/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 The Khronos Group Inc.
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 * Copyright (c) 2016 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.
 *//*--------------------------------------------------------------------*/

#include "vktOpaqueTypeIndexingTests.hpp"

#include "tcuTexture.hpp"
#include "tcuTestLog.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuTextureUtil.hpp"

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

#include "vktShaderExecutor.hpp"

#include <sstream>

namespace vkt
{
namespace shaderexecutor
{

namespace
{

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_LAST
};

class OpaqueTypeIndexingCase : public TestCase
{
public:
										OpaqueTypeIndexingCase		(tcu::TestContext&			testCtx,
																	 const char*				name,
																	 const char*				description,
																	 const glu::ShaderType		shaderType,
																	 const IndexExprType		indexExprType);
	virtual								~OpaqueTypeIndexingCase		(void);
	virtual void						initPrograms				(vk::SourceCollections& programCollection) const
										{
											m_executor->setShaderSources(programCollection);
										}
	virtual TestInstance*				createInstance				(Context& context) const = 0;
	void								init						(void);

protected:
	const char*							m_name;
	const glu::ShaderType				m_shaderType;
	const IndexExprType					m_indexExprType;
	ShaderSpec							m_shaderSpec;
	de::MovePtr<ShaderExecutor>			m_executor;
	UniformSetup*						m_uniformSetup;
};

class OpaqueTypeIndexingTestInstance : public TestInstance
{
public:
										OpaqueTypeIndexingTestInstance		(Context&					context,
																			 const glu::ShaderType		shaderType,
																			 const ShaderSpec&			shaderSpec,
																			 ShaderExecutor&			executor,
																			 const char*				name,
																			 UniformSetup*				uniformSetup,
																			 const IndexExprType		indexExprType);
	virtual								~OpaqueTypeIndexingTestInstance		(void);

	virtual tcu::TestStatus				iterate								(void) = 0;

protected:
	void								checkSupported						(const VkDescriptorType descriptorType);

protected:
	tcu::TestContext&					m_testCtx;
	const glu::ShaderType				m_shaderType;
	const ShaderSpec&					m_shaderSpec;
	const char*							m_name;
	const IndexExprType					m_indexExprType;
	ShaderExecutor&						m_executor;
	UniformSetup*						m_uniformSetup;
};

OpaqueTypeIndexingCase::OpaqueTypeIndexingCase (tcu::TestContext&			testCtx,
												const char*					name,
												const char*					description,
												const glu::ShaderType		shaderType,
												const IndexExprType			indexExprType)
	: TestCase			(testCtx, name, description)
	, m_name			(name)
	, m_shaderType		(shaderType)
	, m_indexExprType	(indexExprType)
	, m_executor		(DE_NULL)
	, m_uniformSetup	(new UniformSetup())
{
}

OpaqueTypeIndexingCase::~OpaqueTypeIndexingCase (void)
{
}

void OpaqueTypeIndexingCase::init (void)
{
	DE_ASSERT(!m_executor);

	m_executor = de::MovePtr<ShaderExecutor>(createExecutor(m_shaderType, m_shaderSpec));
	m_testCtx.getLog() << *m_executor;
}

OpaqueTypeIndexingTestInstance::OpaqueTypeIndexingTestInstance (Context&					context,
																const glu::ShaderType		shaderType,
																const ShaderSpec&			shaderSpec,
																ShaderExecutor&				executor,
																const char*					name,
																UniformSetup*				uniformSetup,
																const IndexExprType			indexExprType)
	: TestInstance		(context)
	, m_testCtx			(context.getTestContext())
	, m_shaderType		(shaderType)
	, m_shaderSpec		(shaderSpec)
	, m_name			(name)
	, m_indexExprType	(indexExprType)
	, m_executor		(executor)
	, m_uniformSetup	(uniformSetup)
{
}

OpaqueTypeIndexingTestInstance::~OpaqueTypeIndexingTestInstance (void)
{
}

void OpaqueTypeIndexingTestInstance::checkSupported (const VkDescriptorType descriptorType)
{
	const VkPhysicalDeviceFeatures& deviceFeatures = m_context.getDeviceFeatures();

	if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
	{
		switch (descriptorType)
		{
			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
				if (!deviceFeatures.shaderSampledImageArrayDynamicIndexing)
					TCU_THROW(NotSupportedError, "Dynamic indexing of sampler arrays is not supported");
				break;

			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
				if (!deviceFeatures.shaderUniformBufferArrayDynamicIndexing)
					TCU_THROW(NotSupportedError, "Dynamic indexing of uniform buffer arrays is not supported");
				break;

			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
				if (!deviceFeatures.shaderStorageBufferArrayDynamicIndexing)
					TCU_THROW(NotSupportedError, "Dynamic indexing of storage buffer arrays is not supported");
				break;

			default:
				break;
		}
	}
}

static deUint32 getFirstFreeBindingLocation (const glu::ShaderType shaderType)
{
	deUint32 location;

	switch (shaderType)
	{
		case glu::SHADERTYPE_TESSELLATION_CONTROL:
		case glu::SHADERTYPE_TESSELLATION_EVALUATION:
		case glu::SHADERTYPE_COMPUTE:
			// 0 - input buffer
			// 1 - output buffer
			location = 2u;
			break;

		default:
			location = 0u;
			break;
	}

	return location;
}

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

static void uploadUniformIndices (UniformSetup* uniformSetup, int numIndices, const int* indices, deUint32& bindingLocation)
{
	for (int varNdx = 0; varNdx < numIndices; varNdx++)
		uniformSetup->addData(new UniformData<int>(bindingLocation++, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, indices[varNdx]));
}

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;

