/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 The Khronos Group Inc.
 * Copyright (c) 2016 Imagination Technologies Ltd.
 *
 * 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 uniform/storage buffers and
 *        uniform/storage texel buffers.
 *//*--------------------------------------------------------------------*/

#include "vktRobustnessBufferAccessTests.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 <limits>
#include <sstream>

namespace vkt
{
namespace robustness
{

using namespace vk;

enum ShaderType
{
	SHADER_TYPE_MATRIX_COPY,
	SHADER_TYPE_VECTOR_COPY,
	SHADER_TYPE_SCALAR_COPY,
	SHADER_TYPE_TEXEL_COPY,

	SHADER_TYPE_COUNT
};

enum BufferAccessType
{
	BUFFER_ACCESS_TYPE_READ,
	BUFFER_ACCESS_TYPE_READ_FROM_STORAGE,
	BUFFER_ACCESS_TYPE_WRITE,
};

static VkDeviceSize min (VkDeviceSize a, VkDeviceSize b)
{
	return (a < b) ? a : b;
}

class RobustBufferAccessTest : public vkt::TestCase
{
public:
	static const deUint32		s_testArraySize;
	static const deUint32		s_numberOfBytesAccessed;

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

	virtual						~RobustBufferAccessTest		(void) {}

	virtual void				checkSupport				(Context& context) const;

private:
	static void					genBufferShaderAccess		(ShaderType				shaderType,
															 VkFormat				bufferFormat,
															 bool					readFromStorage,
															 std::ostringstream&	bufferDefinition,
															 std::ostringstream&	bufferUse);

	static void					genTexelBufferShaderAccess	(VkFormat				bufferFormat,
															 std::ostringstream&	bufferDefinition,
															 std::ostringstream&	bufferUse,
															 bool					readFromStorage);

protected:
	static void					initBufferAccessPrograms	(SourceCollections&		programCollection,
															 VkShaderStageFlags		shaderStage,
															 ShaderType				shaderType,
															 VkFormat				bufferFormat,
															 bool					readFromStorage);

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

class RobustBufferReadTest : public RobustBufferAccessTest
{
public:
								RobustBufferReadTest		(tcu::TestContext&		testContext,
															 const std::string&		name,
															 const std::string&		description,
															 VkShaderStageFlags		shaderStage,
															 ShaderType				shaderType,
															 VkFormat				bufferFormat,
															 VkDeviceSize			readAccessRange,
															 bool					readFromStorage,
															 bool					accessOutOfBackingMemory);

	virtual						~RobustBufferReadTest		(void) {}

	virtual void				initPrograms				(SourceCollections& programCollection) const;
	virtual TestInstance*		createInstance				(Context& context) const;

private:
	const bool					m_readFromStorage;
	const VkDeviceSize			m_readAccessRange;
	const bool					m_accessOutOfBackingMemory;
};

class RobustBufferWriteTest : public RobustBufferAccessTest
{
public:
								RobustBufferWriteTest		(tcu::TestContext&		testContext,
															 const std::string&		name,
															 const std::string&		description,
															 VkShaderStageFlags		shaderStage,
															 ShaderType				shaderType,
															 VkFormat				bufferFormat,
															 VkDeviceSize			writeAccessRange,
															 bool					accessOutOfBackingMemory);

	virtual						~RobustBufferWriteTest		(void) {}

	virtual void				initPrograms				(SourceCollections& programCollection) const;
	virtual TestInstance*		createInstance				(Context& context) const;

private:
	const VkDeviceSize			m_writeAccessRange;
	const bool					m_accessOutOfBackingMemory;
};

class BufferAccessInstance : public vkt::TestInstance
{
public:
									BufferAccessInstance			(Context&			context,
																	 Move<VkDevice>		device,
																	 ShaderType			shaderType,
																	 VkShaderStageFlags	shaderStage,
																	 VkFormat			bufferFormat,
																	 BufferAccessType	bufferAccessType,
																	 VkDeviceSize		inBufferAccessRange,
																	 VkDeviceSize		outBufferAccessRange,
																	 bool				accessOutOfBackingMemory);

	virtual							~BufferAccessInstance			(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;

	const VkDeviceSize				m_inBufferAccessRange;
	Move<VkBuffer>					m_inBuffer;
	de::MovePtr<Allocation>			m_inBufferAlloc;
	VkDeviceSize					m_inBufferAllocSize;
	VkDeviceSize					m_inBufferMaxAccessRange;

	const VkDeviceSize				m_outBufferAccessRange;
	Move<VkBuffer>					m_outBuffer;
	de::MovePtr<Allocation>			m_outBufferAlloc;
	VkDeviceSize					m_outBufferAllocSize;
	VkDeviceSize					m_outBufferMaxAccessRange;

	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;

	// Used when m_shaderType == SHADER_TYPE_TEXEL_COPY
	Move<VkBufferView>				m_inTexelBufferView;
	Move<VkBufferView>				m_outTexelBufferView;

	const bool						m_accessOutOfBackingMemory;
};

class BufferReadInstance: public BufferAccessInstance
{
public:
									BufferReadInstance			(Context&				context,
																 Move<VkDevice>			device,
																 ShaderType				shaderType,
																 VkShaderStageFlags		shaderStage,
																 VkFormat				bufferFormat,
																 bool					readFromStorage,
																 VkDeviceSize			inBufferAccessRange,
																 bool					accessOutOfBackingMemory);

	virtual							~BufferReadInstance			(void) {}

private:
};

class BufferWriteInstance: public BufferAccessInstance
{
public:
									BufferWriteInstance			(Context&				context,
																 Move<VkDevice>			device,
																 ShaderType				shaderType,
																 VkShaderStageFlags		shaderStage,
																 VkFormat				bufferFormat,
																 VkDeviceSize			writeBufferAccessRange,
																 bool					accessOutOfBackingMemory);

