/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2014-2016 The Khronos Group Inc.
 *
 * 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
 */ /*-------------------------------------------------------------------*/
#include "es31cLayoutBindingTests.hpp"

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

#include "deRandom.hpp"
#include "deStringUtil.hpp"

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

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

namespace glcts
{

//=========================================================================
//= typedefs
//=========================================================================
typedef std::string String;
typedef std::map<String, String>		 StringMap;
typedef std::map<String, glw::GLint>	 StringIntMap;
typedef std::map<glw::GLint, glw::GLint> IntIntMap;
typedef std::vector<String> StringVector;
typedef std::vector<int>	IntVector;

typedef std::map<int, glu::Texture2D*>		Texture2DMap;
typedef std::map<int, glu::Texture2DArray*> Texture2DArrayMap;
typedef std::map<int, glu::Texture3D*>		Texture3DMap;

//=========================================================================
//= utility classes
//=========================================================================

//= string stream that saves some typing
class StringStream : public std::ostringstream
{
public:
	void reset()
	{
		clear();
		str("");
	}
};

class LayoutBindingProgram;

class IProgramContextSupplier
{
public:
	virtual ~IProgramContextSupplier()
	{
	}
	virtual Context&					   getContext()		   = 0;
	virtual const LayoutBindingParameters& getTestParameters() = 0;
	virtual eStageType					   getStage()		   = 0;
	virtual const String& getSource(eStageType stage)		   = 0;
	virtual LayoutBindingProgram* createProgram()			   = 0;
};

class LayoutBindingProgram
{
public:
	LayoutBindingProgram(IProgramContextSupplier& contextSupplier)
		: m_contextSupplier(contextSupplier)
		, m_context(contextSupplier.getContext().getRenderContext())
		, m_stage(contextSupplier.getStage())
		, m_testParams(contextSupplier.getTestParameters())
		, m_gl(contextSupplier.getContext().getRenderContext().getFunctions())
	{
		if (getStage() != ComputeShader)
			m_program = new glu::ShaderProgram(
				m_context, glu::makeVtxFragSources(m_contextSupplier.getSource(VertexShader).c_str(),
												   m_contextSupplier.getSource(FragmentShader).c_str()));
		else
			m_program = new glu::ShaderProgram(
				m_context,
				glu::ProgramSources() << glu::ComputeSource(m_contextSupplier.getSource(ComputeShader).c_str()));
	}
	virtual ~LayoutBindingProgram()
	{
		delete m_program;
	}

	class LayoutBindingProgramAutoPtr
	{
	public:
		LayoutBindingProgramAutoPtr(IProgramContextSupplier& contextSupplier)
		{
			m_program = contextSupplier.createProgram();
		}
		~LayoutBindingProgramAutoPtr()
		{
			delete m_program;
		}
		LayoutBindingProgram* operator->()
		{
			return m_program;
		}

	private:
		LayoutBindingProgram* m_program;
	};

	String getErrorLog(bool dumpShaders = false)
	{
		StringStream errLog;

		if (getStage() != ComputeShader)
		{
			const glu::ShaderInfo& fragmentShaderInfo = m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT);
			const glu::ShaderInfo& vertexShaderInfo   = m_program->getShaderInfo(glu::SHADERTYPE_VERTEX);

			if (!fragmentShaderInfo.compileOk || !m_program->getProgramInfo().linkOk || dumpShaders)
			{
				errLog << "### dump of " << stageToName(FragmentShader) << "###\n";
				String msg((dumpShaders ? "Fragment shader should not have compiled" :
										  "Vertex shader compile failed while testing "));
				errLog << "Fragment shader compile failed while testing " << stageToName(getStage()) << ": "
					   << fragmentShaderInfo.infoLog << "\n";
				errLog << m_contextSupplier.getSource(FragmentShader);
			}
			if (!vertexShaderInfo.compileOk || !m_program->getProgramInfo().linkOk || dumpShaders)
			{
				errLog << "### dump of " << stageToName(VertexShader) << "###\n";
				String msg((dumpShaders ? "Vertex shader should not have compiled" :
										  "Vertex shader compile failed while testing "));
				errLog << msg << stageToName(getStage()) << ": " << vertexShaderInfo.infoLog << "\n";
				errLog << m_contextSupplier.getSource(VertexShader);
			}
		}
		else
		{
			const glu::ShaderInfo& computeShaderInfo = m_program->getShaderInfo(glu::SHADERTYPE_COMPUTE);

			if (!computeShaderInfo.compileOk || !m_program->getProgramInfo().linkOk || dumpShaders)
			{
				errLog << "### dump of " << stageToName(ComputeShader) << "###\n";
				String msg((dumpShaders ? "Compute shader should not have compiled" :
										  "Compute shader compile failed while testing "));
				errLog << msg << stageToName(ComputeShader) << ": " << computeShaderInfo.infoLog << "\n";
				errLog << m_contextSupplier.getSource(ComputeShader);
			}
		}
		if (!m_program->getProgramInfo().linkOk)
		{
			getStage();
			errLog << "Linking failed while testing " << stageToName(getStage()) << ": "
				   << m_program->getProgramInfo().infoLog << "\n";
			errLog << "### other stages ###\n";
			switch (getStage())
			{
			case FragmentShader:
				errLog << "### dump of " << stageToName(VertexShader) << "###\n";
				errLog << m_contextSupplier.getSource(VertexShader);
				break;
			case VertexShader:
				errLog << "### dump of " << stageToName(FragmentShader) << "###\n";
				errLog << stageToName(FragmentShader) << "\n";
				errLog << m_contextSupplier.getSource(FragmentShader);
				break;
			case ComputeShader:
				errLog << "### dump of " << stageToName(ComputeShader) << "###\n";
				errLog << stageToName(ComputeShader) << "\n";
				errLog << m_contextSupplier.getSource(ComputeShader);
				break;
			default:
				DE_ASSERT(0);
				break;
			}
		}
		return errLog.str();
	}

private:
	IProgramContextSupplier& m_contextSupplier;

	const glu::RenderContext&	  m_context;
	const eStageType			   m_stage;		 // shader stage currently tested
	const LayoutBindingParameters& m_testParams; // parameters for shader generation (table at end of file)
	const glw::Functions&		   m_gl;

	glu::ShaderProgram* m_program;

private:
	StringIntMap getUniformLocations(StringVector args) const
	{
		StringVector::iterator it;
		StringIntMap		   locations;
		bool				   passed = true;

		for (it = args.begin(); it != args.end(); it++)
		{
			const char* name	 = (*it).c_str();
			glw::GLint  location = m_gl.getUniformLocation(getProgram(), name);
			passed &= (0 <= location);
			if (passed)
			{
				locations[name] = location;
			}
		}

		return locations;
	}

public:
	glw::GLint getProgram() const
	{
		return m_program->getProgram();
	}

	const glw::Functions& gl() const
	{
		return m_gl;
	}

	virtual eStageType getStage() const
	{
		return m_stage;
	}

	String stageToName(eStageType stage) const
	{
		switch (stage)
		{
		case FragmentShader:
			return "FragmentShader";
		case VertexShader:
			return "VertexShader";
		case ComputeShader:
			return "ComputeShader";
		default:
			DE_ASSERT(0);
			break;
		}
		return String();
	}

	bool error() const
	{
		return (m_gl.getError() == GL_NO_ERROR);
	}

	bool compiledAndLinked() const
	{
		if (getStage() != ComputeShader)
			return m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT).compileOk &&
				   m_program->getShaderInfo(glu::SHADERTYPE_VERTEX).compileOk && m_program->getProgramInfo().linkOk;

		return m_program->getShaderInfo(glu::SHADERTYPE_COMPUTE).compileOk && m_program->getProgramInfo().linkOk;
	}

	virtual StringIntMap getBindingPoints(StringVector args) const
	{
		StringIntMap bindingPoints;

		StringIntMap locations = getUniformLocations(args);
		if (!locations.empty())
		{
			glw::GLint bindingPoint;
			for (StringIntMap::iterator it = locations.begin(); it != locations.end(); it++)
			{
				glw::GLint location = it->second;
				m_gl.getUniformiv(getProgram(), location, &bindingPoint);
				bool hasNoError = (GL_NO_ERROR == m_gl.getError());
				if (hasNoError)
				{
					bindingPoints[it->first] = bindingPoint;
				}
			}
		}
		return bindingPoints;
	}

	virtual bool setBindingPoints(StringVector list, glw::GLint bindingPoint) const
	{
		bool bNoError = true;

		StringIntMap locations = getUniformLocations(list);
		if (!locations.empty())
		{
			for (StringIntMap::iterator it = locations.begin(); it != locations.end(); it++)
			{
				m_gl.uniform1i(it->second, bindingPoint);
				bNoError &= (GL_NO_ERROR == m_gl.getError());
			}
		}
		return bNoError;
	}

	virtual StringIntMap getOffsets(StringVector /*args*/) const
	{
		return StringIntMap();
	}
};

class LayoutBindingTestResult
{
public:
	LayoutBindingTestResult(bool passed = true, const String& reason = String(), bool notRunforThisContext = false)
		: m_passed(passed), m_notRunForThisContext(notRunforThisContext), m_reason(reason)
	{
	}

public:
	bool testPassed() const
	{
		return m_passed;
	}

	String getReason() const
	{
		return m_reason;
	}

	bool runForThisContext() const
	{
		return !m_notRunForThisContext;
	}

private:
	bool   m_passed;
	bool   m_notRunForThisContext;
	String m_reason;
};

class IntegerConstant
{
public:
	enum Literals
	{
		decimal = 0,
		decimal_u,
		decimal_U,
		octal,
		octal_u,
		octal_U,
		hex_x,
		hex_X,
		hex_u,
		hex_u_X,
		hex_U,
		hex_U_X,
		last
	};

public:
	IntegerConstant(Literals lit, int ai) : asInt(ai)
	{
		StringStream s;
		switch (lit)
		{
		case decimal:
			s << asInt;
			break;
		case decimal_u:
			s << asInt << "u";
			break;
		case decimal_U:
			s << asInt << "U";
			break;
		case octal:
			s << "0" << std::oct << asInt;
			break;
		case octal_u:
			s << "0" << std::oct << asInt << "u";
			break;
		case octal_U:
			s << "0" << std::oct << asInt << "U";
			break;
		case hex_x:
			s << "0x" << std::hex << asInt;
			break;
		case hex_X:
			s << "0X" << std::hex << asInt;
			break;
		case hex_u:
			s << "0x" << std::hex << asInt << "u";
			break;
		case hex_u_X:
			s << "0X" << std::hex << asInt << "u";
			break;
		case hex_U:
			s << "0x" << std::hex << asInt << "U";
			break;
		case hex_U_X:
			s << "0X" << std::hex << asInt << "U";
			break;
		case last:
		default:
			DE_ASSERT(0);
		}

		asString = s.str();
	}

public:
	String asString;
	int	asInt;
};

//*****************************************************************************
class LayoutBindingBaseCase : public TestCase, public IProgramContextSupplier
{
public:
	LayoutBindingBaseCase(Context& context, const char* name, const char* description, StageType stage,
						  LayoutBindingParameters& samplerType, glu::GLSLVersion glslVersion);
	virtual ~LayoutBindingBaseCase(void);

	IterateResult iterate(void);

	// overrideable subtests
	virtual LayoutBindingTestResult binding_basic_default(void);
	virtual LayoutBindingTestResult binding_basic_explicit(void);
	virtual LayoutBindingTestResult binding_basic_multiple(void);
	virtual LayoutBindingTestResult binding_basic_render(void);
	virtual LayoutBindingTestResult binding_integer_constant(void);
	virtual LayoutBindingTestResult binding_array_size(void);
	virtual LayoutBindingTestResult binding_array_implicit(void);
	virtual LayoutBindingTestResult binding_array_multiple(void);
	virtual LayoutBindingTestResult binding_api_update(void);
	virtual LayoutBindingTestResult binding_compilation_errors(void);
	virtual LayoutBindingTestResult binding_link_errors(void);
	virtual LayoutBindingTestResult binding_examples(void);
	virtual LayoutBindingTestResult binding_mixed_order(void);

private:
	// drawTest normal vs. compute
	typedef LayoutBindingTestResult (LayoutBindingBaseCase::*LayoutBindingDrawTestPtr)(glw::GLint program, int binding);

	LayoutBindingDrawTestPtr m_drawTest;

	// pointer type for subtests
	typedef LayoutBindingTestResult (LayoutBindingBaseCase::*LayoutBindingSubTestPtr)();

	// test table entry
	struct LayoutBindingSubTest
	{
		char const*				name;
		char const*				description;
		LayoutBindingSubTestPtr test;
	};

	// IProgramContextSupplier interface
protected:
	const LayoutBindingParameters& getTestParameters()
	{
		return m_testParams;
	}

