/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2018 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Robust buffer access tests for storage buffers and
 *        storage texel buffers with variable pointers.
 *
 * \note These tests are checking if accessing a memory through a variable
 *       pointer that points outside of accessible buffer memory is robust.
 *       To do this the tests are creating proper SPIRV code that creates
 *       variable pointers. Those pointers are either pointing into a
 *       memory allocated for a buffer but "not accesible" - meaning
 *       DescriptorBufferInfo has smaller size than a memory we access in
 *       shader or entirely outside of allocated memory (i.e. buffer is
 *       256 bytes big but we are trying to access under offset of 1k from
 *       buffer start). There is a set of valid behaviours defined when
 *       robust buffer access extension is enabled described in chapter 32
 *       section 1 of Vulkan spec.
 *
 *//*--------------------------------------------------------------------*/

#include "vktRobustBufferAccessWithVariablePointersTests.hpp"
#include "vktRobustnessUtil.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkPrograms.hpp"
#include "vkQueryUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "tcuTestLog.hpp"
#include "vkDefs.hpp"
#include "deRandom.hpp"

#include <limits>
#include <sstream>

namespace vkt
{
namespace robustness
{

using namespace vk;

// keep local things local
namespace
{

// Creates a custom device with robust buffer access and variable pointer features.
Move<VkDevice> createRobustBufferAccessVariablePointersDevice (Context& context)
{
	auto pointerFeatures = context.getVariablePointersFeatures();

	VkPhysicalDeviceFeatures2 features2 = initVulkanStructure();
	features2.features = context.getDeviceFeatures();
	features2.features.robustBufferAccess = VK_TRUE;
	features2.pNext = &pointerFeatures;

	return createRobustBufferAccessDevice(context, &features2);
}

// A supplementary structures that can hold information about buffer size
struct AccessRangesData
{
	VkDeviceSize	allocSize;
	VkDeviceSize	accessRange;
	VkDeviceSize	maxAccessRange;
};

// Pointer to function that can be used to fill a buffer with some data - it is passed as an parameter to buffer creation utility function
typedef void(*FillBufferProcPtr)(void*, vk::VkDeviceSize, const void* const);

// An utility function for creating a buffer
// This function not only allocates memory for the buffer but also fills buffer up with a data
void createTestBuffer (const vk::DeviceInterface&				deviceInterface,
					   const VkDevice&							device,
					   VkDeviceSize								accessRange,
					   VkBufferUsageFlags						usage,
					   SimpleAllocator&							allocator,
					   Move<VkBuffer>&							buffer,
					   de::MovePtr<Allocation>&					bufferAlloc,
					   AccessRangesData&						data,
					   FillBufferProcPtr						fillBufferProc,
					   const void* const						blob)
{
	const VkBufferCreateInfo	bufferParams	=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
		DE_NULL,									// const void*			pNext;
		0u,											// VkBufferCreateFlags	flags;
		accessRange,								// VkDeviceSize			size;
		usage,										// VkBufferUsageFlags	usage;
		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32				queueFamilyIndexCount;
		DE_NULL										// const deUint32*		pQueueFamilyIndices;
	};

	buffer = createBuffer(deviceInterface, device, &bufferParams);

	VkMemoryRequirements bufferMemoryReqs		= getBufferMemoryRequirements(deviceInterface, device, *buffer);
	bufferAlloc = allocator.allocate(bufferMemoryReqs, MemoryRequirement::HostVisible);

	data.allocSize = bufferMemoryReqs.size;
	data.accessRange = accessRange;
	data.maxAccessRange = deMinu64(data.allocSize, deMinu64(bufferParams.size, accessRange));

	VK_CHECK(deviceInterface.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
	fillBufferProc(bufferAlloc->getHostPtr(), bufferMemoryReqs.size, blob);
	flushMappedMemoryRange(deviceInterface, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), VK_WHOLE_SIZE);
}

// An adapter function matching FillBufferProcPtr interface. Fills a buffer with "randomly" generated test data matching desired format.
void populateBufferWithValues (void*				buffer,
							   VkDeviceSize			size,
							   const void* const	blob)
{
	populateBufferWithTestValues(buffer, size, *static_cast<const vk::VkFormat*>(blob));
}

// An adapter function matching FillBufferProcPtr interface. Fills a buffer with 0xBABABABABABA... pattern. Used to fill up output buffers.
// Since this pattern cannot show up in generated test data it should not show up in the valid output.
void populateBufferWithDummy (void*					buffer,
							  VkDeviceSize			size,
							  const void* const		blob)
{
	DE_UNREF(blob);
	deMemset(buffer, 0xBA, static_cast<size_t>(size));
}

// An adapter function matching FillBufferProcPtr interface. Fills a buffer with a copy of memory contents pointed to by blob.
void populateBufferWithCopy (void*					buffer,
							 VkDeviceSize			size,
							 const void* const		blob)
{
	deMemcpy(buffer, blob, static_cast<size_t>(size));
}

// A composite types used in test
// Those composites can be made of unsigned ints, signed ints or floats (except for matrices that work with floats only).
enum ShaderType
{
	SHADER_TYPE_MATRIX_COPY					= 0,
	SHADER_TYPE_VECTOR_COPY,
	SHADER_TYPE_SCALAR_COPY,

	SHADER_TYPE_COUNT
};

// We are testing reads or writes
// In case of testing reads - writes are always
enum BufferAccessType
{
	BUFFER_ACCESS_TYPE_READ_FROM_STORAGE	= 0,
	BUFFER_ACCESS_TYPE_WRITE_TO_STORAGE,
};

// Test case for checking robust buffer access with variable pointers
class RobustAccessWithPointersTest : public vkt::TestCase
{
public:
	static const deUint32		s_testArraySize;
	static const deUint32		s_numberOfBytesAccessed;

								RobustAccessWithPointersTest	(tcu::TestContext&		testContext,
																 const std::string&		name,
																 const std::string&		description,
																 VkShaderStageFlags		shaderStage,
																 ShaderType				shaderType,
																 VkFormat				bufferFormat);

	virtual						~RobustAccessWithPointersTest	(void)
	{
	}

	void						checkSupport (Context &context) const override;

protected:
	const VkShaderStageFlags	m_shaderStage;
	const ShaderType			m_shaderType;
	const VkFormat				m_bufferFormat;
};

const deUint32 RobustAccessWithPointersTest::s_testArraySize = 1024u;
const deUint32 RobustAccessWithPointersTest::s_numberOfBytesAccessed = static_cast<deUint32>(16ull * sizeof(float));

RobustAccessWithPointersTest::RobustAccessWithPointersTest(tcu::TestContext&		testContext,
	const std::string&		name,
	const std::string&		description,
	VkShaderStageFlags		shaderStage,
	ShaderType				shaderType,
	VkFormat				bufferFormat)
	: vkt::TestCase(testContext, name, description)
	, m_shaderStage(shaderStage)
	, m_shaderType(shaderType)
	, m_bufferFormat(bufferFormat)
{
	DE_ASSERT(m_shaderStage == VK_SHADER_STAGE_VERTEX_BIT || m_shaderStage == VK_SHADER_STAGE_FRAGMENT_BIT || m_shaderStage == VK_SHADER_STAGE_COMPUTE_BIT);
}

void RobustAccessWithPointersTest::checkSupport (Context &context) const
{
	const auto& pointerFeatures = context.getVariablePointersFeatures();
	if (!pointerFeatures.variablePointersStorageBuffer)
		TCU_THROW(NotSupportedError, "VariablePointersStorageBuffer SPIR-V capability not supported");
}

// A subclass for testing reading with variable pointers
class RobustReadTest : public RobustAccessWithPointersTest
{
public:
								RobustReadTest					(tcu::TestContext&		testContext,
																 const std::string&		name,
																 const std::string&		description,
																 VkShaderStageFlags		shaderStage,
																 ShaderType				shaderType,
																 VkFormat				bufferFormat,
																 VkDeviceSize			readAccessRange,
																 bool					accessOutOfBackingMemory);

	virtual						~RobustReadTest					(void)
	{}
	virtual TestInstance*		createInstance					(Context&				context) const;
private:
	virtual void				initPrograms					(SourceCollections&		programCollection) const;
	const VkDeviceSize			m_readAccessRange;
	const bool					m_accessOutOfBackingMemory;
};

// A subclass for testing writing with variable pointers
class RobustWriteTest : public RobustAccessWithPointersTest
{
public:
								RobustWriteTest				(tcu::TestContext&		testContext,
															 const std::string&		name,
															 const std::string&		description,
															 VkShaderStageFlags		shaderStage,
															 ShaderType				shaderType,
															 VkFormat				bufferFormat,
															 VkDeviceSize			writeAccessRange,
															 bool					accessOutOfBackingMemory);

	virtual						~RobustWriteTest			(void) {}
	virtual TestInstance*		createInstance				(Context& context) const;
private:
	virtual void				initPrograms				(SourceCollections&		programCollection) const;
	const VkDeviceSize			m_writeAccessRange;
	const bool					m_accessOutOfBackingMemory;
};

// In case I detect that some prerequisites are not fullfilled I am creating this lightweight dummy test instance instead of AccessInstance. Should be bit faster that way.
class NotSupportedInstance : public vkt::TestInstance
{
public:
								NotSupportedInstance		(Context&			context,
															 const std::string&	message)
		: TestInstance(context)
		, m_notSupportedMessage(message)
	{}

	virtual						~NotSupportedInstance		(void)
	{
	}

	virtual tcu::TestStatus		iterate						(void)
	{
		TCU_THROW(NotSupportedError, m_notSupportedMessage.c_str());
	}

private:
	std::string					m_notSupportedMessage;
};

// A superclass for instances testing reading and writing
// holds all necessary object members
class AccessInstance : public vkt::TestInstance
{
public:
								AccessInstance				(Context&			context,
															 Move<VkDevice>		device,
															 ShaderType			shaderType,
															 VkShaderStageFlags	shaderStage,
															 VkFormat			bufferFormat,
															 BufferAccessType	bufferAccessType,
															 VkDeviceSize		inBufferAccessRange,
															 VkDeviceSize		outBufferAccessRange,
															 bool				accessOutOfBackingMemory);