	virtual							~BufferWriteInstance		(void) {}
};

// RobustBufferAccessTest

const deUint32 RobustBufferAccessTest::s_testArraySize = 1024;
const deUint32 RobustBufferAccessTest::s_numberOfBytesAccessed	= (deUint32)(16 * sizeof(float)); // size of mat4

RobustBufferAccessTest::RobustBufferAccessTest (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 RobustBufferAccessTest::checkSupport(Context& context) const
{
	if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") && !context.getDeviceFeatures().robustBufferAccess)
		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: robustBufferAccess not supported by this implementation");
}

void RobustBufferAccessTest::genBufferShaderAccess (ShaderType			shaderType,
												    VkFormat			bufferFormat,
												    bool				readFromStorage,
												    std::ostringstream&	bufferDefinition,
												    std::ostringstream&	bufferUse)
{
	if (isFloatFormat(bufferFormat))
	{
		bufferDefinition <<
			"layout(binding = 0, " << (readFromStorage ? "std430" : "std140") << ") " << (readFromStorage ? "buffer" : "uniform") << " InBuffer\n"
			"{\n"
			"	mat4 inMatrix[" << s_testArraySize << "];\n"
			"};\n\n";

		bufferDefinition <<
			"layout(binding = 1, std430) buffer OutBuffer\n"
			"{\n"
			"	mat4 outMatrix[" << s_testArraySize << "];\n"
			"};\n\n";

		bufferDefinition <<
			"layout(binding = 2, std140) uniform Indices\n"
			"{\n"
			"	int inIndex;\n"
			"	int outIndex;\n"
			"};\n\n";

		switch (shaderType)
		{
			case SHADER_TYPE_MATRIX_COPY:
				bufferUse <<
					"	mat4 tmp = inMatrix[inIndex];\n"
					"	outMatrix[outIndex] = tmp;\n";
				break;

			case SHADER_TYPE_VECTOR_COPY:
				bufferUse <<
					"	outMatrix[outIndex][0] = inMatrix[inIndex][0];\n"
					"	outMatrix[outIndex][1] = inMatrix[inIndex][1];\n"
					"	outMatrix[outIndex][2] = inMatrix[inIndex][2];\n"
					"	outMatrix[outIndex][3] = inMatrix[inIndex][3];\n";
				break;

			case SHADER_TYPE_SCALAR_COPY:
				bufferUse <<
					"	outMatrix[outIndex][0][0] = inMatrix[inIndex][0][0];\n"
					"	outMatrix[outIndex][0][1] = inMatrix[inIndex][0][1];\n"
					"	outMatrix[outIndex][0][2] = inMatrix[inIndex][0][2];\n"
					"	outMatrix[outIndex][0][3] = inMatrix[inIndex][0][3];\n"

					"	outMatrix[outIndex][1][0] = inMatrix[inIndex][1][0];\n"
					"	outMatrix[outIndex][1][1] = inMatrix[inIndex][1][1];\n"
					"	outMatrix[outIndex][1][2] = inMatrix[inIndex][1][2];\n"
					"	outMatrix[outIndex][1][3] = inMatrix[inIndex][1][3];\n"

					"	outMatrix[outIndex][2][0] = inMatrix[inIndex][2][0];\n"
					"	outMatrix[outIndex][2][1] = inMatrix[inIndex][2][1];\n"
					"	outMatrix[outIndex][2][2] = inMatrix[inIndex][2][2];\n"
					"	outMatrix[outIndex][2][3] = inMatrix[inIndex][2][3];\n"

					"	outMatrix[outIndex][3][0] = inMatrix[inIndex][3][0];\n"
					"	outMatrix[outIndex][3][1] = inMatrix[inIndex][3][1];\n"
					"	outMatrix[outIndex][3][2] = inMatrix[inIndex][3][2];\n"
					"	outMatrix[outIndex][3][3] = inMatrix[inIndex][3][3];\n";
				break;

			default:
				DE_ASSERT(false);
		}
	}
	else
	{
		std::string typePrefixStr;

		if (isUintFormat(bufferFormat))
		{
			typePrefixStr = "u";
		}
		else if (isIntFormat(bufferFormat))
		{
			typePrefixStr =  "i";
		}
		else
		{
			DE_ASSERT(false);
		}

		typePrefixStr += (bufferFormat == vk::VK_FORMAT_R64_UINT || bufferFormat == vk::VK_FORMAT_R64_SINT) ?
						 "64" : "";

		bufferDefinition <<
			"layout(binding = 0, " << (readFromStorage ? "std430" : "std140") << ") " << (readFromStorage ? "buffer readonly" : "uniform") << " InBuffer\n"
			"{\n"
			"	" << typePrefixStr << "vec4 inVecs[" << s_testArraySize << "][4];\n"
			"};\n\n";

		bufferDefinition <<
			"layout(binding = 1, std430) buffer OutBuffer\n"
			"{\n"
			"	" << typePrefixStr << "vec4 outVecs[" << s_testArraySize << "][4];\n"
			"};\n\n";

		bufferDefinition <<
			"layout(binding = 2, std140) uniform Indices\n"
			"{\n"
			"	int inIndex;\n"
			"	int outIndex;\n"
			"};\n\n";

		switch (shaderType)
		{
			case SHADER_TYPE_MATRIX_COPY:
				// Shader type not supported for integer types.
				DE_ASSERT(false);
				break;

			case SHADER_TYPE_VECTOR_COPY:
				bufferUse <<
					"	outVecs[outIndex][0] = inVecs[inIndex][0];\n"
					"	outVecs[outIndex][1] = inVecs[inIndex][1];\n"
					"	outVecs[outIndex][2] = inVecs[inIndex][2];\n"
					"	outVecs[outIndex][3] = inVecs[inIndex][3];\n";
				break;

			case SHADER_TYPE_SCALAR_COPY:
				bufferUse <<
					"	outVecs[outIndex][0][0] = inVecs[inIndex][0][0];\n"
					"	outVecs[outIndex][0][1] = inVecs[inIndex][0][1];\n"
					"	outVecs[outIndex][0][2] = inVecs[inIndex][0][2];\n"
					"	outVecs[outIndex][0][3] = inVecs[inIndex][0][3];\n"

					"	outVecs[outIndex][1][0] = inVecs[inIndex][1][0];\n"
					"	outVecs[outIndex][1][1] = inVecs[inIndex][1][1];\n"
					"	outVecs[outIndex][1][2] = inVecs[inIndex][1][2];\n"
					"	outVecs[outIndex][1][3] = inVecs[inIndex][1][3];\n"

					"	outVecs[outIndex][2][0] = inVecs[inIndex][2][0];\n"
					"	outVecs[outIndex][2][1] = inVecs[inIndex][2][1];\n"
					"	outVecs[outIndex][2][2] = inVecs[inIndex][2][2];\n"
					"	outVecs[outIndex][2][3] = inVecs[inIndex][2][3];\n"

					"	outVecs[outIndex][3][0] = inVecs[inIndex][3][0];\n"
					"	outVecs[outIndex][3][1] = inVecs[inIndex][3][1];\n"
					"	outVecs[outIndex][3][2] = inVecs[inIndex][3][2];\n"
					"	outVecs[outIndex][3][3] = inVecs[inIndex][3][3];\n";
				break;

			default:
				DE_ASSERT(false);
		}
	}
}

void RobustBufferAccessTest::genTexelBufferShaderAccess (VkFormat				bufferFormat,
														 std::ostringstream&	bufferDefinition,
														 std::ostringstream&	bufferUse,
														 bool					readFromStorage)
{
	const char*		layoutTypeStr;
	const char*		inTexelBufferTypeStr;
	const char*		outTexelBufferTypeStr;
	const deUint32	texelSize				= mapVkFormat(bufferFormat).getPixelSize();

	if (isFloatFormat(bufferFormat))
	{
		layoutTypeStr			= "rgba32f";
		inTexelBufferTypeStr	= readFromStorage ? "imageBuffer" : "textureBuffer";
		outTexelBufferTypeStr	= "imageBuffer";
	}
	else if (isUintFormat(bufferFormat))
	{
		layoutTypeStr			= "rgba32ui";
		inTexelBufferTypeStr	= readFromStorage ? "uimageBuffer" : "utextureBuffer";
		outTexelBufferTypeStr	= "uimageBuffer";
	}
	else if (isIntFormat(bufferFormat))
	{
		layoutTypeStr			= "rgba32i";
		inTexelBufferTypeStr	= readFromStorage ? "iimageBuffer" : "itextureBuffer";
		outTexelBufferTypeStr	= "iimageBuffer";
	}
	else if (bufferFormat == VK_FORMAT_A2B10G10R10_UNORM_PACK32)
	{
		layoutTypeStr			= "rgb10_a2";
		inTexelBufferTypeStr	= readFromStorage ? "imageBuffer" : "textureBuffer"; outTexelBufferTypeStr	= "imageBuffer";
	}
	else
	{
		TCU_THROW(NotSupportedError, (std::string("Unsupported format: ") + getFormatName(bufferFormat)).c_str());
	}

	bufferDefinition << "layout(set = 0, binding = 0" << ((readFromStorage) ? (std::string(", ") + layoutTypeStr) : "") << ") uniform highp "
					 << ((readFromStorage) ? "readonly " : "") << inTexelBufferTypeStr << " inImage;\n";

	bufferDefinition << "layout(set = 0, binding = 1, " << layoutTypeStr << ") uniform highp writeonly " << outTexelBufferTypeStr << " outImage;\n";

	bufferDefinition <<
		"layout(binding = 2, std140) uniform Offsets\n"
		"{\n"
		"	int inOffset;\n"
		"	int outOffset;\n"
		"};\n\n";

	bufferUse << "	for (int i = 0; i < " << (s_numberOfBytesAccessed / texelSize) << "; i++)\n"
			  << "	{\n"
			  << "		imageStore(outImage, outOffset + i, " << (readFromStorage ? "imageLoad" : "texelFetch") << "(inImage, inOffset + i));\n"
			  << "	}\n";
}

void RobustBufferAccessTest::initBufferAccessPrograms (SourceCollections&	programCollection,
													   VkShaderStageFlags	shaderStage,
													   ShaderType			shaderType,
													   VkFormat				bufferFormat,
													   bool					readFromStorage)
{
	std::ostringstream	bufferDefinition;
	std::ostringstream	bufferUse;
	std::string			extensions;

	if (bufferFormat == vk::VK_FORMAT_R64_UINT || bufferFormat == vk::VK_FORMAT_R64_SINT)
	{
		extensions = "#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require\n";
	}

	if (shaderType != SHADER_TYPE_TEXEL_COPY)
	{
		genBufferShaderAccess(shaderType, bufferFormat, readFromStorage, bufferDefinition, bufferUse);
	}

	if (shaderStage == VK_SHADER_STAGE_COMPUTE_BIT)
	{
		std::ostringstream computeShaderSource;

		if (shaderType == SHADER_TYPE_TEXEL_COPY)
			genTexelBufferShaderAccess(bufferFormat, bufferDefinition, bufferUse, readFromStorage);

		computeShaderSource <<
			"#version 440\n"
			"#extension GL_EXT_texture_buffer : require\n"
			<< extensions <<
			"precision highp float;\n"
			"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
			<< bufferDefinition.str() <<
			"void main (void)\n"
			"{\n"
			<< bufferUse.str() <<
			"}\n";

		programCollection.glslSources.add("compute") << glu::ComputeSource(computeShaderSource.str());
	}
	else
	{
		std::ostringstream vertexShaderSource;
		std::ostringstream fragmentShaderSource;

		if (shaderStage == VK_SHADER_STAGE_VERTEX_BIT)
		{
			if (shaderType == SHADER_TYPE_TEXEL_COPY)
				genTexelBufferShaderAccess(bufferFormat, bufferDefinition, bufferUse, readFromStorage);

			vertexShaderSource <<
				"#version 440\n"
				"#extension GL_EXT_texture_buffer : require\n"
				<< extensions <<
				"precision highp float;\n"
				"layout(location = 0) in vec4 position;\n\n"
				<< bufferDefinition.str() << "\n"
				"out gl_PerVertex {\n"
				"	vec4 gl_Position;\n"
				"};\n\n"
				"void main (void)\n"
				"{\n"
				<< bufferUse.str() <<
				"	gl_Position = position;\n"
				"}\n";
		}
		else
		{
			vertexShaderSource <<
				"#version 440\n"
				"precision highp float;\n"
				"layout(location = 0) in vec4 position;\n\n"
				"out gl_PerVertex {\n"
				"	vec4 gl_Position;\n"
				"};\n\n"
				"void main (void)\n"
				"{\n"
				"	gl_Position = position;\n"
				"}\n";
		}

		programCollection.glslSources.add("vertex") << glu::VertexSource(vertexShaderSource.str());

		if (shaderStage == VK_SHADER_STAGE_FRAGMENT_BIT)
		{
			if (shaderType == SHADER_TYPE_TEXEL_COPY)
				genTexelBufferShaderAccess(bufferFormat, bufferDefinition, bufferUse, readFromStorage);

			fragmentShaderSource <<
				"#version 440\n"
				"#extension GL_EXT_texture_buffer : require\n"
				<< extensions <<
				"precision highp float;\n"
				"layout(location = 0) out vec4 fragColor;\n"
				<< bufferDefinition.str() <<
				"void main (void)\n"
				"{\n"
				<< bufferUse.str() <<
				"	fragColor = vec4(1.0);\n"
				"}\n";
		}
		else
		{
			fragmentShaderSource <<
				"#version 440\n"
				"precision highp float;\n"
				"layout(location = 0) out vec4 fragColor;\n\n"
				"void main (void)\n"
				"{\n"
				"	fragColor = vec4(1.0);\n"
				"}\n";
		}

		programCollection.glslSources.add("fragment") << glu::FragmentSource(fragmentShaderSource.str());
	}
}

// RobustBufferReadTest

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

void RobustBufferReadTest::initPrograms (SourceCollections& programCollection) const
{
	initBufferAccessPrograms(programCollection, m_shaderStage, m_shaderType, m_bufferFormat, m_readFromStorage);
}

TestInstance* RobustBufferReadTest::createInstance (Context& context) const
{
	Move<VkDevice>	device			= createRobustBufferAccessDevice(context);

	return new BufferReadInstance(context, device, m_shaderType, m_shaderStage, m_bufferFormat, m_readFromStorage, m_readAccessRange, m_accessOutOfBackingMemory);
}

// RobustBufferWriteTest

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

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

void RobustBufferWriteTest::initPrograms (SourceCollections& programCollection) const
{
	initBufferAccessPrograms(programCollection, m_shaderStage, m_shaderType, m_bufferFormat, false /* readFromStorage */);
}

TestInstance* RobustBufferWriteTest::createInstance (Context& context) const
{
	Move<VkDevice>	device			= createRobustBufferAccessDevice(context);

	return new BufferWriteInstance(context, device, m_shaderType, m_shaderStage, m_bufferFormat, m_writeAccessRange, m_accessOutOfBackingMemory);
}

// BufferAccessInstance

BufferAccessInstance::BufferAccessInstance (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_inBufferAccessRange			(inBufferAccessRange)
	, m_outBufferAccessRange		(outBufferAccessRange)
	, m_accessOutOfBackingMemory	(accessOutOfBackingMemory)
{
	const DeviceInterface&		vk						= context.getDeviceInterface();
	const deUint32				queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
	const bool					isTexelAccess			= !!(m_shaderType == SHADER_TYPE_TEXEL_COPY);
	const bool					readFromStorage			= !!(m_bufferAccessType == BUFFER_ACCESS_TYPE_READ_FROM_STORAGE);
	SimpleAllocator				memAlloc				(vk, *m_device, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
	tcu::TestLog&				log						= m_context.getTestContext().getLog();

	DE_ASSERT(RobustBufferAccessTest::s_numberOfBytesAccessed % sizeof(deUint32) == 0);
	DE_ASSERT(inBufferAccessRange <= RobustBufferAccessTest::s_numberOfBytesAccessed);
	DE_ASSERT(outBufferAccessRange <= RobustBufferAccessTest::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");
		}
	}

	// Check format support
	{
		VkFormatFeatureFlags		requiredFormatFeatures	= 0;
		const VkFormatProperties	formatProperties		= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), m_bufferFormat);

		if (isTexelAccess)
		{
			requiredFormatFeatures	= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
		}

		if ((formatProperties.bufferFeatures & requiredFormatFeatures) != requiredFormatFeatures)
		{
			TCU_THROW(NotSupportedError, (std::string("Format cannot be used in uniform and storage") + (isTexelAccess ? " texel" : "") + " buffers: "
										  + getFormatName(m_bufferFormat)).c_str());
		}
	}

	// Create buffer to read data from
	{
		VkBufferUsageFlags		inBufferUsageFlags;
		VkMemoryRequirements	inBufferMemoryReqs;

		if (isTexelAccess)
		{
			inBufferUsageFlags = readFromStorage ? VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
		}
		else
		{
			inBufferUsageFlags = readFromStorage ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
		}

		const VkBufferCreateInfo	inBufferParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			m_inBufferAccessRange,						// VkDeviceSize			size;
			inBufferUsageFlags,							// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32				queueFamilyIndexCount;
			DE_NULL										// const deUint32*		pQueueFamilyIndices;
		};

		m_inBuffer				= createBuffer(vk, *m_device, &inBufferParams);

		inBufferMemoryReqs		= getBufferMemoryRequirements(vk, *m_device, *m_inBuffer);
		m_inBufferAllocSize		= inBufferMemoryReqs.size;
		m_inBufferAlloc			= memAlloc.allocate(inBufferMemoryReqs, MemoryRequirement::HostVisible);

		// Size of the most restrictive bound
		m_inBufferMaxAccessRange = min(m_inBufferAllocSize, min(inBufferParams.size, m_inBufferAccessRange));

		VK_CHECK(vk.bindBufferMemory(*m_device, *m_inBuffer, m_inBufferAlloc->getMemory(), m_inBufferAlloc->getOffset()));
		populateBufferWithTestValues(m_inBufferAlloc->getHostPtr(), m_inBufferAllocSize, m_bufferFormat);
		flushMappedMemoryRange(vk, *m_device, m_inBufferAlloc->getMemory(), m_inBufferAlloc->getOffset(), VK_WHOLE_SIZE);

		log << tcu::TestLog::Message << "inBufferAllocSize = " << m_inBufferAllocSize << tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "inBufferMaxAccessRange = " << m_inBufferMaxAccessRange << tcu::TestLog::EndMessage;
	}

