xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gles31/es31cDrawIndirectTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 #include "es31cDrawIndirectTests.hpp"
25 #include "gluContextInfo.hpp"
26 #include "glwEnums.hpp"
27 #include "tcuMatrix.hpp"
28 #include "tcuRenderTarget.hpp"
29 #include "tcuVectorUtil.hpp"
30 
31 #include <map>
32 
33 namespace glcts
34 {
35 using namespace glw;
36 namespace
37 {
38 
39 class DILogger
40 {
41 public:
DILogger()42     DILogger() : null_log_(0)
43     {
44     }
45 
DILogger(const DILogger & rhs)46     DILogger(const DILogger &rhs)
47     {
48         null_log_ = rhs.null_log_;
49         if (!null_log_)
50         {
51             str_ << rhs.str_.str();
52         }
53     }
54 
~DILogger()55     ~DILogger()
56     {
57         s_tcuLog->writeMessage(str_.str().c_str());
58         if (!str_.str().empty())
59         {
60             s_tcuLog->writeMessage(NL);
61         }
62     }
63 
64     template <class T>
operator <<(const T & t)65     DILogger &operator<<(const T &t)
66     {
67         if (!null_log_)
68         {
69             str_ << t;
70         }
71         return *this;
72     }
73 
nullify()74     DILogger &nullify()
75     {
76         null_log_ = true;
77         return *this;
78     }
79 
setOutput(tcu::TestLog & log)80     static void setOutput(tcu::TestLog &log)
81     {
82         s_tcuLog = &log;
83     }
84 
85 private:
86     void operator=(const DILogger &);
87     bool null_log_;
88     std::ostringstream str_;
89     static tcu::TestLog *s_tcuLog;
90 };
91 tcu::TestLog *DILogger::s_tcuLog = NULL;
92 
93 class DIResult
94 {
95 public:
DIResult()96     DIResult() : status_(NO_ERROR)
97     {
98     }
99 
error()100     DILogger error()
101     {
102         return sub_result(ERROR);
103     }
code() const104     long code() const
105     {
106         return status_;
107     }
sub_result(long _code)108     DILogger sub_result(long _code)
109     {
110         if (_code == NO_ERROR)
111         {
112             return sub_result_inner(_code).nullify();
113         }
114         else
115         {
116             return sub_result_inner(_code);
117         }
118     }
119 
120 private:
sub_result_inner(long _code)121     DILogger sub_result_inner(long _code)
122     {
123         status_ |= _code;
124         return DILogger();
125     }
126     DILogger logger_;
127     long status_;
128 };
129 
130 namespace test_api
131 {
132 struct ES3
133 {
isESglcts::__anon253d27190111::test_api::ES3134     static bool isES()
135     {
136         return true;
137     }
glslVerglcts::__anon253d27190111::test_api::ES3138     static std::string glslVer(bool = false)
139     {
140         return "#version 310 es";
141     }
ES_Onlyglcts::__anon253d27190111::test_api::ES3142     static void ES_Only()
143     {
144     }
145 };
146 
147 struct GL
148 {
isESglcts::__anon253d27190111::test_api::GL149     static bool isES()
150     {
151         return false;
152     }
glslVerglcts::__anon253d27190111::test_api::GL153     static std::string glslVer(bool compute = false)
154     {
155         if (compute)
156         {
157             return "#version 430";
158         }
159         else
160         {
161             return "#version 400";
162         }
163     }
GL_Onlyglcts::__anon253d27190111::test_api::GL164     static void GL_Only()
165     {
166     }
167 };
168 } // namespace test_api
169 
170 namespace shaders
171 {
172 
173 template <typename api>
vshSimple()174 std::string vshSimple()
175 {
176     return api::glslVer() + NL "in vec4 i_vertex;" NL "void main()" NL "{" NL "    gl_Position = i_vertex;" NL "}";
177 }
178 template <typename api>
vshSimple_point()179 std::string vshSimple_point()
180 {
181     return api::glslVer() + NL "in vec4 i_vertex;" NL "void main()" NL "{" NL "    gl_Position = i_vertex;" NL
182                                "#if defined(GL_ES)" NL "    gl_PointSize = 1.0;" NL "#endif" NL "}";
183 }
184 
185 template <typename api>
fshSimple()186 std::string fshSimple()
187 {
188     return api::glslVer() + NL "precision highp float; " NL "out vec4 outColor;" NL "void main() {" NL
189                                "  outColor = vec4(0.1,0.2,0.3,1.0);" NL "}";
190 }
191 } // namespace shaders
192 
193 class DrawIndirectBase : public glcts::SubcaseBase
194 {
195 protected:
196     typedef std::vector<unsigned int> CDataArray;
197     typedef std::vector<tcu::Vec3> CVertexArray;
198     typedef std::vector<tcu::Vec4> CColorArray;
199     typedef std::vector<GLuint> CElementArray;
200 
201     enum TDrawFunction
202     {
203         DRAW_ARRAYS,
204         DRAW_ELEMENTS,
205     };
206 
207     typedef struct
208     {
209         GLuint count;
210         GLuint primCount;
211         GLuint first;
212         GLuint reservedMustBeZero;
213     } DrawArraysIndirectCommand;
214 
215     typedef struct
216     {
217         GLuint count;
218         GLuint primCount;
219         GLuint firstIndex;
220         GLint baseVertex;
221         GLuint reservedMustBeZero;
222     } DrawElementsIndirectCommand;
223 
getWindowWidth()224     int getWindowWidth()
225     {
226         return m_context.getRenderContext().getRenderTarget().getWidth();
227     }
228 
getWindowHeight()229     int getWindowHeight()
230     {
231         return m_context.getRenderContext().getRenderTarget().getHeight();
232     }
233 
getDataSize(int & width,int & height)234     void getDataSize(int &width, int &height)
235     {
236         width  = std::min(getWindowWidth(), 16384);              // Cap width to 16384
237         height = std::min(getWindowHeight(), 4 * 16384 / width); // Height is 4 if width is capped
238     }
239 
CreateComputeProgram(const std::string & cs,bool linkAndCheck)240     GLuint CreateComputeProgram(const std::string &cs, bool linkAndCheck)
241     {
242         const GLuint p = glCreateProgram();
243 
244         const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
245         glAttachShader(p, sh);
246         glDeleteShader(sh);
247         const char *const src[1] = {cs.c_str()};
248         glShaderSource(sh, 1, src, NULL);
249         glCompileShader(sh);
250 
251         if (linkAndCheck)
252         {
253             glLinkProgram(p);
254             if (!CheckProgram(p))
255             {
256                 return 0;
257             }
258         }
259 
260         return p;
261     }
262 
CreateProgram(const std::string & vs,const std::string & gs,const std::string & fs,bool linkAndCheck)263     GLuint CreateProgram(const std::string &vs, const std::string &gs, const std::string &fs, bool linkAndCheck)
264     {
265         const GLuint p = glCreateProgram();
266 
267         if (!vs.empty())
268         {
269             const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
270             glAttachShader(p, sh);
271             glDeleteShader(sh);
272             const char *const src[1] = {vs.c_str()};
273             glShaderSource(sh, 1, src, NULL);
274             glCompileShader(sh);
275         }
276         if (!gs.empty())
277         {
278             const GLuint sh = glCreateShader(GL_GEOMETRY_SHADER);
279             glAttachShader(p, sh);
280             glDeleteShader(sh);
281             const char *const src[1] = {gs.c_str()};
282             glShaderSource(sh, 1, src, NULL);
283             glCompileShader(sh);
284         }
285         if (!fs.empty())
286         {
287             const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
288             glAttachShader(p, sh);
289             glDeleteShader(sh);
290             const char *const src[1] = {fs.c_str()};
291             glShaderSource(sh, 1, src, NULL);
292             glCompileShader(sh);
293         }
294 
295         if (linkAndCheck)
296         {
297             glLinkProgram(p);
298             if (!CheckProgram(p))
299             {
300                 return 0;
301             }
302         }
303 
304         return p;
305     }
306 
CheckProgram(GLuint program)307     long CheckProgram(GLuint program)
308     {
309         DIResult status;
310         GLint progStatus;
311         glGetProgramiv(program, GL_LINK_STATUS, &progStatus);
312 
313         if (progStatus == GL_FALSE)
314         {
315 
316             status.error() << "GL_LINK_STATUS is false";
317 
318             GLint attached_shaders;
319             glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
320 
321             if (attached_shaders > 0)
322             {
323                 std::vector<GLuint> shaders(attached_shaders);
324                 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
325 
326                 for (GLint i = 0; i < attached_shaders; ++i)
327                 {
328                     // shader type
329                     GLenum type;
330                     glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint *>(&type));
331                     switch (type)
332                     {
333                     case GL_VERTEX_SHADER:
334                         status.error() << "*** Vertex Shader ***\n";
335                         break;
336                     case GL_FRAGMENT_SHADER:
337                         status.error() << "*** Fragment Shader ***\n";
338                         break;
339                     case GL_COMPUTE_SHADER:
340                         status.error() << "*** Compute Shader ***\n";
341                         break;
342                     default:
343                         status.error() << "*** Unknown Shader ***\n";
344                         break;
345                     }
346 
347                     // shader source
348                     GLint length;
349                     glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
350                     if (length > 0)
351                     {
352                         std::vector<GLchar> source(length);
353                         glGetShaderSource(shaders[i], length, NULL, &source[0]);
354                         status.error() << source[0];
355                     }
356 
357                     // shader info log
358                     glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
359                     if (length > 0)
360                     {
361                         std::vector<GLchar> log(length);
362                         glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
363                         status.error() << &log[0];
364                     }
365                 }
366             }
367 
368             // program info log
369             GLint length;
370             glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
371             if (length > 0)
372             {
373                 std::vector<GLchar> log(length);
374                 glGetProgramInfoLog(program, length, NULL, &log[0]);
375                 status.error() << &log[0];
376             }
377         }
378 
379         return status.code() == NO_ERROR;
380     }
381 
382     template <typename api>
383     void ReadPixelsFloat(int x, int y, int width, int height, void *data);
384 
385     template <typename api>
386     void GetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
387 
388     template <typename T>
DataGen(std::vector<T> & data,unsigned int sizeX,unsigned int sizeY,T valueMin,T valueMax)389     void DataGen(std::vector<T> &data, unsigned int sizeX, unsigned int sizeY, T valueMin, T valueMax)
390     {
391         data.resize(sizeX * sizeY, 0);
392         T range = valueMax - valueMin;
393         T stepX = range / sizeX;
394         T stepY = range / sizeY;
395 
396         for (unsigned int i = 0; i < sizeY; ++i)
397         {
398             T valueY = i * stepY;
399 
400             for (unsigned int j = 0; j < sizeX; ++j)
401             {
402                 data[j + i * sizeX] = valueMin + j * stepX + valueY;
403             }
404         }
405     }
406 
407     template <typename T>
DataCompare(const std::vector<T> & dataRef,unsigned int widthRef,unsigned int heightRef,const std::vector<T> & dataTest,unsigned int widthTest,unsigned int heightTest,unsigned offsetYRef=0,unsigned offsetYTest=0)408     long DataCompare(const std::vector<T> &dataRef, unsigned int widthRef, unsigned int heightRef,
409                      const std::vector<T> &dataTest, unsigned int widthTest, unsigned int heightTest,
410                      unsigned offsetYRef = 0, unsigned offsetYTest = 0)
411     {
412         if (widthRef * heightRef > dataRef.size())
413             throw std::runtime_error("Invalid reference buffer resolution!");
414 
415         if (widthTest * heightTest > dataTest.size())
416             throw std::runtime_error("Invalid test buffer resolution!");
417 
418         unsigned int width  = std::min(widthRef, widthTest);
419         unsigned int height = std::min(heightRef, heightTest);
420 
421         for (unsigned int i = 0; i < height; ++i)
422         {
423             unsigned int offsetRef  = (i + offsetYRef) * widthRef;
424             unsigned int offsetTest = (i + offsetYTest) * widthTest;
425 
426             for (size_t j = 0; j < width; ++j)
427             {
428                 if (dataRef[offsetRef + j] != dataTest[offsetTest + j])
429                 {
430                     DIResult status;
431                     status.error() << "Compare failed: different values [x: " << j << ", y: " << i + offsetYTest
432                                    << ", reference: " << dataRef[offsetRef + j]
433                                    << ", test: " << dataTest[offsetTest + j] << "]";
434                     return status.code();
435                 }
436             }
437         }
438 
439         return NO_ERROR;
440     }
441 
442     template <typename api>
BindingPointCheck(GLuint expectedValue)443     long BindingPointCheck(GLuint expectedValue)
444     {
445         DIResult status;
446 
447         GLint valueInt = -9999;
448         glGetIntegerv(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueInt);
449         if (valueInt != static_cast<GLint>(expectedValue))
450         {
451             status.error() << "glGetIntegerv(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: " << valueInt
452                            << ", expected: " << expectedValue;
453         }
454 
455         GLboolean valueBool = expectedValue ? GL_FALSE : GL_TRUE;
456         glGetBooleanv(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueBool);
457         if (valueBool != (expectedValue ? GL_TRUE : GL_FALSE))
458         {
459             status.error() << "glGetBooleanv(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: "
460                            << BoolToString(valueBool)
461                            << ", expected: " << BoolToString(expectedValue ? GL_TRUE : GL_FALSE);
462         }
463 
464         GLfloat valueFloat         = -9999;
465         GLfloat expectedFloatValue = static_cast<GLfloat>(expectedValue);
466         glGetFloatv(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueFloat);
467         if (valueFloat != expectedFloatValue)
468         {
469             status.error() << "glGetFloatv(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: " << valueFloat
470                            << ", expected: " << expectedValue;
471         }
472 
473         if (!api::isES())
474         {
475             GLdouble valueDouble = -9999;
476             glGetDoublev(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueDouble);
477             if (valueDouble != static_cast<GLdouble>(expectedValue))
478             {
479                 status.error() << "glGetDoublev(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: "
480                                << valueDouble << ", expected: " << expectedValue;
481             }
482         }
483 
484         return status.code();
485     }
486 
487     template <typename T>
BuffersCompare(const std::vector<T> & bufferTest,unsigned int widthTest,unsigned int heightTest,const std::vector<T> & bufferRef,unsigned int widthRef,unsigned int heightRef)488     long BuffersCompare(const std::vector<T> &bufferTest, unsigned int widthTest, unsigned int heightTest,
489                         const std::vector<T> &bufferRef, unsigned int widthRef, unsigned int heightRef)
490     {
491 
492         const tcu::PixelFormat &pixelFormat = m_context.getRenderContext().getRenderTarget().getPixelFormat();
493         tcu::Vec4 epsilon                   = tcu::Vec4(
494             1.f / static_cast<float>(1 << pixelFormat.redBits), 1.f / static_cast<float>(1 << pixelFormat.greenBits),
495             1.f / static_cast<float>(1 << pixelFormat.blueBits), 1.f / static_cast<float>(1 << pixelFormat.alphaBits));
496 
497         double stepX = widthRef / static_cast<double>(widthTest);
498         double stepY = heightRef / static_cast<double>(heightTest);
499         for (unsigned int i = 0; i < heightTest; ++i)
500         {
501             unsigned int offsetTest = i * widthTest;
502             unsigned int offsetRef  = static_cast<int>(i * stepY + 0.5) * widthRef;
503             for (unsigned int j = 0; j < widthTest; ++j)
504             {
505                 unsigned int posXRef = static_cast<int>(j * stepX + 0.5);
506                 if (!ColorVerify(bufferTest[j + offsetTest], bufferRef[posXRef + offsetRef], epsilon))
507                 {
508                     DIResult status;
509                     status.error() << "(x,y)= (" << j << "," << i << "). Color RGBA(" << bufferTest[j + offsetTest][0]
510                                    << "," << bufferTest[j + offsetTest][1] << "," << bufferTest[j + offsetTest][2]
511                                    << "," << bufferTest[j + offsetTest][3] << ") is different than expected RGBA("
512                                    << bufferRef[posXRef + offsetRef][0] << "," << bufferRef[posXRef + offsetRef][1]
513                                    << "," << bufferRef[posXRef + offsetRef][2] << ","
514                                    << bufferRef[posXRef + offsetRef][3] << ")";
515                     return status.code();
516                 }
517             }
518         }
519         return NO_ERROR;
520     }
521 
522     template <typename T>
ColorVerify(T color,T colorExpected,tcu::Vec4 epsilon)523     bool ColorVerify(T color, T colorExpected, tcu::Vec4 epsilon)
524     {
525         for (int i = 0; i < 3; ++i)
526         {
527             if (fabsf(colorExpected[i] - color[i]) > epsilon[i])
528                 return false;
529         }
530         return true;
531     }
532 
BufferCheck(const CDataArray & dataRef,unsigned int widthRef,unsigned int heightRef,const void * bufTest,unsigned int widthTest,unsigned int heightTest,unsigned int offsetYRef=0,unsigned int offsetYTest=0)533     long BufferCheck(const CDataArray &dataRef, unsigned int widthRef, unsigned int heightRef, const void *bufTest,
534                      unsigned int widthTest, unsigned int heightTest, unsigned int offsetYRef = 0,
535                      unsigned int offsetYTest = 0)
536     {
537         if (bufTest == 0)
538         {
539             throw std::runtime_error("Invalid test buffer!");
540         }
541 
542         CDataArray dataTest(widthTest * heightTest, 0);
543         memcpy(&dataTest[0], bufTest, widthTest * heightTest * sizeof(unsigned int));
544 
545         return DataCompare(dataRef, widthRef, heightRef, dataTest, widthTest, heightTest, offsetYRef, offsetYTest);
546     }
547 
548     template <typename api>
StateValidate(GLboolean mapped,GLbitfield access,GLbitfield accessFlag,GLintptr offset,GLsizeiptr length)549     long StateValidate(GLboolean mapped, GLbitfield access, GLbitfield accessFlag, GLintptr offset, GLsizeiptr length)
550     {
551         DIResult result;
552 
553         if (!api::isES())
554         {
555             int v;
556             glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_ACCESS, &v);
557             if (v != static_cast<int>(access))
558             {
559                 result.error() << "glGetBufferParameteriv(GL_BUFFER_ACCESS) returned incorrect state: "
560                                << AccessToString(v) << ", expected: " << AccessToString(access);
561             }
562         }
563 
564         int v;
565         glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_ACCESS_FLAGS, &v);
566         if (v != static_cast<int>(accessFlag))
567         {
568             result.error() << "glGetBufferParameteriv(GL_BUFFER_ACCESS_FLAGS) returned incorrect state: " << v
569                            << ", expected: " << accessFlag;
570         }
571 
572         glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAPPED, &v);
573         if (v != mapped)
574         {
575             result.error() << "glGetBufferParameteriv(GL_BUFFER_MAPPED) returned incorrect state: "
576                            << BoolToString((GLboolean)v) << ", expected: " << BoolToString((GLboolean)access);
577         }
578 
579         glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_OFFSET, &v);
580         if (v != offset)
581         {
582             result.error() << "glGetBufferParameteriv(GL_BUFFER_MAP_OFFSET) returned incorrect offset: " << v
583                            << ", expected: " << offset;
584         }
585 
586         glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_LENGTH, &v);
587         if (v != length)
588         {
589             result.error() << "glGetBufferParameteriv(GL_BUFFER_MAP_LENGTH) returned incorrect length: " << v
590                            << ", expected: " << length;
591         }
592 
593         return result.code();
594     }
595 
PointsGen(unsigned int drawSizeX,unsigned int drawSizeY,CColorArray & output)596     void PointsGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray &output)
597     {
598         output.reserve(drawSizeY * 2);
599         float rasterSizeX = 2.0f / static_cast<float>(getWindowWidth());
600         float rasterSizeY = 2.0f / static_cast<float>(getWindowHeight());
601         for (unsigned int i = 0; i < drawSizeY; ++i)
602         {
603             float offsetY = -1.0f + rasterSizeY * static_cast<float>(i) + rasterSizeY / 2;
604             for (unsigned int j = 0; j < drawSizeX; ++j)
605             {
606                 float offsetX = -1.0f + rasterSizeX * static_cast<float>(j) + rasterSizeX / 2;
607                 output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
608             }
609         }
610     }
611 
LinesOffsetY(unsigned int i,float rasterSize)612     float LinesOffsetY(unsigned int i, float rasterSize)
613     {
614         // Offset lines slightly from the center of pixels so as not to hit rasterizer
615         // tie-break conditions (the right-edge of the screen at half-integer pixel
616         // heights is the right corner of a diamond). rasterSize/16 is the smallest
617         // offset that the spec guarantees the rasterizer can resolve.
618         return -1.0f + rasterSize * static_cast<float>(i) + rasterSize / 2 + rasterSize / 16;
619     }
620 
LinesGen(unsigned int,unsigned int drawSizeY,CColorArray & output)621     void LinesGen(unsigned int, unsigned int drawSizeY, CColorArray &output)
622     {
623         output.reserve(drawSizeY * 2);
624         float rasterSize = 2.0f / static_cast<float>(getWindowHeight());
625         for (unsigned int i = 0; i < drawSizeY; ++i)
626         {
627             float offsetY = LinesOffsetY(i, rasterSize);
628             output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f));
629             output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f));
630         }
631     }
632 
LinesAdjacencyGen(unsigned int,unsigned int drawSizeY,CColorArray & output)633     void LinesAdjacencyGen(unsigned int, unsigned int drawSizeY, CColorArray &output)
634     {
635         float rasterSize = 2.0f / static_cast<float>(getWindowHeight());
636         for (unsigned int i = 0; i < drawSizeY; ++i)
637         {
638             float offsetY = LinesOffsetY(i, rasterSize);
639             output.push_back(tcu::Vec4(-1.5f, -1.0f + offsetY, 0.0f, 1.0f)); //adj
640             output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f));
641             output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f));
642             output.push_back(tcu::Vec4(1.5f, -1.0f + offsetY, 0.0f, 1.0f)); //adj
643         }
644     }
645 
LineStripAdjacencyGen(unsigned int,unsigned int drawSizeY,CColorArray & output)646     void LineStripAdjacencyGen(unsigned int, unsigned int drawSizeY, CColorArray &output)
647     {
648         float rasterSize = 2.0f / static_cast<float>(getWindowHeight());
649         output.push_back(tcu::Vec4(-1.5f, rasterSize / 2, 0.0f, 1.0f));
650         for (unsigned int i = 0; i < drawSizeY; ++i)
651         {
652             float offsetY = LinesOffsetY(i, rasterSize);
653             output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f));
654             output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f));
655             output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f));
656             output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f));
657         }
658         output.push_back(tcu::Vec4(1.5f, 1.0f - rasterSize / 2, 0.0f, 1.0f));
659     }
660 
TrianglesGen(unsigned int drawSizeX,unsigned int drawSizeY,CColorArray & output)661     void TrianglesGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray &output)
662     {
663         output.reserve(drawSizeX * 2 * 6);
664 
665         switch (drawSizeX)
666         {
667         case 1:
668         {
669             output.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
670             output.push_back(tcu::Vec4(4.0f, -1.0f, 0.0f, 1.0f));
671             output.push_back(tcu::Vec4(-1.0f, 4.0f, 0.0f, 1.0f));
672         }
673         break;
674         case 0:
675         {
676             throw std::runtime_error("Invalid drawSizeX!");
677         }
678         default:
679         {
680             float drawStepX = 2.0f / static_cast<float>(drawSizeX);
681             float drawStepY = 2.0f / static_cast<float>(drawSizeY);
682 
683             for (unsigned int i = 0; i < drawSizeY; ++i)
684             {
685                 float offsetY = -1.0f + drawStepY * static_cast<float>(i);
686                 for (unsigned int j = 0; j < drawSizeX; ++j)
687                 {
688                     float offsetX = -1.0f + drawStepX * static_cast<float>(j);
689 
690                     output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
691                     output.push_back(tcu::Vec4(offsetX + drawStepX, offsetY, 0.0f, 1.0f));
692                     output.push_back(tcu::Vec4(offsetX, offsetY + drawStepY, 0.0f, 1.0f));
693 
694                     output.push_back(tcu::Vec4(offsetX + drawStepX, offsetY, 0.0f, 1.0f));
695                     output.push_back(tcu::Vec4(offsetX + drawStepX, offsetY + drawStepY, 0.0f, 1.0f));
696                     output.push_back(tcu::Vec4(offsetX, offsetY + drawStepY, 0.0f, 1.0f));
697                 }
698             }
699         }
700         break;
701         }
702     }
703 
TrianglesAdjacencyGen(unsigned int drawSizeX,unsigned int drawSizeY,CColorArray & output)704     void TrianglesAdjacencyGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray &output)
705     {
706         // Add a small amount (quarter pixel) of jitter to add to the rectangle sides to avoid
707         // triangle edges landing precisely on fragment centers.
708         float jigX = 0.5f / getWindowWidth();
709         float jigY = 0.5f / getWindowHeight();
710 
711         float sizeX = 1.0f / static_cast<float>(drawSizeX);
712         float sizeY = 1.0f / static_cast<float>(drawSizeY);
713 
714         for (unsigned int i = 0; i < drawSizeX; ++i)
715         {
716             float offsetY = -0.5f + jigY + sizeY * static_cast<float>(i);
717             for (unsigned int j = 0; j < drawSizeY; ++j)
718             {
719                 float offsetX = -0.5f + jigX + sizeX * static_cast<float>(j);
720 
721                 output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
722                 output.push_back(tcu::Vec4(offsetX - sizeX, offsetY + sizeY, 0.0f, 1.0f));
723                 output.push_back(tcu::Vec4(offsetX, offsetY + sizeY, 0.0f, 1.0f));
724                 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY + sizeY, 0.0f, 1.0f));
725                 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY, 0.0f, 1.0f));
726                 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY - sizeY, 0.0f, 1.0f));
727 
728                 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY + sizeY, 0.0f, 1.0f));
729                 output.push_back(tcu::Vec4(offsetX + 2 * sizeX, offsetY, 0.0f, 1.0f));
730                 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY, 0.0f, 1.0f));
731                 output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
732                 output.push_back(tcu::Vec4(offsetX, offsetY + sizeY, 0.0f, 1.0f));
733                 output.push_back(tcu::Vec4(offsetX, offsetY + 2 * sizeY, 0.0f, 1.0f));
734             }
735         }
736     }
737 
TriangleStripAdjacencyGen(unsigned int drawSizeX,unsigned int drawSizeY,CColorArray & output)738     void TriangleStripAdjacencyGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray &output)
739     {
740         // Add a small amount (quarter pixel) of jitter to add to the rectangle sides to avoid
741         // triangle edges landing precisely on fragment centers.
742         float jigX = 0.5f / getWindowWidth();
743         float jigY = 0.5f / getWindowHeight();
744 
745         float sizeX = 1.0f / static_cast<float>(drawSizeX);
746         float sizeY = 1.0f / static_cast<float>(drawSizeY);
747 
748         for (unsigned int i = 0; i < drawSizeX; ++i)
749         {
750             float offsetY = -0.5f + jigY + sizeY * static_cast<float>(i);
751             for (unsigned int j = 0; j < drawSizeY; ++j)
752             {
753                 float offsetX = -0.5f + jigX + sizeX * static_cast<float>(j);
754 
755                 output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
756                 output.push_back(tcu::Vec4(offsetX - sizeX, offsetY + sizeY, 0.0f, 1.0f));
757                 output.push_back(tcu::Vec4(offsetX, offsetY + sizeY, 0.0f, 1.0f));
758                 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY - sizeY, 0.0f, 1.0f));
759                 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY, 0.0f, 1.0f));
760                 output.push_back(tcu::Vec4(offsetX, offsetY + 2 * sizeY, 0.0f, 1.0f));
761                 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY + sizeY, 0.0f, 1.0f));
762                 output.push_back(tcu::Vec4(offsetX + 2 * sizeX, offsetY - sizeY, 0.0f, 1.0f));
763             }
764         }
765     }
766 
PrimitiveGen(GLenum primitiveType,unsigned int drawSizeX,unsigned int drawSizeY,CColorArray & output)767     void PrimitiveGen(GLenum primitiveType, unsigned int drawSizeX, unsigned int drawSizeY, CColorArray &output)
768     {
769         switch (primitiveType)
770         {
771         case GL_POINTS:
772             PointsGen(drawSizeX, drawSizeY, output);
773             break;
774         case GL_LINES:
775         case GL_LINE_STRIP:
776         case GL_LINE_LOOP:
777             LinesGen(drawSizeX, drawSizeY, output);
778             break;
779         case GL_LINES_ADJACENCY:
780             LinesAdjacencyGen(drawSizeX, drawSizeY, output);
781             break;
782         case GL_LINE_STRIP_ADJACENCY:
783             LineStripAdjacencyGen(drawSizeX, drawSizeY, output);
784             break;
785         case GL_TRIANGLES:
786         case GL_TRIANGLE_STRIP:
787         case GL_TRIANGLE_FAN:
788             TrianglesGen(drawSizeX, drawSizeY, output);
789             break;
790         case GL_TRIANGLES_ADJACENCY:
791             TrianglesAdjacencyGen(drawSizeX, drawSizeY, output);
792             break;
793         case GL_TRIANGLE_STRIP_ADJACENCY:
794             TriangleStripAdjacencyGen(drawSizeX, drawSizeY, output);
795             break;
796         default:
797             throw std::runtime_error("Unknown primitive type!");
798         }
799     }
800 
BoolToString(GLboolean value)801     std::string BoolToString(GLboolean value)
802     {
803         if (value == GL_TRUE)
804             return "GL_TRUE";
805 
806         return "GL_FALSE";
807     }
808 
AccessToString(GLbitfield access)809     std::string AccessToString(GLbitfield access)
810     {
811         switch (access)
812         {
813         case GL_READ_WRITE:
814             return "GL_READ_WRITE";
815         case GL_READ_ONLY:
816             return "GL_READ_ONLY";
817         case GL_WRITE_ONLY:
818             return "GL_WRITE_ONLY";
819         default:
820             throw std::runtime_error("Invalid access type!");
821         }
822     }
823 };
824 
825 template <>
ReadPixelsFloat(int x,int y,int width,int height,void * data)826 void DrawIndirectBase::ReadPixelsFloat<test_api::GL>(int x, int y, int width, int height, void *data)
827 {
828     glReadPixels(x, y, width, height, GL_RGBA, GL_FLOAT, data);
829 }
830 
831 template <>
ReadPixelsFloat(int x,int y,int width,int height,void * data)832 void DrawIndirectBase::ReadPixelsFloat<test_api::ES3>(int x, int y, int width, int height, void *data)
833 {
834     // Use 1010102/101010 pixel buffer for RGB10_A2/RGB10 FBO to preserve precision during pixel transfer
835     std::vector<GLuint> uData(width * height);
836     const tcu::PixelFormat &pixelFormat = m_context.getRenderContext().getRenderTarget().getPixelFormat();
837     GLfloat *fData                      = reinterpret_cast<GLfloat *>(data);
838     GLenum type = ((pixelFormat.redBits == 10) && (pixelFormat.greenBits == 10) && (pixelFormat.blueBits == 10) &&
839                    (pixelFormat.alphaBits == 2 || pixelFormat.alphaBits == 0)) ?
840                       GL_UNSIGNED_INT_2_10_10_10_REV :
841                       GL_UNSIGNED_BYTE;
842 
843     glReadPixels(x, y, width, height, GL_RGBA, type, &uData[0]);
844 
845     if (type == GL_UNSIGNED_BYTE)
846     {
847         for (size_t i = 0; i < uData.size(); i++)
848         {
849             GLubyte *uCompData = reinterpret_cast<GLubyte *>(&uData[i]);
850 
851             for (size_t c = 0; c < 4; c++)
852             {
853                 fData[i * 4 + c] = float(uCompData[c]) / 255.0f;
854             }
855         }
856     }
857     else
858     {
859         for (size_t i = 0; i < uData.size(); i++)
860         {
861             fData[i * 4]     = float(uData[i] & 0x3FF) / 1023.0f;
862             fData[i * 4 + 1] = float((uData[i] >> 10) & 0x3FF) / 1023.0f;
863             fData[i * 4 + 2] = float((uData[i] >> 20) & 0x3FF) / 1023.0f;
864             fData[i * 4 + 3] = float((uData[i] >> 30) & 0x3) / 3.0f;
865         }
866     }
867 }
868 
869 template <>
GetBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,GLvoid * data)870 void DrawIndirectBase::GetBufferSubData<test_api::GL>(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data)
871 {
872     glGetBufferSubData(target, offset, size, data);
873 }
874 
875 template <>
GetBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,GLvoid * data)876 void DrawIndirectBase::GetBufferSubData<test_api::ES3>(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data)
877 {
878     void *ptr = glMapBufferRange(target, offset, size, GL_MAP_READ_BIT);
879     memcpy(data, ptr, size);
880     glUnmapBuffer(target);
881 }
882 
883 template <typename api>
884 struct CDefaultBindingPoint : public DrawIndirectBase
885 {
Titleglcts::__anon253d27190111::CDefaultBindingPoint886     virtual std::string Title()
887     {
888         return "Draw Indirect: Check default binding point";
889     }
890 
Purposeglcts::__anon253d27190111::CDefaultBindingPoint891     virtual std::string Purpose()
892     {
893         return "Verify that default binding point is set to zero";
894     }
895 
Methodglcts::__anon253d27190111::CDefaultBindingPoint896     virtual std::string Method()
897     {
898         return "Use glGetIntegerv, glGetBooleanv, glGetFloatv, glGetDoublev to get default binding point";
899     }
900 
PassCriteriaglcts::__anon253d27190111::CDefaultBindingPoint901     virtual std::string PassCriteria()
902     {
903         return "The test will pass if default binding point is zero";
904     }
905 
Runglcts::__anon253d27190111::CDefaultBindingPoint906     virtual long Run()
907     {
908         return BindingPointCheck<api>(0);
909     }
910 };
911 
912 template <typename api>
913 struct CZeroBindingPoint : public DrawIndirectBase
914 {
Titleglcts::__anon253d27190111::CZeroBindingPoint915     virtual std::string Title()
916     {
917         return "Draw Indirect: Zero binding point";
918     }
919 
Purposeglcts::__anon253d27190111::CZeroBindingPoint920     virtual std::string Purpose()
921     {
922         return "Verify that binding point is set to zero";
923     }
924 
Methodglcts::__anon253d27190111::CZeroBindingPoint925     virtual std::string Method()
926     {
927         return "Bind zero and check that binding point is set to zero";
928     }
929 
PassCriteriaglcts::__anon253d27190111::CZeroBindingPoint930     virtual std::string PassCriteria()
931     {
932         return "The test will pass if binding point is set to zero";
933     }
934 
Runglcts::__anon253d27190111::CZeroBindingPoint935     virtual long Run()
936     {
937         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
938 
939         return BindingPointCheck<api>(0);
940     }
941 };
942 
943 template <typename api>
944 struct CSingleBindingPoint : public DrawIndirectBase
945 {
Titleglcts::__anon253d27190111::CSingleBindingPoint946     virtual std::string Title()
947     {
948         return "Draw Indirect: Single binding point";
949     }
950 
Purposeglcts::__anon253d27190111::CSingleBindingPoint951     virtual std::string Purpose()
952     {
953         return "Verify that binding point is set to correct value";
954     }
955 
Methodglcts::__anon253d27190111::CSingleBindingPoint956     virtual std::string Method()
957     {
958         return "Bind non-zero buffer and check that binding point is set to correct value";
959     }
960 
PassCriteriaglcts::__anon253d27190111::CSingleBindingPoint961     virtual std::string PassCriteria()
962     {
963         return "The test will pass if binding point is set to correct value";
964     }
965 
Runglcts::__anon253d27190111::CSingleBindingPoint966     virtual long Run()
967     {
968         glGenBuffers(1, &_buffer);
969         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
970 
971         long ret = BindingPointCheck<api>(_buffer);
972 
973         return ret;
974     }
975 
Cleanupglcts::__anon253d27190111::CSingleBindingPoint976     virtual long Cleanup()
977     {
978         glDeleteBuffers(1, &_buffer);
979         return BindingPointCheck<api>(0);
980     }
981 
982 private:
983     GLuint _buffer;
984 };
985 
986 template <typename api>
987 class CMultiBindingPoint : public DrawIndirectBase
988 {
989 public:
Title()990     virtual std::string Title()
991     {
992         return "Draw Indirect: Multi binding point";
993     }
994 
Purpose()995     virtual std::string Purpose()
996     {
997         return "Verify that binding points are set to correct value";
998     }
999 
Method()1000     virtual std::string Method()
1001     {
1002         return "Bind in loop non-zero buffers and check that binding points are set to correct value";
1003     }
1004 
PassCriteria()1005     virtual std::string PassCriteria()
1006     {
1007         return "The test will pass if binding points are set to correct value";
1008     }
1009 
Run()1010     virtual long Run()
1011     {
1012         DIResult result;
1013 
1014         const int buffNum = sizeof(_buffers) / sizeof(_buffers[0]);
1015 
1016         glGenBuffers(buffNum, _buffers);
1017 
1018         for (int i = 0; i < buffNum; ++i)
1019         {
1020             glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[i]);
1021             result.sub_result(BindingPointCheck<api>(_buffers[i]));
1022         }
1023 
1024         return result.code();
1025     }
1026 
Cleanup()1027     virtual long Cleanup()
1028     {
1029         glDeleteBuffers(sizeof(_buffers) / sizeof(_buffers[0]), _buffers);
1030         return BindingPointCheck<api>(0);
1031     }
1032 
1033 private:
1034     GLuint _buffers[10];
1035 };
1036 
1037 template <typename api>
1038 struct CDeleteBindingPoint : public DrawIndirectBase
1039 {
Titleglcts::__anon253d27190111::CDeleteBindingPoint1040     virtual std::string Title()
1041     {
1042         return "Draw Indirect: Delete binding point";
1043     }
1044 
Purposeglcts::__anon253d27190111::CDeleteBindingPoint1045     virtual std::string Purpose()
1046     {
1047         return "Verify that after deleting buffer, binding point is set to correct value";
1048     }
1049 
Methodglcts::__anon253d27190111::CDeleteBindingPoint1050     virtual std::string Method()
1051     {
1052         return "Bind non-zero buffer, delete buffer, check that binding point is set to 0";
1053     }
1054 
PassCriteriaglcts::__anon253d27190111::CDeleteBindingPoint1055     virtual std::string PassCriteria()
1056     {
1057         return "The test will pass if binding point is set to correct value";
1058     }
1059 
Runglcts::__anon253d27190111::CDeleteBindingPoint1060     virtual long Run()
1061     {
1062         glGenBuffers(1, &_buffer);
1063         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
1064         glDeleteBuffers(1, &_buffer);
1065         return BindingPointCheck<api>(0);
1066     }
1067 
1068 private:
1069     GLuint _buffer;
1070 };
1071 
1072 template <typename api>
1073 struct CBufferData : public DrawIndirectBase
1074 {
Titleglcts::__anon253d27190111::CBufferData1075     virtual std::string Title()
1076     {
1077         return "Check functions: glBufferData and GetBufferSubData<api>";
1078     }
1079 
Purposeglcts::__anon253d27190111::CBufferData1080     virtual std::string Purpose()
1081     {
1082         return "Verify that glBufferData and GetBufferSubData<api> accepts GL_DRAW_INDIRECT_BUFFER enum";
1083     }
1084 
Methodglcts::__anon253d27190111::CBufferData1085     virtual std::string Method()
1086     {
1087         return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data using glBufferData" NL
1088                "4. Get data using GetBufferSubData<api>" NL "5. Verify results";
1089     }
1090 
PassCriteriaglcts::__anon253d27190111::CBufferData1091     virtual std::string PassCriteria()
1092     {
1093         return "The test will pass if no OpenGL errors reported";
1094     }
1095 
Runglcts::__anon253d27190111::CBufferData1096     virtual long Run()
1097     {
1098         DIResult result;
1099 
1100         int dataWidth, dataHeight;
1101         getDataSize(dataWidth, dataHeight);
1102 
1103         CDataArray dataTest(dataWidth * dataHeight, 0);
1104 
1105         glGenBuffers(sizeof(_buffers) / sizeof(_buffers[0]), _buffers);
1106         CDataArray dataRef1;
1107         DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 0, 50);
1108 
1109         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[1]);
1110         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef1.size() * sizeof(unsigned int)), &dataRef1[0],
1111                      GL_DYNAMIC_DRAW);
1112         result.sub_result(BindingPointCheck<api>(_buffers[1]));
1113 
1114         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1115                               &dataTest[0]);
1116         result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1117 
1118         CDataArray dataRef2;
1119         DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 10, 70);
1120 
1121         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[2]);
1122         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0],
1123                      GL_STREAM_DRAW);
1124         result.sub_result(BindingPointCheck<api>(_buffers[2]));
1125 
1126         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1127                               &dataTest[0]);
1128         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1129 
1130         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[3]);
1131         glBufferData(GL_DRAW_INDIRECT_BUFFER, 300, NULL, GL_STATIC_DRAW);
1132         result.sub_result(BindingPointCheck<api>(_buffers[3]));
1133 
1134         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[4]);
1135         glBufferData(GL_DRAW_INDIRECT_BUFFER, 400, NULL, GL_DYNAMIC_READ);
1136         result.sub_result(BindingPointCheck<api>(_buffers[4]));
1137 
1138         CDataArray dataRef5;
1139         DataGen<unsigned int>(dataRef5, dataWidth, dataHeight, 0, 50);
1140 
1141         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[5]);
1142         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef5.size() * sizeof(unsigned int)), &dataRef5[0],
1143                      GL_STREAM_READ);
1144         result.sub_result(BindingPointCheck<api>(_buffers[5]));
1145 
1146         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1147                               &dataTest[0]);
1148         result.sub_result(DataCompare(dataRef5, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1149 
1150         CDataArray dataRef6;
1151         DataGen<unsigned int>(dataRef6, dataWidth, dataHeight, 10, 40);
1152 
1153         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[6]);
1154         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef6.size() * sizeof(unsigned int)), &dataRef6[0],
1155                      GL_STATIC_READ);
1156         result.sub_result(BindingPointCheck<api>(_buffers[6]));
1157 
1158         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1159                               &dataTest[0]);
1160         result.sub_result(DataCompare(dataRef6, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1161 
1162         CDataArray dataRef7;
1163         DataGen<unsigned int>(dataRef7, dataWidth, dataHeight, 4, 70);
1164 
1165         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[7]);
1166         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef7.size() * sizeof(unsigned int)), &dataRef7[0],
1167                      GL_DYNAMIC_COPY);
1168         result.sub_result(BindingPointCheck<api>(_buffers[7]));
1169 
1170         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1171                               &dataTest[0]);
1172         result.sub_result(DataCompare(dataRef7, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1173 
1174         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[8]);
1175         glBufferData(GL_DRAW_INDIRECT_BUFFER, 800, NULL, GL_STREAM_COPY);
1176         result.sub_result(BindingPointCheck<api>(_buffers[8]));
1177 
1178         CDataArray dataRef9;
1179         DataGen<unsigned int>(dataRef9, dataWidth, dataHeight, 18, 35);
1180 
1181         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[9]);
1182         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0],
1183                      GL_STATIC_COPY);
1184         result.sub_result(BindingPointCheck<api>(_buffers[9]));
1185 
1186         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1187                               &dataTest[0]);
1188         result.sub_result(DataCompare(dataRef9, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1189 
1190         //reallocation: same size
1191         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0],
1192                      GL_STATIC_COPY);
1193         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1194                               &dataTest[0]);
1195         result.sub_result(DataCompare(dataRef9, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1196 
1197         //reallocation: larger size
1198         DataGen<unsigned int>(dataRef9, dataWidth * 2, dataHeight * 2, 18, 35);
1199         dataTest.resize(dataRef9.size());
1200         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0],
1201                      GL_STATIC_COPY);
1202         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1203                               &dataTest[0]);
1204         result.sub_result(
1205             DataCompare(dataRef9, dataWidth * 2, dataHeight * 2, dataTest, dataWidth * 2, dataHeight * 2));
1206 
1207         //reallocation: smaller size
1208         DataGen<unsigned int>(dataRef9, dataWidth / 2, dataHeight / 2, 18, 35);
1209         dataTest.resize(dataRef9.size());
1210         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0],
1211                      GL_STATIC_COPY);
1212         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1213                               &dataTest[0]);
1214         result.sub_result(
1215             DataCompare(dataRef9, dataWidth / 2, dataHeight / 2, dataTest, dataWidth / 2, dataHeight / 2));
1216 
1217         return result.code();
1218     }
1219 
Cleanupglcts::__anon253d27190111::CBufferData1220     virtual long Cleanup()
1221     {
1222         glDeleteBuffers(sizeof(_buffers) / sizeof(_buffers[0]), _buffers);
1223         return BindingPointCheck<api>(0);
1224     }
1225 
1226 private:
1227     GLuint _buffers[10];
1228 };
1229 
1230 template <typename api>
1231 struct CBufferSubData : public DrawIndirectBase
1232 {
Titleglcts::__anon253d27190111::CBufferSubData1233     virtual std::string Title()
1234     {
1235         return "Check function: glBufferSubData and GetBufferSubData<api>";
1236     }
1237 
Purposeglcts::__anon253d27190111::CBufferSubData1238     virtual std::string Purpose()
1239     {
1240         return "Verify that glBufferSubData and GetBufferSubData<api> accepts GL_DRAW_INDIRECT_BUFFER enum";
1241     }
1242 
Methodglcts::__anon253d27190111::CBufferSubData1243     virtual std::string Method()
1244     {
1245         return "1. Create buffer" NL "2. Bind buffer" NL "3. Allocate buffer using glBufferData" NL
1246                "4. Set data using glBufferSubData" NL "5. Get data using GetBufferSubData<api>" NL "6. Verify results";
1247     }
1248 
PassCriteriaglcts::__anon253d27190111::CBufferSubData1249     virtual std::string PassCriteria()
1250     {
1251         return "The test will pass if no OpenGL errors reported";
1252     }
1253 
Runglcts::__anon253d27190111::CBufferSubData1254     virtual long Run()
1255     {
1256         DIResult result;
1257 
1258         glGenBuffers(1, &_buffer);
1259         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
1260 
1261         CDataArray dataRef;
1262         int dataWidth, dataHeight;
1263         getDataSize(dataWidth, dataHeight);
1264         DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 4, 70);
1265         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), NULL,
1266                      GL_DYNAMIC_DRAW);
1267         glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0]);
1268 
1269         CDataArray dataTest(dataWidth * dataHeight, 0);
1270         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1271                               &dataTest[0]);
1272 
1273         result.sub_result(DataCompare(dataRef, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1274 
1275         CDataArray dataSubRef;
1276         DataGen<unsigned int>(dataSubRef, dataWidth / 2, dataHeight / 2, 80, 90);
1277         glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 4, (GLsizeiptr)(dataSubRef.size() * sizeof(unsigned int)),
1278                         &dataSubRef[0]);
1279         std::copy(dataSubRef.begin(), dataSubRef.end(), dataRef.begin() + 1);
1280 
1281         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1282                               &dataTest[0]);
1283         result.sub_result(DataCompare(dataRef, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1284 
1285         return result.code();
1286     }
1287 
Cleanupglcts::__anon253d27190111::CBufferSubData1288     virtual long Cleanup()
1289     {
1290         glDeleteBuffers(1, &_buffer);
1291         return BindingPointCheck<api>(0);
1292     }
1293 
1294 private:
1295     GLuint _buffer;
1296 };
1297 
1298 template <typename api>
1299 struct CBufferMap : public DrawIndirectBase
1300 {
Titleglcts::__anon253d27190111::CBufferMap1301     virtual std::string Title()
1302     {
1303         return "Check functions: glMapBuffer, glUnmapBuffer and getParameteriv";
1304     }
1305 
Purposeglcts::__anon253d27190111::CBufferMap1306     virtual std::string Purpose()
1307     {
1308         return "Verify that glMapBuffer, glUnmapBuffer and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum";
1309     }
1310 
Methodglcts::__anon253d27190111::CBufferMap1311     virtual std::string Method()
1312     {
1313         return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer" NL
1314                "5. Verify mapped buffer" NL "6. Check state" NL "7. Unmap buffer" NL "8. Check state";
1315     }
1316 
PassCriteriaglcts::__anon253d27190111::CBufferMap1317     virtual std::string PassCriteria()
1318     {
1319         return "The test will pass if no OpenGL errors reported";
1320     }
1321 
Runglcts::__anon253d27190111::CBufferMap1322     virtual long Run()
1323     {
1324         DIResult result;
1325 
1326         api::GL_Only();
1327 
1328         glGenBuffers(1, &_buffer);
1329         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
1330 
1331         CDataArray dataRef;
1332         int dataWidth, dataHeight;
1333         getDataSize(dataWidth, dataHeight);
1334         DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50);
1335         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
1336                      GL_DYNAMIC_DRAW);
1337 
1338         result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1339 
1340         void *buf = glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_ONLY);
1341         if (buf == 0)
1342         {
1343             result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_ONLY) returned NULL";
1344         }
1345 
1346         if (buf)
1347         {
1348             result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight));
1349 
1350             result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_ONLY, GL_MAP_READ_BIT, 0,
1351                                                  (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));
1352 
1353             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
1354             {
1355                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1356             }
1357             buf = 0;
1358 
1359             result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1360         }
1361 
1362         buf = glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_WRITE_ONLY);
1363         if (buf == 0)
1364         {
1365             result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_WRITE_ONLY) returned NULL";
1366         }
1367 
1368         if (buf)
1369         {
1370             result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight));
1371 
1372             result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT, 0,
1373                                                  (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));
1374 
1375             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE)
1376             {
1377                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1378             }
1379             buf = 0;
1380 
1381             result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1382         }
1383 
1384         buf = glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_WRITE);
1385         if (buf == 0)
1386         {
1387             result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_WRITE) returned NULL";
1388         }
1389 
1390         if (buf)
1391         {
1392             result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight));
1393 
1394             result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_WRITE, GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, 0,
1395                                                  (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));
1396 
1397             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
1398             {
1399                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1400             }
1401             buf = 0;
1402 
1403             result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1404         }
1405 
1406         return result.code();
1407     }
1408 
Cleanupglcts::__anon253d27190111::CBufferMap1409     virtual long Cleanup()
1410     {
1411         glDeleteBuffers(1, &_buffer);
1412         return BindingPointCheck<api>(0);
1413     }
1414 
1415 private:
1416     GLuint _buffer;
1417 };
1418 
1419 template <typename api>
1420 struct CBufferGetPointerv : public DrawIndirectBase
1421 {
Titleglcts::__anon253d27190111::CBufferGetPointerv1422     virtual std::string Title()
1423     {
1424         return "Check functions: glBuffergetPointerv";
1425     }
1426 
Purposeglcts::__anon253d27190111::CBufferGetPointerv1427     virtual std::string Purpose()
1428     {
1429         return "Verify that glBuffergetPointerv accepts GL_DRAW_INDIRECT_BUFFER enum";
1430     }
1431 
Methodglcts::__anon253d27190111::CBufferGetPointerv1432     virtual std::string Method()
1433     {
1434         return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer" NL
1435                "5. Get a pointer to buffer" NL "6. Compare pointers from point 4) and 5)" NL
1436                "7. Verify mapped buffer" NL "8. Unmap buffer";
1437     }
1438 
PassCriteriaglcts::__anon253d27190111::CBufferGetPointerv1439     virtual std::string PassCriteria()
1440     {
1441         return "The test will pass if no OpenGL errors reported";
1442     }
1443 
Runglcts::__anon253d27190111::CBufferGetPointerv1444     virtual long Run()
1445     {
1446         DIResult result;
1447 
1448         glGenBuffers(1, &_buffer);
1449         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
1450 
1451         CDataArray dataRef;
1452         int dataWidth, dataHeight;
1453         getDataSize(dataWidth, dataHeight);
1454         DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50);
1455         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
1456                      GL_DYNAMIC_DRAW);
1457 
1458         void *ptr = 0;
1459         glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER, &ptr);
1460 
1461         if (ptr != 0)
1462         {
1463             result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) returned invalid "
1464                               "pointer, expected: NULL";
1465         }
1466 
1467         void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)),
1468                                      GL_MAP_READ_BIT);
1469         if (buf == 0)
1470         {
1471             result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
1472 
1473             return result.code();
1474         }
1475 
1476         glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER, &ptr);
1477 
1478         if (ptr == 0)
1479         {
1480             result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) returned NULL";
1481         }
1482 
1483         if (ptr)
1484         {
1485             result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, ptr, dataWidth, dataHeight));
1486         }
1487 
1488         if (ptr != buf)
1489         {
1490             result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) different pointer "
1491                               "than glMapBuffer(GL_DRAW_INDIRECT_BUFFER)";
1492         }
1493 
1494         if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
1495         {
1496             result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1497         }
1498         buf = 0;
1499         ptr = 0;
1500 
1501         return result.code();
1502     }
1503 
Cleanupglcts::__anon253d27190111::CBufferGetPointerv1504     virtual long Cleanup()
1505     {
1506         glDeleteBuffers(1, &_buffer);
1507         return BindingPointCheck<api>(0);
1508     }
1509 
1510 private:
1511     GLuint _buffer;
1512 };
1513 
1514 template <class api>
1515 struct CBufferMapRange : public DrawIndirectBase
1516 {
Titleglcts::__anon253d27190111::CBufferMapRange1517     virtual std::string Title()
1518     {
1519         return "Check functions: glMapRangeBuffer, glUnmapBuffer and getParameteriv";
1520     }
1521 
Purposeglcts::__anon253d27190111::CBufferMapRange1522     virtual std::string Purpose()
1523     {
1524         return "Verify that glMapRangeBuffer, glUnmapBuffer and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum";
1525     }
1526 
Methodglcts::__anon253d27190111::CBufferMapRange1527     virtual std::string Method()
1528     {
1529         return "Bind non-zero buffer and check that binding point is set to correct value";
1530     }
1531 
PassCriteriaglcts::__anon253d27190111::CBufferMapRange1532     virtual std::string PassCriteria()
1533     {
1534         return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer using glMapBufferRange" NL
1535                "5. Check state" NL "6. Verify mapped buffer" NL "7. Unmap buffer" NL "8. Check state";
1536     }
1537 
Runglcts::__anon253d27190111::CBufferMapRange1538     virtual long Run()
1539     {
1540         DIResult result;
1541 
1542         glGenBuffers(1, &_buffer);
1543         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
1544 
1545         CDataArray dataRef;
1546         int dataWidth, dataHeight;
1547         getDataSize(dataWidth, dataHeight);
1548         DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50);
1549         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
1550                      GL_DYNAMIC_DRAW);
1551 
1552         result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1553 
1554         void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)),
1555                                      GL_MAP_READ_BIT);
1556         if (buf == 0)
1557         {
1558             result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
1559         }
1560 
1561         if (buf)
1562         {
1563             result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight));
1564 
1565             result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_ONLY, GL_MAP_READ_BIT, 0,
1566                                                  (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));
1567 
1568             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
1569             {
1570                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1571             }
1572             buf = 0;
1573 
1574             result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1575         }
1576 
1577         buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int)),
1578                                GL_MAP_WRITE_BIT);
1579         if (buf == 0)
1580         {
1581             result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL";
1582         }
1583 
1584         if (buf)
1585         {
1586             result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight / 2, buf, dataWidth, dataHeight / 2));
1587 
1588             result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT, 0,
1589                                                  (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int))));
1590 
1591             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
1592             {
1593                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1594             }
1595             buf = 0;
1596 
1597             result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1598         }
1599 
1600         buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, (GLintptr)(dataRef.size() / 4 * sizeof(unsigned int)),
1601                                (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int)), GL_MAP_WRITE_BIT);
1602         if (buf == 0)
1603         {
1604             result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL";
1605         }
1606 
1607         if (buf)
1608         {
1609             result.sub_result(
1610                 BufferCheck(dataRef, dataWidth, dataHeight / 2, buf, dataWidth, dataHeight / 2, dataHeight / 4));
1611 
1612             result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT,
1613                                                  (GLintptr)(dataRef.size() / 4 * sizeof(unsigned int)),
1614                                                  (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int))));
1615 
1616             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
1617             {
1618                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1619             }
1620             buf = 0;
1621 
1622             result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1623         }
1624 
1625         return result.code();
1626     }
1627 
Cleanupglcts::__anon253d27190111::CBufferMapRange1628     virtual long Cleanup()
1629     {
1630         glDeleteBuffers(1, &_buffer);
1631         return BindingPointCheck<api>(0);
1632     }
1633 
1634 private:
1635     GLuint _buffer;
1636 };
1637 
1638 template <class api>
1639 struct CBufferFlushMappedRange : public DrawIndirectBase
1640 {
Titleglcts::__anon253d27190111::CBufferFlushMappedRange1641     virtual std::string Title()
1642     {
1643         return "Check functions: glFlushMappedBufferRange";
1644     }
1645 
Purposeglcts::__anon253d27190111::CBufferFlushMappedRange1646     virtual std::string Purpose()
1647     {
1648         return "Verify that glFlushMappedBufferRange and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum";
1649     }
1650 
Methodglcts::__anon253d27190111::CBufferFlushMappedRange1651     virtual std::string Method()
1652     {
1653         return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL
1654                "4. Map buffer with GL_MAP_FLUSH_EXPLICIT_BIT flag" NL "5. Check state" NL "6. Modify mapped buffer" NL
1655                "7. Flush buffer" NL "8. Unmap buffer" NL "9. Check state" NL "10. Verify buffer";
1656     }
1657 
PassCriteriaglcts::__anon253d27190111::CBufferFlushMappedRange1658     virtual std::string PassCriteria()
1659     {
1660         return "The test will pass if no OpenGL errors reported";
1661     }
1662 
Runglcts::__anon253d27190111::CBufferFlushMappedRange1663     virtual long Run()
1664     {
1665         DIResult result;
1666 
1667         glGenBuffers(1, &_buffer);
1668         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
1669 
1670         CDataArray dataRef;
1671         int dataWidth, dataHeight;
1672         getDataSize(dataWidth, dataHeight);
1673         DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 1, 1000);
1674 
1675         CDataArray dataRef2;
1676         DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 1000, 2000);
1677 
1678         const int halfSize    = dataHeight / 2 * dataWidth;
1679         const int quarterSize = dataHeight / 4 * dataWidth;
1680 
1681         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
1682                      GL_DYNAMIC_DRAW);
1683 
1684         result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1685 
1686         void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, quarterSize * sizeof(unsigned int),
1687                                      halfSize * sizeof(unsigned int), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
1688 
1689         if (buf == 0)
1690         {
1691             result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL";
1692         }
1693 
1694         if (buf)
1695         {
1696             result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT,
1697                                                  quarterSize * sizeof(unsigned int), halfSize * sizeof(unsigned int)));
1698 
1699             memcpy(buf, &dataRef2[quarterSize], halfSize * sizeof(unsigned int));
1700             glFlushMappedBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, halfSize * sizeof(unsigned int));
1701 
1702             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
1703             {
1704                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1705             }
1706             buf = 0;
1707 
1708             result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1709         }
1710 
1711         CDataArray dataTest(dataWidth * dataHeight, 0);
1712         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1713                               &dataTest[0]);
1714 
1715         result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4));
1716 
1717         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2,
1718                                       dataHeight / 4, dataHeight / 4));
1719 
1720         result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4,
1721                                       dataHeight * 3 / 4, dataHeight * 3 / 4));
1722 
1723         return result.code();
1724     }
1725 
Cleanupglcts::__anon253d27190111::CBufferFlushMappedRange1726     virtual long Cleanup()
1727     {
1728         glDeleteBuffers(1, &_buffer);
1729         return BindingPointCheck<api>(0);
1730     }
1731 
1732 private:
1733     GLuint _buffer;
1734 };
1735 
1736 template <class api>
1737 struct CBufferBindRange : public DrawIndirectBase
1738 {
Titleglcts::__anon253d27190111::CBufferBindRange1739     virtual std::string Title()
1740     {
1741         return "Check functions: glBindBufferRange";
1742     }
1743 
Purposeglcts::__anon253d27190111::CBufferBindRange1744     virtual std::string Purpose()
1745     {
1746         return "Verify that glBindBufferRange accepts GL_DRAW_INDIRECT_BUFFER enum";
1747     }
1748 
Methodglcts::__anon253d27190111::CBufferBindRange1749     virtual std::string Method()
1750     {
1751         return "1. Create buffer" NL "2. Bind buffer using glBindBufferRange" NL "3. Set data" NL "4. Verify buffer";
1752     }
1753 
PassCriteriaglcts::__anon253d27190111::CBufferBindRange1754     virtual std::string PassCriteria()
1755     {
1756         return "The test will pass if no OpenGL errors reported";
1757     }
1758 
Runglcts::__anon253d27190111::CBufferBindRange1759     virtual long Run()
1760     {
1761         DIResult result;
1762 
1763         glGenBuffers(1, &_buffer);
1764         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
1765 
1766         CDataArray dataRef;
1767         int dataWidth, dataHeight;
1768         getDataSize(dataWidth, dataHeight);
1769         DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 1, 100);
1770         glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef.size() * sizeof(unsigned int), &dataRef[0], GL_DYNAMIC_DRAW);
1771 
1772         CDataArray dataTest(dataWidth * dataHeight, 0);
1773         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
1774         result.sub_result(DataCompare(dataRef, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1775 
1776         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
1777         result.sub_result(BindingPointCheck<api>(0));
1778 
1779         glBindBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _buffer, 0, dataTest.size() * sizeof(unsigned int) / 4);
1780         result.sub_result(BindingPointCheck<api>(_buffer));
1781 
1782         CDataArray dataRef2;
1783         DataGen<unsigned int>(dataRef2, dataWidth, dataHeight / 2, 10, 15);
1784         glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int) / 4, &dataRef2[0],
1785                      GL_DYNAMIC_DRAW);
1786 
1787         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
1788         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4));
1789         result.sub_result(DataCompare(dataRef, dataWidth, dataHeight * 3 / 4, dataTest, dataWidth, dataHeight * 3 / 4,
1790                                       dataHeight / 4, dataHeight / 4));
1791 
1792         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
1793         result.sub_result(BindingPointCheck<api>(0));
1794 
1795         glBindBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _buffer, dataTest.size() * sizeof(unsigned int) / 4,
1796                           dataTest.size() * sizeof(unsigned int) / 4);
1797         result.sub_result(BindingPointCheck<api>(_buffer));
1798 
1799         glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int) / 2,
1800                      &dataRef2[dataRef2.size() / 2], GL_DYNAMIC_DRAW);
1801         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2));
1802         result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2,
1803                                       dataHeight / 2, dataHeight / 2));
1804 
1805         return result.code();
1806     }
1807 
Cleanupglcts::__anon253d27190111::CBufferBindRange1808     virtual long Cleanup()
1809     {
1810         glDeleteBuffers(1, &_buffer);
1811 
1812         return BindingPointCheck<api>(0);
1813     }
1814 
1815 private:
1816     GLuint _buffer;
1817 };
1818 
1819 template <class api>
1820 struct CBufferBindBase : public DrawIndirectBase
1821 {
Titleglcts::__anon253d27190111::CBufferBindBase1822     virtual std::string Title()
1823     {
1824         return "Check functions: glBindBufferBase";
1825     }
1826 
Purposeglcts::__anon253d27190111::CBufferBindBase1827     virtual std::string Purpose()
1828     {
1829         return "Verify that glBindBufferBase accepts GL_DRAW_INDIRECT_BUFFER enum";
1830     }
1831 
Methodglcts::__anon253d27190111::CBufferBindBase1832     virtual std::string Method()
1833     {
1834         return "1. Create buffer" NL "2. Bind buffer using glBindBufferBase" NL "3. Set data" NL "4. Verify buffer";
1835     }
1836 
PassCriteriaglcts::__anon253d27190111::CBufferBindBase1837     virtual std::string PassCriteria()
1838     {
1839         return "The test will pass if no OpenGL errors reported";
1840     }
1841 
Runglcts::__anon253d27190111::CBufferBindBase1842     virtual long Run()
1843     {
1844         DIResult result;
1845 
1846         glGenBuffers(2, _buffers);
1847 
1848         int dataWidth, dataHeight;
1849         getDataSize(dataWidth, dataHeight);
1850         CDataArray dataTest(dataWidth * dataHeight, 0);
1851 
1852         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[0]);
1853         CDataArray dataRef1;
1854         DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 1, 100);
1855         glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef1.size() * sizeof(unsigned int), &dataRef1[0], GL_DYNAMIC_DRAW);
1856 
1857         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
1858         result.sub_result(BindingPointCheck<api>(0));
1859 
1860         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
1861         result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1862         result.sub_result(BindingPointCheck<api>(_buffers[0]));
1863 
1864         glBindBufferBase(GL_DRAW_INDIRECT_BUFFER, 0, _buffers[1]);
1865         result.sub_result(BindingPointCheck<api>(_buffers[1]));
1866 
1867         CDataArray dataRef2;
1868         DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 50, 70);
1869         glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int), &dataRef2[0], GL_DYNAMIC_DRAW);
1870 
1871         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
1872         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1873 
1874         result.sub_result(BindingPointCheck<api>(_buffers[1]));
1875 
1876         return result.code();
1877     }
1878 
Cleanupglcts::__anon253d27190111::CBufferBindBase1879     virtual long Cleanup()
1880     {
1881         glDeleteBuffers(2, _buffers);
1882         return BindingPointCheck<api>(0);
1883     }
1884 
1885 private:
1886     GLuint _buffers[2];
1887 };
1888 
1889 template <class api>
1890 struct CBufferCopySubData : public DrawIndirectBase
1891 {
Titleglcts::__anon253d27190111::CBufferCopySubData1892     virtual std::string Title()
1893     {
1894         return "Check functions: glCopyBufferSubData";
1895     }
1896 
Purposeglcts::__anon253d27190111::CBufferCopySubData1897     virtual std::string Purpose()
1898     {
1899         return "Verify that glCopyBufferSubData accepts GL_DRAW_INDIRECT_BUFFER enum";
1900     }
1901 
Methodglcts::__anon253d27190111::CBufferCopySubData1902     virtual std::string Method()
1903     {
1904         return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Verify buffer" NL
1905                "5. Modify buffer using glCopyBufferSubData" NL "6. Verify buffer";
1906     }
1907 
PassCriteriaglcts::__anon253d27190111::CBufferCopySubData1908     virtual std::string PassCriteria()
1909     {
1910         return "The test will pass if no OpenGL errors reported";
1911     }
1912 
Runglcts::__anon253d27190111::CBufferCopySubData1913     virtual long Run()
1914     {
1915         DIResult result;
1916         int dataWidth, dataHeight;
1917         getDataSize(dataWidth, dataHeight);
1918         CDataArray dataTest(dataWidth * dataHeight, 0);
1919 
1920         glGenBuffers(2, _buffers);
1921         glBindBuffer(GL_ARRAY_BUFFER, _buffers[0]);
1922 
1923         CDataArray dataRef1;
1924         DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 1, 100);
1925         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(dataRef1.size() * sizeof(unsigned int)), &dataRef1[0],
1926                      GL_DYNAMIC_DRAW);
1927 
1928         GetBufferSubData<api>(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), &dataTest[0]);
1929         result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1930 
1931         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[1]);
1932 
1933         CDataArray dataRef2;
1934         DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 10, 30);
1935         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0],
1936                      GL_DYNAMIC_DRAW);
1937 
1938         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1939                               &dataTest[0]);
1940         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1941 
1942         glCopyBufferSubData(GL_ARRAY_BUFFER, GL_DRAW_INDIRECT_BUFFER, 0, 0,
1943                             (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)));
1944 
1945         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1946                               &dataTest[0]);
1947         result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1948 
1949         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0],
1950                      GL_DYNAMIC_DRAW);
1951 
1952         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1953                               &dataTest[0]);
1954         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1955 
1956         glCopyBufferSubData(GL_DRAW_INDIRECT_BUFFER, GL_ARRAY_BUFFER, 0, 0,
1957                             (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)));
1958 
1959         GetBufferSubData<api>(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), &dataTest[0]);
1960         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1961 
1962         return result.code();
1963     }
1964 
Cleanupglcts::__anon253d27190111::CBufferCopySubData1965     virtual long Cleanup()
1966     {
1967         glDeleteBuffers(2, _buffers);
1968         return BindingPointCheck<api>(0);
1969     }
1970 
1971 private:
1972     GLuint _buffers[2];
1973 };
1974 
1975 class CBasicVertexDef : public DrawIndirectBase
1976 {
1977 public:
Setup()1978     virtual long Setup()
1979     {
1980         glClear(GL_COLOR_BUFFER_BIT);
1981         return NO_ERROR;
1982     }
1983 
1984     template <typename api>
Run()1985     long Run()
1986     {
1987         CColorArray coords;
1988         PrimitiveGen(_primitiveType, _drawSizeX, _drawSizeY, coords);
1989 
1990         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
1991         if (!_program)
1992         {
1993             return ERROR;
1994         }
1995         glUseProgram(_program);
1996 
1997         glGenBuffers(1, &_vbo);
1998         glBindBuffer(GL_ARRAY_BUFFER, _vbo);
1999         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW);
2000 
2001         glGenVertexArrays(1, &_vao);
2002         glBindVertexArray(_vao);
2003         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
2004         glEnableVertexAttribArray(0);
2005 
2006         DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
2007         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
2008 
2009         CElementArray elements(coords.size(), 0);
2010         for (size_t i = 0; i < elements.size(); ++i)
2011         {
2012             elements[i] = static_cast<GLuint>(i);
2013         }
2014 
2015         switch (_drawFunc)
2016         {
2017         case DRAW_ARRAYS:
2018         {
2019             indirectArrays.count              = static_cast<GLuint>(coords.size());
2020             indirectArrays.primCount          = 1;
2021             indirectArrays.first              = 0;
2022             indirectArrays.reservedMustBeZero = 0;
2023 
2024             {
2025                 GLuint buffer;
2026                 glGenBuffers(1, &buffer);
2027                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
2028                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
2029                 glDrawArraysIndirect(_primitiveType, 0);
2030                 glDeleteBuffers(1, &buffer);
2031             }
2032         }
2033         break;
2034         case DRAW_ELEMENTS:
2035         {
2036             indirectElements.count              = static_cast<GLuint>(coords.size());
2037             indirectElements.primCount          = 1;
2038             indirectElements.firstIndex         = 0;
2039             indirectElements.baseVertex         = 0;
2040             indirectElements.reservedMustBeZero = 0;
2041 
2042             glGenBuffers(1, &_ebo);
2043             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
2044             glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
2045                          GL_STATIC_DRAW);
2046 
2047             {
2048                 GLuint buffer;
2049                 glGenBuffers(1, &buffer);
2050                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
2051                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
2052                 glDrawElementsIndirect(_primitiveType, GL_UNSIGNED_INT, 0);
2053                 glDeleteBuffers(1, &buffer);
2054             }
2055         }
2056         break;
2057         default:
2058             throw std::runtime_error("Unknown draw function!");
2059             break;
2060         }
2061 
2062         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
2063         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
2064         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
2065 
2066         DIResult result;
2067         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
2068                                          getWindowHeight()));
2069 
2070         return result.code();
2071     }
2072 
Cleanup()2073     virtual long Cleanup()
2074     {
2075         glDisableVertexAttribArray(0);
2076         glBindBuffer(GL_ARRAY_BUFFER, 0);
2077         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2078         glBindVertexArray(0);
2079         glUseProgram(0);
2080 
2081         if (_vao)
2082         {
2083             glDeleteVertexArrays(1, &_vao);
2084         }
2085         if (_vbo)
2086         {
2087             glDeleteBuffers(1, &_vbo);
2088         }
2089         if (_ebo)
2090         {
2091             glDeleteBuffers(1, &_ebo);
2092         }
2093         if (_program)
2094         {
2095             glDeleteProgram(_program);
2096         }
2097 
2098         return NO_ERROR;
2099     }
2100 
CBasicVertexDef(TDrawFunction drawFunc,GLenum primitiveType,unsigned int drawSizeX,unsigned int drawSizeY)2101     CBasicVertexDef(TDrawFunction drawFunc, GLenum primitiveType, unsigned int drawSizeX, unsigned int drawSizeY)
2102         : _drawFunc(drawFunc)
2103         , _primitiveType(primitiveType)
2104         , _drawSizeX(drawSizeX)
2105         , _drawSizeY(drawSizeY)
2106         , _vao(0)
2107         , _vbo(0)
2108         , _ebo(0)
2109         , _program(0)
2110     {
2111     }
2112 
2113 private:
2114     TDrawFunction _drawFunc;
2115     GLenum _primitiveType;
2116     unsigned int _drawSizeX;
2117     unsigned int _drawSizeY;
2118 
2119     GLuint _vao;
2120     GLuint _vbo, _ebo;
2121     GLuint _program;
2122 
CBasicVertexDef()2123     CBasicVertexDef()
2124     {
2125     }
2126 };
2127 
2128 class CBasicVertexInstancingDef : public DrawIndirectBase
2129 {
2130 public:
Setup()2131     virtual long Setup()
2132     {
2133         glClear(GL_COLOR_BUFFER_BIT);
2134         return NO_ERROR;
2135     }
2136 
2137     template <typename api>
Run()2138     long Run()
2139     {
2140         CColorArray coords;
2141         PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords);
2142 
2143         CColorArray coords_instanced(4);
2144         coords_instanced[0] = tcu::Vec4(0.5, 0.5, 0.0, 0.0);
2145         coords_instanced[1] = tcu::Vec4(-0.5, 0.5, 0.0, 0.0);
2146         coords_instanced[2] = tcu::Vec4(-0.5, -0.5, 0.0, 0.0);
2147         coords_instanced[3] = tcu::Vec4(0.5, -0.5, 0.0, 0.0);
2148 
2149         CColorArray colors_instanced(2);
2150         colors_instanced[0] = tcu::Vec4(1.0, 0.0, 0.0, 1.0);
2151         colors_instanced[1] = tcu::Vec4(0.0, 1.0, 0.0, 1.0);
2152 
2153         _program = CreateProgram(Vsh<api>(), "", Fsh<api>(), true);
2154         if (!_program)
2155         {
2156             return ERROR;
2157         }
2158         glUseProgram(_program);
2159 
2160         glGenBuffers(1, &_vbo);
2161         glBindBuffer(GL_ARRAY_BUFFER, _vbo);
2162         glBufferData(GL_ARRAY_BUFFER,
2163                      (GLsizeiptr)(coords.size() * sizeof(coords[0]) +
2164                                   coords_instanced.size() * sizeof(coords_instanced[0]) +
2165                                   colors_instanced.size() * sizeof(colors_instanced[0])),
2166                      NULL, GL_STATIC_DRAW);
2167 
2168         const size_t coords_offset           = 0;
2169         const size_t coords_instanced_offset = coords_offset + coords.size() * sizeof(coords[0]);
2170         const size_t colors_instanced_offset =
2171             coords_instanced_offset + coords_instanced.size() * sizeof(coords_instanced[0]);
2172 
2173         glBufferSubData(GL_ARRAY_BUFFER, coords_offset, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0]);
2174         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)coords_instanced_offset,
2175                         (GLsizeiptr)(coords_instanced.size() * sizeof(coords_instanced[0])), &coords_instanced[0]);
2176         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)colors_instanced_offset,
2177                         (GLsizeiptr)(colors_instanced.size() * sizeof(colors_instanced[0])), &colors_instanced[0]);
2178 
2179         glGenVertexArrays(1, &_vao);
2180         glBindVertexArray(_vao);
2181 
2182         //i_vertex (coords)
2183         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(coords_offset));
2184         glEnableVertexAttribArray(0);
2185 
2186         //i_vertex_instanced (coords_instanced)
2187         glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(coords_instanced_offset));
2188         glEnableVertexAttribArray(1);
2189         glVertexAttribDivisor(1, 1);
2190 
2191         //i_vertex_color_instanced (color_instanced)
2192         glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(colors_instanced_offset));
2193         glEnableVertexAttribArray(2);
2194         glVertexAttribDivisor(2, 3);
2195 
2196         DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
2197         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
2198 
2199         CElementArray elements(coords.size(), 0);
2200         for (size_t i = 0; i < elements.size(); ++i)
2201         {
2202             elements[i] = static_cast<GLuint>(i);
2203         }
2204 
2205         switch (_drawFunc)
2206         {
2207         case DRAW_ARRAYS:
2208         {
2209             indirectArrays.count              = static_cast<GLuint>(coords.size());
2210             indirectArrays.primCount          = 4;
2211             indirectArrays.first              = 0;
2212             indirectArrays.reservedMustBeZero = 0;
2213 
2214             {
2215                 GLuint buffer;
2216                 glGenBuffers(1, &buffer);
2217                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
2218                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
2219                 glDrawArraysIndirect(GL_TRIANGLES, 0);
2220                 glDeleteBuffers(1, &buffer);
2221             }
2222         }
2223         break;
2224         case DRAW_ELEMENTS:
2225         {
2226             indirectElements.count              = static_cast<GLuint>(coords.size());
2227             indirectElements.primCount          = 4;
2228             indirectElements.firstIndex         = 0;
2229             indirectElements.baseVertex         = 0;
2230             indirectElements.reservedMustBeZero = 0;
2231 
2232             glGenBuffers(1, &_ebo);
2233             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
2234             glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
2235                          GL_STATIC_DRAW);
2236 
2237             {
2238                 GLuint buffer;
2239                 glGenBuffers(1, &buffer);
2240                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
2241                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
2242                 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
2243                 glDeleteBuffers(1, &buffer);
2244             }
2245         }
2246         break;
2247         default:
2248             throw std::runtime_error("Unknown draw function!");
2249             break;
2250         }
2251 
2252         CColorArray bufferRef1(getWindowWidth() / 2 * getWindowHeight() / 2, colors_instanced[0]);
2253         CColorArray bufferRef2(getWindowWidth() / 2 * getWindowHeight() / 2, colors_instanced[1]);
2254 
2255         CColorArray bufferTest(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f));
2256         DIResult result;
2257 
2258         ReadPixelsFloat<api>(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, &bufferTest[0]);
2259         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
2260                                          getWindowWidth() / 2, getWindowHeight() / 2));
2261 
2262         ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, 0, getWindowWidth() / 2, getWindowHeight() / 2,
2263                              &bufferTest[0]);
2264         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef2,
2265                                          getWindowWidth() / 2, getWindowHeight() / 2));
2266 
2267         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth() / 2, getWindowHeight() / 2,
2268                              &bufferTest[0]);
2269         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
2270                                          getWindowWidth() / 2, getWindowHeight() / 2));
2271 
2272         ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, (getWindowHeight() + 1) / 2, getWindowWidth() / 2,
2273                              getWindowHeight() / 2, &bufferTest[0]);
2274         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
2275                                          getWindowWidth() / 2, getWindowHeight() / 2));
2276 
2277         return result.code();
2278     }
2279 
Cleanup()2280     virtual long Cleanup()
2281     {
2282         glDisableVertexAttribArray(0);
2283         glBindBuffer(GL_ARRAY_BUFFER, 0);
2284         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2285         glBindVertexArray(0);
2286         glUseProgram(0);
2287 
2288         if (_vao)
2289         {
2290             glDeleteVertexArrays(1, &_vao);
2291         }
2292         if (_vbo)
2293         {
2294             glDeleteBuffers(1, &_vbo);
2295         }
2296         if (_ebo)
2297         {
2298             glDeleteBuffers(1, &_ebo);
2299         }
2300         if (_program)
2301         {
2302             glDeleteProgram(_program);
2303         }
2304 
2305         return NO_ERROR;
2306     }
2307 
2308     template <typename api>
Vsh()2309     std::string Vsh()
2310     {
2311         return api::glslVer() + NL
2312                "layout(location = 0) in vec4 i_vertex;" NL "layout(location = 1) in vec4 i_vertex_instanced;" NL
2313                "layout(location = 2) in vec4 i_vertex_color_instanced;" NL "out vec4 vertex_color_instanced;" NL
2314                "void main()" NL "{" NL "    gl_Position = vec4(i_vertex.xyz * .5, 1.0) + i_vertex_instanced;" NL
2315                "    vertex_color_instanced = i_vertex_color_instanced;" NL "}";
2316     }
2317 
2318     template <typename api>
Fsh()2319     std::string Fsh()
2320     {
2321         return api::glslVer() + NL "precision highp float; " NL "in  vec4 vertex_color_instanced;" NL
2322                                    "out vec4 outColor;" NL "void main() {" NL "  outColor = vertex_color_instanced;" NL
2323                                    "}";
2324     }
2325 
CBasicVertexInstancingDef(TDrawFunction drawFunc)2326     CBasicVertexInstancingDef(TDrawFunction drawFunc)
2327         : _drawFunc(drawFunc)
2328         , _drawSizeX(2)
2329         , _drawSizeY(2)
2330         , _vao(0)
2331         , _vbo(0)
2332         , _ebo(0)
2333         , _program(0)
2334     {
2335     }
2336 
2337 private:
2338     TDrawFunction _drawFunc;
2339     unsigned int _drawSizeX;
2340     unsigned int _drawSizeY;
2341 
2342     GLuint _vao;
2343     GLuint _vbo, _ebo;
2344     GLuint _program;
2345 
CBasicVertexInstancingDef()2346     CBasicVertexInstancingDef()
2347     {
2348     }
2349 };
2350 
2351 template <typename api>
2352 class CVBODrawArraysSingle : public CBasicVertexDef
2353 {
2354 public:
Title()2355     virtual std::string Title()
2356     {
2357         return "VBO: Single primitive using glDrawArraysIndirect";
2358     }
2359 
Purpose()2360     virtual std::string Purpose()
2361     {
2362         return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect";
2363     }
2364 
Method()2365     virtual std::string Method()
2366     {
2367         return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
2368                "3. Verify results";
2369     }
2370 
PassCriteria()2371     virtual std::string PassCriteria()
2372     {
2373         return "The test will pass if no OpenGL errors reported";
2374     }
2375 
CVBODrawArraysSingle()2376     CVBODrawArraysSingle() : CBasicVertexDef(DRAW_ARRAYS, GL_TRIANGLES, 1, 1)
2377     {
2378     }
Run()2379     virtual long Run()
2380     {
2381         return CBasicVertexDef::Run<api>();
2382     }
2383 };
2384 
2385 template <typename api>
2386 class CVBODrawArraysMany : public CBasicVertexDef
2387 {
2388 public:
Title()2389     virtual std::string Title()
2390     {
2391         return "VBO: Many primitives using glDrawArraysIndirect";
2392     }
2393 
Purpose()2394     virtual std::string Purpose()
2395     {
2396         return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect";
2397     }
2398 
Method()2399     virtual std::string Method()
2400     {
2401         return "1. Define primitives using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
2402                "3. Verify results";
2403     }
2404 
PassCriteria()2405     virtual std::string PassCriteria()
2406     {
2407         return "The test will pass if no OpenGL errors reported";
2408     }
2409 
CVBODrawArraysMany()2410     CVBODrawArraysMany() : CBasicVertexDef(DRAW_ARRAYS, GL_TRIANGLES, 8, 8)
2411     {
2412     }
Run()2413     virtual long Run()
2414     {
2415         return CBasicVertexDef::Run<api>();
2416     }
2417 };
2418 
2419 template <typename api>
2420 class CVBODrawArraysInstancing : public CBasicVertexInstancingDef
2421 {
2422 public:
Title()2423     virtual std::string Title()
2424     {
2425         return "VBO: Single primitive using glDrawArraysIndirect, multiple instances";
2426     }
2427 
Purpose()2428     virtual std::string Purpose()
2429     {
2430         return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect";
2431     }
2432 
Method()2433     virtual std::string Method()
2434     {
2435         return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
2436                "3. Verify results";
2437     }
2438 
PassCriteria()2439     virtual std::string PassCriteria()
2440     {
2441         return "The test will pass if no OpenGL errors reported";
2442     }
2443 
CVBODrawArraysInstancing()2444     CVBODrawArraysInstancing() : CBasicVertexInstancingDef(DRAW_ARRAYS)
2445     {
2446     }
Run()2447     virtual long Run()
2448     {
2449         return CBasicVertexInstancingDef::Run<api>();
2450     }
2451 };
2452 
2453 class CBasicXFBPausedDef : public DrawIndirectBase
2454 {
2455 public:
Setup()2456     virtual long Setup()
2457     {
2458         glClear(GL_COLOR_BUFFER_BIT);
2459         return NO_ERROR;
2460     }
2461 
2462     template <typename api>
Run()2463     long Run()
2464     {
2465         CColorArray coords;
2466         PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords);
2467 
2468         _program = CreateProgram(Vsh<api>(), "", shaders::fshSimple<api>(), false);
2469 
2470         const GLchar *varyings[] = {"dataOut"};
2471         glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS);
2472         glLinkProgram(_program);
2473         if (!CheckProgram(_program))
2474         {
2475             return ERROR;
2476         }
2477         glUseProgram(_program);
2478 
2479         glGenBuffers(1, &_vbo);
2480         glBindBuffer(GL_ARRAY_BUFFER, _vbo);
2481         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW);
2482 
2483         glGenVertexArrays(1, &_vao);
2484         glBindVertexArray(_vao);
2485         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
2486         glEnableVertexAttribArray(0);
2487 
2488         DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
2489         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
2490 
2491         CElementArray elements(coords.size(), 0);
2492         for (size_t i = 0; i < elements.size(); ++i)
2493         {
2494             elements[i] = static_cast<GLuint>(i);
2495         }
2496 
2497         glGenTransformFeedbacks(1, &_xfo);
2498         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, _xfo);
2499 
2500         glGenBuffers(1, &_xfbo);
2501         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _xfbo);
2502         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, NULL, GL_STATIC_DRAW);
2503         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfbo);
2504 
2505         glBeginTransformFeedback(GL_TRIANGLES);
2506         glPauseTransformFeedback();
2507 
2508         switch (_drawFunc)
2509         {
2510         case DRAW_ARRAYS:
2511         {
2512             indirectArrays.count              = static_cast<GLuint>(coords.size());
2513             indirectArrays.primCount          = 1;
2514             indirectArrays.first              = 0;
2515             indirectArrays.reservedMustBeZero = 0;
2516 
2517             {
2518                 GLuint buffer;
2519                 glGenBuffers(1, &buffer);
2520                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
2521                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
2522                 glDrawArraysIndirect(GL_TRIANGLES, 0);
2523                 glDeleteBuffers(1, &buffer);
2524             }
2525         }
2526         break;
2527         case DRAW_ELEMENTS:
2528         {
2529             indirectElements.count              = static_cast<GLuint>(coords.size());
2530             indirectElements.primCount          = 1;
2531             indirectElements.firstIndex         = 0;
2532             indirectElements.baseVertex         = 0;
2533             indirectElements.reservedMustBeZero = 0;
2534 
2535             glGenBuffers(1, &_ebo);
2536             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
2537             glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
2538                          GL_STATIC_DRAW);
2539 
2540             {
2541                 GLuint buffer;
2542                 glGenBuffers(1, &buffer);
2543                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
2544                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
2545                 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
2546                 glDeleteBuffers(1, &buffer);
2547             }
2548         }
2549 
2550         break;
2551         default:
2552             throw std::runtime_error("Unknown draw function!");
2553             break;
2554         }
2555 
2556         glResumeTransformFeedback();
2557         glEndTransformFeedback();
2558 
2559         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
2560         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
2561         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
2562 
2563         DIResult result;
2564         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
2565                                          getWindowHeight()));
2566 
2567         return result.code();
2568     }
2569 
Cleanup()2570     virtual long Cleanup()
2571     {
2572         glDisableVertexAttribArray(0);
2573         glBindBuffer(GL_ARRAY_BUFFER, 0);
2574         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2575         glBindVertexArray(0);
2576         glUseProgram(0);
2577 
2578         if (_vao)
2579         {
2580             glDeleteVertexArrays(1, &_vao);
2581         }
2582         if (_vbo)
2583         {
2584             glDeleteBuffers(1, &_vbo);
2585         }
2586         if (_ebo)
2587         {
2588             glDeleteBuffers(1, &_ebo);
2589         }
2590         if (_xfbo)
2591         {
2592             glDeleteBuffers(1, &_xfbo);
2593         }
2594         if (_program)
2595         {
2596             glDeleteProgram(_program);
2597         }
2598         if (_xfo)
2599         {
2600             glDeleteTransformFeedbacks(1, &_xfo);
2601         }
2602 
2603         return NO_ERROR;
2604     }
2605 
2606     template <typename api>
Vsh()2607     std::string Vsh()
2608     {
2609         return api::glslVer() + NL "in vec4 i_vertex;" NL "out vec4 dataOut;" NL "void main()" NL "{" NL
2610                                    "    gl_Position = i_vertex;" NL "    dataOut = i_vertex;" NL "}";
2611     }
2612 
CBasicXFBPausedDef(TDrawFunction drawFunc)2613     CBasicXFBPausedDef(TDrawFunction drawFunc)
2614         : _drawFunc(drawFunc)
2615         , _drawSizeX(2)
2616         , _drawSizeY(2)
2617         , _vao(0)
2618         , _vbo(0)
2619         , _ebo(0)
2620         , _xfbo(0)
2621         , _program(0)
2622         , _xfo(0)
2623     {
2624     }
2625 
2626 private:
2627     TDrawFunction _drawFunc;
2628     unsigned int _drawSizeX;
2629     unsigned int _drawSizeY;
2630 
2631     GLuint _vao;
2632     GLuint _vbo, _ebo, _xfbo;
2633     GLuint _program;
2634     GLuint _xfo;
2635 
CBasicXFBPausedDef()2636     CBasicXFBPausedDef()
2637     {
2638     }
2639 };
2640 
2641 template <typename api>
2642 class CVBODrawArraysXFBPaused : public CBasicXFBPausedDef
2643 {
2644 public:
Title()2645     virtual std::string Title()
2646     {
2647         return "VBO: glDrawArraysIndirect, in paused transform feedback operation";
2648     }
2649 
Purpose()2650     virtual std::string Purpose()
2651     {
2652         return "Verify  glDrawArraysIndirect works, if XFB is active and paused";
2653     }
2654 
Method()2655     virtual std::string Method()
2656     {
2657         return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
2658                "3. Verify results";
2659     }
2660 
PassCriteria()2661     virtual std::string PassCriteria()
2662     {
2663         return "The test will pass if no OpenGL errors reported";
2664     }
2665 
CVBODrawArraysXFBPaused()2666     CVBODrawArraysXFBPaused() : CBasicXFBPausedDef(DRAW_ARRAYS)
2667     {
2668     }
Run()2669     virtual long Run()
2670     {
2671         return CBasicXFBPausedDef::Run<api>();
2672     }
2673 };
2674 
2675 template <typename api>
2676 class CVBODrawElementsSingle : public CBasicVertexDef
2677 {
2678 public:
Title()2679     virtual std::string Title()
2680     {
2681         return "VBO: Single primitive using glDrawElementsIndirect";
2682     }
2683 
Purpose()2684     virtual std::string Purpose()
2685     {
2686         return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect";
2687     }
2688 
Method()2689     virtual std::string Method()
2690     {
2691         return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL
2692                "3. Verify results";
2693     }
2694 
PassCriteria()2695     virtual std::string PassCriteria()
2696     {
2697         return "The test will pass if no OpenGL errors reported";
2698     }
2699 
CVBODrawElementsSingle()2700     CVBODrawElementsSingle() : CBasicVertexDef(DRAW_ELEMENTS, GL_TRIANGLES, 1, 1)
2701     {
2702     }
Run()2703     virtual long Run()
2704     {
2705         return CBasicVertexDef::Run<api>();
2706     }
2707 };
2708 
2709 template <typename api>
2710 class CVBODrawElementsMany : public CBasicVertexDef
2711 {
2712 public:
Title()2713     virtual std::string Title()
2714     {
2715         return "VBO: Many primitives using glDrawElementsIndirect";
2716     }
2717 
Purpose()2718     virtual std::string Purpose()
2719     {
2720         return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect";
2721     }
2722 
Method()2723     virtual std::string Method()
2724     {
2725         return "1. Define primitives using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL
2726                "3. Verify results";
2727     }
2728 
PassCriteria()2729     virtual std::string PassCriteria()
2730     {
2731         return "The test will pass if no OpenGL errors reported";
2732     }
2733 
CVBODrawElementsMany()2734     CVBODrawElementsMany() : CBasicVertexDef(DRAW_ELEMENTS, GL_TRIANGLES, 8, 8)
2735     {
2736     }
2737 
Run()2738     virtual long Run()
2739     {
2740         return CBasicVertexDef::Run<api>();
2741     }
2742 };
2743 
2744 template <typename api>
2745 class CVBODrawElementsInstancing : public CBasicVertexInstancingDef
2746 {
2747 public:
Title()2748     virtual std::string Title()
2749     {
2750         return "VBO: Single primitive using glDrawElementsIndirect, multiple instances";
2751     }
2752 
Purpose()2753     virtual std::string Purpose()
2754     {
2755         return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect";
2756     }
2757 
Method()2758     virtual std::string Method()
2759     {
2760         return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL
2761                "3. Verify results";
2762     }
2763 
PassCriteria()2764     virtual std::string PassCriteria()
2765     {
2766         return "The test will pass if no OpenGL errors reported";
2767     }
2768 
CVBODrawElementsInstancing()2769     CVBODrawElementsInstancing() : CBasicVertexInstancingDef(DRAW_ELEMENTS)
2770     {
2771     }
Run()2772     virtual long Run()
2773     {
2774         return CBasicVertexInstancingDef::Run<api>();
2775     }
2776 };
2777 
2778 template <typename api>
2779 class CVBODrawElementsXFBPaused : public CBasicXFBPausedDef
2780 {
2781 public:
Title()2782     virtual std::string Title()
2783     {
2784         return "VBO: glDrawElementsIndirect, in paused transform feedback operation";
2785     }
2786 
Purpose()2787     virtual std::string Purpose()
2788     {
2789         return "Verify  glDrawElementsIndirect works, if XFB is active and paused";
2790     }
2791 
Method()2792     virtual std::string Method()
2793     {
2794         return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
2795                "3. Verify results";
2796     }
2797 
PassCriteria()2798     virtual std::string PassCriteria()
2799     {
2800         return "The test will pass if no OpenGL errors reported";
2801     }
2802 
CVBODrawElementsXFBPaused()2803     CVBODrawElementsXFBPaused() : CBasicXFBPausedDef(DRAW_ELEMENTS)
2804     {
2805     }
Run()2806     virtual long Run()
2807     {
2808         return CBasicXFBPausedDef::Run<api>();
2809     }
2810 };
2811 
2812 template <typename api>
2813 class CBufferIndirectDrawArraysSimple : public DrawIndirectBase
2814 {
2815 public:
Title()2816     virtual std::string Title()
2817     {
2818         return "Indirect buffer glDrawArraysIndirect: many primitives simple";
2819     }
2820 
Purpose()2821     virtual std::string Purpose()
2822     {
2823         return "Verify that it is possible to draw primitives with specified indirect structure" NL "in a buffer";
2824     }
2825 
Method()2826     virtual std::string Method()
2827     {
2828         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
2829                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
2830     }
2831 
PassCriteria()2832     virtual std::string PassCriteria()
2833     {
2834         return "The test will pass if no OpenGL errors reported";
2835     }
2836 
Setup()2837     virtual long Setup()
2838     {
2839         glClear(GL_COLOR_BUFFER_BIT);
2840         return NO_ERROR;
2841     }
2842 
Run()2843     virtual long Run()
2844     {
2845         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
2846         if (!_program)
2847         {
2848             return ERROR;
2849         }
2850         glUseProgram(_program);
2851 
2852         CColorArray coords;
2853         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
2854 
2855         glGenVertexArrays(1, &_vao);
2856         glBindVertexArray(_vao);
2857 
2858         glGenBuffers(1, &_buffer);
2859         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
2860 
2861         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
2862         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
2863         glEnableVertexAttribArray(0);
2864 
2865         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
2866         indirectArrays.count                     = static_cast<GLuint>(coords.size());
2867         indirectArrays.primCount                 = 1;
2868         indirectArrays.first                     = 0;
2869         indirectArrays.reservedMustBeZero        = 0;
2870 
2871         glGenBuffers(1, &_bufferIndirect);
2872         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
2873         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
2874 
2875         glDrawArraysIndirect(GL_TRIANGLES, 0);
2876 
2877         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
2878         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
2879 
2880         DIResult result;
2881         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
2882         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
2883                                          getWindowHeight()));
2884 
2885         return result.code();
2886     }
2887 
Cleanup()2888     virtual long Cleanup()
2889     {
2890         glDisableVertexAttribArray(0);
2891         glUseProgram(0);
2892         glDeleteProgram(_program);
2893         glDeleteVertexArrays(1, &_vao);
2894         glDeleteBuffers(1, &_buffer);
2895         glDeleteBuffers(1, &_bufferIndirect);
2896         return NO_ERROR;
2897     }
2898 
2899 private:
2900     GLuint _program;
2901     GLuint _vao, _buffer, _bufferIndirect;
2902 };
2903 
2904 template <typename api>
2905 class CBufferIndirectDrawArraysNoFirst : public DrawIndirectBase
2906 {
2907 public:
Title()2908     virtual std::string Title()
2909     {
2910         return "Indirect buffer glDrawArraysIndirect: non-zero 'first' argument";
2911     }
2912 
Purpose()2913     virtual std::string Purpose()
2914     {
2915         return "Verify that it is possible to draw primitives with specified non-zero 'first' argument" NL
2916                "in indirect buffer";
2917     }
2918 
Method()2919     virtual std::string Method()
2920     {
2921         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
2922                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
2923     }
2924 
PassCriteria()2925     virtual std::string PassCriteria()
2926     {
2927         return "The test will pass if no OpenGL errors reported";
2928     }
2929 
Setup()2930     virtual long Setup()
2931     {
2932         glClear(GL_COLOR_BUFFER_BIT);
2933         return NO_ERROR;
2934     }
2935 
Run()2936     virtual long Run()
2937     {
2938         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
2939         if (!_program)
2940         {
2941             return ERROR;
2942         }
2943         glUseProgram(_program);
2944 
2945         CColorArray coords;
2946         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
2947 
2948         glGenVertexArrays(1, &_vao);
2949         glBindVertexArray(_vao);
2950 
2951         glGenBuffers(1, &_buffer);
2952         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
2953 
2954         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
2955         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
2956         glEnableVertexAttribArray(0);
2957 
2958         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
2959         indirectArrays.count                     = static_cast<GLuint>(coords.size()) / 2;
2960         indirectArrays.primCount                 = 1;
2961         indirectArrays.first                     = static_cast<GLuint>(coords.size()) / 2;
2962         indirectArrays.reservedMustBeZero        = 0;
2963 
2964         glGenBuffers(1, &_bufferIndirect);
2965         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
2966         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
2967 
2968         glDrawArraysIndirect(GL_TRIANGLES, 0);
2969 
2970         CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
2971         CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
2972         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
2973 
2974         DIResult result;
2975         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
2976         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
2977                                          getWindowWidth(), getWindowHeight() / 2));
2978 
2979         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
2980         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
2981                                          getWindowWidth(), getWindowHeight() / 2));
2982 
2983         return result.code();
2984     }
2985 
Cleanup()2986     virtual long Cleanup()
2987     {
2988         glDisableVertexAttribArray(0);
2989         glUseProgram(0);
2990         glDeleteProgram(_program);
2991         glDeleteVertexArrays(1, &_vao);
2992         glDeleteBuffers(1, &_buffer);
2993         glDeleteBuffers(1, &_bufferIndirect);
2994         return NO_ERROR;
2995     }
2996 
2997 private:
2998     GLuint _program;
2999     GLuint _vao, _buffer, _bufferIndirect;
3000 };
3001 
3002 template <typename api>
3003 class CBufferIndirectDrawArraysOffset : public DrawIndirectBase
3004 {
3005 public:
Title()3006     virtual std::string Title()
3007     {
3008         return "Indirect buffer glDrawArraysIndirect: offset as a function parameter";
3009     }
3010 
Purpose()3011     virtual std::string Purpose()
3012     {
3013         return "Verify that it is possible to draw primitives with offset as a function parameter";
3014     }
3015 
Method()3016     virtual std::string Method()
3017     {
3018         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3019                "3. Draw primitives using glDrawArraysIndirect with offset" NL "4. Verify results";
3020     }
3021 
PassCriteria()3022     virtual std::string PassCriteria()
3023     {
3024         return "The test will pass if no OpenGL errors reported";
3025     }
3026 
Setup()3027     virtual long Setup()
3028     {
3029         glClear(GL_COLOR_BUFFER_BIT);
3030         return NO_ERROR;
3031     }
3032 
Run()3033     virtual long Run()
3034     {
3035         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3036         if (!_program)
3037         {
3038             return ERROR;
3039         }
3040         glUseProgram(_program);
3041 
3042         CColorArray coords;
3043         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
3044 
3045         glGenVertexArrays(1, &_vao);
3046         glBindVertexArray(_vao);
3047 
3048         glGenBuffers(1, &_buffer);
3049         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3050 
3051         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3052         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
3053         glEnableVertexAttribArray(0);
3054 
3055         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
3056         indirectArrays.count                     = static_cast<GLuint>(coords.size());
3057         indirectArrays.primCount                 = 1;
3058         indirectArrays.first                     = 0;
3059         indirectArrays.reservedMustBeZero        = 0;
3060 
3061         glGenBuffers(1, &_bufferIndirect);
3062         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
3063         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand) * 3, NULL, GL_STATIC_DRAW);
3064         glBufferSubData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), sizeof(DrawArraysIndirectCommand),
3065                         &indirectArrays);
3066         glDrawArraysIndirect(GL_TRIANGLES, (void *)sizeof(DrawArraysIndirectCommand));
3067 
3068         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
3069         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
3070 
3071         DIResult result;
3072         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
3073         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
3074                                          getWindowHeight()));
3075 
3076         return result.code();
3077     }
3078 
Cleanup()3079     virtual long Cleanup()
3080     {
3081         glDisableVertexAttribArray(0);
3082         glUseProgram(0);
3083         glDeleteProgram(_program);
3084         glDeleteVertexArrays(1, &_vao);
3085         glDeleteBuffers(1, &_buffer);
3086         glDeleteBuffers(1, &_bufferIndirect);
3087         return NO_ERROR;
3088     }
3089 
3090 private:
3091     GLuint _program;
3092     GLuint _vao, _buffer, _bufferIndirect;
3093 };
3094 
3095 template <typename api>
3096 class CBufferIndirectDrawElementsSimple : public DrawIndirectBase
3097 {
3098 public:
Title()3099     virtual std::string Title()
3100     {
3101         return "Indirect buffer glDrawElementsIndirect: many primitives simple";
3102     }
3103 
Purpose()3104     virtual std::string Purpose()
3105     {
3106         return "Verify that it is possible to draw primitives with specified indirect structure" NL "in a buffer";
3107     }
3108 
Method()3109     virtual std::string Method()
3110     {
3111         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3112                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
3113     }
3114 
PassCriteria()3115     virtual std::string PassCriteria()
3116     {
3117         return "The test will pass if no OpenGL errors reported";
3118     }
3119 
Setup()3120     virtual long Setup()
3121     {
3122         glClear(GL_COLOR_BUFFER_BIT);
3123         return NO_ERROR;
3124     }
3125 
Run()3126     virtual long Run()
3127     {
3128         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3129         if (!_program)
3130         {
3131             return ERROR;
3132         }
3133         glUseProgram(_program);
3134 
3135         CColorArray coords;
3136         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
3137 
3138         glGenVertexArrays(1, &_vao);
3139         glBindVertexArray(_vao);
3140 
3141         glGenBuffers(1, &_buffer);
3142         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3143 
3144         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3145         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
3146         glEnableVertexAttribArray(0);
3147 
3148         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
3149         indirectElements.count                       = static_cast<GLuint>(coords.size());
3150         indirectElements.primCount                   = 1;
3151         indirectElements.baseVertex                  = 0;
3152         indirectElements.firstIndex                  = 0;
3153         indirectElements.reservedMustBeZero          = 0;
3154 
3155         CElementArray elements(coords.size(), 0);
3156         for (size_t i = 0; i < elements.size(); ++i)
3157         {
3158             elements[i] = static_cast<GLuint>(i);
3159         }
3160 
3161         glGenBuffers(1, &_bufferIndirect);
3162         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
3163         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
3164 
3165         glGenBuffers(1, &_ebo);
3166         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
3167         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
3168                      GL_STATIC_DRAW);
3169 
3170         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
3171 
3172         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
3173         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
3174 
3175         DIResult result;
3176         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
3177         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
3178                                          getWindowHeight()));
3179 
3180         return result.code();
3181     }
3182 
Cleanup()3183     virtual long Cleanup()
3184     {
3185         glDisableVertexAttribArray(0);
3186         glUseProgram(0);
3187         glDeleteProgram(_program);
3188         glDeleteVertexArrays(1, &_vao);
3189         glDeleteBuffers(1, &_buffer);
3190         glDeleteBuffers(1, &_bufferIndirect);
3191         glDeleteBuffers(1, &_ebo);
3192         return NO_ERROR;
3193     }
3194 
3195 private:
3196     GLuint _program;
3197     GLuint _vao, _buffer, _bufferIndirect, _ebo;
3198 };
3199 
3200 template <typename api>
3201 class CBufferIndirectDrawElementsNoFirstIndex : public DrawIndirectBase
3202 {
3203 public:
Title()3204     virtual std::string Title()
3205     {
3206         return "Indirect buffer glDrawElementsIndirect: non-zero first index";
3207     }
3208 
Purpose()3209     virtual std::string Purpose()
3210     {
3211         return "Verify that it is possible to draw primitives with non-zero first index" NL "in indirect buffer";
3212     }
3213 
Method()3214     virtual std::string Method()
3215     {
3216         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3217                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
3218     }
3219 
PassCriteria()3220     virtual std::string PassCriteria()
3221     {
3222         return "The test will pass if no OpenGL errors reported";
3223     }
3224 
Setup()3225     virtual long Setup()
3226     {
3227         glClear(GL_COLOR_BUFFER_BIT);
3228         return NO_ERROR;
3229     }
3230 
Run()3231     virtual long Run()
3232     {
3233         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3234         if (!_program)
3235         {
3236             return ERROR;
3237         }
3238         glUseProgram(_program);
3239 
3240         CColorArray coords;
3241         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
3242 
3243         glGenVertexArrays(1, &_vao);
3244         glBindVertexArray(_vao);
3245 
3246         glGenBuffers(1, &_buffer);
3247         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3248 
3249         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3250         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
3251         glEnableVertexAttribArray(0);
3252 
3253         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
3254         indirectElements.count                       = static_cast<GLuint>(coords.size()) / 2;
3255         indirectElements.primCount                   = 1;
3256         indirectElements.baseVertex                  = 0;
3257         indirectElements.firstIndex                  = static_cast<GLuint>(coords.size()) / 2;
3258         indirectElements.reservedMustBeZero          = 0;
3259 
3260         CElementArray elements(coords.size(), 0);
3261         for (size_t i = 0; i < elements.size(); ++i)
3262         {
3263             elements[i] = static_cast<GLuint>(i);
3264         }
3265 
3266         glGenBuffers(1, &_bufferIndirect);
3267         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
3268         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
3269 
3270         glGenBuffers(1, &_ebo);
3271         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
3272         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
3273                      GL_STATIC_DRAW);
3274 
3275         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
3276 
3277         CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
3278         CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
3279         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
3280 
3281         DIResult result;
3282         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
3283         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
3284                                          getWindowWidth(), getWindowHeight() / 2));
3285 
3286         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
3287         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
3288                                          getWindowWidth(), getWindowHeight() / 2));
3289 
3290         return result.code();
3291     }
3292 
Cleanup()3293     virtual long Cleanup()
3294     {
3295         glDisableVertexAttribArray(0);
3296         glUseProgram(0);
3297         glDeleteProgram(_program);
3298         glDeleteVertexArrays(1, &_vao);
3299         glDeleteBuffers(1, &_buffer);
3300         glDeleteBuffers(1, &_ebo);
3301         glDeleteBuffers(1, &_bufferIndirect);
3302         return NO_ERROR;
3303     }
3304 
3305 private:
3306     GLuint _program;
3307     GLuint _vao, _buffer, _bufferIndirect, _ebo;
3308 };
3309 
3310 template <typename api>
3311 class CBufferIndirectDrawElementsNoBasevertex : public DrawIndirectBase
3312 {
3313 public:
Title()3314     virtual std::string Title()
3315     {
3316         return "Indirect buffer glDrawElementsIndirect: non-zero base vertex";
3317     }
3318 
Purpose()3319     virtual std::string Purpose()
3320     {
3321         return "Verify that it is possible to draw primitives with non-zero base vertex" NL "in indirect buffer";
3322     }
3323 
Method()3324     virtual std::string Method()
3325     {
3326         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3327                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
3328     }
3329 
PassCriteria()3330     virtual std::string PassCriteria()
3331     {
3332         return "The test will pass if no OpenGL errors reported";
3333     }
3334 
Setup()3335     virtual long Setup()
3336     {
3337         glClear(GL_COLOR_BUFFER_BIT);
3338         return NO_ERROR;
3339     }
3340 
Run()3341     virtual long Run()
3342     {
3343         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3344         if (!_program)
3345         {
3346             return ERROR;
3347         }
3348         glUseProgram(_program);
3349 
3350         CColorArray coords;
3351         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
3352 
3353         glGenVertexArrays(1, &_vao);
3354         glBindVertexArray(_vao);
3355 
3356         glGenBuffers(1, &_buffer);
3357         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3358 
3359         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3360         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
3361         glEnableVertexAttribArray(0);
3362 
3363         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
3364         indirectElements.count                       = static_cast<GLuint>(coords.size()) / 2;
3365         indirectElements.primCount                   = 1;
3366         indirectElements.baseVertex                  = static_cast<GLint>(coords.size()) / 2;
3367         indirectElements.firstIndex                  = 0;
3368         indirectElements.reservedMustBeZero          = 0;
3369 
3370         CElementArray elements(coords.size(), 0);
3371         for (size_t i = 0; i < elements.size(); ++i)
3372         {
3373             elements[i] = static_cast<GLuint>(i);
3374         }
3375 
3376         glGenBuffers(1, &_bufferIndirect);
3377         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
3378         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
3379 
3380         glGenBuffers(1, &_ebo);
3381         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
3382         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
3383                      GL_STATIC_DRAW);
3384 
3385         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
3386 
3387         CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
3388         CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
3389         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
3390 
3391         DIResult result;
3392         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
3393         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
3394                                          getWindowWidth(), getWindowHeight() / 2));
3395 
3396         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
3397         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
3398                                          getWindowWidth(), getWindowHeight() / 2));
3399 
3400         return result.code();
3401     }
3402 
Cleanup()3403     virtual long Cleanup()
3404     {
3405         glDisableVertexAttribArray(0);
3406         glUseProgram(0);
3407         glDeleteProgram(_program);
3408         glDeleteVertexArrays(1, &_vao);
3409         glDeleteBuffers(1, &_buffer);
3410         glDeleteBuffers(1, &_ebo);
3411         glDeleteBuffers(1, &_bufferIndirect);
3412         return NO_ERROR;
3413     }
3414 
3415 private:
3416     GLuint _program;
3417     GLuint _vao, _buffer, _ebo, _bufferIndirect;
3418 };
3419 
3420 template <typename api>
3421 class CBufferIndirectDrawElementsOffset : public DrawIndirectBase
3422 {
3423 public:
Title()3424     virtual std::string Title()
3425     {
3426         return "Indirect buffer glDrawElementsIndirect: offset as a function parameter";
3427     }
3428 
Purpose()3429     virtual std::string Purpose()
3430     {
3431         return "Verify that it is possible to draw primitives with offset as a function parameter";
3432     }
3433 
Method()3434     virtual std::string Method()
3435     {
3436         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3437                "3. Draw primitives using glDrawElementsIndirect with offset" NL "4. Verify results";
3438     }
3439 
PassCriteria()3440     virtual std::string PassCriteria()
3441     {
3442         return "The test will pass if no OpenGL errors reported";
3443     }
3444 
Setup()3445     virtual long Setup()
3446     {
3447         glClear(GL_COLOR_BUFFER_BIT);
3448         return NO_ERROR;
3449     }
3450 
Run()3451     virtual long Run()
3452     {
3453         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3454         if (!_program)
3455         {
3456             return ERROR;
3457         }
3458         glUseProgram(_program);
3459 
3460         CColorArray coords;
3461         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
3462 
3463         glGenVertexArrays(1, &_vao);
3464         glBindVertexArray(_vao);
3465 
3466         glGenBuffers(1, &_buffer);
3467         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3468 
3469         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3470         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
3471         glEnableVertexAttribArray(0);
3472 
3473         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
3474         indirectElements.count                       = static_cast<GLuint>(coords.size());
3475         indirectElements.primCount                   = 1;
3476         indirectElements.baseVertex                  = 0;
3477         indirectElements.firstIndex                  = 0;
3478         indirectElements.reservedMustBeZero          = 0;
3479 
3480         CElementArray elements(coords.size(), 0);
3481         for (size_t i = 0; i < elements.size(); ++i)
3482         {
3483             elements[i] = static_cast<GLuint>(i);
3484         }
3485 
3486         glGenBuffers(1, &_bufferIndirect);
3487         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
3488         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand) * 3, NULL, GL_STATIC_DRAW);
3489         glBufferSubData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand),
3490                         sizeof(DrawElementsIndirectCommand), &indirectElements);
3491 
3492         glGenBuffers(1, &_ebo);
3493         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
3494         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
3495                      GL_STATIC_DRAW);
3496         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void *)sizeof(DrawElementsIndirectCommand));
3497 
3498         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
3499         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
3500 
3501         DIResult result;
3502         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
3503         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
3504                                          getWindowHeight()));
3505 
3506         return result.code();
3507     }
3508 
Cleanup()3509     virtual long Cleanup()
3510     {
3511         glDisableVertexAttribArray(0);
3512         glUseProgram(0);
3513         glDeleteProgram(_program);
3514         glDeleteVertexArrays(1, &_vao);
3515         glDeleteBuffers(1, &_buffer);
3516         glDeleteBuffers(1, &_ebo);
3517         glDeleteBuffers(1, &_bufferIndirect);
3518         return NO_ERROR;
3519     }
3520 
3521 private:
3522     GLuint _program;
3523     GLuint _vao, _buffer, _ebo, _bufferIndirect;
3524 };
3525 
3526 class CBasicVertexIDsDef : public DrawIndirectBase
3527 {
3528 public:
Setup()3529     virtual long Setup()
3530     {
3531         glClear(GL_COLOR_BUFFER_BIT);
3532         return NO_ERROR;
3533     }
3534 
3535     template <typename api>
Run()3536     long Run()
3537     {
3538         CColorArray coords;
3539         PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords);
3540 
3541         CColorArray coords_instanced(4);
3542         coords_instanced[0] = tcu::Vec4(0.5, 0.5, 0.0, 0.0);
3543         coords_instanced[1] = tcu::Vec4(-0.5, 0.5, 0.0, 0.0);
3544         coords_instanced[2] = tcu::Vec4(-0.5, -0.5, 0.0, 0.0);
3545         coords_instanced[3] = tcu::Vec4(0.5, -0.5, 0.0, 0.0);
3546 
3547         std::vector<glw::GLfloat> ref_VertexId(coords.size());
3548         for (size_t i = 0; i < ref_VertexId.size(); i++)
3549         {
3550             ref_VertexId[i] = glw::GLfloat(i);
3551         }
3552 
3553         std::vector<glw::GLfloat> ref_InstanceId(4);
3554         for (size_t i = 0; i < ref_InstanceId.size(); i++)
3555         {
3556             ref_InstanceId[i] = glw::GLfloat(i);
3557         }
3558 
3559         _program = CreateProgram(Vsh<api>(), "", Fsh<api>(), true);
3560         if (!_program)
3561         {
3562             return ERROR;
3563         }
3564         glUseProgram(_program);
3565 
3566         glGenBuffers(1, &_vbo);
3567         glBindBuffer(GL_ARRAY_BUFFER, _vbo);
3568         glBufferData(GL_ARRAY_BUFFER,
3569                      (GLsizeiptr)(coords.size() * sizeof(coords[0]) +
3570                                   coords_instanced.size() * sizeof(coords_instanced[0]) +
3571                                   ref_VertexId.size() * sizeof(ref_VertexId[0]) +
3572                                   ref_InstanceId.size() * sizeof(ref_InstanceId[0])),
3573                      NULL, GL_STATIC_DRAW);
3574 
3575         const size_t coords_offset           = 0;
3576         const size_t coords_instanced_offset = coords_offset + coords.size() * sizeof(coords[0]);
3577         const size_t ref_VertexId_offset =
3578             coords_instanced_offset + coords_instanced.size() * sizeof(coords_instanced[0]);
3579         const size_t ref_InstanceId_offset = ref_VertexId_offset + ref_VertexId.size() * sizeof(ref_VertexId[0]);
3580 
3581         glBufferSubData(GL_ARRAY_BUFFER, coords_offset, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0]);
3582         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)coords_instanced_offset,
3583                         (GLsizeiptr)(coords_instanced.size() * sizeof(coords_instanced[0])), &coords_instanced[0]);
3584         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)ref_VertexId_offset,
3585                         (GLsizeiptr)(ref_VertexId.size() * sizeof(ref_VertexId[0])), &ref_VertexId[0]);
3586         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)ref_InstanceId_offset,
3587                         (GLsizeiptr)(ref_InstanceId.size() * sizeof(ref_InstanceId[0])), &ref_InstanceId[0]);
3588 
3589         glGenVertexArrays(1, &_vao);
3590         glBindVertexArray(_vao);
3591 
3592         //i_vertex (coords)
3593         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(coords_offset));
3594         glEnableVertexAttribArray(0);
3595 
3596         //i_vertex_instanced (coords_instanced)
3597         glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(coords_instanced_offset));
3598         glEnableVertexAttribArray(1);
3599         glVertexAttribDivisor(1, 1);
3600 
3601         //i_ref_VertexId
3602         glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(ref_VertexId_offset));
3603         glEnableVertexAttribArray(2);
3604         //i_ref_InstanceId
3605         glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(ref_InstanceId_offset));
3606         glEnableVertexAttribArray(3);
3607         glVertexAttribDivisor(3, 1);
3608 
3609         DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
3610         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
3611 
3612         CElementArray elements(coords.size(), 0);
3613         for (size_t i = 0; i < elements.size(); ++i)
3614         {
3615             elements[i] = static_cast<GLuint>(i);
3616         }
3617 
3618         switch (_drawFunc)
3619         {
3620         case DRAW_ARRAYS:
3621         {
3622             indirectArrays.count              = static_cast<GLuint>(coords.size());
3623             indirectArrays.primCount          = 4;
3624             indirectArrays.first              = 0;
3625             indirectArrays.reservedMustBeZero = 0;
3626 
3627             {
3628                 GLuint buffer;
3629                 glGenBuffers(1, &buffer);
3630                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
3631                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
3632                 glDrawArraysIndirect(GL_TRIANGLES, 0);
3633                 glDeleteBuffers(1, &buffer);
3634             }
3635         }
3636         break;
3637         case DRAW_ELEMENTS:
3638         {
3639             indirectElements.count              = static_cast<GLuint>(coords.size());
3640             indirectElements.primCount          = 4;
3641             indirectElements.firstIndex         = 0;
3642             indirectElements.baseVertex         = 0;
3643             indirectElements.reservedMustBeZero = 0;
3644 
3645             glGenBuffers(1, &_ebo);
3646             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
3647             glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
3648                          GL_STATIC_DRAW);
3649 
3650             {
3651                 GLuint buffer;
3652                 glGenBuffers(1, &buffer);
3653                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
3654                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
3655                 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
3656                 glDeleteBuffers(1, &buffer);
3657             }
3658         }
3659         break;
3660         default:
3661             throw std::runtime_error("Unknown draw function!");
3662             break;
3663         }
3664 
3665         CColorArray bufferRef1(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.5f, 0.0f));
3666         CColorArray bufferRef2(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.75f, 0.0f));
3667         CColorArray bufferRef3(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.25f, 0.0f));
3668         CColorArray bufferRef4(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.0f, 0.0f));
3669 
3670         CColorArray bufferTest(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f));
3671         DIResult result;
3672 
3673         ReadPixelsFloat<api>(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, &bufferTest[0]);
3674         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
3675                                          getWindowWidth() / 2, getWindowHeight() / 2));
3676 
3677         ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, 0, getWindowWidth() / 2, getWindowHeight() / 2,
3678                              &bufferTest[0]);
3679         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef2,
3680                                          getWindowWidth() / 2, getWindowHeight() / 2));
3681 
3682         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth() / 2, getWindowHeight() / 2,
3683                              &bufferTest[0]);
3684         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef3,
3685                                          getWindowWidth() / 2, getWindowHeight() / 2));
3686 
3687         ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, (getWindowHeight() + 1) / 2, getWindowWidth() / 2,
3688                              getWindowHeight() / 2, &bufferTest[0]);
3689         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef4,
3690                                          getWindowWidth() / 2, getWindowHeight() / 2));
3691 
3692         return result.code();
3693     }
3694 
Cleanup()3695     virtual long Cleanup()
3696     {
3697         glDisableVertexAttribArray(0);
3698         glBindBuffer(GL_ARRAY_BUFFER, 0);
3699         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3700         glBindVertexArray(0);
3701         glUseProgram(0);
3702 
3703         if (_vao)
3704         {
3705             glDeleteVertexArrays(1, &_vao);
3706         }
3707         if (_vbo)
3708         {
3709             glDeleteBuffers(1, &_vbo);
3710         }
3711         if (_ebo)
3712         {
3713             glDeleteBuffers(1, &_ebo);
3714         }
3715         if (_program)
3716         {
3717             glDeleteProgram(_program);
3718         }
3719 
3720         return NO_ERROR;
3721     }
3722 
3723     template <typename api>
Vsh()3724     std::string Vsh()
3725     {
3726         return api::glslVer() + NL
3727                "layout(location = 0) in vec4 i_vertex;" NL "layout(location = 1) in vec4 i_vertex_instanced;" NL
3728                "layout(location = 2) in float i_ref_VertexId;" NL "layout(location = 3) in float i_ref_InstanceId;" NL
3729                "out vec4 val_Result;" NL "void main()" NL "{" NL
3730                "    gl_Position = vec4(i_vertex.xyz * .5, 1.0) + i_vertex_instanced;" NL
3731                "    if ( gl_VertexID == int(i_ref_VertexId + .5) && gl_InstanceID == int(i_ref_InstanceId + .5)) {" NL
3732                "        val_Result = vec4(0.0, 1.0, float(gl_InstanceID) / 4.0, 1.0);" NL "    } else {" NL
3733                "        val_Result = vec4(1.0, 0.0, 0.0, 1.0);" NL "    }" NL "}";
3734     }
3735 
3736     template <typename api>
Fsh()3737     std::string Fsh()
3738     {
3739         return api::glslVer() + NL "precision highp float; " NL "in vec4 val_Result;" NL "out vec4 outColor;" NL
3740                                    "void main() {" NL "  outColor = val_Result;" NL "}";
3741     }
3742 
CBasicVertexIDsDef(TDrawFunction drawFunc)3743     CBasicVertexIDsDef(TDrawFunction drawFunc)
3744         : _drawFunc(drawFunc)
3745         , _drawSizeX(2)
3746         , _drawSizeY(2)
3747         , _vao(0)
3748         , _vbo(0)
3749         , _ebo(0)
3750         , _program(0)
3751     {
3752     }
3753 
3754 private:
3755     TDrawFunction _drawFunc;
3756     unsigned int _drawSizeX;
3757     unsigned int _drawSizeY;
3758 
3759     GLuint _vao;
3760     GLuint _vbo, _ebo;
3761     GLuint _program;
3762 
CBasicVertexIDsDef()3763     CBasicVertexIDsDef()
3764     {
3765     }
3766 };
3767 
3768 template <typename api>
3769 class CBufferIndirectDrawArraysVertexIds : public CBasicVertexIDsDef
3770 {
3771 public:
Title()3772     virtual std::string Title()
3773     {
3774         return "Indirect buffer glDrawArraysIndirect: all non-zero arguments, verify vertex ids";
3775     }
3776 
Purpose()3777     virtual std::string Purpose()
3778     {
3779         return "Verify that it is possible to draw primitives with all non-zero arguments" NL "in indirect buffer";
3780     }
3781 
Method()3782     virtual std::string Method()
3783     {
3784         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3785                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
3786     }
3787 
PassCriteria()3788     virtual std::string PassCriteria()
3789     {
3790         return "The test will pass if no OpenGL errors reported";
3791     }
3792 
Run()3793     virtual long Run()
3794     {
3795         return CBasicVertexIDsDef::Run<api>();
3796     }
3797 
CBufferIndirectDrawArraysVertexIds()3798     CBufferIndirectDrawArraysVertexIds() : CBasicVertexIDsDef(DRAW_ARRAYS)
3799     {
3800     }
3801 };
3802 
3803 template <typename api>
3804 class CBufferIndirectDrawElementsVertexIds : public CBasicVertexIDsDef
3805 {
3806 public:
Title()3807     virtual std::string Title()
3808     {
3809         return "Indirect buffer glDrawElementsIndirect: all non-zero arguments, verify vertex ids";
3810     }
3811 
Purpose()3812     virtual std::string Purpose()
3813     {
3814         return "Verify that it is possible to draw primitives with all non-zero arguments" NL "in indirect buffer";
3815     }
3816 
Method()3817     virtual std::string Method()
3818     {
3819         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3820                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
3821     }
3822 
PassCriteria()3823     virtual std::string PassCriteria()
3824     {
3825         return "The test will pass if no OpenGL errors reported";
3826     }
3827 
Run()3828     virtual long Run()
3829     {
3830         return CBasicVertexIDsDef::Run<api>();
3831     }
3832 
CBufferIndirectDrawElementsVertexIds()3833     CBufferIndirectDrawElementsVertexIds() : CBasicVertexIDsDef(DRAW_ELEMENTS)
3834     {
3835     }
3836 };
3837 
3838 template <typename api>
3839 class CIndicesDataTypeUnsignedShort : public DrawIndirectBase
3840 {
3841 public:
Title()3842     virtual std::string Title()
3843     {
3844         return "glDrawElementsIndirect indices data type: unsigned short";
3845     }
3846 
Purpose()3847     virtual std::string Purpose()
3848     {
3849         return "Verify that unsigned short indices are accepted by glDrawElementsIndirect";
3850     }
3851 
Method()3852     virtual std::string Method()
3853     {
3854         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL "3. Create element buffer" NL
3855                "4. Draw primitives using glDrawElementsIndirect" NL "5. Verify results";
3856     }
3857 
PassCriteria()3858     virtual std::string PassCriteria()
3859     {
3860         return "The test will pass if no OpenGL errors reported";
3861     }
3862 
Setup()3863     virtual long Setup()
3864     {
3865         glClear(GL_COLOR_BUFFER_BIT);
3866         return NO_ERROR;
3867     }
3868 
Run()3869     virtual long Run()
3870     {
3871         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3872         if (!_program)
3873         {
3874             return ERROR;
3875         }
3876         glUseProgram(_program);
3877 
3878         CColorArray coords;
3879         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
3880 
3881         glGenVertexArrays(1, &_vao);
3882         glBindVertexArray(_vao);
3883 
3884         glGenBuffers(1, &_buffer);
3885         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3886 
3887         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3888         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
3889         glEnableVertexAttribArray(0);
3890 
3891         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
3892         indirectElements.count                       = static_cast<GLuint>(coords.size()) / 2;
3893         indirectElements.primCount                   = 1;
3894         indirectElements.baseVertex                  = -static_cast<GLint>(coords.size()) / 4;
3895         indirectElements.firstIndex                  = static_cast<GLuint>(coords.size()) / 4;
3896         indirectElements.reservedMustBeZero          = 0;
3897 
3898         std::vector<GLushort> elements(coords.size(), 0);
3899         for (size_t i = 0; i < elements.size(); ++i)
3900         {
3901             elements[i] = static_cast<GLushort>(i);
3902         }
3903 
3904         glGenBuffers(1, &_bufferIndirect);
3905         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
3906         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW);
3907         glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements);
3908 
3909         glGenBuffers(1, &_ebo);
3910         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
3911         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
3912                      GL_STATIC_DRAW);
3913 
3914         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0);
3915 
3916         CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
3917         CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
3918         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
3919 
3920         DIResult result;
3921         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
3922         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
3923                                          getWindowWidth(), getWindowHeight() / 2));
3924 
3925         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
3926         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
3927                                          getWindowWidth(), getWindowHeight() / 2));
3928 
3929         return result.code();
3930     }
3931 
Cleanup()3932     virtual long Cleanup()
3933     {
3934         glDisableVertexAttribArray(0);
3935         glUseProgram(0);
3936         glDeleteProgram(_program);
3937         glDeleteVertexArrays(1, &_vao);
3938         glDeleteBuffers(1, &_buffer);
3939         glDeleteBuffers(1, &_ebo);
3940         glDeleteBuffers(1, &_bufferIndirect);
3941         return NO_ERROR;
3942     }
3943 
3944 private:
3945     GLuint _program;
3946     GLuint _vao, _buffer, _ebo, _bufferIndirect;
3947 };
3948 
3949 template <typename api>
3950 class CIndicesDataTypeUnsignedByte : public DrawIndirectBase
3951 {
3952 public:
Title()3953     virtual std::string Title()
3954     {
3955         return "glDrawElementsIndirect indices data type: unsigned byte";
3956     }
3957 
Purpose()3958     virtual std::string Purpose()
3959     {
3960         return "Verify that unsigned byte indices are accepted by glDrawElementsIndirect";
3961     }
3962 
Method()3963     virtual std::string Method()
3964     {
3965         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL "3. Create element buffer" NL
3966                "4. Draw primitives using glDrawElementsIndirect" NL "5. Verify results";
3967     }
3968 
PassCriteria()3969     virtual std::string PassCriteria()
3970     {
3971         return "The test will pass if no OpenGL errors reported";
3972     }
3973 
Setup()3974     virtual long Setup()
3975     {
3976         glClear(GL_COLOR_BUFFER_BIT);
3977         return NO_ERROR;
3978     }
3979 
Run()3980     virtual long Run()
3981     {
3982         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3983         if (!_program)
3984         {
3985             return ERROR;
3986         }
3987         glUseProgram(_program);
3988 
3989         CColorArray coords;
3990         PrimitiveGen(GL_TRIANGLES, 2, 2, coords);
3991 
3992         glGenVertexArrays(1, &_vao);
3993         glBindVertexArray(_vao);
3994 
3995         glGenBuffers(1, &_buffer);
3996         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3997 
3998         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3999         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
4000         glEnableVertexAttribArray(0);
4001 
4002         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
4003         indirectElements.count                       = static_cast<GLuint>(coords.size()) / 2;
4004         indirectElements.primCount                   = 1;
4005         indirectElements.baseVertex                  = -static_cast<GLint>(coords.size()) / 4;
4006         indirectElements.firstIndex                  = static_cast<GLuint>(coords.size()) / 4;
4007         indirectElements.reservedMustBeZero          = 0;
4008 
4009         std::vector<GLubyte> elements(coords.size(), 0);
4010         for (size_t i = 0; i < elements.size(); ++i)
4011         {
4012             elements[i] = static_cast<GLubyte>(i);
4013         }
4014 
4015         glGenBuffers(1, &_bufferIndirect);
4016         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
4017         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW);
4018         glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements);
4019 
4020         glGenBuffers(1, &_ebo);
4021         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
4022         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
4023                      GL_STATIC_DRAW);
4024 
4025         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_BYTE, 0);
4026 
4027         CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
4028         CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
4029         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
4030 
4031         DIResult result;
4032         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
4033         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
4034                                          getWindowWidth(), getWindowHeight() / 2));
4035 
4036         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
4037         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
4038                                          getWindowWidth(), getWindowHeight() / 2));
4039 
4040         return result.code();
4041     }
4042 
Cleanup()4043     virtual long Cleanup()
4044     {
4045         glDisableVertexAttribArray(0);
4046         glUseProgram(0);
4047         glDeleteProgram(_program);
4048         glDeleteVertexArrays(1, &_vao);
4049         glDeleteBuffers(1, &_buffer);
4050         glDeleteBuffers(1, &_ebo);
4051         glDeleteBuffers(1, &_bufferIndirect);
4052         return NO_ERROR;
4053     }
4054 
4055 private:
4056     GLuint _program;
4057     GLuint _vao, _buffer, _ebo, _bufferIndirect;
4058 };
4059 
4060 class CPrimitiveMode : public DrawIndirectBase
4061 {
4062 public:
4063     template <typename api>
IsGeometryShaderSupported()4064     bool IsGeometryShaderSupported()
4065     {
4066         if (api::isES())
4067         {
4068             const glu::ContextInfo &info = m_context.getContextInfo();
4069             const glu::ContextType &type = m_context.getRenderContext().getType();
4070 
4071             /* ES 3.2+ included geometry shaders into the core */
4072             if (glu::contextSupports(type, glu::ApiType(3, 2, glu::PROFILE_ES)))
4073             {
4074                 return true;
4075             }
4076             /* ES 3.1 may be able to support geometry shaders via extensions */
4077             else if ((glu::contextSupports(type, glu::ApiType(3, 1, glu::PROFILE_ES))) &&
4078                      ((true == info.isExtensionSupported("GL_EXT_geometry_shader")) ||
4079                       (true == info.isExtensionSupported("GL_OES_geometry_shader"))))
4080             {
4081                 return true;
4082             }
4083             else
4084             {
4085                 OutputNotSupported("Geometry shader is not supported\n");
4086                 return false;
4087             }
4088         }
4089         else
4090         {
4091             return true;
4092         }
4093     }
Setup()4094     virtual long Setup()
4095     {
4096         _sizeX = getWindowWidth();
4097         _sizeY = getWindowHeight();
4098         if (_primitiveType != GL_TRIANGLE_STRIP && _primitiveType != GL_TRIANGLE_STRIP_ADJACENCY &&
4099             _primitiveType != GL_TRIANGLES && _primitiveType != GL_TRIANGLES_ADJACENCY &&
4100             _primitiveType != GL_TRIANGLE_FAN)
4101         {
4102             _sizeX &= (-4);
4103             _sizeY &= (-4);
4104         }
4105         if ((int)_drawSizeX < 0 || (int)_drawSizeY < 0)
4106         {
4107             //no PrimitiveGen dimensions given. assume same dimensions as rendered image^
4108             _drawSizeX = _sizeX;
4109             _drawSizeY = _sizeY;
4110             if (_primitiveType == GL_POINTS)
4111             {
4112                 //clamp vertex number (and rendering size) for points to max. 10000
4113                 _sizeX = _drawSizeX = std::min(_drawSizeX, 100u);
4114                 _sizeY = _drawSizeY = std::min(_drawSizeY, 100u);
4115             }
4116         }
4117 
4118         glClear(GL_COLOR_BUFFER_BIT);
4119         return NO_ERROR;
4120     }
4121 
4122     template <typename api>
Run(bool pointMode=false)4123     long Run(bool pointMode = false)
4124     {
4125 
4126         glClear(GL_COLOR_BUFFER_BIT);
4127 
4128         _program = CreateProgram(pointMode ? shaders::vshSimple_point<api>() : shaders::vshSimple<api>(), "",
4129                                  shaders::fshSimple<api>(), true);
4130         if (!_program)
4131         {
4132             return ERROR;
4133         }
4134         glUseProgram(_program);
4135 
4136         CColorArray coords;
4137         PrimitiveGen(_primitiveType, _drawSizeX, _drawSizeY, coords);
4138 
4139         glGenVertexArrays(1, &_vao);
4140         glBindVertexArray(_vao);
4141 
4142         glGenBuffers(1, &_buffer);
4143         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
4144 
4145         CColorArray padding(10, tcu::Vec4(0.0f));
4146 
4147         glBufferData(GL_ARRAY_BUFFER,
4148                      (GLsizeiptr)(coords.size() * (sizeof(coords[0])) + padding.size() * (sizeof(padding[0]))), NULL,
4149                      GL_STREAM_DRAW);
4150         glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(padding.size() * (sizeof(padding[0]))), &padding[0]);
4151         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(padding.size() * (sizeof(padding[0]))),
4152                         (GLsizeiptr)(coords.size() * (sizeof(coords[0]))), &coords[0]);
4153 
4154         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
4155         glEnableVertexAttribArray(0);
4156 
4157         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
4158         DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
4159 
4160         CElementArray elements(coords.size(), 0);
4161         for (size_t i = 0; i < elements.size(); ++i)
4162         {
4163             elements[i] = static_cast<GLuint>(i);
4164         }
4165 
4166         glGenBuffers(1, &_bufferIndirect);
4167         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
4168 
4169         switch (_drawFunc)
4170         {
4171         case DRAW_ARRAYS:
4172         {
4173             indirectArrays.count              = static_cast<GLuint>(coords.size()) / 2;
4174             indirectArrays.primCount          = 1;
4175             indirectArrays.first              = 10;
4176             indirectArrays.reservedMustBeZero = 0;
4177 
4178             glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), NULL, GL_STATIC_DRAW);
4179             glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawArraysIndirectCommand), &indirectArrays);
4180 
4181             glDrawArraysIndirect(_primitiveType, 0);
4182         }
4183         break;
4184         case DRAW_ELEMENTS:
4185         {
4186             indirectElements.count              = static_cast<GLuint>(coords.size()) / 2;
4187             indirectElements.primCount          = 1;
4188             indirectElements.baseVertex         = 7;
4189             indirectElements.firstIndex         = 3;
4190             indirectElements.reservedMustBeZero = 0;
4191 
4192             glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW);
4193             glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements);
4194 
4195             glGenBuffers(1, &_ebo);
4196             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
4197             glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
4198                          GL_STATIC_DRAW);
4199 
4200             glDrawElementsIndirect(_primitiveType, GL_UNSIGNED_INT, 0);
4201         }
4202         break;
4203         default:
4204             throw std::runtime_error("Unknown draw function!");
4205             break;
4206         }
4207 
4208         CColorArray bufferRef1(_sizeX * _sizeY / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
4209         CColorArray bufferRef2(_sizeX * _sizeY / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
4210         CColorArray bufferTest(_sizeX * _sizeY, tcu::Vec4(0.0f));
4211 
4212         DIResult result;
4213         ReadPixelsFloat<api>(0, (_sizeY + 1) / 2, _sizeX, _sizeY / 2, &bufferTest[0]);
4214         result.sub_result(BuffersCompare(bufferTest, _sizeX, _sizeY / 2, bufferRef1, _sizeX, _sizeY / 2));
4215 
4216         switch (_primitiveType)
4217         {
4218         case GL_TRIANGLES_ADJACENCY:
4219         case GL_TRIANGLE_STRIP_ADJACENCY:
4220         {
4221             CColorArray bufferRef3(_sizeX * _sizeY / 16, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
4222             CColorArray bufferRef4(_sizeX * _sizeY / 8, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
4223             CColorArray bufferRef5(_sizeX * _sizeY / 4, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
4224 
4225             CColorArray bufferTest3(_sizeX * _sizeY / 16, tcu::Vec4(0.0f));
4226             CColorArray bufferTest4(_sizeX * _sizeY / 8, tcu::Vec4(0.0f));
4227             CColorArray bufferTest5(_sizeX * _sizeY / 4, tcu::Vec4(0.0f));
4228 
4229             ReadPixelsFloat<api>(0, (_sizeY + 3) / 4, _sizeX / 4, _sizeY / 4, &bufferTest3[0]);
4230             result.sub_result(BuffersCompare(bufferTest3, _sizeX / 4, _sizeY / 4, bufferRef3, _sizeX / 4, _sizeY / 4));
4231 
4232             ReadPixelsFloat<api>((_sizeX + 3) / 4, (_sizeY + 3) / 4, _sizeX / 2, _sizeY / 4, &bufferTest4[0]);
4233             result.sub_result(BuffersCompare(bufferTest4, _sizeX / 2, _sizeY / 4, bufferRef4, _sizeX / 2, _sizeY / 4));
4234 
4235             ReadPixelsFloat<api>((_sizeX * 3 + 3) / 4, (_sizeY + 3) / 4, _sizeX / 4, _sizeY / 4, &bufferTest3[0]);
4236             result.sub_result(BuffersCompare(bufferTest3, _sizeX / 4, _sizeY / 4, bufferRef3, _sizeX / 4, _sizeY / 4));
4237 
4238             ReadPixelsFloat<api>(0, 0, _sizeX, _sizeY / 4, &bufferTest5[0]);
4239             result.sub_result(BuffersCompare(bufferTest5, _sizeX, _sizeY / 4, bufferRef5, _sizeX, _sizeY / 4));
4240         }
4241         break;
4242         default:
4243         {
4244             ReadPixelsFloat<api>(0, 0, _sizeX, _sizeY / 2, &bufferTest[0]);
4245             result.sub_result(BuffersCompare(bufferTest, _sizeX, _sizeY / 2, bufferRef2, _sizeX, _sizeY / 2));
4246         }
4247         break;
4248         }
4249 
4250         return result.code();
4251     }
4252 
Cleanup()4253     virtual long Cleanup()
4254     {
4255         glDisableVertexAttribArray(0);
4256         glUseProgram(0);
4257         glDeleteProgram(_program);
4258         glDeleteVertexArrays(1, &_vao);
4259         glDeleteBuffers(1, &_buffer);
4260         glDeleteBuffers(1, &_ebo);
4261         glDeleteBuffers(1, &_bufferIndirect);
4262         return NO_ERROR;
4263     }
4264 
CPrimitiveMode(TDrawFunction drawFunc,GLenum primitiveType,unsigned int sizeX=-1,unsigned sizeY=-1)4265     CPrimitiveMode(TDrawFunction drawFunc, GLenum primitiveType, unsigned int sizeX = -1, unsigned sizeY = -1)
4266         : _drawFunc(drawFunc)
4267         , _primitiveType(primitiveType)
4268         , _drawSizeX(sizeX)
4269         , _drawSizeY(sizeY)
4270         , _sizeX(0)
4271         , _sizeY(0)
4272         , _program(0)
4273         , _vao(0)
4274         , _buffer(0)
4275         , _ebo(0)
4276         , _bufferIndirect(0)
4277     {
4278     }
4279 
4280 private:
4281     TDrawFunction _drawFunc;
4282     GLenum _primitiveType;
4283     unsigned int _drawSizeX, _drawSizeY; //dims for primitive generator
4284     unsigned int _sizeX, _sizeY;         //rendering size
4285     GLuint _program;
4286     GLuint _vao, _buffer, _ebo, _bufferIndirect;
4287 
4288     CPrimitiveMode();
4289 };
4290 
4291 template <typename api>
4292 class CModeDrawArraysPoints : public CPrimitiveMode
4293 {
4294 public:
Title()4295     virtual std::string Title()
4296     {
4297         return "glDrawArraysIndirect mode: GL_POINTS";
4298     }
4299 
Purpose()4300     virtual std::string Purpose()
4301     {
4302         return "Verify that glDrawArraysIndirect with GL_POINTS works correctly";
4303     }
4304 
Method()4305     virtual std::string Method()
4306     {
4307         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4308                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4309     }
4310 
PassCriteria()4311     virtual std::string PassCriteria()
4312     {
4313         return "The test will pass if no OpenGL errors reported";
4314     }
4315 
CModeDrawArraysPoints()4316     CModeDrawArraysPoints() : CPrimitiveMode(DRAW_ARRAYS, GL_POINTS)
4317     {
4318     }
4319 
Run()4320     virtual long Run()
4321     {
4322         return CPrimitiveMode::Run<api>(true);
4323     }
4324 };
4325 
4326 template <typename api>
4327 class CModeDrawArraysLines : public CPrimitiveMode
4328 {
4329 public:
Title()4330     virtual std::string Title()
4331     {
4332         return "glDrawArraysIndirect mode: GL_LINES";
4333     }
4334 
Purpose()4335     virtual std::string Purpose()
4336     {
4337         return "Verify that glDrawArraysIndirect with GL_LINES works correctly";
4338     }
4339 
Method()4340     virtual std::string Method()
4341     {
4342         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4343                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4344     }
4345 
PassCriteria()4346     virtual std::string PassCriteria()
4347     {
4348         return "The test will pass if no OpenGL errors reported";
4349     }
4350 
CModeDrawArraysLines()4351     CModeDrawArraysLines() : CPrimitiveMode(DRAW_ARRAYS, GL_LINES)
4352     {
4353     }
4354 
Run()4355     virtual long Run()
4356     {
4357         return CPrimitiveMode::Run<api>();
4358     }
4359 };
4360 
4361 template <typename api>
4362 class CModeDrawArraysLineStrip : public CPrimitiveMode
4363 {
4364 public:
Title()4365     virtual std::string Title()
4366     {
4367         return "glDrawArraysIndirect mode: GL_LINE_STRIP";
4368     }
4369 
Purpose()4370     virtual std::string Purpose()
4371     {
4372         return "Verify that glDrawArraysIndirect with GL_LINE_STRIP works correctly";
4373     }
4374 
Method()4375     virtual std::string Method()
4376     {
4377         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4378                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4379     }
4380 
PassCriteria()4381     virtual std::string PassCriteria()
4382     {
4383         return "The test will pass if no OpenGL errors reported";
4384     }
4385 
CModeDrawArraysLineStrip()4386     CModeDrawArraysLineStrip() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_STRIP)
4387     {
4388     }
Run()4389     virtual long Run()
4390     {
4391         return CPrimitiveMode::Run<api>();
4392     }
4393 };
4394 
4395 template <typename api>
4396 class CModeDrawArraysLineLoop : public CPrimitiveMode
4397 {
4398 public:
Title()4399     virtual std::string Title()
4400     {
4401         return "glDrawArraysIndirect mode: GL_LINE_LOOP";
4402     }
4403 
Purpose()4404     virtual std::string Purpose()
4405     {
4406         return "Verify that glDrawArraysIndirect with GL_LINE_LOOP works correctly";
4407     }
4408 
Method()4409     virtual std::string Method()
4410     {
4411         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4412                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4413     }
4414 
PassCriteria()4415     virtual std::string PassCriteria()
4416     {
4417         return "The test will pass if no OpenGL errors reported";
4418     }
4419 
CModeDrawArraysLineLoop()4420     CModeDrawArraysLineLoop() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_LOOP)
4421     {
4422     }
4423 
Run()4424     virtual long Run()
4425     {
4426         return CPrimitiveMode::Run<api>();
4427     }
4428 };
4429 
4430 template <typename api>
4431 class CModeDrawArraysTriangleStrip : public CPrimitiveMode
4432 {
4433 public:
Title()4434     virtual std::string Title()
4435     {
4436         return "glDrawArraysIndirect mode: GL_TRIANGLE_STRIP";
4437     }
4438 
Purpose()4439     virtual std::string Purpose()
4440     {
4441         return "Verify that glDrawArraysIndirect with GL_TRIANGLE_STRIP works correctly";
4442     }
4443 
Method()4444     virtual std::string Method()
4445     {
4446         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4447                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4448     }
4449 
PassCriteria()4450     virtual std::string PassCriteria()
4451     {
4452         return "The test will pass if no OpenGL errors reported";
4453     }
4454 
CModeDrawArraysTriangleStrip()4455     CModeDrawArraysTriangleStrip() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_STRIP, 2, 2)
4456     {
4457     }
4458 
Run()4459     virtual long Run()
4460     {
4461         return CPrimitiveMode::Run<api>();
4462     }
4463 };
4464 
4465 template <typename api>
4466 class CModeDrawArraysTriangleFan : public CPrimitiveMode
4467 {
4468 public:
Title()4469     virtual std::string Title()
4470     {
4471         return "glDrawArraysIndirect mode: GL_TRIANGLE_FAN";
4472     }
4473 
Purpose()4474     virtual std::string Purpose()
4475     {
4476         return "Verify that glDrawArraysIndirect with GL_TRIANGLE_FAN works correctly";
4477     }
4478 
Method()4479     virtual std::string Method()
4480     {
4481         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4482                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4483     }
4484 
PassCriteria()4485     virtual std::string PassCriteria()
4486     {
4487         return "The test will pass if no OpenGL errors reported";
4488     }
4489 
CModeDrawArraysTriangleFan()4490     CModeDrawArraysTriangleFan() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_FAN, 2, 2)
4491     {
4492     }
4493 
Run()4494     virtual long Run()
4495     {
4496         return CPrimitiveMode::Run<api>();
4497     }
4498 };
4499 
4500 template <typename api>
4501 class CModeDrawArraysLinesAdjacency : public CPrimitiveMode
4502 {
4503 public:
Title()4504     virtual std::string Title()
4505     {
4506         return "glDrawArraysIndirect mode: GL_LINES_ADJACENCY";
4507     }
4508 
Purpose()4509     virtual std::string Purpose()
4510     {
4511         return "Verify that glDrawArraysIndirect with GL_LINES_ADJACENCY works correctly";
4512     }
4513 
Method()4514     virtual std::string Method()
4515     {
4516         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4517                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4518     }
4519 
PassCriteria()4520     virtual std::string PassCriteria()
4521     {
4522         return "The test will pass if no OpenGL errors reported";
4523     }
4524 
CModeDrawArraysLinesAdjacency()4525     CModeDrawArraysLinesAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_LINES_ADJACENCY)
4526     {
4527     }
4528 
Run()4529     virtual long Run()
4530     {
4531         if (!IsGeometryShaderSupported<api>())
4532             return NOT_SUPPORTED;
4533         return CPrimitiveMode::Run<api>();
4534     }
4535 };
4536 
4537 template <typename api>
4538 class CModeDrawArraysLineStripAdjacency : public CPrimitiveMode
4539 {
4540 public:
Title()4541     virtual std::string Title()
4542     {
4543         return "glDrawArraysIndirect mode: GL_LINE_STRIP_ADJACENCY";
4544     }
4545 
Purpose()4546     virtual std::string Purpose()
4547     {
4548         return "Verify that glDrawArraysIndirect with GL_LINE_STRIP_ADJACENCY works correctly";
4549     }
4550 
Method()4551     virtual std::string Method()
4552     {
4553         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4554                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4555     }
4556 
PassCriteria()4557     virtual std::string PassCriteria()
4558     {
4559         return "The test will pass if no OpenGL errors reported";
4560     }
4561 
CModeDrawArraysLineStripAdjacency()4562     CModeDrawArraysLineStripAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_STRIP_ADJACENCY)
4563     {
4564     }
4565 
Run()4566     virtual long Run()
4567     {
4568         if (!IsGeometryShaderSupported<api>())
4569             return NOT_SUPPORTED;
4570         return CPrimitiveMode::Run<api>();
4571     }
4572 };
4573 
4574 template <typename api>
4575 class CModeDrawArraysTrianglesAdjacency : public CPrimitiveMode
4576 {
4577 public:
Title()4578     virtual std::string Title()
4579     {
4580         return "glDrawArraysIndirect mode: GL_TRIANGLES_ADJACENCY";
4581     }
4582 
Purpose()4583     virtual std::string Purpose()
4584     {
4585         return "Verify that glDrawArraysIndirect with GL_TRIANGLES_ADJACENCY works correctly";
4586     }
4587 
Method()4588     virtual std::string Method()
4589     {
4590         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4591                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4592     }
4593 
PassCriteria()4594     virtual std::string PassCriteria()
4595     {
4596         return "The test will pass if no OpenGL errors reported";
4597     }
4598 
CModeDrawArraysTrianglesAdjacency()4599     CModeDrawArraysTrianglesAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLES_ADJACENCY, 4, 4)
4600     {
4601     }
4602 
Run()4603     virtual long Run()
4604     {
4605         if (!IsGeometryShaderSupported<api>())
4606             return NOT_SUPPORTED;
4607         return CPrimitiveMode::Run<api>();
4608     }
4609 };
4610 
4611 template <typename api>
4612 class CModeDrawArraysTriangleStripAdjacency : public CPrimitiveMode
4613 {
4614 public:
Title()4615     virtual std::string Title()
4616     {
4617         return "glDrawArraysIndirect mode: GL_TRIANGLE_STRIP_ADJACENCY";
4618     }
4619 
Purpose()4620     virtual std::string Purpose()
4621     {
4622         return "Verify that glDrawArraysIndirect with GL_TRIANGLE_STRIP_ADJACENCY works correctly";
4623     }
4624 
Method()4625     virtual std::string Method()
4626     {
4627         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4628                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4629     }
4630 
PassCriteria()4631     virtual std::string PassCriteria()
4632     {
4633         return "The test will pass if no OpenGL errors reported";
4634     }
4635 
CModeDrawArraysTriangleStripAdjacency()4636     CModeDrawArraysTriangleStripAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_STRIP_ADJACENCY, 4, 4)
4637     {
4638     }
Run()4639     virtual long Run()
4640     {
4641         if (!IsGeometryShaderSupported<api>())
4642             return NOT_SUPPORTED;
4643         return CPrimitiveMode::Run<api>();
4644     }
4645 };
4646 
4647 template <typename api>
4648 class CModeDrawElementsPoints : public CPrimitiveMode
4649 {
4650 public:
Title()4651     virtual std::string Title()
4652     {
4653         return "glDrawElementsIndirect mode: GL_POINTS";
4654     }
4655 
Purpose()4656     virtual std::string Purpose()
4657     {
4658         return "Verify that glDrawElementsIndirect with GL_POINTS works correctly";
4659     }
4660 
Method()4661     virtual std::string Method()
4662     {
4663         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4664                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4665     }
4666 
PassCriteria()4667     virtual std::string PassCriteria()
4668     {
4669         return "The test will pass if no OpenGL errors reported";
4670     }
4671 
CModeDrawElementsPoints()4672     CModeDrawElementsPoints() : CPrimitiveMode(DRAW_ELEMENTS, GL_POINTS)
4673     {
4674     }
4675 
Run()4676     virtual long Run()
4677     {
4678         return CPrimitiveMode::Run<api>(true);
4679     }
4680 };
4681 
4682 template <typename api>
4683 class CModeDrawElementsLines : public CPrimitiveMode
4684 {
4685 public:
Title()4686     virtual std::string Title()
4687     {
4688         return "glDrawElementsIndirect mode: GL_LINES";
4689     }
4690 
Purpose()4691     virtual std::string Purpose()
4692     {
4693         return "Verify that glDrawElementsIndirect with GL_LINES works correctly";
4694     }
4695 
Method()4696     virtual std::string Method()
4697     {
4698         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4699                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4700     }
4701 
PassCriteria()4702     virtual std::string PassCriteria()
4703     {
4704         return "The test will pass if no OpenGL errors reported";
4705     }
4706 
CModeDrawElementsLines()4707     CModeDrawElementsLines() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINES)
4708     {
4709     }
Run()4710     virtual long Run()
4711     {
4712         return CPrimitiveMode::Run<api>();
4713     }
4714 };
4715 
4716 template <typename api>
4717 class CModeDrawElementsLineStrip : public CPrimitiveMode
4718 {
4719 public:
Title()4720     virtual std::string Title()
4721     {
4722         return "glDrawElementsIndirect mode: GL_LINE_STRIP";
4723     }
4724 
Purpose()4725     virtual std::string Purpose()
4726     {
4727         return "Verify that glDrawElementsIndirect with GL_LINE_STRIP works correctly";
4728     }
4729 
Method()4730     virtual std::string Method()
4731     {
4732         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4733                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4734     }
4735 
PassCriteria()4736     virtual std::string PassCriteria()
4737     {
4738         return "The test will pass if no OpenGL errors reported";
4739     }
4740 
CModeDrawElementsLineStrip()4741     CModeDrawElementsLineStrip() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_STRIP)
4742     {
4743     }
Run()4744     virtual long Run()
4745     {
4746         return CPrimitiveMode::Run<api>();
4747     }
4748 };
4749 
4750 template <typename api>
4751 class CModeDrawElementsLineLoop : public CPrimitiveMode
4752 {
4753 public:
Title()4754     virtual std::string Title()
4755     {
4756         return "glDrawElementsIndirect mode: GL_LINE_LOOP";
4757     }
4758 
Purpose()4759     virtual std::string Purpose()
4760     {
4761         return "Verify that glDrawElementsIndirect with GL_LINE_LOOP works correctly";
4762     }
4763 
Method()4764     virtual std::string Method()
4765     {
4766         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4767                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4768     }
4769 
PassCriteria()4770     virtual std::string PassCriteria()
4771     {
4772         return "The test will pass if no OpenGL errors reported";
4773     }
4774 
CModeDrawElementsLineLoop()4775     CModeDrawElementsLineLoop() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_LOOP)
4776     {
4777     }
Run()4778     virtual long Run()
4779     {
4780         return CPrimitiveMode::Run<api>();
4781     }
4782 };
4783 
4784 template <typename api>
4785 class CModeDrawElementsTriangleStrip : public CPrimitiveMode
4786 {
4787 public:
Title()4788     virtual std::string Title()
4789     {
4790         return "glDrawElementsIndirect mode: GL_TRIANGLE_STRIP";
4791     }
4792 
Purpose()4793     virtual std::string Purpose()
4794     {
4795         return "Verify that glDrawElementsIndirect with GL_TRIANGLE_STRIP works correctly";
4796     }
4797 
Method()4798     virtual std::string Method()
4799     {
4800         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4801                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4802     }
4803 
PassCriteria()4804     virtual std::string PassCriteria()
4805     {
4806         return "The test will pass if no OpenGL errors reported";
4807     }
4808 
CModeDrawElementsTriangleStrip()4809     CModeDrawElementsTriangleStrip() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_STRIP, 2, 2)
4810     {
4811     }
Run()4812     virtual long Run()
4813     {
4814         return CPrimitiveMode::Run<api>();
4815     }
4816 };
4817 
4818 template <typename api>
4819 class CModeDrawElementsTriangleFan : public CPrimitiveMode
4820 {
4821 public:
Title()4822     virtual std::string Title()
4823     {
4824         return "glDrawElementsIndirect mode: GL_TRIANGLE_FAN";
4825     }
4826 
Purpose()4827     virtual std::string Purpose()
4828     {
4829         return "Verify that glDrawElementsIndirect with GL_TRIANGLE_FAN works correctly";
4830     }
4831 
Method()4832     virtual std::string Method()
4833     {
4834         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4835                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4836     }
4837 
PassCriteria()4838     virtual std::string PassCriteria()
4839     {
4840         return "The test will pass if no OpenGL errors reported";
4841     }
4842 
CModeDrawElementsTriangleFan()4843     CModeDrawElementsTriangleFan() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_FAN, 2, 2)
4844     {
4845     }
Run()4846     virtual long Run()
4847     {
4848         return CPrimitiveMode::Run<api>();
4849     }
4850 };
4851 
4852 template <typename api>
4853 class CModeDrawElementsLinesAdjacency : public CPrimitiveMode
4854 {
4855 public:
Title()4856     virtual std::string Title()
4857     {
4858         return "glDrawElementsIndirect mode: GL_LINES_ADJACENCY";
4859     }
4860 
Purpose()4861     virtual std::string Purpose()
4862     {
4863         return "Verify that glDrawElementsIndirect with GL_LINES_ADJACENCY works correctly";
4864     }
4865 
Method()4866     virtual std::string Method()
4867     {
4868         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4869                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4870     }
4871 
PassCriteria()4872     virtual std::string PassCriteria()
4873     {
4874         return "The test will pass if no OpenGL errors reported";
4875     }
4876 
CModeDrawElementsLinesAdjacency()4877     CModeDrawElementsLinesAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINES_ADJACENCY)
4878     {
4879     }
Run()4880     virtual long Run()
4881     {
4882         if (!IsGeometryShaderSupported<api>())
4883             return NOT_SUPPORTED;
4884         return CPrimitiveMode::Run<api>();
4885     }
4886 };
4887 
4888 template <typename api>
4889 class CModeDrawElementsLineStripAdjacency : public CPrimitiveMode
4890 {
4891 public:
Title()4892     virtual std::string Title()
4893     {
4894         return "glDrawElementsIndirect mode: GL_LINE_STRIP_ADJACENCY";
4895     }
4896 
Purpose()4897     virtual std::string Purpose()
4898     {
4899         return "Verify that glDrawElementsIndirect with GL_LINE_STRIP_ADJACENCY works correctly";
4900     }
4901 
Method()4902     virtual std::string Method()
4903     {
4904         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4905                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4906     }
4907 
PassCriteria()4908     virtual std::string PassCriteria()
4909     {
4910         return "The test will pass if no OpenGL errors reported";
4911     }
4912 
CModeDrawElementsLineStripAdjacency()4913     CModeDrawElementsLineStripAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_STRIP_ADJACENCY)
4914     {
4915     }
Run()4916     virtual long Run()
4917     {
4918         if (!IsGeometryShaderSupported<api>())
4919             return NOT_SUPPORTED;
4920         return CPrimitiveMode::Run<api>();
4921     }
4922 };
4923 
4924 template <typename api>
4925 class CModeDrawElementsTrianglesAdjacency : public CPrimitiveMode
4926 {
4927 public:
Title()4928     virtual std::string Title()
4929     {
4930         return "glDrawElementsIndirect mode: GL_TRIANGLES_ADJACENCY";
4931     }
4932 
Purpose()4933     virtual std::string Purpose()
4934     {
4935         return "Verify that glDrawElementsIndirect with GL_TRIANGLES_ADJACENCY works correctly";
4936     }
4937 
Method()4938     virtual std::string Method()
4939     {
4940         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4941                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4942     }
4943 
PassCriteria()4944     virtual std::string PassCriteria()
4945     {
4946         return "The test will pass if no OpenGL errors reported";
4947     }
4948 
CModeDrawElementsTrianglesAdjacency()4949     CModeDrawElementsTrianglesAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLES_ADJACENCY, 4, 4)
4950     {
4951     }
Run()4952     virtual long Run()
4953     {
4954         if (!IsGeometryShaderSupported<api>())
4955             return NOT_SUPPORTED;
4956         return CPrimitiveMode::Run<api>();
4957     }
4958 };
4959 
4960 template <typename api>
4961 class CModeDrawElementsTriangleStripAdjacency : public CPrimitiveMode
4962 {
4963 public:
Title()4964     virtual std::string Title()
4965     {
4966         return "glDrawElementsIndirect mode: GL_TRIANGLE_STRIP_ADJACENCY";
4967     }
4968 
Purpose()4969     virtual std::string Purpose()
4970     {
4971         return "Verify that glDrawElementsIndirect with GL_TRIANGLE_STRIP_ADJACENCY works correctly";
4972     }
4973 
Method()4974     virtual std::string Method()
4975     {
4976         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4977                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4978     }
4979 
PassCriteria()4980     virtual std::string PassCriteria()
4981     {
4982         return "The test will pass if no OpenGL errors reported";
4983     }
4984 
CModeDrawElementsTriangleStripAdjacency()4985     CModeDrawElementsTriangleStripAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_STRIP_ADJACENCY, 4, 4)
4986     {
4987     }
Run()4988     virtual long Run()
4989     {
4990         if (!IsGeometryShaderSupported<api>())
4991             return NOT_SUPPORTED;
4992         return CPrimitiveMode::Run<api>();
4993     }
4994 };
4995 
4996 class CTransformFeedback : public DrawIndirectBase
4997 {
4998 public:
Setup()4999     virtual long Setup()
5000     {
5001         glClear(GL_COLOR_BUFFER_BIT);
5002         return NO_ERROR;
5003     }
5004 
5005     template <typename api>
Run()5006     long Run()
5007     {
5008         CColorArray coords;
5009         PrimitiveGen(GL_TRIANGLE_STRIP, 8, 8, coords);
5010 
5011         glClear(GL_COLOR_BUFFER_BIT);
5012 
5013         _program                 = CreateProgram(Vsh<api>(), "", shaders::fshSimple<api>(), false);
5014         const GLchar *varyings[] = {"dataOut"};
5015         glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS);
5016         glLinkProgram(_program);
5017         if (!CheckProgram(_program))
5018         {
5019             return ERROR;
5020         }
5021         glUseProgram(_program);
5022 
5023         glGenBuffers(1, &_vbo);
5024         glBindBuffer(GL_ARRAY_BUFFER, _vbo);
5025         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW);
5026 
5027         glGenBuffers(1, &_ubo);
5028         glBindBuffer(GL_UNIFORM_BUFFER, _ubo);
5029         glBufferData(GL_UNIFORM_BUFFER, 4 * 5 * sizeof(GLuint), NULL, GL_STATIC_DRAW);
5030         glBindBufferBase(GL_UNIFORM_BUFFER, glGetUniformBlockIndex(_program, "BLOCK"), _ubo);
5031         std::vector<GLuint> uboData;
5032 
5033         switch (_drawFunc)
5034         {
5035         case DRAW_ARRAYS:
5036         {
5037             uboData.resize(4 * 4, 0);
5038 
5039             uboData[0]  = static_cast<GLuint>(coords.size()); //count
5040             uboData[4]  = 1;                                  //primcount
5041             uboData[8]  = 0;                                  //first
5042             uboData[12] = 0;                                  //mbz
5043         }
5044         break;
5045         case DRAW_ELEMENTS:
5046         {
5047             uboData.resize(4 * 5, 0);
5048             uboData[0]  = static_cast<GLuint>(coords.size()); //count
5049             uboData[4]  = 1;                                  //primcount
5050             uboData[8]  = 0;                                  //firstindex
5051             uboData[12] = 0;                                  //basevertex
5052             uboData[16] = 0;                                  //mbz
5053         }
5054         break;
5055         default:
5056             throw std::runtime_error("Unknown draw function!");
5057             break;
5058         }
5059         glBufferSubData(GL_UNIFORM_BUFFER, 0, (GLsizeiptr)(uboData.size() * sizeof(uboData[0])), &uboData[0]);
5060 
5061         glGenVertexArrays(1, &_vao);
5062         glBindVertexArray(_vao);
5063         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
5064         glEnableVertexAttribArray(0);
5065 
5066         CElementArray elements(coords.size(), 0);
5067         for (size_t i = 0; i < elements.size(); ++i)
5068         {
5069             elements[i] = static_cast<GLuint>(i);
5070         }
5071 
5072         glGenBuffers(1, &_ebo);
5073         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
5074         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
5075                      GL_STATIC_DRAW);
5076 
5077         glGenBuffers(1, &_bufferIndirect);
5078 
5079         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _bufferIndirect);
5080         GLuint zeroes[] = {0, 0, 0, 0, 0};
5081         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(zeroes), zeroes, GL_DYNAMIC_DRAW);
5082         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _bufferIndirect);
5083         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
5084 
5085         glEnable(GL_RASTERIZER_DISCARD);
5086         glBeginTransformFeedback(GL_POINTS);
5087         glDrawArrays(GL_POINTS, 0, 5);
5088         glEndTransformFeedback();
5089         glDisable(GL_RASTERIZER_DISCARD);
5090 
5091         switch (_drawFunc)
5092         {
5093         case DRAW_ARRAYS:
5094             glDrawArraysIndirect(GL_TRIANGLES, 0);
5095             break;
5096         case DRAW_ELEMENTS:
5097             glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
5098 
5099             break;
5100         default:
5101             throw std::runtime_error("Unknown draw function!");
5102             break;
5103         }
5104 
5105         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
5106         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
5107         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
5108 
5109         DIResult result;
5110         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
5111                                          getWindowHeight()));
5112 
5113         return result.code();
5114     }
5115 
Cleanup()5116     virtual long Cleanup()
5117     {
5118         glDisableVertexAttribArray(0);
5119         glBindBuffer(GL_ARRAY_BUFFER, 0);
5120         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
5121         glBindVertexArray(0);
5122         glUseProgram(0);
5123 
5124         if (_vao)
5125         {
5126             glDeleteVertexArrays(1, &_vao);
5127         }
5128         if (_vbo)
5129         {
5130             glDeleteBuffers(1, &_vbo);
5131         }
5132         if (_ebo)
5133         {
5134             glDeleteBuffers(1, &_ebo);
5135         }
5136         if (_ubo)
5137         {
5138             glDeleteBuffers(1, &_ubo);
5139         }
5140         if (_bufferIndirect)
5141         {
5142             glDeleteBuffers(1, &_bufferIndirect);
5143         }
5144         if (_program)
5145         {
5146             glDeleteProgram(_program);
5147         }
5148         return NO_ERROR;
5149     }
5150 
CTransformFeedback(TDrawFunction drawFunc)5151     CTransformFeedback(TDrawFunction drawFunc)
5152         : _drawFunc(drawFunc)
5153         , _program(0)
5154         , _vao(0)
5155         , _vbo(0)
5156         , _ebo(0)
5157         , _ubo(0)
5158         , _bufferIndirect(0)
5159     {
5160     }
5161 
5162 private:
5163     TDrawFunction _drawFunc;
5164     GLuint _program;
5165     GLuint _vao, _vbo, _ebo, _ubo, _bufferIndirect;
5166 
5167     CTransformFeedback();
5168 
5169     template <typename api>
Vsh()5170     std::string Vsh()
5171     {
5172         return api::glslVer() + NL "flat out highp uint dataOut;" NL "in vec4 i_vertex;" NL
5173                                    "layout(std140) uniform  BLOCK {" NL " uint m[5];" NL "} b;" NL "void main() {" NL
5174                                    "  dataOut = b.m[min(4, gl_VertexID)];" NL "    gl_Position = i_vertex;" NL "}";
5175     }
5176 };
5177 
5178 template <typename api>
5179 struct CTransformFeedbackArray : public CTransformFeedback
5180 {
Titleglcts::__anon253d27190111::CTransformFeedbackArray5181     virtual std::string Title()
5182     {
5183         return "Transform feedback: glDrawArrayIndirect";
5184     }
5185 
Purposeglcts::__anon253d27190111::CTransformFeedbackArray5186     virtual std::string Purpose()
5187     {
5188         return "Verify that transform feedback works correctly with glDrawArrayIndirect";
5189     }
5190 
Methodglcts::__anon253d27190111::CTransformFeedbackArray5191     virtual std::string Method()
5192     {
5193         return "1. Create data" NL "2. Use data as input to glDrawArrayIndirect" NL "3. Verify results";
5194     }
5195 
PassCriteriaglcts::__anon253d27190111::CTransformFeedbackArray5196     virtual std::string PassCriteria()
5197     {
5198         return "The test will pass if no OpenGL errors reported";
5199     }
5200 
CTransformFeedbackArrayglcts::__anon253d27190111::CTransformFeedbackArray5201     CTransformFeedbackArray() : CTransformFeedback(DRAW_ARRAYS)
5202     {
5203     }
5204 
Runglcts::__anon253d27190111::CTransformFeedbackArray5205     virtual long Run()
5206     {
5207         return CTransformFeedback::Run<api>();
5208     }
5209 };
5210 
5211 template <typename api>
5212 struct CTransformFeedbackElements : public CTransformFeedback
5213 {
Titleglcts::__anon253d27190111::CTransformFeedbackElements5214     virtual std::string Title()
5215     {
5216         return "Transform feedback: glDrawElementsIndirect";
5217     }
5218 
Purposeglcts::__anon253d27190111::CTransformFeedbackElements5219     virtual std::string Purpose()
5220     {
5221         return "Verify that transform feedback works correctly with glDrawElementsIndirect";
5222     }
5223 
Methodglcts::__anon253d27190111::CTransformFeedbackElements5224     virtual std::string Method()
5225     {
5226         return "1. Create data" NL "2. Use data as input to glDrawElementsIndirect" NL "3. Verify results";
5227     }
5228 
PassCriteriaglcts::__anon253d27190111::CTransformFeedbackElements5229     virtual std::string PassCriteria()
5230     {
5231         return "The test will pass if no OpenGL errors reported";
5232     }
5233 
CTransformFeedbackElementsglcts::__anon253d27190111::CTransformFeedbackElements5234     CTransformFeedbackElements() : CTransformFeedback(DRAW_ELEMENTS)
5235     {
5236     }
5237 
Runglcts::__anon253d27190111::CTransformFeedbackElements5238     virtual long Run()
5239     {
5240         return CTransformFeedback::Run<api>();
5241     }
5242 };
5243 
5244 class CComputeBase : public DrawIndirectBase
5245 {
5246 public:
Setup()5247     virtual long Setup()
5248     {
5249         glClear(GL_COLOR_BUFFER_BIT);
5250         return NO_ERROR;
5251     }
5252 
5253     template <typename api>
Run()5254     long Run()
5255     {
5256 
5257         int width, height;
5258         glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &width);
5259         glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &height);
5260 
5261         width  = std::min(width, getWindowWidth());
5262         height = std::min(height, getWindowHeight());
5263 
5264         glViewport(0, 0, width, height);
5265 
5266         CColorArray coords(width * height, tcu::Vec4(0));
5267         CColorArray colors(width * height, tcu::Vec4(0));
5268 
5269         _program = CreateProgram(Vsh<api>(), "", Fsh<api>(), false);
5270         glBindAttribLocation(_program, 0, "in_coords");
5271         glBindAttribLocation(_program, 1, "in_colors");
5272         glLinkProgram(_program);
5273         if (!CheckProgram(_program))
5274         {
5275             return ERROR;
5276         }
5277         glUseProgram(_program);
5278 
5279         glGenVertexArrays(1, &_vao);
5280         glBindVertexArray(_vao);
5281 
5282         glGenBuffers(1, &_bufferCoords);
5283         glBindBuffer(GL_ARRAY_BUFFER, _bufferCoords);
5284         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), 0, GL_STREAM_DRAW);
5285 
5286         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
5287         glEnableVertexAttribArray(0);
5288 
5289         glGenBuffers(1, &_bufferColors);
5290         glBindBuffer(GL_ARRAY_BUFFER, _bufferColors);
5291         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(colors.size() * sizeof(colors[0])), 0, GL_STREAM_DRAW);
5292 
5293         glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
5294         glEnableVertexAttribArray(1);
5295 
5296         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
5297         DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
5298 
5299         CElementArray elements(width * height, 0);
5300         for (size_t i = 0; i < elements.size(); ++i)
5301         {
5302             elements[i] = static_cast<GLuint>(i);
5303         }
5304 
5305         glGenBuffers(1, &_bufferIndirect);
5306         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
5307         switch (_drawFunc)
5308         {
5309         case DRAW_ARRAYS:
5310         {
5311             glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
5312         }
5313         break;
5314         case DRAW_ELEMENTS:
5315         {
5316             glGenBuffers(1, &_ebo);
5317             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
5318             glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
5319                          GL_STATIC_DRAW);
5320 
5321             glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements,
5322                          GL_STATIC_DRAW);
5323         }
5324         break;
5325         default:
5326             throw std::runtime_error("Unknown draw function!");
5327             break;
5328         }
5329 
5330         _programCompute = CreateComputeProgram(Csh<api>(), false);
5331         glLinkProgram(_programCompute);
5332         if (!CheckProgram(_programCompute))
5333         {
5334             return ERROR;
5335         }
5336         glUseProgram(_programCompute);
5337         glUniform1ui(glGetUniformLocation(_programCompute, "width"), width);
5338         glUniform1ui(glGetUniformLocation(_programCompute, "height"), height);
5339         glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, _bufferCoords);
5340         glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, _bufferColors);
5341         glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, _bufferIndirect);
5342 
5343         glDispatchCompute(width, height, 1);
5344         glMemoryBarrier(GL_COMMAND_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT);
5345 
5346         glUseProgram(_program);
5347 
5348         switch (_drawFunc)
5349         {
5350         case DRAW_ARRAYS:
5351         {
5352             glDrawArraysIndirect(GL_POINTS, 0);
5353         }
5354         break;
5355         case DRAW_ELEMENTS:
5356         {
5357             glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, 0);
5358         }
5359         break;
5360         default:
5361             throw std::runtime_error("Unknown draw function!");
5362             break;
5363         }
5364 
5365         CColorArray bufferRef1(width * height / 4, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
5366         CColorArray bufferRef2(width * height / 4, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
5367         CColorArray bufferRef3(width * height / 4, tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f));
5368         CColorArray bufferRef4(width * height / 4, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f));
5369         CColorArray bufferTest(width * height / 4, tcu::Vec4(0.0f));
5370 
5371         DIResult result;
5372         ReadPixelsFloat<api>(0, 0, width / 2, height / 2, &bufferTest[0]);
5373         result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef1, width / 2, height / 2))
5374             << "Region 0 verification failed";
5375 
5376         ReadPixelsFloat<api>((width + 1) / 2, 0, width / 2, height / 2, &bufferTest[0]);
5377         result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef2, width / 2, height / 2))
5378             << "Region 1 verification failed";
5379 
5380         ReadPixelsFloat<api>(0, (height + 1) / 2, width / 2, height / 2, &bufferTest[0]);
5381         result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef3, width / 2, height / 2))
5382             << "Region 2 verification failed";
5383 
5384         ReadPixelsFloat<api>((width + 1) / 2, (height + 1) / 2, width / 2, height / 2, &bufferTest[0]);
5385         result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef4, width / 2, height / 2))
5386             << "Region 3 verification failed";
5387 
5388         return result.code();
5389     }
5390 
Cleanup()5391     virtual long Cleanup()
5392     {
5393         glDisableVertexAttribArray(1);
5394         glDisableVertexAttribArray(0);
5395         glDeleteProgram(_program);
5396         glDeleteProgram(_programCompute);
5397         glDeleteVertexArrays(1, &_vao);
5398         if (_ebo)
5399             glDeleteBuffers(1, &_ebo);
5400         glDeleteBuffers(1, &_bufferCoords);
5401         glDeleteBuffers(1, &_bufferColors);
5402         glDeleteBuffers(1, &_bufferIndirect);
5403         glViewport(0, 0, getWindowWidth(), getWindowHeight());
5404         return NO_ERROR;
5405     }
CComputeBase(TDrawFunction drawFunc)5406     CComputeBase(TDrawFunction drawFunc)
5407         : _drawFunc(drawFunc)
5408         , _program(0)
5409         , _programCompute(0)
5410         , _vao(0)
5411         , _ebo(0)
5412         , _bufferCoords(0)
5413         , _bufferColors(0)
5414         , _bufferIndirect(0)
5415     {
5416     }
5417 
5418 private:
5419     CComputeBase();
5420     TDrawFunction _drawFunc;
5421 
5422     template <typename api>
Vsh()5423     std::string Vsh()
5424     {
5425         return api::glslVer() + NL "in vec4 in_coords;" NL "in vec4 in_colors;" NL "out vec4 colors;" NL
5426                                    "void main() {" NL "  colors = in_colors;" NL "  gl_Position = in_coords;" NL
5427                                    "#if defined(GL_ES)" NL "  gl_PointSize = 1.0;" NL "#endif" NL "}";
5428     }
5429 
5430     template <typename api>
Fsh()5431     std::string Fsh()
5432     {
5433         return api::glslVer() + NL "precision highp float;" NL "in vec4 colors;" NL "out vec4 outColor;" NL
5434                                    "void main() {" NL "  outColor = colors;" NL "}";
5435     }
5436 
5437     template <typename api>
Csh()5438     std::string Csh()
5439     {
5440         return api::glslVer(true) + NL "precision highp int;                                           " NL
5441                                        "precision highp float;                                         " NL
5442                                        "                                                               " NL
5443                                        "layout(local_size_x = 1) in;                                   " NL
5444                                        "layout(std430, binding = 0) buffer Vertices {                  " NL
5445                                        "    vec4 vertices[];                                           " NL
5446                                        "};                                                             " NL
5447                                        "layout(std430, binding = 1) buffer Colors {                    " NL
5448                                        "    vec4 colors[];                                             " NL
5449                                        "};                                                             " NL
5450                                        "layout(std430, binding = 2) buffer Indirect {                  " NL
5451                                        "    uint indirect[4];                                          " NL
5452                                        "};                                                             " NL
5453                                        "                                                               " NL
5454                                        "uniform uint height;                                           " NL
5455                                        "uniform uint width;                                            " NL
5456                                        "                                                               " NL
5457                                        "void main() {                                                  " NL
5458                                        "    uint w = gl_GlobalInvocationID.x;                          " NL
5459                                        "    uint h = gl_GlobalInvocationID.y;                          " NL
5460                                        "    float stepX = 2.0 / float(width);                          " NL
5461                                        "    float stepY = 2.0 / float(height);                         " NL
5462                                        "    float offsetX = -1.0 + stepX * float(w) + stepX / 2.0;     " NL
5463                                        "    float offsetY = -1.0 + stepY * float(h) + stepY / 2.0;     " NL
5464                                        "    uint arrayOffset = h * width + w;                          " NL
5465                                        "    vertices[ arrayOffset ] = vec4(offsetX, offsetY, 0.0, 1.0);" NL
5466                                        "    vec4 color = vec4(0.0, 0.0, 0.0, 1.0);                     " NL
5467                                        "    if(w > (width / 2u - 1u)) {                                " NL
5468                                        "        color = color + vec4(0.5, 0.0, 0.0, 0.0);              " NL
5469                                        "    }                                                          " NL
5470                                        "    if(h > (height / 2u - 1u)) {                               " NL
5471                                        "        color = color + vec4(0.0, 0.5, 0.0, 0.0);              " NL
5472                                        "    }                                                          " NL
5473                                        "    colors[ arrayOffset ] = color;                             " NL
5474                                        "    if(w == 0u && h == 0u) {                                   " NL
5475                                        "        indirect[0] = width * height;                          " NL
5476                                        "        indirect[1] =  1u;                                     " NL
5477                                        "    }                                                          " NL
5478                                        "}                                                              ";
5479     }
5480 
5481     GLuint _program, _programCompute;
5482     GLuint _vao;
5483     GLuint _ebo;
5484     GLuint _bufferCoords;
5485     GLuint _bufferColors;
5486     GLuint _bufferIndirect;
5487 };
5488 
5489 template <typename api>
5490 struct CComputeShaderArray : public CComputeBase
5491 {
Titleglcts::__anon253d27190111::CComputeShaderArray5492     virtual std::string Title()
5493     {
5494         return "Compute Shader: glDrawArrayIndirect";
5495     }
5496 
Purposeglcts::__anon253d27190111::CComputeShaderArray5497     virtual std::string Purpose()
5498     {
5499         return "Verify that data created by Compute Shader can be used as an input to glDrawArrayIndirect";
5500     }
5501 
Methodglcts::__anon253d27190111::CComputeShaderArray5502     virtual std::string Method()
5503     {
5504         return "1. Create data by Compute Shader" NL "2. Use data as input to glDrawArrayIndirect" NL
5505                "3. Verify results";
5506     }
5507 
PassCriteriaglcts::__anon253d27190111::CComputeShaderArray5508     virtual std::string PassCriteria()
5509     {
5510         return "The test will pass if no OpenGL errors reported";
5511     }
5512 
CComputeShaderArrayglcts::__anon253d27190111::CComputeShaderArray5513     CComputeShaderArray() : CComputeBase(DRAW_ARRAYS)
5514     {
5515     }
5516 
Runglcts::__anon253d27190111::CComputeShaderArray5517     virtual long Run()
5518     {
5519         return CComputeBase::Run<api>();
5520     }
5521 };
5522 
5523 template <typename api>
5524 struct CComputeShaderElements : public CComputeBase
5525 {
Titleglcts::__anon253d27190111::CComputeShaderElements5526     virtual std::string Title()
5527     {
5528         return "Compute Shader: glDrawElementsIndirect";
5529     }
5530 
Purposeglcts::__anon253d27190111::CComputeShaderElements5531     virtual std::string Purpose()
5532     {
5533         return "Verify that data created by Compute Shader can be used as an input to glDrawElementsIndirect";
5534     }
5535 
Methodglcts::__anon253d27190111::CComputeShaderElements5536     virtual std::string Method()
5537     {
5538         return "1. Create data by Compute Shader" NL "2. Use data as input to glDrawElementsIndirect" NL
5539                "3. Verify results";
5540     }
5541 
PassCriteriaglcts::__anon253d27190111::CComputeShaderElements5542     virtual std::string PassCriteria()
5543     {
5544         return "The test will pass if no OpenGL errors reported";
5545     }
5546 
CComputeShaderElementsglcts::__anon253d27190111::CComputeShaderElements5547     CComputeShaderElements() : CComputeBase(DRAW_ELEMENTS)
5548     {
5549     }
5550 
Runglcts::__anon253d27190111::CComputeShaderElements5551     virtual long Run()
5552     {
5553         return CComputeBase::Run<api>();
5554     }
5555 };
5556 
5557 template <typename api>
5558 class CPrimitiveRestartElements : public DrawIndirectBase
5559 {
5560 public:
Title()5561     virtual std::string Title()
5562     {
5563         return "Primitive restart - glDrawElementsIndirect";
5564     }
5565 
Purpose()5566     virtual std::string Purpose()
5567     {
5568         return "Verify that primitive restart works correctly with glDrawElementsIndirect";
5569     }
5570 
Method()5571     virtual std::string Method()
5572     {
5573         return "1. Define primitives using VBO" NL "2. Draw primitives using glDrawElementsIndirect" NL
5574                "3. Verify results";
5575     }
5576 
PassCriteria()5577     virtual std::string PassCriteria()
5578     {
5579         return "The test will pass if no OpenGL errors reported";
5580     }
5581 
Setup()5582     virtual long Setup()
5583     {
5584         glClear(GL_COLOR_BUFFER_BIT);
5585         return NO_ERROR;
5586     }
5587 
5588     int PrimitiveRestartIndex();
5589 
5590     void EnablePrimitiveRestart();
5591 
5592     void DisablePrimitiveRestart();
5593 
Run()5594     virtual long Run()
5595     {
5596         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
5597         if (!_program)
5598         {
5599             return ERROR;
5600         }
5601         glUseProgram(_program);
5602 
5603         CColorArray coords1;
5604         TriangleStipGen(coords1, -1.0f, 1.0f, -1.0, -0.5, 2);
5605 
5606         CColorArray coords2;
5607         TriangleStipGen(coords2, -1.0f, 1.0f, 0.5, 1.0, 4);
5608 
5609         glGenVertexArrays(1, &_vao);
5610         glBindVertexArray(_vao);
5611 
5612         glGenBuffers(1, &_buffer);
5613         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
5614 
5615         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords1.size() + coords2.size()) * sizeof(coords1[0]), NULL,
5616                      GL_STREAM_DRAW);
5617         glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(coords1.size() * sizeof(coords1[0])), &coords1[0]);
5618         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(coords1.size() * sizeof(coords1[0])),
5619                         (GLsizeiptr)(coords2.size() * sizeof(coords2[0])), &coords2[0]);
5620         glVertexAttribPointer(0, sizeof(coords1[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords1[0]), 0);
5621         glEnableVertexAttribArray(0);
5622 
5623         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
5624         indirectElements.count                       = static_cast<GLuint>(coords1.size() + coords2.size() + 1);
5625         indirectElements.primCount                   = static_cast<GLuint>((coords1.size() + coords2.size()) / 2);
5626 
5627         CElementArray elements;
5628         for (size_t i = 0; i < coords1.size(); ++i)
5629         {
5630             elements.push_back(static_cast<GLuint>(i));
5631         }
5632 
5633         elements.push_back(PrimitiveRestartIndex());
5634         for (size_t i = 0; i < coords2.size(); ++i)
5635         {
5636             elements.push_back(static_cast<GLuint>(coords1.size() + i));
5637         }
5638 
5639         glGenBuffers(1, &_bufferIndirect);
5640         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
5641         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
5642 
5643         glGenBuffers(1, &_ebo);
5644         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
5645         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
5646                      GL_STATIC_DRAW);
5647 
5648         EnablePrimitiveRestart();
5649 
5650         glDrawElementsIndirect(GL_TRIANGLE_STRIP, GL_UNSIGNED_INT, 0);
5651 
5652         CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 4, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
5653         CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f));
5654         CColorArray bufferTest1(getWindowWidth() * getWindowHeight() / 4, tcu::Vec4(0.0f));
5655         CColorArray bufferTest2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f));
5656 
5657         DIResult result;
5658         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 4, &bufferTest1[0]);
5659         result.sub_result(BuffersCompare(bufferTest1, getWindowWidth(), getWindowHeight() / 4, bufferRef1,
5660                                          getWindowWidth(), getWindowHeight() / 4));
5661         // height = 2 * (getWindowHeight() / 4)  to avoid border pixels
5662         // in case the height is not a multiple of 4.
5663         ReadPixelsFloat<api>(0, (getWindowHeight() + 3) / 4, getWindowWidth(), 2 * (getWindowHeight() / 4),
5664                              &bufferTest2[0]);
5665         result.sub_result(BuffersCompare(bufferTest2, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
5666                                          getWindowWidth(), 2 * (getWindowHeight() / 4)));
5667 
5668         ReadPixelsFloat<api>(0, (getWindowHeight() * 3 + 3) / 4, getWindowWidth(), getWindowHeight() / 4,
5669                              &bufferTest1[0]);
5670         result.sub_result(BuffersCompare(bufferTest1, getWindowWidth(), getWindowHeight() / 4, bufferRef1,
5671                                          getWindowWidth(), getWindowHeight() / 4));
5672 
5673         return result.code();
5674     }
5675 
Cleanup()5676     virtual long Cleanup()
5677     {
5678 
5679         DisablePrimitiveRestart();
5680         glDisableVertexAttribArray(0);
5681         glUseProgram(0);
5682         glDeleteProgram(_program);
5683         glDeleteVertexArrays(1, &_vao);
5684         glDeleteBuffers(1, &_buffer);
5685         glDeleteBuffers(1, &_ebo);
5686         glDeleteBuffers(1, &_bufferIndirect);
5687         return NO_ERROR;
5688     }
5689 
5690 private:
TriangleStipGen(CColorArray & coords,float widthStart,float widthEnd,float heightStart,float heightEnd,unsigned int primNum)5691     void TriangleStipGen(CColorArray &coords, float widthStart, float widthEnd, float heightStart, float heightEnd,
5692                          unsigned int primNum)
5693     {
5694         float widthStep  = (widthEnd - widthStart) / static_cast<float>(primNum);
5695         float heightStep = (heightEnd - heightStart) / static_cast<float>(primNum);
5696         for (unsigned int i = 0; i < primNum; ++i)
5697         {
5698             float heightOffset = heightStart + heightStep * static_cast<float>(i);
5699             for (unsigned int j = 0; j < primNum; ++j)
5700             {
5701                 float widthOffset = widthStart + widthStep * static_cast<float>(j);
5702 
5703                 coords.push_back(tcu::Vec4(widthOffset, heightOffset, 0.0f, 1.0f));
5704                 coords.push_back(tcu::Vec4(widthOffset, heightOffset + heightStep, 0.0f, 1.0f));
5705                 coords.push_back(tcu::Vec4(widthOffset + widthStep, heightOffset, 0.0f, 1.0f));
5706                 coords.push_back(tcu::Vec4(widthOffset + widthStep, heightOffset + heightStep, 0.0f, 1.0f));
5707             }
5708         }
5709     }
5710     GLuint _program;
5711     GLuint _vao, _buffer, _ebo, _bufferIndirect;
5712 };
5713 
5714 template <>
PrimitiveRestartIndex()5715 int CPrimitiveRestartElements<test_api::ES3>::PrimitiveRestartIndex()
5716 {
5717     return 0xffffffff;
5718 }
5719 
5720 template <>
PrimitiveRestartIndex()5721 int CPrimitiveRestartElements<test_api::GL>::PrimitiveRestartIndex()
5722 {
5723     return 3432432;
5724 }
5725 
5726 template <>
DisablePrimitiveRestart()5727 void CPrimitiveRestartElements<test_api::ES3>::DisablePrimitiveRestart()
5728 {
5729     glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
5730 }
5731 
5732 template <>
DisablePrimitiveRestart()5733 void CPrimitiveRestartElements<test_api::GL>::DisablePrimitiveRestart()
5734 {
5735     glDisable(GL_PRIMITIVE_RESTART);
5736 }
5737 
5738 template <>
EnablePrimitiveRestart()5739 void CPrimitiveRestartElements<test_api::ES3>::EnablePrimitiveRestart()
5740 {
5741     glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
5742 }
5743 
5744 template <>
EnablePrimitiveRestart()5745 void CPrimitiveRestartElements<test_api::GL>::EnablePrimitiveRestart()
5746 {
5747     glPrimitiveRestartIndex(PrimitiveRestartIndex());
5748     glEnable(GL_PRIMITIVE_RESTART);
5749 }
5750 
5751 template <typename api>
5752 struct CNegativeZeroBufferArray : public DrawIndirectBase
5753 {
Titleglcts::__anon253d27190111::CNegativeZeroBufferArray5754     virtual std::string Title()
5755     {
5756         return "Negative: no indirect buffer/parameter - glDrawArrayIndirect";
5757     }
5758 
Purposeglcts::__anon253d27190111::CNegativeZeroBufferArray5759     virtual std::string Purpose()
5760     {
5761         return "Verify that a driver sets error and no driver crash occurred";
5762     }
5763 
Methodglcts::__anon253d27190111::CNegativeZeroBufferArray5764     virtual std::string Method()
5765     {
5766         return "Call glDrawArrayIndirect";
5767     }
5768 
PassCriteriaglcts::__anon253d27190111::CNegativeZeroBufferArray5769     virtual std::string PassCriteria()
5770     {
5771         return "The test will pass if OpenGL errors reported and no driver crash occurred";
5772     }
5773 
Setupglcts::__anon253d27190111::CNegativeZeroBufferArray5774     virtual long Setup()
5775     {
5776         glClear(GL_COLOR_BUFFER_BIT);
5777         return NO_ERROR;
5778     }
5779 
Runglcts::__anon253d27190111::CNegativeZeroBufferArray5780     virtual long Run()
5781     {
5782         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
5783         if (!_program)
5784         {
5785             return ERROR;
5786         }
5787         glUseProgram(_program);
5788 
5789         CColorArray coords;
5790         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
5791 
5792         glGenVertexArrays(1, &_vao);
5793         glBindVertexArray(_vao);
5794 
5795         glGenBuffers(1, &_buffer);
5796         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
5797         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
5798 
5799         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
5800         glEnableVertexAttribArray(0);
5801 
5802         glDrawArraysIndirect(GL_TRIANGLES, 0);
5803         DIResult result;
5804         if (glGetError() != GL_INVALID_OPERATION)
5805         {
5806             result.error() << "Invalid error code returned by a driver";
5807         }
5808 
5809         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
5810         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
5811 
5812         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
5813         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
5814                                          getWindowHeight()));
5815 
5816         return result.code();
5817     }
5818 
Cleanupglcts::__anon253d27190111::CNegativeZeroBufferArray5819     virtual long Cleanup()
5820     {
5821         glDisableVertexAttribArray(0);
5822         glUseProgram(0);
5823         glDeleteProgram(_program);
5824         glDeleteVertexArrays(1, &_vao);
5825         glDeleteBuffers(1, &_buffer);
5826         return NO_ERROR;
5827     }
5828 
5829 private:
5830     GLuint _program;
5831     GLuint _vao, _buffer;
5832 };
5833 
5834 template <typename api>
5835 struct CNegativeZeroBufferElements : public DrawIndirectBase
5836 {
Titleglcts::__anon253d27190111::CNegativeZeroBufferElements5837     virtual std::string Title()
5838     {
5839         return "Negative: no indirect buffer/parameter - glDrawElementsIndirect";
5840     }
5841 
Purposeglcts::__anon253d27190111::CNegativeZeroBufferElements5842     virtual std::string Purpose()
5843     {
5844         return "Verify that a driver sets error and no driver crash occurred";
5845     }
5846 
Methodglcts::__anon253d27190111::CNegativeZeroBufferElements5847     virtual std::string Method()
5848     {
5849         return "Call glDrawElementsIndirect";
5850     }
5851 
PassCriteriaglcts::__anon253d27190111::CNegativeZeroBufferElements5852     virtual std::string PassCriteria()
5853     {
5854         return "The test will pass if OpenGL errors reported and no driver crash occurred";
5855     }
5856 
Setupglcts::__anon253d27190111::CNegativeZeroBufferElements5857     virtual long Setup()
5858     {
5859         glClear(GL_COLOR_BUFFER_BIT);
5860         return NO_ERROR;
5861     }
5862 
Runglcts::__anon253d27190111::CNegativeZeroBufferElements5863     virtual long Run()
5864     {
5865         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
5866         if (!_program)
5867         {
5868             return ERROR;
5869         }
5870         glUseProgram(_program);
5871 
5872         CColorArray coords;
5873         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
5874 
5875         glGenVertexArrays(1, &_vao);
5876         glBindVertexArray(_vao);
5877 
5878         glGenBuffers(1, &_buffer);
5879         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
5880 
5881         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
5882         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
5883         glEnableVertexAttribArray(0);
5884 
5885         CElementArray elements(coords.size(), 0);
5886         for (size_t i = 0; i < elements.size(); ++i)
5887         {
5888             elements[i] = static_cast<GLuint>(i);
5889         }
5890 
5891         glGenBuffers(1, &_ebo);
5892         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
5893         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
5894                      GL_STATIC_DRAW);
5895 
5896         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
5897 
5898         DIResult result;
5899         if (glGetError() != GL_INVALID_OPERATION)
5900         {
5901             result.error() << "Invalid error code returned by a driver";
5902         }
5903 
5904         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
5905         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
5906 
5907         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
5908         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
5909                                          getWindowHeight()));
5910 
5911         return result.code();
5912     }
5913 
Cleanupglcts::__anon253d27190111::CNegativeZeroBufferElements5914     virtual long Cleanup()
5915     {
5916         glDisableVertexAttribArray(0);
5917         glUseProgram(0);
5918         glDeleteProgram(_program);
5919         glDeleteVertexArrays(1, &_vao);
5920         glDeleteBuffers(1, &_buffer);
5921         glDeleteBuffers(1, &_ebo);
5922         return NO_ERROR;
5923     }
5924 
5925 private:
5926     GLuint _program;
5927     GLuint _vao, _buffer, _ebo;
5928 };
5929 
5930 template <typename api>
5931 struct CNegativeInvalidModeArray : public DrawIndirectBase
5932 {
Titleglcts::__anon253d27190111::CNegativeInvalidModeArray5933     virtual std::string Title()
5934     {
5935         return "Negative: invalid mode - glDrawArrayIndirect";
5936     }
5937 
Purposeglcts::__anon253d27190111::CNegativeInvalidModeArray5938     virtual std::string Purpose()
5939     {
5940         return "Verify that a driver sets error and no driver crash occurred";
5941     }
5942 
Methodglcts::__anon253d27190111::CNegativeInvalidModeArray5943     virtual std::string Method()
5944     {
5945         return "Set invalid mode to glDrawArrayIndirect";
5946     }
5947 
PassCriteriaglcts::__anon253d27190111::CNegativeInvalidModeArray5948     virtual std::string PassCriteria()
5949     {
5950         return "The test will pass if OpenGL errors reported and no driver crash occurred";
5951     }
5952 
Setupglcts::__anon253d27190111::CNegativeInvalidModeArray5953     virtual long Setup()
5954     {
5955         glClear(GL_COLOR_BUFFER_BIT);
5956         return NO_ERROR;
5957     }
5958 
Runglcts::__anon253d27190111::CNegativeInvalidModeArray5959     virtual long Run()
5960     {
5961         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
5962         if (!_program)
5963         {
5964             return ERROR;
5965         }
5966         glUseProgram(_program);
5967 
5968         CColorArray coords;
5969         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
5970 
5971         glGenVertexArrays(1, &_vao);
5972         glBindVertexArray(_vao);
5973 
5974         glGenBuffers(1, &_buffer);
5975         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
5976 
5977         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
5978         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
5979         glEnableVertexAttribArray(0);
5980 
5981         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
5982         indirectArrays.count                     = static_cast<GLuint>(coords.size());
5983         indirectArrays.primCount                 = 1;
5984 
5985         glGenBuffers(1, &_bufferIndirect);
5986         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
5987         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
5988 
5989         glDrawArraysIndirect(GL_FLOAT, 0);
5990 
5991         DIResult result;
5992         if (glGetError() != GL_INVALID_ENUM)
5993         {
5994             result.error() << "Invalid error code returned by a driver for GL_FLOAT as mode";
5995         }
5996 
5997         glDrawArraysIndirect(GL_STATIC_DRAW, 0);
5998         if (glGetError() != GL_INVALID_ENUM)
5999         {
6000             result.error() << "Invalid error code returned by a driver for GL_STATIC_DRAW as mode";
6001         }
6002 
6003         glDrawArraysIndirect(GL_DRAW_INDIRECT_BUFFER, 0);
6004         if (glGetError() != GL_INVALID_ENUM)
6005         {
6006             result.error() << "Invalid error code returned by a driver for GL_DRAW_INDIRECT_BUFFER as mode";
6007         }
6008 
6009         glDrawArraysIndirect(GL_INVALID_ENUM, 0);
6010         if (glGetError() != GL_INVALID_ENUM)
6011         {
6012             result.error() << "Invalid error code returned by a driver for GL_INVALID_ENUM as mode";
6013         }
6014 
6015         glDrawArraysIndirect(GL_COLOR_BUFFER_BIT, 0);
6016         if (glGetError() != GL_INVALID_ENUM)
6017         {
6018             result.error() << "Invalid error code returned by a driver for GL_COLOR_BUFFER_BIT as mode";
6019         }
6020 
6021         glDrawArraysIndirect(GL_ARRAY_BUFFER, 0);
6022         if (glGetError() != GL_INVALID_ENUM)
6023         {
6024             result.error() << "Invalid error code returned by a driver for GL_ARRAY_BUFFER as mode";
6025         }
6026 
6027         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6028         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6029 
6030         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6031         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6032                                          getWindowHeight()));
6033 
6034         return result.code();
6035     }
6036 
Cleanupglcts::__anon253d27190111::CNegativeInvalidModeArray6037     virtual long Cleanup()
6038     {
6039         glDisableVertexAttribArray(0);
6040         glUseProgram(0);
6041         glDeleteProgram(_program);
6042         glDeleteVertexArrays(1, &_vao);
6043         glDeleteBuffers(1, &_buffer);
6044         glDeleteBuffers(1, &_bufferIndirect);
6045         return NO_ERROR;
6046     }
6047 
6048 private:
6049     GLuint _program;
6050     GLuint _vao, _buffer, _bufferIndirect;
6051 };
6052 
6053 template <typename api>
6054 struct CNegativeInvalidModeElements : public DrawIndirectBase
6055 {
Titleglcts::__anon253d27190111::CNegativeInvalidModeElements6056     virtual std::string Title()
6057     {
6058         return "Negative: invalid mode - glDrawElementsIndirect";
6059     }
6060 
Purposeglcts::__anon253d27190111::CNegativeInvalidModeElements6061     virtual std::string Purpose()
6062     {
6063         return "Verify that a driver sets error and no driver crash occurred";
6064     }
6065 
Methodglcts::__anon253d27190111::CNegativeInvalidModeElements6066     virtual std::string Method()
6067     {
6068         return "Set invalid mode to glDrawElemenetsIndirect";
6069     }
6070 
PassCriteriaglcts::__anon253d27190111::CNegativeInvalidModeElements6071     virtual std::string PassCriteria()
6072     {
6073         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6074     }
6075 
Setupglcts::__anon253d27190111::CNegativeInvalidModeElements6076     virtual long Setup()
6077     {
6078         glClear(GL_COLOR_BUFFER_BIT);
6079         return NO_ERROR;
6080     }
6081 
Runglcts::__anon253d27190111::CNegativeInvalidModeElements6082     virtual long Run()
6083     {
6084         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6085         if (!_program)
6086         {
6087             return ERROR;
6088         }
6089         glUseProgram(_program);
6090 
6091         CColorArray coords;
6092         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6093 
6094         glGenVertexArrays(1, &_vao);
6095         glBindVertexArray(_vao);
6096 
6097         glGenBuffers(1, &_buffer);
6098         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
6099 
6100         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
6101         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
6102         glEnableVertexAttribArray(0);
6103 
6104         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
6105         indirectElements.count                       = static_cast<GLuint>(coords.size());
6106         indirectElements.primCount                   = 1;
6107 
6108         CElementArray elements(coords.size(), 0);
6109         for (size_t i = 0; i < elements.size(); ++i)
6110         {
6111             elements[i] = static_cast<GLuint>(i);
6112         }
6113 
6114         glGenBuffers(1, &_bufferIndirect);
6115         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6116         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
6117 
6118         glGenBuffers(1, &_ebo);
6119         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
6120         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
6121                      GL_STATIC_DRAW);
6122 
6123         DIResult result;
6124         glDrawElementsIndirect(GL_INVALID_ENUM, GL_UNSIGNED_INT, 0);
6125         if (glGetError() != GL_INVALID_ENUM)
6126         {
6127             result.error() << "Invalid error code returned by a driver for GL_FLOAT as mode";
6128         }
6129 
6130         glDrawElementsIndirect(GL_UNSIGNED_INT, GL_UNSIGNED_INT, 0);
6131         if (glGetError() != GL_INVALID_ENUM)
6132         {
6133             result.error() << "Invalid error code returned by a driver for GL_UNSIGNED_INT as mode";
6134         }
6135 
6136         glDrawElementsIndirect(GL_ELEMENT_ARRAY_BUFFER, GL_UNSIGNED_INT, 0);
6137         if (glGetError() != GL_INVALID_ENUM)
6138         {
6139             result.error() << "Invalid error code returned by a driver for GL_ELEMENT_ARRAY_BUFFER as mode";
6140         }
6141 
6142         glDrawElementsIndirect(GL_FASTEST, GL_UNSIGNED_INT, 0);
6143         if (glGetError() != GL_INVALID_ENUM)
6144         {
6145             result.error() << "Invalid error code returned by a driver for GL_FASTEST as mode";
6146         }
6147 
6148         glDrawElementsIndirect(GL_PACK_ALIGNMENT, GL_UNSIGNED_INT, 0);
6149         if (glGetError() != GL_INVALID_ENUM)
6150         {
6151             result.error() << "Invalid error code returned by a driver for GL_PACK_ALIGNMENT as mode";
6152         }
6153 
6154         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6155         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6156 
6157         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6158         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6159                                          getWindowHeight()));
6160 
6161         return result.code();
6162     }
6163 
Cleanupglcts::__anon253d27190111::CNegativeInvalidModeElements6164     virtual long Cleanup()
6165     {
6166         glDisableVertexAttribArray(0);
6167         glUseProgram(0);
6168         glDeleteProgram(_program);
6169         glDeleteVertexArrays(1, &_vao);
6170         glDeleteBuffers(1, &_buffer);
6171         glDeleteBuffers(1, &_ebo);
6172         glDeleteBuffers(1, &_bufferIndirect);
6173         return NO_ERROR;
6174     }
6175 
6176 private:
6177     GLuint _program;
6178     GLuint _vao, _buffer, _ebo, _bufferIndirect;
6179 };
6180 
6181 template <typename api>
6182 struct CNegativeNoVAOArrays : public DrawIndirectBase
6183 {
Titleglcts::__anon253d27190111::CNegativeNoVAOArrays6184     virtual std::string Title()
6185     {
6186         return "Negative: no VAO - glDrawArraysIndirect";
6187     }
6188 
Purposeglcts::__anon253d27190111::CNegativeNoVAOArrays6189     virtual std::string Purpose()
6190     {
6191         return "Verify that a driver sets error and no driver crash occurred";
6192     }
6193 
Methodglcts::__anon253d27190111::CNegativeNoVAOArrays6194     virtual std::string Method()
6195     {
6196         return "Use glDrawArraysIndirect with default VAO";
6197     }
6198 
PassCriteriaglcts::__anon253d27190111::CNegativeNoVAOArrays6199     virtual std::string PassCriteria()
6200     {
6201         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6202     }
6203 
Setupglcts::__anon253d27190111::CNegativeNoVAOArrays6204     virtual long Setup()
6205     {
6206         glClear(GL_COLOR_BUFFER_BIT);
6207         return NO_ERROR;
6208     }
6209 
Runglcts::__anon253d27190111::CNegativeNoVAOArrays6210     virtual long Run()
6211     {
6212         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6213         if (!_program)
6214         {
6215             return ERROR;
6216         }
6217         glUseProgram(_program);
6218 
6219         CColorArray coords;
6220         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6221 
6222         glGenBuffers(1, &_buffer);
6223         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
6224 
6225         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
6226         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
6227         glEnableVertexAttribArray(0);
6228 
6229         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
6230         indirectArrays.count                     = static_cast<GLuint>(coords.size());
6231         indirectArrays.primCount                 = 1;
6232 
6233         glGenBuffers(1, &_bufferIndirect);
6234         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6235         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
6236 
6237         DIResult result;
6238         glDrawArraysIndirect(GL_TRIANGLES, 0);
6239         if (glGetError() != GL_INVALID_OPERATION)
6240         {
6241             result.error() << "Invalid error code returned by a driver";
6242         }
6243 
6244         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
6245             glDisableVertexAttribArray(0);
6246 
6247         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6248         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6249 
6250         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6251         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6252                                          getWindowHeight()));
6253 
6254         return result.code();
6255     }
6256 
Cleanupglcts::__anon253d27190111::CNegativeNoVAOArrays6257     virtual long Cleanup()
6258     {
6259 
6260         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
6261             glDisableVertexAttribArray(0);
6262 
6263         glUseProgram(0);
6264         glDeleteProgram(_program);
6265         glDeleteBuffers(1, &_buffer);
6266         glDeleteBuffers(1, &_bufferIndirect);
6267         return NO_ERROR;
6268     }
6269 
6270 private:
6271     GLuint _program;
6272     GLuint _buffer, _ebo, _bufferIndirect;
6273 };
6274 
6275 template <typename api>
6276 struct CNegativeNoVAOElements : public DrawIndirectBase
6277 {
Titleglcts::__anon253d27190111::CNegativeNoVAOElements6278     virtual std::string Title()
6279     {
6280         return "Negative: no VAO - glDrawElementsIndirect";
6281     }
6282 
Purposeglcts::__anon253d27190111::CNegativeNoVAOElements6283     virtual std::string Purpose()
6284     {
6285         return "Verify that a driver sets error and no driver crash occurred";
6286     }
6287 
Methodglcts::__anon253d27190111::CNegativeNoVAOElements6288     virtual std::string Method()
6289     {
6290         return "Use glDrawElemenetsIndirect with default VAO";
6291     }
6292 
PassCriteriaglcts::__anon253d27190111::CNegativeNoVAOElements6293     virtual std::string PassCriteria()
6294     {
6295         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6296     }
6297 
Setupglcts::__anon253d27190111::CNegativeNoVAOElements6298     virtual long Setup()
6299     {
6300         glClear(GL_COLOR_BUFFER_BIT);
6301         return NO_ERROR;
6302     }
6303 
Runglcts::__anon253d27190111::CNegativeNoVAOElements6304     virtual long Run()
6305     {
6306         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6307         if (!_program)
6308         {
6309             return ERROR;
6310         }
6311         glUseProgram(_program);
6312 
6313         CColorArray coords;
6314         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6315 
6316         glGenBuffers(1, &_buffer);
6317         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
6318 
6319         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
6320         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
6321         glEnableVertexAttribArray(0);
6322 
6323         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
6324         indirectElements.count                       = static_cast<GLuint>(coords.size());
6325         indirectElements.primCount                   = 1;
6326 
6327         CElementArray elements(coords.size(), 0);
6328         for (size_t i = 0; i < elements.size(); ++i)
6329         {
6330             elements[i] = static_cast<GLuint>(i);
6331         }
6332 
6333         glGenBuffers(1, &_bufferIndirect);
6334         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6335         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
6336 
6337         glGenBuffers(1, &_ebo);
6338         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
6339         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
6340                      GL_STATIC_DRAW);
6341 
6342         DIResult result;
6343         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
6344         if (glGetError() != GL_INVALID_OPERATION)
6345         {
6346             result.error() << "Invalid error code returned by a driver";
6347         }
6348 
6349         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
6350             glDisableVertexAttribArray(0);
6351 
6352         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6353         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6354 
6355         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6356         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6357                                          getWindowHeight()));
6358 
6359         return result.code();
6360     }
6361 
Cleanupglcts::__anon253d27190111::CNegativeNoVAOElements6362     virtual long Cleanup()
6363     {
6364         glUseProgram(0);
6365         glDeleteProgram(_program);
6366         glDeleteBuffers(1, &_buffer);
6367         glDeleteBuffers(1, &_ebo);
6368         glDeleteBuffers(1, &_bufferIndirect);
6369         return NO_ERROR;
6370     }
6371 
6372 private:
6373     GLuint _program;
6374     GLuint _buffer, _ebo, _bufferIndirect;
6375 };
6376 
6377 template <typename api>
6378 struct CNegativeNoVBOArrays : public DrawIndirectBase
6379 {
Titleglcts::__anon253d27190111::CNegativeNoVBOArrays6380     virtual std::string Title()
6381     {
6382         return "Negative: no VBO - glDrawArraysIndirect";
6383     }
6384 
Purposeglcts::__anon253d27190111::CNegativeNoVBOArrays6385     virtual std::string Purpose()
6386     {
6387         return "Verify that a driver sets error and no driver crash occurred";
6388     }
6389 
Methodglcts::__anon253d27190111::CNegativeNoVBOArrays6390     virtual std::string Method()
6391     {
6392         return "Use glDrawArraysIndirect with enabled vertex array, that has no VBO bound";
6393     }
6394 
PassCriteriaglcts::__anon253d27190111::CNegativeNoVBOArrays6395     virtual std::string PassCriteria()
6396     {
6397         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6398     }
6399 
Setupglcts::__anon253d27190111::CNegativeNoVBOArrays6400     virtual long Setup()
6401     {
6402         glClear(GL_COLOR_BUFFER_BIT);
6403         return NO_ERROR;
6404     }
6405 
Runglcts::__anon253d27190111::CNegativeNoVBOArrays6406     virtual long Run()
6407     {
6408         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6409         if (!_program)
6410         {
6411             return ERROR;
6412         }
6413         glUseProgram(_program);
6414 
6415         CColorArray coords;
6416         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6417 
6418         glGenVertexArrays(1, &_vao);
6419         glBindVertexArray(_vao);
6420         glEnableVertexAttribArray(0);
6421 
6422         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
6423         indirectArrays.count                     = static_cast<GLuint>(coords.size());
6424         indirectArrays.primCount                 = 1;
6425 
6426         glGenBuffers(1, &_bufferIndirect);
6427         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6428         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
6429 
6430         DIResult result;
6431         glDrawArraysIndirect(GL_TRIANGLES, 0);
6432         if (glGetError() != GL_INVALID_OPERATION)
6433         {
6434             result.error() << "Invalid error code returned by a driver";
6435         }
6436 
6437         glDisableVertexAttribArray(0);
6438 
6439         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6440         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6441 
6442         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6443         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6444                                          getWindowHeight()));
6445 
6446         return result.code();
6447     }
6448 
Cleanupglcts::__anon253d27190111::CNegativeNoVBOArrays6449     virtual long Cleanup()
6450     {
6451         glDisableVertexAttribArray(0);
6452         glUseProgram(0);
6453         glDeleteProgram(_program);
6454         glDeleteVertexArrays(1, &_vao);
6455         glDeleteBuffers(1, &_bufferIndirect);
6456         return NO_ERROR;
6457     }
6458 
6459 private:
6460     GLuint _program;
6461     GLuint _vao, _ebo, _bufferIndirect;
6462 };
6463 
6464 template <typename api>
6465 struct CNegativeNoVBOElements : public DrawIndirectBase
6466 {
Titleglcts::__anon253d27190111::CNegativeNoVBOElements6467     virtual std::string Title()
6468     {
6469         return "Negative: no VBO - glDrawElementsIndirect";
6470     }
6471 
Purposeglcts::__anon253d27190111::CNegativeNoVBOElements6472     virtual std::string Purpose()
6473     {
6474         return "Verify that a driver sets error and no driver crash occurred";
6475     }
6476 
Methodglcts::__anon253d27190111::CNegativeNoVBOElements6477     virtual std::string Method()
6478     {
6479         return "Use glDrawElementsIndirect with enabled vertex array, that has no VBO bound";
6480     }
6481 
PassCriteriaglcts::__anon253d27190111::CNegativeNoVBOElements6482     virtual std::string PassCriteria()
6483     {
6484         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6485     }
6486 
Setupglcts::__anon253d27190111::CNegativeNoVBOElements6487     virtual long Setup()
6488     {
6489         glClear(GL_COLOR_BUFFER_BIT);
6490         return NO_ERROR;
6491     }
6492 
Runglcts::__anon253d27190111::CNegativeNoVBOElements6493     virtual long Run()
6494     {
6495 
6496         api::ES_Only();
6497 
6498         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6499         if (!_program)
6500         {
6501             return ERROR;
6502         }
6503         glUseProgram(_program);
6504 
6505         CColorArray coords;
6506         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6507 
6508         glGenVertexArrays(1, &_vao);
6509         glBindVertexArray(_vao);
6510         glEnableVertexAttribArray(0);
6511         glEnableVertexAttribArray(0);
6512 
6513         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
6514         indirectElements.count                       = static_cast<GLuint>(coords.size());
6515         indirectElements.primCount                   = 1;
6516 
6517         CElementArray elements(coords.size(), 0);
6518         for (size_t i = 0; i < elements.size(); ++i)
6519         {
6520             elements[i] = static_cast<GLuint>(i);
6521         }
6522 
6523         glGenBuffers(1, &_bufferIndirect);
6524         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6525         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
6526 
6527         glGenBuffers(1, &_ebo);
6528         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
6529         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
6530                      GL_STATIC_DRAW);
6531 
6532         DIResult result;
6533         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
6534         if (glGetError() != GL_INVALID_OPERATION)
6535         {
6536             result.error() << "Invalid error code returned by a driver";
6537         }
6538 
6539         glDisableVertexAttribArray(0);
6540 
6541         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6542         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6543 
6544         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6545         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6546                                          getWindowHeight()));
6547 
6548         return result.code();
6549     }
6550 
Cleanupglcts::__anon253d27190111::CNegativeNoVBOElements6551     virtual long Cleanup()
6552     {
6553         glDisableVertexAttribArray(0);
6554         glUseProgram(0);
6555         glDeleteProgram(_program);
6556         glDeleteVertexArrays(1, &_vao);
6557         glDeleteBuffers(1, &_ebo);
6558         glDeleteBuffers(1, &_bufferIndirect);
6559         return NO_ERROR;
6560     }
6561 
6562 private:
6563     GLuint _program;
6564     GLuint _vao, _ebo, _bufferIndirect;
6565 };
6566 
6567 template <typename api>
6568 struct CNegativeBufferMappedArray : public DrawIndirectBase
6569 {
Titleglcts::__anon253d27190111::CNegativeBufferMappedArray6570     virtual std::string Title()
6571     {
6572         return "Negative: buffer mapped - glDrawArraysIndirect";
6573     }
6574 
Purposeglcts::__anon253d27190111::CNegativeBufferMappedArray6575     virtual std::string Purpose()
6576     {
6577         return "Verify that a driver sets error and no driver crash occurred";
6578     }
6579 
Methodglcts::__anon253d27190111::CNegativeBufferMappedArray6580     virtual std::string Method()
6581     {
6582         return "1. Create and bind buffer" NL "2. Map buffer" NL "3. Call glDrawArrayIndirect";
6583     }
6584 
PassCriteriaglcts::__anon253d27190111::CNegativeBufferMappedArray6585     virtual std::string PassCriteria()
6586     {
6587         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6588     }
6589 
Setupglcts::__anon253d27190111::CNegativeBufferMappedArray6590     virtual long Setup()
6591     {
6592         glClear(GL_COLOR_BUFFER_BIT);
6593         return NO_ERROR;
6594     }
6595 
Runglcts::__anon253d27190111::CNegativeBufferMappedArray6596     virtual long Run()
6597     {
6598         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6599         if (!_program)
6600         {
6601             return ERROR;
6602         }
6603         glUseProgram(_program);
6604 
6605         CColorArray coords;
6606         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6607 
6608         glGenVertexArrays(1, &_vao);
6609         glBindVertexArray(_vao);
6610 
6611         glGenBuffers(1, &_buffer);
6612         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
6613 
6614         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
6615         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
6616         glEnableVertexAttribArray(0);
6617 
6618         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
6619         indirectArrays.count                     = static_cast<GLuint>(coords.size());
6620         indirectArrays.primCount                 = 1;
6621 
6622         glGenBuffers(1, &_bufferIndirect);
6623         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6624         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
6625 
6626         DIResult result;
6627         void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawArraysIndirectCommand), GL_MAP_READ_BIT);
6628         if (buf == 0)
6629         {
6630             result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
6631         }
6632 
6633         glDrawArraysIndirect(GL_TRIANGLES, 0);
6634 
6635         GLenum error = glGetError();
6636         if (error == GL_INVALID_OPERATION)
6637         {
6638             //GL error: nothing is rendered
6639             CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6640             CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6641 
6642             ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6643             result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef,
6644                                              getWindowWidth(), getWindowHeight()));
6645         }
6646         else if (error == GL_NO_ERROR)
6647         {
6648             //No GL error: undefined
6649         }
6650         else
6651         {
6652             result.error() << "Invalid error code returned by a driver";
6653         }
6654 
6655         if (buf)
6656         {
6657             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE)
6658             {
6659                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
6660             }
6661             buf = 0;
6662         }
6663 
6664         return result.code();
6665     }
6666 
Cleanupglcts::__anon253d27190111::CNegativeBufferMappedArray6667     virtual long Cleanup()
6668     {
6669         glDisableVertexAttribArray(0);
6670         glUseProgram(0);
6671         glDeleteProgram(_program);
6672         glDeleteVertexArrays(1, &_vao);
6673         glDeleteBuffers(1, &_buffer);
6674         glDeleteBuffers(1, &_bufferIndirect);
6675         return NO_ERROR;
6676     }
6677 
6678 private:
6679     GLuint _program;
6680     GLuint _vao, _buffer, _bufferIndirect;
6681 };
6682 
6683 template <typename api>
6684 struct CNegativeBufferMappedElements : public DrawIndirectBase
6685 {
Titleglcts::__anon253d27190111::CNegativeBufferMappedElements6686     virtual std::string Title()
6687     {
6688         return "Negative: buffer mapped - glDrawElementsIndirect";
6689     }
6690 
Purposeglcts::__anon253d27190111::CNegativeBufferMappedElements6691     virtual std::string Purpose()
6692     {
6693         return "Verify that a driver sets error and no driver crash occurred";
6694     }
6695 
Methodglcts::__anon253d27190111::CNegativeBufferMappedElements6696     virtual std::string Method()
6697     {
6698         return "1. Create and bind buffer" NL "2. Map buffer" NL "3. Call glDrawElementsIndirect";
6699     }
6700 
PassCriteriaglcts::__anon253d27190111::CNegativeBufferMappedElements6701     virtual std::string PassCriteria()
6702     {
6703         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6704     }
6705 
Setupglcts::__anon253d27190111::CNegativeBufferMappedElements6706     virtual long Setup()
6707     {
6708         glClear(GL_COLOR_BUFFER_BIT);
6709         return NO_ERROR;
6710     }
6711 
Runglcts::__anon253d27190111::CNegativeBufferMappedElements6712     virtual long Run()
6713     {
6714         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6715         if (!_program)
6716         {
6717             return ERROR;
6718         }
6719         glUseProgram(_program);
6720 
6721         CColorArray coords;
6722         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6723 
6724         glGenVertexArrays(1, &_vao);
6725         glBindVertexArray(_vao);
6726 
6727         glGenBuffers(1, &_buffer);
6728         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
6729 
6730         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
6731         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
6732         glEnableVertexAttribArray(0);
6733 
6734         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
6735         indirectElements.count                       = static_cast<GLuint>(coords.size());
6736         indirectElements.primCount                   = 1;
6737 
6738         CElementArray elements(coords.size(), 0);
6739         for (size_t i = 0; i < elements.size(); ++i)
6740         {
6741             elements[i] = static_cast<GLuint>(i);
6742         }
6743 
6744         glGenBuffers(1, &_bufferIndirect);
6745         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6746         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
6747 
6748         glGenBuffers(1, &_ebo);
6749         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
6750         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
6751                      GL_STATIC_DRAW);
6752 
6753         DIResult result;
6754         void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT);
6755         if (buf == 0)
6756         {
6757             result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL";
6758         }
6759 
6760         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
6761 
6762         GLenum error = glGetError();
6763         if (error == GL_INVALID_OPERATION)
6764         {
6765             //GL error: nothing is rendered
6766             CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6767             CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6768 
6769             ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6770             result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef,
6771                                              getWindowWidth(), getWindowHeight()));
6772         }
6773         else if (error == GL_NO_ERROR)
6774         {
6775             //No GL error: undefined
6776         }
6777         else
6778         {
6779             result.error() << "Invalid error code returned by a driver";
6780         }
6781 
6782         if (buf)
6783         {
6784             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE)
6785             {
6786                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
6787             }
6788             buf = 0;
6789         }
6790 
6791         return result.code();
6792     }
6793 
Cleanupglcts::__anon253d27190111::CNegativeBufferMappedElements6794     virtual long Cleanup()
6795     {
6796         glDisableVertexAttribArray(0);
6797         glUseProgram(0);
6798         glDeleteProgram(_program);
6799         glDeleteVertexArrays(1, &_vao);
6800         glDeleteBuffers(1, &_buffer);
6801         glDeleteBuffers(1, &_ebo);
6802         glDeleteBuffers(1, &_bufferIndirect);
6803         return NO_ERROR;
6804     }
6805 
6806 private:
6807     GLuint _program;
6808     GLuint _vao, _buffer, _ebo, _bufferIndirect;
6809 };
6810 
6811 template <typename api>
6812 struct CNegativeDataWrongElements : public DrawIndirectBase
6813 {
Titleglcts::__anon253d27190111::CNegativeDataWrongElements6814     virtual std::string Title()
6815     {
6816         return "Negative: invalid type - glDrawElementsIndirect";
6817     }
6818 
Purposeglcts::__anon253d27190111::CNegativeDataWrongElements6819     virtual std::string Purpose()
6820     {
6821         return "Verify that a driver sets error and no driver crash occurred";
6822     }
6823 
Methodglcts::__anon253d27190111::CNegativeDataWrongElements6824     virtual std::string Method()
6825     {
6826         return "1. Bind non-zero buffer" NL "2. Call glDrawElementsIndirect with invalid type";
6827     }
6828 
PassCriteriaglcts::__anon253d27190111::CNegativeDataWrongElements6829     virtual std::string PassCriteria()
6830     {
6831         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6832     }
6833 
Setupglcts::__anon253d27190111::CNegativeDataWrongElements6834     virtual long Setup()
6835     {
6836         glClear(GL_COLOR_BUFFER_BIT);
6837         return NO_ERROR;
6838     }
6839 
Runglcts::__anon253d27190111::CNegativeDataWrongElements6840     virtual long Run()
6841     {
6842         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6843         if (!_program)
6844         {
6845             return ERROR;
6846         }
6847         glUseProgram(_program);
6848 
6849         CColorArray coords;
6850         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6851 
6852         glGenVertexArrays(1, &_vao);
6853         glBindVertexArray(_vao);
6854 
6855         glGenBuffers(1, &_buffer);
6856         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
6857 
6858         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
6859         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
6860         glEnableVertexAttribArray(0);
6861 
6862         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
6863         indirectElements.count                       = static_cast<GLuint>(coords.size());
6864         indirectElements.primCount                   = 1;
6865 
6866         CElementArray elements(coords.size(), 0);
6867         for (size_t i = 0; i < elements.size(); ++i)
6868         {
6869             elements[i] = static_cast<GLuint>(i);
6870         }
6871 
6872         glGenBuffers(1, &_bufferIndirect);
6873         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6874         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
6875 
6876         glGenBuffers(1, &_ebo);
6877         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
6878         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
6879                      GL_STATIC_DRAW);
6880 
6881         DIResult result;
6882 
6883         glDrawElementsIndirect(GL_TRIANGLES, GL_FLOAT, 0);
6884         if (glGetError() != GL_INVALID_ENUM)
6885         {
6886             result.error() << "Invalid error code returned by a driver for GL_FLOAT type";
6887         }
6888 
6889         glDrawElementsIndirect(GL_TRIANGLES, GL_INT, 0);
6890         if (glGetError() != GL_INVALID_ENUM)
6891         {
6892             result.error() << "Invalid error code returned by a driver for GL_INT type";
6893         }
6894 
6895         glDrawElementsIndirect(GL_TRIANGLES, GL_STATIC_DRAW, 0);
6896         if (glGetError() != GL_INVALID_ENUM)
6897         {
6898             result.error() << "Invalid error code returned by a driver for GL_STATIC_DRAW type";
6899         }
6900 
6901         glDrawElementsIndirect(GL_TRIANGLES, GL_SHORT, 0);
6902         if (glGetError() != GL_INVALID_ENUM)
6903         {
6904             result.error() << "Invalid error code returned by a driver for GL_SHORT type";
6905         }
6906 
6907         glDrawElementsIndirect(GL_TRIANGLES, GL_BYTE, 0);
6908         if (glGetError() != GL_INVALID_ENUM)
6909         {
6910             result.error() << "Invalid error code returned by a driver for GL_BYTE type";
6911         }
6912 
6913         glDrawElementsIndirect(GL_TRIANGLES, GL_DOUBLE, 0);
6914         if (glGetError() != GL_INVALID_ENUM)
6915         {
6916             result.error() << "Invalid error code returned by a driver for GL_DOUBLE type";
6917         }
6918 
6919         glDrawElementsIndirect(GL_TRIANGLES, GL_INVALID_ENUM, 0);
6920         if (glGetError() != GL_INVALID_ENUM)
6921         {
6922             result.error() << "Invalid error code returned by a driver for GL_INVALID_ENUM type";
6923         }
6924 
6925         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6926         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6927 
6928         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6929         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6930                                          getWindowHeight()));
6931 
6932         return result.code();
6933     }
6934 
Cleanupglcts::__anon253d27190111::CNegativeDataWrongElements6935     virtual long Cleanup()
6936     {
6937         glDisableVertexAttribArray(0);
6938         glUseProgram(0);
6939         glDeleteProgram(_program);
6940         glDeleteVertexArrays(1, &_vao);
6941         glDeleteBuffers(1, &_buffer);
6942         glDeleteBuffers(1, &_ebo);
6943         glDeleteBuffers(1, &_bufferIndirect);
6944         return NO_ERROR;
6945     }
6946 
6947 private:
6948     GLuint _program;
6949     GLuint _vao, _buffer, _ebo, _bufferIndirect;
6950 };
6951 
6952 template <typename api>
6953 class CNegativeGshArray : public DrawIndirectBase
6954 {
6955 public:
Title()6956     virtual std::string Title()
6957     {
6958         return "Negative: incompatible the input primitive type of gsh - glDrawArrayIndirect";
6959     }
6960 
Purpose()6961     virtual std::string Purpose()
6962     {
6963         return "Verify that a driver sets error and no driver crash occurred";
6964     }
6965 
Method()6966     virtual std::string Method()
6967     {
6968         return "1. Bind non-zero buffer" NL "2. Set data" NL "3. Set wrong geometry shader" NL
6969                "4. Call glDrawArrayIndirect";
6970     }
6971 
PassCriteria()6972     virtual std::string PassCriteria()
6973     {
6974         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6975     }
6976 
Setup()6977     virtual long Setup()
6978     {
6979         glClear(GL_COLOR_BUFFER_BIT);
6980         return NO_ERROR;
6981     }
6982 
Run()6983     virtual long Run()
6984     {
6985         _program = CreateProgram(Vsh(), Gsh(), Fsh(), true);
6986         if (!_program)
6987         {
6988             return ERROR;
6989         }
6990         glUseProgram(_program);
6991 
6992         CColorArray coords;
6993         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6994 
6995         glGenVertexArrays(1, &_vao);
6996         glBindVertexArray(_vao);
6997 
6998         glGenBuffers(1, &_buffer);
6999         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7000 
7001         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
7002         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
7003         glEnableVertexAttribArray(0);
7004 
7005         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
7006         indirectArrays.count                     = static_cast<GLuint>(coords.size());
7007         indirectArrays.primCount                 = 1;
7008         indirectArrays.first                     = 0;
7009         indirectArrays.reservedMustBeZero        = 0;
7010 
7011         glGenBuffers(1, &_bufferIndirect);
7012         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7013         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
7014 
7015         DIResult result;
7016 
7017         glDrawArraysIndirect(GL_POINTS, 0);
7018         if (glGetError() != GL_INVALID_OPERATION)
7019         {
7020             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7021         }
7022 
7023         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
7024         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
7025 
7026         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
7027         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
7028                                          getWindowHeight()));
7029 
7030         return result.code();
7031     }
7032 
Cleanup()7033     virtual long Cleanup()
7034     {
7035         glDisableVertexAttribArray(0);
7036         glUseProgram(0);
7037         glDeleteProgram(_program);
7038         glDeleteVertexArrays(1, &_vao);
7039         glDeleteBuffers(1, &_buffer);
7040         glDeleteBuffers(1, &_bufferIndirect);
7041         return NO_ERROR;
7042     }
7043 
7044 private:
Vsh()7045     std::string Vsh()
7046     {
7047         return "#version 150" NL "in vec4 coords;" NL "void main() {" NL "  gl_Position = coords;" NL "}";
7048     }
7049 
Gsh()7050     std::string Gsh()
7051     {
7052         return "#version 150" NL "layout(triangles) in;" NL "layout(triangle_strip, max_vertices = 10) out;" NL
7053                "void main() {" NL " for (int i=0; i<gl_in.length(); ++i) {" NL
7054                "     gl_Position = gl_in[i].gl_Position;" NL "     EmitVertex();" NL " }" NL "}";
7055     }
7056 
Fsh()7057     std::string Fsh()
7058     {
7059         return "#version 140" NL "out vec4 outColor;" NL "void main() {" NL
7060                "  outColor = vec4(0.1f, 0.2f, 0.3f, 1.0f);" NL "}";
7061     }
7062     GLuint _program;
7063     GLuint _vao, _buffer, _bufferIndirect;
7064 };
7065 
7066 template <typename api>
7067 class CNegativeGshElements : public DrawIndirectBase
7068 {
7069 public:
Title()7070     virtual std::string Title()
7071     {
7072         return "Negative: incompatible the input primitive type of gsh - glDrawElementsIndirect";
7073     }
7074 
Purpose()7075     virtual std::string Purpose()
7076     {
7077         return "Verify that a driver sets error and no driver crash occurred";
7078     }
7079 
Method()7080     virtual std::string Method()
7081     {
7082         return "1. Bind non-zero buffer" NL "2. Set data" NL "3. Set wrong geometry shader" NL
7083                "4. Call glDrawElementsIndirect";
7084     }
7085 
PassCriteria()7086     virtual std::string PassCriteria()
7087     {
7088         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7089     }
7090 
Setup()7091     virtual long Setup()
7092     {
7093         glClear(GL_COLOR_BUFFER_BIT);
7094         return NO_ERROR;
7095     }
7096 
Run()7097     virtual long Run()
7098     {
7099         _program = CreateProgram(Vsh(), Gsh(), Fsh(), true);
7100         if (!_program)
7101         {
7102             return ERROR;
7103         }
7104         glUseProgram(_program);
7105 
7106         CColorArray coords;
7107         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
7108 
7109         glGenVertexArrays(1, &_vao);
7110         glBindVertexArray(_vao);
7111 
7112         glGenBuffers(1, &_buffer);
7113         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7114 
7115         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
7116         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
7117         glEnableVertexAttribArray(0);
7118 
7119         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
7120         indirectElements.count                       = static_cast<GLuint>(coords.size());
7121         indirectElements.primCount                   = 1;
7122 
7123         CElementArray elements(coords.size(), 0);
7124         for (size_t i = 0; i < elements.size(); ++i)
7125         {
7126             elements[i] = static_cast<GLuint>(i);
7127         }
7128 
7129         glGenBuffers(1, &_bufferIndirect);
7130         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7131         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
7132 
7133         glGenBuffers(1, &_ebo);
7134         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
7135         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
7136                      GL_STATIC_DRAW);
7137 
7138         DIResult result;
7139 
7140         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
7141         if (glGetError() != GL_INVALID_OPERATION)
7142         {
7143             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7144         }
7145 
7146         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
7147         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
7148 
7149         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
7150         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
7151                                          getWindowHeight()));
7152 
7153         return result.code();
7154     }
7155 
Cleanup()7156     virtual long Cleanup()
7157     {
7158         glDisableVertexAttribArray(0);
7159         glUseProgram(0);
7160         glDeleteProgram(_program);
7161         glDeleteVertexArrays(1, &_vao);
7162         glDeleteBuffers(1, &_buffer);
7163         glDeleteBuffers(1, &_ebo);
7164         glDeleteBuffers(1, &_bufferIndirect);
7165         return NO_ERROR;
7166     }
7167 
7168 private:
Vsh()7169     std::string Vsh()
7170     {
7171         return "#version 150" NL "in vec4 coords;" NL "void main() {" NL "  gl_Position = coords;" NL "}";
7172     }
7173 
Gsh()7174     std::string Gsh()
7175     {
7176         return "#version 150" NL "layout(lines) in;" NL "layout(line_strip, max_vertices = 10) out;" NL
7177                "void main() {" NL " for (int i=0; i<gl_in.length(); ++i) {" NL
7178                "     gl_Position = gl_in[i].gl_Position;" NL "     EmitVertex();" NL " }" NL "}";
7179     }
7180 
Fsh()7181     std::string Fsh()
7182     {
7183         return "#version 140" NL "out vec4 outColor;" NL "void main() {" NL
7184                "  outColor = vec4(0.1f, 0.2f, 0.3f, 1.0f);" NL "}";
7185     }
7186     int _program;
7187     GLuint _vao, _buffer, _ebo, _bufferIndirect;
7188 };
7189 
7190 template <typename api>
7191 struct CNegativeInvalidSizeArrays : public DrawIndirectBase
7192 {
7193     struct TWrongStructure1
7194     {
7195         GLuint count;
7196         GLuint primCount;
7197     };
7198 
7199     struct TWrongStructure2
7200     {
7201         GLfloat count;
7202         GLuint primCount;
7203     };
7204 
Titleglcts::__anon253d27190111::CNegativeInvalidSizeArrays7205     virtual std::string Title()
7206     {
7207         return "Negative: wrong structure - glDrawArrayIndirect";
7208     }
7209 
Purposeglcts::__anon253d27190111::CNegativeInvalidSizeArrays7210     virtual std::string Purpose()
7211     {
7212         return "Verify that a driver sets error and no driver crash occurred";
7213     }
7214 
Methodglcts::__anon253d27190111::CNegativeInvalidSizeArrays7215     virtual std::string Method()
7216     {
7217         return "Call glDrawArrayIndirect with wrong structure";
7218     }
7219 
PassCriteriaglcts::__anon253d27190111::CNegativeInvalidSizeArrays7220     virtual std::string PassCriteria()
7221     {
7222         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7223     }
7224 
Setupglcts::__anon253d27190111::CNegativeInvalidSizeArrays7225     virtual long Setup()
7226     {
7227         glClear(GL_COLOR_BUFFER_BIT);
7228         return NO_ERROR;
7229     }
7230 
Runglcts::__anon253d27190111::CNegativeInvalidSizeArrays7231     virtual long Run()
7232     {
7233         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
7234         if (!_program)
7235         {
7236             return ERROR;
7237         }
7238         glUseProgram(_program);
7239 
7240         CColorArray coords;
7241         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
7242 
7243         glGenVertexArrays(1, &_vao);
7244         glBindVertexArray(_vao);
7245 
7246         glGenBuffers(1, &_buffer);
7247         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7248 
7249         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
7250         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
7251         glEnableVertexAttribArray(0);
7252 
7253         TWrongStructure1 indirectArrays = {0, 0};
7254         indirectArrays.count            = static_cast<GLuint>(coords.size());
7255         indirectArrays.primCount        = 1;
7256 
7257         glGenBuffers(1, &_bufferIndirect);
7258         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7259         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure1), &indirectArrays, GL_STATIC_DRAW);
7260 
7261         DIResult result;
7262 
7263         glDrawArraysIndirect(GL_TRIANGLES, 0);
7264         if (glGetError() != GL_INVALID_OPERATION)
7265         {
7266             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7267         }
7268 
7269         glDeleteBuffers(1, &_bufferIndirect);
7270 
7271         TWrongStructure2 indirectArrays2 = {0, 0};
7272         indirectArrays2.count            = static_cast<GLfloat>(coords.size());
7273         indirectArrays2.primCount        = 1;
7274 
7275         glGenBuffers(1, &_bufferIndirect);
7276         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7277         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure2), &indirectArrays2, GL_STATIC_DRAW);
7278 
7279         glDrawArraysIndirect(GL_TRIANGLES, 0);
7280         if (glGetError() != GL_INVALID_OPERATION)
7281         {
7282             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7283         }
7284 
7285         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
7286         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
7287 
7288         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
7289         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
7290                                          getWindowHeight()));
7291 
7292         return result.code();
7293     }
7294 
Cleanupglcts::__anon253d27190111::CNegativeInvalidSizeArrays7295     virtual long Cleanup()
7296     {
7297         glDisableVertexAttribArray(0);
7298         glUseProgram(0);
7299         glDeleteProgram(_program);
7300         glDeleteVertexArrays(1, &_vao);
7301         glDeleteBuffers(1, &_buffer);
7302         glDeleteBuffers(1, &_bufferIndirect);
7303         return NO_ERROR;
7304     }
7305 
7306 private:
7307     GLuint _program;
7308     GLuint _vao, _buffer, _bufferIndirect;
7309 };
7310 
7311 template <typename api>
7312 struct CNegativeInvalidSizeElements : public DrawIndirectBase
7313 {
7314     struct TWrongStructure
7315     {
7316         GLfloat count;
7317         GLuint primCount;
7318     };
7319 
Titleglcts::__anon253d27190111::CNegativeInvalidSizeElements7320     virtual std::string Title()
7321     {
7322         return "Negative: wrong structure - glDrawElementsIndirect";
7323     }
7324 
Purposeglcts::__anon253d27190111::CNegativeInvalidSizeElements7325     virtual std::string Purpose()
7326     {
7327         return "Verify that a driver sets error and no driver crash occurred";
7328     }
7329 
Methodglcts::__anon253d27190111::CNegativeInvalidSizeElements7330     virtual std::string Method()
7331     {
7332         return "Call glDrawElementsIndirect with wrong structure";
7333     }
7334 
PassCriteriaglcts::__anon253d27190111::CNegativeInvalidSizeElements7335     virtual std::string PassCriteria()
7336     {
7337         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7338     }
7339 
Setupglcts::__anon253d27190111::CNegativeInvalidSizeElements7340     virtual long Setup()
7341     {
7342         glClear(GL_COLOR_BUFFER_BIT);
7343         return NO_ERROR;
7344     }
7345 
Runglcts::__anon253d27190111::CNegativeInvalidSizeElements7346     virtual long Run()
7347     {
7348         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
7349         if (!_program)
7350         {
7351             return ERROR;
7352         }
7353         glUseProgram(_program);
7354 
7355         CColorArray coords;
7356         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
7357 
7358         glGenVertexArrays(1, &_vao);
7359         glBindVertexArray(_vao);
7360 
7361         glGenBuffers(1, &_buffer);
7362         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7363 
7364         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
7365         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
7366         glEnableVertexAttribArray(0);
7367 
7368         DrawArraysIndirectCommand indirectElements = {0, 0, 0, 0};
7369         indirectElements.count                     = static_cast<GLuint>(coords.size());
7370         indirectElements.primCount                 = 1;
7371 
7372         CElementArray elements(coords.size(), 0);
7373         for (size_t i = 0; i < elements.size(); ++i)
7374         {
7375             elements[i] = static_cast<GLuint>(i);
7376         }
7377 
7378         glGenBuffers(1, &_bufferIndirect);
7379         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7380         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectElements, GL_STATIC_DRAW);
7381 
7382         glGenBuffers(1, &_ebo);
7383         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
7384         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
7385                      GL_STATIC_DRAW);
7386 
7387         DIResult result;
7388 
7389         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
7390         if (glGetError() != GL_INVALID_OPERATION)
7391         {
7392             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7393         }
7394 
7395         TWrongStructure indirectElements2 = {0, 0};
7396         indirectElements2.count           = static_cast<GLfloat>(coords.size());
7397         indirectElements2.primCount       = 1;
7398 
7399         glDeleteBuffers(1, &_bufferIndirect);
7400         glGenBuffers(1, &_bufferIndirect);
7401         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7402         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure), &indirectElements2, GL_STATIC_DRAW);
7403 
7404         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
7405         if (glGetError() != GL_INVALID_OPERATION)
7406         {
7407             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7408         }
7409 
7410         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
7411         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
7412 
7413         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
7414         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
7415                                          getWindowHeight()));
7416 
7417         return result.code();
7418     }
7419 
Cleanupglcts::__anon253d27190111::CNegativeInvalidSizeElements7420     virtual long Cleanup()
7421     {
7422         glDisableVertexAttribArray(0);
7423         glUseProgram(0);
7424         glDeleteProgram(_program);
7425         glDeleteVertexArrays(1, &_vao);
7426         glDeleteBuffers(1, &_buffer);
7427         glDeleteBuffers(1, &_ebo);
7428         glDeleteBuffers(1, &_bufferIndirect);
7429         return NO_ERROR;
7430     }
7431 
7432 private:
7433     GLuint _program;
7434     GLuint _vao, _buffer, _ebo, _bufferIndirect;
7435 };
7436 
7437 template <typename api>
7438 struct CNegativeStructureWrongOffsetArray : public DrawIndirectBase
7439 {
Titleglcts::__anon253d27190111::CNegativeStructureWrongOffsetArray7440     virtual std::string Title()
7441     {
7442         return "Negative: wrong offset - glDrawArrayIndirect";
7443     }
7444 
Purposeglcts::__anon253d27190111::CNegativeStructureWrongOffsetArray7445     virtual std::string Purpose()
7446     {
7447         return "Verify that a driver sets error and no driver crash occurred";
7448     }
7449 
Methodglcts::__anon253d27190111::CNegativeStructureWrongOffsetArray7450     virtual std::string Method()
7451     {
7452         return "Call glDrawArrayIndirect with wrong offset";
7453     }
7454 
PassCriteriaglcts::__anon253d27190111::CNegativeStructureWrongOffsetArray7455     virtual std::string PassCriteria()
7456     {
7457         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7458     }
7459 
Setupglcts::__anon253d27190111::CNegativeStructureWrongOffsetArray7460     virtual long Setup()
7461     {
7462         glClear(GL_COLOR_BUFFER_BIT);
7463         return NO_ERROR;
7464     }
7465 
Runglcts::__anon253d27190111::CNegativeStructureWrongOffsetArray7466     virtual long Run()
7467     {
7468         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
7469         if (!_program)
7470         {
7471             return ERROR;
7472         }
7473         glUseProgram(_program);
7474 
7475         CColorArray coords;
7476         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
7477 
7478         glGenVertexArrays(1, &_vao);
7479         glBindVertexArray(_vao);
7480 
7481         glGenBuffers(1, &_buffer);
7482         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7483 
7484         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
7485         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
7486         glEnableVertexAttribArray(0);
7487 
7488         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
7489         indirectArrays.count                     = static_cast<GLuint>(coords.size());
7490         indirectArrays.primCount                 = 1;
7491 
7492         glGenBuffers(1, &_bufferIndirect);
7493         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7494         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
7495 
7496         DIResult result;
7497 
7498         glDrawArraysIndirect(GL_TRIANGLES, (void *)(sizeof(DrawArraysIndirectCommand) * 2));
7499         if (glGetError() != GL_INVALID_OPERATION)
7500         {
7501             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7502         }
7503 
7504         glDrawArraysIndirect(GL_TRIANGLES, (void *)(sizeof(GLuint)));
7505         if (glGetError() != GL_INVALID_OPERATION)
7506         {
7507             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7508         }
7509 
7510         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
7511         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
7512 
7513         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
7514         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
7515                                          getWindowHeight()));
7516 
7517         return result.code();
7518     }
7519 
Cleanupglcts::__anon253d27190111::CNegativeStructureWrongOffsetArray7520     virtual long Cleanup()
7521     {
7522         glDisableVertexAttribArray(0);
7523         glUseProgram(0);
7524         glDeleteProgram(_program);
7525         glDeleteVertexArrays(1, &_vao);
7526         glDeleteBuffers(1, &_buffer);
7527         glDeleteBuffers(1, &_bufferIndirect);
7528         return NO_ERROR;
7529     }
7530 
7531 private:
7532     GLuint _program;
7533     GLuint _vao, _buffer, _bufferIndirect;
7534 };
7535 
7536 template <typename api>
7537 struct CNegativeStructureWrongOffsetElements : public DrawIndirectBase
7538 {
Titleglcts::__anon253d27190111::CNegativeStructureWrongOffsetElements7539     virtual std::string Title()
7540     {
7541         return "Negative: wrong offset - glDrawElementsIndirect";
7542     }
7543 
Purposeglcts::__anon253d27190111::CNegativeStructureWrongOffsetElements7544     virtual std::string Purpose()
7545     {
7546         return "Verify that a driver sets error and no driver crash occurred";
7547     }
7548 
Methodglcts::__anon253d27190111::CNegativeStructureWrongOffsetElements7549     virtual std::string Method()
7550     {
7551         return "Call glDrawElementsIndirect with wrong structure";
7552     }
7553 
PassCriteriaglcts::__anon253d27190111::CNegativeStructureWrongOffsetElements7554     virtual std::string PassCriteria()
7555     {
7556         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7557     }
7558 
Setupglcts::__anon253d27190111::CNegativeStructureWrongOffsetElements7559     virtual long Setup()
7560     {
7561         glClear(GL_COLOR_BUFFER_BIT);
7562         return NO_ERROR;
7563     }
7564 
Runglcts::__anon253d27190111::CNegativeStructureWrongOffsetElements7565     virtual long Run()
7566     {
7567         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
7568         if (!_program)
7569         {
7570             return ERROR;
7571         }
7572         glUseProgram(_program);
7573 
7574         CColorArray coords;
7575         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
7576 
7577         glGenVertexArrays(1, &_vao);
7578         glBindVertexArray(_vao);
7579 
7580         glGenBuffers(1, &_buffer);
7581         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7582 
7583         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
7584         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
7585         glEnableVertexAttribArray(0);
7586 
7587         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
7588         indirectElements.count                       = static_cast<GLuint>(coords.size());
7589         indirectElements.primCount                   = 1;
7590 
7591         CElementArray elements(coords.size(), 0);
7592         for (size_t i = 0; i < elements.size(); ++i)
7593         {
7594             elements[i] = static_cast<GLuint>(i);
7595         }
7596 
7597         glGenBuffers(1, &_bufferIndirect);
7598         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7599         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
7600 
7601         glGenBuffers(1, &_ebo);
7602         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
7603         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
7604                      GL_STATIC_DRAW);
7605 
7606         DIResult result;
7607 
7608         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void *)(sizeof(DrawElementsIndirectCommand) * 2));
7609         if (glGetError() != GL_INVALID_OPERATION)
7610         {
7611             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7612         }
7613 
7614         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void *)(sizeof(GLuint)));
7615         if (glGetError() != GL_INVALID_OPERATION)
7616         {
7617             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7618         }
7619 
7620         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
7621         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
7622 
7623         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
7624         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
7625                                          getWindowHeight()));
7626 
7627         return result.code();
7628     }
7629 
Cleanupglcts::__anon253d27190111::CNegativeStructureWrongOffsetElements7630     virtual long Cleanup()
7631     {
7632         glDisableVertexAttribArray(0);
7633         glUseProgram(0);
7634         glDeleteProgram(_program);
7635         glDeleteVertexArrays(1, &_vao);
7636         glDeleteBuffers(1, &_buffer);
7637         glDeleteBuffers(1, &_ebo);
7638         glDeleteBuffers(1, &_bufferIndirect);
7639         return NO_ERROR;
7640     }
7641 
7642 private:
7643     GLuint _program;
7644     GLuint _vao, _buffer, _ebo, _bufferIndirect;
7645 };
7646 
7647 template <typename api>
7648 struct CNegativeUnalignedOffset : public DrawIndirectBase
7649 {
Titleglcts::__anon253d27190111::CNegativeUnalignedOffset7650     virtual std::string Title()
7651     {
7652         return "Negative: unaligned offset - glDrawElementsIndirect and glDrawArraysIndirect";
7653     }
7654 
Purposeglcts::__anon253d27190111::CNegativeUnalignedOffset7655     virtual std::string Purpose()
7656     {
7657         return "Verify that a driver sets error and no system/driver crash occurred";
7658     }
7659 
Methodglcts::__anon253d27190111::CNegativeUnalignedOffset7660     virtual std::string Method()
7661     {
7662         return "Call with unaligned offset (1, 3, 1023)";
7663     }
7664 
PassCriteriaglcts::__anon253d27190111::CNegativeUnalignedOffset7665     virtual std::string PassCriteria()
7666     {
7667         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7668     }
7669 
Runglcts::__anon253d27190111::CNegativeUnalignedOffset7670     virtual long Run()
7671     {
7672         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
7673         if (!_program)
7674         {
7675             return ERROR;
7676         }
7677         glUseProgram(_program);
7678 
7679         glGenVertexArrays(1, &_vao);
7680         glBindVertexArray(_vao);
7681 
7682         std::vector<GLuint> zarro(4096, 0);
7683 
7684         glGenBuffers(1, &_buffer);
7685         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7686         glBufferData(GL_ARRAY_BUFFER, 4096, &zarro[0], GL_STREAM_DRAW);
7687         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
7688         glEnableVertexAttribArray(0);
7689 
7690         glGenBuffers(1, &_bufferIndirect);
7691         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7692         glBufferData(GL_DRAW_INDIRECT_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);
7693 
7694         glGenBuffers(1, &_ebo);
7695         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
7696         glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);
7697 
7698         DIResult result;
7699 
7700         int offsets[] = {1, 3, 1023};
7701         for (size_t i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++)
7702         {
7703             glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, reinterpret_cast<void *>((uintptr_t)offsets[i]));
7704             if (glGetError() != GL_INVALID_VALUE)
7705             {
7706                 result.error() << "Invalid error code returned by a driver for GL_INVALID_VALUE type";
7707             }
7708             glDrawArraysIndirect(GL_TRIANGLES, reinterpret_cast<void *>((uintptr_t)offsets[i]));
7709             if (glGetError() != GL_INVALID_VALUE)
7710             {
7711                 result.error() << "Invalid error code returned by a driver for GL_INVALID_VALUE type";
7712             }
7713         }
7714 
7715         return result.code();
7716     }
7717 
Cleanupglcts::__anon253d27190111::CNegativeUnalignedOffset7718     virtual long Cleanup()
7719     {
7720         glDisableVertexAttribArray(0);
7721         glUseProgram(0);
7722         glDeleteProgram(_program);
7723         glDeleteVertexArrays(1, &_vao);
7724         glDeleteBuffers(1, &_buffer);
7725         glDeleteBuffers(1, &_ebo);
7726         glDeleteBuffers(1, &_bufferIndirect);
7727         return NO_ERROR;
7728     }
7729 
7730 private:
7731     GLuint _program;
7732     GLuint _vao, _buffer, _ebo, _bufferIndirect;
7733 };
7734 
7735 template <typename api>
7736 struct CNegativeXFB : public DrawIndirectBase
7737 {
Titleglcts::__anon253d27190111::CNegativeXFB7738     virtual std::string Title()
7739     {
7740         return "Negative: transform feedback active and not paused - glDrawElementsIndirect and glDrawArraysIndirect";
7741     }
7742 
Purposeglcts::__anon253d27190111::CNegativeXFB7743     virtual std::string Purpose()
7744     {
7745         return "Verify that a driver sets error and no system/driver crash occurred";
7746     }
7747 
Methodglcts::__anon253d27190111::CNegativeXFB7748     virtual std::string Method()
7749     {
7750         return "Call with transform feedback active";
7751     }
7752 
PassCriteriaglcts::__anon253d27190111::CNegativeXFB7753     virtual std::string PassCriteria()
7754     {
7755         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7756     }
7757 
Runglcts::__anon253d27190111::CNegativeXFB7758     virtual long Run()
7759     {
7760         api::ES_Only();
7761 
7762         bool drawWithXFBAllowed = m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader");
7763 
7764         _program                 = CreateProgram(Vsh(), "", shaders::fshSimple<api>(), false);
7765         const GLchar *varyings[] = {"dataOut"};
7766         glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS);
7767         glLinkProgram(_program);
7768         if (!CheckProgram(_program))
7769         {
7770             return ERROR;
7771         }
7772         glUseProgram(_program);
7773 
7774         glGenVertexArrays(1, &_vao);
7775         glBindVertexArray(_vao);
7776 
7777         std::vector<GLuint> zarro(4096, 0);
7778 
7779         glGenBuffers(1, &_buffer);
7780         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7781         glBufferData(GL_ARRAY_BUFFER, 4096, &zarro[0], GL_STREAM_DRAW);
7782         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
7783         glEnableVertexAttribArray(0);
7784 
7785         glGenBuffers(1, &_bufferIndirect);
7786         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7787         glBufferData(GL_DRAW_INDIRECT_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);
7788 
7789         glGenBuffers(1, &_ebo);
7790         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
7791         glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);
7792 
7793         glGenBuffers(1, &_xfb);
7794         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _xfb);
7795         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);
7796         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfb);
7797 
7798         DIResult result;
7799 
7800         //Without XFO
7801         glBeginTransformFeedback(GL_POINTS);
7802 
7803         glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, NULL);
7804         if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
7805         {
7806             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7807         }
7808         glDrawArraysIndirect(GL_POINTS, NULL);
7809         if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
7810         {
7811             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7812         }
7813         glEndTransformFeedback();
7814 
7815         //With XFO
7816         glGenTransformFeedbacks(1, &_xfo);
7817         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, _xfo);
7818         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfb);
7819         glBeginTransformFeedback(GL_POINTS);
7820         glPauseTransformFeedback();
7821         glResumeTransformFeedback();
7822 
7823         glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, NULL);
7824         if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
7825         {
7826             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7827         }
7828         glDrawArraysIndirect(GL_POINTS, NULL);
7829         if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
7830         {
7831             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7832         }
7833         glEndTransformFeedback();
7834 
7835         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
7836         return result.code();
7837     }
7838 
Cleanupglcts::__anon253d27190111::CNegativeXFB7839     virtual long Cleanup()
7840     {
7841         glDisableVertexAttribArray(0);
7842         glUseProgram(0);
7843         glDeleteProgram(_program);
7844         glDeleteVertexArrays(1, &_vao);
7845         glDeleteBuffers(1, &_buffer);
7846         glDeleteBuffers(1, &_ebo);
7847         glDeleteBuffers(1, &_bufferIndirect);
7848         glDeleteBuffers(1, &_xfb);
7849         glDeleteTransformFeedbacks(1, &_xfo);
7850         return NO_ERROR;
7851     }
7852 
Vshglcts::__anon253d27190111::CNegativeXFB7853     std::string Vsh()
7854     {
7855         return api::glslVer() + NL "out highp vec4 dataOut;" NL "in vec4 i_vertex;" NL "void main() {" NL
7856                                    "  dataOut = i_vertex;" NL "  gl_Position = i_vertex;" NL "}";
7857     }
7858 
7859 private:
7860     GLuint _program;
7861     GLuint _vao, _buffer, _ebo, _bufferIndirect, _xfo, _xfb;
7862 };
7863 
7864 } // namespace
DrawIndirectTestsGL40(glcts::Context & context)7865 DrawIndirectTestsGL40::DrawIndirectTestsGL40(glcts::Context &context) : TestCaseGroup(context, "draw_indirect", "")
7866 {
7867 }
7868 
~DrawIndirectTestsGL40(void)7869 DrawIndirectTestsGL40::~DrawIndirectTestsGL40(void)
7870 {
7871 }
7872 
init()7873 void DrawIndirectTestsGL40::init()
7874 {
7875     using namespace glcts;
7876 
7877     DILogger::setOutput(m_context.getTestContext().getLog());
7878 
7879     addChild(
7880         new TestSubcase(m_context, "basic-binding-default", TestSubcase::Create<CDefaultBindingPoint<test_api::GL>>));
7881     addChild(new TestSubcase(m_context, "basic-binding-zero", TestSubcase::Create<CZeroBindingPoint<test_api::GL>>));
7882     addChild(
7883         new TestSubcase(m_context, "basic-binding-single", TestSubcase::Create<CSingleBindingPoint<test_api::GL>>));
7884     addChild(new TestSubcase(m_context, "basic-binding-multi", TestSubcase::Create<CMultiBindingPoint<test_api::GL>>));
7885     addChild(
7886         new TestSubcase(m_context, "basic-binding-delete", TestSubcase::Create<CDeleteBindingPoint<test_api::GL>>));
7887 
7888     addChild(new TestSubcase(m_context, "basic-buffer-data", TestSubcase::Create<CBufferData<test_api::GL>>));
7889     addChild(new TestSubcase(m_context, "basic-buffer-subData", TestSubcase::Create<CBufferSubData<test_api::GL>>));
7890     addChild(new TestSubcase(m_context, "basic-buffer-unMap", TestSubcase::Create<CBufferMap<test_api::GL>>));
7891     addChild(
7892         new TestSubcase(m_context, "basic-buffer-getPointerv", TestSubcase::Create<CBufferGetPointerv<test_api::GL>>));
7893     addChild(new TestSubcase(m_context, "basic-buffer-mapRange", TestSubcase::Create<CBufferMapRange<test_api::GL>>));
7894     addChild(new TestSubcase(m_context, "basic-buffer-flushMappedRange",
7895                              TestSubcase::Create<CBufferFlushMappedRange<test_api::GL>>));
7896     addChild(
7897         new TestSubcase(m_context, "basic-buffer-copySubData", TestSubcase::Create<CBufferCopySubData<test_api::GL>>));
7898 
7899     addChild(new TestSubcase(m_context, "basic-drawArrays-singlePrimitive",
7900                              TestSubcase::Create<CVBODrawArraysSingle<test_api::GL>>));
7901     addChild(new TestSubcase(m_context, "basic-drawArrays-manyPrimitives",
7902                              TestSubcase::Create<CVBODrawArraysMany<test_api::GL>>));
7903     addChild(new TestSubcase(m_context, "basic-drawArrays-instancing",
7904                              TestSubcase::Create<CVBODrawArraysInstancing<test_api::GL>>));
7905     addChild(new TestSubcase(m_context, "basic-drawArrays-xfbPaused",
7906                              TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::GL>>));
7907     addChild(new TestSubcase(m_context, "basic-drawElements-singlePrimitive",
7908                              TestSubcase::Create<CVBODrawElementsSingle<test_api::GL>>));
7909     addChild(new TestSubcase(m_context, "basic-drawElements-manyPrimitives",
7910                              TestSubcase::Create<CVBODrawElementsMany<test_api::GL>>));
7911     addChild(new TestSubcase(m_context, "basic-drawElements-instancing",
7912                              TestSubcase::Create<CVBODrawElementsInstancing<test_api::GL>>));
7913     addChild(new TestSubcase(m_context, "basic-drawElements-xfbPaused",
7914                              TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::GL>>));
7915 
7916     addChild(new TestSubcase(m_context, "basic-drawArrays-simple",
7917                              TestSubcase::Create<CBufferIndirectDrawArraysSimple<test_api::GL>>));
7918     addChild(new TestSubcase(m_context, "basic-drawArrays-noFirst",
7919                              TestSubcase::Create<CBufferIndirectDrawArraysNoFirst<test_api::GL>>));
7920     addChild(new TestSubcase(m_context, "basic-drawArrays-bufferOffset",
7921                              TestSubcase::Create<CBufferIndirectDrawArraysOffset<test_api::GL>>));
7922     addChild(new TestSubcase(m_context, "basic-drawArrays-vertexIds",
7923                              TestSubcase::Create<CBufferIndirectDrawArraysVertexIds<test_api::GL>>));
7924     addChild(new TestSubcase(m_context, "basic-drawElements-simple",
7925                              TestSubcase::Create<CBufferIndirectDrawElementsSimple<test_api::GL>>));
7926     addChild(new TestSubcase(m_context, "basic-drawElements-noFirstIndex",
7927                              TestSubcase::Create<CBufferIndirectDrawElementsNoFirstIndex<test_api::GL>>));
7928     addChild(new TestSubcase(m_context, "basic-drawElements-basevertex",
7929                              TestSubcase::Create<CBufferIndirectDrawElementsNoBasevertex<test_api::GL>>));
7930     addChild(new TestSubcase(m_context, "basic-drawElements-bufferOffset",
7931                              TestSubcase::Create<CBufferIndirectDrawElementsOffset<test_api::GL>>));
7932     addChild(new TestSubcase(m_context, "basic-drawElements-vertexIds",
7933                              TestSubcase::Create<CBufferIndirectDrawElementsVertexIds<test_api::GL>>));
7934 
7935     addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_short",
7936                              TestSubcase::Create<CIndicesDataTypeUnsignedShort<test_api::GL>>));
7937     addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_byte",
7938                              TestSubcase::Create<CIndicesDataTypeUnsignedByte<test_api::GL>>));
7939 
7940     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-points",
7941                              TestSubcase::Create<CModeDrawArraysPoints<test_api::GL>>));
7942     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines",
7943                              TestSubcase::Create<CModeDrawArraysLines<test_api::GL>>));
7944     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip",
7945                              TestSubcase::Create<CModeDrawArraysLineStrip<test_api::GL>>));
7946     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_loop",
7947                              TestSubcase::Create<CModeDrawArraysLineLoop<test_api::GL>>));
7948     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip",
7949                              TestSubcase::Create<CModeDrawArraysTriangleStrip<test_api::GL>>));
7950     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_fan",
7951                              TestSubcase::Create<CModeDrawArraysTriangleFan<test_api::GL>>));
7952     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines_adjacency",
7953                              TestSubcase::Create<CModeDrawArraysLinesAdjacency<test_api::GL>>));
7954     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip_adjacency",
7955                              TestSubcase::Create<CModeDrawArraysLineStripAdjacency<test_api::GL>>));
7956     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangles_adjacency",
7957                              TestSubcase::Create<CModeDrawArraysTrianglesAdjacency<test_api::GL>>));
7958     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip_adjacency",
7959                              TestSubcase::Create<CModeDrawArraysTriangleStripAdjacency<test_api::GL>>));
7960 
7961     addChild(new TestSubcase(m_context, "basic-mode-drawElements-points",
7962                              TestSubcase::Create<CModeDrawElementsPoints<test_api::GL>>));
7963     addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines",
7964                              TestSubcase::Create<CModeDrawElementsLines<test_api::GL>>));
7965     addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip",
7966                              TestSubcase::Create<CModeDrawElementsLineStrip<test_api::GL>>));
7967     addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_loop",
7968                              TestSubcase::Create<CModeDrawElementsLineLoop<test_api::GL>>));
7969     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip",
7970                              TestSubcase::Create<CModeDrawElementsTriangleStrip<test_api::GL>>));
7971     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_fan",
7972                              TestSubcase::Create<CModeDrawElementsTriangleFan<test_api::GL>>));
7973     addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines_adjacency",
7974                              TestSubcase::Create<CModeDrawElementsLinesAdjacency<test_api::GL>>));
7975     addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip_adjacency",
7976                              TestSubcase::Create<CModeDrawElementsLineStripAdjacency<test_api::GL>>));
7977     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangles_adjacency",
7978                              TestSubcase::Create<CModeDrawElementsTrianglesAdjacency<test_api::GL>>));
7979     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip_adjacency",
7980                              TestSubcase::Create<CModeDrawElementsTriangleStripAdjacency<test_api::GL>>));
7981 
7982     addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-arrays",
7983                              TestSubcase::Create<CTransformFeedbackArray<test_api::GL>>));
7984     addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-elements",
7985                              TestSubcase::Create<CTransformFeedbackElements<test_api::GL>>));
7986 
7987     addChild(new TestSubcase(m_context, "advanced-primitiveRestart-elements",
7988                              TestSubcase::Create<CPrimitiveRestartElements<test_api::GL>>));
7989 
7990     addChild(new TestSubcase(m_context, "negative-noindirect-arrays",
7991                              TestSubcase::Create<CNegativeZeroBufferArray<test_api::GL>>));
7992     addChild(new TestSubcase(m_context, "negative-noindirect-elements",
7993                              TestSubcase::Create<CNegativeZeroBufferElements<test_api::GL>>));
7994     addChild(new TestSubcase(m_context, "negative-invalidMode-arrays",
7995                              TestSubcase::Create<CNegativeInvalidModeArray<test_api::GL>>));
7996     addChild(new TestSubcase(m_context, "negative-invalidMode-elements",
7997                              TestSubcase::Create<CNegativeInvalidModeElements<test_api::GL>>));
7998     addChild(
7999         new TestSubcase(m_context, "negative-noVAO-arrays", TestSubcase::Create<CNegativeNoVAOArrays<test_api::GL>>));
8000     addChild(new TestSubcase(m_context, "negative-noVAO-elements",
8001                              TestSubcase::Create<CNegativeNoVAOElements<test_api::GL>>));
8002     addChild(new TestSubcase(m_context, "negative-bufferMapped-arrays",
8003                              TestSubcase::Create<CNegativeBufferMappedArray<test_api::GL>>));
8004     addChild(new TestSubcase(m_context, "negative-bufferMapped-elements",
8005                              TestSubcase::Create<CNegativeBufferMappedElements<test_api::GL>>));
8006     addChild(new TestSubcase(m_context, "negative-invalidType-elements",
8007                              TestSubcase::Create<CNegativeDataWrongElements<test_api::GL>>));
8008     addChild(new TestSubcase(m_context, "negative-gshIncompatible-arrays",
8009                              TestSubcase::Create<CNegativeGshArray<test_api::GL>>));
8010     addChild(new TestSubcase(m_context, "negative-gshIncompatible-elements",
8011                              TestSubcase::Create<CNegativeGshElements<test_api::GL>>));
8012     addChild(new TestSubcase(m_context, "negative-wrongOffset-arrays",
8013                              TestSubcase::Create<CNegativeStructureWrongOffsetArray<test_api::GL>>));
8014     addChild(new TestSubcase(m_context, "negative-wrongOffset-elements",
8015                              TestSubcase::Create<CNegativeStructureWrongOffsetElements<test_api::GL>>));
8016     addChild(new TestSubcase(m_context, "negative-invalidSize-arrays",
8017                              TestSubcase::Create<CNegativeInvalidSizeArrays<test_api::GL>>));
8018     addChild(new TestSubcase(m_context, "negative-invalidSize-elements",
8019                              TestSubcase::Create<CNegativeInvalidSizeElements<test_api::GL>>));
8020     addChild(new TestSubcase(m_context, "negative-unalignedOffset",
8021                              TestSubcase::Create<CNegativeUnalignedOffset<test_api::GL>>));
8022 }
8023 
DrawIndirectTestsGL43(glcts::Context & context)8024 DrawIndirectTestsGL43::DrawIndirectTestsGL43(glcts::Context &context) : TestCaseGroup(context, "draw_indirect_43", "")
8025 {
8026 }
8027 
~DrawIndirectTestsGL43(void)8028 DrawIndirectTestsGL43::~DrawIndirectTestsGL43(void)
8029 {
8030 }
8031 
init()8032 void DrawIndirectTestsGL43::init()
8033 {
8034     using namespace glcts;
8035 
8036     DILogger::setOutput(m_context.getTestContext().getLog());
8037     addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-arrays",
8038                              TestSubcase::Create<CComputeShaderArray<test_api::GL>>));
8039     addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-elements",
8040                              TestSubcase::Create<CComputeShaderElements<test_api::GL>>));
8041 }
8042 
DrawIndirectTestsES31(glcts::Context & context)8043 DrawIndirectTestsES31::DrawIndirectTestsES31(glcts::Context &context) : TestCaseGroup(context, "draw_indirect", "")
8044 {
8045 }
8046 
~DrawIndirectTestsES31(void)8047 DrawIndirectTestsES31::~DrawIndirectTestsES31(void)
8048 {
8049 }
8050 
init()8051 void DrawIndirectTestsES31::init()
8052 {
8053     using namespace glcts;
8054 
8055     DILogger::setOutput(m_context.getTestContext().getLog());
8056 
8057     addChild(
8058         new TestSubcase(m_context, "basic-binding-default", TestSubcase::Create<CDefaultBindingPoint<test_api::ES3>>));
8059     addChild(new TestSubcase(m_context, "basic-binding-zero", TestSubcase::Create<CZeroBindingPoint<test_api::ES3>>));
8060     addChild(
8061         new TestSubcase(m_context, "basic-binding-single", TestSubcase::Create<CSingleBindingPoint<test_api::ES3>>));
8062     addChild(new TestSubcase(m_context, "basic-binding-multi", TestSubcase::Create<CMultiBindingPoint<test_api::ES3>>));
8063     addChild(
8064         new TestSubcase(m_context, "basic-binding-delete", TestSubcase::Create<CDeleteBindingPoint<test_api::ES3>>));
8065 
8066     addChild(new TestSubcase(m_context, "basic-buffer-data", TestSubcase::Create<CBufferData<test_api::ES3>>));
8067     addChild(new TestSubcase(m_context, "basic-buffer-subData", TestSubcase::Create<CBufferSubData<test_api::ES3>>));
8068     addChild(
8069         new TestSubcase(m_context, "basic-buffer-getPointerv", TestSubcase::Create<CBufferGetPointerv<test_api::ES3>>));
8070     addChild(new TestSubcase(m_context, "basic-buffer-mapRange", TestSubcase::Create<CBufferMapRange<test_api::ES3>>));
8071     addChild(new TestSubcase(m_context, "basic-buffer-flushMappedRange",
8072                              TestSubcase::Create<CBufferFlushMappedRange<test_api::ES3>>));
8073     addChild(
8074         new TestSubcase(m_context, "basic-buffer-copySubData", TestSubcase::Create<CBufferCopySubData<test_api::ES3>>));
8075 
8076     addChild(new TestSubcase(m_context, "basic-drawArrays-singlePrimitive",
8077                              TestSubcase::Create<CVBODrawArraysSingle<test_api::ES3>>));
8078     addChild(new TestSubcase(m_context, "basic-drawArrays-manyPrimitives",
8079                              TestSubcase::Create<CVBODrawArraysMany<test_api::ES3>>));
8080     addChild(new TestSubcase(m_context, "basic-drawArrays-instancing",
8081                              TestSubcase::Create<CVBODrawArraysInstancing<test_api::ES3>>));
8082     addChild(new TestSubcase(m_context, "basic-drawArrays-xfbPaused",
8083                              TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::ES3>>));
8084     addChild(new TestSubcase(m_context, "basic-drawElements-singlePrimitive",
8085                              TestSubcase::Create<CVBODrawElementsSingle<test_api::ES3>>));
8086     addChild(new TestSubcase(m_context, "basic-drawElements-manyPrimitives",
8087                              TestSubcase::Create<CVBODrawElementsMany<test_api::ES3>>));
8088     addChild(new TestSubcase(m_context, "basic-drawElements-instancing",
8089                              TestSubcase::Create<CVBODrawElementsInstancing<test_api::ES3>>));
8090     addChild(new TestSubcase(m_context, "basic-drawElements-xfbPaused",
8091                              TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::ES3>>));
8092 
8093     addChild(new TestSubcase(m_context, "basic-drawArrays-simple",
8094                              TestSubcase::Create<CBufferIndirectDrawArraysSimple<test_api::ES3>>));
8095     addChild(new TestSubcase(m_context, "basic-drawArrays-noFirst",
8096                              TestSubcase::Create<CBufferIndirectDrawArraysNoFirst<test_api::ES3>>));
8097     addChild(new TestSubcase(m_context, "basic-drawArrays-bufferOffset",
8098                              TestSubcase::Create<CBufferIndirectDrawArraysOffset<test_api::ES3>>));
8099     addChild(new TestSubcase(m_context, "basic-drawArrays-vertexIds",
8100                              TestSubcase::Create<CBufferIndirectDrawArraysVertexIds<test_api::ES3>>));
8101     addChild(new TestSubcase(m_context, "basic-drawElements-simple",
8102                              TestSubcase::Create<CBufferIndirectDrawElementsSimple<test_api::ES3>>));
8103     addChild(new TestSubcase(m_context, "basic-drawElements-noFirstIndex",
8104                              TestSubcase::Create<CBufferIndirectDrawElementsNoFirstIndex<test_api::ES3>>));
8105     addChild(new TestSubcase(m_context, "basic-drawElements-basevertex",
8106                              TestSubcase::Create<CBufferIndirectDrawElementsNoBasevertex<test_api::ES3>>));
8107     addChild(new TestSubcase(m_context, "basic-drawElements-bufferOffset",
8108                              TestSubcase::Create<CBufferIndirectDrawElementsOffset<test_api::ES3>>));
8109     addChild(new TestSubcase(m_context, "basic-drawElements-vertexIds",
8110                              TestSubcase::Create<CBufferIndirectDrawElementsVertexIds<test_api::ES3>>));
8111 
8112     addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_short",
8113                              TestSubcase::Create<CIndicesDataTypeUnsignedShort<test_api::ES3>>));
8114     addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_byte",
8115                              TestSubcase::Create<CIndicesDataTypeUnsignedByte<test_api::ES3>>));
8116 
8117     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-points",
8118                              TestSubcase::Create<CModeDrawArraysPoints<test_api::ES3>>));
8119     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines",
8120                              TestSubcase::Create<CModeDrawArraysLines<test_api::ES3>>));
8121     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip",
8122                              TestSubcase::Create<CModeDrawArraysLineStrip<test_api::ES3>>));
8123     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_loop",
8124                              TestSubcase::Create<CModeDrawArraysLineLoop<test_api::ES3>>));
8125     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip",
8126                              TestSubcase::Create<CModeDrawArraysTriangleStrip<test_api::ES3>>));
8127     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_fan",
8128                              TestSubcase::Create<CModeDrawArraysTriangleFan<test_api::ES3>>));
8129     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines_adjacency",
8130                              TestSubcase::Create<CModeDrawArraysLinesAdjacency<test_api::ES3>>));
8131     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip_adjacency",
8132                              TestSubcase::Create<CModeDrawArraysLineStripAdjacency<test_api::ES3>>));
8133     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangles_adjacency",
8134                              TestSubcase::Create<CModeDrawArraysTrianglesAdjacency<test_api::ES3>>));
8135     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip_adjacency",
8136                              TestSubcase::Create<CModeDrawArraysTriangleStripAdjacency<test_api::ES3>>));
8137 
8138     addChild(new TestSubcase(m_context, "basic-mode-drawElements-points",
8139                              TestSubcase::Create<CModeDrawElementsPoints<test_api::ES3>>));
8140     addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines",
8141                              TestSubcase::Create<CModeDrawElementsLines<test_api::ES3>>));
8142     addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip",
8143                              TestSubcase::Create<CModeDrawElementsLineStrip<test_api::ES3>>));
8144     addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_loop",
8145                              TestSubcase::Create<CModeDrawElementsLineLoop<test_api::ES3>>));
8146     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip",
8147                              TestSubcase::Create<CModeDrawElementsTriangleStrip<test_api::ES3>>));
8148     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_fan",
8149                              TestSubcase::Create<CModeDrawElementsTriangleFan<test_api::ES3>>));
8150     addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines_adjacency",
8151                              TestSubcase::Create<CModeDrawElementsLinesAdjacency<test_api::ES3>>));
8152     addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip_adjacency",
8153                              TestSubcase::Create<CModeDrawElementsLineStripAdjacency<test_api::ES3>>));
8154     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangles_adjacency",
8155                              TestSubcase::Create<CModeDrawElementsTrianglesAdjacency<test_api::ES3>>));
8156     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip_adjacency",
8157                              TestSubcase::Create<CModeDrawElementsTriangleStripAdjacency<test_api::ES3>>));
8158 
8159     addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-arrays",
8160                              TestSubcase::Create<CTransformFeedbackArray<test_api::ES3>>));
8161     addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-elements",
8162                              TestSubcase::Create<CTransformFeedbackElements<test_api::ES3>>));
8163 
8164     addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-arrays",
8165                              TestSubcase::Create<CComputeShaderArray<test_api::ES3>>));
8166     addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-elements",
8167                              TestSubcase::Create<CComputeShaderElements<test_api::ES3>>));
8168 
8169     addChild(new TestSubcase(m_context, "advanced-primitiveRestart-elements",
8170                              TestSubcase::Create<CPrimitiveRestartElements<test_api::ES3>>));
8171 
8172     addChild(new TestSubcase(m_context, "negative-noindirect-arrays",
8173                              TestSubcase::Create<CNegativeZeroBufferArray<test_api::ES3>>));
8174     addChild(new TestSubcase(m_context, "negative-noindirect-elements",
8175                              TestSubcase::Create<CNegativeZeroBufferElements<test_api::ES3>>));
8176     addChild(new TestSubcase(m_context, "negative-invalidMode-arrays",
8177                              TestSubcase::Create<CNegativeInvalidModeArray<test_api::ES3>>));
8178     addChild(new TestSubcase(m_context, "negative-invalidMode-elements",
8179                              TestSubcase::Create<CNegativeInvalidModeElements<test_api::ES3>>));
8180     addChild(
8181         new TestSubcase(m_context, "negative-noVAO-arrays", TestSubcase::Create<CNegativeNoVAOArrays<test_api::ES3>>));
8182     addChild(new TestSubcase(m_context, "negative-noVAO-elements",
8183                              TestSubcase::Create<CNegativeNoVAOElements<test_api::ES3>>));
8184     addChild(
8185         new TestSubcase(m_context, "negative-noVBO-arrays", TestSubcase::Create<CNegativeNoVBOArrays<test_api::ES3>>));
8186     addChild(new TestSubcase(m_context, "negative-noVBO-elements",
8187                              TestSubcase::Create<CNegativeNoVBOElements<test_api::ES3>>));
8188     addChild(new TestSubcase(m_context, "negative-bufferMapped-arrays",
8189                              TestSubcase::Create<CNegativeBufferMappedArray<test_api::ES3>>));
8190     addChild(new TestSubcase(m_context, "negative-bufferMapped-elements",
8191                              TestSubcase::Create<CNegativeBufferMappedElements<test_api::ES3>>));
8192     addChild(new TestSubcase(m_context, "negative-invalidType-elements",
8193                              TestSubcase::Create<CNegativeDataWrongElements<test_api::ES3>>));
8194 
8195     addChild(new TestSubcase(m_context, "negative-wrongOffset-arrays",
8196                              TestSubcase::Create<CNegativeStructureWrongOffsetArray<test_api::ES3>>));
8197     addChild(new TestSubcase(m_context, "negative-wrongOffset-elements",
8198                              TestSubcase::Create<CNegativeStructureWrongOffsetElements<test_api::ES3>>));
8199     addChild(new TestSubcase(m_context, "negative-invalidSize-arrays",
8200                              TestSubcase::Create<CNegativeInvalidSizeArrays<test_api::ES3>>));
8201     addChild(new TestSubcase(m_context, "negative-invalidSize-elements",
8202                              TestSubcase::Create<CNegativeInvalidSizeElements<test_api::ES3>>));
8203     addChild(new TestSubcase(m_context, "negative-unalignedOffset",
8204                              TestSubcase::Create<CNegativeUnalignedOffset<test_api::ES3>>));
8205     addChild(new TestSubcase(m_context, "negative-xfb", TestSubcase::Create<CNegativeXFB<test_api::ES3>>));
8206 }
8207 } // namespace glcts
8208