		default:
			throw tcu::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;
}

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:
			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:
			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:
			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:
			return glu::TYPE_UINT_VEC4;

		default:
			throw tcu::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:
			throw tcu::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;
		default:
			DE_ASSERT(false);
	}

	if (isShadowSampler(samplerType))
		numCoords += 1;

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

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

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

	if (access.getFormat().order == tcu::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 == tcu::TextureFormat::RGBA && access.getFormat().getPixelSize() == 4);

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

static vk::VkImageType getVkImageType (TextureType texType)
{
	switch (texType)
	{
		case TEXTURE_TYPE_1D:			return vk::VK_IMAGE_TYPE_1D;
		case TEXTURE_TYPE_2D:
		case TEXTURE_TYPE_2D_ARRAY:		return vk::VK_IMAGE_TYPE_2D;
		case TEXTURE_TYPE_CUBE:			return vk::VK_IMAGE_TYPE_2D;
		case TEXTURE_TYPE_3D:			return vk::VK_IMAGE_TYPE_3D;
		default:
			DE_FATAL("Impossible");
			return (vk::VkImageType)0;
	}
}

static vk::VkImageViewType getVkImageViewType (TextureType texType)
{
	switch (texType)
	{
		case TEXTURE_TYPE_1D:			return vk::VK_IMAGE_VIEW_TYPE_1D;
		case TEXTURE_TYPE_2D:			return vk::VK_IMAGE_VIEW_TYPE_2D;
		case TEXTURE_TYPE_2D_ARRAY:		return vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY;
		case TEXTURE_TYPE_CUBE:			return vk::VK_IMAGE_VIEW_TYPE_CUBE;
		case TEXTURE_TYPE_3D:			return vk::VK_IMAGE_VIEW_TYPE_3D;
		default:
			DE_FATAL("Impossible");
			return (vk::VkImageViewType)0;
	}
}

// SamplerIndexingCaseInstance

class SamplerIndexingCaseInstance : public OpaqueTypeIndexingTestInstance
{
public:
	enum
	{
		NUM_INVOCATIONS		= 64,
		NUM_SAMPLERS		= 8,
		NUM_LOOKUPS			= 4
	};

								SamplerIndexingCaseInstance		(Context&					context,
																 const glu::ShaderType		shaderType,
																 const ShaderSpec&			shaderSpec,
																 ShaderExecutor&			executor,
																 const char*				name,
																 glu::DataType				samplerType,
																 const IndexExprType		indexExprType,
																 UniformSetup*				uniformSetup,
																 const std::vector<int>&	lookupIndices);
	virtual						~SamplerIndexingCaseInstance	(void);

