/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 The Khronos Group Inc.
 * Copyright (c) 2015 ARM Limited.
 *
 * 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 PushConstant Tests
 *//*--------------------------------------------------------------------*/

#include "vktPipelinePushConstantTests.hpp"
#include "vktPipelineClearUtil.hpp"
#include "vktPipelineImageUtil.hpp"
#include "vktPipelineVertexUtil.hpp"
#include "vktPipelineReferenceRenderer.hpp"

#include "vktTestCase.hpp"
#include "vkImageUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPrograms.hpp"
#include "vkQueryUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkImageWithMemory.hpp"
#include "vkBufferWithMemory.hpp"
#include "vkBarrierUtil.hpp"

#include "tcuImageCompare.hpp"
#include "tcuTestLog.hpp"

#include "deMemory.h"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"

#include <algorithm>
#include <sstream>
#include <vector>

namespace vkt
{
namespace pipeline
{

using namespace vk;

namespace
{

enum
{
	TRIANGLE_COUNT	= 2,
	MAX_RANGE_COUNT	= 5
};

enum RangeSizeCase
{
	SIZE_CASE_4	= 0,
	SIZE_CASE_8,
	SIZE_CASE_12,
	SIZE_CASE_16,
	SIZE_CASE_32,
	SIZE_CASE_36,
	SIZE_CASE_48,
	SIZE_CASE_128,
	SIZE_CASE_UNSUPPORTED
};

enum CommandType
{
	CMD_BIND_PIPELINE_GRAPHICS = 0,
	CMD_BIND_PIPELINE_COMPUTE,
	CMD_PUSH_CONSTANT,
	CMD_DRAW,
	CMD_DISPATCH,
	CMD_UNSUPPORTED
};

struct CommandData
{
	CommandType cType;
	deInt32 rangeNdx;
};

struct PushConstantData
{
	struct PushConstantRange
	{
		VkShaderStageFlags		shaderStage;
		deUint32				offset;
		deUint32				size;
	} range;
	struct PushConstantUpdate
	{
		deUint32				offset;
		deUint32				size;
	} update;
};

// These values will be loaded from push constants and used as an index
static const deUint32 DYNAMIC_VEC_INDEX = 2u;
static const deUint32 DYNAMIC_MAT_INDEX = 0u;
static const deUint32 DYNAMIC_ARR_INDEX = 3u;

// These reference values will be compared in the shader to ensure the correct index was read
static const float DYNAMIC_VEC_CONSTANT = 0.25f;
static const float DYNAMIC_MAT_CONSTANT = 0.50f;
static const float DYNAMIC_ARR_CONSTANT = 0.75f;

enum IndexType
{
	INDEX_TYPE_CONST_LITERAL = 0,
	INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR,

	INDEX_TYPE_LAST
};

enum ComputeTestType
{
	CTT_SIMPLE = 0,
	CTT_UNINITIALIZED,

	CTT_LAST
};

std::string getShaderStageNameStr (VkShaderStageFlags stageFlags)
{
	const VkShaderStageFlags	shaderStages[]		=
	{
		VK_SHADER_STAGE_VERTEX_BIT,
		VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
		VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
		VK_SHADER_STAGE_GEOMETRY_BIT,
		VK_SHADER_STAGE_FRAGMENT_BIT
	};

	const char*					shaderStageNames[]	=
	{
		"VK_SHADER_STAGE_VERTEX_BIT",
		"VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT",
		"VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT",
		"VK_SHADER_STAGE_GEOMETRY_BIT",
		"VK_SHADER_STAGE_FRAGMENT_BIT",
	};

	std::stringstream			shaderStageStr;

	for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(shaderStages); stageNdx++)
	{
		if (stageFlags & shaderStages[stageNdx])
		{
			if (!(shaderStageStr.str().empty()))
				shaderStageStr << " | ";

			shaderStageStr << shaderStageNames[stageNdx];
		}
	}

	return shaderStageStr.str();
}

std::vector<Vertex4RGBA> createQuad(const float size, const tcu::Vec4 &color)
{
	std::vector<Vertex4RGBA>	vertices;

	const Vertex4RGBA			lowerLeftVertex		= {tcu::Vec4(-size, -size, 0.0f, 1.0f), color};
	const Vertex4RGBA			lowerRightVertex	= {tcu::Vec4(size, -size, 0.0f, 1.0f), color};
	const Vertex4RGBA			UpperLeftVertex		= {tcu::Vec4(-size, size, 0.0f, 1.0f), color};
	const Vertex4RGBA			UpperRightVertex	= {tcu::Vec4(size, size, 0.0f, 1.0f), color};

	vertices.push_back(lowerLeftVertex);
	vertices.push_back(lowerRightVertex);
	vertices.push_back(UpperLeftVertex);
	vertices.push_back(UpperLeftVertex);
	vertices.push_back(lowerRightVertex);
	vertices.push_back(UpperRightVertex);

	return vertices;
}

class PushConstantGraphicsTestInstance : public vkt::TestInstance {
public:
												PushConstantGraphicsTestInstance	(Context&					context,
																					 const deUint32				rangeCount,
																					 const PushConstantData		pushConstantRange[MAX_RANGE_COUNT],
																					 const deBool				multipleUpdate,
																					 const IndexType			indexType);
	virtual										~PushConstantGraphicsTestInstance	(void);
	void										init								(void);
	virtual tcu::TestStatus						iterate								(void);
	virtual std::vector<VkPushConstantRange>	getPushConstantRanges				(void) = 0;
	virtual void								updatePushConstants					(VkCommandBuffer cmdBuffer, VkPipelineLayout pipelineLayout) = 0;
	virtual void								setReferenceColor					(tcu::Vec4 initColor) = 0;
	void										createShaderModule					(const DeviceInterface&		vk,
																					 VkDevice					device,
																					 const BinaryCollection&	programCollection,
																					 const char*				name,
																					 Move<VkShaderModule>*		module);
	tcu::TestStatus								verifyImage							(void);

protected:
	std::vector<Vertex4RGBA>						m_vertices;
	const deUint32									m_rangeCount;
	PushConstantData								m_pushConstantRange[MAX_RANGE_COUNT];
	const IndexType									m_indexType;

private:
	const tcu::UVec2								m_renderSize;
	const VkFormat									m_colorFormat;
	const deBool									m_multipleUpdate;

	VkImageCreateInfo								m_colorImageCreateInfo;
	Move<VkImage>									m_colorImage;
	de::MovePtr<Allocation>							m_colorImageAlloc;
	Move<VkImageView>								m_colorAttachmentView;
	Move<VkRenderPass>								m_renderPass;
	Move<VkFramebuffer>								m_framebuffer;

	Move<VkShaderModule>							m_vertexShaderModule;
	Move<VkShaderModule>							m_fragmentShaderModule;
	Move<VkShaderModule>							m_geometryShaderModule;
	Move<VkShaderModule>							m_tessControlShaderModule;
	Move<VkShaderModule>							m_tessEvaluationShaderModule;

	VkShaderStageFlags								m_shaderFlags;
	std::vector<VkPipelineShaderStageCreateInfo>	m_shaderStage;

	Move<VkBuffer>									m_vertexBuffer;
	de::MovePtr<Allocation>							m_vertexBufferAlloc;

	Move<VkBuffer>									m_uniformBuffer;
	de::MovePtr<Allocation>							m_uniformBufferAlloc;
	Move<VkDescriptorPool>							m_descriptorPool;
	Move<VkDescriptorSetLayout>						m_descriptorSetLayout;
	Move<VkDescriptorSet>							m_descriptorSet;

	Move<VkPipelineLayout>							m_pipelineLayout;
	Move<VkPipeline>								m_graphicsPipelines;

	Move<VkCommandPool>								m_cmdPool;
	Move<VkCommandBuffer>							m_cmdBuffer;
};

void PushConstantGraphicsTestInstance::createShaderModule (const DeviceInterface&	vk,
														   VkDevice					device,
														   const BinaryCollection&	programCollection,
														   const char*				name,
														   Move<VkShaderModule>*	module)
{
	*module = vk::createShaderModule(vk, device, programCollection.get(name), 0);
}

PushConstantGraphicsTestInstance::PushConstantGraphicsTestInstance (Context&				context,
																	const deUint32			rangeCount,
																	const PushConstantData	pushConstantRange[MAX_RANGE_COUNT],
																	deBool					multipleUpdate,
																	IndexType				indexType)
	: vkt::TestInstance	(context)
	, m_rangeCount		(rangeCount)
	, m_indexType		(indexType)
	, m_renderSize		(32, 32)
	, m_colorFormat		(VK_FORMAT_R8G8B8A8_UNORM)
	, m_multipleUpdate	(multipleUpdate)
	, m_shaderFlags		(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT)
{
	deMemcpy(m_pushConstantRange, pushConstantRange, sizeof(PushConstantData) * MAX_RANGE_COUNT);
}

void PushConstantGraphicsTestInstance::init (void)
{
	const DeviceInterface&					vk						= m_context.getDeviceInterface();
	const VkDevice							vkDevice				= m_context.getDevice();
	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	SimpleAllocator							memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
	const VkComponentMapping				componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
	const std::vector<VkPushConstantRange>	pushConstantRanges		= getPushConstantRanges();
	bool									useTessellation			= false;
	bool									useGeometry				= false;

	// Create color image
	{
		const VkImageCreateInfo colorImageParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
			DE_NULL,																// const void*				pNext;
			0u,																		// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,														// VkImageType				imageType;
			m_colorFormat,															// VkFormat					format;
			{ m_renderSize.x(), m_renderSize.y(), 1u },								// VkExtent3D				extent;
			1u,																		// deUint32					mipLevels;
			1u,																		// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
			1u,																		// deUint32					queueFamilyIndexCount;
			&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout			initialLayout;
		};

		m_colorImageCreateInfo	= colorImageParams;
		m_colorImage			= createImage(vk, vkDevice, &m_colorImageCreateInfo);

		// Allocate and bind color image memory
		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
	}

	// Create color attachment view
	{
		const VkImageViewCreateInfo colorAttachmentViewParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType				sType;
			DE_NULL,										// const void*					pNext;
			0u,												// VkImageViewCreateFlags		flags;
			*m_colorImage,									// VkImage						image;
			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType				viewType;
			m_colorFormat,									// VkFormat						format;
			componentMappingRGBA,							// VkChannelMapping				channels;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange		subresourceRange;
		};

		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
	}

	// Create render pass
	m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat);

	// Create framebuffer
	{
		const VkImageView attachmentBindInfos[1] =
		{
		  *m_colorAttachmentView
		};

		const VkFramebufferCreateInfo framebufferParams =
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType				sType;
			DE_NULL,									// const void*					pNext;
			0u,											// VkFramebufferCreateFlags		flags;
			*m_renderPass,								// VkRenderPass					renderPass;
			1u,											// deUint32						attachmentCount;
			attachmentBindInfos,						// const VkImageView*			pAttachments;
			(deUint32)m_renderSize.x(),					// deUint32						width;
			(deUint32)m_renderSize.y(),					// deUint32						height;
			1u											// deUint32						layers;
		};

		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
	}

	// Create pipeline layout
	{
		// create descriptor set layout
		m_descriptorSetLayout = DescriptorSetLayoutBuilder().addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT).build(vk, vkDevice);

		// create descriptor pool
		m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u).build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

		// create uniform buffer
		const VkBufferCreateInfo			uniformBufferCreateInfo	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			0u,										// VkBufferCreateFlags	flags
			16u,									// VkDeviceSize			size;
			VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,		// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
		};

		m_uniformBuffer			= createBuffer(vk, vkDevice, &uniformBufferCreateInfo);
		m_uniformBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_uniformBuffer), MemoryRequirement::HostVisible);
		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferAlloc->getMemory(), m_uniformBufferAlloc->getOffset()));

		const tcu::Vec4						value					= tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
		deMemcpy(m_uniformBufferAlloc->getHostPtr(), &value, 16u);
		flushAlloc(vk, vkDevice, *m_uniformBufferAlloc);

		// create and update descriptor set
		const VkDescriptorSetAllocateInfo	allocInfo				=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType                             sType;
			DE_NULL,										// const void*                                 pNext;
			*m_descriptorPool,								// VkDescriptorPool                            descriptorPool;
			1u,												// deUint32                                    setLayoutCount;
			&(*m_descriptorSetLayout),						// const VkDescriptorSetLayout*                pSetLayouts;
		};
		m_descriptorSet	= allocateDescriptorSet(vk, vkDevice, &allocInfo);

		const VkDescriptorBufferInfo		descriptorInfo			= makeDescriptorBufferInfo(*m_uniformBuffer, (VkDeviceSize)0u, (VkDeviceSize)16u);

		DescriptorSetUpdateBuilder()
			.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descriptorInfo)
			.update(vk, vkDevice);

		// create pipeline layout
		const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType;
			DE_NULL,										// const void*					pNext;
			0u,												// VkPipelineLayoutCreateFlags	flags;
			1u,												// deUint32						descriptorSetCount;
			&(*m_descriptorSetLayout),						// const VkDescriptorSetLayout*	pSetLayouts;
			(deUint32)pushConstantRanges.size(),			// deUint32						pushConstantRangeCount;
			&pushConstantRanges.front()						// const VkPushConstantRange*	pPushConstantRanges;
		};

		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
	}

	// Create shaders
	{
		for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
		{
			if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_GEOMETRY_BIT)
			{
				m_shaderFlags |= VK_SHADER_STAGE_GEOMETRY_BIT;
			}
			if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
			{
				m_shaderFlags |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
			}
			if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
			{
				m_shaderFlags |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
			}
		}

		VkPhysicalDeviceFeatures features = m_context.getDeviceFeatures();

		createShaderModule(vk, vkDevice, m_context.getBinaryCollection(), "color_vert", &m_vertexShaderModule);
		if (m_shaderFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || m_shaderFlags & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
		{
			if (features.tessellationShader == VK_FALSE)
			{
				TCU_THROW(NotSupportedError, "Tessellation Not Supported");
			}
			createShaderModule(vk, vkDevice, m_context.getBinaryCollection(), "color_tesc", &m_tessControlShaderModule);
			createShaderModule(vk, vkDevice, m_context.getBinaryCollection(), "color_tese", &m_tessEvaluationShaderModule);
			useTessellation = true;
		}
		if (m_shaderFlags & VK_SHADER_STAGE_GEOMETRY_BIT)
		{
			if (features.geometryShader == VK_FALSE)
			{
				TCU_THROW(NotSupportedError, "Geometry Not Supported");
			}
			createShaderModule(vk, vkDevice, m_context.getBinaryCollection(), "color_geom", &m_geometryShaderModule);
			useGeometry = true;
		}
		createShaderModule(vk, vkDevice, m_context.getBinaryCollection(), "color_frag", &m_fragmentShaderModule);
	}

	// Create pipeline
	{
		const VkVertexInputBindingDescription			vertexInputBindingDescription		=
		{
			0u,							// deUint32					binding;
			sizeof(Vertex4RGBA),		// deUint32					strideInBytes;
			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate;
		};

		const VkVertexInputAttributeDescription			vertexInputAttributeDescriptions[]	=
		{
			{
				0u,								// deUint32	location;
				0u,								// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
				0u								// deUint32	offsetInBytes;
			},
			{
				1u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
			}
		};

		const VkPipelineVertexInputStateCreateInfo		vertexInputStateParams				=
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
			DE_NULL,													// const void*								pNext;
			0u,															// vkPipelineVertexInputStateCreateFlags	flags;
			1u,															// deUint32									bindingCount;
			&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
			2u,															// deUint32									attributeCount;
			vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
		};

		const VkPrimitiveTopology						topology							= (m_shaderFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;

		const std::vector<VkViewport>					viewports							(1, makeViewport(m_renderSize));
		const std::vector<VkRect2D>						scissors							(1, makeRect2D(m_renderSize));

		m_graphicsPipelines = makeGraphicsPipeline(vk,															// const DeviceInterface&                        vk
												   vkDevice,													// const VkDevice                                device
												   *m_pipelineLayout,											// const VkPipelineLayout                        pipelineLayout
												   *m_vertexShaderModule,										// const VkShaderModule                          vertexShaderModule
												   useTessellation ? *m_tessControlShaderModule : DE_NULL,		// const VkShaderModule                          tessellationControlShaderModule
												   useTessellation ? *m_tessEvaluationShaderModule : DE_NULL,	// const VkShaderModule                          tessellationEvalShaderModule
												   useGeometry ? *m_geometryShaderModule : DE_NULL,				// const VkShaderModule                          geometryShaderModule
												   *m_fragmentShaderModule,										// const VkShaderModule                          fragmentShaderModule
												   *m_renderPass,												// const VkRenderPass                            renderPass
												   viewports,													// const std::vector<VkViewport>&                viewports
												   scissors,													// const std::vector<VkRect2D>&                  scissors
												   topology,													// const VkPrimitiveTopology                     topology
												   0u,															// const deUint32                                subpass
												   3u,															// const deUint32                                patchControlPoints
												   &vertexInputStateParams);									// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
	}

	// Create vertex buffer
	{
		m_vertices			= createQuad(1.0f, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));

		const VkBufferCreateInfo vertexBufferParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,						// VkStructureType		sType;
			DE_NULL,													// const void*			pNext;
			0u,															// VkBufferCreateFlags	flags;
			(VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()),	// VkDeviceSize			size;
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,							// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,									// VkSharingMode		sharingMode;
			1u,															// deUint32				queueFamilyCount;
			&queueFamilyIndex											// const deUint32*		pQueueFamilyIndices;
		};

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

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

		// Load vertices into vertex buffer
		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
	}

	// Create command pool
	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);

	// Create command buffer
	{
		const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);

		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

		beginCommandBuffer(vk, *m_cmdBuffer, 0u);

		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);

		// Update push constant values
		updatePushConstants(*m_cmdBuffer, *m_pipelineLayout);

		// draw quad
		const VkDeviceSize				triangleOffset			= (m_vertices.size() / TRIANGLE_COUNT) * sizeof(Vertex4RGBA);

		for (int triangleNdx = 0; triangleNdx < TRIANGLE_COUNT; triangleNdx++)
		{
			VkDeviceSize vertexBufferOffset = triangleOffset * triangleNdx;

			if (m_multipleUpdate)
				vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange[0].range.shaderStage, m_pushConstantRange[0].range.offset, m_pushConstantRange[0].range.size, &triangleNdx);

			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
			vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &(*m_descriptorSet), 0, DE_NULL);

			vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / TRIANGLE_COUNT), 1, 0, 0);
		}

		endRenderPass(vk, *m_cmdBuffer);
		endCommandBuffer(vk, *m_cmdBuffer);
	}
}

