/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Basic Layout Binding Tests.
 *//*--------------------------------------------------------------------*/

#include "es31fLayoutBindingTests.hpp"

#include "gluShaderProgram.hpp"
#include "gluPixelTransfer.hpp"
#include "gluTextureUtil.hpp"

#include "glwFunctions.hpp"
#include "glwEnums.hpp"

#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuRenderTarget.hpp"

#include "deString.h"
#include "deStringUtil.hpp"
#include "deRandom.hpp"

using tcu::TestLog;
using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

enum TestType
{
	TESTTYPE_BINDING_SINGLE = 0,
	TESTTYPE_BINDING_MAX,
	TESTTYPE_BINDING_MULTIPLE,
	TESTTYPE_BINDING_ARRAY,
	TESTTYPE_BINDING_MAX_ARRAY,

	TESTTYPE_BINDING_LAST,
};

enum ShaderType
{
	SHADERTYPE_VERTEX = 0,
	SHADERTYPE_FRAGMENT,
	SHADERTYPE_BOTH,

	SHADERTYPE_LAST,
};

enum
{
	MAX_UNIFORM_MULTIPLE_INSTANCES	= 7,
	MAX_UNIFORM_ARRAY_SIZE			= 7,
};

std::string generateVertexShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
{
	static const char* const s_simpleVertexShaderSource	=	"#version 310 es\n"
															"in highp vec4 a_position;\n"
															"void main (void)\n"
															"{\n"
															"	gl_Position = a_position;\n"
															"}\n";

	switch (shaderType)
	{
		case SHADERTYPE_VERTEX:
		case SHADERTYPE_BOTH:
		{
			std::ostringstream vertexShaderSource;
			vertexShaderSource	<<	"#version 310 es\n"
								<<	"in highp vec4 a_position;\n"
								<<	"out highp vec4 v_color;\n"
								<<	"uniform highp int u_arrayNdx;\n\n"
								<<	shaderUniformDeclarations << "\n"
								<<	"void main (void)\n"
								<<	"{\n"
								<<	"	highp vec4 color;\n\n"
								<<	shaderBody << "\n"
								<<	"	v_color = color;\n"
								<<	"	gl_Position = a_position;\n"
								<<	"}\n";

			return vertexShaderSource.str();
		}

		case SHADERTYPE_FRAGMENT:
			return s_simpleVertexShaderSource;

		default:
			DE_ASSERT(false);
			return "";
	}
}

std::string generateFragmentShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
{
	static const char* const s_simpleFragmentShaderSource = "#version 310 es\n"
															"in highp vec4 v_color;\n"
															"layout(location = 0) out highp vec4 fragColor;\n"
															"void main (void)\n"
															"{\n"
															"	fragColor = v_color;\n"
															"}\n";

	switch (shaderType)
	{
		case SHADERTYPE_VERTEX:
			return s_simpleFragmentShaderSource;

		case SHADERTYPE_FRAGMENT:
		{
			std::ostringstream fragmentShaderSource;
			fragmentShaderSource	<<	"#version 310 es\n"
									<<	"layout(location = 0) out highp vec4 fragColor;\n"
									<<	"uniform highp int u_arrayNdx;\n\n"
									<<	shaderUniformDeclarations << "\n"
									<<	"void main (void)\n"
									<<	"{\n"
									<<	"	highp vec4 color;\n\n"
									<<	shaderBody << "\n"
									<<	"	fragColor = color;\n"
									<<	"}\n";

			return fragmentShaderSource.str();
		}
		case SHADERTYPE_BOTH:
		{
			std::ostringstream fragmentShaderSource;
			fragmentShaderSource	<<	"#version 310 es\n"
									<<	"in highp vec4 v_color;\n"
									<<	"layout(location = 0) out highp vec4 fragColor;\n"
									<<	"uniform highp int u_arrayNdx;\n\n"
									<<	shaderUniformDeclarations << "\n"
									<<	"void main (void)\n"
									<<	"{\n"
									<<	"	if (v_color.x > 2.0) discard;\n"
									<<	"	highp vec4 color;\n\n"
									<<	shaderBody << "\n"
									<<	"	fragColor = color;\n"
									<<	"}\n";

			return fragmentShaderSource.str();
		}

		default:
			DE_ASSERT(false);
			return "";
	}
}

std::string getUniformName (const std::string& name, int declNdx)
{
	return name + de::toString(declNdx);
}

std::string getUniformName (const std::string& name, int declNdx, int arrNdx)
{
	return name + de::toString(declNdx) + "[" + de::toString(arrNdx) + "]";
}

Vec4 getRandomColor (de::Random& rnd)
{
	const float r = rnd.getFloat(0.2f, 0.9f);
	const float g = rnd.getFloat(0.2f, 0.9f);
	const float b = rnd.getFloat(0.2f, 0.9f);
	return Vec4(r, g, b, 1.0f);
}

class LayoutBindingRenderCase : public TestCase
{
public:
	enum
	{
		MAX_TEST_RENDER_WIDTH	= 256,
		MAX_TEST_RENDER_HEIGHT	= 256,
		TEST_TEXTURE_SIZE	= 1,
	};

										LayoutBindingRenderCase			(Context&			context,
																		 const char*		name,
																		 const char*		desc,
																		 ShaderType			shaderType,
																		 TestType			testType,
																		 glw::GLenum		maxBindingPointEnum,
																		 glw::GLenum		maxVertexUnitsEnum,
																		 glw::GLenum		maxFragmentUnitsEnum,
																		 glw::GLenum		maxCombinedUnitsEnum,
																		 const std::string& uniformName);
	virtual								~LayoutBindingRenderCase		(void);

	virtual void						init							(void);
	virtual void						deinit							(void);

	int									getRenderWidth					(void) const { return de::min((int)MAX_TEST_RENDER_WIDTH, m_context.getRenderTarget().getWidth()); }
	int									getRenderHeight					(void) const { return de::min((int)MAX_TEST_RENDER_HEIGHT, m_context.getRenderTarget().getHeight()); }
protected:
	virtual glu::ShaderProgram*			generateShaders					(void) const = 0;

	void								initRenderState					(void);
	bool								drawAndVerifyResult				(const Vec4& expectedColor);
	void								setTestResult					(bool queryTestPassed, bool imageTestPassed);

	const glu::ShaderProgram*			m_program;
	const ShaderType					m_shaderType;
	const TestType						m_testType;
	const std::string					m_uniformName;

	const glw::GLenum					m_maxBindingPointEnum;
	const glw::GLenum					m_maxVertexUnitsEnum;
	const glw::GLenum					m_maxFragmentUnitsEnum;
	const glw::GLenum					m_maxCombinedUnitsEnum;

	glw::GLuint							m_vertexBuffer;
	glw::GLuint							m_indexBuffer;
	glw::GLint							m_shaderProgramLoc;
	glw::GLint							m_shaderProgramPosLoc;
	glw::GLint							m_shaderProgramArrayNdxLoc;
	glw::GLint							m_numBindings;

	std::vector<glw::GLint>				m_bindings;

private:
	void								initBindingPoints				(int minBindingPoint, int numBindingPoints);
};

LayoutBindingRenderCase::LayoutBindingRenderCase (Context&				context,
												  const char*			name,
												  const char*			desc,
												  ShaderType			shaderType,
												  TestType				testType,
												  glw::GLenum			maxBindingPointEnum,
												  glw::GLenum			maxVertexUnitsEnum,
												  glw::GLenum			maxFragmentUnitsEnum,
												  glw::GLenum			maxCombinedUnitsEnum,
												  const std::string&	uniformName)
	: TestCase						(context, name, desc)
	, m_program						(DE_NULL)
	, m_shaderType					(shaderType)
	, m_testType					(testType)
	, m_uniformName					(uniformName)
	, m_maxBindingPointEnum			(maxBindingPointEnum)
	, m_maxVertexUnitsEnum			(maxVertexUnitsEnum)
	, m_maxFragmentUnitsEnum		(maxFragmentUnitsEnum)
	, m_maxCombinedUnitsEnum		(maxCombinedUnitsEnum)
	, m_vertexBuffer				(0)
	, m_indexBuffer					(0)
	, m_shaderProgramLoc			(0)
	, m_shaderProgramPosLoc			(0)
	, m_shaderProgramArrayNdxLoc	(0)
	, m_numBindings					(0)
{
}

