/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2014-2018 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 glcLayoutLocationTests.cpp
 * \brief
 */ /*-------------------------------------------------------------------*/
#include "glcLayoutLocationTests.hpp"

#include "tcuRenderTarget.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.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"

using namespace glw;

namespace glcts
{

static const GLuint WIDTH  = 2;
static const GLuint HEIGHT = 2;

// Helper function used to set texture parameters
void setTexParameters(const Functions& gl, GLenum target, bool depthTexture)
{
	gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	if (depthTexture)
	{
		gl.texParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
		gl.texParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
	}
}

// Helper function used to create texture data
template <typename DATA_TYPE>
std::vector<DATA_TYPE> generateData(std::size_t width, std::size_t height, std::size_t components)
{
	DE_ASSERT((components == 1) || (components == 4));
	std::size_t			   size = width * height * components;
	std::vector<DATA_TYPE> data(size, 0);
	for (std::size_t i = 0; i < size; i += components)
		data[i]		   = static_cast<DATA_TYPE>(255);
	return data;
}

// Structure used to return id of created object it had to be defined to support
// GL_TEXTURE_BUFFER cases which require creation of both texture and buffer
struct ResultData
{
	deUint32 textureId; // id of created texture
	deUint32 bufferId;  // used only by GL_TEXTURE_BUFFER

	ResultData(deUint32 tId) : textureId(tId), bufferId(0)
	{
	}

	ResultData(deUint32 tId, deUint32 bId) : textureId(tId), bufferId(bId)
	{
	}
};

template <typename DATA_TYPE>
ResultData createTexture1D(const Functions& gl, std::size_t components, GLenum internalFormat, GLenum format,
						   GLenum type)
{
	std::vector<DATA_TYPE> data = generateData<DATA_TYPE>(WIDTH, 1, components);

	deUint32 id;
	gl.genTextures(1, &id);
	gl.bindTexture(GL_TEXTURE_1D, id);
	gl.texImage1D(GL_TEXTURE_1D, 0, internalFormat, WIDTH, 0, format, type, &data[0]);
	setTexParameters(gl, GL_TEXTURE_1D, components == 1);
	return id;
}

template <typename DATA_TYPE>
ResultData createTexture2D(const Functions& gl, std::size_t components, GLenum target, GLenum internalFormat,
						   GLenum format, GLenum type)
{
	std::vector<DATA_TYPE> data = generateData<DATA_TYPE>(WIDTH, HEIGHT, components);

	deUint32 id;
	gl.genTextures(1, &id);
	gl.bindTexture(target, id);
	gl.texStorage2D(target, 1, internalFormat, WIDTH, HEIGHT);
	gl.texSubImage2D(target, 0, 0, 0, WIDTH, HEIGHT, format, type, &data[0]);
	setTexParameters(gl, target, components == 1);
	return id;
}

template <typename DATA_TYPE>
ResultData createTexture3D(const Functions& gl, std::size_t components, GLenum internalFormat, GLenum format,
						   GLenum type)
{
	std::vector<DATA_TYPE> data = generateData<DATA_TYPE>(WIDTH, HEIGHT, components);

	deUint32 id;
	gl.genTextures(1, &id);
	gl.bindTexture(GL_TEXTURE_3D, id);
	gl.texStorage3D(GL_TEXTURE_3D, 1, internalFormat, WIDTH, HEIGHT, 1);
	gl.texSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, WIDTH, HEIGHT, 1, format, type, &data[0]);
	setTexParameters(gl, GL_TEXTURE_3D, components == 1);
	return id;
}