PushConstantGraphicsTestInstance::~PushConstantGraphicsTestInstance (void)
{
}

tcu::TestStatus PushConstantGraphicsTestInstance::iterate (void)
{
	init();

	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	const VkQueue				queue		= m_context.getUniversalQueue();

	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());

	return verifyImage();
}

tcu::TestStatus PushConstantGraphicsTestInstance::verifyImage (void)
{
	const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_colorFormat);
	const tcu::TextureFormat	tcuDepthFormat	= tcu::TextureFormat();
	const ColorVertexShader		vertexShader;
	const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
	const rr::Program			program			(&vertexShader, &fragmentShader);
	ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
	bool						compareOk		= false;

	// Render reference image
	{
		if (m_shaderFlags & VK_SHADER_STAGE_GEOMETRY_BIT)
		{
			m_vertices = createQuad(0.5f, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
		}

		setReferenceColor(m_vertices[0].color);

		if (m_multipleUpdate)
		{
			for (size_t vertexNdx = 0; vertexNdx < 3; vertexNdx++)
			{
				m_vertices[vertexNdx].color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f);
			}
			for (size_t vertexNdx = 3; vertexNdx < m_vertices.size(); vertexNdx++)
			{
				m_vertices[vertexNdx].color.xyz() = tcu::Vec3(0.0f, 0.0f, 1.0f);
			}
		}

		for (int triangleNdx = 0; triangleNdx < TRIANGLE_COUNT; triangleNdx++)
		{
			rr::RenderState renderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);

			refRenderer.draw(renderState,
							 rr::PRIMITIVETYPE_TRIANGLES,
							 std::vector<Vertex4RGBA>(m_vertices.begin() + triangleNdx * 3,
													  m_vertices.begin() + (triangleNdx + 1) * 3));
		}
	}

	// Compare result with reference image
	{
		const DeviceInterface&			vk					= m_context.getDeviceInterface();
		const VkDevice					vkDevice			= m_context.getDevice();
		const VkQueue					queue				= m_context.getUniversalQueue();
		const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
		SimpleAllocator					allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
		de::MovePtr<tcu::TextureLevel>	result				= readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);

		compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
															  "IntImageCompare",
															  "Image comparison",
															  refRenderer.getAccess(),
															  result->getAccess(),
															  tcu::UVec4(2, 2, 2, 2),
															  tcu::IVec3(1, 1, 0),
															  true,
															  tcu::COMPARE_LOG_RESULT);
	}

	if (compareOk)
		return tcu::TestStatus::pass("Result image matches reference");
	else
		return tcu::TestStatus::fail("Image mismatch");
}

class PushConstantGraphicsDisjointInstance : public PushConstantGraphicsTestInstance
{
public:
										PushConstantGraphicsDisjointInstance	(Context&					context,
																				 const deUint32				rangeCount,
																				 const PushConstantData		pushConstantRange[MAX_RANGE_COUNT],
																				 const deBool				multipleUpdate,
																				 const IndexType			indexType);
	virtual								~PushConstantGraphicsDisjointInstance	(void);
	std::vector<VkPushConstantRange>	getPushConstantRanges					(void);
	void								updatePushConstants						(VkCommandBuffer cmdBuffer, VkPipelineLayout pipelineLayout);
	void								setReferenceColor						(tcu::Vec4 initColor);
};


PushConstantGraphicsDisjointInstance::PushConstantGraphicsDisjointInstance (Context&					context,
																			const deUint32				rangeCount,
																			const PushConstantData		pushConstantRange[MAX_RANGE_COUNT],
																			deBool						multipleUpdate,
																			IndexType					indexType)
	: PushConstantGraphicsTestInstance (context, rangeCount, pushConstantRange, multipleUpdate, indexType)
{
	deMemcpy(m_pushConstantRange, pushConstantRange, sizeof(PushConstantData) * MAX_RANGE_COUNT);
}

PushConstantGraphicsDisjointInstance::~PushConstantGraphicsDisjointInstance(void)
{
}

std::vector<VkPushConstantRange> PushConstantGraphicsDisjointInstance::getPushConstantRanges (void)
{
	std::vector<VkPushConstantRange> pushConstantRanges;

	for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
	{
		const VkPushConstantRange pushConstantRange =
		{
			m_pushConstantRange[rangeNdx].range.shaderStage,
			m_pushConstantRange[rangeNdx].range.offset,
			m_pushConstantRange[rangeNdx].range.size
		};

		pushConstantRanges.push_back(pushConstantRange);
	}

	return pushConstantRanges;
}

void PushConstantGraphicsDisjointInstance::updatePushConstants (VkCommandBuffer cmdBuffer, VkPipelineLayout pipelineLayout)
{
	const DeviceInterface&	vk		= m_context.getDeviceInterface();
	std::vector<tcu::Vec4>	color	(8, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
	std::vector<tcu::Vec4>	allOnes	(8, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));

	switch (m_indexType)
	{
		case INDEX_TYPE_CONST_LITERAL:
			// Do nothing
			break;
		case INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR:
			// Stick our dynamic index at the beginning of a vector
			color[0] = tcu::Vec4(	float(DYNAMIC_VEC_INDEX),
									float(DYNAMIC_MAT_INDEX),
									float(DYNAMIC_ARR_INDEX),
									1.0f);

			// Place our reference values at each type offset

			// vec4[i]
			DE_ASSERT(DYNAMIC_VEC_INDEX <= 3);
			color[1] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
			color[1][DYNAMIC_VEC_INDEX] = DYNAMIC_VEC_CONSTANT;

			// mat2[i][0]
			DE_ASSERT(DYNAMIC_MAT_INDEX <= 1);
			color[2] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
			color[2][DYNAMIC_MAT_INDEX * 2] = DYNAMIC_MAT_CONSTANT;

			// float[i]
			DE_ASSERT(DYNAMIC_ARR_INDEX <= 3);
			color[3] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
			color[3][DYNAMIC_ARR_INDEX] = DYNAMIC_ARR_CONSTANT;
			break;
		default:
			DE_FATAL("Unhandled IndexType");
			break;
	}

	const deUint32			kind	= 2u;
	const void*				value	= DE_NULL;

	for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
	{
		value = (m_pushConstantRange[rangeNdx].range.size == 4u) ? (void*)(&kind) : (void*)(&color[0]);

		vk.cmdPushConstants(cmdBuffer, pipelineLayout, m_pushConstantRange[rangeNdx].range.shaderStage, m_pushConstantRange[rangeNdx].range.offset, m_pushConstantRange[rangeNdx].range.size, value);

		if (m_pushConstantRange[rangeNdx].update.size < m_pushConstantRange[rangeNdx].range.size)
		{
			value = (void*)(&allOnes[0]);
			vk.cmdPushConstants(cmdBuffer, pipelineLayout, m_pushConstantRange[rangeNdx].range.shaderStage, m_pushConstantRange[rangeNdx].update.offset, m_pushConstantRange[rangeNdx].update.size, value);
		}
	}
}

void PushConstantGraphicsDisjointInstance::setReferenceColor (tcu::Vec4 initColor)
{
	DE_UNREF(initColor);

	const tcu::Vec4 color = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);

	for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
	{
		if (m_pushConstantRange[rangeNdx].update.size < m_pushConstantRange[rangeNdx].range.size)
		{
			for (size_t vertexNdx = 0; vertexNdx < m_vertices.size(); vertexNdx++)
			{
				m_vertices[vertexNdx].color.xyzw() = color;
			}
		}
	}
}

class PushConstantGraphicsOverlapTestInstance : public PushConstantGraphicsTestInstance
{
public:
										PushConstantGraphicsOverlapTestInstance		(Context&					context,
																				const deUint32				rangeCount,
																				const PushConstantData		pushConstantRange[MAX_RANGE_COUNT],
																				const deBool				multipleUpdate,
																				const IndexType			indexType);
	virtual								~PushConstantGraphicsOverlapTestInstance	(void);
	std::vector<VkPushConstantRange>	getPushConstantRanges					(void);
	std::vector<VkPushConstantRange>	getPushConstantUpdates					(void);
	void								updatePushConstants						(VkCommandBuffer cmdBuffer, VkPipelineLayout pipelineLayout);
	void								setReferenceColor						(tcu::Vec4 initColor);

private:
	const std::vector<float>			m_colorData;
	std::vector<float>					m_referenceData;
};

std::vector<float> generateColorData (deUint32 numBytes)
{
	DE_ASSERT(numBytes % 4u == 0u);

	std::vector<float> colorData;

	deRandom random;
	deRandom_init(&random, numBytes);

	for (deUint32 elementNdx = 0u; elementNdx < numBytes / 4u; elementNdx++)
		colorData.push_back(deRandom_getFloat(&random));

	return colorData;
}

PushConstantGraphicsOverlapTestInstance::PushConstantGraphicsOverlapTestInstance (Context&					context,
																				  const deUint32			rangeCount,
																				  const PushConstantData	pushConstantRange[MAX_RANGE_COUNT],
																				  deBool					multipleUpdate,
																				  IndexType					indexType)
	: PushConstantGraphicsTestInstance	(context, rangeCount, pushConstantRange, multipleUpdate, indexType)
	, m_colorData						(generateColorData(256u))
{
	deMemcpy(m_pushConstantRange, pushConstantRange, sizeof(PushConstantData) * MAX_RANGE_COUNT);
}

PushConstantGraphicsOverlapTestInstance::~PushConstantGraphicsOverlapTestInstance(void)
{
}

std::vector<VkPushConstantRange> PushConstantGraphicsOverlapTestInstance::getPushConstantRanges (void)
{
	// Find push constant ranges for each shader stage
	const VkShaderStageFlags			shaderStages[]		=
	{
		VK_SHADER_STAGE_VERTEX_BIT,
		VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
		VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
		VK_SHADER_STAGE_GEOMETRY_BIT,
		VK_SHADER_STAGE_FRAGMENT_BIT,
	};

	std::vector<VkPushConstantRange>	pushConstantRanges;

	m_context.getTestContext().getLog() << tcu::TestLog::Section("Ranges", "Push constant ranges");

	for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(shaderStages); stageNdx++)
	{
		deUint32 firstByte	= ~0u;
		deUint32 lastByte	= 0u;

		for (deUint32 rangeNdx = 0u; rangeNdx < m_rangeCount; rangeNdx++)
		{
			if (m_pushConstantRange[rangeNdx].range.shaderStage & shaderStages[stageNdx])
			{
				firstByte	= deMinu32(firstByte, m_pushConstantRange[rangeNdx].range.offset);
				lastByte	= deMaxu32(lastByte, m_pushConstantRange[rangeNdx].range.offset + m_pushConstantRange[rangeNdx].range.size);
			}
		}

		if (firstByte != ~0u)
		{
			const VkPushConstantRange pushConstantRange =
			{
				shaderStages[stageNdx],	// VkShaderStageFlags    stageFlags
				firstByte,				// deUint32              offset
				lastByte - firstByte	// deUint32              size
			};

			pushConstantRanges.push_back(pushConstantRange);

			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "VkShaderStageFlags    stageFlags    " << getShaderStageNameStr(shaderStages[stageNdx]) << ",\n"
				<< "deUint32              offset        " << pushConstantRange.offset << ",\n"
				<< "deUint32              size          " << pushConstantRange.size << "\n"
				<< tcu::TestLog::EndMessage;
		}
	}

	m_context.getTestContext().getLog() << tcu::TestLog::EndSection;

	return pushConstantRanges;
}

std::vector<VkPushConstantRange> PushConstantGraphicsOverlapTestInstance::getPushConstantUpdates (void)
{
	VkShaderStageFlags					lastStageFlags		= (VkShaderStageFlags)~0u;
	std::vector<VkPushConstantRange>	pushConstantUpdates;

	// Find matching shader stages for every 4 byte chunk
	for (deUint32 offset = 0u; offset < 128u; offset += 4u)
	{
		VkShaderStageFlags	stageFlags	= (VkShaderStageFlags)0u;
		bool				updateRange	= false;

		// For each byte in the range specified by offset and size and for each push constant range that overlaps that byte,
		// stageFlags must include all stages in that push constant range's VkPushConstantRange::stageFlags
		for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
		{
			const deUint32 rangeStart	= m_pushConstantRange[rangeNdx].range.offset;
			const deUint32 rangeEnd		= rangeStart + m_pushConstantRange[rangeNdx].range.size;

			const deUint32 updateStart	= m_pushConstantRange[rangeNdx].update.offset;
			const deUint32 updateEnd	= updateStart + m_pushConstantRange[rangeNdx].update.size;

			updateRange |= (updateStart <= offset && updateEnd >= offset + 4u);

			DE_ASSERT(rangeEnd <= 128u);

			if (rangeStart <= offset && rangeEnd >= offset + 4u)
				stageFlags |= m_pushConstantRange[rangeNdx].range.shaderStage;
		}

		// Skip chunks with no updates
		if (!stageFlags || !updateRange)
			continue;

		// Add new update entry
		if (stageFlags != lastStageFlags)
		{
			const VkPushConstantRange update =
			{
				stageFlags,	// VkShaderStageFlags    stageFlags;
				offset,		// deUint32              offset;
				4u			// deUint32              size;
			};

			pushConstantUpdates.push_back(update);
			lastStageFlags = stageFlags;
		}
		// Increase current update entry size
		else
		{
			DE_ASSERT(pushConstantUpdates.size() > 0u);
			pushConstantUpdates.back().size += 4u;
		}
	}

	return pushConstantUpdates;
}

