• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
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 Basic Layout Binding Tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es31fLayoutBindingTests.hpp"
25 
26 #include "gluShaderProgram.hpp"
27 #include "gluPixelTransfer.hpp"
28 #include "gluTextureUtil.hpp"
29 #include "gluContextInfo.hpp"
30 
31 #include "glwFunctions.hpp"
32 #include "glwEnums.hpp"
33 
34 #include "tcuSurface.hpp"
35 #include "tcuTestLog.hpp"
36 #include "tcuTexture.hpp"
37 #include "tcuTextureUtil.hpp"
38 #include "tcuImageCompare.hpp"
39 #include "tcuStringTemplate.hpp"
40 #include "tcuRenderTarget.hpp"
41 
42 #include "deString.h"
43 #include "deStringUtil.hpp"
44 #include "deRandom.hpp"
45 
46 using tcu::TestLog;
47 using tcu::Vec2;
48 using tcu::Vec3;
49 using tcu::Vec4;
50 
51 namespace deqp
52 {
53 namespace gles31
54 {
55 namespace Functional
56 {
57 namespace
58 {
59 
60 enum TestType
61 {
62 	TESTTYPE_BINDING_SINGLE = 0,
63 	TESTTYPE_BINDING_MAX,
64 	TESTTYPE_BINDING_MULTIPLE,
65 	TESTTYPE_BINDING_ARRAY,
66 	TESTTYPE_BINDING_MAX_ARRAY,
67 
68 	TESTTYPE_BINDING_LAST,
69 };
70 
71 enum ShaderType
72 {
73 	SHADERTYPE_VERTEX = 0,
74 	SHADERTYPE_FRAGMENT,
75 	SHADERTYPE_TESS_CONTROL,
76 	SHADERTYPE_TESS_EVALUATION,
77 	SHADERTYPE_ALL,
78 
79 	SHADERTYPE_LAST,
80 };
81 
82 enum
83 {
84 	MAX_UNIFORM_MULTIPLE_INSTANCES	= 7,
85 	MAX_UNIFORM_ARRAY_SIZE			= 7,
86 };
87 
generateVertexShader(ShaderType shaderType,const std::string & shaderUniformDeclarations,const std::string & shaderBody)88 std::string generateVertexShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
89 {
90 	static const char* const s_simpleVertexShaderSource	=	"#version 310 es\n"
91 															"in highp vec4 a_position;\n"
92 															"void main (void)\n"
93 															"{\n"
94 															"	gl_Position = a_position;\n"
95 															"}\n";
96 
97 	switch (shaderType)
98 	{
99 		case SHADERTYPE_VERTEX:
100 		case SHADERTYPE_ALL:
101 		{
102 			std::ostringstream vertexShaderSource;
103 			vertexShaderSource	<<	"#version 310 es\n"
104 								<<	"in highp vec4 a_position;\n"
105 								<<	"out highp vec4 v_color;\n"
106 								<<	"uniform highp int u_arrayNdx;\n\n"
107 								<<	shaderUniformDeclarations << "\n"
108 								<<	"void main (void)\n"
109 								<<	"{\n"
110 								<<	"	highp vec4 color;\n\n"
111 								<<	shaderBody << "\n"
112 								<<	"	v_color = color;\n"
113 								<<	"	gl_Position = a_position;\n"
114 								<<	"}\n";
115 
116 			return vertexShaderSource.str();
117 		}
118 
119 		case SHADERTYPE_FRAGMENT:
120 		case SHADERTYPE_TESS_CONTROL:
121 		case SHADERTYPE_TESS_EVALUATION:
122 			return s_simpleVertexShaderSource;
123 
124 		default:
125 			DE_ASSERT(false);
126 			return "";
127 	}
128 }
129 
generateFragmentShader(ShaderType shaderType,const std::string & shaderUniformDeclarations,const std::string & shaderBody)130 std::string generateFragmentShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
131 {
132 	static const char* const s_simpleFragmentShaderSource = "#version 310 es\n"
133 															"in highp vec4 v_color;\n"
134 															"layout(location = 0) out highp vec4 fragColor;\n"
135 															"void main (void)\n"
136 															"{\n"
137 															"	fragColor = v_color;\n"
138 															"}\n";
139 
140 	switch (shaderType)
141 	{
142 		case SHADERTYPE_VERTEX:
143 		case SHADERTYPE_TESS_CONTROL:
144 		case SHADERTYPE_TESS_EVALUATION:
145 			return s_simpleFragmentShaderSource;
146 
147 		case SHADERTYPE_FRAGMENT:
148 		{
149 			std::ostringstream fragmentShaderSource;
150 			fragmentShaderSource	<<	"#version 310 es\n"
151 									<<	"layout(location = 0) out highp vec4 fragColor;\n"
152 									<<	"uniform highp int u_arrayNdx;\n\n"
153 									<<	shaderUniformDeclarations << "\n"
154 									<<	"void main (void)\n"
155 									<<	"{\n"
156 									<<	"	highp vec4 color;\n\n"
157 									<<	shaderBody << "\n"
158 									<<	"	fragColor = color;\n"
159 									<<	"}\n";
160 
161 			return fragmentShaderSource.str();
162 		}
163 		case SHADERTYPE_ALL:
164 		{
165 			std::ostringstream fragmentShaderSource;
166 			fragmentShaderSource	<<	"#version 310 es\n"
167 									<<	"in highp vec4 v_color;\n"
168 									<<	"layout(location = 0) out highp vec4 fragColor;\n"
169 									<<	"uniform highp int u_arrayNdx;\n\n"
170 									<<	shaderUniformDeclarations << "\n"
171 									<<	"void main (void)\n"
172 									<<	"{\n"
173 									<<	"	if (v_color.x > 2.0) discard;\n"
174 									<<	"	highp vec4 color;\n\n"
175 									<<	shaderBody << "\n"
176 									<<	"	fragColor = color;\n"
177 									<<	"}\n";
178 
179 			return fragmentShaderSource.str();
180 		}
181 
182 		default:
183 			DE_ASSERT(false);
184 			return "";
185 	}
186 }
187 
generateTessControlShader(ShaderType shaderType,const std::string & shaderUniformDeclarations,const std::string & shaderBody)188 std::string generateTessControlShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
189 {
190 	static const char* const s_simpleTessContorlShaderSource =	"#version 310 es\n"
191 																"#extension GL_EXT_tessellation_shader : require\n"
192 																"layout (vertices=3) out;\n"
193 																"\n"
194 																"void main (void)\n"
195 																"{\n"
196 																"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
197 																"}\n";
198 
199 	switch (shaderType)
200 	{
201 		case SHADERTYPE_VERTEX:
202 		case SHADERTYPE_FRAGMENT:
203 		case SHADERTYPE_TESS_EVALUATION:
204 			return s_simpleTessContorlShaderSource;
205 
206 		case SHADERTYPE_TESS_CONTROL:
207 		case SHADERTYPE_ALL:
208 		{
209 			std::ostringstream tessControlShaderSource;
210 			tessControlShaderSource <<	"#version 310 es\n"
211 									<<	"#extension GL_EXT_tessellation_shader : require\n"
212 									<<	"layout (vertices=3) out;\n"
213 									<<	"\n"
214 									<<	"uniform highp int u_arrayNdx;\n\n"
215 									<<	shaderUniformDeclarations << "\n"
216 									<<	"void main (void)\n"
217 									<<	"{\n"
218 									<<	"	highp vec4 color;\n\n"
219 									<<	shaderBody << "\n"
220 									<<	"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
221 									<<	"}\n";
222 
223 			return tessControlShaderSource.str();
224 		}
225 
226 		default:
227 			DE_ASSERT(false);
228 			return "";
229 	}
230 }
231 
generateTessEvaluationShader(ShaderType shaderType,const std::string & shaderUniformDeclarations,const std::string & shaderBody)232 std::string generateTessEvaluationShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
233 {
234 	static const char* const s_simpleTessEvaluationShaderSource =	"#version 310 es\n"
235 																	"#extension GL_EXT_tessellation_shader : require\n"
236 																	"layout (triangles) in;\n"
237 																	"\n"
238 																	"void main (void)\n"
239 																	"{\n"
240 																	"	gl_Position = gl_TessCoord[0] * gl_in[0].gl_Position + gl_TessCoord[1] * gl_in[1].gl_Position + gl_TessCoord[2] * gl_in[2].gl_Position;\n"
241 																	"}\n";
242 
243 	switch (shaderType)
244 	{
245 		case SHADERTYPE_VERTEX:
246 		case SHADERTYPE_FRAGMENT:
247 		case SHADERTYPE_TESS_CONTROL:
248 			return s_simpleTessEvaluationShaderSource;
249 
250 		case SHADERTYPE_TESS_EVALUATION:
251 		case SHADERTYPE_ALL:
252 		{
253 			std::ostringstream tessEvaluationShaderSource;
254 			tessEvaluationShaderSource	<< "#version 310 es\n"
255 										<< "#extension GL_EXT_tessellation_shader : require\n"
256 										<< "layout (triangles) in;\n"
257 										<< "\n"
258 										<< "uniform highp int u_arrayNdx;\n\n"
259 										<< shaderUniformDeclarations << "\n"
260 										<< "out mediump vec4 v_color;\n"
261 										<< "void main (void)\n"
262 										<< "{\n"
263 										<< "	highp vec4 color;\n\n"
264 										<<	shaderBody << "\n"
265 										<< "	v_color = color;\n"
266 										<< "	gl_Position = gl_TessCoord[0] * gl_in[0].gl_Position + gl_TessCoord[1] * gl_in[1].gl_Position + gl_TessCoord[2] * gl_in[2].gl_Position;\n"
267 										<< "}\n";
268 
269 			return tessEvaluationShaderSource.str();
270 		}
271 
272 		default:
273 			DE_ASSERT(false);
274 			return "";
275 	}
276 }
277 
getUniformName(const std::string & name,int declNdx)278 std::string getUniformName (const std::string& name, int declNdx)
279 {
280 	return name + de::toString(declNdx);
281 }
282 
getUniformName(const std::string & name,int declNdx,int arrNdx)283 std::string getUniformName (const std::string& name, int declNdx, int arrNdx)
284 {
285 	return name + de::toString(declNdx) + "[" + de::toString(arrNdx) + "]";
286 }
287 
getRandomColor(de::Random & rnd)288 Vec4 getRandomColor (de::Random& rnd)
289 {
290 	const float r = rnd.getFloat(0.2f, 0.9f);
291 	const float g = rnd.getFloat(0.2f, 0.9f);
292 	const float b = rnd.getFloat(0.2f, 0.9f);
293 	return Vec4(r, g, b, 1.0f);
294 }
295 
296 class LayoutBindingRenderCase : public TestCase
297 {
298 public:
299 	enum
300 	{
301 		MAX_TEST_RENDER_WIDTH	= 256,
302 		MAX_TEST_RENDER_HEIGHT	= 256,
303 		TEST_TEXTURE_SIZE	= 1,
304 	};
305 
306 										LayoutBindingRenderCase			(Context&			context,
307 																		 const char*		name,
308 																		 const char*		desc,
309 																		 ShaderType			shaderType,
310 																		 TestType			testType,
311 																		 glw::GLenum		maxBindingPointEnum,
312 																		 glw::GLenum		maxVertexUnitsEnum,
313 																		 glw::GLenum		maxFragmentUnitsEnum,
314 																		 glw::GLenum		maxCombinedUnitsEnum,
315 																		 const std::string& uniformName);
316 	virtual								~LayoutBindingRenderCase		(void);
317 
318 	virtual void						init							(void);
319 	virtual void						deinit							(void);
320 
getRenderWidth(void) const321 	int									getRenderWidth					(void) const { return de::min((int)MAX_TEST_RENDER_WIDTH, m_context.getRenderTarget().getWidth()); }
getRenderHeight(void) const322 	int									getRenderHeight					(void) const { return de::min((int)MAX_TEST_RENDER_HEIGHT, m_context.getRenderTarget().getHeight()); }
323 protected:
324 	virtual glu::ShaderProgram*			generateShaders					(void) const = 0;
325 
326 	void								initRenderState					(void);
327 	bool								drawAndVerifyResult				(const Vec4& expectedColor);
328 	void								setTestResult					(bool queryTestPassed, bool imageTestPassed);
329 
330 	const glu::ShaderProgram*			m_program;
331 	const ShaderType					m_shaderType;
332 	const TestType						m_testType;
333 	const std::string					m_uniformName;
334 
335 	const glw::GLenum					m_maxBindingPointEnum;
336 	const glw::GLenum					m_maxVertexUnitsEnum;
337 	const glw::GLenum					m_maxFragmentUnitsEnum;
338 	const glw::GLenum					m_maxCombinedUnitsEnum;
339 
340 	glw::GLuint							m_vao;
341 	glw::GLuint							m_vertexBuffer;
342 	glw::GLuint							m_indexBuffer;
343 	glw::GLint							m_shaderProgramLoc;
344 	glw::GLint							m_shaderProgramPosLoc;
345 	glw::GLint							m_shaderProgramArrayNdxLoc;
346 	glw::GLint							m_numBindings;
347 
348 	std::vector<glw::GLint>				m_bindings;
349 
350 private:
351 	void								initBindingPoints				(int minBindingPoint, int numBindingPoints);
352 };
353 
LayoutBindingRenderCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,glw::GLenum maxBindingPointEnum,glw::GLenum maxVertexUnitsEnum,glw::GLenum maxFragmentUnitsEnum,glw::GLenum maxCombinedUnitsEnum,const std::string & uniformName)354 LayoutBindingRenderCase::LayoutBindingRenderCase (Context&				context,
355 												  const char*			name,
356 												  const char*			desc,
357 												  ShaderType			shaderType,
358 												  TestType				testType,
359 												  glw::GLenum			maxBindingPointEnum,
360 												  glw::GLenum			maxVertexUnitsEnum,
361 												  glw::GLenum			maxFragmentUnitsEnum,
362 												  glw::GLenum			maxCombinedUnitsEnum,
363 												  const std::string&	uniformName)
364 	: TestCase						(context, name, desc)
365 	, m_program						(DE_NULL)
366 	, m_shaderType					(shaderType)
367 	, m_testType					(testType)
368 	, m_uniformName					(uniformName)
369 	, m_maxBindingPointEnum			(maxBindingPointEnum)
370 	, m_maxVertexUnitsEnum			(maxVertexUnitsEnum)
371 	, m_maxFragmentUnitsEnum		(maxFragmentUnitsEnum)
372 	, m_maxCombinedUnitsEnum		(maxCombinedUnitsEnum)
373 	, m_vao							(0)
374 	, m_vertexBuffer				(0)
375 	, m_indexBuffer					(0)
376 	, m_shaderProgramLoc			(0)
377 	, m_shaderProgramPosLoc			(0)
378 	, m_shaderProgramArrayNdxLoc	(0)
379 	, m_numBindings					(0)
380 {
381 }
382 
~LayoutBindingRenderCase(void)383 LayoutBindingRenderCase::~LayoutBindingRenderCase (void)
384 {
385 	deinit();
386 }
387 
init(void)388 void LayoutBindingRenderCase::init (void)
389 {
390 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
391 
392 	{
393 		de::Random				rnd					(deStringHash(getName()) ^ 0xff23a4);
394 		glw::GLint				numBindingPoints	= 0;	// Number of available binding points
395 		glw::GLint				maxVertexUnits		= 0;	// Available uniforms in the vertex shader
396 		glw::GLint				maxFragmentUnits	= 0;	// Available uniforms in the fragment shader
397 		glw::GLint				maxCombinedUnits	= 0;	// Available uniforms in all the shader stages combined
398 		glw::GLint				maxUnits			= 0;	// Maximum available uniforms for this test
399 
400 		gl.getIntegerv(m_maxVertexUnitsEnum, &maxVertexUnits);
401 		gl.getIntegerv(m_maxFragmentUnitsEnum, &maxFragmentUnits);
402 		gl.getIntegerv(m_maxCombinedUnitsEnum, &maxCombinedUnits);
403 		gl.getIntegerv(m_maxBindingPointEnum, &numBindingPoints);
404 		GLU_EXPECT_NO_ERROR(gl.getError(), "Querying available uniform numbers failed");
405 
406 		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the vertex shader: " << maxVertexUnits << tcu::TestLog::EndMessage;
407 		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the fragment shader: " << maxFragmentUnits << tcu::TestLog::EndMessage;
408 		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum combined units for uniform type: " << maxCombinedUnits << tcu::TestLog::EndMessage;
409 		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum binding point for uniform type: " << numBindingPoints-1 << tcu::TestLog::EndMessage;
410 
411 		// Select maximum number of uniforms used for the test
412 		switch (m_shaderType)
413 		{
414 			case SHADERTYPE_VERTEX:
415 				maxUnits = maxVertexUnits;
416 				break;
417 
418 			case SHADERTYPE_FRAGMENT:
419 				maxUnits = maxFragmentUnits;
420 				break;
421 
422 			case SHADERTYPE_ALL:
423 				maxUnits = maxCombinedUnits/2;
424 				break;
425 
426 			default:
427 				DE_ASSERT(false);
428 		}
429 
430 		// Select the number of uniforms (= bindings) used for this test
431 		switch (m_testType)
432 		{
433 			case TESTTYPE_BINDING_SINGLE:
434 			case TESTTYPE_BINDING_MAX:
435 				m_numBindings = 1;
436 				break;
437 
438 			case TESTTYPE_BINDING_MULTIPLE:
439 				if (maxUnits < 2)
440 					throw tcu::NotSupportedError("Not enough uniforms available for test");
441 				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_MULTIPLE_INSTANCES, maxUnits));
442 				break;
443 
444 			case TESTTYPE_BINDING_ARRAY:
445 			case TESTTYPE_BINDING_MAX_ARRAY:
446 				if (maxUnits < 2)
447 					throw tcu::NotSupportedError("Not enough uniforms available for test");
448 				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits));
449 				break;
450 
451 			default:
452 				DE_ASSERT(false);
453 		}
454 
455 		// Check that we have enough uniforms in different shaders to perform the tests
456 		if ( ((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_ALL)) && (maxVertexUnits < m_numBindings) )
457 			throw tcu::NotSupportedError("Vertex shader: not enough uniforms available for test");
458 		if ( ((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_ALL)) && (maxFragmentUnits < m_numBindings) )
459 			throw tcu::NotSupportedError("Fragment shader: not enough uniforms available for test");
460 		if ( (m_shaderType == SHADERTYPE_ALL) && (maxCombinedUnits < m_numBindings*2) )
461 			throw tcu::NotSupportedError("Not enough uniforms available for test");
462 
463 		// Check that we have enough binding points to perform the tests
464 		if (numBindingPoints < m_numBindings)
465 			throw tcu::NotSupportedError("Not enough binding points available for test");
466 
467 		// Initialize the binding points i.e. populate the two binding point vectors
468 		initBindingPoints(0, numBindingPoints);
469 	}
470 
471 	// Generate the shader program - note: this must be done after deciding the binding points
472 	DE_ASSERT(!m_program);
473 	m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shaders" << tcu::TestLog::EndMessage;
474 	m_program = generateShaders();
475 	m_testCtx.getLog() << *m_program;
476 
477 	if (!m_program->isOk())
478 		throw tcu::TestError("Shader compile failed");
479 
480 	// Setup vertex and index buffers
481 	{
482 		// Get attribute and uniform locations
483 		const deUint32	program	= m_program->getProgram();
484 
485 		m_shaderProgramPosLoc		= gl.getAttribLocation(program, "a_position");
486 		m_shaderProgramArrayNdxLoc	= gl.getUniformLocation(program, "u_arrayNdx");
487 		m_vertexBuffer				= 0;
488 		m_indexBuffer				= 0;
489 
490 		// Setup buffers so that we render one quad covering the whole viewport
491 		const Vec3 vertices[] =
492 		{
493 			Vec3(-1.0f, -1.0f, +1.0f),
494 			Vec3(+1.0f, -1.0f, +1.0f),
495 			Vec3(+1.0f, +1.0f, +1.0f),
496 			Vec3(-1.0f, +1.0f, +1.0f),
497 		};
498 
499 		const deUint16 indices[] =
500 		{
501 			0, 1, 2,
502 			0, 2, 3,
503 		};
504 
505 		TCU_CHECK((m_shaderProgramPosLoc >= 0) && (m_shaderProgramArrayNdxLoc >= 0));
506 
507 		// Generate and bind vao
508 		if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
509 		{
510 			gl.genVertexArrays(1, &m_vao);
511 			gl.bindVertexArray(m_vao);
512 		}
513 
514 		// Generate and bind index buffer
515 		gl.genBuffers(1, &m_indexBuffer);
516 		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
517 		gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (DE_LENGTH_OF_ARRAY(indices)*(glw::GLsizeiptr)sizeof(indices[0])), &indices[0], GL_STATIC_DRAW);
518 		GLU_EXPECT_NO_ERROR(gl.getError(), "Index buffer setup failed");
519 
520 		// Generate and bind vertex buffer
521 		gl.genBuffers(1, &m_vertexBuffer);
522 		gl.bindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
523 		gl.bufferData(GL_ARRAY_BUFFER, (DE_LENGTH_OF_ARRAY(vertices)*(glw::GLsizeiptr)sizeof(vertices[0])), &vertices[0], GL_STATIC_DRAW);
524 		gl.enableVertexAttribArray(m_shaderProgramPosLoc);
525 		gl.vertexAttribPointer(m_shaderProgramPosLoc, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
526 		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex buffer setup failed");
527 	}
528 }
529 
deinit(void)530 void LayoutBindingRenderCase::deinit (void)
531 {
532 	if (m_program)
533 	{
534 		delete m_program;
535 		m_program = DE_NULL;
536 	}
537 
538 	if (m_shaderProgramPosLoc)
539 		m_context.getRenderContext().getFunctions().disableVertexAttribArray(m_shaderProgramPosLoc);
540 
541 	if (m_vao)
542 		m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_vao);
543 
544 	if (m_vertexBuffer)
545 	{
546 		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_vertexBuffer);
547 		m_context.getRenderContext().getFunctions().bindBuffer(GL_ARRAY_BUFFER, 0);
548 	}
549 
550 	if (m_indexBuffer)
551 	{
552 		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_indexBuffer);
553 		m_context.getRenderContext().getFunctions().bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
554 	}
555 }
556 
initBindingPoints(int minBindingPoint,int numBindingPoints)557 void LayoutBindingRenderCase::initBindingPoints (int minBindingPoint, int numBindingPoints)
558 {
559 	de::Random rnd(deStringHash(getName()) ^ 0xff23a4);
560 
561 	switch (m_testType)
562 	{
563 		case TESTTYPE_BINDING_SINGLE:
564 		{
565 			const int bpoint = rnd.getInt(minBindingPoint, numBindingPoints-1);
566 			m_bindings.push_back(bpoint);
567 			break;
568 		}
569 
570 		case TESTTYPE_BINDING_MAX:
571 			m_bindings.push_back(numBindingPoints-1);
572 			break;
573 
574 		case TESTTYPE_BINDING_MULTIPLE:
575 		{
576 			// Choose multiple unique binding points from the low and high end of available binding points
577 			std::vector<deUint32> lowBindingPoints;
578 			std::vector<deUint32> highBindingPoints;
579 
580 			for (int bpoint = 0; bpoint < numBindingPoints/2; ++bpoint)
581 				lowBindingPoints.push_back(bpoint);
582 			for (int bpoint = numBindingPoints/2; bpoint < numBindingPoints; ++bpoint)
583 				highBindingPoints.push_back(bpoint);
584 
585 			rnd.shuffle(lowBindingPoints.begin(), lowBindingPoints.end());
586 			rnd.shuffle(highBindingPoints.begin(), highBindingPoints.end());
587 
588 			for (int ndx = 0; ndx < m_numBindings; ++ndx)
589 			{
590 				if (ndx%2 == 0)
591 				{
592 					const int bpoint = lowBindingPoints.back();
593 					lowBindingPoints.pop_back();
594 					m_bindings.push_back(bpoint);
595 				}
596 				else
597 				{
598 					const int bpoint = highBindingPoints.back();
599 					highBindingPoints.pop_back();
600 					m_bindings.push_back(bpoint);
601 				}
602 
603 			}
604 			break;
605 		}
606 
607 		case TESTTYPE_BINDING_ARRAY:
608 		{
609 			const glw::GLint binding = rnd.getInt(minBindingPoint, numBindingPoints-m_numBindings);
610 			for (int ndx = 0; ndx < m_numBindings; ++ndx)
611 				m_bindings.push_back(binding+ndx);
612 			break;
613 		}
614 
615 		case TESTTYPE_BINDING_MAX_ARRAY:
616 		{
617 			const glw::GLint binding = numBindingPoints-m_numBindings;
618 			for (int ndx = 0; ndx < m_numBindings; ++ndx)
619 				m_bindings.push_back(binding+ndx);
620 			break;
621 		}
622 
623 		default:
624 			DE_ASSERT(false);
625 	}
626 }
627 
initRenderState(void)628 void LayoutBindingRenderCase::initRenderState (void)
629 {
630 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
631 
632 	gl.useProgram(m_program->getProgram());
633 	gl.viewport(0, 0, getRenderWidth(), getRenderHeight());
634 	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
635 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set render state");
636 }
637 
drawAndVerifyResult(const Vec4 & expectedColor)638 bool LayoutBindingRenderCase::drawAndVerifyResult (const Vec4& expectedColor)
639 {
640 	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
641 	tcu::Surface			reference			(getRenderWidth(), getRenderHeight());
642 
643 	// the point of these test is to check layout_binding. For this purpose, we can use quite
644 	// large thresholds.
645 	const tcu::RGBA			surfaceThreshold	= m_context.getRenderContext().getRenderTarget().getPixelFormat().getColorThreshold();
646 	const tcu::RGBA			compareThreshold	= tcu::RGBA(de::clamp(2 * surfaceThreshold.getRed(),   0, 255),
647 															de::clamp(2 * surfaceThreshold.getGreen(), 0, 255),
648 															de::clamp(2 * surfaceThreshold.getBlue(),  0, 255),
649 															de::clamp(2 * surfaceThreshold.getAlpha(), 0, 255));
650 
651 	gl.clear(GL_COLOR_BUFFER_BIT);
652 
653 	// Draw
654 	gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
655 	GLU_EXPECT_NO_ERROR(gl.getError(), "Drawing failed");
656 
657 	// Verify
658 	tcu::Surface result(getRenderWidth(), getRenderHeight());
659 	m_testCtx.getLog() << TestLog::Message << "Reading pixels" << TestLog::EndMessage;
660 	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
661 	GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels failed");
662 
663 	tcu::clear(reference.getAccess(), expectedColor);
664 	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output image, fragment output color is " << expectedColor << tcu::TestLog::EndMessage;
665 
666 	return tcu::pixelThresholdCompare(m_testCtx.getLog(), "Render result", "Result verification", reference, result, compareThreshold, tcu::COMPARE_LOG_RESULT);
667 }
668 
setTestResult(bool queryTestPassed,bool imageTestPassed)669 void LayoutBindingRenderCase::setTestResult (bool queryTestPassed, bool imageTestPassed)
670 {
671 	if (queryTestPassed && imageTestPassed)
672 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
673 	else if (!queryTestPassed && !imageTestPassed)
674 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more binding point queries and image comparisons failed");
675 	else if (!queryTestPassed)
676 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more binding point queries failed");
677 	else
678 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more image comparisons failed");
679 }
680 
681 class LayoutBindingNegativeCase : public TestCase
682 {
683 public:
684 	enum ErrorType
685 	{
686 		ERRORTYPE_OVER_MAX_UNITS = 0,
687 		ERRORTYPE_LESS_THAN_ZERO,
688 		ERRORTYPE_CONTRADICTORY,
689 
690 		ERRORTYPE_LAST,
691 	};
692 
693 										LayoutBindingNegativeCase		(Context&			context,
694 																		 const char*		name,
695 																		 const char*		desc,
696 																		 ShaderType			shaderType,
697 																		 TestType			testType,
698 																		 ErrorType			errorType,
699 																		 glw::GLenum		maxBindingPointEnum,
700 																		 glw::GLenum		maxVertexUnitsEnum,
701 																		 glw::GLenum		maxFragmentUnitsEnum,
702 																		 glw::GLenum		maxTessCtrlUnitsEnum,
703 																		 glw::GLenum		maxTessEvalUnitsEnum,
704 																		 glw::GLenum		maxCombinedUnitsEnum,
705 																		 const std::string& uniformName);
706 	virtual								~LayoutBindingNegativeCase		(void);
707 
708 	virtual void						init							(void);
709 	virtual void						deinit							(void);
710 	virtual IterateResult				iterate							(void);
711 
712 protected:
713 	virtual glu::ShaderProgram*			generateShaders					(void) const = 0;
714 
715 	const glu::ShaderProgram*			m_program;
716 	const ShaderType					m_shaderType;
717 	const TestType						m_testType;
718 	const ErrorType						m_errorType;
719 	const glw::GLenum					m_maxBindingPointEnum;
720 	const glw::GLenum					m_maxVertexUnitsEnum;
721 	const glw::GLenum					m_maxFragmentUnitsEnum;
722 	const glw::GLenum					m_maxTessCtrlUnitsEnum;
723 	const glw::GLenum					m_maxTessEvalUnitsEnum;
724 	const glw::GLenum					m_maxCombinedUnitsEnum;
725 	const std::string					m_uniformName;
726 	glw::GLint							m_numBindings;
727 	std::vector<glw::GLint>				m_vertexShaderBinding;
728 	std::vector<glw::GLint>				m_fragmentShaderBinding;
729 	std::vector<glw::GLint>				m_tessCtrlShaderBinding;
730 	std::vector<glw::GLint>				m_tessEvalShaderBinding;
731 	bool								m_tessSupport;
732 
733 private:
734 	void								initBindingPoints				(int minBindingPoint, int numBindingPoints);
735 };
736 
LayoutBindingNegativeCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,ErrorType errorType,glw::GLenum maxBindingPointEnum,glw::GLenum maxVertexUnitsEnum,glw::GLenum maxTessCtrlUnitsEnum,glw::GLenum maxTessEvalUnitsEnum,glw::GLenum maxFragmentUnitsEnum,glw::GLenum maxCombinedUnitsEnum,const std::string & uniformName)737 LayoutBindingNegativeCase::LayoutBindingNegativeCase (Context&				context,
738 													  const char*			name,
739 													  const char*			desc,
740 													  ShaderType			shaderType,
741 													  TestType				testType,
742 													  ErrorType				errorType,
743 													  glw::GLenum			maxBindingPointEnum,
744 													  glw::GLenum			maxVertexUnitsEnum,
745 													  glw::GLenum			maxTessCtrlUnitsEnum,
746 													  glw::GLenum			maxTessEvalUnitsEnum,
747 													  glw::GLenum			maxFragmentUnitsEnum,
748 													  glw::GLenum			maxCombinedUnitsEnum,
749 													  const std::string&	uniformName)
750 	: TestCase					(context, name, desc)
751 	, m_program					(DE_NULL)
752 	, m_shaderType				(shaderType)
753 	, m_testType				(testType)
754 	, m_errorType				(errorType)
755 	, m_maxBindingPointEnum		(maxBindingPointEnum)
756 	, m_maxVertexUnitsEnum		(maxVertexUnitsEnum)
757 	, m_maxFragmentUnitsEnum	(maxFragmentUnitsEnum)
758 	, m_maxTessCtrlUnitsEnum	(maxTessCtrlUnitsEnum)
759 	, m_maxTessEvalUnitsEnum	(maxTessEvalUnitsEnum)
760 	, m_maxCombinedUnitsEnum	(maxCombinedUnitsEnum)
761 	, m_uniformName				(uniformName)
762 	, m_numBindings				(0)
763 	, m_tessSupport				(false)
764 {
765 }
766 
~LayoutBindingNegativeCase(void)767 LayoutBindingNegativeCase::~LayoutBindingNegativeCase (void)
768 {
769 	deinit();
770 }
771 
init(void)772 void LayoutBindingNegativeCase::init (void)
773 {
774 	// Decide appropriate binding points for the vertex and fragment shaders
775 	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
776 	de::Random				rnd					(deStringHash(getName()) ^ 0xff23a4);
777 	glw::GLint				numBindingPoints	= 0;	// Number of binding points
778 	glw::GLint				maxVertexUnits		= 0;	// Available uniforms in the vertex shader
779 	glw::GLint				maxFragmentUnits	= 0;	// Available uniforms in the fragment shader
780 	glw::GLint				maxCombinedUnits	= 0;	// Available uniforms in all the shader stages combined
781 	glw::GLint				maxTessCtrlUnits	= 0;	// Available uniforms in tessellation control shader
782 	glw::GLint				maxTessEvalUnits	= 0;	// Available uniforms in tessellation evaluation shader
783 	glw::GLint				maxUnits			= 0;	// Maximum available uniforms for this test
784 
785 	m_tessSupport = m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader")
786 					|| contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2))
787 					|| contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
788 
789 	if (!m_tessSupport && (m_shaderType == SHADERTYPE_TESS_EVALUATION || m_shaderType == SHADERTYPE_TESS_CONTROL))
790 		TCU_THROW(NotSupportedError, "Tesselation shaders not supported");
791 
792 	int numShaderStages = m_tessSupport ? 4 : 2;
793 
794 	gl.getIntegerv(m_maxVertexUnitsEnum, &maxVertexUnits);
795 	gl.getIntegerv(m_maxFragmentUnitsEnum, &maxFragmentUnits);
796 
797 	if (m_tessSupport)
798 	{
799 		gl.getIntegerv(m_maxTessCtrlUnitsEnum, &maxTessCtrlUnits);
800 		gl.getIntegerv(m_maxTessEvalUnitsEnum, &maxTessEvalUnits);
801 	}
802 
803 	gl.getIntegerv(m_maxCombinedUnitsEnum, &maxCombinedUnits);
804 	gl.getIntegerv(m_maxBindingPointEnum, &numBindingPoints);
805 	GLU_EXPECT_NO_ERROR(gl.getError(), "Querying available uniform numbers failed");
806 
807 	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the vertex shader: " << maxVertexUnits << tcu::TestLog::EndMessage;
808 	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the fragment shader: " << maxFragmentUnits << tcu::TestLog::EndMessage;
809 
810 	if (m_tessSupport)
811 	{
812 		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the tessellation control shader: " << maxTessCtrlUnits << tcu::TestLog::EndMessage;
813 		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the tessellation evaluation shader: " << maxTessCtrlUnits << tcu::TestLog::EndMessage;
814 	}
815 
816 	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum combined units for uniform type: " << maxCombinedUnits << tcu::TestLog::EndMessage;
817 	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum binding point for uniform type: " << numBindingPoints-1 << tcu::TestLog::EndMessage;
818 
819 	// Select maximum number of uniforms used for the test
820 	switch (m_shaderType)
821 	{
822 		case SHADERTYPE_VERTEX:
823 			maxUnits = maxVertexUnits;
824 			break;
825 
826 		case SHADERTYPE_FRAGMENT:
827 			maxUnits = maxFragmentUnits;
828 			break;
829 
830 		case SHADERTYPE_ALL:
831 			maxUnits = de::min(de::min(de::min(maxVertexUnits, maxFragmentUnits), de::min(maxTessCtrlUnits, maxTessEvalUnits)), maxCombinedUnits/numShaderStages);
832 			break;
833 
834 		case SHADERTYPE_TESS_CONTROL:
835 			maxUnits = maxTessCtrlUnits;
836 			break;
837 
838 		case SHADERTYPE_TESS_EVALUATION:
839 			maxUnits = maxTessEvalUnits;
840 			break;
841 
842 		default:
843 			DE_ASSERT(false);
844 	}
845 
846 	// Select the number of uniforms (= bindings) used for this test
847 	switch (m_testType)
848 	{
849 		case TESTTYPE_BINDING_SINGLE:
850 		case TESTTYPE_BINDING_MAX:
851 			m_numBindings = 1;
852 			break;
853 
854 		case TESTTYPE_BINDING_MULTIPLE:
855 		case TESTTYPE_BINDING_ARRAY:
856 		case TESTTYPE_BINDING_MAX_ARRAY:
857 			if (m_errorType == ERRORTYPE_CONTRADICTORY)
858 			{
859 				// leave room for contradictory case
860 				if (maxUnits < 3)
861 					TCU_THROW(NotSupportedError, "Not enough uniforms available for test");
862 				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits-1));
863 			}
864 			else
865 			{
866 				if (maxUnits < 2)
867 					TCU_THROW(NotSupportedError, "Not enough uniforms available for test");
868 				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits));
869 			}
870 			break;
871 
872 		default:
873 			DE_ASSERT(false);
874 	}
875 
876 	// Check that we have enough uniforms in different shaders to perform the tests
877 	if (((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_ALL)) && (maxVertexUnits < m_numBindings) )
878 		TCU_THROW(NotSupportedError, "Vertex shader: not enough uniforms available for test");
879 
880 	if (((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_ALL)) && (maxFragmentUnits < m_numBindings) )
881 		TCU_THROW(NotSupportedError, "Fragment shader: not enough uniforms available for test");
882 
883 	if (m_tessSupport && ((m_shaderType == SHADERTYPE_TESS_CONTROL) || (m_shaderType == SHADERTYPE_ALL)) && (maxTessCtrlUnits < m_numBindings) )
884 		TCU_THROW(NotSupportedError, "Tessellation control shader: not enough uniforms available for test");
885 
886 	if (m_tessSupport && ((m_shaderType == SHADERTYPE_TESS_EVALUATION) || (m_shaderType == SHADERTYPE_ALL)) && (maxTessEvalUnits < m_numBindings) )
887 		TCU_THROW(NotSupportedError, "Tessellation evaluation shader: not enough uniforms available for test");
888 
889 	if ((m_shaderType == SHADERTYPE_ALL) && (maxCombinedUnits < m_numBindings*numShaderStages) )
890 		TCU_THROW(NotSupportedError, "Not enough uniforms available for test");
891 
892 	// Check that we have enough binding points to perform the tests
893 	if (numBindingPoints < m_numBindings)
894 		TCU_THROW(NotSupportedError, "Not enough binding points available for test");
895 
896 	if (m_errorType == ERRORTYPE_CONTRADICTORY && numBindingPoints == m_numBindings)
897 		TCU_THROW(NotSupportedError, "Not enough binding points available for test");
898 
899 	// Initialize the binding points i.e. populate the two binding point vectors
900 	initBindingPoints(0, numBindingPoints);
901 
902 	// Generate the shader program - note: this must be done after deciding the binding points
903 	DE_ASSERT(!m_program);
904 	m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shaders" << tcu::TestLog::EndMessage;
905 	m_program = generateShaders();
906 	m_testCtx.getLog() << *m_program;
907 }
908 
deinit(void)909 void LayoutBindingNegativeCase::deinit (void)
910 {
911 	if (m_program)
912 	{
913 		delete m_program;
914 		m_program = DE_NULL;
915 	}
916 }
917 
iterate(void)918 TestCase::IterateResult LayoutBindingNegativeCase::iterate (void)
919 {
920 	bool pass = false;
921 	std::string failMessage;
922 
923 	switch (m_errorType)
924 	{
925 		case ERRORTYPE_CONTRADICTORY:		// Contradictory binding points should cause a link-time error
926 			if (!(m_program->getProgramInfo()).linkOk)
927 				pass = true;
928 			failMessage = "Test failed - expected a link-time error";
929 			break;
930 
931 		case ERRORTYPE_LESS_THAN_ZERO:		// Out of bounds binding points should cause a compile-time error
932 		case ERRORTYPE_OVER_MAX_UNITS:
933 			if (m_tessSupport)
934 			{
935 				if (!(m_program->getShaderInfo(glu::SHADERTYPE_VERTEX)).compileOk
936 					|| !(m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT).compileOk)
937 					|| !(m_program->getShaderInfo(glu::SHADERTYPE_TESSELLATION_CONTROL).compileOk)
938 					|| !(m_program->getShaderInfo(glu::SHADERTYPE_TESSELLATION_EVALUATION)).compileOk)
939 					pass = true;
940 			}
941 			else
942 			{
943 				if (!(m_program->getShaderInfo(glu::SHADERTYPE_VERTEX)).compileOk
944 					|| !(m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT).compileOk))
945 					pass = true;
946 			}
947 
948 			failMessage = "Test failed - expected a compile-time error";
949 			break;
950 
951 		default:
952 			DE_ASSERT(false);
953 	}
954 
955 	if (pass)
956 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
957 	else
958 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, failMessage.c_str());
959 
960 	return STOP;
961 }
962 
initBindingPoints(int minBindingPoint,int numBindingPoints)963 void LayoutBindingNegativeCase::initBindingPoints (int minBindingPoint, int numBindingPoints)
964 {
965 	de::Random rnd(deStringHash(getName()) ^ 0xff23a4);
966 
967 	switch (m_errorType)
968 	{
969 		case ERRORTYPE_OVER_MAX_UNITS:	// Select a binding point that is 1 over the maximum
970 		{
971 			m_vertexShaderBinding.push_back(numBindingPoints+1-m_numBindings);
972 			m_fragmentShaderBinding.push_back(numBindingPoints+1-m_numBindings);
973 			m_tessCtrlShaderBinding.push_back(numBindingPoints+1-m_numBindings);
974 			m_tessEvalShaderBinding.push_back(numBindingPoints+1-m_numBindings);
975 			break;
976 		}
977 
978 		case ERRORTYPE_LESS_THAN_ZERO:	// Select a random negative binding point
979 		{
980 			const glw::GLint binding = -rnd.getInt(1, m_numBindings);
981 			m_vertexShaderBinding.push_back(binding);
982 			m_fragmentShaderBinding.push_back(binding);
983 			m_tessCtrlShaderBinding.push_back(binding);
984 			m_tessEvalShaderBinding.push_back(binding);
985 			break;
986 		}
987 
988 		case ERRORTYPE_CONTRADICTORY:	// Select two valid, but contradictory binding points
989 		{
990 			m_vertexShaderBinding.push_back(minBindingPoint);
991 			m_fragmentShaderBinding.push_back((minBindingPoint+1)%numBindingPoints);
992 			m_tessCtrlShaderBinding.push_back((minBindingPoint+2)%numBindingPoints);
993 			m_tessEvalShaderBinding.push_back((minBindingPoint+3)%numBindingPoints);
994 
995 			DE_ASSERT(m_vertexShaderBinding.back()		!= m_fragmentShaderBinding.back());
996 			DE_ASSERT(m_fragmentShaderBinding.back()	!= m_tessEvalShaderBinding.back());
997 			DE_ASSERT(m_tessEvalShaderBinding.back()	!= m_tessCtrlShaderBinding.back());
998 			DE_ASSERT(m_tessCtrlShaderBinding.back()	!= m_vertexShaderBinding.back());
999 			DE_ASSERT(m_vertexShaderBinding.back()		!= m_tessEvalShaderBinding.back());
1000 			DE_ASSERT(m_tessCtrlShaderBinding.back()	!= m_fragmentShaderBinding.back());
1001 			break;
1002 		}
1003 
1004 		default:
1005 			DE_ASSERT(false);
1006 	}
1007 
1008 	// In case we are testing with multiple uniforms populate the rest of the binding points
1009 	for (int ndx = 1; ndx < m_numBindings; ++ndx)
1010 	{
1011 		m_vertexShaderBinding.push_back(m_vertexShaderBinding.front()+ndx);
1012 		m_fragmentShaderBinding.push_back(m_fragmentShaderBinding.front()+ndx);
1013 		m_tessCtrlShaderBinding.push_back(m_tessCtrlShaderBinding.front()+ndx);
1014 		m_tessEvalShaderBinding.push_back(m_tessCtrlShaderBinding.front()+ndx);
1015 	}
1016 }
1017 
1018 class SamplerBindingRenderCase : public LayoutBindingRenderCase
1019 {
1020 public:
1021 									SamplerBindingRenderCase		(Context& context, const char* name, const char* desc, ShaderType shaderType, TestType testType, glw::GLenum samplerType, glw::GLenum textureType);
1022 									~SamplerBindingRenderCase		(void);
1023 
1024 	void							init							(void);
1025 	void							deinit							(void);
1026 	IterateResult					iterate							(void);
1027 
1028 private:
1029 	glu::ShaderProgram*				generateShaders					(void) const;
1030 	glu::DataType					getSamplerTexCoordType			(void) const;
1031 	void							initializeTexture				(glw::GLint bindingPoint, glw::GLint textureName, const Vec4& color) const;
1032 
1033 	const glw::GLenum				m_samplerType;
1034 	const glw::GLenum				m_textureType;
1035 
1036 	std::vector<glw::GLuint>		m_textures;
1037 	std::vector<Vec4>				m_textureColors;
1038 };
1039 
1040 
SamplerBindingRenderCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,glw::GLenum samplerType,glw::GLenum textureType)1041 SamplerBindingRenderCase::SamplerBindingRenderCase (Context&		context,
1042 													const char*		name,
1043 													const char*		desc,
1044 													ShaderType		shaderType,
1045 													TestType		testType,
1046 													glw::GLenum		samplerType,
1047 													glw::GLenum		textureType)
1048 	: LayoutBindingRenderCase	(context, name, desc, shaderType, testType, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, GL_MAX_TEXTURE_IMAGE_UNITS, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, "u_sampler")
1049 	, m_samplerType				(samplerType)
1050 	, m_textureType				(textureType)
1051 {
1052 }
1053 
~SamplerBindingRenderCase(void)1054 SamplerBindingRenderCase::~SamplerBindingRenderCase (void)
1055 {
1056 	deinit();
1057 }
1058 
init(void)1059 void SamplerBindingRenderCase::init (void)
1060 {
1061 	LayoutBindingRenderCase::init();
1062 	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
1063 	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);
1064 
1065 
1066 	// Initialize texture resources
1067 	m_textures = std::vector<glw::GLuint>(m_numBindings,  0);
1068 
1069 	// Texture colors
1070 	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1071 		m_textureColors.push_back(getRandomColor(rnd));
1072 
1073 	// Textures
1074 	gl.genTextures((glw::GLsizei)m_textures.size(), &m_textures[0]);
1075 
1076 	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1077 		initializeTexture(m_bindings[texNdx], m_textures[texNdx], m_textureColors[texNdx]);
1078 
1079 	gl.activeTexture(GL_TEXTURE0);
1080 }
1081 
deinit(void)1082 void SamplerBindingRenderCase::deinit(void)
1083 {
1084 	LayoutBindingRenderCase::deinit();
1085 
1086 	// Clean up texture data
1087 	for (int i = 0; i < (int)m_textures.size(); ++i)
1088 	{
1089 		if (m_textures[i])
1090 		{
1091 			m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[i]);
1092 			m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0);
1093 		}
1094 	}
1095 }
1096 
iterate(void)1097 TestCase::IterateResult SamplerBindingRenderCase::iterate (void)
1098 {
1099 	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
1100 	const int				iterations		= m_numBindings;
1101 	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1102 	bool					imageTestPassed	= true;
1103 	bool					queryTestPassed	= true;
1104 
1105 	// Set the viewport and enable the shader program
1106 	initRenderState();
1107 
1108 	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
1109 	{
1110 		// Set the uniform value indicating the current array index
1111 		gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx);
1112 
1113 		// Query binding point
1114 		const std::string	name	= arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx);
1115 		const glw::GLint	binding = m_bindings[iterNdx];
1116 		glw::GLint			val		= -1;
1117 
1118 		gl.getUniformiv(m_program->getProgram(), gl.getUniformLocation(m_program->getProgram(), name.c_str()), &val);
1119 		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
1120 		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
1121 
1122 		// Draw and verify
1123 		if (val != binding)
1124 			queryTestPassed = false;
1125 		if (!drawAndVerifyResult(m_textureColors[iterNdx]))
1126 			imageTestPassed = false;
1127 	}
1128 
1129 	setTestResult(queryTestPassed, imageTestPassed);
1130 	return STOP;
1131 }
1132 
generateShaders(void) const1133 glu::ShaderProgram* SamplerBindingRenderCase::generateShaders (void) const
1134 {
1135 	std::ostringstream		shaderUniformDecl;
1136 	std::ostringstream		shaderBody;
1137 
1138 	const std::string		texCoordType	= glu::getDataTypeName(getSamplerTexCoordType());
1139 	const std::string		samplerType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_samplerType));
1140 	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY) ? true : false;
1141 	const int				numDeclarations =  arrayInstance ? 1 : m_numBindings;
1142 
1143 	// Generate the uniform declarations for the vertex and fragment shaders
1144 	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1145 	{
1146 		shaderUniformDecl << "layout(binding = " << m_bindings[declNdx] << ") uniform highp " << samplerType << " "
1147 			<< (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1148 	}
1149 
1150 	// Generate the shader body for the vertex and fragment shaders
1151 	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1152 	{
1153 		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1154 					<< "	{\n"
1155 					<< "		color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n"
1156 					<< "	}\n";
1157 	}
1158 
1159 	shaderBody	<< "	else\n"
1160 				<< "	{\n"
1161 				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1162 				<< "	}\n";
1163 
1164 	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1165 					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
1166 					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
1167 }
1168 
initializeTexture(glw::GLint bindingPoint,glw::GLint textureName,const Vec4 & color) const1169 void SamplerBindingRenderCase::initializeTexture (glw::GLint bindingPoint, glw::GLint textureName, const Vec4& color) const
1170 {
1171 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1172 
1173 	gl.activeTexture(GL_TEXTURE0 + bindingPoint);
1174 	gl.bindTexture(m_textureType, textureName);
1175 	gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1176 
1177 	switch (m_textureType)
1178 	{
1179 		case GL_TEXTURE_2D:
1180 		{
1181 			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1182 			tcu::clear(level.getAccess(), color);
1183 			glu::texImage2D(m_context.getRenderContext(), m_textureType, 0, GL_RGBA8, level.getAccess());
1184 			break;
1185 		}
1186 
1187 		case GL_TEXTURE_3D:
1188 		{
1189 			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1190 			tcu::clear(level.getAccess(), color);
1191 			glu::texImage3D(m_context.getRenderContext(), m_textureType, 0, GL_RGBA8, level.getAccess());
1192 			break;
1193 		}
1194 
1195 		default:
1196 			DE_ASSERT(false);
1197 	}
1198 
1199 	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture initialization failed");
1200 }
1201 
getSamplerTexCoordType(void) const1202 glu::DataType SamplerBindingRenderCase::getSamplerTexCoordType (void) const
1203 {
1204 	switch (m_samplerType)
1205 	{
1206 		case GL_SAMPLER_2D:
1207 			return glu::TYPE_FLOAT_VEC2;
1208 
1209 		case GL_SAMPLER_3D:
1210 			return glu::TYPE_FLOAT_VEC3;
1211 
1212 		default:
1213 			DE_ASSERT(false);
1214 			return glu::TYPE_INVALID;
1215 	}
1216 }
1217 
1218 
1219 class SamplerBindingNegativeCase : public LayoutBindingNegativeCase
1220 {
1221 public:
1222 									SamplerBindingNegativeCase		(Context&		context,
1223 																	 const char*	name,
1224 																	 const char*	desc,
1225 																	 ShaderType		shaderType,
1226 																	 TestType		testType,
1227 																	 ErrorType		errorType,
1228 																	 glw::GLenum	samplerType);
1229 									~SamplerBindingNegativeCase		(void);
1230 
1231 private:
1232 	glu::ShaderProgram*				generateShaders					(void) const;
1233 	glu::DataType					getSamplerTexCoordType			(void) const;
1234 
1235 	const glw::GLenum				m_samplerType;
1236 };
1237 
SamplerBindingNegativeCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,ErrorType errorType,glw::GLenum samplerType)1238 SamplerBindingNegativeCase::SamplerBindingNegativeCase (Context&		context,
1239 														const char*		name,
1240 														const char*		desc,
1241 														ShaderType		shaderType,
1242 														TestType		testType,
1243 														ErrorType		errorType,
1244 														glw::GLenum		samplerType)
1245 	: LayoutBindingNegativeCase		(context,
1246 									 name,
1247 									 desc,
1248 									 shaderType,
1249 									 testType,
1250 									 errorType,
1251 									 GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
1252 									 GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
1253 									 GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS,
1254 									 GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS,
1255 									 GL_MAX_TEXTURE_IMAGE_UNITS,
1256 									 GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
1257 									 "u_sampler")
1258 	, m_samplerType					(samplerType)
1259 {
1260 }
1261 
~SamplerBindingNegativeCase(void)1262 SamplerBindingNegativeCase::~SamplerBindingNegativeCase (void)
1263 {
1264 	LayoutBindingNegativeCase::deinit();
1265 }
1266 
generateShaders(void) const1267 glu::ShaderProgram*	SamplerBindingNegativeCase::generateShaders	(void) const
1268 {
1269 	std::ostringstream		vertexUniformDecl;
1270 	std::ostringstream		fragmentUniformDecl;
1271 	std::ostringstream		tessCtrlUniformDecl;
1272 	std::ostringstream		tessEvalUniformDecl;
1273 	std::ostringstream		shaderBody;
1274 
1275 	const std::string		texCoordType	= glu::getDataTypeName(getSamplerTexCoordType());
1276 	const std::string		samplerType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_samplerType));
1277 	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1278 	const int				numDeclarations = arrayInstance ? 1 : m_numBindings;
1279 
1280 	// Generate the uniform declarations for the vertex and fragment shaders
1281 	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1282 	{
1283 		vertexUniformDecl << "layout(binding = " << m_vertexShaderBinding[declNdx] << ") uniform highp " << samplerType
1284 			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1285 		fragmentUniformDecl << "layout(binding = " << m_fragmentShaderBinding[declNdx] << ") uniform highp " << samplerType
1286 			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1287 		tessCtrlUniformDecl << "layout(binding = " << m_tessCtrlShaderBinding[declNdx] << ") uniform highp " << samplerType
1288 			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1289 		tessEvalUniformDecl << "layout(binding = " << m_tessEvalShaderBinding[declNdx] << ") uniform highp " << samplerType
1290 			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1291 	}
1292 
1293 	// Generate the shader body for the vertex and fragment shaders
1294 	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1295 	{
1296 		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1297 					<< "	{\n"
1298 					<< "		color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n"
1299 					<< "	}\n";
1300 	}
1301 
1302 	shaderBody	<< "	else\n"
1303 				<< "	{\n"
1304 				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1305 				<< "	}\n";
1306 
1307 	glu::ProgramSources sources = glu::ProgramSources()
1308 				<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
1309 				<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str()));
1310 
1311 	if (m_tessSupport)
1312 		sources << glu::TessellationControlSource(generateTessControlShader(m_shaderType, tessCtrlUniformDecl.str(), shaderBody.str()))
1313 				<< glu::TessellationEvaluationSource(generateTessEvaluationShader(m_shaderType, tessEvalUniformDecl.str(), shaderBody.str()));
1314 
1315 	return new glu::ShaderProgram(m_context.getRenderContext(), sources);
1316 
1317 }
1318 
getSamplerTexCoordType(void) const1319 glu::DataType SamplerBindingNegativeCase::getSamplerTexCoordType(void) const
1320 {
1321 	switch (m_samplerType)
1322 	{
1323 		case GL_SAMPLER_2D:
1324 			return glu::TYPE_FLOAT_VEC2;
1325 
1326 		case GL_SAMPLER_3D:
1327 			return glu::TYPE_FLOAT_VEC3;
1328 
1329 		default:
1330 			DE_ASSERT(false);
1331 			return glu::TYPE_INVALID;
1332 	}
1333 }
1334 
1335 class ImageBindingRenderCase : public LayoutBindingRenderCase
1336 {
1337 public:
1338 											ImageBindingRenderCase			(Context&		context,
1339 																			 const char*	name,
1340 																			 const char*	desc,
1341 																			 ShaderType		shaderType,
1342 																			 TestType		testType,
1343 																			 glw::GLenum	imageType,
1344 																			 glw::GLenum	textureType);
1345 											~ImageBindingRenderCase			(void);
1346 
1347 	void									init							(void);
1348 	void									deinit							(void);
1349 	IterateResult							iterate							(void);
1350 
1351 private:
1352 	glu::ShaderProgram*						generateShaders					(void) const;
1353 	void									initializeImage					(glw::GLint imageBindingPoint, glw::GLint textureBindingPoint, glw::GLint textureName, const Vec4& color) const;
1354 	glu::DataType							getImageTexCoordType			(void) const;
1355 
1356 	const glw::GLenum						m_imageType;
1357 	const glw::GLenum						m_textureType;
1358 
1359 	std::vector<glw::GLuint>				m_textures;
1360 	std::vector<Vec4>						m_textureColors;
1361 };
1362 
1363 
ImageBindingRenderCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,glw::GLenum imageType,glw::GLenum textureType)1364 ImageBindingRenderCase::ImageBindingRenderCase (Context&		context,
1365 												const char*		name,
1366 												const char*		desc,
1367 												ShaderType		shaderType,
1368 												TestType		testType,
1369 												glw::GLenum		imageType,
1370 												glw::GLenum		textureType)
1371 	: LayoutBindingRenderCase		(context, name, desc, shaderType, testType, GL_MAX_IMAGE_UNITS, GL_MAX_VERTEX_IMAGE_UNIFORMS, GL_MAX_FRAGMENT_IMAGE_UNIFORMS, GL_MAX_COMBINED_IMAGE_UNIFORMS, "u_image")
1372 	, m_imageType					(imageType)
1373 	, m_textureType					(textureType)
1374 {
1375 }
1376 
~ImageBindingRenderCase(void)1377 ImageBindingRenderCase::~ImageBindingRenderCase (void)
1378 {
1379 	deinit();
1380 }
1381 
init(void)1382 void ImageBindingRenderCase::init (void)
1383 {
1384 	LayoutBindingRenderCase::init();
1385 
1386 	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
1387 	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);
1388 
1389 	// Initialize image / texture resources
1390 	m_textures = std::vector<glw::GLuint>(m_numBindings,  0);
1391 
1392 	// Texture colors
1393 	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1394 		m_textureColors.push_back(getRandomColor(rnd));
1395 
1396 	// Image textures
1397 	gl.genTextures(m_numBindings, &m_textures[0]);
1398 
1399 	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1400 		initializeImage(m_bindings[texNdx], texNdx, m_textures[texNdx], m_textureColors[texNdx]);
1401 }
1402 
deinit(void)1403 void ImageBindingRenderCase::deinit (void)
1404 {
1405 	LayoutBindingRenderCase::deinit();
1406 
1407 	// Clean up texture data
1408 	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1409 	{
1410 		if (m_textures[texNdx])
1411 		{
1412 			m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[texNdx]);
1413 			m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0);
1414 		}
1415 	}
1416 }
1417 
iterate(void)1418 TestCase::IterateResult ImageBindingRenderCase::iterate	(void)
1419 {
1420 	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
1421 	const int				iterations		= m_numBindings;
1422 	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1423 	bool					queryTestPassed	= true;
1424 	bool					imageTestPassed = true;
1425 
1426 	// Set the viewport and enable the shader program
1427 	initRenderState();
1428 
1429 	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
1430 	{
1431 		// Set the uniform value indicating the current array index
1432 		gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx);
1433 
1434 		const std::string	name	= (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
1435 		const glw::GLint	binding = m_bindings[iterNdx];
1436 		glw::GLint			val		= -1;
1437 
1438 		gl.getUniformiv(m_program->getProgram(), gl.getUniformLocation(m_program->getProgram(), name.c_str()), &val);
1439 		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
1440 		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
1441 
1442 		// Draw and verify
1443 		if (val != binding)
1444 			queryTestPassed = false;
1445 		if (!drawAndVerifyResult(m_textureColors[iterNdx]))
1446 			imageTestPassed = false;
1447 	}
1448 
1449 	setTestResult(queryTestPassed, imageTestPassed);
1450 	return STOP;
1451 }
1452 
initializeImage(glw::GLint imageBindingPoint,glw::GLint textureBindingPoint,glw::GLint textureName,const Vec4 & color) const1453 void ImageBindingRenderCase::initializeImage (glw::GLint imageBindingPoint, glw::GLint textureBindingPoint, glw::GLint textureName, const Vec4& color) const
1454 {
1455 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1456 
1457 	gl.activeTexture(GL_TEXTURE0 + textureBindingPoint);
1458 	gl.bindTexture(m_textureType, textureName);
1459 	gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1460 
1461 	switch (m_textureType)
1462 	{
1463 		case GL_TEXTURE_2D:
1464 		{
1465 			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1466 			tcu::clear(level.getAccess(), color);
1467 			gl.texStorage2D(m_textureType, 1, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1468 			gl.texSubImage2D(m_textureType, 0, 0, 0, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, level.getAccess().getDataPtr());
1469 			break;
1470 		}
1471 
1472 		case GL_TEXTURE_3D:
1473 		{
1474 			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1475 			tcu::clear(level.getAccess(), color);
1476 			gl.texStorage3D(m_textureType, 1, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1477 			gl.texSubImage3D(m_textureType, 0, 0, 0, 0, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, level.getAccess().getDataPtr());
1478 			break;
1479 		}
1480 
1481 		default:
1482 			DE_ASSERT(false);
1483 	}
1484 
1485 	gl.bindTexture(m_textureType, 0);
1486 	gl.bindImageTexture(imageBindingPoint, textureName, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA8);
1487 	GLU_EXPECT_NO_ERROR(gl.getError(), "Image initialization failed");
1488 }
1489 
generateShaders(void) const1490 glu::ShaderProgram* ImageBindingRenderCase::generateShaders (void) const
1491 {
1492 	std::ostringstream		shaderUniformDecl;
1493 	std::ostringstream		shaderBody;
1494 
1495 	const std::string		texCoordType	= glu::getDataTypeName(getImageTexCoordType());
1496 	const std::string		imageType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_imageType));
1497 	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY) ? true : false;
1498 	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
1499 
1500 	// Generate the uniform declarations for the vertex and fragment shaders
1501 	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1502 	{
1503 		shaderUniformDecl << "layout(rgba8, binding = " << m_bindings[declNdx] << ") uniform readonly highp " << imageType
1504 			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1505 	}
1506 
1507 	// Generate the shader body for the vertex and fragment shaders
1508 	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1509 	{
1510 		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1511 					<< "	{\n"
1512 					<< "		color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n"
1513 					<< "	}\n";
1514 	}
1515 
1516 	shaderBody	<< "	else\n"
1517 				<< "	{\n"
1518 				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1519 				<< "	}\n";
1520 
1521 	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1522 					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
1523 					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
1524 }
1525 
getImageTexCoordType(void) const1526 glu::DataType ImageBindingRenderCase::getImageTexCoordType(void) const
1527 {
1528 	switch (m_imageType)
1529 	{
1530 		case GL_IMAGE_2D:
1531 			return glu::TYPE_INT_VEC2;
1532 
1533 		case GL_IMAGE_3D:
1534 			return glu::TYPE_INT_VEC3;
1535 
1536 		default:
1537 			DE_ASSERT(false);
1538 			return glu::TYPE_INVALID;
1539 	}
1540 }
1541 
1542 
1543 class ImageBindingNegativeCase : public LayoutBindingNegativeCase
1544 {
1545 public:
1546 											ImageBindingNegativeCase		(Context&		context,
1547 																			 const char*	name,
1548 																			 const char*	desc,
1549 																			 ShaderType		shaderType,
1550 																			 TestType		testType,
1551 																			 ErrorType		errorType,
1552 																			 glw::GLenum	imageType);
1553 											~ImageBindingNegativeCase		(void);
1554 
1555 private:
1556 	glu::ShaderProgram*						generateShaders					(void) const;
1557 	glu::DataType							getImageTexCoordType			(void) const;
1558 
1559 	const glw::GLenum						m_imageType;
1560 };
1561 
ImageBindingNegativeCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,ErrorType errorType,glw::GLenum imageType)1562 ImageBindingNegativeCase::ImageBindingNegativeCase (Context&		context,
1563 													const char*		name,
1564 													const char*		desc,
1565 													ShaderType		shaderType,
1566 													TestType		testType,
1567 													ErrorType		errorType,
1568 													glw::GLenum		imageType)
1569 	: LayoutBindingNegativeCase		(context,
1570 									 name,
1571 									 desc,
1572 									 shaderType,
1573 									 testType,
1574 									 errorType,
1575 									 GL_MAX_IMAGE_UNITS,
1576 									 GL_MAX_VERTEX_IMAGE_UNIFORMS,
1577 									 GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS,
1578 									 GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS,
1579 									 GL_MAX_FRAGMENT_IMAGE_UNIFORMS,
1580 									 GL_MAX_COMBINED_IMAGE_UNIFORMS,
1581 									 "u_image")
1582 	, m_imageType					(imageType)
1583 {
1584 }
1585 
~ImageBindingNegativeCase(void)1586 ImageBindingNegativeCase::~ImageBindingNegativeCase (void)
1587 {
1588 	deinit();
1589 }
1590 
generateShaders(void) const1591 glu::ShaderProgram* ImageBindingNegativeCase::generateShaders (void) const
1592 {
1593 	std::ostringstream		vertexUniformDecl;
1594 	std::ostringstream		fragmentUniformDecl;
1595 	std::ostringstream		tessCtrlUniformDecl;
1596 	std::ostringstream		tessEvalUniformDecl;
1597 	std::ostringstream		shaderBody;
1598 
1599 	const std::string		texCoordType	= glu::getDataTypeName(getImageTexCoordType());
1600 	const std::string		imageType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_imageType));
1601 	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1602 	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
1603 
1604 	// Generate the uniform declarations for the vertex and fragment shaders
1605 	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1606 	{
1607 		vertexUniformDecl << "layout(rgba8, binding = " << m_vertexShaderBinding[declNdx] << ") uniform readonly highp " << imageType
1608 			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1609 		fragmentUniformDecl << "layout(rgba8, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform readonly highp " << imageType
1610 			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1611 		tessCtrlUniformDecl << "layout(rgba8, binding = " << m_tessCtrlShaderBinding[declNdx] << ") uniform readonly highp " << imageType
1612 			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1613 		tessEvalUniformDecl << "layout(rgba8, binding = " << m_tessEvalShaderBinding[declNdx] << ") uniform readonly highp " << imageType
1614 			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1615 	}
1616 
1617 	// Generate the shader body for the vertex and fragment shaders
1618 	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1619 	{
1620 		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1621 					<< "	{\n"
1622 					<< "		color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n"
1623 					<< "	}\n";
1624 	}
1625 
1626 	shaderBody	<< "	else\n"
1627 				<< "	{\n"
1628 				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1629 				<< "	}\n";
1630 
1631 	glu::ProgramSources sources = glu::ProgramSources()
1632 				<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
1633 				<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str()));
1634 
1635 	if (m_tessSupport)
1636 		sources << glu::TessellationControlSource(generateTessControlShader(m_shaderType, tessCtrlUniformDecl.str(), shaderBody.str()))
1637 				<< glu::TessellationEvaluationSource(generateTessEvaluationShader(m_shaderType, tessEvalUniformDecl.str(), shaderBody.str()));
1638 
1639 	return new glu::ShaderProgram(m_context.getRenderContext(), sources);
1640 }
1641 
getImageTexCoordType(void) const1642 glu::DataType ImageBindingNegativeCase::getImageTexCoordType(void) const
1643 {
1644 	switch (m_imageType)
1645 	{
1646 		case GL_IMAGE_2D:
1647 			return glu::TYPE_INT_VEC2;
1648 
1649 		case GL_IMAGE_3D:
1650 			return glu::TYPE_INT_VEC3;
1651 
1652 		default:
1653 			DE_ASSERT(false);
1654 			return glu::TYPE_INVALID;
1655 	}
1656 }
1657 
1658 
1659 class UBOBindingRenderCase : public LayoutBindingRenderCase
1660 {
1661 public:
1662 											UBOBindingRenderCase		(Context&		context,
1663 																		 const char*	name,
1664 																		 const char*	desc,
1665 																		 ShaderType		shaderType,
1666 																		 TestType		testType);
1667 											~UBOBindingRenderCase		(void);
1668 
1669 	void									init						(void);
1670 	void									deinit						(void);
1671 	IterateResult							iterate						(void);
1672 
1673 private:
1674 	glu::ShaderProgram*						generateShaders				(void) const;
1675 
1676 	std::vector<deUint32>					m_buffers;
1677 	std::vector<Vec4>						m_expectedColors;
1678 };
1679 
UBOBindingRenderCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType)1680 UBOBindingRenderCase::UBOBindingRenderCase (Context&		context,
1681 											const char*		name,
1682 											const char*		desc,
1683 											ShaderType		shaderType,
1684 											TestType		testType)
1685 	: LayoutBindingRenderCase (context, name, desc, shaderType, testType, GL_MAX_UNIFORM_BUFFER_BINDINGS, GL_MAX_VERTEX_UNIFORM_BLOCKS, GL_MAX_FRAGMENT_UNIFORM_BLOCKS, GL_MAX_COMBINED_UNIFORM_BLOCKS, "ColorBlock")
1686 {
1687 }
1688 
~UBOBindingRenderCase(void)1689 UBOBindingRenderCase::~UBOBindingRenderCase (void)
1690 {
1691 	deinit();
1692 }
1693 
init(void)1694 void UBOBindingRenderCase::init (void)
1695 {
1696 	LayoutBindingRenderCase::init();
1697 
1698 	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
1699 	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);
1700 
1701 	// Initialize UBOs and related data
1702 	m_buffers = std::vector<glw::GLuint>(m_numBindings,  0);
1703 	gl.genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]);
1704 
1705 	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1706 	{
1707 			m_expectedColors.push_back(getRandomColor(rnd));
1708 			m_expectedColors.push_back(getRandomColor(rnd));
1709 	}
1710 
1711 	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1712 	{
1713 		gl.bindBuffer(GL_UNIFORM_BUFFER, m_buffers[bufNdx]);
1714 		gl.bufferData(GL_UNIFORM_BUFFER, 2*sizeof(Vec4), &(m_expectedColors[2*bufNdx]), GL_STATIC_DRAW);
1715 		gl.bindBufferBase(GL_UNIFORM_BUFFER, m_bindings[bufNdx], m_buffers[bufNdx]);
1716 	}
1717 
1718 	GLU_EXPECT_NO_ERROR(gl.getError(), "UBO setup failed");
1719 }
1720 
deinit(void)1721 void UBOBindingRenderCase::deinit (void)
1722 {
1723 	LayoutBindingRenderCase::deinit();
1724 
1725 	// Clean up UBO data
1726 	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1727 	{
1728 		if (m_buffers[bufNdx])
1729 		{
1730 			m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffers[bufNdx]);
1731 			m_context.getRenderContext().getFunctions().bindBuffer(GL_UNIFORM_BUFFER, 0);
1732 		}
1733 	}
1734 }
1735 
iterate(void)1736 TestCase::IterateResult UBOBindingRenderCase::iterate (void)
1737 {
1738 	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
1739 	const int				iterations		= m_numBindings;
1740 	const glw::GLenum		prop			= GL_BUFFER_BINDING;
1741 	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1742 	bool					queryTestPassed	= true;
1743 	bool					imageTestPassed = true;
1744 
1745 	// Set the viewport and enable the shader program
1746 	initRenderState();
1747 
1748 	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
1749 	{
1750 		// Query binding point
1751 		const std::string	name	= (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
1752 		const glw::GLint	binding = m_bindings[iterNdx];
1753 		glw::GLint			val		= -1;
1754 
1755 		gl.getProgramResourceiv(m_program->getProgram(), GL_UNIFORM_BLOCK, gl.getProgramResourceIndex(m_program->getProgram(), GL_UNIFORM_BLOCK, name.c_str() ), 1, &prop, 1, DE_NULL, &val);
1756 		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
1757 		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
1758 
1759 		if (val != binding)
1760 			queryTestPassed = false;
1761 
1762 		// Draw twice to render both colors within the UBO
1763 		for (int drawCycle = 0; drawCycle < 2; ++drawCycle)
1764 		{
1765 			// Set the uniform indicating the array index to be used and set the expected color
1766 			const int arrayNdx = iterNdx*2 + drawCycle;
1767 			gl.uniform1i(m_shaderProgramArrayNdxLoc, arrayNdx);
1768 
1769 			if (!drawAndVerifyResult(m_expectedColors[arrayNdx]))
1770 				imageTestPassed = false;
1771 		}
1772 	}
1773 
1774 	setTestResult(queryTestPassed, imageTestPassed);
1775 	return STOP;
1776 }
1777 
generateShaders(void) const1778 glu::ShaderProgram* UBOBindingRenderCase::generateShaders (void) const
1779 {
1780 	std::ostringstream		shaderUniformDecl;
1781 	std::ostringstream		shaderBody;
1782 	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1783 	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
1784 
1785 	// Generate the uniform declarations for the vertex and fragment shaders
1786 	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1787 	{
1788 		shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") uniform "
1789 			<< getUniformName(m_uniformName, declNdx) << "\n"
1790 			<< "{\n"
1791 			<< "	highp vec4 color1;\n"
1792 			<< "	highp vec4 color2;\n"
1793 			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1794 	}
1795 
1796 	// Generate the shader body for the vertex and fragment shaders
1797 	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
1798 	{
1799 		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
1800 		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1801 					<< "	{\n"
1802 					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
1803 					<< "	}\n";
1804 	}
1805 
1806 	shaderBody	<< "	else\n"
1807 				<< "	{\n"
1808 				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1809 				<< "	}\n";
1810 
1811 	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1812 					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
1813 					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
1814 }
1815 
1816 
1817 class UBOBindingNegativeCase : public LayoutBindingNegativeCase
1818 {
1819 public:
1820 											UBOBindingNegativeCase			(Context&		context,
1821 																			 const char*	name,
1822 																			 const char*	desc,
1823 																			 ShaderType		shaderType,
1824 																			 TestType		testType,
1825 																			 ErrorType		errorType);
1826 											~UBOBindingNegativeCase			(void);
1827 
1828 private:
1829 	glu::ShaderProgram*						generateShaders					(void) const;
1830 };
1831 
UBOBindingNegativeCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,ErrorType errorType)1832 UBOBindingNegativeCase::UBOBindingNegativeCase (Context&		context,
1833 												const char*		name,
1834 												const char*		desc,
1835 												ShaderType		shaderType,
1836 												TestType		testType,
1837 												ErrorType		errorType)
1838 	: LayoutBindingNegativeCase(context,
1839 								name,
1840 								desc,
1841 								shaderType,
1842 								testType,
1843 								errorType,
1844 								GL_MAX_UNIFORM_BUFFER_BINDINGS,
1845 								GL_MAX_VERTEX_UNIFORM_BLOCKS,
1846 								GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS,
1847 								GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS,
1848 								GL_MAX_FRAGMENT_UNIFORM_BLOCKS,
1849 								GL_MAX_COMBINED_UNIFORM_BLOCKS,
1850 								"ColorBlock")
1851 {
1852 }
1853 
~UBOBindingNegativeCase(void)1854 UBOBindingNegativeCase::~UBOBindingNegativeCase (void)
1855 {
1856 	deinit();
1857 }
1858 
generateShaders(void) const1859 glu::ShaderProgram* UBOBindingNegativeCase::generateShaders (void) const
1860 {
1861 	std::ostringstream		vertexUniformDecl;
1862 	std::ostringstream		fragmentUniformDecl;
1863 	std::ostringstream		tessCtrlUniformDecl;
1864 	std::ostringstream		tessEvalUniformDecl;
1865 	std::ostringstream		shaderBody;
1866 	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1867 	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
1868 
1869 	// Generate the uniform declarations for the vertex and fragment shaders
1870 	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1871 	{
1872 		vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[declNdx] << ") uniform "
1873 			<< getUniformName(m_uniformName, declNdx) << "\n"
1874 			<< "{\n"
1875 			<< "	highp vec4 color1;\n"
1876 			<< "	highp vec4 color2;\n"
1877 			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1878 
1879 		fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform "
1880 			<< getUniformName(m_uniformName, declNdx) << "\n"
1881 			<< "{\n"
1882 			<< "	highp vec4 color1;\n"
1883 			<< "	highp vec4 color2;\n"
1884 			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1885 
1886 		tessCtrlUniformDecl << "layout(std140, binding = " << m_tessCtrlShaderBinding[declNdx] << ") uniform "
1887 			<< getUniformName(m_uniformName, declNdx) << "\n"
1888 			<< "{\n"
1889 			<< "	highp vec4 color1;\n"
1890 			<< "	highp vec4 color2;\n"
1891 			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1892 
1893 		tessEvalUniformDecl << "layout(std140, binding = " << m_tessCtrlShaderBinding[declNdx] << ") uniform "
1894 			<< getUniformName(m_uniformName, declNdx) << "\n"
1895 			<< "{\n"
1896 			<< "	highp vec4 color1;\n"
1897 			<< "	highp vec4 color2;\n"
1898 			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1899 	}
1900 
1901 	// Generate the shader body for the vertex and fragment shaders
1902 	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
1903 	{
1904 		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
1905 		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1906 					<< "	{\n"
1907 					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
1908 					<< "	}\n";
1909 	}
1910 
1911 	shaderBody	<< "	else\n"
1912 				<< "	{\n"
1913 				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1914 				<< "	}\n";
1915 
1916 	glu::ProgramSources sources = glu::ProgramSources()
1917 				<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
1918 				<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str()));
1919 
1920 	if (m_tessSupport)
1921 		sources << glu::TessellationControlSource(generateTessControlShader(m_shaderType, tessCtrlUniformDecl.str(), shaderBody.str()))
1922 				<< glu::TessellationEvaluationSource(generateTessEvaluationShader(m_shaderType, tessEvalUniformDecl.str(), shaderBody.str()));
1923 
1924 	return new glu::ShaderProgram(m_context.getRenderContext(), sources);
1925 }
1926 
1927 
1928 class SSBOBindingRenderCase : public LayoutBindingRenderCase
1929 {
1930 public:
1931 											SSBOBindingRenderCase		(Context&		context,
1932 																		 const char*	name,
1933 																		 const char*	desc,
1934 																		 ShaderType		shaderType,
1935 																		 TestType		testType);
1936 											~SSBOBindingRenderCase		(void);
1937 
1938 	void									init						(void);
1939 	void									deinit						(void);
1940 	IterateResult							iterate						(void);
1941 
1942 private:
1943 	glu::ShaderProgram*						generateShaders				(void) const;
1944 
1945 	std::vector<glw::GLuint>				m_buffers;
1946 	std::vector<Vec4>						m_expectedColors;
1947 };
1948 
SSBOBindingRenderCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType)1949 SSBOBindingRenderCase::SSBOBindingRenderCase (Context&		context,
1950 											  const char*	name,
1951 											  const char*	desc,
1952 											  ShaderType	shaderType,
1953 											  TestType		testType)
1954 	: LayoutBindingRenderCase (context, name, desc, shaderType, testType, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, "ColorBuffer")
1955 {
1956 }
1957 
~SSBOBindingRenderCase(void)1958 SSBOBindingRenderCase::~SSBOBindingRenderCase (void)
1959 {
1960 	deinit();
1961 }
1962 
init(void)1963 void SSBOBindingRenderCase::init (void)
1964 {
1965 	LayoutBindingRenderCase::init();
1966 
1967 	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
1968 	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);
1969 
1970 	// Initialize SSBOs and related data
1971 	m_buffers = std::vector<glw::GLuint>(m_numBindings, 0);
1972 	gl.genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]);
1973 
1974 	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1975 	{
1976 		m_expectedColors.push_back(getRandomColor(rnd));
1977 		m_expectedColors.push_back(getRandomColor(rnd));
1978 	}
1979 
1980 	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1981 	{
1982 		gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffers[bufNdx]);
1983 		gl.bufferData(GL_SHADER_STORAGE_BUFFER, 2*sizeof(Vec4), &(m_expectedColors[2*bufNdx]), GL_STATIC_DRAW);
1984 		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, m_bindings[bufNdx], m_buffers[bufNdx]);
1985 	}
1986 
1987 	GLU_EXPECT_NO_ERROR(gl.getError(), "SSBO setup failed");
1988 }
1989 
deinit(void)1990 void SSBOBindingRenderCase::deinit (void)
1991 {
1992 	LayoutBindingRenderCase::deinit();
1993 
1994 	// Clean up SSBO data
1995 	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1996 	{
1997 		if (m_buffers[bufNdx])
1998 		{
1999 			m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffers[bufNdx]);
2000 			m_context.getRenderContext().getFunctions().bindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
2001 			m_buffers[bufNdx] = 0;
2002 		}
2003 	}
2004 }
2005 
iterate(void)2006 TestCase::IterateResult SSBOBindingRenderCase::iterate (void)
2007 {
2008 	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
2009 	const int				iterations		= m_numBindings;
2010 	const glw::GLenum		prop			= GL_BUFFER_BINDING;
2011 	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
2012 	bool					queryTestPassed	= true;
2013 	bool					imageTestPassed = true;
2014 
2015 	initRenderState();
2016 
2017 	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
2018 	{
2019 		// Query binding point
2020 		const std::string	name	= (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
2021 		const glw::GLint	binding = m_bindings[iterNdx];
2022 		glw::GLint			val		= -1;
2023 
2024 		gl.getProgramResourceiv(m_program->getProgram(), GL_SHADER_STORAGE_BLOCK, gl.getProgramResourceIndex(m_program->getProgram(), GL_SHADER_STORAGE_BLOCK, name.c_str() ), 1, &prop, 1, DE_NULL, &val);
2025 		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
2026 		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
2027 
2028 		if (val != binding)
2029 			queryTestPassed = false;
2030 
2031 		// Draw twice to render both colors within the SSBO
2032 		for (int drawCycle = 0; drawCycle < 2; ++drawCycle)
2033 		{
2034 			// Set the uniform indicating the array index to be used and set the expected color
2035 			const int arrayNdx = iterNdx*2 + drawCycle;
2036 			gl.uniform1i(m_shaderProgramArrayNdxLoc, arrayNdx);
2037 
2038 			if (!drawAndVerifyResult(m_expectedColors[arrayNdx]))
2039 				imageTestPassed = false;
2040 		}
2041 	}
2042 
2043 	setTestResult(queryTestPassed, imageTestPassed);
2044 	return STOP;
2045 }
2046 
generateShaders(void) const2047 glu::ShaderProgram* SSBOBindingRenderCase::generateShaders (void) const
2048 {
2049 	std::ostringstream		shaderUniformDecl;
2050 	std::ostringstream		shaderBody;
2051 	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
2052 	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
2053 
2054 	// Generate the uniform declarations for the vertex and fragment shaders
2055 	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
2056 	{
2057 		shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") buffer "
2058 			<< getUniformName(m_uniformName, declNdx) << "\n"
2059 			<< "{\n"
2060 			<< "	highp vec4 color1;\n"
2061 			<< "	highp vec4 color2;\n"
2062 			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
2063 	}
2064 
2065 	// Generate the shader body for the vertex and fragment shaders
2066 	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
2067 	{
2068 		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
2069 		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
2070 					<< "	{\n"
2071 					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
2072 					<< "	}\n";
2073 	}
2074 
2075 	shaderBody	<< "	else\n"
2076 				<< "	{\n"
2077 				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
2078 				<< "	}\n";
2079 
2080 	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
2081 					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
2082 					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
2083 }
2084 
2085 
2086 class SSBOBindingNegativeCase : public LayoutBindingNegativeCase
2087 {
2088 public:
2089 											SSBOBindingNegativeCase			(Context&		context,
2090 																			 const char*	name,
2091 																			 const char*	desc,
2092 																			 ShaderType		shaderType,
2093 																			 TestType		testType,
2094 																			 ErrorType		errorType);
2095 											~SSBOBindingNegativeCase		(void);
2096 
2097 private:
2098 	glu::ShaderProgram*						generateShaders					(void) const;
2099 };
2100 
SSBOBindingNegativeCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,ErrorType errorType)2101 SSBOBindingNegativeCase::SSBOBindingNegativeCase (Context& context,
2102 												  const char* name,
2103 												  const char* desc,
2104 												  ShaderType shaderType,
2105 												  TestType testType,
2106 												  ErrorType errorType)
2107 	: LayoutBindingNegativeCase(context,
2108 								name,
2109 								desc,
2110 								shaderType,
2111 								testType,
2112 								errorType,
2113 								GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS,
2114 								GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS,
2115 								GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS,
2116 								GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS,
2117 								GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS,
2118 								GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS,
2119 								"ColorBuffer")
2120 {
2121 }
2122 
~SSBOBindingNegativeCase(void)2123 SSBOBindingNegativeCase::~SSBOBindingNegativeCase (void)
2124 {
2125 	deinit();
2126 }
2127 
generateShaders(void) const2128 glu::ShaderProgram* SSBOBindingNegativeCase::generateShaders (void) const
2129 {
2130 	std::ostringstream		vertexUniformDecl;
2131 	std::ostringstream		fragmentUniformDecl;
2132 	std::ostringstream		tessCtrlUniformDecl;
2133 	std::ostringstream		tessEvalUniformDecl;
2134 	std::ostringstream		shaderBody;
2135 	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
2136 	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
2137 
2138 	// Generate the uniform declarations for the vertex and fragment shaders
2139 	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
2140 	{
2141 		vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[declNdx] << ") buffer "
2142 			<< getUniformName(m_uniformName, declNdx) << "\n"
2143 			<< "{\n"
2144 			<< "	highp vec4 color1;\n"
2145 			<< "	highp vec4 color2;\n"
2146 			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
2147 
2148 		fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") buffer "
2149 			<< getUniformName(m_uniformName, declNdx) << "\n"
2150 			<< "{\n"
2151 			<< "	highp vec4 color1;\n"
2152 			<< "	highp vec4 color2;\n"
2153 			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
2154 
2155 		tessCtrlUniformDecl << "layout(std140, binding = " << m_tessCtrlShaderBinding[declNdx] << ") buffer "
2156 			<< getUniformName(m_uniformName, declNdx) << "\n"
2157 			<< "{\n"
2158 			<< "	highp vec4 color1;\n"
2159 			<< "	highp vec4 color2;\n"
2160 			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
2161 
2162 		tessEvalUniformDecl << "layout(std140, binding = " << m_tessEvalShaderBinding[declNdx] << ") buffer "
2163 			<< getUniformName(m_uniformName, declNdx) << "\n"
2164 			<< "{\n"
2165 			<< "	highp vec4 color1;\n"
2166 			<< "	highp vec4 color2;\n"
2167 			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
2168 	}
2169 
2170 	// Generate the shader body for the vertex and fragment shaders
2171 	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
2172 	{
2173 		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
2174 		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
2175 					<< "	{\n"
2176 					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
2177 					<< "	}\n";
2178 	}
2179 
2180 	shaderBody	<< "	else\n"
2181 				<< "	{\n"
2182 				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
2183 				<< "	}\n";
2184 
2185 	glu::ProgramSources sources = glu::ProgramSources()
2186 				<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
2187 				<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str()));
2188 
2189 	if (m_tessSupport)
2190 		sources << glu::TessellationControlSource(generateTessControlShader(m_shaderType, tessCtrlUniformDecl.str(), shaderBody.str()))
2191 				<< glu::TessellationEvaluationSource(generateTessEvaluationShader(m_shaderType, tessEvalUniformDecl.str(), shaderBody.str()));
2192 
2193 	return new glu::ShaderProgram(m_context.getRenderContext(), sources);
2194 }
2195 
2196 
2197 } // Anonymous
2198 
LayoutBindingTests(Context & context)2199 LayoutBindingTests::LayoutBindingTests (Context& context)
2200 	: TestCaseGroup (context, "layout_binding", "Layout binding tests")
2201 {
2202 }
2203 
~LayoutBindingTests(void)2204 LayoutBindingTests::~LayoutBindingTests (void)
2205 {
2206 }
2207 
init(void)2208 void LayoutBindingTests::init (void)
2209 {
2210 	// Render test groups
2211 	tcu::TestCaseGroup* const samplerBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "sampler",		"Test sampler layout binding");
2212 	tcu::TestCaseGroup* const sampler2dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "sampler2d",	"Test sampler2d layout binding");
2213 	tcu::TestCaseGroup* const sampler3dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "sampler3d",	"Test sampler3d layout binding");
2214 
2215 	tcu::TestCaseGroup* const imageBindingTestGroup				= new tcu::TestCaseGroup(m_testCtx, "image",		"Test image layout binding");
2216 	tcu::TestCaseGroup* const image2dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "image2d",		"Test image2d layout binding");
2217 	tcu::TestCaseGroup* const image3dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "image3d",		"Test image3d layout binding");
2218 
2219 	tcu::TestCaseGroup* const UBOBindingTestGroup				= new tcu::TestCaseGroup(m_testCtx, "ubo",			"Test UBO layout binding");
2220 	tcu::TestCaseGroup* const SSBOBindingTestGroup				= new tcu::TestCaseGroup(m_testCtx, "ssbo",			"Test SSBO layout binding");
2221 
2222 	// Negative test groups
2223 	tcu::TestCaseGroup* const negativeBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "negative",		"Test layout binding with invalid bindings");
2224 
2225 	tcu::TestCaseGroup* const negativeSamplerBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "sampler",		"Test sampler layout binding with invalid bindings");
2226 	tcu::TestCaseGroup* const negativeSampler2dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "sampler2d",	"Test sampler2d layout binding with invalid bindings");
2227 	tcu::TestCaseGroup* const negativeSampler3dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "sampler3d",	"Test sampler3d layout binding with invalid bindings");
2228 
2229 	tcu::TestCaseGroup* const negativeImageBindingTestGroup		= new tcu::TestCaseGroup(m_testCtx, "image",		"Test image layout binding with invalid bindings");
2230 	tcu::TestCaseGroup* const negativeImage2dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "image2d",		"Test image2d layout binding with invalid bindings");
2231 	tcu::TestCaseGroup* const negativeImage3dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "image3d",		"Test image3d layout binding with invalid bindings");
2232 
2233 	tcu::TestCaseGroup* const negativeUBOBindingTestGroup		= new tcu::TestCaseGroup(m_testCtx, "ubo",			"Test UBO layout binding with invalid bindings");
2234 	tcu::TestCaseGroup* const negativeSSBOBindingTestGroup		= new tcu::TestCaseGroup(m_testCtx, "ssbo",			"Test SSBO layout binding with invalid bindings");
2235 
2236 	static const struct RenderTestType
2237 	{
2238 		ShaderType				shaderType;
2239 		TestType				testType;
2240 		std::string				name;
2241 		std::string				descPostfix;
2242 	} s_renderTestTypes[] =
2243 	{
2244 		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_SINGLE,		"vertex_binding_single",		"a single instance" },
2245 		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_MAX,			"vertex_binding_max",			"maximum binding point"	},
2246 		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_MULTIPLE,		"vertex_binding_multiple",		"multiple instances"},
2247 		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_ARRAY,			"vertex_binding_array",			"an array instance" },
2248 		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_MAX_ARRAY,		"vertex_binding_max_array",		"an array instance with maximum binding point" },
2249 
2250 		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_SINGLE,		"fragment_binding_single",		"a single instance" },
2251 		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_MAX,			"fragment_binding_max",			"maximum binding point"	},
2252 		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_MULTIPLE,		"fragment_binding_multiple",	"multiple instances"},
2253 		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_ARRAY,			"fragment_binding_array",		"an array instance" },
2254 		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_MAX_ARRAY,		"fragment_binding_max_array",	"an array instance with maximum binding point" },
2255 	};
2256 
2257 	static const struct NegativeTestType
2258 	{
2259 		ShaderType								shaderType;
2260 		TestType								testType;
2261 		LayoutBindingNegativeCase::ErrorType	errorType;
2262 		std::string								name;
2263 		std::string								descPostfix;
2264 	} s_negativeTestTypes[] =
2265 	{
2266 		{ SHADERTYPE_VERTEX,			TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"vertex_binding_over_max",					"over maximum binding point"   },
2267 		{ SHADERTYPE_FRAGMENT,			TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"fragment_binding_over_max",				"over maximum binding point"   },
2268 		{ SHADERTYPE_TESS_CONTROL,		TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"tess_control_binding_over_max",			"over maximum binding point"   },
2269 		{ SHADERTYPE_TESS_EVALUATION,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"tess_evaluation_binding_over_max",			"over maximum binding point"   },
2270 		{ SHADERTYPE_VERTEX,			TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"vertex_binding_neg",						"negative binding point"	   },
2271 		{ SHADERTYPE_FRAGMENT,			TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"fragment_binding_neg",						"negative binding point"	   },
2272 		{ SHADERTYPE_TESS_CONTROL,		TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"tess_control_binding_neg",					"negative binding point"	   },
2273 		{ SHADERTYPE_TESS_EVALUATION,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"tess_evaluation_binding_neg",				"negative binding point"	   },
2274 
2275 		{ SHADERTYPE_VERTEX,			TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"vertex_binding_over_max_array",			"over maximum binding point"   },
2276 		{ SHADERTYPE_FRAGMENT,			TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"fragment_binding_over_max_array",			"over maximum binding point"   },
2277 		{ SHADERTYPE_TESS_CONTROL,		TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"tess_control_binding_over_max_array",		"over maximum binding point"   },
2278 		{ SHADERTYPE_TESS_EVALUATION,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"tess_evaluation_binding_over_max_array",	"over maximum binding point"   },
2279 		{ SHADERTYPE_VERTEX,			TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"vertex_binding_neg_array",					"negative binding point"	   },
2280 		{ SHADERTYPE_FRAGMENT,			TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"fragment_binding_neg_array",				"negative binding point"	   },
2281 		{ SHADERTYPE_TESS_CONTROL,		TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"tess_control_binding_neg_array",			"negative binding point"	   },
2282 		{ SHADERTYPE_TESS_EVALUATION,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"tess_evaluation_binding_neg_array",		"negative binding point"	   },
2283 
2284 		{ SHADERTYPE_ALL,				TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY,		"binding_contradictory",					"contradictory binding points" },
2285 		{ SHADERTYPE_ALL,				TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY,		"binding_contradictory_array",				"contradictory binding points" },
2286 	};
2287 
2288 	// Render tests
2289 	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_renderTestTypes); ++testNdx)
2290 	{
2291 		const RenderTestType& test = s_renderTestTypes[testNdx];
2292 
2293 		// Render sampler binding tests
2294 		sampler2dBindingTestGroup->addChild(new SamplerBindingRenderCase(m_context, test.name.c_str(), ("Sampler2D layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType, GL_SAMPLER_2D, GL_TEXTURE_2D));
2295 		sampler3dBindingTestGroup->addChild(new SamplerBindingRenderCase(m_context, test.name.c_str(), ("Sampler3D layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType, GL_SAMPLER_3D, GL_TEXTURE_3D));
2296 
2297 		// Render image binding tests
2298 		image2dBindingTestGroup->addChild(new ImageBindingRenderCase(m_context, test.name.c_str(), ("Image2D layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType, GL_IMAGE_2D, GL_TEXTURE_2D));
2299 		image3dBindingTestGroup->addChild(new ImageBindingRenderCase(m_context, test.name.c_str(), ("Image3D layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType, GL_IMAGE_3D, GL_TEXTURE_3D));
2300 
2301 		// Render UBO binding tests
2302 		UBOBindingTestGroup->addChild(new UBOBindingRenderCase(m_context, test.name.c_str(), ("UBO layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType));
2303 
2304 		// Render SSBO binding tests
2305 		SSBOBindingTestGroup->addChild(new SSBOBindingRenderCase(m_context, test.name.c_str(), ("SSBO layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType));
2306 	}
2307 
2308 	// Negative binding tests
2309 	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_negativeTestTypes); ++testNdx)
2310 	{
2311 		const NegativeTestType& test = s_negativeTestTypes[testNdx];
2312 
2313 		// Negative sampler binding tests
2314 		negativeSampler2dBindingTestGroup->addChild(new SamplerBindingNegativeCase(m_context, test.name.c_str(), ("Invalid sampler2d layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType, GL_SAMPLER_2D));
2315 		negativeSampler3dBindingTestGroup->addChild(new SamplerBindingNegativeCase(m_context, test.name.c_str(), ("Invalid sampler3d layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType, GL_SAMPLER_3D));
2316 
2317 		// Negative image binding tests
2318 		negativeImage2dBindingTestGroup->addChild(new ImageBindingNegativeCase(m_context, test.name.c_str(), ("Invalid image2d layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType, GL_IMAGE_2D));
2319 		negativeImage3dBindingTestGroup->addChild(new ImageBindingNegativeCase(m_context, test.name.c_str(), ("Invalid image3d layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType, GL_IMAGE_3D));
2320 
2321 		// Negative UBO binding tests
2322 		negativeUBOBindingTestGroup->addChild(new UBOBindingNegativeCase(m_context, test.name.c_str(), ("Invalid UBO layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType));
2323 
2324 		// Negative SSBO binding tests
2325 		negativeSSBOBindingTestGroup->addChild(new SSBOBindingNegativeCase(m_context, test.name.c_str(), ("Invalid SSBO layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType));
2326 	}
2327 
2328 	samplerBindingTestGroup->addChild(sampler2dBindingTestGroup);
2329 	samplerBindingTestGroup->addChild(sampler3dBindingTestGroup);
2330 
2331 	imageBindingTestGroup->addChild(image2dBindingTestGroup);
2332 	imageBindingTestGroup->addChild(image3dBindingTestGroup);
2333 
2334 	negativeSamplerBindingTestGroup->addChild(negativeSampler2dBindingTestGroup);
2335 	negativeSamplerBindingTestGroup->addChild(negativeSampler3dBindingTestGroup);
2336 
2337 	negativeImageBindingTestGroup->addChild(negativeImage2dBindingTestGroup);
2338 	negativeImageBindingTestGroup->addChild(negativeImage3dBindingTestGroup);
2339 
2340 	negativeBindingTestGroup->addChild(negativeSamplerBindingTestGroup);
2341 	negativeBindingTestGroup->addChild(negativeUBOBindingTestGroup);
2342 	negativeBindingTestGroup->addChild(negativeSSBOBindingTestGroup);
2343 	negativeBindingTestGroup->addChild(negativeImageBindingTestGroup);
2344 
2345 	addChild(samplerBindingTestGroup);
2346 	addChild(UBOBindingTestGroup);
2347 	addChild(SSBOBindingTestGroup);
2348 	addChild(imageBindingTestGroup);
2349 	addChild(negativeBindingTestGroup);
2350 }
2351 
2352 } // Functional
2353 } // gles31
2354 } // deqp
2355