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	tcu::Surface			reference			(TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT);
531
532	// the point of these test is to check layout_binding. For this purpose, we can use quite
533	// large thresholds.
534	const tcu::RGBA			surfaceThreshold	= m_context.getRenderContext().getRenderTarget().getPixelFormat().getColorThreshold();
535	const tcu::RGBA			compareThreshold	= tcu::RGBA(de::clamp(2 * surfaceThreshold.getRed(),   0, 255),
536															de::clamp(2 * surfaceThreshold.getGreen(), 0, 255),
537															de::clamp(2 * surfaceThreshold.getBlue(),  0, 255),
538															de::clamp(2 * surfaceThreshold.getAlpha(), 0, 255));
539
540	gl.clear(GL_COLOR_BUFFER_BIT);
541
542	// Draw
543	gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
544	GLU_EXPECT_NO_ERROR(gl.getError(), "Drawing failed");
545
546	// Verify
547	tcu::Surface result(TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT);
548	m_testCtx.getLog() << TestLog::Message << "Reading pixels" << TestLog::EndMessage;
549	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
550	GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels failed");
551
552	tcu::clear(reference.getAccess(), expectedColor);
553	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output image, fragment output color is " << expectedColor << tcu::TestLog::EndMessage;
554
555	return tcu::pixelThresholdCompare(m_testCtx.getLog(), "Render result", "Result verification", reference, result, compareThreshold, tcu::COMPARE_LOG_RESULT);
556}
557
558void LayoutBindingRenderCase::setTestResult (bool queryTestPassed, bool imageTestPassed)
559{
560	if (queryTestPassed && imageTestPassed)
561		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
562	else if (!queryTestPassed && !imageTestPassed)
563		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more binding point queries and image comparisons failed");
564	else if (!queryTestPassed)
565		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more binding point queries failed");
566	else
567		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more image comparisons failed");
568}
569
570class LayoutBindingNegativeCase : public TestCase
571{
572public:
573	enum ErrorType
574	{
575		ERRORTYPE_OVER_MAX_UNITS = 0,
576		ERRORTYPE_LESS_THAN_ZERO,
577		ERRORTYPE_CONTRADICTORY,
578
579		ERRORTYPE_LAST,
580	};
581
582										LayoutBindingNegativeCase		(Context&			context,
583																		 const char*		name,
584																		 const char*		desc,
585																		 ShaderType			shaderType,
586																		 TestType			testType,
587																		 ErrorType			errorType,
588																		 glw::GLenum		maxBindingPointEnum,
589																		 glw::GLenum		maxVertexUnitsEnum,
590																		 glw::GLenum		maxFragmentUnitsEnum,
591																		 glw::GLenum		maxCombinedUnitsEnum,
592																		 const std::string& uniformName);
593	virtual								~LayoutBindingNegativeCase		(void);
594
595	virtual void						init							(void);
596	virtual void						deinit							(void);
597	virtual IterateResult				iterate							(void);
598
599protected:
600	virtual glu::ShaderProgram*			generateShaders					(void) const = 0;
601
602	const glu::ShaderProgram*			m_program;
603	const ShaderType					m_shaderType;
604	const TestType						m_testType;
605	const ErrorType						m_errorType;
606	const glw::GLenum					m_maxBindingPointEnum;
607	const glw::GLenum					m_maxVertexUnitsEnum;
608	const glw::GLenum					m_maxFragmentUnitsEnum;
609	const glw::GLenum					m_maxCombinedUnitsEnum;
610	const std::string					m_uniformName;
611	glw::GLint							m_numBindings;
612	std::vector<glw::GLint>				m_vertexShaderBinding;
613	std::vector<glw::GLint>				m_fragmentShaderBinding;
614
615private:
616	void								initBindingPoints				(int minBindingPoint, int numBindingPoints);
617};
618
619LayoutBindingNegativeCase::LayoutBindingNegativeCase (Context&				context,
620													  const char*			name,
621													  const char*			desc,
622													  ShaderType			shaderType,
623													  TestType				testType,
624													  ErrorType				errorType,
625													  glw::GLenum			maxBindingPointEnum,
626													  glw::GLenum			maxVertexUnitsEnum,
627													  glw::GLenum			maxFragmentUnitsEnum,
628													  glw::GLenum			maxCombinedUnitsEnum,
629													  const std::string&	uniformName)
630	: TestCase					(context, name, desc)
631	, m_program					(DE_NULL)
632	, m_shaderType				(shaderType)
633	, m_testType				(testType)
634	, m_errorType				(errorType)
635	, m_maxBindingPointEnum		(maxBindingPointEnum)
636	, m_maxVertexUnitsEnum		(maxVertexUnitsEnum)
637	, m_maxFragmentUnitsEnum	(maxFragmentUnitsEnum)
638	, m_maxCombinedUnitsEnum	(maxCombinedUnitsEnum)
639	, m_uniformName				(uniformName)
640	, m_numBindings				(0)
641{
642}
643
644LayoutBindingNegativeCase::~LayoutBindingNegativeCase (void)
645{
646	deinit();
647}
648
649void LayoutBindingNegativeCase::init (void)
650{
651	// Decide appropriate binding points for the vertex and fragment shaders
652	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
653	de::Random				rnd					(deStringHash(getName()) ^ 0xff23a4);
654	glw::GLint				numBindingPoints	= 0;	// Number of binding points
655	glw::GLint				maxVertexUnits		= 0;	// Available uniforms in the vertex shader
656	glw::GLint				maxFragmentUnits	= 0;	// Available uniforms in the fragment shader
657	glw::GLint				maxCombinedUnits	= 0;	// Available uniforms in all the shader stages combined
658	glw::GLint				maxUnits			= 0;	// Maximum available uniforms for this test
659
660	gl.getIntegerv(m_maxVertexUnitsEnum, &maxVertexUnits);
661	gl.getIntegerv(m_maxFragmentUnitsEnum, &maxFragmentUnits);
662	gl.getIntegerv(m_maxCombinedUnitsEnum, &maxCombinedUnits);
663	gl.getIntegerv(m_maxBindingPointEnum, &numBindingPoints);
664	GLU_EXPECT_NO_ERROR(gl.getError(), "Querying available uniform numbers failed");
665
666	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the vertex shader: " << maxVertexUnits << tcu::TestLog::EndMessage;
667	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the fragment shader: " << maxFragmentUnits << tcu::TestLog::EndMessage;
668	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum combined units for uniform type: " << maxCombinedUnits << tcu::TestLog::EndMessage;
669	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum binding point for uniform type: " << numBindingPoints-1 << tcu::TestLog::EndMessage;
670
671	// Select maximum number of uniforms used for the test
672	switch (m_shaderType)
673	{
674		case SHADERTYPE_VERTEX:
675			maxUnits = maxVertexUnits;
676			break;
677
678		case SHADERTYPE_FRAGMENT:
679			maxUnits = maxFragmentUnits;
680			break;
681
682		case SHADERTYPE_BOTH:
683			maxUnits = de::min(de::min(maxVertexUnits, maxFragmentUnits), maxCombinedUnits/2);
684			break;
685
686		default:
687			DE_ASSERT(false);
688	}
689
690	// Select the number of uniforms (= bindings) used for this test
691	switch (m_testType)
692	{
693		case TESTTYPE_BINDING_SINGLE:
694		case TESTTYPE_BINDING_MAX:
695			m_numBindings = 1;
696			break;
697
698		case TESTTYPE_BINDING_MULTIPLE:
699		case TESTTYPE_BINDING_ARRAY:
700		case TESTTYPE_BINDING_MAX_ARRAY:
701			if (m_errorType == ERRORTYPE_CONTRADICTORY)
702			{
703				// leave room for contradictory case
704				if (maxUnits < 3)
705					throw tcu::NotSupportedError("Not enough uniforms available for test");
706				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits-1));
707			}
708			else
709			{
710				if (maxUnits < 2)
711					throw tcu::NotSupportedError("Not enough uniforms available for test");
712				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits));
713			}
714			break;
715
716		default:
717			DE_ASSERT(false);
718	}
719
720	// Check that we have enough uniforms in different shaders to perform the tests
721	if ( ((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_BOTH)) && (maxVertexUnits < m_numBindings) )
722		throw tcu::NotSupportedError("Vertex shader: not enough uniforms available for test");
723	if ( ((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_BOTH)) && (maxFragmentUnits < m_numBindings) )
724		throw tcu::NotSupportedError("Fragment shader: not enough uniforms available for test");
725	if ( (m_shaderType == SHADERTYPE_BOTH) && (maxCombinedUnits < m_numBindings*2) )
726		throw tcu::NotSupportedError("Not enough uniforms available for test");
727
728	// Check that we have enough binding points to perform the tests
729	if (numBindingPoints < m_numBindings)
730		throw tcu::NotSupportedError("Not enough binding points available for test");
731	if (m_errorType == ERRORTYPE_CONTRADICTORY && numBindingPoints == m_numBindings)
732		throw tcu::NotSupportedError("Not enough binding points available for test");
733
734	// Initialize the binding points i.e. populate the two binding point vectors
735	initBindingPoints(0, numBindingPoints);
736
737	// Generate the shader program - note: this must be done after deciding the binding points
738	DE_ASSERT(!m_program);
739	m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shaders" << tcu::TestLog::EndMessage;
740	m_program = generateShaders();
741	m_testCtx.getLog() << *m_program;
742}
743
744void LayoutBindingNegativeCase::deinit (void)
745{
746	if (m_program)
747	{
748		delete m_program;
749		m_program = DE_NULL;
750	}
751}
752
753TestCase::IterateResult LayoutBindingNegativeCase::iterate (void)
754{
755	bool pass = false;
756	std::string failMessage;
757
758	switch (m_errorType)
759	{
760		case ERRORTYPE_CONTRADICTORY:		// Contradictory binding points should cause a link-time error
761			if (!(m_program->getProgramInfo()).linkOk)
762				pass = true;
763			failMessage = "Test failed - expected a link-time error";
764			break;
765
766		case ERRORTYPE_LESS_THAN_ZERO:		// Out of bounds binding points should cause a compile-time error
767		case ERRORTYPE_OVER_MAX_UNITS:
768			if (!(m_program->getShaderInfo(glu::SHADERTYPE_VERTEX)).compileOk || !(m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT)).compileOk)
769				pass = true;
770			failMessage = "Test failed - expected a compile-time error";
771			break;
772
773		default:
774			DE_ASSERT(false);
775	}
776
777	if (pass)
778		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
779	else
780		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, failMessage.c_str());
781
782	return STOP;
783}
784
785void LayoutBindingNegativeCase::initBindingPoints (int minBindingPoint, int numBindingPoints)
786{
787	de::Random rnd(deStringHash(getName()) ^ 0xff23a4);
788
789	switch (m_errorType)
790	{
791		case ERRORTYPE_OVER_MAX_UNITS:	// Select a binding point that is 1 over the maximum
792		{
793			m_vertexShaderBinding.push_back(numBindingPoints+1-m_numBindings);
794			m_fragmentShaderBinding.push_back(numBindingPoints+1-m_numBindings);
795			break;
796		}
797
798		case ERRORTYPE_LESS_THAN_ZERO:	// Select a random negative binding point
799		{
800			const glw::GLint binding = -rnd.getInt(1, m_numBindings);
801			m_vertexShaderBinding.push_back(binding);
802			m_fragmentShaderBinding.push_back(binding);
803			break;
804		}
805
806		case ERRORTYPE_CONTRADICTORY:	// Select two valid, but contradictory binding points
807		{
808			m_vertexShaderBinding.push_back(minBindingPoint);
809			m_fragmentShaderBinding.push_back((minBindingPoint+1)%numBindingPoints);
810			DE_ASSERT(m_vertexShaderBinding.back() != m_fragmentShaderBinding.back());
811			break;
812		}
813
814		default:
815			DE_ASSERT(false);
816	}
817
818	// In case we are testing with multiple uniforms populate the rest of the binding points
819	for (int ndx = 1; ndx < m_numBindings; ++ndx)
820	{
821		m_vertexShaderBinding.push_back(m_vertexShaderBinding.front()+ndx);
822		m_fragmentShaderBinding.push_back(m_fragmentShaderBinding.front()+ndx);
823	}
824}
825
826class SamplerBindingRenderCase : public LayoutBindingRenderCase
827{
828public:
829									SamplerBindingRenderCase		(Context& context, const char* name, const char* desc, ShaderType shaderType, TestType testType, glw::GLenum samplerType, glw::GLenum textureType);
830									~SamplerBindingRenderCase		(void);
831
832	void 							init							(void);
833	void 							deinit							(void);
834	IterateResult 					iterate							(void);
835
836private:
837	glu::ShaderProgram*				generateShaders					(void) const;
838	glu::DataType					getSamplerTexCoordType			(void) const;
839	void							initializeTexture				(glw::GLint bindingPoint, glw::GLint textureName, const Vec4& color) const;
840
841	const glw::GLenum				m_samplerType;
842	const glw::GLenum				m_textureType;
843
844	std::vector<glw::GLuint>		m_textures;
845	std::vector<Vec4>				m_textureColors;
846};
847
848
849SamplerBindingRenderCase::SamplerBindingRenderCase (Context&		context,
850													const char*		name,
851													const char*		desc,
852													ShaderType		shaderType,
853													TestType		testType,
854													glw::GLenum		samplerType,
855													glw::GLenum		textureType)
856	: 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")
857	, m_samplerType				(samplerType)
858	, m_textureType				(textureType)
859{
860}
861
862SamplerBindingRenderCase::~SamplerBindingRenderCase (void)
863{
864	deinit();
865}
866
867void SamplerBindingRenderCase::init (void)
868{
869	LayoutBindingRenderCase::init();
870	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
871	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);
872
873
874	// Initialize texture resources
875	m_textures = std::vector<glw::GLuint>(m_numBindings,  0);
876
877	// Texture colors
878	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
879		m_textureColors.push_back(getRandomColor(rnd));
880
881	// Textures
882	gl.genTextures((glw::GLsizei)m_textures.size(), &m_textures[0]);
883
884	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
885		initializeTexture(m_bindings[texNdx], m_textures[texNdx], m_textureColors[texNdx]);
886
887	gl.activeTexture(GL_TEXTURE0);
888}
889
890void SamplerBindingRenderCase::deinit(void)
891{
892	LayoutBindingRenderCase::deinit();
893
894	// Clean up texture data
895	for (int i = 0; i < (int)m_textures.size(); ++i)
896	{
897		if (m_textures[i])
898		{
899			m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[i]);
900			m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0);
901		}
902	}
903}
904
905TestCase::IterateResult SamplerBindingRenderCase::iterate (void)
906{
907	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
908	const int				iterations		= m_numBindings;
909	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
910	bool					imageTestPassed	= true;
911	bool					queryTestPassed	= true;
912
913	// Set the viewport and enable the shader program
914	initRenderState();
915
916	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
917	{
918		// Set the uniform value indicating the current array index
919		gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx);
920
921		// Query binding point
922		const std::string	name	= arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx);
923		const glw::GLint	binding = m_bindings[iterNdx];
924		glw::GLint			val		= -1;
925
926		gl.getUniformiv(m_program->getProgram(), gl.getUniformLocation(m_program->getProgram(), name.c_str()), &val);
927		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
928		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
929
930		// Draw and verify
931		if (val != binding)
932			queryTestPassed = false;
933		if (!drawAndVerifyResult(m_textureColors[iterNdx]))
934			imageTestPassed = false;
935	}
936
937	setTestResult(queryTestPassed, imageTestPassed);
938	return STOP;
939}
940
941glu::ShaderProgram* SamplerBindingRenderCase::generateShaders (void) const
942{
943	std::ostringstream		shaderUniformDecl;
944	std::ostringstream		shaderBody;
945
946	const std::string		texCoordType	= glu::getDataTypeName(getSamplerTexCoordType());
947	const std::string		samplerType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_samplerType));
948	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY) ? true : false;
949	const int				numDeclarations =  arrayInstance ? 1 : m_numBindings;
950
951	// Generate the uniform declarations for the vertex and fragment shaders
952	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
953	{
954		shaderUniformDecl << "layout(binding = " << m_bindings[declNdx] << ") uniform highp " << samplerType << " "
955			<< (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
956	}
957
958	// Generate the shader body for the vertex and fragment shaders
959	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
960	{
961		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
962					<< "	{\n"
963					<< "		color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n"
964					<< "	}\n";
965	}
966
967	shaderBody	<< "	else\n"
968				<< "	{\n"
969				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
970				<< "	}\n";
971
972	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
973					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
974					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
975}
976
977void SamplerBindingRenderCase::initializeTexture (glw::GLint bindingPoint, glw::GLint textureName, const Vec4& color) const
978{
979	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
980
981	gl.activeTexture(GL_TEXTURE0 + bindingPoint);
982	gl.bindTexture(m_textureType, textureName);
983	gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
984
985	switch (m_textureType)
986	{
987		case GL_TEXTURE_2D:
988		{
989			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
990			tcu::clear(level.getAccess(), color);
991			glu::texImage2D(m_context.getRenderContext(), m_textureType, 0, GL_RGBA8, level.getAccess());
992			break;
993		}
994
995		case GL_TEXTURE_3D:
996		{
997			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
998			tcu::clear(level.getAccess(), color);
999			glu::texImage3D(m_context.getRenderContext(), m_textureType, 0, GL_RGBA8, level.getAccess());
1000			break;
1001		}
1002
1003		default:
1004			DE_ASSERT(false);
1005	}
1006
1007	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture initialization failed");
1008}
1009
1010glu::DataType SamplerBindingRenderCase::getSamplerTexCoordType (void) const
1011{
1012	switch (m_samplerType)
1013	{
1014		case GL_SAMPLER_2D:
1015			return glu::TYPE_FLOAT_VEC2;
1016
1017		case GL_SAMPLER_3D:
1018			return glu::TYPE_FLOAT_VEC3;
1019
1020		default:
1021			DE_ASSERT(false);
1022			return glu::TYPE_INVALID;
1023	}
1024}
1025
1026
1027class SamplerBindingNegativeCase : public LayoutBindingNegativeCase
1028{
1029public:
1030									SamplerBindingNegativeCase		(Context&		context,
1031																	 const char*	name,
1032																	 const char*	desc,
1033																	 ShaderType		shaderType,
1034																	 TestType		testType,
1035																	 ErrorType		errorType,
1036																	 glw::GLenum	samplerType);
1037									~SamplerBindingNegativeCase		(void);
1038
1039private:
1040	glu::ShaderProgram*				generateShaders					(void) const;
1041	glu::DataType					getSamplerTexCoordType			(void) const;
1042
1043	const glw::GLenum				m_samplerType;
1044};
1045
1046SamplerBindingNegativeCase::SamplerBindingNegativeCase (Context&		context,
1047														const char*		name,
1048														const char*		desc,
1049														ShaderType		shaderType,
1050														TestType		testType,
1051														ErrorType		errorType,
1052														glw::GLenum		samplerType)
1053	: 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")
1054	, m_samplerType					(samplerType)
1055{
1056}
1057
1058SamplerBindingNegativeCase::~SamplerBindingNegativeCase (void)
1059{
1060	LayoutBindingNegativeCase::deinit();
1061}
1062
1063glu::ShaderProgram*	SamplerBindingNegativeCase::generateShaders	(void) const
1064{
1065	std::ostringstream		vertexUniformDecl;
1066	std::ostringstream		fragmentUniformDecl;
1067	std::ostringstream		shaderBody;
1068
1069	const std::string		texCoordType	= glu::getDataTypeName(getSamplerTexCoordType());
1070	const std::string		samplerType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_samplerType));
1071	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1072	const int				numDeclarations = arrayInstance ? 1 : m_numBindings;
1073
1074	// Generate the uniform declarations for the vertex and fragment shaders
1075	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1076	{
1077		vertexUniformDecl << "layout(binding = " << m_vertexShaderBinding[declNdx] << ") uniform highp " << samplerType
1078			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1079		fragmentUniformDecl << "layout(binding = " << m_fragmentShaderBinding[declNdx] << ") uniform highp " << samplerType
1080			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1081	}
1082
1083	// Generate the shader body for the vertex and fragment shaders
1084	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1085	{
1086		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1087					<< "	{\n"
1088					<< "		color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n"
1089					<< "	}\n";
1090	}
1091
1092	shaderBody	<< "	else\n"
1093				<< "	{\n"
1094				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1095				<< "	}\n";
1096
1097	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1098				<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
1099				<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
1100}
1101
1102glu::DataType SamplerBindingNegativeCase::getSamplerTexCoordType(void) const
1103{
1104	switch (m_samplerType)
1105	{
1106		case GL_SAMPLER_2D:
1107			return glu::TYPE_FLOAT_VEC2;
1108
1109		case GL_SAMPLER_3D:
1110			return glu::TYPE_FLOAT_VEC3;
1111
1112		default:
1113			DE_ASSERT(false);
1114			return glu::TYPE_INVALID;
1115	}
1116}
1117
1118class ImageBindingRenderCase : public LayoutBindingRenderCase
1119{
1120public:
1121											ImageBindingRenderCase			(Context&		context,
1122																			 const char*	name,
1123																			 const char*	desc,
1124																			 ShaderType		shaderType,
1125																			 TestType		testType,
1126																			 glw::GLenum	imageType,
1127																			 glw::GLenum	textureType);
1128											~ImageBindingRenderCase			(void);
1129
1130	void 									init							(void);
1131	void 									deinit							(void);
1132	IterateResult 							iterate							(void);
1133
1134private:
1135	glu::ShaderProgram*						generateShaders					(void) const;
1136	void									initializeImage					(glw::GLint imageBindingPoint, glw::GLint textureBindingPoint, glw::GLint textureName, const Vec4& color) const;
1137	glu::DataType							getImageTexCoordType			(void) const;
1138
1139	const glw::GLenum						m_imageType;
1140	const glw::GLenum						m_textureType;
1141
1142	std::vector<glw::GLuint>				m_textures;
1143	std::vector<Vec4>						m_textureColors;
1144};
1145
1146
1147ImageBindingRenderCase::ImageBindingRenderCase (Context&		context,
1148												const char*		name,
1149												const char*		desc,
1150												ShaderType		shaderType,
1151												TestType		testType,
1152												glw::GLenum		imageType,
1153												glw::GLenum		textureType)
1154	: 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")
1155	, m_imageType					(imageType)
1156	, m_textureType					(textureType)
1157{
1158}
1159
1160ImageBindingRenderCase::~ImageBindingRenderCase (void)
1161{
1162	deinit();
1163}
1164
1165void ImageBindingRenderCase::init (void)
1166{
1167	LayoutBindingRenderCase::init();
1168
1169	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
1170	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);
1171
1172	// Initialize image / texture resources
1173	m_textures = std::vector<glw::GLuint>(m_numBindings,  0);
1174
1175	// Texture colors
1176	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1177		m_textureColors.push_back(getRandomColor(rnd));
1178
1179	// Image textures
1180	gl.genTextures(m_numBindings, &m_textures[0]);
1181
1182	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1183		initializeImage(m_bindings[texNdx], texNdx, m_textures[texNdx], m_textureColors[texNdx]);
1184}
1185
1186void ImageBindingRenderCase::deinit (void)
1187{
1188	LayoutBindingRenderCase::deinit();
1189
1190	// Clean up texture data
1191	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1192	{
1193		if (m_textures[texNdx])
1194		{
1195			m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[texNdx]);
1196			m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0);
1197		}
1198	}
1199}
1200
1201TestCase::IterateResult ImageBindingRenderCase::iterate	(void)
1202{
1203	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
1204	const int				iterations		= m_numBindings;
1205	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1206	bool					queryTestPassed	= true;
1207	bool					imageTestPassed = true;
1208
1209	// Set the viewport and enable the shader program
1210	initRenderState();
1211
1212	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
1213	{
1214		// Set the uniform value indicating the current array index
1215		gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx);
1216
1217		const std::string	name	= (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
1218		const glw::GLint	binding = m_bindings[iterNdx];
1219		glw::GLint			val		= -1;
1220
1221		gl.getUniformiv(m_program->getProgram(), gl.getUniformLocation(m_program->getProgram(), name.c_str()), &val);
1222		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
1223		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
1224
1225		// Draw and verify
1226		if (val != binding)
1227			queryTestPassed = false;
1228		if (!drawAndVerifyResult(m_textureColors[iterNdx]))
1229			imageTestPassed = false;
1230	}
1231
1232	setTestResult(queryTestPassed, imageTestPassed);
1233	return STOP;
1234}
1235
1236void ImageBindingRenderCase::initializeImage (glw::GLint imageBindingPoint, glw::GLint textureBindingPoint, glw::GLint textureName, const Vec4& color) const
1237{
1238	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1239
1240	gl.activeTexture(GL_TEXTURE0 + textureBindingPoint);
1241	gl.bindTexture(m_textureType, textureName);
1242	gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1243
1244	switch (m_textureType)
1245	{
1246		case GL_TEXTURE_2D:
1247		{
1248			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1249			tcu::clear(level.getAccess(), color);
1250			gl.texStorage2D(m_textureType, 1, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1251			gl.texSubImage2D(m_textureType, 0, 0, 0, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, level.getAccess().getDataPtr());
1252			break;
1253		}
1254
1255		case GL_TEXTURE_3D:
1256		{
1257			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1258			tcu::clear(level.getAccess(), color);
1259			gl.texStorage3D(m_textureType, 1, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1260			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());
1261			break;
1262		}
1263
1264		default:
1265			DE_ASSERT(false);
1266	}
1267
1268	gl.bindTexture(m_textureType, 0);
1269	gl.bindImageTexture(imageBindingPoint, textureName, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA8);
1270	GLU_EXPECT_NO_ERROR(gl.getError(), "Image initialization failed");
1271}
1272
1273glu::ShaderProgram* ImageBindingRenderCase::generateShaders (void) const
1274{
1275	std::ostringstream		shaderUniformDecl;
1276	std::ostringstream		shaderBody;
1277
1278	const std::string		texCoordType	= glu::getDataTypeName(getImageTexCoordType());
1279	const std::string		imageType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_imageType));
1280	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY) ? true : false;
1281	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
1282
1283	// Generate the uniform declarations for the vertex and fragment shaders
1284	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1285	{
1286		shaderUniformDecl << "layout(rgba8, binding = " << m_bindings[declNdx] << ") uniform readonly highp " << imageType
1287			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1288	}
1289
1290	// Generate the shader body for the vertex and fragment shaders
1291	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1292	{
1293		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1294					<< "	{\n"
1295					<< "		color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n"
1296					<< "	}\n";
1297	}
1298
1299	shaderBody	<< "	else\n"
1300				<< "	{\n"
1301				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1302				<< "	}\n";
1303
1304	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1305					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
1306					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
1307}
1308
1309glu::DataType ImageBindingRenderCase::getImageTexCoordType(void) const
1310{
1311	switch (m_imageType)
1312	{
1313		case GL_IMAGE_2D:
1314			return glu::TYPE_INT_VEC2;
1315
1316		case GL_IMAGE_3D:
1317			return glu::TYPE_INT_VEC3;
1318
1319		default:
1320			DE_ASSERT(false);
1321			return glu::TYPE_INVALID;
1322	}
1323}
1324
1325
1326class ImageBindingNegativeCase : public LayoutBindingNegativeCase
1327{
1328public:
1329											ImageBindingNegativeCase		(Context&		context,
1330																			 const char*	name,
1331																			 const char*	desc,
1332																			 ShaderType		shaderType,
1333																			 TestType		testType,
1334																			 ErrorType		errorType,
1335																			 glw::GLenum	imageType);
1336											~ImageBindingNegativeCase		(void);
1337
1338private:
1339	glu::ShaderProgram*						generateShaders					(void) const;
1340	glu::DataType							getImageTexCoordType			(void) const;
1341
1342	const glw::GLenum						m_imageType;
1343};
1344
1345ImageBindingNegativeCase::ImageBindingNegativeCase (Context&		context,
1346													const char*		name,
1347													const char*		desc,
1348													ShaderType		shaderType,
1349													TestType		testType,
1350													ErrorType		errorType,
1351													glw::GLenum		imageType)
1352	: 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")
1353	, m_imageType					(imageType)
1354{
1355}
1356
1357ImageBindingNegativeCase::~ImageBindingNegativeCase (void)
1358{
1359	deinit();
1360}
1361
1362glu::ShaderProgram* ImageBindingNegativeCase::generateShaders (void) const
1363{
1364	std::ostringstream		vertexUniformDecl;
1365	std::ostringstream		fragmentUniformDecl;
1366	std::ostringstream		shaderBody;
1367
1368	const std::string		texCoordType	= glu::getDataTypeName(getImageTexCoordType());
1369	const std::string		imageType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_imageType));
1370	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1371	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
1372
1373	// Generate the uniform declarations for the vertex and fragment shaders
1374	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1375	{
1376		vertexUniformDecl << "layout(rgba8, binding = " << m_vertexShaderBinding[declNdx] << ") uniform readonly highp " << imageType
1377			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1378		fragmentUniformDecl << "layout(rgba8, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform readonly highp " << imageType
1379			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1380	}
1381
1382	// Generate the shader body for the vertex and fragment shaders
1383	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1384	{
1385		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1386					<< "	{\n"
1387					<< "		color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n"
1388					<< "	}\n";
1389	}
1390
1391	shaderBody	<< "	else\n"
1392				<< "	{\n"
1393				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1394				<< "	}\n";
1395
1396	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1397					<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
1398					<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
1399}
1400
1401glu::DataType ImageBindingNegativeCase::getImageTexCoordType(void) const
1402{
1403	switch (m_imageType)
1404	{
1405		case GL_IMAGE_2D:
1406			return glu::TYPE_INT_VEC2;
1407
1408		case GL_IMAGE_3D:
1409			return glu::TYPE_INT_VEC3;
1410
1411		default:
1412			DE_ASSERT(false);
1413			return glu::TYPE_INVALID;
1414	}
1415}
1416
1417
1418class UBOBindingRenderCase : public LayoutBindingRenderCase
1419{
1420public:
1421											UBOBindingRenderCase		(Context&		context,
1422																		 const char*	name,
1423																		 const char*	desc,
1424																		 ShaderType		shaderType,
1425																		 TestType		testType);
1426											~UBOBindingRenderCase		(void);
1427
1428	void 									init						(void);
1429	void 									deinit						(void);
1430	IterateResult 							iterate						(void);
1431
1432private:
1433	glu::ShaderProgram*						generateShaders				(void) const;
1434
1435	std::vector<deUint32>					m_buffers;
1436	std::vector<Vec4>						m_expectedColors;
1437};
1438
1439UBOBindingRenderCase::UBOBindingRenderCase (Context&		context,
1440											const char*		name,
1441											const char*		desc,
1442											ShaderType		shaderType,
1443											TestType		testType)
1444	: 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")
1445{
1446}
1447
1448UBOBindingRenderCase::~UBOBindingRenderCase (void)
1449{
1450	deinit();
1451}
1452
1453void UBOBindingRenderCase::init (void)
1454{
1455	LayoutBindingRenderCase::init();
1456
1457	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
1458	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);
1459
1460	// Initialize UBOs and related data
1461	m_buffers = std::vector<glw::GLuint>(m_numBindings,  0);
1462	gl.genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]);
1463
1464	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1465	{
1466			m_expectedColors.push_back(getRandomColor(rnd));
1467			m_expectedColors.push_back(getRandomColor(rnd));
1468	}
1469
1470	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1471	{
1472		gl.bindBuffer(GL_UNIFORM_BUFFER, m_buffers[bufNdx]);
1473		gl.bufferData(GL_UNIFORM_BUFFER, 2*sizeof(Vec4), &(m_expectedColors[2*bufNdx]), GL_STATIC_DRAW);
1474		gl.bindBufferBase(GL_UNIFORM_BUFFER, m_bindings[bufNdx], m_buffers[bufNdx]);
1475	}
1476
1477	GLU_EXPECT_NO_ERROR(gl.getError(), "UBO setup failed");
1478}
1479
1480void UBOBindingRenderCase::deinit (void)
1481{
1482	LayoutBindingRenderCase::deinit();
1483
1484	// Clean up UBO data
1485	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1486	{
1487		if (m_buffers[bufNdx])
1488		{
1489			m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffers[bufNdx]);
1490			m_context.getRenderContext().getFunctions().bindBuffer(GL_UNIFORM_BUFFER, 0);
1491		}
1492	}
1493}
1494
1495TestCase::IterateResult UBOBindingRenderCase::iterate (void)
1496{
1497	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
1498	const int				iterations		= m_numBindings;
1499	const glw::GLenum		prop			= GL_BUFFER_BINDING;
1500	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1501	bool					queryTestPassed	= true;
1502	bool					imageTestPassed = true;
1503
1504	// Set the viewport and enable the shader program
1505	initRenderState();
1506
1507	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
1508	{
1509		// Query binding point
1510		const std::string	name	= (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
1511		const glw::GLint	binding = m_bindings[iterNdx];
1512		glw::GLint			val		= -1;
1513
1514		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);
1515		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
1516		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
1517
1518		if (val != binding)
1519			queryTestPassed = false;
1520
1521		// Draw twice to render both colors within the UBO
1522		for (int drawCycle = 0; drawCycle < 2; ++drawCycle)
1523		{
1524			// Set the uniform indicating the array index to be used and set the expected color
1525			const int arrayNdx = iterNdx*2 + drawCycle;
1526			gl.uniform1i(m_shaderProgramArrayNdxLoc, arrayNdx);
1527
1528			if (!drawAndVerifyResult(m_expectedColors[arrayNdx]))
1529				imageTestPassed = false;
1530		}
1531	}
1532
1533	setTestResult(queryTestPassed, imageTestPassed);
1534	return STOP;
1535}
1536
1537glu::ShaderProgram* UBOBindingRenderCase::generateShaders (void) const
1538{
1539	std::ostringstream		shaderUniformDecl;
1540	std::ostringstream		shaderBody;
1541	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1542	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
1543
1544	// Generate the uniform declarations for the vertex and fragment shaders
1545	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1546	{
1547		shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") uniform "
1548			<< getUniformName(m_uniformName, declNdx) << "\n"
1549			<< "{\n"
1550			<< "	highp vec4 color1;\n"
1551			<< "	highp vec4 color2;\n"
1552			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1553	}
1554
1555	// Generate the shader body for the vertex and fragment shaders
1556	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
1557	{
1558		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
1559		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1560					<< "	{\n"
1561					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
1562					<< "	}\n";
1563	}
1564
1565	shaderBody	<< "	else\n"
1566				<< "	{\n"
1567				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1568				<< "	}\n";
1569
1570	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1571					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
1572					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
1573}
1574
1575
1576class UBOBindingNegativeCase : public LayoutBindingNegativeCase
1577{
1578public:
1579											UBOBindingNegativeCase			(Context&		context,
1580																			 const char*	name,
1581																			 const char*	desc,
1582																			 ShaderType		shaderType,
1583																			 TestType		testType,
1584																			 ErrorType		errorType);
1585											~UBOBindingNegativeCase			(void);
1586
1587private:
1588	glu::ShaderProgram*						generateShaders					(void) const;
1589};
1590
1591UBOBindingNegativeCase::UBOBindingNegativeCase (Context&		context,
1592												const char*		name,
1593												const char*		desc,
1594												ShaderType		shaderType,
1595												TestType		testType,
1596												ErrorType		errorType)
1597	: 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")
1598{
1599}
1600
1601UBOBindingNegativeCase::~UBOBindingNegativeCase (void)
1602{
1603	deinit();
1604}
1605
1606glu::ShaderProgram* UBOBindingNegativeCase::generateShaders (void) const
1607{
1608	std::ostringstream		vertexUniformDecl;
1609	std::ostringstream		fragmentUniformDecl;
1610	std::ostringstream		shaderBody;
1611	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1612	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
1613
1614	// Generate the uniform declarations for the vertex and fragment shaders
1615	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1616	{
1617		vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[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		fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform "
1625			<< getUniformName(m_uniformName, declNdx) << "\n"
1626			<< "{\n"
1627			<< "	highp vec4 color1;\n"
1628			<< "	highp vec4 color2;\n"
1629			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1630	}
1631
1632	// Generate the shader body for the vertex and fragment shaders
1633	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
1634	{
1635		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
1636		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1637					<< "	{\n"
1638					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
1639					<< "	}\n";
1640	}
1641
1642	shaderBody	<< "	else\n"
1643				<< "	{\n"
1644				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1645				<< "	}\n";
1646
1647	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1648					<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
1649					<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
1650}
1651
1652
1653class SSBOBindingRenderCase : public LayoutBindingRenderCase
1654{
1655public:
1656											SSBOBindingRenderCase		(Context&		context,
1657																		 const char*	name,
1658																		 const char*	desc,
1659																		 ShaderType		shaderType,
1660																		 TestType		testType);
1661											~SSBOBindingRenderCase		(void);
1662
1663	void 									init						(void);
1664	void 									deinit						(void);
1665	IterateResult 							iterate						(void);
1666
1667private:
1668	glu::ShaderProgram*						generateShaders				(void) const;
1669
1670	std::vector<glw::GLuint>				m_buffers;
1671	std::vector<Vec4>						m_expectedColors;
1672};
1673
1674SSBOBindingRenderCase::SSBOBindingRenderCase (Context&		context,
1675											  const char*	name,
1676											  const char*	desc,
1677											  ShaderType	shaderType,
1678											  TestType		testType)
1679	: 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")
1680{
1681}
1682
1683SSBOBindingRenderCase::~SSBOBindingRenderCase (void)
1684{
1685	deinit();
1686}
1687
1688void SSBOBindingRenderCase::init (void)
1689{
1690	LayoutBindingRenderCase::init();
1691
1692	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
1693	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);
1694
1695	// Initialize SSBOs and related data
1696	m_buffers = std::vector<glw::GLuint>(m_numBindings, 0);
1697	gl.genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]);
1698
1699	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1700	{
1701		m_expectedColors.push_back(getRandomColor(rnd));
1702		m_expectedColors.push_back(getRandomColor(rnd));
1703	}
1704
1705	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1706	{
1707		gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffers[bufNdx]);
1708		gl.bufferData(GL_SHADER_STORAGE_BUFFER, 2*sizeof(Vec4), &(m_expectedColors[2*bufNdx]), GL_STATIC_DRAW);
1709		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, m_bindings[bufNdx], m_buffers[bufNdx]);
1710	}
1711
1712	GLU_EXPECT_NO_ERROR(gl.getError(), "SSBO setup failed");
1713}
1714
1715void SSBOBindingRenderCase::deinit (void)
1716{
1717	LayoutBindingRenderCase::deinit();
1718
1719	// Clean up SSBO data
1720	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1721	{
1722		if (m_buffers[bufNdx])
1723		{
1724			m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffers[bufNdx]);
1725			m_context.getRenderContext().getFunctions().bindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
1726			m_buffers[bufNdx] = 0;
1727		}
1728	}
1729}
1730
1731TestCase::IterateResult SSBOBindingRenderCase::iterate (void)
1732{
1733	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
1734	const int				iterations		= m_numBindings;
1735	const glw::GLenum		prop			= GL_BUFFER_BINDING;
1736	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1737	bool					queryTestPassed	= true;
1738	bool					imageTestPassed = true;
1739
1740	initRenderState();
1741
1742	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
1743	{
1744		// Query binding point
1745		const std::string	name	= (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
1746		const glw::GLint	binding = m_bindings[iterNdx];
1747		glw::GLint			val		= -1;
1748
1749		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);
1750		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
1751		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
1752
1753		if (val != binding)
1754			queryTestPassed = false;
1755
1756		// Draw twice to render both colors within the SSBO
1757		for (int drawCycle = 0; drawCycle < 2; ++drawCycle)
1758		{
1759			// Set the uniform indicating the array index to be used and set the expected color
1760			const int arrayNdx = iterNdx*2 + drawCycle;
1761			gl.uniform1i(m_shaderProgramArrayNdxLoc, arrayNdx);
1762
1763			if (!drawAndVerifyResult(m_expectedColors[arrayNdx]))
1764				imageTestPassed = false;
1765		}
1766	}
1767
1768	setTestResult(queryTestPassed, imageTestPassed);
1769	return STOP;
1770}
1771
1772glu::ShaderProgram* SSBOBindingRenderCase::generateShaders (void) const
1773{
1774	std::ostringstream		shaderUniformDecl;
1775	std::ostringstream		shaderBody;
1776	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1777	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
1778
1779	// Generate the uniform declarations for the vertex and fragment shaders
1780	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1781	{
1782		shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") buffer "
1783			<< getUniformName(m_uniformName, declNdx) << "\n"
1784			<< "{\n"
1785			<< "	highp vec4 color1;\n"
1786			<< "	highp vec4 color2;\n"
1787			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1788	}
1789
1790	// Generate the shader body for the vertex and fragment shaders
1791	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
1792	{
1793		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
1794		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1795					<< "	{\n"
1796					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
1797					<< "	}\n";
1798	}
1799
1800	shaderBody	<< "	else\n"
1801				<< "	{\n"
1802				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1803				<< "	}\n";
1804
1805	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1806					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
1807					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
1808}
1809
1810
1811class SSBOBindingNegativeCase : public LayoutBindingNegativeCase
1812{
1813public:
1814											SSBOBindingNegativeCase			(Context&		context,
1815																			 const char*	name,
1816																			 const char*	desc,
1817																			 ShaderType		shaderType,
1818																			 TestType		testType,
1819																			 ErrorType		errorType);
1820											~SSBOBindingNegativeCase		(void);
1821
1822private:
1823	glu::ShaderProgram*						generateShaders					(void) const;
1824};
1825
1826SSBOBindingNegativeCase::SSBOBindingNegativeCase (Context& context,
1827												  const char* name,
1828												  const char* desc,
1829												  ShaderType shaderType,
1830												  TestType testType,
1831												  ErrorType errorType)
1832	: 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")
1833{
1834}
1835
1836SSBOBindingNegativeCase::~SSBOBindingNegativeCase (void)
1837{
1838	deinit();
1839}
1840
1841glu::ShaderProgram* SSBOBindingNegativeCase::generateShaders (void) const
1842{
1843	std::ostringstream		vertexUniformDecl;
1844	std::ostringstream		fragmentUniformDecl;
1845	std::ostringstream		shaderBody;
1846	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1847	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
1848
1849	// Generate the uniform declarations for the vertex and fragment shaders
1850	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1851	{
1852		vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[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		fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") buffer "
1860			<< getUniformName(m_uniformName, declNdx) << "\n"
1861			<< "{\n"
1862			<< "	highp vec4 color1;\n"
1863			<< "	highp vec4 color2;\n"
1864			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1865	}
1866
1867	// Generate the shader body for the vertex and fragment shaders
1868	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
1869	{
1870		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
1871		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1872					<< "	{\n"
1873					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
1874					<< "	}\n";
1875	}
1876
1877	shaderBody	<< "	else\n"
1878				<< "	{\n"
1879				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1880				<< "	}\n";
1881
1882	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1883					<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
1884					<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
1885}
1886
1887
1888} // Anonymous
1889
1890LayoutBindingTests::LayoutBindingTests (Context& context)
1891	: TestCaseGroup (context, "layout_binding", "Layout binding tests")
1892{
1893}
1894
1895LayoutBindingTests::~LayoutBindingTests (void)
1896{
1897}
1898
1899void LayoutBindingTests::init (void)
1900{
1901	// Render test groups
1902	tcu::TestCaseGroup* const samplerBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "sampler",		"Test sampler layout binding");
1903	tcu::TestCaseGroup* const sampler2dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "sampler2d",	"Test sampler2d layout binding");
1904	tcu::TestCaseGroup* const sampler3dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "sampler3d",	"Test sampler3d layout binding");
1905
1906	tcu::TestCaseGroup* const imageBindingTestGroup				= new tcu::TestCaseGroup(m_testCtx, "image",		"Test image layout binding");
1907	tcu::TestCaseGroup* const image2dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "image2d",		"Test image2d layout binding");
1908	tcu::TestCaseGroup* const image3dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "image3d",		"Test image3d layout binding");
1909
1910	tcu::TestCaseGroup* const UBOBindingTestGroup				= new tcu::TestCaseGroup(m_testCtx, "ubo",			"Test UBO layout binding");
1911	tcu::TestCaseGroup* const SSBOBindingTestGroup				= new tcu::TestCaseGroup(m_testCtx, "ssbo",			"Test SSBO layout binding");
1912
1913	// Negative test groups
1914	tcu::TestCaseGroup* const negativeBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "negative",		"Test layout binding with invalid bindings");
1915
1916	tcu::TestCaseGroup* const negativeSamplerBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "sampler",		"Test sampler layout binding with invalid bindings");
1917	tcu::TestCaseGroup* const negativeSampler2dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "sampler2d",	"Test sampler2d layout binding with invalid bindings");
1918	tcu::TestCaseGroup* const negativeSampler3dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "sampler3d",	"Test sampler3d layout binding with invalid bindings");
1919
1920	tcu::TestCaseGroup* const negativeImageBindingTestGroup		= new tcu::TestCaseGroup(m_testCtx, "image",		"Test image layout binding with invalid bindings");
1921	tcu::TestCaseGroup* const negativeImage2dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "image2d",		"Test image2d layout binding with invalid bindings");
1922	tcu::TestCaseGroup* const negativeImage3dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "image3d",		"Test image3d layout binding with invalid bindings");
1923
1924	tcu::TestCaseGroup* const negativeUBOBindingTestGroup		= new tcu::TestCaseGroup(m_testCtx, "ubo",			"Test UBO layout binding with invalid bindings");
1925	tcu::TestCaseGroup* const negativeSSBOBindingTestGroup		= new tcu::TestCaseGroup(m_testCtx, "ssbo",			"Test SSBO layout binding with invalid bindings");
1926
1927	static const struct RenderTestType
1928	{
1929		ShaderType				shaderType;
1930		TestType			 	testType;
1931		std::string 			name;
1932		std::string 			descPostfix;
1933	} s_renderTestTypes[] =
1934	{
1935		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_SINGLE, 		"vertex_binding_single",	 	"a single instance" },
1936		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_MAX,			"vertex_binding_max",			"maximum binding point"	},
1937		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_MULTIPLE,		"vertex_binding_multiple",		"multiple instances"},
1938		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_ARRAY,			"vertex_binding_array",			"an array instance" },
1939		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_MAX_ARRAY,		"vertex_binding_max_array",		"an array instance with maximum binding point" },
1940
1941		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_SINGLE, 		"fragment_binding_single",	 	"a single instance" },
1942		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_MAX,			"fragment_binding_max",			"maximum binding point"	},
1943		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_MULTIPLE,		"fragment_binding_multiple",	"multiple instances"},
1944		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_ARRAY,			"fragment_binding_array",		"an array instance" },
1945		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_MAX_ARRAY,		"fragment_binding_max_array",	"an array instance with maximum binding point" },
1946	};
1947
1948	static const struct NegativeTestType
1949	{
1950		ShaderType								shaderType;
1951		TestType								testType;
1952		LayoutBindingNegativeCase::ErrorType	errorType;
1953		std::string								name;
1954		std::string								descPostfix;
1955	} s_negativeTestTypes[] =
1956	{
1957		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"vertex_binding_over_max",			"over maximum binding point"},
1958		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"fragment_binding_over_max",		"over maximum binding point"},
1959		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"vertex_binding_neg",				"negative binding point"},
1960		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"fragment_binding_neg",				"negative binding point"},
1961
1962		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"vertex_binding_over_max_array",	"over maximum binding point"},
1963		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"fragment_binding_over_max_array",	"over maximum binding point"},
1964		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"vertex_binding_neg_array",			"negative binding point"},
1965		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"fragment_binding_neg_array",		"negative binding point"},
1966
1967		{ SHADERTYPE_BOTH,		TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY,		"binding_contradictory",			"contradictory binding points"},
1968		{ SHADERTYPE_BOTH,		TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY,		"binding_contradictory_array",		"contradictory binding points"},
1969	};
1970
1971	// Render tests
1972	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_renderTestTypes); ++testNdx)
1973	{
1974		const RenderTestType& test = s_renderTestTypes[testNdx];
1975
1976		// Render sampler binding tests
1977		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));
1978		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));
1979
1980		// Render image binding tests
1981		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));
1982		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));
1983
1984		// Render UBO binding tests
1985		UBOBindingTestGroup->addChild(new UBOBindingRenderCase(m_context, test.name.c_str(), ("UBO layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType));
1986
1987		// Render SSBO binding tests
1988		SSBOBindingTestGroup->addChild(new SSBOBindingRenderCase(m_context, test.name.c_str(), ("SSBO layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType));
1989	}
1990
1991	// Negative binding tests
1992	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_negativeTestTypes); ++testNdx)
1993	{
1994		const NegativeTestType& test = s_negativeTestTypes[testNdx];
1995
1996		// Negative sampler binding tests
1997		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));
1998		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));
1999
2000		// Negative image binding tests
2001		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));
2002		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));
2003
2004		// Negative UBO binding tests
2005		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));
2006
2007		// Negative SSBO binding tests
2008		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));
2009	}
2010
2011	samplerBindingTestGroup->addChild(sampler2dBindingTestGroup);
2012	samplerBindingTestGroup->addChild(sampler3dBindingTestGroup);
2013
2014	imageBindingTestGroup->addChild(image2dBindingTestGroup);
2015	imageBindingTestGroup->addChild(image3dBindingTestGroup);
2016
2017	negativeSamplerBindingTestGroup->addChild(negativeSampler2dBindingTestGroup);
2018	negativeSamplerBindingTestGroup->addChild(negativeSampler3dBindingTestGroup);
2019
2020	negativeImageBindingTestGroup->addChild(negativeImage2dBindingTestGroup);
2021	negativeImageBindingTestGroup->addChild(negativeImage3dBindingTestGroup);
2022
2023	negativeBindingTestGroup->addChild(negativeSamplerBindingTestGroup);
2024	negativeBindingTestGroup->addChild(negativeUBOBindingTestGroup);
2025	negativeBindingTestGroup->addChild(negativeSSBOBindingTestGroup);
2026	negativeBindingTestGroup->addChild(negativeImageBindingTestGroup);
2027
2028	addChild(samplerBindingTestGroup);
2029	addChild(UBOBindingTestGroup);
2030	addChild(SSBOBindingTestGroup);
2031	addChild(imageBindingTestGroup);
2032	addChild(negativeBindingTestGroup);
2033}
2034
2035} // Functional
2036} // gles31
2037} // deqp
2038