LayoutBindingRenderCase::~LayoutBindingRenderCase (void)
{
	deinit();
}

void LayoutBindingRenderCase::init (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	{
		de::Random				rnd					(deStringHash(getName()) ^ 0xff23a4);
		glw::GLint				numBindingPoints	= 0;	// Number of available binding points
		glw::GLint				maxVertexUnits		= 0;	// Available uniforms in the vertex shader
		glw::GLint				maxFragmentUnits	= 0;	// Available uniforms in the fragment shader
		glw::GLint				maxCombinedUnits	= 0;	// Available uniforms in all the shader stages combined
		glw::GLint				maxUnits			= 0;	// Maximum available uniforms for this test

		gl.getIntegerv(m_maxVertexUnitsEnum, &maxVertexUnits);
		gl.getIntegerv(m_maxFragmentUnitsEnum, &maxFragmentUnits);
		gl.getIntegerv(m_maxCombinedUnitsEnum, &maxCombinedUnits);
		gl.getIntegerv(m_maxBindingPointEnum, &numBindingPoints);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Querying available uniform numbers failed");

		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the vertex shader: " << maxVertexUnits << tcu::TestLog::EndMessage;
		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the fragment shader: " << maxFragmentUnits << tcu::TestLog::EndMessage;
		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum combined units for uniform type: " << maxCombinedUnits << tcu::TestLog::EndMessage;
		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum binding point for uniform type: " << numBindingPoints-1 << tcu::TestLog::EndMessage;

		// Select maximum number of uniforms used for the test
		switch (m_shaderType)
		{
			case SHADERTYPE_VERTEX:
				maxUnits = maxVertexUnits;
				break;

			case SHADERTYPE_FRAGMENT:
				maxUnits = maxFragmentUnits;
				break;

			case SHADERTYPE_BOTH:
				maxUnits = maxCombinedUnits/2;
				break;

			default:
				DE_ASSERT(false);
		}

		// Select the number of uniforms (= bindings) used for this test
		switch (m_testType)
		{
			case TESTTYPE_BINDING_SINGLE:
			case TESTTYPE_BINDING_MAX:
				m_numBindings = 1;
				break;

			case TESTTYPE_BINDING_MULTIPLE:
				if (maxUnits < 2)
					throw tcu::NotSupportedError("Not enough uniforms available for test");
				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_MULTIPLE_INSTANCES, maxUnits));
				break;

			case TESTTYPE_BINDING_ARRAY:
			case TESTTYPE_BINDING_MAX_ARRAY:
				if (maxUnits < 2)
					throw tcu::NotSupportedError("Not enough uniforms available for test");
				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits));
				break;

			default:
				DE_ASSERT(false);
		}

		// Check that we have enough uniforms in different shaders to perform the tests
		if ( ((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_BOTH)) && (maxVertexUnits < m_numBindings) )
			throw tcu::NotSupportedError("Vertex shader: not enough uniforms available for test");
		if ( ((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_BOTH)) && (maxFragmentUnits < m_numBindings) )
			throw tcu::NotSupportedError("Fragment shader: not enough uniforms available for test");
		if ( (m_shaderType == SHADERTYPE_BOTH) && (maxCombinedUnits < m_numBindings*2) )
			throw tcu::NotSupportedError("Not enough uniforms available for test");

		// Check that we have enough binding points to perform the tests
		if (numBindingPoints < m_numBindings)
			throw tcu::NotSupportedError("Not enough binding points available for test");

		// Initialize the binding points i.e. populate the two binding point vectors
		initBindingPoints(0, numBindingPoints);
	}

	// Generate the shader program - note: this must be done after deciding the binding points
	DE_ASSERT(!m_program);
	m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shaders" << tcu::TestLog::EndMessage;
	m_program = generateShaders();
	m_testCtx.getLog() << *m_program;

	if (!m_program->isOk())
		throw tcu::TestError("Shader compile failed");

	// Setup vertex and index buffers
	{
		// Get attribute and uniform locations
		const deUint32	program	= m_program->getProgram();

		m_shaderProgramPosLoc		= gl.getAttribLocation(program, "a_position");
		m_shaderProgramArrayNdxLoc	= gl.getUniformLocation(program, "u_arrayNdx");
		m_vertexBuffer				= 0;
		m_indexBuffer				= 0;

		// Setup buffers so that we render one quad covering the whole viewport
		const Vec3 vertices[] =
		{
			Vec3(-1.0f, -1.0f, +1.0f),
			Vec3(+1.0f, -1.0f, +1.0f),
			Vec3(+1.0f, +1.0f, +1.0f),
			Vec3(-1.0f, +1.0f, +1.0f),
		};

		const deUint16 indices[] =
		{
			0, 1, 2,
			0, 2, 3,
		};

		TCU_CHECK((m_shaderProgramPosLoc >= 0) && (m_shaderProgramArrayNdxLoc >= 0));

		// Generate and bind index buffer
		gl.genBuffers(1, &m_indexBuffer);
		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
		gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (DE_LENGTH_OF_ARRAY(indices)*(glw::GLsizeiptr)sizeof(indices[0])), &indices[0], GL_STATIC_DRAW);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Index buffer setup failed");

		// Generate and bind vertex buffer
		gl.genBuffers(1, &m_vertexBuffer);
		gl.bindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
		gl.bufferData(GL_ARRAY_BUFFER, (DE_LENGTH_OF_ARRAY(vertices)*(glw::GLsizeiptr)sizeof(vertices[0])), &vertices[0], GL_STATIC_DRAW);
		gl.enableVertexAttribArray(m_shaderProgramPosLoc);
		gl.vertexAttribPointer(m_shaderProgramPosLoc, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex buffer setup failed");
	}
}

void LayoutBindingRenderCase::deinit (void)
{
	if (m_program)
	{
		delete m_program;
		m_program = DE_NULL;
	}

	if (m_shaderProgramPosLoc)
		m_context.getRenderContext().getFunctions().disableVertexAttribArray(m_shaderProgramPosLoc);

	if (m_vertexBuffer)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_vertexBuffer);
		m_context.getRenderContext().getFunctions().bindBuffer(GL_ARRAY_BUFFER, 0);
	}

	if (m_indexBuffer)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_indexBuffer);
		m_context.getRenderContext().getFunctions().bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	}
}

