/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Opaque type (sampler, buffer, atomic counter, ...) indexing tests.
 *
 * \todo [2014-03-05 pyry] Extend with following:
 *  + sampler: different filtering modes, multiple sizes, incomplete textures
 *  + SSBO: write, atomic op, unsized array .length()
 *//*--------------------------------------------------------------------*/

#include "es31fOpaqueTypeIndexingTests.hpp"
#include "tcuTexture.hpp"
#include "tcuTestLog.hpp"
#include "tcuFormatUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "gluShaderUtil.hpp"
#include "gluShaderProgram.hpp"
#include "gluObjectWrapper.hpp"
#include "gluTextureUtil.hpp"
#include "gluRenderContext.hpp"
#include "gluProgramInterfaceQuery.hpp"
#include "gluContextInfo.hpp"
#include "glsShaderExecUtil.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"
#include "deUniquePtr.hpp"
#include "deStringUtil.hpp"
#include "deRandom.hpp"

#include <sstream>

namespace deqp
{
namespace gles31
{
namespace Functional
{

namespace
{

using namespace gls::ShaderExecUtil;
using namespace glu;
using std::string;
using std::vector;
using tcu::TextureFormat;
using tcu::TestLog;

typedef de::UniquePtr<ShaderExecutor> ShaderExecutorPtr;

enum IndexExprType
{
	INDEX_EXPR_TYPE_CONST_LITERAL	= 0,
	INDEX_EXPR_TYPE_CONST_EXPRESSION,
	INDEX_EXPR_TYPE_UNIFORM,
	INDEX_EXPR_TYPE_DYNAMIC_UNIFORM,

	INDEX_EXPR_TYPE_LAST
};

enum TextureType
{
	TEXTURE_TYPE_1D = 0,
	TEXTURE_TYPE_2D,
	TEXTURE_TYPE_CUBE,
	TEXTURE_TYPE_2D_ARRAY,
	TEXTURE_TYPE_3D,
	TEXTURE_TYPE_CUBE_ARRAY,

	TEXTURE_TYPE_LAST
};

static void declareUniformIndexVars (std::ostream& str, const char* varPrefix, int numVars)
{
	for (int varNdx = 0; varNdx < numVars; varNdx++)
		str << "uniform highp int " << varPrefix << varNdx << ";\n";
}

static void uploadUniformIndices (const glw::Functions& gl, deUint32 program, const char* varPrefix, int numIndices, const int* indices)
{
	for (int varNdx = 0; varNdx < numIndices; varNdx++)
	{
		const string	varName		= varPrefix + de::toString(varNdx);
		const int		loc			= gl.getUniformLocation(program, varName.c_str());
		TCU_CHECK_MSG(loc >= 0, ("No location assigned for uniform '" + varName + "'").c_str());

		gl.uniform1i(loc, indices[varNdx]);
	}
}

template<typename T>
static T maxElement (const std::vector<T>& elements)
{
	T maxElem = elements[0];

	for (size_t ndx = 1; ndx < elements.size(); ndx++)
		maxElem = de::max(maxElem, elements[ndx]);

	return maxElem;
}

static TextureType getTextureType (glu::DataType samplerType)
{
	switch (samplerType)
	{
		case glu::TYPE_SAMPLER_1D:
		case glu::TYPE_INT_SAMPLER_1D:
		case glu::TYPE_UINT_SAMPLER_1D:
		case glu::TYPE_SAMPLER_1D_SHADOW:
			return TEXTURE_TYPE_1D;

		case glu::TYPE_SAMPLER_2D:
		case glu::TYPE_INT_SAMPLER_2D:
		case glu::TYPE_UINT_SAMPLER_2D:
		case glu::TYPE_SAMPLER_2D_SHADOW:
			return TEXTURE_TYPE_2D;

		case glu::TYPE_SAMPLER_CUBE:
		case glu::TYPE_INT_SAMPLER_CUBE:
		case glu::TYPE_UINT_SAMPLER_CUBE:
		case glu::TYPE_SAMPLER_CUBE_SHADOW:
			return TEXTURE_TYPE_CUBE;

		case glu::TYPE_SAMPLER_2D_ARRAY:
		case glu::TYPE_INT_SAMPLER_2D_ARRAY:
		case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
		case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
			return TEXTURE_TYPE_2D_ARRAY;

		case glu::TYPE_SAMPLER_3D:
		case glu::TYPE_INT_SAMPLER_3D:
		case glu::TYPE_UINT_SAMPLER_3D:
			return TEXTURE_TYPE_3D;

		case glu::TYPE_SAMPLER_CUBE_ARRAY:
		case glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW:
		case glu::TYPE_INT_SAMPLER_CUBE_ARRAY:
		case glu::TYPE_UINT_SAMPLER_CUBE_ARRAY:
			return TEXTURE_TYPE_CUBE_ARRAY;

		default:
			TCU_THROW(InternalError, "Invalid sampler type");
	}
}

static bool isShadowSampler (glu::DataType samplerType)
{
	return samplerType == glu::TYPE_SAMPLER_1D_SHADOW		||
		   samplerType == glu::TYPE_SAMPLER_2D_SHADOW		||
		   samplerType == glu::TYPE_SAMPLER_2D_ARRAY_SHADOW	||
		   samplerType == glu::TYPE_SAMPLER_CUBE_SHADOW		||
		   samplerType == glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW;
}

static glu::DataType getSamplerOutputType (glu::DataType samplerType)
{
	switch (samplerType)
	{
		case glu::TYPE_SAMPLER_1D:
		case glu::TYPE_SAMPLER_2D:
		case glu::TYPE_SAMPLER_CUBE:
		case glu::TYPE_SAMPLER_2D_ARRAY:
		case glu::TYPE_SAMPLER_3D:
		case glu::TYPE_SAMPLER_CUBE_ARRAY:
			return glu::TYPE_FLOAT_VEC4;

		case glu::TYPE_SAMPLER_1D_SHADOW:
		case glu::TYPE_SAMPLER_2D_SHADOW:
		case glu::TYPE_SAMPLER_CUBE_SHADOW:
		case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
		case glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW:
			return glu::TYPE_FLOAT;

		case glu::TYPE_INT_SAMPLER_1D:
		case glu::TYPE_INT_SAMPLER_2D:
		case glu::TYPE_INT_SAMPLER_CUBE:
		case glu::TYPE_INT_SAMPLER_2D_ARRAY:
		case glu::TYPE_INT_SAMPLER_3D:
		case glu::TYPE_INT_SAMPLER_CUBE_ARRAY:
			return glu::TYPE_INT_VEC4;

		case glu::TYPE_UINT_SAMPLER_1D:
		case glu::TYPE_UINT_SAMPLER_2D:
		case glu::TYPE_UINT_SAMPLER_CUBE:
		case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
		case glu::TYPE_UINT_SAMPLER_3D:
		case glu::TYPE_UINT_SAMPLER_CUBE_ARRAY:
			return glu::TYPE_UINT_VEC4;

		default:
			TCU_THROW(InternalError, "Invalid sampler type");
	}
}

static tcu::TextureFormat getSamplerTextureFormat (glu::DataType samplerType)
{
	const glu::DataType		outType			= getSamplerOutputType(samplerType);
	const glu::DataType		outScalarType	= glu::getDataTypeScalarType(outType);

	switch (outScalarType)
	{
		case glu::TYPE_FLOAT:
			if (isShadowSampler(samplerType))
				return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
			else
				return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);

		case glu::TYPE_INT:		return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT8);
		case glu::TYPE_UINT:	return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8);

