/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2017-2019 The Khronos Group Inc.
 * Copyright (c) 2018-2019 NVIDIA Corporation
 *
 * 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 Tests for VK_EXT_buffer_device_address.
 *//*--------------------------------------------------------------------*/

#include "vktBindingBufferDeviceAddressTests.hpp"

#include "vkBufferWithMemory.hpp"
#include "vkImageWithMemory.hpp"
#include "vkQueryUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkObjUtil.hpp"

#include "vktTestGroupUtil.hpp"
#include "vktTestCase.hpp"

#include "deDefs.h"
#include "deMath.h"
#include "deRandom.h"
#include "deSharedPtr.hpp"
#include "deString.h"

#include "tcuTestCase.hpp"
#include "tcuTestLog.hpp"

#include <string>
#include <sstream>

namespace vkt
{
namespace BindingModel
{
namespace
{
using namespace vk;
using namespace std;

typedef de::MovePtr<Unique<VkBuffer> >	VkBufferSp;
typedef de::MovePtr<Allocation>			AllocationSp;

static const deUint32 DIM = 8;

typedef enum
{
	BASE_UBO = 0,
	BASE_SSBO,
} Base;

#define ENABLE_RAYTRACING 0

typedef enum
{
	STAGE_COMPUTE = 0,
	STAGE_VERTEX,
	STAGE_FRAGMENT,
	STAGE_RAYGEN,
} Stage;

typedef enum
{
	BT_SINGLE = 0,
	BT_MULTI,
	BT_REPLAY,
} BufType;

typedef enum
{
	LAYOUT_STD140 = 0,
	LAYOUT_SCALAR,
} Layout;

typedef enum
{
	CONVERT_NONE = 0,
	CONVERT_UTOPTR,
	CONVERT_UVEC2,
} Convert;

struct CaseDef
{
	deUint32 set;
	deUint32 depth;
	Base base;
	Stage stage;
	Convert convertUToPtr;
	bool storeInLocal;
	BufType bufType;
	Layout layout;
};

class BufferAddressTestInstance : public TestInstance
{
public:
						BufferAddressTestInstance	(Context& context, const CaseDef& data);
						~BufferAddressTestInstance	(void);
	tcu::TestStatus		iterate						(void);
	virtual	void		fillBuffer					(const std::vector<deUint8 *>& cpuAddrs,
													 const std::vector<deUint64>& gpuAddrs,
													 deUint32 bufNum, deUint32 curDepth) const;
private:
	CaseDef				m_data;

