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