	const glu::RenderContext& getRenderContext()
	{
		return m_context.getRenderContext();
	}

	virtual eStageType getStage()
	{
		return m_stage.type;
	}

	const String& getSource(eStageType stage)
	{
		return m_sources[stage];
	}

	Context& getContext()
	{
		return m_context;
	}

	const glw::Functions& gl()
	{
		return m_context.getRenderContext().getFunctions();
	}

	bool needsPrecision() const
	{
		if (isContextTypeES(m_context.getRenderContext().getType()) || m_glslVersion == glu::GLSL_VERSION_450)
		{
			return (m_testParams.surface_type != UniformBlock) && (m_testParams.surface_type != ShaderStorageBuffer);
		}
		else
		{
			return (m_testParams.surface_type != UniformBlock) && (m_testParams.surface_type != ShaderStorageBuffer) &&
				   (m_testParams.surface_type != AtomicCounter) && (m_testParams.surface_type != Image);
		}
	}

protected:
	std::vector<int> makeSparseRange(int maxElement, int minElement = 0) const
	{
		static float	   rangeT[]		 = { 0.0f, 0.1f, 0.5f, 0.6f, 0.9f, 1.0f };
		std::vector<float> rangeTemplate = makeVector(rangeT);
		float			   max			 = rangeTemplate.back();
		float			   range		 = (float)((maxElement - 1) - minElement);

		std::vector<int> result;
		for (std::vector<float>::iterator it = rangeTemplate.begin(); it != rangeTemplate.end(); it++)
		{
			float e = *it;
			e		= (e * range) / max;
			result.insert(result.end(), minElement + (int)e);
		}
		return result;
	}

	glu::GLSLVersion getGLSLVersion()
	{
		return m_glslVersion;
	}

	bool isStage(eStageType stage)
	{
		return (stage == m_stage.type);
	}

	void setTemplateParam(eStageType stage, const char* param, const String& value)
	{
		m_templateParams[stage][param] = value.c_str();
	}

	void setTemplateParam(const char* param, const String& value)
	{
		setTemplateParam(m_stage.type, param, value);
	}

	void updateTemplate(eStageType stage)
	{
		m_sources[stage] = tcu::StringTemplate(m_templates[stage]).specialize(m_templateParams[stage]);
	}

	void updateTemplate()
	{
		updateTemplate(m_stage.type);
	}

	template <class T0, class T1>
	String generateLog(const String& msg, T0 result, T1 expected)
	{
		StringStream s;
		s << msg << " expected: " << expected << " actual: " << result << "\n";
		s << getSource(VertexShader) << "\n";
		s << getSource(FragmentShader) << "\n";
		return s.str();
	}

private:
	std::vector<LayoutBindingSubTest> m_tests;

	void init(void)
	{
		m_drawTest =
			(getStage() == ComputeShader) ? &LayoutBindingBaseCase::drawTestCompute : &LayoutBindingBaseCase::drawTest;

#define MAKE_TEST_ENTRY(__subtest_name__) { #__subtest_name__, "", &LayoutBindingBaseCase::__subtest_name__ }
		LayoutBindingSubTest tests[] = {
			MAKE_TEST_ENTRY(binding_basic_default),		 MAKE_TEST_ENTRY(binding_basic_explicit),
			MAKE_TEST_ENTRY(binding_basic_multiple),	 MAKE_TEST_ENTRY(binding_basic_render),
			MAKE_TEST_ENTRY(binding_integer_constant),
			MAKE_TEST_ENTRY(binding_array_size),		 MAKE_TEST_ENTRY(binding_array_implicit),
			MAKE_TEST_ENTRY(binding_array_multiple),	 MAKE_TEST_ENTRY(binding_api_update),
			MAKE_TEST_ENTRY(binding_compilation_errors), MAKE_TEST_ENTRY(binding_link_errors),
			MAKE_TEST_ENTRY(binding_examples),			 MAKE_TEST_ENTRY(binding_mixed_order)
		};
		m_tests = makeVector(tests);

		m_uniformDeclTemplate = "${LAYOUT}${KEYWORD}${UNIFORM_TYPE}${UNIFORM_BLOCK_NAME}${UNIFORM_BLOCK}${UNIFORM_"
								"INSTANCE_NAME}${UNIFORM_ARRAY};\n";

		m_expectedColor = tcu::Vec4(0.0, 1.0f, 0.0f, 1.0f);

		switch (getTestParameters().texture_type)
		{
		case TwoD:
		{
			// 2D
			glu::ImmutableTexture2D* texture2D =
				new glu::ImmutableTexture2D(getContext().getRenderContext(), GL_RGBA8, 2, 2);

			texture2D->getRefTexture().allocLevel(0);
			tcu::clear(texture2D->getRefTexture().getLevel(0), m_expectedColor);
			texture2D->upload();

			if (m_textures2D.find(0) != m_textures2D.end())
			{
				delete m_textures2D[0];
			}

			m_textures2D[0] = texture2D;
		}
		break;
		case TwoDArray:
		{
			// 2DArray
			glu::Texture2DArray* texture2DArray =
				new glu::Texture2DArray(getContext().getRenderContext(), GL_RGBA8, 2, 2, 1);

			texture2DArray->getRefTexture().allocLevel(0);
			tcu::clear(texture2DArray->getRefTexture().getLevel(0), m_expectedColor);
			texture2DArray->upload();

			if (m_textures2DArray.find(0) != m_textures2DArray.end())
			{
				delete m_textures2DArray[0];
			}

			m_textures2DArray[0] = texture2DArray;
		}
		break;
		// 3D
		case ThreeD:
		{
			glu::Texture3D* texture3D = new glu::Texture3D(getContext().getRenderContext(), GL_RGBA8, 2, 2, 1);

			texture3D->getRefTexture().allocLevel(0);
			tcu::clear(texture3D->getRefTexture().getLevel(0), m_expectedColor);
			texture3D->upload();

			if (m_textures3D.find(0) != m_textures3D.end())
			{
				delete m_textures3D[0];
			}

			m_textures3D[0] = texture3D;
		}
		break;
		case None:
			// test case where no texture allocation is needed
			break;
		default:
			DE_ASSERT(0);
			break;
		}
	}

	String initDefaultVSContext()
	{
		m_templates[VertexShader] = "${VERSION}"
									"layout(location=0) in vec2 inPosition;\n"
									"${UNIFORM_DECL}\n"
									"flat out ${OUT_VAR_TYPE} fragColor;\n"
									"${OPTIONAL_FUNCTION_BLOCK}\n"
									"void main(void)\n"
									"{\n"
									"  ${OUT_ASSIGNMENT} ${UNIFORM_ACCESS}\n"
									"  gl_Position = vec4(inPosition, 0.0, 1.0);\n"
									"}\n";

		StringMap& args = m_templateParams[VertexShader];
		// some samplers and all images don't have default precision qualifier (sampler3D)
		// so append a precision default in all sampler and image cases.
		StringStream s;
		s << glu::getGLSLVersionDeclaration(m_glslVersion) << "\n";
		s << "precision highp float;\n";
		if (needsPrecision())
		{
			s << "precision highp " << getTestParameters().uniform_type << ";\n";
		}

		args["VERSION"]					= s.str();
		args["UNIFORM_DECL"]			= "";
		args["OPTIONAL_FUNCTION_BLOCK"] = "";
		args["UNIFORM_ACCESS"]			= "";
		args["OUT_ASSIGNMENT"]			= "fragColor =";
		args["OUT_VAR_TYPE"]			= getTestParameters().vector_type;
		args["OUT_VAR"]					= "fragColor";
		if (m_stage.type != VertexShader)
		{
			args["OUT_ASSIGNMENT"] = "";
		}
		return tcu::StringTemplate(m_templates[VertexShader]).specialize(args);
	}

	String initDefaultFSContext()
	{
		// build fragment shader
		m_templates[FragmentShader] = "${VERSION}"
									  "layout(location=0) out ${OUT_VAR_TYPE} ${OUT_VAR};\n"
									  "flat in ${OUT_VAR_TYPE} fragColor;\n"
									  "${UNIFORM_DECL}\n"
									  "${OPTIONAL_FUNCTION_BLOCK}\n"
									  "void main(void)\n"
									  "{\n"
									  "  ${OUT_ASSIGNMENT} ${UNIFORM_ACCESS}\n"
									  "}\n";

		StringMap& args = m_templateParams[FragmentShader];
		// samplers and images don't have default precision qualifier
		StringStream s;
		s << glu::getGLSLVersionDeclaration(m_glslVersion) << "\n";
		s << "precision highp float;\n";
		if (needsPrecision())
		{
			s << "precision highp " << getTestParameters().uniform_type << ";\n";
		}
		args["VERSION"]					= s.str();
		args["OUT_VAR_TYPE"]			= getTestParameters().vector_type;
		args["UNIFORM_ACCESS"]			= "vec4(0.0,0.0,0.0,0.0);";
		args["UNIFORM_DECL"]			= "";
		args["OPTIONAL_FUNCTION_BLOCK"] = "";
		args["OUT_ASSIGNMENT"]			= "outColor =";
		args["OUT_VAR"]					= "outColor";
		// must have a linkage between stage and fragment shader
		// that the compiler can't optimize away
		if (FragmentShader != m_stage.type)
		{
			args["UNIFORM_ACCESS"] = "fragColor;";
		}
		return tcu::StringTemplate(m_templates[FragmentShader]).specialize(args);
	}

	String initDefaultCSContext()
	{
		// build compute shader
		m_templates[ComputeShader] = "${VERSION}"
									 "${UNIFORM_DECL}\n"
									 "${OPTIONAL_FUNCTION_BLOCK}\n"
									 "void main(void)\n"
									 "{\n"
									 "  ${OUT_VAR_TYPE} tmp = ${UNIFORM_ACCESS}\n"
									 "  ${OUT_ASSIGNMENT} tmp ${OUT_END}\n"
									 "}\n";

		StringMap& args = m_templateParams[ComputeShader];
		// images don't have default precision qualifier
		StringStream s;
		s << glu::getGLSLVersionDeclaration(m_glslVersion) << "\n";
		s << "layout (local_size_x = 1) in;\n"
			 "precision highp float;\n";
		if (needsPrecision())
		{
			s << "precision highp " << getTestParameters().uniform_type << ";\n";
		}

		// bindings are per uniform type...
		if (getTestParameters().surface_type == Image)
		{
			s << "layout(binding=0, std430) buffer outData {\n"
				 "    "
			  << getTestParameters().vector_type << " outColor;\n"
													"};\n";
			args["OUT_ASSIGNMENT"] = "outColor =";
			args["OUT_END"]		   = ";";
		}
		else
		{
			s << "layout(binding=0, rgba8) uniform highp writeonly image2D outImage;\n";
			args["OUT_ASSIGNMENT"] = "imageStore(outImage, ivec2(0), ";
			args["OUT_END"]		   = ");";
		}
		args["VERSION"]					= s.str();
		args["OUT_VAR_TYPE"]			= getTestParameters().vector_type;
		args["UNIFORM_ACCESS"]			= "vec4(0.0,0.0,0.0,0.0);";
		args["UNIFORM_DECL"]			= "";
		args["OPTIONAL_FUNCTION_BLOCK"] = "";

		return tcu::StringTemplate(m_templates[ComputeShader]).specialize(args);
	}

protected:
	String buildUniformDecl(const String& keyword, const String& layout, const String& uniform_type,
							const String& uniform_block_name, const String& uniform_block,
							const String& uniform_instance, const String& uniform_array) const
	{
		StringMap args;
		setArg(args["LAYOUT"], layout);
		setArg(args["KEYWORD"], keyword);
		if (uniform_block_name.empty())
			setArg(args["UNIFORM_TYPE"], uniform_type);
		else
			args["UNIFORM_TYPE"] = "";
		if (!uniform_instance.empty() && !uniform_block_name.empty())
			setArg(args["UNIFORM_BLOCK_NAME"], uniform_block_name + "_block");
		else
			setArg(args["UNIFORM_BLOCK_NAME"], uniform_block_name);
		setArg(args["UNIFORM_BLOCK"], uniform_block);
		if ((uniform_block_name.empty() && uniform_block.empty()) || !uniform_array.empty())
			args["UNIFORM_INSTANCE_NAME"] = uniform_instance;
		else
			args["UNIFORM_INSTANCE_NAME"] = "";
		args["UNIFORM_ARRAY"]			  = uniform_array;
		return tcu::StringTemplate(m_uniformDeclTemplate).specialize(args);
	}

	virtual String getDefaultUniformName(int idx = 0)
	{
		StringStream s;
		s << "uniform" << idx;
		return s.str();
	}

	virtual String buildUniformName(String& var)
	{
		std::ostringstream s;
		s << var;
		return s.str();
	}

