Home | History | Annotate | Download | only in functional
      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 
     45 using tcu::TestLog;
     46 using tcu::Vec2;
     47 using tcu::Vec3;
     48 using tcu::Vec4;
     49 
     50 namespace deqp
     51 {
     52 namespace gles31
     53 {
     54 namespace Functional
     55 {
     56 namespace
     57 {
     58 
     59 enum 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 
     70 enum ShaderType
     71 {
     72 	SHADERTYPE_VERTEX = 0,
     73 	SHADERTYPE_FRAGMENT,
     74 	SHADERTYPE_BOTH,
     75 
     76 	SHADERTYPE_LAST,
     77 };
     78 
     79 enum
     80 {
     81 	MAX_UNIFORM_MULTIPLE_INSTANCES	= 7,
     82 	MAX_UNIFORM_ARRAY_SIZE			= 7,
     83 };
     84 
     85 std::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 
    125 std::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 
    181 std::string getUniformName (const std::string& name, int declNdx)
    182 {
    183 	return name + de::toString(declNdx);
    184 }
    185 
    186 std::string getUniformName (const std::string& name, int declNdx, int arrNdx)
    187 {
    188 	return name + de::toString(declNdx) + "[" + de::toString(arrNdx) + "]";
    189 }
    190 
    191 Vec4 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 
    199 class LayoutBindingRenderCase : public TestCase
    200 {
    201 public:
    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 
    224 protected:
    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 
    250 private:
    251 	void								initBindingPoints				(int minBindingPoint, int numBindingPoints);
    252 };
    253 
    254 LayoutBindingRenderCase::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 
    282 LayoutBindingRenderCase::~LayoutBindingRenderCase (void)
    283 {
    284 	deinit();
    285 }
    286 
    287 void 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 
    422 void 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 
    446 void 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 
    517 void 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 
    527 bool 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 
    551 void 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 
    563 class LayoutBindingNegativeCase : public TestCase
    564 {
    565 public:
    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 
    592 protected:
    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 
    608 private:
    609 	void								initBindingPoints				(int minBindingPoint, int numBindingPoints);
    610 };
    611 
    612 LayoutBindingNegativeCase::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 
    637 LayoutBindingNegativeCase::~LayoutBindingNegativeCase (void)
    638 {
    639 	deinit();
    640 }
    641 
    642 void 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 
    737 void LayoutBindingNegativeCase::deinit (void)
    738 {
    739 	if (m_program)
    740 	{
    741 		delete m_program;
    742 		m_program = DE_NULL;
    743 	}
    744 }
    745 
    746 TestCase::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 
    778 void 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 
    819 class SamplerBindingRenderCase : public LayoutBindingRenderCase
    820 {
    821 public:
    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 
    829 private:
    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 
    842 SamplerBindingRenderCase::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 
    855 SamplerBindingRenderCase::~SamplerBindingRenderCase (void)
    856 {
    857 	deinit();
    858 }
    859 
    860 void 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 
    883 void 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 
    898 TestCase::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 
    934 glu::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 
    970 void 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 
   1003 glu::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 
   1020 class SamplerBindingNegativeCase : public LayoutBindingNegativeCase
   1021 {
   1022 public:
   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 
   1032 private:
   1033 	glu::ShaderProgram*				generateShaders					(void) const;
   1034 	glu::DataType					getSamplerTexCoordType			(void) const;
   1035 
   1036 	const glw::GLenum				m_samplerType;
   1037 };
   1038 
   1039 SamplerBindingNegativeCase::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 
   1051 SamplerBindingNegativeCase::~SamplerBindingNegativeCase (void)
   1052 {
   1053 	LayoutBindingNegativeCase::deinit();
   1054 }
   1055 
   1056 glu::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 
   1095 glu::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 
   1111 class ImageBindingRenderCase : public LayoutBindingRenderCase
   1112 {
   1113 public:
   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 
   1127 private:
   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 
   1140 ImageBindingRenderCase::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 
   1153 ImageBindingRenderCase::~ImageBindingRenderCase (void)
   1154 {
   1155 	deinit();
   1156 }
   1157 
   1158 void 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 
   1179 void 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 
   1194 TestCase::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 
   1229 void 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 
   1266 glu::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 
   1302 glu::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 
   1319 class ImageBindingNegativeCase : public LayoutBindingNegativeCase
   1320 {
   1321 public:
   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 
   1331 private:
   1332 	glu::ShaderProgram*						generateShaders					(void) const;
   1333 	glu::DataType							getImageTexCoordType			(void) const;
   1334 
   1335 	const glw::GLenum						m_imageType;
   1336 };
   1337 
   1338 ImageBindingNegativeCase::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 
   1350 ImageBindingNegativeCase::~ImageBindingNegativeCase (void)
   1351 {
   1352 	deinit();
   1353 }
   1354 
   1355 glu::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 
   1394 glu::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 
   1411 class UBOBindingRenderCase : public LayoutBindingRenderCase
   1412 {
   1413 public:
   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 
   1425 private:
   1426 	glu::ShaderProgram*						generateShaders				(void) const;
   1427 
   1428 	std::vector<deUint32>					m_buffers;
   1429 	std::vector<Vec4>						m_expectedColors;
   1430 };
   1431 
   1432 UBOBindingRenderCase::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 
   1441 UBOBindingRenderCase::~UBOBindingRenderCase (void)
   1442 {
   1443 	deinit();
   1444 }
   1445 
   1446 void 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 
   1473 void 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 
   1488 TestCase::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 
   1530 glu::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 
   1569 class UBOBindingNegativeCase : public LayoutBindingNegativeCase
   1570 {
   1571 public:
   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 
   1580 private:
   1581 	glu::ShaderProgram*						generateShaders					(void) const;
   1582 };
   1583 
   1584 UBOBindingNegativeCase::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 
   1594 UBOBindingNegativeCase::~UBOBindingNegativeCase (void)
   1595 {
   1596 	deinit();
   1597 }
   1598 
   1599 glu::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 
   1646 class SSBOBindingRenderCase : public LayoutBindingRenderCase
   1647 {
   1648 public:
   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 
   1660 private:
   1661 	glu::ShaderProgram*						generateShaders				(void) const;
   1662 
   1663 	std::vector<glw::GLuint>				m_buffers;
   1664 	std::vector<Vec4>						m_expectedColors;
   1665 };
   1666 
   1667 SSBOBindingRenderCase::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 
   1676 SSBOBindingRenderCase::~SSBOBindingRenderCase (void)
   1677 {
   1678 	deinit();
   1679 }
   1680 
   1681 void 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 
   1708 void 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 
   1724 TestCase::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 
   1765 glu::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 
   1804 class SSBOBindingNegativeCase : public LayoutBindingNegativeCase
   1805 {
   1806 public:
   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 
   1815 private:
   1816 	glu::ShaderProgram*						generateShaders					(void) const;
   1817 };
   1818 
   1819 SSBOBindingNegativeCase::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 
   1829 SSBOBindingNegativeCase::~SSBOBindingNegativeCase (void)
   1830 {
   1831 	deinit();
   1832 }
   1833 
   1834 glu::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 
   1883 LayoutBindingTests::LayoutBindingTests (Context& context)
   1884 	: TestCaseGroup (context, "layout_binding", "Layout binding tests")
   1885 {
   1886 }
   1887 
   1888 LayoutBindingTests::~LayoutBindingTests (void)
   1889 {
   1890 }
   1891 
   1892 void 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