/*------------------------------------------------------------------------
 * 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
{

// A function for getting information on variable pointer features supported through physical device
vk::VkPhysicalDeviceVariablePointersFeatures querySupportedVariablePointersFeatures (const Context& context)
{
	VkPhysicalDeviceVariablePointersFeatures extensionFeatures =
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR,	// sType
		DE_NULL,															// pNext
		false,																// variablePointersStorageBuffer
		false,																// variablePointers
	};

	VkPhysicalDeviceFeatures2	features;
	deMemset(&features, 0, sizeof(features));
	features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
	features.pNext = &extensionFeatures;

	// Call the getter only if supported. Otherwise above "zero" defaults are used
	if (context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2"))
	{
		context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features);
	}

	return extensionFeatures;
}

// 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)
	{
	}

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

// 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				(void);

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)
		, s32(autoincrement)
		, f32(autoincrement)
		, u32(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				s32;
	const Variable				f32;
	const Variable				u32;
	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)
{
	// 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")
	(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)
		{
			shaderSource
			(op::Decorate, var.array_content_type, "ArrayStride", 16);
		}
		// 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
		(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)

		(var.v4f32, is, op::TypeVector, var.f32, 4)
		(var.v4s32, is, op::TypeVector, var.s32, 4)
		(var.v4u32, is, op::TypeVector, var.u32, 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;
		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
{
	VkPhysicalDeviceVariablePointersFeatures pointerFeatures = querySupportedVariablePointersFeatures(context);

	if (pointerFeatures.variablePointersStorageBuffer != DE_TRUE)
		return new NotSupportedInstance(context, std::string("VariablePointersStorageBuffer support is required for this test."));

	// We need a device with enabled robust buffer access feature (it is disabled in default device)
	Move<VkDevice>	device = createRobustBufferAccessDevice(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
{
	VkPhysicalDeviceVariablePointersFeatures pointerFeatures = querySupportedVariablePointersFeatures(context);
	if (pointerFeatures.variablePointersStorageBuffer != DE_TRUE)
		return new NotSupportedInstance(context, std::string("VariablePointersStorageBuffer support is required for this test."));

	// We need a device with enabled robust buffer access feature (it is disabled in default device)
	Move<VkDevice>	device = createRobustBufferAccessDevice(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);

	// 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);

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

	if (isUintFormat(m_bufferFormat))
	{
		return !deMemCmp(valuePtr, &valueIndex, (size_t)valueSize);
	}
	else if (isIntFormat(m_bufferFormat))
	{
		const deInt32 value = -deInt32(valueIndex);
		return !deMemCmp(valuePtr, &value, (size_t)valueSize);
	}
	else if (isFloatFormat(m_bufferFormat))
	{
		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 <= 4);
	const deUint8 *const	outValuePtr		= (deUint8*)m_outBufferAlloc->getHostPtr() + offsetInBytes;
	const deUint32			defaultValue	= 0xBABABABAu;

	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 (void)
{
	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;

	for (VkDeviceSize offsetInBytes = 0; offsetInBytes < m_outBufferAccess.allocSize; offsetInBytes += 4)
	{
		const deUint8*		outValuePtr		= static_cast<const deUint8*>(outDataPtr) + offsetInBytes;
		const size_t		outValueSize	= static_cast<size_t>(deMinu64(4, (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.
			if (!isOutOfBoundsAccess && distanceToOutOfBounds < 16)
			{
				deUint32 operandSize = 0;

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

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

					case SHADER_TYPE_MATRIX_COPY:
						operandSize		= 4 * 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 < 4));
				bool		isValidValue				= false;

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

					bool	isOutOfBoundsPartOk  = true;
					bool	isWithinBoundsPartOk = true;

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

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

					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)
				{
					// 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 / 4 + 1) % 4 == 0);
					bool		matchesVec4Pattern	= false;

					if (canMatchVec4Pattern)
					{
						matchesVec4Pattern	= verifyOutOfBoundsVec4(static_cast<const deUint32*>(static_cast<const void*>(outValuePtr)) - 3, 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, 4))
					{
						logMsg << ", Failed: unexpected value";
						allOk = false;
					}
				}
				else
				{
					// Out of bounds writes may change values within the bounds.
					if (!isValueWithinBufferOrZero(inDataPtr, m_inBufferAccess.accessRange, outValuePtr, 4))
					{
						logMsg << ", Failed: unexpected value";
						allOk = false;
					}
				}
			}
		}
	}

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

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