	virtual String buildLayout(const String& binding)
	{
		std::ostringstream s;
		if (!binding.empty())
			s << "layout(binding=" << binding << ") ";
		return s.str();
	}

	virtual String buildLayout(int binding)
	{
		std::ostringstream bindingStr;
		bindingStr << binding;
		return buildLayout(bindingStr.str());
	}

	virtual String buildAccess(const String& var)
	{
		std::ostringstream s;
		s << getTestParameters().access_function << "(" << var << "," << getTestParameters().coord_vector_type << "(0)"
		  << ")";
		return s.str();
	}

	virtual String buildBlockName(const String& /*name*/)
	{
		return String();
	}

	virtual String buildBlock(const String& /*name*/, const String& /*type*/ = String("float"))
	{
		return String();
	}

	virtual String buildArray(int idx)
	{
		StringStream s;
		s << "[" << idx << "]";
		return s.str();
	}

	virtual String buildArrayAccess(int uniform, int idx)
	{
		StringStream s;
		s << getDefaultUniformName(uniform) << buildArray(idx);
		if (!buildBlockName(getDefaultUniformName()).empty())
		{
			s << "." << getDefaultUniformName(uniform);
		}
		return s.str();
	}

	// return max. binding point allowed
	virtual int maxBindings()
	{
		int units = 0;

		if (getTestParameters().surface_type == Image)
		{
			gl().getIntegerv(GL_MAX_IMAGE_UNITS, &units);
		}
		else
		{
			gl().getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &units);
		}

		return units;
	}

	// return max. array size allowed
	virtual int maxArraySize()
	{
		int units = 0;

		if (getTestParameters().surface_type == Image)
		{
			switch (m_stage.type)
			{
			case VertexShader:
				gl().getIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &units);
				break;
			case FragmentShader:
				gl().getIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &units);
				break;
			default:
				DE_ASSERT(0);
				break;
			}
		}
		else
		{
			switch (m_stage.type)
			{
			case VertexShader:
				gl().getIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &units);
				break;
			case FragmentShader:
				gl().getIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &units);
				break;
			default:
				DE_ASSERT(0);
				break;
			}
		}

		return units;
	}

	virtual bool isSupported()
	{
		return (maxArraySize() > 0);
	}

	virtual void bind(int binding)
	{
		glw::GLint texTarget = 0;
		glw::GLint texName   = 0;

		switch (getTestParameters().texture_type)
		{
		case TwoD:
			texTarget = GL_TEXTURE_2D;
			texName   = m_textures2D[0]->getGLTexture();
			break;
		case TwoDArray:
			texTarget = GL_TEXTURE_2D_ARRAY;
			texName   = m_textures2DArray[0]->getGLTexture();
			break;
		case ThreeD:
			texTarget = GL_TEXTURE_3D;
			texName   = m_textures3D[0]->getGLTexture();
			break;
		default:
			DE_ASSERT(0);
			break;
		}

		switch (getTestParameters().surface_type)
		{
		case Texture:
			gl().activeTexture(GL_TEXTURE0 + binding);
			gl().bindTexture(texTarget, texName);
			gl().texParameteri(texTarget, GL_TEXTURE_WRAP_S, glu::getGLWrapMode(tcu::Sampler::CLAMP_TO_EDGE));
			gl().texParameteri(texTarget, GL_TEXTURE_WRAP_T, glu::getGLWrapMode(tcu::Sampler::CLAMP_TO_EDGE));
			gl().texParameteri(texTarget, GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(tcu::Sampler::NEAREST));
			gl().texParameteri(texTarget, GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(tcu::Sampler::NEAREST));
			break;
		case Image:
			gl().bindImageTexture(binding, texName, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
			break;
		default:
			DE_ASSERT(0);
			break;
		}
	}

	virtual void unbind(int binding)
	{
		glw::GLint texTarget = 0;

		switch (getTestParameters().texture_type)
		{
		case TwoD:
			texTarget = GL_TEXTURE_2D;
			break;
		case TwoDArray:
			texTarget = GL_TEXTURE_2D_ARRAY;
			break;
		case ThreeD:
			texTarget = GL_TEXTURE_3D;
			break;
		default:
			DE_ASSERT(0);
			break;
		}

		switch (getTestParameters().surface_type)
		{
		case Texture:
			gl().activeTexture(GL_TEXTURE0 + binding);
			gl().bindTexture(texTarget, 0);
			break;
		case Image:
			gl().bindImageTexture(binding, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32F);
			break;
		default:
			DE_ASSERT(0);
			break;
		}
	}

	virtual LayoutBindingTestResult drawTest(glw::GLint program, int binding);
	virtual LayoutBindingTestResult drawTestCompute(glw::GLint program, int binding);

	// allocate resources needed for all subtests, i.e. textures
	virtual void setupTest()
	{
	}

	// cleanup resources needed for all subtests
	virtual void teardownTest()
	{
		for (Texture2DMap::iterator it = m_textures2D.begin(); it != m_textures2D.end(); it++)
		{
			delete it->second;
		}
		m_textures2D.clear();

		for (Texture2DArrayMap::iterator it = m_textures2DArray.begin(); it != m_textures2DArray.end(); it++)
		{
			delete it->second;
		}
		m_textures2DArray.clear();

		for (Texture3DMap::iterator it = m_textures3D.begin(); it != m_textures3D.end(); it++)
		{
			delete it->second;
		}
		m_textures3D.clear();
	}

private:
	// appends a space to the argument (make shader source pretty)
	void setArg(String& arg, const String& value) const
	{
		if (!value.empty())
			arg = value + String(" ");
		else
			arg = String();
	}

private:
	LayoutBindingParameters m_testParams;
	StageType				m_stage;

	std::map<eStageType, String>	  m_sources;
	std::map<eStageType, StringMap>   m_templateParams;
	std::map<eStageType, const char*> m_templates;

	Texture2DMap	  m_textures2D;
	Texture2DArrayMap m_textures2DArray;
	Texture3DMap	  m_textures3D;
	tcu::Vec4		  m_expectedColor;

	const char* m_uniformDeclTemplate;

	glu::GLSLVersion m_glslVersion;
};

LayoutBindingBaseCase::LayoutBindingBaseCase(Context& context, const char* name, const char* description,
											 StageType stage, LayoutBindingParameters& samplerType,
											 glu::GLSLVersion glslVersion)
	: TestCase(context, name, description)
	, m_drawTest(DE_NULL)
	, m_testParams(samplerType)
	, m_stage(stage)
	, m_uniformDeclTemplate(DE_NULL)
	, m_glslVersion(glslVersion)
{
}

LayoutBindingBaseCase::~LayoutBindingBaseCase(void)
{
	teardownTest();
}

LayoutBindingBaseCase::IterateResult LayoutBindingBaseCase::iterate(void)
{
	tcu::TestLog& log	= m_context.getTestContext().getLog();
	bool		  passed = true;

	if (!isSupported())
	{
		log << tcu::TestLog::Section("NotSupported", "");
		log << tcu::TestLog::Message << "This test was not run as minimum requirements were not met."
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::EndSection;
		getContext().getTestContext().setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "NotSupported");
		return STOP;
	}

	// init test case (create shader templates and textures)
	init();

	// allocate resources for all subtests
	setupTest();

	for (std::vector<LayoutBindingSubTest>::iterator it = m_tests.begin(); it != m_tests.end(); it++)
	{
		// need to reset templates and their args to a clean state before every
		// test to avoid bleeding.
		m_sources[VertexShader]   = initDefaultVSContext();
		m_sources[FragmentShader] = initDefaultFSContext();
		m_sources[ComputeShader]  = initDefaultCSContext();

		LayoutBindingTestResult result = ((*this).*((*it).test))();
		if (!result.testPassed())
		{
			log << tcu::TestLog::Section((*it).name, (*it).description);
			log << tcu::TestLog::Message << result.getReason() << tcu::TestLog::EndMessage;
			log << tcu::TestLog::EndSection;
		}
		if (!result.runForThisContext())
		{
			log << tcu::TestLog::Section((*it).name, (*it).description);
			log << tcu::TestLog::Message << "This test was not run for this context as it does not apply."
				<< tcu::TestLog::EndMessage;
			log << tcu::TestLog::EndSection;
		}
		passed &= result.testPassed();
	}

	// cleanup resources
	teardownTest();

	/*=========================================================================
	 TEST results
	 =========================================================================*/

	getContext().getTestContext().setTestResult(passed ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
												passed ? "Pass" : "Fail");

	return STOP;
}

/*=========================================================================
 // bind resource to specified binding point and program and
 // dispatch a computation, read back image at (0,0)
 =========================================================================*/
LayoutBindingTestResult LayoutBindingBaseCase::drawTestCompute(glw::GLint program, int binding)
{
	const glw::Functions& l_gl   = getContext().getRenderContext().getFunctions();
	bool				  passed = true;

	DE_TEST_ASSERT(getStage() == ComputeShader);

	l_gl.useProgram(program);

	deUint32 fb_or_ssb;

	if (getTestParameters().surface_type == Image)
	{
		bind(binding);

		glw::GLfloat buffer[4] = { 0.1f, 0.2f, 0.3f, 0.4f };
		l_gl.genBuffers(1, &fb_or_ssb);
		l_gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, fb_or_ssb);

		l_gl.bufferData(GL_SHADER_STORAGE_BUFFER, 4 * sizeof(glw::GLfloat), buffer, GL_DYNAMIC_COPY);

		l_gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, fb_or_ssb);

		l_gl.dispatchCompute(1, 1, 1);
		l_gl.memoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);

		tcu::Vec4 pixel =
			*(tcu::Vec4*)l_gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * sizeof(glw::GLfloat), GL_MAP_READ_BIT);
		l_gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);

		l_gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
		l_gl.deleteBuffers(1, &fb_or_ssb);

		unbind(binding);

		tcu::Vec4 expected(0.0f, 1.0f, 0.0f, 1.0f);
		passed = (pixel == expected);
		if (!passed)
		{
			return LayoutBindingTestResult(passed, generateLog(String("drawTestCompute failed"), expected, pixel));
		}
	}
	else
	{
		deUint32 something = 0x01020304, tex;

		l_gl.genTextures(1, &tex);
		l_gl.bindTexture(GL_TEXTURE_2D, tex);
		l_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		l_gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
		l_gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &something);

		bind(binding);

		l_gl.bindImageTexture(0, tex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);

		l_gl.dispatchCompute(1, 1, 1);
		l_gl.memoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);

		l_gl.bindImageTexture(0, 0, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);

		l_gl.genFramebuffers(1, &fb_or_ssb);
		l_gl.bindFramebuffer(GL_FRAMEBUFFER, fb_or_ssb);
		l_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);

		l_gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &something);

		l_gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
		l_gl.deleteFramebuffers(1, &fb_or_ssb);
		l_gl.deleteTextures(1, &tex);

		unbind(binding);

		const deUint32 expected = 0xff00ff00;
		passed					= (expected == something);
		if (!passed)
		{
			return LayoutBindingTestResult(
				passed, generateLog(String("drawTestCompute failed"), tcu::RGBA(expected), tcu::RGBA(something)));
		}
	}

	return passed;
}

/*=========================================================================
 // bind resource to specified binding point and program and
 // return result of comparison of rendered pixel at (0,0) with expected
 =========================================================================*/
LayoutBindingTestResult LayoutBindingBaseCase::drawTest(glw::GLint program, int binding)
{
	const glw::Functions&	GL			  = getContext().getRenderContext().getFunctions();
	const tcu::RenderTarget& renderTarget = getContext().getRenderContext().getRenderTarget();
	glw::GLuint				 viewportW	= renderTarget.getWidth();
	glw::GLuint				 viewportH	= renderTarget.getHeight();
	tcu::Surface			 renderedFrame(viewportW, viewportH);
	bool					 passed = true;

	DE_TEST_ASSERT(getStage() != ComputeShader);

	GL.viewport(0, 0, viewportW, viewportH);
	GL.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	GL.clear(GL_COLOR_BUFFER_BIT);

	static const float position[] = {
		-1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f,
	};
	static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };

	GL.useProgram(program);

	bind(binding);

	static const glu::VertexArrayBinding vertexArrays[] = {
		glu::va::Float("inPosition", 2, 4, 0, &position[0]),
	};
	glu::draw(getContext().getRenderContext(), program, DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
			  glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));

	glu::readPixels(getContext().getRenderContext(), 0, 0, renderedFrame.getAccess());

	tcu::RGBA pixel = renderedFrame.getPixel(0, 0);

	passed = (pixel == tcu::RGBA(m_expectedColor));

	unbind(binding);

	if (!passed)
	{
		return LayoutBindingTestResult(passed,
									   generateLog(String("drawTest failed"), m_expectedColor, pixel.getPacked()));
	}

	return true;
}