	// Create buffer to write data into
	{
		VkMemoryRequirements		outBufferMemoryReqs;
		const VkBufferUsageFlags	outBufferUsageFlags	= (m_shaderType == SHADER_TYPE_TEXEL_COPY) ? VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
																								   : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;

		const VkBufferCreateInfo	outBufferParams		=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			m_outBufferAccessRange,						// VkDeviceSize			size;
			outBufferUsageFlags,						// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32				queueFamilyIndexCount;
			DE_NULL										// const deUint32*		pQueueFamilyIndices;
		};

		m_outBuffer					= createBuffer(vk, *m_device, &outBufferParams);

		outBufferMemoryReqs			= getBufferMemoryRequirements(vk, *m_device, *m_outBuffer);
		m_outBufferAllocSize		= outBufferMemoryReqs.size;
		m_outBufferAlloc			= memAlloc.allocate(outBufferMemoryReqs, MemoryRequirement::HostVisible);

		// If we are requesting access out of the memory that backs the buffer, make sure the test is able to do so.
		if (m_accessOutOfBackingMemory)
		{
			if (m_outBufferAllocSize >= ((RobustBufferAccessTest::s_testArraySize + 1) * RobustBufferAccessTest::s_numberOfBytesAccessed))
			{
				TCU_THROW(NotSupportedError, "Cannot access beyond the end of the memory that backs the buffer");
			}
		}

