/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2018 Google Inc.
 *
 * 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 Descriptor set tests
 *//*--------------------------------------------------------------------*/

#include "amber/vktAmberTestCase.hpp"
#include "vktApiDescriptorSetTests.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkMemUtil.hpp"
#include "vktApiBufferComputeInstance.hpp"
#include "vktApiComputeInstanceResultBuffer.hpp"
#include "vkBufferWithMemory.hpp"
#include "vkObjUtil.hpp"

#include "vkQueryUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkPrograms.hpp"

namespace vkt
{
namespace api
{

namespace
{

using namespace std;
using namespace vk;

// Descriptor set layout used to create a pipeline layout is destroyed prior to creating a pipeline
Move<VkPipelineLayout> createPipelineLayoutDestroyDescriptorSetLayout (const DeviceInterface& vk, const VkDevice& device)
{
	const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutInfo		=
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType;
		DE_NULL,												// const void*							pNext;
		(VkDescriptorSetLayoutCreateFlags)0,					// VkDescriptorSetLayoutCreateFlags		flags;
		0u,														// deUint32								bindingCount;
		DE_NULL,												// const VkDescriptorSetLayoutBinding*	pBindings;
	};

	Unique<VkDescriptorSetLayout>			descriptorSetLayout			(createDescriptorSetLayout(vk, device, &descriptorSetLayoutInfo));

	const VkPipelineLayoutCreateInfo		pipelineLayoutCreateInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// VkStructureType					sType;
		DE_NULL,												// const void*						pNext;
		(VkPipelineLayoutCreateFlags)0,							// VkPipelineLayoutCreateFlags		flags;
		1u,														// deUint32							setLayoutCount;
		&descriptorSetLayout.get(),								// const VkDescriptorSetLayout*		pSetLayouts;
		0u,														// deUint32							pushConstantRangeCount;
		DE_NULL													// const VkPushConstantRange*		pPushConstantRanges;
	};

	return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
}

tcu::TestStatus descriptorSetLayoutLifetimeGraphicsTest (Context& context)
{
	const DeviceInterface&							vk								= context.getDeviceInterface();
	const VkDevice									device							= context.getDevice();
    deUint32					                    queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
    const VkQueue					                queue				            = context.getUniversalQueue();

	Unique<VkPipelineLayout>						pipelineLayout					(createPipelineLayoutDestroyDescriptorSetLayout(vk, device));

	const Unique<VkShaderModule>					vertexShaderModule				(createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0));

	const VkPipelineShaderStageCreateInfo			shaderStageCreateInfo			=
	{
		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
		DE_NULL,												// const void*						pNext;
		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags	flags;
		VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits			stage;
		vertexShaderModule.get(),								// VkShaderModule					shader;
		"main",													// const char*						pName;
		DE_NULL,												// const VkSpecializationInfo*		pSpecializationInfo;
	};

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