	enum
	{
		WIDTH = 256,
		HEIGHT = 256
	};
};

BufferAddressTestInstance::BufferAddressTestInstance (Context& context, const CaseDef& data)
	: vkt::TestInstance		(context)
	, m_data				(data)
{
}

BufferAddressTestInstance::~BufferAddressTestInstance (void)
{
}

class BufferAddressTestCase : public TestCase
{
	public:
							BufferAddressTestCase	(tcu::TestContext& context, const char* name, const char* desc, const CaseDef data);
							~BufferAddressTestCase	(void);
	virtual	void			initPrograms			(SourceCollections& programCollection) const;
	virtual TestInstance*	createInstance			(Context& context) const;
	virtual void			checkSupport			(Context& context) const;
	virtual	void			checkBuffer				(std::stringstream& checks, deUint32 bufNum, deUint32 curDepth, const std::string &prefix) const;

private:
	CaseDef					m_data;
};

BufferAddressTestCase::BufferAddressTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data)
	: vkt::TestCase	(context, name, desc)
	, m_data		(data)
{
}

BufferAddressTestCase::~BufferAddressTestCase	(void)
{
}

void BufferAddressTestCase::checkSupport (Context& context) const
{
	if (!context.isBufferDeviceAddressSupported())
		TCU_THROW(NotSupportedError, "Physical storage buffer pointers not supported");

	if (m_data.stage == STAGE_VERTEX && !context.getDeviceFeatures().vertexPipelineStoresAndAtomics)
		TCU_THROW(NotSupportedError, "Vertex pipeline stores and atomics not supported");

	if (m_data.set >= context.getDeviceProperties().limits.maxBoundDescriptorSets)
		TCU_THROW(NotSupportedError, "descriptor set number not supported");

	if (m_data.convertUToPtr == VK_TRUE && !context.getDeviceFeatures().shaderInt64)
		TCU_THROW(NotSupportedError, "64-bit integers in shader not supported");

	bool isBufferDeviceAddressWithCaptureReplaySupported =
			(context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") && context.getBufferDeviceAddressFeatures().bufferDeviceAddressCaptureReplay) ||
			(context.isDeviceFunctionalitySupported("VK_EXT_buffer_device_address") && context.getBufferDeviceAddressFeaturesEXT().bufferDeviceAddressCaptureReplay);
	if (m_data.bufType == BT_REPLAY && !isBufferDeviceAddressWithCaptureReplaySupported)
		TCU_THROW(NotSupportedError, "Capture/replay of physical storage buffer pointers not supported");

	if (m_data.layout == LAYOUT_SCALAR && !context.getScalarBlockLayoutFeatures().scalarBlockLayout)
		TCU_THROW(NotSupportedError, "Scalar block layout not supported");

#if ENABLE_RAYTRACING
	if (m_data.stage == STAGE_RAYGEN &&
		!context.isDeviceFunctionalitySupported("VK_NV_ray_tracing"))
	{
		TCU_THROW(NotSupportedError, "Ray tracing not supported");
	}
#endif

	if (m_data.convertUToPtr == CONVERT_UTOPTR && !context.getDeviceFeatures().shaderInt64)
		TCU_THROW(NotSupportedError, "Int64 not supported");
	if (m_data.convertUToPtr == CONVERT_UVEC2 && !context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address"))
		TCU_THROW(NotSupportedError, "VK_KHR_buffer_device_address not supported");
}

void BufferAddressTestCase::checkBuffer (std::stringstream& checks, deUint32 bufNum, deUint32 curDepth, const std::string &prefix) const
{
	string newPrefix = prefix;
	if (curDepth > 0)
	{
		if (m_data.convertUToPtr == CONVERT_UTOPTR)
			newPrefix = "T1(uint64_t(T1(" + newPrefix + ")))";
		else if (m_data.convertUToPtr == CONVERT_UVEC2)
			newPrefix = "T1(uvec2(T1(" + newPrefix + ")))";
	}

	if (m_data.storeInLocal && curDepth != 0)
	{
		std::string localName = "l" + de::toString(bufNum);
		checks << "   " << ((bufNum & 1) ? "restrict " : "") << "T1 " << localName << " = " << newPrefix << ";\n";
		newPrefix = localName;
	}

	checks << "   accum |= " << newPrefix << ".a[0] - " << bufNum*3+0 << ";\n";
	checks << "   accum |= " << newPrefix << ".a[pc.identity[1]] - " << bufNum*3+1 << ";\n";
	checks << "   accum |= " << newPrefix << ".b - " << bufNum*3+2 << ";\n";
	checks << "   accum |= int(" << newPrefix << ".e[0][0] - " << bufNum*3+3 << ");\n";
	checks << "   accum |= int(" << newPrefix << ".e[0][1] - " << bufNum*3+5 << ");\n";
	checks << "   accum |= int(" << newPrefix << ".e[1][0] - " << bufNum*3+4 << ");\n";
	checks << "   accum |= int(" << newPrefix << ".e[1][1] - " << bufNum*3+6 << ");\n";

	if (m_data.layout == LAYOUT_SCALAR)
	{
		checks << "   f = " << newPrefix << ".f;\n";
		checks << "   accum |= f.x - " << bufNum*3+7 << ";\n";
		checks << "   accum |= f.y - " << bufNum*3+8 << ";\n";
		checks << "   accum |= f.z - " << bufNum*3+9 << ";\n";
	}

	if (curDepth != m_data.depth)
	{
		checkBuffer(checks, bufNum*3+1, curDepth+1, newPrefix + ".c[0]");
		checkBuffer(checks, bufNum*3+2, curDepth+1, newPrefix + ".c[pc.identity[1]]");
		checkBuffer(checks, bufNum*3+3, curDepth+1, newPrefix + ".d");
	}
}

void BufferAddressTestInstance::fillBuffer (const std::vector<deUint8 *>& cpuAddrs,
										  const std::vector<deUint64>& gpuAddrs,
										  deUint32 bufNum, deUint32 curDepth) const
{
	deUint8 *buf = cpuAddrs[bufNum];

	deUint32 aStride = m_data.layout == LAYOUT_SCALAR ? 1 : 4; // (in deUint32s)
	deUint32 cStride = m_data.layout == LAYOUT_SCALAR ? 1 : 2; // (in deUint64s)
	deUint32 matStride = m_data.layout == LAYOUT_SCALAR ? 2 : 4; // (in floats)

	// a
	((deUint32 *)(buf+0))[0] = bufNum*3+0;
	((deUint32 *)(buf+0))[aStride] = bufNum*3+1;
	// b
	((deUint32 *)(buf+32))[0] = bufNum*3+2;
	if (m_data.layout == LAYOUT_SCALAR)
	{
		// f
		((deUint32 *)(buf+36))[0] = bufNum*3+7;
		((deUint32 *)(buf+36))[1] = bufNum*3+8;
		((deUint32 *)(buf+36))[2] = bufNum*3+9;
	}
	// e
	((float *)(buf+96))[0] = (float)(bufNum*3+3);
	((float *)(buf+96))[1] = (float)(bufNum*3+4);
	((float *)(buf+96))[matStride] = (float)(bufNum*3+5);
	((float *)(buf+96))[matStride+1] = (float)(bufNum*3+6);

	if (curDepth != m_data.depth)
	{
		// c
		((deUint64 *)(buf+48))[0] = gpuAddrs[bufNum*3+1];
		((deUint64 *)(buf+48))[cStride] = gpuAddrs[bufNum*3+2];
		// d
		((deUint64 *)(buf+80))[0] = gpuAddrs[bufNum*3+3];

		fillBuffer(cpuAddrs, gpuAddrs, bufNum*3+1, curDepth+1);
		fillBuffer(cpuAddrs, gpuAddrs, bufNum*3+2, curDepth+1);
		fillBuffer(cpuAddrs, gpuAddrs, bufNum*3+3, curDepth+1);
	}
}


void BufferAddressTestCase::initPrograms (SourceCollections& programCollection) const
{
	std::stringstream decls, checks;

	std::string baseStorage = m_data.base == BASE_UBO ? "uniform" : "buffer";
	std::string memberStorage = "buffer";

	decls << "layout(r32ui, set = " << m_data.set << ", binding = 0) uniform uimage2D image0_0;\n";
	decls << "layout(buffer_reference) " << memberStorage << " T1;\n";
	std::string refType = m_data.convertUToPtr == CONVERT_UTOPTR ? "uint64_t" : m_data.convertUToPtr == CONVERT_UVEC2 ? "uvec2" : "T1";
	std::string layout = m_data.layout == LAYOUT_SCALAR ? "scalar" : "std140";
	decls <<
			"layout(set = " << m_data.set << ", binding = 1, " << layout << ") " << baseStorage << " T2 {\n"
			"   layout(offset = 0) int a[2]; // stride = 4 for scalar, 16 for std140\n"
			"   layout(offset = 32) int b;\n"
			<< ((m_data.layout == LAYOUT_SCALAR) ? "   layout(offset = 36) ivec3 f;\n" : "") <<
			"   layout(offset = 48) " << refType << " c[2]; // stride = 8 for scalar, 16 for std140\n"
			"   layout(offset = 80) " << refType << " d;\n"
			"   layout(offset = 96, row_major) mat2 e; // tightly packed for scalar, 16 byte matrix stride for std140\n"
			"} x;\n";
	decls <<
			"layout(buffer_reference, " << layout << ") " << memberStorage << " T1 {\n"
			"   layout(offset = 0) int a[2]; // stride = 4 for scalar, 16 for std140\n"
			"   layout(offset = 32) int b;\n"
			<< ((m_data.layout == LAYOUT_SCALAR) ? "   layout(offset = 36) ivec3 f;\n" : "") <<
			"   layout(offset = 48) " << refType << " c[2]; // stride = 8 for scalar, 16 for std140\n"
			"   layout(offset = 80) " << refType << " d;\n"
			"   layout(offset = 96, row_major) mat2 e; // tightly packed for scalar, 16 byte matrix stride for std140\n"
			"};\n";

	checkBuffer(checks, 0, 0, "x");

	std::stringstream pushdecl;
	pushdecl << "layout (push_constant, std430) uniform Block { int identity[32]; } pc;\n";

	vk::ShaderBuildOptions::Flags flags = vk::ShaderBuildOptions::Flags(0);
	if (m_data.layout == LAYOUT_SCALAR)
		flags = vk::ShaderBuildOptions::FLAG_ALLOW_SCALAR_OFFSETS;

	switch (m_data.stage)
	{
	default: DE_ASSERT(0); // Fallthrough
	case STAGE_COMPUTE:
		{
			std::stringstream css;
			css <<
				"#version 450 core\n"
				"#extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable\n"
				"#extension GL_EXT_buffer_reference : enable\n"
				"#extension GL_EXT_scalar_block_layout : enable\n"
				"#extension GL_EXT_buffer_reference_uvec2 : enable\n"
				<< pushdecl.str()
				<< decls.str() <<
				"layout(local_size_x = 1, local_size_y = 1) in;\n"
				"void main()\n"
				"{\n"
				"  int accum = 0, temp;\n"
				"  ivec3 f;\n"
				<< checks.str() <<
				"  uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n"
				"  imageStore(image0_0, ivec2(gl_GlobalInvocationID.xy), color);\n"
				"}\n";

			programCollection.glslSources.add("test") << glu::ComputeSource(css.str())
				<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, flags);
			break;
		}
#if ENABLE_RAYTRACING
	case STAGE_RAYGEN:
		{
			std::stringstream css;
			css <<
				"#version 460 core\n"
				"#extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable\n"
				"#extension GL_EXT_buffer_reference : enable\n"
				"#extension GL_EXT_scalar_block_layout : enable\n"
				"#extension GL_EXT_buffer_reference_uvec2 : enable\n"
				"#extension GL_NV_ray_tracing : require\n"
				<< pushdecl.str()
				<< decls.str() <<
				"void main()\n"
				"{\n"
				"  int accum = 0, temp;\n"
				"  ivec3 f;\n"
				<< checks.str() <<
				"  uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n"
				"  imageStore(image0_0, ivec2(gl_LaunchIDNV.xy), color);\n"
				"}\n";

			programCollection.glslSources.add("test") << glu::RaygenSource(css.str())
				<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, flags);
			break;
		}
#endif
	case STAGE_VERTEX:
		{
			std::stringstream vss;
			vss <<
				"#version 450 core\n"
				"#extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable\n"
				"#extension GL_EXT_buffer_reference : enable\n"
				"#extension GL_EXT_scalar_block_layout : enable\n"
				"#extension GL_EXT_buffer_reference_uvec2 : enable\n"
				<< pushdecl.str()
				<< decls.str()  <<
				"void main()\n"
				"{\n"
				"  int accum = 0, temp;\n"
				"  ivec3 f;\n"
				<< checks.str() <<
				"  uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n"
				"  imageStore(image0_0, ivec2(gl_VertexIndex % " << DIM << ", gl_VertexIndex / " << DIM << "), color);\n"
				"  gl_PointSize = 1.0f;\n"
				"}\n";

			programCollection.glslSources.add("test") << glu::VertexSource(vss.str())
				<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, flags);
			break;
		}
	case STAGE_FRAGMENT:
		{
			std::stringstream vss;
			vss <<
				"#version 450 core\n"
				"void main()\n"
				"{\n"
				// full-viewport quad
				"  gl_Position = vec4( 2.0*float(gl_VertexIndex&2) - 1.0, 4.0*(gl_VertexIndex&1)-1.0, 1.0 - 2.0 * float(gl_VertexIndex&1), 1);\n"
				"}\n";

			programCollection.glslSources.add("vert") << glu::VertexSource(vss.str());

			std::stringstream fss;
			fss <<
				"#version 450 core\n"
				"#extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable\n"
				"#extension GL_EXT_buffer_reference : enable\n"
				"#extension GL_EXT_scalar_block_layout : enable\n"
				"#extension GL_EXT_buffer_reference_uvec2 : enable\n"
				<< pushdecl.str()
				<< decls.str() <<
				"void main()\n"
				"{\n"
				"  int accum = 0, temp;\n"
				"  ivec3 f;\n"
				<< checks.str() <<
				"  uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n"
				"  imageStore(image0_0, ivec2(gl_FragCoord.x, gl_FragCoord.y), color);\n"
				"}\n";

			programCollection.glslSources.add("test") << glu::FragmentSource(fss.str())
				<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, flags);
			break;
		}
	}

}