		// Size of the most restrictive bound
		m_outBufferMaxAccessRange = min(m_outBufferAllocSize, min(outBufferParams.size, m_outBufferAccessRange));

		VK_CHECK(vk.bindBufferMemory(*m_device, *m_outBuffer, m_outBufferAlloc->getMemory(), m_outBufferAlloc->getOffset()));
		deMemset(m_outBufferAlloc->getHostPtr(), 0xFF, (size_t)m_outBufferAllocSize);
		flushMappedMemoryRange(vk, *m_device, m_outBufferAlloc->getMemory(), m_outBufferAlloc->getOffset(), VK_WHOLE_SIZE);

		log << tcu::TestLog::Message << "outBufferAllocSize = " << m_outBufferAllocSize << tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "outBufferMaxAccessRange = " << m_outBufferMaxAccessRange << tcu::TestLog::EndMessage;
	}

	// Create buffer for indices/offsets
	{
		struct IndicesBuffer
		{
			deInt32 inIndex;
			deInt32 outIndex;
		};

		IndicesBuffer indices = { 0, 0 };

		const VkBufferCreateInfo	indicesBufferParams			=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			sizeof(IndicesBuffer),						// VkDeviceSize			size;
			VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32				queueFamilyIndexCount;
			DE_NULL,									// const deUint32*		pQueueFamilyIndices;
		};