void LayoutBindingRenderCase::initBindingPoints (int minBindingPoint, int numBindingPoints)
{
	de::Random rnd(deStringHash(getName()) ^ 0xff23a4);

	switch (m_testType)
	{
		case TESTTYPE_BINDING_SINGLE:
		{
			const int bpoint = rnd.getInt(minBindingPoint, numBindingPoints-1);
			m_bindings.push_back(bpoint);
			break;
		}

		case TESTTYPE_BINDING_MAX:
			m_bindings.push_back(numBindingPoints-1);
			break;

		case TESTTYPE_BINDING_MULTIPLE:
		{
			// Choose multiple unique binding points from the low and high end of available binding points
			std::vector<deUint32> lowBindingPoints;
			std::vector<deUint32> highBindingPoints;

			for (int bpoint = 0; bpoint < numBindingPoints/2; ++bpoint)
				lowBindingPoints.push_back(bpoint);
			for (int bpoint = numBindingPoints/2; bpoint < numBindingPoints; ++bpoint)
				highBindingPoints.push_back(bpoint);

			rnd.shuffle(lowBindingPoints.begin(), lowBindingPoints.end());
			rnd.shuffle(highBindingPoints.begin(), highBindingPoints.end());

			for (int ndx = 0; ndx < m_numBindings; ++ndx)
			{
				if (ndx%2 == 0)
				{
					const int bpoint = lowBindingPoints.back();
					lowBindingPoints.pop_back();
					m_bindings.push_back(bpoint);
				}
				else
				{
					const int bpoint = highBindingPoints.back();
					highBindingPoints.pop_back();
					m_bindings.push_back(bpoint);
				}

			}
			break;
		}

		case TESTTYPE_BINDING_ARRAY:
		{
			const glw::GLint binding = rnd.getInt(minBindingPoint, numBindingPoints-m_numBindings);
			for (int ndx = 0; ndx < m_numBindings; ++ndx)
				m_bindings.push_back(binding+ndx);
			break;
		}

		case TESTTYPE_BINDING_MAX_ARRAY:
		{
			const glw::GLint binding = numBindingPoints-m_numBindings;
			for (int ndx = 0; ndx < m_numBindings; ++ndx)
				m_bindings.push_back(binding+ndx);
			break;
		}

		default:
			DE_ASSERT(false);
	}
}

void LayoutBindingRenderCase::initRenderState (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.useProgram(m_program->getProgram());
	gl.viewport(0, 0, getRenderWidth(), getRenderHeight());
	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set render state");
}

bool LayoutBindingRenderCase::drawAndVerifyResult (const Vec4& expectedColor)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	tcu::Surface			reference			(getRenderWidth(), getRenderHeight());

	// the point of these test is to check layout_binding. For this purpose, we can use quite
	// large thresholds.
	const tcu::RGBA			surfaceThreshold	= m_context.getRenderContext().getRenderTarget().getPixelFormat().getColorThreshold();
	const tcu::RGBA			compareThreshold	= tcu::RGBA(de::clamp(2 * surfaceThreshold.getRed(),   0, 255),
															de::clamp(2 * surfaceThreshold.getGreen(), 0, 255),
															de::clamp(2 * surfaceThreshold.getBlue(),  0, 255),
															de::clamp(2 * surfaceThreshold.getAlpha(), 0, 255));

	gl.clear(GL_COLOR_BUFFER_BIT);

	// Draw
	gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Drawing failed");

	// Verify
	tcu::Surface result(getRenderWidth(), getRenderHeight());
	m_testCtx.getLog() << TestLog::Message << "Reading pixels" << TestLog::EndMessage;
	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
	GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels failed");

	tcu::clear(reference.getAccess(), expectedColor);
	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output image, fragment output color is " << expectedColor << tcu::TestLog::EndMessage;

	return tcu::pixelThresholdCompare(m_testCtx.getLog(), "Render result", "Result verification", reference, result, compareThreshold, tcu::COMPARE_LOG_RESULT);
}

void LayoutBindingRenderCase::setTestResult (bool queryTestPassed, bool imageTestPassed)
{
	if (queryTestPassed && imageTestPassed)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else if (!queryTestPassed && !imageTestPassed)
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more binding point queries and image comparisons failed");
	else if (!queryTestPassed)
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more binding point queries failed");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more image comparisons failed");
}

class LayoutBindingNegativeCase : public TestCase
{
public:
	enum ErrorType
	{
		ERRORTYPE_OVER_MAX_UNITS = 0,
		ERRORTYPE_LESS_THAN_ZERO,
		ERRORTYPE_CONTRADICTORY,

		ERRORTYPE_LAST,
	};

										LayoutBindingNegativeCase		(Context&			context,
																		 const char*		name,
																		 const char*		desc,
																		 ShaderType			shaderType,
																		 TestType			testType,
																		 ErrorType			errorType,
																		 glw::GLenum		maxBindingPointEnum,
																		 glw::GLenum		maxVertexUnitsEnum,
																		 glw::GLenum		maxFragmentUnitsEnum,
																		 glw::GLenum		maxCombinedUnitsEnum,
																		 const std::string& uniformName);
	virtual								~LayoutBindingNegativeCase		(void);

	virtual void						init							(void);
	virtual void						deinit							(void);
	virtual IterateResult				iterate							(void);

protected:
	virtual glu::ShaderProgram*			generateShaders					(void) const = 0;

	const glu::ShaderProgram*			m_program;
	const ShaderType					m_shaderType;
	const TestType						m_testType;
	const ErrorType						m_errorType;
	const glw::GLenum					m_maxBindingPointEnum;
	const glw::GLenum					m_maxVertexUnitsEnum;
	const glw::GLenum					m_maxFragmentUnitsEnum;
	const glw::GLenum					m_maxCombinedUnitsEnum;
	const std::string					m_uniformName;
	glw::GLint							m_numBindings;
	std::vector<glw::GLint>				m_vertexShaderBinding;
	std::vector<glw::GLint>				m_fragmentShaderBinding;

private:
	void								initBindingPoints				(int minBindingPoint, int numBindingPoints);
};

LayoutBindingNegativeCase::LayoutBindingNegativeCase (Context&				context,
													  const char*			name,
													  const char*			desc,
													  ShaderType			shaderType,
													  TestType				testType,
													  ErrorType				errorType,
													  glw::GLenum			maxBindingPointEnum,
													  glw::GLenum			maxVertexUnitsEnum,
													  glw::GLenum			maxFragmentUnitsEnum,
													  glw::GLenum			maxCombinedUnitsEnum,
													  const std::string&	uniformName)
	: TestCase					(context, name, desc)
	, m_program					(DE_NULL)
	, m_shaderType				(shaderType)
	, m_testType				(testType)
	, m_errorType				(errorType)
	, m_maxBindingPointEnum		(maxBindingPointEnum)
	, m_maxVertexUnitsEnum		(maxVertexUnitsEnum)
	, m_maxFragmentUnitsEnum	(maxFragmentUnitsEnum)
	, m_maxCombinedUnitsEnum	(maxCombinedUnitsEnum)
	, m_uniformName				(uniformName)
	, m_numBindings				(0)
{
}

LayoutBindingNegativeCase::~LayoutBindingNegativeCase (void)
{
	deinit();
}