//== verify that binding point is default w/o layout binding
LayoutBindingTestResult LayoutBindingBaseCase::binding_basic_default()
{
	bool passed = true;

	StringStream s;
	s << buildAccess(getDefaultUniformName()) << ";\n";
	setTemplateParam("UNIFORM_ACCESS", s.str());

	String decl = buildUniformDecl(String(getTestParameters().keyword), buildLayout(String()),
								   String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
								   buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
	setTemplateParam("UNIFORM_DECL", decl);
	updateTemplate();

	LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
	passed &= program->compiledAndLinked();
	if (!passed)
	{
		return LayoutBindingTestResult(passed, program->getErrorLog());
	}

	StringVector  list;
	const String& u = buildBlockName(getDefaultUniformName());
	if (!u.empty())
		list.push_back(u + "_block");
	else
		list.push_back(getDefaultUniformName());

	StringIntMap bindingPoints = program->getBindingPoints(list);

	passed &= bindingPoints.size() == list.size() && (bindingPoints[u] == 0);
	if (!passed)
	{
		return LayoutBindingTestResult(passed,
									   generateLog(String("binding point did not match default"), bindingPoints[u], 0));
	}

	return true;
}

//== verify that binding point has specified value
LayoutBindingTestResult LayoutBindingBaseCase::binding_basic_explicit()
{
	bool passed = true;

	{
		StringStream s;
		s << buildAccess(getDefaultUniformName()) << ";\n";
		setTemplateParam("UNIFORM_ACCESS", s.str());
	}

	std::vector<int> bindings = makeSparseRange(maxBindings());
	for (std::vector<int>::iterator it = bindings.begin(); it < bindings.end(); it++)
	{
		int	binding = *it;
		String decl =
			buildUniformDecl(String(getTestParameters().keyword), buildLayout(binding),
							 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
							 buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
		setTemplateParam("UNIFORM_DECL", decl);
		updateTemplate();

		LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
		passed &= program->compiledAndLinked();
		if (!passed)
		{
			return LayoutBindingTestResult(passed, program->getErrorLog());
		}

		StringVector  list;
		const String& s = buildBlockName(getDefaultUniformName());
		if (!s.empty())
			list.push_back(s + "_block");
		else
			list.push_back(getDefaultUniformName());

		StringIntMap bindingPoints = program->getBindingPoints(list);
		passed &= bindingPoints.size() == list.size() && (binding == bindingPoints[list[0]]);
		if (!passed)
		{
			return LayoutBindingTestResult(
				passed, generateLog(String("binding point did not match default"), bindingPoints[list[0]], binding));
		}
	}
	return true;
}

//== verify that binding works with multiple samplers (same binding points)
LayoutBindingTestResult LayoutBindingBaseCase::binding_basic_multiple()
{
	bool passed = true;

	glw::GLint baseBindingPoint = maxBindings() - 1;

	String decl0 = buildUniformDecl(String(getTestParameters().keyword), buildLayout(baseBindingPoint),
									String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
									buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
	String decl1 = buildUniformDecl(String(getTestParameters().keyword), buildLayout(baseBindingPoint),
									String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName(1)),
									buildBlock(getDefaultUniformName(1)), getDefaultUniformName(1), String());
	setTemplateParam("UNIFORM_DECL", decl0 + decl1);

	StringStream s;
	s << buildAccess(getDefaultUniformName()) << " + " << buildAccess(getDefaultUniformName(1)) << ";\n";
	setTemplateParam("UNIFORM_ACCESS", s.str());
	updateTemplate();

	LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
	passed &= program->compiledAndLinked();
	if (!passed)
	{
		return LayoutBindingTestResult(passed, program->getErrorLog());
	}

	StringVector list;
	String		 u = buildBlockName(getDefaultUniformName());
	if (!u.empty())
		list.push_back(u + "_block");
	else
		list.push_back(getDefaultUniformName());

	u = buildBlockName(getDefaultUniformName(1));
	if (!u.empty())
		list.push_back(u + "_block");
	else
		list.push_back(getDefaultUniformName(1));

	StringIntMap bindingPoints = program->getBindingPoints(list);
	passed &= (baseBindingPoint == bindingPoints[list[0]]) && (baseBindingPoint == bindingPoints[list[1]]);
	if (!passed)
	{
		String err;
		err = generateLog(String("binding point did not match default"), bindingPoints[list[0]], baseBindingPoint);
		err += generateLog(String("binding point did not match default"), bindingPoints[list[1]], baseBindingPoint);
		return LayoutBindingTestResult(passed, err);
	}

	return true;
}

//== verify that binding point has specified value
LayoutBindingTestResult LayoutBindingBaseCase::binding_basic_render()
{
	bool passed = true;

	StringStream s;
	s << buildAccess(getDefaultUniformName()) << ";\n";
	setTemplateParam("UNIFORM_ACCESS", s.str());

	std::vector<int> bindings = makeSparseRange(maxBindings());
	for (std::vector<int>::iterator it = bindings.begin(); it < bindings.end(); it++)
	{
		int	binding = *it;
		String decl =
			buildUniformDecl(String(getTestParameters().keyword), buildLayout(binding),
							 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
							 buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
		setTemplateParam("UNIFORM_DECL", decl);
		updateTemplate();

		LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
		passed &= program->compiledAndLinked();
		if (!passed)
		{
			return LayoutBindingTestResult(passed, program->getErrorLog());
		}

		LayoutBindingTestResult drawTestResult = ((*this).*(m_drawTest))(program->getProgram(), binding);
		if (!drawTestResult.testPassed())
		{
			return LayoutBindingTestResult(drawTestResult.testPassed(), drawTestResult.getReason());
		}
	}
	return true;
}

LayoutBindingTestResult LayoutBindingBaseCase::binding_integer_constant()
{
	bool			 passed   = true;
	std::vector<int> integers = makeSparseRange(maxBindings(), 0);

	std::vector<IntegerConstant> integerConstants;
	for (int idx = 0; idx < IntegerConstant::last; idx++)
	{
		for (IntVector::iterator it = integers.begin(); it != integers.end(); it++)
		{
			integerConstants.push_back(IntegerConstant((IntegerConstant::Literals)idx, (*it)));
		}
	}

	//== verify that binding point can be set with integer constant
	for (std::vector<IntegerConstant>::iterator it = integerConstants.begin(); it != integerConstants.end(); it++)
	{
		String& intConst = (*it).asString;

		String decl =
			buildUniformDecl(String(getTestParameters().keyword), buildLayout(intConst),
							 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
							 buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
		setTemplateParam("UNIFORM_DECL", decl);

		StringStream s;
		s << buildAccess(getDefaultUniformName()) << ";\n";
		setTemplateParam("UNIFORM_ACCESS", s.str());
		updateTemplate();

		LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
		passed &= program->compiledAndLinked();
		if (!passed)
		{
			return LayoutBindingTestResult(passed, program->getErrorLog());
		}

		StringVector  list;
		const String& u = buildBlockName(getDefaultUniformName());
		if (!u.empty())
			list.push_back(u + "_block");
		else
			list.push_back(getDefaultUniformName());

		StringIntMap bindingPoints = program->getBindingPoints(list);
		passed &= ((*it).asInt == bindingPoints[list[0]]);
		if (!passed)
		{
			return LayoutBindingTestResult(passed, generateLog(String("binding point did not match default"),
															   bindingPoints[list[0]], (*it).asInt));
		}
	}

	//== verify that binding point can be set with integer constant resulting from a preprocessor substitution
	for (std::vector<IntegerConstant>::iterator it = integerConstants.begin(); it != integerConstants.end(); it++)
	{
		String& intConst = (*it).asString;

		StringStream s;
		s << "#define INT_CONST " << intConst << std::endl;

		String decl =
			buildUniformDecl(String(getTestParameters().keyword), buildLayout(String("INT_CONST")),
							 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
							 buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
		setTemplateParam("UNIFORM_DECL", s.str() + decl);

		s.reset();
		s << buildAccess(getDefaultUniformName()) << ";\n";
		setTemplateParam("UNIFORM_ACCESS", s.str());
		updateTemplate();

		LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
		passed &= program->compiledAndLinked();
		if (!passed)
		{
			return LayoutBindingTestResult(passed, program->getErrorLog());
		}

		StringVector  list;
		const String& u = buildBlockName(getDefaultUniformName());
		if (!u.empty())
			list.push_back(u + "_block");
		else
			list.push_back(getDefaultUniformName());

		StringIntMap bindingPoints = program->getBindingPoints(list);
		passed &= ((*it).asInt == bindingPoints[list[0]]);
		if (!passed)
		{
			return LayoutBindingTestResult(passed, generateLog(String("binding point did not match default"),
															   bindingPoints[list[0]], (*it).asInt));
		}
	}

	return true;
}

//== test different sized arrays
LayoutBindingTestResult LayoutBindingBaseCase::binding_array_size(void)
{
	bool passed = true;

	std::vector<int> arraySizes = makeSparseRange(maxArraySize(), 1);
	for (std::vector<int>::iterator it = arraySizes.begin(); it < arraySizes.end(); it++)
	{
		int	arraySize = *it;
		String decl =
			buildUniformDecl(String(getTestParameters().keyword), buildLayout(maxBindings() - arraySize - 1),
							 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
							 buildBlock(getDefaultUniformName()), getDefaultUniformName(), buildArray(arraySize));
		setTemplateParam("UNIFORM_DECL", decl);

		StringStream s;
		for (int idx = 0; idx < arraySize; idx++)
		{
			s << (idx ? " + " : "") << buildAccess(buildArrayAccess(0, idx));
		}
		s << ";\n";
		setTemplateParam("UNIFORM_ACCESS", s.str());
		updateTemplate();

		LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
		passed &= program->compiledAndLinked();
		if (!passed)
		{
			return LayoutBindingTestResult(passed, program->getErrorLog());
		}

		StringVector list;
		for (int idx = 0; idx < arraySize; idx++)
		{
			std::ostringstream texUnitStr;
			texUnitStr << getDefaultUniformName();
			const String& u = buildBlockName(getDefaultUniformName());
			if (!u.empty())
				texUnitStr << "_block";
			texUnitStr << buildArray(idx);
			list.push_back(texUnitStr.str());
		}

		StringIntMap bindingPoints = program->getBindingPoints(list);
		for (int idx = 0; idx < arraySize; idx++)
		{
			passed &= (((maxBindings() - arraySize - 1) + idx) == bindingPoints[list[idx]]);
			if (!passed)
			{
				return LayoutBindingTestResult(passed, generateLog(String("binding point did not match default"),
																   bindingPoints[list[idx]],
																   (maxBindings() - arraySize - 1) + idx));
			}
		}
	}

	return LayoutBindingTestResult(passed, String());
}

//== verify first element takes binding point specified in binding and
//== subsequent entries take the next consecutive units
LayoutBindingTestResult LayoutBindingBaseCase::binding_array_implicit(void)
{
	bool passed = true;

	std::vector<int> bindings = makeSparseRange(maxBindings(), 0);
	for (std::vector<int>::iterator it = bindings.begin(); it < bindings.end(); it++)
	{
		int baseBindingPoint = *it;
		int arraySize		 = std::min(maxBindings() - baseBindingPoint, 4);

		String decl =
			buildUniformDecl(String(getTestParameters().keyword), buildLayout(baseBindingPoint),
							 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
							 buildBlock(getDefaultUniformName()), getDefaultUniformName(), buildArray(arraySize));
		setTemplateParam("UNIFORM_DECL", decl);

		StringStream s;
		for (int idx = 0; idx < arraySize; idx++)
		{
			s << (idx ? " + " : "") << buildAccess(buildArrayAccess(0, idx));
		}
		s << ";\n";
		setTemplateParam("UNIFORM_ACCESS", s.str());
		updateTemplate();

		LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
		passed &= program->compiledAndLinked();
		if (!passed)
		{
			return LayoutBindingTestResult(passed, program->getErrorLog());
		}
		StringVector list;
		for (int idx = 0; idx < arraySize; idx++)
		{
			std::ostringstream texUnitStr;
			texUnitStr << getDefaultUniformName();
			const String& u = buildBlockName(getDefaultUniformName());
			if (!u.empty())
				texUnitStr << "_block";
			texUnitStr << buildArray(idx);
			list.push_back(texUnitStr.str());
		}

		StringIntMap bindingPoints = program->getBindingPoints(list);
		for (int idx = 0; idx < arraySize; idx++)
		{
			passed &= ((baseBindingPoint + idx) == bindingPoints[list[idx]]);
			if (!passed)
			{
				return LayoutBindingTestResult(passed, generateLog(String("binding point did not match default"),
																   bindingPoints[list[idx]], (baseBindingPoint + idx)));
			}
		}
	}
	return LayoutBindingTestResult(passed, String());
}

//== multiple arrays :verify first element takes binding point specified in binding and
//== subsequent entries take the next consecutive units
LayoutBindingTestResult LayoutBindingBaseCase::binding_array_multiple(void)
{
	bool passed = true;

	// two arrays, limit max. binding to one
	std::vector<int> bindings = makeSparseRange(maxBindings() - 2, 0);
	for (std::vector<int>::iterator it = bindings.begin(); it < bindings.end(); it++)
	{
		int baseBindingPoint = *it;

		// total distance from current binding point to end of binding range
		// split over two arrays, making sure that the array sizes don't
		// exceed max. array sizes per stage
		int arraySize = (maxBindings() - baseBindingPoint - 1) / 2;
		arraySize	 = std::min(arraySize, maxArraySize() / 2);

		StringStream s;
		String		 decl =
			buildUniformDecl(String(getTestParameters().keyword), buildLayout(baseBindingPoint),
							 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
							 buildBlock(getDefaultUniformName()), getDefaultUniformName(), buildArray(arraySize));
		String another_decl =
			buildUniformDecl(String(getTestParameters().keyword), buildLayout(baseBindingPoint),
							 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName(1)),
							 buildBlock(getDefaultUniformName(1)), getDefaultUniformName(1), buildArray(arraySize));
		setTemplateParam("UNIFORM_DECL", decl + another_decl);

		s.reset();
		for (int uniform = 0; uniform < 2; uniform++)
		{
			for (int idx = 0; idx < arraySize; idx++)
			{
				s << ((idx | uniform) ? " + " : "") << buildAccess(buildArrayAccess(uniform, idx));
			}
		}
		s << ";\n";
		setTemplateParam("UNIFORM_ACCESS", s.str());
		updateTemplate();

		LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
		passed &= program->compiledAndLinked();
		if (!passed)
		{
			return LayoutBindingTestResult(passed, program->getErrorLog());
		}

		StringVector list;
		for (int uniform = 0; uniform < 2; uniform++)
		{
			list.clear();
			for (int idx = 0; idx < arraySize; idx++)
			{
				std::ostringstream texUnitStr;
				texUnitStr << getDefaultUniformName(uniform);
				const String& u = buildBlockName(getDefaultUniformName(uniform));
				if (!u.empty())
					texUnitStr << "_block";
				texUnitStr << buildArray(idx);
				list.push_back(texUnitStr.str());
			}

			StringIntMap bindingPoints = program->getBindingPoints(list);
			for (int idx = 0; idx < arraySize; idx++)
			{
				passed &= ((baseBindingPoint + idx) == bindingPoints[list[idx]]);
				if (!passed)
				{
					return LayoutBindingTestResult(passed,
												   generateLog(String("binding point did not match default"),
															   bindingPoints[list[idx]], (baseBindingPoint + idx)));
				}
			}
		}
	}
	return LayoutBindingTestResult(passed, String());
}

//== verify that explicit binding point can be changed via API
LayoutBindingTestResult LayoutBindingBaseCase::binding_api_update(void)
{
	bool passed = true;

	String decl = buildUniformDecl(String(getTestParameters().keyword), buildLayout(1),
								   String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
								   buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
	setTemplateParam("UNIFORM_DECL", decl);

	StringStream s;
	s << buildAccess(getDefaultUniformName()) << ";\n";
	setTemplateParam("UNIFORM_ACCESS", s.str());
	updateTemplate();

	LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
	passed &= program->compiledAndLinked();
	if (!passed)
	{
		return LayoutBindingTestResult(passed, program->getErrorLog());
	}

	StringVector  list;
	const String& u = buildBlockName(getDefaultUniformName());
	if (!u.empty())
		list.push_back(u + "_block");
	else
		list.push_back(getDefaultUniformName());

	StringIntMap bindingPoints = program->getBindingPoints(list);

	gl().useProgram(program->getProgram());
	program->setBindingPoints(list, maxBindings() - 1);
	gl().useProgram(0);

	bindingPoints = program->getBindingPoints(list);

	passed &= bindingPoints[list[0]] == (maxBindings() - 1);
	if (!passed)
	{
		return LayoutBindingTestResult(passed, generateLog(String("binding point did not match default"),
														   bindingPoints[list[0]], maxBindings() - 1));
	}

	return LayoutBindingTestResult(passed, String());
}

LayoutBindingTestResult LayoutBindingBaseCase::binding_compilation_errors(void)
{
	bool   passed = true;
	String decl;

	// verify "uniform float var;" doesn't compile
	{
		StringStream s;
		s << getTestParameters().vector_type << "(0.0);";

		setTemplateParam("UNIFORM_ACCESS", s.str());
		s.reset();
		s << "layout(binding=0) "
		  << "uniform float tex0;";
		setTemplateParam("UNIFORM_DECL", s.str());
		updateTemplate();

		LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
		passed &= !program->compiledAndLinked();
		if (!passed)
		{
			return LayoutBindingTestResult(passed, program->getErrorLog(true));
		}
	}

	// verify that non-constant integer expression in binding fails
	{
		decl = buildUniformDecl(String(getTestParameters().keyword), buildLayout(String("0.0")),
								String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
								buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
		setTemplateParam("UNIFORM_DECL", decl);
		updateTemplate();

		LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
		passed &= !program->compiledAndLinked();
		if (!passed)
		{
			return LayoutBindingTestResult(passed, program->getErrorLog(true));
		}
	}

	{
		decl = buildUniformDecl(String(getTestParameters().keyword), buildLayout(String("-1")),
								String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
								buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
		setTemplateParam("UNIFORM_DECL", decl);
		updateTemplate();

		LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
		passed &= !program->compiledAndLinked();
		if (!passed)
		{
			return LayoutBindingTestResult(passed, program->getErrorLog(true));
		}
	}
	{
		decl = buildUniformDecl(String(getTestParameters().keyword), buildLayout(maxBindings()),
								String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
								buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
		setTemplateParam("UNIFORM_DECL", decl);
		updateTemplate();

		LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
		passed &= !program->compiledAndLinked();
		if (!passed)
		{
			return LayoutBindingTestResult(passed, program->getErrorLog(true));
		}
	}
	{
		decl = buildUniformDecl(String(getTestParameters().keyword), buildLayout(maxBindings()),
								String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
								buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
		setTemplateParam("UNIFORM_DECL", decl);

		StringStream s;
		s << "vec4(0.0);\n";
		setTemplateParam("UNIFORM_ACCESS", s.str());
		updateTemplate();

		LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
		passed &= !program->compiledAndLinked();
		if (!passed)
		{
			return LayoutBindingTestResult(passed, program->getErrorLog(true));
		}
	}
	return LayoutBindingTestResult(passed, String());
}

LayoutBindingTestResult LayoutBindingBaseCase::binding_link_errors(void)
{
	bool passed = true;

	// same sampler with different binding in two compilation units
	if (isStage(VertexShader))
	{
		String decl =
			buildUniformDecl(String(getTestParameters().keyword), buildLayout(1),
							 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
							 buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
		setTemplateParam(VertexShader, "UNIFORM_DECL", decl);

		setTemplateParam(VertexShader, "OUT_ASSIGNMENT", String("fragColor ="));

		StringStream s;
		s << buildAccess(getDefaultUniformName()) << ";\n";
		setTemplateParam(VertexShader, "UNIFORM_ACCESS", s.str());
		updateTemplate(VertexShader);

		decl = buildUniformDecl(String(getTestParameters().keyword), buildLayout(3),
								String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
								buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
		setTemplateParam(FragmentShader, "UNIFORM_DECL", decl);

		s.reset();
		s << "fragColor + " << buildAccess(getDefaultUniformName()) << ";\n";
		setTemplateParam(FragmentShader, "UNIFORM_ACCESS", s.str());
		updateTemplate(FragmentShader);

		LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
		passed = !program->compiledAndLinked();
		if (!passed)
		{
			return LayoutBindingTestResult(passed, program->getErrorLog(true));
		}
	}

	return LayoutBindingTestResult(passed, String());
}

// this subtest is generically empty. Overwritten in test cases as needed.
LayoutBindingTestResult LayoutBindingBaseCase::binding_examples(void)
{
	return true;
}

// just for image and atomic counter cases
LayoutBindingTestResult LayoutBindingBaseCase::binding_mixed_order(void)
{
	return true;
}

//=========================================================================
// test case Sampler layout binding
//=========================================================================
class SamplerLayoutBindingCase : public LayoutBindingBaseCase

{
public:
	SamplerLayoutBindingCase(Context& context, const char* name, const char* description, StageType stage,
							 LayoutBindingParameters& samplerType, glu::GLSLVersion glslVersion);
	~SamplerLayoutBindingCase(void);

private:
	/*virtual*/
	LayoutBindingProgram* createProgram()
	{
		return new LayoutBindingProgram(*this);
	}

	/*virtual*/
	String getDefaultUniformName(int idx = 0)
	{
		StringStream s;

		s << "sampler" << idx;
		return s.str();
	}

	/*virtual*/
	String buildLayout(const String& binding)
	{
		std::ostringstream s;
		if (!binding.empty())
			s << "layout(binding=" << binding << ") ";
		return s.str();
	}

	virtual int maxBindings()
	{
		int units = 0;
		gl().getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &units);
		return units;
	}

	// return max. array size allowed
	virtual int maxArraySize()
	{
		int units = 0;

		switch (getStage())
		{
		case VertexShader:
			gl().getIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &units);
			break;
		case FragmentShader:
			gl().getIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &units);
			break;
		case ComputeShader:
			gl().getIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &units);
			break;
		default:
			DE_ASSERT(0);
			break;
		}

		return units;
	}
};

SamplerLayoutBindingCase::SamplerLayoutBindingCase(Context& context, const char* name, const char* description,
												   StageType stage, LayoutBindingParameters& samplerType,
												   glu::GLSLVersion glslVersion)
	: LayoutBindingBaseCase(context, name, description, stage, samplerType, glslVersion)
{
}

SamplerLayoutBindingCase::~SamplerLayoutBindingCase(void)
{
}

//=========================================================================
// test case Image layout binding
//=========================================================================
class ImageLayoutBindingCase : public LayoutBindingBaseCase

{
public:
	ImageLayoutBindingCase(Context& context, const char* name, const char* description, StageType stage,
						   LayoutBindingParameters& samplerType, glu::GLSLVersion glslVersion);
	~ImageLayoutBindingCase(void);

private:
	class ImageLayoutBindingProgram : public LayoutBindingProgram
	{
	public:
		ImageLayoutBindingProgram(IProgramContextSupplier& contextSupplier) : LayoutBindingProgram(contextSupplier)
		{
		}
	};

private:
	// IProgramContextSupplier
	/*virtual*/
	LayoutBindingProgram* createProgram()
	{
		return new ImageLayoutBindingProgram(*this);
	}

private:
	/*virtual*/
	String getDefaultUniformName(int idx = 0)
	{
		StringStream s;
		s << "image" << idx;
		return s.str();
	}

	/*virtual*/
	String buildLayout(const String& binding)
	{
		std::ostringstream s;
		if (!binding.empty())
			s << "layout(binding=" << binding << ", rgba8) readonly ";
		else
			s << "layout(rgba8) readonly ";
		return s.str();
	}

	/*virtual*/
	int maxBindings()
	{
		int units = 0;
		gl().getIntegerv(GL_MAX_IMAGE_UNITS, &units);
		return units;
	}

	/*virtual*/
	int maxArraySize()
	{
		int units = 0;
		switch (getStage())
		{
		case VertexShader:
			gl().getIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &units);
			break;
		case FragmentShader:
			gl().getIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &units);
			break;
		case ComputeShader:
			gl().getIntegerv(GL_MAX_COMPUTE_IMAGE_UNIFORMS, &units);
			break;
		default:
			DE_ASSERT(0);
			break;
		}
		return units;
	}

private:
	//virtual LayoutBindingTestResult        binding_basic_default               (void);
	//virtual LayoutBindingTestResult        binding_basic_explicit              (void);
	//virtual LayoutBindingTestResult        binding_basic_multiple              (void);
	//virtual LayoutBindingTestResult        binding_basic_render                (void);
	//virtual LayoutBindingTestResult        binding_integer_constant            (void);
	//virtual LayoutBindingTestResult        binding_array_size                  (void);
	//virtual LayoutBindingTestResult        binding_array_implicit              (void);
	//virtual LayoutBindingTestResult        binding_array_multiple              (void);
	/*virtual*/
	LayoutBindingTestResult binding_api_update(void)
	{
		// only for GL
		if (getGLSLVersion() == glu::GLSL_VERSION_310_ES)
			return LayoutBindingTestResult(true, String(), true);

		return LayoutBindingBaseCase::binding_api_update();
	}
	//virtual LayoutBindingTestResult        binding_compilation_errors          (void);
	//virtual LayoutBindingTestResult        binding_link_errors                 (void);
	//virtual LayoutBindingTestResult        binding_link_examples               (void);
	/*virtual*/
	LayoutBindingTestResult binding_mixed_order(void)
	{
		bool passed = true;

		{
			StringStream s;
			s << buildAccess(getDefaultUniformName()) << ";\n";
			setTemplateParam("UNIFORM_ACCESS", s.str());

			String decl =
				buildUniformDecl(String(getTestParameters().keyword), String("layout(binding=0, rgba8) readonly"),
								 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
								 buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
			setTemplateParam("UNIFORM_DECL", decl);
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (!passed)
			{
				return LayoutBindingTestResult(passed, program->getErrorLog());
			}
		}
		{
			String decl =
				buildUniformDecl(String(getTestParameters().keyword), String("layout(r32f, binding=0) readonly"),
								 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
								 buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
			setTemplateParam("UNIFORM_DECL", decl);
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (!passed)
			{
				return LayoutBindingTestResult(passed, program->getErrorLog());
			}
		}

		return true;
	}
};

ImageLayoutBindingCase::ImageLayoutBindingCase(Context& context, const char* name, const char* description,
											   StageType stage, LayoutBindingParameters& samplerType,
											   glu::GLSLVersion glslVersion)
	: LayoutBindingBaseCase(context, name, description, stage, samplerType, glslVersion)
{
}

ImageLayoutBindingCase::~ImageLayoutBindingCase(void)
{
}

//=========================================================================
// test case Atomic counter binding
//=========================================================================
class AtomicCounterLayoutBindingCase : public LayoutBindingBaseCase

{
public:
	AtomicCounterLayoutBindingCase(Context& context, const char* name, const char* description, StageType stage,
								   LayoutBindingParameters& samplerType, glu::GLSLVersion glslVersion);
	~AtomicCounterLayoutBindingCase(void)
	{
	}

private:
	class AtomicCounterLayoutBindingProgram : public LayoutBindingProgram
	{
	public:
		AtomicCounterLayoutBindingProgram(IProgramContextSupplier& contextSupplier)
			: LayoutBindingProgram(contextSupplier)
		{
		}

	private:
		/*virtual*/
		StringIntMap getBindingPoints(StringVector args) const
		{
			StringIntMap bindingPoints;

			for (StringVector::iterator it = args.begin(); it != args.end(); it++)
			{
				glw::GLuint idx = gl().getProgramResourceIndex(getProgram(), GL_UNIFORM, (*it).c_str());
				if (idx != GL_INVALID_INDEX)
				{
					glw::GLenum param					  = GL_ATOMIC_COUNTER_BUFFER_INDEX;
					glw::GLint  atomic_counter_buffer_idx = -1;
					gl().getProgramResourceiv(getProgram(), GL_UNIFORM, idx, 1, &param, 1, NULL,
											  &atomic_counter_buffer_idx);
					bool hasNoError = (GL_NO_ERROR == gl().getError()) && (-1 != atomic_counter_buffer_idx);
					if (!hasNoError)
						continue;

					param			 = GL_BUFFER_BINDING;
					glw::GLint value = -1;
					gl().getProgramResourceiv(getProgram(), GL_ATOMIC_COUNTER_BUFFER, atomic_counter_buffer_idx, 1,
											  &param, 1, NULL, &value);
					hasNoError = (GL_NO_ERROR == gl().getError()) && (-1 != value);
					if (!hasNoError)
						continue;

					bindingPoints[*it] = value;
				}
			}
			return bindingPoints;
		}

		/*virtual*/
		StringIntMap getOffsets(StringVector args) const
		{
			StringIntMap bindingPoints;

			for (StringVector::iterator it = args.begin(); it != args.end(); it++)
			{
				glw::GLuint idx = gl().getProgramResourceIndex(getProgram(), GL_UNIFORM, (*it).c_str());
				if (idx != GL_INVALID_INDEX)
				{
					glw::GLenum param = GL_OFFSET;
					glw::GLint  value = -1;
					gl().getProgramResourceiv(getProgram(), GL_UNIFORM, idx, 1, &param, 1, NULL, &value);
					bool hasNoError = (GL_NO_ERROR == gl().getError());
					if (hasNoError)
					{
						bindingPoints[*it] = value;
					}
				}
			}
			return bindingPoints;
		}
	};

private:
	// IProgramContextSupplier
	/*virtual*/
	LayoutBindingProgram* createProgram()
	{
		return new AtomicCounterLayoutBindingProgram(*this);
	}

private:
	/*virtual*/
	String getDefaultUniformName(int idx = 0)
	{
		StringStream s;
		s << "atomic" << idx;
		return s.str();
	}

	/*virtual*/
	String buildAccess(const String& var)
	{
		std::ostringstream s;
		s << "vec4(float(atomicCounter(" << var << ")), 1.0, 0.0, 1.0)";
		return s.str();
	}

	int maxBindings()
	{
		int units = 0;
		gl().getIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &units);
		return units;
	}

	// return max. array size allowed
	int maxArraySize()
	{
		int units = 0;
		switch (getStage())
		{
		case FragmentShader:
			gl().getIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, &units);
			break;
		case VertexShader:
			gl().getIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS, &units);
			break;
		case ComputeShader:
			gl().getIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTERS, &units);
			break;
		default:
			DE_ASSERT(0);
			break;
		}
		return units;
	}

	//=========================================================================
	// sub-tests overrides
	//=========================================================================
private:
	LayoutBindingTestResult binding_basic_default(void)
	{
		return true;
	}
	//virtual LayoutBindingTestResult binding_basic_explicit          (void);
	//virtual LayoutBindingTestResult binding_basic_multiple          (void);
	LayoutBindingTestResult binding_basic_render(void)
	{
		return true;
	}
	//virtual LayoutBindingTestResult binding_integer_constant        (void);
	/*virtual*/
	LayoutBindingTestResult binding_array_size(void)
	{
		bool passed = true;

		//== test different sized arrays
		std::vector<int> arraySizes = makeSparseRange(maxArraySize(), 1);
		for (std::vector<int>::iterator it = arraySizes.begin(); it < arraySizes.end(); it++)
		{
			int			 arraySize = *it;
			StringStream s;
			s << "[" << arraySize << "]";
			String decl =
				buildUniformDecl(String(getTestParameters().keyword), buildLayout(0),
								 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
								 buildBlock(getDefaultUniformName()), getDefaultUniformName(), buildArray(arraySize));
			setTemplateParam("UNIFORM_DECL", decl);

			s.reset();
			// build a function that accesses the whole array
			s << "float accumulate(void)\n";
			s << "{\n";
			s << "  float acc = 0.0;\n";
			s << "  for(int i=0; i < " << arraySize << " ; i++)\n";
			s << "    acc = float(atomicCounter(" << getDefaultUniformName() << "[i]));\n";
			s << "  return acc;\n";
			s << "}\n";

			setTemplateParam("OPTIONAL_FUNCTION_BLOCK", s.str());

			s.reset();
			s << "vec4(accumulate(), 1.0, 0.0, 1.0);\n";
			setTemplateParam("UNIFORM_ACCESS", s.str());
			updateTemplate();

			setTemplateParam("OPTIONAL_FUNCTION_BLOCK", String());

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (!passed)
			{
				return LayoutBindingTestResult(passed, program->getErrorLog());
			}

			StringVector	   list;
			std::ostringstream texUnitStr;
			texUnitStr << getDefaultUniformName() << "[0]";
			list.push_back(texUnitStr.str());

			StringIntMap bindingPoints = program->getBindingPoints(list);
			passed &= (0 == bindingPoints[list[0]]);
			if (!passed)
			{
				return LayoutBindingTestResult(
					passed, generateLog(String("binding point did not match default"), bindingPoints[list[0]], 1));
			}
		}

		return LayoutBindingTestResult(passed, String());
	}
	LayoutBindingTestResult binding_array_implicit(void)
	{
		return true;
	}
	LayoutBindingTestResult binding_array_multiple(void)
	{
		return true;
	}
	LayoutBindingTestResult binding_api_update(void)
	{
		return true;
	}
	//virtual LayoutBindingTestResult binding_compilation_errors      (void);
	//virtual LayoutBindingTestResult binding_link_errors             (void);

	LayoutBindingTestResult binding_examples_many_bindings(void)
	{
		int max_bindings = 0;

		if (isStage(VertexShader))
		{
			gl().getIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS, &max_bindings);
		}
		else if (isStage(FragmentShader))
		{
			gl().getIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &max_bindings);
		}
		else
		{
			gl().getIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_bindings);
		}

		// example 1 in atomic counter CTS spec ac-binding-examples
		{
			bool		 passed = true;
			StringStream s;
			s << buildAccess(getDefaultUniformName()) << ";\n";
			setTemplateParam("UNIFORM_ACCESS", s.str());

			s.reset();
			s << "layout(binding=2, offset=4) uniform atomic_uint;\n";
			s << "layout(binding=2) uniform atomic_uint " << getDefaultUniformName() << ";\n";
			setTemplateParam("UNIFORM_DECL", s.str());
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (!passed)
			{
				return LayoutBindingTestResult(passed, program->getErrorLog());
			}

			StringVector list;
			list.push_back(getDefaultUniformName());

			StringIntMap offsets = program->getOffsets(list);
			passed &= (4 == offsets[list[0]]);
			if (!passed)
			{
				return LayoutBindingTestResult(
					passed, generateLog(String("offset did not match requested"), offsets[list[0]], 1));
			}
		}

		// example 2 in atomic counter CTS spec ac-binding-examples
		if (max_bindings >= 2)
		{
			bool		 passed = true;
			StringStream s;
			s << buildAccess(getDefaultUniformName()) << "\n";
			s << "+" << buildAccess(getDefaultUniformName(1)) << "\n";
			s << "+" << buildAccess(getDefaultUniformName(2)) << "\n";
			s << "+" << buildAccess(getDefaultUniformName(3)) << ";\n";
			setTemplateParam("UNIFORM_ACCESS", s.str());

			s.reset();
			s << "layout(binding=3, offset=4) uniform atomic_uint " << getDefaultUniformName() << ";\n";
			s << "layout(binding=2) uniform atomic_uint " << getDefaultUniformName(1) << ";\n";
			s << "layout(binding=3) uniform atomic_uint " << getDefaultUniformName(2) << ";\n";
			s << "layout(binding=2) uniform atomic_uint " << getDefaultUniformName(3) << ";\n";
			setTemplateParam("UNIFORM_DECL", s.str());
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (!passed)
			{
				return LayoutBindingTestResult(passed, program->getErrorLog());
			}

			StringVector list;
			list.push_back(getDefaultUniformName());
			list.push_back(getDefaultUniformName(1));
			list.push_back(getDefaultUniformName(2));
			list.push_back(getDefaultUniformName(3));

			StringIntMap offsets = program->getOffsets(list);
			IntVector	expected;
			expected.insert(expected.end(), 4);
			expected.insert(expected.end(), 0);
			expected.insert(expected.end(), 8);
			expected.insert(expected.end(), 4);
			for (unsigned int idx = 0; idx < list.size(); idx++)
			{
				passed &= (expected[idx] == offsets[list[idx]]);
				if (!passed)
				{
					return LayoutBindingTestResult(
						passed, generateLog(String("offset of") + String(list[idx]) + String("did not match requested"),
											offsets[list[idx]], 4));
				}
			}
		}

		// example 3 in atomic counter CTS spec ac-binding-examples
		{
			bool		 passed = true;
			StringStream s;
			s << buildAccess(getDefaultUniformName()) << ";\n";
			setTemplateParam("UNIFORM_ACCESS", s.str());

			s.reset();
			s << "layout(binding=2, offset=4) uniform atomic_uint;\n";
			s << "layout(offset=8) uniform atomic_uint " << getDefaultUniformName() << ";\n";
			setTemplateParam("UNIFORM_DECL", s.str());
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (passed)
			{
				return LayoutBindingTestResult(!passed, String("should not compile"));
			}
		}

		// example 4 in atomic counter CTS spec ac-binding-examples
		{
			bool		 passed = true;
			StringStream s;
			s << buildAccess(getDefaultUniformName()) << ";\n";
			setTemplateParam("UNIFORM_ACCESS", s.str());

			s.reset();
			s << "layout(offset=4) uniform atomic_uint " << getDefaultUniformName() << ";\n";
			setTemplateParam("UNIFORM_DECL", s.str());
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (passed)
			{
				return LayoutBindingTestResult(!passed, String("should not compile"));
			}
		}

		// example 5 in atomic counter CTS spec ac-binding-examples
		// first check working example, then amend it with an error
		if (max_bindings >= 2)
		{
			for (int pass = 0; pass < 2; pass++)
			{
				bool passed = true;

				StringStream s;
				s << buildAccess(getDefaultUniformName()) << "\n";
				if (pass)
				{
					s << "+" << buildAccess(getDefaultUniformName(1)) << "\n";
					s << "+" << buildAccess(getDefaultUniformName(2)) << ";\n";
				}
				else
				{
					s << "+" << buildAccess(getDefaultUniformName(1)) << ";\n";
				}
				setTemplateParam("UNIFORM_ACCESS", s.str());

				s.reset();
				s << "layout(binding=1, offset=0) uniform atomic_uint " << getDefaultUniformName() << ";\n";
				s << "layout(binding=2, offset=0) uniform atomic_uint " << getDefaultUniformName(1) << ";\n";
				if (pass)
					s << "layout(binding=1, offset=0) uniform atomic_uint " << getDefaultUniformName(2) << ";\n";
				setTemplateParam("UNIFORM_DECL", s.str());
				updateTemplate();

				LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
				passed &= program->compiledAndLinked();
				if (pass != 0)
				{
					if (passed)
					{
						return LayoutBindingTestResult(passed, program->getErrorLog());
					}
				}
				else
				{
					if (!passed)
					{
						return LayoutBindingTestResult(passed, String("should not compile"));
					}
				}
			}
		}

		// example 6 in atomic counter CTS spec ac-binding-examples
		// first check working example, then amend it with an error
		if (max_bindings >= 2)
		{
			for (int pass = 0; pass < 2; pass++)
			{
				bool passed = true;

				StringStream s;
				s << buildAccess(getDefaultUniformName()) << "\n";
				if (pass)
				{
					s << "+" << buildAccess(getDefaultUniformName(1)) << "\n";
					s << "+" << buildAccess(getDefaultUniformName(2)) << ";\n";
				}
				else
				{
					s << "+" << buildAccess(getDefaultUniformName(1)) << ";\n";
				}
				setTemplateParam("UNIFORM_ACCESS", s.str());

				s.reset();
				s << "layout(binding=1, offset=0) uniform atomic_uint " << getDefaultUniformName() << ";\n";
				s << "layout(binding=2, offset=0) uniform atomic_uint " << getDefaultUniformName(1) << ";\n";
				if (pass)
					s << "layout(binding=1, offset=2) uniform atomic_uint " << getDefaultUniformName(2) << ";\n";
				setTemplateParam("UNIFORM_DECL", s.str());
				updateTemplate();

				LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
				passed &= program->compiledAndLinked();
				if (pass != 0)
				{
					if (passed)
					{
						return LayoutBindingTestResult(passed, program->getErrorLog());
					}
				}
				else
				{
					if (!passed)
					{
						return LayoutBindingTestResult(passed, String("should not compile"));
					}
				}
			}
		}

		return true;
	}

	LayoutBindingTestResult binding_examples_one_binding(void)
	{
		// example 1 in atomic counter CTS spec ac-binding-examples
		{
			bool		 passed = true;
			StringStream s;
			s << buildAccess(getDefaultUniformName()) << ";\n";
			setTemplateParam("UNIFORM_ACCESS", s.str());

			s.reset();
			s << "layout(binding=0, offset=4) uniform atomic_uint;\n";
			s << "layout(binding=0) uniform atomic_uint " << getDefaultUniformName() << ";\n";
			setTemplateParam("UNIFORM_DECL", s.str());
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (!passed)
			{
				return LayoutBindingTestResult(passed, program->getErrorLog());
			}

			StringVector list;
			list.push_back(getDefaultUniformName());

			StringIntMap offsets = program->getOffsets(list);
			passed &= (4 == offsets[list[0]]);
			if (!passed)
			{
				return LayoutBindingTestResult(
					passed, generateLog(String("offset did not match requested"), offsets[list[0]], 1));
			}
		}

		// example 2 in atomic counter CTS spec ac-binding-examples
		{
			bool		 passed = true;
			StringStream s;
			s << buildAccess(getDefaultUniformName()) << "\n";
			s << "+" << buildAccess(getDefaultUniformName(1)) << "\n";
			s << "+" << buildAccess(getDefaultUniformName(2)) << "\n";
			s << "+" << buildAccess(getDefaultUniformName(3)) << ";\n";
			setTemplateParam("UNIFORM_ACCESS", s.str());

			s.reset();
			s << "layout(binding=0, offset=4) uniform atomic_uint " << getDefaultUniformName() << ";\n";
			s << "layout(binding=0) uniform atomic_uint " << getDefaultUniformName(1) << ";\n";
			s << "layout(binding=0) uniform atomic_uint " << getDefaultUniformName(2) << ";\n";
			s << "layout(binding=0) uniform atomic_uint " << getDefaultUniformName(3) << ";\n";
			setTemplateParam("UNIFORM_DECL", s.str());
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (!passed)
			{
				return LayoutBindingTestResult(passed, program->getErrorLog());
			}

			StringVector list;
			list.push_back(getDefaultUniformName());
			list.push_back(getDefaultUniformName(1));
			list.push_back(getDefaultUniformName(2));
			list.push_back(getDefaultUniformName(3));

			StringIntMap offsets = program->getOffsets(list);
			IntVector	expected;
			expected.insert(expected.end(), 4);
			expected.insert(expected.end(), 8);
			expected.insert(expected.end(), 12);
			expected.insert(expected.end(), 16);
			for (unsigned int idx = 0; idx < list.size(); idx++)
			{
				passed &= (expected[idx] == offsets[list[idx]]);
				if (!passed)
				{
					return LayoutBindingTestResult(
						passed, generateLog(String("offset of") + String(list[idx]) + String("did not match requested"),
											offsets[list[idx]], expected[idx]));
				}
			}
		}

		// example 3 in atomic counter CTS spec ac-binding-examples
		{
			bool		 passed = true;
			StringStream s;
			s << buildAccess(getDefaultUniformName()) << ";\n";
			setTemplateParam("UNIFORM_ACCESS", s.str());

			s.reset();
			s << "layout(binding=0, offset=4) uniform atomic_uint;\n";
			s << "layout(offset=8) uniform atomic_uint " << getDefaultUniformName() << ";\n";
			setTemplateParam("UNIFORM_DECL", s.str());
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (passed)
			{
				return LayoutBindingTestResult(!passed, String("should not compile"));
			}
		}

		// example 4 in atomic counter CTS spec ac-binding-examples
		{
			bool		 passed = true;
			StringStream s;
			s << buildAccess(getDefaultUniformName()) << ";\n";
			setTemplateParam("UNIFORM_ACCESS", s.str());

			s.reset();
			s << "layout(offset=4) uniform atomic_uint " << getDefaultUniformName() << ";\n";
			setTemplateParam("UNIFORM_DECL", s.str());
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (passed)
			{
				return LayoutBindingTestResult(!passed, String("should not compile"));
			}
		}

		// example 5 in atomic counter CTS spec ac-binding-examples
		// first check working example, then amend it with an error
		for (int pass = 0; pass < 2; pass++)
		{
			bool passed = true;

			StringStream s;

			if (pass)
			{
				s << buildAccess(getDefaultUniformName()) << "\n";
				s << "+" << buildAccess(getDefaultUniformName(1)) << ";\n";
			}
			else
			{
				s << buildAccess(getDefaultUniformName()) << ";\n";
			}
			setTemplateParam("UNIFORM_ACCESS", s.str());

			s.reset();
			s << "layout(binding=0, offset=0) uniform atomic_uint " << getDefaultUniformName() << ";\n";
			if (pass)
				s << "layout(binding=0, offset=0) uniform atomic_uint " << getDefaultUniformName(1) << ";\n";
			setTemplateParam("UNIFORM_DECL", s.str());
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (pass != 0)
			{
				if (passed)
				{
					return LayoutBindingTestResult(passed, program->getErrorLog());
				}
			}
			else
			{
				if (!passed)
				{
					return LayoutBindingTestResult(passed, String("should not compile"));
				}
			}
		}

		// example 6 in atomic counter CTS spec ac-binding-examples
		// first check working example, then amend it with an error
		for (int pass = 0; pass < 2; pass++)
		{
			bool passed = true;

			StringStream s;
			if (pass)
			{
				s << buildAccess(getDefaultUniformName()) << "\n";
				s << "+" << buildAccess(getDefaultUniformName(1)) << ";\n";
			}
			else
			{
				s << buildAccess(getDefaultUniformName()) << ";\n";
			}
			setTemplateParam("UNIFORM_ACCESS", s.str());

			s.reset();
			s << "layout(binding=0, offset=0) uniform atomic_uint " << getDefaultUniformName() << ";\n";
			if (pass)
				s << "layout(binding=0, offset=2) uniform atomic_uint " << getDefaultUniformName(1) << ";\n";
			setTemplateParam("UNIFORM_DECL", s.str());
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (pass != 0)
			{
				if (passed)
				{
					return LayoutBindingTestResult(passed, program->getErrorLog());
				}
			}
			else
			{
				if (!passed)
				{
					return LayoutBindingTestResult(passed, String("should not compile"));
				}
			}
		}

		return true;
	}

	/*virtual*/
	LayoutBindingTestResult binding_examples(void)
	{
		if (maxBindings() >= 4)
		{
			return binding_examples_many_bindings();
		}
		else
		{
			return binding_examples_one_binding();
		}
	}

	/*virtual*/
	LayoutBindingTestResult binding_mixed_order(void)
	{
		bool passed = true;

		{
			StringStream s;
			s << buildAccess(getDefaultUniformName()) << ";\n";
			setTemplateParam("UNIFORM_ACCESS", s.str());

			String decl =
				buildUniformDecl(String(getTestParameters().keyword), String("layout(binding=0, offset=0)"),
								 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
								 buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
			setTemplateParam("UNIFORM_DECL", decl);
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (!passed)
			{
				return LayoutBindingTestResult(passed, program->getErrorLog());
			}
		}
		{
			String decl =
				buildUniformDecl(String(getTestParameters().keyword), String("layout(offset=0, binding=0)"),
								 String(getTestParameters().uniform_type), buildBlockName(getDefaultUniformName()),
								 buildBlock(getDefaultUniformName()), getDefaultUniformName(), String());
			setTemplateParam("UNIFORM_DECL", decl);
			updateTemplate();

			LayoutBindingProgram::LayoutBindingProgramAutoPtr program(*this);
			passed &= program->compiledAndLinked();
			if (!passed)
			{
				return LayoutBindingTestResult(passed, program->getErrorLog());
			}
		}

		return true;
	}
};

AtomicCounterLayoutBindingCase::AtomicCounterLayoutBindingCase(Context& context, const char* name,
															   const char* description, StageType stage,
															   LayoutBindingParameters& samplerType,
															   glu::GLSLVersion			glslVersion)
	: LayoutBindingBaseCase(context, name, description, stage, samplerType, glslVersion)
{
}

//=========================================================================
// test case Uniform blocks binding
//=========================================================================
class UniformBlocksLayoutBindingCase : public LayoutBindingBaseCase

{
public:
	UniformBlocksLayoutBindingCase(Context& context, const char* name, const char* description, StageType stage,
								   LayoutBindingParameters& samplerType, glu::GLSLVersion glslVersion);
	~UniformBlocksLayoutBindingCase(void);

private:
	class UniformBlocksLayoutBindingProgram : public LayoutBindingProgram
	{
	public:
		UniformBlocksLayoutBindingProgram(IProgramContextSupplier& contextSupplier)
			: LayoutBindingProgram(contextSupplier)
		{
		}

		~UniformBlocksLayoutBindingProgram()
		{
		}

	private:
		/*virtual*/
		StringIntMap getBindingPoints(StringVector args) const
		{
			StringIntMap bindingPoints;

			for (StringVector::iterator it = args.begin(); it != args.end(); it++)
			{
				glw::GLuint idx = gl().getProgramResourceIndex(getProgram(), GL_UNIFORM_BLOCK, (*it).c_str());
				if (idx != glw::GLuint(-1))
				{
					glw::GLenum param = GL_BUFFER_BINDING;
					glw::GLint  value = -1;
					gl().getProgramResourceiv(getProgram(), GL_UNIFORM_BLOCK, idx, 1, &param, 1, NULL, &value);
					bool hasNoError = (GL_NO_ERROR == gl().getError());
					if (hasNoError)
					{
						bindingPoints[*it] = value;
					}
				}
			}

			return bindingPoints;
		}

		/*virtual*/
		bool setBindingPoints(StringVector list, glw::GLint bindingPoint) const
		{
			bool bNoError = true;

			for (StringVector::iterator it = list.begin(); it != list.end(); it++)
			{
				glw::GLuint blockIndex = gl().getUniformBlockIndex(getProgram(), (*it).c_str());
				if (blockIndex == GL_INVALID_INDEX)

				{
					return false;
				}
				gl().uniformBlockBinding(getProgram(), blockIndex, bindingPoint);
			}
			return bNoError;
		}
	};

private:
	// IProgramContextSupplier
	/*virtual*/
	LayoutBindingProgram* createProgram()
	{
		return new UniformBlocksLayoutBindingProgram(*this);
	}

private:
	/*virtual*/
	String buildBlockName(const String& name)
	{

		return name;
	}

	/*virtual*/
	String buildBlock(const String& name, const String& type)
	{

		std::ostringstream s;
		s << "{";
		s << type << " " << name << "_a; ";
		s << type << " " << name << "_b; ";
		s << "}";
		return s.str();
	}

	/*virtual*/
	String buildAccess(const String& var)
	{
		std::ostringstream s;
		s << "vec4(0.0, " << var << "_a, 0.0, 1.0) + vec4(0.0, " << var << "_b, 0.0, 1.0)";
		return s.str();
	}

	/*virtual*/
	String buildLayout(const String& binding)
	{
		std::ostringstream s;
		if (!binding.empty())
			s << "layout(binding=" << binding << ", std140) ";
		else
			s << "layout(std140) ";
		return s.str();
	}

	/*virtual*/
	int maxBindings()
	{
		int units = 0;
		gl().getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &units);
		return units;
	}

	// return max. array size allowed
	/*virtual*/
	int maxArraySize()
	{
		int units = 0;
		switch (getStage())
		{
		case FragmentShader:
			gl().getIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &units);
			break;
		case VertexShader:
			gl().getIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &units);
			break;
		case ComputeShader:
			gl().getIntegerv(GL_MAX_COMPUTE_UNIFORM_BLOCKS, &units);
			break;
		default:
			DE_ASSERT(0);
			break;
		}
		return units;
	}

	/*virtual*/
	void bind(int binding)
	{
		gl().bindBufferBase(GL_UNIFORM_BUFFER, binding, m_buffername);
	}

	/*virtual*/
	void unbind(int binding)
	{
		gl().bindBufferBase(GL_UNIFORM_BUFFER, binding, 0);
	}

	/*virtual*/
	void setupTest(void)
	{
		const float f[2] = { 0.25f, 0.75f };
		gl().genBuffers(1, &m_buffername);
		gl().bindBuffer(GL_UNIFORM_BUFFER, m_buffername);
		gl().bufferData(GL_UNIFORM_BUFFER, sizeof(f), f, GL_STATIC_DRAW);
	}

	/*virtual*/
	void teardownTest(void)
	{
		gl().bindBuffer(GL_UNIFORM_BUFFER, 0);
		gl().deleteBuffers(1, &m_buffername);
	}