TestInstance* BufferAddressTestCase::createInstance (Context& context) const
{
	return new BufferAddressTestInstance(context, m_data);
}

VkBufferCreateInfo makeBufferCreateInfo (const void*				pNext,
										 const VkDeviceSize			bufferSize,
										 const VkBufferUsageFlags	usage,
										 const VkBufferCreateFlags  flags)
{
	const VkBufferCreateInfo bufferCreateInfo =
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
		pNext,									// const void*			pNext;
		flags,									// VkBufferCreateFlags	flags;
		bufferSize,								// VkDeviceSize			size;
		usage,									// VkBufferUsageFlags	usage;
		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
		0u,										// deUint32				queueFamilyIndexCount;
		DE_NULL,								// const deUint32*		pQueueFamilyIndices;
	};
	return bufferCreateInfo;
}

tcu::TestStatus BufferAddressTestInstance::iterate (void)
{
	const InstanceInterface&vki						= m_context.getInstanceInterface();
	const DeviceInterface&	vk						= m_context.getDeviceInterface();
	const VkPhysicalDevice&	physDevice				= m_context.getPhysicalDevice();
	const VkDevice			device					= m_context.getDevice();
	Allocator&				allocator				= m_context.getDefaultAllocator();
	const bool				useKHR					= m_context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address");


	VkFlags allShaderStages = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
	VkFlags allPipelineStages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;

#if ENABLE_RAYTRACING
	if (m_data.stage == STAGE_RAYGEN)
	{
		allShaderStages = VK_SHADER_STAGE_RAYGEN_BIT_NV;
		allPipelineStages = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV;
	}
#endif

	VkPhysicalDeviceProperties2 properties;
	deMemset(&properties, 0, sizeof(properties));
	properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;

#if ENABLE_RAYTRACING
	VkPhysicalDeviceRayTracingPropertiesNV rayTracingProperties;
	deMemset(&rayTracingProperties, 0, sizeof(rayTracingProperties));
	rayTracingProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV;

	if (m_context.isDeviceFunctionalitySupported("VK_NV_ray_tracing"))
	{
		properties.pNext = &rayTracingProperties;
	}
#endif

	m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &properties);

	VkPipelineBindPoint bindPoint;

	switch (m_data.stage)
	{
	case STAGE_COMPUTE:
		bindPoint = VK_PIPELINE_BIND_POINT_COMPUTE;
		break;
#if ENABLE_RAYTRACING
	case STAGE_RAYGEN:
		bindPoint = VK_PIPELINE_BIND_POINT_RAY_TRACING_NV;
		break;
#endif
	default:
		bindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
		break;
	}

	Move<vk::VkDescriptorPool>	descriptorPool;
	Move<vk::VkDescriptorSet>	descriptorSet;

	VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;

	VkDescriptorSetLayoutBinding bindings[2];
	bindings[0].binding = 0;
	bindings[0].stageFlags = allShaderStages;
	bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
	bindings[0].descriptorCount = 1;
	bindings[1].binding = 1;
	bindings[1].stageFlags = allShaderStages;
	bindings[1].descriptorType = m_data.base == BASE_UBO ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
	bindings[1].descriptorCount = 1;

	// Create a layout and allocate a descriptor set for it.
	VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
		DE_NULL,

		0,
		(deUint32)2,
		&bindings[0]
	};

	Move<vk::VkDescriptorSetLayout>	descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &setLayoutCreateInfo);

	setLayoutCreateInfo.bindingCount = 0;
	Move<vk::VkDescriptorSetLayout>	emptyDescriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &setLayoutCreateInfo);

	vk::DescriptorPoolBuilder poolBuilder;
	poolBuilder.addType(bindings[1].descriptorType, 1);
	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1);

	descriptorPool = poolBuilder.build(vk, device, poolCreateFlags, 1u);
	descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);

	VkDeviceSize	align = de::max(de::max(properties.properties.limits.minUniformBufferOffsetAlignment,
											properties.properties.limits.minStorageBufferOffsetAlignment),
											(VkDeviceSize)128 /*sizeof(T1)*/);

	deUint32 numBindings = 1;
	for (deUint32 d = 0; d < m_data.depth; ++d)
	{
		numBindings = numBindings*3+1;
	}

	VkBufferDeviceAddressCreateInfoEXT addressCreateInfoEXT =
	{
		VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT,	// VkStructureType	 sType;
		DE_NULL,													// const void*		 pNext;
		0x000000000ULL,												// VkDeviceSize		 deviceAddress
	};

	VkBufferOpaqueCaptureAddressCreateInfoKHR bufferOpaqueCaptureAddressCreateInfo =
	{
		VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR,// VkStructureType	 sType;
		DE_NULL,														// const void*		 pNext;
		0x000000000ULL,													// VkDeviceSize		 opaqueCaptureAddress
	};

	std::vector<deUint8 *> cpuAddrs(numBindings);
	std::vector<VkDeviceAddress> gpuAddrs(numBindings);
	std::vector<deUint64> opaqueBufferAddrs(numBindings);
	std::vector<deUint64> opaqueMemoryAddrs(numBindings);

	VkBufferDeviceAddressInfoKHR bufferDeviceAddressInfo =
	{
		VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,// VkStructureType	 sType;
		DE_NULL,										// const void*		 pNext;
		0,												// VkBuffer			 buffer
	};

	VkDeviceMemoryOpaqueCaptureAddressInfoKHR deviceMemoryOpaqueCaptureAddressInfo =
	{
		VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR,// VkStructureType	 sType;
		DE_NULL,														// const void*		 pNext;
		0,																// VkDeviceMemory	 memory;
	};

	bool multiBuffer = m_data.bufType != BT_SINGLE;
	deUint32 numBuffers = multiBuffer ? numBindings : 1;
	VkDeviceSize bufferSize = multiBuffer ? align : (align*numBindings);

	vector<VkBufferSp>			buffers(numBuffers);
	vector<AllocationSp>		allocations(numBuffers);

	VkBufferCreateInfo			bufferCreateInfo = makeBufferCreateInfo(DE_NULL, bufferSize,
														VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
														VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
														VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR,
														m_data.bufType == BT_REPLAY ? VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR : 0);

	// VkMemoryAllocateFlags to be filled out later
	VkMemoryAllocateFlagsInfo	allocFlagsInfo =
	{
		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,	//	VkStructureType	sType
		DE_NULL,										//	const void*		pNext
		0,												//	VkMemoryAllocateFlags    flags
		0,												//	uint32_t                 deviceMask
	};

	VkMemoryOpaqueCaptureAddressAllocateInfoKHR memoryOpaqueCaptureAddressAllocateInfo =
	{
		VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR,// VkStructureType    sType;
		DE_NULL,														// const void*        pNext;
		0,																// uint64_t           opaqueCaptureAddress;
	};

	if (useKHR)
		allocFlagsInfo.flags |= VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;

	if (useKHR && m_data.bufType == BT_REPLAY)
	{
		allocFlagsInfo.flags |= VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR;
		allocFlagsInfo.pNext = &memoryOpaqueCaptureAddressAllocateInfo;
	}

	for (deUint32 i = 0; i < numBuffers; ++i)
	{
		buffers[i] = VkBufferSp(new Unique<VkBuffer>(createBuffer(vk, device, &bufferCreateInfo)));

		// query opaque capture address before binding memory
		if (useKHR) {
			bufferDeviceAddressInfo.buffer = **buffers[i];
			opaqueBufferAddrs[i] = vk.getBufferOpaqueCaptureAddressKHR(device, &bufferDeviceAddressInfo);
		}

		allocations[i] = AllocationSp(allocateExtended(vki, vk, physDevice, device, getBufferMemoryRequirements(vk, device, **buffers[i]), MemoryRequirement::HostVisible, &allocFlagsInfo));

		if (useKHR) {
			deviceMemoryOpaqueCaptureAddressInfo.memory = allocations[i]->getMemory();
			opaqueMemoryAddrs[i] = vk.getDeviceMemoryOpaqueCaptureAddressKHR(device, &deviceMemoryOpaqueCaptureAddressInfo);
		}

		VK_CHECK(vk.bindBufferMemory(device, **buffers[i], allocations[i]->getMemory(), 0));
	}

	if (m_data.bufType == BT_REPLAY)
	{
		for (deUint32 i = 0; i < numBuffers; ++i)
		{
			bufferDeviceAddressInfo.buffer = **buffers[i];
			if (useKHR)
				gpuAddrs[i] = vk.getBufferDeviceAddressKHR(device, &bufferDeviceAddressInfo);
			else
				gpuAddrs[i] = vk.getBufferDeviceAddressEXT(device, &bufferDeviceAddressInfo);
		}
		buffers.clear();
		buffers.resize(numBuffers);
		allocations.clear();
		allocations.resize(numBuffers);

		bufferCreateInfo.pNext = useKHR ? (void *)&bufferOpaqueCaptureAddressCreateInfo : (void *)&addressCreateInfoEXT;

		for (deInt32 i = numBuffers-1; i >= 0; --i)
		{
			addressCreateInfoEXT.deviceAddress = gpuAddrs[i];
			bufferOpaqueCaptureAddressCreateInfo.opaqueCaptureAddress = opaqueBufferAddrs[i];
			memoryOpaqueCaptureAddressAllocateInfo.opaqueCaptureAddress = opaqueMemoryAddrs[i];

			buffers[i] = VkBufferSp(new Unique<VkBuffer>(createBuffer(vk, device, &bufferCreateInfo)));
			allocations[i] = AllocationSp(allocateExtended(vki, vk, physDevice, device, getBufferMemoryRequirements(vk, device, **buffers[i]), MemoryRequirement::HostVisible, &allocFlagsInfo));
			VK_CHECK(vk.bindBufferMemory(device, **buffers[i], allocations[i]->getMemory(), 0));

			bufferDeviceAddressInfo.buffer = **buffers[i];
			VkDeviceSize newAddr;
			if (useKHR)
				newAddr = vk.getBufferDeviceAddressKHR(device, &bufferDeviceAddressInfo);
			else
				newAddr = vk.getBufferDeviceAddressEXT(device, &bufferDeviceAddressInfo);
			if (newAddr != gpuAddrs[i])
				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "address mismatch");
		}
	}

	// Create a buffer and compute the address for each "align" bytes.
	for (deUint32 i = 0; i < numBindings; ++i)
	{
		bufferDeviceAddressInfo.buffer = **buffers[multiBuffer ? i : 0];

		if (useKHR)
			gpuAddrs[i] = vk.getBufferDeviceAddressKHR(device, &bufferDeviceAddressInfo);
		else
			gpuAddrs[i] = vk.getBufferDeviceAddressEXT(device, &bufferDeviceAddressInfo);
		cpuAddrs[i] = (deUint8 *)allocations[multiBuffer ? i : 0]->getHostPtr();
		if (!multiBuffer)
		{
			cpuAddrs[i] = cpuAddrs[i] + align*i;
			gpuAddrs[i] = gpuAddrs[i] + align*i;
		}
		//printf("addr 0x%08x`%08x\n", (unsigned)(gpuAddrs[i]>>32), (unsigned)(gpuAddrs[i]));
	}

	fillBuffer(cpuAddrs, gpuAddrs, 0, 0);

	for (deUint32 i = 0; i < numBuffers; ++i)
		flushAlloc(vk, device, *allocations[i]);

	const VkQueue					queue					= m_context.getUniversalQueue();
	Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, 0, m_context.getUniversalQueueFamilyIndex());
	Move<VkCommandBuffer>			cmdBuffer				= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

	beginCommandBuffer(vk, *cmdBuffer, 0u);

	// Push constants are used for dynamic indexing. PushConstant[i] = i.

	const VkPushConstantRange pushConstRange =
	{
		allShaderStages,		// VkShaderStageFlags	stageFlags
		0,						// deUint32				offset
		128						// deUint32				size
	};

	deUint32 nonEmptySetLimit = m_data.base == BASE_UBO ? properties.properties.limits.maxPerStageDescriptorUniformBuffers :
														  properties.properties.limits.maxPerStageDescriptorStorageBuffers;
	nonEmptySetLimit = de::min(nonEmptySetLimit, properties.properties.limits.maxPerStageDescriptorStorageImages);

	vector<vk::VkDescriptorSetLayout>	descriptorSetLayoutsRaw(m_data.set+1);
	for (size_t i = 0; i < m_data.set+1; ++i)
	{
		// use nonempty descriptor sets to consume resources until we run out of descriptors
		if (i < nonEmptySetLimit - 1 || i == m_data.set)
			descriptorSetLayoutsRaw[i] = descriptorSetLayout.get();
		else
			descriptorSetLayoutsRaw[i] = emptyDescriptorSetLayout.get();
	}

	const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// sType
		DE_NULL,													// pNext
		(VkPipelineLayoutCreateFlags)0,
		m_data.set+1,												// setLayoutCount
		&descriptorSetLayoutsRaw[0],								// pSetLayouts
		1u,															// pushConstantRangeCount
		&pushConstRange,											// pPushConstantRanges
	};

	Move<VkPipelineLayout> pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo, NULL);

	// PushConstant[i] = i
	for (deUint32 i = 0; i < (deUint32)(128 / sizeof(deUint32)); ++i)
	{
		vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, allShaderStages,
							(deUint32)(i * sizeof(deUint32)), (deUint32)sizeof(deUint32), &i);
	}

	de::MovePtr<BufferWithMemory> copyBuffer;
	copyBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
		vk, device, allocator, makeBufferCreateInfo(DE_NULL, DIM*DIM*sizeof(deUint32), VK_BUFFER_USAGE_TRANSFER_DST_BIT, 0), MemoryRequirement::HostVisible));

	const VkImageCreateInfo			imageCreateInfo			=
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType;
		DE_NULL,								// const void*				pNext;
		(VkImageCreateFlags)0u,					// VkImageCreateFlags		flags;
		VK_IMAGE_TYPE_2D,						// VkImageType				imageType;
		VK_FORMAT_R32_UINT,						// VkFormat					format;
		{
			DIM,								// deUint32	width;
			DIM,								// deUint32	height;
			1u									// deUint32	depth;
		},										// VkExtent3D				extent;
		1u,										// deUint32					mipLevels;
		1u,										// deUint32					arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling;
		VK_IMAGE_USAGE_STORAGE_BIT
		| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
		| VK_IMAGE_USAGE_TRANSFER_DST_BIT,		// VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode;
		0u,										// deUint32					queueFamilyIndexCount;
		DE_NULL,								// const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout;
	};

	VkImageViewCreateInfo		imageViewCreateInfo		=
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		(VkImageViewCreateFlags)0u,					// VkImageViewCreateFlags	flags;
		DE_NULL,									// VkImage					image;
		VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType;
		VK_FORMAT_R32_UINT,							// VkFormat					format;
		{
			VK_COMPONENT_SWIZZLE_R,					// VkComponentSwizzle	r;
			VK_COMPONENT_SWIZZLE_G,					// VkComponentSwizzle	g;
			VK_COMPONENT_SWIZZLE_B,					// VkComponentSwizzle	b;
			VK_COMPONENT_SWIZZLE_A					// VkComponentSwizzle	a;
		},											// VkComponentMapping		 components;
		{
			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
			0u,										// deUint32				baseMipLevel;
			1u,										// deUint32				levelCount;
			0u,										// deUint32				baseArrayLayer;
			1u										// deUint32				layerCount;
		}											// VkImageSubresourceRange	subresourceRange;
	};

	de::MovePtr<ImageWithMemory> image;
	Move<VkImageView> imageView;

	image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
		vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
	imageViewCreateInfo.image = **image;
	imageView = createImageView(vk, device, &imageViewCreateInfo, NULL);

	VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
	VkDescriptorBufferInfo bufferInfo = makeDescriptorBufferInfo(**buffers[0], 0, align);

	VkWriteDescriptorSet w =
	{
		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,							// sType
		DE_NULL,														// pNext
		*descriptorSet,													// dstSet
		(deUint32)0,													// dstBinding
		0,																// dstArrayElement
		1u,																// descriptorCount
		bindings[0].descriptorType,										// descriptorType
		&imageInfo,														// pImageInfo
		&bufferInfo,													// pBufferInfo
		DE_NULL,														// pTexelBufferView
	};
	vk.updateDescriptorSets(device, 1, &w, 0, NULL);

	w.dstBinding = 1;
	w.descriptorType = bindings[1].descriptorType;
	vk.updateDescriptorSets(device, 1, &w, 0, NULL);

	vk.cmdBindDescriptorSets(*cmdBuffer, bindPoint, *pipelineLayout, m_data.set, 1, &descriptorSet.get(), 0, DE_NULL);

	Move<VkPipeline> pipeline;
	Move<VkRenderPass> renderPass;
	Move<VkFramebuffer> framebuffer;
	de::MovePtr<BufferWithMemory> sbtBuffer;

	if (m_data.stage == STAGE_COMPUTE)
	{
		const Unique<VkShaderModule>	shader(createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0));

		const VkPipelineShaderStageCreateInfo	shaderCreateInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
			DE_NULL,
			(VkPipelineShaderStageCreateFlags)0,
			VK_SHADER_STAGE_COMPUTE_BIT,								// stage
			*shader,													// shader
			"main",
			DE_NULL,													// pSpecializationInfo
		};

		const VkComputePipelineCreateInfo		pipelineCreateInfo =
		{
			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
			DE_NULL,
			0u,															// flags
			shaderCreateInfo,											// cs
			*pipelineLayout,											// layout
			(vk::VkPipeline)0,											// basePipelineHandle
			0u,															// basePipelineIndex
		};
		pipeline = createComputePipeline(vk, device, DE_NULL, &pipelineCreateInfo, NULL);
	}