		default:
			TCU_THROW(InternalError, "Invalid sampler type");
	}
}

static glu::DataType getSamplerCoordType (glu::DataType samplerType)
{
	const TextureType	texType		= getTextureType(samplerType);
	int					numCoords	= 0;

	switch (texType)
	{
		case TEXTURE_TYPE_1D:			numCoords = 1;	break;
		case TEXTURE_TYPE_2D:			numCoords = 2;	break;
		case TEXTURE_TYPE_2D_ARRAY:		numCoords = 3;	break;
		case TEXTURE_TYPE_CUBE:			numCoords = 3;	break;
		case TEXTURE_TYPE_3D:			numCoords = 3;	break;
		case TEXTURE_TYPE_CUBE_ARRAY:	numCoords = 4;	break;
		default:
			TCU_THROW(InternalError, "Invalid texture type");
	}

	if (isShadowSampler(samplerType) && samplerType != TYPE_SAMPLER_CUBE_ARRAY_SHADOW)
		numCoords += 1;

	DE_ASSERT(de::inRange(numCoords, 1, 4));

	return numCoords == 1 ? glu::TYPE_FLOAT : glu::getDataTypeFloatVec(numCoords);
}

static deUint32 getGLTextureTarget (TextureType texType)
{
	switch (texType)
	{
		case TEXTURE_TYPE_1D:			return GL_TEXTURE_1D;
		case TEXTURE_TYPE_2D:			return GL_TEXTURE_2D;
		case TEXTURE_TYPE_2D_ARRAY:		return GL_TEXTURE_2D_ARRAY;
		case TEXTURE_TYPE_CUBE:			return GL_TEXTURE_CUBE_MAP;
		case TEXTURE_TYPE_3D:			return GL_TEXTURE_3D;
		case TEXTURE_TYPE_CUBE_ARRAY:	return GL_TEXTURE_CUBE_MAP_ARRAY;
		default:
			TCU_THROW(InternalError, "Invalid texture type");
	}
}

static void setupTexture (const glw::Functions&	gl,
						  deUint32				texture,
						  glu::DataType			samplerType,
						  tcu::TextureFormat	texFormat,
						  const void*			color)
{
	const TextureType			texType		= getTextureType(samplerType);
	const deUint32				texTarget	= getGLTextureTarget(texType);
	const deUint32				intFormat	= glu::getInternalFormat(texFormat);
	const glu::TransferFormat	transferFmt	= glu::getTransferFormat(texFormat);

	// \todo [2014-03-04 pyry] Use larger than 1x1 textures?

	gl.bindTexture(texTarget, texture);

	switch (texType)
	{
		case TEXTURE_TYPE_1D:
			gl.texStorage1D(texTarget, 1, intFormat, 1);
			gl.texSubImage1D(texTarget, 0, 0, 1, transferFmt.format, transferFmt.dataType, color);
			break;

		case TEXTURE_TYPE_2D:
			gl.texStorage2D(texTarget, 1, intFormat, 1, 1);
			gl.texSubImage2D(texTarget, 0, 0, 0, 1, 1, transferFmt.format, transferFmt.dataType, color);
			break;

		case TEXTURE_TYPE_2D_ARRAY:
		case TEXTURE_TYPE_3D:
			gl.texStorage3D(texTarget, 1, intFormat, 1, 1, 1);
			gl.texSubImage3D(texTarget, 0, 0, 0, 0, 1, 1, 1, transferFmt.format, transferFmt.dataType, color);
			break;

		case TEXTURE_TYPE_CUBE_ARRAY:
			gl.texStorage3D(texTarget, 1, intFormat, 1, 1, 6);
			for (int zoffset = 0; zoffset < 6; ++zoffset)
				for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
					gl.texSubImage3D(texTarget, 0, 0, 0, zoffset, 1, 1, 1, transferFmt.format, transferFmt.dataType, color);
			break;

		case TEXTURE_TYPE_CUBE:
			gl.texStorage2D(texTarget, 1, intFormat, 1, 1);
			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
				gl.texSubImage2D(glu::getGLCubeFace((tcu::CubeFace)face), 0, 0, 0, 1, 1, transferFmt.format, transferFmt.dataType, color);
			break;

		default:
			TCU_THROW(InternalError, "Invalid texture type");
	}

	gl.texParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	if (isShadowSampler(samplerType))
		gl.texParameteri(texTarget, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);

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

class SamplerIndexingCase : public TestCase
{
public:
							SamplerIndexingCase			(Context& context, const char* name, const char* description, glu::ShaderType shaderType, glu::DataType samplerType, IndexExprType indexExprType);
							~SamplerIndexingCase		(void);

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

private:
							SamplerIndexingCase			(const SamplerIndexingCase&);
	SamplerIndexingCase&	operator=					(const SamplerIndexingCase&);

	void					getShaderSpec				(ShaderSpec* spec, int numSamplers, int numLookups, const int* lookupIndices, const RenderContext& renderContext) const;

	const glu::ShaderType	m_shaderType;
	const glu::DataType		m_samplerType;
	const IndexExprType		m_indexExprType;
};

SamplerIndexingCase::SamplerIndexingCase (Context& context, const char* name, const char* description, glu::ShaderType shaderType, glu::DataType samplerType, IndexExprType indexExprType)
	: TestCase			(context, name, description)
	, m_shaderType		(shaderType)
	, m_samplerType		(samplerType)
	, m_indexExprType	(indexExprType)
{
}

SamplerIndexingCase::~SamplerIndexingCase (void)
{
}

void SamplerIndexingCase::init (void)
{
	const bool			supportsES32	= contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
											hasExtension(m_context.getRenderContext().getFunctions(), glu::ApiType::core(4, 5), "GL_ARB_ES3_2_compatibility");

	if (!supportsES32)
	{
		if (m_shaderType == SHADERTYPE_GEOMETRY)
			TCU_CHECK_AND_THROW(NotSupportedError,
				m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"),
				"GL_EXT_geometry_shader extension is required to run geometry shader tests.");

		if (m_shaderType == SHADERTYPE_TESSELLATION_CONTROL || m_shaderType == SHADERTYPE_TESSELLATION_EVALUATION)
			TCU_CHECK_AND_THROW(NotSupportedError,
				m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"),
				"GL_EXT_tessellation_shader extension is required to run tessellation shader tests.");

		if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
			TCU_CHECK_AND_THROW(NotSupportedError,
				m_context.getContextInfo().isExtensionSupported("GL_EXT_gpu_shader5"),
				"GL_EXT_gpu_shader5 extension is required for dynamic indexing of sampler arrays.");

		if (m_samplerType == TYPE_SAMPLER_CUBE_ARRAY
			|| m_samplerType == TYPE_SAMPLER_CUBE_ARRAY_SHADOW
			|| m_samplerType == TYPE_INT_SAMPLER_CUBE_ARRAY
			|| m_samplerType == TYPE_UINT_SAMPLER_CUBE_ARRAY)
		{
			TCU_CHECK_AND_THROW(NotSupportedError,
				m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_cube_map_array"),
				"GL_EXT_texture_cube_map_array extension is required for cube map arrays.");
		}
	}
}

void SamplerIndexingCase::getShaderSpec (ShaderSpec* spec, int numSamplers, int numLookups, const int* lookupIndices, const RenderContext& renderContext) const
{
	const char*			samplersName	= "sampler";
	const char*			coordsName		= "coords";
	const char*			indicesPrefix	= "index";
	const char*			resultPrefix	= "result";
	const DataType		coordType		= getSamplerCoordType(m_samplerType);
	const DataType		outType			= getSamplerOutputType(m_samplerType);
	const bool			supportsES32	= contextSupports(renderContext.getType(), glu::ApiType::es(3, 2)) ||
											hasExtension(renderContext.getFunctions(), glu::ApiType::core(4, 5), "GL_ARB_ES3_2_compatibility");
	std::ostringstream	global;
	std::ostringstream	code;

	spec->inputs.push_back(Symbol(coordsName, VarType(coordType, PRECISION_HIGHP)));

	if (!supportsES32 && m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
		global << "#extension GL_EXT_gpu_shader5 : require\n";

	if (!supportsES32
		&& (m_samplerType == TYPE_SAMPLER_CUBE_ARRAY
			|| m_samplerType == TYPE_SAMPLER_CUBE_ARRAY_SHADOW
			|| m_samplerType == TYPE_INT_SAMPLER_CUBE_ARRAY
			|| m_samplerType == TYPE_UINT_SAMPLER_CUBE_ARRAY))
	{
		global << "#extension GL_EXT_texture_cube_map_array: require\n";
	}

	if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
		global << "const highp int indexBase = 1;\n";

	global <<
		"uniform highp " << getDataTypeName(m_samplerType) << " " << samplersName << "[" << numSamplers << "];\n";

	if (m_indexExprType == INDEX_EXPR_TYPE_DYNAMIC_UNIFORM)
	{
		for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
		{
			const string varName = indicesPrefix + de::toString(lookupNdx);
			spec->inputs.push_back(Symbol(varName, VarType(TYPE_INT, PRECISION_HIGHP)));
		}
	}
	else if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
		declareUniformIndexVars(global, indicesPrefix, numLookups);

	for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
	{
		const string varName = resultPrefix + de::toString(lookupNdx);
		spec->outputs.push_back(Symbol(varName, VarType(outType, PRECISION_HIGHP)));
	}

	for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
	{
		code << resultPrefix << "" << lookupNdx << " = texture(" << samplersName << "[";

		if (m_indexExprType == INDEX_EXPR_TYPE_CONST_LITERAL)
			code << lookupIndices[lookupNdx];
		else if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
			code << "indexBase + " << (lookupIndices[lookupNdx]-1);
		else
			code << indicesPrefix << lookupNdx;


		code << "], " << coordsName << (m_samplerType == TYPE_SAMPLER_CUBE_ARRAY_SHADOW ? ", 0.0" : "") << ");\n";
	}

	spec->version				= supportsES32 ? GLSL_VERSION_320_ES : GLSL_VERSION_310_ES;
	spec->globalDeclarations	= global.str();
	spec->source				= code.str();
}

static void fillTextureData (const tcu::PixelBufferAccess& access, de::Random& rnd)
{
	DE_ASSERT(access.getHeight() == 1 && access.getDepth() == 1);

	if (access.getFormat().order == TextureFormat::D)
	{
		// \note Texture uses odd values, lookup even values to avoid precision issues.
		const float values[] = { 0.1f, 0.3f, 0.5f, 0.7f, 0.9f };

		for (int ndx = 0; ndx < access.getWidth(); ndx++)
			access.setPixDepth(rnd.choose<float>(DE_ARRAY_BEGIN(values), DE_ARRAY_END(values)), ndx, 0);
	}
	else
	{
		TCU_CHECK_INTERNAL(access.getFormat().order == TextureFormat::RGBA && access.getFormat().getPixelSize() == 4);

		for (int ndx = 0; ndx < access.getWidth(); ndx++)
			*((deUint32*)access.getDataPtr() + ndx) = rnd.getUint32();
	}
}

SamplerIndexingCase::IterateResult SamplerIndexingCase::iterate (void)
{
	const int						numInvocations		= 64;
	const int						numSamplers			= 8;
	const int						numLookups			= 4;
	const DataType					coordType			= getSamplerCoordType(m_samplerType);
	const DataType					outputType			= getSamplerOutputType(m_samplerType);
	const TextureFormat				texFormat			= getSamplerTextureFormat(m_samplerType);
	const int						outLookupStride		= numInvocations*getDataTypeScalarSize(outputType);
	vector<int>						lookupIndices		(numLookups);
	vector<float>					coords;
	vector<deUint32>				outData;
	vector<deUint8>					texData				(numSamplers * texFormat.getPixelSize());
	const tcu::PixelBufferAccess	refTexAccess		(texFormat, numSamplers, 1, 1, &texData[0]);

	ShaderSpec						shaderSpec;
	de::Random						rnd					(deInt32Hash(m_samplerType) ^ deInt32Hash(m_shaderType) ^ deInt32Hash(m_indexExprType));

	for (int ndx = 0; ndx < numLookups; ndx++)
		lookupIndices[ndx] = rnd.getInt(0, numSamplers-1);

	getShaderSpec(&shaderSpec, numSamplers, numLookups, &lookupIndices[0], m_context.getRenderContext());

	coords.resize(numInvocations * getDataTypeScalarSize(coordType));

	if (m_samplerType != TYPE_SAMPLER_CUBE_ARRAY_SHADOW && isShadowSampler(m_samplerType))
	{
		// Use different comparison value per invocation.
		// \note Texture uses odd values, comparison even values.
		const int	numCoordComps	= getDataTypeScalarSize(coordType);
		const float	cmpValues[]		= { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f };

		for (int invocationNdx = 0; invocationNdx < numInvocations; invocationNdx++)
			coords[invocationNdx*numCoordComps + (numCoordComps-1)] = rnd.choose<float>(DE_ARRAY_BEGIN(cmpValues), DE_ARRAY_END(cmpValues));
	}

	fillTextureData(refTexAccess, rnd);

	outData.resize(numLookups*outLookupStride);

	{
		const RenderContext&	renderCtx		= m_context.getRenderContext();
		const glw::Functions&	gl				= renderCtx.getFunctions();
		ShaderExecutorPtr		executor		(createExecutor(m_context.getRenderContext(), m_shaderType, shaderSpec));
		TextureVector			textures		(renderCtx, numSamplers);
		vector<void*>			inputs;
		vector<void*>			outputs;
		vector<int>				expandedIndices;
		const int				maxIndex		= maxElement(lookupIndices);

		m_testCtx.getLog() << *executor;

		if (!executor->isOk())
			TCU_FAIL("Compile failed");

		executor->useProgram();

		// \todo [2014-03-05 pyry] Do we want to randomize tex unit assignments?
		for (int samplerNdx = 0; samplerNdx < numSamplers; samplerNdx++)
		{
			const string	samplerName	= string("sampler[") + de::toString(samplerNdx) + "]";
			const int		samplerLoc	= gl.getUniformLocation(executor->getProgram(), samplerName.c_str());

			if (samplerNdx > maxIndex && samplerLoc < 0)
				continue; // Unused uniform eliminated by compiler

			TCU_CHECK_MSG(samplerLoc >= 0, (string("No location for uniform '") + samplerName + "' found").c_str());

			gl.activeTexture(GL_TEXTURE0 + samplerNdx);
			setupTexture(gl, textures[samplerNdx], m_samplerType, texFormat, &texData[samplerNdx*texFormat.getPixelSize()]);

			gl.uniform1i(samplerLoc, samplerNdx);
		}

		inputs.push_back(&coords[0]);

		if (m_indexExprType == INDEX_EXPR_TYPE_DYNAMIC_UNIFORM)
		{
			expandedIndices.resize(numInvocations * lookupIndices.size());
			for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
			{
				for (int invNdx = 0; invNdx < numInvocations; invNdx++)
					expandedIndices[lookupNdx*numInvocations + invNdx] = lookupIndices[lookupNdx];
			}

			for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
				inputs.push_back(&expandedIndices[lookupNdx*numInvocations]);
		}
		else if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
			uploadUniformIndices(gl, executor->getProgram(), "index", numLookups, &lookupIndices[0]);

		for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
			outputs.push_back(&outData[outLookupStride*lookupNdx]);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Setup failed");

		executor->execute(numInvocations, &inputs[0], &outputs[0]);
	}

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	if (isShadowSampler(m_samplerType))
	{
		const tcu::Sampler	refSampler		(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
											 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST, 0.0f, false /* non-normalized */,
											 tcu::Sampler::COMPAREMODE_LESS);
		const int			numCoordComps	= getDataTypeScalarSize(coordType);

		TCU_CHECK_INTERNAL(getDataTypeScalarSize(outputType) == 1);

		// Each invocation may have different results.
		for (int invocationNdx = 0; invocationNdx < numInvocations; invocationNdx++)
		{
			const float	coord	= coords[invocationNdx*numCoordComps + (numCoordComps-1)];

			for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
			{
				const int		texNdx		= lookupIndices[lookupNdx];
				const float		result		= *((const float*)(const deUint8*)&outData[lookupNdx*outLookupStride + invocationNdx]);
				const float		reference	= refTexAccess.sample2DCompare(refSampler, tcu::Sampler::NEAREST, coord, (float)texNdx, 0.0f, tcu::IVec3(0));

				if (de::abs(result-reference) > 0.005f)
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: at invocation " << invocationNdx << ", lookup " << lookupNdx << ": expected "
														   << reference << ", got " << result
									   << TestLog::EndMessage;

					if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
						m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid lookup result");
				}
			}
		}
	}
	else
	{
		TCU_CHECK_INTERNAL(getDataTypeScalarSize(outputType) == 4);

		// Validate results from first invocation
		for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
		{
			const int		texNdx	= lookupIndices[lookupNdx];
			const deUint8*	resPtr	= (const deUint8*)&outData[lookupNdx*outLookupStride];
			bool			isOk;

			if (outputType == TYPE_FLOAT_VEC4)
			{
				const float			threshold		= 1.0f / 256.0f;
				const tcu::Vec4		reference		= refTexAccess.getPixel(texNdx, 0);
				const float*		floatPtr		= (const float*)resPtr;
				const tcu::Vec4		result			(floatPtr[0], floatPtr[1], floatPtr[2], floatPtr[3]);

				isOk = boolAll(lessThanEqual(abs(reference-result), tcu::Vec4(threshold)));

				if (!isOk)
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: at lookup " << lookupNdx << ": expected "
														   << reference << ", got " << result
									   << TestLog::EndMessage;
				}
			}
			else
			{
				const tcu::UVec4	reference		= refTexAccess.getPixelUint(texNdx, 0);
				const deUint32*		uintPtr			= (const deUint32*)resPtr;
				const tcu::UVec4	result			(uintPtr[0], uintPtr[1], uintPtr[2], uintPtr[3]);

				isOk = boolAll(equal(reference, result));

				if (!isOk)
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: at lookup " << lookupNdx << ": expected "
														   << reference << ", got " << result
									   << TestLog::EndMessage;
				}
			}

			if (!isOk && m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid lookup result");
		}

		// Check results of other invocations against first one
		for (int invocationNdx = 1; invocationNdx < numInvocations; invocationNdx++)
		{
			for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
			{
				const deUint32*		refPtr		= &outData[lookupNdx*outLookupStride];
				const deUint32*		resPtr		= refPtr + invocationNdx*4;
				bool				isOk		= true;

				for (int ndx = 0; ndx < 4; ndx++)
					isOk = isOk && (refPtr[ndx] == resPtr[ndx]);

				if (!isOk)
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: invocation " << invocationNdx << " result "
														   << tcu::formatArray(tcu::Format::HexIterator<deUint32>(resPtr), tcu::Format::HexIterator<deUint32>(resPtr+4))
														   << " for lookup " << lookupNdx << " doesn't match result from first invocation "
														   << tcu::formatArray(tcu::Format::HexIterator<deUint32>(refPtr), tcu::Format::HexIterator<deUint32>(refPtr+4))
									   << TestLog::EndMessage;

					if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
						m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Inconsistent lookup results");
				}
			}
		}
	}

