/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2021 The Khronos Group Inc.
 * Copyright (c) 2021 Valve 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 Dynamic State tests mixing it with compute and transfer.
 *//*--------------------------------------------------------------------*/
#include "vktDynamicStateComputeTests.hpp"
#include "vktCustomInstancesDevices.hpp"

#include "vkBufferWithMemory.hpp"
#include "vkObjUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkTypeUtil.hpp"

#include "tcuCommandLine.hpp"
#include "tcuVector.hpp"

#include <vector>
#include <string>
#include <functional>
#include <map>
#include <sstream>
#include <cstring>
#include <iterator>
#include <numeric>
#include <memory>

namespace vkt
{
namespace DynamicState
{

namespace
{

using namespace vk;

// Additional objects needed to set a given dynamic state that need to exist beyond the state-setting call. Empty by default.
struct DynamicStateData
{
	virtual ~DynamicStateData() {}
};

// A vertex buffer and graphics pipeline are needed for vkCmdBindVertexBuffers2EXT().
struct BindVertexBuffersData : public DynamicStateData
{
private:
	using BufferPtr			= de::MovePtr<BufferWithMemory>;
	using RenderPassPtr		= Move<VkRenderPass>;
	using LayoutPtr			= Move<VkPipelineLayout>;
	using ModulePtr			= Move<VkShaderModule>;
	using PipelinePtr		= Move<VkPipeline>;

	static constexpr deUint32 kWidth	= 16u;
	static constexpr deUint32 kHeight	= 16u;

	VkExtent3D getExtent (void)
	{
		return makeExtent3D(kWidth, kHeight, 1u);
	}

public:
	BindVertexBuffersData(Context& ctx, VkDevice device)
		: m_vertexBuffer		()
		, m_dataSize			(0u)
		, m_vertexBufferSize	(0ull)
		, m_renderPass			()
		, m_pipelineLayout		()
		, m_vertexShader		()
		, m_graphicsPipeline	()
	{
		const auto&	vki			= ctx.getInstanceInterface();
		const auto	phyDev		= ctx.getPhysicalDevice();
		const auto&	vkd			= ctx.getDeviceInterface();
		auto&		alloc		= ctx.getDefaultAllocator();

		// Vertex buffer.
		tcu::Vec4	vertex		(0.f, 0.f, 0.f, 1.f);
		m_dataSize				= sizeof(vertex);
		m_vertexBufferSize		= de::roundUp(static_cast<VkDeviceSize>(m_dataSize), getPhysicalDeviceProperties(vki, phyDev).limits.nonCoherentAtomSize);
		const auto	bufferInfo	= makeBufferCreateInfo(m_vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);

		m_vertexBuffer			= BufferPtr(new BufferWithMemory(vkd, device, alloc, bufferInfo, MemoryRequirement::HostVisible));
		auto&	bufferAlloc		= m_vertexBuffer->getAllocation();

		deMemcpy(bufferAlloc.getHostPtr(), &vertex, m_dataSize);
		flushAlloc(vkd, device, bufferAlloc);

		// Empty render pass.
		m_renderPass = makeRenderPass(vkd, device);

		// Empty pipeline layout.
		m_pipelineLayout = makePipelineLayout(vkd, device);

		// Passthrough vertex shader.
		m_vertexShader = createShaderModule(vkd, device, ctx.getBinaryCollection().get("vert"), 0u);

		const auto						extent		= getExtent();
		const std::vector<VkViewport>	viewports	(1, makeViewport(extent));
		const std::vector<VkRect2D>		scissors	(1, makeRect2D(extent));
		const VkDynamicState			state		= VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT;

		const VkPipelineDynamicStateCreateInfo dynamicStateInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	//	VkStructureType						sType;
			nullptr,												//	const void*							pNext;
			0u,														//	VkPipelineDynamicStateCreateFlags	flags;
			1u,														//	deUint32							dynamicStateCount;
			&state,													//	const VkDynamicState*				pDynamicStates;
		};

		// Graphics pipeline.
		m_graphicsPipeline = makeGraphicsPipeline(vkd, device, m_pipelineLayout.get(),
			m_vertexShader.get(), DE_NULL, DE_NULL, DE_NULL, DE_NULL,
			m_renderPass.get(), viewports, scissors, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0u, 0u,
			nullptr, nullptr, nullptr, nullptr, nullptr, &dynamicStateInfo);
	}

	const BufferWithMemory*	getVertexBuffer () const
	{
		return m_vertexBuffer.get();
	}

	size_t getDataSize () const
	{
		return m_dataSize;
	}

	VkPipeline getPipeline () const
	{
		return m_graphicsPipeline.get();
	}