		m_indicesBuffer				= createBuffer(vk, *m_device, &indicesBufferParams);
		m_indicesBufferAlloc		= memAlloc.allocate(getBufferMemoryRequirements(vk, *m_device, *m_indicesBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vk.bindBufferMemory(*m_device, *m_indicesBuffer, m_indicesBufferAlloc->getMemory(), m_indicesBufferAlloc->getOffset()));

		if (m_accessOutOfBackingMemory)
		{
			if (m_bufferAccessType == BUFFER_ACCESS_TYPE_WRITE)
			{
				indices.outIndex = RobustBufferAccessTest::s_testArraySize - 1;
			}
			else
			{
				indices.inIndex = RobustBufferAccessTest::s_testArraySize - 1;
			}
		}

		deMemcpy(m_indicesBufferAlloc->getHostPtr(), &indices, sizeof(IndicesBuffer));

		flushMappedMemoryRange(vk, *m_device, m_indicesBufferAlloc->getMemory(), m_indicesBufferAlloc->getOffset(), VK_WHOLE_SIZE);

		log << tcu::TestLog::Message << "inIndex = " << indices.inIndex << tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "outIndex = " << indices.outIndex << tcu::TestLog::EndMessage;
	}

	// Create descriptor data
	{
		VkDescriptorType	inBufferDescriptorType;
		VkDescriptorType	outBufferDescriptorType;

		if (isTexelAccess)
		{
			inBufferDescriptorType	= readFromStorage ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
			outBufferDescriptorType	= VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
		}
		else
		{
			inBufferDescriptorType	= readFromStorage ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
			outBufferDescriptorType	= VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
		}

		DescriptorPoolBuilder descriptorPoolBuilder;
		descriptorPoolBuilder.addType(inBufferDescriptorType, 1u);
		descriptorPoolBuilder.addType(outBufferDescriptorType, 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(inBufferDescriptorType, VK_SHADER_STAGE_ALL);
		setLayoutBuilder.addSingleBinding(outBufferDescriptorType, 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);

		DescriptorSetUpdateBuilder setUpdateBuilder;

		if (isTexelAccess)
		{
			const VkBufferViewCreateInfo inBufferViewCreateInfo =
			{
				VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,		// VkStructureType			sType;
				DE_NULL,										// const void*				pNext;
				0u,												// VkBufferViewCreateFlags	flags;
				*m_inBuffer,									// VkBuffer					buffer;
				m_bufferFormat,									// VkFormat					format;
				0ull,											// VkDeviceSize				offset;
				m_inBufferAccessRange							// VkDeviceSize				range;
			};
			m_inTexelBufferView	= createBufferView(vk, *m_device, &inBufferViewCreateInfo, DE_NULL);

			const VkBufferViewCreateInfo outBufferViewCreateInfo =
			{
				VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,		// VkStructureType			sType;
				DE_NULL,										// const void*				pNext;
				0u,												// VkBufferViewCreateFlags	flags;
				*m_outBuffer,									// VkBuffer					buffer;
				m_bufferFormat,									// VkFormat					format;
				0ull,											// VkDeviceSize				offset;
				m_outBufferAccessRange,							// VkDeviceSize				range;
			};
			m_outTexelBufferView	= createBufferView(vk, *m_device, &outBufferViewCreateInfo, DE_NULL);

			setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0), inBufferDescriptorType, &m_inTexelBufferView.get());
			setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1), outBufferDescriptorType, &m_outTexelBufferView.get());
		}
		else
		{
			const VkDescriptorBufferInfo inBufferDescriptorInfo		= makeDescriptorBufferInfo(*m_inBuffer, 0ull, m_inBufferAccessRange);
			const VkDescriptorBufferInfo outBufferDescriptorInfo	= makeDescriptorBufferInfo(*m_outBuffer, 0ull, m_outBufferAccessRange);

			setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0), inBufferDescriptorType, &inBufferDescriptorInfo);
			setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1), outBufferDescriptorType, &outBufferDescriptorInfo);
		}

		const VkDescriptorBufferInfo indicesBufferDescriptorInfo	= makeDescriptorBufferInfo(*m_indicesBuffer, 0ull, 8ull);
		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;
		};

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

		// Create vertex buffer
		{
			const VkDeviceSize			vertexBufferSize	= (VkDeviceSize)(4u * sizeof(tcu::Vec4));
			const VkBufferCreateInfo	vertexBufferParams	=
			{
				VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
				DE_NULL,									// const void*			pNext;
				0u,											// VkBufferCreateFlags	flags;
				vertexBufferSize,							// VkDeviceSize			size;
				VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
				VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
				VK_QUEUE_FAMILY_IGNORED,					// deUint32				queueFamilyIndexCount;
				DE_NULL										// const deUint32*		pQueueFamilyIndices;
			};

			DE_ASSERT(vertexBufferSize > 0);

			m_vertexBuffer		= createBuffer(vk, *m_device, &vertexBufferParams);
			m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, *m_device, *m_vertexBuffer), MemoryRequirement::HostVisible);

			VK_CHECK(vk.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));

			// Load vertices into vertex buffer
			deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertices, sizeof(tcu::Vec4) * DE_LENGTH_OF_ARRAY(vertices));
			flushMappedMemoryRange(vk, *m_device, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), VK_WHOLE_SIZE);
		}

		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 BufferAccessInstance::isExpectedValueFromInBuffer (VkDeviceSize offsetInBytes, const void* valuePtr, VkDeviceSize valueSize)
{
	DE_ASSERT(offsetInBytes % 4 == 0);
	DE_ASSERT(offsetInBytes < m_inBufferAllocSize);

	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 if (m_bufferFormat == VK_FORMAT_A2B10G10R10_UNORM_PACK32)
	{
		const deUint32	r		= ((valueIndex + 0) & ((2u << 10) - 1u));
		const deUint32	g		= ((valueIndex + 1) & ((2u << 10) - 1u));
		const deUint32	b		= ((valueIndex + 2) & ((2u << 10) - 1u));
		const deUint32	a		= ((valueIndex + 0) & ((2u << 2) - 1u));
		const deUint32	abgr	= (a << 30) | (b << 20) | (g << 10) | r;

		return !deMemCmp(valuePtr, &abgr, (size_t)valueSize);
	}
	else
	{
		DE_ASSERT(false);
		return false;
	}
}