private:
	glw::GLuint m_buffername;
};

UniformBlocksLayoutBindingCase::UniformBlocksLayoutBindingCase(Context& context, const char* name,
															   const char* description, StageType stage,
															   LayoutBindingParameters& samplerType,
															   glu::GLSLVersion			glslVersion)
	: LayoutBindingBaseCase(context, name, description, stage, samplerType, glslVersion), m_buffername(0)
{
}

UniformBlocksLayoutBindingCase::~UniformBlocksLayoutBindingCase()
{
}

//*****************************************************************************

//=========================================================================
// test case Shader storage buffer binding
//=========================================================================
class ShaderStorageBufferLayoutBindingCase : public LayoutBindingBaseCase
{
public:
	ShaderStorageBufferLayoutBindingCase(Context& context, const char* name, const char* description, StageType stage,
										 LayoutBindingParameters& samplerType, glu::GLSLVersion glslVersion);
	~ShaderStorageBufferLayoutBindingCase(void);

private:
	class ShaderStorageBufferLayoutBindingProgram : public LayoutBindingProgram
	{
	public:
		ShaderStorageBufferLayoutBindingProgram(IProgramContextSupplier& contextSupplier)
			: LayoutBindingProgram(contextSupplier)
		{
		}

		~ShaderStorageBufferLayoutBindingProgram()
		{
		}
		//*******************************************************************************
		// overwritten virtual methods
	private:
		/*virtual*/
		StringIntMap getBindingPoints(StringVector args) const
		{
			StringIntMap bindingPoints;

			for (StringVector::iterator it = args.begin(); it != args.end(); it++)
			{
				glw::GLuint idx = gl().getProgramResourceIndex(getProgram(), GL_SHADER_STORAGE_BLOCK, (*it).c_str());
				if (idx != GL_INVALID_INDEX)
				{
					glw::GLenum param = GL_BUFFER_BINDING;
					glw::GLint  value = -1;
					gl().getProgramResourceiv(getProgram(), GL_SHADER_STORAGE_BLOCK, idx, 1, &param, 1, NULL, &value);
					bool hasNoError = (GL_NO_ERROR == gl().getError());
					if (hasNoError)
					{
						bindingPoints[*it] = value;
					}
				}
			}

			return bindingPoints;
		}