	const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyStateCreateInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,														// const void*								pNext;
		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags	flags;
		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,							// VkPrimitiveTopology						topology;
		VK_FALSE														// VkBool32									primitiveRestartEnable;
	};

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

	const VkSubpassDescription						subpassDescription				=
	{
		(VkSubpassDescriptionFlags)0,		// VkSubpassDescriptionFlags		flags;
		VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint				pipelineBindPoint
		0u,									// deUint32							inputAttachmentCount
		DE_NULL,							// const VkAttachmentReference*		pInputAttachments
		0u,									// deUint32							colorAttachmentCount
		DE_NULL,							// const VkAttachmentReference*		pColorAttachments
		DE_NULL,							// const VkAttachmentReference*		pResolveAttachments
		DE_NULL,							// const VkAttachmentReference*		pDepthStencilAttachment
		0u,									// deUint32							preserveAttachmentCount
		DE_NULL								// const deUint32*					pPreserveAttachments
	};

	const VkRenderPassCreateInfo					renderPassCreateInfo			=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,		// VkStructureType					sType;
		DE_NULL,										// const void*						pNext;
		(VkRenderPassCreateFlags)0,						// VkRenderPassCreateFlags			flags;
		0u,												// deUint32							attachmentCount
		DE_NULL,										// const VkAttachmentDescription*	pAttachments
		1u,												// deUint32							subpassCount
		&subpassDescription,							// const VkSubpassDescription*		pSubpasses
		0u,												// deUint32							dependencyCount
		DE_NULL											// const VkSubpassDependency*		pDependencies
	};

	Unique<VkRenderPass>							renderPass						(createRenderPass(vk, device, &renderPassCreateInfo));

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

	Unique<VkPipeline>								graphicsPipeline				(createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo));


	VkFramebufferCreateInfo framebufferCreateInfo
	{
		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType			sType
		DE_NULL,										// const void*				pNext
		0,												// VkFramebufferCreateFlags	flags
		*renderPass,									// VkRenderPass				renderPass
		0,												// uint32_t					attachmentCount
		DE_NULL,										// const VkImageView*		pAttachments
		16,												// uint32_t					width
		16,												// uint32_t					height
		1												// uint32_t					layers
	};

	Move <VkFramebuffer> framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);

	const VkCommandPoolCreateInfo cmdPoolInfo			=
	{
		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// Stype
		DE_NULL,										// PNext
		DE_NULL,										// flags
		queueFamilyIndex,								// queuefamilyindex
	};

	const Unique<VkCommandPool>				cmdPool(createCommandPool(vk, device, &cmdPoolInfo));

	const VkCommandBufferAllocateInfo		cmdBufParams =
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	//	VkStructureType			sType;
		DE_NULL,										//	const void*				pNext;
		*cmdPool,										//	VkCommandPool			pool;
		VK_COMMAND_BUFFER_LEVEL_PRIMARY,				//	VkCommandBufferLevel	level;
		1u,												//	uint32_t				bufferCount;
	};

	const Unique<VkCommandBuffer>			cmdBuf(allocateCommandBuffer(vk, device, &cmdBufParams));

	const VkRenderPassBeginInfo renderPassBeginInfo		=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
		DE_NULL,
		*renderPass,
		*framebuffer,
		{{0, 0}, {16, 16}},
		0,
		DE_NULL
	};

	beginCommandBuffer(vk, *cmdBuf, 0u);
	{
		vk.cmdBeginRenderPass(*cmdBuf, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
		vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
		vk.cmdDraw(*cmdBuf, 3u, 1u, 0, 0);
		vk.cmdEndRenderPass(*cmdBuf);
    }
    endCommandBuffer(vk, *cmdBuf);

    submitCommandsAndWait(vk, device, queue, *cmdBuf);

	// Test should always pass
	return tcu::TestStatus::pass("Pass");
}

tcu::TestStatus descriptorSetLayoutLifetimeComputeTest (Context& context)
{
	const DeviceInterface&					vk							= context.getDeviceInterface();
	const VkDevice							device						= context.getDevice();
    deUint32					            queueFamilyIndex            = context.getUniversalQueueFamilyIndex();
    const VkQueue					        queue				        = context.getUniversalQueue();
    Allocator&								allocator = context.getDefaultAllocator();
    const ComputeInstanceResultBuffer		result(vk, device, allocator, 0.0f);


    Unique<VkPipelineLayout>				pipelineLayout				(createPipelineLayoutDestroyDescriptorSetLayout(vk, device));

	const Unique<VkShaderModule>			computeShaderModule			(createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0));

	const VkPipelineShaderStageCreateInfo	shaderStageCreateInfo		=
	{
		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
		DE_NULL,												// const void*						pNext;
		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags	flags;
		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage;
		computeShaderModule.get(),								// VkShaderModule					shader;
		"main",													// const char*						pName;
		DE_NULL													// const VkSpecializationInfo*		pSpecializationInfo;
	};

	const VkComputePipelineCreateInfo		computePipelineCreateInfo	=
	{
		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			// VkStructureType					sType
		DE_NULL,												// const void*						pNext
		(VkPipelineCreateFlags)0,								// VkPipelineCreateFlags			flags
		shaderStageCreateInfo,									// VkPipelineShaderStageCreateInfo	stage
		pipelineLayout.get(),									// VkPipelineLayout					layout
		DE_NULL,												// VkPipeline						basePipelineHandle
		0														// int								basePipelineIndex
	};

	const deUint32							offset = (0u);
	const deUint32							addressableSize = 256;
	const deUint32							dataSize = 8;
	de::MovePtr<Allocation>					bufferMem;
	const Unique<VkBuffer>					buffer						(createDataBuffer(context, offset, addressableSize, 0x00, dataSize, 0x5A, &bufferMem));
	const Unique<VkDescriptorSetLayout>		descriptorSetLayout			(createDescriptorSetLayout(context));
	const Unique<VkDescriptorPool>			descriptorPool				(createDescriptorPool(context));
	const Unique<VkDescriptorSet>			descriptorSet				(createDescriptorSet(context, *descriptorPool, *descriptorSetLayout, *buffer, offset, result.getBuffer()));

	Unique<VkPipeline>						computePipeline				(createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo));

	const VkCommandPoolCreateInfo cmdPoolInfo				=
	{
		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,				// Stype
		DE_NULL,												// PNext
		DE_NULL,												// flags
		queueFamilyIndex,										// queuefamilyindex
	};

	const Unique<VkCommandPool>				cmdPool(createCommandPool(vk, device, &cmdPoolInfo));

	const VkCommandBufferAllocateInfo		cmdBufParams	=
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,			//	VkStructureType			sType;
		DE_NULL,												//	const void*				pNext;
		*cmdPool,												//	VkCommandPool			pool;
		VK_COMMAND_BUFFER_LEVEL_PRIMARY,						//	VkCommandBufferLevel	level;
		1u,														//	uint32_t				bufferCount;
	};

	const Unique<VkCommandBuffer>			cmdBuf(allocateCommandBuffer(vk, device, &cmdBufParams));

	beginCommandBuffer(vk, *cmdBuf, 0u);
	{
		vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
		vk.cmdBindDescriptorSets(*cmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1u, &*descriptorSet, 0, 0);
		vk.cmdDispatch(*cmdBuf, 1u, 1u, 1u);
	}
	endCommandBuffer(vk, *cmdBuf);

	submitCommandsAndWait(vk, device, queue, *cmdBuf);

	// Test should always pass
	return tcu::TestStatus::pass("Pass");
}