bool BufferAccessInstance::isOutBufferValueUnchanged (VkDeviceSize offsetInBytes, VkDeviceSize valueSize)
{
	const deUint8 *const	outValuePtr		= (deUint8*)m_outBufferAlloc->getHostPtr() + offsetInBytes;
	const deUint32			defaultValue	= 0xFFFFFFFFu;

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

tcu::TestStatus BufferAccessInstance::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_outBufferAllocSize,					//  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 BufferAccessInstance::verifyResult (void)
{
	std::ostringstream	logMsg;
	tcu::TestLog&		log					= m_context.getTestContext().getLog();
	const bool			isReadAccess		= !!(m_bufferAccessType == BUFFER_ACCESS_TYPE_READ || 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_inBufferMaxAccessRange : m_outBufferMaxAccessRange;

	for (VkDeviceSize offsetInBytes = 0; offsetInBytes < m_outBufferAllocSize; offsetInBytes += 4)
	{
		deUint8*			outValuePtr		= (deUint8*)outDataPtr + offsetInBytes;
		const size_t		outValueSize	= (size_t)min(4, (m_outBufferAllocSize - offsetInBytes));

		if (offsetInBytes >= RobustBufferAccessTest::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_inBufferAllocSize, outValuePtr, 4)))
			{
				logMsg << "\nValue " << valueNdx++ << " has been modified with an unknown value: " << *((deUint32 *)outValuePtr);
				allOk = false;
			}
		}
		else
		{
			const deInt32	distanceToOutOfBounds	= (deInt32)maxAccessRange - (deInt32)offsetInBytes;
			bool			isOutOfBoundsAccess		= false;

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

			logValue(logMsg, outValuePtr, m_bufferFormat, outValueSize);

			if (m_accessOutOfBackingMemory)
			{
				isOutOfBoundsAccess = true;
			}
			else
			{
				// Check if the shader operation accessed an operand located less than 16 bytes away
				// from the out of bounds address.

				deUint32 operandSize = 0;

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

					case SHADER_TYPE_VECTOR_COPY:
						operandSize		= 4 * ((m_bufferFormat == vk::VK_FORMAT_R64_UINT || m_bufferFormat == vk::VK_FORMAT_R64_SINT) ? 8 : 4);// Size of vec4
						break;

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

					case SHADER_TYPE_TEXEL_COPY:
						operandSize		= mapVkFormat(m_bufferFormat).getPixelSize();
						break;

					default:
						DE_ASSERT(false);
				}

				isOutOfBoundsAccess = (maxAccessRange < 16)
									|| (((offsetInBytes / operandSize + 1) * operandSize) > (maxAccessRange - 16));
			}

			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_inBufferAllocSize, outValuePtr, distanceToOutOfBounds);
						isOutOfBoundsPartOk		= isValueWithinBufferOrZero(inDataPtr, m_inBufferAllocSize, (deUint8*)outValuePtr + distanceToOutOfBounds , outValueSize - distanceToOutOfBounds);
					}
					else
					{
						isWithinBoundsPartOk	= isValueWithinBufferOrZero(inDataPtr, m_inBufferAllocSize, outValuePtr, distanceToOutOfBounds)
												  || isOutBufferValueUnchanged(offsetInBytes, distanceToOutOfBounds);

						isOutOfBoundsPartOk		= isValueWithinBufferOrZero(inDataPtr, m_inBufferAllocSize, (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_inBufferAllocSize, 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_inBufferAllocSize, 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 || m_shaderType == SHADER_TYPE_TEXEL_COPY)
													&& ((offsetInBytes / 4 + 1) % 4 == 0 || m_bufferFormat == VK_FORMAT_A2B10G10R10_UNORM_PACK32));
					bool		matchesVec4Pattern	= false;

					if (canMatchVec4Pattern)
					{
						if (m_bufferFormat == VK_FORMAT_A2B10G10R10_UNORM_PACK32)
							matchesVec4Pattern	= verifyOutOfBoundsVec4(outValuePtr, m_bufferFormat);
						else
							matchesVec4Pattern	= verifyOutOfBoundsVec4(reinterpret_cast<deUint32*>(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_inBufferAccessRange, outValuePtr, 4))
					{
						logMsg << ", Failed: unexpected value";
						allOk = false;
					}
				}
			}
		}
	}

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

	return allOk;
}

