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