1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL ES 3.0 Module
3*35238bceSAndroid Build Coastguard Worker * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief Primitive restart tests.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "es3fPrimitiveRestartTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
33*35238bceSAndroid Build Coastguard Worker #include "deString.h"
34*35238bceSAndroid Build Coastguard Worker
35*35238bceSAndroid Build Coastguard Worker #include "glw.h"
36*35238bceSAndroid Build Coastguard Worker
37*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
38*35238bceSAndroid Build Coastguard Worker
39*35238bceSAndroid Build Coastguard Worker namespace deqp
40*35238bceSAndroid Build Coastguard Worker {
41*35238bceSAndroid Build Coastguard Worker namespace gles3
42*35238bceSAndroid Build Coastguard Worker {
43*35238bceSAndroid Build Coastguard Worker namespace Functional
44*35238bceSAndroid Build Coastguard Worker {
45*35238bceSAndroid Build Coastguard Worker
46*35238bceSAndroid Build Coastguard Worker static const int MAX_RENDER_WIDTH = 256;
47*35238bceSAndroid Build Coastguard Worker static const int MAX_RENDER_HEIGHT = 256;
48*35238bceSAndroid Build Coastguard Worker
49*35238bceSAndroid Build Coastguard Worker static const uint32_t MAX_UNSIGNED_BYTE = (1 << 8) - 1;
50*35238bceSAndroid Build Coastguard Worker static const uint32_t MAX_UNSIGNED_SHORT = (1 << 16) - 1;
51*35238bceSAndroid Build Coastguard Worker static const uint32_t MAX_UNSIGNED_INT = (uint32_t)((1ULL << 32) - 1);
52*35238bceSAndroid Build Coastguard Worker
53*35238bceSAndroid Build Coastguard Worker static const uint8_t RESTART_INDEX_UNSIGNED_BYTE = (uint8_t)MAX_UNSIGNED_BYTE;
54*35238bceSAndroid Build Coastguard Worker static const uint16_t RESTART_INDEX_UNSIGNED_SHORT = (uint16_t)MAX_UNSIGNED_SHORT;
55*35238bceSAndroid Build Coastguard Worker static const uint32_t RESTART_INDEX_UNSIGNED_INT = MAX_UNSIGNED_INT;
56*35238bceSAndroid Build Coastguard Worker
57*35238bceSAndroid Build Coastguard Worker class PrimitiveRestartCase : public TestCase
58*35238bceSAndroid Build Coastguard Worker {
59*35238bceSAndroid Build Coastguard Worker public:
60*35238bceSAndroid Build Coastguard Worker enum PrimitiveType
61*35238bceSAndroid Build Coastguard Worker {
62*35238bceSAndroid Build Coastguard Worker PRIMITIVE_POINTS = 0,
63*35238bceSAndroid Build Coastguard Worker PRIMITIVE_LINE_STRIP,
64*35238bceSAndroid Build Coastguard Worker PRIMITIVE_LINE_LOOP,
65*35238bceSAndroid Build Coastguard Worker PRIMITIVE_LINES,
66*35238bceSAndroid Build Coastguard Worker PRIMITIVE_TRIANGLE_STRIP,
67*35238bceSAndroid Build Coastguard Worker PRIMITIVE_TRIANGLE_FAN,
68*35238bceSAndroid Build Coastguard Worker PRIMITIVE_TRIANGLES,
69*35238bceSAndroid Build Coastguard Worker
70*35238bceSAndroid Build Coastguard Worker PRIMITIVE_LAST
71*35238bceSAndroid Build Coastguard Worker };
72*35238bceSAndroid Build Coastguard Worker
73*35238bceSAndroid Build Coastguard Worker enum IndexType
74*35238bceSAndroid Build Coastguard Worker {
75*35238bceSAndroid Build Coastguard Worker INDEX_UNSIGNED_BYTE = 0,
76*35238bceSAndroid Build Coastguard Worker INDEX_UNSIGNED_SHORT,
77*35238bceSAndroid Build Coastguard Worker INDEX_UNSIGNED_INT,
78*35238bceSAndroid Build Coastguard Worker
79*35238bceSAndroid Build Coastguard Worker INDEX_LAST
80*35238bceSAndroid Build Coastguard Worker };
81*35238bceSAndroid Build Coastguard Worker
82*35238bceSAndroid Build Coastguard Worker enum Function
83*35238bceSAndroid Build Coastguard Worker {
84*35238bceSAndroid Build Coastguard Worker FUNCTION_DRAW_ELEMENTS = 0,
85*35238bceSAndroid Build Coastguard Worker FUNCTION_DRAW_ELEMENTS_INSTANCED,
86*35238bceSAndroid Build Coastguard Worker FUNCTION_DRAW_RANGE_ELEMENTS,
87*35238bceSAndroid Build Coastguard Worker
88*35238bceSAndroid Build Coastguard Worker FUNCTION_LAST
89*35238bceSAndroid Build Coastguard Worker };
90*35238bceSAndroid Build Coastguard Worker
91*35238bceSAndroid Build Coastguard Worker PrimitiveRestartCase(Context &context, const char *name, const char *description, PrimitiveType primType,
92*35238bceSAndroid Build Coastguard Worker IndexType indexType, Function function, bool beginWithRestart, bool endWithRestart,
93*35238bceSAndroid Build Coastguard Worker bool duplicateRestarts);
94*35238bceSAndroid Build Coastguard Worker ~PrimitiveRestartCase(void);
95*35238bceSAndroid Build Coastguard Worker
96*35238bceSAndroid Build Coastguard Worker void init(void);
97*35238bceSAndroid Build Coastguard Worker void deinit(void);
98*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
99*35238bceSAndroid Build Coastguard Worker
100*35238bceSAndroid Build Coastguard Worker private:
101*35238bceSAndroid Build Coastguard Worker PrimitiveRestartCase(const PrimitiveRestartCase &other);
102*35238bceSAndroid Build Coastguard Worker PrimitiveRestartCase &operator=(const PrimitiveRestartCase &other);
103*35238bceSAndroid Build Coastguard Worker
104*35238bceSAndroid Build Coastguard Worker void draw(int startNdx, int count);
105*35238bceSAndroid Build Coastguard Worker
106*35238bceSAndroid Build Coastguard Worker void renderWithRestart(void);
107*35238bceSAndroid Build Coastguard Worker void renderWithoutRestart(void);
108*35238bceSAndroid Build Coastguard Worker
109*35238bceSAndroid Build Coastguard Worker // Helper functions for handling the appropriate index vector (according to m_indexType).
110*35238bceSAndroid Build Coastguard Worker void addIndex(uint32_t index);
111*35238bceSAndroid Build Coastguard Worker uint32_t getIndex(int indexNdx);
112*35238bceSAndroid Build Coastguard Worker int getNumIndices(void);
113*35238bceSAndroid Build Coastguard Worker void *getIndexPtr(int indexNdx);
114*35238bceSAndroid Build Coastguard Worker
115*35238bceSAndroid Build Coastguard Worker // \note Only one of the following index vectors is used (according to m_indexType).
116*35238bceSAndroid Build Coastguard Worker std::vector<uint8_t> m_indicesUB;
117*35238bceSAndroid Build Coastguard Worker std::vector<uint16_t> m_indicesUS;
118*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> m_indicesUI;
119*35238bceSAndroid Build Coastguard Worker
120*35238bceSAndroid Build Coastguard Worker std::vector<float> m_positions;
121*35238bceSAndroid Build Coastguard Worker
122*35238bceSAndroid Build Coastguard Worker PrimitiveType m_primType;
123*35238bceSAndroid Build Coastguard Worker IndexType m_indexType;
124*35238bceSAndroid Build Coastguard Worker Function m_function;
125*35238bceSAndroid Build Coastguard Worker
126*35238bceSAndroid Build Coastguard Worker bool m_beginWithRestart; // Whether there will be restart indices at the beginning of the index array.
127*35238bceSAndroid Build Coastguard Worker bool m_endWithRestart; // Whether there will be restart indices at the end of the index array.
128*35238bceSAndroid Build Coastguard Worker bool m_duplicateRestarts; // Whether two consecutive restarts are used instead of one.
129*35238bceSAndroid Build Coastguard Worker
130*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_program;
131*35238bceSAndroid Build Coastguard Worker };
132*35238bceSAndroid Build Coastguard Worker
PrimitiveRestartCase(Context & context,const char * name,const char * description,PrimitiveType primType,IndexType indexType,Function function,bool beginWithRestart,bool endWithRestart,bool duplicateRestarts)133*35238bceSAndroid Build Coastguard Worker PrimitiveRestartCase::PrimitiveRestartCase(Context &context, const char *name, const char *description,
134*35238bceSAndroid Build Coastguard Worker PrimitiveType primType, IndexType indexType, Function function,
135*35238bceSAndroid Build Coastguard Worker bool beginWithRestart, bool endWithRestart, bool duplicateRestarts)
136*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
137*35238bceSAndroid Build Coastguard Worker , m_primType(primType)
138*35238bceSAndroid Build Coastguard Worker , m_indexType(indexType)
139*35238bceSAndroid Build Coastguard Worker , m_function(function)
140*35238bceSAndroid Build Coastguard Worker , m_beginWithRestart(beginWithRestart)
141*35238bceSAndroid Build Coastguard Worker , m_endWithRestart(endWithRestart)
142*35238bceSAndroid Build Coastguard Worker , m_duplicateRestarts(duplicateRestarts)
143*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
144*35238bceSAndroid Build Coastguard Worker {
145*35238bceSAndroid Build Coastguard Worker }
146*35238bceSAndroid Build Coastguard Worker
~PrimitiveRestartCase(void)147*35238bceSAndroid Build Coastguard Worker PrimitiveRestartCase::~PrimitiveRestartCase(void)
148*35238bceSAndroid Build Coastguard Worker {
149*35238bceSAndroid Build Coastguard Worker PrimitiveRestartCase::deinit();
150*35238bceSAndroid Build Coastguard Worker }
151*35238bceSAndroid Build Coastguard Worker
deinit(void)152*35238bceSAndroid Build Coastguard Worker void PrimitiveRestartCase::deinit(void)
153*35238bceSAndroid Build Coastguard Worker {
154*35238bceSAndroid Build Coastguard Worker delete m_program;
155*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
156*35238bceSAndroid Build Coastguard Worker }
157*35238bceSAndroid Build Coastguard Worker
addIndex(uint32_t index)158*35238bceSAndroid Build Coastguard Worker void PrimitiveRestartCase::addIndex(uint32_t index)
159*35238bceSAndroid Build Coastguard Worker {
160*35238bceSAndroid Build Coastguard Worker if (m_indexType == INDEX_UNSIGNED_BYTE)
161*35238bceSAndroid Build Coastguard Worker {
162*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inRange(index, (uint32_t)0, MAX_UNSIGNED_BYTE));
163*35238bceSAndroid Build Coastguard Worker m_indicesUB.push_back((uint8_t)index);
164*35238bceSAndroid Build Coastguard Worker }
165*35238bceSAndroid Build Coastguard Worker else if (m_indexType == INDEX_UNSIGNED_SHORT)
166*35238bceSAndroid Build Coastguard Worker {
167*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inRange(index, (uint32_t)0, MAX_UNSIGNED_SHORT));
168*35238bceSAndroid Build Coastguard Worker m_indicesUS.push_back((uint16_t)index);
169*35238bceSAndroid Build Coastguard Worker }
170*35238bceSAndroid Build Coastguard Worker else if (m_indexType == INDEX_UNSIGNED_INT)
171*35238bceSAndroid Build Coastguard Worker {
172*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inRange(index, (uint32_t)0, MAX_UNSIGNED_INT));
173*35238bceSAndroid Build Coastguard Worker m_indicesUI.push_back((uint32_t)index);
174*35238bceSAndroid Build Coastguard Worker }
175*35238bceSAndroid Build Coastguard Worker else
176*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
177*35238bceSAndroid Build Coastguard Worker }
178*35238bceSAndroid Build Coastguard Worker
getIndex(int indexNdx)179*35238bceSAndroid Build Coastguard Worker uint32_t PrimitiveRestartCase::getIndex(int indexNdx)
180*35238bceSAndroid Build Coastguard Worker {
181*35238bceSAndroid Build Coastguard Worker switch (m_indexType)
182*35238bceSAndroid Build Coastguard Worker {
183*35238bceSAndroid Build Coastguard Worker case INDEX_UNSIGNED_BYTE:
184*35238bceSAndroid Build Coastguard Worker return (uint32_t)m_indicesUB[indexNdx];
185*35238bceSAndroid Build Coastguard Worker case INDEX_UNSIGNED_SHORT:
186*35238bceSAndroid Build Coastguard Worker return (uint32_t)m_indicesUS[indexNdx];
187*35238bceSAndroid Build Coastguard Worker case INDEX_UNSIGNED_INT:
188*35238bceSAndroid Build Coastguard Worker return m_indicesUI[indexNdx];
189*35238bceSAndroid Build Coastguard Worker default:
190*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
191*35238bceSAndroid Build Coastguard Worker return 0;
192*35238bceSAndroid Build Coastguard Worker }
193*35238bceSAndroid Build Coastguard Worker }
194*35238bceSAndroid Build Coastguard Worker
getNumIndices(void)195*35238bceSAndroid Build Coastguard Worker int PrimitiveRestartCase::getNumIndices(void)
196*35238bceSAndroid Build Coastguard Worker {
197*35238bceSAndroid Build Coastguard Worker switch (m_indexType)
198*35238bceSAndroid Build Coastguard Worker {
199*35238bceSAndroid Build Coastguard Worker case INDEX_UNSIGNED_BYTE:
200*35238bceSAndroid Build Coastguard Worker return (int)m_indicesUB.size();
201*35238bceSAndroid Build Coastguard Worker case INDEX_UNSIGNED_SHORT:
202*35238bceSAndroid Build Coastguard Worker return (int)m_indicesUS.size();
203*35238bceSAndroid Build Coastguard Worker case INDEX_UNSIGNED_INT:
204*35238bceSAndroid Build Coastguard Worker return (int)m_indicesUI.size();
205*35238bceSAndroid Build Coastguard Worker default:
206*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
207*35238bceSAndroid Build Coastguard Worker return 0;
208*35238bceSAndroid Build Coastguard Worker }
209*35238bceSAndroid Build Coastguard Worker }
210*35238bceSAndroid Build Coastguard Worker
211*35238bceSAndroid Build Coastguard Worker // Pointer to the index value at index indexNdx.
getIndexPtr(int indexNdx)212*35238bceSAndroid Build Coastguard Worker void *PrimitiveRestartCase::getIndexPtr(int indexNdx)
213*35238bceSAndroid Build Coastguard Worker {
214*35238bceSAndroid Build Coastguard Worker switch (m_indexType)
215*35238bceSAndroid Build Coastguard Worker {
216*35238bceSAndroid Build Coastguard Worker case INDEX_UNSIGNED_BYTE:
217*35238bceSAndroid Build Coastguard Worker return (void *)&m_indicesUB[indexNdx];
218*35238bceSAndroid Build Coastguard Worker case INDEX_UNSIGNED_SHORT:
219*35238bceSAndroid Build Coastguard Worker return (void *)&m_indicesUS[indexNdx];
220*35238bceSAndroid Build Coastguard Worker case INDEX_UNSIGNED_INT:
221*35238bceSAndroid Build Coastguard Worker return (void *)&m_indicesUI[indexNdx];
222*35238bceSAndroid Build Coastguard Worker default:
223*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
224*35238bceSAndroid Build Coastguard Worker return DE_NULL;
225*35238bceSAndroid Build Coastguard Worker }
226*35238bceSAndroid Build Coastguard Worker }
227*35238bceSAndroid Build Coastguard Worker
init(void)228*35238bceSAndroid Build Coastguard Worker void PrimitiveRestartCase::init(void)
229*35238bceSAndroid Build Coastguard Worker {
230*35238bceSAndroid Build Coastguard Worker // Create shader program.
231*35238bceSAndroid Build Coastguard Worker std::string vertShaderSource;
232*35238bceSAndroid Build Coastguard Worker if (m_primType == PRIMITIVE_POINTS)
233*35238bceSAndroid Build Coastguard Worker {
234*35238bceSAndroid Build Coastguard Worker vertShaderSource = "#version 300 es\n"
235*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
236*35238bceSAndroid Build Coastguard Worker "\n"
237*35238bceSAndroid Build Coastguard Worker "void main()\n"
238*35238bceSAndroid Build Coastguard Worker "{\n"
239*35238bceSAndroid Build Coastguard Worker " gl_Position = a_position;\n"
240*35238bceSAndroid Build Coastguard Worker " gl_PointSize = 1.0f;\n"
241*35238bceSAndroid Build Coastguard Worker "}\n";
242*35238bceSAndroid Build Coastguard Worker }
243*35238bceSAndroid Build Coastguard Worker else
244*35238bceSAndroid Build Coastguard Worker {
245*35238bceSAndroid Build Coastguard Worker vertShaderSource = "#version 300 es\n"
246*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
247*35238bceSAndroid Build Coastguard Worker "\n"
248*35238bceSAndroid Build Coastguard Worker "void main()\n"
249*35238bceSAndroid Build Coastguard Worker "{\n"
250*35238bceSAndroid Build Coastguard Worker " gl_Position = a_position;\n"
251*35238bceSAndroid Build Coastguard Worker "}\n";
252*35238bceSAndroid Build Coastguard Worker }
253*35238bceSAndroid Build Coastguard Worker
254*35238bceSAndroid Build Coastguard Worker static const char *fragShaderSource = "#version 300 es\n"
255*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out mediump vec4 o_color;\n"
256*35238bceSAndroid Build Coastguard Worker "\n"
257*35238bceSAndroid Build Coastguard Worker "void main()\n"
258*35238bceSAndroid Build Coastguard Worker "{\n"
259*35238bceSAndroid Build Coastguard Worker " o_color = vec4(1.0f);\n"
260*35238bceSAndroid Build Coastguard Worker "}\n";
261*35238bceSAndroid Build Coastguard Worker
262*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_program);
263*35238bceSAndroid Build Coastguard Worker m_program = new glu::ShaderProgram(m_context.getRenderContext(),
264*35238bceSAndroid Build Coastguard Worker glu::makeVtxFragSources(vertShaderSource, fragShaderSource));
265*35238bceSAndroid Build Coastguard Worker
266*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
267*35238bceSAndroid Build Coastguard Worker {
268*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_program;
269*35238bceSAndroid Build Coastguard Worker TCU_FAIL("Failed to compile shader");
270*35238bceSAndroid Build Coastguard Worker }
271*35238bceSAndroid Build Coastguard Worker
272*35238bceSAndroid Build Coastguard Worker uint32_t restartIndex = m_indexType == INDEX_UNSIGNED_BYTE ? RESTART_INDEX_UNSIGNED_BYTE :
273*35238bceSAndroid Build Coastguard Worker m_indexType == INDEX_UNSIGNED_SHORT ? RESTART_INDEX_UNSIGNED_SHORT :
274*35238bceSAndroid Build Coastguard Worker m_indexType == INDEX_UNSIGNED_INT ? RESTART_INDEX_UNSIGNED_INT :
275*35238bceSAndroid Build Coastguard Worker 0;
276*35238bceSAndroid Build Coastguard Worker
277*35238bceSAndroid Build Coastguard Worker DE_ASSERT(restartIndex != 0);
278*35238bceSAndroid Build Coastguard Worker
279*35238bceSAndroid Build Coastguard Worker DE_ASSERT(getNumIndices() == 0);
280*35238bceSAndroid Build Coastguard Worker
281*35238bceSAndroid Build Coastguard Worker // If testing a case with restart at beginning, add it there.
282*35238bceSAndroid Build Coastguard Worker if (m_beginWithRestart)
283*35238bceSAndroid Build Coastguard Worker {
284*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
285*35238bceSAndroid Build Coastguard Worker if (m_duplicateRestarts)
286*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
287*35238bceSAndroid Build Coastguard Worker }
288*35238bceSAndroid Build Coastguard Worker
289*35238bceSAndroid Build Coastguard Worker // Generate vertex positions and indices depending on primitive type.
290*35238bceSAndroid Build Coastguard Worker // \note At this point, restarts shall not be added to the start or the end of the index vector. Those are special cases, and are done above and after the following if-else chain, respectively.
291*35238bceSAndroid Build Coastguard Worker
292*35238bceSAndroid Build Coastguard Worker if (m_primType == PRIMITIVE_POINTS)
293*35238bceSAndroid Build Coastguard Worker {
294*35238bceSAndroid Build Coastguard Worker // Generate rows with different numbers of points.
295*35238bceSAndroid Build Coastguard Worker
296*35238bceSAndroid Build Coastguard Worker uint32_t curIndex = 0;
297*35238bceSAndroid Build Coastguard Worker const int numRows = 20;
298*35238bceSAndroid Build Coastguard Worker
299*35238bceSAndroid Build Coastguard Worker for (int row = 0; row < numRows; row++)
300*35238bceSAndroid Build Coastguard Worker {
301*35238bceSAndroid Build Coastguard Worker for (int col = 0; col < row + 1; col++)
302*35238bceSAndroid Build Coastguard Worker {
303*35238bceSAndroid Build Coastguard Worker float fx = -1.0f + 2.0f * ((float)col + 0.5f) / (float)numRows;
304*35238bceSAndroid Build Coastguard Worker float fy = -1.0f + 2.0f * ((float)row + 0.5f) / (float)numRows;
305*35238bceSAndroid Build Coastguard Worker
306*35238bceSAndroid Build Coastguard Worker m_positions.push_back(fx);
307*35238bceSAndroid Build Coastguard Worker m_positions.push_back(fy);
308*35238bceSAndroid Build Coastguard Worker
309*35238bceSAndroid Build Coastguard Worker addIndex(curIndex++);
310*35238bceSAndroid Build Coastguard Worker }
311*35238bceSAndroid Build Coastguard Worker
312*35238bceSAndroid Build Coastguard Worker if (row < numRows - 1) // Add a restart after all but last row.
313*35238bceSAndroid Build Coastguard Worker {
314*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
315*35238bceSAndroid Build Coastguard Worker if (m_duplicateRestarts)
316*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
317*35238bceSAndroid Build Coastguard Worker }
318*35238bceSAndroid Build Coastguard Worker }
319*35238bceSAndroid Build Coastguard Worker }
320*35238bceSAndroid Build Coastguard Worker else if (m_primType == PRIMITIVE_LINE_STRIP || m_primType == PRIMITIVE_LINE_LOOP || m_primType == PRIMITIVE_LINES)
321*35238bceSAndroid Build Coastguard Worker {
322*35238bceSAndroid Build Coastguard Worker // Generate a numRows x numCols arrangement of line polygons of different vertex counts.
323*35238bceSAndroid Build Coastguard Worker
324*35238bceSAndroid Build Coastguard Worker uint32_t curIndex = 0;
325*35238bceSAndroid Build Coastguard Worker const int numRows = 4;
326*35238bceSAndroid Build Coastguard Worker const int numCols = 4;
327*35238bceSAndroid Build Coastguard Worker
328*35238bceSAndroid Build Coastguard Worker for (int row = 0; row < numRows; row++)
329*35238bceSAndroid Build Coastguard Worker {
330*35238bceSAndroid Build Coastguard Worker float centerY = -1.0f + 2.0f * ((float)row + 0.5f) / (float)numRows;
331*35238bceSAndroid Build Coastguard Worker
332*35238bceSAndroid Build Coastguard Worker for (int col = 0; col < numCols; col++)
333*35238bceSAndroid Build Coastguard Worker {
334*35238bceSAndroid Build Coastguard Worker float centerX = -1.0f + 2.0f * ((float)col + 0.5f) / (float)numCols;
335*35238bceSAndroid Build Coastguard Worker int numVertices = row * numCols + col + 1;
336*35238bceSAndroid Build Coastguard Worker
337*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < numVertices; i++)
338*35238bceSAndroid Build Coastguard Worker {
339*35238bceSAndroid Build Coastguard Worker float fx =
340*35238bceSAndroid Build Coastguard Worker centerX + 0.9f * deFloatCos((float)i * 2.0f * DE_PI / (float)numVertices) / (float)numCols;
341*35238bceSAndroid Build Coastguard Worker float fy =
342*35238bceSAndroid Build Coastguard Worker centerY + 0.9f * deFloatSin((float)i * 2.0f * DE_PI / (float)numVertices) / (float)numRows;
343*35238bceSAndroid Build Coastguard Worker
344*35238bceSAndroid Build Coastguard Worker m_positions.push_back(fx);
345*35238bceSAndroid Build Coastguard Worker m_positions.push_back(fy);
346*35238bceSAndroid Build Coastguard Worker
347*35238bceSAndroid Build Coastguard Worker addIndex(curIndex++);
348*35238bceSAndroid Build Coastguard Worker }
349*35238bceSAndroid Build Coastguard Worker
350*35238bceSAndroid Build Coastguard Worker if (col < numCols - 1 || row < numRows - 1) // Add a restart after all but last polygon.
351*35238bceSAndroid Build Coastguard Worker {
352*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
353*35238bceSAndroid Build Coastguard Worker if (m_duplicateRestarts)
354*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
355*35238bceSAndroid Build Coastguard Worker }
356*35238bceSAndroid Build Coastguard Worker }
357*35238bceSAndroid Build Coastguard Worker }
358*35238bceSAndroid Build Coastguard Worker }
359*35238bceSAndroid Build Coastguard Worker else if (m_primType == PRIMITIVE_TRIANGLE_STRIP)
360*35238bceSAndroid Build Coastguard Worker {
361*35238bceSAndroid Build Coastguard Worker // Generate a number of horizontal triangle strips of different lengths.
362*35238bceSAndroid Build Coastguard Worker
363*35238bceSAndroid Build Coastguard Worker uint32_t curIndex = 0;
364*35238bceSAndroid Build Coastguard Worker const int numStrips = 20;
365*35238bceSAndroid Build Coastguard Worker
366*35238bceSAndroid Build Coastguard Worker for (int stripNdx = 0; stripNdx < numStrips; stripNdx++)
367*35238bceSAndroid Build Coastguard Worker {
368*35238bceSAndroid Build Coastguard Worker int numVertices = stripNdx + 1;
369*35238bceSAndroid Build Coastguard Worker
370*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < numVertices; i++)
371*35238bceSAndroid Build Coastguard Worker {
372*35238bceSAndroid Build Coastguard Worker float fx = -0.9f + 1.8f * (float)(i / 2 * 2) / numStrips;
373*35238bceSAndroid Build Coastguard Worker float fy = -0.9f + 1.8f * ((float)stripNdx + (i % 2 == 0 ? 0.0f : 0.8f)) / numStrips;
374*35238bceSAndroid Build Coastguard Worker
375*35238bceSAndroid Build Coastguard Worker m_positions.push_back(fx);
376*35238bceSAndroid Build Coastguard Worker m_positions.push_back(fy);
377*35238bceSAndroid Build Coastguard Worker
378*35238bceSAndroid Build Coastguard Worker addIndex(curIndex++);
379*35238bceSAndroid Build Coastguard Worker }
380*35238bceSAndroid Build Coastguard Worker
381*35238bceSAndroid Build Coastguard Worker if (stripNdx < numStrips - 1) // Add a restart after all but last strip.
382*35238bceSAndroid Build Coastguard Worker {
383*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
384*35238bceSAndroid Build Coastguard Worker if (m_duplicateRestarts)
385*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
386*35238bceSAndroid Build Coastguard Worker }
387*35238bceSAndroid Build Coastguard Worker }
388*35238bceSAndroid Build Coastguard Worker }
389*35238bceSAndroid Build Coastguard Worker else if (m_primType == PRIMITIVE_TRIANGLE_FAN)
390*35238bceSAndroid Build Coastguard Worker {
391*35238bceSAndroid Build Coastguard Worker // Generate a numRows x numCols arrangement of triangle fan polygons of different vertex counts.
392*35238bceSAndroid Build Coastguard Worker
393*35238bceSAndroid Build Coastguard Worker uint32_t curIndex = 0;
394*35238bceSAndroid Build Coastguard Worker const int numRows = 4;
395*35238bceSAndroid Build Coastguard Worker const int numCols = 4;
396*35238bceSAndroid Build Coastguard Worker
397*35238bceSAndroid Build Coastguard Worker for (int row = 0; row < numRows; row++)
398*35238bceSAndroid Build Coastguard Worker {
399*35238bceSAndroid Build Coastguard Worker float centerY = -1.0f + 2.0f * ((float)row + 0.5f) / (float)numRows;
400*35238bceSAndroid Build Coastguard Worker
401*35238bceSAndroid Build Coastguard Worker for (int col = 0; col < numCols; col++)
402*35238bceSAndroid Build Coastguard Worker {
403*35238bceSAndroid Build Coastguard Worker float centerX = -1.0f + 2.0f * ((float)col + 0.5f) / (float)numCols;
404*35238bceSAndroid Build Coastguard Worker int numArcVertices = row * numCols + col;
405*35238bceSAndroid Build Coastguard Worker
406*35238bceSAndroid Build Coastguard Worker m_positions.push_back(centerX);
407*35238bceSAndroid Build Coastguard Worker m_positions.push_back(centerY);
408*35238bceSAndroid Build Coastguard Worker
409*35238bceSAndroid Build Coastguard Worker addIndex(curIndex++);
410*35238bceSAndroid Build Coastguard Worker
411*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < numArcVertices; i++)
412*35238bceSAndroid Build Coastguard Worker {
413*35238bceSAndroid Build Coastguard Worker float fx =
414*35238bceSAndroid Build Coastguard Worker centerX + 0.9f * deFloatCos((float)i * 2.0f * DE_PI / (float)numArcVertices) / (float)numCols;
415*35238bceSAndroid Build Coastguard Worker float fy =
416*35238bceSAndroid Build Coastguard Worker centerY + 0.9f * deFloatSin((float)i * 2.0f * DE_PI / (float)numArcVertices) / (float)numRows;
417*35238bceSAndroid Build Coastguard Worker
418*35238bceSAndroid Build Coastguard Worker m_positions.push_back(fx);
419*35238bceSAndroid Build Coastguard Worker m_positions.push_back(fy);
420*35238bceSAndroid Build Coastguard Worker
421*35238bceSAndroid Build Coastguard Worker addIndex(curIndex++);
422*35238bceSAndroid Build Coastguard Worker }
423*35238bceSAndroid Build Coastguard Worker
424*35238bceSAndroid Build Coastguard Worker if (col < numCols - 1 || row < numRows - 1) // Add a restart after all but last polygon.
425*35238bceSAndroid Build Coastguard Worker {
426*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
427*35238bceSAndroid Build Coastguard Worker if (m_duplicateRestarts)
428*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
429*35238bceSAndroid Build Coastguard Worker }
430*35238bceSAndroid Build Coastguard Worker }
431*35238bceSAndroid Build Coastguard Worker }
432*35238bceSAndroid Build Coastguard Worker }
433*35238bceSAndroid Build Coastguard Worker else if (m_primType == PRIMITIVE_TRIANGLES)
434*35238bceSAndroid Build Coastguard Worker {
435*35238bceSAndroid Build Coastguard Worker // Generate a number of rows with (potentially incomplete) triangles.
436*35238bceSAndroid Build Coastguard Worker
437*35238bceSAndroid Build Coastguard Worker uint32_t curIndex = 0;
438*35238bceSAndroid Build Coastguard Worker const int numRows = 3 * 7;
439*35238bceSAndroid Build Coastguard Worker
440*35238bceSAndroid Build Coastguard Worker for (int rowNdx = 0; rowNdx < numRows; rowNdx++)
441*35238bceSAndroid Build Coastguard Worker {
442*35238bceSAndroid Build Coastguard Worker int numVertices = rowNdx + 1;
443*35238bceSAndroid Build Coastguard Worker
444*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < numVertices; i++)
445*35238bceSAndroid Build Coastguard Worker {
446*35238bceSAndroid Build Coastguard Worker float fx = -0.9f + 1.8f * ((float)(i / 3) + (i % 3 == 2 ? 0.8f : 0.0f)) * 3 / numRows;
447*35238bceSAndroid Build Coastguard Worker float fy = -0.9f + 1.8f * ((float)rowNdx + (i % 3 == 0 ? 0.0f : 0.8f)) / numRows;
448*35238bceSAndroid Build Coastguard Worker
449*35238bceSAndroid Build Coastguard Worker m_positions.push_back(fx);
450*35238bceSAndroid Build Coastguard Worker m_positions.push_back(fy);
451*35238bceSAndroid Build Coastguard Worker
452*35238bceSAndroid Build Coastguard Worker addIndex(curIndex++);
453*35238bceSAndroid Build Coastguard Worker }
454*35238bceSAndroid Build Coastguard Worker
455*35238bceSAndroid Build Coastguard Worker if (rowNdx < numRows - 1) // Add a restart after all but last row.
456*35238bceSAndroid Build Coastguard Worker {
457*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
458*35238bceSAndroid Build Coastguard Worker if (m_duplicateRestarts)
459*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
460*35238bceSAndroid Build Coastguard Worker }
461*35238bceSAndroid Build Coastguard Worker }
462*35238bceSAndroid Build Coastguard Worker }
463*35238bceSAndroid Build Coastguard Worker else
464*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
465*35238bceSAndroid Build Coastguard Worker
466*35238bceSAndroid Build Coastguard Worker // If testing a case with restart at end, add it there.
467*35238bceSAndroid Build Coastguard Worker if (m_endWithRestart)
468*35238bceSAndroid Build Coastguard Worker {
469*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
470*35238bceSAndroid Build Coastguard Worker if (m_duplicateRestarts)
471*35238bceSAndroid Build Coastguard Worker addIndex(restartIndex);
472*35238bceSAndroid Build Coastguard Worker }
473*35238bceSAndroid Build Coastguard Worker
474*35238bceSAndroid Build Coastguard Worker // Special case assertions.
475*35238bceSAndroid Build Coastguard Worker
476*35238bceSAndroid Build Coastguard Worker int numIndices = getNumIndices();
477*35238bceSAndroid Build Coastguard Worker
478*35238bceSAndroid Build Coastguard Worker DE_ASSERT(numIndices > 0);
479*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_beginWithRestart ||
480*35238bceSAndroid Build Coastguard Worker getIndex(0) != restartIndex); // We don't want restarts at beginning unless the case is a special case.
481*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_endWithRestart || getIndex(numIndices - 1) !=
482*35238bceSAndroid Build Coastguard Worker restartIndex); // We don't want restarts at end unless the case is a special case.
483*35238bceSAndroid Build Coastguard Worker
484*35238bceSAndroid Build Coastguard Worker if (!m_duplicateRestarts)
485*35238bceSAndroid Build Coastguard Worker for (int i = 1; i < numIndices; i++)
486*35238bceSAndroid Build Coastguard Worker DE_ASSERT(getIndex(i) != restartIndex ||
487*35238bceSAndroid Build Coastguard Worker getIndex(i - 1) !=
488*35238bceSAndroid Build Coastguard Worker restartIndex); // We don't want duplicate restarts unless the case is a special case.
489*35238bceSAndroid Build Coastguard Worker }
490*35238bceSAndroid Build Coastguard Worker
iterate(void)491*35238bceSAndroid Build Coastguard Worker PrimitiveRestartCase::IterateResult PrimitiveRestartCase::iterate(void)
492*35238bceSAndroid Build Coastguard Worker {
493*35238bceSAndroid Build Coastguard Worker int width = deMin32(m_context.getRenderTarget().getWidth(), MAX_RENDER_WIDTH);
494*35238bceSAndroid Build Coastguard Worker int height = deMin32(m_context.getRenderTarget().getHeight(), MAX_RENDER_HEIGHT);
495*35238bceSAndroid Build Coastguard Worker
496*35238bceSAndroid Build Coastguard Worker int xOffsetMax = m_context.getRenderTarget().getWidth() - width;
497*35238bceSAndroid Build Coastguard Worker int yOffsetMax = m_context.getRenderTarget().getHeight() - height;
498*35238bceSAndroid Build Coastguard Worker
499*35238bceSAndroid Build Coastguard Worker de::Random rnd(deStringHash(getName()));
500*35238bceSAndroid Build Coastguard Worker
501*35238bceSAndroid Build Coastguard Worker int xOffset = rnd.getInt(0, xOffsetMax);
502*35238bceSAndroid Build Coastguard Worker int yOffset = rnd.getInt(0, yOffsetMax);
503*35238bceSAndroid Build Coastguard Worker tcu::Surface referenceImg(width, height);
504*35238bceSAndroid Build Coastguard Worker tcu::Surface resultImg(width, height);
505*35238bceSAndroid Build Coastguard Worker
506*35238bceSAndroid Build Coastguard Worker glViewport(xOffset, yOffset, width, height);
507*35238bceSAndroid Build Coastguard Worker glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
508*35238bceSAndroid Build Coastguard Worker
509*35238bceSAndroid Build Coastguard Worker uint32_t program = m_program->getProgram();
510*35238bceSAndroid Build Coastguard Worker glUseProgram(program);
511*35238bceSAndroid Build Coastguard Worker
512*35238bceSAndroid Build Coastguard Worker // Setup position attribute.
513*35238bceSAndroid Build Coastguard Worker
514*35238bceSAndroid Build Coastguard Worker int loc = glGetAttribLocation(program, "a_position");
515*35238bceSAndroid Build Coastguard Worker glEnableVertexAttribArray(loc);
516*35238bceSAndroid Build Coastguard Worker glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, &m_positions[0]);
517*35238bceSAndroid Build Coastguard Worker
518*35238bceSAndroid Build Coastguard Worker // Render result.
519*35238bceSAndroid Build Coastguard Worker
520*35238bceSAndroid Build Coastguard Worker renderWithRestart();
521*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), xOffset, yOffset, resultImg.getAccess());
522*35238bceSAndroid Build Coastguard Worker
523*35238bceSAndroid Build Coastguard Worker // Render reference (same scene as the real deal, but emulate primitive restart without actually using it).
524*35238bceSAndroid Build Coastguard Worker
525*35238bceSAndroid Build Coastguard Worker renderWithoutRestart();
526*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), xOffset, yOffset, referenceImg.getAccess());
527*35238bceSAndroid Build Coastguard Worker
528*35238bceSAndroid Build Coastguard Worker // Compare.
529*35238bceSAndroid Build Coastguard Worker
530*35238bceSAndroid Build Coastguard Worker bool testOk = tcu::pixelThresholdCompare(m_testCtx.getLog(), "ComparisonResult", "Image comparison result",
531*35238bceSAndroid Build Coastguard Worker referenceImg, resultImg, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
532*35238bceSAndroid Build Coastguard Worker
533*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(testOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, testOk ? "Pass" : "Fail");
534*35238bceSAndroid Build Coastguard Worker
535*35238bceSAndroid Build Coastguard Worker glUseProgram(0);
536*35238bceSAndroid Build Coastguard Worker
537*35238bceSAndroid Build Coastguard Worker return STOP;
538*35238bceSAndroid Build Coastguard Worker }
539*35238bceSAndroid Build Coastguard Worker
540*35238bceSAndroid Build Coastguard Worker // Draw with the appropriate GLES3 draw function.
draw(int startNdx,int count)541*35238bceSAndroid Build Coastguard Worker void PrimitiveRestartCase::draw(int startNdx, int count)
542*35238bceSAndroid Build Coastguard Worker {
543*35238bceSAndroid Build Coastguard Worker GLenum primTypeGL;
544*35238bceSAndroid Build Coastguard Worker
545*35238bceSAndroid Build Coastguard Worker switch (m_primType)
546*35238bceSAndroid Build Coastguard Worker {
547*35238bceSAndroid Build Coastguard Worker case PRIMITIVE_POINTS:
548*35238bceSAndroid Build Coastguard Worker primTypeGL = GL_POINTS;
549*35238bceSAndroid Build Coastguard Worker break;
550*35238bceSAndroid Build Coastguard Worker case PRIMITIVE_LINE_STRIP:
551*35238bceSAndroid Build Coastguard Worker primTypeGL = GL_LINE_STRIP;
552*35238bceSAndroid Build Coastguard Worker break;
553*35238bceSAndroid Build Coastguard Worker case PRIMITIVE_LINE_LOOP:
554*35238bceSAndroid Build Coastguard Worker primTypeGL = GL_LINE_LOOP;
555*35238bceSAndroid Build Coastguard Worker break;
556*35238bceSAndroid Build Coastguard Worker case PRIMITIVE_LINES:
557*35238bceSAndroid Build Coastguard Worker primTypeGL = GL_LINES;
558*35238bceSAndroid Build Coastguard Worker break;
559*35238bceSAndroid Build Coastguard Worker case PRIMITIVE_TRIANGLE_STRIP:
560*35238bceSAndroid Build Coastguard Worker primTypeGL = GL_TRIANGLE_STRIP;
561*35238bceSAndroid Build Coastguard Worker break;
562*35238bceSAndroid Build Coastguard Worker case PRIMITIVE_TRIANGLE_FAN:
563*35238bceSAndroid Build Coastguard Worker primTypeGL = GL_TRIANGLE_FAN;
564*35238bceSAndroid Build Coastguard Worker break;
565*35238bceSAndroid Build Coastguard Worker case PRIMITIVE_TRIANGLES:
566*35238bceSAndroid Build Coastguard Worker primTypeGL = GL_TRIANGLES;
567*35238bceSAndroid Build Coastguard Worker break;
568*35238bceSAndroid Build Coastguard Worker default:
569*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
570*35238bceSAndroid Build Coastguard Worker primTypeGL = 0;
571*35238bceSAndroid Build Coastguard Worker }
572*35238bceSAndroid Build Coastguard Worker
573*35238bceSAndroid Build Coastguard Worker GLenum indexTypeGL;
574*35238bceSAndroid Build Coastguard Worker
575*35238bceSAndroid Build Coastguard Worker switch (m_indexType)
576*35238bceSAndroid Build Coastguard Worker {
577*35238bceSAndroid Build Coastguard Worker case INDEX_UNSIGNED_BYTE:
578*35238bceSAndroid Build Coastguard Worker indexTypeGL = GL_UNSIGNED_BYTE;
579*35238bceSAndroid Build Coastguard Worker break;
580*35238bceSAndroid Build Coastguard Worker case INDEX_UNSIGNED_SHORT:
581*35238bceSAndroid Build Coastguard Worker indexTypeGL = GL_UNSIGNED_SHORT;
582*35238bceSAndroid Build Coastguard Worker break;
583*35238bceSAndroid Build Coastguard Worker case INDEX_UNSIGNED_INT:
584*35238bceSAndroid Build Coastguard Worker indexTypeGL = GL_UNSIGNED_INT;
585*35238bceSAndroid Build Coastguard Worker break;
586*35238bceSAndroid Build Coastguard Worker default:
587*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
588*35238bceSAndroid Build Coastguard Worker indexTypeGL = 0;
589*35238bceSAndroid Build Coastguard Worker }
590*35238bceSAndroid Build Coastguard Worker
591*35238bceSAndroid Build Coastguard Worker uint32_t restartIndex = m_indexType == INDEX_UNSIGNED_BYTE ? RESTART_INDEX_UNSIGNED_BYTE :
592*35238bceSAndroid Build Coastguard Worker m_indexType == INDEX_UNSIGNED_SHORT ? RESTART_INDEX_UNSIGNED_SHORT :
593*35238bceSAndroid Build Coastguard Worker m_indexType == INDEX_UNSIGNED_INT ? RESTART_INDEX_UNSIGNED_INT :
594*35238bceSAndroid Build Coastguard Worker 0;
595*35238bceSAndroid Build Coastguard Worker
596*35238bceSAndroid Build Coastguard Worker DE_ASSERT(restartIndex != 0);
597*35238bceSAndroid Build Coastguard Worker
598*35238bceSAndroid Build Coastguard Worker if (m_function == FUNCTION_DRAW_ELEMENTS)
599*35238bceSAndroid Build Coastguard Worker glDrawElements(primTypeGL, (GLsizei)count, indexTypeGL, (GLvoid *)getIndexPtr(startNdx));
600*35238bceSAndroid Build Coastguard Worker else if (m_function == FUNCTION_DRAW_ELEMENTS_INSTANCED)
601*35238bceSAndroid Build Coastguard Worker glDrawElementsInstanced(primTypeGL, (GLsizei)count, indexTypeGL, (GLvoid *)getIndexPtr(startNdx), 1);
602*35238bceSAndroid Build Coastguard Worker else
603*35238bceSAndroid Build Coastguard Worker {
604*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_function == FUNCTION_DRAW_RANGE_ELEMENTS);
605*35238bceSAndroid Build Coastguard Worker
606*35238bceSAndroid Build Coastguard Worker // Find the largest non-restart index in the index array (for glDrawRangeElements() end parameter).
607*35238bceSAndroid Build Coastguard Worker
608*35238bceSAndroid Build Coastguard Worker uint32_t max = 0;
609*35238bceSAndroid Build Coastguard Worker
610*35238bceSAndroid Build Coastguard Worker int numIndices = getNumIndices();
611*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < numIndices; i++)
612*35238bceSAndroid Build Coastguard Worker {
613*35238bceSAndroid Build Coastguard Worker uint32_t index = getIndex(i);
614*35238bceSAndroid Build Coastguard Worker if (index != restartIndex && index > max)
615*35238bceSAndroid Build Coastguard Worker max = index;
616*35238bceSAndroid Build Coastguard Worker }
617*35238bceSAndroid Build Coastguard Worker
618*35238bceSAndroid Build Coastguard Worker glDrawRangeElements(primTypeGL, 0, (GLuint)max, (GLsizei)count, indexTypeGL, (GLvoid *)getIndexPtr(startNdx));
619*35238bceSAndroid Build Coastguard Worker }
620*35238bceSAndroid Build Coastguard Worker }
621*35238bceSAndroid Build Coastguard Worker
renderWithRestart(void)622*35238bceSAndroid Build Coastguard Worker void PrimitiveRestartCase::renderWithRestart(void)
623*35238bceSAndroid Build Coastguard Worker {
624*35238bceSAndroid Build Coastguard Worker GLU_CHECK_MSG("PrimitiveRestartCase::renderWithRestart() begin");
625*35238bceSAndroid Build Coastguard Worker
626*35238bceSAndroid Build Coastguard Worker glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
627*35238bceSAndroid Build Coastguard Worker GLU_CHECK_MSG("Enable primitive restart");
628*35238bceSAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
629*35238bceSAndroid Build Coastguard Worker GLU_CHECK_MSG("Clear in PrimitiveRestartCase::renderWithRestart()");
630*35238bceSAndroid Build Coastguard Worker
631*35238bceSAndroid Build Coastguard Worker draw(0, getNumIndices());
632*35238bceSAndroid Build Coastguard Worker
633*35238bceSAndroid Build Coastguard Worker GLU_CHECK_MSG("Draw in PrimitiveRestartCase::renderWithRestart()");
634*35238bceSAndroid Build Coastguard Worker
635*35238bceSAndroid Build Coastguard Worker GLU_CHECK_MSG("PrimitiveRestartCase::renderWithRestart() end");
636*35238bceSAndroid Build Coastguard Worker }
637*35238bceSAndroid Build Coastguard Worker
renderWithoutRestart(void)638*35238bceSAndroid Build Coastguard Worker void PrimitiveRestartCase::renderWithoutRestart(void)
639*35238bceSAndroid Build Coastguard Worker {
640*35238bceSAndroid Build Coastguard Worker GLU_CHECK_MSG("PrimitiveRestartCase::renderWithoutRestart() begin");
641*35238bceSAndroid Build Coastguard Worker
642*35238bceSAndroid Build Coastguard Worker uint32_t restartIndex = m_indexType == INDEX_UNSIGNED_BYTE ? RESTART_INDEX_UNSIGNED_BYTE :
643*35238bceSAndroid Build Coastguard Worker m_indexType == INDEX_UNSIGNED_SHORT ? RESTART_INDEX_UNSIGNED_SHORT :
644*35238bceSAndroid Build Coastguard Worker m_indexType == INDEX_UNSIGNED_INT ? RESTART_INDEX_UNSIGNED_INT :
645*35238bceSAndroid Build Coastguard Worker 0;
646*35238bceSAndroid Build Coastguard Worker
647*35238bceSAndroid Build Coastguard Worker DE_ASSERT(restartIndex != 0);
648*35238bceSAndroid Build Coastguard Worker
649*35238bceSAndroid Build Coastguard Worker glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
650*35238bceSAndroid Build Coastguard Worker GLU_CHECK_MSG("Disable primitive restart");
651*35238bceSAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
652*35238bceSAndroid Build Coastguard Worker GLU_CHECK_MSG("Clear in PrimitiveRestartCase::renderWithoutRestart()");
653*35238bceSAndroid Build Coastguard Worker
654*35238bceSAndroid Build Coastguard Worker // Draw, emulating primitive restart.
655*35238bceSAndroid Build Coastguard Worker
656*35238bceSAndroid Build Coastguard Worker int numIndices = getNumIndices();
657*35238bceSAndroid Build Coastguard Worker
658*35238bceSAndroid Build Coastguard Worker DE_ASSERT(numIndices >= 0);
659*35238bceSAndroid Build Coastguard Worker
660*35238bceSAndroid Build Coastguard Worker int indexArrayStartNdx =
661*35238bceSAndroid Build Coastguard Worker 0; // Keep track of the draw start index - first index after a primitive restart, or initially the first index altogether.
662*35238bceSAndroid Build Coastguard Worker
663*35238bceSAndroid Build Coastguard Worker for (int indexArrayNdx = 0; indexArrayNdx <= numIndices;
664*35238bceSAndroid Build Coastguard Worker indexArrayNdx++) // \note Goes one "too far" in order to detect end of array as well.
665*35238bceSAndroid Build Coastguard Worker {
666*35238bceSAndroid Build Coastguard Worker if (indexArrayNdx >= numIndices ||
667*35238bceSAndroid Build Coastguard Worker getIndex(indexArrayNdx) ==
668*35238bceSAndroid Build Coastguard Worker restartIndex) // \note Handle end of array the same way as a restart index encounter.
669*35238bceSAndroid Build Coastguard Worker {
670*35238bceSAndroid Build Coastguard Worker if (indexArrayStartNdx < numIndices)
671*35238bceSAndroid Build Coastguard Worker {
672*35238bceSAndroid Build Coastguard Worker // Draw from index indexArrayStartNdx to index indexArrayNdx-1 .
673*35238bceSAndroid Build Coastguard Worker
674*35238bceSAndroid Build Coastguard Worker draw(indexArrayStartNdx, indexArrayNdx - indexArrayStartNdx);
675*35238bceSAndroid Build Coastguard Worker GLU_CHECK_MSG("Draw in PrimitiveRestartCase::renderWithoutRestart()");
676*35238bceSAndroid Build Coastguard Worker }
677*35238bceSAndroid Build Coastguard Worker
678*35238bceSAndroid Build Coastguard Worker indexArrayStartNdx = indexArrayNdx + 1; // Next draw starts just after this restart index.
679*35238bceSAndroid Build Coastguard Worker }
680*35238bceSAndroid Build Coastguard Worker }
681*35238bceSAndroid Build Coastguard Worker
682*35238bceSAndroid Build Coastguard Worker GLU_CHECK_MSG("PrimitiveRestartCase::renderWithoutRestart() end");
683*35238bceSAndroid Build Coastguard Worker }
684*35238bceSAndroid Build Coastguard Worker
PrimitiveRestartTests(Context & context)685*35238bceSAndroid Build Coastguard Worker PrimitiveRestartTests::PrimitiveRestartTests(Context &context)
686*35238bceSAndroid Build Coastguard Worker : TestCaseGroup(context, "primitive_restart", "Primitive restart tests")
687*35238bceSAndroid Build Coastguard Worker {
688*35238bceSAndroid Build Coastguard Worker }
689*35238bceSAndroid Build Coastguard Worker
~PrimitiveRestartTests(void)690*35238bceSAndroid Build Coastguard Worker PrimitiveRestartTests::~PrimitiveRestartTests(void)
691*35238bceSAndroid Build Coastguard Worker {
692*35238bceSAndroid Build Coastguard Worker }
693*35238bceSAndroid Build Coastguard Worker
init(void)694*35238bceSAndroid Build Coastguard Worker void PrimitiveRestartTests::init(void)
695*35238bceSAndroid Build Coastguard Worker {
696*35238bceSAndroid Build Coastguard Worker for (int isRestartBeginCaseI = 0; isRestartBeginCaseI <= 1; isRestartBeginCaseI++)
697*35238bceSAndroid Build Coastguard Worker for (int isRestartEndCaseI = 0; isRestartEndCaseI <= 1; isRestartEndCaseI++)
698*35238bceSAndroid Build Coastguard Worker for (int isDuplicateRestartCaseI = 0; isDuplicateRestartCaseI <= 1; isDuplicateRestartCaseI++)
699*35238bceSAndroid Build Coastguard Worker {
700*35238bceSAndroid Build Coastguard Worker bool isRestartBeginCase = isRestartBeginCaseI != 0;
701*35238bceSAndroid Build Coastguard Worker bool isRestartEndCase = isRestartEndCaseI != 0;
702*35238bceSAndroid Build Coastguard Worker bool isDuplicateRestartCase = isDuplicateRestartCaseI != 0;
703*35238bceSAndroid Build Coastguard Worker
704*35238bceSAndroid Build Coastguard Worker std::string specialCaseGroupName;
705*35238bceSAndroid Build Coastguard Worker
706*35238bceSAndroid Build Coastguard Worker if (isRestartBeginCase)
707*35238bceSAndroid Build Coastguard Worker specialCaseGroupName = "begin_restart";
708*35238bceSAndroid Build Coastguard Worker if (isRestartEndCase)
709*35238bceSAndroid Build Coastguard Worker specialCaseGroupName += std::string(specialCaseGroupName.empty() ? "" : "_") + "end_restart";
710*35238bceSAndroid Build Coastguard Worker if (isDuplicateRestartCase)
711*35238bceSAndroid Build Coastguard Worker specialCaseGroupName += std::string(specialCaseGroupName.empty() ? "" : "_") + "duplicate_restarts";
712*35238bceSAndroid Build Coastguard Worker
713*35238bceSAndroid Build Coastguard Worker if (specialCaseGroupName.empty())
714*35238bceSAndroid Build Coastguard Worker specialCaseGroupName = "basic";
715*35238bceSAndroid Build Coastguard Worker
716*35238bceSAndroid Build Coastguard Worker TestCaseGroup *specialCaseGroup = new TestCaseGroup(m_context, specialCaseGroupName.c_str(), "");
717*35238bceSAndroid Build Coastguard Worker addChild(specialCaseGroup);
718*35238bceSAndroid Build Coastguard Worker
719*35238bceSAndroid Build Coastguard Worker for (int primType = 0; primType < (int)PrimitiveRestartCase::PRIMITIVE_LAST; primType++)
720*35238bceSAndroid Build Coastguard Worker {
721*35238bceSAndroid Build Coastguard Worker const char *primTypeName =
722*35238bceSAndroid Build Coastguard Worker primType == (int)PrimitiveRestartCase::PRIMITIVE_POINTS ? "points" :
723*35238bceSAndroid Build Coastguard Worker primType == (int)PrimitiveRestartCase::PRIMITIVE_LINE_STRIP ? "line_strip" :
724*35238bceSAndroid Build Coastguard Worker primType == (int)PrimitiveRestartCase::PRIMITIVE_LINE_LOOP ? "line_loop" :
725*35238bceSAndroid Build Coastguard Worker primType == (int)PrimitiveRestartCase::PRIMITIVE_LINES ? "lines" :
726*35238bceSAndroid Build Coastguard Worker primType == (int)PrimitiveRestartCase::PRIMITIVE_TRIANGLE_STRIP ? "triangle_strip" :
727*35238bceSAndroid Build Coastguard Worker primType == (int)PrimitiveRestartCase::PRIMITIVE_TRIANGLE_FAN ? "triangle_fan" :
728*35238bceSAndroid Build Coastguard Worker primType == (int)PrimitiveRestartCase::PRIMITIVE_TRIANGLES ? "triangles" :
729*35238bceSAndroid Build Coastguard Worker DE_NULL;
730*35238bceSAndroid Build Coastguard Worker
731*35238bceSAndroid Build Coastguard Worker DE_ASSERT(primTypeName != DE_NULL);
732*35238bceSAndroid Build Coastguard Worker
733*35238bceSAndroid Build Coastguard Worker TestCaseGroup *primTypeGroup = new TestCaseGroup(m_context, primTypeName, "");
734*35238bceSAndroid Build Coastguard Worker specialCaseGroup->addChild(primTypeGroup);
735*35238bceSAndroid Build Coastguard Worker
736*35238bceSAndroid Build Coastguard Worker for (int indexType = 0; indexType < (int)PrimitiveRestartCase::INDEX_LAST; indexType++)
737*35238bceSAndroid Build Coastguard Worker {
738*35238bceSAndroid Build Coastguard Worker const char *indexTypeName =
739*35238bceSAndroid Build Coastguard Worker indexType == (int)PrimitiveRestartCase::INDEX_UNSIGNED_BYTE ? "unsigned_byte" :
740*35238bceSAndroid Build Coastguard Worker indexType == (int)PrimitiveRestartCase::INDEX_UNSIGNED_SHORT ? "unsigned_short" :
741*35238bceSAndroid Build Coastguard Worker indexType == (int)PrimitiveRestartCase::INDEX_UNSIGNED_INT ? "unsigned_int" :
742*35238bceSAndroid Build Coastguard Worker DE_NULL;
743*35238bceSAndroid Build Coastguard Worker
744*35238bceSAndroid Build Coastguard Worker DE_ASSERT(indexTypeName != DE_NULL);
745*35238bceSAndroid Build Coastguard Worker
746*35238bceSAndroid Build Coastguard Worker TestCaseGroup *indexTypeGroup = new TestCaseGroup(m_context, indexTypeName, "");
747*35238bceSAndroid Build Coastguard Worker primTypeGroup->addChild(indexTypeGroup);
748*35238bceSAndroid Build Coastguard Worker
749*35238bceSAndroid Build Coastguard Worker for (int function = 0; function < (int)PrimitiveRestartCase::FUNCTION_LAST; function++)
750*35238bceSAndroid Build Coastguard Worker {
751*35238bceSAndroid Build Coastguard Worker const char *functionName =
752*35238bceSAndroid Build Coastguard Worker function == (int)PrimitiveRestartCase::FUNCTION_DRAW_ELEMENTS ?
753*35238bceSAndroid Build Coastguard Worker "draw_elements" :
754*35238bceSAndroid Build Coastguard Worker function == (int)PrimitiveRestartCase::FUNCTION_DRAW_ELEMENTS_INSTANCED ?
755*35238bceSAndroid Build Coastguard Worker "draw_elements_instanced" :
756*35238bceSAndroid Build Coastguard Worker function == (int)PrimitiveRestartCase::FUNCTION_DRAW_RANGE_ELEMENTS ?
757*35238bceSAndroid Build Coastguard Worker "draw_range_elements" :
758*35238bceSAndroid Build Coastguard Worker DE_NULL;
759*35238bceSAndroid Build Coastguard Worker
760*35238bceSAndroid Build Coastguard Worker DE_ASSERT(functionName != DE_NULL);
761*35238bceSAndroid Build Coastguard Worker
762*35238bceSAndroid Build Coastguard Worker indexTypeGroup->addChild(new PrimitiveRestartCase(
763*35238bceSAndroid Build Coastguard Worker m_context, functionName, "", (PrimitiveRestartCase::PrimitiveType)primType,
764*35238bceSAndroid Build Coastguard Worker (PrimitiveRestartCase::IndexType)indexType, (PrimitiveRestartCase::Function)function,
765*35238bceSAndroid Build Coastguard Worker isRestartBeginCase, isRestartEndCase, isDuplicateRestartCase));
766*35238bceSAndroid Build Coastguard Worker }
767*35238bceSAndroid Build Coastguard Worker }
768*35238bceSAndroid Build Coastguard Worker }
769*35238bceSAndroid Build Coastguard Worker }
770*35238bceSAndroid Build Coastguard Worker }
771*35238bceSAndroid Build Coastguard Worker
772*35238bceSAndroid Build Coastguard Worker } // namespace Functional
773*35238bceSAndroid Build Coastguard Worker } // namespace gles3
774*35238bceSAndroid Build Coastguard Worker } // namespace deqp
775