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