	virtual tcu::TestStatus		iterate							(void);

protected:
	const glu::DataType			m_samplerType;
	const std::vector<int>&		m_lookupIndices;
};

SamplerIndexingCaseInstance::SamplerIndexingCaseInstance (Context&						context,
														  const glu::ShaderType			shaderType,
														  const ShaderSpec&				shaderSpec,
														  ShaderExecutor&				executor,
														  const char*					name,
														  glu::DataType					samplerType,
														  const IndexExprType			indexExprType,
														  UniformSetup*					uniformSetup,
														  const std::vector<int>&		lookupIndices)
	: OpaqueTypeIndexingTestInstance	(context, shaderType, shaderSpec, executor, name, uniformSetup, indexExprType)
	, m_samplerType						(samplerType)
	, m_lookupIndices					(lookupIndices)
{
}

SamplerIndexingCaseInstance::~SamplerIndexingCaseInstance (void)
{
}

bool isIntegerFormat (const tcu::TextureFormat& format)
{
	const tcu::TextureChannelClass	chnClass	= tcu::getTextureChannelClass(format.type);

	return chnClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
		   chnClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
}

tcu::TestStatus SamplerIndexingCaseInstance::iterate (void)
{
	const int						numInvocations		= SamplerIndexingCaseInstance::NUM_INVOCATIONS;
	const int						numSamplers			= SamplerIndexingCaseInstance::NUM_SAMPLERS;
	const int						numLookups			= SamplerIndexingCaseInstance::NUM_LOOKUPS;
	const glu::DataType				coordType			= getSamplerCoordType(m_samplerType);
	const glu::DataType				outputType			= getSamplerOutputType(m_samplerType);
	const tcu::TextureFormat		texFormat			= getSamplerTextureFormat(m_samplerType);
	const int						outLookupStride		= numInvocations*getDataTypeScalarSize(outputType);
	std::vector<float>				coords;
	std::vector<deUint32>			outData;
	std::vector<deUint8>			texData				(numSamplers * texFormat.getPixelSize());
	const tcu::PixelBufferAccess	refTexAccess		(texFormat, numSamplers, 1, 1, &texData[0]);
	de::Random						rnd					(deInt32Hash(m_samplerType) ^ deInt32Hash(m_shaderType) ^ deInt32Hash(m_indexExprType));
	const TextureType				texType				= getTextureType(m_samplerType);
	const vk::VkImageType			imageType			= getVkImageType(texType);
	const vk::VkImageViewType		imageViewType		= getVkImageViewType(texType);
	const tcu::Sampler::FilterMode	filterMode			= (isShadowSampler(m_samplerType) || isIntegerFormat(texFormat)) ? tcu::Sampler::NEAREST : tcu::Sampler::LINEAR;

	// The shadow sampler with unnormalized coordinates is only used with the reference texture. Actual samplers in shaders use normalized coords.
	const tcu::Sampler				refSampler			= isShadowSampler(m_samplerType)
																? tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
																				filterMode, filterMode, 0.0f, false /* non-normalized */,
																				tcu::Sampler::COMPAREMODE_LESS)
																: tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
																				filterMode, filterMode);

	checkSupported(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);

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

	if (texType == TEXTURE_TYPE_CUBE)
	{
		if (isShadowSampler(m_samplerType))
		{
			for (size_t i = 0; i < coords.size() / 4; i++)
			{
				coords[4 * i] = 1.0f;
				coords[4 * i + 1] = coords[4 * i + 2] = coords[4 * i + 3] = 0.0f;
			}
		}
		else
		{
			for (size_t i = 0; i < coords.size() / 3; i++)
			{
				coords[3 * i] = 1.0f;
				coords[3 * i + 1] = coords[3 * i + 2] = 0.0f;
			}
		}
	}

	if (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);

	{
		std::vector<void*>		inputs;
		std::vector<void*>		outputs;
		std::vector<int>		expandedIndices;
		deUint32				bindingLocation		= getFirstFreeBindingLocation(m_shaderType);

		inputs.push_back(&coords[0]);

		{
			tcu::Sampler sampler		= refSampler;
			sampler.normalizedCoords	= true;

			m_uniformSetup->addData(new SamplerUniformData(bindingLocation++, (deUint32)numSamplers, sampler, texFormat, tcu::IVec3(1, 1, 1), imageType, imageViewType, &texData[0]));
		}

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

			for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
				inputs.push_back(&expandedIndices[lookupNdx*numInvocations]);
		}
		else if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
			uploadUniformIndices(m_uniformSetup, numLookups, &m_lookupIndices[0], bindingLocation);

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

		m_executor.setUniforms(m_uniformSetup);

		m_executor.execute(m_context, numInvocations, &inputs[0], &outputs[0]);
	}

	{
		tcu::TestLog&		log				= m_context.getTestContext().getLog();
		tcu::TestStatus		testResult		= tcu::TestStatus::pass("Pass");

		if (isShadowSampler(m_samplerType))
		{
			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		= m_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)
					{
						log << tcu::TestLog::Message << "ERROR: at invocation " << invocationNdx << ", lookup " << lookupNdx << ": expected "
							<< reference << ", got " << result
							<< tcu::TestLog::EndMessage;

						if (testResult.getCode() == QP_TEST_RESULT_PASS)
							testResult = tcu::TestStatus::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	= m_lookupIndices[lookupNdx];
				const deUint8*	resPtr	= (const deUint8*)&outData[lookupNdx*outLookupStride];
				bool			isOk;

				if (outputType == glu::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)
					{
						log << tcu::TestLog::Message << "ERROR: at lookup " << lookupNdx << ": expected "
							<< reference << ", got " << result
							<< tcu::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)
					{
						log << tcu::TestLog::Message << "ERROR: at lookup " << lookupNdx << ": expected "
							<< reference << ", got " << result
							<< tcu::TestLog::EndMessage;
					}
				}

				if (!isOk && testResult.getCode() == QP_TEST_RESULT_PASS)
					testResult = tcu::TestStatus::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)
					{
						log << tcu::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))
							<< tcu::TestLog::EndMessage;

						if (testResult.getCode() == QP_TEST_RESULT_PASS)
							testResult = tcu::TestStatus::fail("Inconsistent lookup results");
					}
				}
			}
		}

		return testResult;
	}
}