	return STOP;
}

class BlockArrayIndexingCase : public TestCase
{
public:
	enum BlockType
	{
		BLOCKTYPE_UNIFORM = 0,
		BLOCKTYPE_BUFFER,

		BLOCKTYPE_LAST
	};
								BlockArrayIndexingCase		(Context& context, const char* name, const char* description, BlockType blockType, IndexExprType indexExprType, ShaderType shaderType);
								~BlockArrayIndexingCase		(void);

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

private:
								BlockArrayIndexingCase		(const BlockArrayIndexingCase&);
	BlockArrayIndexingCase&		operator=					(const BlockArrayIndexingCase&);

	void						getShaderSpec				(ShaderSpec* spec, int numInstances, int numReads, const int* readIndices, const RenderContext& renderContext) const;

	const BlockType				m_blockType;
	const IndexExprType			m_indexExprType;
	const ShaderType			m_shaderType;

	const int					m_numInstances;
};

BlockArrayIndexingCase::BlockArrayIndexingCase (Context& context, const char* name, const char* description, BlockType blockType, IndexExprType indexExprType, ShaderType shaderType)
	: TestCase			(context, name, description)
	, m_blockType		(blockType)
	, m_indexExprType	(indexExprType)
	, m_shaderType		(shaderType)
	, m_numInstances	(4)
{
}