void PushConstantGraphicsOverlapTestInstance::updatePushConstants (VkCommandBuffer cmdBuffer, VkPipelineLayout pipelineLayout)
{
	const DeviceInterface&				vk = m_context.getDeviceInterface();
	const std::vector<VkPushConstantRange> pushConstantUpdates = getPushConstantUpdates();

	m_referenceData.resize(m_colorData.size(), 0.0f);

	m_context.getTestContext().getLog() << tcu::TestLog::Section("Updates", "Push constant updates");

	for (deUint32 pushNdx = 0u; pushNdx < pushConstantUpdates.size(); pushNdx++)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "VkShaderStageFlags    stageFlags    " << getShaderStageNameStr(pushConstantUpdates[pushNdx].stageFlags) << ",\n"
			<< "deUint32              offset        " << pushConstantUpdates[pushNdx].offset << ",\n"
			<< "deUint32              size          " << pushConstantUpdates[pushNdx].size << ",\n"
			<< "const void*           pValues       " << &m_colorData[pushConstantUpdates[pushNdx].offset / 2u] << "\n"
			<< tcu::TestLog::EndMessage;

		vk.cmdPushConstants(cmdBuffer, pipelineLayout, pushConstantUpdates[pushNdx].stageFlags, pushConstantUpdates[pushNdx].offset, pushConstantUpdates[pushNdx].size, &m_colorData[pushConstantUpdates[pushNdx].offset / 2u]);

		// Copy push constant values to reference buffer
		DE_ASSERT((pushConstantUpdates[pushNdx].offset / 2u + pushConstantUpdates[pushNdx].size) < 4u * m_colorData.size());
		deMemcpy(&m_referenceData.at(pushConstantUpdates[pushNdx].offset / 4u), &m_colorData.at(pushConstantUpdates[pushNdx].offset / 2u), pushConstantUpdates[pushNdx].size);
	}

	m_context.getTestContext().getLog() << tcu::TestLog::EndSection;
}

void PushConstantGraphicsOverlapTestInstance::setReferenceColor (tcu::Vec4 initColor)
{
	tcu::Vec4 expectedColor = initColor;

	// Calculate reference color
	for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
	{
		const deUint32	offset = m_pushConstantRange[rangeNdx].range.offset / 4u;
		const deUint32	size = m_pushConstantRange[rangeNdx].range.size / 4u;
		const deUint32	numComponents = (size < 4u) ? size : 4u;
		const deUint32	colorNdx = (offset + size - numComponents);

		for (deUint32 componentNdx = 0u; componentNdx < numComponents; componentNdx++)
			expectedColor[componentNdx] += m_referenceData[colorNdx + componentNdx];
	}

	expectedColor = tcu::min(tcu::mod(expectedColor, tcu::Vec4(2.0f)), 2.0f - tcu::mod(expectedColor, tcu::Vec4(2.0f)));

	for (size_t vertexNdx = 0; vertexNdx < m_vertices.size(); vertexNdx++)
	{
		m_vertices[vertexNdx].color.xyzw() = expectedColor;
	}
}

class PushConstantGraphicsTest : public vkt::TestCase
{
public:
							PushConstantGraphicsTest	(tcu::TestContext&			testContext,
														 const std::string&			name,
														 const std::string&			description,
														 const deUint32				rangeCount,
														 const PushConstantData		pushConstantRange[MAX_RANGE_COUNT],
														 const deBool				multipleUpdate,
														 const IndexType			indexType);
	virtual					~PushConstantGraphicsTest	(void);
	virtual void			initPrograms				(SourceCollections& sourceCollections) const = 0;
	virtual TestInstance*	createInstance				(Context& context) const = 0;
	RangeSizeCase			getRangeSizeCase			(deUint32 rangeSize) const;

protected:
	const deUint32			m_rangeCount;
	PushConstantData		m_pushConstantRange[MAX_RANGE_COUNT];
	const deBool			m_multipleUpdate;
	const IndexType			m_indexType;
};

PushConstantGraphicsTest::PushConstantGraphicsTest (tcu::TestContext&			testContext,
													const std::string&			name,
													const std::string&			description,
													const deUint32				rangeCount,
													const PushConstantData		pushConstantRange[MAX_RANGE_COUNT],
													const deBool				multipleUpdate,
													const IndexType				indexType)
	: vkt::TestCase		(testContext, name, description)
	, m_rangeCount		(rangeCount)
	, m_multipleUpdate	(multipleUpdate)
	, m_indexType		(indexType)
{
	deMemcpy(m_pushConstantRange, pushConstantRange, sizeof(PushConstantData) * MAX_RANGE_COUNT);
}

PushConstantGraphicsTest::~PushConstantGraphicsTest (void)
{
}

RangeSizeCase PushConstantGraphicsTest::getRangeSizeCase (deUint32 rangeSize) const
{
	switch (rangeSize)
	{
		case 8:
			return SIZE_CASE_8;
		case 4:
			return SIZE_CASE_4;
		case 12:
			return SIZE_CASE_12;
		case 16:
			return SIZE_CASE_16;
		case 32:
			return SIZE_CASE_32;
		case 36:
			return SIZE_CASE_36;
		case 48:
			return SIZE_CASE_48;
		case 128:
			return SIZE_CASE_128;
		default:
			DE_FATAL("Range size unsupported yet");
			return SIZE_CASE_UNSUPPORTED;
	}
}

class PushConstantGraphicsDisjointTest : public PushConstantGraphicsTest
{
public:
							PushConstantGraphicsDisjointTest	(tcu::TestContext&			testContext,
																 const std::string&			name,
																 const std::string&			description,
																 const deUint32				rangeCount,
																 const PushConstantData		pushConstantRange[MAX_RANGE_COUNT],
																 const deBool				multipleUpdate,
																 const IndexType			indexType);
	virtual					~PushConstantGraphicsDisjointTest	(void);
	virtual void			initPrograms						(SourceCollections& sourceCollections) const;
	virtual TestInstance*	createInstance						(Context& context) const;
};

PushConstantGraphicsDisjointTest::PushConstantGraphicsDisjointTest (tcu::TestContext&		testContext,
																	const std::string&		name,
																	const std::string&		description,
																	const deUint32			rangeCount,
																	const PushConstantData	pushConstantRange[MAX_RANGE_COUNT],
																	const deBool			multipleUpdate,
																	const IndexType			indexType)
	: PushConstantGraphicsTest (testContext, name, description, rangeCount, pushConstantRange, multipleUpdate, indexType)
{
}

PushConstantGraphicsDisjointTest::~PushConstantGraphicsDisjointTest (void)
{
}

void PushConstantGraphicsDisjointTest::initPrograms (SourceCollections& sourceCollections) const
{
	std::ostringstream	vertexSrc;
	std::ostringstream	fragmentSrc;
	std::ostringstream	geometrySrc;
	std::ostringstream	tessControlSrc;
	std::ostringstream	tessEvaluationSrc;

	for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
	{
		if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_VERTEX_BIT)
		{
			vertexSrc << "#version 450\n"
					  << "layout(location = 0) in highp vec4 position;\n"
					  << "layout(location = 1) in highp vec4 color;\n"
					  << "layout(location = 0) out highp vec4 vtxColor;\n"
					  << "out gl_PerVertex { vec4 gl_Position; };\n"
					  << "layout(push_constant) uniform Material {\n";

			switch (m_indexType)
			{
				case INDEX_TYPE_CONST_LITERAL:
					switch (getRangeSizeCase(m_pushConstantRange[rangeNdx].range.size))
					{
						case SIZE_CASE_4:
							vertexSrc << "int kind;\n"
									  << "} matInst;\n";
							break;
						case SIZE_CASE_16:
							vertexSrc << "vec4 color;\n"
									  << "} matInst;\n"
									  << "layout(std140, binding = 0) uniform UniformBuf {\n"
									  << "vec4 element;\n"
									  << "} uniformBuf;\n";
							break;
						case SIZE_CASE_32:
							vertexSrc << "vec4 color[2];\n"
									  << "} matInst;\n";
							break;
						case SIZE_CASE_48:
							vertexSrc << "int dummy1;\n"
									  << "vec4 dummy2;\n"
									  << "vec4 color;\n"
									  << "} matInst;\n";
							break;
						case SIZE_CASE_128:
							vertexSrc << "vec4 color[8];\n"
									  << "} matInst;\n";
							break;
						default:
							DE_FATAL("Not implemented yet");
							break;
					}
					break;
				case INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR:
					vertexSrc << "    layout(offset = 0)  vec4 index; \n"
							  << "    layout(offset = 16) vec4 vecType; \n"
							  << "    layout(offset = 32) mat2 matType; \n"
							  << "    layout(offset = 48) float[4] arrType; \n"
							  << "} matInst;\n";
					break;
				default:
					DE_FATAL("Unhandled IndexType");
					break;
			}

			vertexSrc << "void main()\n"
					  << "{\n"
					  << "	gl_Position = position;\n";

			switch (m_indexType)
			{
				case INDEX_TYPE_CONST_LITERAL:
					switch (getRangeSizeCase(m_pushConstantRange[rangeNdx].range.size))
					{
						case SIZE_CASE_4:
							vertexSrc << "switch (matInst.kind) {\n"
									  << "case 0: vtxColor = vec4(0.0, 1.0, 0, 1.0); break;\n"
									  << "case 1: vtxColor = vec4(0.0, 0.0, 1.0, 1.0); break;\n"
									  << "case 2: vtxColor = vec4(1.0, 0.0, 0, 1.0); break;\n"
									  << "default: vtxColor = color; break;}\n"
									  << "}\n";
							break;
						case SIZE_CASE_16:
							vertexSrc << "vtxColor = (matInst.color + uniformBuf.element) * 0.5;\n"
									  << "}\n";
							break;
						case SIZE_CASE_32:
							vertexSrc << "vtxColor = (matInst.color[0] + matInst.color[1]) * 0.5;\n"
									  << "}\n";
							break;
						case SIZE_CASE_48:
							vertexSrc << "vtxColor = matInst.color;\n"
									  << "}\n";
							break;
						case SIZE_CASE_128:
							vertexSrc << "vec4 color = vec4(0.0, 0, 0, 0.0);\n"
									  << "for (int i = 0; i < 8; i++)\n"
									  << "{\n"
									  << "  color = color + matInst.color[i];\n"
									  << "}\n"
									  << "vtxColor = color * 0.125;\n"
									  << "}\n";
							break;
						default:
							DE_FATAL("Not implemented yet");
							break;
					}
					break;
				case INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR:
					{
						vertexSrc << "    vtxColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
								  // Mix in gl_Position to (hopefully) prevent optimizing our index away
								  << "    int vec_selector = int(abs(gl_Position.x) * 0.0000001 + 0);\n"
								  << "    int mat_selector = int(abs(gl_Position.x) * 0.0000001 + 1);\n"
								  << "    int arr_selector = int(abs(gl_Position.x) * 0.0000001 + 2);\n";

						// Use the dynamic index to pull our real index value from push constants
						// Then use that value to index into three variable types
						std::string vecValue = "matInst.vecType[int(matInst.index[vec_selector])]";
						std::string matValue = "matInst.matType[int(matInst.index[mat_selector])][0]";
						std::string arrValue = "matInst.arrType[int(matInst.index[arr_selector])]";

						// Test vector indexing
						vertexSrc << "    if (" << vecValue << " != " << DYNAMIC_VEC_CONSTANT << ")\n"
								  << "        vtxColor += vec4(0.0, 0.5, 0.0, 1.0);\n";

						// Test matrix indexing
						vertexSrc << "    if (" << matValue << " != " << DYNAMIC_MAT_CONSTANT << ")\n"
								  << "        vtxColor += vec4(0.0, 0.0, 0.5, 1.0);\n";

						// Test array indexing
						vertexSrc << "    if (" << arrValue << " != " << DYNAMIC_ARR_CONSTANT << ")\n"
								  << "        vtxColor = vec4(0.0, 0.5, 0.5, 1.0);\n";

						vertexSrc << "}\n";
					}
					break;
				default:
					DE_FATAL("Unhandled IndexType");
					break;
			}

			sourceCollections.glslSources.add("color_vert") << glu::VertexSource(vertexSrc.str());
		}

		if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
		{
			tessControlSrc << "#version 450\n"
						   << "layout (vertices = 3) out;\n"
						   << "layout(push_constant) uniform TessLevel {\n"
						   << "    layout(offset = 24) int level;\n"
						   << "} tessLevel;\n"
						   << "layout(location = 0) in highp vec4 color[];\n"
						   << "layout(location = 0) out highp vec4 vtxColor[];\n"
						   << "in gl_PerVertex { vec4 gl_Position; } gl_in[gl_MaxPatchVertices];\n"
						   << "out gl_PerVertex { vec4 gl_Position; } gl_out[];\n"
						   << "void main()\n"
						   << "{\n"
						   << "  gl_TessLevelInner[0] = tessLevel.level;\n"
						   << "  gl_TessLevelOuter[0] = tessLevel.level;\n"
						   << "  gl_TessLevelOuter[1] = tessLevel.level;\n"
						   << "  gl_TessLevelOuter[2] = tessLevel.level;\n"
						   << "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
						   << "  vtxColor[gl_InvocationID] = color[gl_InvocationID];\n"
						   << "}\n";

			sourceCollections.glslSources.add("color_tesc") << glu::TessellationControlSource(tessControlSrc.str());
		}

		if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
		{
			tessEvaluationSrc << "#version 450\n"
							  << "layout (triangles) in;\n"
							  << "layout(push_constant) uniform Material {\n"
							  << "    layout(offset = 32) vec4 color;\n"
							  << "} matInst;\n"
							  << "layout(location = 0) in highp vec4 color[];\n"
							  << "layout(location = 0) out highp vec4 vtxColor;\n"
							  << "in gl_PerVertex { vec4 gl_Position; } gl_in[gl_MaxPatchVertices];\n"
							  << "out gl_PerVertex { vec4 gl_Position; };\n"
							  << "void main()\n"
							  << "{\n"
							  << "  gl_Position = gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position;\n"
							  << "  vtxColor = matInst.color;\n"
							  << "}\n";

			sourceCollections.glslSources.add("color_tese") << glu::TessellationEvaluationSource(tessEvaluationSrc.str());
		}

		if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_GEOMETRY_BIT)
		{
			geometrySrc << "#version 450\n"
						<< "layout(triangles) in;\n"
						<< "layout(triangle_strip, max_vertices=3) out;\n"
						<< "layout(push_constant) uniform Material {\n"
						<< "    layout(offset = 20) int kind;\n"
						<< "} matInst;\n"
						<< "layout(location = 0) in highp vec4 color[];\n"
						<< "layout(location = 0) out highp vec4 vtxColor;\n"
						<< "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n"
						<< "out gl_PerVertex { vec4 gl_Position; };\n"
						<< "void main()\n"
						<< "{\n"
						<< "  for(int i=0; i<3; i++)\n"
						<< "  {\n"
						<< "    gl_Position.xyz = gl_in[i].gl_Position.xyz / matInst.kind;\n"
						<< "    gl_Position.w = gl_in[i].gl_Position.w;\n"
						<< "    vtxColor = color[i];\n"
						<< "    EmitVertex();\n"
						<< "  }\n"
						<< "  EndPrimitive();\n"
						<< "}\n";

			sourceCollections.glslSources.add("color_geom") << glu::GeometrySource(geometrySrc.str());
		}

		if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_FRAGMENT_BIT)
		{
			fragmentSrc << "#version 450\n"
						<< "layout(location = 0) in highp vec4 vtxColor;\n"
						<< "layout(location = 0) out highp vec4 fragColor;\n"
						<< "layout(push_constant) uniform Material {\n";

			switch (m_indexType)
			{
				case INDEX_TYPE_CONST_LITERAL:
					if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_VERTEX_BIT)
					{
						fragmentSrc << "    layout(offset = 0) int kind; \n"
									<< "} matInst;\n";
					}
					else
					{
						fragmentSrc << "    layout(offset = 16) int kind;\n"
									<< "} matInst;\n";
					}

					fragmentSrc << "void main (void)\n"
						<< "{\n"
						<< "    switch (matInst.kind) {\n"
						<< "    case 0: fragColor = vec4(0, 1.0, 0, 1.0); break;\n"
						<< "    case 1: fragColor = vec4(0, 0.0, 1.0, 1.0); break;\n"
						<< "    case 2: fragColor = vtxColor; break;\n"
						<< "    default: fragColor = vec4(1.0, 1.0, 1.0, 1.0); break;}\n"
						<< "}\n";
					break;
				case INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR:
					{
						fragmentSrc << "    layout(offset = 0)  vec4 index; \n"
									<< "    layout(offset = 16) vec4 vecType; \n"
									<< "    layout(offset = 32) mat2 matType; \n"
									<< "    layout(offset = 48) float[4] arrType; \n"
									<< "} matInst;\n";

						fragmentSrc << "void main (void)\n"
									<< "{\n"
									<< "    fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"

									// Mix in gl_FragCoord to (hopefully) prevent optimizing our index away
									<< "    int vec_selector = int(gl_FragCoord.x * 0.0000001 + 0);\n"
									<< "    int mat_selector = int(gl_FragCoord.x * 0.0000001 + 1);\n"
									<< "    int arr_selector = int(gl_FragCoord.x * 0.0000001 + 2);\n";

						// Use the dynamic index to pull our real index value from push constants
						// Then use that value to index into three variable types
						std::string vecValue = "matInst.vecType[int(matInst.index[vec_selector])]";
						std::string matValue = "matInst.matType[int(matInst.index[mat_selector])][0]";
						std::string arrValue = "matInst.arrType[int(matInst.index[arr_selector])]";

						// Test vector indexing
						fragmentSrc << "    if (" << vecValue << " != " << DYNAMIC_VEC_CONSTANT << ")\n"
									<< "        fragColor += vec4(0.0, 0.5, 0.0, 1.0);\n";

						// Test matrix indexing
						fragmentSrc << "    if (" << matValue << " != " << DYNAMIC_MAT_CONSTANT << ")\n"
									<< "        fragColor += vec4(0.0, 0.0, 0.5, 1.0);\n";

						// Test array indexing
						fragmentSrc << "    if (" << arrValue << " != " << DYNAMIC_ARR_CONSTANT << ")\n"
									<< "        fragColor = vec4(0.0, 0.5, 0.5, 1.0);\n";

						fragmentSrc << "}\n";
					}
					break;
				default:
					DE_FATAL("Unhandled IndexType");
					break;
			}

			sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(fragmentSrc.str());
		}
	}

	// add a pass through fragment shader if it's not activated in push constant ranges
	if (fragmentSrc.str().empty())
	{
		fragmentSrc << "#version 450\n"
					<< "layout(location = 0) in highp vec4 vtxColor;\n"
					<< "layout(location = 0) out highp vec4 fragColor;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	fragColor = vtxColor;\n"
					<< "}\n";

		sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(fragmentSrc.str());
	}
}