	virtual ~BindVertexBuffersData() {}

private:
	BufferPtr		m_vertexBuffer;
	size_t			m_dataSize;
	VkDeviceSize	m_vertexBufferSize;
	RenderPassPtr	m_renderPass;
	LayoutPtr		m_pipelineLayout;
	ModulePtr		m_vertexShader;
	PipelinePtr		m_graphicsPipeline;
};

// Function that records a state-setting command in the given command buffer.
using RecordStateFunction = std::function<void(const DeviceInterface*, VkCommandBuffer, const DynamicStateData*)>;

// State-setting functions
void setViewport (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	const VkViewport viewport =
	{
		0.0f,	//	float	x;
		0.0f,	//	float	y;
		1.0f,	//	float	width;
		1.0f,	//	float	height;
		0.0f,	//	float	minDepth;
		1.0f,	//	float	maxDepth;
	};
	vkd->cmdSetViewport(cmdBuffer, 0u, 1u, &viewport);
}

void setScissor (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	const VkRect2D scissor =
	{
		{ 0, 0 },	//	VkOffset2D	offset;
		{ 1u, 1u },	//	VkExtent2D	extent;
	};
	vkd->cmdSetScissor(cmdBuffer, 0u, 1u, &scissor);
}

void setLineWidth (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetLineWidth(cmdBuffer, 1.0f);
}

void setDepthBias (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetDepthBias(cmdBuffer, 0.0f, 0.0f, 0.0f);
}

void setBlendConstants (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	const float blendConstants[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
	vkd->cmdSetBlendConstants(cmdBuffer, blendConstants);
}

void setDepthBounds (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetDepthBounds(cmdBuffer, 0.0f, 1.0f);
}

void setStencilCompareMask (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetStencilCompareMask(cmdBuffer, VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFu);
}

void setStencilWriteMask (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetStencilWriteMask(cmdBuffer, VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFu);
}

void setStencilReference (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetStencilReference(cmdBuffer, VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFu);
}

void setDiscardRectangle (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	const VkRect2D rectangle =
	{
		{ 0, 0 },	//	VkOffset2D	offset;
		{ 1u, 1u },	//	VkExtent2D	extent;
	};
	vkd->cmdSetDiscardRectangleEXT(cmdBuffer, 0u, 1u, &rectangle);
}

void setSampleLocations (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	const VkSampleLocationEXT locations[] =
	{
		{ 0.5f, 0.5f },
		{ 0.5f, 1.5f },
		{ 1.5f, 0.5f },
		{ 1.5f, 1.5f },
	};
	const VkSampleLocationsInfoEXT info =
	{
		VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,	//	VkStructureType				sType;
		nullptr,										//	const void*					pNext;
		VK_SAMPLE_COUNT_4_BIT,							//	VkSampleCountFlagBits		sampleLocationsPerPixel;
		{ 1u, 1u },										//	VkExtent2D					sampleLocationGridSize;
		4u,												//	deUint32					sampleLocationsCount;
		locations,										//	const VkSampleLocationEXT*	pSampleLocations;
	};
	vkd->cmdSetSampleLocationsEXT(cmdBuffer, &info);
}

void setRTPipelineStatckSize (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetRayTracingPipelineStackSizeKHR(cmdBuffer, 4096u);
}

void setFragmentShadingRage (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	const VkExtent2D							fragmentSize	= { 1u, 1u };
	const VkFragmentShadingRateCombinerOpKHR	combinerOps[2]	=
	{
		VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
		VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
	};
	vkd->cmdSetFragmentShadingRateKHR(cmdBuffer, &fragmentSize, combinerOps);
}

void setLineStipple (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetLineStippleEXT(cmdBuffer, 1u, 1u);
}

void setCullMode (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetCullMode(cmdBuffer, VK_CULL_MODE_FRONT_AND_BACK);
}

void setFrontFace (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetFrontFace(cmdBuffer, VK_FRONT_FACE_COUNTER_CLOCKWISE);
}

void setPrimitiveTopology (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetPrimitiveTopology(cmdBuffer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
}

void setViewportWithCount (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	const VkViewport viewport =
	{
		0.0f,	//	float	x;
		0.0f,	//	float	y;
		1.0f,	//	float	width;
		1.0f,	//	float	height;
		0.0f,	//	float	minDepth;
		1.0f,	//	float	maxDepth;
	};
	vkd->cmdSetViewportWithCount(cmdBuffer, 1u, &viewport);
}

void setScissorWithCount (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	const VkRect2D scissor =
	{
		{ 0, 0 },	//	VkOffset2D	offset;
		{ 1u, 1u },	//	VkExtent2D	extent;
	};
	vkd->cmdSetScissorWithCount(cmdBuffer, 1u, &scissor);
}

void bindVertexBuffers (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData* data)
{
	const auto bindData			= dynamic_cast<const BindVertexBuffersData*>(data);
	DE_ASSERT(bindData != nullptr);
	const auto vertexBuffer		= bindData->getVertexBuffer();
	const auto dataSize			= static_cast<VkDeviceSize>(bindData->getDataSize());
	const auto bufferOffset		= vertexBuffer->getAllocation().getOffset();
	const auto stride			= static_cast<VkDeviceSize>(0);
	const auto pipeline			= bindData->getPipeline();

	vkd->cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
	vkd->cmdBindVertexBuffers2(cmdBuffer, 0u, 1u, &vertexBuffer->get(), &bufferOffset, &dataSize, &stride);
}

void setDepthTestEnable (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetDepthTestEnable(cmdBuffer, VK_TRUE);
}

void setDepthWriteEnable (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetDepthWriteEnable(cmdBuffer, VK_TRUE);
}

void setDepthCompareOp (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetDepthCompareOp(cmdBuffer, VK_COMPARE_OP_LESS);
}

void setDepthBoundsTestEnable (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetDepthBoundsTestEnable(cmdBuffer, VK_TRUE);
}

void setStencilTestEnable (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetStencilTestEnable(cmdBuffer, VK_TRUE);
}

void setStencilOp (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	vkd->cmdSetStencilOp(cmdBuffer, VK_STENCIL_FRONT_AND_BACK, VK_STENCIL_OP_ZERO, VK_STENCIL_OP_INCREMENT_AND_CLAMP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS);
}

void setViewportWScaling (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	const VkViewportWScalingNV viewport =
	{
		1.0f,	//	float	xcoeff;
		1.0f,	//	float	ycoeff;
	};
	vkd->cmdSetViewportWScalingNV(cmdBuffer, 0u, 1u, &viewport);
}

void setViewportShadingRatePalette (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	const VkShadingRatePaletteEntryNV	entry	= VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV;
	const VkShadingRatePaletteNV		palette	=
	{
		1u,		//	deUint32							shadingRatePaletteEntryCount;
		&entry,	//	const VkShadingRatePaletteEntryNV*	pShadingRatePaletteEntries;
	};
	vkd->cmdSetViewportShadingRatePaletteNV(cmdBuffer, 0u, 1u, &palette);
}

void setCoarseSamplingOrder (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	const VkCoarseSampleLocationNV locations[2] =
	{
		{
			0u,	//	deUint32	pixelX;
			0u,	//	deUint32	pixelY;
			0u,	//	deUint32	sample;
		},
		{
			0u,	//	deUint32	pixelX;
			1u,	//	deUint32	pixelY;
			1u,	//	deUint32	sample;
		},
	};
	const VkCoarseSampleOrderCustomNV order =
	{
		VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV,	//	VkShadingRatePaletteEntryNV		shadingRate;
		1u,																//	deUint32						sampleCount;
		2u,																//	deUint32						sampleLocationCount;
		locations														//	const VkCoarseSampleLocationNV*	pSampleLocations;
	};
	vkd->cmdSetCoarseSampleOrderNV(cmdBuffer, VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV, 1u, &order);
}

void setExclusiveScissor (const DeviceInterface* vkd, VkCommandBuffer cmdBuffer, const DynamicStateData*)
{
	const VkRect2D scissor =
	{
		{ 0, 0 },	//	VkOffset2D	offset;
		{ 1u, 1u },	//	VkExtent2D	extent;
	};
	vkd->cmdSetExclusiveScissorNV(cmdBuffer, 0u, 1u, &scissor);
}

const VkDynamicState dynamicStateList[] =
{
	VK_DYNAMIC_STATE_VIEWPORT,
	VK_DYNAMIC_STATE_SCISSOR,
	VK_DYNAMIC_STATE_LINE_WIDTH,
	VK_DYNAMIC_STATE_DEPTH_BIAS,
	VK_DYNAMIC_STATE_BLEND_CONSTANTS,
	VK_DYNAMIC_STATE_DEPTH_BOUNDS,
	VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
	VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
	VK_DYNAMIC_STATE_STENCIL_REFERENCE,
	VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT,
	VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT,
	VK_DYNAMIC_STATE_RAY_TRACING_PIPELINE_STACK_SIZE_KHR,
	VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR,
	VK_DYNAMIC_STATE_LINE_STIPPLE_EXT,
	VK_DYNAMIC_STATE_CULL_MODE_EXT,
	VK_DYNAMIC_STATE_FRONT_FACE_EXT,
	VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,
	VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT,
	VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT,
	VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT,
	VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
	VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
	VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,
	VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT,
	VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT,
	VK_DYNAMIC_STATE_STENCIL_OP_EXT,
	VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV,
	VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV,
	VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV,
	VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV,
};

// Information about a dynamic state.
struct StateInfo
{
	std::vector<std::string>	requirements;	// List of required functionalities.
	RecordStateFunction			recorder;		// Function that records the state to the command buffer being used.
};

// Returns the state info for a given dynamic state.
const StateInfo& getDynamicStateInfo (VkDynamicState state)
{
	// Maps a given state to its state info structure.
	using StateInfoMap = std::map<VkDynamicState, StateInfo>;

	static const StateInfoMap result =
	{
		{	VK_DYNAMIC_STATE_VIEWPORT,								{	{},										setViewport						}	},
		{	VK_DYNAMIC_STATE_SCISSOR,								{	{},										setScissor						}	},
		{	VK_DYNAMIC_STATE_LINE_WIDTH,							{	{},										setLineWidth					}	},
		{	VK_DYNAMIC_STATE_DEPTH_BIAS,							{	{},										setDepthBias					}	},
		{	VK_DYNAMIC_STATE_BLEND_CONSTANTS,						{	{},										setBlendConstants				}	},
		{	VK_DYNAMIC_STATE_DEPTH_BOUNDS,							{	{},										setDepthBounds					}	},
		{	VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,					{	{},										setStencilCompareMask			}	},
		{	VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,					{	{},										setStencilWriteMask				}	},
		{	VK_DYNAMIC_STATE_STENCIL_REFERENCE,						{	{},										setStencilReference				}	},
		{	VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT,					{	{ "VK_EXT_discard_rectangles" },		setDiscardRectangle				}	},
		{	VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT,					{	{ "VK_EXT_sample_locations" },			setSampleLocations				}	},
		{	VK_DYNAMIC_STATE_RAY_TRACING_PIPELINE_STACK_SIZE_KHR,	{	{ "VK_KHR_ray_tracing_pipeline" },		setRTPipelineStatckSize			}	},
		{	VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR,				{	{ "VK_KHR_fragment_shading_rate" },		setFragmentShadingRage			}	},
		{	VK_DYNAMIC_STATE_LINE_STIPPLE_EXT,						{	{ "VK_EXT_line_rasterization" },		setLineStipple					}	},
		{	VK_DYNAMIC_STATE_CULL_MODE_EXT,							{	{ "VK_EXT_extended_dynamic_state" },	setCullMode						}	},
		{	VK_DYNAMIC_STATE_FRONT_FACE_EXT,						{	{ "VK_EXT_extended_dynamic_state" },	setFrontFace					}	},
		{	VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,				{	{ "VK_EXT_extended_dynamic_state" },	setPrimitiveTopology			}	},
		{	VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT,				{	{ "VK_EXT_extended_dynamic_state" },	setViewportWithCount			}	},
		{	VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT,				{	{ "VK_EXT_extended_dynamic_state" },	setScissorWithCount				}	},
		{	VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT,		{	{ "VK_EXT_extended_dynamic_state" },	bindVertexBuffers				}	},
		{	VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,					{	{ "VK_EXT_extended_dynamic_state" },	setDepthTestEnable				}	},
		{	VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,				{	{ "VK_EXT_extended_dynamic_state" },	setDepthWriteEnable				}	},
		{	VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,					{	{ "VK_EXT_extended_dynamic_state" },	setDepthCompareOp				}	},
		{	VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT,			{	{ "VK_EXT_extended_dynamic_state" },	setDepthBoundsTestEnable		}	},
		{	VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT,				{	{ "VK_EXT_extended_dynamic_state" },	setStencilTestEnable			}	},
		{	VK_DYNAMIC_STATE_STENCIL_OP_EXT,						{	{ "VK_EXT_extended_dynamic_state" },	setStencilOp					}	},
		{	VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV,					{	{ "VK_NV_clip_space_w_scaling" },		setViewportWScaling				}	},
		{	VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV,		{	{ "VK_NV_shading_rate_image"},			setViewportShadingRatePalette	}	},
		{	VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV,		{	{ "VK_NV_shading_rate_image"},			setCoarseSamplingOrder			}	},
		{	VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV,					{	{ "VK_NV_scissor_exclusive"},			setExclusiveScissor				}	},
	};

	const auto itr = result.find(state);
	DE_ASSERT(itr != result.end());

	return itr->second;
}

// Device helper: this is needed in some tests when we create custom devices.
class DeviceHelper
{
public:
	virtual ~DeviceHelper () {}
	virtual const DeviceInterface&	getDeviceInterface	(void) const = 0;
	virtual VkDevice				getDevice			(void) const = 0;
	virtual uint32_t				getQueueFamilyIndex	(void) const = 0;
	virtual VkQueue					getQueue			(void) const = 0;
	virtual Allocator&				getAllocator		(void) const = 0;
};

// This one just reuses the default device from the context.
class ContextDeviceHelper : public DeviceHelper
{
public:
	ContextDeviceHelper (Context& context)
		: m_deviceInterface		(context.getDeviceInterface())
		, m_device				(context.getDevice())
		, m_queueFamilyIndex	(context.getUniversalQueueFamilyIndex())
		, m_queue				(context.getUniversalQueue())
		, m_allocator			(context.getDefaultAllocator())
		{}

	virtual ~ContextDeviceHelper () {}

	const DeviceInterface&	getDeviceInterface	(void) const override	{ return m_deviceInterface;		}
	VkDevice				getDevice			(void) const override	{ return m_device;				}
	uint32_t				getQueueFamilyIndex	(void) const override	{ return m_queueFamilyIndex;	}
	VkQueue					getQueue			(void) const override	{ return m_queue;				}
	Allocator&				getAllocator		(void) const override	{ return m_allocator;			}

protected:
	const DeviceInterface&	m_deviceInterface;
	const VkDevice			m_device;
	const uint32_t			m_queueFamilyIndex;
	const VkQueue			m_queue;
	Allocator&				m_allocator;
};

// This one creates a new device with VK_NV_shading_rate_image.
class ShadingRateImageDeviceHelper : public DeviceHelper
{
public:
	ShadingRateImageDeviceHelper (Context& context)
	{
		const auto&	vkp				= context.getPlatformInterface();
		const auto&	vki				= context.getInstanceInterface();
		const auto	instance		= context.getInstance();
		const auto	physicalDevice	= context.getPhysicalDevice();
		const auto	queuePriority	= 1.0f;

		// Queue index first.
		m_queueFamilyIndex = context.getUniversalQueueFamilyIndex();

		// Create a universal queue that supports graphics and compute.
		const VkDeviceQueueCreateInfo queueParams =
		{
			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// VkStructureType				sType;
			DE_NULL,									// const void*					pNext;
			0u,											// VkDeviceQueueCreateFlags		flags;
			m_queueFamilyIndex,							// deUint32						queueFamilyIndex;
			1u,											// deUint32						queueCount;
			&queuePriority								// const float*					pQueuePriorities;
		};

		const char* extensions[] =
		{
			"VK_NV_shading_rate_image",
		};

		VkPhysicalDeviceShadingRateImageFeaturesNV	shadingRateImageFeatures	= initVulkanStructure();
		VkPhysicalDeviceFeatures2					features2					= initVulkanStructure(&shadingRateImageFeatures);

		vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);

		const VkDeviceCreateInfo deviceCreateInfo =
		{
			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,					//sType;
			&features2,												//pNext;
			0u,														//flags
			1u,														//queueRecordCount;
			&queueParams,											//pRequestedQueues;
			0u,														//layerCount;
			nullptr,												//ppEnabledLayerNames;
			static_cast<uint32_t>(de::arrayLength(extensions)),		// deUint32							enabledExtensionCount;
			extensions,												// const char* const*				ppEnabledExtensionNames;
			nullptr,												//pEnabledFeatures;
		};

		m_device	= createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, physicalDevice, &deviceCreateInfo);
		m_vkd		.reset(new DeviceDriver(vkp, instance, m_device.get()));
		m_queue		= getDeviceQueue(*m_vkd, *m_device, m_queueFamilyIndex, 0u);
		m_allocator	.reset(new SimpleAllocator(*m_vkd, m_device.get(), getPhysicalDeviceMemoryProperties(vki, physicalDevice)));
	}

	virtual ~ShadingRateImageDeviceHelper () {}

	const DeviceInterface&	getDeviceInterface	(void) const override	{ return *m_vkd;				}
	VkDevice				getDevice			(void) const override	{ return m_device.get();		}
	uint32_t				getQueueFamilyIndex	(void) const override	{ return m_queueFamilyIndex;	}
	VkQueue					getQueue			(void) const override	{ return m_queue;				}
	Allocator&				getAllocator		(void) const override	{ return *m_allocator;			}

protected:
	Move<VkDevice>						m_device;
	std::unique_ptr<DeviceDriver>		m_vkd;
	deUint32							m_queueFamilyIndex;
	VkQueue								m_queue;
	std::unique_ptr<SimpleAllocator>	m_allocator;
};

std::unique_ptr<DeviceHelper> g_shadingRateDeviceHelper;
std::unique_ptr<DeviceHelper> g_contextDeviceHelper;

DeviceHelper& getDeviceHelper(Context& context, VkDynamicState dynamicState)
{
	const auto& stateInfo = getDynamicStateInfo(dynamicState);

	if (de::contains(stateInfo.requirements.begin(), stateInfo.requirements.end(), "VK_NV_shading_rate_image"))
	{
		if (!g_shadingRateDeviceHelper)
			g_shadingRateDeviceHelper.reset(new ShadingRateImageDeviceHelper(context));
		return *g_shadingRateDeviceHelper;
	}

	if (!g_contextDeviceHelper)
		g_contextDeviceHelper.reset(new ContextDeviceHelper(context));
	return *g_contextDeviceHelper;
}

// Returns the set of auxiliary data needed to set a given state.
de::MovePtr<DynamicStateData> getDynamicStateData (Context& ctx, VkDevice device, VkDynamicState state)
{
	// Create vertex buffer for VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT.
	if (state == VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT)
		return de::MovePtr<DynamicStateData>(new BindVertexBuffersData(ctx, device));

	// null pointer normally.
	return de::MovePtr<DynamicStateData>();
}

enum class OperType		{ COMPUTE = 0,	TRANSFER	};
enum class WhenToSet	{ BEFORE = 0,	AFTER		};

// Set dynamic state before or after attempting to run a compute or transfer operation.
struct TestParams
{
	OperType					operationType;
	WhenToSet					whenToSet;
	std::vector<VkDynamicState>	states;
};

class DynamicStateComputeCase : public vkt::TestCase
{
public:

							DynamicStateComputeCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params);
	virtual					~DynamicStateComputeCase	(void) {}

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

protected:
	TestParams				m_params;
};

class DynamicStateComputeInstance : public vkt::TestInstance
{
public:
								DynamicStateComputeInstance		(Context& context, const TestParams& params);
	virtual						~DynamicStateComputeInstance	(void) {}

	virtual tcu::TestStatus		iterate							(void);

protected:
	tcu::TestStatus				iterateTransfer					(void);
	tcu::TestStatus				iterateCompute					(void);

	TestParams					m_params;
};

DynamicStateComputeCase::DynamicStateComputeCase(tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
	: vkt::TestCase	(testCtx, name, description)
	, m_params		(params)
{}

DynamicStateComputeInstance::DynamicStateComputeInstance (Context& context, const TestParams& params)
	: vkt::TestInstance (context)
	, m_params			(params)
{}

void DynamicStateComputeCase::checkSupport (Context& context) const
{
	// Check required functionalities.
	for (const auto& state : m_params.states)
	{
		const auto stateInfo = getDynamicStateInfo(state);
		for (const auto& functionality : stateInfo.requirements)
			context.requireDeviceFunctionality(functionality);
	}
}

void DynamicStateComputeCase::initPrograms (vk::SourceCollections& programCollection) const
{
	if (m_params.operationType == OperType::COMPUTE)
	{
		std::ostringstream comp;
		comp
			<< "#version 450\n"
			<< "\n"
			<< "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
			<< "\n"
			<< "layout (push_constant, std430) uniform PushConstants {\n"
			<< "	uint valueIndex;\n"
			<< "} pc;\n"
			<< "\n"
			<< "layout (set=0, binding=0, std430) buffer OutputBlock {\n"
			<< "	uint value[];\n"
			<< "} ob;\n"
			<< "\n"
			<< "void main ()\n"
			<< "{\n"
			<< "	ob.value[pc.valueIndex] = 1u;\n"
			<< "}\n"
			;

		programCollection.glslSources.add("comp") << glu::ComputeSource(comp.str());
	}

	if (de::contains(begin(m_params.states), end(m_params.states), VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT))
	{
		// Passthrough vertex shader for stand-in graphics pipeline.
		std::ostringstream vert;
		vert
			<< "#version 450\n"
			<< "layout (location=0) in vec4 inVertex;\n"
			<< "void main() {\n"
			<< "    gl_Position = inVertex;\n"
			<< "}\n"
			;

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

vkt::TestInstance* DynamicStateComputeCase::createInstance (Context& context) const
{
	return new DynamicStateComputeInstance(context, m_params);
}

tcu::TestStatus DynamicStateComputeInstance::iterate (void)
{
	if (m_params.operationType == OperType::COMPUTE)
		return iterateCompute();
	else
		return iterateTransfer();
}

void fillBuffer(const DeviceInterface& vkd, VkDevice device, BufferWithMemory& buffer, const std::vector<deUint32> &values)
{
	auto& alloc = buffer.getAllocation();

	deMemcpy(alloc.getHostPtr(), values.data(), de::dataSize(values));
	flushAlloc(vkd, device, alloc);
}

tcu::TestStatus DynamicStateComputeInstance::iterateTransfer (void)
{
	const auto&	vki			= m_context.getInstanceInterface();
	const auto	phyDev		= m_context.getPhysicalDevice();
	auto&		devHelper	= getDeviceHelper(m_context, m_params.states.at(0));
	const auto&	vkd			= devHelper.getDeviceInterface();
	const auto	device		= devHelper.getDevice();
	const auto	qIndex		= devHelper.getQueueFamilyIndex();
	const auto	queue		= devHelper.getQueue();
	auto&		alloc		= devHelper.getAllocator();

	const auto	cmdPool			= makeCommandPool(vkd, device, qIndex);
	const auto	cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	const auto	cmdBuffer		= cmdBufferPtr.get();

	// Prepare two host-visible buffers for a transfer operation, with one element per dynamic state.
	const deUint32		seqStart	= 1611747605u;

	DE_ASSERT(!m_params.states.empty());
	std::vector<deUint32>		srcValues(m_params.states.size());
	const decltype(srcValues)	dstValues(srcValues.size(), 0u);
	std::iota(begin(srcValues), end(srcValues), seqStart);

	const auto			elemSize	= static_cast<VkDeviceSize>(sizeof(decltype(srcValues)::value_type));
	const auto			dataSize	= static_cast<VkDeviceSize>(de::dataSize(srcValues));
	const auto			bufferSize	= de::roundUp(dataSize, getPhysicalDeviceProperties(vki, phyDev).limits.nonCoherentAtomSize);
	const auto			srcInfo		= makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
	const auto			dstInfo		= makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
	BufferWithMemory	srcBuffer	(vkd, device, alloc, srcInfo, MemoryRequirement::HostVisible);
	BufferWithMemory	dstBuffer	(vkd, device, alloc, dstInfo, MemoryRequirement::HostVisible);

	// Fill source and destination buffer.
	fillBuffer(vkd, device, srcBuffer, srcValues);
	fillBuffer(vkd, device, dstBuffer, dstValues);

	beginCommandBuffer(vkd, cmdBuffer);

	// We need to preserve dynamic state data until the command buffer has run.
	std::vector<de::MovePtr<DynamicStateData>> statesData;

	for (size_t stateIdx = 0; stateIdx < m_params.states.size(); ++stateIdx)
	{
		// Get extra data needed for using the dynamic state.
		const auto	offset		= elemSize * stateIdx;
		const auto&	state		= m_params.states[stateIdx];
		const auto	stateInfo	= getDynamicStateInfo(state);
		statesData.push_back(getDynamicStateData(m_context, device, state));

		// Record command if before.
		if (m_params.whenToSet == WhenToSet::BEFORE)
			stateInfo.recorder(&vkd, cmdBuffer, statesData.back().get());

		// Transfer op (copy one buffer element per dynamic state).
		const VkBufferCopy region = { offset, offset, elemSize };
		vkd.cmdCopyBuffer(cmdBuffer, srcBuffer.get(), dstBuffer.get(), 1u, &region);

		// Record command if after.
		if (m_params.whenToSet == WhenToSet::AFTER)
			stateInfo.recorder(&vkd, cmdBuffer, statesData.back().get());
	}

	const auto barrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);

	endCommandBuffer(vkd, cmdBuffer);
	submitCommandsAndWait(vkd, device, queue, cmdBuffer);

	// Invalidate alloc and check destination buffer.
	auto& dstBufferAlloc = dstBuffer.getAllocation();
	invalidateAlloc(vkd, device, dstBufferAlloc);

	decltype(srcValues) results (srcValues.size());
	deMemcpy(results.data(), dstBufferAlloc.getHostPtr(), de::dataSize(srcValues));

	for (size_t valueIdx = 0; valueIdx < srcValues.size(); ++valueIdx)
	{
		const auto& orig	= srcValues[valueIdx];
		const auto& res		= results[valueIdx];

		if (orig != res)
		{
			std::ostringstream msg;
			msg << "Unexpected value found in destination buffer at position " << valueIdx << " (found=" << res << " expected=" << orig << ")";
			TCU_FAIL(msg.str());
		}
	}

	return tcu::TestStatus::pass("Pass");
}

tcu::TestStatus DynamicStateComputeInstance::iterateCompute (void)
{
	const auto&	vki			= m_context.getInstanceInterface();
	const auto	phyDev		= m_context.getPhysicalDevice();
	auto&		devHelper	= getDeviceHelper(m_context, m_params.states.at(0));
	const auto&	vkd			= devHelper.getDeviceInterface();
	const auto	device		= devHelper.getDevice();
	const auto	qIndex		= devHelper.getQueueFamilyIndex();
	const auto	queue		= devHelper.getQueue();
	auto&		alloc		= devHelper.getAllocator();

	const auto	cmdPool			= makeCommandPool(vkd, device, qIndex);
	const auto	cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	const auto	cmdBuffer		= cmdBufferPtr.get();

	DescriptorSetLayoutBuilder setLayoutBuilder;
	setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
	const auto	setLayout		= setLayoutBuilder.build(vkd, device);

	// Push constants.
	const deUint32	pcSize		= static_cast<deUint32>(sizeof(deUint32));
	const auto		pcRange		= makePushConstantRange(VK_SHADER_STAGE_COMPUTE_BIT, 0u, pcSize);

	// Pipeline.
	const VkPipelineLayoutCreateInfo layoutInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	//	VkStructureType					sType;
		nullptr,										//	const void*						pNext;
		0u,												//	VkPipelineLayoutCreateFlags		flags;
		1u,												//	deUint32						setLayoutCount;
		&setLayout.get(),								//	const VkDescriptorSetLayout*	pSetLayouts;
		1u,												//	deUint32						pushConstantRangeCount;
		&pcRange,										//	const VkPushConstantRange*		pPushConstantRanges;
	};
	const auto pipelineLayout = createPipelineLayout(vkd, device, &layoutInfo);

	const auto shaderModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("comp"), 0u);

	const VkPipelineShaderStageCreateInfo shaderStageInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	//	VkStructureType						sType;
		nullptr,												//	const void*							pNext;
		0u,														//	VkPipelineShaderStageCreateFlags	flags;
		VK_SHADER_STAGE_COMPUTE_BIT,							//	VkShaderStageFlagBits				stage;
		shaderModule.get(),										//	VkShaderModule						module;
		"main",													//	const char*							pName;
		nullptr,												//	const VkSpecializationInfo*			pSpecializationInfo;
	};