BlockArrayIndexingCase::~BlockArrayIndexingCase (void)
{
}

void BlockArrayIndexingCase::init (void)
{
	const bool			supportsES32	= contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
											hasExtension(m_context.getRenderContext().getFunctions(), glu::ApiType::core(4, 5), "GL_ARB_ES3_2_compatibility");

	if (!supportsES32)
	{
		if (m_shaderType == SHADERTYPE_GEOMETRY)
			TCU_CHECK_AND_THROW(NotSupportedError,
				m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"),
				"GL_EXT_geometry_shader extension is required to run geometry shader tests.");

		if (m_shaderType == SHADERTYPE_TESSELLATION_CONTROL || m_shaderType == SHADERTYPE_TESSELLATION_EVALUATION)
			TCU_CHECK_AND_THROW(NotSupportedError,
				m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"),
				"GL_EXT_tessellation_shader extension is required to run tessellation shader tests.");

		if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
			TCU_CHECK_AND_THROW(NotSupportedError,
				m_context.getContextInfo().isExtensionSupported("GL_EXT_gpu_shader5"),
				"GL_EXT_gpu_shader5 extension is required for dynamic indexing of interface blocks.");
	}

	if (m_blockType == BLOCKTYPE_BUFFER)
	{
		const deUint32 limitPnames[] =
		{
			GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS,
			GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS,
			GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS,
			GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS,
			GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS,
			GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS
		};

		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		int						maxBlocks	= 0;

		gl.getIntegerv(limitPnames[m_shaderType], &maxBlocks);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");

		if (maxBlocks < 2 + m_numInstances)
			throw tcu::NotSupportedError("Not enough shader storage blocks supported for shader type");
	}
}