#if ENABLE_RAYTRACING
	else if (m_data.stage == STAGE_RAYGEN)
	{
		const Unique<VkShaderModule>	shader(createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0));

		const VkPipelineShaderStageCreateInfo	shaderCreateInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
			DE_NULL,
			(VkPipelineShaderStageCreateFlags)0,
			VK_SHADER_STAGE_RAYGEN_BIT_NV,								// stage
			*shader,													// shader
			"main",
			DE_NULL,													// pSpecializationInfo
		};

		VkRayTracingShaderGroupCreateInfoNV group =
		{
			VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
			DE_NULL,
			VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV,			// type
			0,														// generalShader
			VK_SHADER_UNUSED_NV,									// closestHitShader
			VK_SHADER_UNUSED_NV,									// anyHitShader
			VK_SHADER_UNUSED_NV,									// intersectionShader
		};

		VkRayTracingPipelineCreateInfoNV pipelineCreateInfo = {
			VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV,	// sType
			DE_NULL,												// pNext
			0,														// flags
			1,														// stageCount
			&shaderCreateInfo,										// pStages
			1,														// groupCount
			&group,													// pGroups
			0,														// maxRecursionDepth
			*pipelineLayout,										// layout
			(vk::VkPipeline)0,										// basePipelineHandle
			0u,														// basePipelineIndex
		};

		pipeline = createRayTracingPipelineNV(vk, device, DE_NULL, &pipelineCreateInfo, NULL);

		sbtBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
			vk, device, allocator, makeBufferCreateInfo(DE_NULL, rayTracingProperties.shaderGroupHandleSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_RAY_TRACING_BIT_NV, 0), MemoryRequirement::HostVisible));
		deUint32 *ptr = (deUint32 *)sbtBuffer->getAllocation().getHostPtr();
		invalidateMappedMemoryRange(vk, device, sbtBuffer->getAllocation().getMemory(), sbtBuffer->getAllocation().getOffset(), rayTracingProperties.shaderGroupHandleSize);

		vk.getRayTracingShaderGroupHandlesNV(device, *pipeline, 0, 1, rayTracingProperties.shaderGroupHandleSize, ptr);
	}
