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