/*-------------------------------------------------------------------------
 * 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
	{
		TEST_RENDER_WIDTH	= 256,
		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);

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, TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT);
	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			(TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT);

	// 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(TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT);
	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