	virtual						~AccessInstance				(void) {}

	virtual tcu::TestStatus		iterate						(void);

	virtual bool				verifyResult				(bool splitAccess = false);

private:
	bool						isExpectedValueFromInBuffer	(VkDeviceSize		offsetInBytes,
															 const void*		valuePtr,
															 VkDeviceSize		valueSize);
	bool						isOutBufferValueUnchanged	(VkDeviceSize		offsetInBytes,
															 VkDeviceSize		valueSize);

protected:
	Move<VkDevice>				m_device;
	de::MovePtr<TestEnvironment>m_testEnvironment;

	const ShaderType			m_shaderType;
	const VkShaderStageFlags	m_shaderStage;

	const VkFormat				m_bufferFormat;
	const BufferAccessType		m_bufferAccessType;

	AccessRangesData			m_inBufferAccess;
	Move<VkBuffer>				m_inBuffer;
	de::MovePtr<Allocation>		m_inBufferAlloc;

	AccessRangesData			m_outBufferAccess;
	Move<VkBuffer>				m_outBuffer;
	de::MovePtr<Allocation>		m_outBufferAlloc;

	Move<VkBuffer>				m_indicesBuffer;
	de::MovePtr<Allocation>		m_indicesBufferAlloc;

	Move<VkDescriptorPool>		m_descriptorPool;
	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
	Move<VkDescriptorSet>		m_descriptorSet;

	Move<VkFence>				m_fence;
	VkQueue						m_queue;

	// Used when m_shaderStage == VK_SHADER_STAGE_VERTEX_BIT
	Move<VkBuffer>				m_vertexBuffer;
	de::MovePtr<Allocation>		m_vertexBufferAlloc;

	const bool					m_accessOutOfBackingMemory;
};

// A subclass for read tests
class ReadInstance: public AccessInstance
{
public:
								ReadInstance			(Context&				context,
														 Move<VkDevice>			device,
														 ShaderType				shaderType,
														 VkShaderStageFlags		shaderStage,
														 VkFormat				bufferFormat,
														 VkDeviceSize			inBufferAccessRange,
														 bool					accessOutOfBackingMemory);

	virtual						~ReadInstance			(void) {}
};

// A subclass for write tests
class WriteInstance: public AccessInstance
{
public:
								WriteInstance			(Context&				context,
														 Move<VkDevice>			device,
														 ShaderType				shaderType,
														 VkShaderStageFlags		shaderStage,
														 VkFormat				bufferFormat,
														 VkDeviceSize			writeBufferAccessRange,
														 bool					accessOutOfBackingMemory);

	virtual						~WriteInstance			(void) {}
};

// Automatically incremented counter.
// Each read of value bumps counter up.
class Autocounter
{
public:
								Autocounter()
		:value(0u)
	{}
	deUint32					incrementAndGetValue()
	{
		return ++value;
	}
private:
	deUint32					value;
};

// A class representing SPIRV variable.
// This class internally has an unique identificator.
// When such variable is used in shader composition routine it is mapped on a in-SPIRV-code variable name.
class Variable
{
	friend bool					operator < (const Variable& a, const Variable& b);
public:
								Variable(Autocounter& autoincrement)
		: value(autoincrement.incrementAndGetValue())
	{}
private:
	deUint32					value;
};

bool operator < (const Variable& a, const Variable& b)
{
	return a.value < b.value;
}

// A class representing SPIRV operation.
// Since those are not copyable they don't need internal id. Memory address is used instead.
class Operation
{
	friend bool					operator==(const Operation& a, const Operation& b);
public:
								Operation(const char* text)
		: value(text)
	{
	}
	const std::string&			getValue() const
	{
		return value;
	}

private:
								Operation(const Operation& other);
	const std::string			value;
};

bool operator == (const Operation& a, const Operation& b)
{
	return &a == &b; // a fast & simple address comparison - making copies was disabled
}

// A namespace containing all SPIRV operations used in those tests.
namespace op {
#define OP(name) const Operation name("Op"#name)
	OP(Capability);
	OP(Extension);
	OP(ExtInstImport);
	OP(EntryPoint);
	OP(MemoryModel);
	OP(ExecutionMode);

	OP(Decorate);
	OP(MemberDecorate);
	OP(Name);
	OP(MemberName);

	OP(TypeVoid);
	OP(TypeBool);
	OP(TypeInt);
	OP(TypeFloat);
	OP(TypeVector);
	OP(TypeMatrix);
	OP(TypeArray);
	OP(TypeStruct);
	OP(TypeFunction);
	OP(TypePointer);
	OP(TypeImage);
	OP(TypeSampledImage);

	OP(Constant);
	OP(ConstantComposite);
	OP(Variable);

	OP(Function);
	OP(FunctionEnd);
	OP(Label);
	OP(Return);

	OP(LogicalEqual);
	OP(IEqual);
	OP(Select);

	OP(AccessChain);
	OP(Load);
	OP(Store);
#undef OP
}

// A class that allows to easily compose SPIRV code.
// This class automatically keeps correct order of most of operations
// i.e. capabilities to the top,
class ShaderStream
{
public:
								ShaderStream ()
	{}
	// composes shader string out of shader substreams.
	std::string					str () const
	{
		std::stringstream stream;
		stream << capabilities.str()
			<< "; ----------------- PREAMBLE -----------------\n"
			<< preamble.str()
			<< "; ----------------- DEBUG --------------------\n"
			<< names.str()
			<< "; ----------------- DECORATIONS --------------\n"
			<< decorations.str()
			<< "; ----------------- TYPES --------------------\n"
			<< basictypes.str()
			<< "; ----------------- CONSTANTS ----------------\n"
			<< constants.str()
			<< "; ----------------- ADVANCED TYPES -----------\n"
			<< compositetypes.str()
			<< ((compositeconstants.str().length() > 0) ? "; ----------------- CONSTANTS ----------------\n" : "")
			<< compositeconstants.str()
			<< "; ----------------- VARIABLES & FUNCTIONS ----\n"
			<< shaderstream.str();
		return stream.str();
	}
	// Functions below are used to push Operations, Variables and other strings, numbers and characters to the shader.
	// Each function uses selectStream and map subroutines.
	// selectStream is used to choose a proper substream of shader.
	// E.g. if an operation is OpConstant it should be put into constants definitions stream - so selectStream will return that stream.
	// map on the other hand is used to replace Variables and Operations to their in-SPIRV-code representations.
	// for types like ints or floats map simply calls << operator to produce its string representation
	// for Operations a proper operation string is returned
	// for Variables there is a special mapping between in-C++ variable and in-SPIRV-code variable name.
	// following sequence of functions could be squashed to just two using variadic templates once we move to C++11 or higher
	// each method returns *this to allow chaining calls to these methods.
	template <typename T>
	ShaderStream&				operator () (const T& a)
	{
		selectStream(a, 0) << map(a) << '\n';
		return *this;
	}
	template <typename T1, typename T2>
	ShaderStream&				operator () (const T1& a, const T2& b)
	{
		selectStream(a, 0) << map(a) << '\t' << map(b) << '\n';
		return *this;
	}
	template <typename T1, typename T2, typename T3>
	ShaderStream&				operator () (const T1& a, const T2& b, const T3& c)
	{
		selectStream(a, c) << map(a) << '\t' << map(b) << '\t' << map(c) << '\n';
		return *this;
	}
	template <typename T1, typename T2, typename T3, typename T4>
	ShaderStream&				operator () (const T1& a, const T2& b, const T3& c, const T4& d)
	{
		selectStream(a, c) << map(a) << '\t' << map(b) << '\t' << map(c) << '\t' << map(d) << '\n';
		return *this;
	}
	template <typename T1, typename T2, typename T3, typename T4, typename T5>
	ShaderStream&				operator () (const T1& a, const T2& b, const T3& c, const T4& d, const T5& e)
	{
		selectStream(a, c) << map(a) << '\t' << map(b) << '\t' << map(c) << '\t' << map(d) << '\t' << map(e) << '\n';
		return *this;
	}
	template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
	ShaderStream&				operator () (const T1& a, const T2& b, const T3& c, const T4& d, const T5& e, const T6& f)
	{
		selectStream(a, c) << map(a) << '\t' << map(b) << '\t' << map(c) << '\t' << map(d) << '\t' << map(e) << '\t' << map(f) << '\n';
		return *this;
	}
	template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
	ShaderStream&				operator () (const T1& a, const T2& b, const  T3& c, const T4& d, const T5& e, const T6& f, const T7& g)
	{
		selectStream(a, c) << map(a) << '\t' << map(b) << '\t' << map(c) << '\t' << map(d) << '\t' << map(e) << '\t' << map(f) << '\t' << map(g) << '\n';
		return *this;
	}
	template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
	ShaderStream&				operator () (const T1& a, const T2& b, const  T3& c, const T4& d, const T5& e, const T6& f, const T7& g, const T8& h)
	{
		selectStream(a, c) << map(a) << '\t' << map(b) << '\t' << map(c) << '\t' << map(d) << '\t' << map(e) << '\t' << map(f) << '\t' << map(g) << '\t' << map(h) << '\n';
		return *this;
	}
	template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
	ShaderStream&				operator () (const T1& a, const T2& b, const  T3& c, const T4& d, const T5& e, const T6& f, const T7& g, const T8& h, const T9& i)
	{
		selectStream(a, c) << map(a) << '\t' << map(b) << '\t' << map(c) << '\t' << map(d) << '\t' << map(e) << '\t' << map(f) << '\t' << map(g) << '\t' << map(h) << '\t' << map(i) << '\n';
		return *this;
	}
	template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
	ShaderStream&				operator () (const T1& a, const T2& b, const  T3& c, const T4& d, const T5& e, const T6& f, const T7& g, const T8& h, const T9& i, const T10& k)
	{
		selectStream(a, c) << map(a) << '\t' << map(b) << '\t' << map(c) << '\t' << map(d) << '\t' << map(e) << '\t' << map(f) << '\t' << map(g) << '\t' << map(h) << '\t' << map(i) << '\t' << map(k) << '\n';
		return *this;
	}

