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