tcu::TestStatus emptyDescriptorSetLayoutTest (Context& context, VkDescriptorSetLayoutCreateFlags descriptorSetLayoutCreateFlags)
{
	const DeviceInterface&					vk								= context.getDeviceInterface();
	const VkDevice							device							= context.getDevice();

	if (descriptorSetLayoutCreateFlags == VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)
		if (!context.isDeviceFunctionalitySupported("VK_KHR_push_descriptor"))
			TCU_THROW(NotSupportedError, "VK_KHR_push_descriptor extension not supported");

	const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType                        sType;
		DE_NULL,												// const void*                            pNext;
		descriptorSetLayoutCreateFlags,							// VkDescriptorSetLayoutCreateFlags       flags;
		0u,														// deUint32                               bindingCount;
		DE_NULL													// const VkDescriptorSetLayoutBinding*    pBindings;
	};

	Unique<VkDescriptorSetLayout>			descriptorSetLayout				(createDescriptorSetLayout(vk, device, &descriptorSetLayoutCreateInfo));

	// Test should always pass
	return tcu::TestStatus::pass("Pass");
}

tcu::TestStatus descriptorSetLayoutBindingOrderingTest (Context& context)
{
	/*
		This test tests that if dstBinding has fewer than
		descriptorCount array elements remaining starting from dstArrayElement,
		then the remainder will be used to update the subsequent binding.
	*/

	const DeviceInterface&		vk					= context.getDeviceInterface();
	const VkDevice				device				= context.getDevice();
	deUint32					queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	const VkQueue				queue				= context.getUniversalQueue();

	const Unique<VkShaderModule> computeShaderModule (createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0));

	de::MovePtr<BufferWithMemory> buffer;
	buffer			= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk,
																		device,
																		context.getDefaultAllocator(),
																		makeBufferCreateInfo(4u, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),
																		MemoryRequirement::HostVisible));
	deUint32 *bufferPtr = (deUint32 *)buffer->getAllocation().getHostPtr();
	*bufferPtr = 5;

	de::MovePtr<BufferWithMemory> resultBuffer;
	resultBuffer	= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk,
																		device,
																		context.getDefaultAllocator(),
																		makeBufferCreateInfo(4u * 3, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
																		MemoryRequirement::HostVisible));

	const VkDescriptorBufferInfo	descriptorBufferInfos[]		=
	{
		{
			buffer->get(),		// VkBuffer			buffer
			0u,					// VkDeviceSize		offset
			VK_WHOLE_SIZE		// VkDeviceSize		range
		},
		{
			buffer->get(),		// VkBuffer			buffer
			0u,					// VkDeviceSize		offset
			VK_WHOLE_SIZE		// VkDeviceSize		range
		},
		{
			buffer->get(),		// VkBuffer			buffer
			0u,					// VkDeviceSize		offset
			VK_WHOLE_SIZE		// VkDeviceSize		range
		},
	};

	const VkDescriptorBufferInfo	descriptorBufferInfoResult	=
	{
		resultBuffer->get(),	// VkBuffer			buffer
		0u,						// VkDeviceSize		offset
		VK_WHOLE_SIZE			// VkDeviceSize		range
	};

	const VkDescriptorSetLayoutBinding layoutBindings[] =
	{
		{
			0u,										// deUint32				binding;
			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,		// VkDescriptorType		descriptorType;
			2u,										// deUint32				descriptorCount;
			VK_SHADER_STAGE_ALL,					// VkShaderStageFlags	stageFlags;
			DE_NULL									// const VkSampler*		pImmutableSamplers;
		},
		{
			1u,										// deUint32				binding;
			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,		// VkDescriptorType		descriptorType;
			1u,										// deUint32				descriptorCount;
			VK_SHADER_STAGE_ALL,					// VkShaderStageFlags	stageFlags;
			DE_NULL									// const VkSampler*		pImmutableSamplers;
		},
		{
			2u,										// deUint32				binding;
			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,		// VkDescriptorType		descriptorType;
			1u,										// deUint32				descriptorCount;
			VK_SHADER_STAGE_ALL,					// VkShaderStageFlags	stageFlags;
			DE_NULL									// const VkSampler*		pImmutableSamplers;
		}
	};

	const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,												// const void*								pNext;
		0u,														// VkDescriptorSetLayoutCreateFlags			flags;
		DE_LENGTH_OF_ARRAY(layoutBindings),						// deUint32									bindingCount;
		layoutBindings											// const VkDescriptorSetLayoutBinding*		pBindings;
	};

	Move<VkDescriptorSetLayout> descriptorSetLayout(createDescriptorSetLayout(vk, device, &descriptorSetLayoutCreateInfo));

	const VkDescriptorPoolSize				poolSize[]						=
	{
		{
			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,			// VkDescriptorType				type
			3u											// uint32_t						descriptorCount
		},
		{
			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,			// VkDescriptorType				type
			1u											// uint32_t						descriptorCount
		}
	};

	const VkDescriptorPoolCreateInfo		descriptorPoolCreateInfo		=
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,	// VkStructureType				sType
		DE_NULL,										// const void*					pNext
		0u,												// VkDescriptorPoolCreateFlags	flags
		1u,												// uint32_t						maxSets
		2u,												// uint32_t						poolSizeCount
		poolSize										// const VkDescriptorPoolSize*	pPoolSizes
	};

	Move<VkDescriptorPool> descriptorPool(createDescriptorPool(vk, device, &descriptorPoolCreateInfo));

	VkDescriptorSet descriptorSet;
	{
		const VkDescriptorSetAllocateInfo allocInfo =
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructure						sType
			DE_NULL,											// const void*						pNext
			*descriptorPool,									// VkDescriptorPool					descriptorPool
			1u,													// uint32_t							descriptorSetCount
			&*descriptorSetLayout								// const VkDescriptorSetLayout*		pSetLayouts
		};

		VK_CHECK(vk.allocateDescriptorSets(device, &allocInfo, &descriptorSet));
	}

	const VkWriteDescriptorSet				descriptorWrite			=
	{
		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,					// VkStructureType					sType
		DE_NULL,												// const void*						pNext
		descriptorSet,											// VkDescriptorSet					dstSet
		0u,														// deUint32							dstBinding
		0u,														// deUint32							dstArrayElement
		3u,														// deUint32							descriptorCount
		VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,						// VkDescriptorType					descriptorType
		DE_NULL,												// const VkDescriptorImageInfo		pImageInfo
		descriptorBufferInfos,									// const VkDescriptorBufferInfo*	pBufferInfo
		DE_NULL													// const VkBufferView*				pTexelBufferView
	};

	const VkWriteDescriptorSet				descriptorWriteResult	=
	{
		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,					// VkStructureType					sType
		DE_NULL,												// const void*						pNext
		descriptorSet,											// VkDescriptorSet					dstSet
		2u,														// deUint32							dstBinding
		0u,														// deUint32							dstArrayElement
		1u,														// deUint32							descriptorCount
		VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,						// VkDescriptorType					descriptorType
		DE_NULL,												// const VkDescriptorImageInfo		pImageInfo
		&descriptorBufferInfoResult,							// const VkDescriptorBufferInfo*	pBufferInfo
		DE_NULL													// const VkBufferView*				pTexelBufferView
	};

	const VkCommandPoolCreateInfo			cmdPoolInfo				=
	{
		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,				// VkStructureType					Stype
		DE_NULL,												// const void*						PNext
		DE_NULL,												// VkCommandPoolCreateFlags			flags
		queueFamilyIndex,										// uint32_t							queuefamilyindex
	};

	const Unique<VkCommandPool>				cmdPool(createCommandPool(vk, device, &cmdPoolInfo));

	const VkCommandBufferAllocateInfo		cmdBufParams			=
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,			// VkStructureType					sType;
		DE_NULL,												// const void*						pNext;
		*cmdPool,												// VkCommandPool					pool;
		VK_COMMAND_BUFFER_LEVEL_PRIMARY,						// VkCommandBufferLevel				level;
		1u,														// uint32_t							bufferCount;
	};

	const Unique<VkCommandBuffer>			cmdBuf(allocateCommandBuffer(vk, device, &cmdBufParams));

	const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// VkStructureType					sType
		DE_NULL,												// const void*						pNext
		0,														// VkPipelineLayoutCreateFlags		flags
		1u,														// uint32_t							setLayoutCount
		&*descriptorSetLayout,									// const VkDescriptorSetLayout*		pSetLayouts
		0u,														// uint32_t							pushConstantRangeCount
		nullptr													// const VkPushConstantRange*		pPushConstantRanges
	};

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

	const VkPipelineShaderStageCreateInfo	shaderStageCreateInfo		=
	{
		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
		DE_NULL,												// const void*						pNext;
		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags	flags;
		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage;
		computeShaderModule.get(),								// VkShaderModule					shader;
		"main",													// const char*						pName;
		DE_NULL													// const VkSpecializationInfo*		pSpecializationInfo;
	};

	const VkComputePipelineCreateInfo		computePipelineCreateInfo	=
	{
		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			// VkStructureType					sType
		DE_NULL,												// const void*						pNext
		(VkPipelineCreateFlags)0,								// VkPipelineCreateFlags			flags
		shaderStageCreateInfo,									// VkPipelineShaderStageCreateInfo	stage
		*pipelineLayout,										// VkPipelineLayout					layout
		DE_NULL,												// VkPipeline						basePipelineHandle
		0														// int								basePipelineIndex
	};

	Unique<VkPipeline> computePipeline(createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo));

	beginCommandBuffer(vk, *cmdBuf, 0u);
	{
		vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
		vk.updateDescriptorSets(device, 1u, &descriptorWrite, 0u, DE_NULL);
		vk.updateDescriptorSets(device, 1u, &descriptorWriteResult, 0u, DE_NULL);
		vk.cmdBindDescriptorSets(*cmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1u, &descriptorSet, 0, nullptr);
		flushAlloc(vk, device, buffer->getAllocation());
		vk.cmdDispatch(*cmdBuf, 1u, 1u, 1u);
	}

	endCommandBuffer(vk, *cmdBuf);
	submitCommandsAndWait(vk, device, queue, *cmdBuf);

	const Allocation& bufferAllocationResult = resultBuffer->getAllocation();
	invalidateAlloc(vk, device, bufferAllocationResult);

	const deUint32* resultPtr = static_cast<deUint32*>(bufferAllocationResult.getHostPtr());

	if (resultPtr[0] == 5 && resultPtr[1] == 5 && resultPtr[2] == 5)
		return tcu::TestStatus::pass("Pass");
	else
		return tcu::TestStatus::fail("Fail");
}
} // anonymous