	// returns true if two variables has the same in-SPIRV-code names
	bool						areSame (const Variable a, const Variable b)
	{
		VariableIt varA = vars.find(a);
		VariableIt varB = vars.find(b);
		return varA != vars.end() && varB != vars.end() && varA->second == varB->second;
	}

	// makes variable 'a' in-SPIRV-code name to be the same as variable 'b' in-SPIRV-code name
	void						makeSame (const Variable a, const Variable b)
	{
		VariableIt varB = vars.find(b);
		if (varB != vars.end())
		{
			std::pair<VariableIt, bool> inserted = vars.insert(std::make_pair(a, varB->second));
			if (!inserted.second)
				inserted.first->second = varB->second;
		}
	}
private:
	// generic version of map (tries to push whatever came to stringstream to get its string representation)
	template <typename T>
	std::string					map (const T& a)
	{
		std::stringstream temp;
		temp << a;
		return temp.str();
	}

	// looks for mapping of c++ Variable object onto in-SPIRV-code name.
	// if there was not yet such mapping generated a new mapping is created based on incremented local counter.
	std::string					map (const Variable& a)
	{
		VariableIt var = vars.find(a);
		if (var != vars.end())
			return var->second;
		std::stringstream temp;
		temp << '%';
		temp.width(4);
		temp.fill('0');
		temp << std::hex << varCounter.incrementAndGetValue();
		vars.insert(std::make_pair(a, temp.str()));
		return temp.str();
	}

	// a simple specification for Operation
	std::string					map (const Operation& a)
	{
		return a.getValue();
	}

	// a specification for char* - faster than going through stringstream << operator
	std::string					map (const char*& a)
	{
		return std::string(a);
	}

	// a specification for char - faster than going through stringstream << operator
	std::string					map (const char& a)
	{
		return std::string(1, a);
	}

	// a generic version of selectStream - used when neither 1st nor 3rd SPIRV line token is Operation.
	// In general should never happen.
	// All SPIRV lines are constructed in a one of two forms:
	// Variable = Operation operands...
	// or
	// Operation operands...
	// So operation is either 1st or 3rd token.
	template <typename T0, typename T1>
	std::stringstream&			selectStream (const T0& op0, const T1& op1)
	{
		DE_UNREF(op0);
		DE_UNREF(op1);
		return shaderstream;
	}

	// Specialisation for Operation being 1st parameter
	// Certain operations make the SPIRV code line to be pushed to different substreams.
	template <typename T1>
	std::stringstream&			selectStream (const Operation& op, const T1& op1)
	{
		DE_UNREF(op1);
		if (op == op::Decorate || op == op::MemberDecorate)
			return decorations;
		if (op == op::Name || op == op::MemberName)
			return names;
		if (op == op::Capability || op == op::Extension)
			return capabilities;
		if (op == op::MemoryModel || op == op::ExecutionMode || op == op::EntryPoint)
			return preamble;
		return shaderstream;
	}

	// Specialisation for Operation being 3rd parameter
	// Certain operations make the SPIRV code line to be pushed to different substreams.
	// If we would like to use this way of generating SPIRV we could use this method as SPIRV line validation point
	// e.g. here instead of heving partial specialisation I could specialise for T0 being Variable since this has to match Variable = Operation operands...
	template <typename T0>
	std::stringstream&			selectStream (const T0& op0, const Operation& op)
	{
		DE_UNREF(op0);
		if (op == op::ExtInstImport)
			return preamble;
		if (op == op::TypeVoid || op == op::TypeBool || op == op::TypeInt || op == op::TypeFloat || op == op::TypeVector || op == op::TypeMatrix)
			return basictypes;
		if (op == op::TypeArray || op == op::TypeStruct || op == op::TypeFunction || op == op::TypePointer || op == op::TypeImage || op == op::TypeSampledImage)
			return compositetypes;
		if (op == op::Constant)
			return constants;
		if (op == op::ConstantComposite)
			return compositeconstants;
		return shaderstream;
	}

	typedef std::map<Variable, std::string>	VariablesPack;
	typedef VariablesPack::iterator			VariableIt;

	// local mappings between c++ Variable objects and in-SPIRV-code names
	VariablesPack				vars;

	// shader substreams
	std::stringstream			capabilities;
	std::stringstream			preamble;
	std::stringstream			names;
	std::stringstream			decorations;
	std::stringstream			basictypes;
	std::stringstream			constants;
	std::stringstream			compositetypes;
	std::stringstream			compositeconstants;
	std::stringstream			shaderstream;