class SamplerIndexingCase : public OpaqueTypeIndexingCase
{
public:
								SamplerIndexingCase			(tcu::TestContext&			testCtx,
															 const char*				name,
															 const char*				description,
															 const glu::ShaderType		shaderType,
															 glu::DataType				samplerType,
															 IndexExprType				indexExprType);
	virtual						~SamplerIndexingCase		(void);

	virtual TestInstance*		createInstance				(Context& ctx) const;

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

	void						createShaderSpec			(void);

	const glu::DataType			m_samplerType;
	const int					m_numSamplers;
	const int					m_numLookups;
	std::vector<int>			m_lookupIndices;
};

SamplerIndexingCase::SamplerIndexingCase (tcu::TestContext&			testCtx,
										  const char*				name,
										  const char*				description,
										  const glu::ShaderType		shaderType,
										  glu::DataType				samplerType,
										  IndexExprType				indexExprType)
	: OpaqueTypeIndexingCase	(testCtx, name, description, shaderType, indexExprType)
	, m_samplerType				(samplerType)
	, m_numSamplers				(SamplerIndexingCaseInstance::NUM_SAMPLERS)
	, m_numLookups				(SamplerIndexingCaseInstance::NUM_LOOKUPS)
	, m_lookupIndices			(m_numLookups)
{
	createShaderSpec();
	init();
}

SamplerIndexingCase::~SamplerIndexingCase (void)
{
}

TestInstance* SamplerIndexingCase::createInstance (Context& ctx) const
{
	return new SamplerIndexingCaseInstance(ctx,
										   m_shaderType,
										   m_shaderSpec,
										   *m_executor,
										   m_name,
										   m_samplerType,
										   m_indexExprType,
										   m_uniformSetup,
										   m_lookupIndices);
}

