• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::__anon91df61990111::test_api::ES3134     static bool isES()
135     {
136         return true;
137     }
glslVerglcts::__anon91df61990111::test_api::ES3138     static std::string glslVer(bool = false)
139     {
140         return "#version 310 es";
141     }
ES_Onlyglcts::__anon91df61990111::test_api::ES3142     static void ES_Only()
143     {
144     }
145 };
146 
147 struct GL
148 {
isESglcts::__anon91df61990111::test_api::GL149     static bool isES()
150     {
151         return false;
152     }
glslVerglcts::__anon91df61990111::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::__anon91df61990111::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::__anon91df61990111::CDefaultBindingPoint886     virtual std::string Title()
887     {
888         return "Draw Indirect: Check default binding point";
889     }
890 
Purposeglcts::__anon91df61990111::CDefaultBindingPoint891     virtual std::string Purpose()
892     {
893         return "Verify that default binding point is set to zero";
894     }
895 
Methodglcts::__anon91df61990111::CDefaultBindingPoint896     virtual std::string Method()
897     {
898         return "Use glGetIntegerv, glGetBooleanv, glGetFloatv, glGetDoublev to get default binding point";
899     }
900 
PassCriteriaglcts::__anon91df61990111::CDefaultBindingPoint901     virtual std::string PassCriteria()
902     {
903         return "The test will pass if default binding point is zero";
904     }
905 
Runglcts::__anon91df61990111::CDefaultBindingPoint906     virtual long Run()
907     {
908         return BindingPointCheck<api>(0);
909     }
910 };
911 
912 template <typename api>
913 struct CZeroBindingPoint : public DrawIndirectBase
914 {
Titleglcts::__anon91df61990111::CZeroBindingPoint915     virtual std::string Title()
916     {
917         return "Draw Indirect: Zero binding point";
918     }
919 
Purposeglcts::__anon91df61990111::CZeroBindingPoint920     virtual std::string Purpose()
921     {
922         return "Verify that binding point is set to zero";
923     }
924 
Methodglcts::__anon91df61990111::CZeroBindingPoint925     virtual std::string Method()
926     {
927         return "Bind zero and check that binding point is set to zero";
928     }
929 
PassCriteriaglcts::__anon91df61990111::CZeroBindingPoint930     virtual std::string PassCriteria()
931     {
932         return "The test will pass if binding point is set to zero";
933     }
934 
Runglcts::__anon91df61990111::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::__anon91df61990111::CSingleBindingPoint946     virtual std::string Title()
947     {
948         return "Draw Indirect: Single binding point";
949     }
950 
Purposeglcts::__anon91df61990111::CSingleBindingPoint951     virtual std::string Purpose()
952     {
953         return "Verify that binding point is set to correct value";
954     }
955 
Methodglcts::__anon91df61990111::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::__anon91df61990111::CSingleBindingPoint961     virtual std::string PassCriteria()
962     {
963         return "The test will pass if binding point is set to correct value";
964     }
965 
Runglcts::__anon91df61990111::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::__anon91df61990111::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::__anon91df61990111::CDeleteBindingPoint1040     virtual std::string Title()
1041     {
1042         return "Draw Indirect: Delete binding point";
1043     }
1044 
Purposeglcts::__anon91df61990111::CDeleteBindingPoint1045     virtual std::string Purpose()
1046     {
1047         return "Verify that after deleting buffer, binding point is set to correct value";
1048     }
1049 
Methodglcts::__anon91df61990111::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::__anon91df61990111::CDeleteBindingPoint1055     virtual std::string PassCriteria()
1056     {
1057         return "The test will pass if binding point is set to correct value";
1058     }
1059 
Runglcts::__anon91df61990111::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::__anon91df61990111::CBufferData1075     virtual std::string Title()
1076     {
1077         return "Check functions: glBufferData and GetBufferSubData<api>";
1078     }
1079 
Purposeglcts::__anon91df61990111::CBufferData1080     virtual std::string Purpose()
1081     {
1082         return "Verify that glBufferData and GetBufferSubData<api> accepts GL_DRAW_INDIRECT_BUFFER enum";
1083     }
1084 
Methodglcts::__anon91df61990111::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::__anon91df61990111::CBufferData1091     virtual std::string PassCriteria()
1092     {
1093         return "The test will pass if no OpenGL errors reported";
1094     }
1095 
Runglcts::__anon91df61990111::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::__anon91df61990111::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::__anon91df61990111::CBufferSubData1233     virtual std::string Title()
1234     {
1235         return "Check function: glBufferSubData and GetBufferSubData<api>";
1236     }
1237 
Purposeglcts::__anon91df61990111::CBufferSubData1238     virtual std::string Purpose()
1239     {
1240         return "Verify that glBufferSubData and GetBufferSubData<api> accepts GL_DRAW_INDIRECT_BUFFER enum";
1241     }
1242 
Methodglcts::__anon91df61990111::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::__anon91df61990111::CBufferSubData1249     virtual std::string PassCriteria()
1250     {
1251         return "The test will pass if no OpenGL errors reported";
1252     }
1253 
Runglcts::__anon91df61990111::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::__anon91df61990111::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::__anon91df61990111::CBufferMap1301     virtual std::string Title()
1302     {
1303         return "Check functions: glMapBuffer, glUnmapBuffer and getParameteriv";
1304     }
1305 
Purposeglcts::__anon91df61990111::CBufferMap1306     virtual std::string Purpose()
1307     {
1308         return "Verify that glMapBuffer, glUnmapBuffer and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum";
1309     }
1310 
Methodglcts::__anon91df61990111::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::__anon91df61990111::CBufferMap1317     virtual std::string PassCriteria()
1318     {
1319         return "The test will pass if no OpenGL errors reported";
1320     }
1321 
Runglcts::__anon91df61990111::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(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT, 0,
1371                                                  (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));
1372             memcpy(buf, &dataRef[0], dataRef.size() * sizeof(unsigned int));
1373             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE)
1374             {
1375                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1376             }
1377             buf = 0;
1378 
1379             result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1380         }
1381 
1382         buf = glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_WRITE);
1383         if (buf == 0)
1384         {
1385             result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_WRITE) returned NULL";
1386         }
1387 
1388         if (buf)
1389         {
1390             result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight));
1391 
1392             result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_WRITE, GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, 0,
1393                                                  (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));
1394 
1395             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
1396             {
1397                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1398             }
1399             buf = 0;
1400 
1401             result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1402         }
1403 
1404         return result.code();
1405     }
1406 
Cleanupglcts::__anon91df61990111::CBufferMap1407     virtual long Cleanup()
1408     {
1409         glDeleteBuffers(1, &_buffer);
1410         return BindingPointCheck<api>(0);
1411     }
1412 
1413 private:
1414     GLuint _buffer;
1415 };
1416 
1417 template <typename api>
1418 struct CBufferGetPointerv : public DrawIndirectBase
1419 {
Titleglcts::__anon91df61990111::CBufferGetPointerv1420     virtual std::string Title()
1421     {
1422         return "Check functions: glBuffergetPointerv";
1423     }
1424 
Purposeglcts::__anon91df61990111::CBufferGetPointerv1425     virtual std::string Purpose()
1426     {
1427         return "Verify that glBuffergetPointerv accepts GL_DRAW_INDIRECT_BUFFER enum";
1428     }
1429 
Methodglcts::__anon91df61990111::CBufferGetPointerv1430     virtual std::string Method()
1431     {
1432         return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer" NL
1433                "5. Get a pointer to buffer" NL "6. Compare pointers from point 4) and 5)" NL
1434                "7. Verify mapped buffer" NL "8. Unmap buffer";
1435     }
1436 
PassCriteriaglcts::__anon91df61990111::CBufferGetPointerv1437     virtual std::string PassCriteria()
1438     {
1439         return "The test will pass if no OpenGL errors reported";
1440     }
1441 
Runglcts::__anon91df61990111::CBufferGetPointerv1442     virtual long Run()
1443     {
1444         DIResult result;
1445 
1446         glGenBuffers(1, &_buffer);
1447         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
1448 
1449         CDataArray dataRef;
1450         int dataWidth, dataHeight;
1451         getDataSize(dataWidth, dataHeight);
1452         DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50);
1453         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
1454                      GL_DYNAMIC_DRAW);
1455 
1456         void *ptr = 0;
1457         glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER, &ptr);
1458 
1459         if (ptr != 0)
1460         {
1461             result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) returned invalid "
1462                               "pointer, expected: NULL";
1463         }
1464 
1465         void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)),
1466                                      GL_MAP_READ_BIT);
1467         if (buf == 0)
1468         {
1469             result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
1470 
1471             return result.code();
1472         }
1473 
1474         glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER, &ptr);
1475 
1476         if (ptr == 0)
1477         {
1478             result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) returned NULL";
1479         }
1480 
1481         if (ptr)
1482         {
1483             result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, ptr, dataWidth, dataHeight));
1484         }
1485 
1486         if (ptr != buf)
1487         {
1488             result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) different pointer "
1489                               "than glMapBuffer(GL_DRAW_INDIRECT_BUFFER)";
1490         }
1491 
1492         if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
1493         {
1494             result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1495         }
1496         buf = 0;
1497         ptr = 0;
1498 
1499         return result.code();
1500     }
1501 
Cleanupglcts::__anon91df61990111::CBufferGetPointerv1502     virtual long Cleanup()
1503     {
1504         glDeleteBuffers(1, &_buffer);
1505         return BindingPointCheck<api>(0);
1506     }
1507 
1508 private:
1509     GLuint _buffer;
1510 };
1511 
1512 template <class api>
1513 struct CBufferMapRange : public DrawIndirectBase
1514 {
Titleglcts::__anon91df61990111::CBufferMapRange1515     virtual std::string Title()
1516     {
1517         return "Check functions: glMapRangeBuffer, glUnmapBuffer and getParameteriv";
1518     }
1519 
Purposeglcts::__anon91df61990111::CBufferMapRange1520     virtual std::string Purpose()
1521     {
1522         return "Verify that glMapRangeBuffer, glUnmapBuffer and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum";
1523     }
1524 
Methodglcts::__anon91df61990111::CBufferMapRange1525     virtual std::string Method()
1526     {
1527         return "Bind non-zero buffer and check that binding point is set to correct value";
1528     }
1529 
PassCriteriaglcts::__anon91df61990111::CBufferMapRange1530     virtual std::string PassCriteria()
1531     {
1532         return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer using glMapBufferRange" NL
1533                "5. Check state" NL "6. Verify mapped buffer" NL "7. Unmap buffer" NL "8. Check state";
1534     }
1535 
Runglcts::__anon91df61990111::CBufferMapRange1536     virtual long Run()
1537     {
1538         DIResult result;
1539 
1540         glGenBuffers(1, &_buffer);
1541         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
1542 
1543         CDataArray dataRef;
1544         int dataWidth, dataHeight;
1545         getDataSize(dataWidth, dataHeight);
1546         DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50);
1547         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
1548                      GL_DYNAMIC_DRAW);
1549 
1550         result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1551 
1552         void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)),
1553                                      GL_MAP_READ_BIT);
1554         if (buf == 0)
1555         {
1556             result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
1557         }
1558 
1559         if (buf)
1560         {
1561             result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight));
1562 
1563             result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_ONLY, GL_MAP_READ_BIT, 0,
1564                                                  (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));
1565 
1566             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
1567             {
1568                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1569             }
1570             buf = 0;
1571 
1572             result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1573         }
1574 
1575         buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int)),
1576                                GL_MAP_READ_BIT);
1577         if (buf == 0)
1578         {
1579             result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
1580         }
1581 
1582         if (buf)
1583         {
1584             result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight / 2, buf, dataWidth, dataHeight / 2));
1585 
1586             result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_ONLY, GL_MAP_READ_BIT, 0,
1587                                                  (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int))));
1588 
1589             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
1590             {
1591                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1592             }
1593             buf = 0;
1594 
1595             result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1596         }
1597 
1598         buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, (GLintptr)(dataRef.size() / 4 * sizeof(unsigned int)),
1599                                (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int)), GL_MAP_READ_BIT);
1600         if (buf == 0)
1601         {
1602             result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
1603         }
1604 
1605         if (buf)
1606         {
1607             result.sub_result(
1608                 BufferCheck(dataRef, dataWidth, dataHeight / 2, buf, dataWidth, dataHeight / 2, dataHeight / 4));
1609 
1610             result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_ONLY, GL_MAP_READ_BIT,
1611                                                  (GLintptr)(dataRef.size() / 4 * sizeof(unsigned int)),
1612                                                  (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int))));
1613 
1614             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
1615             {
1616                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1617             }
1618             buf = 0;
1619 
1620             result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1621         }
1622 
1623         return result.code();
1624     }
1625 
Cleanupglcts::__anon91df61990111::CBufferMapRange1626     virtual long Cleanup()
1627     {
1628         glDeleteBuffers(1, &_buffer);
1629         return BindingPointCheck<api>(0);
1630     }
1631 
1632 private:
1633     GLuint _buffer;
1634 };
1635 
1636 template <class api>
1637 struct CBufferFlushMappedRange : public DrawIndirectBase
1638 {
Titleglcts::__anon91df61990111::CBufferFlushMappedRange1639     virtual std::string Title()
1640     {
1641         return "Check functions: glFlushMappedBufferRange";
1642     }
1643 
Purposeglcts::__anon91df61990111::CBufferFlushMappedRange1644     virtual std::string Purpose()
1645     {
1646         return "Verify that glFlushMappedBufferRange and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum";
1647     }
1648 
Methodglcts::__anon91df61990111::CBufferFlushMappedRange1649     virtual std::string Method()
1650     {
1651         return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL
1652                "4. Map buffer with GL_MAP_FLUSH_EXPLICIT_BIT flag" NL "5. Check state" NL "6. Modify mapped buffer" NL
1653                "7. Flush buffer" NL "8. Unmap buffer" NL "9. Check state" NL "10. Verify buffer";
1654     }
1655 
PassCriteriaglcts::__anon91df61990111::CBufferFlushMappedRange1656     virtual std::string PassCriteria()
1657     {
1658         return "The test will pass if no OpenGL errors reported";
1659     }
1660 
Runglcts::__anon91df61990111::CBufferFlushMappedRange1661     virtual long Run()
1662     {
1663         DIResult result;
1664 
1665         glGenBuffers(1, &_buffer);
1666         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
1667 
1668         CDataArray dataRef;
1669         int dataWidth, dataHeight;
1670         getDataSize(dataWidth, dataHeight);
1671         DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 1, 1000);
1672 
1673         CDataArray dataRef2;
1674         DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 1000, 2000);
1675 
1676         const int halfSize    = dataHeight / 2 * dataWidth;
1677         const int quarterSize = dataHeight / 4 * dataWidth;
1678 
1679         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
1680                      GL_DYNAMIC_DRAW);
1681 
1682         result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1683 
1684         void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, quarterSize * sizeof(unsigned int),
1685                                      halfSize * sizeof(unsigned int), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
1686 
1687         if (buf == 0)
1688         {
1689             result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL";
1690         }
1691 
1692         if (buf)
1693         {
1694             result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT,
1695                                                  quarterSize * sizeof(unsigned int), halfSize * sizeof(unsigned int)));
1696 
1697             memcpy(buf, &dataRef2[quarterSize], halfSize * sizeof(unsigned int));
1698             glFlushMappedBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, halfSize * sizeof(unsigned int));
1699 
1700             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
1701             {
1702                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
1703             }
1704             buf = 0;
1705 
1706             result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
1707         }
1708 
1709         CDataArray dataTest(dataWidth * dataHeight, 0);
1710         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1711                               &dataTest[0]);
1712 
1713         result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4));
1714 
1715         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2,
1716                                       dataHeight / 4, dataHeight / 4));
1717 
1718         result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4,
1719                                       dataHeight * 3 / 4, dataHeight * 3 / 4));
1720 
1721         return result.code();
1722     }
1723 
Cleanupglcts::__anon91df61990111::CBufferFlushMappedRange1724     virtual long Cleanup()
1725     {
1726         glDeleteBuffers(1, &_buffer);
1727         return BindingPointCheck<api>(0);
1728     }
1729 
1730 private:
1731     GLuint _buffer;
1732 };
1733 
1734 template <class api>
1735 struct CBufferBindRange : public DrawIndirectBase
1736 {
Titleglcts::__anon91df61990111::CBufferBindRange1737     virtual std::string Title()
1738     {
1739         return "Check functions: glBindBufferRange";
1740     }
1741 
Purposeglcts::__anon91df61990111::CBufferBindRange1742     virtual std::string Purpose()
1743     {
1744         return "Verify that glBindBufferRange accepts GL_DRAW_INDIRECT_BUFFER enum";
1745     }
1746 
Methodglcts::__anon91df61990111::CBufferBindRange1747     virtual std::string Method()
1748     {
1749         return "1. Create buffer" NL "2. Bind buffer using glBindBufferRange" NL "3. Set data" NL "4. Verify buffer";
1750     }
1751 
PassCriteriaglcts::__anon91df61990111::CBufferBindRange1752     virtual std::string PassCriteria()
1753     {
1754         return "The test will pass if no OpenGL errors reported";
1755     }
1756 
Runglcts::__anon91df61990111::CBufferBindRange1757     virtual long Run()
1758     {
1759         DIResult result;
1760 
1761         glGenBuffers(1, &_buffer);
1762         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
1763 
1764         CDataArray dataRef;
1765         int dataWidth, dataHeight;
1766         getDataSize(dataWidth, dataHeight);
1767         DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 1, 100);
1768         glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef.size() * sizeof(unsigned int), &dataRef[0], GL_DYNAMIC_DRAW);
1769 
1770         CDataArray dataTest(dataWidth * dataHeight, 0);
1771         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
1772         result.sub_result(DataCompare(dataRef, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1773 
1774         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
1775         result.sub_result(BindingPointCheck<api>(0));
1776 
1777         glBindBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _buffer, 0, dataTest.size() * sizeof(unsigned int) / 4);
1778         result.sub_result(BindingPointCheck<api>(_buffer));
1779 
1780         CDataArray dataRef2;
1781         DataGen<unsigned int>(dataRef2, dataWidth, dataHeight / 2, 10, 15);
1782         glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int) / 4, &dataRef2[0],
1783                      GL_DYNAMIC_DRAW);
1784 
1785         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
1786         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4));
1787         result.sub_result(DataCompare(dataRef, dataWidth, dataHeight * 3 / 4, dataTest, dataWidth, dataHeight * 3 / 4,
1788                                       dataHeight / 4, dataHeight / 4));
1789 
1790         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
1791         result.sub_result(BindingPointCheck<api>(0));
1792 
1793         glBindBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _buffer, dataTest.size() * sizeof(unsigned int) / 4,
1794                           dataTest.size() * sizeof(unsigned int) / 4);
1795         result.sub_result(BindingPointCheck<api>(_buffer));
1796 
1797         glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int) / 2,
1798                      &dataRef2[dataRef2.size() / 2], GL_DYNAMIC_DRAW);
1799         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2));
1800         result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2,
1801                                       dataHeight / 2, dataHeight / 2));
1802 
1803         return result.code();
1804     }
1805 
Cleanupglcts::__anon91df61990111::CBufferBindRange1806     virtual long Cleanup()
1807     {
1808         glDeleteBuffers(1, &_buffer);
1809 
1810         return BindingPointCheck<api>(0);
1811     }
1812 
1813 private:
1814     GLuint _buffer;
1815 };
1816 
1817 template <class api>
1818 struct CBufferBindBase : public DrawIndirectBase
1819 {
Titleglcts::__anon91df61990111::CBufferBindBase1820     virtual std::string Title()
1821     {
1822         return "Check functions: glBindBufferBase";
1823     }
1824 
Purposeglcts::__anon91df61990111::CBufferBindBase1825     virtual std::string Purpose()
1826     {
1827         return "Verify that glBindBufferBase accepts GL_DRAW_INDIRECT_BUFFER enum";
1828     }
1829 
Methodglcts::__anon91df61990111::CBufferBindBase1830     virtual std::string Method()
1831     {
1832         return "1. Create buffer" NL "2. Bind buffer using glBindBufferBase" NL "3. Set data" NL "4. Verify buffer";
1833     }
1834 
PassCriteriaglcts::__anon91df61990111::CBufferBindBase1835     virtual std::string PassCriteria()
1836     {
1837         return "The test will pass if no OpenGL errors reported";
1838     }
1839 
Runglcts::__anon91df61990111::CBufferBindBase1840     virtual long Run()
1841     {
1842         DIResult result;
1843 
1844         glGenBuffers(2, _buffers);
1845 
1846         int dataWidth, dataHeight;
1847         getDataSize(dataWidth, dataHeight);
1848         CDataArray dataTest(dataWidth * dataHeight, 0);
1849 
1850         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[0]);
1851         CDataArray dataRef1;
1852         DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 1, 100);
1853         glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef1.size() * sizeof(unsigned int), &dataRef1[0], GL_DYNAMIC_DRAW);
1854 
1855         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
1856         result.sub_result(BindingPointCheck<api>(0));
1857 
1858         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
1859         result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1860         result.sub_result(BindingPointCheck<api>(_buffers[0]));
1861 
1862         glBindBufferBase(GL_DRAW_INDIRECT_BUFFER, 0, _buffers[1]);
1863         result.sub_result(BindingPointCheck<api>(_buffers[1]));
1864 
1865         CDataArray dataRef2;
1866         DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 50, 70);
1867         glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int), &dataRef2[0], GL_DYNAMIC_DRAW);
1868 
1869         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
1870         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1871 
1872         result.sub_result(BindingPointCheck<api>(_buffers[1]));
1873 
1874         return result.code();
1875     }
1876 
Cleanupglcts::__anon91df61990111::CBufferBindBase1877     virtual long Cleanup()
1878     {
1879         glDeleteBuffers(2, _buffers);
1880         return BindingPointCheck<api>(0);
1881     }
1882 
1883 private:
1884     GLuint _buffers[2];
1885 };
1886 
1887 template <class api>
1888 struct CBufferCopySubData : public DrawIndirectBase
1889 {
Titleglcts::__anon91df61990111::CBufferCopySubData1890     virtual std::string Title()
1891     {
1892         return "Check functions: glCopyBufferSubData";
1893     }
1894 
Purposeglcts::__anon91df61990111::CBufferCopySubData1895     virtual std::string Purpose()
1896     {
1897         return "Verify that glCopyBufferSubData accepts GL_DRAW_INDIRECT_BUFFER enum";
1898     }
1899 
Methodglcts::__anon91df61990111::CBufferCopySubData1900     virtual std::string Method()
1901     {
1902         return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Verify buffer" NL
1903                "5. Modify buffer using glCopyBufferSubData" NL "6. Verify buffer";
1904     }
1905 
PassCriteriaglcts::__anon91df61990111::CBufferCopySubData1906     virtual std::string PassCriteria()
1907     {
1908         return "The test will pass if no OpenGL errors reported";
1909     }
1910 
Runglcts::__anon91df61990111::CBufferCopySubData1911     virtual long Run()
1912     {
1913         DIResult result;
1914         int dataWidth, dataHeight;
1915         getDataSize(dataWidth, dataHeight);
1916         CDataArray dataTest(dataWidth * dataHeight, 0);
1917 
1918         glGenBuffers(2, _buffers);
1919         glBindBuffer(GL_ARRAY_BUFFER, _buffers[0]);
1920 
1921         CDataArray dataRef1;
1922         DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 1, 100);
1923         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(dataRef1.size() * sizeof(unsigned int)), &dataRef1[0],
1924                      GL_DYNAMIC_DRAW);
1925 
1926         GetBufferSubData<api>(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), &dataTest[0]);
1927         result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1928 
1929         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[1]);
1930 
1931         CDataArray dataRef2;
1932         DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 10, 30);
1933         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0],
1934                      GL_DYNAMIC_DRAW);
1935 
1936         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1937                               &dataTest[0]);
1938         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1939 
1940         glCopyBufferSubData(GL_ARRAY_BUFFER, GL_DRAW_INDIRECT_BUFFER, 0, 0,
1941                             (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)));
1942 
1943         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1944                               &dataTest[0]);
1945         result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1946 
1947         glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0],
1948                      GL_DYNAMIC_DRAW);
1949 
1950         GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
1951                               &dataTest[0]);
1952         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1953 
1954         glCopyBufferSubData(GL_DRAW_INDIRECT_BUFFER, GL_ARRAY_BUFFER, 0, 0,
1955                             (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)));
1956 
1957         GetBufferSubData<api>(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), &dataTest[0]);
1958         result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
1959 
1960         return result.code();
1961     }
1962 
Cleanupglcts::__anon91df61990111::CBufferCopySubData1963     virtual long Cleanup()
1964     {
1965         glDeleteBuffers(2, _buffers);
1966         return BindingPointCheck<api>(0);
1967     }
1968 
1969 private:
1970     GLuint _buffers[2];
1971 };
1972 
1973 class CBasicVertexDef : public DrawIndirectBase
1974 {
1975 public:
Setup()1976     virtual long Setup()
1977     {
1978         glClear(GL_COLOR_BUFFER_BIT);
1979         return NO_ERROR;
1980     }
1981 
1982     template <typename api>
Run()1983     long Run()
1984     {
1985         CColorArray coords;
1986         PrimitiveGen(_primitiveType, _drawSizeX, _drawSizeY, coords);
1987 
1988         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
1989         if (!_program)
1990         {
1991             return ERROR;
1992         }
1993         glUseProgram(_program);
1994 
1995         glGenBuffers(1, &_vbo);
1996         glBindBuffer(GL_ARRAY_BUFFER, _vbo);
1997         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW);
1998 
1999         glGenVertexArrays(1, &_vao);
2000         glBindVertexArray(_vao);
2001         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
2002         glEnableVertexAttribArray(0);
2003 
2004         DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
2005         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
2006 
2007         CElementArray elements(coords.size(), 0);
2008         for (size_t i = 0; i < elements.size(); ++i)
2009         {
2010             elements[i] = static_cast<GLuint>(i);
2011         }
2012 
2013         switch (_drawFunc)
2014         {
2015         case DRAW_ARRAYS:
2016         {
2017             indirectArrays.count              = static_cast<GLuint>(coords.size());
2018             indirectArrays.primCount          = 1;
2019             indirectArrays.first              = 0;
2020             indirectArrays.reservedMustBeZero = 0;
2021 
2022             {
2023                 GLuint buffer;
2024                 glGenBuffers(1, &buffer);
2025                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
2026                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
2027                 glDrawArraysIndirect(_primitiveType, 0);
2028                 glDeleteBuffers(1, &buffer);
2029             }
2030         }
2031         break;
2032         case DRAW_ELEMENTS:
2033         {
2034             indirectElements.count              = static_cast<GLuint>(coords.size());
2035             indirectElements.primCount          = 1;
2036             indirectElements.firstIndex         = 0;
2037             indirectElements.baseVertex         = 0;
2038             indirectElements.reservedMustBeZero = 0;
2039 
2040             glGenBuffers(1, &_ebo);
2041             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
2042             glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
2043                          GL_STATIC_DRAW);
2044 
2045             {
2046                 GLuint buffer;
2047                 glGenBuffers(1, &buffer);
2048                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
2049                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
2050                 glDrawElementsIndirect(_primitiveType, GL_UNSIGNED_INT, 0);
2051                 glDeleteBuffers(1, &buffer);
2052             }
2053         }
2054         break;
2055         default:
2056             throw std::runtime_error("Unknown draw function!");
2057             break;
2058         }
2059 
2060         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
2061         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
2062         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
2063 
2064         DIResult result;
2065         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
2066                                          getWindowHeight()));
2067 
2068         return result.code();
2069     }
2070 
Cleanup()2071     virtual long Cleanup()
2072     {
2073         glDisableVertexAttribArray(0);
2074         glBindBuffer(GL_ARRAY_BUFFER, 0);
2075         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2076         glBindVertexArray(0);
2077         glUseProgram(0);
2078 
2079         if (_vao)
2080         {
2081             glDeleteVertexArrays(1, &_vao);
2082         }
2083         if (_vbo)
2084         {
2085             glDeleteBuffers(1, &_vbo);
2086         }
2087         if (_ebo)
2088         {
2089             glDeleteBuffers(1, &_ebo);
2090         }
2091         if (_program)
2092         {
2093             glDeleteProgram(_program);
2094         }
2095 
2096         return NO_ERROR;
2097     }
2098 
CBasicVertexDef(TDrawFunction drawFunc,GLenum primitiveType,unsigned int drawSizeX,unsigned int drawSizeY)2099     CBasicVertexDef(TDrawFunction drawFunc, GLenum primitiveType, unsigned int drawSizeX, unsigned int drawSizeY)
2100         : _drawFunc(drawFunc)
2101         , _primitiveType(primitiveType)
2102         , _drawSizeX(drawSizeX)
2103         , _drawSizeY(drawSizeY)
2104         , _vao(0)
2105         , _vbo(0)
2106         , _ebo(0)
2107         , _program(0)
2108     {
2109     }
2110 
2111 private:
2112     TDrawFunction _drawFunc;
2113     GLenum _primitiveType;
2114     unsigned int _drawSizeX;
2115     unsigned int _drawSizeY;
2116 
2117     GLuint _vao;
2118     GLuint _vbo, _ebo;
2119     GLuint _program;
2120 
CBasicVertexDef()2121     CBasicVertexDef()
2122     {
2123     }
2124 };
2125 
2126 class CBasicVertexInstancingDef : public DrawIndirectBase
2127 {
2128 public:
Setup()2129     virtual long Setup()
2130     {
2131         glClear(GL_COLOR_BUFFER_BIT);
2132         return NO_ERROR;
2133     }
2134 
2135     template <typename api>
Run()2136     long Run()
2137     {
2138         CColorArray coords;
2139         PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords);
2140 
2141         CColorArray coords_instanced(4);
2142         coords_instanced[0] = tcu::Vec4(0.5, 0.5, 0.0, 0.0);
2143         coords_instanced[1] = tcu::Vec4(-0.5, 0.5, 0.0, 0.0);
2144         coords_instanced[2] = tcu::Vec4(-0.5, -0.5, 0.0, 0.0);
2145         coords_instanced[3] = tcu::Vec4(0.5, -0.5, 0.0, 0.0);
2146 
2147         CColorArray colors_instanced(2);
2148         colors_instanced[0] = tcu::Vec4(1.0, 0.0, 0.0, 1.0);
2149         colors_instanced[1] = tcu::Vec4(0.0, 1.0, 0.0, 1.0);
2150 
2151         _program = CreateProgram(Vsh<api>(), "", Fsh<api>(), true);
2152         if (!_program)
2153         {
2154             return ERROR;
2155         }
2156         glUseProgram(_program);
2157 
2158         glGenBuffers(1, &_vbo);
2159         glBindBuffer(GL_ARRAY_BUFFER, _vbo);
2160         glBufferData(GL_ARRAY_BUFFER,
2161                      (GLsizeiptr)(coords.size() * sizeof(coords[0]) +
2162                                   coords_instanced.size() * sizeof(coords_instanced[0]) +
2163                                   colors_instanced.size() * sizeof(colors_instanced[0])),
2164                      NULL, GL_STATIC_DRAW);
2165 
2166         const size_t coords_offset           = 0;
2167         const size_t coords_instanced_offset = coords_offset + coords.size() * sizeof(coords[0]);
2168         const size_t colors_instanced_offset =
2169             coords_instanced_offset + coords_instanced.size() * sizeof(coords_instanced[0]);
2170 
2171         glBufferSubData(GL_ARRAY_BUFFER, coords_offset, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0]);
2172         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)coords_instanced_offset,
2173                         (GLsizeiptr)(coords_instanced.size() * sizeof(coords_instanced[0])), &coords_instanced[0]);
2174         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)colors_instanced_offset,
2175                         (GLsizeiptr)(colors_instanced.size() * sizeof(colors_instanced[0])), &colors_instanced[0]);
2176 
2177         glGenVertexArrays(1, &_vao);
2178         glBindVertexArray(_vao);
2179 
2180         //i_vertex (coords)
2181         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(coords_offset));
2182         glEnableVertexAttribArray(0);
2183 
2184         //i_vertex_instanced (coords_instanced)
2185         glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(coords_instanced_offset));
2186         glEnableVertexAttribArray(1);
2187         glVertexAttribDivisor(1, 1);
2188 
2189         //i_vertex_color_instanced (color_instanced)
2190         glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(colors_instanced_offset));
2191         glEnableVertexAttribArray(2);
2192         glVertexAttribDivisor(2, 3);
2193 
2194         DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
2195         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
2196 
2197         CElementArray elements(coords.size(), 0);
2198         for (size_t i = 0; i < elements.size(); ++i)
2199         {
2200             elements[i] = static_cast<GLuint>(i);
2201         }
2202 
2203         switch (_drawFunc)
2204         {
2205         case DRAW_ARRAYS:
2206         {
2207             indirectArrays.count              = static_cast<GLuint>(coords.size());
2208             indirectArrays.primCount          = 4;
2209             indirectArrays.first              = 0;
2210             indirectArrays.reservedMustBeZero = 0;
2211 
2212             {
2213                 GLuint buffer;
2214                 glGenBuffers(1, &buffer);
2215                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
2216                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
2217                 glDrawArraysIndirect(GL_TRIANGLES, 0);
2218                 glDeleteBuffers(1, &buffer);
2219             }
2220         }
2221         break;
2222         case DRAW_ELEMENTS:
2223         {
2224             indirectElements.count              = static_cast<GLuint>(coords.size());
2225             indirectElements.primCount          = 4;
2226             indirectElements.firstIndex         = 0;
2227             indirectElements.baseVertex         = 0;
2228             indirectElements.reservedMustBeZero = 0;
2229 
2230             glGenBuffers(1, &_ebo);
2231             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
2232             glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
2233                          GL_STATIC_DRAW);
2234 
2235             {
2236                 GLuint buffer;
2237                 glGenBuffers(1, &buffer);
2238                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
2239                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
2240                 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
2241                 glDeleteBuffers(1, &buffer);
2242             }
2243         }
2244         break;
2245         default:
2246             throw std::runtime_error("Unknown draw function!");
2247             break;
2248         }
2249 
2250         CColorArray bufferRef1(getWindowWidth() / 2 * getWindowHeight() / 2, colors_instanced[0]);
2251         CColorArray bufferRef2(getWindowWidth() / 2 * getWindowHeight() / 2, colors_instanced[1]);
2252 
2253         CColorArray bufferTest(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f));
2254         DIResult result;
2255 
2256         ReadPixelsFloat<api>(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, &bufferTest[0]);
2257         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
2258                                          getWindowWidth() / 2, getWindowHeight() / 2));
2259 
2260         ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, 0, getWindowWidth() / 2, getWindowHeight() / 2,
2261                              &bufferTest[0]);
2262         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef2,
2263                                          getWindowWidth() / 2, getWindowHeight() / 2));
2264 
2265         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth() / 2, getWindowHeight() / 2,
2266                              &bufferTest[0]);
2267         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
2268                                          getWindowWidth() / 2, getWindowHeight() / 2));
2269 
2270         ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, (getWindowHeight() + 1) / 2, getWindowWidth() / 2,
2271                              getWindowHeight() / 2, &bufferTest[0]);
2272         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
2273                                          getWindowWidth() / 2, getWindowHeight() / 2));
2274 
2275         return result.code();
2276     }
2277 
Cleanup()2278     virtual long Cleanup()
2279     {
2280         glDisableVertexAttribArray(0);
2281         glBindBuffer(GL_ARRAY_BUFFER, 0);
2282         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2283         glBindVertexArray(0);
2284         glUseProgram(0);
2285 
2286         if (_vao)
2287         {
2288             glDeleteVertexArrays(1, &_vao);
2289         }
2290         if (_vbo)
2291         {
2292             glDeleteBuffers(1, &_vbo);
2293         }
2294         if (_ebo)
2295         {
2296             glDeleteBuffers(1, &_ebo);
2297         }
2298         if (_program)
2299         {
2300             glDeleteProgram(_program);
2301         }
2302 
2303         return NO_ERROR;
2304     }
2305 
2306     template <typename api>
Vsh()2307     std::string Vsh()
2308     {
2309         return api::glslVer() + NL
2310                "layout(location = 0) in vec4 i_vertex;" NL "layout(location = 1) in vec4 i_vertex_instanced;" NL
2311                "layout(location = 2) in vec4 i_vertex_color_instanced;" NL "out vec4 vertex_color_instanced;" NL
2312                "void main()" NL "{" NL "    gl_Position = vec4(i_vertex.xyz * .5, 1.0) + i_vertex_instanced;" NL
2313                "    vertex_color_instanced = i_vertex_color_instanced;" NL "}";
2314     }
2315 
2316     template <typename api>
Fsh()2317     std::string Fsh()
2318     {
2319         return api::glslVer() + NL "precision highp float; " NL "in  vec4 vertex_color_instanced;" NL
2320                                    "out vec4 outColor;" NL "void main() {" NL "  outColor = vertex_color_instanced;" NL
2321                                    "}";
2322     }
2323 
CBasicVertexInstancingDef(TDrawFunction drawFunc)2324     CBasicVertexInstancingDef(TDrawFunction drawFunc)
2325         : _drawFunc(drawFunc)
2326         , _drawSizeX(2)
2327         , _drawSizeY(2)
2328         , _vao(0)
2329         , _vbo(0)
2330         , _ebo(0)
2331         , _program(0)
2332     {
2333     }
2334 
2335 private:
2336     TDrawFunction _drawFunc;
2337     unsigned int _drawSizeX;
2338     unsigned int _drawSizeY;
2339 
2340     GLuint _vao;
2341     GLuint _vbo, _ebo;
2342     GLuint _program;
2343 
CBasicVertexInstancingDef()2344     CBasicVertexInstancingDef()
2345     {
2346     }
2347 };
2348 
2349 template <typename api>
2350 class CVBODrawArraysSingle : public CBasicVertexDef
2351 {
2352 public:
Title()2353     virtual std::string Title()
2354     {
2355         return "VBO: Single primitive using glDrawArraysIndirect";
2356     }
2357 
Purpose()2358     virtual std::string Purpose()
2359     {
2360         return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect";
2361     }
2362 
Method()2363     virtual std::string Method()
2364     {
2365         return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
2366                "3. Verify results";
2367     }
2368 
PassCriteria()2369     virtual std::string PassCriteria()
2370     {
2371         return "The test will pass if no OpenGL errors reported";
2372     }
2373 
CVBODrawArraysSingle()2374     CVBODrawArraysSingle() : CBasicVertexDef(DRAW_ARRAYS, GL_TRIANGLES, 1, 1)
2375     {
2376     }
Run()2377     virtual long Run()
2378     {
2379         return CBasicVertexDef::Run<api>();
2380     }
2381 };
2382 
2383 template <typename api>
2384 class CVBODrawArraysMany : public CBasicVertexDef
2385 {
2386 public:
Title()2387     virtual std::string Title()
2388     {
2389         return "VBO: Many primitives using glDrawArraysIndirect";
2390     }
2391 
Purpose()2392     virtual std::string Purpose()
2393     {
2394         return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect";
2395     }
2396 
Method()2397     virtual std::string Method()
2398     {
2399         return "1. Define primitives using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
2400                "3. Verify results";
2401     }
2402 
PassCriteria()2403     virtual std::string PassCriteria()
2404     {
2405         return "The test will pass if no OpenGL errors reported";
2406     }
2407 
CVBODrawArraysMany()2408     CVBODrawArraysMany() : CBasicVertexDef(DRAW_ARRAYS, GL_TRIANGLES, 8, 8)
2409     {
2410     }
Run()2411     virtual long Run()
2412     {
2413         return CBasicVertexDef::Run<api>();
2414     }
2415 };
2416 
2417 template <typename api>
2418 class CVBODrawArraysInstancing : public CBasicVertexInstancingDef
2419 {
2420 public:
Title()2421     virtual std::string Title()
2422     {
2423         return "VBO: Single primitive using glDrawArraysIndirect, multiple instances";
2424     }
2425 
Purpose()2426     virtual std::string Purpose()
2427     {
2428         return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect";
2429     }
2430 
Method()2431     virtual std::string Method()
2432     {
2433         return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
2434                "3. Verify results";
2435     }
2436 
PassCriteria()2437     virtual std::string PassCriteria()
2438     {
2439         return "The test will pass if no OpenGL errors reported";
2440     }
2441 
CVBODrawArraysInstancing()2442     CVBODrawArraysInstancing() : CBasicVertexInstancingDef(DRAW_ARRAYS)
2443     {
2444     }
Run()2445     virtual long Run()
2446     {
2447         return CBasicVertexInstancingDef::Run<api>();
2448     }
2449 };
2450 
2451 class CBasicXFBPausedDef : public DrawIndirectBase
2452 {
2453 public:
Setup()2454     virtual long Setup()
2455     {
2456         glClear(GL_COLOR_BUFFER_BIT);
2457         return NO_ERROR;
2458     }
2459 
2460     template <typename api>
Run()2461     long Run()
2462     {
2463         CColorArray coords;
2464         PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords);
2465 
2466         _program = CreateProgram(Vsh<api>(), "", shaders::fshSimple<api>(), false);
2467 
2468         const GLchar *varyings[] = {"dataOut"};
2469         glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS);
2470         glLinkProgram(_program);
2471         if (!CheckProgram(_program))
2472         {
2473             return ERROR;
2474         }
2475         glUseProgram(_program);
2476 
2477         glGenBuffers(1, &_vbo);
2478         glBindBuffer(GL_ARRAY_BUFFER, _vbo);
2479         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW);
2480 
2481         glGenVertexArrays(1, &_vao);
2482         glBindVertexArray(_vao);
2483         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
2484         glEnableVertexAttribArray(0);
2485 
2486         DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
2487         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
2488 
2489         CElementArray elements(coords.size(), 0);
2490         for (size_t i = 0; i < elements.size(); ++i)
2491         {
2492             elements[i] = static_cast<GLuint>(i);
2493         }
2494 
2495         glGenTransformFeedbacks(1, &_xfo);
2496         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, _xfo);
2497 
2498         glGenBuffers(1, &_xfbo);
2499         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _xfbo);
2500         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, NULL, GL_STATIC_DRAW);
2501         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfbo);
2502 
2503         glBeginTransformFeedback(GL_TRIANGLES);
2504         glPauseTransformFeedback();
2505 
2506         switch (_drawFunc)
2507         {
2508         case DRAW_ARRAYS:
2509         {
2510             indirectArrays.count              = static_cast<GLuint>(coords.size());
2511             indirectArrays.primCount          = 1;
2512             indirectArrays.first              = 0;
2513             indirectArrays.reservedMustBeZero = 0;
2514 
2515             {
2516                 GLuint buffer;
2517                 glGenBuffers(1, &buffer);
2518                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
2519                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
2520                 glDrawArraysIndirect(GL_TRIANGLES, 0);
2521                 glDeleteBuffers(1, &buffer);
2522             }
2523         }
2524         break;
2525         case DRAW_ELEMENTS:
2526         {
2527             indirectElements.count              = static_cast<GLuint>(coords.size());
2528             indirectElements.primCount          = 1;
2529             indirectElements.firstIndex         = 0;
2530             indirectElements.baseVertex         = 0;
2531             indirectElements.reservedMustBeZero = 0;
2532 
2533             glGenBuffers(1, &_ebo);
2534             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
2535             glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
2536                          GL_STATIC_DRAW);
2537 
2538             {
2539                 GLuint buffer;
2540                 glGenBuffers(1, &buffer);
2541                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
2542                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
2543                 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
2544                 glDeleteBuffers(1, &buffer);
2545             }
2546         }
2547 
2548         break;
2549         default:
2550             throw std::runtime_error("Unknown draw function!");
2551             break;
2552         }
2553 
2554         glResumeTransformFeedback();
2555         glEndTransformFeedback();
2556 
2557         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
2558         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
2559         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
2560 
2561         DIResult result;
2562         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
2563                                          getWindowHeight()));
2564 
2565         return result.code();
2566     }
2567 
Cleanup()2568     virtual long Cleanup()
2569     {
2570         glDisableVertexAttribArray(0);
2571         glBindBuffer(GL_ARRAY_BUFFER, 0);
2572         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2573         glBindVertexArray(0);
2574         glUseProgram(0);
2575 
2576         if (_vao)
2577         {
2578             glDeleteVertexArrays(1, &_vao);
2579         }
2580         if (_vbo)
2581         {
2582             glDeleteBuffers(1, &_vbo);
2583         }
2584         if (_ebo)
2585         {
2586             glDeleteBuffers(1, &_ebo);
2587         }
2588         if (_xfbo)
2589         {
2590             glDeleteBuffers(1, &_xfbo);
2591         }
2592         if (_program)
2593         {
2594             glDeleteProgram(_program);
2595         }
2596         if (_xfo)
2597         {
2598             glDeleteTransformFeedbacks(1, &_xfo);
2599         }
2600 
2601         return NO_ERROR;
2602     }
2603 
2604     template <typename api>
Vsh()2605     std::string Vsh()
2606     {
2607         return api::glslVer() + NL "in vec4 i_vertex;" NL "out vec4 dataOut;" NL "void main()" NL "{" NL
2608                                    "    gl_Position = i_vertex;" NL "    dataOut = i_vertex;" NL "}";
2609     }
2610 
CBasicXFBPausedDef(TDrawFunction drawFunc)2611     CBasicXFBPausedDef(TDrawFunction drawFunc)
2612         : _drawFunc(drawFunc)
2613         , _drawSizeX(2)
2614         , _drawSizeY(2)
2615         , _vao(0)
2616         , _vbo(0)
2617         , _ebo(0)
2618         , _xfbo(0)
2619         , _program(0)
2620         , _xfo(0)
2621     {
2622     }
2623 
2624 private:
2625     TDrawFunction _drawFunc;
2626     unsigned int _drawSizeX;
2627     unsigned int _drawSizeY;
2628 
2629     GLuint _vao;
2630     GLuint _vbo, _ebo, _xfbo;
2631     GLuint _program;
2632     GLuint _xfo;
2633 
CBasicXFBPausedDef()2634     CBasicXFBPausedDef()
2635     {
2636     }
2637 };
2638 
2639 template <typename api>
2640 class CVBODrawArraysXFBPaused : public CBasicXFBPausedDef
2641 {
2642 public:
Title()2643     virtual std::string Title()
2644     {
2645         return "VBO: glDrawArraysIndirect, in paused transform feedback operation";
2646     }
2647 
Purpose()2648     virtual std::string Purpose()
2649     {
2650         return "Verify  glDrawArraysIndirect works, if XFB is active and paused";
2651     }
2652 
Method()2653     virtual std::string Method()
2654     {
2655         return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
2656                "3. Verify results";
2657     }
2658 
PassCriteria()2659     virtual std::string PassCriteria()
2660     {
2661         return "The test will pass if no OpenGL errors reported";
2662     }
2663 
CVBODrawArraysXFBPaused()2664     CVBODrawArraysXFBPaused() : CBasicXFBPausedDef(DRAW_ARRAYS)
2665     {
2666     }
Run()2667     virtual long Run()
2668     {
2669         return CBasicXFBPausedDef::Run<api>();
2670     }
2671 };
2672 
2673 template <typename api>
2674 class CVBODrawElementsSingle : public CBasicVertexDef
2675 {
2676 public:
Title()2677     virtual std::string Title()
2678     {
2679         return "VBO: Single primitive using glDrawElementsIndirect";
2680     }
2681 
Purpose()2682     virtual std::string Purpose()
2683     {
2684         return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect";
2685     }
2686 
Method()2687     virtual std::string Method()
2688     {
2689         return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL
2690                "3. Verify results";
2691     }
2692 
PassCriteria()2693     virtual std::string PassCriteria()
2694     {
2695         return "The test will pass if no OpenGL errors reported";
2696     }
2697 
CVBODrawElementsSingle()2698     CVBODrawElementsSingle() : CBasicVertexDef(DRAW_ELEMENTS, GL_TRIANGLES, 1, 1)
2699     {
2700     }
Run()2701     virtual long Run()
2702     {
2703         return CBasicVertexDef::Run<api>();
2704     }
2705 };
2706 
2707 template <typename api>
2708 class CVBODrawElementsMany : public CBasicVertexDef
2709 {
2710 public:
Title()2711     virtual std::string Title()
2712     {
2713         return "VBO: Many primitives using glDrawElementsIndirect";
2714     }
2715 
Purpose()2716     virtual std::string Purpose()
2717     {
2718         return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect";
2719     }
2720 
Method()2721     virtual std::string Method()
2722     {
2723         return "1. Define primitives using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL
2724                "3. Verify results";
2725     }
2726 
PassCriteria()2727     virtual std::string PassCriteria()
2728     {
2729         return "The test will pass if no OpenGL errors reported";
2730     }
2731 
CVBODrawElementsMany()2732     CVBODrawElementsMany() : CBasicVertexDef(DRAW_ELEMENTS, GL_TRIANGLES, 8, 8)
2733     {
2734     }
2735 
Run()2736     virtual long Run()
2737     {
2738         return CBasicVertexDef::Run<api>();
2739     }
2740 };
2741 
2742 template <typename api>
2743 class CVBODrawElementsInstancing : public CBasicVertexInstancingDef
2744 {
2745 public:
Title()2746     virtual std::string Title()
2747     {
2748         return "VBO: Single primitive using glDrawElementsIndirect, multiple instances";
2749     }
2750 
Purpose()2751     virtual std::string Purpose()
2752     {
2753         return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect";
2754     }
2755 
Method()2756     virtual std::string Method()
2757     {
2758         return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL
2759                "3. Verify results";
2760     }
2761 
PassCriteria()2762     virtual std::string PassCriteria()
2763     {
2764         return "The test will pass if no OpenGL errors reported";
2765     }
2766 
CVBODrawElementsInstancing()2767     CVBODrawElementsInstancing() : CBasicVertexInstancingDef(DRAW_ELEMENTS)
2768     {
2769     }
Run()2770     virtual long Run()
2771     {
2772         return CBasicVertexInstancingDef::Run<api>();
2773     }
2774 };
2775 
2776 template <typename api>
2777 class CVBODrawElementsXFBPaused : public CBasicXFBPausedDef
2778 {
2779 public:
Title()2780     virtual std::string Title()
2781     {
2782         return "VBO: glDrawElementsIndirect, in paused transform feedback operation";
2783     }
2784 
Purpose()2785     virtual std::string Purpose()
2786     {
2787         return "Verify  glDrawElementsIndirect works, if XFB is active and paused";
2788     }
2789 
Method()2790     virtual std::string Method()
2791     {
2792         return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
2793                "3. Verify results";
2794     }
2795 
PassCriteria()2796     virtual std::string PassCriteria()
2797     {
2798         return "The test will pass if no OpenGL errors reported";
2799     }
2800 
CVBODrawElementsXFBPaused()2801     CVBODrawElementsXFBPaused() : CBasicXFBPausedDef(DRAW_ELEMENTS)
2802     {
2803     }
Run()2804     virtual long Run()
2805     {
2806         return CBasicXFBPausedDef::Run<api>();
2807     }
2808 };
2809 
2810 template <typename api>
2811 class CBufferIndirectDrawArraysSimple : public DrawIndirectBase
2812 {
2813 public:
Title()2814     virtual std::string Title()
2815     {
2816         return "Indirect buffer glDrawArraysIndirect: many primitives simple";
2817     }
2818 
Purpose()2819     virtual std::string Purpose()
2820     {
2821         return "Verify that it is possible to draw primitives with specified indirect structure" NL "in a buffer";
2822     }
2823 
Method()2824     virtual std::string Method()
2825     {
2826         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
2827                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
2828     }
2829 
PassCriteria()2830     virtual std::string PassCriteria()
2831     {
2832         return "The test will pass if no OpenGL errors reported";
2833     }
2834 
Setup()2835     virtual long Setup()
2836     {
2837         glClear(GL_COLOR_BUFFER_BIT);
2838         return NO_ERROR;
2839     }
2840 
Run()2841     virtual long Run()
2842     {
2843         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
2844         if (!_program)
2845         {
2846             return ERROR;
2847         }
2848         glUseProgram(_program);
2849 
2850         CColorArray coords;
2851         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
2852 
2853         glGenVertexArrays(1, &_vao);
2854         glBindVertexArray(_vao);
2855 
2856         glGenBuffers(1, &_buffer);
2857         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
2858 
2859         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
2860         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
2861         glEnableVertexAttribArray(0);
2862 
2863         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
2864         indirectArrays.count                     = static_cast<GLuint>(coords.size());
2865         indirectArrays.primCount                 = 1;
2866         indirectArrays.first                     = 0;
2867         indirectArrays.reservedMustBeZero        = 0;
2868 
2869         glGenBuffers(1, &_bufferIndirect);
2870         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
2871         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
2872 
2873         glDrawArraysIndirect(GL_TRIANGLES, 0);
2874 
2875         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
2876         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
2877 
2878         DIResult result;
2879         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
2880         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
2881                                          getWindowHeight()));
2882 
2883         return result.code();
2884     }
2885 
Cleanup()2886     virtual long Cleanup()
2887     {
2888         glDisableVertexAttribArray(0);
2889         glUseProgram(0);
2890         glDeleteProgram(_program);
2891         glDeleteVertexArrays(1, &_vao);
2892         glDeleteBuffers(1, &_buffer);
2893         glDeleteBuffers(1, &_bufferIndirect);
2894         return NO_ERROR;
2895     }
2896 
2897 private:
2898     GLuint _program;
2899     GLuint _vao, _buffer, _bufferIndirect;
2900 };
2901 
2902 template <typename api>
2903 class CBufferIndirectDrawArraysNoFirst : public DrawIndirectBase
2904 {
2905 public:
Title()2906     virtual std::string Title()
2907     {
2908         return "Indirect buffer glDrawArraysIndirect: non-zero 'first' argument";
2909     }
2910 
Purpose()2911     virtual std::string Purpose()
2912     {
2913         return "Verify that it is possible to draw primitives with specified non-zero 'first' argument" NL
2914                "in indirect buffer";
2915     }
2916 
Method()2917     virtual std::string Method()
2918     {
2919         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
2920                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
2921     }
2922 
PassCriteria()2923     virtual std::string PassCriteria()
2924     {
2925         return "The test will pass if no OpenGL errors reported";
2926     }
2927 
Setup()2928     virtual long Setup()
2929     {
2930         glClear(GL_COLOR_BUFFER_BIT);
2931         return NO_ERROR;
2932     }
2933 
Run()2934     virtual long Run()
2935     {
2936         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
2937         if (!_program)
2938         {
2939             return ERROR;
2940         }
2941         glUseProgram(_program);
2942 
2943         CColorArray coords;
2944         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
2945 
2946         glGenVertexArrays(1, &_vao);
2947         glBindVertexArray(_vao);
2948 
2949         glGenBuffers(1, &_buffer);
2950         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
2951 
2952         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
2953         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
2954         glEnableVertexAttribArray(0);
2955 
2956         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
2957         indirectArrays.count                     = static_cast<GLuint>(coords.size()) / 2;
2958         indirectArrays.primCount                 = 1;
2959         indirectArrays.first                     = static_cast<GLuint>(coords.size()) / 2;
2960         indirectArrays.reservedMustBeZero        = 0;
2961 
2962         glGenBuffers(1, &_bufferIndirect);
2963         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
2964         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
2965 
2966         glDrawArraysIndirect(GL_TRIANGLES, 0);
2967 
2968         CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
2969         CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
2970         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
2971 
2972         DIResult result;
2973         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
2974         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
2975                                          getWindowWidth(), getWindowHeight() / 2));
2976 
2977         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
2978         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
2979                                          getWindowWidth(), getWindowHeight() / 2));
2980 
2981         return result.code();
2982     }
2983 
Cleanup()2984     virtual long Cleanup()
2985     {
2986         glDisableVertexAttribArray(0);
2987         glUseProgram(0);
2988         glDeleteProgram(_program);
2989         glDeleteVertexArrays(1, &_vao);
2990         glDeleteBuffers(1, &_buffer);
2991         glDeleteBuffers(1, &_bufferIndirect);
2992         return NO_ERROR;
2993     }
2994 
2995 private:
2996     GLuint _program;
2997     GLuint _vao, _buffer, _bufferIndirect;
2998 };
2999 
3000 template <typename api>
3001 class CBufferIndirectDrawArraysOffset : public DrawIndirectBase
3002 {
3003 public:
Title()3004     virtual std::string Title()
3005     {
3006         return "Indirect buffer glDrawArraysIndirect: offset as a function parameter";
3007     }
3008 
Purpose()3009     virtual std::string Purpose()
3010     {
3011         return "Verify that it is possible to draw primitives with offset as a function parameter";
3012     }
3013 
Method()3014     virtual std::string Method()
3015     {
3016         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3017                "3. Draw primitives using glDrawArraysIndirect with offset" NL "4. Verify results";
3018     }
3019 
PassCriteria()3020     virtual std::string PassCriteria()
3021     {
3022         return "The test will pass if no OpenGL errors reported";
3023     }
3024 
Setup()3025     virtual long Setup()
3026     {
3027         glClear(GL_COLOR_BUFFER_BIT);
3028         return NO_ERROR;
3029     }
3030 
Run()3031     virtual long Run()
3032     {
3033         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3034         if (!_program)
3035         {
3036             return ERROR;
3037         }
3038         glUseProgram(_program);
3039 
3040         CColorArray coords;
3041         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
3042 
3043         glGenVertexArrays(1, &_vao);
3044         glBindVertexArray(_vao);
3045 
3046         glGenBuffers(1, &_buffer);
3047         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3048 
3049         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3050         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
3051         glEnableVertexAttribArray(0);
3052 
3053         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
3054         indirectArrays.count                     = static_cast<GLuint>(coords.size());
3055         indirectArrays.primCount                 = 1;
3056         indirectArrays.first                     = 0;
3057         indirectArrays.reservedMustBeZero        = 0;
3058 
3059         glGenBuffers(1, &_bufferIndirect);
3060         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
3061         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand) * 3, NULL, GL_STATIC_DRAW);
3062         glBufferSubData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), sizeof(DrawArraysIndirectCommand),
3063                         &indirectArrays);
3064         glDrawArraysIndirect(GL_TRIANGLES, (void *)sizeof(DrawArraysIndirectCommand));
3065 
3066         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
3067         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
3068 
3069         DIResult result;
3070         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
3071         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
3072                                          getWindowHeight()));
3073 
3074         return result.code();
3075     }
3076 
Cleanup()3077     virtual long Cleanup()
3078     {
3079         glDisableVertexAttribArray(0);
3080         glUseProgram(0);
3081         glDeleteProgram(_program);
3082         glDeleteVertexArrays(1, &_vao);
3083         glDeleteBuffers(1, &_buffer);
3084         glDeleteBuffers(1, &_bufferIndirect);
3085         return NO_ERROR;
3086     }
3087 
3088 private:
3089     GLuint _program;
3090     GLuint _vao, _buffer, _bufferIndirect;
3091 };
3092 
3093 template <typename api>
3094 class CBufferIndirectDrawElementsSimple : public DrawIndirectBase
3095 {
3096 public:
Title()3097     virtual std::string Title()
3098     {
3099         return "Indirect buffer glDrawElementsIndirect: many primitives simple";
3100     }
3101 
Purpose()3102     virtual std::string Purpose()
3103     {
3104         return "Verify that it is possible to draw primitives with specified indirect structure" NL "in a buffer";
3105     }
3106 
Method()3107     virtual std::string Method()
3108     {
3109         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3110                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
3111     }
3112 
PassCriteria()3113     virtual std::string PassCriteria()
3114     {
3115         return "The test will pass if no OpenGL errors reported";
3116     }
3117 
Setup()3118     virtual long Setup()
3119     {
3120         glClear(GL_COLOR_BUFFER_BIT);
3121         return NO_ERROR;
3122     }
3123 
Run()3124     virtual long Run()
3125     {
3126         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3127         if (!_program)
3128         {
3129             return ERROR;
3130         }
3131         glUseProgram(_program);
3132 
3133         CColorArray coords;
3134         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
3135 
3136         glGenVertexArrays(1, &_vao);
3137         glBindVertexArray(_vao);
3138 
3139         glGenBuffers(1, &_buffer);
3140         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3141 
3142         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3143         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
3144         glEnableVertexAttribArray(0);
3145 
3146         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
3147         indirectElements.count                       = static_cast<GLuint>(coords.size());
3148         indirectElements.primCount                   = 1;
3149         indirectElements.baseVertex                  = 0;
3150         indirectElements.firstIndex                  = 0;
3151         indirectElements.reservedMustBeZero          = 0;
3152 
3153         CElementArray elements(coords.size(), 0);
3154         for (size_t i = 0; i < elements.size(); ++i)
3155         {
3156             elements[i] = static_cast<GLuint>(i);
3157         }
3158 
3159         glGenBuffers(1, &_bufferIndirect);
3160         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
3161         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
3162 
3163         glGenBuffers(1, &_ebo);
3164         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
3165         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
3166                      GL_STATIC_DRAW);
3167 
3168         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
3169 
3170         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
3171         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
3172 
3173         DIResult result;
3174         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
3175         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
3176                                          getWindowHeight()));
3177 
3178         return result.code();
3179     }
3180 
Cleanup()3181     virtual long Cleanup()
3182     {
3183         glDisableVertexAttribArray(0);
3184         glUseProgram(0);
3185         glDeleteProgram(_program);
3186         glDeleteVertexArrays(1, &_vao);
3187         glDeleteBuffers(1, &_buffer);
3188         glDeleteBuffers(1, &_bufferIndirect);
3189         glDeleteBuffers(1, &_ebo);
3190         return NO_ERROR;
3191     }
3192 
3193 private:
3194     GLuint _program;
3195     GLuint _vao, _buffer, _bufferIndirect, _ebo;
3196 };
3197 
3198 template <typename api>
3199 class CBufferIndirectDrawElementsNoFirstIndex : public DrawIndirectBase
3200 {
3201 public:
Title()3202     virtual std::string Title()
3203     {
3204         return "Indirect buffer glDrawElementsIndirect: non-zero first index";
3205     }
3206 
Purpose()3207     virtual std::string Purpose()
3208     {
3209         return "Verify that it is possible to draw primitives with non-zero first index" NL "in indirect buffer";
3210     }
3211 
Method()3212     virtual std::string Method()
3213     {
3214         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3215                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
3216     }
3217 
PassCriteria()3218     virtual std::string PassCriteria()
3219     {
3220         return "The test will pass if no OpenGL errors reported";
3221     }
3222 
Setup()3223     virtual long Setup()
3224     {
3225         glClear(GL_COLOR_BUFFER_BIT);
3226         return NO_ERROR;
3227     }
3228 
Run()3229     virtual long Run()
3230     {
3231         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3232         if (!_program)
3233         {
3234             return ERROR;
3235         }
3236         glUseProgram(_program);
3237 
3238         CColorArray coords;
3239         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
3240 
3241         glGenVertexArrays(1, &_vao);
3242         glBindVertexArray(_vao);
3243 
3244         glGenBuffers(1, &_buffer);
3245         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3246 
3247         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3248         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
3249         glEnableVertexAttribArray(0);
3250 
3251         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
3252         indirectElements.count                       = static_cast<GLuint>(coords.size()) / 2;
3253         indirectElements.primCount                   = 1;
3254         indirectElements.baseVertex                  = 0;
3255         indirectElements.firstIndex                  = static_cast<GLuint>(coords.size()) / 2;
3256         indirectElements.reservedMustBeZero          = 0;
3257 
3258         CElementArray elements(coords.size(), 0);
3259         for (size_t i = 0; i < elements.size(); ++i)
3260         {
3261             elements[i] = static_cast<GLuint>(i);
3262         }
3263 
3264         glGenBuffers(1, &_bufferIndirect);
3265         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
3266         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
3267 
3268         glGenBuffers(1, &_ebo);
3269         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
3270         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
3271                      GL_STATIC_DRAW);
3272 
3273         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
3274 
3275         CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
3276         CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
3277         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
3278 
3279         DIResult result;
3280         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
3281         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
3282                                          getWindowWidth(), getWindowHeight() / 2));
3283 
3284         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
3285         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
3286                                          getWindowWidth(), getWindowHeight() / 2));
3287 
3288         return result.code();
3289     }
3290 
Cleanup()3291     virtual long Cleanup()
3292     {
3293         glDisableVertexAttribArray(0);
3294         glUseProgram(0);
3295         glDeleteProgram(_program);
3296         glDeleteVertexArrays(1, &_vao);
3297         glDeleteBuffers(1, &_buffer);
3298         glDeleteBuffers(1, &_ebo);
3299         glDeleteBuffers(1, &_bufferIndirect);
3300         return NO_ERROR;
3301     }
3302 
3303 private:
3304     GLuint _program;
3305     GLuint _vao, _buffer, _bufferIndirect, _ebo;
3306 };
3307 
3308 template <typename api>
3309 class CBufferIndirectDrawElementsNoBasevertex : public DrawIndirectBase
3310 {
3311 public:
Title()3312     virtual std::string Title()
3313     {
3314         return "Indirect buffer glDrawElementsIndirect: non-zero base vertex";
3315     }
3316 
Purpose()3317     virtual std::string Purpose()
3318     {
3319         return "Verify that it is possible to draw primitives with non-zero base vertex" NL "in indirect buffer";
3320     }
3321 
Method()3322     virtual std::string Method()
3323     {
3324         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3325                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
3326     }
3327 
PassCriteria()3328     virtual std::string PassCriteria()
3329     {
3330         return "The test will pass if no OpenGL errors reported";
3331     }
3332 
Setup()3333     virtual long Setup()
3334     {
3335         glClear(GL_COLOR_BUFFER_BIT);
3336         return NO_ERROR;
3337     }
3338 
Run()3339     virtual long Run()
3340     {
3341         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3342         if (!_program)
3343         {
3344             return ERROR;
3345         }
3346         glUseProgram(_program);
3347 
3348         CColorArray coords;
3349         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
3350 
3351         glGenVertexArrays(1, &_vao);
3352         glBindVertexArray(_vao);
3353 
3354         glGenBuffers(1, &_buffer);
3355         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3356 
3357         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3358         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
3359         glEnableVertexAttribArray(0);
3360 
3361         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
3362         indirectElements.count                       = static_cast<GLuint>(coords.size()) / 2;
3363         indirectElements.primCount                   = 1;
3364         indirectElements.baseVertex                  = static_cast<GLint>(coords.size()) / 2;
3365         indirectElements.firstIndex                  = 0;
3366         indirectElements.reservedMustBeZero          = 0;
3367 
3368         CElementArray elements(coords.size(), 0);
3369         for (size_t i = 0; i < elements.size(); ++i)
3370         {
3371             elements[i] = static_cast<GLuint>(i);
3372         }
3373 
3374         glGenBuffers(1, &_bufferIndirect);
3375         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
3376         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
3377 
3378         glGenBuffers(1, &_ebo);
3379         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
3380         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
3381                      GL_STATIC_DRAW);
3382 
3383         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
3384 
3385         CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
3386         CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
3387         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
3388 
3389         DIResult result;
3390         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
3391         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
3392                                          getWindowWidth(), getWindowHeight() / 2));
3393 
3394         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
3395         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
3396                                          getWindowWidth(), getWindowHeight() / 2));
3397 
3398         return result.code();
3399     }
3400 
Cleanup()3401     virtual long Cleanup()
3402     {
3403         glDisableVertexAttribArray(0);
3404         glUseProgram(0);
3405         glDeleteProgram(_program);
3406         glDeleteVertexArrays(1, &_vao);
3407         glDeleteBuffers(1, &_buffer);
3408         glDeleteBuffers(1, &_ebo);
3409         glDeleteBuffers(1, &_bufferIndirect);
3410         return NO_ERROR;
3411     }
3412 
3413 private:
3414     GLuint _program;
3415     GLuint _vao, _buffer, _ebo, _bufferIndirect;
3416 };
3417 
3418 template <typename api>
3419 class CBufferIndirectDrawElementsOffset : public DrawIndirectBase
3420 {
3421 public:
Title()3422     virtual std::string Title()
3423     {
3424         return "Indirect buffer glDrawElementsIndirect: offset as a function parameter";
3425     }
3426 
Purpose()3427     virtual std::string Purpose()
3428     {
3429         return "Verify that it is possible to draw primitives with offset as a function parameter";
3430     }
3431 
Method()3432     virtual std::string Method()
3433     {
3434         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3435                "3. Draw primitives using glDrawElementsIndirect with offset" NL "4. Verify results";
3436     }
3437 
PassCriteria()3438     virtual std::string PassCriteria()
3439     {
3440         return "The test will pass if no OpenGL errors reported";
3441     }
3442 
Setup()3443     virtual long Setup()
3444     {
3445         glClear(GL_COLOR_BUFFER_BIT);
3446         return NO_ERROR;
3447     }
3448 
Run()3449     virtual long Run()
3450     {
3451         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3452         if (!_program)
3453         {
3454             return ERROR;
3455         }
3456         glUseProgram(_program);
3457 
3458         CColorArray coords;
3459         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
3460 
3461         glGenVertexArrays(1, &_vao);
3462         glBindVertexArray(_vao);
3463 
3464         glGenBuffers(1, &_buffer);
3465         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3466 
3467         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3468         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
3469         glEnableVertexAttribArray(0);
3470 
3471         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
3472         indirectElements.count                       = static_cast<GLuint>(coords.size());
3473         indirectElements.primCount                   = 1;
3474         indirectElements.baseVertex                  = 0;
3475         indirectElements.firstIndex                  = 0;
3476         indirectElements.reservedMustBeZero          = 0;
3477 
3478         CElementArray elements(coords.size(), 0);
3479         for (size_t i = 0; i < elements.size(); ++i)
3480         {
3481             elements[i] = static_cast<GLuint>(i);
3482         }
3483 
3484         glGenBuffers(1, &_bufferIndirect);
3485         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
3486         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand) * 3, NULL, GL_STATIC_DRAW);
3487         glBufferSubData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand),
3488                         sizeof(DrawElementsIndirectCommand), &indirectElements);
3489 
3490         glGenBuffers(1, &_ebo);
3491         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
3492         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
3493                      GL_STATIC_DRAW);
3494         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void *)sizeof(DrawElementsIndirectCommand));
3495 
3496         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
3497         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
3498 
3499         DIResult result;
3500         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
3501         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
3502                                          getWindowHeight()));
3503 
3504         return result.code();
3505     }
3506 
Cleanup()3507     virtual long Cleanup()
3508     {
3509         glDisableVertexAttribArray(0);
3510         glUseProgram(0);
3511         glDeleteProgram(_program);
3512         glDeleteVertexArrays(1, &_vao);
3513         glDeleteBuffers(1, &_buffer);
3514         glDeleteBuffers(1, &_ebo);
3515         glDeleteBuffers(1, &_bufferIndirect);
3516         return NO_ERROR;
3517     }
3518 
3519 private:
3520     GLuint _program;
3521     GLuint _vao, _buffer, _ebo, _bufferIndirect;
3522 };
3523 
3524 class CBasicVertexIDsDef : public DrawIndirectBase
3525 {
3526 public:
Setup()3527     virtual long Setup()
3528     {
3529         glClear(GL_COLOR_BUFFER_BIT);
3530         return NO_ERROR;
3531     }
3532 
3533     template <typename api>
Run()3534     long Run()
3535     {
3536         CColorArray coords;
3537         PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords);
3538 
3539         CColorArray coords_instanced(4);
3540         coords_instanced[0] = tcu::Vec4(0.5, 0.5, 0.0, 0.0);
3541         coords_instanced[1] = tcu::Vec4(-0.5, 0.5, 0.0, 0.0);
3542         coords_instanced[2] = tcu::Vec4(-0.5, -0.5, 0.0, 0.0);
3543         coords_instanced[3] = tcu::Vec4(0.5, -0.5, 0.0, 0.0);
3544 
3545         std::vector<glw::GLfloat> ref_VertexId(coords.size());
3546         for (size_t i = 0; i < ref_VertexId.size(); i++)
3547         {
3548             ref_VertexId[i] = glw::GLfloat(i);
3549         }
3550 
3551         std::vector<glw::GLfloat> ref_InstanceId(4);
3552         for (size_t i = 0; i < ref_InstanceId.size(); i++)
3553         {
3554             ref_InstanceId[i] = glw::GLfloat(i);
3555         }
3556 
3557         _program = CreateProgram(Vsh<api>(), "", Fsh<api>(), true);
3558         if (!_program)
3559         {
3560             return ERROR;
3561         }
3562         glUseProgram(_program);
3563 
3564         glGenBuffers(1, &_vbo);
3565         glBindBuffer(GL_ARRAY_BUFFER, _vbo);
3566         glBufferData(GL_ARRAY_BUFFER,
3567                      (GLsizeiptr)(coords.size() * sizeof(coords[0]) +
3568                                   coords_instanced.size() * sizeof(coords_instanced[0]) +
3569                                   ref_VertexId.size() * sizeof(ref_VertexId[0]) +
3570                                   ref_InstanceId.size() * sizeof(ref_InstanceId[0])),
3571                      NULL, GL_STATIC_DRAW);
3572 
3573         const size_t coords_offset           = 0;
3574         const size_t coords_instanced_offset = coords_offset + coords.size() * sizeof(coords[0]);
3575         const size_t ref_VertexId_offset =
3576             coords_instanced_offset + coords_instanced.size() * sizeof(coords_instanced[0]);
3577         const size_t ref_InstanceId_offset = ref_VertexId_offset + ref_VertexId.size() * sizeof(ref_VertexId[0]);
3578 
3579         glBufferSubData(GL_ARRAY_BUFFER, coords_offset, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0]);
3580         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)coords_instanced_offset,
3581                         (GLsizeiptr)(coords_instanced.size() * sizeof(coords_instanced[0])), &coords_instanced[0]);
3582         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)ref_VertexId_offset,
3583                         (GLsizeiptr)(ref_VertexId.size() * sizeof(ref_VertexId[0])), &ref_VertexId[0]);
3584         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)ref_InstanceId_offset,
3585                         (GLsizeiptr)(ref_InstanceId.size() * sizeof(ref_InstanceId[0])), &ref_InstanceId[0]);
3586 
3587         glGenVertexArrays(1, &_vao);
3588         glBindVertexArray(_vao);
3589 
3590         //i_vertex (coords)
3591         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(coords_offset));
3592         glEnableVertexAttribArray(0);
3593 
3594         //i_vertex_instanced (coords_instanced)
3595         glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(coords_instanced_offset));
3596         glEnableVertexAttribArray(1);
3597         glVertexAttribDivisor(1, 1);
3598 
3599         //i_ref_VertexId
3600         glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(ref_VertexId_offset));
3601         glEnableVertexAttribArray(2);
3602         //i_ref_InstanceId
3603         glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(ref_InstanceId_offset));
3604         glEnableVertexAttribArray(3);
3605         glVertexAttribDivisor(3, 1);
3606 
3607         DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
3608         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
3609 
3610         CElementArray elements(coords.size(), 0);
3611         for (size_t i = 0; i < elements.size(); ++i)
3612         {
3613             elements[i] = static_cast<GLuint>(i);
3614         }
3615 
3616         switch (_drawFunc)
3617         {
3618         case DRAW_ARRAYS:
3619         {
3620             indirectArrays.count              = static_cast<GLuint>(coords.size());
3621             indirectArrays.primCount          = 4;
3622             indirectArrays.first              = 0;
3623             indirectArrays.reservedMustBeZero = 0;
3624 
3625             {
3626                 GLuint buffer;
3627                 glGenBuffers(1, &buffer);
3628                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
3629                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
3630                 glDrawArraysIndirect(GL_TRIANGLES, 0);
3631                 glDeleteBuffers(1, &buffer);
3632             }
3633         }
3634         break;
3635         case DRAW_ELEMENTS:
3636         {
3637             indirectElements.count              = static_cast<GLuint>(coords.size());
3638             indirectElements.primCount          = 4;
3639             indirectElements.firstIndex         = 0;
3640             indirectElements.baseVertex         = 0;
3641             indirectElements.reservedMustBeZero = 0;
3642 
3643             glGenBuffers(1, &_ebo);
3644             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
3645             glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
3646                          GL_STATIC_DRAW);
3647 
3648             {
3649                 GLuint buffer;
3650                 glGenBuffers(1, &buffer);
3651                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
3652                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
3653                 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
3654                 glDeleteBuffers(1, &buffer);
3655             }
3656         }
3657         break;
3658         default:
3659             throw std::runtime_error("Unknown draw function!");
3660             break;
3661         }
3662 
3663         CColorArray bufferRef1(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.5f, 0.0f));
3664         CColorArray bufferRef2(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.75f, 0.0f));
3665         CColorArray bufferRef3(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.25f, 0.0f));
3666         CColorArray bufferRef4(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.0f, 0.0f));
3667 
3668         CColorArray bufferTest(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f));
3669         DIResult result;
3670 
3671         ReadPixelsFloat<api>(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, &bufferTest[0]);
3672         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
3673                                          getWindowWidth() / 2, getWindowHeight() / 2));
3674 
3675         ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, 0, getWindowWidth() / 2, getWindowHeight() / 2,
3676                              &bufferTest[0]);
3677         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef2,
3678                                          getWindowWidth() / 2, getWindowHeight() / 2));
3679 
3680         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth() / 2, getWindowHeight() / 2,
3681                              &bufferTest[0]);
3682         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef3,
3683                                          getWindowWidth() / 2, getWindowHeight() / 2));
3684 
3685         ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, (getWindowHeight() + 1) / 2, getWindowWidth() / 2,
3686                              getWindowHeight() / 2, &bufferTest[0]);
3687         result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef4,
3688                                          getWindowWidth() / 2, getWindowHeight() / 2));
3689 
3690         return result.code();
3691     }
3692 
Cleanup()3693     virtual long Cleanup()
3694     {
3695         glDisableVertexAttribArray(0);
3696         glBindBuffer(GL_ARRAY_BUFFER, 0);
3697         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3698         glBindVertexArray(0);
3699         glUseProgram(0);
3700 
3701         if (_vao)
3702         {
3703             glDeleteVertexArrays(1, &_vao);
3704         }
3705         if (_vbo)
3706         {
3707             glDeleteBuffers(1, &_vbo);
3708         }
3709         if (_ebo)
3710         {
3711             glDeleteBuffers(1, &_ebo);
3712         }
3713         if (_program)
3714         {
3715             glDeleteProgram(_program);
3716         }
3717 
3718         return NO_ERROR;
3719     }
3720 
3721     template <typename api>
Vsh()3722     std::string Vsh()
3723     {
3724         return api::glslVer() + NL
3725                "layout(location = 0) in vec4 i_vertex;" NL "layout(location = 1) in vec4 i_vertex_instanced;" NL
3726                "layout(location = 2) in float i_ref_VertexId;" NL "layout(location = 3) in float i_ref_InstanceId;" NL
3727                "out vec4 val_Result;" NL "void main()" NL "{" NL
3728                "    gl_Position = vec4(i_vertex.xyz * .5, 1.0) + i_vertex_instanced;" NL
3729                "    if ( gl_VertexID == int(i_ref_VertexId + .5) && gl_InstanceID == int(i_ref_InstanceId + .5)) {" NL
3730                "        val_Result = vec4(0.0, 1.0, float(gl_InstanceID) / 4.0, 1.0);" NL "    } else {" NL
3731                "        val_Result = vec4(1.0, 0.0, 0.0, 1.0);" NL "    }" NL "}";
3732     }
3733 
3734     template <typename api>
Fsh()3735     std::string Fsh()
3736     {
3737         return api::glslVer() + NL "precision highp float; " NL "in vec4 val_Result;" NL "out vec4 outColor;" NL
3738                                    "void main() {" NL "  outColor = val_Result;" NL "}";
3739     }
3740 
CBasicVertexIDsDef(TDrawFunction drawFunc)3741     CBasicVertexIDsDef(TDrawFunction drawFunc)
3742         : _drawFunc(drawFunc)
3743         , _drawSizeX(2)
3744         , _drawSizeY(2)
3745         , _vao(0)
3746         , _vbo(0)
3747         , _ebo(0)
3748         , _program(0)
3749     {
3750     }
3751 
3752 private:
3753     TDrawFunction _drawFunc;
3754     unsigned int _drawSizeX;
3755     unsigned int _drawSizeY;
3756 
3757     GLuint _vao;
3758     GLuint _vbo, _ebo;
3759     GLuint _program;
3760 
CBasicVertexIDsDef()3761     CBasicVertexIDsDef()
3762     {
3763     }
3764 };
3765 
3766 template <typename api>
3767 class CBufferIndirectDrawArraysVertexIds : public CBasicVertexIDsDef
3768 {
3769 public:
Title()3770     virtual std::string Title()
3771     {
3772         return "Indirect buffer glDrawArraysIndirect: all non-zero arguments, verify vertex ids";
3773     }
3774 
Purpose()3775     virtual std::string Purpose()
3776     {
3777         return "Verify that it is possible to draw primitives with all non-zero arguments" NL "in indirect buffer";
3778     }
3779 
Method()3780     virtual std::string Method()
3781     {
3782         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3783                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
3784     }
3785 
PassCriteria()3786     virtual std::string PassCriteria()
3787     {
3788         return "The test will pass if no OpenGL errors reported";
3789     }
3790 
Run()3791     virtual long Run()
3792     {
3793         return CBasicVertexIDsDef::Run<api>();
3794     }
3795 
CBufferIndirectDrawArraysVertexIds()3796     CBufferIndirectDrawArraysVertexIds() : CBasicVertexIDsDef(DRAW_ARRAYS)
3797     {
3798     }
3799 };
3800 
3801 template <typename api>
3802 class CBufferIndirectDrawElementsVertexIds : public CBasicVertexIDsDef
3803 {
3804 public:
Title()3805     virtual std::string Title()
3806     {
3807         return "Indirect buffer glDrawElementsIndirect: all non-zero arguments, verify vertex ids";
3808     }
3809 
Purpose()3810     virtual std::string Purpose()
3811     {
3812         return "Verify that it is possible to draw primitives with all non-zero arguments" NL "in indirect buffer";
3813     }
3814 
Method()3815     virtual std::string Method()
3816     {
3817         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
3818                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
3819     }
3820 
PassCriteria()3821     virtual std::string PassCriteria()
3822     {
3823         return "The test will pass if no OpenGL errors reported";
3824     }
3825 
Run()3826     virtual long Run()
3827     {
3828         return CBasicVertexIDsDef::Run<api>();
3829     }
3830 
CBufferIndirectDrawElementsVertexIds()3831     CBufferIndirectDrawElementsVertexIds() : CBasicVertexIDsDef(DRAW_ELEMENTS)
3832     {
3833     }
3834 };
3835 
3836 template <typename api>
3837 class CIndicesDataTypeUnsignedShort : public DrawIndirectBase
3838 {
3839 public:
Title()3840     virtual std::string Title()
3841     {
3842         return "glDrawElementsIndirect indices data type: unsigned short";
3843     }
3844 
Purpose()3845     virtual std::string Purpose()
3846     {
3847         return "Verify that unsigned short indices are accepted by glDrawElementsIndirect";
3848     }
3849 
Method()3850     virtual std::string Method()
3851     {
3852         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL "3. Create element buffer" NL
3853                "4. Draw primitives using glDrawElementsIndirect" NL "5. Verify results";
3854     }
3855 
PassCriteria()3856     virtual std::string PassCriteria()
3857     {
3858         return "The test will pass if no OpenGL errors reported";
3859     }
3860 
Setup()3861     virtual long Setup()
3862     {
3863         glClear(GL_COLOR_BUFFER_BIT);
3864         return NO_ERROR;
3865     }
3866 
Run()3867     virtual long Run()
3868     {
3869         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3870         if (!_program)
3871         {
3872             return ERROR;
3873         }
3874         glUseProgram(_program);
3875 
3876         CColorArray coords;
3877         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
3878 
3879         glGenVertexArrays(1, &_vao);
3880         glBindVertexArray(_vao);
3881 
3882         glGenBuffers(1, &_buffer);
3883         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3884 
3885         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3886         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
3887         glEnableVertexAttribArray(0);
3888 
3889         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
3890         indirectElements.count                       = static_cast<GLuint>(coords.size()) / 2;
3891         indirectElements.primCount                   = 1;
3892         indirectElements.baseVertex                  = -static_cast<GLint>(coords.size()) / 4;
3893         indirectElements.firstIndex                  = static_cast<GLuint>(coords.size()) / 4;
3894         indirectElements.reservedMustBeZero          = 0;
3895 
3896         std::vector<GLushort> elements(coords.size(), 0);
3897         for (size_t i = 0; i < elements.size(); ++i)
3898         {
3899             elements[i] = static_cast<GLushort>(i);
3900         }
3901 
3902         glGenBuffers(1, &_bufferIndirect);
3903         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
3904         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW);
3905         glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements);
3906 
3907         glGenBuffers(1, &_ebo);
3908         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
3909         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
3910                      GL_STATIC_DRAW);
3911 
3912         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0);
3913 
3914         CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
3915         CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
3916         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
3917 
3918         DIResult result;
3919         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
3920         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
3921                                          getWindowWidth(), getWindowHeight() / 2));
3922 
3923         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
3924         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
3925                                          getWindowWidth(), getWindowHeight() / 2));
3926 
3927         return result.code();
3928     }
3929 
Cleanup()3930     virtual long Cleanup()
3931     {
3932         glDisableVertexAttribArray(0);
3933         glUseProgram(0);
3934         glDeleteProgram(_program);
3935         glDeleteVertexArrays(1, &_vao);
3936         glDeleteBuffers(1, &_buffer);
3937         glDeleteBuffers(1, &_ebo);
3938         glDeleteBuffers(1, &_bufferIndirect);
3939         return NO_ERROR;
3940     }
3941 
3942 private:
3943     GLuint _program;
3944     GLuint _vao, _buffer, _ebo, _bufferIndirect;
3945 };
3946 
3947 template <typename api>
3948 class CIndicesDataTypeUnsignedByte : public DrawIndirectBase
3949 {
3950 public:
Title()3951     virtual std::string Title()
3952     {
3953         return "glDrawElementsIndirect indices data type: unsigned byte";
3954     }
3955 
Purpose()3956     virtual std::string Purpose()
3957     {
3958         return "Verify that unsigned byte indices are accepted by glDrawElementsIndirect";
3959     }
3960 
Method()3961     virtual std::string Method()
3962     {
3963         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL "3. Create element buffer" NL
3964                "4. Draw primitives using glDrawElementsIndirect" NL "5. Verify results";
3965     }
3966 
PassCriteria()3967     virtual std::string PassCriteria()
3968     {
3969         return "The test will pass if no OpenGL errors reported";
3970     }
3971 
Setup()3972     virtual long Setup()
3973     {
3974         glClear(GL_COLOR_BUFFER_BIT);
3975         return NO_ERROR;
3976     }
3977 
Run()3978     virtual long Run()
3979     {
3980         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
3981         if (!_program)
3982         {
3983             return ERROR;
3984         }
3985         glUseProgram(_program);
3986 
3987         CColorArray coords;
3988         PrimitiveGen(GL_TRIANGLES, 2, 2, coords);
3989 
3990         glGenVertexArrays(1, &_vao);
3991         glBindVertexArray(_vao);
3992 
3993         glGenBuffers(1, &_buffer);
3994         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
3995 
3996         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
3997         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
3998         glEnableVertexAttribArray(0);
3999 
4000         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
4001         indirectElements.count                       = static_cast<GLuint>(coords.size()) / 2;
4002         indirectElements.primCount                   = 1;
4003         indirectElements.baseVertex                  = -static_cast<GLint>(coords.size()) / 4;
4004         indirectElements.firstIndex                  = static_cast<GLuint>(coords.size()) / 4;
4005         indirectElements.reservedMustBeZero          = 0;
4006 
4007         std::vector<GLubyte> elements(coords.size(), 0);
4008         for (size_t i = 0; i < elements.size(); ++i)
4009         {
4010             elements[i] = static_cast<GLubyte>(i);
4011         }
4012 
4013         glGenBuffers(1, &_bufferIndirect);
4014         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
4015         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW);
4016         glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements);
4017 
4018         glGenBuffers(1, &_ebo);
4019         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
4020         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
4021                      GL_STATIC_DRAW);
4022 
4023         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_BYTE, 0);
4024 
4025         CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
4026         CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
4027         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
4028 
4029         DIResult result;
4030         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
4031         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
4032                                          getWindowWidth(), getWindowHeight() / 2));
4033 
4034         ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
4035         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
4036                                          getWindowWidth(), getWindowHeight() / 2));
4037 
4038         return result.code();
4039     }
4040 
Cleanup()4041     virtual long Cleanup()
4042     {
4043         glDisableVertexAttribArray(0);
4044         glUseProgram(0);
4045         glDeleteProgram(_program);
4046         glDeleteVertexArrays(1, &_vao);
4047         glDeleteBuffers(1, &_buffer);
4048         glDeleteBuffers(1, &_ebo);
4049         glDeleteBuffers(1, &_bufferIndirect);
4050         return NO_ERROR;
4051     }
4052 
4053 private:
4054     GLuint _program;
4055     GLuint _vao, _buffer, _ebo, _bufferIndirect;
4056 };
4057 
4058 class CPrimitiveMode : public DrawIndirectBase
4059 {
4060 public:
4061     template <typename api>
IsGeometryShaderSupported()4062     bool IsGeometryShaderSupported()
4063     {
4064         if (api::isES())
4065         {
4066             const glu::ContextInfo &info = m_context.getContextInfo();
4067             const glu::ContextType &type = m_context.getRenderContext().getType();
4068 
4069             /* ES 3.2+ included geometry shaders into the core */
4070             if (glu::contextSupports(type, glu::ApiType(3, 2, glu::PROFILE_ES)))
4071             {
4072                 return true;
4073             }
4074             /* ES 3.1 may be able to support geometry shaders via extensions */
4075             else if ((glu::contextSupports(type, glu::ApiType(3, 1, glu::PROFILE_ES))) &&
4076                      ((true == info.isExtensionSupported("GL_EXT_geometry_shader")) ||
4077                       (true == info.isExtensionSupported("GL_OES_geometry_shader"))))
4078             {
4079                 return true;
4080             }
4081             else
4082             {
4083                 OutputNotSupported("Geometry shader is not supported\n");
4084                 return false;
4085             }
4086         }
4087         else
4088         {
4089             return true;
4090         }
4091     }
Setup()4092     virtual long Setup()
4093     {
4094         _sizeX = getWindowWidth();
4095         _sizeY = getWindowHeight();
4096         if (_primitiveType != GL_TRIANGLE_STRIP && _primitiveType != GL_TRIANGLE_STRIP_ADJACENCY &&
4097             _primitiveType != GL_TRIANGLES && _primitiveType != GL_TRIANGLES_ADJACENCY &&
4098             _primitiveType != GL_TRIANGLE_FAN)
4099         {
4100             _sizeX &= (-4);
4101             _sizeY &= (-4);
4102         }
4103         if ((int)_drawSizeX < 0 || (int)_drawSizeY < 0)
4104         {
4105             //no PrimitiveGen dimensions given. assume same dimensions as rendered image^
4106             _drawSizeX = _sizeX;
4107             _drawSizeY = _sizeY;
4108             if (_primitiveType == GL_POINTS)
4109             {
4110                 //clamp vertex number (and rendering size) for points to max. 10000
4111                 _sizeX = _drawSizeX = std::min(_drawSizeX, 100u);
4112                 _sizeY = _drawSizeY = std::min(_drawSizeY, 100u);
4113             }
4114         }
4115 
4116         glClear(GL_COLOR_BUFFER_BIT);
4117         return NO_ERROR;
4118     }
4119 
4120     template <typename api>
Run(bool pointMode=false)4121     long Run(bool pointMode = false)
4122     {
4123 
4124         glClear(GL_COLOR_BUFFER_BIT);
4125 
4126         _program = CreateProgram(pointMode ? shaders::vshSimple_point<api>() : shaders::vshSimple<api>(), "",
4127                                  shaders::fshSimple<api>(), true);
4128         if (!_program)
4129         {
4130             return ERROR;
4131         }
4132         glUseProgram(_program);
4133 
4134         CColorArray coords;
4135         PrimitiveGen(_primitiveType, _drawSizeX, _drawSizeY, coords);
4136 
4137         glGenVertexArrays(1, &_vao);
4138         glBindVertexArray(_vao);
4139 
4140         glGenBuffers(1, &_buffer);
4141         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
4142 
4143         CColorArray padding(10, tcu::Vec4(0.0f));
4144 
4145         glBufferData(GL_ARRAY_BUFFER,
4146                      (GLsizeiptr)(coords.size() * (sizeof(coords[0])) + padding.size() * (sizeof(padding[0]))), NULL,
4147                      GL_STREAM_DRAW);
4148         glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(padding.size() * (sizeof(padding[0]))), &padding[0]);
4149         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(padding.size() * (sizeof(padding[0]))),
4150                         (GLsizeiptr)(coords.size() * (sizeof(coords[0]))), &coords[0]);
4151 
4152         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
4153         glEnableVertexAttribArray(0);
4154 
4155         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
4156         DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
4157 
4158         CElementArray elements(coords.size(), 0);
4159         for (size_t i = 0; i < elements.size(); ++i)
4160         {
4161             elements[i] = static_cast<GLuint>(i);
4162         }
4163 
4164         glGenBuffers(1, &_bufferIndirect);
4165         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
4166 
4167         switch (_drawFunc)
4168         {
4169         case DRAW_ARRAYS:
4170         {
4171             indirectArrays.count              = static_cast<GLuint>(coords.size()) / 2;
4172             indirectArrays.primCount          = 1;
4173             indirectArrays.first              = 10;
4174             indirectArrays.reservedMustBeZero = 0;
4175 
4176             glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), NULL, GL_STATIC_DRAW);
4177             glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawArraysIndirectCommand), &indirectArrays);
4178 
4179             glDrawArraysIndirect(_primitiveType, 0);
4180         }
4181         break;
4182         case DRAW_ELEMENTS:
4183         {
4184             indirectElements.count              = static_cast<GLuint>(coords.size()) / 2;
4185             indirectElements.primCount          = 1;
4186             indirectElements.baseVertex         = 7;
4187             indirectElements.firstIndex         = 3;
4188             indirectElements.reservedMustBeZero = 0;
4189 
4190             glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW);
4191             glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements);
4192 
4193             glGenBuffers(1, &_ebo);
4194             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
4195             glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
4196                          GL_STATIC_DRAW);
4197 
4198             glDrawElementsIndirect(_primitiveType, GL_UNSIGNED_INT, 0);
4199         }
4200         break;
4201         default:
4202             throw std::runtime_error("Unknown draw function!");
4203             break;
4204         }
4205 
4206         CColorArray bufferRef1(_sizeX * _sizeY / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
4207         CColorArray bufferRef2(_sizeX * _sizeY / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
4208         CColorArray bufferTest(_sizeX * _sizeY, tcu::Vec4(0.0f));
4209 
4210         DIResult result;
4211         ReadPixelsFloat<api>(0, (_sizeY + 1) / 2, _sizeX, _sizeY / 2, &bufferTest[0]);
4212         result.sub_result(BuffersCompare(bufferTest, _sizeX, _sizeY / 2, bufferRef1, _sizeX, _sizeY / 2));
4213 
4214         switch (_primitiveType)
4215         {
4216         case GL_TRIANGLES_ADJACENCY:
4217         case GL_TRIANGLE_STRIP_ADJACENCY:
4218         {
4219             CColorArray bufferRef3(_sizeX * _sizeY / 16, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
4220             CColorArray bufferRef4(_sizeX * _sizeY / 8, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
4221             CColorArray bufferRef5(_sizeX * _sizeY / 4, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
4222 
4223             CColorArray bufferTest3(_sizeX * _sizeY / 16, tcu::Vec4(0.0f));
4224             CColorArray bufferTest4(_sizeX * _sizeY / 8, tcu::Vec4(0.0f));
4225             CColorArray bufferTest5(_sizeX * _sizeY / 4, tcu::Vec4(0.0f));
4226 
4227             ReadPixelsFloat<api>(0, (_sizeY + 3) / 4, _sizeX / 4, _sizeY / 4, &bufferTest3[0]);
4228             result.sub_result(BuffersCompare(bufferTest3, _sizeX / 4, _sizeY / 4, bufferRef3, _sizeX / 4, _sizeY / 4));
4229 
4230             ReadPixelsFloat<api>((_sizeX + 3) / 4, (_sizeY + 3) / 4, _sizeX / 2, _sizeY / 4, &bufferTest4[0]);
4231             result.sub_result(BuffersCompare(bufferTest4, _sizeX / 2, _sizeY / 4, bufferRef4, _sizeX / 2, _sizeY / 4));
4232 
4233             ReadPixelsFloat<api>((_sizeX * 3 + 3) / 4, (_sizeY + 3) / 4, _sizeX / 4, _sizeY / 4, &bufferTest3[0]);
4234             result.sub_result(BuffersCompare(bufferTest3, _sizeX / 4, _sizeY / 4, bufferRef3, _sizeX / 4, _sizeY / 4));
4235 
4236             ReadPixelsFloat<api>(0, 0, _sizeX, _sizeY / 4, &bufferTest5[0]);
4237             result.sub_result(BuffersCompare(bufferTest5, _sizeX, _sizeY / 4, bufferRef5, _sizeX, _sizeY / 4));
4238         }
4239         break;
4240         default:
4241         {
4242             ReadPixelsFloat<api>(0, 0, _sizeX, _sizeY / 2, &bufferTest[0]);
4243             result.sub_result(BuffersCompare(bufferTest, _sizeX, _sizeY / 2, bufferRef2, _sizeX, _sizeY / 2));
4244         }
4245         break;
4246         }
4247 
4248         return result.code();
4249     }
4250 
Cleanup()4251     virtual long Cleanup()
4252     {
4253         glDisableVertexAttribArray(0);
4254         glUseProgram(0);
4255         glDeleteProgram(_program);
4256         glDeleteVertexArrays(1, &_vao);
4257         glDeleteBuffers(1, &_buffer);
4258         glDeleteBuffers(1, &_ebo);
4259         glDeleteBuffers(1, &_bufferIndirect);
4260         return NO_ERROR;
4261     }
4262 
CPrimitiveMode(TDrawFunction drawFunc,GLenum primitiveType,unsigned int sizeX=-1,unsigned sizeY=-1)4263     CPrimitiveMode(TDrawFunction drawFunc, GLenum primitiveType, unsigned int sizeX = -1, unsigned sizeY = -1)
4264         : _drawFunc(drawFunc)
4265         , _primitiveType(primitiveType)
4266         , _drawSizeX(sizeX)
4267         , _drawSizeY(sizeY)
4268         , _sizeX(0)
4269         , _sizeY(0)
4270         , _program(0)
4271         , _vao(0)
4272         , _buffer(0)
4273         , _ebo(0)
4274         , _bufferIndirect(0)
4275     {
4276     }
4277 
4278 private:
4279     TDrawFunction _drawFunc;
4280     GLenum _primitiveType;
4281     unsigned int _drawSizeX, _drawSizeY; //dims for primitive generator
4282     unsigned int _sizeX, _sizeY;         //rendering size
4283     GLuint _program;
4284     GLuint _vao, _buffer, _ebo, _bufferIndirect;
4285 
4286     CPrimitiveMode();
4287 };
4288 
4289 template <typename api>
4290 class CModeDrawArraysPoints : public CPrimitiveMode
4291 {
4292 public:
Title()4293     virtual std::string Title()
4294     {
4295         return "glDrawArraysIndirect mode: GL_POINTS";
4296     }
4297 
Purpose()4298     virtual std::string Purpose()
4299     {
4300         return "Verify that glDrawArraysIndirect with GL_POINTS works correctly";
4301     }
4302 
Method()4303     virtual std::string Method()
4304     {
4305         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4306                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4307     }
4308 
PassCriteria()4309     virtual std::string PassCriteria()
4310     {
4311         return "The test will pass if no OpenGL errors reported";
4312     }
4313 
CModeDrawArraysPoints()4314     CModeDrawArraysPoints() : CPrimitiveMode(DRAW_ARRAYS, GL_POINTS)
4315     {
4316     }
4317 
Run()4318     virtual long Run()
4319     {
4320         return CPrimitiveMode::Run<api>(true);
4321     }
4322 };
4323 
4324 template <typename api>
4325 class CModeDrawArraysLines : public CPrimitiveMode
4326 {
4327 public:
Title()4328     virtual std::string Title()
4329     {
4330         return "glDrawArraysIndirect mode: GL_LINES";
4331     }
4332 
Purpose()4333     virtual std::string Purpose()
4334     {
4335         return "Verify that glDrawArraysIndirect with GL_LINES works correctly";
4336     }
4337 
Method()4338     virtual std::string Method()
4339     {
4340         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4341                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4342     }
4343 
PassCriteria()4344     virtual std::string PassCriteria()
4345     {
4346         return "The test will pass if no OpenGL errors reported";
4347     }
4348 
CModeDrawArraysLines()4349     CModeDrawArraysLines() : CPrimitiveMode(DRAW_ARRAYS, GL_LINES)
4350     {
4351     }
4352 
Run()4353     virtual long Run()
4354     {
4355         return CPrimitiveMode::Run<api>();
4356     }
4357 };
4358 
4359 template <typename api>
4360 class CModeDrawArraysLineStrip : public CPrimitiveMode
4361 {
4362 public:
Title()4363     virtual std::string Title()
4364     {
4365         return "glDrawArraysIndirect mode: GL_LINE_STRIP";
4366     }
4367 
Purpose()4368     virtual std::string Purpose()
4369     {
4370         return "Verify that glDrawArraysIndirect with GL_LINE_STRIP works correctly";
4371     }
4372 
Method()4373     virtual std::string Method()
4374     {
4375         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4376                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4377     }
4378 
PassCriteria()4379     virtual std::string PassCriteria()
4380     {
4381         return "The test will pass if no OpenGL errors reported";
4382     }
4383 
CModeDrawArraysLineStrip()4384     CModeDrawArraysLineStrip() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_STRIP)
4385     {
4386     }
Run()4387     virtual long Run()
4388     {
4389         return CPrimitiveMode::Run<api>();
4390     }
4391 };
4392 
4393 template <typename api>
4394 class CModeDrawArraysLineLoop : public CPrimitiveMode
4395 {
4396 public:
Title()4397     virtual std::string Title()
4398     {
4399         return "glDrawArraysIndirect mode: GL_LINE_LOOP";
4400     }
4401 
Purpose()4402     virtual std::string Purpose()
4403     {
4404         return "Verify that glDrawArraysIndirect with GL_LINE_LOOP works correctly";
4405     }
4406 
Method()4407     virtual std::string Method()
4408     {
4409         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4410                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4411     }
4412 
PassCriteria()4413     virtual std::string PassCriteria()
4414     {
4415         return "The test will pass if no OpenGL errors reported";
4416     }
4417 
CModeDrawArraysLineLoop()4418     CModeDrawArraysLineLoop() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_LOOP)
4419     {
4420     }
4421 
Run()4422     virtual long Run()
4423     {
4424         return CPrimitiveMode::Run<api>();
4425     }
4426 };
4427 
4428 template <typename api>
4429 class CModeDrawArraysTriangleStrip : public CPrimitiveMode
4430 {
4431 public:
Title()4432     virtual std::string Title()
4433     {
4434         return "glDrawArraysIndirect mode: GL_TRIANGLE_STRIP";
4435     }
4436 
Purpose()4437     virtual std::string Purpose()
4438     {
4439         return "Verify that glDrawArraysIndirect with GL_TRIANGLE_STRIP works correctly";
4440     }
4441 
Method()4442     virtual std::string Method()
4443     {
4444         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4445                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4446     }
4447 
PassCriteria()4448     virtual std::string PassCriteria()
4449     {
4450         return "The test will pass if no OpenGL errors reported";
4451     }
4452 
CModeDrawArraysTriangleStrip()4453     CModeDrawArraysTriangleStrip() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_STRIP, 2, 2)
4454     {
4455     }
4456 
Run()4457     virtual long Run()
4458     {
4459         return CPrimitiveMode::Run<api>();
4460     }
4461 };
4462 
4463 template <typename api>
4464 class CModeDrawArraysTriangleFan : public CPrimitiveMode
4465 {
4466 public:
Title()4467     virtual std::string Title()
4468     {
4469         return "glDrawArraysIndirect mode: GL_TRIANGLE_FAN";
4470     }
4471 
Purpose()4472     virtual std::string Purpose()
4473     {
4474         return "Verify that glDrawArraysIndirect with GL_TRIANGLE_FAN works correctly";
4475     }
4476 
Method()4477     virtual std::string Method()
4478     {
4479         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4480                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4481     }
4482 
PassCriteria()4483     virtual std::string PassCriteria()
4484     {
4485         return "The test will pass if no OpenGL errors reported";
4486     }
4487 
CModeDrawArraysTriangleFan()4488     CModeDrawArraysTriangleFan() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_FAN, 2, 2)
4489     {
4490     }
4491 
Run()4492     virtual long Run()
4493     {
4494         return CPrimitiveMode::Run<api>();
4495     }
4496 };
4497 
4498 template <typename api>
4499 class CModeDrawArraysLinesAdjacency : public CPrimitiveMode
4500 {
4501 public:
Title()4502     virtual std::string Title()
4503     {
4504         return "glDrawArraysIndirect mode: GL_LINES_ADJACENCY";
4505     }
4506 
Purpose()4507     virtual std::string Purpose()
4508     {
4509         return "Verify that glDrawArraysIndirect with GL_LINES_ADJACENCY works correctly";
4510     }
4511 
Method()4512     virtual std::string Method()
4513     {
4514         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4515                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4516     }
4517 
PassCriteria()4518     virtual std::string PassCriteria()
4519     {
4520         return "The test will pass if no OpenGL errors reported";
4521     }
4522 
CModeDrawArraysLinesAdjacency()4523     CModeDrawArraysLinesAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_LINES_ADJACENCY)
4524     {
4525     }
4526 
Run()4527     virtual long Run()
4528     {
4529         if (!IsGeometryShaderSupported<api>())
4530             return NOT_SUPPORTED;
4531         return CPrimitiveMode::Run<api>();
4532     }
4533 };
4534 
4535 template <typename api>
4536 class CModeDrawArraysLineStripAdjacency : public CPrimitiveMode
4537 {
4538 public:
Title()4539     virtual std::string Title()
4540     {
4541         return "glDrawArraysIndirect mode: GL_LINE_STRIP_ADJACENCY";
4542     }
4543 
Purpose()4544     virtual std::string Purpose()
4545     {
4546         return "Verify that glDrawArraysIndirect with GL_LINE_STRIP_ADJACENCY works correctly";
4547     }
4548 
Method()4549     virtual std::string Method()
4550     {
4551         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4552                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4553     }
4554 
PassCriteria()4555     virtual std::string PassCriteria()
4556     {
4557         return "The test will pass if no OpenGL errors reported";
4558     }
4559 
CModeDrawArraysLineStripAdjacency()4560     CModeDrawArraysLineStripAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_STRIP_ADJACENCY)
4561     {
4562     }
4563 
Run()4564     virtual long Run()
4565     {
4566         if (!IsGeometryShaderSupported<api>())
4567             return NOT_SUPPORTED;
4568         return CPrimitiveMode::Run<api>();
4569     }
4570 };
4571 
4572 template <typename api>
4573 class CModeDrawArraysTrianglesAdjacency : public CPrimitiveMode
4574 {
4575 public:
Title()4576     virtual std::string Title()
4577     {
4578         return "glDrawArraysIndirect mode: GL_TRIANGLES_ADJACENCY";
4579     }
4580 
Purpose()4581     virtual std::string Purpose()
4582     {
4583         return "Verify that glDrawArraysIndirect with GL_TRIANGLES_ADJACENCY works correctly";
4584     }
4585 
Method()4586     virtual std::string Method()
4587     {
4588         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4589                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4590     }
4591 
PassCriteria()4592     virtual std::string PassCriteria()
4593     {
4594         return "The test will pass if no OpenGL errors reported";
4595     }
4596 
CModeDrawArraysTrianglesAdjacency()4597     CModeDrawArraysTrianglesAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLES_ADJACENCY, 4, 4)
4598     {
4599     }
4600 
Run()4601     virtual long Run()
4602     {
4603         if (!IsGeometryShaderSupported<api>())
4604             return NOT_SUPPORTED;
4605         return CPrimitiveMode::Run<api>();
4606     }
4607 };
4608 
4609 template <typename api>
4610 class CModeDrawArraysTriangleStripAdjacency : public CPrimitiveMode
4611 {
4612 public:
Title()4613     virtual std::string Title()
4614     {
4615         return "glDrawArraysIndirect mode: GL_TRIANGLE_STRIP_ADJACENCY";
4616     }
4617 
Purpose()4618     virtual std::string Purpose()
4619     {
4620         return "Verify that glDrawArraysIndirect with GL_TRIANGLE_STRIP_ADJACENCY works correctly";
4621     }
4622 
Method()4623     virtual std::string Method()
4624     {
4625         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4626                "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
4627     }
4628 
PassCriteria()4629     virtual std::string PassCriteria()
4630     {
4631         return "The test will pass if no OpenGL errors reported";
4632     }
4633 
CModeDrawArraysTriangleStripAdjacency()4634     CModeDrawArraysTriangleStripAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_STRIP_ADJACENCY, 4, 4)
4635     {
4636     }
Run()4637     virtual long Run()
4638     {
4639         if (!IsGeometryShaderSupported<api>())
4640             return NOT_SUPPORTED;
4641         return CPrimitiveMode::Run<api>();
4642     }
4643 };
4644 
4645 template <typename api>
4646 class CModeDrawElementsPoints : public CPrimitiveMode
4647 {
4648 public:
Title()4649     virtual std::string Title()
4650     {
4651         return "glDrawElementsIndirect mode: GL_POINTS";
4652     }
4653 
Purpose()4654     virtual std::string Purpose()
4655     {
4656         return "Verify that glDrawElementsIndirect with GL_POINTS works correctly";
4657     }
4658 
Method()4659     virtual std::string Method()
4660     {
4661         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4662                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4663     }
4664 
PassCriteria()4665     virtual std::string PassCriteria()
4666     {
4667         return "The test will pass if no OpenGL errors reported";
4668     }
4669 
CModeDrawElementsPoints()4670     CModeDrawElementsPoints() : CPrimitiveMode(DRAW_ELEMENTS, GL_POINTS)
4671     {
4672     }
4673 
Run()4674     virtual long Run()
4675     {
4676         return CPrimitiveMode::Run<api>(true);
4677     }
4678 };
4679 
4680 template <typename api>
4681 class CModeDrawElementsLines : public CPrimitiveMode
4682 {
4683 public:
Title()4684     virtual std::string Title()
4685     {
4686         return "glDrawElementsIndirect mode: GL_LINES";
4687     }
4688 
Purpose()4689     virtual std::string Purpose()
4690     {
4691         return "Verify that glDrawElementsIndirect with GL_LINES works correctly";
4692     }
4693 
Method()4694     virtual std::string Method()
4695     {
4696         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4697                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4698     }
4699 
PassCriteria()4700     virtual std::string PassCriteria()
4701     {
4702         return "The test will pass if no OpenGL errors reported";
4703     }
4704 
CModeDrawElementsLines()4705     CModeDrawElementsLines() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINES)
4706     {
4707     }
Run()4708     virtual long Run()
4709     {
4710         return CPrimitiveMode::Run<api>();
4711     }
4712 };
4713 
4714 template <typename api>
4715 class CModeDrawElementsLineStrip : public CPrimitiveMode
4716 {
4717 public:
Title()4718     virtual std::string Title()
4719     {
4720         return "glDrawElementsIndirect mode: GL_LINE_STRIP";
4721     }
4722 
Purpose()4723     virtual std::string Purpose()
4724     {
4725         return "Verify that glDrawElementsIndirect with GL_LINE_STRIP works correctly";
4726     }
4727 
Method()4728     virtual std::string Method()
4729     {
4730         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4731                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4732     }
4733 
PassCriteria()4734     virtual std::string PassCriteria()
4735     {
4736         return "The test will pass if no OpenGL errors reported";
4737     }
4738 
CModeDrawElementsLineStrip()4739     CModeDrawElementsLineStrip() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_STRIP)
4740     {
4741     }
Run()4742     virtual long Run()
4743     {
4744         return CPrimitiveMode::Run<api>();
4745     }
4746 };
4747 
4748 template <typename api>
4749 class CModeDrawElementsLineLoop : public CPrimitiveMode
4750 {
4751 public:
Title()4752     virtual std::string Title()
4753     {
4754         return "glDrawElementsIndirect mode: GL_LINE_LOOP";
4755     }
4756 
Purpose()4757     virtual std::string Purpose()
4758     {
4759         return "Verify that glDrawElementsIndirect with GL_LINE_LOOP works correctly";
4760     }
4761 
Method()4762     virtual std::string Method()
4763     {
4764         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4765                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4766     }
4767 
PassCriteria()4768     virtual std::string PassCriteria()
4769     {
4770         return "The test will pass if no OpenGL errors reported";
4771     }
4772 
CModeDrawElementsLineLoop()4773     CModeDrawElementsLineLoop() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_LOOP)
4774     {
4775     }
Run()4776     virtual long Run()
4777     {
4778         return CPrimitiveMode::Run<api>();
4779     }
4780 };
4781 
4782 template <typename api>
4783 class CModeDrawElementsTriangleStrip : public CPrimitiveMode
4784 {
4785 public:
Title()4786     virtual std::string Title()
4787     {
4788         return "glDrawElementsIndirect mode: GL_TRIANGLE_STRIP";
4789     }
4790 
Purpose()4791     virtual std::string Purpose()
4792     {
4793         return "Verify that glDrawElementsIndirect with GL_TRIANGLE_STRIP works correctly";
4794     }
4795 
Method()4796     virtual std::string Method()
4797     {
4798         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4799                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4800     }
4801 
PassCriteria()4802     virtual std::string PassCriteria()
4803     {
4804         return "The test will pass if no OpenGL errors reported";
4805     }
4806 
CModeDrawElementsTriangleStrip()4807     CModeDrawElementsTriangleStrip() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_STRIP, 2, 2)
4808     {
4809     }
Run()4810     virtual long Run()
4811     {
4812         return CPrimitiveMode::Run<api>();
4813     }
4814 };
4815 
4816 template <typename api>
4817 class CModeDrawElementsTriangleFan : public CPrimitiveMode
4818 {
4819 public:
Title()4820     virtual std::string Title()
4821     {
4822         return "glDrawElementsIndirect mode: GL_TRIANGLE_FAN";
4823     }
4824 
Purpose()4825     virtual std::string Purpose()
4826     {
4827         return "Verify that glDrawElementsIndirect with GL_TRIANGLE_FAN works correctly";
4828     }
4829 
Method()4830     virtual std::string Method()
4831     {
4832         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4833                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4834     }
4835 
PassCriteria()4836     virtual std::string PassCriteria()
4837     {
4838         return "The test will pass if no OpenGL errors reported";
4839     }
4840 
CModeDrawElementsTriangleFan()4841     CModeDrawElementsTriangleFan() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_FAN, 2, 2)
4842     {
4843     }
Run()4844     virtual long Run()
4845     {
4846         return CPrimitiveMode::Run<api>();
4847     }
4848 };
4849 
4850 template <typename api>
4851 class CModeDrawElementsLinesAdjacency : public CPrimitiveMode
4852 {
4853 public:
Title()4854     virtual std::string Title()
4855     {
4856         return "glDrawElementsIndirect mode: GL_LINES_ADJACENCY";
4857     }
4858 
Purpose()4859     virtual std::string Purpose()
4860     {
4861         return "Verify that glDrawElementsIndirect with GL_LINES_ADJACENCY works correctly";
4862     }
4863 
Method()4864     virtual std::string Method()
4865     {
4866         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4867                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4868     }
4869 
PassCriteria()4870     virtual std::string PassCriteria()
4871     {
4872         return "The test will pass if no OpenGL errors reported";
4873     }
4874 
CModeDrawElementsLinesAdjacency()4875     CModeDrawElementsLinesAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINES_ADJACENCY)
4876     {
4877     }
Run()4878     virtual long Run()
4879     {
4880         if (!IsGeometryShaderSupported<api>())
4881             return NOT_SUPPORTED;
4882         return CPrimitiveMode::Run<api>();
4883     }
4884 };
4885 
4886 template <typename api>
4887 class CModeDrawElementsLineStripAdjacency : public CPrimitiveMode
4888 {
4889 public:
Title()4890     virtual std::string Title()
4891     {
4892         return "glDrawElementsIndirect mode: GL_LINE_STRIP_ADJACENCY";
4893     }
4894 
Purpose()4895     virtual std::string Purpose()
4896     {
4897         return "Verify that glDrawElementsIndirect with GL_LINE_STRIP_ADJACENCY works correctly";
4898     }
4899 
Method()4900     virtual std::string Method()
4901     {
4902         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4903                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4904     }
4905 
PassCriteria()4906     virtual std::string PassCriteria()
4907     {
4908         return "The test will pass if no OpenGL errors reported";
4909     }
4910 
CModeDrawElementsLineStripAdjacency()4911     CModeDrawElementsLineStripAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_STRIP_ADJACENCY)
4912     {
4913     }
Run()4914     virtual long Run()
4915     {
4916         if (!IsGeometryShaderSupported<api>())
4917             return NOT_SUPPORTED;
4918         return CPrimitiveMode::Run<api>();
4919     }
4920 };
4921 
4922 template <typename api>
4923 class CModeDrawElementsTrianglesAdjacency : public CPrimitiveMode
4924 {
4925 public:
Title()4926     virtual std::string Title()
4927     {
4928         return "glDrawElementsIndirect mode: GL_TRIANGLES_ADJACENCY";
4929     }
4930 
Purpose()4931     virtual std::string Purpose()
4932     {
4933         return "Verify that glDrawElementsIndirect with GL_TRIANGLES_ADJACENCY works correctly";
4934     }
4935 
Method()4936     virtual std::string Method()
4937     {
4938         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4939                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4940     }
4941 
PassCriteria()4942     virtual std::string PassCriteria()
4943     {
4944         return "The test will pass if no OpenGL errors reported";
4945     }
4946 
CModeDrawElementsTrianglesAdjacency()4947     CModeDrawElementsTrianglesAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLES_ADJACENCY, 4, 4)
4948     {
4949     }
Run()4950     virtual long Run()
4951     {
4952         if (!IsGeometryShaderSupported<api>())
4953             return NOT_SUPPORTED;
4954         return CPrimitiveMode::Run<api>();
4955     }
4956 };
4957 
4958 template <typename api>
4959 class CModeDrawElementsTriangleStripAdjacency : public CPrimitiveMode
4960 {
4961 public:
Title()4962     virtual std::string Title()
4963     {
4964         return "glDrawElementsIndirect mode: GL_TRIANGLE_STRIP_ADJACENCY";
4965     }
4966 
Purpose()4967     virtual std::string Purpose()
4968     {
4969         return "Verify that glDrawElementsIndirect with GL_TRIANGLE_STRIP_ADJACENCY works correctly";
4970     }
4971 
Method()4972     virtual std::string Method()
4973     {
4974         return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
4975                "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
4976     }
4977 
PassCriteria()4978     virtual std::string PassCriteria()
4979     {
4980         return "The test will pass if no OpenGL errors reported";
4981     }
4982 
CModeDrawElementsTriangleStripAdjacency()4983     CModeDrawElementsTriangleStripAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_STRIP_ADJACENCY, 4, 4)
4984     {
4985     }
Run()4986     virtual long Run()
4987     {
4988         if (!IsGeometryShaderSupported<api>())
4989             return NOT_SUPPORTED;
4990         return CPrimitiveMode::Run<api>();
4991     }
4992 };
4993 
4994 class CTransformFeedback : public DrawIndirectBase
4995 {
4996 public:
Setup()4997     virtual long Setup()
4998     {
4999         glClear(GL_COLOR_BUFFER_BIT);
5000         return NO_ERROR;
5001     }
5002 
5003     template <typename api>
Run()5004     long Run()
5005     {
5006         CColorArray coords;
5007         PrimitiveGen(GL_TRIANGLE_STRIP, 8, 8, coords);
5008 
5009         glClear(GL_COLOR_BUFFER_BIT);
5010 
5011         _program                 = CreateProgram(Vsh<api>(), "", shaders::fshSimple<api>(), false);
5012         const GLchar *varyings[] = {"dataOut"};
5013         glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS);
5014         glLinkProgram(_program);
5015         if (!CheckProgram(_program))
5016         {
5017             return ERROR;
5018         }
5019         glUseProgram(_program);
5020 
5021         glGenBuffers(1, &_vbo);
5022         glBindBuffer(GL_ARRAY_BUFFER, _vbo);
5023         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW);
5024 
5025         glGenBuffers(1, &_ubo);
5026         glBindBuffer(GL_UNIFORM_BUFFER, _ubo);
5027         glBufferData(GL_UNIFORM_BUFFER, 4 * 5 * sizeof(GLuint), NULL, GL_STATIC_DRAW);
5028         glBindBufferBase(GL_UNIFORM_BUFFER, glGetUniformBlockIndex(_program, "BLOCK"), _ubo);
5029         std::vector<GLuint> uboData;
5030 
5031         switch (_drawFunc)
5032         {
5033         case DRAW_ARRAYS:
5034         {
5035             uboData.resize(4 * 4, 0);
5036 
5037             uboData[0]  = static_cast<GLuint>(coords.size()); //count
5038             uboData[4]  = 1;                                  //primcount
5039             uboData[8]  = 0;                                  //first
5040             uboData[12] = 0;                                  //mbz
5041         }
5042         break;
5043         case DRAW_ELEMENTS:
5044         {
5045             uboData.resize(4 * 5, 0);
5046             uboData[0]  = static_cast<GLuint>(coords.size()); //count
5047             uboData[4]  = 1;                                  //primcount
5048             uboData[8]  = 0;                                  //firstindex
5049             uboData[12] = 0;                                  //basevertex
5050             uboData[16] = 0;                                  //mbz
5051         }
5052         break;
5053         default:
5054             throw std::runtime_error("Unknown draw function!");
5055             break;
5056         }
5057         glBufferSubData(GL_UNIFORM_BUFFER, 0, (GLsizeiptr)(uboData.size() * sizeof(uboData[0])), &uboData[0]);
5058 
5059         glGenVertexArrays(1, &_vao);
5060         glBindVertexArray(_vao);
5061         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
5062         glEnableVertexAttribArray(0);
5063 
5064         CElementArray elements(coords.size(), 0);
5065         for (size_t i = 0; i < elements.size(); ++i)
5066         {
5067             elements[i] = static_cast<GLuint>(i);
5068         }
5069 
5070         glGenBuffers(1, &_ebo);
5071         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
5072         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
5073                      GL_STATIC_DRAW);
5074 
5075         glGenBuffers(1, &_bufferIndirect);
5076 
5077         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _bufferIndirect);
5078         GLuint zeroes[] = {0, 0, 0, 0, 0};
5079         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(zeroes), zeroes, GL_DYNAMIC_DRAW);
5080         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _bufferIndirect);
5081         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
5082 
5083         glEnable(GL_RASTERIZER_DISCARD);
5084         glBeginTransformFeedback(GL_POINTS);
5085         glDrawArrays(GL_POINTS, 0, 5);
5086         glEndTransformFeedback();
5087         glDisable(GL_RASTERIZER_DISCARD);
5088 
5089         switch (_drawFunc)
5090         {
5091         case DRAW_ARRAYS:
5092             glDrawArraysIndirect(GL_TRIANGLES, 0);
5093             break;
5094         case DRAW_ELEMENTS:
5095             glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
5096 
5097             break;
5098         default:
5099             throw std::runtime_error("Unknown draw function!");
5100             break;
5101         }
5102 
5103         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
5104         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
5105         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
5106 
5107         DIResult result;
5108         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
5109                                          getWindowHeight()));
5110 
5111         return result.code();
5112     }
5113 
Cleanup()5114     virtual long Cleanup()
5115     {
5116         glDisableVertexAttribArray(0);
5117         glBindBuffer(GL_ARRAY_BUFFER, 0);
5118         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
5119         glBindVertexArray(0);
5120         glUseProgram(0);
5121 
5122         if (_vao)
5123         {
5124             glDeleteVertexArrays(1, &_vao);
5125         }
5126         if (_vbo)
5127         {
5128             glDeleteBuffers(1, &_vbo);
5129         }
5130         if (_ebo)
5131         {
5132             glDeleteBuffers(1, &_ebo);
5133         }
5134         if (_ubo)
5135         {
5136             glDeleteBuffers(1, &_ubo);
5137         }
5138         if (_bufferIndirect)
5139         {
5140             glDeleteBuffers(1, &_bufferIndirect);
5141         }
5142         if (_program)
5143         {
5144             glDeleteProgram(_program);
5145         }
5146         return NO_ERROR;
5147     }
5148 
CTransformFeedback(TDrawFunction drawFunc)5149     CTransformFeedback(TDrawFunction drawFunc)
5150         : _drawFunc(drawFunc)
5151         , _program(0)
5152         , _vao(0)
5153         , _vbo(0)
5154         , _ebo(0)
5155         , _ubo(0)
5156         , _bufferIndirect(0)
5157     {
5158     }
5159 
5160 private:
5161     TDrawFunction _drawFunc;
5162     GLuint _program;
5163     GLuint _vao, _vbo, _ebo, _ubo, _bufferIndirect;
5164 
5165     CTransformFeedback();
5166 
5167     template <typename api>
Vsh()5168     std::string Vsh()
5169     {
5170         return api::glslVer() + NL "flat out highp uint dataOut;" NL "in vec4 i_vertex;" NL
5171                                    "layout(std140) uniform  BLOCK {" NL " uint m[5];" NL "} b;" NL "void main() {" NL
5172                                    "  dataOut = b.m[min(4, gl_VertexID)];" NL "    gl_Position = i_vertex;" NL "}";
5173     }
5174 };
5175 
5176 template <typename api>
5177 struct CTransformFeedbackArray : public CTransformFeedback
5178 {
Titleglcts::__anon91df61990111::CTransformFeedbackArray5179     virtual std::string Title()
5180     {
5181         return "Transform feedback: glDrawArrayIndirect";
5182     }
5183 
Purposeglcts::__anon91df61990111::CTransformFeedbackArray5184     virtual std::string Purpose()
5185     {
5186         return "Verify that transform feedback works correctly with glDrawArrayIndirect";
5187     }
5188 
Methodglcts::__anon91df61990111::CTransformFeedbackArray5189     virtual std::string Method()
5190     {
5191         return "1. Create data" NL "2. Use data as input to glDrawArrayIndirect" NL "3. Verify results";
5192     }
5193 
PassCriteriaglcts::__anon91df61990111::CTransformFeedbackArray5194     virtual std::string PassCriteria()
5195     {
5196         return "The test will pass if no OpenGL errors reported";
5197     }
5198 
CTransformFeedbackArrayglcts::__anon91df61990111::CTransformFeedbackArray5199     CTransformFeedbackArray() : CTransformFeedback(DRAW_ARRAYS)
5200     {
5201     }
5202 
Runglcts::__anon91df61990111::CTransformFeedbackArray5203     virtual long Run()
5204     {
5205         return CTransformFeedback::Run<api>();
5206     }
5207 };
5208 
5209 template <typename api>
5210 struct CTransformFeedbackElements : public CTransformFeedback
5211 {
Titleglcts::__anon91df61990111::CTransformFeedbackElements5212     virtual std::string Title()
5213     {
5214         return "Transform feedback: glDrawElementsIndirect";
5215     }
5216 
Purposeglcts::__anon91df61990111::CTransformFeedbackElements5217     virtual std::string Purpose()
5218     {
5219         return "Verify that transform feedback works correctly with glDrawElementsIndirect";
5220     }
5221 
Methodglcts::__anon91df61990111::CTransformFeedbackElements5222     virtual std::string Method()
5223     {
5224         return "1. Create data" NL "2. Use data as input to glDrawElementsIndirect" NL "3. Verify results";
5225     }
5226 
PassCriteriaglcts::__anon91df61990111::CTransformFeedbackElements5227     virtual std::string PassCriteria()
5228     {
5229         return "The test will pass if no OpenGL errors reported";
5230     }
5231 
CTransformFeedbackElementsglcts::__anon91df61990111::CTransformFeedbackElements5232     CTransformFeedbackElements() : CTransformFeedback(DRAW_ELEMENTS)
5233     {
5234     }
5235 
Runglcts::__anon91df61990111::CTransformFeedbackElements5236     virtual long Run()
5237     {
5238         return CTransformFeedback::Run<api>();
5239     }
5240 };
5241 
5242 class CComputeBase : public DrawIndirectBase
5243 {
5244 public:
Setup()5245     virtual long Setup()
5246     {
5247         glClear(GL_COLOR_BUFFER_BIT);
5248         return NO_ERROR;
5249     }
5250 
5251     template <typename api>
Run()5252     long Run()
5253     {
5254 
5255         int width, height;
5256         glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &width);
5257         glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &height);
5258 
5259         width  = std::min(width, getWindowWidth());
5260         height = std::min(height, getWindowHeight());
5261 
5262         glViewport(0, 0, width, height);
5263 
5264         CColorArray coords(width * height, tcu::Vec4(0));
5265         CColorArray colors(width * height, tcu::Vec4(0));
5266 
5267         _program = CreateProgram(Vsh<api>(), "", Fsh<api>(), false);
5268         glBindAttribLocation(_program, 0, "in_coords");
5269         glBindAttribLocation(_program, 1, "in_colors");
5270         glLinkProgram(_program);
5271         if (!CheckProgram(_program))
5272         {
5273             return ERROR;
5274         }
5275         glUseProgram(_program);
5276 
5277         glGenVertexArrays(1, &_vao);
5278         glBindVertexArray(_vao);
5279 
5280         glGenBuffers(1, &_bufferCoords);
5281         glBindBuffer(GL_ARRAY_BUFFER, _bufferCoords);
5282         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), 0, GL_STREAM_DRAW);
5283 
5284         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
5285         glEnableVertexAttribArray(0);
5286 
5287         glGenBuffers(1, &_bufferColors);
5288         glBindBuffer(GL_ARRAY_BUFFER, _bufferColors);
5289         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(colors.size() * sizeof(colors[0])), 0, GL_STREAM_DRAW);
5290 
5291         glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
5292         glEnableVertexAttribArray(1);
5293 
5294         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
5295         DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
5296 
5297         CElementArray elements(width * height, 0);
5298         for (size_t i = 0; i < elements.size(); ++i)
5299         {
5300             elements[i] = static_cast<GLuint>(i);
5301         }
5302 
5303         glGenBuffers(1, &_bufferIndirect);
5304         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
5305         switch (_drawFunc)
5306         {
5307         case DRAW_ARRAYS:
5308         {
5309             glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
5310         }
5311         break;
5312         case DRAW_ELEMENTS:
5313         {
5314             glGenBuffers(1, &_ebo);
5315             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
5316             glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
5317                          GL_STATIC_DRAW);
5318 
5319             glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements,
5320                          GL_STATIC_DRAW);
5321         }
5322         break;
5323         default:
5324             throw std::runtime_error("Unknown draw function!");
5325             break;
5326         }
5327 
5328         _programCompute = CreateComputeProgram(Csh<api>(), false);
5329         glLinkProgram(_programCompute);
5330         if (!CheckProgram(_programCompute))
5331         {
5332             return ERROR;
5333         }
5334         glUseProgram(_programCompute);
5335         glUniform1ui(glGetUniformLocation(_programCompute, "width"), width);
5336         glUniform1ui(glGetUniformLocation(_programCompute, "height"), height);
5337         glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, _bufferCoords);
5338         glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, _bufferColors);
5339         glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, _bufferIndirect);
5340 
5341         glDispatchCompute(width, height, 1);
5342         glMemoryBarrier(GL_COMMAND_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT);
5343 
5344         glUseProgram(_program);
5345 
5346         switch (_drawFunc)
5347         {
5348         case DRAW_ARRAYS:
5349         {
5350             glDrawArraysIndirect(GL_POINTS, 0);
5351         }
5352         break;
5353         case DRAW_ELEMENTS:
5354         {
5355             glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, 0);
5356         }
5357         break;
5358         default:
5359             throw std::runtime_error("Unknown draw function!");
5360             break;
5361         }
5362 
5363         CColorArray bufferRef1(width * height / 4, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
5364         CColorArray bufferRef2(width * height / 4, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
5365         CColorArray bufferRef3(width * height / 4, tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f));
5366         CColorArray bufferRef4(width * height / 4, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f));
5367         CColorArray bufferTest(width * height / 4, tcu::Vec4(0.0f));
5368 
5369         DIResult result;
5370         ReadPixelsFloat<api>(0, 0, width / 2, height / 2, &bufferTest[0]);
5371         result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef1, width / 2, height / 2))
5372             << "Region 0 verification failed";
5373 
5374         ReadPixelsFloat<api>((width + 1) / 2, 0, width / 2, height / 2, &bufferTest[0]);
5375         result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef2, width / 2, height / 2))
5376             << "Region 1 verification failed";
5377 
5378         ReadPixelsFloat<api>(0, (height + 1) / 2, width / 2, height / 2, &bufferTest[0]);
5379         result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef3, width / 2, height / 2))
5380             << "Region 2 verification failed";
5381 
5382         ReadPixelsFloat<api>((width + 1) / 2, (height + 1) / 2, width / 2, height / 2, &bufferTest[0]);
5383         result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef4, width / 2, height / 2))
5384             << "Region 3 verification failed";
5385 
5386         return result.code();
5387     }
5388 
Cleanup()5389     virtual long Cleanup()
5390     {
5391         glDisableVertexAttribArray(1);
5392         glDisableVertexAttribArray(0);
5393         glDeleteProgram(_program);
5394         glDeleteProgram(_programCompute);
5395         glDeleteVertexArrays(1, &_vao);
5396         if (_ebo)
5397             glDeleteBuffers(1, &_ebo);
5398         glDeleteBuffers(1, &_bufferCoords);
5399         glDeleteBuffers(1, &_bufferColors);
5400         glDeleteBuffers(1, &_bufferIndirect);
5401         glViewport(0, 0, getWindowWidth(), getWindowHeight());
5402         return NO_ERROR;
5403     }
CComputeBase(TDrawFunction drawFunc)5404     CComputeBase(TDrawFunction drawFunc)
5405         : _drawFunc(drawFunc)
5406         , _program(0)
5407         , _programCompute(0)
5408         , _vao(0)
5409         , _ebo(0)
5410         , _bufferCoords(0)
5411         , _bufferColors(0)
5412         , _bufferIndirect(0)
5413     {
5414     }
5415 
5416 private:
5417     CComputeBase();
5418     TDrawFunction _drawFunc;
5419 
5420     template <typename api>
Vsh()5421     std::string Vsh()
5422     {
5423         return api::glslVer() + NL "in vec4 in_coords;" NL "in vec4 in_colors;" NL "out vec4 colors;" NL
5424                                    "void main() {" NL "  colors = in_colors;" NL "  gl_Position = in_coords;" NL
5425                                    "#if defined(GL_ES)" NL "  gl_PointSize = 1.0;" NL "#endif" NL "}";
5426     }
5427 
5428     template <typename api>
Fsh()5429     std::string Fsh()
5430     {
5431         return api::glslVer() + NL "precision highp float;" NL "in vec4 colors;" NL "out vec4 outColor;" NL
5432                                    "void main() {" NL "  outColor = colors;" NL "}";
5433     }
5434 
5435     template <typename api>
Csh()5436     std::string Csh()
5437     {
5438         return api::glslVer(true) + NL "precision highp int;                                           " NL
5439                                        "precision highp float;                                         " NL
5440                                        "                                                               " NL
5441                                        "layout(local_size_x = 1) in;                                   " NL
5442                                        "layout(std430, binding = 0) buffer Vertices {                  " NL
5443                                        "    vec4 vertices[];                                           " NL
5444                                        "};                                                             " NL
5445                                        "layout(std430, binding = 1) buffer Colors {                    " NL
5446                                        "    vec4 colors[];                                             " NL
5447                                        "};                                                             " NL
5448                                        "layout(std430, binding = 2) buffer Indirect {                  " NL
5449                                        "    uint indirect[4];                                          " NL
5450                                        "};                                                             " NL
5451                                        "                                                               " NL
5452                                        "uniform uint height;                                           " NL
5453                                        "uniform uint width;                                            " NL
5454                                        "                                                               " NL
5455                                        "void main() {                                                  " NL
5456                                        "    uint w = gl_GlobalInvocationID.x;                          " NL
5457                                        "    uint h = gl_GlobalInvocationID.y;                          " NL
5458                                        "    float stepX = 2.0 / float(width);                          " NL
5459                                        "    float stepY = 2.0 / float(height);                         " NL
5460                                        "    float offsetX = -1.0 + stepX * float(w) + stepX / 2.0;     " NL
5461                                        "    float offsetY = -1.0 + stepY * float(h) + stepY / 2.0;     " NL
5462                                        "    uint arrayOffset = h * width + w;                          " NL
5463                                        "    vertices[ arrayOffset ] = vec4(offsetX, offsetY, 0.0, 1.0);" NL
5464                                        "    vec4 color = vec4(0.0, 0.0, 0.0, 1.0);                     " NL
5465                                        "    if(w > (width / 2u - 1u)) {                                " NL
5466                                        "        color = color + vec4(0.5, 0.0, 0.0, 0.0);              " NL
5467                                        "    }                                                          " NL
5468                                        "    if(h > (height / 2u - 1u)) {                               " NL
5469                                        "        color = color + vec4(0.0, 0.5, 0.0, 0.0);              " NL
5470                                        "    }                                                          " NL
5471                                        "    colors[ arrayOffset ] = color;                             " NL
5472                                        "    if(w == 0u && h == 0u) {                                   " NL
5473                                        "        indirect[0] = width * height;                          " NL
5474                                        "        indirect[1] =  1u;                                     " NL
5475                                        "    }                                                          " NL
5476                                        "}                                                              ";
5477     }
5478 
5479     GLuint _program, _programCompute;
5480     GLuint _vao;
5481     GLuint _ebo;
5482     GLuint _bufferCoords;
5483     GLuint _bufferColors;
5484     GLuint _bufferIndirect;
5485 };
5486 
5487 template <typename api>
5488 struct CComputeShaderArray : public CComputeBase
5489 {
Titleglcts::__anon91df61990111::CComputeShaderArray5490     virtual std::string Title()
5491     {
5492         return "Compute Shader: glDrawArrayIndirect";
5493     }
5494 
Purposeglcts::__anon91df61990111::CComputeShaderArray5495     virtual std::string Purpose()
5496     {
5497         return "Verify that data created by Compute Shader can be used as an input to glDrawArrayIndirect";
5498     }
5499 
Methodglcts::__anon91df61990111::CComputeShaderArray5500     virtual std::string Method()
5501     {
5502         return "1. Create data by Compute Shader" NL "2. Use data as input to glDrawArrayIndirect" NL
5503                "3. Verify results";
5504     }
5505 
PassCriteriaglcts::__anon91df61990111::CComputeShaderArray5506     virtual std::string PassCriteria()
5507     {
5508         return "The test will pass if no OpenGL errors reported";
5509     }
5510 
CComputeShaderArrayglcts::__anon91df61990111::CComputeShaderArray5511     CComputeShaderArray() : CComputeBase(DRAW_ARRAYS)
5512     {
5513     }
5514 
Runglcts::__anon91df61990111::CComputeShaderArray5515     virtual long Run()
5516     {
5517         return CComputeBase::Run<api>();
5518     }
5519 };
5520 
5521 template <typename api>
5522 struct CComputeShaderElements : public CComputeBase
5523 {
Titleglcts::__anon91df61990111::CComputeShaderElements5524     virtual std::string Title()
5525     {
5526         return "Compute Shader: glDrawElementsIndirect";
5527     }
5528 
Purposeglcts::__anon91df61990111::CComputeShaderElements5529     virtual std::string Purpose()
5530     {
5531         return "Verify that data created by Compute Shader can be used as an input to glDrawElementsIndirect";
5532     }
5533 
Methodglcts::__anon91df61990111::CComputeShaderElements5534     virtual std::string Method()
5535     {
5536         return "1. Create data by Compute Shader" NL "2. Use data as input to glDrawElementsIndirect" NL
5537                "3. Verify results";
5538     }
5539 
PassCriteriaglcts::__anon91df61990111::CComputeShaderElements5540     virtual std::string PassCriteria()
5541     {
5542         return "The test will pass if no OpenGL errors reported";
5543     }
5544 
CComputeShaderElementsglcts::__anon91df61990111::CComputeShaderElements5545     CComputeShaderElements() : CComputeBase(DRAW_ELEMENTS)
5546     {
5547     }
5548 
Runglcts::__anon91df61990111::CComputeShaderElements5549     virtual long Run()
5550     {
5551         return CComputeBase::Run<api>();
5552     }
5553 };
5554 
5555 template <typename api>
5556 class CPrimitiveRestartElements : public DrawIndirectBase
5557 {
5558 public:
Title()5559     virtual std::string Title()
5560     {
5561         return "Primitive restart - glDrawElementsIndirect";
5562     }
5563 
Purpose()5564     virtual std::string Purpose()
5565     {
5566         return "Verify that primitive restart works correctly with glDrawElementsIndirect";
5567     }
5568 
Method()5569     virtual std::string Method()
5570     {
5571         return "1. Define primitives using VBO" NL "2. Draw primitives using glDrawElementsIndirect" NL
5572                "3. Verify results";
5573     }
5574 
PassCriteria()5575     virtual std::string PassCriteria()
5576     {
5577         return "The test will pass if no OpenGL errors reported";
5578     }
5579 
Setup()5580     virtual long Setup()
5581     {
5582         glClear(GL_COLOR_BUFFER_BIT);
5583         return NO_ERROR;
5584     }
5585 
5586     int PrimitiveRestartIndex();
5587 
5588     void EnablePrimitiveRestart();
5589 
5590     void DisablePrimitiveRestart();
5591 
Run()5592     virtual long Run()
5593     {
5594         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
5595         if (!_program)
5596         {
5597             return ERROR;
5598         }
5599         glUseProgram(_program);
5600 
5601         CColorArray coords1;
5602         TriangleStipGen(coords1, -1.0f, 1.0f, -1.0, -0.5, 2);
5603 
5604         CColorArray coords2;
5605         TriangleStipGen(coords2, -1.0f, 1.0f, 0.5, 1.0, 4);
5606 
5607         glGenVertexArrays(1, &_vao);
5608         glBindVertexArray(_vao);
5609 
5610         glGenBuffers(1, &_buffer);
5611         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
5612 
5613         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords1.size() + coords2.size()) * sizeof(coords1[0]), NULL,
5614                      GL_STREAM_DRAW);
5615         glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(coords1.size() * sizeof(coords1[0])), &coords1[0]);
5616         glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(coords1.size() * sizeof(coords1[0])),
5617                         (GLsizeiptr)(coords2.size() * sizeof(coords2[0])), &coords2[0]);
5618         glVertexAttribPointer(0, sizeof(coords1[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords1[0]), 0);
5619         glEnableVertexAttribArray(0);
5620 
5621         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
5622         indirectElements.count                       = static_cast<GLuint>(coords1.size() + coords2.size() + 1);
5623         indirectElements.primCount                   = static_cast<GLuint>((coords1.size() + coords2.size()) / 2);
5624 
5625         CElementArray elements;
5626         for (size_t i = 0; i < coords1.size(); ++i)
5627         {
5628             elements.push_back(static_cast<GLuint>(i));
5629         }
5630 
5631         elements.push_back(PrimitiveRestartIndex());
5632         for (size_t i = 0; i < coords2.size(); ++i)
5633         {
5634             elements.push_back(static_cast<GLuint>(coords1.size() + i));
5635         }
5636 
5637         glGenBuffers(1, &_bufferIndirect);
5638         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
5639         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
5640 
5641         glGenBuffers(1, &_ebo);
5642         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
5643         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
5644                      GL_STATIC_DRAW);
5645 
5646         EnablePrimitiveRestart();
5647 
5648         glDrawElementsIndirect(GL_TRIANGLE_STRIP, GL_UNSIGNED_INT, 0);
5649 
5650         CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 4, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
5651         CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f));
5652         CColorArray bufferTest1(getWindowWidth() * getWindowHeight() / 4, tcu::Vec4(0.0f));
5653         CColorArray bufferTest2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f));
5654 
5655         DIResult result;
5656         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 4, &bufferTest1[0]);
5657         result.sub_result(BuffersCompare(bufferTest1, getWindowWidth(), getWindowHeight() / 4, bufferRef1,
5658                                          getWindowWidth(), getWindowHeight() / 4));
5659         // height = 2 * (getWindowHeight() / 4)  to avoid border pixels
5660         // in case the height is not a multiple of 4.
5661         ReadPixelsFloat<api>(0, (getWindowHeight() + 3) / 4, getWindowWidth(), 2 * (getWindowHeight() / 4),
5662                              &bufferTest2[0]);
5663         result.sub_result(BuffersCompare(bufferTest2, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
5664                                          getWindowWidth(), 2 * (getWindowHeight() / 4)));
5665 
5666         ReadPixelsFloat<api>(0, (getWindowHeight() * 3 + 3) / 4, getWindowWidth(), getWindowHeight() / 4,
5667                              &bufferTest1[0]);
5668         result.sub_result(BuffersCompare(bufferTest1, getWindowWidth(), getWindowHeight() / 4, bufferRef1,
5669                                          getWindowWidth(), getWindowHeight() / 4));
5670 
5671         return result.code();
5672     }
5673 
Cleanup()5674     virtual long Cleanup()
5675     {
5676 
5677         DisablePrimitiveRestart();
5678         glDisableVertexAttribArray(0);
5679         glUseProgram(0);
5680         glDeleteProgram(_program);
5681         glDeleteVertexArrays(1, &_vao);
5682         glDeleteBuffers(1, &_buffer);
5683         glDeleteBuffers(1, &_ebo);
5684         glDeleteBuffers(1, &_bufferIndirect);
5685         return NO_ERROR;
5686     }
5687 
5688 private:
TriangleStipGen(CColorArray & coords,float widthStart,float widthEnd,float heightStart,float heightEnd,unsigned int primNum)5689     void TriangleStipGen(CColorArray &coords, float widthStart, float widthEnd, float heightStart, float heightEnd,
5690                          unsigned int primNum)
5691     {
5692         float widthStep  = (widthEnd - widthStart) / static_cast<float>(primNum);
5693         float heightStep = (heightEnd - heightStart) / static_cast<float>(primNum);
5694         for (unsigned int i = 0; i < primNum; ++i)
5695         {
5696             float heightOffset = heightStart + heightStep * static_cast<float>(i);
5697             for (unsigned int j = 0; j < primNum; ++j)
5698             {
5699                 float widthOffset = widthStart + widthStep * static_cast<float>(j);
5700 
5701                 coords.push_back(tcu::Vec4(widthOffset, heightOffset, 0.0f, 1.0f));
5702                 coords.push_back(tcu::Vec4(widthOffset, heightOffset + heightStep, 0.0f, 1.0f));
5703                 coords.push_back(tcu::Vec4(widthOffset + widthStep, heightOffset, 0.0f, 1.0f));
5704                 coords.push_back(tcu::Vec4(widthOffset + widthStep, heightOffset + heightStep, 0.0f, 1.0f));
5705             }
5706         }
5707     }
5708     GLuint _program;
5709     GLuint _vao, _buffer, _ebo, _bufferIndirect;
5710 };
5711 
5712 template <>
PrimitiveRestartIndex()5713 int CPrimitiveRestartElements<test_api::ES3>::PrimitiveRestartIndex()
5714 {
5715     return 0xffffffff;
5716 }
5717 
5718 template <>
PrimitiveRestartIndex()5719 int CPrimitiveRestartElements<test_api::GL>::PrimitiveRestartIndex()
5720 {
5721     return 3432432;
5722 }
5723 
5724 template <>
DisablePrimitiveRestart()5725 void CPrimitiveRestartElements<test_api::ES3>::DisablePrimitiveRestart()
5726 {
5727     glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
5728 }
5729 
5730 template <>
DisablePrimitiveRestart()5731 void CPrimitiveRestartElements<test_api::GL>::DisablePrimitiveRestart()
5732 {
5733     glDisable(GL_PRIMITIVE_RESTART);
5734 }
5735 
5736 template <>
EnablePrimitiveRestart()5737 void CPrimitiveRestartElements<test_api::ES3>::EnablePrimitiveRestart()
5738 {
5739     glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
5740 }
5741 
5742 template <>
EnablePrimitiveRestart()5743 void CPrimitiveRestartElements<test_api::GL>::EnablePrimitiveRestart()
5744 {
5745     glPrimitiveRestartIndex(PrimitiveRestartIndex());
5746     glEnable(GL_PRIMITIVE_RESTART);
5747 }
5748 
5749 template <typename api>
5750 struct CNegativeZeroBufferArray : public DrawIndirectBase
5751 {
Titleglcts::__anon91df61990111::CNegativeZeroBufferArray5752     virtual std::string Title()
5753     {
5754         return "Negative: no indirect buffer/parameter - glDrawArrayIndirect";
5755     }
5756 
Purposeglcts::__anon91df61990111::CNegativeZeroBufferArray5757     virtual std::string Purpose()
5758     {
5759         return "Verify that a driver sets error and no driver crash occurred";
5760     }
5761 
Methodglcts::__anon91df61990111::CNegativeZeroBufferArray5762     virtual std::string Method()
5763     {
5764         return "Call glDrawArrayIndirect";
5765     }
5766 
PassCriteriaglcts::__anon91df61990111::CNegativeZeroBufferArray5767     virtual std::string PassCriteria()
5768     {
5769         return "The test will pass if OpenGL errors reported and no driver crash occurred";
5770     }
5771 
Setupglcts::__anon91df61990111::CNegativeZeroBufferArray5772     virtual long Setup()
5773     {
5774         glClear(GL_COLOR_BUFFER_BIT);
5775         return NO_ERROR;
5776     }
5777 
Runglcts::__anon91df61990111::CNegativeZeroBufferArray5778     virtual long Run()
5779     {
5780         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
5781         if (!_program)
5782         {
5783             return ERROR;
5784         }
5785         glUseProgram(_program);
5786 
5787         CColorArray coords;
5788         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
5789 
5790         glGenVertexArrays(1, &_vao);
5791         glBindVertexArray(_vao);
5792 
5793         glGenBuffers(1, &_buffer);
5794         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
5795         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
5796 
5797         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
5798         glEnableVertexAttribArray(0);
5799 
5800         glDrawArraysIndirect(GL_TRIANGLES, 0);
5801         DIResult result;
5802         if (glGetError() != GL_INVALID_OPERATION)
5803         {
5804             result.error() << "Invalid error code returned by a driver";
5805         }
5806 
5807         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
5808         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
5809 
5810         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
5811         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
5812                                          getWindowHeight()));
5813 
5814         return result.code();
5815     }
5816 
Cleanupglcts::__anon91df61990111::CNegativeZeroBufferArray5817     virtual long Cleanup()
5818     {
5819         glDisableVertexAttribArray(0);
5820         glUseProgram(0);
5821         glDeleteProgram(_program);
5822         glDeleteVertexArrays(1, &_vao);
5823         glDeleteBuffers(1, &_buffer);
5824         return NO_ERROR;
5825     }
5826 
5827 private:
5828     GLuint _program;
5829     GLuint _vao, _buffer;
5830 };
5831 
5832 template <typename api>
5833 struct CNegativeZeroBufferElements : public DrawIndirectBase
5834 {
Titleglcts::__anon91df61990111::CNegativeZeroBufferElements5835     virtual std::string Title()
5836     {
5837         return "Negative: no indirect buffer/parameter - glDrawElementsIndirect";
5838     }
5839 
Purposeglcts::__anon91df61990111::CNegativeZeroBufferElements5840     virtual std::string Purpose()
5841     {
5842         return "Verify that a driver sets error and no driver crash occurred";
5843     }
5844 
Methodglcts::__anon91df61990111::CNegativeZeroBufferElements5845     virtual std::string Method()
5846     {
5847         return "Call glDrawElementsIndirect";
5848     }
5849 
PassCriteriaglcts::__anon91df61990111::CNegativeZeroBufferElements5850     virtual std::string PassCriteria()
5851     {
5852         return "The test will pass if OpenGL errors reported and no driver crash occurred";
5853     }
5854 
Setupglcts::__anon91df61990111::CNegativeZeroBufferElements5855     virtual long Setup()
5856     {
5857         glClear(GL_COLOR_BUFFER_BIT);
5858         return NO_ERROR;
5859     }
5860 
Runglcts::__anon91df61990111::CNegativeZeroBufferElements5861     virtual long Run()
5862     {
5863         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
5864         if (!_program)
5865         {
5866             return ERROR;
5867         }
5868         glUseProgram(_program);
5869 
5870         CColorArray coords;
5871         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
5872 
5873         glGenVertexArrays(1, &_vao);
5874         glBindVertexArray(_vao);
5875 
5876         glGenBuffers(1, &_buffer);
5877         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
5878 
5879         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
5880         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
5881         glEnableVertexAttribArray(0);
5882 
5883         CElementArray elements(coords.size(), 0);
5884         for (size_t i = 0; i < elements.size(); ++i)
5885         {
5886             elements[i] = static_cast<GLuint>(i);
5887         }
5888 
5889         glGenBuffers(1, &_ebo);
5890         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
5891         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
5892                      GL_STATIC_DRAW);
5893 
5894         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
5895 
5896         DIResult result;
5897         if (glGetError() != GL_INVALID_OPERATION)
5898         {
5899             result.error() << "Invalid error code returned by a driver";
5900         }
5901 
5902         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
5903         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
5904 
5905         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
5906         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
5907                                          getWindowHeight()));
5908 
5909         return result.code();
5910     }
5911 
Cleanupglcts::__anon91df61990111::CNegativeZeroBufferElements5912     virtual long Cleanup()
5913     {
5914         glDisableVertexAttribArray(0);
5915         glUseProgram(0);
5916         glDeleteProgram(_program);
5917         glDeleteVertexArrays(1, &_vao);
5918         glDeleteBuffers(1, &_buffer);
5919         glDeleteBuffers(1, &_ebo);
5920         return NO_ERROR;
5921     }
5922 
5923 private:
5924     GLuint _program;
5925     GLuint _vao, _buffer, _ebo;
5926 };
5927 
5928 template <typename api>
5929 struct CNegativeInvalidModeArray : public DrawIndirectBase
5930 {
Titleglcts::__anon91df61990111::CNegativeInvalidModeArray5931     virtual std::string Title()
5932     {
5933         return "Negative: invalid mode - glDrawArrayIndirect";
5934     }
5935 
Purposeglcts::__anon91df61990111::CNegativeInvalidModeArray5936     virtual std::string Purpose()
5937     {
5938         return "Verify that a driver sets error and no driver crash occurred";
5939     }
5940 
Methodglcts::__anon91df61990111::CNegativeInvalidModeArray5941     virtual std::string Method()
5942     {
5943         return "Set invalid mode to glDrawArrayIndirect";
5944     }
5945 
PassCriteriaglcts::__anon91df61990111::CNegativeInvalidModeArray5946     virtual std::string PassCriteria()
5947     {
5948         return "The test will pass if OpenGL errors reported and no driver crash occurred";
5949     }
5950 
Setupglcts::__anon91df61990111::CNegativeInvalidModeArray5951     virtual long Setup()
5952     {
5953         glClear(GL_COLOR_BUFFER_BIT);
5954         return NO_ERROR;
5955     }
5956 
Runglcts::__anon91df61990111::CNegativeInvalidModeArray5957     virtual long Run()
5958     {
5959         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
5960         if (!_program)
5961         {
5962             return ERROR;
5963         }
5964         glUseProgram(_program);
5965 
5966         CColorArray coords;
5967         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
5968 
5969         glGenVertexArrays(1, &_vao);
5970         glBindVertexArray(_vao);
5971 
5972         glGenBuffers(1, &_buffer);
5973         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
5974 
5975         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
5976         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
5977         glEnableVertexAttribArray(0);
5978 
5979         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
5980         indirectArrays.count                     = static_cast<GLuint>(coords.size());
5981         indirectArrays.primCount                 = 1;
5982 
5983         glGenBuffers(1, &_bufferIndirect);
5984         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
5985         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
5986 
5987         glDrawArraysIndirect(GL_FLOAT, 0);
5988 
5989         DIResult result;
5990         if (glGetError() != GL_INVALID_ENUM)
5991         {
5992             result.error() << "Invalid error code returned by a driver for GL_FLOAT as mode";
5993         }
5994 
5995         glDrawArraysIndirect(GL_STATIC_DRAW, 0);
5996         if (glGetError() != GL_INVALID_ENUM)
5997         {
5998             result.error() << "Invalid error code returned by a driver for GL_STATIC_DRAW as mode";
5999         }
6000 
6001         glDrawArraysIndirect(GL_DRAW_INDIRECT_BUFFER, 0);
6002         if (glGetError() != GL_INVALID_ENUM)
6003         {
6004             result.error() << "Invalid error code returned by a driver for GL_DRAW_INDIRECT_BUFFER as mode";
6005         }
6006 
6007         glDrawArraysIndirect(GL_INVALID_ENUM, 0);
6008         if (glGetError() != GL_INVALID_ENUM)
6009         {
6010             result.error() << "Invalid error code returned by a driver for GL_INVALID_ENUM as mode";
6011         }
6012 
6013         glDrawArraysIndirect(GL_COLOR_BUFFER_BIT, 0);
6014         if (glGetError() != GL_INVALID_ENUM)
6015         {
6016             result.error() << "Invalid error code returned by a driver for GL_COLOR_BUFFER_BIT as mode";
6017         }
6018 
6019         glDrawArraysIndirect(GL_ARRAY_BUFFER, 0);
6020         if (glGetError() != GL_INVALID_ENUM)
6021         {
6022             result.error() << "Invalid error code returned by a driver for GL_ARRAY_BUFFER as mode";
6023         }
6024 
6025         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6026         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6027 
6028         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6029         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6030                                          getWindowHeight()));
6031 
6032         return result.code();
6033     }
6034 
Cleanupglcts::__anon91df61990111::CNegativeInvalidModeArray6035     virtual long Cleanup()
6036     {
6037         glDisableVertexAttribArray(0);
6038         glUseProgram(0);
6039         glDeleteProgram(_program);
6040         glDeleteVertexArrays(1, &_vao);
6041         glDeleteBuffers(1, &_buffer);
6042         glDeleteBuffers(1, &_bufferIndirect);
6043         return NO_ERROR;
6044     }
6045 
6046 private:
6047     GLuint _program;
6048     GLuint _vao, _buffer, _bufferIndirect;
6049 };
6050 
6051 template <typename api>
6052 struct CNegativeInvalidModeElements : public DrawIndirectBase
6053 {
Titleglcts::__anon91df61990111::CNegativeInvalidModeElements6054     virtual std::string Title()
6055     {
6056         return "Negative: invalid mode - glDrawElementsIndirect";
6057     }
6058 
Purposeglcts::__anon91df61990111::CNegativeInvalidModeElements6059     virtual std::string Purpose()
6060     {
6061         return "Verify that a driver sets error and no driver crash occurred";
6062     }
6063 
Methodglcts::__anon91df61990111::CNegativeInvalidModeElements6064     virtual std::string Method()
6065     {
6066         return "Set invalid mode to glDrawElemenetsIndirect";
6067     }
6068 
PassCriteriaglcts::__anon91df61990111::CNegativeInvalidModeElements6069     virtual std::string PassCriteria()
6070     {
6071         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6072     }
6073 
Setupglcts::__anon91df61990111::CNegativeInvalidModeElements6074     virtual long Setup()
6075     {
6076         glClear(GL_COLOR_BUFFER_BIT);
6077         return NO_ERROR;
6078     }
6079 
Runglcts::__anon91df61990111::CNegativeInvalidModeElements6080     virtual long Run()
6081     {
6082         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6083         if (!_program)
6084         {
6085             return ERROR;
6086         }
6087         glUseProgram(_program);
6088 
6089         CColorArray coords;
6090         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6091 
6092         glGenVertexArrays(1, &_vao);
6093         glBindVertexArray(_vao);
6094 
6095         glGenBuffers(1, &_buffer);
6096         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
6097 
6098         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
6099         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
6100         glEnableVertexAttribArray(0);
6101 
6102         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
6103         indirectElements.count                       = static_cast<GLuint>(coords.size());
6104         indirectElements.primCount                   = 1;
6105 
6106         CElementArray elements(coords.size(), 0);
6107         for (size_t i = 0; i < elements.size(); ++i)
6108         {
6109             elements[i] = static_cast<GLuint>(i);
6110         }
6111 
6112         glGenBuffers(1, &_bufferIndirect);
6113         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6114         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
6115 
6116         glGenBuffers(1, &_ebo);
6117         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
6118         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
6119                      GL_STATIC_DRAW);
6120 
6121         DIResult result;
6122         glDrawElementsIndirect(GL_INVALID_ENUM, GL_UNSIGNED_INT, 0);
6123         if (glGetError() != GL_INVALID_ENUM)
6124         {
6125             result.error() << "Invalid error code returned by a driver for GL_FLOAT as mode";
6126         }
6127 
6128         glDrawElementsIndirect(GL_UNSIGNED_INT, GL_UNSIGNED_INT, 0);
6129         if (glGetError() != GL_INVALID_ENUM)
6130         {
6131             result.error() << "Invalid error code returned by a driver for GL_UNSIGNED_INT as mode";
6132         }
6133 
6134         glDrawElementsIndirect(GL_ELEMENT_ARRAY_BUFFER, GL_UNSIGNED_INT, 0);
6135         if (glGetError() != GL_INVALID_ENUM)
6136         {
6137             result.error() << "Invalid error code returned by a driver for GL_ELEMENT_ARRAY_BUFFER as mode";
6138         }
6139 
6140         glDrawElementsIndirect(GL_FASTEST, GL_UNSIGNED_INT, 0);
6141         if (glGetError() != GL_INVALID_ENUM)
6142         {
6143             result.error() << "Invalid error code returned by a driver for GL_FASTEST as mode";
6144         }
6145 
6146         glDrawElementsIndirect(GL_PACK_ALIGNMENT, GL_UNSIGNED_INT, 0);
6147         if (glGetError() != GL_INVALID_ENUM)
6148         {
6149             result.error() << "Invalid error code returned by a driver for GL_PACK_ALIGNMENT as mode";
6150         }
6151 
6152         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6153         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6154 
6155         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6156         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6157                                          getWindowHeight()));
6158 
6159         return result.code();
6160     }
6161 
Cleanupglcts::__anon91df61990111::CNegativeInvalidModeElements6162     virtual long Cleanup()
6163     {
6164         glDisableVertexAttribArray(0);
6165         glUseProgram(0);
6166         glDeleteProgram(_program);
6167         glDeleteVertexArrays(1, &_vao);
6168         glDeleteBuffers(1, &_buffer);
6169         glDeleteBuffers(1, &_ebo);
6170         glDeleteBuffers(1, &_bufferIndirect);
6171         return NO_ERROR;
6172     }
6173 
6174 private:
6175     GLuint _program;
6176     GLuint _vao, _buffer, _ebo, _bufferIndirect;
6177 };
6178 
6179 template <typename api>
6180 struct CNegativeNoVAOArrays : public DrawIndirectBase
6181 {
Titleglcts::__anon91df61990111::CNegativeNoVAOArrays6182     virtual std::string Title()
6183     {
6184         return "Negative: no VAO - glDrawArraysIndirect";
6185     }
6186 
Purposeglcts::__anon91df61990111::CNegativeNoVAOArrays6187     virtual std::string Purpose()
6188     {
6189         return "Verify that a driver sets error and no driver crash occurred";
6190     }
6191 
Methodglcts::__anon91df61990111::CNegativeNoVAOArrays6192     virtual std::string Method()
6193     {
6194         return "Use glDrawArraysIndirect with default VAO";
6195     }
6196 
PassCriteriaglcts::__anon91df61990111::CNegativeNoVAOArrays6197     virtual std::string PassCriteria()
6198     {
6199         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6200     }
6201 
Setupglcts::__anon91df61990111::CNegativeNoVAOArrays6202     virtual long Setup()
6203     {
6204         glClear(GL_COLOR_BUFFER_BIT);
6205         return NO_ERROR;
6206     }
6207 
Runglcts::__anon91df61990111::CNegativeNoVAOArrays6208     virtual long Run()
6209     {
6210         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6211         if (!_program)
6212         {
6213             return ERROR;
6214         }
6215         glUseProgram(_program);
6216 
6217         CColorArray coords;
6218         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6219 
6220         glGenBuffers(1, &_buffer);
6221         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
6222 
6223         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
6224         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
6225         glEnableVertexAttribArray(0);
6226 
6227         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
6228         indirectArrays.count                     = static_cast<GLuint>(coords.size());
6229         indirectArrays.primCount                 = 1;
6230 
6231         glGenBuffers(1, &_bufferIndirect);
6232         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6233         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
6234 
6235         DIResult result;
6236         glDrawArraysIndirect(GL_TRIANGLES, 0);
6237         if (glGetError() != GL_INVALID_OPERATION)
6238         {
6239             result.error() << "Invalid error code returned by a driver";
6240         }
6241 
6242         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
6243             glDisableVertexAttribArray(0);
6244 
6245         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6246         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6247 
6248         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6249         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6250                                          getWindowHeight()));
6251 
6252         return result.code();
6253     }
6254 
Cleanupglcts::__anon91df61990111::CNegativeNoVAOArrays6255     virtual long Cleanup()
6256     {
6257 
6258         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
6259             glDisableVertexAttribArray(0);
6260 
6261         glUseProgram(0);
6262         glDeleteProgram(_program);
6263         glDeleteBuffers(1, &_buffer);
6264         glDeleteBuffers(1, &_bufferIndirect);
6265         return NO_ERROR;
6266     }
6267 
6268 private:
6269     GLuint _program;
6270     GLuint _buffer, _ebo, _bufferIndirect;
6271 };
6272 
6273 template <typename api>
6274 struct CNegativeNoVAOElements : public DrawIndirectBase
6275 {
Titleglcts::__anon91df61990111::CNegativeNoVAOElements6276     virtual std::string Title()
6277     {
6278         return "Negative: no VAO - glDrawElementsIndirect";
6279     }
6280 
Purposeglcts::__anon91df61990111::CNegativeNoVAOElements6281     virtual std::string Purpose()
6282     {
6283         return "Verify that a driver sets error and no driver crash occurred";
6284     }
6285 
Methodglcts::__anon91df61990111::CNegativeNoVAOElements6286     virtual std::string Method()
6287     {
6288         return "Use glDrawElemenetsIndirect with default VAO";
6289     }
6290 
PassCriteriaglcts::__anon91df61990111::CNegativeNoVAOElements6291     virtual std::string PassCriteria()
6292     {
6293         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6294     }
6295 
Setupglcts::__anon91df61990111::CNegativeNoVAOElements6296     virtual long Setup()
6297     {
6298         glClear(GL_COLOR_BUFFER_BIT);
6299         return NO_ERROR;
6300     }
6301 
Runglcts::__anon91df61990111::CNegativeNoVAOElements6302     virtual long Run()
6303     {
6304         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6305         if (!_program)
6306         {
6307             return ERROR;
6308         }
6309         glUseProgram(_program);
6310 
6311         CColorArray coords;
6312         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6313 
6314         glGenBuffers(1, &_buffer);
6315         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
6316 
6317         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
6318         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
6319         glEnableVertexAttribArray(0);
6320 
6321         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
6322         indirectElements.count                       = static_cast<GLuint>(coords.size());
6323         indirectElements.primCount                   = 1;
6324 
6325         CElementArray elements(coords.size(), 0);
6326         for (size_t i = 0; i < elements.size(); ++i)
6327         {
6328             elements[i] = static_cast<GLuint>(i);
6329         }
6330 
6331         glGenBuffers(1, &_bufferIndirect);
6332         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6333         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
6334 
6335         glGenBuffers(1, &_ebo);
6336         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
6337         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
6338                      GL_STATIC_DRAW);
6339 
6340         DIResult result;
6341         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
6342         if (glGetError() != GL_INVALID_OPERATION)
6343         {
6344             result.error() << "Invalid error code returned by a driver";
6345         }
6346 
6347         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
6348             glDisableVertexAttribArray(0);
6349 
6350         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6351         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6352 
6353         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6354         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6355                                          getWindowHeight()));
6356 
6357         return result.code();
6358     }
6359 
Cleanupglcts::__anon91df61990111::CNegativeNoVAOElements6360     virtual long Cleanup()
6361     {
6362         glUseProgram(0);
6363         glDeleteProgram(_program);
6364         glDeleteBuffers(1, &_buffer);
6365         glDeleteBuffers(1, &_ebo);
6366         glDeleteBuffers(1, &_bufferIndirect);
6367         return NO_ERROR;
6368     }
6369 
6370 private:
6371     GLuint _program;
6372     GLuint _buffer, _ebo, _bufferIndirect;
6373 };
6374 
6375 template <typename api>
6376 struct CNegativeNoVBOArrays : public DrawIndirectBase
6377 {
Titleglcts::__anon91df61990111::CNegativeNoVBOArrays6378     virtual std::string Title()
6379     {
6380         return "Negative: no VBO - glDrawArraysIndirect";
6381     }
6382 
Purposeglcts::__anon91df61990111::CNegativeNoVBOArrays6383     virtual std::string Purpose()
6384     {
6385         return "Verify that a driver sets error and no driver crash occurred";
6386     }
6387 
Methodglcts::__anon91df61990111::CNegativeNoVBOArrays6388     virtual std::string Method()
6389     {
6390         return "Use glDrawArraysIndirect with enabled vertex array, that has no VBO bound";
6391     }
6392 
PassCriteriaglcts::__anon91df61990111::CNegativeNoVBOArrays6393     virtual std::string PassCriteria()
6394     {
6395         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6396     }
6397 
Setupglcts::__anon91df61990111::CNegativeNoVBOArrays6398     virtual long Setup()
6399     {
6400         glClear(GL_COLOR_BUFFER_BIT);
6401         return NO_ERROR;
6402     }
6403 
Runglcts::__anon91df61990111::CNegativeNoVBOArrays6404     virtual long Run()
6405     {
6406         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6407         if (!_program)
6408         {
6409             return ERROR;
6410         }
6411         glUseProgram(_program);
6412 
6413         CColorArray coords;
6414         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6415 
6416         glGenVertexArrays(1, &_vao);
6417         glBindVertexArray(_vao);
6418         glEnableVertexAttribArray(0);
6419 
6420         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
6421         indirectArrays.count                     = static_cast<GLuint>(coords.size());
6422         indirectArrays.primCount                 = 1;
6423 
6424         glGenBuffers(1, &_bufferIndirect);
6425         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6426         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
6427 
6428         DIResult result;
6429         glDrawArraysIndirect(GL_TRIANGLES, 0);
6430         if (glGetError() != GL_INVALID_OPERATION)
6431         {
6432             result.error() << "Invalid error code returned by a driver";
6433         }
6434 
6435         glDisableVertexAttribArray(0);
6436 
6437         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6438         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6439 
6440         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6441         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6442                                          getWindowHeight()));
6443 
6444         return result.code();
6445     }
6446 
Cleanupglcts::__anon91df61990111::CNegativeNoVBOArrays6447     virtual long Cleanup()
6448     {
6449         glDisableVertexAttribArray(0);
6450         glUseProgram(0);
6451         glDeleteProgram(_program);
6452         glDeleteVertexArrays(1, &_vao);
6453         glDeleteBuffers(1, &_bufferIndirect);
6454         return NO_ERROR;
6455     }
6456 
6457 private:
6458     GLuint _program;
6459     GLuint _vao, _ebo, _bufferIndirect;
6460 };
6461 
6462 template <typename api>
6463 struct CNegativeNoVBOElements : public DrawIndirectBase
6464 {
Titleglcts::__anon91df61990111::CNegativeNoVBOElements6465     virtual std::string Title()
6466     {
6467         return "Negative: no VBO - glDrawElementsIndirect";
6468     }
6469 
Purposeglcts::__anon91df61990111::CNegativeNoVBOElements6470     virtual std::string Purpose()
6471     {
6472         return "Verify that a driver sets error and no driver crash occurred";
6473     }
6474 
Methodglcts::__anon91df61990111::CNegativeNoVBOElements6475     virtual std::string Method()
6476     {
6477         return "Use glDrawElementsIndirect with enabled vertex array, that has no VBO bound";
6478     }
6479 
PassCriteriaglcts::__anon91df61990111::CNegativeNoVBOElements6480     virtual std::string PassCriteria()
6481     {
6482         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6483     }
6484 
Setupglcts::__anon91df61990111::CNegativeNoVBOElements6485     virtual long Setup()
6486     {
6487         glClear(GL_COLOR_BUFFER_BIT);
6488         return NO_ERROR;
6489     }
6490 
Runglcts::__anon91df61990111::CNegativeNoVBOElements6491     virtual long Run()
6492     {
6493 
6494         api::ES_Only();
6495 
6496         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6497         if (!_program)
6498         {
6499             return ERROR;
6500         }
6501         glUseProgram(_program);
6502 
6503         CColorArray coords;
6504         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6505 
6506         glGenVertexArrays(1, &_vao);
6507         glBindVertexArray(_vao);
6508         glEnableVertexAttribArray(0);
6509         glEnableVertexAttribArray(0);
6510 
6511         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
6512         indirectElements.count                       = static_cast<GLuint>(coords.size());
6513         indirectElements.primCount                   = 1;
6514 
6515         CElementArray elements(coords.size(), 0);
6516         for (size_t i = 0; i < elements.size(); ++i)
6517         {
6518             elements[i] = static_cast<GLuint>(i);
6519         }
6520 
6521         glGenBuffers(1, &_bufferIndirect);
6522         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6523         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
6524 
6525         glGenBuffers(1, &_ebo);
6526         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
6527         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
6528                      GL_STATIC_DRAW);
6529 
6530         DIResult result;
6531         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
6532         if (glGetError() != GL_INVALID_OPERATION)
6533         {
6534             result.error() << "Invalid error code returned by a driver";
6535         }
6536 
6537         glDisableVertexAttribArray(0);
6538 
6539         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6540         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6541 
6542         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6543         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6544                                          getWindowHeight()));
6545 
6546         return result.code();
6547     }
6548 
Cleanupglcts::__anon91df61990111::CNegativeNoVBOElements6549     virtual long Cleanup()
6550     {
6551         glDisableVertexAttribArray(0);
6552         glUseProgram(0);
6553         glDeleteProgram(_program);
6554         glDeleteVertexArrays(1, &_vao);
6555         glDeleteBuffers(1, &_ebo);
6556         glDeleteBuffers(1, &_bufferIndirect);
6557         return NO_ERROR;
6558     }
6559 
6560 private:
6561     GLuint _program;
6562     GLuint _vao, _ebo, _bufferIndirect;
6563 };
6564 
6565 template <typename api>
6566 struct CNegativeBufferMappedArray : public DrawIndirectBase
6567 {
Titleglcts::__anon91df61990111::CNegativeBufferMappedArray6568     virtual std::string Title()
6569     {
6570         return "Negative: buffer mapped - glDrawArraysIndirect";
6571     }
6572 
Purposeglcts::__anon91df61990111::CNegativeBufferMappedArray6573     virtual std::string Purpose()
6574     {
6575         return "Verify that a driver sets error and no driver crash occurred";
6576     }
6577 
Methodglcts::__anon91df61990111::CNegativeBufferMappedArray6578     virtual std::string Method()
6579     {
6580         return "1. Create and bind buffer" NL "2. Map buffer" NL "3. Call glDrawArrayIndirect";
6581     }
6582 
PassCriteriaglcts::__anon91df61990111::CNegativeBufferMappedArray6583     virtual std::string PassCriteria()
6584     {
6585         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6586     }
6587 
Setupglcts::__anon91df61990111::CNegativeBufferMappedArray6588     virtual long Setup()
6589     {
6590         glClear(GL_COLOR_BUFFER_BIT);
6591         return NO_ERROR;
6592     }
6593 
Runglcts::__anon91df61990111::CNegativeBufferMappedArray6594     virtual long Run()
6595     {
6596         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6597         if (!_program)
6598         {
6599             return ERROR;
6600         }
6601         glUseProgram(_program);
6602 
6603         CColorArray coords;
6604         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6605 
6606         glGenVertexArrays(1, &_vao);
6607         glBindVertexArray(_vao);
6608 
6609         glGenBuffers(1, &_buffer);
6610         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
6611 
6612         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
6613         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
6614         glEnableVertexAttribArray(0);
6615 
6616         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
6617         indirectArrays.count                     = static_cast<GLuint>(coords.size());
6618         indirectArrays.primCount                 = 1;
6619 
6620         glGenBuffers(1, &_bufferIndirect);
6621         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6622         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
6623 
6624         DIResult result;
6625         void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawArraysIndirectCommand), GL_MAP_READ_BIT);
6626         if (buf == 0)
6627         {
6628             result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
6629         }
6630 
6631         glDrawArraysIndirect(GL_TRIANGLES, 0);
6632 
6633         GLenum error = glGetError();
6634         if (error == GL_INVALID_OPERATION)
6635         {
6636             //GL error: nothing is rendered
6637             CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6638             CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6639 
6640             ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6641             result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef,
6642                                              getWindowWidth(), getWindowHeight()));
6643         }
6644         else if (error == GL_NO_ERROR)
6645         {
6646             //No GL error: undefined
6647         }
6648         else
6649         {
6650             result.error() << "Invalid error code returned by a driver";
6651         }
6652 
6653         if (buf)
6654         {
6655             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE)
6656             {
6657                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
6658             }
6659             buf = 0;
6660         }
6661 
6662         return result.code();
6663     }
6664 
Cleanupglcts::__anon91df61990111::CNegativeBufferMappedArray6665     virtual long Cleanup()
6666     {
6667         glDisableVertexAttribArray(0);
6668         glUseProgram(0);
6669         glDeleteProgram(_program);
6670         glDeleteVertexArrays(1, &_vao);
6671         glDeleteBuffers(1, &_buffer);
6672         glDeleteBuffers(1, &_bufferIndirect);
6673         return NO_ERROR;
6674     }
6675 
6676 private:
6677     GLuint _program;
6678     GLuint _vao, _buffer, _bufferIndirect;
6679 };
6680 
6681 template <typename api>
6682 struct CNegativeBufferMappedElements : public DrawIndirectBase
6683 {
Titleglcts::__anon91df61990111::CNegativeBufferMappedElements6684     virtual std::string Title()
6685     {
6686         return "Negative: buffer mapped - glDrawElementsIndirect";
6687     }
6688 
Purposeglcts::__anon91df61990111::CNegativeBufferMappedElements6689     virtual std::string Purpose()
6690     {
6691         return "Verify that a driver sets error and no driver crash occurred";
6692     }
6693 
Methodglcts::__anon91df61990111::CNegativeBufferMappedElements6694     virtual std::string Method()
6695     {
6696         return "1. Create and bind buffer" NL "2. Map buffer" NL "3. Call glDrawElementsIndirect";
6697     }
6698 
PassCriteriaglcts::__anon91df61990111::CNegativeBufferMappedElements6699     virtual std::string PassCriteria()
6700     {
6701         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6702     }
6703 
Setupglcts::__anon91df61990111::CNegativeBufferMappedElements6704     virtual long Setup()
6705     {
6706         glClear(GL_COLOR_BUFFER_BIT);
6707         return NO_ERROR;
6708     }
6709 
Runglcts::__anon91df61990111::CNegativeBufferMappedElements6710     virtual long Run()
6711     {
6712         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6713         if (!_program)
6714         {
6715             return ERROR;
6716         }
6717         glUseProgram(_program);
6718 
6719         CColorArray coords;
6720         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6721 
6722         glGenVertexArrays(1, &_vao);
6723         glBindVertexArray(_vao);
6724 
6725         glGenBuffers(1, &_buffer);
6726         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
6727 
6728         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
6729         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
6730         glEnableVertexAttribArray(0);
6731 
6732         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
6733         indirectElements.count                       = static_cast<GLuint>(coords.size());
6734         indirectElements.primCount                   = 1;
6735 
6736         CElementArray elements(coords.size(), 0);
6737         for (size_t i = 0; i < elements.size(); ++i)
6738         {
6739             elements[i] = static_cast<GLuint>(i);
6740         }
6741 
6742         glGenBuffers(1, &_bufferIndirect);
6743         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6744         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
6745 
6746         glGenBuffers(1, &_ebo);
6747         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
6748         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
6749                      GL_STATIC_DRAW);
6750 
6751         DIResult result;
6752         void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT);
6753         if (buf == 0)
6754         {
6755             result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL";
6756         }
6757 
6758         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
6759 
6760         GLenum error = glGetError();
6761         if (error == GL_INVALID_OPERATION)
6762         {
6763             //GL error: nothing is rendered
6764             CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6765             CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6766 
6767             ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6768             result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef,
6769                                              getWindowWidth(), getWindowHeight()));
6770         }
6771         else if (error == GL_NO_ERROR)
6772         {
6773             //No GL error: undefined
6774         }
6775         else
6776         {
6777             result.error() << "Invalid error code returned by a driver";
6778         }
6779 
6780         if (buf)
6781         {
6782             if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE)
6783             {
6784                 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
6785             }
6786             buf = 0;
6787         }
6788 
6789         return result.code();
6790     }
6791 
Cleanupglcts::__anon91df61990111::CNegativeBufferMappedElements6792     virtual long Cleanup()
6793     {
6794         glDisableVertexAttribArray(0);
6795         glUseProgram(0);
6796         glDeleteProgram(_program);
6797         glDeleteVertexArrays(1, &_vao);
6798         glDeleteBuffers(1, &_buffer);
6799         glDeleteBuffers(1, &_ebo);
6800         glDeleteBuffers(1, &_bufferIndirect);
6801         return NO_ERROR;
6802     }
6803 
6804 private:
6805     GLuint _program;
6806     GLuint _vao, _buffer, _ebo, _bufferIndirect;
6807 };
6808 
6809 template <typename api>
6810 struct CNegativeDataWrongElements : public DrawIndirectBase
6811 {
Titleglcts::__anon91df61990111::CNegativeDataWrongElements6812     virtual std::string Title()
6813     {
6814         return "Negative: invalid type - glDrawElementsIndirect";
6815     }
6816 
Purposeglcts::__anon91df61990111::CNegativeDataWrongElements6817     virtual std::string Purpose()
6818     {
6819         return "Verify that a driver sets error and no driver crash occurred";
6820     }
6821 
Methodglcts::__anon91df61990111::CNegativeDataWrongElements6822     virtual std::string Method()
6823     {
6824         return "1. Bind non-zero buffer" NL "2. Call glDrawElementsIndirect with invalid type";
6825     }
6826 
PassCriteriaglcts::__anon91df61990111::CNegativeDataWrongElements6827     virtual std::string PassCriteria()
6828     {
6829         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6830     }
6831 
Setupglcts::__anon91df61990111::CNegativeDataWrongElements6832     virtual long Setup()
6833     {
6834         glClear(GL_COLOR_BUFFER_BIT);
6835         return NO_ERROR;
6836     }
6837 
Runglcts::__anon91df61990111::CNegativeDataWrongElements6838     virtual long Run()
6839     {
6840         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
6841         if (!_program)
6842         {
6843             return ERROR;
6844         }
6845         glUseProgram(_program);
6846 
6847         CColorArray coords;
6848         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6849 
6850         glGenVertexArrays(1, &_vao);
6851         glBindVertexArray(_vao);
6852 
6853         glGenBuffers(1, &_buffer);
6854         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
6855 
6856         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
6857         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
6858         glEnableVertexAttribArray(0);
6859 
6860         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
6861         indirectElements.count                       = static_cast<GLuint>(coords.size());
6862         indirectElements.primCount                   = 1;
6863 
6864         CElementArray elements(coords.size(), 0);
6865         for (size_t i = 0; i < elements.size(); ++i)
6866         {
6867             elements[i] = static_cast<GLuint>(i);
6868         }
6869 
6870         glGenBuffers(1, &_bufferIndirect);
6871         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
6872         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
6873 
6874         glGenBuffers(1, &_ebo);
6875         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
6876         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
6877                      GL_STATIC_DRAW);
6878 
6879         DIResult result;
6880 
6881         glDrawElementsIndirect(GL_TRIANGLES, GL_FLOAT, 0);
6882         if (glGetError() != GL_INVALID_ENUM)
6883         {
6884             result.error() << "Invalid error code returned by a driver for GL_FLOAT type";
6885         }
6886 
6887         glDrawElementsIndirect(GL_TRIANGLES, GL_INT, 0);
6888         if (glGetError() != GL_INVALID_ENUM)
6889         {
6890             result.error() << "Invalid error code returned by a driver for GL_INT type";
6891         }
6892 
6893         glDrawElementsIndirect(GL_TRIANGLES, GL_STATIC_DRAW, 0);
6894         if (glGetError() != GL_INVALID_ENUM)
6895         {
6896             result.error() << "Invalid error code returned by a driver for GL_STATIC_DRAW type";
6897         }
6898 
6899         glDrawElementsIndirect(GL_TRIANGLES, GL_SHORT, 0);
6900         if (glGetError() != GL_INVALID_ENUM)
6901         {
6902             result.error() << "Invalid error code returned by a driver for GL_SHORT type";
6903         }
6904 
6905         glDrawElementsIndirect(GL_TRIANGLES, GL_BYTE, 0);
6906         if (glGetError() != GL_INVALID_ENUM)
6907         {
6908             result.error() << "Invalid error code returned by a driver for GL_BYTE type";
6909         }
6910 
6911         glDrawElementsIndirect(GL_TRIANGLES, GL_DOUBLE, 0);
6912         if (glGetError() != GL_INVALID_ENUM)
6913         {
6914             result.error() << "Invalid error code returned by a driver for GL_DOUBLE type";
6915         }
6916 
6917         glDrawElementsIndirect(GL_TRIANGLES, GL_INVALID_ENUM, 0);
6918         if (glGetError() != GL_INVALID_ENUM)
6919         {
6920             result.error() << "Invalid error code returned by a driver for GL_INVALID_ENUM type";
6921         }
6922 
6923         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
6924         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
6925 
6926         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
6927         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
6928                                          getWindowHeight()));
6929 
6930         return result.code();
6931     }
6932 
Cleanupglcts::__anon91df61990111::CNegativeDataWrongElements6933     virtual long Cleanup()
6934     {
6935         glDisableVertexAttribArray(0);
6936         glUseProgram(0);
6937         glDeleteProgram(_program);
6938         glDeleteVertexArrays(1, &_vao);
6939         glDeleteBuffers(1, &_buffer);
6940         glDeleteBuffers(1, &_ebo);
6941         glDeleteBuffers(1, &_bufferIndirect);
6942         return NO_ERROR;
6943     }
6944 
6945 private:
6946     GLuint _program;
6947     GLuint _vao, _buffer, _ebo, _bufferIndirect;
6948 };
6949 
6950 template <typename api>
6951 class CNegativeGshArray : public DrawIndirectBase
6952 {
6953 public:
Title()6954     virtual std::string Title()
6955     {
6956         return "Negative: incompatible the input primitive type of gsh - glDrawArrayIndirect";
6957     }
6958 
Purpose()6959     virtual std::string Purpose()
6960     {
6961         return "Verify that a driver sets error and no driver crash occurred";
6962     }
6963 
Method()6964     virtual std::string Method()
6965     {
6966         return "1. Bind non-zero buffer" NL "2. Set data" NL "3. Set wrong geometry shader" NL
6967                "4. Call glDrawArrayIndirect";
6968     }
6969 
PassCriteria()6970     virtual std::string PassCriteria()
6971     {
6972         return "The test will pass if OpenGL errors reported and no driver crash occurred";
6973     }
6974 
Setup()6975     virtual long Setup()
6976     {
6977         glClear(GL_COLOR_BUFFER_BIT);
6978         return NO_ERROR;
6979     }
6980 
Run()6981     virtual long Run()
6982     {
6983         _program = CreateProgram(Vsh(), Gsh(), Fsh(), true);
6984         if (!_program)
6985         {
6986             return ERROR;
6987         }
6988         glUseProgram(_program);
6989 
6990         CColorArray coords;
6991         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
6992 
6993         glGenVertexArrays(1, &_vao);
6994         glBindVertexArray(_vao);
6995 
6996         glGenBuffers(1, &_buffer);
6997         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
6998 
6999         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
7000         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
7001         glEnableVertexAttribArray(0);
7002 
7003         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
7004         indirectArrays.count                     = static_cast<GLuint>(coords.size());
7005         indirectArrays.primCount                 = 1;
7006         indirectArrays.first                     = 0;
7007         indirectArrays.reservedMustBeZero        = 0;
7008 
7009         glGenBuffers(1, &_bufferIndirect);
7010         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7011         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
7012 
7013         DIResult result;
7014 
7015         glDrawArraysIndirect(GL_POINTS, 0);
7016         if (glGetError() != GL_INVALID_OPERATION)
7017         {
7018             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7019         }
7020 
7021         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
7022         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
7023 
7024         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
7025         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
7026                                          getWindowHeight()));
7027 
7028         return result.code();
7029     }
7030 
Cleanup()7031     virtual long Cleanup()
7032     {
7033         glDisableVertexAttribArray(0);
7034         glUseProgram(0);
7035         glDeleteProgram(_program);
7036         glDeleteVertexArrays(1, &_vao);
7037         glDeleteBuffers(1, &_buffer);
7038         glDeleteBuffers(1, &_bufferIndirect);
7039         return NO_ERROR;
7040     }
7041 
7042 private:
Vsh()7043     std::string Vsh()
7044     {
7045         return "#version 150" NL "in vec4 coords;" NL "void main() {" NL "  gl_Position = coords;" NL "}";
7046     }
7047 
Gsh()7048     std::string Gsh()
7049     {
7050         return "#version 150" NL "layout(triangles) in;" NL "layout(triangle_strip, max_vertices = 10) out;" NL
7051                "void main() {" NL " for (int i=0; i<gl_in.length(); ++i) {" NL
7052                "     gl_Position = gl_in[i].gl_Position;" NL "     EmitVertex();" NL " }" NL "}";
7053     }
7054 
Fsh()7055     std::string Fsh()
7056     {
7057         return "#version 140" NL "out vec4 outColor;" NL "void main() {" NL
7058                "  outColor = vec4(0.1f, 0.2f, 0.3f, 1.0f);" NL "}";
7059     }
7060     GLuint _program;
7061     GLuint _vao, _buffer, _bufferIndirect;
7062 };
7063 
7064 template <typename api>
7065 class CNegativeGshElements : public DrawIndirectBase
7066 {
7067 public:
Title()7068     virtual std::string Title()
7069     {
7070         return "Negative: incompatible the input primitive type of gsh - glDrawElementsIndirect";
7071     }
7072 
Purpose()7073     virtual std::string Purpose()
7074     {
7075         return "Verify that a driver sets error and no driver crash occurred";
7076     }
7077 
Method()7078     virtual std::string Method()
7079     {
7080         return "1. Bind non-zero buffer" NL "2. Set data" NL "3. Set wrong geometry shader" NL
7081                "4. Call glDrawElementsIndirect";
7082     }
7083 
PassCriteria()7084     virtual std::string PassCriteria()
7085     {
7086         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7087     }
7088 
Setup()7089     virtual long Setup()
7090     {
7091         glClear(GL_COLOR_BUFFER_BIT);
7092         return NO_ERROR;
7093     }
7094 
Run()7095     virtual long Run()
7096     {
7097         _program = CreateProgram(Vsh(), Gsh(), Fsh(), true);
7098         if (!_program)
7099         {
7100             return ERROR;
7101         }
7102         glUseProgram(_program);
7103 
7104         CColorArray coords;
7105         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
7106 
7107         glGenVertexArrays(1, &_vao);
7108         glBindVertexArray(_vao);
7109 
7110         glGenBuffers(1, &_buffer);
7111         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7112 
7113         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
7114         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
7115         glEnableVertexAttribArray(0);
7116 
7117         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
7118         indirectElements.count                       = static_cast<GLuint>(coords.size());
7119         indirectElements.primCount                   = 1;
7120 
7121         CElementArray elements(coords.size(), 0);
7122         for (size_t i = 0; i < elements.size(); ++i)
7123         {
7124             elements[i] = static_cast<GLuint>(i);
7125         }
7126 
7127         glGenBuffers(1, &_bufferIndirect);
7128         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7129         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
7130 
7131         glGenBuffers(1, &_ebo);
7132         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
7133         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
7134                      GL_STATIC_DRAW);
7135 
7136         DIResult result;
7137 
7138         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
7139         if (glGetError() != GL_INVALID_OPERATION)
7140         {
7141             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7142         }
7143 
7144         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
7145         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
7146 
7147         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
7148         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
7149                                          getWindowHeight()));
7150 
7151         return result.code();
7152     }
7153 
Cleanup()7154     virtual long Cleanup()
7155     {
7156         glDisableVertexAttribArray(0);
7157         glUseProgram(0);
7158         glDeleteProgram(_program);
7159         glDeleteVertexArrays(1, &_vao);
7160         glDeleteBuffers(1, &_buffer);
7161         glDeleteBuffers(1, &_ebo);
7162         glDeleteBuffers(1, &_bufferIndirect);
7163         return NO_ERROR;
7164     }
7165 
7166 private:
Vsh()7167     std::string Vsh()
7168     {
7169         return "#version 150" NL "in vec4 coords;" NL "void main() {" NL "  gl_Position = coords;" NL "}";
7170     }
7171 
Gsh()7172     std::string Gsh()
7173     {
7174         return "#version 150" NL "layout(lines) in;" NL "layout(line_strip, max_vertices = 10) out;" NL
7175                "void main() {" NL " for (int i=0; i<gl_in.length(); ++i) {" NL
7176                "     gl_Position = gl_in[i].gl_Position;" NL "     EmitVertex();" NL " }" NL "}";
7177     }
7178 
Fsh()7179     std::string Fsh()
7180     {
7181         return "#version 140" NL "out vec4 outColor;" NL "void main() {" NL
7182                "  outColor = vec4(0.1f, 0.2f, 0.3f, 1.0f);" NL "}";
7183     }
7184     int _program;
7185     GLuint _vao, _buffer, _ebo, _bufferIndirect;
7186 };
7187 
7188 template <typename api>
7189 struct CNegativeInvalidSizeArrays : public DrawIndirectBase
7190 {
7191     struct TWrongStructure1
7192     {
7193         GLuint count;
7194         GLuint primCount;
7195     };
7196 
7197     struct TWrongStructure2
7198     {
7199         GLfloat count;
7200         GLuint primCount;
7201     };
7202 
Titleglcts::__anon91df61990111::CNegativeInvalidSizeArrays7203     virtual std::string Title()
7204     {
7205         return "Negative: wrong structure - glDrawArrayIndirect";
7206     }
7207 
Purposeglcts::__anon91df61990111::CNegativeInvalidSizeArrays7208     virtual std::string Purpose()
7209     {
7210         return "Verify that a driver sets error and no driver crash occurred";
7211     }
7212 
Methodglcts::__anon91df61990111::CNegativeInvalidSizeArrays7213     virtual std::string Method()
7214     {
7215         return "Call glDrawArrayIndirect with wrong structure";
7216     }
7217 
PassCriteriaglcts::__anon91df61990111::CNegativeInvalidSizeArrays7218     virtual std::string PassCriteria()
7219     {
7220         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7221     }
7222 
Setupglcts::__anon91df61990111::CNegativeInvalidSizeArrays7223     virtual long Setup()
7224     {
7225         glClear(GL_COLOR_BUFFER_BIT);
7226         return NO_ERROR;
7227     }
7228 
Runglcts::__anon91df61990111::CNegativeInvalidSizeArrays7229     virtual long Run()
7230     {
7231         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
7232         if (!_program)
7233         {
7234             return ERROR;
7235         }
7236         glUseProgram(_program);
7237 
7238         CColorArray coords;
7239         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
7240 
7241         glGenVertexArrays(1, &_vao);
7242         glBindVertexArray(_vao);
7243 
7244         glGenBuffers(1, &_buffer);
7245         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7246 
7247         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
7248         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
7249         glEnableVertexAttribArray(0);
7250 
7251         TWrongStructure1 indirectArrays = {0, 0};
7252         indirectArrays.count            = static_cast<GLuint>(coords.size());
7253         indirectArrays.primCount        = 1;
7254 
7255         glGenBuffers(1, &_bufferIndirect);
7256         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7257         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure1), &indirectArrays, GL_STATIC_DRAW);
7258 
7259         DIResult result;
7260 
7261         glDrawArraysIndirect(GL_TRIANGLES, 0);
7262         if (glGetError() != GL_INVALID_OPERATION)
7263         {
7264             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7265         }
7266 
7267         glDeleteBuffers(1, &_bufferIndirect);
7268 
7269         TWrongStructure2 indirectArrays2 = {0, 0};
7270         indirectArrays2.count            = static_cast<GLfloat>(coords.size());
7271         indirectArrays2.primCount        = 1;
7272 
7273         glGenBuffers(1, &_bufferIndirect);
7274         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7275         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure2), &indirectArrays2, GL_STATIC_DRAW);
7276 
7277         glDrawArraysIndirect(GL_TRIANGLES, 0);
7278         if (glGetError() != GL_INVALID_OPERATION)
7279         {
7280             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7281         }
7282 
7283         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
7284         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
7285 
7286         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
7287         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
7288                                          getWindowHeight()));
7289 
7290         return result.code();
7291     }
7292 
Cleanupglcts::__anon91df61990111::CNegativeInvalidSizeArrays7293     virtual long Cleanup()
7294     {
7295         glDisableVertexAttribArray(0);
7296         glUseProgram(0);
7297         glDeleteProgram(_program);
7298         glDeleteVertexArrays(1, &_vao);
7299         glDeleteBuffers(1, &_buffer);
7300         glDeleteBuffers(1, &_bufferIndirect);
7301         return NO_ERROR;
7302     }
7303 
7304 private:
7305     GLuint _program;
7306     GLuint _vao, _buffer, _bufferIndirect;
7307 };
7308 
7309 template <typename api>
7310 struct CNegativeInvalidSizeElements : public DrawIndirectBase
7311 {
7312     struct TWrongStructure
7313     {
7314         GLfloat count;
7315         GLuint primCount;
7316     };
7317 
Titleglcts::__anon91df61990111::CNegativeInvalidSizeElements7318     virtual std::string Title()
7319     {
7320         return "Negative: wrong structure - glDrawElementsIndirect";
7321     }
7322 
Purposeglcts::__anon91df61990111::CNegativeInvalidSizeElements7323     virtual std::string Purpose()
7324     {
7325         return "Verify that a driver sets error and no driver crash occurred";
7326     }
7327 
Methodglcts::__anon91df61990111::CNegativeInvalidSizeElements7328     virtual std::string Method()
7329     {
7330         return "Call glDrawElementsIndirect with wrong structure";
7331     }
7332 
PassCriteriaglcts::__anon91df61990111::CNegativeInvalidSizeElements7333     virtual std::string PassCriteria()
7334     {
7335         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7336     }
7337 
Setupglcts::__anon91df61990111::CNegativeInvalidSizeElements7338     virtual long Setup()
7339     {
7340         glClear(GL_COLOR_BUFFER_BIT);
7341         return NO_ERROR;
7342     }
7343 
Runglcts::__anon91df61990111::CNegativeInvalidSizeElements7344     virtual long Run()
7345     {
7346         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
7347         if (!_program)
7348         {
7349             return ERROR;
7350         }
7351         glUseProgram(_program);
7352 
7353         CColorArray coords;
7354         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
7355 
7356         glGenVertexArrays(1, &_vao);
7357         glBindVertexArray(_vao);
7358 
7359         glGenBuffers(1, &_buffer);
7360         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7361 
7362         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
7363         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
7364         glEnableVertexAttribArray(0);
7365 
7366         DrawArraysIndirectCommand indirectElements = {0, 0, 0, 0};
7367         indirectElements.count                     = static_cast<GLuint>(coords.size());
7368         indirectElements.primCount                 = 1;
7369 
7370         CElementArray elements(coords.size(), 0);
7371         for (size_t i = 0; i < elements.size(); ++i)
7372         {
7373             elements[i] = static_cast<GLuint>(i);
7374         }
7375 
7376         glGenBuffers(1, &_bufferIndirect);
7377         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7378         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectElements, GL_STATIC_DRAW);
7379 
7380         glGenBuffers(1, &_ebo);
7381         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
7382         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
7383                      GL_STATIC_DRAW);
7384 
7385         DIResult result;
7386 
7387         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
7388         if (glGetError() != GL_INVALID_OPERATION)
7389         {
7390             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7391         }
7392 
7393         TWrongStructure indirectElements2 = {0, 0};
7394         indirectElements2.count           = static_cast<GLfloat>(coords.size());
7395         indirectElements2.primCount       = 1;
7396 
7397         glDeleteBuffers(1, &_bufferIndirect);
7398         glGenBuffers(1, &_bufferIndirect);
7399         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7400         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure), &indirectElements2, GL_STATIC_DRAW);
7401 
7402         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
7403         if (glGetError() != GL_INVALID_OPERATION)
7404         {
7405             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7406         }
7407 
7408         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
7409         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
7410 
7411         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
7412         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
7413                                          getWindowHeight()));
7414 
7415         return result.code();
7416     }
7417 
Cleanupglcts::__anon91df61990111::CNegativeInvalidSizeElements7418     virtual long Cleanup()
7419     {
7420         glDisableVertexAttribArray(0);
7421         glUseProgram(0);
7422         glDeleteProgram(_program);
7423         glDeleteVertexArrays(1, &_vao);
7424         glDeleteBuffers(1, &_buffer);
7425         glDeleteBuffers(1, &_ebo);
7426         glDeleteBuffers(1, &_bufferIndirect);
7427         return NO_ERROR;
7428     }
7429 
7430 private:
7431     GLuint _program;
7432     GLuint _vao, _buffer, _ebo, _bufferIndirect;
7433 };
7434 
7435 template <typename api>
7436 struct CNegativeStructureWrongOffsetArray : public DrawIndirectBase
7437 {
Titleglcts::__anon91df61990111::CNegativeStructureWrongOffsetArray7438     virtual std::string Title()
7439     {
7440         return "Negative: wrong offset - glDrawArrayIndirect";
7441     }
7442 
Purposeglcts::__anon91df61990111::CNegativeStructureWrongOffsetArray7443     virtual std::string Purpose()
7444     {
7445         return "Verify that a driver sets error and no driver crash occurred";
7446     }
7447 
Methodglcts::__anon91df61990111::CNegativeStructureWrongOffsetArray7448     virtual std::string Method()
7449     {
7450         return "Call glDrawArrayIndirect with wrong offset";
7451     }
7452 
PassCriteriaglcts::__anon91df61990111::CNegativeStructureWrongOffsetArray7453     virtual std::string PassCriteria()
7454     {
7455         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7456     }
7457 
Setupglcts::__anon91df61990111::CNegativeStructureWrongOffsetArray7458     virtual long Setup()
7459     {
7460         glClear(GL_COLOR_BUFFER_BIT);
7461         return NO_ERROR;
7462     }
7463 
Runglcts::__anon91df61990111::CNegativeStructureWrongOffsetArray7464     virtual long Run()
7465     {
7466         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
7467         if (!_program)
7468         {
7469             return ERROR;
7470         }
7471         glUseProgram(_program);
7472 
7473         CColorArray coords;
7474         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
7475 
7476         glGenVertexArrays(1, &_vao);
7477         glBindVertexArray(_vao);
7478 
7479         glGenBuffers(1, &_buffer);
7480         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7481 
7482         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
7483         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
7484         glEnableVertexAttribArray(0);
7485 
7486         DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
7487         indirectArrays.count                     = static_cast<GLuint>(coords.size());
7488         indirectArrays.primCount                 = 1;
7489 
7490         glGenBuffers(1, &_bufferIndirect);
7491         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7492         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
7493 
7494         DIResult result;
7495 
7496         glDrawArraysIndirect(GL_TRIANGLES, (void *)(sizeof(DrawArraysIndirectCommand) * 2));
7497         if (glGetError() != GL_INVALID_OPERATION)
7498         {
7499             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7500         }
7501 
7502         glDrawArraysIndirect(GL_TRIANGLES, (void *)(sizeof(GLuint)));
7503         if (glGetError() != GL_INVALID_OPERATION)
7504         {
7505             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7506         }
7507 
7508         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
7509         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
7510 
7511         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
7512         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
7513                                          getWindowHeight()));
7514 
7515         return result.code();
7516     }
7517 
Cleanupglcts::__anon91df61990111::CNegativeStructureWrongOffsetArray7518     virtual long Cleanup()
7519     {
7520         glDisableVertexAttribArray(0);
7521         glUseProgram(0);
7522         glDeleteProgram(_program);
7523         glDeleteVertexArrays(1, &_vao);
7524         glDeleteBuffers(1, &_buffer);
7525         glDeleteBuffers(1, &_bufferIndirect);
7526         return NO_ERROR;
7527     }
7528 
7529 private:
7530     GLuint _program;
7531     GLuint _vao, _buffer, _bufferIndirect;
7532 };
7533 
7534 template <typename api>
7535 struct CNegativeStructureWrongOffsetElements : public DrawIndirectBase
7536 {
Titleglcts::__anon91df61990111::CNegativeStructureWrongOffsetElements7537     virtual std::string Title()
7538     {
7539         return "Negative: wrong offset - glDrawElementsIndirect";
7540     }
7541 
Purposeglcts::__anon91df61990111::CNegativeStructureWrongOffsetElements7542     virtual std::string Purpose()
7543     {
7544         return "Verify that a driver sets error and no driver crash occurred";
7545     }
7546 
Methodglcts::__anon91df61990111::CNegativeStructureWrongOffsetElements7547     virtual std::string Method()
7548     {
7549         return "Call glDrawElementsIndirect with wrong structure";
7550     }
7551 
PassCriteriaglcts::__anon91df61990111::CNegativeStructureWrongOffsetElements7552     virtual std::string PassCriteria()
7553     {
7554         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7555     }
7556 
Setupglcts::__anon91df61990111::CNegativeStructureWrongOffsetElements7557     virtual long Setup()
7558     {
7559         glClear(GL_COLOR_BUFFER_BIT);
7560         return NO_ERROR;
7561     }
7562 
Runglcts::__anon91df61990111::CNegativeStructureWrongOffsetElements7563     virtual long Run()
7564     {
7565         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
7566         if (!_program)
7567         {
7568             return ERROR;
7569         }
7570         glUseProgram(_program);
7571 
7572         CColorArray coords;
7573         PrimitiveGen(GL_TRIANGLES, 8, 8, coords);
7574 
7575         glGenVertexArrays(1, &_vao);
7576         glBindVertexArray(_vao);
7577 
7578         glGenBuffers(1, &_buffer);
7579         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7580 
7581         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
7582         glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
7583         glEnableVertexAttribArray(0);
7584 
7585         DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
7586         indirectElements.count                       = static_cast<GLuint>(coords.size());
7587         indirectElements.primCount                   = 1;
7588 
7589         CElementArray elements(coords.size(), 0);
7590         for (size_t i = 0; i < elements.size(); ++i)
7591         {
7592             elements[i] = static_cast<GLuint>(i);
7593         }
7594 
7595         glGenBuffers(1, &_bufferIndirect);
7596         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7597         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);
7598 
7599         glGenBuffers(1, &_ebo);
7600         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
7601         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
7602                      GL_STATIC_DRAW);
7603 
7604         DIResult result;
7605 
7606         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void *)(sizeof(DrawElementsIndirectCommand) * 2));
7607         if (glGetError() != GL_INVALID_OPERATION)
7608         {
7609             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7610         }
7611 
7612         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void *)(sizeof(GLuint)));
7613         if (glGetError() != GL_INVALID_OPERATION)
7614         {
7615             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7616         }
7617 
7618         CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
7619         CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));
7620 
7621         ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
7622         result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
7623                                          getWindowHeight()));
7624 
7625         return result.code();
7626     }
7627 
Cleanupglcts::__anon91df61990111::CNegativeStructureWrongOffsetElements7628     virtual long Cleanup()
7629     {
7630         glDisableVertexAttribArray(0);
7631         glUseProgram(0);
7632         glDeleteProgram(_program);
7633         glDeleteVertexArrays(1, &_vao);
7634         glDeleteBuffers(1, &_buffer);
7635         glDeleteBuffers(1, &_ebo);
7636         glDeleteBuffers(1, &_bufferIndirect);
7637         return NO_ERROR;
7638     }
7639 
7640 private:
7641     GLuint _program;
7642     GLuint _vao, _buffer, _ebo, _bufferIndirect;
7643 };
7644 
7645 template <typename api>
7646 struct CNegativeUnalignedOffset : public DrawIndirectBase
7647 {
Titleglcts::__anon91df61990111::CNegativeUnalignedOffset7648     virtual std::string Title()
7649     {
7650         return "Negative: unaligned offset - glDrawElementsIndirect and glDrawArraysIndirect";
7651     }
7652 
Purposeglcts::__anon91df61990111::CNegativeUnalignedOffset7653     virtual std::string Purpose()
7654     {
7655         return "Verify that a driver sets error and no system/driver crash occurred";
7656     }
7657 
Methodglcts::__anon91df61990111::CNegativeUnalignedOffset7658     virtual std::string Method()
7659     {
7660         return "Call with unaligned offset (1, 3, 1023)";
7661     }
7662 
PassCriteriaglcts::__anon91df61990111::CNegativeUnalignedOffset7663     virtual std::string PassCriteria()
7664     {
7665         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7666     }
7667 
Runglcts::__anon91df61990111::CNegativeUnalignedOffset7668     virtual long Run()
7669     {
7670         _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
7671         if (!_program)
7672         {
7673             return ERROR;
7674         }
7675         glUseProgram(_program);
7676 
7677         glGenVertexArrays(1, &_vao);
7678         glBindVertexArray(_vao);
7679 
7680         std::vector<GLuint> zarro(4096, 0);
7681 
7682         glGenBuffers(1, &_buffer);
7683         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7684         glBufferData(GL_ARRAY_BUFFER, 4096, &zarro[0], GL_STREAM_DRAW);
7685         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
7686         glEnableVertexAttribArray(0);
7687 
7688         glGenBuffers(1, &_bufferIndirect);
7689         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7690         glBufferData(GL_DRAW_INDIRECT_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);
7691 
7692         glGenBuffers(1, &_ebo);
7693         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
7694         glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);
7695 
7696         DIResult result;
7697 
7698         int offsets[] = {1, 3, 1023};
7699         for (size_t i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++)
7700         {
7701             glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, reinterpret_cast<void *>((uintptr_t)offsets[i]));
7702             if (glGetError() != GL_INVALID_VALUE)
7703             {
7704                 result.error() << "Invalid error code returned by a driver for GL_INVALID_VALUE type";
7705             }
7706             glDrawArraysIndirect(GL_TRIANGLES, reinterpret_cast<void *>((uintptr_t)offsets[i]));
7707             if (glGetError() != GL_INVALID_VALUE)
7708             {
7709                 result.error() << "Invalid error code returned by a driver for GL_INVALID_VALUE type";
7710             }
7711         }
7712 
7713         return result.code();
7714     }
7715 
Cleanupglcts::__anon91df61990111::CNegativeUnalignedOffset7716     virtual long Cleanup()
7717     {
7718         glDisableVertexAttribArray(0);
7719         glUseProgram(0);
7720         glDeleteProgram(_program);
7721         glDeleteVertexArrays(1, &_vao);
7722         glDeleteBuffers(1, &_buffer);
7723         glDeleteBuffers(1, &_ebo);
7724         glDeleteBuffers(1, &_bufferIndirect);
7725         return NO_ERROR;
7726     }
7727 
7728 private:
7729     GLuint _program;
7730     GLuint _vao, _buffer, _ebo, _bufferIndirect;
7731 };
7732 
7733 template <typename api>
7734 struct CNegativeXFB : public DrawIndirectBase
7735 {
Titleglcts::__anon91df61990111::CNegativeXFB7736     virtual std::string Title()
7737     {
7738         return "Negative: transform feedback active and not paused - glDrawElementsIndirect and glDrawArraysIndirect";
7739     }
7740 
Purposeglcts::__anon91df61990111::CNegativeXFB7741     virtual std::string Purpose()
7742     {
7743         return "Verify that a driver sets error and no system/driver crash occurred";
7744     }
7745 
Methodglcts::__anon91df61990111::CNegativeXFB7746     virtual std::string Method()
7747     {
7748         return "Call with transform feedback active";
7749     }
7750 
PassCriteriaglcts::__anon91df61990111::CNegativeXFB7751     virtual std::string PassCriteria()
7752     {
7753         return "The test will pass if OpenGL errors reported and no driver crash occurred";
7754     }
7755 
Runglcts::__anon91df61990111::CNegativeXFB7756     virtual long Run()
7757     {
7758         api::ES_Only();
7759 
7760         bool drawWithXFBAllowed = m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader");
7761 
7762         _program                 = CreateProgram(Vsh(), "", shaders::fshSimple<api>(), false);
7763         const GLchar *varyings[] = {"dataOut"};
7764         glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS);
7765         glLinkProgram(_program);
7766         if (!CheckProgram(_program))
7767         {
7768             return ERROR;
7769         }
7770         glUseProgram(_program);
7771 
7772         glGenVertexArrays(1, &_vao);
7773         glBindVertexArray(_vao);
7774 
7775         std::vector<GLuint> zarro(4096, 0);
7776 
7777         glGenBuffers(1, &_buffer);
7778         glBindBuffer(GL_ARRAY_BUFFER, _buffer);
7779         glBufferData(GL_ARRAY_BUFFER, 4096, &zarro[0], GL_STREAM_DRAW);
7780         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
7781         glEnableVertexAttribArray(0);
7782 
7783         glGenBuffers(1, &_bufferIndirect);
7784         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
7785         glBufferData(GL_DRAW_INDIRECT_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);
7786 
7787         glGenBuffers(1, &_ebo);
7788         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
7789         glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);
7790 
7791         glGenBuffers(1, &_xfb);
7792         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _xfb);
7793         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);
7794         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfb);
7795 
7796         DIResult result;
7797 
7798         //Without XFO
7799         glBeginTransformFeedback(GL_POINTS);
7800 
7801         glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, NULL);
7802         if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
7803         {
7804             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7805         }
7806         glDrawArraysIndirect(GL_POINTS, NULL);
7807         if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
7808         {
7809             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7810         }
7811         glEndTransformFeedback();
7812 
7813         //With XFO
7814         glGenTransformFeedbacks(1, &_xfo);
7815         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, _xfo);
7816         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfb);
7817         glBeginTransformFeedback(GL_POINTS);
7818         glPauseTransformFeedback();
7819         glResumeTransformFeedback();
7820 
7821         glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, NULL);
7822         if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
7823         {
7824             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7825         }
7826         glDrawArraysIndirect(GL_POINTS, NULL);
7827         if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
7828         {
7829             result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
7830         }
7831         glEndTransformFeedback();
7832 
7833         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
7834         return result.code();
7835     }
7836 
Cleanupglcts::__anon91df61990111::CNegativeXFB7837     virtual long Cleanup()
7838     {
7839         glDisableVertexAttribArray(0);
7840         glUseProgram(0);
7841         glDeleteProgram(_program);
7842         glDeleteVertexArrays(1, &_vao);
7843         glDeleteBuffers(1, &_buffer);
7844         glDeleteBuffers(1, &_ebo);
7845         glDeleteBuffers(1, &_bufferIndirect);
7846         glDeleteBuffers(1, &_xfb);
7847         glDeleteTransformFeedbacks(1, &_xfo);
7848         return NO_ERROR;
7849     }
7850 
Vshglcts::__anon91df61990111::CNegativeXFB7851     std::string Vsh()
7852     {
7853         return api::glslVer() + NL "out highp vec4 dataOut;" NL "in vec4 i_vertex;" NL "void main() {" NL
7854                                    "  dataOut = i_vertex;" NL "  gl_Position = i_vertex;" NL "}";
7855     }
7856 
7857 private:
7858     GLuint _program;
7859     GLuint _vao, _buffer, _ebo, _bufferIndirect, _xfo, _xfb;
7860 };
7861 
7862 } // namespace
DrawIndirectTestsGL40(glcts::Context & context)7863 DrawIndirectTestsGL40::DrawIndirectTestsGL40(glcts::Context &context) : TestCaseGroup(context, "draw_indirect", "")
7864 {
7865 }
7866 
~DrawIndirectTestsGL40(void)7867 DrawIndirectTestsGL40::~DrawIndirectTestsGL40(void)
7868 {
7869 }
7870 
init()7871 void DrawIndirectTestsGL40::init()
7872 {
7873     using namespace glcts;
7874 
7875     DILogger::setOutput(m_context.getTestContext().getLog());
7876 
7877     addChild(
7878         new TestSubcase(m_context, "basic-binding-default", TestSubcase::Create<CDefaultBindingPoint<test_api::GL>>));
7879     addChild(new TestSubcase(m_context, "basic-binding-zero", TestSubcase::Create<CZeroBindingPoint<test_api::GL>>));
7880     addChild(
7881         new TestSubcase(m_context, "basic-binding-single", TestSubcase::Create<CSingleBindingPoint<test_api::GL>>));
7882     addChild(new TestSubcase(m_context, "basic-binding-multi", TestSubcase::Create<CMultiBindingPoint<test_api::GL>>));
7883     addChild(
7884         new TestSubcase(m_context, "basic-binding-delete", TestSubcase::Create<CDeleteBindingPoint<test_api::GL>>));
7885 
7886     addChild(new TestSubcase(m_context, "basic-buffer-data", TestSubcase::Create<CBufferData<test_api::GL>>));
7887     addChild(new TestSubcase(m_context, "basic-buffer-subData", TestSubcase::Create<CBufferSubData<test_api::GL>>));
7888     addChild(new TestSubcase(m_context, "basic-buffer-unMap", TestSubcase::Create<CBufferMap<test_api::GL>>));
7889     addChild(
7890         new TestSubcase(m_context, "basic-buffer-getPointerv", TestSubcase::Create<CBufferGetPointerv<test_api::GL>>));
7891     addChild(new TestSubcase(m_context, "basic-buffer-mapRange", TestSubcase::Create<CBufferMapRange<test_api::GL>>));
7892     addChild(new TestSubcase(m_context, "basic-buffer-flushMappedRange",
7893                              TestSubcase::Create<CBufferFlushMappedRange<test_api::GL>>));
7894     addChild(
7895         new TestSubcase(m_context, "basic-buffer-copySubData", TestSubcase::Create<CBufferCopySubData<test_api::GL>>));
7896 
7897     addChild(new TestSubcase(m_context, "basic-drawArrays-singlePrimitive",
7898                              TestSubcase::Create<CVBODrawArraysSingle<test_api::GL>>));
7899     addChild(new TestSubcase(m_context, "basic-drawArrays-manyPrimitives",
7900                              TestSubcase::Create<CVBODrawArraysMany<test_api::GL>>));
7901     addChild(new TestSubcase(m_context, "basic-drawArrays-instancing",
7902                              TestSubcase::Create<CVBODrawArraysInstancing<test_api::GL>>));
7903     addChild(new TestSubcase(m_context, "basic-drawArrays-xfbPaused",
7904                              TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::GL>>));
7905     addChild(new TestSubcase(m_context, "basic-drawElements-singlePrimitive",
7906                              TestSubcase::Create<CVBODrawElementsSingle<test_api::GL>>));
7907     addChild(new TestSubcase(m_context, "basic-drawElements-manyPrimitives",
7908                              TestSubcase::Create<CVBODrawElementsMany<test_api::GL>>));
7909     addChild(new TestSubcase(m_context, "basic-drawElements-instancing",
7910                              TestSubcase::Create<CVBODrawElementsInstancing<test_api::GL>>));
7911     addChild(new TestSubcase(m_context, "basic-drawElements-xfbPaused",
7912                              TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::GL>>));
7913 
7914     addChild(new TestSubcase(m_context, "basic-drawArrays-simple",
7915                              TestSubcase::Create<CBufferIndirectDrawArraysSimple<test_api::GL>>));
7916     addChild(new TestSubcase(m_context, "basic-drawArrays-noFirst",
7917                              TestSubcase::Create<CBufferIndirectDrawArraysNoFirst<test_api::GL>>));
7918     addChild(new TestSubcase(m_context, "basic-drawArrays-bufferOffset",
7919                              TestSubcase::Create<CBufferIndirectDrawArraysOffset<test_api::GL>>));
7920     addChild(new TestSubcase(m_context, "basic-drawArrays-vertexIds",
7921                              TestSubcase::Create<CBufferIndirectDrawArraysVertexIds<test_api::GL>>));
7922     addChild(new TestSubcase(m_context, "basic-drawElements-simple",
7923                              TestSubcase::Create<CBufferIndirectDrawElementsSimple<test_api::GL>>));
7924     addChild(new TestSubcase(m_context, "basic-drawElements-noFirstIndex",
7925                              TestSubcase::Create<CBufferIndirectDrawElementsNoFirstIndex<test_api::GL>>));
7926     addChild(new TestSubcase(m_context, "basic-drawElements-basevertex",
7927                              TestSubcase::Create<CBufferIndirectDrawElementsNoBasevertex<test_api::GL>>));
7928     addChild(new TestSubcase(m_context, "basic-drawElements-bufferOffset",
7929                              TestSubcase::Create<CBufferIndirectDrawElementsOffset<test_api::GL>>));
7930     addChild(new TestSubcase(m_context, "basic-drawElements-vertexIds",
7931                              TestSubcase::Create<CBufferIndirectDrawElementsVertexIds<test_api::GL>>));
7932 
7933     addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_short",
7934                              TestSubcase::Create<CIndicesDataTypeUnsignedShort<test_api::GL>>));
7935     addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_byte",
7936                              TestSubcase::Create<CIndicesDataTypeUnsignedByte<test_api::GL>>));
7937 
7938     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-points",
7939                              TestSubcase::Create<CModeDrawArraysPoints<test_api::GL>>));
7940     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines",
7941                              TestSubcase::Create<CModeDrawArraysLines<test_api::GL>>));
7942     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip",
7943                              TestSubcase::Create<CModeDrawArraysLineStrip<test_api::GL>>));
7944     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_loop",
7945                              TestSubcase::Create<CModeDrawArraysLineLoop<test_api::GL>>));
7946     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip",
7947                              TestSubcase::Create<CModeDrawArraysTriangleStrip<test_api::GL>>));
7948     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_fan",
7949                              TestSubcase::Create<CModeDrawArraysTriangleFan<test_api::GL>>));
7950     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines_adjacency",
7951                              TestSubcase::Create<CModeDrawArraysLinesAdjacency<test_api::GL>>));
7952     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip_adjacency",
7953                              TestSubcase::Create<CModeDrawArraysLineStripAdjacency<test_api::GL>>));
7954     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangles_adjacency",
7955                              TestSubcase::Create<CModeDrawArraysTrianglesAdjacency<test_api::GL>>));
7956     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip_adjacency",
7957                              TestSubcase::Create<CModeDrawArraysTriangleStripAdjacency<test_api::GL>>));
7958 
7959     addChild(new TestSubcase(m_context, "basic-mode-drawElements-points",
7960                              TestSubcase::Create<CModeDrawElementsPoints<test_api::GL>>));
7961     addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines",
7962                              TestSubcase::Create<CModeDrawElementsLines<test_api::GL>>));
7963     addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip",
7964                              TestSubcase::Create<CModeDrawElementsLineStrip<test_api::GL>>));
7965     addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_loop",
7966                              TestSubcase::Create<CModeDrawElementsLineLoop<test_api::GL>>));
7967     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip",
7968                              TestSubcase::Create<CModeDrawElementsTriangleStrip<test_api::GL>>));
7969     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_fan",
7970                              TestSubcase::Create<CModeDrawElementsTriangleFan<test_api::GL>>));
7971     addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines_adjacency",
7972                              TestSubcase::Create<CModeDrawElementsLinesAdjacency<test_api::GL>>));
7973     addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip_adjacency",
7974                              TestSubcase::Create<CModeDrawElementsLineStripAdjacency<test_api::GL>>));
7975     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangles_adjacency",
7976                              TestSubcase::Create<CModeDrawElementsTrianglesAdjacency<test_api::GL>>));
7977     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip_adjacency",
7978                              TestSubcase::Create<CModeDrawElementsTriangleStripAdjacency<test_api::GL>>));
7979 
7980     addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-arrays",
7981                              TestSubcase::Create<CTransformFeedbackArray<test_api::GL>>));
7982     addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-elements",
7983                              TestSubcase::Create<CTransformFeedbackElements<test_api::GL>>));
7984 
7985     addChild(new TestSubcase(m_context, "advanced-primitiveRestart-elements",
7986                              TestSubcase::Create<CPrimitiveRestartElements<test_api::GL>>));
7987 
7988     addChild(new TestSubcase(m_context, "negative-noindirect-arrays",
7989                              TestSubcase::Create<CNegativeZeroBufferArray<test_api::GL>>));
7990     addChild(new TestSubcase(m_context, "negative-noindirect-elements",
7991                              TestSubcase::Create<CNegativeZeroBufferElements<test_api::GL>>));
7992     addChild(new TestSubcase(m_context, "negative-invalidMode-arrays",
7993                              TestSubcase::Create<CNegativeInvalidModeArray<test_api::GL>>));
7994     addChild(new TestSubcase(m_context, "negative-invalidMode-elements",
7995                              TestSubcase::Create<CNegativeInvalidModeElements<test_api::GL>>));
7996     addChild(
7997         new TestSubcase(m_context, "negative-noVAO-arrays", TestSubcase::Create<CNegativeNoVAOArrays<test_api::GL>>));
7998     addChild(new TestSubcase(m_context, "negative-noVAO-elements",
7999                              TestSubcase::Create<CNegativeNoVAOElements<test_api::GL>>));
8000     addChild(new TestSubcase(m_context, "negative-bufferMapped-arrays",
8001                              TestSubcase::Create<CNegativeBufferMappedArray<test_api::GL>>));
8002     addChild(new TestSubcase(m_context, "negative-bufferMapped-elements",
8003                              TestSubcase::Create<CNegativeBufferMappedElements<test_api::GL>>));
8004     addChild(new TestSubcase(m_context, "negative-invalidType-elements",
8005                              TestSubcase::Create<CNegativeDataWrongElements<test_api::GL>>));
8006     addChild(new TestSubcase(m_context, "negative-gshIncompatible-arrays",
8007                              TestSubcase::Create<CNegativeGshArray<test_api::GL>>));
8008     addChild(new TestSubcase(m_context, "negative-gshIncompatible-elements",
8009                              TestSubcase::Create<CNegativeGshElements<test_api::GL>>));
8010     addChild(new TestSubcase(m_context, "negative-wrongOffset-arrays",
8011                              TestSubcase::Create<CNegativeStructureWrongOffsetArray<test_api::GL>>));
8012     addChild(new TestSubcase(m_context, "negative-wrongOffset-elements",
8013                              TestSubcase::Create<CNegativeStructureWrongOffsetElements<test_api::GL>>));
8014     addChild(new TestSubcase(m_context, "negative-invalidSize-arrays",
8015                              TestSubcase::Create<CNegativeInvalidSizeArrays<test_api::GL>>));
8016     addChild(new TestSubcase(m_context, "negative-invalidSize-elements",
8017                              TestSubcase::Create<CNegativeInvalidSizeElements<test_api::GL>>));
8018     addChild(new TestSubcase(m_context, "negative-unalignedOffset",
8019                              TestSubcase::Create<CNegativeUnalignedOffset<test_api::GL>>));
8020 }
8021 
DrawIndirectTestsGL43(glcts::Context & context)8022 DrawIndirectTestsGL43::DrawIndirectTestsGL43(glcts::Context &context) : TestCaseGroup(context, "draw_indirect_43", "")
8023 {
8024 }
8025 
~DrawIndirectTestsGL43(void)8026 DrawIndirectTestsGL43::~DrawIndirectTestsGL43(void)
8027 {
8028 }
8029 
init()8030 void DrawIndirectTestsGL43::init()
8031 {
8032     using namespace glcts;
8033 
8034     DILogger::setOutput(m_context.getTestContext().getLog());
8035     addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-arrays",
8036                              TestSubcase::Create<CComputeShaderArray<test_api::GL>>));
8037     addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-elements",
8038                              TestSubcase::Create<CComputeShaderElements<test_api::GL>>));
8039 }
8040 
DrawIndirectTestsES31(glcts::Context & context)8041 DrawIndirectTestsES31::DrawIndirectTestsES31(glcts::Context &context) : TestCaseGroup(context, "draw_indirect", "")
8042 {
8043 }
8044 
~DrawIndirectTestsES31(void)8045 DrawIndirectTestsES31::~DrawIndirectTestsES31(void)
8046 {
8047 }
8048 
init()8049 void DrawIndirectTestsES31::init()
8050 {
8051     using namespace glcts;
8052 
8053     DILogger::setOutput(m_context.getTestContext().getLog());
8054 
8055     addChild(
8056         new TestSubcase(m_context, "basic-binding-default", TestSubcase::Create<CDefaultBindingPoint<test_api::ES3>>));
8057     addChild(new TestSubcase(m_context, "basic-binding-zero", TestSubcase::Create<CZeroBindingPoint<test_api::ES3>>));
8058     addChild(
8059         new TestSubcase(m_context, "basic-binding-single", TestSubcase::Create<CSingleBindingPoint<test_api::ES3>>));
8060     addChild(new TestSubcase(m_context, "basic-binding-multi", TestSubcase::Create<CMultiBindingPoint<test_api::ES3>>));
8061     addChild(
8062         new TestSubcase(m_context, "basic-binding-delete", TestSubcase::Create<CDeleteBindingPoint<test_api::ES3>>));
8063 
8064     addChild(new TestSubcase(m_context, "basic-buffer-data", TestSubcase::Create<CBufferData<test_api::ES3>>));
8065     addChild(new TestSubcase(m_context, "basic-buffer-subData", TestSubcase::Create<CBufferSubData<test_api::ES3>>));
8066     addChild(
8067         new TestSubcase(m_context, "basic-buffer-getPointerv", TestSubcase::Create<CBufferGetPointerv<test_api::ES3>>));
8068     addChild(new TestSubcase(m_context, "basic-buffer-mapRange", TestSubcase::Create<CBufferMapRange<test_api::ES3>>));
8069     addChild(new TestSubcase(m_context, "basic-buffer-flushMappedRange",
8070                              TestSubcase::Create<CBufferFlushMappedRange<test_api::ES3>>));
8071     addChild(
8072         new TestSubcase(m_context, "basic-buffer-copySubData", TestSubcase::Create<CBufferCopySubData<test_api::ES3>>));
8073 
8074     addChild(new TestSubcase(m_context, "basic-drawArrays-singlePrimitive",
8075                              TestSubcase::Create<CVBODrawArraysSingle<test_api::ES3>>));
8076     addChild(new TestSubcase(m_context, "basic-drawArrays-manyPrimitives",
8077                              TestSubcase::Create<CVBODrawArraysMany<test_api::ES3>>));
8078     addChild(new TestSubcase(m_context, "basic-drawArrays-instancing",
8079                              TestSubcase::Create<CVBODrawArraysInstancing<test_api::ES3>>));
8080     addChild(new TestSubcase(m_context, "basic-drawArrays-xfbPaused",
8081                              TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::ES3>>));
8082     addChild(new TestSubcase(m_context, "basic-drawElements-singlePrimitive",
8083                              TestSubcase::Create<CVBODrawElementsSingle<test_api::ES3>>));
8084     addChild(new TestSubcase(m_context, "basic-drawElements-manyPrimitives",
8085                              TestSubcase::Create<CVBODrawElementsMany<test_api::ES3>>));
8086     addChild(new TestSubcase(m_context, "basic-drawElements-instancing",
8087                              TestSubcase::Create<CVBODrawElementsInstancing<test_api::ES3>>));
8088     addChild(new TestSubcase(m_context, "basic-drawElements-xfbPaused",
8089                              TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::ES3>>));
8090 
8091     addChild(new TestSubcase(m_context, "basic-drawArrays-simple",
8092                              TestSubcase::Create<CBufferIndirectDrawArraysSimple<test_api::ES3>>));
8093     addChild(new TestSubcase(m_context, "basic-drawArrays-noFirst",
8094                              TestSubcase::Create<CBufferIndirectDrawArraysNoFirst<test_api::ES3>>));
8095     addChild(new TestSubcase(m_context, "basic-drawArrays-bufferOffset",
8096                              TestSubcase::Create<CBufferIndirectDrawArraysOffset<test_api::ES3>>));
8097     addChild(new TestSubcase(m_context, "basic-drawArrays-vertexIds",
8098                              TestSubcase::Create<CBufferIndirectDrawArraysVertexIds<test_api::ES3>>));
8099     addChild(new TestSubcase(m_context, "basic-drawElements-simple",
8100                              TestSubcase::Create<CBufferIndirectDrawElementsSimple<test_api::ES3>>));
8101     addChild(new TestSubcase(m_context, "basic-drawElements-noFirstIndex",
8102                              TestSubcase::Create<CBufferIndirectDrawElementsNoFirstIndex<test_api::ES3>>));
8103     addChild(new TestSubcase(m_context, "basic-drawElements-basevertex",
8104                              TestSubcase::Create<CBufferIndirectDrawElementsNoBasevertex<test_api::ES3>>));
8105     addChild(new TestSubcase(m_context, "basic-drawElements-bufferOffset",
8106                              TestSubcase::Create<CBufferIndirectDrawElementsOffset<test_api::ES3>>));
8107     addChild(new TestSubcase(m_context, "basic-drawElements-vertexIds",
8108                              TestSubcase::Create<CBufferIndirectDrawElementsVertexIds<test_api::ES3>>));
8109 
8110     addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_short",
8111                              TestSubcase::Create<CIndicesDataTypeUnsignedShort<test_api::ES3>>));
8112     addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_byte",
8113                              TestSubcase::Create<CIndicesDataTypeUnsignedByte<test_api::ES3>>));
8114 
8115     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-points",
8116                              TestSubcase::Create<CModeDrawArraysPoints<test_api::ES3>>));
8117     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines",
8118                              TestSubcase::Create<CModeDrawArraysLines<test_api::ES3>>));
8119     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip",
8120                              TestSubcase::Create<CModeDrawArraysLineStrip<test_api::ES3>>));
8121     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_loop",
8122                              TestSubcase::Create<CModeDrawArraysLineLoop<test_api::ES3>>));
8123     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip",
8124                              TestSubcase::Create<CModeDrawArraysTriangleStrip<test_api::ES3>>));
8125     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_fan",
8126                              TestSubcase::Create<CModeDrawArraysTriangleFan<test_api::ES3>>));
8127     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines_adjacency",
8128                              TestSubcase::Create<CModeDrawArraysLinesAdjacency<test_api::ES3>>));
8129     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip_adjacency",
8130                              TestSubcase::Create<CModeDrawArraysLineStripAdjacency<test_api::ES3>>));
8131     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangles_adjacency",
8132                              TestSubcase::Create<CModeDrawArraysTrianglesAdjacency<test_api::ES3>>));
8133     addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip_adjacency",
8134                              TestSubcase::Create<CModeDrawArraysTriangleStripAdjacency<test_api::ES3>>));
8135 
8136     addChild(new TestSubcase(m_context, "basic-mode-drawElements-points",
8137                              TestSubcase::Create<CModeDrawElementsPoints<test_api::ES3>>));
8138     addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines",
8139                              TestSubcase::Create<CModeDrawElementsLines<test_api::ES3>>));
8140     addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip",
8141                              TestSubcase::Create<CModeDrawElementsLineStrip<test_api::ES3>>));
8142     addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_loop",
8143                              TestSubcase::Create<CModeDrawElementsLineLoop<test_api::ES3>>));
8144     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip",
8145                              TestSubcase::Create<CModeDrawElementsTriangleStrip<test_api::ES3>>));
8146     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_fan",
8147                              TestSubcase::Create<CModeDrawElementsTriangleFan<test_api::ES3>>));
8148     addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines_adjacency",
8149                              TestSubcase::Create<CModeDrawElementsLinesAdjacency<test_api::ES3>>));
8150     addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip_adjacency",
8151                              TestSubcase::Create<CModeDrawElementsLineStripAdjacency<test_api::ES3>>));
8152     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangles_adjacency",
8153                              TestSubcase::Create<CModeDrawElementsTrianglesAdjacency<test_api::ES3>>));
8154     addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip_adjacency",
8155                              TestSubcase::Create<CModeDrawElementsTriangleStripAdjacency<test_api::ES3>>));
8156 
8157     addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-arrays",
8158                              TestSubcase::Create<CTransformFeedbackArray<test_api::ES3>>));
8159     addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-elements",
8160                              TestSubcase::Create<CTransformFeedbackElements<test_api::ES3>>));
8161 
8162     addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-arrays",
8163                              TestSubcase::Create<CComputeShaderArray<test_api::ES3>>));
8164     addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-elements",
8165                              TestSubcase::Create<CComputeShaderElements<test_api::ES3>>));
8166 
8167     addChild(new TestSubcase(m_context, "advanced-primitiveRestart-elements",
8168                              TestSubcase::Create<CPrimitiveRestartElements<test_api::ES3>>));
8169 
8170     addChild(new TestSubcase(m_context, "negative-noindirect-arrays",
8171                              TestSubcase::Create<CNegativeZeroBufferArray<test_api::ES3>>));
8172     addChild(new TestSubcase(m_context, "negative-noindirect-elements",
8173                              TestSubcase::Create<CNegativeZeroBufferElements<test_api::ES3>>));
8174     addChild(new TestSubcase(m_context, "negative-invalidMode-arrays",
8175                              TestSubcase::Create<CNegativeInvalidModeArray<test_api::ES3>>));
8176     addChild(new TestSubcase(m_context, "negative-invalidMode-elements",
8177                              TestSubcase::Create<CNegativeInvalidModeElements<test_api::ES3>>));
8178     addChild(
8179         new TestSubcase(m_context, "negative-noVAO-arrays", TestSubcase::Create<CNegativeNoVAOArrays<test_api::ES3>>));
8180     addChild(new TestSubcase(m_context, "negative-noVAO-elements",
8181                              TestSubcase::Create<CNegativeNoVAOElements<test_api::ES3>>));
8182     addChild(
8183         new TestSubcase(m_context, "negative-noVBO-arrays", TestSubcase::Create<CNegativeNoVBOArrays<test_api::ES3>>));
8184     addChild(new TestSubcase(m_context, "negative-noVBO-elements",
8185                              TestSubcase::Create<CNegativeNoVBOElements<test_api::ES3>>));
8186     addChild(new TestSubcase(m_context, "negative-bufferMapped-arrays",
8187                              TestSubcase::Create<CNegativeBufferMappedArray<test_api::ES3>>));
8188     addChild(new TestSubcase(m_context, "negative-bufferMapped-elements",
8189                              TestSubcase::Create<CNegativeBufferMappedElements<test_api::ES3>>));
8190     addChild(new TestSubcase(m_context, "negative-invalidType-elements",
8191                              TestSubcase::Create<CNegativeDataWrongElements<test_api::ES3>>));
8192 
8193     addChild(new TestSubcase(m_context, "negative-wrongOffset-arrays",
8194                              TestSubcase::Create<CNegativeStructureWrongOffsetArray<test_api::ES3>>));
8195     addChild(new TestSubcase(m_context, "negative-wrongOffset-elements",
8196                              TestSubcase::Create<CNegativeStructureWrongOffsetElements<test_api::ES3>>));
8197     addChild(new TestSubcase(m_context, "negative-invalidSize-arrays",
8198                              TestSubcase::Create<CNegativeInvalidSizeArrays<test_api::ES3>>));
8199     addChild(new TestSubcase(m_context, "negative-invalidSize-elements",
8200                              TestSubcase::Create<CNegativeInvalidSizeElements<test_api::ES3>>));
8201     addChild(new TestSubcase(m_context, "negative-unalignedOffset",
8202                              TestSubcase::Create<CNegativeUnalignedOffset<test_api::ES3>>));
8203     addChild(new TestSubcase(m_context, "negative-xfb", TestSubcase::Create<CNegativeXFB<test_api::ES3>>));
8204 }
8205 } // namespace glcts
8206