	// local incremented counter
	Autocounter					varCounter;
};

// A suppliementary class to group frequently used Variables together
class Variables
{
public:
								Variables (Autocounter &autoincrement)
		: version(autoincrement)
		, mainFunc(autoincrement)
		, mainFuncLabel(autoincrement)
		, voidFuncVoid(autoincrement)
		, copy_type(autoincrement)
		, copy_type_vec(autoincrement)
		, buffer_type_vec(autoincrement)
		, copy_type_ptr(autoincrement)
		, buffer_type(autoincrement)
		, voidId(autoincrement)
		, v4f32(autoincrement)
		, v4s32(autoincrement)
		, v4u32(autoincrement)
		, v4s64(autoincrement)
		, v4u64(autoincrement)
		, s32(autoincrement)
		, f32(autoincrement)
		, u32(autoincrement)
		, s64(autoincrement)
		, u64(autoincrement)
		, boolean(autoincrement)
		, array_content_type(autoincrement)
		, s32_type_ptr(autoincrement)
		, dataSelectorStructPtrType(autoincrement)
		, dataSelectorStructPtr(autoincrement)
		, dataArrayType(autoincrement)
		, dataInput(autoincrement)
		, dataInputPtrType(autoincrement)
		, dataInputType(autoincrement)
		, dataInputSampledType(autoincrement)
		, dataOutput(autoincrement)
		, dataOutputPtrType(autoincrement)
		, dataOutputType(autoincrement)
		, dataSelectorStructType(autoincrement)
		, input(autoincrement)
		, inputPtr(autoincrement)
		, output(autoincrement)
		, outputPtr(autoincrement)
	{
		for (deUint32 i = 0; i < 32; ++i)
			constants.push_back(Variable(autoincrement));
	}
	const Variable				version;
	const Variable				mainFunc;
	const Variable				mainFuncLabel;
	const Variable				voidFuncVoid;
	std::vector<Variable>		constants;
	const Variable				copy_type;
	const Variable				copy_type_vec;
	const Variable				buffer_type_vec;
	const Variable				copy_type_ptr;
	const Variable				buffer_type;
	const Variable				voidId;
	const Variable				v4f32;
	const Variable				v4s32;
	const Variable				v4u32;
	const Variable				v4s64;
	const Variable				v4u64;
	const Variable				s32;
	const Variable				f32;
	const Variable				u32;
	const Variable				s64;
	const Variable				u64;
	const Variable				boolean;
	const Variable				array_content_type;
	const Variable				s32_type_ptr;
	const Variable				dataSelectorStructPtrType;
	const Variable				dataSelectorStructPtr;
	const Variable				dataArrayType;
	const Variable				dataInput;
	const Variable				dataInputPtrType;
	const Variable				dataInputType;
	const Variable				dataInputSampledType;
	const Variable				dataOutput;
	const Variable				dataOutputPtrType;
	const Variable				dataOutputType;
	const Variable				dataSelectorStructType;
	const Variable				input;
	const Variable				inputPtr;
	const Variable				output;
	const Variable				outputPtr;
};

// A routing generating SPIRV code for all test cases in this group
std::string MakeShader(VkShaderStageFlags shaderStage, ShaderType shaderType, VkFormat bufferFormat, bool reads, bool dummy)
{
	const bool					isR64				= (bufferFormat == VK_FORMAT_R64_UINT || bufferFormat == VK_FORMAT_R64_SINT);
	// faster to write
	const char					is					= '=';

	// variables require such counter to generate their unique ids. Since there is possibility that in the future this code will
	// run parallel this counter is made local to this function body to be safe.
	Autocounter					localcounter;

	// A frequently used Variables (gathered into this single object for readability)
	Variables					var					(localcounter);

	// A SPIRV code builder
	ShaderStream				shaderSource;

	// A basic preamble of SPIRV shader. Turns on required capabilities and extensions.
	shaderSource
	(op::Capability, "Shader")
	(op::Capability, "VariablePointersStorageBuffer");

	if (isR64)
	{
		shaderSource
		(op::Capability, "Int64");
	}

	shaderSource
	(op::Extension, "\"SPV_KHR_storage_buffer_storage_class\"")
	(op::Extension, "\"SPV_KHR_variable_pointers\"")
	(var.version, is, op::ExtInstImport, "\"GLSL.std.450\"")
	(op::MemoryModel, "Logical", "GLSL450");

	// Use correct entry point definition depending on shader stage
	if (shaderStage == VK_SHADER_STAGE_COMPUTE_BIT)
	{
		shaderSource
		(op::EntryPoint, "GLCompute", var.mainFunc, "\"main\"")
		(op::ExecutionMode, var.mainFunc, "LocalSize", 1, 1, 1);
	}
	else if (shaderStage == VK_SHADER_STAGE_VERTEX_BIT)
	{
		shaderSource
		(op::EntryPoint, "Vertex", var.mainFunc, "\"main\"", var.input, var.output)
		(op::Decorate, var.output, "BuiltIn", "Position")
		(op::Decorate, var.input, "Location", 0);
	}
	else if (shaderStage == VK_SHADER_STAGE_FRAGMENT_BIT)
	{
		shaderSource
		(op::EntryPoint, "Fragment", var.mainFunc, "\"main\"", var.output)
		(op::ExecutionMode, var.mainFunc, "OriginUpperLeft")
		(op::Decorate, var.output, "Location", 0);
	}

	// If we are testing vertex shader or fragment shader we need to provide the other one for the pipeline too.
	// So the not tested one is 'dummy'. It is then a minimal/simplest possible pass-through shader.
	// If we are testing compute shader we dont need dummy shader at all.
	if (dummy)
	{
		if (shaderStage == VK_SHADER_STAGE_FRAGMENT_BIT)
		{
			shaderSource
			(var.voidId, is, op::TypeVoid)
			(var.voidFuncVoid, is, op::TypeFunction, var.voidId)
			(var.f32, is, op::TypeFloat, 32)
			(var.v4f32, is, op::TypeVector, var.f32, 4)
			(var.outputPtr, is, op::TypePointer, "Output", var.v4f32)
			(var.output, is, op::Variable, var.outputPtr, "Output")
			(var.constants[6], is, op::Constant, var.f32, 1)
			(var.constants[7], is, op::ConstantComposite, var.v4f32, var.constants[6], var.constants[6], var.constants[6], var.constants[6])
			(var.mainFunc, is, op::Function, var.voidId, "None", var.voidFuncVoid)
			(var.mainFuncLabel, is, op::Label);
		}
		else if (shaderStage == VK_SHADER_STAGE_VERTEX_BIT)
		{
			shaderSource
			(var.voidId, is, op::TypeVoid)
			(var.voidFuncVoid, is, op::TypeFunction , var.voidId)
			(var.f32, is, op::TypeFloat, 32)
			(var.v4f32, is, op::TypeVector , var.f32, 4)
			(var.outputPtr, is, op::TypePointer, "Output" , var.v4f32)
			(var.output, is, op::Variable , var.outputPtr, "Output")
			(var.inputPtr, is, op::TypePointer, "Input" , var.v4f32)
			(var.input, is, op::Variable , var.inputPtr, "Input")
			(var.mainFunc, is, op::Function , var.voidId, "None", var.voidFuncVoid)
			(var.mainFuncLabel, is, op::Label);
		}
	}
	else // this is a start of actual shader that tests variable pointers
	{
		shaderSource
		(op::Decorate, var.dataInput, "DescriptorSet", 0)
		(op::Decorate, var.dataInput, "Binding", 0)

		(op::Decorate, var.dataOutput, "DescriptorSet", 0)
		(op::Decorate, var.dataOutput, "Binding", 1);

		// for scalar types and vector types we use 1024 element array of 4 elements arrays of 4-component vectors
		// so the stride of internal array is size of 4-component vector
		if (shaderType == SHADER_TYPE_SCALAR_COPY || shaderType == SHADER_TYPE_VECTOR_COPY)
		{
			if (isR64)
			{
				shaderSource
				(op::Decorate, var.array_content_type, "ArrayStride", 32);
			}
			else
			{
				shaderSource
				(op::Decorate, var.array_content_type, "ArrayStride", 16);
			}
		}

		if (isR64)
		{
			shaderSource
			(op::Decorate, var.dataArrayType, "ArrayStride", 128);
		}
		else
		{
			// for matrices we use array of 4x4-component matrices
			// stride of outer array is then 64 in every case
			shaderSource
			(op::Decorate, var.dataArrayType, "ArrayStride", 64);
		}

		// an output block
		shaderSource
		(op::MemberDecorate, var.dataOutputType, 0, "Offset", 0)
		(op::Decorate, var.dataOutputType, "Block")

		// an input block. Marked readonly.
		(op::MemberDecorate, var.dataInputType, 0, "NonWritable")
		(op::MemberDecorate, var.dataInputType, 0, "Offset", 0)
		(op::Decorate, var.dataInputType, "Block")

		//a special structure matching data in one of our buffers.
		// member at 0 is an index to read position
		// member at 1 is an index to write position
		// member at 2 is always zero. It is used to perform OpSelect. I used value coming from buffer to avoid incidental optimisations that could prune OpSelect if the value was compile time known.
		(op::MemberDecorate, var.dataSelectorStructType, 0, "Offset", 0)
		(op::MemberDecorate, var.dataSelectorStructType, 1, "Offset", 4)
		(op::MemberDecorate, var.dataSelectorStructType, 2, "Offset", 8)
		(op::Decorate, var.dataSelectorStructType, "Block")

		// binding to matching buffer
		(op::Decorate, var.dataSelectorStructPtr, "DescriptorSet", 0)
		(op::Decorate, var.dataSelectorStructPtr, "Binding", 2)

		// making composite types used in shader
		(var.voidId, is, op::TypeVoid)
		(var.voidFuncVoid, is, op::TypeFunction, var.voidId)

		(var.boolean, is, op::TypeBool)

		(var.f32, is, op::TypeFloat, 32)
		(var.s32, is, op::TypeInt, 32, 1)
		(var.u32, is, op::TypeInt, 32, 0);

		if (isR64)
		{
			shaderSource
			(var.s64, is, op::TypeInt, 64, 1)
			(var.u64, is, op::TypeInt, 64, 0);
		}

		shaderSource
		(var.v4f32, is, op::TypeVector, var.f32, 4)
		(var.v4s32, is, op::TypeVector, var.s32, 4)
		(var.v4u32, is, op::TypeVector, var.u32, 4);

		if (isR64)
		{
			shaderSource
			(var.v4s64, is, op::TypeVector, var.s64, 4)
			(var.v4u64, is, op::TypeVector, var.u64, 4);
		}

		// since the shared tests scalars, vectors, matrices of ints, uints and floats I am generating alternative names for some of the types so I can use those and not need to use "if" everywhere.
		// A Variable mappings will make sure the proper variable name is used
		// below is a first part of aliasing types based on int, uint, float
		switch (bufferFormat)
		{
		case vk::VK_FORMAT_R32_SINT:
			shaderSource.makeSame(var.buffer_type, var.s32);
			shaderSource.makeSame(var.buffer_type_vec, var.v4s32);
			break;
		case vk::VK_FORMAT_R32_UINT:
			shaderSource.makeSame(var.buffer_type, var.u32);
			shaderSource.makeSame(var.buffer_type_vec, var.v4u32);
			break;
		case vk::VK_FORMAT_R32_SFLOAT:
			shaderSource.makeSame(var.buffer_type, var.f32);
			shaderSource.makeSame(var.buffer_type_vec, var.v4f32);
			break;
		case vk::VK_FORMAT_R64_SINT:
			shaderSource.makeSame(var.buffer_type, var.s64);
			shaderSource.makeSame(var.buffer_type_vec, var.v4s64);
			break;
		case vk::VK_FORMAT_R64_UINT:
			shaderSource.makeSame(var.buffer_type, var.u64);
			shaderSource.makeSame(var.buffer_type_vec, var.v4u64);
			break;
		default:
			// to prevent compiler from complaining not all cases are handled (but we should not get here).
			deAssertFail("This point should be not reachable with correct program flow.", __FILE__, __LINE__);
			break;
		}

		// below is a second part that aliases based on scalar, vector, matrix
		switch (shaderType)
		{
		case SHADER_TYPE_SCALAR_COPY:
			shaderSource.makeSame(var.copy_type, var.buffer_type);
			break;
		case SHADER_TYPE_VECTOR_COPY:
			shaderSource.makeSame(var.copy_type, var.buffer_type_vec);
			break;
		case SHADER_TYPE_MATRIX_COPY:
			if (bufferFormat != VK_FORMAT_R32_SFLOAT)
				TCU_THROW(NotSupportedError, "Matrices can be used only with floating point types.");
			shaderSource
			(var.copy_type, is, op::TypeMatrix, var.buffer_type_vec, 4);
			break;
		default:
			// to prevent compiler from complaining not all cases are handled (but we should not get here).
			deAssertFail("This point should be not reachable with correct program flow.", __FILE__, __LINE__);
			break;
		}

		// I will need some constants so lets add them to shader source
		shaderSource
		(var.constants[0], is, op::Constant, var.s32, 0)
		(var.constants[1], is, op::Constant, var.s32, 1)
		(var.constants[2], is, op::Constant, var.s32, 2)
		(var.constants[3], is, op::Constant, var.s32, 3)
		(var.constants[4], is, op::Constant, var.u32, 4)
		(var.constants[5], is, op::Constant, var.u32, 1024);

		// for fragment shaders I need additionally a constant vector (output "colour") so lets make it
		if (shaderStage == VK_SHADER_STAGE_FRAGMENT_BIT)
		{
			shaderSource
			(var.constants[6], is, op::Constant, var.f32, 1)
			(var.constants[7], is, op::ConstantComposite, var.v4f32, var.constants[6], var.constants[6], var.constants[6], var.constants[6]);
		}

		// additional alias for the type of content of this 1024-element outer array.
		if (shaderType == SHADER_TYPE_SCALAR_COPY || shaderType == SHADER_TYPE_VECTOR_COPY)
		{
			shaderSource
			(var.array_content_type, is, op::TypeArray, var.buffer_type_vec, var.constants[4]);
		}
		else
		{
			shaderSource.makeSame(var.array_content_type, var.copy_type);
		}

		// Lets create pointer types to the input data type, output data type and a struct
		// This must be distinct types due to different type decorations
		// Lets make also actual poiters to the data
		shaderSource
		(var.dataArrayType, is, op::TypeArray, var.array_content_type, var.constants[5])
		(var.dataInputType, is, op::TypeStruct, var.dataArrayType)
		(var.dataOutputType, is, op::TypeStruct, var.dataArrayType)
		(var.dataInputPtrType, is, op::TypePointer, "StorageBuffer", var.dataInputType)
		(var.dataOutputPtrType, is, op::TypePointer, "StorageBuffer", var.dataOutputType)
		(var.dataInput, is, op::Variable, var.dataInputPtrType, "StorageBuffer")
		(var.dataOutput, is, op::Variable, var.dataOutputPtrType, "StorageBuffer")
		(var.dataSelectorStructType, is, op::TypeStruct, var.s32, var.s32, var.s32)
		(var.dataSelectorStructPtrType, is, op::TypePointer, "Uniform", var.dataSelectorStructType)
		(var.dataSelectorStructPtr, is, op::Variable, var.dataSelectorStructPtrType, "Uniform");

		// we need also additional pointers to fullfil stage requirements on shaders inputs and outputs
		if (shaderStage == VK_SHADER_STAGE_VERTEX_BIT)
		{
			shaderSource
			(var.inputPtr, is, op::TypePointer, "Input", var.v4f32)
			(var.input, is, op::Variable, var.inputPtr, "Input")
			(var.outputPtr, is, op::TypePointer, "Output", var.v4f32)
			(var.output, is, op::Variable, var.outputPtr, "Output");
		}
		else if (shaderStage == VK_SHADER_STAGE_FRAGMENT_BIT)
		{
			shaderSource
			(var.outputPtr, is, op::TypePointer, "Output", var.v4f32)
			(var.output, is, op::Variable, var.outputPtr, "Output");
		}

		shaderSource
		(var.copy_type_ptr, is, op::TypePointer, "StorageBuffer", var.copy_type)
		(var.s32_type_ptr, is, op::TypePointer, "Uniform", var.s32);

		// Make a shader main function
		shaderSource
		(var.mainFunc, is, op::Function, var.voidId, "None", var.voidFuncVoid)
		(var.mainFuncLabel, is, op::Label);

		Variable copyFromPtr(localcounter), copyToPtr(localcounter), zeroPtr(localcounter);
		Variable copyFrom(localcounter), copyTo(localcounter), zero(localcounter);

		// Lets load data from our auxiliary buffer with reading index, writing index and zero.
		shaderSource
		(copyToPtr, is, op::AccessChain, var.s32_type_ptr, var.dataSelectorStructPtr, var.constants[1])
		(copyTo, is, op::Load, var.s32, copyToPtr)
		(copyFromPtr, is, op::AccessChain, var.s32_type_ptr, var.dataSelectorStructPtr, var.constants[0])
		(copyFrom, is, op::Load, var.s32, copyFromPtr)
		(zeroPtr, is, op::AccessChain, var.s32_type_ptr, var.dataSelectorStructPtr, var.constants[2])
		(zero, is, op::Load, var.s32, zeroPtr);

		// let start copying data using variable pointers
		switch (shaderType)
		{
		case SHADER_TYPE_SCALAR_COPY:
			for (int i = 0; i < 4; ++i)
			{
				for (int j = 0; j < 4; ++j)
				{
					Variable actualLoadChain(localcounter), actualStoreChain(localcounter), loadResult(localcounter);
					Variable selection(localcounter);
					Variable lcA(localcounter), lcB(localcounter), scA(localcounter), scB(localcounter);

					shaderSource
					(selection, is, op::IEqual, var.boolean, zero, var.constants[0]);

					if (reads)
					{
						// if we check reads we use variable pointers only for reading part
						shaderSource
						(lcA, is, op::AccessChain, var.copy_type_ptr, var.dataInput, var.constants[0], copyFrom, var.constants[i], var.constants[j])
						(lcB, is, op::AccessChain, var.copy_type_ptr, var.dataInput, var.constants[0], copyFrom, var.constants[i], var.constants[j])
						// actualLoadChain will be a variable pointer as it was created through OpSelect
						(actualLoadChain, is, op::Select, var.copy_type_ptr, selection, lcA, lcB)
						// actualStoreChain will be a regular pointer
						(actualStoreChain, is, op::AccessChain, var.copy_type_ptr, var.dataOutput, var.constants[0], copyTo, var.constants[i], var.constants[j]);
					}
					else
					{
						// if we check writes we use variable pointers only for writing part only
						shaderSource
						// actualLoadChain will be regular regualar pointer
						(actualLoadChain, is, op::AccessChain, var.copy_type_ptr, var.dataInput, var.constants[0], copyFrom, var.constants[i], var.constants[j])
						(scA, is, op::AccessChain, var.copy_type_ptr, var.dataOutput, var.constants[0], copyTo, var.constants[i], var.constants[j])
						(scB, is, op::AccessChain, var.copy_type_ptr, var.dataOutput, var.constants[0], copyTo, var.constants[i], var.constants[j])
						// actualStoreChain will be a variable pointer as it was created through OpSelect
						(actualStoreChain, is, op::Select, var.copy_type_ptr, selection, scA, scB);
					}
					// do actual copying
					shaderSource
					(loadResult, is, op::Load, var.copy_type, actualLoadChain)
					(op::Store, actualStoreChain, loadResult);
				}
			}
			break;
		// cases below have the same logic as the one above - just we are copying bigger chunks of data with every load/store pair
		case SHADER_TYPE_VECTOR_COPY:
			for (int i = 0; i < 4; ++i)
			{
				Variable actualLoadChain(localcounter), actualStoreChain(localcounter), loadResult(localcounter);
				Variable selection(localcounter);
				Variable lcA(localcounter), lcB(localcounter), scA(localcounter), scB(localcounter);

				shaderSource
				(selection, is, op::IEqual, var.boolean, zero, var.constants[0]);

				if (reads)
				{
					shaderSource
					(lcA, is, op::AccessChain, var.copy_type_ptr, var.dataInput, var.constants[0], copyFrom, var.constants[i])
					(lcB, is, op::AccessChain, var.copy_type_ptr, var.dataInput, var.constants[0], copyFrom, var.constants[i])
					(actualLoadChain, is, op::Select, var.copy_type_ptr, selection, lcA, lcB)
					(actualStoreChain, is, op::AccessChain, var.copy_type_ptr, var.dataOutput, var.constants[0], copyTo, var.constants[i]);
				}
				else
				{
					shaderSource
					(actualLoadChain, is, op::AccessChain, var.copy_type_ptr, var.dataInput, var.constants[0], copyFrom, var.constants[i])
					(scA, is, op::AccessChain, var.copy_type_ptr, var.dataOutput, var.constants[0], copyTo, var.constants[i])
					(scB, is, op::AccessChain, var.copy_type_ptr, var.dataOutput, var.constants[0], copyTo, var.constants[i])
					(actualStoreChain, is, op::Select, var.copy_type_ptr, selection, scA, scB);
				}

				shaderSource
				(loadResult, is, op::Load, var.copy_type, actualLoadChain)
				(op::Store, actualStoreChain, loadResult);
			}
			break;
		case SHADER_TYPE_MATRIX_COPY:
			{
				Variable actualLoadChain(localcounter), actualStoreChain(localcounter), loadResult(localcounter);
				Variable selection(localcounter);
				Variable lcA(localcounter), lcB(localcounter), scA(localcounter), scB(localcounter);

				shaderSource
				(selection, is, op::IEqual, var.boolean, zero, var.constants[0]);

				if (reads)
				{
					shaderSource
					(lcA, is, op::AccessChain, var.copy_type_ptr, var.dataInput, var.constants[0], copyFrom)
					(lcB, is, op::AccessChain, var.copy_type_ptr, var.dataInput, var.constants[0], copyFrom)
					(actualLoadChain, is, op::Select, var.copy_type_ptr, selection, lcA, lcB)
					(actualStoreChain, is, op::AccessChain, var.copy_type_ptr, var.dataOutput, var.constants[0], copyTo);
				}
				else
				{
					shaderSource
					(actualLoadChain, is, op::AccessChain, var.copy_type_ptr, var.dataInput, var.constants[0], copyFrom)
					(scA, is, op::AccessChain, var.copy_type_ptr, var.dataOutput, var.constants[0], copyTo)
					(scB, is, op::AccessChain, var.copy_type_ptr, var.dataOutput, var.constants[0], copyTo)
					(actualStoreChain, is, op::Select, var.copy_type_ptr, selection, scA, scB);
				}

				shaderSource
				(loadResult, is, op::Load, var.copy_type, actualLoadChain)
				(op::Store, actualStoreChain, loadResult);
			}
			break;
		default:
			// to prevent compiler from complaining not all cases are handled (but we should not get here).
			deAssertFail("This point should be not reachable with correct program flow.", __FILE__, __LINE__);
			break;
		}
	}

	// This is common for test shaders and dummy ones
	// We need to fill stage ouput from shader properly
	// output vertices positions in vertex shader
	if (shaderStage == VK_SHADER_STAGE_VERTEX_BIT)
	{
		Variable inputValue(localcounter), outputLocation(localcounter);
		shaderSource
		(inputValue, is, op::Load, var.v4f32, var.input)
		(outputLocation, is, op::AccessChain, var.outputPtr, var.output)
		(op::Store, outputLocation, inputValue);
	}
	// output colour in fragment shader
	else if (shaderStage == VK_SHADER_STAGE_FRAGMENT_BIT)
	{
		shaderSource
		(op::Store, var.output, var.constants[7]);
	}

	// We are done. Lets close main function body
	shaderSource
	(op::Return)
	(op::FunctionEnd);

	return shaderSource.str();
}

RobustReadTest::RobustReadTest (tcu::TestContext&		testContext,
								const std::string&		name,
								const std::string&		description,
								VkShaderStageFlags		shaderStage,
								ShaderType				shaderType,
								VkFormat				bufferFormat,
								VkDeviceSize			readAccessRange,
								bool					accessOutOfBackingMemory)
	: RobustAccessWithPointersTest	(testContext, name, description, shaderStage, shaderType, bufferFormat)
	, m_readAccessRange				(readAccessRange)
	, m_accessOutOfBackingMemory	(accessOutOfBackingMemory)
{
}

TestInstance* RobustReadTest::createInstance (Context& context) const
{
	auto device = createRobustBufferAccessVariablePointersDevice(context);
	return new ReadInstance(context, device, m_shaderType, m_shaderStage, m_bufferFormat, m_readAccessRange, m_accessOutOfBackingMemory);
}

void RobustReadTest::initPrograms(SourceCollections&	programCollection) const
{
	if (m_shaderStage == VK_SHADER_STAGE_COMPUTE_BIT)
	{
		programCollection.spirvAsmSources.add("compute") << MakeShader(VK_SHADER_STAGE_COMPUTE_BIT, m_shaderType, m_bufferFormat, true, false);
	}
	else
	{
		programCollection.spirvAsmSources.add("vertex") << MakeShader(VK_SHADER_STAGE_VERTEX_BIT, m_shaderType, m_bufferFormat, true, m_shaderStage != VK_SHADER_STAGE_VERTEX_BIT);
		programCollection.spirvAsmSources.add("fragment") << MakeShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_shaderType, m_bufferFormat, true, m_shaderStage != VK_SHADER_STAGE_FRAGMENT_BIT);
	}
}

RobustWriteTest::RobustWriteTest (tcu::TestContext&		testContext,
								  const std::string&	name,
								  const std::string&	description,
								  VkShaderStageFlags	shaderStage,
								  ShaderType			shaderType,
								  VkFormat				bufferFormat,
								  VkDeviceSize			writeAccessRange,
								  bool					accessOutOfBackingMemory)

