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