		/*virtual*/
		bool setBindingPoints(StringVector list, glw::GLint bindingPoint) const
		{
			for (StringVector::iterator it = list.begin(); it != list.end(); it++)
			{
				glw::GLuint blockIndex =
					gl().getProgramResourceIndex(getProgram(), GL_SHADER_STORAGE_BLOCK, (*it).c_str());
				if (blockIndex == GL_INVALID_INDEX)
				{
					return false;
				}
				gl().shaderStorageBlockBinding(getProgram(), blockIndex, bindingPoint);
			}
			return true;
		}
	};

private:
	// IProgramContextSupplier
	/*virtual*/
	LayoutBindingProgram* createProgram()
	{
		return new ShaderStorageBufferLayoutBindingProgram(*this);
	}

private:
	/*virtual*/
	String buildLayout(const String& binding)
	{
		std::ostringstream s;
		if (!binding.empty())
			s << "layout(binding=" << binding << ", std430) ";
		else
			s << "layout(std430) ";
		return s.str();
	}

	/*virtual*/
	String getDefaultUniformName(int idx = 0)
	{
		StringStream s;

		s << "buffer" << idx;
		return s.str();
	}
	/*virtual*/
	String buildBlockName(const String& name)
	{
		return name;
	}

	/*virtual*/
	String buildBlock(const String& name, const String& type)
	{
		std::ostringstream s;
		s << "{";
		s << type << " " << name << "_a[2];\n";
		s << "}";
		return s.str();
	}