void BlockArrayIndexingCase::getShaderSpec (ShaderSpec* spec, int numInstances, int numReads, const int* readIndices, const RenderContext& renderContext) const
{
	const int			binding			= 2;
	const char*			blockName		= "Block";
	const char*			instanceName	= "block";
	const char*			indicesPrefix	= "index";
	const char*			resultPrefix	= "result";
	const char*			interfaceName	= m_blockType == BLOCKTYPE_UNIFORM ? "uniform" : "buffer";
	const char*			layout			= m_blockType == BLOCKTYPE_UNIFORM ? "std140" : "std430";
	const bool			supportsES32	= contextSupports(renderContext.getType(), glu::ApiType::es(3, 2)) ||
							hasExtension(renderContext.getFunctions(), glu::ApiType::core(4, 5), "GL_ARB_ES3_2_compatibility");
	std::ostringstream	global;
	std::ostringstream	code;

	if (!supportsES32 && m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
		global << "#extension GL_EXT_gpu_shader5 : require\n";

	if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
		global << "const highp int indexBase = 1;\n";

	global <<
		"layout(" << layout << ", binding = " << binding << ") " << interfaceName << " " << blockName << "\n"
		"{\n"
		"	uint value;\n"
		"} " << instanceName << "[" << numInstances << "];\n";

	if (m_indexExprType == INDEX_EXPR_TYPE_DYNAMIC_UNIFORM)
	{
		for (int readNdx = 0; readNdx < numReads; readNdx++)
		{
			const string varName = indicesPrefix + de::toString(readNdx);
			spec->inputs.push_back(Symbol(varName, VarType(TYPE_INT, PRECISION_HIGHP)));
		}
	}
	else if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
		declareUniformIndexVars(global, indicesPrefix, numReads);

	for (int readNdx = 0; readNdx < numReads; readNdx++)
	{
		const string varName = resultPrefix + de::toString(readNdx);
		spec->outputs.push_back(Symbol(varName, VarType(TYPE_UINT, PRECISION_HIGHP)));
	}

	for (int readNdx = 0; readNdx < numReads; readNdx++)
	{
		code << resultPrefix << readNdx << " = " << instanceName << "[";

		if (m_indexExprType == INDEX_EXPR_TYPE_CONST_LITERAL)
			code << readIndices[readNdx];
		else if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
			code << "indexBase + " << (readIndices[readNdx]-1);
		else
			code << indicesPrefix << readNdx;

		code << "].value;\n";
	}

	spec->version				= supportsES32 ? GLSL_VERSION_320_ES : GLSL_VERSION_310_ES;
	spec->globalDeclarations	= global.str();
	spec->source				= code.str();
}

BlockArrayIndexingCase::IterateResult BlockArrayIndexingCase::iterate (void)
{
	const int			numInvocations		= 32;
	const int			numInstances		= m_numInstances;
	const int			numReads			= 4;
	vector<int>			readIndices			(numReads);
	vector<deUint32>	inValues			(numInstances);
	vector<deUint32>	outValues			(numInvocations*numReads);
	ShaderSpec			shaderSpec;
	de::Random			rnd					(deInt32Hash(m_shaderType) ^ deInt32Hash(m_blockType) ^ deInt32Hash(m_indexExprType));

	for (int readNdx = 0; readNdx < numReads; readNdx++)
		readIndices[readNdx] = rnd.getInt(0, numInstances-1);

	for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
		inValues[instanceNdx] = rnd.getUint32();

	getShaderSpec(&shaderSpec, numInstances, numReads, &readIndices[0], m_context.getRenderContext());

	{
		const RenderContext&	renderCtx		= m_context.getRenderContext();
		const glw::Functions&	gl				= renderCtx.getFunctions();
		const int				baseBinding		= 2;
		const BufferVector		buffers			(renderCtx, numInstances);
		const deUint32			bufTarget		= m_blockType == BLOCKTYPE_BUFFER ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER;
		ShaderExecutorPtr		shaderExecutor	(createExecutor(renderCtx, m_shaderType, shaderSpec));
		vector<int>				expandedIndices;
		vector<void*>			inputs;
		vector<void*>			outputs;

		m_testCtx.getLog() << *shaderExecutor;

		if (!shaderExecutor->isOk())
			TCU_FAIL("Compile failed");

		shaderExecutor->useProgram();

		for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
		{
			gl.bindBuffer(bufTarget, buffers[instanceNdx]);
			gl.bufferData(bufTarget, (glw::GLsizeiptr)sizeof(deUint32), &inValues[instanceNdx], GL_STATIC_DRAW);
			gl.bindBufferBase(bufTarget, baseBinding+instanceNdx, buffers[instanceNdx]);
		}

		if (m_indexExprType == INDEX_EXPR_TYPE_DYNAMIC_UNIFORM)
		{
			expandedIndices.resize(numInvocations * readIndices.size());

			for (int readNdx = 0; readNdx < numReads; readNdx++)
			{
				int* dst = &expandedIndices[numInvocations*readNdx];
				std::fill(dst, dst+numInvocations, readIndices[readNdx]);
			}

			for (int readNdx = 0; readNdx < numReads; readNdx++)
				inputs.push_back(&expandedIndices[readNdx*numInvocations]);
		}
		else if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
			uploadUniformIndices(gl, shaderExecutor->getProgram(), "index", numReads, &readIndices[0]);

		for (int readNdx = 0; readNdx < numReads; readNdx++)
			outputs.push_back(&outValues[readNdx*numInvocations]);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Setup failed");

		shaderExecutor->execute(numInvocations, inputs.empty() ? DE_NULL : &inputs[0], &outputs[0]);
	}

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	for (int invocationNdx = 0; invocationNdx < numInvocations; invocationNdx++)
	{
		for (int readNdx = 0; readNdx < numReads; readNdx++)
		{
			const deUint32	refValue	= inValues[readIndices[readNdx]];
			const deUint32	resValue	= outValues[readNdx*numInvocations + invocationNdx];

			if (refValue != resValue)
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: at invocation " << invocationNdx
													   << ", read " << readNdx << ": expected "
													   << tcu::toHex(refValue) << ", got " << tcu::toHex(resValue)
								   << TestLog::EndMessage;

				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid result value");
			}
		}
	}

	return STOP;
}