TestInstance* PushConstantGraphicsDisjointTest::createInstance (Context& context) const
{
	return new PushConstantGraphicsDisjointInstance(context, m_rangeCount, m_pushConstantRange, m_multipleUpdate, m_indexType);
}

class PushConstantGraphicsOverlapTest : public PushConstantGraphicsTest
{
public:
							PushConstantGraphicsOverlapTest		(tcu::TestContext&			testContext,
																 const std::string&			name,
																 const std::string&			description,
																 const deUint32				rangeCount,
																 const PushConstantData		pushConstantRange[MAX_RANGE_COUNT]);
	virtual					~PushConstantGraphicsOverlapTest	(void);
	std::string				getPushConstantDeclarationStr		(VkShaderStageFlags shaderStage) const;
	virtual void			initPrograms						(SourceCollections& sourceCollections) const;
	virtual TestInstance*	createInstance						(Context& context) const;
};

PushConstantGraphicsOverlapTest::PushConstantGraphicsOverlapTest (tcu::TestContext&			testContext,
																  const std::string&		name,
																  const std::string&		description,
																  const deUint32			rangeCount,
																  const PushConstantData	pushConstantRange[MAX_RANGE_COUNT])
	: PushConstantGraphicsTest (testContext, name, description, rangeCount, pushConstantRange, false, INDEX_TYPE_CONST_LITERAL)
{
}

PushConstantGraphicsOverlapTest::~PushConstantGraphicsOverlapTest (void)
{
}

std::string PushConstantGraphicsOverlapTest::getPushConstantDeclarationStr (VkShaderStageFlags shaderStage) const
{
	std::stringstream src;

	src	<< "layout(push_constant) uniform Material\n"
		<< "{\n";

	for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
	{
		if (m_pushConstantRange[rangeNdx].range.shaderStage & shaderStage)
		{
			switch (getRangeSizeCase(m_pushConstantRange[rangeNdx].range.size))
			{
				case SIZE_CASE_4:
					src	<< "    layout(offset = " << m_pushConstantRange[rangeNdx].range.offset << ") float color;\n";
					break;
				case SIZE_CASE_8:
					src << "    layout(offset = " << m_pushConstantRange[rangeNdx].range.offset << ") vec2 color;\n";
					break;
				case SIZE_CASE_12:
					src << "    layout(offset = " << m_pushConstantRange[rangeNdx].range.offset << ") vec3 color;\n";
					break;
				case SIZE_CASE_16:
					src << "    layout(offset = " << m_pushConstantRange[rangeNdx].range.offset << ") vec4 color;\n";
					break;
				case SIZE_CASE_32:
					src << "    layout(offset = " << m_pushConstantRange[rangeNdx].range.offset << ") vec4 color[2];\n";
					break;
				case SIZE_CASE_36:
					src << "    layout(offset = " << m_pushConstantRange[rangeNdx].range.offset << ") int dummy1;\n"
						<< "    layout(offset = " << (m_pushConstantRange[rangeNdx].range.offset + 4) << ") vec4 dummy2;\n"
						<< "    layout(offset = " << (m_pushConstantRange[rangeNdx].range.offset + 20) << ") vec4 color;\n";
					break;
				case SIZE_CASE_128:
					src << "    layout(offset = " << m_pushConstantRange[rangeNdx].range.offset << ") vec4 color[8];\n";
					break;
				default:
					DE_FATAL("Not implemented");
					break;
			}
		}
	}

	src	<< "} matInst;\n";

	return src.str();
}

std::string getSwizzleStr (deUint32 size)
{
	switch (size)
	{
		case 4:		return ".x";
		case 8:		return ".xy";
		case 12:	return ".xyz";
		case 16:
		case 32:
		case 36:
		case 128:	return "";
		default:	DE_FATAL("Not implemented");
					return "";
	}
}

std::string getColorReadStr (deUint32 size)
{
	// Always read the last element from array types
	const std::string	arrayNdx		= (size == 128u)	? "[7]"
										: (size == 32u)		? "[1]"
										: "";
	const std::string	colorReadStr	= getSwizzleStr(size) + " += matInst.color" + arrayNdx + ";\n";

	return colorReadStr;
}

void PushConstantGraphicsOverlapTest::initPrograms (SourceCollections& sourceCollections) const
{
	for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
	{
		if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_VERTEX_BIT)
		{
			const std::string source =
				"#version 450\n"
				"layout(location = 0) in highp vec4 position;\n"
				"layout(location = 1) in highp vec4 inColor;\n"
				"layout(location = 0) out highp vec4 vtxColor;\n"
				"out gl_PerVertex\n"
				"{\n"
				"    vec4 gl_Position;\n"
				"};\n"
				+ getPushConstantDeclarationStr(VK_SHADER_STAGE_VERTEX_BIT) +
				"void main()\n"
				"{\n"
				"    gl_Position = position;\n"
				"    vec4 color = inColor;\n"
				"    color" + getColorReadStr(m_pushConstantRange[rangeNdx].range.size) +
				"    vtxColor = color;\n"
				"}\n";

			sourceCollections.glslSources.add("color_vert") << glu::VertexSource(source);
		}

		if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
		{
			const std::string source =
				"#version 450\n"
				"layout (vertices = 3) out;\n"
				+ getPushConstantDeclarationStr(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) +
				"layout(location = 0) in highp vec4 color[];\n"
				"layout(location = 0) out highp vec4 vtxColor[];\n"
				"in gl_PerVertex\n"
				"{\n"
				"    vec4 gl_Position;\n"
				"} gl_in[gl_MaxPatchVertices];\n"
				"out gl_PerVertex\n"
				"{\n"
				"    vec4 gl_Position;\n"
				"} gl_out[];\n"
				"void main()\n"
				"{\n"
				"    gl_TessLevelInner[0] = 2.0;\n"
				"    gl_TessLevelOuter[0] = 2.0;\n"
				"    gl_TessLevelOuter[1] = 2.0;\n"
				"    gl_TessLevelOuter[2] = 2.0;\n"
				"    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
				"    vec4 outColor = color[gl_InvocationID];\n"
				"    outColor" + getColorReadStr(m_pushConstantRange[rangeNdx].range.size) +
				"    vtxColor[gl_InvocationID] = outColor;\n"
				"}\n";

			sourceCollections.glslSources.add("color_tesc") << glu::TessellationControlSource(source);
		}

		if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
		{
			const std::string source =
				"#version 450\n"
				"layout (triangles) in;\n"
				+ getPushConstantDeclarationStr(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) +
				"layout(location = 0) in highp vec4 color[];\n"
				"layout(location = 0) out highp vec4 vtxColor;\n"
				"in gl_PerVertex\n"
				"{\n"
				"    vec4 gl_Position;\n"
				"} gl_in[gl_MaxPatchVertices];\n"
				"out gl_PerVertex\n"
				"{\n"
				"    vec4 gl_Position;\n"
				"};\n"
				"void main()\n"
				"{\n"
				"    gl_Position = gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position;\n"
				"    vtxColor = gl_TessCoord.x * color[0] + gl_TessCoord.y * color[1] + gl_TessCoord.z * color[2];\n"
				"    vtxColor" + getColorReadStr(m_pushConstantRange[rangeNdx].range.size) +
				"}\n";

			sourceCollections.glslSources.add("color_tese") << glu::TessellationEvaluationSource(source);
		}

		if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_GEOMETRY_BIT)
		{
			const std::string source =
				"#version 450\n"
				"layout(triangles) in;\n"
				"layout(triangle_strip, max_vertices=3) out;\n"
				+ getPushConstantDeclarationStr(VK_SHADER_STAGE_GEOMETRY_BIT) +
				"layout(location = 0) in highp vec4 color[];\n"
				"layout(location = 0) out highp vec4 vtxColor;\n"
				"in gl_PerVertex\n"
				"{\n"
				"    vec4 gl_Position;\n"
				"} gl_in[];\n"
				"out gl_PerVertex\n"
				"{\n"
				"    vec4 gl_Position;\n"
				"};\n"
				"void main()\n"
				"{\n"
				"    for(int i = 0; i < 3; i++)\n"
				"    {\n"
				"        gl_Position.xyz = gl_in[i].gl_Position.xyz / 2.0;\n"
				"        gl_Position.w = gl_in[i].gl_Position.w;\n"
				"        vtxColor = color[i];\n"
				"        vtxColor" + getColorReadStr(m_pushConstantRange[rangeNdx].range.size) +
				"        EmitVertex();\n"
				"    }\n"
				"    EndPrimitive();\n"
				"}\n";

			sourceCollections.glslSources.add("color_geom") << glu::GeometrySource(source);
		}

		if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_FRAGMENT_BIT)
		{
			const std::string source =
				"#version 450\n"
				"layout(location = 0) in highp vec4 vtxColor;\n"
				"layout(location = 0) out highp vec4 fragColor;\n"
				+ getPushConstantDeclarationStr(VK_SHADER_STAGE_FRAGMENT_BIT) +
				"void main (void)\n"
				"{\n"
				"    fragColor = vtxColor;\n"
				"    fragColor" + getColorReadStr(m_pushConstantRange[rangeNdx].range.size) +
				"    fragColor = min(mod(fragColor, 2.0), 2.0 - mod(fragColor, 2.0));\n"
				"}\n";

			sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(source);
		}
	}
}

TestInstance* PushConstantGraphicsOverlapTest::createInstance (Context& context) const
{
	return new PushConstantGraphicsOverlapTestInstance(context, m_rangeCount, m_pushConstantRange, false, INDEX_TYPE_CONST_LITERAL);
}

class PushConstantComputeTest : public vkt::TestCase
{
public:
							PushConstantComputeTest		(tcu::TestContext&		testContext,
														 const std::string&		name,
														 const std::string&		description,
														 const ComputeTestType	testType,
														 const PushConstantData	pushConstantRange);
	virtual					~PushConstantComputeTest	(void);
	virtual void			initPrograms				(SourceCollections& sourceCollections) const;
	virtual TestInstance*	createInstance				(Context& context) const;
	virtual void			checkSupport				(Context& context) const;

private:
	const ComputeTestType	m_testType;
	const PushConstantData	m_pushConstantRange;
};

class PushConstantComputeTestInstance : public vkt::TestInstance
{
public:
							PushConstantComputeTestInstance		(Context&				context,
																 const ComputeTestType	testType,
																 const PushConstantData	pushConstantRange);
	virtual					~PushConstantComputeTestInstance	(void);
	virtual tcu::TestStatus	iterate								(void);

private:
	const ComputeTestType			m_testType;
	const PushConstantData			m_pushConstantRange;

	Move<VkBuffer>					m_outBuffer;
	de::MovePtr<Allocation>			m_outBufferAlloc;
	Move<VkDescriptorPool>			m_descriptorPool;
	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
	Move<VkDescriptorSet>			m_descriptorSet;

	Move<VkPipelineLayout>			m_pipelineLayout;
	Move<VkPipeline>				m_computePipelines;

	Move<VkShaderModule>			m_computeShaderModule;

	Move<VkCommandPool>				m_cmdPool;
	Move<VkCommandBuffer>			m_cmdBuffer;
};

PushConstantComputeTest::PushConstantComputeTest (tcu::TestContext&			testContext,
												  const std::string&		name,
												  const std::string&		description,
												  const ComputeTestType		testType,
												  const PushConstantData	pushConstantRange)
	: vkt::TestCase			(testContext, name, description)
	, m_testType			(testType)
	, m_pushConstantRange	(pushConstantRange)
{
}