void SamplerIndexingCase::createShaderSpec (void)
{
	de::Random			rnd				(deInt32Hash(m_samplerType) ^ deInt32Hash(m_shaderType) ^ deInt32Hash(m_indexExprType));
	deUint32			binding			= getFirstFreeBindingLocation(m_shaderType);
	const char*			samplersName	= "texSampler";
	const char*			coordsName		= "coords";
	const char*			indicesPrefix	= "index";
	const char*			resultPrefix	= "result";
	const glu::DataType	coordType		= getSamplerCoordType(m_samplerType);
	const glu::DataType	outType			= getSamplerOutputType(m_samplerType);
	std::ostringstream	global, code;

	for (int ndx = 0; ndx < m_numLookups; ndx++)
		m_lookupIndices[ndx] = rnd.getInt(0, m_numSamplers-1);

	m_shaderSpec.inputs.push_back(Symbol(coordsName, glu::VarType(coordType, glu::PRECISION_HIGHP)));

	if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL)
		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(set = 0, binding = " << binding++ << ") uniform highp " << getDataTypeName(m_samplerType) << " " << samplersName << "[" << m_numSamplers << "];\n";

	if (m_indexExprType == INDEX_EXPR_TYPE_DYNAMIC_UNIFORM)
	{
		for (int lookupNdx = 0; lookupNdx < m_numLookups; lookupNdx++)
		{
			const std::string varName = indicesPrefix + de::toString(lookupNdx);
			m_shaderSpec.inputs.push_back(Symbol(varName, glu::VarType(glu::TYPE_INT, glu::PRECISION_HIGHP)));
		}
	}
	else if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
		declareUniformIndexVars(global, indicesPrefix, m_numLookups, binding);

	for (int lookupNdx = 0; lookupNdx < m_numLookups; lookupNdx++)
	{
		const std::string varName = resultPrefix + de::toString(lookupNdx);
		m_shaderSpec.outputs.push_back(Symbol(varName, glu::VarType(outType, glu::PRECISION_HIGHP)));
	}

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

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

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

	m_shaderSpec.globalDeclarations	= global.str();
	m_shaderSpec.source				= code.str();
}

enum BlockType
{
	BLOCKTYPE_UNIFORM = 0,
	BLOCKTYPE_BUFFER,

	BLOCKTYPE_LAST
};

class BlockArrayIndexingCaseInstance : public OpaqueTypeIndexingTestInstance
{
public:
	enum
	{
		NUM_INVOCATIONS		= 32,
		NUM_INSTANCES		= 4,
		NUM_READS			= 4
	};

									BlockArrayIndexingCaseInstance	(Context&						context,
																	 const glu::ShaderType			shaderType,
																	 const ShaderSpec&				shaderSpec,
																	 ShaderExecutor&				executor,
																	 const char*					name,
																	 BlockType						blockType,
																	 const IndexExprType			indexExprType,
																	 UniformSetup*					uniformSetup,
																	 const std::vector<int>&		readIndices,
																	 const std::vector<deUint32>&	inValues);
	virtual							~BlockArrayIndexingCaseInstance	(void);

	virtual tcu::TestStatus			iterate							(void);

private:
	const BlockType					m_blockType;
	const std::vector<int>&			m_readIndices;
	const std::vector<deUint32>&	m_inValues;
};

BlockArrayIndexingCaseInstance::BlockArrayIndexingCaseInstance (Context&						context,
																const glu::ShaderType			shaderType,
																const ShaderSpec&				shaderSpec,
																ShaderExecutor&					executor,
																const char*						name,
																BlockType						blockType,
																const IndexExprType				indexExprType,
																UniformSetup*					uniformSetup,
																const std::vector<int>&			readIndices,
																const std::vector<deUint32>&	inValues)
	: OpaqueTypeIndexingTestInstance	(context, shaderType, shaderSpec, executor, name, uniformSetup, indexExprType)
	, m_blockType						(blockType)
	, m_readIndices						(readIndices)
	, m_inValues						(inValues)
{
}

BlockArrayIndexingCaseInstance::~BlockArrayIndexingCaseInstance (void)
{
}