class AtomicCounterIndexingCase : public TestCase
{
public:
								AtomicCounterIndexingCase		(Context& context, const char* name, const char* description, IndexExprType indexExprType, ShaderType shaderType);
								~AtomicCounterIndexingCase		(void);

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

private:
								AtomicCounterIndexingCase		(const AtomicCounterIndexingCase&);
	AtomicCounterIndexingCase&	operator=						(const AtomicCounterIndexingCase&);

	void						getShaderSpec					(ShaderSpec* spec, int numCounters, int numOps, const int* opIndices, const RenderContext& renderContext) const;

	const IndexExprType			m_indexExprType;
	const glu::ShaderType		m_shaderType;
	deInt32						m_numCounters;
};

AtomicCounterIndexingCase::AtomicCounterIndexingCase (Context& context, const char* name, const char* description, IndexExprType indexExprType, ShaderType shaderType)
	: TestCase			(context, name, description)
	, m_indexExprType	(indexExprType)
	, m_shaderType		(shaderType)
	, m_numCounters		(0)
{
}

AtomicCounterIndexingCase::~AtomicCounterIndexingCase (void)
{
}

deUint32 getMaxAtomicCounterEnum (glu::ShaderType type)
{
	switch (type)
	{
		case glu::SHADERTYPE_VERTEX:					return GL_MAX_VERTEX_ATOMIC_COUNTERS;
		case glu::SHADERTYPE_FRAGMENT:					return GL_MAX_FRAGMENT_ATOMIC_COUNTERS;
		case glu::SHADERTYPE_GEOMETRY:					return GL_MAX_GEOMETRY_ATOMIC_COUNTERS;
		case glu::SHADERTYPE_COMPUTE:					return GL_MAX_COMPUTE_ATOMIC_COUNTERS;
		case glu::SHADERTYPE_TESSELLATION_CONTROL:		return GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS;
		case glu::SHADERTYPE_TESSELLATION_EVALUATION:	return GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS;

		default:
			DE_FATAL("Unknown shader type");
			return -1;
	}
}

void AtomicCounterIndexingCase::init (void)
{
	const bool			supportsES32	= contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
											hasExtension(m_context.getRenderContext().getFunctions(), glu::ApiType::core(4, 5), "GL_ARB_ES3_2_compatibility");

	if (!supportsES32)
	{
		if (m_shaderType == SHADERTYPE_GEOMETRY)
			TCU_CHECK_AND_THROW(NotSupportedError,
				m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"),
				"GL_EXT_geometry_shader extension is required to run geometry shader tests.");

		if (m_shaderType == SHADERTYPE_TESSELLATION_CONTROL || m_shaderType == SHADERTYPE_TESSELLATION_EVALUATION)
			TCU_CHECK_AND_THROW(NotSupportedError,
				m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"),
				"GL_EXT_tessellation_shader extension is required to run tessellation shader tests.");

		if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
			TCU_CHECK_AND_THROW(NotSupportedError,
				m_context.getContextInfo().isExtensionSupported("GL_EXT_gpu_shader5"),
				"GL_EXT_gpu_shader5 extension is required for dynamic indexing of atomic counters.");
	}

	{
		m_context.getRenderContext().getFunctions().getIntegerv(getMaxAtomicCounterEnum(m_shaderType),
																&m_numCounters);

		if (m_numCounters < 1)
		{
			const string message =  "Atomic counters not supported in " + string(glu::getShaderTypeName(m_shaderType)) + " shader";
			TCU_THROW(NotSupportedError, message.c_str());
		}
	}
}