PushConstantComputeTest::~PushConstantComputeTest (void)
{
}

TestInstance* PushConstantComputeTest::createInstance (Context& context) const
{
	return new PushConstantComputeTestInstance(context, m_testType, m_pushConstantRange);
}

void PushConstantComputeTest::checkSupport(Context& context) const
{
	if (CTT_UNINITIALIZED == m_testType)
		context.requireDeviceFunctionality("VK_KHR_maintenance4");
}

void PushConstantComputeTest::initPrograms (SourceCollections& sourceCollections) const
{
	std::ostringstream	computeSrc;

	computeSrc << "#version 450\n"
			   << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
			   << "layout(std140, set = 0, binding = 0) writeonly buffer Output {\n"
			   << "  vec4 elements[];\n"
			   << "} outData;\n"
			   << "layout(push_constant) uniform Material{\n"
			   << "  vec4 element;\n"
			   << "} matInst;\n"
			   << "void main (void)\n"
			   << "{\n"
			   << "  outData.elements[gl_GlobalInvocationID.x] = matInst.element;\n"
			   << "}\n";

	sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc.str());
}

PushConstantComputeTestInstance::PushConstantComputeTestInstance (Context&					context,
																  const ComputeTestType		testType,
																  const PushConstantData	pushConstantRange)
	: vkt::TestInstance		(context)
	, m_testType			(testType)
	, m_pushConstantRange	(pushConstantRange)
{
	const DeviceInterface&		vk					= context.getDeviceInterface();
	const VkDevice				vkDevice			= context.getDevice();
	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	SimpleAllocator				memAlloc			(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));

	// Create pipeline layout
	{
		// create push constant range
		VkPushConstantRange	pushConstantRanges;
		pushConstantRanges.stageFlags	= m_pushConstantRange.range.shaderStage;
		pushConstantRanges.offset		= m_pushConstantRange.range.offset;
		pushConstantRanges.size			= m_pushConstantRange.range.size;

		// create descriptor set layout
		m_descriptorSetLayout = DescriptorSetLayoutBuilder().addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT).build(vk, vkDevice);

		// create descriptor pool
		m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u).build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

		// create uniform buffer
		const VkDeviceSize			bufferSize			= sizeof(tcu::Vec4) * 8;
		const VkBufferCreateInfo	bufferCreateInfo	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,						// VkStructureType		sType;
			DE_NULL,													// const void*			pNext;
			0u,															// VkBufferCreateFlags	flags
			bufferSize,													// VkDeviceSize			size;
			VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,							// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,									// VkSharingMode		sharingMode;
			1u,															// deUint32				queueFamilyCount;
			&queueFamilyIndex											// const deUint32*		pQueueFamilyIndices;
		};

		m_outBuffer			= createBuffer(vk, vkDevice, &bufferCreateInfo);
		m_outBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outBuffer), MemoryRequirement::HostVisible);
		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outBuffer, m_outBufferAlloc->getMemory(), m_outBufferAlloc->getOffset()));

		// create and update descriptor set
		const VkDescriptorSetAllocateInfo allocInfo =
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,				// VkStructureType                             sType;
			DE_NULL,													// const void*                                 pNext;
			*m_descriptorPool,											// VkDescriptorPool                            descriptorPool;
			1u,															// uint32_t                                    setLayoutCount;
			&(*m_descriptorSetLayout),									// const VkDescriptorSetLayout*                pSetLayouts;
		};
		m_descriptorSet	= allocateDescriptorSet(vk, vkDevice, &allocInfo);

		const VkDescriptorBufferInfo descriptorInfo = makeDescriptorBufferInfo(*m_outBuffer, (VkDeviceSize)0u, bufferSize);

		DescriptorSetUpdateBuilder()
			.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
			.update(vk, vkDevice);

		// create pipeline layout
		const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
			DE_NULL,											// const void*					pNext;
			0u,													// VkPipelineLayoutCreateFlags	flags;
			1u,													// deUint32						descriptorSetCount;
			&(*m_descriptorSetLayout),							// const VkDescriptorSetLayout*	pSetLayouts;
			1u,													// deUint32						pushConstantRangeCount;
			&pushConstantRanges									// const VkPushConstantRange*	pPushConstantRanges;
		};

		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
	}

	// create pipeline
	{
		m_computeShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("compute"), 0);

		const VkPipelineShaderStageCreateInfo	stageCreateInfo	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
			DE_NULL,												// const void*							pNext;
			0u,														// VkPipelineShaderStageCreateFlags		flags;
			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
			*m_computeShaderModule,									// VkShaderModule						module;
			"main",													// const char*							pName;
			DE_NULL													// const VkSpecializationInfo*			pSpecializationInfo;
		};

		const VkComputePipelineCreateInfo		createInfo	=
		{
			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			// VkStructureType                             sType;
			DE_NULL,												// const void*                                 pNext;
			0u,														// VkPipelineCreateFlags                       flags;
			stageCreateInfo,										// VkPipelineShaderStageCreateInfo             stage;
			*m_pipelineLayout,										// VkPipelineLayout                            layout;
			(VkPipeline)0,											// VkPipeline                                  basePipelineHandle;
			0u,														// int32_t                                     basePipelineIndex;
		};

		m_computePipelines = createComputePipeline(vk, vkDevice, (vk::VkPipelineCache)0u, &createInfo);
	}

	// Create command pool
	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);

	// Create command buffer
	{
		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

		beginCommandBuffer(vk, *m_cmdBuffer, 0u);

		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipelines);
		vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1, &(*m_descriptorSet), 0, DE_NULL);

		// update push constant
		if (CTT_UNINITIALIZED != m_testType)
		{
			tcu::Vec4	value	= tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
			vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange.range.shaderStage, m_pushConstantRange.range.offset, m_pushConstantRange.range.size, &value);
		}

		vk.cmdDispatch(*m_cmdBuffer, 8, 1, 1);

		const VkBufferMemoryBarrier buf_barrier =
		{
			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,				//    VkStructureType    sType;
			DE_NULL,												//    const void*        pNext;
			VK_ACCESS_SHADER_WRITE_BIT,								//    VkAccessFlags      srcAccessMask;
			VK_ACCESS_HOST_READ_BIT,								//    VkAccessFlags      dstAccessMask;
			VK_QUEUE_FAMILY_IGNORED,								//    uint32_t           srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,								//    uint32_t           dstQueueFamilyIndex;
			*m_outBuffer,											//    VkBuffer           buffer;
			0,														//    VkDeviceSize       offset;
			VK_WHOLE_SIZE											//    VkDeviceSize       size;
		};

		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, DE_NULL, 1, &buf_barrier, 0, DE_NULL);

		endCommandBuffer(vk, *m_cmdBuffer);
	}
}

PushConstantComputeTestInstance::~PushConstantComputeTestInstance (void)
{
}

tcu::TestStatus PushConstantComputeTestInstance::iterate (void)
{
	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	const VkQueue				queue		= m_context.getUniversalQueue();

	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());

	// The test should run without crashing when reading that undefined value.
	// The actual value is not important, test just shouldn't crash.
	if (CTT_UNINITIALIZED == m_testType)
		return tcu::TestStatus::pass("pass");

	invalidateAlloc(vk, vkDevice, *m_outBufferAlloc);

	// verify result
	std::vector<tcu::Vec4>	expectValue(8, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
	if (deMemCmp((void*)(&expectValue[0]), m_outBufferAlloc->getHostPtr(), (size_t)(sizeof(tcu::Vec4) * 8)))
	{
		return tcu::TestStatus::fail("Image mismatch");
	}
	return tcu::TestStatus::pass("result image matches with reference");
}

class PushConstantLifetimeTest : public vkt::TestCase {
public:
	PushConstantLifetimeTest(tcu::TestContext &testContext,
			const std::string &name,
			const std::string &description,
			const PushConstantData pushConstantRange[MAX_RANGE_COUNT],
			const std::vector<CommandData> &cmdList);

	virtual                    ~PushConstantLifetimeTest(void);

	virtual void initPrograms(SourceCollections &sourceCollections) const;

	virtual TestInstance *createInstance(Context &context) const;

private:
	PushConstantData m_pushConstantRange[MAX_RANGE_COUNT];
	std::vector<CommandData> m_cmdList;

};

class PushConstantLifetimeTestInstance : public vkt::TestInstance {
public:
	PushConstantLifetimeTestInstance(Context &context,
			const PushConstantData pushConstantRange[MAX_RANGE_COUNT],
			const std::vector<CommandData> &cmdList);

	virtual                                        ~PushConstantLifetimeTestInstance(void);

	virtual tcu::TestStatus iterate(void);

	void init(void);

	tcu::TestStatus verify(deBool verifyGraphics, deBool verifyCompute);

private:
	PushConstantData m_pushConstantRange[MAX_RANGE_COUNT];
	std::vector<CommandData> m_cmdList;

	std::vector<Vertex4RGBA> m_vertices;

	const tcu::UVec2 m_renderSize;
	const VkFormat m_colorFormat;

	VkImageCreateInfo m_colorImageCreateInfo;
	Move<VkImage> m_colorImage;
	de::MovePtr<Allocation> m_colorImageAlloc;
	Move<VkImageView> m_colorAttachmentView;
	Move<VkRenderPass> m_renderPass;
	Move<VkFramebuffer> m_framebuffer;

	Move<VkShaderModule> m_vertexShaderModule;
	Move<VkShaderModule> m_fragmentShaderModule;
	Move<VkShaderModule> m_computeShaderModule;

	std::vector<VkPipelineShaderStageCreateInfo> m_shaderStage;

	Move<VkBuffer> m_vertexBuffer;
	de::MovePtr<Allocation> m_vertexBufferAlloc;

	Move<VkBuffer> m_outBuffer;
	de::MovePtr<Allocation> m_outBufferAlloc;
	Move<VkDescriptorPool> m_descriptorPool;
	Move<VkDescriptorSetLayout> m_descriptorSetLayout;
	Move<VkDescriptorSet> m_descriptorSet;

	Move<VkPipelineLayout> m_pipelineLayout[3];
	Move<VkPipeline> m_graphicsPipeline[3];
	Move<VkPipeline> m_computePipeline[3];

	Move<VkCommandPool> m_cmdPool;
	Move<VkCommandBuffer> m_cmdBuffer;
};

PushConstantLifetimeTest::PushConstantLifetimeTest(tcu::TestContext &testContext,
		const std::string &name,
		const std::string &description,
		const PushConstantData pushConstantRange[MAX_RANGE_COUNT],
		const std::vector<CommandData> &cmdList)
		: vkt::TestCase(testContext, name, description), m_cmdList(cmdList) {
	deMemcpy(m_pushConstantRange, pushConstantRange, sizeof(PushConstantData) * MAX_RANGE_COUNT);
}

PushConstantLifetimeTest::~PushConstantLifetimeTest(void) {

}

void PushConstantLifetimeTest::initPrograms(SourceCollections &sourceCollections) const
{
	std::ostringstream	vertexSrc;

	vertexSrc	<< "#version 450\n"
				<< "layout(location = 0) in highp vec4 position;\n"
				<< "layout(location = 1) in highp vec4 inColor;\n"
				<< "layout(location = 0) out highp vec4 vtxColor;\n"
				<< "out gl_PerVertex\n"
				<< "{\n"
				<< "  vec4 gl_Position;\n"
				<< "};\n"
				<< "layout(push_constant) uniform Material {\n"
				<< "    layout(offset = 16) vec4 color;\n"
				<< "}matInst;\n"
				<< "void main()\n"
				<< "{\n"
				<< "    gl_Position = position;\n"
				<< "    vtxColor = vec4(inColor.x + matInst.color.x,\n"
				<< "                    inColor.y - matInst.color.y,\n"
				<< "                    inColor.z + matInst.color.z,\n"
				<< "					inColor.w + matInst.color.w);\n"
				<< "}\n";

	sourceCollections.glslSources.add("color_vert_lt") << glu::VertexSource(vertexSrc.str());

	std::ostringstream	fragmentSrc;

	fragmentSrc << "#version 450\n"
				<< "layout(location = 0) in highp vec4 vtxColor;\n"
				<< "layout(location = 0) out highp vec4 fragColor;\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "    fragColor = vtxColor;\n"
				<< "}\n";

	sourceCollections.glslSources.add("color_frag_lt") << glu::FragmentSource(fragmentSrc.str());

	std::ostringstream	computeSrc;

	computeSrc  << "#version 450\n"
				<< "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
				<< "layout(std140, set = 0, binding = 0) writeonly buffer Output {\n"
				<< "  vec4 elements[];\n"
				<< "} outData;\n"
				<< "layout(push_constant) uniform Material{\n"
				<< "    layout(offset = 16) vec4 element;\n"
				<< "} matInst;\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "  outData.elements[gl_GlobalInvocationID.x] = matInst.element;\n"
				<< "}\n";

	sourceCollections.glslSources.add("compute_lt") << glu::ComputeSource(computeSrc.str());
}

TestInstance* PushConstantLifetimeTest::createInstance (Context& context) const
{
	return new PushConstantLifetimeTestInstance(context, m_pushConstantRange, m_cmdList);
}

PushConstantLifetimeTestInstance::PushConstantLifetimeTestInstance (Context&						context,
																	const PushConstantData			pushConstantRange[MAX_RANGE_COUNT],
																	const std::vector<CommandData>&	cmdList)
		: vkt::TestInstance		(context)
		, m_cmdList				(cmdList)
		, m_renderSize			(32, 32)
		, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
{
	deMemcpy(m_pushConstantRange, pushConstantRange, sizeof(PushConstantData) * MAX_RANGE_COUNT);
}