	/*virtual*/
	String buildAccess(const String& var)
	{
		std::ostringstream s;
		s << "vec4(0.0, " << var << "_a[0] + " << var << "_a[1], 0.0, 1.0)";
		return s.str();
	}

	int maxBindings()
	{
		int units = 0;
		gl().getIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &units);
		return units;
	}

	// return max. array size allowed
	int maxArraySize()
	{
		int units = 0;
		switch (getStage())
		{
		case FragmentShader:
			gl().getIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &units);
			break;
		case VertexShader:
			gl().getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &units);
			break;
		case ComputeShader:
			gl().getIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &units);
			break;
		default:
			DE_ASSERT(0);
			break;
		}
		return units;
	}

	/*virtual*/
	void bind(int binding)
	{
		gl().bindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, m_buffername);
	}

	/*virtual*/
	void unbind(int binding)
	{
		gl().bindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, 0);
	}

	/*virtual*/
	void setupTest(void)
	{
		const float f[2] = { 0.25f, 0.75f };
		gl().genBuffers(1, &m_buffername);
		gl().bindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffername);
		gl().bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(f), f, GL_STATIC_DRAW);
	}

	/*virtual*/
	void teardownTest(void)
	{
		gl().bindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
		gl().deleteBuffers(1, &m_buffername);
	}

	//=========================================================================
	// sub-tests overrides
	//=========================================================================
