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