xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fPrimitiveRestartTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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