	: RobustAccessWithPointersTest	(testContext, name, description, shaderStage, shaderType, bufferFormat)
	, m_writeAccessRange			(writeAccessRange)
	, m_accessOutOfBackingMemory	(accessOutOfBackingMemory)
{
}

TestInstance* RobustWriteTest::createInstance (Context& context) const
{
	auto device = createRobustBufferAccessVariablePointersDevice(context);
	return new WriteInstance(context, device, m_shaderType, m_shaderStage, m_bufferFormat, m_writeAccessRange, m_accessOutOfBackingMemory);
}

void RobustWriteTest::initPrograms(SourceCollections&	programCollection) const
{
	if (m_shaderStage == VK_SHADER_STAGE_COMPUTE_BIT)
	{
		programCollection.spirvAsmSources.add("compute") << MakeShader(VK_SHADER_STAGE_COMPUTE_BIT, m_shaderType, m_bufferFormat, false, false);
	}
	else
	{
		programCollection.spirvAsmSources.add("vertex") << MakeShader(VK_SHADER_STAGE_VERTEX_BIT, m_shaderType, m_bufferFormat, false, m_shaderStage != VK_SHADER_STAGE_VERTEX_BIT);
		programCollection.spirvAsmSources.add("fragment") << MakeShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_shaderType, m_bufferFormat, false, m_shaderStage != VK_SHADER_STAGE_FRAGMENT_BIT);
	}
}