void PushConstantLifetimeTestInstance::init (void)
{
	const DeviceInterface		&vk = m_context.getDeviceInterface();
	const VkDevice				vkDevice = m_context.getDevice();
	const deUint32				queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
	SimpleAllocator				memAlloc(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
	const VkComponentMapping	componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};

	// Create color image
	{
		const VkImageCreateInfo colorImageParams =
			{
				VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
				DE_NULL,																// const void*				pNext;
				0u,																		// VkImageCreateFlags		flags;
				VK_IMAGE_TYPE_2D,														// VkImageType				imageType;
				m_colorFormat,															// VkFormat					format;
				{ m_renderSize.x(), m_renderSize.y(), 1u },								// VkExtent3D				extent;
				1u,																		// deUint32					mipLevels;
				1u,																		// deUint32					arrayLayers;
				VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits	samples;
				VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
				VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage;
				VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
				1u,																		// deUint32					queueFamilyIndexCount;
				&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
				VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout			initialLayout;
			};

		m_colorImageCreateInfo = colorImageParams;
		m_colorImage = createImage(vk, vkDevice, &m_colorImageCreateInfo);

		// Allocate and bind color image memory
		m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
	}

	// Create color attachment view
	{
		const VkImageViewCreateInfo colorAttachmentViewParams =
			{
				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType				sType;
				DE_NULL,										// const void*					pNext;
				0u,												// VkImageViewCreateFlags		flags;
				*m_colorImage,									// VkImage						image;
				VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType				viewType;
				m_colorFormat,									// VkFormat						format;
				componentMappingRGBA,							// VkChannelMapping				channels;
				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange		subresourceRange;
			};

		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
	}

	// Create render pass
	m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat);

	// Create framebuffer
	{
		const VkImageView attachmentBindInfos[1] =
			{
				*m_colorAttachmentView
			};

		const VkFramebufferCreateInfo framebufferParams =
			{
				VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType				sType;
				DE_NULL,									// const void*					pNext;
				0u,											// VkFramebufferCreateFlags		flags;
				*m_renderPass,								// VkRenderPass					renderPass;
				1u,											// deUint32						attachmentCount;
				attachmentBindInfos,						// const VkImageView*			pAttachments;
				(deUint32)m_renderSize.x(),					// deUint32						width;
				(deUint32)m_renderSize.y(),					// deUint32						height;
				1u											// deUint32						layers;
			};

		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
	}

	// Create data for pipeline layout
	{
		// create descriptor set layout
		m_descriptorSetLayout = DescriptorSetLayoutBuilder().addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT).build(vk, vkDevice);

		// create descriptor pool
		m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u).build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

		// create storage buffer
		const VkDeviceSize			bufferSize			= sizeof(tcu::Vec4) * 8;
		const VkBufferCreateInfo	bufferCreateInfo	=
			{
				VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,						// VkStructureType		sType;
				DE_NULL,													// const void*			pNext;
				0u,															// VkBufferCreateFlags	flags
				bufferSize,													// VkDeviceSize			size;
				VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,							// VkBufferUsageFlags	usage;
				VK_SHARING_MODE_EXCLUSIVE,									// VkSharingMode		sharingMode;
				1u,															// deUint32				queueFamilyCount;
				&queueFamilyIndex											// const deUint32*		pQueueFamilyIndices;
			};

		m_outBuffer			= createBuffer(vk, vkDevice, &bufferCreateInfo);
		m_outBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outBuffer), MemoryRequirement::HostVisible);
		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outBuffer, m_outBufferAlloc->getMemory(), m_outBufferAlloc->getOffset()));

		// create and update descriptor set
		const VkDescriptorSetAllocateInfo	allocInfo				=
			{
				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType                             sType;
				DE_NULL,										// const void*                                 pNext;
				*m_descriptorPool,								// VkDescriptorPool                            descriptorPool;
				1u,												// deUint32                                    setLayoutCount;
				&(*m_descriptorSetLayout),						// const VkDescriptorSetLayout*                pSetLayouts;
			};
		m_descriptorSet	= allocateDescriptorSet(vk, vkDevice, &allocInfo);

		const VkDescriptorBufferInfo descriptorInfo = makeDescriptorBufferInfo(*m_outBuffer, (VkDeviceSize)0u, bufferSize);

		DescriptorSetUpdateBuilder()
				.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
				.update(vk, vkDevice);

		// create push constant ranges
		const VkPushConstantRange	pushConstantRanges[]
			{
				{
						m_pushConstantRange[0].range.shaderStage,
						m_pushConstantRange[0].range.offset,
						m_pushConstantRange[0].range.size
				},
				{
						m_pushConstantRange[1].range.shaderStage,
						m_pushConstantRange[1].range.offset,
						m_pushConstantRange[1].range.size
				}
			};

		const VkPipelineLayoutCreateInfo pipelineLayoutParams[] =
			{
				{
					VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType;
					DE_NULL,										// const void*					pNext;
					0u,												// VkPipelineLayoutCreateFlags	flags;
					1u,												// deUint32						descriptorSetCount;
					&(*m_descriptorSetLayout),						// const VkDescriptorSetLayout*	pSetLayouts;
					1u,												// deUint32						pushConstantRangeCount;
					&(pushConstantRanges[0])
				},
				{
					VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType;
					DE_NULL,										// const void*					pNext;
					0u,												// VkPipelineLayoutCreateFlags	flags;
					1u,												// deUint32						descriptorSetCount;
					&(*m_descriptorSetLayout),						// const VkDescriptorSetLayout*	pSetLayouts;
					1u,												// deUint32						pushConstantRangeCount;
					&(pushConstantRanges[1])
				}
			};

		m_pipelineLayout[0] = createPipelineLayout(vk, vkDevice, &(pipelineLayoutParams[0]));
		m_pipelineLayout[1] = createPipelineLayout(vk, vkDevice, &(pipelineLayoutParams[1]));
	}

	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert_lt"), 0);
	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_lt"), 0);

	// Create graphics pipelines
	{
		const VkVertexInputBindingDescription vertexInputBindingDescription =
			{
				0u,								// deUint32					binding;
				sizeof(Vertex4RGBA),			// deUint32					strideInBytes;
				VK_VERTEX_INPUT_RATE_VERTEX		// VkVertexInputStepRate	stepRate;
			};

		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
			{
				{
					0u,									// deUint32	location;
					0u,									// deUint32	binding;
					VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
					0u									// deUint32	offsetInBytes;
				},
				{
					1u,									// deUint32	location;
					0u,									// deUint32	binding;
					VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
					DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
				}
			};

		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
			{
				VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
				DE_NULL,														// const void*								pNext;
				0u,																// vkPipelineVertexInputStateCreateFlags	flags;
				1u,																// deUint32									bindingCount;
				&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
				2u,																// deUint32									attributeCount;
				vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
			};

		const VkPrimitiveTopology		topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;

		const std::vector<VkViewport>	viewports(1, makeViewport(m_renderSize));
		const std::vector<VkRect2D>		scissors(1, makeRect2D(m_renderSize));

		m_graphicsPipeline[0] = makeGraphicsPipeline(vk,														// const DeviceInterface&                        vk
													 vkDevice,													// const VkDevice                                device
													 *(m_pipelineLayout[0]),									// const VkPipelineLayout                        pipelineLayout
													 *m_vertexShaderModule,										// const VkShaderModule                          vertexShaderModule
													 DE_NULL,													// const VkShaderModule                          tessellationControlShaderModule
													 DE_NULL,													// const VkShaderModule                          tessellationEvalShaderModule
													 DE_NULL,													// const VkShaderModule                          geometryShaderModule
													 *m_fragmentShaderModule,									// const VkShaderModule                          fragmentShaderModule
													 *m_renderPass,												// const VkRenderPass                            renderPass
													 viewports,													// const std::vector<VkViewport>&                viewports
													 scissors,													// const std::vector<VkRect2D>&                  scissors
													 topology,													// const VkPrimitiveTopology                     topology
													 0u,														// const deUint32                                subpass
													 0u,														// const deUint32                                patchControlPoints
													 &vertexInputStateParams);									// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo

		m_graphicsPipeline[1] = makeGraphicsPipeline(vk,														// const DeviceInterface&                        vk
													 vkDevice,													// const VkDevice                                device
													 *(m_pipelineLayout[1]),									// const VkPipelineLayout                        pipelineLayout
													 *m_vertexShaderModule,										// const VkShaderModule                          vertexShaderModule
													 DE_NULL,													// const VkShaderModule                          tessellationControlShaderModule
													 DE_NULL,													// const VkShaderModule                          tessellationEvalShaderModule
													 DE_NULL,													// const VkShaderModule                          geometryShaderModule
													 *m_fragmentShaderModule,									// const VkShaderModule                          fragmentShaderModule
													 *m_renderPass,												// const VkRenderPass                            renderPass
													 viewports,													// const std::vector<VkViewport>&                viewports
													 scissors,													// const std::vector<VkRect2D>&                  scissors
													 topology,													// const VkPrimitiveTopology                     topology
													 0u,														// const deUint32                                subpass
													 0u,														// const deUint32                                patchControlPoints
													 &vertexInputStateParams);									// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
	}

	// Create vertex buffer
	{
		m_vertices			= createQuad(1.0f, tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f));

		const VkBufferCreateInfo vertexBufferParams =
			{
				VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,						// VkStructureType		sType;
				DE_NULL,													// const void*			pNext;
				0u,															// VkBufferCreateFlags	flags;
				(VkDeviceSize) (sizeof(Vertex4RGBA) * m_vertices.size()),	// VkDeviceSize			size;
				VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,							// VkBufferUsageFlags	usage;
				VK_SHARING_MODE_EXCLUSIVE,									// VkSharingMode		sharingMode;
				1u,															// deUint32				queueFamilyCount;
				&queueFamilyIndex											// const deUint32*		pQueueFamilyIndices;
			};

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

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

		// Load vertices into vertex buffer
		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
	}

	// Create compute pipelines
	{
		m_computeShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("compute_lt"), 0);

		const VkPipelineShaderStageCreateInfo	stageCreateInfo	=
			{
				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
				DE_NULL,												// const void*							pNext;
				0u,														// VkPipelineShaderStageCreateFlags		flags;
				VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
				*m_computeShaderModule,									// VkShaderModule						module;
				"main",													// const char*							pName;
				DE_NULL													// const VkSpecializationInfo*			pSpecializationInfo;
			};

		if (m_pushConstantRange[0].range.shaderStage & VK_SHADER_STAGE_COMPUTE_BIT)
		{
			const VkComputePipelineCreateInfo computePipelineLayoutParams =
				{
					VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			// VkStructureType								sType;
					DE_NULL,												// const void*									pNext;
					0u,														// VkPipelineCreateFlags						flags;
					stageCreateInfo,										// VkPipelineShaderStageCreateInfo				stage;
					*m_pipelineLayout[0],									// VkPipelineLayout								layout;
					(VkPipeline) 0,											// VkPipeline									basePipelineHandle;
					0u,														// int32_t										basePipelineIndex;
				};

			m_computePipeline[0] = createComputePipeline(vk, vkDevice, (vk::VkPipelineCache) 0u, &computePipelineLayoutParams);
		}
		if (m_pushConstantRange[1].range.shaderStage & VK_SHADER_STAGE_COMPUTE_BIT)
		{
			const VkComputePipelineCreateInfo computePipelineLayoutParams =
				{
					VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			// VkStructureType								sType;
					DE_NULL,												// const void*									pNext;
					0u,														// VkPipelineCreateFlags						flags;
					stageCreateInfo,										// VkPipelineShaderStageCreateInfo				stage;
					*m_pipelineLayout[1],									// VkPipelineLayout								layout;
					(VkPipeline) 0,											// VkPipeline									basePipelineHandle;
					0u,														// int32_t										basePipelineIndex;
				};

			m_computePipeline[1] = createComputePipeline(vk, vkDevice, (vk::VkPipelineCache) 0u, &computePipelineLayoutParams);
		}
	}
}

PushConstantLifetimeTestInstance::~PushConstantLifetimeTestInstance (void)
{

}

tcu::TestStatus PushConstantLifetimeTestInstance::iterate (void)
{
	const DeviceInterface		&vk				 = m_context.getDeviceInterface();
	const VkDevice				vkDevice		 = m_context.getDevice();
	const deUint32				queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
	const VkQueue				queue			 = m_context.getUniversalQueue();

	deBool						verifyGraphics	 = false;
	deBool						verifyCompute	 = false;

	init();

	// Create command pool
	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);

	// Create command buffer
	{
		const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);

		// Set push constant value
		tcu::Vec4	value[2] =
				{
					{0.25f, 0.75f, 0.75f, 1.0f},
					{0.25f, 0.75f, 0.75f, 1.0f}
				};

		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

		beginCommandBuffer(vk, *m_cmdBuffer, 0u);

		for (size_t ndx = 0; ndx < m_cmdList.size(); ndx++)
		{
			const VkPushConstantRange pushConstantRange
				{
					m_pushConstantRange[m_cmdList[ndx].rangeNdx].range.shaderStage,
					m_pushConstantRange[m_cmdList[ndx].rangeNdx].range.offset,
					m_pushConstantRange[m_cmdList[ndx].rangeNdx].range.size
				};

			switch (m_cmdList[ndx].cType)
			{
				case CMD_PUSH_CONSTANT:
				{
					vk.cmdPushConstants(*m_cmdBuffer,
										*m_pipelineLayout[m_cmdList[ndx].rangeNdx],
										 pushConstantRange.stageFlags,
										 pushConstantRange.offset,
										 pushConstantRange.size,
										 &value);
					break;
				}
				case CMD_BIND_PIPELINE_COMPUTE:
				{
					vk.cmdBindDescriptorSets(*m_cmdBuffer,
											  VK_PIPELINE_BIND_POINT_COMPUTE,
											 *m_pipelineLayout[m_cmdList[ndx].rangeNdx],
											  0,
											  1u,
											  &(*m_descriptorSet),
											  0,
											  DE_NULL);

					vk.cmdBindPipeline(*m_cmdBuffer,
										VK_PIPELINE_BIND_POINT_COMPUTE,
										*m_computePipeline[m_cmdList[ndx].rangeNdx]);
					break;
				}
				case CMD_BIND_PIPELINE_GRAPHICS:
				{
					vk.cmdBindPipeline(*m_cmdBuffer,
									   VK_PIPELINE_BIND_POINT_GRAPHICS,
									   *m_graphicsPipeline[m_cmdList[ndx].rangeNdx]);
					break;
				}
				case CMD_DRAW:
				{
					const VkDeviceSize bufferOffset = 0;

					const VkImageMemoryBarrier prePassBarrier =
						{
							VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					//		VkStructureType			sType;
							DE_NULL,												//		const void*				pNext;
							0,														//		VkAccessFlags			srcAccessMask;
							VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,					//		VkAccessFlags			dstAccessMask;
							VK_IMAGE_LAYOUT_UNDEFINED,								//		VkImageLayout			oldLayout;
							VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				//		VkImageLayout			newLayout;
							VK_QUEUE_FAMILY_IGNORED,								//		uint32_t				srcQueueFamilyIndex;
							VK_QUEUE_FAMILY_IGNORED,								//		uint32_t				dstQueueFamilyIndex;
							*m_colorImage,											//		VkImage					image;
							{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }			//		VkImageSubresourceRange	subresourceRange;
						};

					vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1, &prePassBarrier);

					beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);

					vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &bufferOffset);
					vk.cmdDraw(*m_cmdBuffer, (deUint32) m_vertices.size(), 1, 0, 0);

					endRenderPass(vk, *m_cmdBuffer);

					const VkImageMemoryBarrier postPassBarrier =
						{
							VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					//		VkStructureType			sType;
							DE_NULL,												//		const void*				pNext;
							VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,					//		VkAccessFlags			srcAccessMask;
							VK_ACCESS_TRANSFER_WRITE_BIT,							//		VkAccessFlags			dstAccessMask;
							VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				//		VkImageLayout			oldLayout;
							VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				//		VkImageLayout			newLayout;
							VK_QUEUE_FAMILY_IGNORED,								//		uint32_t				srcQueueFamilyIndex;
							VK_QUEUE_FAMILY_IGNORED,								//		uint32_t				dstQueueFamilyIndex;
							*m_colorImage,											//		VkImage					image;
							{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }			//		VkImageSubresourceRange	subresourceRange;
						};

					vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1, &postPassBarrier);

					verifyGraphics = true;
					break;
				}
				case CMD_DISPATCH:
				{

					vk.cmdDispatch(*m_cmdBuffer, 8, 1, 1);

					const VkBufferMemoryBarrier outputBarrier =
						{
							VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,				//		VkStructureType			sType;
							DE_NULL,												//		const void*				pNext;
							VK_ACCESS_SHADER_WRITE_BIT,								//		VkAccessFlags			srcAccessMask;
							VK_ACCESS_HOST_READ_BIT,								//		VkAccessFlags			dstAccessMask;
							VK_QUEUE_FAMILY_IGNORED,								//		uint32_t				srcQueueFamilyIndex;
							VK_QUEUE_FAMILY_IGNORED,								//		uint32_t				dstQueueFamilyIndex;
							*m_outBuffer,											//		VkBuffer				buffer;
							0,														//		VkDeviceSize			offset;
							VK_WHOLE_SIZE											//		VkDeviceSize			size;
						};

					vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, DE_NULL, 1, &outputBarrier, 0, DE_NULL);

					verifyCompute = true;
					break;
				}
				case CMD_UNSUPPORTED:
					break;
				default:
					break;
			}
		}

		endCommandBuffer(vk, *m_cmdBuffer);
	}

	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());

	return verify(verifyGraphics, verifyCompute);
}