template <typename DATA_TYPE>
ResultData createCubeMap(const Functions& gl, std::size_t components, GLenum internalFormat, GLenum format, GLenum type)
{
	std::vector<DATA_TYPE> data = generateData<DATA_TYPE>(WIDTH, HEIGHT, components);

	deUint32 id;
	gl.genTextures(1, &id);
	gl.bindTexture(GL_TEXTURE_CUBE_MAP, id);
	GLenum faces[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
					   GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
	gl.texStorage2D(GL_TEXTURE_CUBE_MAP, 1, internalFormat, WIDTH, HEIGHT);
	for (int i = 0; i < 6; ++i)
		gl.texSubImage2D(faces[i], 0, 0, 0, WIDTH, HEIGHT, format, type, &data[0]);
	setTexParameters(gl, GL_TEXTURE_CUBE_MAP, components == 1);
	return id;
}

template <typename DATA_TYPE>
ResultData createTexture2DArray(const Functions& gl, std::size_t components, GLenum internalFormat, GLenum format,
								GLenum type)
{
	std::vector<DATA_TYPE> data = generateData<DATA_TYPE>(WIDTH, HEIGHT, components);

	deUint32 id;
	gl.genTextures(1, &id);
	gl.bindTexture(GL_TEXTURE_2D_ARRAY, id);
	gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalFormat, WIDTH, HEIGHT, 1);
	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, WIDTH, HEIGHT, 1, format, type, &data[0]);
	setTexParameters(gl, GL_TEXTURE_2D_ARRAY, components == 1);
	return id;
}

template <typename DATA_TYPE>
ResultData createTextureBuffer(const Functions& gl, GLenum internalFormat)
{
	std::vector<DATA_TYPE> data = generateData<DATA_TYPE>(WIDTH, HEIGHT, 4);

	deUint32 bufferId;
	gl.genBuffers(1, &bufferId);
	gl.bindBuffer(GL_TEXTURE_BUFFER, bufferId);
	gl.bufferData(GL_TEXTURE_BUFFER, WIDTH * HEIGHT * 4 * sizeof(DATA_TYPE), &data[0], GL_STATIC_DRAW);

	deUint32 textureId;
	gl.genTextures(1, &textureId);
	gl.bindTexture(GL_TEXTURE_BUFFER, textureId);
	gl.texBuffer(GL_TEXTURE_BUFFER, internalFormat, bufferId);
	return ResultData(textureId, bufferId);
}

// create function was implemented for convinience. Specializations of this
// template simplify definition of test data by reducting the number of
// attributes which were moved to create fn implementation. This aproach
// also simplyfies texture creation in the test as create takes just a single
// parameter for all test cases.
template <GLenum, GLenum>
ResultData create(const Functions& gl)
{
	(void)gl;
	TCU_FAIL("Missing specialization implementation.");
}