AccessInstance::AccessInstance (Context&			context,
								Move<VkDevice>		device,
								ShaderType			shaderType,
								VkShaderStageFlags	shaderStage,
								VkFormat			bufferFormat,
								BufferAccessType	bufferAccessType,
								VkDeviceSize		inBufferAccessRange,
								VkDeviceSize		outBufferAccessRange,
								bool				accessOutOfBackingMemory)
	: vkt::TestInstance				(context)
	, m_device						(device)
	, m_shaderType					(shaderType)
	, m_shaderStage					(shaderStage)
	, m_bufferFormat				(bufferFormat)
	, m_bufferAccessType			(bufferAccessType)
	, m_accessOutOfBackingMemory	(accessOutOfBackingMemory)
{
	tcu::TestLog&									log						= context.getTestContext().getLog();
	const DeviceInterface&							vk						= context.getDeviceInterface();
	const deUint32									queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
	SimpleAllocator									memAlloc				(vk, *m_device, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));

	DE_ASSERT(RobustAccessWithPointersTest::s_numberOfBytesAccessed % sizeof(deUint32) == 0);
	DE_ASSERT(inBufferAccessRange <= RobustAccessWithPointersTest::s_numberOfBytesAccessed);
	DE_ASSERT(outBufferAccessRange <= RobustAccessWithPointersTest::s_numberOfBytesAccessed);

	if (m_bufferFormat == VK_FORMAT_R64_UINT || m_bufferFormat == VK_FORMAT_R64_SINT)
	{
		context.requireDeviceFunctionality("VK_EXT_shader_image_atomic_int64");
	}

	// Check storage support
	if (shaderStage == VK_SHADER_STAGE_VERTEX_BIT)
	{
		if (!context.getDeviceFeatures().vertexPipelineStoresAndAtomics)
		{
			TCU_THROW(NotSupportedError, "Stores not supported in vertex stage");
		}
	}
	else if (shaderStage == VK_SHADER_STAGE_FRAGMENT_BIT)
	{
		if (!context.getDeviceFeatures().fragmentStoresAndAtomics)
		{
			TCU_THROW(NotSupportedError, "Stores not supported in fragment stage");
		}
	}

	createTestBuffer(vk, *m_device, inBufferAccessRange, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, memAlloc, m_inBuffer, m_inBufferAlloc, m_inBufferAccess, &populateBufferWithValues, &m_bufferFormat);
	createTestBuffer(vk, *m_device, outBufferAccessRange, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, memAlloc, m_outBuffer, m_outBufferAlloc, m_outBufferAccess, &populateBufferWithDummy, DE_NULL);

	deInt32 indices[] = {
		(m_accessOutOfBackingMemory && (m_bufferAccessType == BUFFER_ACCESS_TYPE_READ_FROM_STORAGE)) ? static_cast<deInt32>(RobustAccessWithPointersTest::s_testArraySize) - 1 : 0,
		(m_accessOutOfBackingMemory && (m_bufferAccessType == BUFFER_ACCESS_TYPE_WRITE_TO_STORAGE)) ? static_cast<deInt32>(RobustAccessWithPointersTest::s_testArraySize) - 1 : 0,
		0
	};
	AccessRangesData indicesAccess;
	createTestBuffer(vk, *m_device, 3 * sizeof(deInt32), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memAlloc, m_indicesBuffer, m_indicesBufferAlloc, indicesAccess, &populateBufferWithCopy, &indices);

	log << tcu::TestLog::Message << "input  buffer - alloc size: " << m_inBufferAccess.allocSize << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "input  buffer - max access range: " << m_inBufferAccess.maxAccessRange << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "output buffer - alloc size: " << m_outBufferAccess.allocSize << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "output buffer - max access range: " << m_outBufferAccess.maxAccessRange << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "indices - input offset: " << indices[0] << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "indices - output offset: " << indices[1] << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "indices - additional: " << indices[2] << tcu::TestLog::EndMessage;

	// Create descriptor data
	{
		DescriptorPoolBuilder						descriptorPoolBuilder;
		descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u);
		descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u);
		descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u);
		m_descriptorPool = descriptorPoolBuilder.build(vk, *m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

		DescriptorSetLayoutBuilder					setLayoutBuilder;
		setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
		setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
		setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_ALL);
		m_descriptorSetLayout = setLayoutBuilder.build(vk, *m_device);

		const VkDescriptorSetAllocateInfo			descriptorSetAllocateInfo =
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType	sType;
			DE_NULL,								// const void*					pNext;
			*m_descriptorPool,						// VkDescriptorPool				descriptorPool;
			1u,										// deUint32						setLayoutCount;
			&m_descriptorSetLayout.get()			// const VkDescriptorSetLayout*	pSetLayouts;
		};

		m_descriptorSet = allocateDescriptorSet(vk, *m_device, &descriptorSetAllocateInfo);

		const VkDescriptorBufferInfo				inBufferDescriptorInfo			= makeDescriptorBufferInfo(*m_inBuffer, 0ull, m_inBufferAccess.accessRange);
		const VkDescriptorBufferInfo				outBufferDescriptorInfo			= makeDescriptorBufferInfo(*m_outBuffer, 0ull, m_outBufferAccess.accessRange);
		const VkDescriptorBufferInfo				indicesBufferDescriptorInfo		= makeDescriptorBufferInfo(*m_indicesBuffer, 0ull, 12ull);

		DescriptorSetUpdateBuilder					setUpdateBuilder;
		setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inBufferDescriptorInfo);
		setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outBufferDescriptorInfo);
		setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &indicesBufferDescriptorInfo);
		setUpdateBuilder.update(vk, *m_device);
	}

	// Create fence
	{
		const VkFenceCreateInfo fenceParams =
		{
			VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType			sType;
			DE_NULL,								// const void*				pNext;
			0u										// VkFenceCreateFlags		flags;
		};

		m_fence = createFence(vk, *m_device, &fenceParams);
	}

	// Get queue
	vk.getDeviceQueue(*m_device, queueFamilyIndex, 0, &m_queue);

	if (m_shaderStage == VK_SHADER_STAGE_COMPUTE_BIT)
	{
		m_testEnvironment = de::MovePtr<TestEnvironment>(new ComputeEnvironment(m_context, *m_device, *m_descriptorSetLayout, *m_descriptorSet));
	}
	else
	{
		using tcu::Vec4;

		const VkVertexInputBindingDescription		vertexInputBindingDescription =
		{
			0u,										// deUint32					binding;
			sizeof(tcu::Vec4),						// deUint32					strideInBytes;
			VK_VERTEX_INPUT_RATE_VERTEX				// VkVertexInputStepRate	inputRate;
		};

		const VkVertexInputAttributeDescription		vertexInputAttributeDescription =
		{
			0u,										// deUint32	location;
			0u,										// deUint32	binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,			// VkFormat	format;
			0u										// deUint32	offset;
		};

		AccessRangesData							vertexAccess;
		const Vec4									vertices[] =
		{
			Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
			Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
			Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
		};
		const VkDeviceSize							vertexBufferSize = static_cast<VkDeviceSize>(sizeof(vertices));
		createTestBuffer(vk, *m_device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, memAlloc, m_vertexBuffer, m_vertexBufferAlloc, vertexAccess, &populateBufferWithCopy, &vertices);

		const GraphicsEnvironment::DrawConfig		drawWithOneVertexBuffer =
		{
			std::vector<VkBuffer>(1, *m_vertexBuffer), // std::vector<VkBuffer>	vertexBuffers;
			DE_LENGTH_OF_ARRAY(vertices),			// deUint32					vertexCount;
			1,										// deUint32					instanceCount;
			DE_NULL,								// VkBuffer					indexBuffer;
			0u,										// deUint32					indexCount;
		};

		m_testEnvironment = de::MovePtr<TestEnvironment>(new GraphicsEnvironment(m_context,
																				 *m_device,
																				 *m_descriptorSetLayout,
																				 *m_descriptorSet,
																				 GraphicsEnvironment::VertexBindings(1, vertexInputBindingDescription),
																				 GraphicsEnvironment::VertexAttributes(1, vertexInputAttributeDescription),
																				 drawWithOneVertexBuffer));
	}
}