void LayoutBindingNegativeCase::init (void)
{
	// Decide appropriate binding points for the vertex and fragment shaders
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	de::Random				rnd					(deStringHash(getName()) ^ 0xff23a4);
	glw::GLint				numBindingPoints	= 0;	// Number of binding points
	glw::GLint				maxVertexUnits		= 0;	// Available uniforms in the vertex shader
	glw::GLint				maxFragmentUnits	= 0;	// Available uniforms in the fragment shader
	glw::GLint				maxCombinedUnits	= 0;	// Available uniforms in all the shader stages combined
	glw::GLint				maxUnits			= 0;	// Maximum available uniforms for this test

	gl.getIntegerv(m_maxVertexUnitsEnum, &maxVertexUnits);
	gl.getIntegerv(m_maxFragmentUnitsEnum, &maxFragmentUnits);
	gl.getIntegerv(m_maxCombinedUnitsEnum, &maxCombinedUnits);
	gl.getIntegerv(m_maxBindingPointEnum, &numBindingPoints);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Querying available uniform numbers failed");

	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the vertex shader: " << maxVertexUnits << tcu::TestLog::EndMessage;
	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the fragment shader: " << maxFragmentUnits << tcu::TestLog::EndMessage;
	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum combined units for uniform type: " << maxCombinedUnits << tcu::TestLog::EndMessage;
	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum binding point for uniform type: " << numBindingPoints-1 << tcu::TestLog::EndMessage;

	// Select maximum number of uniforms used for the test
	switch (m_shaderType)
	{
		case SHADERTYPE_VERTEX:
			maxUnits = maxVertexUnits;
			break;

		case SHADERTYPE_FRAGMENT:
			maxUnits = maxFragmentUnits;
			break;

		case SHADERTYPE_BOTH:
			maxUnits = de::min(de::min(maxVertexUnits, maxFragmentUnits), maxCombinedUnits/2);
			break;

		default:
			DE_ASSERT(false);
	}

	// Select the number of uniforms (= bindings) used for this test
	switch (m_testType)
	{
		case TESTTYPE_BINDING_SINGLE:
		case TESTTYPE_BINDING_MAX:
			m_numBindings = 1;
			break;

		case TESTTYPE_BINDING_MULTIPLE:
		case TESTTYPE_BINDING_ARRAY:
		case TESTTYPE_BINDING_MAX_ARRAY:
			if (m_errorType == ERRORTYPE_CONTRADICTORY)
			{
				// leave room for contradictory case
				if (maxUnits < 3)
					throw tcu::NotSupportedError("Not enough uniforms available for test");
				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits-1));
			}
			else
			{
				if (maxUnits < 2)
					throw tcu::NotSupportedError("Not enough uniforms available for test");
				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits));
			}
			break;

		default:
			DE_ASSERT(false);
	}

	// Check that we have enough uniforms in different shaders to perform the tests
	if ( ((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_BOTH)) && (maxVertexUnits < m_numBindings) )
		throw tcu::NotSupportedError("Vertex shader: not enough uniforms available for test");
	if ( ((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_BOTH)) && (maxFragmentUnits < m_numBindings) )
		throw tcu::NotSupportedError("Fragment shader: not enough uniforms available for test");
	if ( (m_shaderType == SHADERTYPE_BOTH) && (maxCombinedUnits < m_numBindings*2) )
		throw tcu::NotSupportedError("Not enough uniforms available for test");

	// Check that we have enough binding points to perform the tests
	if (numBindingPoints < m_numBindings)
		throw tcu::NotSupportedError("Not enough binding points available for test");
	if (m_errorType == ERRORTYPE_CONTRADICTORY && numBindingPoints == m_numBindings)
		throw tcu::NotSupportedError("Not enough binding points available for test");

	// Initialize the binding points i.e. populate the two binding point vectors
	initBindingPoints(0, numBindingPoints);

	// Generate the shader program - note: this must be done after deciding the binding points
	DE_ASSERT(!m_program);
	m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shaders" << tcu::TestLog::EndMessage;
	m_program = generateShaders();
	m_testCtx.getLog() << *m_program;
}

void LayoutBindingNegativeCase::deinit (void)
{
	if (m_program)
	{
		delete m_program;
		m_program = DE_NULL;
	}
}

TestCase::IterateResult LayoutBindingNegativeCase::iterate (void)
{
	bool pass = false;
	std::string failMessage;

	switch (m_errorType)
	{
		case ERRORTYPE_CONTRADICTORY:		// Contradictory binding points should cause a link-time error
			if (!(m_program->getProgramInfo()).linkOk)
				pass = true;
			failMessage = "Test failed - expected a link-time error";
			break;

		case ERRORTYPE_LESS_THAN_ZERO:		// Out of bounds binding points should cause a compile-time error
		case ERRORTYPE_OVER_MAX_UNITS:
			if (!(m_program->getShaderInfo(glu::SHADERTYPE_VERTEX)).compileOk || !(m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT)).compileOk)
				pass = true;
			failMessage = "Test failed - expected a compile-time error";
			break;

		default:
			DE_ASSERT(false);
	}

	if (pass)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, failMessage.c_str());

	return STOP;
}

void LayoutBindingNegativeCase::initBindingPoints (int minBindingPoint, int numBindingPoints)
{
	de::Random rnd(deStringHash(getName()) ^ 0xff23a4);

	switch (m_errorType)
	{
		case ERRORTYPE_OVER_MAX_UNITS:	// Select a binding point that is 1 over the maximum
		{
			m_vertexShaderBinding.push_back(numBindingPoints+1-m_numBindings);
			m_fragmentShaderBinding.push_back(numBindingPoints+1-m_numBindings);
			break;
		}

		case ERRORTYPE_LESS_THAN_ZERO:	// Select a random negative binding point
		{
			const glw::GLint binding = -rnd.getInt(1, m_numBindings);
			m_vertexShaderBinding.push_back(binding);
			m_fragmentShaderBinding.push_back(binding);
			break;
		}

		case ERRORTYPE_CONTRADICTORY:	// Select two valid, but contradictory binding points
		{
			m_vertexShaderBinding.push_back(minBindingPoint);
			m_fragmentShaderBinding.push_back((minBindingPoint+1)%numBindingPoints);
			DE_ASSERT(m_vertexShaderBinding.back() != m_fragmentShaderBinding.back());
			break;
		}

		default:
			DE_ASSERT(false);
	}

	// In case we are testing with multiple uniforms populate the rest of the binding points
	for (int ndx = 1; ndx < m_numBindings; ++ndx)
	{
		m_vertexShaderBinding.push_back(m_vertexShaderBinding.front()+ndx);
		m_fragmentShaderBinding.push_back(m_fragmentShaderBinding.front()+ndx);
	}
}

class SamplerBindingRenderCase : public LayoutBindingRenderCase
{
public:
									SamplerBindingRenderCase		(Context& context, const char* name, const char* desc, ShaderType shaderType, TestType testType, glw::GLenum samplerType, glw::GLenum textureType);
									~SamplerBindingRenderCase		(void);

	void							init							(void);
	void							deinit							(void);
	IterateResult					iterate							(void);

private:
	glu::ShaderProgram*				generateShaders					(void) const;
	glu::DataType					getSamplerTexCoordType			(void) const;
	void							initializeTexture				(glw::GLint bindingPoint, glw::GLint textureName, const Vec4& color) const;

	const glw::GLenum				m_samplerType;
	const glw::GLenum				m_textureType;

	std::vector<glw::GLuint>		m_textures;
	std::vector<Vec4>				m_textureColors;
};


SamplerBindingRenderCase::SamplerBindingRenderCase (Context&		context,
													const char*		name,
													const char*		desc,
													ShaderType		shaderType,
													TestType		testType,
													glw::GLenum		samplerType,
													glw::GLenum		textureType)
	: 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")
	, m_samplerType				(samplerType)
	, m_textureType				(textureType)
{
}

SamplerBindingRenderCase::~SamplerBindingRenderCase (void)
{
	deinit();
}

void SamplerBindingRenderCase::init (void)
{
	LayoutBindingRenderCase::init();
	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);


	// Initialize texture resources
	m_textures = std::vector<glw::GLuint>(m_numBindings,  0);

	// Texture colors
	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
		m_textureColors.push_back(getRandomColor(rnd));

	// Textures
	gl.genTextures((glw::GLsizei)m_textures.size(), &m_textures[0]);

	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
		initializeTexture(m_bindings[texNdx], m_textures[texNdx], m_textureColors[texNdx]);

	gl.activeTexture(GL_TEXTURE0);
}

void SamplerBindingRenderCase::deinit(void)
{
	LayoutBindingRenderCase::deinit();

	// Clean up texture data
	for (int i = 0; i < (int)m_textures.size(); ++i)
	{
		if (m_textures[i])
		{
			m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[i]);
			m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0);
		}
	}
}