void AtomicCounterIndexingCase::getShaderSpec (ShaderSpec* spec, int numCounters, int numOps, const int* opIndices, const RenderContext& renderContext) const
{
	const char*			indicesPrefix	= "index";
	const char*			resultPrefix	= "result";
	const bool			supportsES32	= contextSupports(renderContext.getType(), glu::ApiType::es(3, 2)) ||
											hasExtension(renderContext.getFunctions(), glu::ApiType::core(4, 5), "GL_ARB_ES3_2_compatibility");
	std::ostringstream	global;
	std::ostringstream	code;

	if (!supportsES32 && m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
		global << "#extension GL_EXT_gpu_shader5 : require\n";

	if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
		global << "const highp int indexBase = 1;\n";

	global <<
		"layout(binding = 0) uniform atomic_uint counter[" << numCounters << "];\n";

	if (m_indexExprType == INDEX_EXPR_TYPE_DYNAMIC_UNIFORM)
	{
		for (int opNdx = 0; opNdx < numOps; opNdx++)
		{
			const string varName = indicesPrefix + de::toString(opNdx);
			spec->inputs.push_back(Symbol(varName, VarType(TYPE_INT, PRECISION_HIGHP)));
		}
	}
	else if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
		declareUniformIndexVars(global, indicesPrefix, numOps);

	for (int opNdx = 0; opNdx < numOps; opNdx++)
	{
		const string varName = resultPrefix + de::toString(opNdx);
		spec->outputs.push_back(Symbol(varName, VarType(TYPE_UINT, PRECISION_HIGHP)));
	}

	for (int opNdx = 0; opNdx < numOps; opNdx++)
	{
		code << resultPrefix << opNdx << " = atomicCounterIncrement(counter[";

		if (m_indexExprType == INDEX_EXPR_TYPE_CONST_LITERAL)
			code << opIndices[opNdx];
		else if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
			code << "indexBase + " << (opIndices[opNdx]-1);
		else
			code << indicesPrefix << opNdx;

		code << "]);\n";
	}

	spec->version				= supportsES32 ? GLSL_VERSION_320_ES : GLSL_VERSION_310_ES;
	spec->globalDeclarations	= global.str();
	spec->source				= code.str();
}

AtomicCounterIndexingCase::IterateResult AtomicCounterIndexingCase::iterate (void)
{
	const RenderContext&	renderCtx			= m_context.getRenderContext();
	const glw::Functions&	gl					= renderCtx.getFunctions();
	const Buffer			counterBuffer		(renderCtx);

	const int				numInvocations		= 32;
	const int				numOps				= 4;
	vector<int>				opIndices			(numOps);
	vector<deUint32>		outValues			(numInvocations*numOps);
	ShaderSpec				shaderSpec;
	de::Random				rnd					(deInt32Hash(m_shaderType) ^ deInt32Hash(m_indexExprType));

	for (int opNdx = 0; opNdx < numOps; opNdx++)
		opIndices[opNdx] = rnd.getInt(0, numOps-1);

	getShaderSpec(&shaderSpec, m_numCounters, numOps, &opIndices[0], m_context.getRenderContext());

	{
		const BufferVector		buffers			(renderCtx, m_numCounters);
		ShaderExecutorPtr		shaderExecutor	(createExecutor(renderCtx, m_shaderType, shaderSpec));
		vector<int>				expandedIndices;
		vector<void*>			inputs;
		vector<void*>			outputs;

		m_testCtx.getLog() << *shaderExecutor;

		if (!shaderExecutor->isOk())
			TCU_FAIL("Compile failed");

		{
			const int				bufSize		= getProgramResourceInt(gl, shaderExecutor->getProgram(), GL_ATOMIC_COUNTER_BUFFER, 0, GL_BUFFER_DATA_SIZE);
			const int				maxNdx		= maxElement(opIndices);
			std::vector<deUint8>	emptyData	(m_numCounters*4, 0);

			if (bufSize < (maxNdx+1)*4)
				TCU_FAIL((string("GL reported invalid buffer size " + de::toString(bufSize)).c_str()));

			gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, *counterBuffer);
			gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, (glw::GLsizeiptr)emptyData.size(), &emptyData[0], GL_STATIC_DRAW);
			gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, *counterBuffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Atomic counter buffer initialization failed");
		}

		shaderExecutor->useProgram();

		if (m_indexExprType == INDEX_EXPR_TYPE_DYNAMIC_UNIFORM)
		{
			expandedIndices.resize(numInvocations * opIndices.size());

			for (int opNdx = 0; opNdx < numOps; opNdx++)
			{
				int* dst = &expandedIndices[numInvocations*opNdx];
				std::fill(dst, dst+numInvocations, opIndices[opNdx]);
			}

			for (int opNdx = 0; opNdx < numOps; opNdx++)
				inputs.push_back(&expandedIndices[opNdx*numInvocations]);
		}
		else if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
			uploadUniformIndices(gl, shaderExecutor->getProgram(), "index", numOps, &opIndices[0]);

		for (int opNdx = 0; opNdx < numOps; opNdx++)
			outputs.push_back(&outValues[opNdx*numInvocations]);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Setup failed");

		shaderExecutor->execute(numInvocations, inputs.empty() ? DE_NULL : &inputs[0], &outputs[0]);
	}

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	{
		vector<int>				numHits			(m_numCounters, 0);	// Number of hits per counter.
		vector<deUint32>		counterValues	(m_numCounters);
		vector<vector<bool> >	counterMasks	(m_numCounters);

		for (int opNdx = 0; opNdx < numOps; opNdx++)
			numHits[opIndices[opNdx]] += 1;

		// Read counter values
		{
			const void* mapPtr = DE_NULL;

			try
			{
				mapPtr = gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, m_numCounters*4, GL_MAP_READ_BIT);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER)");
				TCU_CHECK(mapPtr);
				std::copy((const deUint32*)mapPtr, (const deUint32*)mapPtr + m_numCounters, &counterValues[0]);
				gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
			}
			catch (...)
			{
				if (mapPtr)
					gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
				throw;
			}
		}

		// Verify counter values
		for (int counterNdx = 0; counterNdx < m_numCounters; counterNdx++)
		{
			const deUint32		refCount	= (deUint32)(numHits[counterNdx]*numInvocations);
			const deUint32		resCount	= counterValues[counterNdx];

			if (refCount != resCount)
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: atomic counter " << counterNdx << " has value " << resCount
													   << ", expected " << refCount
								   << TestLog::EndMessage;

				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid atomic counter value");
			}
		}

		// Allocate bitmasks - one bit per each valid result value
		for (int counterNdx = 0; counterNdx < m_numCounters; counterNdx++)
		{
			const int	counterValue	= numHits[counterNdx]*numInvocations;
			counterMasks[counterNdx].resize(counterValue, false);
		}

		// Verify result values from shaders
		for (int invocationNdx = 0; invocationNdx < numInvocations; invocationNdx++)
		{
			for (int opNdx = 0; opNdx < numOps; opNdx++)
			{
				const int		counterNdx	= opIndices[opNdx];
				const deUint32	resValue	= outValues[opNdx*numInvocations + invocationNdx];
				const bool		rangeOk		= de::inBounds(resValue, 0u, (deUint32)counterMasks[counterNdx].size());
				const bool		notSeen		= rangeOk && !counterMasks[counterNdx][resValue];
				const bool		isOk		= rangeOk && notSeen;

				if (!isOk)
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: at invocation " << invocationNdx
														   << ", op " << opNdx << ": got invalid result value "
														   << resValue
									   << TestLog::EndMessage;

					if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
						m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid result value");
				}
				else
				{
					// Mark as used - no other invocation should see this value from same counter.
					counterMasks[counterNdx][resValue] = true;
				}
			}
		}

		if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
		{
			// Consistency check - all masks should be 1 now
			for (int counterNdx = 0; counterNdx < m_numCounters; counterNdx++)
			{
				for (vector<bool>::const_iterator i = counterMasks[counterNdx].begin(); i != counterMasks[counterNdx].end(); i++)
					TCU_CHECK_INTERNAL(*i);
			}
		}
	}

	return STOP;
}

} // anonymous

