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