TestCase::IterateResult SamplerBindingRenderCase::iterate (void)
{
	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	const int				iterations		= m_numBindings;
	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
	bool					imageTestPassed	= true;
	bool					queryTestPassed	= true;

	// Set the viewport and enable the shader program
	initRenderState();

	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
	{
		// Set the uniform value indicating the current array index
		gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx);

		// Query binding point
		const std::string	name	= arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx);
		const glw::GLint	binding = m_bindings[iterNdx];
		glw::GLint			val		= -1;

		gl.getUniformiv(m_program->getProgram(), gl.getUniformLocation(m_program->getProgram(), name.c_str()), &val);
		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");

		// Draw and verify
		if (val != binding)
			queryTestPassed = false;
		if (!drawAndVerifyResult(m_textureColors[iterNdx]))
			imageTestPassed = false;
	}

	setTestResult(queryTestPassed, imageTestPassed);
	return STOP;
}

glu::ShaderProgram* SamplerBindingRenderCase::generateShaders (void) const
{
	std::ostringstream		shaderUniformDecl;
	std::ostringstream		shaderBody;

	const std::string		texCoordType	= glu::getDataTypeName(getSamplerTexCoordType());
	const std::string		samplerType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_samplerType));
	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY) ? true : false;
	const int				numDeclarations =  arrayInstance ? 1 : m_numBindings;

	// Generate the uniform declarations for the vertex and fragment shaders
	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
	{
		shaderUniformDecl << "layout(binding = " << m_bindings[declNdx] << ") uniform highp " << samplerType << " "
			<< (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
	}

	// Generate the shader body for the vertex and fragment shaders
	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
	{
		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
					<< "	{\n"
					<< "		color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n"
					<< "	}\n";
	}

	shaderBody	<< "	else\n"
				<< "	{\n"
				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
				<< "	}\n";

	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
}

void SamplerBindingRenderCase::initializeTexture (glw::GLint bindingPoint, glw::GLint textureName, const Vec4& color) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.activeTexture(GL_TEXTURE0 + bindingPoint);
	gl.bindTexture(m_textureType, textureName);
	gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	switch (m_textureType)
	{
		case GL_TEXTURE_2D:
		{
			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
			tcu::clear(level.getAccess(), color);
			glu::texImage2D(m_context.getRenderContext(), m_textureType, 0, GL_RGBA8, level.getAccess());
			break;
		}

		case GL_TEXTURE_3D:
		{
			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
			tcu::clear(level.getAccess(), color);
			glu::texImage3D(m_context.getRenderContext(), m_textureType, 0, GL_RGBA8, level.getAccess());
			break;
		}

		default:
			DE_ASSERT(false);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture initialization failed");
}

glu::DataType SamplerBindingRenderCase::getSamplerTexCoordType (void) const
{
	switch (m_samplerType)
	{
		case GL_SAMPLER_2D:
			return glu::TYPE_FLOAT_VEC2;

		case GL_SAMPLER_3D:
			return glu::TYPE_FLOAT_VEC3;

		default:
			DE_ASSERT(false);
			return glu::TYPE_INVALID;
	}
}


class SamplerBindingNegativeCase : public LayoutBindingNegativeCase
{
public:
									SamplerBindingNegativeCase		(Context&		context,
																	 const char*	name,
																	 const char*	desc,
																	 ShaderType		shaderType,
																	 TestType		testType,
																	 ErrorType		errorType,
																	 glw::GLenum	samplerType);
									~SamplerBindingNegativeCase		(void);

private:
	glu::ShaderProgram*				generateShaders					(void) const;
	glu::DataType					getSamplerTexCoordType			(void) const;

	const glw::GLenum				m_samplerType;
};

SamplerBindingNegativeCase::SamplerBindingNegativeCase (Context&		context,
														const char*		name,
														const char*		desc,
														ShaderType		shaderType,
														TestType		testType,
														ErrorType		errorType,
														glw::GLenum		samplerType)
	: 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")
	, m_samplerType					(samplerType)
{
}

SamplerBindingNegativeCase::~SamplerBindingNegativeCase (void)
{
	LayoutBindingNegativeCase::deinit();
}

glu::ShaderProgram*	SamplerBindingNegativeCase::generateShaders	(void) const
{
	std::ostringstream		vertexUniformDecl;
	std::ostringstream		fragmentUniformDecl;
	std::ostringstream		shaderBody;

	const std::string		texCoordType	= glu::getDataTypeName(getSamplerTexCoordType());
	const std::string		samplerType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_samplerType));
	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
	const int				numDeclarations = arrayInstance ? 1 : m_numBindings;

	// Generate the uniform declarations for the vertex and fragment shaders
	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
	{
		vertexUniformDecl << "layout(binding = " << m_vertexShaderBinding[declNdx] << ") uniform highp " << samplerType
			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
		fragmentUniformDecl << "layout(binding = " << m_fragmentShaderBinding[declNdx] << ") uniform highp " << samplerType
			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
	}

	// Generate the shader body for the vertex and fragment shaders
	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
	{
		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
					<< "	{\n"
					<< "		color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n"
					<< "	}\n";
	}

	shaderBody	<< "	else\n"
				<< "	{\n"
				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
				<< "	}\n";

	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
				<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
				<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
}

glu::DataType SamplerBindingNegativeCase::getSamplerTexCoordType(void) const
{
	switch (m_samplerType)
	{
		case GL_SAMPLER_2D:
			return glu::TYPE_FLOAT_VEC2;

		case GL_SAMPLER_3D:
			return glu::TYPE_FLOAT_VEC3;

		default:
			DE_ASSERT(false);
			return glu::TYPE_INVALID;
	}
}

class ImageBindingRenderCase : public LayoutBindingRenderCase
{
public:
											ImageBindingRenderCase			(Context&		context,
																			 const char*	name,
																			 const char*	desc,
																			 ShaderType		shaderType,
																			 TestType		testType,
																			 glw::GLenum	imageType,
																			 glw::GLenum	textureType);
											~ImageBindingRenderCase			(void);

	void									init							(void);
	void									deinit							(void);
	IterateResult							iterate							(void);

private:
	glu::ShaderProgram*						generateShaders					(void) const;
	void									initializeImage					(glw::GLint imageBindingPoint, glw::GLint textureBindingPoint, glw::GLint textureName, const Vec4& color) const;
	glu::DataType							getImageTexCoordType			(void) const;

	const glw::GLenum						m_imageType;
	const glw::GLenum						m_textureType;

	std::vector<glw::GLuint>				m_textures;
	std::vector<Vec4>						m_textureColors;
};


ImageBindingRenderCase::ImageBindingRenderCase (Context&		context,
												const char*		name,
												const char*		desc,
												ShaderType		shaderType,
												TestType		testType,
												glw::GLenum		imageType,
												glw::GLenum		textureType)
	: 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")
	, m_imageType					(imageType)
	, m_textureType					(textureType)
{
}

ImageBindingRenderCase::~ImageBindingRenderCase (void)
{
	deinit();
}

void ImageBindingRenderCase::init (void)
{
	LayoutBindingRenderCase::init();

	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);

	// Initialize image / texture resources
	m_textures = std::vector<glw::GLuint>(m_numBindings,  0);

	// Texture colors
	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
		m_textureColors.push_back(getRandomColor(rnd));

	// Image textures
	gl.genTextures(m_numBindings, &m_textures[0]);

	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
		initializeImage(m_bindings[texNdx], texNdx, m_textures[texNdx], m_textureColors[texNdx]);
}

void ImageBindingRenderCase::deinit (void)
{
	LayoutBindingRenderCase::deinit();

	// Clean up texture data
	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
	{
		if (m_textures[texNdx])
		{
			m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[texNdx]);
			m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0);
		}
	}
}