	const VkComputePipelineCreateInfo pipelineInfo =
	{
		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,	//	VkStructureType					sType;
		nullptr,										//	const void*						pNext;
		0u,												//	VkPipelineCreateFlags			flags;
		shaderStageInfo,								//	VkPipelineShaderStageCreateInfo	stage;
		pipelineLayout.get(),							//	VkPipelineLayout				layout;
		DE_NULL,										//	VkPipeline						basePipelineHandle;
		0,												//	deInt32							basePipelineIndex;
	};
	const auto pipeline = createComputePipeline(vkd, device, DE_NULL, &pipelineInfo);

	DE_ASSERT(!m_params.states.empty());

	// Output buffer with one value per state.
	std::vector<deUint32>	bufferData			(m_params.states.size(), 0u);
	const auto				dataSize			(de::dataSize(bufferData));
	const auto				outputBufferSize	= de::roundUp(static_cast<VkDeviceSize>(dataSize), getPhysicalDeviceProperties(vki, phyDev).limits.nonCoherentAtomSize);
	const auto				bufferCreateInfo	= makeBufferCreateInfo(outputBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);

	BufferWithMemory		outputBuffer		(vkd, device, alloc, bufferCreateInfo, MemoryRequirement::HostVisible);
	auto&					outputBufferAlloc	= outputBuffer.getAllocation();
	auto					outputBufferPtr		= outputBufferAlloc.getHostPtr();