tcu::TestStatus BlockArrayIndexingCaseInstance::iterate (void)
{
	const int					numInvocations		= NUM_INVOCATIONS;
	const int					numReads			= NUM_READS;
	std::vector<deUint32>		outValues			(numInvocations*numReads);

	{
		tcu::TestLog&			log					= m_context.getTestContext().getLog();
		tcu::TestStatus			testResult			= tcu::TestStatus::pass("Pass");
		std::vector<int>		expandedIndices;
		std::vector<void*>		inputs;
		std::vector<void*>		outputs;
		deUint32				bindingLocation		= getFirstFreeBindingLocation(m_shaderType);
		VkDescriptorType		descriptorType		= m_blockType == BLOCKTYPE_UNIFORM ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;

		checkSupported(descriptorType);

		m_uniformSetup->addData(new UniformArrayData<deUint32>(bindingLocation++, descriptorType, m_inValues));

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

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

			for (int readNdx = 0; readNdx < numReads; readNdx++)
				inputs.push_back(&expandedIndices[readNdx*numInvocations]);
		}
		else if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
			uploadUniformIndices(m_uniformSetup, numReads, &m_readIndices[0], bindingLocation);

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

		m_executor.setUniforms(m_uniformSetup);

		m_executor.execute(m_context, numInvocations, inputs.empty() ? DE_NULL : &inputs[0], &outputs[0]);

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

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

					if (testResult.getCode() == QP_TEST_RESULT_PASS)
						testResult = tcu::TestStatus::fail("Invalid result value");
				}
			}
		}

		return testResult;
	}
}

class BlockArrayIndexingCase : public OpaqueTypeIndexingCase
{
public:
								BlockArrayIndexingCase		(tcu::TestContext&			testCtx,
															 const char*				name,
															 const char*				description,
															 BlockType					blockType,
															 IndexExprType				indexExprType,
															 const glu::ShaderType		shaderType);
	virtual						~BlockArrayIndexingCase		(void);

	virtual TestInstance*		createInstance				(Context& ctx) const;

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

	void						createShaderSpec			(void);

	const BlockType				m_blockType;
	std::vector<int>			m_readIndices;
	std::vector<deUint32>		m_inValues;
};

BlockArrayIndexingCase::BlockArrayIndexingCase (tcu::TestContext&			testCtx,
												const char*					name,
												const char*					description,
												BlockType					blockType,
												IndexExprType				indexExprType,
												const glu::ShaderType		shaderType)
	: OpaqueTypeIndexingCase	(testCtx, name, description, shaderType, indexExprType)
	, m_blockType				(blockType)
	, m_readIndices				(BlockArrayIndexingCaseInstance::NUM_READS)
	, m_inValues				(BlockArrayIndexingCaseInstance::NUM_INSTANCES)
{
	createShaderSpec();
	init();
}

BlockArrayIndexingCase::~BlockArrayIndexingCase (void)
{
}

TestInstance* BlockArrayIndexingCase::createInstance (Context& ctx) const
{
	return new BlockArrayIndexingCaseInstance(ctx,
											  m_shaderType,
											  m_shaderSpec,
											  *m_executor,
											  m_name,
											  m_blockType,
											  m_indexExprType,
											  m_uniformSetup,
											  m_readIndices,
											  m_inValues);
}

void BlockArrayIndexingCase::createShaderSpec (void)
{
	const int			numInstances	= BlockArrayIndexingCaseInstance::NUM_INSTANCES;
	const int			numReads		= BlockArrayIndexingCaseInstance::NUM_READS;
	de::Random			rnd				(deInt32Hash(m_shaderType) ^ deInt32Hash(m_blockType) ^ deInt32Hash(m_indexExprType));
	deUint32			binding			= getFirstFreeBindingLocation(m_shaderType);
	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";
	std::ostringstream	global, code;

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

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

	if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL)
		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(set = 0, binding = " << binding++ << ") " << interfaceName << " " << blockName << "\n"
		"{\n"
		"	highp uint value;\n"
		"} " << instanceName << "[" << numInstances << "];\n";

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

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

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

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

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

	m_shaderSpec.globalDeclarations	= global.str();
	m_shaderSpec.source				= code.str();
}

class AtomicCounterIndexingCaseInstance : public OpaqueTypeIndexingTestInstance
{
public:
	enum
	{
		NUM_INVOCATIONS		= 32,
		NUM_COUNTERS		= 4,
		NUM_OPS				= 4
	};

