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