#endif
	else
	{

		const vk::VkSubpassDescription		subpassDesc			=
		{
			(vk::VkSubpassDescriptionFlags)0,
			vk::VK_PIPELINE_BIND_POINT_GRAPHICS,					// pipelineBindPoint
			0u,														// inputCount
			DE_NULL,												// pInputAttachments
			0u,														// colorCount
			DE_NULL,												// pColorAttachments
			DE_NULL,												// pResolveAttachments
			DE_NULL,												// depthStencilAttachment
			0u,														// preserveCount
			DE_NULL,												// pPreserveAttachments
		};
		const vk::VkRenderPassCreateInfo	renderPassParams	=
		{
			vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// sType
			DE_NULL,												// pNext
			(vk::VkRenderPassCreateFlags)0,
			0u,														// attachmentCount
			DE_NULL,												// pAttachments
			1u,														// subpassCount
			&subpassDesc,											// pSubpasses
			0u,														// dependencyCount
			DE_NULL,												// pDependencies
		};

		renderPass = createRenderPass(vk, device, &renderPassParams);

		const vk::VkFramebufferCreateInfo	framebufferParams	=
		{
			vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// sType
			DE_NULL,										// pNext
			(vk::VkFramebufferCreateFlags)0,
			*renderPass,									// renderPass
			0u,												// attachmentCount
			DE_NULL,										// pAttachments
			DIM,											// width
			DIM,											// height
			1u,												// layers
		};

		framebuffer = createFramebuffer(vk, device, &framebufferParams);

		const VkPipelineVertexInputStateCreateInfo		vertexInputStateCreateInfo		=
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
			DE_NULL,													// const void*								pNext;
			(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags	flags;
			0u,															// deUint32									vertexBindingDescriptionCount;
			DE_NULL,													// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
			0u,															// deUint32									vertexAttributeDescriptionCount;
			DE_NULL														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
		};

		const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyStateCreateInfo	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
			DE_NULL,														// const void*								pNext;
			(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags	flags;
			(m_data.stage == STAGE_VERTEX) ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology						topology;
			VK_FALSE														// VkBool32									primitiveRestartEnable;
		};

		const VkPipelineRasterizationStateCreateInfo	rasterizationStateCreateInfo	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
			DE_NULL,														// const void*								pNext;
			(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags	flags;
			VK_FALSE,														// VkBool32									depthClampEnable;
			(m_data.stage == STAGE_VERTEX) ? VK_TRUE : VK_FALSE,			// VkBool32									rasterizerDiscardEnable;
			VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
			VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
			VK_FRONT_FACE_CLOCKWISE,										// VkFrontFace								frontFace;
			VK_FALSE,														// VkBool32									depthBiasEnable;
			0.0f,															// float									depthBiasConstantFactor;
			0.0f,															// float									depthBiasClamp;
			0.0f,															// float									depthBiasSlopeFactor;
			1.0f															// float									lineWidth;
		};

		const VkPipelineMultisampleStateCreateInfo		multisampleStateCreateInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType
			DE_NULL,													// const void*								pNext
			0u,															// VkPipelineMultisampleStateCreateFlags	flags
			VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples
			VK_FALSE,													// VkBool32									sampleShadingEnable
			1.0f,														// float									minSampleShading
			DE_NULL,													// const VkSampleMask*						pSampleMask
			VK_FALSE,													// VkBool32									alphaToCoverageEnable
			VK_FALSE													// VkBool32									alphaToOneEnable
		};

		VkViewport viewport = makeViewport(DIM, DIM);
		VkRect2D scissor = makeRect2D(DIM, DIM);

		const VkPipelineViewportStateCreateInfo			viewportStateCreateInfo				=
		{
			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType							sType
			DE_NULL,												// const void*								pNext
			(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewportStateCreateFlags		flags
			1u,														// deUint32									viewportCount
			&viewport,												// const VkViewport*						pViewports
			1u,														// deUint32									scissorCount
			&scissor												// const VkRect2D*							pScissors
		};

		Move<VkShaderModule> fs;
		Move<VkShaderModule> vs;

		deUint32 numStages;
		if (m_data.stage == STAGE_VERTEX)
		{
			vs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0);
			fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0); // bogus
			numStages = 1u;
		}
		else
		{
			vs = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
			fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0);
			numStages = 2u;
		}

		const VkPipelineShaderStageCreateInfo	shaderCreateInfo[2] =
		{
			{
				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
				DE_NULL,
				(VkPipelineShaderStageCreateFlags)0,
				VK_SHADER_STAGE_VERTEX_BIT,									// stage
				*vs,														// shader
				"main",
				DE_NULL,													// pSpecializationInfo
			},
			{
				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
				DE_NULL,
				(VkPipelineShaderStageCreateFlags)0,
				VK_SHADER_STAGE_FRAGMENT_BIT,								// stage
				*fs,														// shader
				"main",
				DE_NULL,													// pSpecializationInfo
			}
		};

		const VkGraphicsPipelineCreateInfo				graphicsPipelineCreateInfo		=
		{
			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
			DE_NULL,											// const void*										pNext;
			(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags							flags;
			numStages,											// deUint32											stageCount;
			&shaderCreateInfo[0],								// const VkPipelineShaderStageCreateInfo*			pStages;
			&vertexInputStateCreateInfo,						// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
			&inputAssemblyStateCreateInfo,						// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
			DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
			&viewportStateCreateInfo,							// const VkPipelineViewportStateCreateInfo*			pViewportState;
			&rasterizationStateCreateInfo,						// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
			&multisampleStateCreateInfo,						// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
			DE_NULL,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
			DE_NULL,											// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
			DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
			pipelineLayout.get(),								// VkPipelineLayout									layout;
			renderPass.get(),									// VkRenderPass										renderPass;
			0u,													// deUint32											subpass;
			DE_NULL,											// VkPipeline										basePipelineHandle;
			0													// int												basePipelineIndex;
		};

		pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo);
	}

	const VkImageMemoryBarrier imageBarrier =
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType		sType
		DE_NULL,											// const void*			pNext
		0u,													// VkAccessFlags		srcAccessMask
		VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags		dstAccessMask
		VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout		oldLayout
		VK_IMAGE_LAYOUT_GENERAL,							// VkImageLayout		newLayout
		VK_QUEUE_FAMILY_IGNORED,							// uint32_t				srcQueueFamilyIndex
		VK_QUEUE_FAMILY_IGNORED,							// uint32_t				dstQueueFamilyIndex
		**image,											// VkImage				image
		{
			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask
			0u,										// uint32_t				baseMipLevel
			1u,										// uint32_t				mipLevels,
			0u,										// uint32_t				baseArray
			1u,										// uint32_t				arraySize
		}
	};

	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
							(VkDependencyFlags)0,
							0, (const VkMemoryBarrier*)DE_NULL,
							0, (const VkBufferMemoryBarrier*)DE_NULL,
							1, &imageBarrier);

	vk.cmdBindPipeline(*cmdBuffer, bindPoint, *pipeline);

	VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	VkClearValue clearColor = makeClearValueColorU32(0,0,0,0);

	VkMemoryBarrier					memBarrier =
	{
		VK_STRUCTURE_TYPE_MEMORY_BARRIER,	// sType
		DE_NULL,							// pNext
		0u,									// srcAccessMask
		0u,									// dstAccessMask
	};

	vk.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);

	memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
	memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, allPipelineStages,
		0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);

	if (m_data.stage == STAGE_COMPUTE)
	{
		vk.cmdDispatch(*cmdBuffer, DIM, DIM, 1);
	}