// BufferReadInstance

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

	: BufferAccessInstance	(context, device, shaderType, shaderStage, bufferFormat,
							 readFromStorage ? BUFFER_ACCESS_TYPE_READ_FROM_STORAGE : BUFFER_ACCESS_TYPE_READ,
							 inBufferAccessRange,
							 RobustBufferAccessTest::s_numberOfBytesAccessed,	// outBufferAccessRange
							 accessOutOfBackingMemory)
{
}

// BufferWriteInstance

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

	: BufferAccessInstance	(context, device, shaderType, shaderStage, bufferFormat,
							 BUFFER_ACCESS_TYPE_WRITE,
							 RobustBufferAccessTest::s_numberOfBytesAccessed,	// inBufferAccessRange
							 writeBufferAccessRange,
							 accessOutOfBackingMemory)
{
}

// Test node creation functions

static const char* getShaderStageName (VkShaderStageFlagBits shaderStage)
{
	switch (shaderStage)
	{
		case VK_SHADER_STAGE_VERTEX_BIT:					return "vertex";
		case VK_SHADER_STAGE_FRAGMENT_BIT:					return "fragment";
		case VK_SHADER_STAGE_COMPUTE_BIT:					return "compute";
		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:		return "tess_control";
		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:	return "tess_eval";
		case VK_SHADER_STAGE_GEOMETRY_BIT:					return "geometry";

		default:
			DE_ASSERT(false);
	}

	return DE_NULL;
}