tcu::TestStatus PushConstantLifetimeTestInstance::verify (deBool verifyGraphics, deBool verifyCompute)
{
	const DeviceInterface&		vk				= m_context.getDeviceInterface();
	const VkDevice				vkDevice		= m_context.getDevice();

	const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_colorFormat);
	const tcu::TextureFormat	tcuDepthFormat	= tcu::TextureFormat();
	const ColorVertexShader		vertexShader;
	const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
	const rr::Program			program			(&vertexShader, &fragmentShader);
	ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);

	deBool						graphicsOk		= !verifyGraphics;
	deBool						computeOk		= !verifyCompute;

	// Compare result with reference image
	if (verifyGraphics)
	{
		// Render reference image
		{
			rr::RenderState renderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
			refRenderer.draw(renderState, rr::PRIMITIVETYPE_TRIANGLES, m_vertices);
		}

		const VkQueue					queue				= m_context.getUniversalQueue();
		const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
		SimpleAllocator					allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
		de::MovePtr<tcu::TextureLevel>	result				= readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);

		graphicsOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
															  "IntImageCompare",
															  "Image comparison",
															  refRenderer.getAccess(),
															  result->getAccess(),
															  tcu::UVec4(2, 2, 2, 2),
															  tcu::IVec3(1, 1, 0),
															  true,
															  tcu::COMPARE_LOG_RESULT);
	}

	// Compare compute output
	if (verifyCompute)
	{
		invalidateAlloc(vk, vkDevice, *m_outBufferAlloc);

		// verify result
		std::vector<tcu::Vec4>	expectValue(8, tcu::Vec4(0.25f, 0.75f, 0.75f, 1.0f));
		if (deMemCmp((void*)(&expectValue[0]), m_outBufferAlloc->getHostPtr(), (size_t)(sizeof(tcu::Vec4) * 8)))
			computeOk = false;
		else
			computeOk = true;
	}

	if (!graphicsOk)
		return tcu::TestStatus::fail("Image mismatch");

	if (!computeOk)
		return tcu::TestStatus::fail("Wrong output value");

	return tcu::TestStatus::pass("Result image matches reference");
}

// The overwrite-values cases will use a 2x2 storage image and 4 separate draws or dispatches to store the color of each pixel in
// the image. The color will be calculated as baseColor*multiplier+colorOffset, and the base color, multiplier, color component
// offsets and coords will be changed with multiple push commands before each draw/dispatch, to verify overwriting multiple ranges
// works as expected.

struct OverwritePushConstants
{
	tcu::IVec4	coords;				// We will only use the first two components, but an IVec4 eases matching alignments.
	tcu::UVec4	baseColor;
	tcu::UVec4	multiplier;
	deUint32	colorOffsets[4];
	tcu::UVec4	transparentGreen;
};

struct OverwriteTestParams
{
	OverwritePushConstants	pushConstantValues[4];
	VkPipelineBindPoint		bindPoint;
};

class OverwriteTestCase : public vkt::TestCase
{
public:
							OverwriteTestCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, const OverwriteTestParams& params);
	virtual					~OverwriteTestCase		(void) {}

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

protected:
	OverwriteTestParams		m_params;
};

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

	virtual tcu::TestStatus		iterate					(void);

protected:
	OverwriteTestParams			m_params;
};

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

void OverwriteTestCase::initPrograms (vk::SourceCollections& programCollection) const
{
	std::ostringstream shader;

	shader
		<< "#version 450\n"
		<< "layout (push_constant, std430) uniform PushConstants {\n"
		<< "    ivec4   coords;\n" // Note we will only use the .xy swizzle.
		<< "    uvec4   baseColor;\n"
		<< "    uvec4   multiplier;\n"
		<< "    uint    colorOffsets[4];\n"
		<< "    uvec4   transparentGreen;\n"
		<< "} pc;\n"
		<< "layout(rgba8ui, set=0, binding=0) uniform uimage2D simage;\n"
		<< "void main() {\n"
		<< "    uvec4   colorOffsets = uvec4(pc.colorOffsets[0], pc.colorOffsets[1], pc.colorOffsets[2], pc.colorOffsets[3]);\n"
		<< "    uvec4   finalColor   = pc.baseColor * pc.multiplier + colorOffsets + pc.transparentGreen;\n"
		<< "    imageStore(simage, pc.coords.xy, finalColor);\n"
		<< "}\n"
		;

	if (m_params.bindPoint == VK_PIPELINE_BIND_POINT_COMPUTE)
	{
		programCollection.glslSources.add("comp") << glu::ComputeSource(shader.str());
	}
	else if (m_params.bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS)
	{
		std::ostringstream vert;
		vert
			<< "#version 450\n"
			<< "\n"
			<< "void main()\n"
			<< "{\n"
			// Full-screen clockwise triangle fan with 4 vertices.
			<< "    const float x = (-1.0+2.0*(((gl_VertexIndex+1)&2)>>1));\n"
			<< "    const float y = (-1.0+2.0*(( gl_VertexIndex   &2)>>1));\n"
			<< "	gl_Position = vec4(x, y, 0.0, 1.0);\n"
			<< "}\n"
			;

		programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
		programCollection.glslSources.add("frag") << glu::FragmentSource(shader.str());
	}
	else
		DE_ASSERT(false);
}

TestInstance* OverwriteTestCase::createInstance (Context& context) const
{
	return new OverwriteTestInstance(context, m_params);
}

OverwriteTestInstance::OverwriteTestInstance (Context& context, const OverwriteTestParams& params)
	: vkt::TestInstance	(context)
	, m_params			(params)
{}

tcu::TestStatus OverwriteTestInstance::iterate (void)
{
	const auto&	vkd		= m_context.getDeviceInterface();
	const auto	device	= m_context.getDevice();
	auto&		alloc	= m_context.getDefaultAllocator();
	const auto	queue	= m_context.getUniversalQueue();
	const auto	qIndex	= m_context.getUniversalQueueFamilyIndex();
	const bool	isComp	= (m_params.bindPoint == VK_PIPELINE_BIND_POINT_COMPUTE);

	const VkShaderStageFlags	stageFlags	= (isComp ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_FRAGMENT_BIT);
	const VkPipelineStageFlags	writeStages	= (isComp ? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT : VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
	const auto					imageFormat	= VK_FORMAT_R8G8B8A8_UINT;
	const auto					imageExtent	= makeExtent3D(2u, 2u, 1u);

	// Storage image.
	const VkImageCreateInfo imageCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,							//	VkStructureType			sType;
		nullptr,														//	const void*				pNext;
		0u,																//	VkImageCreateFlags		flags;
		VK_IMAGE_TYPE_2D,												//	VkImageType				imageType;
		imageFormat,													//	VkFormat				format;
		imageExtent,													//	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),	//	VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,										//	VkSharingMode			sharingMode;
		0u,																//	deUint32				queueFamilyIndexCount;
		nullptr,														//	const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,										//	VkImageLayout			initialLayout;
	};
	ImageWithMemory storageImage (vkd, device, alloc, imageCreateInfo, MemoryRequirement::Any);
	const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	const auto storageImageView = makeImageView(vkd, device, storageImage.get(), VK_IMAGE_VIEW_TYPE_2D, imageFormat, subresourceRange);

	// Buffer to copy output pixels to.
	const auto tcuFormat	= mapVkFormat(imageFormat);
	const auto pixelSize	= static_cast<VkDeviceSize>(tcu::getPixelSize(tcuFormat));
	const auto bufferSize	= pixelSize * imageExtent.width * imageExtent.height * imageExtent.depth;

	const auto bufferCreateInfo = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
	BufferWithMemory transferBuffer (vkd, device, alloc, bufferCreateInfo, MemoryRequirement::HostVisible);

	// Descriptor set layout and pipeline layout.
	DescriptorSetLayoutBuilder layoutBuilder;
	layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, stageFlags);
	const auto descriptorSetLayout = layoutBuilder.build(vkd, device);

	const VkPushConstantRange pcRange =
	{
		stageFlags,												//	VkShaderStageFlags	stageFlags;
		0u,														//	deUint32			offset;
		static_cast<deUint32>(sizeof(OverwritePushConstants)),	//	deUint32			size;
	};
	const auto pipelineLayout = makePipelineLayout(vkd, device, 1u, &descriptorSetLayout.get(), 1u, &pcRange);

	// Descriptor pool and set.
	DescriptorPoolBuilder poolBuilder;
	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
	const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
	const auto descriptorSet = makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());

	DescriptorSetUpdateBuilder updateBuilder;
	const auto descriptorImageInfo = makeDescriptorImageInfo(DE_NULL, storageImageView.get(), VK_IMAGE_LAYOUT_GENERAL);
	updateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo);
	updateBuilder.update(vkd, device);

	// Command pool and set.
	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();

	// Pipeline.
	const std::vector<VkViewport>	viewports	(1, makeViewport(imageExtent));
	const std::vector<VkRect2D>		scissors	(1, makeRect2D(imageExtent));

	Move<VkShaderModule>	vertModule;
	Move<VkShaderModule>	fragModule;
	Move<VkShaderModule>	compModule;

	Move<VkRenderPass>		renderPass;
	Move<VkFramebuffer>		framebuffer;
	Move<VkPipeline>		pipeline;

	if (isComp)
	{
		compModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("comp"), 0u);
		pipeline	= makeComputePipeline(vkd, device, pipelineLayout.get(), 0u, compModule.get(), 0u, nullptr);
	}
	else
	{
		vertModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
		fragModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);

		const VkPipelineVertexInputStateCreateInfo inputState =
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                             sType
			nullptr,													// const void*                                 pNext
			0u,															// VkPipelineVertexInputStateCreateFlags       flags
			0u,															// deUint32                                    vertexBindingDescriptionCount
			nullptr,													// const VkVertexInputBindingDescription*      pVertexBindingDescriptions
			0u,															// deUint32                                    vertexAttributeDescriptionCount
			nullptr,													// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
		};
		renderPass	= makeRenderPass(vkd, device);
		framebuffer	= makeFramebuffer(vkd, device, renderPass.get(), 0u, nullptr, imageExtent.width, imageExtent.height);
		pipeline	= makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
			vertModule.get(), DE_NULL, DE_NULL, DE_NULL, fragModule.get(), renderPass.get(),
			viewports, scissors, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, 0u, 0u, &inputState);
	}

	// Offsets and sizes.
	const struct
	{
		size_t offset;
		size_t size;
	} pcPush[] =
	{
		// Push members doing some back-and-forth in the range.
		{	offsetof(OverwritePushConstants, baseColor),		sizeof(OverwritePushConstants::baseColor)			},
		{	offsetof(OverwritePushConstants, coords),			sizeof(OverwritePushConstants::coords)				},
		{	offsetof(OverwritePushConstants, colorOffsets),		sizeof(OverwritePushConstants::colorOffsets)		},
		{	offsetof(OverwritePushConstants, multiplier),		sizeof(OverwritePushConstants::multiplier)			},
		{	offsetof(OverwritePushConstants, transparentGreen),	sizeof(OverwritePushConstants::transparentGreen)	},
	};

	beginCommandBuffer(vkd, cmdBuffer);

	// Transition layout for storage image.
	const auto preImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, storageImage.get(), subresourceRange);
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, writeStages, 0u, 0u, nullptr, 0u, nullptr, 1u, &preImageBarrier);

	vkd.cmdBindDescriptorSets(cmdBuffer, m_params.bindPoint, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
	vkd.cmdBindPipeline(cmdBuffer, m_params.bindPoint, pipeline.get());

	if (!isComp)
		beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), scissors[0]);

	for (int pcIndex = 0; pcIndex < DE_LENGTH_OF_ARRAY(m_params.pushConstantValues); ++pcIndex)
	{
		const auto& pc = m_params.pushConstantValues[pcIndex];

		// Push all structure members separately.
		for (int pushIdx = 0; pushIdx < DE_LENGTH_OF_ARRAY(pcPush); ++pushIdx)
		{
			const auto&	push	= pcPush[pushIdx];
			const void*	dataPtr	= reinterpret_cast<const void*>(reinterpret_cast<const char*>(&pc) + push.offset);
			vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), stageFlags, static_cast<deUint32>(push.offset), static_cast<deUint32>(push.size), dataPtr);
		}

		// Draw or dispatch.
		if (isComp)
			vkd.cmdDispatch(cmdBuffer, 1u, 1u, 1u);
		else
			vkd.cmdDraw(cmdBuffer, 4u, 1u, 0u, 0u);
	}

	if (!isComp)
		endRenderPass(vkd, cmdBuffer);

	// Copy storage image to output buffer.
	const auto postImageBarrier = makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, storageImage.get(), subresourceRange);
	vkd.cmdPipelineBarrier(cmdBuffer, writeStages, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &postImageBarrier);

	const auto copyRegion = makeBufferImageCopy(imageExtent, makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
	vkd.cmdCopyImageToBuffer(cmdBuffer, storageImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, transferBuffer.get(), 1u, &copyRegion);

	const auto bufferBarrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, transferBuffer.get(), 0ull, bufferSize);
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &bufferBarrier, 0u, nullptr);

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

	// Verify output colors match.
	auto&		bufferAlloc		= transferBuffer.getAllocation();
	const void*	bufferHostPtr	= bufferAlloc.getHostPtr();
	invalidateAlloc(vkd, device, bufferAlloc);

	const int iWidth	= static_cast<int>(imageExtent.width);
	const int iHeight	= static_cast<int>(imageExtent.height);
	const int iDepth	= static_cast<int>(imageExtent.depth);

	tcu::ConstPixelBufferAccess outputAccess (tcuFormat, iWidth, iHeight, iDepth, bufferHostPtr);

	for (int pixelIdx = 0; pixelIdx < DE_LENGTH_OF_ARRAY(m_params.pushConstantValues); ++pixelIdx)
	{
		const auto&			pc				= m_params.pushConstantValues[pixelIdx];
		const tcu::UVec4	expectedValue	= pc.baseColor * pc.multiplier + tcu::UVec4(pc.colorOffsets[0], pc.colorOffsets[1], pc.colorOffsets[2], pc.colorOffsets[3]) + pc.transparentGreen;
		const tcu::UVec4	outputValue		= outputAccess.getPixelUint(pc.coords.x(), pc.coords.y());

		if (expectedValue != outputValue)
		{
			std::ostringstream msg;
			msg << "Unexpected value in output image at coords " << pc.coords << ": found " << outputValue << " and expected " << expectedValue;
			TCU_FAIL(msg.str());
		}
	}

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

void addOverwriteCase (tcu::TestCaseGroup* group, tcu::TestContext& testCtx, VkPipelineBindPoint bindPoint)
{
	const OverwritePushConstants pushConstants[4] =
	{
	//	coords						baseColor					multiplier							colorOffsets				transparentGreen
		{ tcu::IVec4(0, 0, 0, 0),	tcu::UVec4(1u, 0u, 0u, 0u),	tcu::UVec4( 2u,  2u,  2u,  2u),		{ 128u, 129u, 130u, 131u },	tcu::UVec4(0u, 1u, 0u, 0u) },
		{ tcu::IVec4(0, 1, 0, 0),	tcu::UVec4(0u, 1u, 0u, 0u),	tcu::UVec4( 4u,  4u,  4u,  4u),		{ 132u, 133u, 134u, 135u },	tcu::UVec4(0u, 1u, 0u, 0u) },
		{ tcu::IVec4(1, 0, 0, 0),	tcu::UVec4(0u, 0u, 1u, 0u),	tcu::UVec4( 8u,  8u,  8u,  8u),		{ 136u, 137u, 138u, 139u },	tcu::UVec4(0u, 1u, 0u, 0u) },
		{ tcu::IVec4(1, 1, 0, 0),	tcu::UVec4(0u, 0u, 0u, 1u),	tcu::UVec4(16u, 16u, 16u, 16u),		{ 140u, 141u, 142u, 143u },	tcu::UVec4(0u, 1u, 0u, 0u) },
	};

	OverwriteTestParams testParams;

	DE_ASSERT(DE_LENGTH_OF_ARRAY(pushConstants) == DE_LENGTH_OF_ARRAY(testParams.pushConstantValues));
	for (int pixelIdx = 0; pixelIdx < DE_LENGTH_OF_ARRAY(pushConstants); ++pixelIdx)
		testParams.pushConstantValues[pixelIdx] = pushConstants[pixelIdx];

	testParams.bindPoint = bindPoint;

	group->addChild(new OverwriteTestCase(testCtx, "overwrite", "Test push constant range overwrites", testParams));
}

} // anonymous