TestCase::IterateResult ImageBindingRenderCase::iterate	(void)
{
	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	const int				iterations		= m_numBindings;
	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
	bool					queryTestPassed	= true;
	bool					imageTestPassed = true;

	// Set the viewport and enable the shader program
	initRenderState();

	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
	{
		// Set the uniform value indicating the current array index
		gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx);

		const std::string	name	= (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
		const glw::GLint	binding = m_bindings[iterNdx];
		glw::GLint			val		= -1;

		gl.getUniformiv(m_program->getProgram(), gl.getUniformLocation(m_program->getProgram(), name.c_str()), &val);
		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");

		// Draw and verify
		if (val != binding)
			queryTestPassed = false;
		if (!drawAndVerifyResult(m_textureColors[iterNdx]))
			imageTestPassed = false;
	}

	setTestResult(queryTestPassed, imageTestPassed);
	return STOP;
}

void ImageBindingRenderCase::initializeImage (glw::GLint imageBindingPoint, glw::GLint textureBindingPoint, glw::GLint textureName, const Vec4& color) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.activeTexture(GL_TEXTURE0 + textureBindingPoint);
	gl.bindTexture(m_textureType, textureName);
	gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	switch (m_textureType)
	{
		case GL_TEXTURE_2D:
		{
			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
			tcu::clear(level.getAccess(), color);
			gl.texStorage2D(m_textureType, 1, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
			gl.texSubImage2D(m_textureType, 0, 0, 0, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, level.getAccess().getDataPtr());
			break;
		}

		case GL_TEXTURE_3D:
		{
			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
			tcu::clear(level.getAccess(), color);
			gl.texStorage3D(m_textureType, 1, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
			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());
			break;
		}

		default:
			DE_ASSERT(false);
	}

	gl.bindTexture(m_textureType, 0);
	gl.bindImageTexture(imageBindingPoint, textureName, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA8);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Image initialization failed");
}

glu::ShaderProgram* ImageBindingRenderCase::generateShaders (void) const
{
	std::ostringstream		shaderUniformDecl;
	std::ostringstream		shaderBody;

	const std::string		texCoordType	= glu::getDataTypeName(getImageTexCoordType());
	const std::string		imageType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_imageType));
	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY) ? true : false;
	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);

	// Generate the uniform declarations for the vertex and fragment shaders
	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
	{
		shaderUniformDecl << "layout(rgba8, binding = " << m_bindings[declNdx] << ") uniform readonly highp " << imageType
			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
	}

	// Generate the shader body for the vertex and fragment shaders
	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
	{
		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
					<< "	{\n"
					<< "		color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n"
					<< "	}\n";
	}

	shaderBody	<< "	else\n"
				<< "	{\n"
				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
				<< "	}\n";

	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
}

glu::DataType ImageBindingRenderCase::getImageTexCoordType(void) const
{
	switch (m_imageType)
	{
		case GL_IMAGE_2D:
			return glu::TYPE_INT_VEC2;

		case GL_IMAGE_3D:
			return glu::TYPE_INT_VEC3;

		default:
			DE_ASSERT(false);
			return glu::TYPE_INVALID;
	}
}


class ImageBindingNegativeCase : public LayoutBindingNegativeCase
{
public:
											ImageBindingNegativeCase		(Context&		context,
																			 const char*	name,
																			 const char*	desc,
																			 ShaderType		shaderType,
																			 TestType		testType,
																			 ErrorType		errorType,
																			 glw::GLenum	imageType);
											~ImageBindingNegativeCase		(void);

private:
	glu::ShaderProgram*						generateShaders					(void) const;
	glu::DataType							getImageTexCoordType			(void) const;

	const glw::GLenum						m_imageType;
};

ImageBindingNegativeCase::ImageBindingNegativeCase (Context&		context,
													const char*		name,
													const char*		desc,
													ShaderType		shaderType,
													TestType		testType,
													ErrorType		errorType,
													glw::GLenum		imageType)
	: 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")
	, m_imageType					(imageType)
{
}

ImageBindingNegativeCase::~ImageBindingNegativeCase (void)
{
	deinit();
}

glu::ShaderProgram* ImageBindingNegativeCase::generateShaders (void) const
{
	std::ostringstream		vertexUniformDecl;
	std::ostringstream		fragmentUniformDecl;
	std::ostringstream		shaderBody;

	const std::string		texCoordType	= glu::getDataTypeName(getImageTexCoordType());
	const std::string		imageType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_imageType));
	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);

	// Generate the uniform declarations for the vertex and fragment shaders
	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
	{
		vertexUniformDecl << "layout(rgba8, binding = " << m_vertexShaderBinding[declNdx] << ") uniform readonly highp " << imageType
			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
		fragmentUniformDecl << "layout(rgba8, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform readonly highp " << imageType
			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
	}

	// Generate the shader body for the vertex and fragment shaders
	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
	{
		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
					<< "	{\n"
					<< "		color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n"
					<< "	}\n";
	}

	shaderBody	<< "	else\n"
				<< "	{\n"
				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
				<< "	}\n";

	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
					<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
					<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
}

glu::DataType ImageBindingNegativeCase::getImageTexCoordType(void) const
{
	switch (m_imageType)
	{
		case GL_IMAGE_2D:
			return glu::TYPE_INT_VEC2;

		case GL_IMAGE_3D:
			return glu::TYPE_INT_VEC3;

		default:
			DE_ASSERT(false);
			return glu::TYPE_INVALID;
	}
}


class UBOBindingRenderCase : public LayoutBindingRenderCase
{
public:
											UBOBindingRenderCase		(Context&		context,
																		 const char*	name,
																		 const char*	desc,
																		 ShaderType		shaderType,
																		 TestType		testType);
											~UBOBindingRenderCase		(void);

	void									init						(void);
	void									deinit						(void);
	IterateResult							iterate						(void);

private:
	glu::ShaderProgram*						generateShaders				(void) const;

	std::vector<deUint32>					m_buffers;
	std::vector<Vec4>						m_expectedColors;
};

UBOBindingRenderCase::UBOBindingRenderCase (Context&		context,
											const char*		name,
											const char*		desc,
											ShaderType		shaderType,
											TestType		testType)
	: 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")
{
}

UBOBindingRenderCase::~UBOBindingRenderCase (void)
{
	deinit();
}

void UBOBindingRenderCase::init (void)
{
	LayoutBindingRenderCase::init();

	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);

	// Initialize UBOs and related data
	m_buffers = std::vector<glw::GLuint>(m_numBindings,  0);
	gl.genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]);

	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
	{
			m_expectedColors.push_back(getRandomColor(rnd));
			m_expectedColors.push_back(getRandomColor(rnd));
	}

	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
	{
		gl.bindBuffer(GL_UNIFORM_BUFFER, m_buffers[bufNdx]);
		gl.bufferData(GL_UNIFORM_BUFFER, 2*sizeof(Vec4), &(m_expectedColors[2*bufNdx]), GL_STATIC_DRAW);
		gl.bindBufferBase(GL_UNIFORM_BUFFER, m_bindings[bufNdx], m_buffers[bufNdx]);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "UBO setup failed");
}

void UBOBindingRenderCase::deinit (void)
{
	LayoutBindingRenderCase::deinit();

	// Clean up UBO data
	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
	{
		if (m_buffers[bufNdx])
		{
			m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffers[bufNdx]);
			m_context.getRenderContext().getFunctions().bindBuffer(GL_UNIFORM_BUFFER, 0);
		}
	}
}