void createDescriptorSetLayoutLifetimeGraphicsSource (SourceCollections& dst)
{
	dst.glslSources.add("vertex") << glu::VertexSource(
		"#version 310 es\n"
		"void main (void)\n"
		"{\n"
		"    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
		"}\n");
}

void createDescriptorSetLayoutLifetimeComputeSource (SourceCollections& dst)
{
	dst.glslSources.add("compute") << glu::ComputeSource(
		"#version 310 es\n"
		"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
		"void main (void)\n"
		"{\n"
		"}\n");
}

void createDescriptorSetLayoutBindingOrderingSource (SourceCollections& dst)
{
	dst.glslSources.add("compute") << glu::ComputeSource(
		"#version 310 es\n"
		"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
		"layout (set = 0, binding = 0) uniform UniformBuffer0 {\n"
		"	int data;\n"
		"} uniformbufferarray[2];\n"
		"layout (set = 0, binding = 1) uniform UniformBuffer2 {\n"
		"	int data;\n"
		"} uniformbuffer2;\n"
		"layout (set = 0, binding = 2) buffer StorageBuffer {\n"
		"	int result0;\n"
		"	int result1;\n"
		"	int result2;\n"
		"} results;\n"
		"\n"
		"void main (void)\n"
		"{\n"
		"	results.result0 = uniformbufferarray[0].data;\n"
		"	results.result1 = uniformbufferarray[1].data;\n"
		"	results.result2 = uniformbuffer2.data;\n"
		"}\n");
}