#if ENABLE_RAYTRACING
	else if (m_data.stage == STAGE_RAYGEN)
	{
		vk.cmdTraceRaysNV(*cmdBuffer,
			**sbtBuffer, 0,
			DE_NULL, 0, 0,
			DE_NULL, 0, 0,
			DE_NULL, 0, 0,
			DIM, DIM, 1);
	}
#endif
	else
	{
		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer,
						makeRect2D(DIM, DIM),
						0, DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
		// Draw a point cloud for vertex shader testing, and a single quad for fragment shader testing
		if (m_data.stage == STAGE_VERTEX)
		{
			vk.cmdDraw(*cmdBuffer, DIM*DIM, 1u, 0u, 0u);
		}
		else
		{
			vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
		}
		endRenderPass(vk, *cmdBuffer);
	}

	memBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
	memBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
	vk.cmdPipelineBarrier(*cmdBuffer, allPipelineStages, VK_PIPELINE_STAGE_TRANSFER_BIT,
		0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);

	const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeExtent3D(DIM, DIM, 1u),
															 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
	vk.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **copyBuffer, 1u, &copyRegion);

	endCommandBuffer(vk, *cmdBuffer);

	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());

	deUint32 *ptr = (deUint32 *)copyBuffer->getAllocation().getHostPtr();
	invalidateMappedMemoryRange(vk, device, copyBuffer->getAllocation().getMemory(), copyBuffer->getAllocation().getOffset(), DIM*DIM*sizeof(deUint32));

	qpTestResult res = QP_TEST_RESULT_PASS;

	for (deUint32 i = 0; i < DIM*DIM; ++i)
	{
		if (ptr[i] != 1)
		{
			res = QP_TEST_RESULT_FAIL;
		}
	}

	return tcu::TestStatus(res, qpGetTestResultName(res));
}

}	// anonymous