OpaqueTypeIndexingTests::OpaqueTypeIndexingTests (Context& context)
	: TestCaseGroup(context, "opaque_type_indexing", "Opaque Type Indexing Tests")
{
}

OpaqueTypeIndexingTests::~OpaqueTypeIndexingTests (void)
{
}

void OpaqueTypeIndexingTests::init (void)
{
	static const struct
	{
		IndexExprType	type;
		const char*		name;
		const char*		description;
	} indexingTypes[] =
	{
		{ INDEX_EXPR_TYPE_CONST_LITERAL,	"const_literal",		"Indexing by constant literal"					},
		{ INDEX_EXPR_TYPE_CONST_EXPRESSION,	"const_expression",		"Indexing by constant expression"				},
		{ INDEX_EXPR_TYPE_UNIFORM,			"uniform",				"Indexing by uniform value"						},
		{ INDEX_EXPR_TYPE_DYNAMIC_UNIFORM,	"dynamically_uniform",	"Indexing by dynamically uniform expression"	}
	};

	static const struct
	{
		ShaderType		type;
		const char*		name;
	} shaderTypes[] =
	{
		{ SHADERTYPE_VERTEX,					"vertex"					},
		{ SHADERTYPE_FRAGMENT,					"fragment"					},
		{ SHADERTYPE_COMPUTE,					"compute"					},
		{ SHADERTYPE_GEOMETRY,					"geometry"					},
		{ SHADERTYPE_TESSELLATION_CONTROL,		"tessellation_control"		},
		{ SHADERTYPE_TESSELLATION_EVALUATION,	"tessellation_evaluation"	}
	};

	// .sampler
	{
		static const DataType samplerTypes[] =
		{
			// \note 1D images will be added by a later extension.
//			TYPE_SAMPLER_1D,
			TYPE_SAMPLER_2D,
			TYPE_SAMPLER_CUBE,
			TYPE_SAMPLER_2D_ARRAY,
			TYPE_SAMPLER_3D,
//			TYPE_SAMPLER_1D_SHADOW,
			TYPE_SAMPLER_2D_SHADOW,
			TYPE_SAMPLER_CUBE_SHADOW,
			TYPE_SAMPLER_2D_ARRAY_SHADOW,
//			TYPE_INT_SAMPLER_1D,
			TYPE_INT_SAMPLER_2D,
			TYPE_INT_SAMPLER_CUBE,
			TYPE_INT_SAMPLER_2D_ARRAY,
			TYPE_INT_SAMPLER_3D,
//			TYPE_UINT_SAMPLER_1D,
			TYPE_UINT_SAMPLER_2D,
			TYPE_UINT_SAMPLER_CUBE,
			TYPE_UINT_SAMPLER_2D_ARRAY,
			TYPE_UINT_SAMPLER_3D,
			TYPE_SAMPLER_CUBE_ARRAY,
			TYPE_SAMPLER_CUBE_ARRAY_SHADOW,
			TYPE_INT_SAMPLER_CUBE_ARRAY,
			TYPE_UINT_SAMPLER_CUBE_ARRAY
		};

		tcu::TestCaseGroup* const samplerGroup = new tcu::TestCaseGroup(m_testCtx, "sampler", "Sampler Array Indexing Tests");
		addChild(samplerGroup);

		for (int indexTypeNdx = 0; indexTypeNdx < DE_LENGTH_OF_ARRAY(indexingTypes); indexTypeNdx++)
		{
			const IndexExprType			indexExprType	= indexingTypes[indexTypeNdx].type;
			tcu::TestCaseGroup* const	indexGroup		= new tcu::TestCaseGroup(m_testCtx, indexingTypes[indexTypeNdx].name, indexingTypes[indexTypeNdx].description);
			samplerGroup->addChild(indexGroup);

			for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(shaderTypes); shaderTypeNdx++)
			{
				const ShaderType			shaderType		= shaderTypes[shaderTypeNdx].type;
				tcu::TestCaseGroup* const	shaderGroup		= new tcu::TestCaseGroup(m_testCtx, shaderTypes[shaderTypeNdx].name, "");
				indexGroup->addChild(shaderGroup);

				for (int samplerTypeNdx = 0; samplerTypeNdx < DE_LENGTH_OF_ARRAY(samplerTypes); samplerTypeNdx++)
				{
					const DataType	samplerType	= samplerTypes[samplerTypeNdx];
					const char*		samplerName	= getDataTypeName(samplerType);
					const string	caseName	= de::toLower(samplerName);

					shaderGroup->addChild(new SamplerIndexingCase(m_context, caseName.c_str(), "", shaderType, samplerType, indexExprType));
				}
			}
		}
	}

	// .ubo / .ssbo / .atomic_counter
	{
		tcu::TestCaseGroup* const	uboGroup	= new tcu::TestCaseGroup(m_testCtx, "ubo",				"Uniform Block Instance Array Indexing Tests");
		tcu::TestCaseGroup* const	ssboGroup	= new tcu::TestCaseGroup(m_testCtx, "ssbo",				"Buffer Block Instance Array Indexing Tests");
		tcu::TestCaseGroup* const	acGroup		= new tcu::TestCaseGroup(m_testCtx, "atomic_counter",	"Atomic Counter Array Indexing Tests");
		addChild(uboGroup);
		addChild(ssboGroup);
		addChild(acGroup);

		for (int indexTypeNdx = 0; indexTypeNdx < DE_LENGTH_OF_ARRAY(indexingTypes); indexTypeNdx++)
		{
			const IndexExprType		indexExprType		= indexingTypes[indexTypeNdx].type;
			const char*				indexExprName		= indexingTypes[indexTypeNdx].name;
			const char*				indexExprDesc		= indexingTypes[indexTypeNdx].description;

			for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(shaderTypes); shaderTypeNdx++)
			{
				const ShaderType		shaderType		= shaderTypes[shaderTypeNdx].type;
				const string			name			= string(indexExprName) + "_" + shaderTypes[shaderTypeNdx].name;

				uboGroup->addChild	(new BlockArrayIndexingCase		(m_context, name.c_str(), indexExprDesc, BlockArrayIndexingCase::BLOCKTYPE_UNIFORM,	indexExprType, shaderType));
				acGroup->addChild	(new AtomicCounterIndexingCase	(m_context, name.c_str(), indexExprDesc, indexExprType, shaderType));

				if (indexExprType == INDEX_EXPR_TYPE_CONST_LITERAL || indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
					ssboGroup->addChild	(new BlockArrayIndexingCase		(m_context, name.c_str(), indexExprDesc, BlockArrayIndexingCase::BLOCKTYPE_BUFFER,	indexExprType, shaderType));
			}
		}
	}
}

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