template <>
ResultData create<GL_TEXTURE_2D, GL_RGBA8>(const Functions& gl)
{
	return createTexture2D<unsigned char>(gl, 4, GL_TEXTURE_2D, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
}

template <>
ResultData create<GL_TEXTURE_3D, GL_RGBA8>(const Functions& gl)
{
	return createTexture3D<unsigned char>(gl, 4, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
}

template <>
ResultData create<GL_TEXTURE_CUBE_MAP, GL_RGBA8>(const Functions& gl)
{
	return createCubeMap<unsigned char>(gl, 4, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
}

template <>
ResultData create<GL_TEXTURE_CUBE_MAP, GL_DEPTH_COMPONENT16>(const Functions& gl)
{
	return createCubeMap<short>(gl, 1, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
}

template <>
ResultData create<GL_TEXTURE_2D, GL_DEPTH_COMPONENT16>(const Functions& gl)
{
	return createTexture2D<short>(gl, 1, GL_TEXTURE_2D, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
}

template <>
ResultData create<GL_TEXTURE_2D_ARRAY, GL_RGBA8>(const Functions& gl)
{
	return createTexture2DArray<unsigned char>(gl, 4, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
}

template <>
ResultData create<GL_TEXTURE_2D_ARRAY, GL_DEPTH_COMPONENT16>(const Functions& gl)
{
	return createTexture2DArray<short>(gl, 1, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
}

template <>
ResultData create<GL_TEXTURE_2D, GL_RGBA32I>(const Functions& gl)
{
	return createTexture2D<int>(gl, 4, GL_TEXTURE_2D, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT);
}

template <>
ResultData create<GL_TEXTURE_3D, GL_RGBA32I>(const Functions& gl)
{
	return createTexture3D<int>(gl, 4, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT);
}

template <>
ResultData create<GL_TEXTURE_CUBE_MAP, GL_RGBA32I>(const Functions& gl)
{
	return createCubeMap<int>(gl, 4, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT);
}

template <>
ResultData create<GL_TEXTURE_2D_ARRAY, GL_RGBA32I>(const Functions& gl)
{
	return createTexture2DArray<int>(gl, 4, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT);
}

template <>
ResultData create<GL_TEXTURE_2D, GL_RGBA32UI>(const Functions& gl)
{
	return createTexture2D<unsigned int>(gl, 4, GL_TEXTURE_2D, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
}

template <>
ResultData create<GL_TEXTURE_3D, GL_RGBA32UI>(const Functions& gl)
{
	return createTexture3D<unsigned int>(gl, 4, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
}

template <>
ResultData create<GL_TEXTURE_CUBE_MAP, GL_RGBA32UI>(const Functions& gl)
{
	return createCubeMap<unsigned int>(gl, 4, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
}

template <>
ResultData create<GL_TEXTURE_2D_ARRAY, GL_RGBA32UI>(const Functions& gl)
{
	return createTexture2DArray<unsigned int>(gl, 4, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
}

template <>
ResultData create<GL_TEXTURE_1D, GL_RGBA8>(const Functions& gl)
{
	return createTexture1D<unsigned char>(gl, 4, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
}

template <>
ResultData create<GL_TEXTURE_1D, GL_DEPTH_COMPONENT16>(const Functions& gl)
{
	return createTexture1D<unsigned char>(gl, 1, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
}

template <>
ResultData create<GL_TEXTURE_1D_ARRAY, GL_RGBA8>(const Functions& gl)
{
	return createTexture2D<unsigned char>(gl, 4, GL_TEXTURE_1D_ARRAY, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
}

template <>
ResultData create<GL_TEXTURE_1D_ARRAY, GL_DEPTH_COMPONENT16>(const Functions& gl)
{
	return createTexture2D<short>(gl, 1, GL_TEXTURE_1D_ARRAY, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT,
								  GL_UNSIGNED_SHORT);
}

template <>
ResultData create<GL_TEXTURE_BUFFER, GL_RGBA32F>(const Functions& gl)
{
	return createTextureBuffer<float>(gl, GL_RGBA32F);
}

template <>
ResultData create<GL_TEXTURE_BUFFER, GL_RGBA32I>(const Functions& gl)
{
	return createTextureBuffer<int>(gl, GL_RGBA32I);
}

template <>
ResultData create<GL_TEXTURE_BUFFER, GL_RGBA32UI>(const Functions& gl)
{
	return createTextureBuffer<unsigned int>(gl, GL_RGBA32UI);
}

// Structure used to define all test case data
struct SamplerCaseData
{
	typedef ResultData (*CreateFnPtr)(const Functions& gl);

	CreateFnPtr	create;						// pointer to function that will create texture
	const char*	name;						// test case name
	const char*	opaqueType;					// sampler or image
	const char*	outAssignment;				// operation that determines fragment color
	const int	num_frag_image_uniforms;	// the number of required fragment image uniform
};

class SpecifiedLocationCase : public deqp::TestCase
{
public:
	SpecifiedLocationCase(deqp::Context& context, const SamplerCaseData& data);
	virtual ~SpecifiedLocationCase();

	tcu::TestNode::IterateResult iterate();

private:
	ResultData (*m_createFn)(const Functions& gl);
	std::map<std::string, std::string> m_specializationMap;

	bool		m_isImageCase;
	GLenum		m_imageFormat;
	std::string	m_imageFormatQualifier;
	int			m_num_frag_image_uniform;
};

SpecifiedLocationCase::SpecifiedLocationCase(deqp::Context& context, const SamplerCaseData& data)
	: deqp::TestCase(context, data.name, ""), m_createFn(data.create)
{
	std::string type(data.opaqueType);
	m_specializationMap["OPAQUE_TYPE"]	= type;
	m_specializationMap["OUT_ASSIGNMENT"] = data.outAssignment;

	m_isImageCase = (type.find("sampler") == std::string::npos);
	if (m_isImageCase)
	{
		m_specializationMap["OPAQUE_TYPE_NAME"] = "image";
		m_specializationMap["ACCESS"]			= "readonly";

		if (type.find("iimage") != std::string::npos)
		{
			m_imageFormatQualifier = "rgba32i";
			m_imageFormat		   = GL_RGBA32I;
		}
		else if (type.find("uimage") != std::string::npos)
		{
			m_imageFormatQualifier = "rgba32ui";
			m_imageFormat		   = GL_RGBA32UI;
		}
		else
		{
			m_imageFormatQualifier = "rgba8";
			m_imageFormat		   = GL_RGBA8;
		}
	}
	else
	{
		m_specializationMap["OPAQUE_TYPE_NAME"] = "sampler";
		m_specializationMap["ACCESS"]			= "";
	}
	m_num_frag_image_uniform = data.num_frag_image_uniforms;
}

SpecifiedLocationCase::~SpecifiedLocationCase()
{
}

tcu::TestNode::IterateResult SpecifiedLocationCase::iterate(void)
{
	static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
	static const float	positions[]   = { -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0 };

	static const char* vsTemplate = "${VERSION}\n"
									"precision highp float;\n"
									"layout(location=0) in highp vec2 inPosition;\n"
									"layout(location=0) out highp vec2 coords;\n"
									"void main(void)\n"
									"{\n"
									"  coords = vec2(max(0.0, inPosition.x), max(0.0, inPosition.y));\n"
									"  gl_Position = vec4(inPosition, 0.0, 1.0);\n"
									"}\n";

	static const char* fsTemplate =
		"${VERSION}\n"
		"precision highp float;\n"
		"layout(location=0) in vec2 coords;\n"
		"layout(location=0) out vec4 fragColor;\n"
		"layout(${OPAQUE_TYPE_QUALIFIERS}) ${ACCESS} uniform highp ${OPAQUE_TYPE} ${OPAQUE_TYPE_NAME};\n"
		"void main(void)\n"
		"{\n"
		"  fragColor = ${OUT_ASSIGNMENT};\n"
		"}\n";

	glu::RenderContext& renderContext = m_context.getRenderContext();
	glu::ContextType	contextType   = renderContext.getType();
	glu::GLSLVersion	glslVersion   = glu::getContextTypeGLSLVersion(contextType);
	const Functions&	gl			  = renderContext.getFunctions();
	bool				contextTypeES = glu::isContextTypeES(contextType);
	bool				contextES32	  = glu::contextSupports(contextType, glu::ApiType::es(3, 2));
	if (contextTypeES && !contextES32 && !m_context.getContextInfo().isExtensionSupported("GL_ANDROID_extension_pack_es31a"))
		if (m_context.getContextInfo().getInt(GL_MAX_FRAGMENT_IMAGE_UNIFORMS) < m_num_frag_image_uniform)
			throw tcu::NotSupportedError("The number of required fragment image uniform is larger than GL_MAX_FRAGMENT_IMAGE_UNIFORMS");

	const int expectedLocation = 2;
	const int definedBinding   = 1;

	std::ostringstream layoutSpecification;
	layoutSpecification << "location=" << expectedLocation;
	if (m_isImageCase)
	{
		if (contextTypeES)
			layoutSpecification << ", binding=" << definedBinding;
		layoutSpecification << ", " << m_imageFormatQualifier;
	}

	m_specializationMap["VERSION"]				  = glu::getGLSLVersionDeclaration(glslVersion);
	m_specializationMap["OPAQUE_TYPE_QUALIFIERS"] = layoutSpecification.str();

	std::string		   vs = tcu::StringTemplate(vsTemplate).specialize(m_specializationMap);
	std::string		   fs = tcu::StringTemplate(fsTemplate).specialize(m_specializationMap);
	glu::ShaderProgram program(gl, glu::makeVtxFragSources(vs.c_str(), fs.c_str()));

	m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	if (!program.isOk())
	{
		m_testCtx.getLog() << program << tcu::TestLog::Message << "Creation of program failed."
						   << tcu::TestLog::EndMessage;
		return STOP;
	}

	deUint32 programId = program.getProgram();
	int		 location  = gl.getUniformLocation(programId, m_specializationMap["OPAQUE_TYPE_NAME"].c_str());
	if (location != expectedLocation)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Expected uniform to be at location " << expectedLocation
						   << ", not at " << location << "." << tcu::TestLog::EndMessage;
		return STOP;
	}

	gl.useProgram(programId);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");

	// Prepare texture/buffer
	gl.activeTexture(GL_TEXTURE1);
	ResultData resultData = (*m_createFn)(gl);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GL object creation failed.");

	if (m_isImageCase)
	{
		gl.bindImageTexture(definedBinding, resultData.textureId, 0, GL_TRUE, 0, GL_READ_ONLY, m_imageFormat);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
	}

	// in ES image uniforms cannot be updated
	// through any of the glUniform* commands
	if (!(contextTypeES && m_isImageCase))
	{
		gl.uniform1i(expectedLocation, definedBinding);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
	}

	// Create FBO with RBO
	deUint32 rboId;
	deUint32 fboId;
	gl.genRenderbuffers(1, &rboId);
	gl.bindRenderbuffer(GL_RENDERBUFFER, rboId);
	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, WIDTH, HEIGHT);
	gl.genFramebuffers(1, &fboId);
	gl.bindFramebuffer(GL_FRAMEBUFFER, fboId);
	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboId);

	// Render
	gl.viewport(0, 0, WIDTH, HEIGHT);
	const glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("inPosition", 2, 4, 0, positions) };
	glu::draw(renderContext, programId, DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
			  glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));

	// Grab surface
	tcu::Surface resultFrame(WIDTH, HEIGHT);
	glu::readPixels(renderContext, 0, 0, resultFrame.getAccess());

	// Verify color of just first pixel
	const tcu::RGBA expectedColor(255, 0, 0, 0);
	tcu::RGBA		pixel = resultFrame.getPixel(0, 0);
	if (pixel != expectedColor)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Incorrect color was generated, expected: ["
						   << expectedColor.getRed() << ", " << expectedColor.getGreen() << ", "
						   << expectedColor.getBlue() << ", " << expectedColor.getAlpha() << "], got ["
						   << pixel.getRed() << ", " << pixel.getGreen() << ", " << pixel.getBlue() << ", "
						   << pixel.getAlpha() << "]" << tcu::TestLog::EndMessage;
	}
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	// Cleanup
	if (resultData.bufferId)
		gl.deleteBuffers(1, &resultData.bufferId);
	gl.deleteFramebuffers(1, &fboId);
	gl.deleteRenderbuffers(1, &rboId);
	gl.deleteTextures(1, &resultData.textureId);

	return STOP;
}

class NegativeLocationCase : public deqp::TestCase
{
public:
	NegativeLocationCase(deqp::Context& context);
	virtual ~NegativeLocationCase();

	tcu::TestNode::IterateResult iterate();
};

NegativeLocationCase::NegativeLocationCase(deqp::Context& context) : deqp::TestCase(context, "invalid_cases", "")
{
}

NegativeLocationCase::~NegativeLocationCase()
{
}

tcu::TestNode::IterateResult NegativeLocationCase::iterate()
{
	glu::RenderContext& renderContext = m_context.getRenderContext();
	glu::ContextType	contextType   = renderContext.getType();
	glu::GLSLVersion	glslVersion   = glu::getContextTypeGLSLVersion(contextType);
	const Functions&	gl			  = renderContext.getFunctions();

	m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	static const char* csTemplate = "${VERSION}\n"
									"layout(location=2, binding=0) uniform atomic_uint u_atomic;\n"
									"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
									"layout(binding=0) buffer Output {\n  uint value;\n} sb_out;\n\n"
									"void main (void) {\n"
									"  sb_out.value = atomicCounterIncrement(u_atomic);\n"
									"}";

	std::map<std::string, std::string> specializationMap;
	specializationMap["VERSION"] = glu::getGLSLVersionDeclaration(glslVersion);
	std::string cs				 = tcu::StringTemplate(csTemplate).specialize(specializationMap);

	m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	glu::ProgramSources sourcesCompute;
	sourcesCompute.sources[glu::SHADERTYPE_COMPUTE].push_back(cs);
	glu::ShaderProgram program(gl, sourcesCompute);
	if (program.isOk())
	{
		m_testCtx.getLog() << program << tcu::TestLog::Message
						   << "layout(location = N) is not allowed for atomic counters" << tcu::TestLog::EndMessage;
		return STOP;
	}

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	return STOP;
}

LayoutLocationTests::LayoutLocationTests(Context& context) : TestCaseGroup(context, "layout_location", "")
{
}

LayoutLocationTests::~LayoutLocationTests(void)
{
}

void LayoutLocationTests::init(void)
{
	const SamplerCaseData commonArguments[] =
	{
		{ &create<GL_TEXTURE_2D, GL_RGBA8>,						"sampler_2d",				"sampler2D",			"texture(sampler, coords)",											0 },
		{ &create<GL_TEXTURE_3D, GL_RGBA8>,						"sampler_3d",				"sampler3D",			"texture(sampler, vec3(coords, 0.0))",								0 },
		{ &create<GL_TEXTURE_CUBE_MAP, GL_RGBA8>,				"sampler_cube",				"samplerCube",			"texture(sampler, vec3(coords, 0.0))",								0 },
		{ &create<GL_TEXTURE_CUBE_MAP, GL_DEPTH_COMPONENT16>,	"sampler_cube_shadow",		"samplerCubeShadow",	"vec4(texture(sampler, vec4(coords, 0.0, 0.0)), 0.0, 0.0, 0.0)",	0 },
		{ &create<GL_TEXTURE_2D, GL_DEPTH_COMPONENT16>,			"sampler_2d_shadow",		"sampler2DShadow",		"vec4(texture(sampler, vec3(coords, 0.0)), 0.0, 0.0, 0.0)",			0 },
		{ &create<GL_TEXTURE_2D_ARRAY, GL_RGBA8>,				"sampler_2d_array",			"sampler2DArray",		"texture(sampler, vec3(coords, 0.0))",								0 },
		{ &create<GL_TEXTURE_2D_ARRAY, GL_DEPTH_COMPONENT16>,	"sampler_2d_array_shadow",	"sampler2DArrayShadow",	"vec4(texture(sampler, vec4(coords, 0.0, 0.0)), 0.0, 0.0, 0.0)",	0 },
		{ &create<GL_TEXTURE_2D, GL_RGBA32I>,					"isampler_2d",				"isampler2D",			"vec4(texture(sampler, coords))/255.0",								0 },
		{ &create<GL_TEXTURE_3D, GL_RGBA32I>,					"isampler_3d",				"isampler3D",			"vec4(texture(sampler, vec3(coords, 0.0)))/255.0",					0 },
		{ &create<GL_TEXTURE_CUBE_MAP, GL_RGBA32I>,				"isampler_cube",			"isamplerCube",			"vec4(texture(sampler, vec3(coords, 0.0)))/255.0",					0 },
		{ &create<GL_TEXTURE_2D_ARRAY, GL_RGBA32I>,				"isampler_2d_array",		"isampler2DArray",		"vec4(texture(sampler, vec3(coords, 0.0)))/255.0",					0 },
		{ &create<GL_TEXTURE_2D, GL_RGBA32UI>,					"usampler_2d",				"usampler2D",			"vec4(texture(sampler, coords))/255.0",								0 },
		{ &create<GL_TEXTURE_3D, GL_RGBA32UI>,					"usampler_3d",				"usampler3D",			"vec4(texture(sampler, vec3(coords, 0.0)))/255.0",					0 },
		{ &create<GL_TEXTURE_CUBE_MAP, GL_RGBA32UI>,			"usampler_cube",			"usamplerCube",			"vec4(texture(sampler, vec3(coords, 0.0)))/255.0",					0 },
		{ &create<GL_TEXTURE_2D_ARRAY, GL_RGBA32UI>,			"usampler_2d_array",		"usampler2DArray",		"vec4(texture(sampler, vec3(coords, 0.0)))/255.0",					0 },

		{ &create<GL_TEXTURE_2D, GL_RGBA8>,						"image_2d",					"image2D",				"imageLoad(image, ivec2(0, 0))",									1 },
		{ &create<GL_TEXTURE_2D, GL_RGBA32I>,					"iimage_2d",				"iimage2D",				"vec4(imageLoad(image, ivec2(0, 0)))/255.0",						1 },
		{ &create<GL_TEXTURE_2D, GL_RGBA32UI>,					"uimage_2d",				"uimage2D",				"vec4(imageLoad(image, ivec2(0, 0)))/255.0",						1 },
		{ &create<GL_TEXTURE_3D, GL_RGBA8>,						"image_3d",					"image3D",				"imageLoad(image, ivec3(0, 0, 0))",									1 },
		{ &create<GL_TEXTURE_3D, GL_RGBA32I>,					"iimage_3d",				"iimage3D",				"vec4(imageLoad(image, ivec3(0, 0, 0)))/255.0",						1 },
		{ &create<GL_TEXTURE_3D, GL_RGBA32UI>,					"uimage_3d",				"uimage3D",				"vec4(imageLoad(image, ivec3(0, 0, 0)))/255.0",						1 },
		{ &create<GL_TEXTURE_CUBE_MAP, GL_RGBA8>,				"image_cube",				"imageCube",			"imageLoad(image, ivec3(0, 0, 0))",									1 },
		{ &create<GL_TEXTURE_CUBE_MAP, GL_RGBA32I>,				"iimage_cube",				"iimageCube",			"vec4(imageLoad(image, ivec3(0, 0, 0)))/255.0",						1 },
		{ &create<GL_TEXTURE_CUBE_MAP, GL_RGBA32UI>,			"uimage_cube",				"uimageCube",			"vec4(imageLoad(image, ivec3(0, 0, 0)))/255.0",						1 },
		{ &create<GL_TEXTURE_2D_ARRAY, GL_RGBA8>,				"image_2d_array",			"image2DArray",			"imageLoad(image, ivec3(0, 0, 0))",									1 },
		{ &create<GL_TEXTURE_2D_ARRAY, GL_RGBA32I>,				"iimage_2d_array",			"iimage2DArray",		"vec4(imageLoad(image, ivec3(0, 0, 0)))/255.0",						1 },
		{ &create<GL_TEXTURE_2D_ARRAY, GL_RGBA32UI>,			"uimage_2d_array",			"uimage2DArray",		"vec4(imageLoad(image, ivec3(0, 0, 0)))/255.0",						1 },
	};

	// Additional array containing entries for core gl
	const SamplerCaseData coreArguments[] =
	{
		{ &create<GL_TEXTURE_BUFFER, GL_RGBA32F>,				"sampler_buffer",			"samplerBuffer",		"texelFetch(sampler, 1)",											0 },
		{ &create<GL_TEXTURE_BUFFER, GL_RGBA32I>,				"isampler_buffer",			"isamplerBuffer",		"vec4(texelFetch(sampler, 1))/255.0",								0 },
		{ &create<GL_TEXTURE_BUFFER, GL_RGBA32UI>,				"usampler_buffer",			"usamplerBuffer",		"vec4(texelFetch(sampler, 1))/255.0",								0 },
		{ &create<GL_TEXTURE_1D, GL_RGBA8>,						"sampler_1d",				"sampler1D",			"texture(sampler, coords.x)",										0 },
		{ &create<GL_TEXTURE_1D, GL_DEPTH_COMPONENT16>,			"sampler_1d_shadow",		"sampler1DShadow",		"vec4(texture(sampler, vec3(coords, 0.0)), 0.0, 0.0, 0.0)",			0 },
		{ &create<GL_TEXTURE_1D_ARRAY, GL_RGBA8>,				"sampler_1d_array",			"sampler1DArray",		"texture(sampler, coords, 0.0)",									0 },
		{ &create<GL_TEXTURE_1D_ARRAY, GL_DEPTH_COMPONENT16>,	"sampler_1d_array_shadow",	"sampler1DArrayShadow",	"vec4(texture(sampler, vec3(coords, 0.0)), 0.0, 0.0, 0.0)",			0 },
	};

	for (int i = 0; i < DE_LENGTH_OF_ARRAY(commonArguments); ++i)
		addChild(new SpecifiedLocationCase(m_context, commonArguments[i]));

	glu::RenderContext& renderContext = m_context.getRenderContext();
	glu::ContextType	contextType   = renderContext.getType();
	if (!glu::isContextTypeES(contextType))
	{
		for (int i = 0; i < DE_LENGTH_OF_ARRAY(coreArguments); ++i)
			addChild(new SpecifiedLocationCase(m_context, coreArguments[i]));
	}

	addChild(new NegativeLocationCase(m_context));
}

} // glcts