	deMemcpy(outputBufferPtr, bufferData.data(), dataSize);
	flushAlloc(vkd, device, outputBufferAlloc);

	// Descriptor set.
	DescriptorPoolBuilder poolBuilder;
	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
	const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

	const auto descriptorSet = makeDescriptorSet(vkd, device, descriptorPool.get(), setLayout.get());

	const auto bufferInfo = makeDescriptorBufferInfo(outputBuffer.get(), 0ull, outputBufferSize);
	DescriptorSetUpdateBuilder updateBuilder;
	updateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
	updateBuilder.update(vkd, device);

	// Record and submit.
	beginCommandBuffer(vkd, cmdBuffer);

	// We need to preserve dynamic state data until the command buffer has run.
	std::vector<de::MovePtr<DynamicStateData>> statesData;

	for (size_t stateIdx = 0; stateIdx < m_params.states.size(); ++stateIdx)
	{
		// Objects needed to set the dynamic state.
		const auto&	state		= m_params.states[stateIdx];
		const auto	stateInfo	= getDynamicStateInfo(state);
		statesData.push_back(getDynamicStateData(m_context, device, state));

		if (m_params.whenToSet == WhenToSet::BEFORE)
			stateInfo.recorder(&vkd, cmdBuffer, statesData.back().get());

		vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.get());
		vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
		{
			// Each state will write to a different buffer position.
			const deUint32 pcData = static_cast<deUint32>(stateIdx);
			vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_COMPUTE_BIT, 0u, pcSize, &pcData);
		}
		vkd.cmdDispatch(cmdBuffer, 1u, 1u, 1u);

		if (m_params.whenToSet == WhenToSet::AFTER)
			stateInfo.recorder(&vkd, cmdBuffer, statesData.back().get());
	}

	// Barrier to read buffer contents.
	const auto barrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);

	endCommandBuffer(vkd, cmdBuffer);
	submitCommandsAndWait(vkd, device, queue, cmdBuffer);

	// Read and verify buffer contents.
	invalidateAlloc(vkd, device, outputBufferAlloc);
	deMemcpy(bufferData.data(), outputBufferPtr, dataSize);

	for (size_t idx = 0u; idx < bufferData.size(); ++idx)
	{
		if (bufferData[idx] != 1u)
		{
			std::ostringstream msg;
			msg << "Unexpected value found at buffer position " << idx << ": " << bufferData[idx];
			TCU_FAIL(msg.str());
		}
	}

	return tcu::TestStatus::pass("Pass");
}

