/*------------------------------------------------------------------------
 * 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
};

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 PushConstantData	pushConstantRange);
	virtual					~PushConstantComputeTest	(void);
	virtual void			initPrograms				(SourceCollections& sourceCollections) const;
	virtual TestInstance*	createInstance				(Context& context) const;

private:
	const PushConstantData	m_pushConstantRange;
};

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

private:
	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 PushConstantData	pushConstantRange)
	: vkt::TestCase			(testContext, name, description)
	, m_pushConstantRange	(pushConstantRange)
{
}

PushConstantComputeTest::~PushConstantComputeTest (void)
{
}

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

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 PushConstantData	pushConstantRange)
	: vkt::TestInstance		(context)
	, 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
		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());

	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;
		PushConstantData	range;
	} computeParams[] =
	{
		{
			"simple_test",
			"test compute pipeline",
			{ { 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"));
	computeTests->addChild(new PushConstantComputeTest(testCtx, computeParams[0].name, computeParams[0].description, computeParams[0].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