								AtomicCounterIndexingCaseInstance	(Context&					context,
																	 const glu::ShaderType		shaderType,
																	 const ShaderSpec&			shaderSpec,
																	 ShaderExecutor&			executor,
																	 const char*				name,
																	 UniformSetup*				uniformSetup,
																	 const std::vector<int>&	opIndices,
																	 const IndexExprType		indexExprType);
	virtual						~AtomicCounterIndexingCaseInstance	(void);

	virtual	tcu::TestStatus		iterate								(void);

private:
	const std::vector<int>&		m_opIndices;
};

AtomicCounterIndexingCaseInstance::AtomicCounterIndexingCaseInstance (Context&					context,
																	  const glu::ShaderType		shaderType,
																	  const ShaderSpec&			shaderSpec,
																	  ShaderExecutor&			executor,
																	  const char*				name,
																	  UniformSetup*				uniformSetup,
																	  const std::vector<int>&	opIndices,
																	  const IndexExprType		indexExprType)
	: OpaqueTypeIndexingTestInstance	(context, shaderType, shaderSpec, executor, name, uniformSetup, indexExprType)
	, m_opIndices						(opIndices)
{
}

AtomicCounterIndexingCaseInstance::~AtomicCounterIndexingCaseInstance (void)
{
}

tcu::TestStatus AtomicCounterIndexingCaseInstance::iterate (void)
{
	// \todo [2015-12-02 elecro] Add vertexPipelineStoresAndAtomics feature check.
	const int					numInvocations		= NUM_INVOCATIONS;
	const int					numCounters			= NUM_COUNTERS;
	const int					numOps				= NUM_OPS;
	std::vector<int>			expandedIndices;
	std::vector<void*>			inputs;
	std::vector<void*>			outputs;
	std::vector<deUint32>		outValues			(numInvocations*numOps);
	deUint32					bindingLocation		= getFirstFreeBindingLocation(m_shaderType);

	const deUint32 atomicCounterLocation = bindingLocation++;

	checkSupported(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);

	{
		DE_ASSERT(numCounters <= 4);
		// Add the atomic counters' base value, all zero.
		m_uniformSetup->addData(new UniformData<tcu::Mat4>(atomicCounterLocation, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, tcu::Mat4(0.0)));

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

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

			for (int opNdx = 0; opNdx < numOps; opNdx++)
				inputs.push_back(&expandedIndices[opNdx*numInvocations]);
		}
		else if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
			uploadUniformIndices(m_uniformSetup, numOps, &m_opIndices[0], bindingLocation);

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

		m_executor.setUniforms(m_uniformSetup);

		m_executor.execute(m_context, numInvocations, inputs.empty() ? DE_NULL : &inputs[0], &outputs[0]);
	}

	{
		tcu::TestLog&					log				= m_context.getTestContext().getLog();
		tcu::TestStatus					testResult		= tcu::TestStatus::pass("Pass");
		std::vector<int>				numHits			(numCounters, 0);	// Number of hits per counter.
		std::vector<deUint32>			counterValues	(numCounters);
		std::vector<std::vector<bool> >	counterMasks	(numCounters);

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

		// Read counter values
		{
			const void* mapPtr = m_executor.getBufferPtr(atomicCounterLocation);
			DE_ASSERT(mapPtr != DE_NULL);
			std::copy((const deUint32*)mapPtr, (const deUint32*)mapPtr + numCounters, &counterValues[0]);
		}

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

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

				if (testResult.getCode() == QP_TEST_RESULT_PASS)
					testResult = tcu::TestStatus::fail("Invalid atomic counter value");
			}
		}

		// Allocate bitmasks - one bit per each valid result value
		for (int counterNdx = 0; counterNdx < 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	= m_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)
				{
					log << tcu::TestLog::Message << "ERROR: at invocation " << invocationNdx
						<< ", op " << opNdx << ": got invalid result value "
						<< resValue
						<< tcu::TestLog::EndMessage;

					if (testResult.getCode() == QP_TEST_RESULT_PASS)
						testResult = tcu::TestStatus::fail("Invalid result value");
				}
				else
				{
					// Mark as used - no other invocation should see this value from same counter.
					counterMasks[counterNdx][resValue] = true;
				}
			}
		}

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

		return testResult;
	}
}