std::string getDynamicStateBriefName (VkDynamicState state)
{
	const auto fullName		= de::toString(state);
	const auto prefixLen	= strlen("VK_DYNAMIC_STATE_");

	return de::toLower(fullName.substr(prefixLen));
}

} // anonymous

tcu::TestCaseGroup* createDynamicStateComputeTests (tcu::TestContext& testCtx)
{
	using GroupPtr = de::MovePtr<tcu::TestCaseGroup>;

	GroupPtr mainGroup(new tcu::TestCaseGroup(testCtx, "compute_transfer", "Dynamic state mixed with compute and transfer operations"));

	const struct
	{
		OperType	operationType;
		const char*	name;
	} operations[] =
	{
		{	OperType::COMPUTE,	"compute"	},
		{	OperType::TRANSFER,	"transfer"	},
	};

	const struct
	{
		WhenToSet	when;
		const char*	name;
	} moments[] =
	{
		{	WhenToSet::BEFORE,	"before"	},
		{	WhenToSet::AFTER,	"after"		},
	};

	// Tests with a single dynamic state.
	{
		GroupPtr singleStateGroup(new tcu::TestCaseGroup(testCtx, "single", "Tests using a single dynamic state"));

		for (int operIdx = 0; operIdx < DE_LENGTH_OF_ARRAY(operations); ++operIdx)
		{
			GroupPtr operationGroup(new tcu::TestCaseGroup(testCtx, operations[operIdx].name, ""));

			for (int stateIdx = 0; stateIdx < DE_LENGTH_OF_ARRAY(dynamicStateList); ++stateIdx)
			{
				const auto	state		= dynamicStateList[stateIdx];
				const auto	stateName	= getDynamicStateBriefName(state);

				GroupPtr stateGroup(new tcu::TestCaseGroup(testCtx, stateName.c_str(), ""));

				for (int momentIdx = 0; momentIdx < DE_LENGTH_OF_ARRAY(moments); ++momentIdx)
				{
					const TestParams testParams =
					{
						operations[operIdx].operationType,		//	OperType					operationType;
						moments[momentIdx].when,				//	WhenToSet					whenToSet;
						std::vector<VkDynamicState>(1, state),	//	std::vector<VkDynamicState>	state;
					};

					stateGroup->addChild(new DynamicStateComputeCase(testCtx, moments[momentIdx].name, "", testParams));
				}

				operationGroup->addChild(stateGroup.release());
			}

			singleStateGroup->addChild(operationGroup.release());
		}

		mainGroup->addChild(singleStateGroup.release());
	}

	// A few tests with several dynamic states.
	{
		GroupPtr multiStateGroup(new tcu::TestCaseGroup(testCtx, "multi", "Tests using multiple dynamic states"));

		for (int operIdx = 0; operIdx < DE_LENGTH_OF_ARRAY(operations); ++operIdx)
		{
			GroupPtr operationGroup(new tcu::TestCaseGroup(testCtx, operations[operIdx].name, ""));

			for (int momentIdx = 0; momentIdx < DE_LENGTH_OF_ARRAY(moments); ++momentIdx)
			{
				TestParams testParams =
				{
					operations[operIdx].operationType,	//	OperType					operationType;
					moments[momentIdx].when,			//	WhenToSet					whenToSet;
					std::vector<VkDynamicState>(),		//	std::vector<VkDynamicState>	states;
				};

				// Use the basic states so as not to introduce extra requirements.
				for (int stateIdx = 0; stateIdx < DE_LENGTH_OF_ARRAY(dynamicStateList); ++stateIdx)
				{
					testParams.states.push_back(dynamicStateList[stateIdx]);
					if (dynamicStateList[stateIdx] == VK_DYNAMIC_STATE_STENCIL_REFERENCE)
						break;
				}

				operationGroup->addChild(new DynamicStateComputeCase(testCtx, moments[momentIdx].name, "", testParams));
			}

			multiStateGroup->addChild(operationGroup.release());
		}

		mainGroup->addChild(multiStateGroup.release());
	}

	return mainGroup.release();
}

void cleanupDevice()
{
	g_shadingRateDeviceHelper.reset(nullptr);
	g_contextDeviceHelper.reset(nullptr);
}

} // DynamicState
} // vkt