TestCase::IterateResult UBOBindingRenderCase::iterate (void)
{
	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	const int				iterations		= m_numBindings;
	const glw::GLenum		prop			= GL_BUFFER_BINDING;
	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
	bool					queryTestPassed	= true;
	bool					imageTestPassed = true;

	// Set the viewport and enable the shader program
	initRenderState();

	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
	{
		// Query binding point
		const std::string	name	= (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
		const glw::GLint	binding = m_bindings[iterNdx];
		glw::GLint			val		= -1;

		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);
		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");

		if (val != binding)
			queryTestPassed = false;

		// Draw twice to render both colors within the UBO
		for (int drawCycle = 0; drawCycle < 2; ++drawCycle)
		{
			// Set the uniform indicating the array index to be used and set the expected color
			const int arrayNdx = iterNdx*2 + drawCycle;
			gl.uniform1i(m_shaderProgramArrayNdxLoc, arrayNdx);

			if (!drawAndVerifyResult(m_expectedColors[arrayNdx]))
				imageTestPassed = false;
		}
	}

	setTestResult(queryTestPassed, imageTestPassed);
	return STOP;
}

glu::ShaderProgram* UBOBindingRenderCase::generateShaders (void) const
{
	std::ostringstream		shaderUniformDecl;
	std::ostringstream		shaderBody;
	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);

	// Generate the uniform declarations for the vertex and fragment shaders
	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
	{
		shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") uniform "
			<< getUniformName(m_uniformName, declNdx) << "\n"
			<< "{\n"
			<< "	highp vec4 color1;\n"
			<< "	highp vec4 color2;\n"
			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
	}

	// Generate the shader body for the vertex and fragment shaders
	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
	{
		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
					<< "	{\n"
					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
					<< "	}\n";
	}

	shaderBody	<< "	else\n"
				<< "	{\n"
				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
				<< "	}\n";

	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
}


class UBOBindingNegativeCase : public LayoutBindingNegativeCase
{
public:
											UBOBindingNegativeCase			(Context&		context,
																			 const char*	name,
																			 const char*	desc,
																			 ShaderType		shaderType,
																			 TestType		testType,
																			 ErrorType		errorType);
											~UBOBindingNegativeCase			(void);

private:
	glu::ShaderProgram*						generateShaders					(void) const;
};

UBOBindingNegativeCase::UBOBindingNegativeCase (Context&		context,
												const char*		name,
												const char*		desc,
												ShaderType		shaderType,
												TestType		testType,
												ErrorType		errorType)
	: 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")
{
}

UBOBindingNegativeCase::~UBOBindingNegativeCase (void)
{
	deinit();
}

glu::ShaderProgram* UBOBindingNegativeCase::generateShaders (void) const
{
	std::ostringstream		vertexUniformDecl;
	std::ostringstream		fragmentUniformDecl;
	std::ostringstream		shaderBody;
	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);

	// Generate the uniform declarations for the vertex and fragment shaders
	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
	{
		vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[declNdx] << ") uniform "
			<< getUniformName(m_uniformName, declNdx) << "\n"
			<< "{\n"
			<< "	highp vec4 color1;\n"
			<< "	highp vec4 color2;\n"
			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";

		fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform "
			<< getUniformName(m_uniformName, declNdx) << "\n"
			<< "{\n"
			<< "	highp vec4 color1;\n"
			<< "	highp vec4 color2;\n"
			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
	}

	// Generate the shader body for the vertex and fragment shaders
	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
	{
		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
					<< "	{\n"
					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
					<< "	}\n";
	}

	shaderBody	<< "	else\n"
				<< "	{\n"
				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
				<< "	}\n";

	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
					<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
					<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
}


class SSBOBindingRenderCase : public LayoutBindingRenderCase
{
public:
											SSBOBindingRenderCase		(Context&		context,
																		 const char*	name,
																		 const char*	desc,
																		 ShaderType		shaderType,
																		 TestType		testType);
											~SSBOBindingRenderCase		(void);

	void									init						(void);
	void									deinit						(void);
	IterateResult							iterate						(void);

private:
	glu::ShaderProgram*						generateShaders				(void) const;

	std::vector<glw::GLuint>				m_buffers;
	std::vector<Vec4>						m_expectedColors;
};

SSBOBindingRenderCase::SSBOBindingRenderCase (Context&		context,
											  const char*	name,
											  const char*	desc,
											  ShaderType	shaderType,
											  TestType		testType)
	: 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")
{
}

SSBOBindingRenderCase::~SSBOBindingRenderCase (void)
{
	deinit();
}

void SSBOBindingRenderCase::init (void)
{
	LayoutBindingRenderCase::init();

	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);

	// Initialize SSBOs and related data
	m_buffers = std::vector<glw::GLuint>(m_numBindings, 0);
	gl.genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]);

	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
	{
		m_expectedColors.push_back(getRandomColor(rnd));
		m_expectedColors.push_back(getRandomColor(rnd));
	}

	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
	{
		gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffers[bufNdx]);
		gl.bufferData(GL_SHADER_STORAGE_BUFFER, 2*sizeof(Vec4), &(m_expectedColors[2*bufNdx]), GL_STATIC_DRAW);
		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, m_bindings[bufNdx], m_buffers[bufNdx]);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "SSBO setup failed");
}

void SSBOBindingRenderCase::deinit (void)
{
	LayoutBindingRenderCase::deinit();

	// Clean up SSBO data
	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
	{
		if (m_buffers[bufNdx])
		{
			m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffers[bufNdx]);
			m_context.getRenderContext().getFunctions().bindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
			m_buffers[bufNdx] = 0;
		}
	}
}

TestCase::IterateResult SSBOBindingRenderCase::iterate (void)
{
	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	const int				iterations		= m_numBindings;
	const glw::GLenum		prop			= GL_BUFFER_BINDING;
	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
	bool					queryTestPassed	= true;
	bool					imageTestPassed = true;

	initRenderState();

	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
	{
		// Query binding point
		const std::string	name	= (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
		const glw::GLint	binding = m_bindings[iterNdx];
		glw::GLint			val		= -1;

		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);
		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");

		if (val != binding)
			queryTestPassed = false;

		// Draw twice to render both colors within the SSBO
		for (int drawCycle = 0; drawCycle < 2; ++drawCycle)
		{
			// Set the uniform indicating the array index to be used and set the expected color
			const int arrayNdx = iterNdx*2 + drawCycle;
			gl.uniform1i(m_shaderProgramArrayNdxLoc, arrayNdx);

			if (!drawAndVerifyResult(m_expectedColors[arrayNdx]))
				imageTestPassed = false;
		}
	}

	setTestResult(queryTestPassed, imageTestPassed);
	return STOP;
}

glu::ShaderProgram* SSBOBindingRenderCase::generateShaders (void) const
{
	std::ostringstream		shaderUniformDecl;
	std::ostringstream		shaderBody;
	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);

	// Generate the uniform declarations for the vertex and fragment shaders
	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
	{
		shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") buffer "
			<< getUniformName(m_uniformName, declNdx) << "\n"
			<< "{\n"
			<< "	highp vec4 color1;\n"
			<< "	highp vec4 color2;\n"
			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
	}

	// Generate the shader body for the vertex and fragment shaders
	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
	{
		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
					<< "	{\n"
					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
					<< "	}\n";
	}

	shaderBody	<< "	else\n"
				<< "	{\n"
				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
				<< "	}\n";

	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
}


class SSBOBindingNegativeCase : public LayoutBindingNegativeCase
{
public:
											SSBOBindingNegativeCase			(Context&		context,
																			 const char*	name,
																			 const char*	desc,
																			 ShaderType		shaderType,
																			 TestType		testType,
																			 ErrorType		errorType);
											~SSBOBindingNegativeCase		(void);

private:
	glu::ShaderProgram*						generateShaders					(void) const;
};

SSBOBindingNegativeCase::SSBOBindingNegativeCase (Context& context,
												  const char* name,
												  const char* desc,
												  ShaderType shaderType,
												  TestType testType,
												  ErrorType errorType)
	: 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")
{
}

SSBOBindingNegativeCase::~SSBOBindingNegativeCase (void)
{
	deinit();
}