class AtomicCounterIndexingCase : public OpaqueTypeIndexingCase
{
public:
								AtomicCounterIndexingCase	(tcu::TestContext&			testCtx,
															 const char*				name,
															 const char*				description,
															 IndexExprType				indexExprType,
															 const glu::ShaderType		shaderType);
	virtual						~AtomicCounterIndexingCase	(void);

	virtual TestInstance*		createInstance				(Context& ctx) const;

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

	void						createShaderSpec			(void);

	std::vector<int>			m_opIndices;
};

AtomicCounterIndexingCase::AtomicCounterIndexingCase (tcu::TestContext&			testCtx,
													  const char*				name,
													  const char*				description,
													  IndexExprType				indexExprType,
													  const glu::ShaderType		shaderType)
	: OpaqueTypeIndexingCase	(testCtx, name, description, shaderType, indexExprType)
	, m_opIndices				(AtomicCounterIndexingCaseInstance::NUM_OPS)
{
	createShaderSpec();
	init();
}

AtomicCounterIndexingCase::~AtomicCounterIndexingCase (void)
{
}

TestInstance* AtomicCounterIndexingCase::createInstance (Context& ctx) const
{
	return new AtomicCounterIndexingCaseInstance(ctx,
												 m_shaderType,
												 m_shaderSpec,
												 *m_executor,
												 m_name,
												 m_uniformSetup,
												 m_opIndices,
												 m_indexExprType);
}

void AtomicCounterIndexingCase::createShaderSpec (void)
{
	const int				numCounters		= AtomicCounterIndexingCaseInstance::NUM_COUNTERS;
	const int				numOps			= AtomicCounterIndexingCaseInstance::NUM_OPS;
	deUint32				binding			= getFirstFreeBindingLocation(m_shaderType);
	de::Random				rnd				(deInt32Hash(m_shaderType) ^ deInt32Hash(m_indexExprType));

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

	{
		const char*			indicesPrefix	= "index";
		const char*			resultPrefix	= "result";
		std::ostringstream	global, code;

		if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL)
			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(set = 0, binding = " << binding++ << ") buffer AtomicBuffer { highp uint counter[" << numCounters << "]; };\n";

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

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

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

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

			code << "], uint(1));\n";
		}

		m_shaderSpec.globalDeclarations	= global.str();
		m_shaderSpec.source				= code.str();
	}
}

class OpaqueTypeIndexingTests : public tcu::TestCaseGroup
{
public:
								OpaqueTypeIndexingTests		(tcu::TestContext& testCtx);
	virtual						~OpaqueTypeIndexingTests	(void);

	virtual void				init						(void);

private:
								OpaqueTypeIndexingTests		(const OpaqueTypeIndexingTests&);
	OpaqueTypeIndexingTests&	operator=					(const OpaqueTypeIndexingTests&);
};

OpaqueTypeIndexingTests::OpaqueTypeIndexingTests (tcu::TestContext& testCtx)
	: tcu::TestCaseGroup(testCtx, "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
	{
		glu::ShaderType	type;
		const char*		name;
	} shaderTypes[] =
	{
		{ glu::SHADERTYPE_VERTEX,		"vertex"	},
		{ glu::SHADERTYPE_FRAGMENT,		"fragment"	},
		{ glu::SHADERTYPE_COMPUTE,		"compute"	}
	};

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

		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 glu::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 glu::DataType	samplerType	= samplerTypes[samplerTypeNdx];
					const char*			samplerName	= getDataTypeName(samplerType);
					const std::string	caseName	= de::toLower(samplerName);

					shaderGroup->addChild(new SamplerIndexingCase(m_testCtx, 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 glu::ShaderType	shaderType		= shaderTypes[shaderTypeNdx].type;
				const std::string		name			= std::string(indexExprName) + "_" + shaderTypes[shaderTypeNdx].name;

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

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

} // anonymous

tcu::TestCaseGroup* createOpaqueTypeIndexingTests (tcu::TestContext& testCtx)
{
	return new OpaqueTypeIndexingTests(testCtx);
}

} // shaderexecutor
} // vkt