tcu::TestCaseGroup* createDescriptorSetLayoutLifetimeTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> descriptorSetLayoutLifetimeTests(new tcu::TestCaseGroup(testCtx, "descriptor_set_layout_lifetime", "Descriptor set layout lifetime tests"));

	addFunctionCaseWithPrograms(descriptorSetLayoutLifetimeTests.get(), "graphics", "Test descriptor set layout lifetime in graphics pipeline", createDescriptorSetLayoutLifetimeGraphicsSource, descriptorSetLayoutLifetimeGraphicsTest);
	addFunctionCaseWithPrograms(descriptorSetLayoutLifetimeTests.get(), "compute", "Test descriptor set layout lifetime in compute pipeline", createDescriptorSetLayoutLifetimeComputeSource,  descriptorSetLayoutLifetimeComputeTest);

	return descriptorSetLayoutLifetimeTests.release();
}

tcu::TestCaseGroup* createEmptyDescriptorSetLayoutTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> emptyDescriptorSetLayoutTests(new tcu::TestCaseGroup(testCtx, "empty_set", "Create empty descriptor set layout tests"));

	addFunctionCase(emptyDescriptorSetLayoutTests.get(), "normal", "Create empty desciptor set layout", emptyDescriptorSetLayoutTest, (VkDescriptorSetLayoutCreateFlags)0u);
	addFunctionCase(emptyDescriptorSetLayoutTests.get(), "push_descriptor", "Create empty push descriptor set layout", emptyDescriptorSetLayoutTest, (VkDescriptorSetLayoutCreateFlags)VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);

	return emptyDescriptorSetLayoutTests.release();
}