// Verifies if the buffer has the value initialized by BufferAccessInstance::populateReadBuffer at a given offset.
bool AccessInstance::isExpectedValueFromInBuffer (VkDeviceSize	offsetInBytes,
												  const void*	valuePtr,
												  VkDeviceSize	valueSize)
{
	DE_ASSERT(offsetInBytes % 4 == 0);
	DE_ASSERT(offsetInBytes < m_inBufferAccess.allocSize);
	DE_ASSERT(valueSize == 4ull || valueSize == 8ull);

	const deUint32 valueIndex = deUint32(offsetInBytes / 4) + 2;

	if (isUintFormat(m_bufferFormat))
	{
		const deUint32 expectedValues[2] = { valueIndex, valueIndex + 1u };
		return !deMemCmp(valuePtr, &expectedValues, (size_t)valueSize);
	}
	else if (isIntFormat(m_bufferFormat))
	{
		const deInt32 value				= -deInt32(valueIndex);
		const deInt32 expectedValues[2]	= { value, value - 1 };
		return !deMemCmp(valuePtr, &expectedValues, (size_t)valueSize);
	}
	else if (isFloatFormat(m_bufferFormat))
	{
		DE_ASSERT(valueSize == 4ull);
		const float value = float(valueIndex);
		return !deMemCmp(valuePtr, &value, (size_t)valueSize);
	}
	else
	{
		DE_ASSERT(false);
		return false;
	}
}

bool AccessInstance::isOutBufferValueUnchanged (VkDeviceSize offsetInBytes, VkDeviceSize valueSize)
{
	DE_ASSERT(valueSize <= 8);
	const deUint8 *const	outValuePtr		= (deUint8*)m_outBufferAlloc->getHostPtr() + offsetInBytes;
	const deUint64			defaultValue	= 0xBABABABABABABABAull;

	return !deMemCmp(outValuePtr, &defaultValue, (size_t)valueSize);
}