tcu::TestCaseGroup* createPushConstantTests (tcu::TestContext& testCtx)
{
	static const struct
	{
		const char*			name;
		const char*			description;
		deUint32			count;
		PushConstantData	range[MAX_RANGE_COUNT];
		deBool				hasMultipleUpdates;
		IndexType			indexType;
	} graphicsParams[] =
	{
		// test range size from minimum valid size to maximum
		{
			"range_size_4",
			"test range size is 4 bytes(minimum valid size)",
			1u,
			{ { { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 } , { 0, 4 } } },
			false,
			INDEX_TYPE_CONST_LITERAL
		},
		{
			"range_size_16",
			"test range size is 16 bytes, and together with a normal uniform",
			1u,
			{ { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } } },
			false,
			INDEX_TYPE_CONST_LITERAL
		},
		{
			"range_size_128",
			"test range size is 128 bytes(maximum valid size)",
			1u,
			{ { { VK_SHADER_STAGE_VERTEX_BIT, 0, 128 }, { 0, 128 } } },
			false,
			INDEX_TYPE_CONST_LITERAL
		},
		// test range count, including all valid shader stage in graphics pipeline, and also multiple shader stages share one single range
		{
			"count_2_shaders_vert_frag",
			"test range count is 2, use vertex and fragment shaders",
			2u,
			{
				{ { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } },
				{ { VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4 }, { 16, 4 } },
			},
			false,
			INDEX_TYPE_CONST_LITERAL
		},
		{
			"count_3_shaders_vert_geom_frag",
			"test range count is 3, use vertex, geometry and fragment shaders",
			3u,
			{
				{ { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } },
				{ { VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4 }, { 16, 4 } },
				{ { VK_SHADER_STAGE_GEOMETRY_BIT, 20, 4 }, { 20, 4 } },
			},
			false,
			INDEX_TYPE_CONST_LITERAL
		},
		{
			"count_5_shaders_vert_tess_geom_frag",
			"test range count is 5, use vertex, tessellation, geometry and fragment shaders",
			5u,
			{
				{ { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } },
				{ { VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4 }, { 16, 4 } },
				{ { VK_SHADER_STAGE_GEOMETRY_BIT, 20, 4 }, { 20, 4 } },
				{ { VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 24, 4 }, { 24, 4 } },
				{ { VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 32, 16 }, { 32, 16 } },
			},
			false,
			INDEX_TYPE_CONST_LITERAL
		},
		{
			"count_1_shader_vert_frag",
			"test range count is 1, vertex and fragment shaders share one range",
			1u,
			{ { { VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4 }, { 0, 4 } } },
			false,
			INDEX_TYPE_CONST_LITERAL
		},
		// test data partial update and multiple times update
		{
			"data_update_partial_1",
			"test partial update of the values",
			1u,
			{ { { VK_SHADER_STAGE_VERTEX_BIT, 0, 32 }, { 4, 24 } } },
			false,
			INDEX_TYPE_CONST_LITERAL
		},
		{
			"data_update_partial_2",
			"test partial update of the values",
			1u,
			{ { { VK_SHADER_STAGE_VERTEX_BIT, 0, 48 }, { 32, 16 } } },
			false,
			INDEX_TYPE_CONST_LITERAL
		},
		{
			"data_update_multiple",
			"test multiple times update of the values",
			1u,
			{ { { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 }, { 0, 4 } } },
			true,
			INDEX_TYPE_CONST_LITERAL
		},
		{
			"dynamic_index_vert",
			"dynamically uniform indexing of vertex, matrix, and array in vertex shader",
			1u,
			{ { { VK_SHADER_STAGE_VERTEX_BIT, 0, 64 }, { 0, 64 } } },
			false,
			INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR
		},
		{
			"dynamic_index_frag",
			"dynamically uniform indexing of vertex, matrix, and array in fragment shader",
			1u,
			{ { { VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 64 }, { 0, 64 } } },
			false,
			INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR
		}
	};

	static const struct
	{
		const char*			name;
		const char*			description;
		deUint32			count;
		PushConstantData	range[MAX_RANGE_COUNT];
	} overlapGraphicsParams[] =
	{
		// test ranges with multiple overlapping stages
		{
			"overlap_2_shaders_vert_frag",
			"overlapping range count is 2, use vertex and fragment shaders",
			2u,
			{
				{ { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } },
				{ { VK_SHADER_STAGE_FRAGMENT_BIT, 12, 36 }, { 12, 36 } },
			}
		},
		{
			"overlap_3_shaders_vert_geom_frag",
			"overlapping range count is 3, use vertex, geometry and fragment shaders",
			3u,
			{
				{ { VK_SHADER_STAGE_VERTEX_BIT, 12, 36 }, { 12, 36 } },
				{ { VK_SHADER_STAGE_GEOMETRY_BIT, 0, 32 }, { 16, 16 } },
				{ { VK_SHADER_STAGE_FRAGMENT_BIT, 20, 4 }, { 20, 4 } }
			}
		},
		{
			"overlap_4_shaders_vert_tess_frag",
			"overlapping range count is 4, use vertex, tessellation and fragment shaders",
			4u,
			{
				{ { VK_SHADER_STAGE_VERTEX_BIT, 8, 4 }, { 8, 4 } },
				{ { VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 128 }, { 52, 76 } },
				{ { VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 56, 8 }, { 56, 8 } },
				{ { VK_SHADER_STAGE_FRAGMENT_BIT, 60, 36 }, { 60, 36 } }
			}
		},
		{
			"overlap_5_shaders_vert_tess_geom_frag",
			"overlapping range count is 5, use vertex, tessellation, geometry and fragment shaders",
			5u,
			{
				{ { VK_SHADER_STAGE_VERTEX_BIT, 40, 8 }, { 40, 8 } },
				{ { VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 32, 12 }, { 32, 12 } },
				{ { VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 48, 16 }, { 48, 16 } },
				{ { VK_SHADER_STAGE_GEOMETRY_BIT, 28, 36 }, { 28, 36 } },
				{ { VK_SHADER_STAGE_FRAGMENT_BIT, 56, 8 }, { 60, 4 } }
			}
		}
	};

	static const struct
	{
		const char*			name;
		const char*			description;
		ComputeTestType		type;
		PushConstantData	range;
	} computeParams[] =
	{
		{
			"simple_test",
			"test compute pipeline",
			CTT_SIMPLE,
			{ { VK_SHADER_STAGE_COMPUTE_BIT, 0, 16 }, { 0, 16 } },
		},
		{
			"uninitialized",
			"test push constant that is dynamically unused",
			CTT_UNINITIALIZED,
			{ { VK_SHADER_STAGE_COMPUTE_BIT, 0, 16 }, { 0, 16 } },
		},
	};

	static const struct
	{
		const char*						name;
		const char*						description;
		PushConstantData				range[MAX_RANGE_COUNT];
		std::vector<CommandData>		cmdList;
	} lifetimeParams[] =
	{
		{
			"push_range0_bind_layout1",
			"bind different layout with the same range",
			{
				{{VK_SHADER_STAGE_VERTEX_BIT, 0, 32}, {0, 32}},
				{{VK_SHADER_STAGE_VERTEX_BIT, 0, 32}, {0, 32}}
			},
			{
				{ CMD_PUSH_CONSTANT, 0 },
				{ CMD_BIND_PIPELINE_GRAPHICS, 1 },
				{ CMD_DRAW, -1 },
			}
		},
		{
			"push_range1_bind_layout1_push_range0",
			"bind layout with same range then push different range",
			{
				{{VK_SHADER_STAGE_VERTEX_BIT, 0, 32}, {0, 32}},
				{{VK_SHADER_STAGE_VERTEX_BIT, 0, 32}, {0, 32}}
			},
			{
				{ CMD_PUSH_CONSTANT, 1 },
				{ CMD_BIND_PIPELINE_GRAPHICS, 1 },
				{ CMD_DRAW, -1 },
				{ CMD_PUSH_CONSTANT, 0 },
				{ CMD_DRAW, -1 },
			}
		},
		{
			"push_range0_bind_layout0_push_range1_push_range0",
			"same range same layout then same range from a different layout and same range from the same layout",
			{
				{{VK_SHADER_STAGE_VERTEX_BIT, 0, 32}, {0, 32}},
				{{VK_SHADER_STAGE_VERTEX_BIT, 0, 32}, {0, 32}}
			},
			{
				{ CMD_PUSH_CONSTANT, 0 },
				{ CMD_BIND_PIPELINE_GRAPHICS, 0 },
				{ CMD_PUSH_CONSTANT, 1 },
				{ CMD_PUSH_CONSTANT, 0 },
				{ CMD_DRAW, -1 },
			}
		},
		{
			"push_range0_bind_layout0_push_diff_overlapping_range1_push_range0",
			"same range same layout then diff range and same range update",
			{
				{{VK_SHADER_STAGE_VERTEX_BIT, 0, 32}, {0, 32}},
				{{VK_SHADER_STAGE_VERTEX_BIT, 16, 32}, {16, 32}}
			},
			{
				{ CMD_PUSH_CONSTANT, 0 },
				{ CMD_BIND_PIPELINE_GRAPHICS, 0 },
				{ CMD_PUSH_CONSTANT, 1 },
				{ CMD_PUSH_CONSTANT, 0 },
				{ CMD_DRAW, -1 },
			}
		},
		{
			"push_range0_bind_layout1_bind_layout0",
			"update push constant bind different layout with the same range then bind correct layout",
			{
				{{VK_SHADER_STAGE_VERTEX_BIT, 0, 32}, {0, 32}},
				{{VK_SHADER_STAGE_VERTEX_BIT, 0, 32}, {0, 32}}
			},
			{
				{ CMD_PUSH_CONSTANT, 0 },
				{ CMD_BIND_PIPELINE_GRAPHICS, 1 },
				{ CMD_BIND_PIPELINE_GRAPHICS, 0 },
				{ CMD_DRAW, -1 },
			}
		},
		{
			"push_range0_bind_layout1_overlapping_range_bind_layout0",
			"update push constant then bind different layout with overlapping range then bind correct layout",
			{
				{{VK_SHADER_STAGE_VERTEX_BIT, 0, 32}, {0, 32}},
				{{VK_SHADER_STAGE_VERTEX_BIT, 16, 32}, {16, 32}}
			},
			{
				{ CMD_PUSH_CONSTANT, 0 },
				{ CMD_BIND_PIPELINE_GRAPHICS, 1 },
				{ CMD_BIND_PIPELINE_GRAPHICS, 0 },
				{ CMD_DRAW, -1 },
			}
		},
		{
			"bind_layout1_push_range0_bind_layout0",
			"bind different layout with different range then update push constant and bind correct layout",
			{
				{{VK_SHADER_STAGE_VERTEX_BIT, 0, 32}, {0, 32}},
				{{VK_SHADER_STAGE_VERTEX_BIT, 16, 32}, {16, 32}}
			},
			{
				{ CMD_BIND_PIPELINE_GRAPHICS, 1 },
				{ CMD_PUSH_CONSTANT, 0 },
				{ CMD_BIND_PIPELINE_GRAPHICS, 0 },
				{ CMD_DRAW, -1 },
			}
		},
		{
			"pipeline_change_same_range_bind_push_vert_and_comp",
			"change pipeline same range, bind then push, stages vertex and compute",
			{
				{{VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 0, 32}, {0, 32}},
				{{VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 0, 32}, {0, 32}}
			},
			{
				{ CMD_BIND_PIPELINE_GRAPHICS, 0 },
				{ CMD_BIND_PIPELINE_COMPUTE, 1 },
				{ CMD_PUSH_CONSTANT, 0 },
				{ CMD_DRAW, -1 },
				{ CMD_PUSH_CONSTANT, 1 },
				{ CMD_DISPATCH, -1 },
			}
		},
		{
			"pipeline_change_diff_range_bind_push_vert_and_comp",
			"change pipeline different range overlapping, bind then push, stages vertex and compute",
			{
				{{VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 0, 32}, {0, 32}},
				{{VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 16, 32}, {16, 32}}
			},
			{
				{ CMD_BIND_PIPELINE_GRAPHICS, 0 },
				{ CMD_BIND_PIPELINE_COMPUTE, 1 },
				{ CMD_PUSH_CONSTANT, 0 },
				{ CMD_DRAW, -1 },
				{ CMD_PUSH_CONSTANT, 1 },
				{ CMD_DISPATCH, -1 },
			}
		}
	};

	de::MovePtr<tcu::TestCaseGroup>	pushConstantTests	(new tcu::TestCaseGroup(testCtx, "push_constant", "PushConstant tests"));

	de::MovePtr<tcu::TestCaseGroup>	graphicsTests	(new tcu::TestCaseGroup(testCtx, "graphics_pipeline", "graphics pipeline"));
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(graphicsParams); ndx++)
	{
		graphicsTests->addChild(new PushConstantGraphicsDisjointTest(testCtx, graphicsParams[ndx].name, graphicsParams[ndx].description, graphicsParams[ndx].count, graphicsParams[ndx].range, graphicsParams[ndx].hasMultipleUpdates, graphicsParams[ndx].indexType));
	}

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(overlapGraphicsParams); ndx++)
	{
		graphicsTests->addChild(new PushConstantGraphicsOverlapTest(testCtx, overlapGraphicsParams[ndx].name, overlapGraphicsParams[ndx].description, overlapGraphicsParams[ndx].count, overlapGraphicsParams[ndx].range));
	}
	addOverwriteCase(graphicsTests.get(), testCtx, VK_PIPELINE_BIND_POINT_GRAPHICS);
	pushConstantTests->addChild(graphicsTests.release());

	de::MovePtr<tcu::TestCaseGroup>	computeTests	(new tcu::TestCaseGroup(testCtx, "compute_pipeline", "compute pipeline"));
	for (const auto& params : computeParams)
	{
		computeTests->addChild(new PushConstantComputeTest(testCtx, params.name, params.description, params.type, params.range));
	}
	addOverwriteCase(computeTests.get(), testCtx, VK_PIPELINE_BIND_POINT_COMPUTE);
	pushConstantTests->addChild(computeTests.release());

	de::MovePtr<tcu::TestCaseGroup>	lifetimeTests	(new tcu::TestCaseGroup(testCtx, "lifetime", "lifetime tests"));
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(lifetimeParams); ndx++)
	{
		lifetimeTests->addChild(new PushConstantLifetimeTest(testCtx, lifetimeParams[ndx].name, lifetimeParams[ndx].description, lifetimeParams[ndx].range, lifetimeParams[ndx].cmdList));
	}
	pushConstantTests->addChild(lifetimeTests.release());

	return pushConstantTests.release();
}

} // pipeline
} // vkt