private:
private:
	//virtual LayoutBindingTestResult        binding_basic_default               (void);
	//virtual LayoutBindingTestResult        binding_basic_explicit              (void);
	//virtual LayoutBindingTestResult        binding_basic_multiple              (void);
	//virtual LayoutBindingTestResult        binding_basic_render                (void);
	//virtual LayoutBindingTestResult        binding_integer_constant            (void);
	//virtual LayoutBindingTestResult        binding_array_size                  (void);
	//virtual LayoutBindingTestResult        binding_array_implicit              (void);
	//virtual LayoutBindingTestResult        binding_array_multiple              (void);
	/*virtual*/
	LayoutBindingTestResult binding_api_update(void)
	{
		// only for GL
		if (getGLSLVersion() == glu::GLSL_VERSION_310_ES)
			return LayoutBindingTestResult(true, String(), true);

		return LayoutBindingBaseCase::binding_api_update();
	}
	//virtual LayoutBindingTestResult        binding_compilation_errors          (void);
	//virtual LayoutBindingTestResult        binding_link_errors                 (void);
	//virtual LayoutBindingTestResult        binding_examples                    (void);

private:
	glw::GLuint m_buffername;
};

ShaderStorageBufferLayoutBindingCase::ShaderStorageBufferLayoutBindingCase(Context& context, const char* name,
																		   const char* description, StageType stage,
																		   LayoutBindingParameters& samplerType,
																		   glu::GLSLVersion			glslVersion)
	: LayoutBindingBaseCase(context, name, description, stage, samplerType, glslVersion), m_buffername(0)
{
}

ShaderStorageBufferLayoutBindingCase::~ShaderStorageBufferLayoutBindingCase()
{
}

//*****************************************************************************

LayoutBindingTests::LayoutBindingTests(Context& context, glu::GLSLVersion glslVersion)
	: TestCaseGroup(context, "layout_binding", "Layout Binding LayoutBindingSubTest"), m_glslVersion(glslVersion)
{
}

LayoutBindingTests::~LayoutBindingTests(void)
{
}

StageType LayoutBindingTests::stageTypes[] = {
	{ "ComputeShader", ComputeShader },
	{ "FragmentShader", FragmentShader },
	{ "VertexShader", VertexShader },
};

// uniform_type must match vector_type, i.e. isampler2D=>ivec4
LayoutBindingParameters LayoutBindingTests::test_args[] = {
	{ "uniform", Texture, TwoD, "vec4", "sampler2D", "vec2", "texture" },
	{ "uniform", Texture, ThreeD, "vec4", "sampler3D", "vec3", "texture" },
	{ "uniform", Texture, TwoDArray, "vec4", "sampler2DArray", "vec3", "texture" },
	{ "uniform", Image, TwoD, "vec4", "image2D", "ivec2", "imageLoad" },
	{ "uniform", AtomicCounter, TwoD, "vec4", "atomic_uint", "vec3", "atomic" },
	{ "uniform", UniformBlock, None, "vec4", "block", "vec3", "block" },
	{ "buffer", ShaderStorageBuffer, None, "vec4", "buffer", "vec3", "atomicAdd" },
};

// create test name which must be unique or dEQP framework will throw
// example: sampler2D_layout_binding_vec4_texture_0
String LayoutBindingTests::createTestName(const StageType& stageType, const LayoutBindingParameters& testArgs)
{
	StringStream s;
	s << testArgs.uniform_type;
	s << "_layout_binding_";
	s << testArgs.access_function << "_";
	s << stageType.name;
	return s.str();
}

void LayoutBindingTests::init(void)
{
	std::vector<StageType>				 stages   = makeVector(stageTypes);
	std::vector<LayoutBindingParameters> samplers = makeVector(test_args);
	for (std::vector<StageType>::iterator stagesIter = stages.begin(); stagesIter != stages.end(); stagesIter++)
	{
		for (std::vector<LayoutBindingParameters>::iterator testArgsIter = samplers.begin();
			 testArgsIter != samplers.end(); testArgsIter++)
		{
			String testName = createTestName(*stagesIter, *testArgsIter);
			switch ((*testArgsIter).surface_type)
			{
			case Texture:
				addChild(new SamplerLayoutBindingCase(m_context, testName.c_str(),
													  "test sampler layout binding functionality", *stagesIter,
													  *testArgsIter, m_glslVersion));
				break;
			case Image:
				addChild(new ImageLayoutBindingCase(m_context, testName.c_str(),
													"test image layout binding functionality", *stagesIter,
													*testArgsIter, m_glslVersion));
				break;
			case AtomicCounter:
				addChild(new AtomicCounterLayoutBindingCase(m_context, testName.c_str(),
															"test atomic counters layout binding functionality",
															*stagesIter, *testArgsIter, m_glslVersion));
				break;
			case UniformBlock:
				addChild(new UniformBlocksLayoutBindingCase(m_context, testName.c_str(),
															"test uniform block layout binding functionality",
															*stagesIter, *testArgsIter, m_glslVersion));
				break;
			case ShaderStorageBuffer:
				addChild(new ShaderStorageBufferLayoutBindingCase(
					m_context, testName.c_str(), "test shader storage buffer layout binding functionality", *stagesIter,
					*testArgsIter, m_glslVersion));
				break;
			default:
				DE_ASSERT(0);
				break;
			}
		}
	}
}

} // glcts