tcu::TestStatus AccessInstance::iterate (void)
{
	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const vk::VkCommandBuffer	cmdBuffer	= m_testEnvironment->getCommandBuffer();

	// Submit command buffer
	{
		const VkSubmitInfo	submitInfo	=
		{
			VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
			DE_NULL,						// const void*					pNext;
			0u,								// deUint32						waitSemaphoreCount;
			DE_NULL,						// const VkSemaphore*			pWaitSemaphores;
			DE_NULL,						// const VkPIpelineStageFlags*	pWaitDstStageMask;
			1u,								// deUint32						commandBufferCount;
			&cmdBuffer,						// const VkCommandBuffer*		pCommandBuffers;
			0u,								// deUint32						signalSemaphoreCount;
			DE_NULL							// const VkSemaphore*			pSignalSemaphores;
		};

		VK_CHECK(vk.resetFences(*m_device, 1, &m_fence.get()));
		VK_CHECK(vk.queueSubmit(m_queue, 1, &submitInfo, *m_fence));
		VK_CHECK(vk.waitForFences(*m_device, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
	}

	// Prepare result buffer for read
	{
		const VkMappedMemoryRange	outBufferRange	=
		{
			VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,	//  VkStructureType	sType;
			DE_NULL,								//  const void*		pNext;
			m_outBufferAlloc->getMemory(),			//  VkDeviceMemory	mem;
			0ull,									//  VkDeviceSize	offset;
			m_outBufferAccess.allocSize,			//  VkDeviceSize	size;
		};

		VK_CHECK(vk.invalidateMappedMemoryRanges(*m_device, 1u, &outBufferRange));
	}

	if (verifyResult())
		return tcu::TestStatus::pass("All values OK");
	else
		return tcu::TestStatus::fail("Invalid value(s) found");
}

bool AccessInstance::verifyResult (bool splitAccess)
{
	std::ostringstream	logMsg;
	tcu::TestLog&		log					= m_context.getTestContext().getLog();
	const bool			isReadAccess		= (m_bufferAccessType == BUFFER_ACCESS_TYPE_READ_FROM_STORAGE);
	const void*			inDataPtr			= m_inBufferAlloc->getHostPtr();
	const void*			outDataPtr			= m_outBufferAlloc->getHostPtr();
	bool				allOk				= true;
	deUint32			valueNdx			= 0;
	const VkDeviceSize	maxAccessRange		= isReadAccess ? m_inBufferAccess.maxAccessRange : m_outBufferAccess.maxAccessRange;
	const bool			isR64				= (m_bufferFormat == VK_FORMAT_R64_UINT || m_bufferFormat == VK_FORMAT_R64_SINT);
	const deUint32		unsplitElementSize	= (isR64 ? 8u : 4u);
	const deUint32		elementSize			= ((isR64 && !splitAccess) ? 8u : 4u);

	for (VkDeviceSize offsetInBytes = 0; offsetInBytes < m_outBufferAccess.allocSize; offsetInBytes += elementSize)
	{
		const deUint8*		outValuePtr		= static_cast<const deUint8*>(outDataPtr) + offsetInBytes;
		const size_t		outValueSize	= static_cast<size_t>(deMinu64(elementSize, (m_outBufferAccess.allocSize - offsetInBytes)));

		if (offsetInBytes >= RobustAccessWithPointersTest::s_numberOfBytesAccessed)
		{
			// The shader will only write 16 values into the result buffer. The rest of the values
			// should remain unchanged or may be modified if we are writing out of bounds.
			if (!isOutBufferValueUnchanged(offsetInBytes, outValueSize)
				&& (isReadAccess || !isValueWithinBufferOrZero(inDataPtr, m_inBufferAccess.allocSize, outValuePtr, 4)))
			{
				logMsg << "\nValue " << valueNdx++ << " has been modified with an unknown value: " << *(static_cast<const deUint32*>(static_cast<const void*>(outValuePtr)));
				allOk = false;
			}
		}
		else
		{
			const deInt32	distanceToOutOfBounds	= static_cast<deInt32>(maxAccessRange) - static_cast<deInt32>(offsetInBytes);
			bool			isOutOfBoundsAccess		= false;

			logMsg << "\n" << valueNdx++ << ": ";

			logValue(logMsg, outValuePtr, m_bufferFormat, outValueSize);

			if (m_accessOutOfBackingMemory)
				isOutOfBoundsAccess = true;

			// Check if the shader operation accessed an operand located less than 16 bytes away
			// from the out of bounds address. Less than 32 bytes away for 64 bit accesses.
			if (!isOutOfBoundsAccess && distanceToOutOfBounds < (isR64 ? 32 : 16))
			{
				deUint32 operandSize = 0;

				switch (m_shaderType)
				{
					case SHADER_TYPE_SCALAR_COPY:
						operandSize		= unsplitElementSize; // Size of scalar
						break;

					case SHADER_TYPE_VECTOR_COPY:
						operandSize		= unsplitElementSize * 4; // Size of vec4
						break;

					case SHADER_TYPE_MATRIX_COPY:
						operandSize		= unsplitElementSize * 16; // Size of mat4
						break;

					default:
						DE_ASSERT(false);
				}

				isOutOfBoundsAccess = (((offsetInBytes / operandSize) + 1) * operandSize > maxAccessRange);
			}

			if (isOutOfBoundsAccess)
			{
				logMsg << " (out of bounds " << (isReadAccess ? "read": "write") << ")";

				const bool	isValuePartiallyOutOfBounds = ((distanceToOutOfBounds > 0) && ((deUint32)distanceToOutOfBounds < elementSize));
				bool		isValidValue				= false;

				if (isValuePartiallyOutOfBounds && !m_accessOutOfBackingMemory)
				{
					// The value is partially out of bounds

					bool	isOutOfBoundsPartOk  = true;
					bool	isWithinBoundsPartOk = true;

					deUint32 inBoundPartSize = distanceToOutOfBounds;

					// For cases that partial element is out of bound, the part within the buffer allocated memory can be buffer content per spec.
					// We need to check it as a whole part.
					if (offsetInBytes + elementSize > m_inBufferAccess.allocSize)
					{
						inBoundPartSize = static_cast<deInt32>(m_inBufferAccess.allocSize) - static_cast<deInt32>(offsetInBytes);
					}

					if (isReadAccess)
					{
						isWithinBoundsPartOk	= isValueWithinBufferOrZero(inDataPtr, m_inBufferAccess.allocSize, outValuePtr, inBoundPartSize);
						isOutOfBoundsPartOk		= isValueWithinBufferOrZero(inDataPtr, m_inBufferAccess.allocSize, (deUint8*)outValuePtr + inBoundPartSize, outValueSize - inBoundPartSize);
					}
					else
					{
						isWithinBoundsPartOk	= isValueWithinBufferOrZero(inDataPtr, m_inBufferAccess.allocSize, outValuePtr, inBoundPartSize)
												  || isOutBufferValueUnchanged(offsetInBytes, inBoundPartSize);

						isOutOfBoundsPartOk		= isValueWithinBufferOrZero(inDataPtr, m_inBufferAccess.allocSize, (deUint8*)outValuePtr + inBoundPartSize, outValueSize - inBoundPartSize)
												  || isOutBufferValueUnchanged(offsetInBytes + inBoundPartSize, outValueSize - inBoundPartSize);
					}

					logMsg << ", first " << distanceToOutOfBounds << " byte(s) " << (isWithinBoundsPartOk ? "OK": "wrong");
					logMsg << ", last " << outValueSize - distanceToOutOfBounds << " byte(s) " << (isOutOfBoundsPartOk ? "OK": "wrong");

					isValidValue	= isWithinBoundsPartOk && isOutOfBoundsPartOk;
				}
				else
				{
					if (isReadAccess)
					{
						isValidValue	= isValueWithinBufferOrZero(inDataPtr, m_inBufferAccess.allocSize, outValuePtr, outValueSize);
					}
					else
					{
						isValidValue	= isOutBufferValueUnchanged(offsetInBytes, outValueSize);

						if (!isValidValue)
						{
							// Out of bounds writes may modify values withing the memory ranges bound to the buffer
							isValidValue	= isValueWithinBufferOrZero(inDataPtr, m_inBufferAccess.allocSize, outValuePtr, outValueSize);

							if (isValidValue)
								logMsg << ", OK, written within the memory range bound to the buffer";
						}
					}
				}

				if (!isValidValue && !splitAccess)
				{
					// Check if we are satisfying the [0, 0, 0, x] pattern, where x may be either 0 or 1,
					// or the maximum representable positive integer value (if the format is integer-based).

					const bool	canMatchVec4Pattern	= (isReadAccess
													&& !isValuePartiallyOutOfBounds
													&& (m_shaderType == SHADER_TYPE_VECTOR_COPY)
													&& (offsetInBytes / elementSize + 1) % 4 == 0);
					bool		matchesVec4Pattern	= false;

					if (canMatchVec4Pattern)
					{
						matchesVec4Pattern = verifyOutOfBoundsVec4(outValuePtr - 3u * elementSize, m_bufferFormat);
					}

					if (!canMatchVec4Pattern || !matchesVec4Pattern)
					{
						logMsg << ". Failed: ";

						if (isReadAccess)
						{
							logMsg << "expected value within the buffer range or 0";

							if (canMatchVec4Pattern)
								logMsg << ", or the [0, 0, 0, x] pattern";
						}
						else
						{
							logMsg << "written out of the range";
						}

						allOk = false;
					}
				}
			}
			else // We are within bounds
			{
				if (isReadAccess)
				{
					if (!isExpectedValueFromInBuffer(offsetInBytes, outValuePtr, elementSize))
					{
						logMsg << ", Failed: unexpected value";
						allOk = false;
					}
				}
				else
				{
					// Out of bounds writes may change values within the bounds.
					if (!isValueWithinBufferOrZero(inDataPtr, m_inBufferAccess.accessRange, outValuePtr, elementSize))
					{
						logMsg << ", Failed: unexpected value";
						allOk = false;
					}
				}
			}
		}
	}

	log << tcu::TestLog::Message << logMsg.str() << tcu::TestLog::EndMessage;

	if (!allOk && unsplitElementSize > 4u && !splitAccess)
	{
		// "Non-atomic accesses to storage buffers that are a multiple of 32 bits may be decomposed into 32-bit accesses that are individually bounds-checked."
		return verifyResult(true/*splitAccess*/);
	}

	return allOk;
}

// BufferReadInstance

ReadInstance::ReadInstance (Context&				context,
							Move<VkDevice>			device,
							ShaderType				shaderType,
							VkShaderStageFlags		shaderStage,
							VkFormat				bufferFormat,
							//bool					readFromStorage,
							VkDeviceSize			inBufferAccessRange,
							bool					accessOutOfBackingMemory)

	: AccessInstance	(context, device, shaderType, shaderStage, bufferFormat,
						 BUFFER_ACCESS_TYPE_READ_FROM_STORAGE,
						 inBufferAccessRange, RobustAccessWithPointersTest::s_numberOfBytesAccessed,
						 accessOutOfBackingMemory)
{
}

// BufferWriteInstance

WriteInstance::WriteInstance (Context&				context,
							  Move<VkDevice>		device,
							  ShaderType			shaderType,
							  VkShaderStageFlags	shaderStage,
							  VkFormat				bufferFormat,
							  VkDeviceSize			writeBufferAccessRange,
							  bool					accessOutOfBackingMemory)

	: AccessInstance	(context, device, shaderType, shaderStage, bufferFormat,
						 BUFFER_ACCESS_TYPE_WRITE_TO_STORAGE,
						 RobustAccessWithPointersTest::s_numberOfBytesAccessed, writeBufferAccessRange,
						 accessOutOfBackingMemory)
{
}

} // unnamed namespace

tcu::TestCaseGroup* createBufferAccessWithVariablePointersTests(tcu::TestContext& testCtx)
{
	// Lets make group for the tests
	de::MovePtr<tcu::TestCaseGroup> bufferAccessWithVariablePointersTests	(new tcu::TestCaseGroup(testCtx, "through_pointers", ""));

	// Lets add subgroups to better organise tests
	de::MovePtr<tcu::TestCaseGroup> computeWithVariablePointersTests		(new tcu::TestCaseGroup(testCtx, "compute", ""));
	de::MovePtr<tcu::TestCaseGroup> computeReads							(new tcu::TestCaseGroup(testCtx, "reads", ""));
	de::MovePtr<tcu::TestCaseGroup> computeWrites							(new tcu::TestCaseGroup(testCtx, "writes", ""));

	de::MovePtr<tcu::TestCaseGroup> graphicsWithVariablePointersTests		(new tcu::TestCaseGroup(testCtx, "graphics", ""));
	de::MovePtr<tcu::TestCaseGroup> graphicsReads							(new tcu::TestCaseGroup(testCtx, "reads", ""));
	de::MovePtr<tcu::TestCaseGroup> graphicsReadsVertex						(new tcu::TestCaseGroup(testCtx, "vertex", ""));
	de::MovePtr<tcu::TestCaseGroup> graphicsReadsFragment					(new tcu::TestCaseGroup(testCtx, "fragment", ""));
	de::MovePtr<tcu::TestCaseGroup> graphicsWrites							(new tcu::TestCaseGroup(testCtx, "writes", ""));
	de::MovePtr<tcu::TestCaseGroup> graphicsWritesVertex					(new tcu::TestCaseGroup(testCtx, "vertex", ""));
	de::MovePtr<tcu::TestCaseGroup> graphicsWritesFragment					(new tcu::TestCaseGroup(testCtx, "fragment", ""));

	// A struct for describing formats
	struct Formats
	{
		const VkFormat		value;
		const char * const	name;
	};

	const Formats			bufferFormats[]			=
	{
		{ VK_FORMAT_R32_SINT,		"s32" },
		{ VK_FORMAT_R32_UINT,		"u32" },
		{ VK_FORMAT_R32_SFLOAT,		"f32" },
		{ VK_FORMAT_R64_SINT,		"s64" },
		{ VK_FORMAT_R64_UINT,		"u64" },
	};
	const deUint8			bufferFormatsCount		= static_cast<deUint8>(DE_LENGTH_OF_ARRAY(bufferFormats));

	// Amounts of data to copy
	const VkDeviceSize		rangeSizes[]			=
	{
		1ull, 3ull, 4ull, 16ull, 32ull
	};
	const deUint8			rangeSizesCount			= static_cast<deUint8>(DE_LENGTH_OF_ARRAY(rangeSizes));

	// gather above data into one array
	const struct ShaderTypes
	{
		const ShaderType			value;
		const char * const			name;
		const Formats* const		formats;
		const deUint8				formatsCount;
		const VkDeviceSize* const	sizes;
		const deUint8				sizesCount;
	}						types[]					=
	{
		{ SHADER_TYPE_VECTOR_COPY,	"vec4",		bufferFormats,			bufferFormatsCount,			rangeSizes,			rangeSizesCount },
		{ SHADER_TYPE_SCALAR_COPY,	"scalar",	bufferFormats,			bufferFormatsCount,			rangeSizes,			rangeSizesCount }
	};

	// Specify to which subgroups put various tests
	const struct ShaderStages
	{
		VkShaderStageFlags					stage;
		de::MovePtr<tcu::TestCaseGroup>&	reads;
		de::MovePtr<tcu::TestCaseGroup>&	writes;
	}						stages[]				=
	{
		{ VK_SHADER_STAGE_VERTEX_BIT,		graphicsReadsVertex,	graphicsWritesVertex },
		{ VK_SHADER_STAGE_FRAGMENT_BIT,		graphicsReadsFragment,	graphicsWritesFragment },
		{ VK_SHADER_STAGE_COMPUTE_BIT,		computeReads,			computeWrites }
	};

	// Eventually specify if memory used should be in the "inaccesible" portion of buffer or entirely outside of buffer
	const char* const		backingMemory[]			= { "in_memory", "out_of_memory" };

	for (deInt32 stageId = 0; stageId < DE_LENGTH_OF_ARRAY(stages); ++stageId)
		for (int i = 0; i < DE_LENGTH_OF_ARRAY(types); ++i)
			for (int j = 0; j < types[i].formatsCount; ++j)
				for (int k = 0; k < types[i].sizesCount; ++k)
					for (int s = 0; s < DE_LENGTH_OF_ARRAY(backingMemory); ++s)
					{
						std::ostringstream	name;
						name << types[i].sizes[k] << "B_" << backingMemory[s] << "_with_" << types[i].name << '_' << types[i].formats[j].name;
						stages[stageId].reads->addChild(new RobustReadTest(testCtx, name.str().c_str(), "", stages[stageId].stage, types[i].value, types[i].formats[j].value, types[i].sizes[k], s != 0));
					}

	for (deInt32 stageId = 0; stageId < DE_LENGTH_OF_ARRAY(stages); ++stageId)
		for (int i=0; i<DE_LENGTH_OF_ARRAY(types); ++i)
			for (int j=0; j<types[i].formatsCount; ++j)
				for (int k = 0; k<types[i].sizesCount; ++k)
					for (int s = 0; s < DE_LENGTH_OF_ARRAY(backingMemory); ++s)
					{
						std::ostringstream	name;
						name << types[i].sizes[k] << "B_" << backingMemory[s] << "_with_" << types[i].name << '_' << types[i].formats[j].name;
						stages[stageId].writes->addChild(new RobustWriteTest(testCtx, name.str().c_str(), "", stages[stageId].stage, types[i].value, types[i].formats[j].value, types[i].sizes[k], s != 0));
					}

	graphicsReads->addChild(graphicsReadsVertex.release());
	graphicsReads->addChild(graphicsReadsFragment.release());

	graphicsWrites->addChild(graphicsWritesVertex.release());
	graphicsWrites->addChild(graphicsWritesFragment.release());

	graphicsWithVariablePointersTests->addChild(graphicsReads.release());
	graphicsWithVariablePointersTests->addChild(graphicsWrites.release());

	computeWithVariablePointersTests->addChild(computeReads.release());
	computeWithVariablePointersTests->addChild(computeWrites.release());

	bufferAccessWithVariablePointersTests->addChild(graphicsWithVariablePointersTests.release());
	bufferAccessWithVariablePointersTests->addChild(computeWithVariablePointersTests.release());

	return bufferAccessWithVariablePointersTests.release();
}

} // robustness
} // vkt