static void addBufferAccessTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentNode)
{
	struct BufferRangeConfig
	{
		const char*		name;
		VkDeviceSize	range;
	};

	const VkShaderStageFlagBits bufferAccessStages[] =
	{
		VK_SHADER_STAGE_VERTEX_BIT,
		VK_SHADER_STAGE_FRAGMENT_BIT,
		VK_SHADER_STAGE_COMPUTE_BIT,
	};

	const VkFormat bufferFormats[] =
	{
		VK_FORMAT_R32_SINT,
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R64_SINT,
		VK_FORMAT_R64_UINT,
		VK_FORMAT_R32_SFLOAT
	};

	const VkFormat texelBufferFormats[] =
	{
		VK_FORMAT_R32G32B32A32_SINT,
		VK_FORMAT_R32G32B32A32_UINT,
		VK_FORMAT_R32G32B32A32_SFLOAT,

		VK_FORMAT_A2B10G10R10_UNORM_PACK32
	};

	const BufferRangeConfig bufferRangeConfigs[] =
	{
		{ "range_1_byte",		1ull },
		{ "range_3_bytes",		3ull },
		{ "range_4_bytes",		4ull },		// size of float
		{ "range_32_bytes",		32ull },	// size of half mat4
	};

	const BufferRangeConfig texelBufferRangeConfigs[] =
	{
		{ "range_1_texel",		1u },
		{ "range_3_texels",		3u },
	};

	const char* shaderTypeNames[SHADER_TYPE_COUNT] =
	{
		"mat4_copy",
		"vec4_copy",
		"scalar_copy",
		"texel_copy",
	};

	for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(bufferAccessStages); stageNdx++)
	{
		const VkShaderStageFlagBits			stage			= bufferAccessStages[stageNdx];
		de::MovePtr<tcu::TestCaseGroup>		stageTests		(new tcu::TestCaseGroup(testCtx, getShaderStageName(stage), ""));

		for (int shaderTypeNdx = 0; shaderTypeNdx < SHADER_TYPE_COUNT; shaderTypeNdx++)
		{
			const VkFormat*					formats;
			size_t							formatsLength;
			const BufferRangeConfig*		ranges;
			size_t							rangesLength;
			deUint32						rangeMultiplier;
			de::MovePtr<tcu::TestCaseGroup> shaderTypeTests	(new tcu::TestCaseGroup(testCtx, shaderTypeNames[shaderTypeNdx], ""));

			if ((ShaderType)shaderTypeNdx == SHADER_TYPE_TEXEL_COPY)
			{
				formats			= texelBufferFormats;
				formatsLength	= DE_LENGTH_OF_ARRAY(texelBufferFormats);

				ranges			= texelBufferRangeConfigs;
				rangesLength	= DE_LENGTH_OF_ARRAY(texelBufferRangeConfigs);
			}
			else
			{
				formats			= bufferFormats;
				formatsLength	= DE_LENGTH_OF_ARRAY(bufferFormats);

				ranges			= bufferRangeConfigs;
				rangesLength	= DE_LENGTH_OF_ARRAY(bufferRangeConfigs);
			}

			for (size_t formatNdx = 0; formatNdx < formatsLength; formatNdx++)
			{
				const VkFormat	bufferFormat	= formats[formatNdx];

				rangeMultiplier = ((ShaderType)shaderTypeNdx == SHADER_TYPE_TEXEL_COPY) ? mapVkFormat(bufferFormat).getPixelSize() : 1;

				if (!isFloatFormat(bufferFormat) && ((ShaderType)shaderTypeNdx) == SHADER_TYPE_MATRIX_COPY)
				{
					// Use SHADER_TYPE_MATRIX_COPY with floating-point formats only
					break;
				}

				const std::string				formatName		= getFormatName(bufferFormat);
				de::MovePtr<tcu::TestCaseGroup>	formatTests		(new tcu::TestCaseGroup(testCtx, de::toLower(formatName.substr(10)).c_str(), ""));

				de::MovePtr<tcu::TestCaseGroup> uboReadTests		(new tcu::TestCaseGroup(testCtx, "oob_uniform_read", ""));
				de::MovePtr<tcu::TestCaseGroup> ssboReadTests		(new tcu::TestCaseGroup(testCtx, "oob_storage_read", ""));
				de::MovePtr<tcu::TestCaseGroup> ssboWriteTests		(new tcu::TestCaseGroup(testCtx, "oob_storage_write", ""));

				for (size_t rangeNdx = 0; rangeNdx < rangesLength; rangeNdx++)
				{
					const BufferRangeConfig&	rangeConfig			= ranges[rangeNdx];
					const VkDeviceSize			rangeInBytes		= rangeConfig.range * rangeMultiplier;

					uboReadTests->addChild(new RobustBufferReadTest(testCtx, rangeConfig.name, "", stage, (ShaderType)shaderTypeNdx, bufferFormat, rangeInBytes, false, false));
					ssboReadTests->addChild(new RobustBufferReadTest(testCtx, rangeConfig.name, "", stage, (ShaderType)shaderTypeNdx, bufferFormat, rangeInBytes, true, false));
					ssboWriteTests->addChild(new RobustBufferWriteTest(testCtx, rangeConfig.name, "", stage, (ShaderType)shaderTypeNdx, bufferFormat, rangeInBytes, false));

				}

				formatTests->addChild(uboReadTests.release());
				formatTests->addChild(ssboReadTests.release());
				formatTests->addChild(ssboWriteTests.release());

				shaderTypeTests->addChild(formatTests.release());
			}

			// Read/write out of the memory that backs the buffer
			{
				de::MovePtr<tcu::TestCaseGroup>	outOfAllocTests		(new tcu::TestCaseGroup(testCtx, "out_of_alloc", ""));

				const VkFormat format = (((ShaderType)shaderTypeNdx == SHADER_TYPE_TEXEL_COPY ) ? VK_FORMAT_R32G32B32A32_SFLOAT : VK_FORMAT_R32_SFLOAT);

				outOfAllocTests->addChild(new RobustBufferReadTest(testCtx, "oob_uniform_read", "", stage, (ShaderType)shaderTypeNdx, format, 16, false, true));
				outOfAllocTests->addChild(new RobustBufferReadTest(testCtx, "oob_storage_read", "", stage, (ShaderType)shaderTypeNdx, format, 16, true, true));
				outOfAllocTests->addChild(new RobustBufferWriteTest(testCtx, "oob_storage_write", "", stage, (ShaderType)shaderTypeNdx, format, 16, true));

				shaderTypeTests->addChild(outOfAllocTests.release());
			}

			stageTests->addChild(shaderTypeTests.release());
		}
		parentNode->addChild(stageTests.release());
	}
}

tcu::TestCaseGroup* createBufferAccessTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> bufferAccessTests	(new tcu::TestCaseGroup(testCtx, "buffer_access", ""));

	addBufferAccessTests(testCtx, bufferAccessTests.get());

	return bufferAccessTests.release();
}

} // robustness
} // vkt