tcu::TestCaseGroup*	createBufferDeviceAddressTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "buffer_device_address", "Test VK_EXT_buffer_device_address"));

	typedef struct
	{
		deUint32				count;
		const char*				name;
		const char*				description;
	} TestGroupCase;

	TestGroupCase setCases[] =
	{
		{ 0,	"set0",		"set 0"		},
		{ 3,	"set3",		"set 3"		},
		{ 7,	"set7",		"set 7"		},
		{ 15,	"set15",	"set 15"	},
		{ 31,	"set31",	"set 31"	},
	};

	TestGroupCase depthCases[] =
	{
		{ 1,	"depth1",	"1 nested struct"		},
		{ 2,	"depth2",	"2 nested structs"		},
		{ 3,	"depth3",	"3 nested structs"		},
	};

	TestGroupCase baseCases[] =
	{
		{ BASE_UBO,	"baseubo",	"base ubo"		},
		{ BASE_SSBO,"basessbo",	"base ssbo"		},
	};

	TestGroupCase cvtCases[] =
	{
		{ CONVERT_NONE,		"load",			"load reference"						},
		{ CONVERT_UTOPTR,	"convert",		"load and convert reference"			},
		{ CONVERT_UVEC2,	"convertuvec2",	"load and convert reference to uvec2"	},
	};

	TestGroupCase storeCases[] =
	{
		{ 0,	"nostore",		"don't store intermediate reference"		},
		{ 1,	"store",		"store intermediate reference"				},
	};

	TestGroupCase btCases[] =
	{
		{ BT_SINGLE,	"single",		"single buffer"	},
		{ BT_MULTI,		"multi",		"multiple buffers"	},
		{ BT_REPLAY,	"replay",		"multiple buffers and VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT"	},
	};

	TestGroupCase layoutCases[] =
	{
		{ LAYOUT_STD140,	"std140",		"std140"	},
		{ LAYOUT_SCALAR,	"scalar",		"scalar"	},
	};

	TestGroupCase stageCases[] =
	{
		{ STAGE_COMPUTE,	"comp",		"compute"	},
		{ STAGE_FRAGMENT,	"frag",		"fragment"	},
		{ STAGE_VERTEX,		"vert",		"vertex"	},
#if ENABLE_RAYTRACING
		{ STAGE_RAYGEN,		"rgen",		"raygen"	},
#endif
	};

	for (int setNdx = 0; setNdx < DE_LENGTH_OF_ARRAY(setCases); setNdx++)
	{
		de::MovePtr<tcu::TestCaseGroup> setGroup(new tcu::TestCaseGroup(testCtx, setCases[setNdx].name, setCases[setNdx].description));
		for (int depthNdx = 0; depthNdx < DE_LENGTH_OF_ARRAY(depthCases); depthNdx++)
		{
			de::MovePtr<tcu::TestCaseGroup> depthGroup(new tcu::TestCaseGroup(testCtx, depthCases[depthNdx].name, depthCases[depthNdx].description));
			for (int baseNdx = 0; baseNdx < DE_LENGTH_OF_ARRAY(baseCases); baseNdx++)
			{
				de::MovePtr<tcu::TestCaseGroup> baseGroup(new tcu::TestCaseGroup(testCtx, baseCases[baseNdx].name, baseCases[baseNdx].description));
				for (int cvtNdx = 0; cvtNdx < DE_LENGTH_OF_ARRAY(cvtCases); cvtNdx++)
				{
					de::MovePtr<tcu::TestCaseGroup> cvtGroup(new tcu::TestCaseGroup(testCtx, cvtCases[cvtNdx].name, cvtCases[cvtNdx].description));
					for (int storeNdx = 0; storeNdx < DE_LENGTH_OF_ARRAY(storeCases); storeNdx++)
					{
						de::MovePtr<tcu::TestCaseGroup> storeGroup(new tcu::TestCaseGroup(testCtx, storeCases[storeNdx].name, storeCases[storeNdx].description));
						for (int btNdx = 0; btNdx < DE_LENGTH_OF_ARRAY(btCases); btNdx++)
						{
							de::MovePtr<tcu::TestCaseGroup> btGroup(new tcu::TestCaseGroup(testCtx, btCases[btNdx].name, btCases[btNdx].description));
							for (int layoutNdx = 0; layoutNdx < DE_LENGTH_OF_ARRAY(layoutCases); layoutNdx++)
							{
								de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(testCtx, layoutCases[layoutNdx].name, layoutCases[layoutNdx].description));
								for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stageCases); stageNdx++)
								{
									CaseDef c =
									{
										setCases[setNdx].count,						// deUint32 set;
										depthCases[depthNdx].count,					// deUint32 depth;
										(Base)baseCases[baseNdx].count,				// Base base;
										(Stage)stageCases[stageNdx].count,			// Stage stage;
										(Convert)cvtCases[cvtNdx].count,			// Convert convertUToPtr;
										!!storeCases[storeNdx].count,				// bool storeInLocal;
										(BufType)btCases[btNdx].count,				// BufType bufType;
										(Layout)layoutCases[layoutNdx].count,		// Layout layout;
									};

									// Skip more complex test cases for most descriptor sets, to reduce runtime.
									if (c.set != 3 && (c.depth == 3 || c.layout != LAYOUT_STD140))
										continue;

									layoutGroup->addChild(new BufferAddressTestCase(testCtx, stageCases[stageNdx].name, stageCases[stageNdx].description, c));
								}
								btGroup->addChild(layoutGroup.release());
							}
							storeGroup->addChild(btGroup.release());
						}
						cvtGroup->addChild(storeGroup.release());
					}
					baseGroup->addChild(cvtGroup.release());
				}
				depthGroup->addChild(baseGroup.release());
			}
			setGroup->addChild(depthGroup.release());
		}
		group->addChild(setGroup.release());
	}
	return group.release();
}

}	// BindingModel
}	// vkt