glu::ShaderProgram* SSBOBindingNegativeCase::generateShaders (void) const
{
	std::ostringstream		vertexUniformDecl;
	std::ostringstream		fragmentUniformDecl;
	std::ostringstream		shaderBody;
	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);

	// Generate the uniform declarations for the vertex and fragment shaders
	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
	{
		vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[declNdx] << ") buffer "
			<< getUniformName(m_uniformName, declNdx) << "\n"
			<< "{\n"
			<< "	highp vec4 color1;\n"
			<< "	highp vec4 color2;\n"
			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";

		fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") buffer "
			<< getUniformName(m_uniformName, declNdx) << "\n"
			<< "{\n"
			<< "	highp vec4 color1;\n"
			<< "	highp vec4 color2;\n"
			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
	}

	// Generate the shader body for the vertex and fragment shaders
	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
	{
		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
					<< "	{\n"
					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
					<< "	}\n";
	}

	shaderBody	<< "	else\n"
				<< "	{\n"
				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
				<< "	}\n";

	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
					<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
					<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
}


} // Anonymous

LayoutBindingTests::LayoutBindingTests (Context& context)
	: TestCaseGroup (context, "layout_binding", "Layout binding tests")
{
}

LayoutBindingTests::~LayoutBindingTests (void)
{
}

void LayoutBindingTests::init (void)
{
	// Render test groups
	tcu::TestCaseGroup* const samplerBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "sampler",		"Test sampler layout binding");
	tcu::TestCaseGroup* const sampler2dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "sampler2d",	"Test sampler2d layout binding");
	tcu::TestCaseGroup* const sampler3dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "sampler3d",	"Test sampler3d layout binding");

	tcu::TestCaseGroup* const imageBindingTestGroup				= new tcu::TestCaseGroup(m_testCtx, "image",		"Test image layout binding");
	tcu::TestCaseGroup* const image2dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "image2d",		"Test image2d layout binding");
	tcu::TestCaseGroup* const image3dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "image3d",		"Test image3d layout binding");

	tcu::TestCaseGroup* const UBOBindingTestGroup				= new tcu::TestCaseGroup(m_testCtx, "ubo",			"Test UBO layout binding");
	tcu::TestCaseGroup* const SSBOBindingTestGroup				= new tcu::TestCaseGroup(m_testCtx, "ssbo",			"Test SSBO layout binding");

	// Negative test groups
	tcu::TestCaseGroup* const negativeBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "negative",		"Test layout binding with invalid bindings");

	tcu::TestCaseGroup* const negativeSamplerBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "sampler",		"Test sampler layout binding with invalid bindings");
	tcu::TestCaseGroup* const negativeSampler2dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "sampler2d",	"Test sampler2d layout binding with invalid bindings");
	tcu::TestCaseGroup* const negativeSampler3dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "sampler3d",	"Test sampler3d layout binding with invalid bindings");

	tcu::TestCaseGroup* const negativeImageBindingTestGroup		= new tcu::TestCaseGroup(m_testCtx, "image",		"Test image layout binding with invalid bindings");
	tcu::TestCaseGroup* const negativeImage2dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "image2d",		"Test image2d layout binding with invalid bindings");
	tcu::TestCaseGroup* const negativeImage3dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "image3d",		"Test image3d layout binding with invalid bindings");

	tcu::TestCaseGroup* const negativeUBOBindingTestGroup		= new tcu::TestCaseGroup(m_testCtx, "ubo",			"Test UBO layout binding with invalid bindings");
	tcu::TestCaseGroup* const negativeSSBOBindingTestGroup		= new tcu::TestCaseGroup(m_testCtx, "ssbo",			"Test SSBO layout binding with invalid bindings");

	static const struct RenderTestType
	{
		ShaderType				shaderType;
		TestType				testType;
		std::string				name;
		std::string				descPostfix;
	} s_renderTestTypes[] =
	{
		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_SINGLE,		"vertex_binding_single",		"a single instance" },
		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_MAX,			"vertex_binding_max",			"maximum binding point"	},
		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_MULTIPLE,		"vertex_binding_multiple",		"multiple instances"},
		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_ARRAY,			"vertex_binding_array",			"an array instance" },
		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_MAX_ARRAY,		"vertex_binding_max_array",		"an array instance with maximum binding point" },

		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_SINGLE,		"fragment_binding_single",		"a single instance" },
		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_MAX,			"fragment_binding_max",			"maximum binding point"	},
		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_MULTIPLE,		"fragment_binding_multiple",	"multiple instances"},
		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_ARRAY,			"fragment_binding_array",		"an array instance" },
		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_MAX_ARRAY,		"fragment_binding_max_array",	"an array instance with maximum binding point" },
	};

	static const struct NegativeTestType
	{
		ShaderType								shaderType;
		TestType								testType;
		LayoutBindingNegativeCase::ErrorType	errorType;
		std::string								name;
		std::string								descPostfix;
	} s_negativeTestTypes[] =
	{
		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"vertex_binding_over_max",			"over maximum binding point"},
		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"fragment_binding_over_max",		"over maximum binding point"},
		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"vertex_binding_neg",				"negative binding point"},
		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"fragment_binding_neg",				"negative binding point"},

		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"vertex_binding_over_max_array",	"over maximum binding point"},
		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"fragment_binding_over_max_array",	"over maximum binding point"},
		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"vertex_binding_neg_array",			"negative binding point"},
		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"fragment_binding_neg_array",		"negative binding point"},

		{ SHADERTYPE_BOTH,		TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY,		"binding_contradictory",			"contradictory binding points"},
		{ SHADERTYPE_BOTH,		TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY,		"binding_contradictory_array",		"contradictory binding points"},
	};

	// Render tests
	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_renderTestTypes); ++testNdx)
	{
		const RenderTestType& test = s_renderTestTypes[testNdx];

		// Render sampler binding tests
		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));
		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));

		// Render image binding tests
		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));
		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));

		// Render UBO binding tests
		UBOBindingTestGroup->addChild(new UBOBindingRenderCase(m_context, test.name.c_str(), ("UBO layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType));

		// Render SSBO binding tests
		SSBOBindingTestGroup->addChild(new SSBOBindingRenderCase(m_context, test.name.c_str(), ("SSBO layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType));
	}

	// Negative binding tests
	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_negativeTestTypes); ++testNdx)
	{
		const NegativeTestType& test = s_negativeTestTypes[testNdx];

		// Negative sampler binding tests
		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));
		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));

		// Negative image binding tests
		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));
		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));

		// Negative UBO binding tests
		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));

		// Negative SSBO binding tests
		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));
	}

	samplerBindingTestGroup->addChild(sampler2dBindingTestGroup);
	samplerBindingTestGroup->addChild(sampler3dBindingTestGroup);

	imageBindingTestGroup->addChild(image2dBindingTestGroup);
	imageBindingTestGroup->addChild(image3dBindingTestGroup);

	negativeSamplerBindingTestGroup->addChild(negativeSampler2dBindingTestGroup);
	negativeSamplerBindingTestGroup->addChild(negativeSampler3dBindingTestGroup);

	negativeImageBindingTestGroup->addChild(negativeImage2dBindingTestGroup);
	negativeImageBindingTestGroup->addChild(negativeImage3dBindingTestGroup);

	negativeBindingTestGroup->addChild(negativeSamplerBindingTestGroup);
	negativeBindingTestGroup->addChild(negativeUBOBindingTestGroup);
	negativeBindingTestGroup->addChild(negativeSSBOBindingTestGroup);
	negativeBindingTestGroup->addChild(negativeImageBindingTestGroup);

	addChild(samplerBindingTestGroup);
	addChild(UBOBindingTestGroup);
	addChild(SSBOBindingTestGroup);
	addChild(imageBindingTestGroup);
	addChild(negativeBindingTestGroup);
}

} // Functional
} // gles31
} // deqp
