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