tcu::TestCaseGroup* createDescriptorSetLayoutBindingOrderingTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> descriptorSetLayoutBindingOrderingTests(new tcu::TestCaseGroup(testCtx, "descriptor_set_layout_binding", "Create descriptor set layout ordering tests"));
	addFunctionCaseWithPrograms(descriptorSetLayoutBindingOrderingTests.get(), "update_subsequent_binding", "Test subsequent binding update with remaining elements", createDescriptorSetLayoutBindingOrderingSource, descriptorSetLayoutBindingOrderingTest);

	static const char dataDir[] = "api/descriptor_set/descriptor_set_layout_binding";
	descriptorSetLayoutBindingOrderingTests->addChild(cts_amber::createAmberTestCase(testCtx, "layout_binding_order", "Test descriptor set layout binding order", dataDir, "layout_binding_order.amber"));

	return descriptorSetLayoutBindingOrderingTests.release();
}

tcu::TestCaseGroup* createDescriptorSetLayoutTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> descriptorSetLayoutTests(new tcu::TestCaseGroup(testCtx, "descriptor_set_layout", "Descriptor set layout tests"));

	descriptorSetLayoutTests->addChild(createEmptyDescriptorSetLayoutTests(testCtx));

	return descriptorSetLayoutTests.release();
}

tcu::TestCaseGroup* createDescriptorSetTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> descriptorSetTests(new tcu::TestCaseGroup(testCtx, "descriptor_set", "Descriptor set tests"));

	descriptorSetTests->addChild(createDescriptorSetLayoutLifetimeTests(testCtx));
	descriptorSetTests->addChild(createDescriptorSetLayoutTests(testCtx));
	descriptorSetTests->addChild(createDescriptorSetLayoutBindingOrderingTests(testCtx));

	return descriptorSetTests.release();
}

} // api
} // vkt
