/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2018 The Khronos Group Inc.
 * Copyright (c) 2018 Google Inc.
 * Copyright (c) 2018 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 Push Descriptor Tests
 *//*--------------------------------------------------------------------*/

#include "vktPipelinePushDescriptorTests.hpp"
#include "vktPipelineClearUtil.hpp"
#include "vktPipelineImageUtil.hpp"
#include "vktPipelineVertexUtil.hpp"
#include "vktPipelineReferenceRenderer.hpp"
#include "vktTestCase.hpp"
#include "vktCustomInstancesDevices.hpp"
#include "vkImageUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPrograms.hpp"
#include "vkQueryUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkDeviceUtil.hpp"
#include "tcuImageCompare.hpp"
#include "deMemory.h"
#include "deUniquePtr.hpp"
#include "tcuTestLog.hpp"
#include "tcuCommandLine.hpp"
#include <vector>

namespace vkt
{
namespace pipeline
{

using namespace vk;
using namespace std;

namespace
{
typedef vector<VkExtensionProperties>			Extensions;
typedef de::SharedPtr<Unique<VkBuffer> >		VkBufferSp;
typedef de::SharedPtr<Unique<VkImage> >			VkImageSp;
typedef de::SharedPtr<Unique<VkImageView> >		VkImageViewSp;
typedef de::SharedPtr<Unique<VkBufferView> >	VkBufferViewSp;
typedef de::SharedPtr<Allocation>				AllocationSp;
typedef de::SharedPtr<Unique<VkRenderPass> >	VkRenderPassSp;
typedef de::SharedPtr<Unique<VkFramebuffer> >	VkFramebufferSp;
typedef de::SharedPtr<Unique<VkPipeline> >		VkPipelineSp;

struct TestParams
{
	VkDescriptorType	descriptorType;
	deUint32			binding;
	deUint32			numCalls; // Number of draw or dispatch calls
};

void checkAllSupported (const Extensions& supportedExtensions, const vector<string>& requiredExtensions)
{
	for (auto& requiredExtName : requiredExtensions)
	{
		if (!isExtensionSupported(supportedExtensions, RequiredExtension(requiredExtName)))
			TCU_THROW(NotSupportedError, (requiredExtName + " is not supported").c_str());
	}
}

CustomInstance createInstanceWithGetPhysicalDeviceProperties2 (Context&				context,
															   const Extensions&	supportedExtensions)
{
	vector<string> requiredExtensions = { "VK_KHR_get_physical_device_properties2" };
	checkAllSupported(supportedExtensions, requiredExtensions);

	return createCustomInstanceWithExtensions(context, requiredExtensions);
}

const char *innerCString(const string &str)
{
	return str.c_str();
}

Move<VkDevice> createDeviceWithPushDescriptor (const Context&				context,
											   const PlatformInterface&		vkp,
											   VkInstance					instance,
											   const InstanceInterface&		vki,
											   VkPhysicalDevice				physicalDevice,
											   const Extensions&			supportedExtensions,
											   const deUint32				queueFamilyIndex)
{

	const float						queuePriority			= 1.0f;
	const VkDeviceQueueCreateInfo	queueInfo				=
	{
		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
		DE_NULL,
		(VkDeviceQueueCreateFlags)0,
		queueFamilyIndex,
		1u,
		&queuePriority
	};

	VkPhysicalDeviceFeatures		features;
	deMemset(&features, 0, sizeof(features));

	vector<string>					requiredExtensionsStr	= { "VK_KHR_push_descriptor" };
	vector<const char *>			requiredExtensions;
	checkAllSupported(supportedExtensions, requiredExtensionsStr);
	// We need the contents of requiredExtensionsStr as a vector<const char*> in VkDeviceCreateInfo.
	transform(begin(requiredExtensionsStr), end(requiredExtensionsStr), back_inserter(requiredExtensions), innerCString);

	// Enable validation layers on this device if validation has been requested from the command line.
	const VkDeviceCreateInfo		deviceParams    =
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
		DE_NULL,
		(VkDeviceCreateFlags)0,
		1u,
		&queueInfo,
		0u,
		DE_NULL,
		static_cast<deUint32>(requiredExtensions.size()),
		(requiredExtensions.empty() ? DE_NULL : requiredExtensions.data()),
		&features
	};

	return createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, physicalDevice, &deviceParams, DE_NULL);
}

deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
{
	const vector<VkQueueFamilyProperties>	queueProps	= getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);

	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
	{
		if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
			return (deUint32)queueNdx;
	}

	TCU_THROW(NotSupportedError, "No matching queue found");
}

vector<Vertex4RGBA> createQuads (deUint32 numQuads, float size)
{
	vector<Vertex4RGBA>	vertices;

	for (deUint32 quadNdx = 0; quadNdx < numQuads; quadNdx++)
	{
		const float			xOffset				= -0.5f + (float)quadNdx;
		const tcu::Vec4		color				(0.0f);
		const Vertex4RGBA	lowerLeftVertex		= {tcu::Vec4(-size + xOffset, -size, 0.0f, 1.0f), color};
		const Vertex4RGBA	lowerRightVertex	= {tcu::Vec4(size + xOffset, -size, 0.0f, 1.0f), color};
		const Vertex4RGBA	UpperLeftVertex		= {tcu::Vec4(-size + xOffset, size, 0.0f, 1.0f), color};
		const Vertex4RGBA	UpperRightVertex	= {tcu::Vec4(size + xOffset, 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;
}

vector<Vertex4Tex4> createTexQuads (deUint32 numQuads, float size)
{
	vector<Vertex4Tex4>	vertices;

	for (deUint32 quadNdx = 0; quadNdx < numQuads; quadNdx++)
	{
		const float			xOffset				= -0.5f + (float)quadNdx;
		const Vertex4Tex4	lowerLeftVertex		= {tcu::Vec4(-size + xOffset, -size, 0.0f, 1.0f), tcu::Vec4(-0.2f, -0.2f, 0.0f, 0.0f)};
		const Vertex4Tex4	lowerRightVertex	= {tcu::Vec4(size + xOffset, -size, 0.0f, 1.0f), tcu::Vec4(1.2f, -0.2f, 0.0f, 0.0f)};
		const Vertex4Tex4	UpperLeftVertex		= {tcu::Vec4(-size + xOffset, size, 0.0f, 1.0f), tcu::Vec4(-0.2f, 1.2f, 0.0f, 0.0f)};
		const Vertex4Tex4	UpperRightVertex	= {tcu::Vec4(size + xOffset, size, 0.0f, 1.0f), tcu::Vec4(1.2f, 1.2f, 0.0f, 0.0f)};

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

static const tcu::Vec4 defaultTestColors[] =

{
	tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
	tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)
};

class PushDescriptorBufferGraphicsTestInstance : public vkt::TestInstance
{
public:
								PushDescriptorBufferGraphicsTestInstance	(Context& context, const TestParams& params);
	virtual						~PushDescriptorBufferGraphicsTestInstance	(void);
	void						init										(void);
	virtual tcu::TestStatus		iterate										(void);
	tcu::TestStatus				verifyImage									(void);

private:
	const TestParams			m_params;
	const PlatformInterface&	m_vkp;
	const Extensions			m_instanceExtensions;
	const CustomInstance		m_instance;
	const InstanceDriver&		m_vki;
	const VkPhysicalDevice		m_physicalDevice;
	const deUint32				m_queueFamilyIndex;
	const Extensions			m_deviceExtensions;
	const Unique<VkDevice>		m_device;
	const DeviceDriver			m_vkd;
	const VkQueue				m_queue;
	SimpleAllocator				m_allocator;
	const tcu::UVec2			m_renderSize;
	const VkFormat				m_colorFormat;
	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<VkBuffer>				m_vertexBuffer;
	de::MovePtr<Allocation>		m_vertexBufferAlloc;
	vector<VkBufferSp>			m_buffers;
	vector<AllocationSp>		m_bufferAllocs;
	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
	Move<VkPipelineLayout>		m_pipelineLayout;
	Move<VkPipeline>			m_graphicsPipelines;
	Move<VkCommandPool>			m_cmdPool;
	Move<VkCommandBuffer>		m_cmdBuffer;
	vector<Vertex4RGBA>			m_vertices;
};

PushDescriptorBufferGraphicsTestInstance::PushDescriptorBufferGraphicsTestInstance (Context& context, const TestParams& params)
	: vkt::TestInstance		(context)
	, m_params				(params)
	, m_vkp					(context.getPlatformInterface())
	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
	, m_vki					(m_instance.getDriver())
	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex))
	, m_vkd					(m_vkp, m_instance, *m_device)
	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
	, m_renderSize			(32, 32)
	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
	, m_vertices			(createQuads(params.numCalls, 0.25f))
{
}

void PushDescriptorBufferGraphicsTestInstance::init (void)
{
	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;
			&m_queueFamilyIndex,													// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout			initialLayout;
		};

		m_colorImage			= createImage(m_vkd, *m_device, &colorImageParams);

		// Allocate and bind color image memory
		m_colorImageAlloc		= m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
		VK_CHECK(m_vkd.bindImageMemory(*m_device, *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(m_vkd, *m_device, &colorAttachmentViewParams);
	}

	// Create render pass
	m_renderPass = makeRenderPass(m_vkd, *m_device, m_colorFormat);

	// Create framebuffer
	{
		const VkImageView				attachmentBindInfos[]	=
		{
			*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(m_vkd, *m_device, &framebufferParams);
	}

	// Create pipeline layout
	{
		// Create descriptor set layout
		const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
		{
			m_params.binding,					// uint32_t				binding;
			m_params.descriptorType,			// VkDescriptorType		descriptorType;
			1u,									// uint32_t				descriptorCount;
			VK_SHADER_STAGE_VERTEX_BIT,			// 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;
			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
			1u,															// uint32_t								bindingCount;
			&descriptorSetLayoutBinding									// const VkDescriptorSetLayoutBinding*	pBindings;
		};

		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);

		// 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;
			0u,												// deUint32						pushConstantRangeCount;
			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
		};

		m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
	}

	// Create buffers. One color value in each buffer.
	{
		for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
		{
			const VkBufferUsageFlags	usageFlags			= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;

			const VkBufferCreateInfo	bufferCreateInfo	=
			{
				VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
				DE_NULL,								// const void*			pNext;
				0u,										// VkBufferCreateFlags	flags
				16u,									// VkDeviceSize			size;
				usageFlags,								// VkBufferUsageFlags	usage;
				VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
				1u,										// deUint32				queueFamilyCount;
				&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
			};

			m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
			m_bufferAllocs.push_back(AllocationSp(m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]), MemoryRequirement::HostVisible).release()));
			VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(), m_bufferAllocs[bufIdx]->getOffset()));

			deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &defaultTestColors[bufIdx], 16u);
			flushAlloc(m_vkd, *m_device, *m_bufferAllocs[bufIdx]);
		}
	}

	// Create shaders
	{
		m_vertexShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
		m_fragmentShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
	}

	// 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							= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;

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

		m_graphicsPipelines = makeGraphicsPipeline(m_vkd,						// const DeviceInterface&						vk
												   *m_device,					// const VkDevice								device
												   *m_pipelineLayout,			// 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
	{
		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;
			&m_queueFamilyIndex											// const deUint32*		pQueueFamilyIndices;
		};

		m_vertexBuffer		= createBuffer(m_vkd, *m_device, &vertexBufferParams);
		m_vertexBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *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(m_vkd, *m_device, *m_vertexBufferAlloc);
	}

	// Create command pool
	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);

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

		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
		beginRenderPass(m_vkd, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);
		m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
		m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);

		// Draw quads. Switch input buffer which contains the quad color for each draw call.
		for (deUint32 quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
		{
			VkDescriptorBufferInfo descriptorBufferInfo =
			{
				**m_buffers[quadNdx],	// VkBuffer			buffer;
				0u,						// VkDeviceSize		offset;
				16u						// VkDeviceSize		range;
			};

			VkWriteDescriptorSet writeDescriptorSet =
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
				DE_NULL,								// const void*						pNext;
				0u,										// VkDescriptorSet					dstSet;
				m_params.binding,						// uint32_t							dstBinding;
				0u,										// uint32_t							dstArrayElement;
				1u,										// uint32_t							descriptorCount;
				m_params.descriptorType,				// VkDescriptorType					descriptorType;
				DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
				&descriptorBufferInfo,					// const VkDescriptorBufferInfo*	pBufferInfo;
				DE_NULL									// const VkBufferView*				pTexelBufferView;
			};

			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &writeDescriptorSet);
			m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
		}

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

PushDescriptorBufferGraphicsTestInstance::~PushDescriptorBufferGraphicsTestInstance (void)
{
}

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

	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());

	return verifyImage();
}

tcu::TestStatus PushDescriptorBufferGraphicsTestInstance::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
	{
		for (deUint32 quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
			for (deUint32 vertexIdx = 0; vertexIdx < 6; vertexIdx++)
				m_vertices[quadIdx * 6 + vertexIdx].color.xyzw() = defaultTestColors[quadIdx];

		refRenderer.draw(rr::RenderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits),
						 rr::PRIMITIVETYPE_TRIANGLES, m_vertices);
	}

	// Compare result with reference image
	{
		de::MovePtr<tcu::TextureLevel> result = readColorAttachment(m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_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 PushDescriptorBufferGraphicsTest : public vkt::TestCase
{
public:
						PushDescriptorBufferGraphicsTest	(tcu::TestContext&	testContext,
															 const string&		name,
															 const string&		description,
															 const TestParams&	params);
						~PushDescriptorBufferGraphicsTest	(void);
	void				initPrograms						(SourceCollections& sourceCollections) const;
	TestInstance*		createInstance						(Context& context) const;

protected:
	const TestParams	m_params;
};

PushDescriptorBufferGraphicsTest::PushDescriptorBufferGraphicsTest (tcu::TestContext&	testContext,
																	const string&		name,
																	const string&		description,
																	const TestParams&	params)
	: vkt::TestCase	(testContext, name, description)
	, m_params		(params)
{
}

PushDescriptorBufferGraphicsTest::~PushDescriptorBufferGraphicsTest (void)
{
}

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

void PushDescriptorBufferGraphicsTest::initPrograms (SourceCollections& sourceCollections) const
{
	const string	bufferType	= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? "uniform" : "readonly buffer";
	const string	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"
		"layout(set = 0, binding = " + de::toString(m_params.binding) + ") " + bufferType + " Block\n"
		"{\n"
		"	vec4 color;\n"
		"} inputData;\n"
		"\n"
		"out gl_PerVertex { vec4 gl_Position; };\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_Position = position;\n"
		"	vtxColor = inputData.color;\n"
		"}\n";

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

	sourceCollections.glslSources.add("vert") << glu::VertexSource(vertexSrc);
	sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
}

class PushDescriptorBufferComputeTestInstance : public vkt::TestInstance
{
public:
								PushDescriptorBufferComputeTestInstance		(Context& context, const TestParams& params);
	virtual						~PushDescriptorBufferComputeTestInstance	(void);
	void						init										(void);
	virtual tcu::TestStatus		iterate										(void);
	tcu::TestStatus				verifyOutput								(void);

private:
	const TestParams			m_params;
	const PlatformInterface&	m_vkp;
	const Extensions			m_instanceExtensions;
	const CustomInstance		m_instance;
	const InstanceDriver&		m_vki;
	const VkPhysicalDevice		m_physicalDevice;
	const deUint32				m_queueFamilyIndex;
	const Extensions			m_deviceExtensions;
	const Unique<VkDevice>		m_device;
	const DeviceDriver			m_vkd;
	const VkQueue				m_queue;
	SimpleAllocator				m_allocator;
	Move<VkShaderModule>		m_computeShaderModule;
	vector<VkBufferSp>			m_buffers;
	vector<AllocationSp>		m_bufferAllocs;
	Move<VkBuffer>				m_outputBuffer;
	de::MovePtr<Allocation>		m_outputBufferAlloc;
	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
	Move<VkPipelineLayout>		m_pipelineLayout;
	Move<VkPipeline>			m_computePipeline;
	Move<VkCommandPool>			m_cmdPool;
	Move<VkCommandBuffer>		m_cmdBuffer;
	std::vector<tcu::Vec4>		m_testColors;
};

PushDescriptorBufferComputeTestInstance::PushDescriptorBufferComputeTestInstance (Context& context, const TestParams& params)
	: vkt::TestInstance		(context)
	, m_params				(params)
	, m_vkp					(context.getPlatformInterface())
	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
	, m_vki					(m_instance.getDriver())
	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_COMPUTE_BIT))
	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex))
	, m_vkd					(m_vkp, m_instance, *m_device)
	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
{
}

void PushDescriptorBufferComputeTestInstance::init (void)
{
	// Create pipeline layout
	{
		// Create descriptor set layout
		const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindings[]	=
		{
			{
				m_params.binding,				// uint32_t				binding;
				m_params.descriptorType,		// VkDescriptorType		descriptorType;
				1u,								// uint32_t				descriptorCount;
				VK_SHADER_STAGE_COMPUTE_BIT,	// VkShaderStageFlags	stageFlags;
				DE_NULL							// const VkSampler*		pImmutableSamplers;
			},
			{
				m_params.binding + 1,				// uint32_t				binding;
				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,	// VkDescriptorType		descriptorType;
				1u,									// uint32_t				descriptorCount;
				VK_SHADER_STAGE_COMPUTE_BIT,		// 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;
			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
			2u,															// uint32_t								bindingCount;
			descriptorSetLayoutBindings									// const VkDescriptorSetLayoutBinding*	pBindings;
		};

		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);

		// 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;
			0u,												// deUint32						pushConstantRangeCount;
			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
		};

		m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
	}

	// Fill the test colors table
	m_testColors.resize(m_params.numCalls);
	for (deUint32 colorIdx = 0; colorIdx < m_params.numCalls; colorIdx++)
	{
		if (colorIdx < DE_LENGTH_OF_ARRAY(defaultTestColors))
			m_testColors[colorIdx] = defaultTestColors[colorIdx];
		else
		{
			const float mix = static_cast<float>(colorIdx) / static_cast<float>(m_params.numCalls - 1);

			// interpolate between first and last color, require these colors to be different
			DE_ASSERT(defaultTestColors[0] != defaultTestColors[DE_LENGTH_OF_ARRAY(defaultTestColors) - 1]);
			m_testColors[colorIdx] = defaultTestColors[0] * mix + defaultTestColors[DE_LENGTH_OF_ARRAY(defaultTestColors) - 1] * (1.0f - mix);
		}
	}

	// Create buffers. One color value in each buffer.
	{
		for (deUint32 bufIdx = 0; bufIdx <  m_params.numCalls; bufIdx++)
		{
			const VkBufferUsageFlags	usageFlags			= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;

			const VkBufferCreateInfo	bufferCreateInfo	=
			{
				VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
				DE_NULL,								// const void*			pNext;
				0u,										// VkBufferCreateFlags	flags
				16u,									// VkDeviceSize			size;
				usageFlags,								// VkBufferUsageFlags	usage;
				VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
				1u,										// deUint32				queueFamilyCount;
				&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
			};

			m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
			m_bufferAllocs.push_back(AllocationSp(m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]), MemoryRequirement::HostVisible).release()));
			VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(), m_bufferAllocs[bufIdx]->getOffset()));

			deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &m_testColors[bufIdx], 16u);
			flushAlloc(m_vkd, *m_device, *m_bufferAllocs[bufIdx]);
		}
	}

	// Create output buffer
	{
		const VkBufferCreateInfo bufferCreateInfo =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			0u,										// VkBufferCreateFlags	flags
			16u * m_params.numCalls,				// VkDeviceSize			size;
			VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,		// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
		};

		m_outputBuffer		= createBuffer(m_vkd, *m_device, &bufferCreateInfo);
		m_outputBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_outputBuffer), MemoryRequirement::HostVisible);
		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_outputBuffer, m_outputBufferAlloc->getMemory(), m_outputBufferAlloc->getOffset()));
	}

	// Create shader
	{
		m_computeShaderModule = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("compute"), 0u);
	}

	// Create pipeline
	{
		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_computePipeline = createComputePipeline(m_vkd, *m_device, (vk::VkPipelineCache)0u, &createInfo);
	}

	// Create command pool
	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);

	// Create command buffer
	{
		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
		m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);

		// Dispatch: Each dispatch switches the input buffer.
		// Output buffer is exposed as a vec4 sized window.
		for (deUint32 dispatchNdx = 0; dispatchNdx < m_params.numCalls; dispatchNdx++)
		{
			VkDescriptorBufferInfo descriptorBufferInfoUbo		=
			{
				**m_buffers[dispatchNdx],	// VkBuffer			buffer;
				0u,							// VkDeviceSize		offset;
				16u							// VkDeviceSize		range;
			};

			VkDescriptorBufferInfo descriptorBufferInfoOutput	=
			{
				*m_outputBuffer,	// VkBuffer			buffer;
				16u * dispatchNdx,	// VkDeviceSize		offset;
				16u					// VkDeviceSize		range;
			};

			VkWriteDescriptorSet writeDescriptorSets[] =
			{
				{
					VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
					DE_NULL,								// const void*						pNext;
					0u,										// VkDescriptorSet					dstSet;
					m_params.binding,						// uint32_t							dstBinding;
					0u,										// uint32_t							dstArrayElement;
					1u,										// uint32_t							descriptorCount;
					m_params.descriptorType,				// VkDescriptorType					descriptorType;
					DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
					&descriptorBufferInfoUbo,				// const VkDescriptorBufferInfo*	pBufferInfo;
					DE_NULL									// const VkBufferView*				pTexelBufferView;
				},
				{
					VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
					DE_NULL,								// const void*						pNext;
					0u,										// VkDescriptorSet					dstSet;
					m_params.binding + 1,					// uint32_t							dstBinding;
					0u,										// uint32_t							dstArrayElement;
					1u,										// uint32_t							descriptorCount;
					VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,		// VkDescriptorType					descriptorType;
					DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
					&descriptorBufferInfoOutput,			// const VkDescriptorBufferInfo*	pBufferInfo;
					DE_NULL									// const VkBufferView*				pTexelBufferView;
				}
			};

			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 2, writeDescriptorSets);
			m_vkd.cmdDispatch(*m_cmdBuffer, 1, 1, 1);
		}

		endCommandBuffer(m_vkd, *m_cmdBuffer);
	}
}

PushDescriptorBufferComputeTestInstance::~PushDescriptorBufferComputeTestInstance (void)
{
}

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

	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());

	return verifyOutput();
}

tcu::TestStatus PushDescriptorBufferComputeTestInstance::verifyOutput (void)
{
	invalidateAlloc(m_vkd, *m_device, *m_outputBufferAlloc);

	// Verify result
	if (deMemCmp((void*)&m_testColors[0], m_outputBufferAlloc->getHostPtr(), (size_t)(16u * m_params.numCalls)))
	{
		return tcu::TestStatus::fail("Output mismatch");
	}
	return tcu::TestStatus::pass("Output matches expected values");
}

class PushDescriptorBufferComputeTest : public vkt::TestCase
{
public:
						PushDescriptorBufferComputeTest		(tcu::TestContext&	testContext,
															 const string&		name,
															 const string&		description,
															 const TestParams&	params);
						~PushDescriptorBufferComputeTest	(void);
	void				initPrograms						(SourceCollections& sourceCollections) const;
	TestInstance*		createInstance						(Context& context) const;

protected:
	const TestParams	m_params;
};

PushDescriptorBufferComputeTest::PushDescriptorBufferComputeTest (tcu::TestContext&	testContext,
																  const string&		name,
																  const string&		description,
																  const TestParams&	params)
	: vkt::TestCase	(testContext, name, description)
	, m_params		(params)
{
}

PushDescriptorBufferComputeTest::~PushDescriptorBufferComputeTest (void)
{
}

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

void PushDescriptorBufferComputeTest::initPrograms (SourceCollections& sourceCollections) const
{
	const string	bufferType	= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? "uniform" : "buffer";
	const string	computeSrc	=
		"#version 450\n"
		"layout(set = 0, binding = " + de::toString(m_params.binding) + ") " + bufferType + " Block\n"
		"{\n"
		"	vec4 color;\n"
		"} inputData;\n"
		"\n"
		"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
		"{\n"
		"	vec4 color;\n"
		"} outData;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	outData.color = inputData.color;\n"
		"}\n";

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

class PushDescriptorImageGraphicsTestInstance : public vkt::TestInstance
{
public:
								PushDescriptorImageGraphicsTestInstance		(Context& context, const TestParams& params);
	virtual						~PushDescriptorImageGraphicsTestInstance	(void);
	void						init										(void);
	virtual tcu::TestStatus		iterate										(void);
	tcu::TestStatus				verifyImage									(void);

private:
	const TestParams				m_params;
	const PlatformInterface&		m_vkp;
	const Extensions				m_instanceExtensions;
	const CustomInstance			m_instance;
	const InstanceDriver&			m_vki;
	const VkPhysicalDevice			m_physicalDevice;
	const deUint32					m_queueFamilyIndex;
	const Extensions				m_deviceExtensions;
	const Unique<VkDevice>			m_device;
	const DeviceDriver				m_vkd;
	const VkQueue					m_queue;
	SimpleAllocator					m_allocator;
	const tcu::UVec2				m_renderSize;
	const tcu::UVec2				m_textureSize;
	const VkFormat					m_colorFormat;
	Move<VkImage>					m_colorImage;
	de::MovePtr<Allocation>			m_colorImageAlloc;
	Move<VkImageView>				m_colorAttachmentView;
	vector<VkImageSp>				m_textureImages;
	vector<AllocationSp>			m_textureImageAllocs;
	vector<VkImageViewSp>			m_textureViews;
	Move<VkSampler>					m_whiteBorderSampler;
	Move<VkSampler>					m_blackBorderSampler;
	Move<VkRenderPass>				m_renderPass;
	Move<VkFramebuffer>				m_framebuffer;
	Move<VkShaderModule>			m_vertexShaderModule;
	Move<VkShaderModule>			m_fragmentShaderModule;
	Move<VkBuffer>					m_vertexBuffer;
	de::MovePtr<Allocation>			m_vertexBufferAlloc;
	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
	Move<VkPipelineLayout>			m_pipelineLayout;
	Move<VkPipeline>				m_graphicsPipelines;
	Move<VkCommandPool>				m_cmdPool;
	Move<VkCommandBuffer>			m_cmdBuffer;
	vector<Vertex4Tex4>				m_vertices;
};

PushDescriptorImageGraphicsTestInstance::PushDescriptorImageGraphicsTestInstance (Context& context, const TestParams& params)
	: vkt::TestInstance		(context)
	, m_params				(params)
	, m_vkp					(context.getPlatformInterface())
	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
	, m_vki					(m_instance.getDriver())
	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex))
	, m_vkd					(m_vkp, m_instance, *m_device)
	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
	, m_renderSize			(32, 32)
	, m_textureSize			(32, 32)
	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
	, m_vertices			(createTexQuads(params.numCalls, 0.25f))
{
}

void PushDescriptorImageGraphicsTestInstance::init (void)
{
	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;
			&m_queueFamilyIndex,													// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED												// VkImageLayout			initialLayout;
		};

		m_colorImage			= createImage(m_vkd, *m_device, &colorImageParams);

		// Allocate and bind color image memory
		m_colorImageAlloc		= m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
		VK_CHECK(m_vkd.bindImageMemory(*m_device, *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(m_vkd, *m_device, &colorAttachmentViewParams);
	}

	// Create texture images
	for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
	{
		VkImageUsageFlags			usageFlags			= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
		if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
			usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
		if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
			usageFlags |= VK_IMAGE_USAGE_STORAGE_BIT;

		const VkImageCreateInfo		textureImageParams	=
		{
			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_textureSize.x(), m_textureSize.y(), 1u },	// VkExtent3D				extent;
			1u,												// deUint32					mipLevels;
			1u,												// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
			usageFlags,										// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
			1u,												// deUint32					queueFamilyIndexCount;
			&m_queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED						// VkImageLayout			initialLayout;
		};

		m_textureImages.push_back(VkImageSp(new Unique<VkImage>(createImage(m_vkd, *m_device, &textureImageParams))));

		// Allocate and bind texture image memory
		m_textureImageAllocs.push_back(AllocationSp(m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, **m_textureImages.back()), MemoryRequirement::Any).release()));
		VK_CHECK(m_vkd.bindImageMemory(*m_device, **m_textureImages.back(), m_textureImageAllocs.back()->getMemory(), m_textureImageAllocs.back()->getOffset()));
	}

	// Create texture image views
	for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
	{
		const VkImageViewCreateInfo textureViewParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
			DE_NULL,										// const void*				pNext;
			0u,												// VkImageViewCreateFlags	flags;
			**m_textureImages[texIdx],						// 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_textureViews.push_back(VkImageViewSp(new Unique<VkImageView>(createImageView(m_vkd, *m_device, &textureViewParams))));
	}

	VkClearValue	clearValues[2];
	clearValues[0].color.float32[0] = 0.0f;
	clearValues[0].color.float32[1] = 1.0f;
	clearValues[0].color.float32[2] = 0.0f;
	clearValues[0].color.float32[3] = 1.0f;
	clearValues[1].color.float32[0] = 1.0f;
	clearValues[1].color.float32[1] = 0.0f;
	clearValues[1].color.float32[2] = 0.0f;
	clearValues[1].color.float32[3] = 1.0f;

	const VkImageLayout	textureImageLayout	= (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ?
											  VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;

	// Clear textures
	for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
	{
		const VkImageAspectFlags	aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
		Move<VkCommandPool>			cmdPool;
		Move<VkCommandBuffer>		cmdBuffer;

		cmdPool		= createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
		cmdBuffer	= allocateCommandBuffer(m_vkd, *m_device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

		const VkImageMemoryBarrier preImageBarrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
			DE_NULL,								// const void*				pNext;
			0u,										// VkAccessFlags			srcAccessMask;
			VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
			**m_textureImages[texIdx],				// VkImage					image;
			{										// VkImageSubresourceRange	subresourceRange;
				aspectMask,							// VkImageAspect			aspect;
				0u,									// deUint32					baseMipLevel;
				1u,									// deUint32					mipLevels;
				0u,									// deUint32					baseArraySlice;
				1u									// deUint32					arraySize;
			}
		};

		const VkImageMemoryBarrier	postImageBarrier	=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
			VK_ACCESS_SHADER_READ_BIT,					// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
			textureImageLayout,							// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
			**m_textureImages[texIdx],					// VkImage					image;
			{											// VkImageSubresourceRange	subresourceRange;
				aspectMask,								// VkImageAspect			aspect;
				0u,										// deUint32					baseMipLevel;
				1u,										// deUint32					mipLevels;
				0u,										// deUint32					baseArraySlice;
				1u										// deUint32					arraySize;
			}
		};

		const VkImageSubresourceRange clearRange	=
		{
			aspectMask,	// VkImageAspectFlags	aspectMask;
			0u,			// deUint32				baseMipLevel;
			1u,			// deUint32				levelCount;
			0u,			// deUint32				baseArrayLayer;
			1u			// deUint32				layerCount;
		};

		beginCommandBuffer(m_vkd, *cmdBuffer);
		m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
		m_vkd.cmdClearColorImage(*cmdBuffer, **m_textureImages[texIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValues[texIdx].color, 1, &clearRange);
		m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
		endCommandBuffer(m_vkd, *cmdBuffer);

		submitCommandsAndWait(m_vkd, *m_device, m_queue, cmdBuffer.get());
	}

	// Create samplers: one with white and one with black border color to have a visible effect on switching the sampler
	{
		VkSamplerCreateInfo samplerParams =
		{
			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkSamplerCreateFlags	flags;
			VK_FILTER_NEAREST,							// VkFilter				magFilter;
			VK_FILTER_NEAREST,							// VkFilter				minFilter;
			VK_SAMPLER_MIPMAP_MODE_NEAREST,				// VkSamplerMipmapMode	mipmapMode;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,	// VkSamplerAddressMode	addressModeU;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,	// VkSamplerAddressMode	addressModeV;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,	// VkSamplerAddressMode	addressModeW;
			0.0f,										// float				mipLodBias;
			VK_FALSE,									// VkBool32				anisotropyEnable;
			0.0f,										// float				maxAnisotropy;
			VK_FALSE,									// VkBool32				compareEnable;
			VK_COMPARE_OP_NEVER,						// VkCompareOp			compareOp;
			0.0f,										// float				minLod;
			0.0f,										// float				maxLod;
			VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,			// VkBorderColor		borderColor;
			VK_FALSE									// VkBool32				unnormalizedCoordinates;
		};

		m_whiteBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
		samplerParams.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
		m_blackBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
	}

	// Create render pass
	{
		const VkAttachmentDescription	attachmentDescription	=
		{
			(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags	flags
			VK_FORMAT_R8G8B8A8_UNORM,					// VkFormat						format
			VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits		samples
			VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp			loadOp
			VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp			storeOp
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp			stencilLoadOp
			VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp			stencilStoreOp
			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout				initialLayout
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout				finalLayout
		};

		const VkAttachmentReference		resultAttachmentRef		=
		{
			0u,											// deUint32			attachment
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
		};

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

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

		m_renderPass = createRenderPass(m_vkd, *m_device, &renderPassInfo);
	}

	// Create framebuffer
	{
		const VkImageView				attachmentBindInfos[]	=
		{
			*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(m_vkd, *m_device, &framebufferParams);
	}

	// Create pipeline layout
	{
		// Create descriptor set layout
		vector<VkDescriptorSetLayoutBinding>	layoutBindings;

		switch(m_params.descriptorType)
		{
			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
				{
					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
					{
						m_params.binding,							// uint32_t				binding;
						VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	// VkDescriptorType		descriptorType;
						1u,											// uint32_t				descriptorCount;
						VK_SHADER_STAGE_FRAGMENT_BIT,				// VkShaderStageFlags	stageFlags;
						DE_NULL										// const VkSampler*		pImmutableSamplers;
					};
					layoutBindings.push_back(descriptorSetLayoutBinding);
				}
				break;

			case VK_DESCRIPTOR_TYPE_SAMPLER:
				{
					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingSampler	=
					{
						m_params.binding,				// uint32_t				binding;
						VK_DESCRIPTOR_TYPE_SAMPLER,		// VkDescriptorType		descriptorType;
						1u,								// uint32_t				descriptorCount;
						VK_SHADER_STAGE_FRAGMENT_BIT,	// VkShaderStageFlags	stageFlags;
						DE_NULL							// const VkSampler*		pImmutableSamplers;
					};
					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingTex	=
					{
						m_params.binding + 1,				// uint32_t				binding;
						VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,	// VkDescriptorType		descriptorType;
						1u,									// uint32_t				descriptorCount;
						VK_SHADER_STAGE_FRAGMENT_BIT,		// VkShaderStageFlags	stageFlags;
						DE_NULL								// const VkSampler*		pImmutableSamplers;
					};
					layoutBindings.push_back(descriptorSetLayoutBindingSampler);
					layoutBindings.push_back(descriptorSetLayoutBindingTex);
				}
				break;

			case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
				{
					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingSampler	=
					{
						m_params.binding + 1,			// uint32_t				binding;
						VK_DESCRIPTOR_TYPE_SAMPLER,		// VkDescriptorType		descriptorType;
						1u,								// uint32_t				descriptorCount;
						VK_SHADER_STAGE_FRAGMENT_BIT,	// VkShaderStageFlags	stageFlags;
						DE_NULL							// const VkSampler*		pImmutableSamplers;
					};
					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingTex	=
					{
						m_params.binding,					// uint32_t				binding;
						VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,	// VkDescriptorType		descriptorType;
						1u,									// uint32_t				descriptorCount;
						VK_SHADER_STAGE_FRAGMENT_BIT,		// VkShaderStageFlags	stageFlags;
						DE_NULL								// const VkSampler*		pImmutableSamplers;
					};
					layoutBindings.push_back(descriptorSetLayoutBindingSampler);
					layoutBindings.push_back(descriptorSetLayoutBindingTex);
				}
				break;

			case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
				{
					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
					{
						m_params.binding,					// uint32_t				binding;
						VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,	// VkDescriptorType		descriptorType;
						1u,									// uint32_t				descriptorCount;
						VK_SHADER_STAGE_FRAGMENT_BIT,		// VkShaderStageFlags	stageFlags;
						DE_NULL								// const VkSampler*		pImmutableSamplers;
					};
					layoutBindings.push_back(descriptorSetLayoutBinding);
				}
				break;

			default:
				DE_FATAL("unexpected descriptor type");
				break;
		};

		const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType;
			DE_NULL,													// const void*							pNext;
			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
			(deUint32)layoutBindings.size(),							// uint32_t								bindingCount;
			layoutBindings.data()										// const VkDescriptorSetLayoutBinding*	pBindings;
		};

		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);

		// 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;
			0u,												// deUint32						pushConstantRangeCount;
			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
		};

		m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
	}

	// Create shaders
	{
		m_vertexShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
		m_fragmentShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
	}

	// Create pipeline
	{
		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
		{
			0u,							// deUint32					binding;
			sizeof(Vertex4Tex4),		// 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(Vertex4Tex4, texCoord),	// 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 vector<VkViewport>					viewports							(1, makeViewport(m_renderSize));
		const vector<VkRect2D>						scissors							(1, makeRect2D(m_renderSize));

		m_graphicsPipelines = makeGraphicsPipeline(m_vkd,						// const DeviceInterface&						vk
												   *m_device,					// const VkDevice								device
												   *m_pipelineLayout,			// 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
	{
		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;
			&m_queueFamilyIndex											// const deUint32*		pQueueFamilyIndices;
		};

		m_vertexBuffer		= createBuffer(m_vkd, *m_device, &vertexBufferParams);
		m_vertexBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));

		// Load vertices into vertex buffer
		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4Tex4));
		flushAlloc(m_vkd, *m_device, *m_vertexBufferAlloc);
	}

	// Create command pool
	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);

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

		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
		beginRenderPass(m_vkd, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);
		m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
		m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);

		// Draw quads. Switch sampler or image view depending on the test.
		vector<VkSampler>	samplers;
		vector<VkImageView> imageViews;

		samplers.push_back(*m_whiteBorderSampler);
		if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
		{
			// Vary sampler between draws
			samplers.push_back(*m_blackBorderSampler);
		}
		else
		{
			// Usa a single sampler
			samplers.push_back(*m_whiteBorderSampler);
		}

		imageViews.push_back(**m_textureViews[0]);
		if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
		{
			// Vary image view between draws
			imageViews.push_back(**m_textureViews[1]);
		}
		else
		{
			// Usa a single image view
			imageViews.push_back(**m_textureViews[0]);
		}

		for (deUint32 quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
		{
			VkDescriptorImageInfo	descriptorImageInfo	=
			{
				samplers[quadNdx],							// VkSampler		sampler;
				imageViews[quadNdx],						// VkImageView		imageView;
				textureImageLayout							// VkImageLayout	imageLayout;
			};

			VkWriteDescriptorSet	writeDescriptorSet	=
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
				DE_NULL,								// const void*						pNext;
				0u,										// VkDescriptorSet					dstSet;
				m_params.binding,						// uint32_t							dstBinding;
				0u,										// uint32_t							dstArrayElement;
				1u,										// uint32_t							descriptorCount;
				m_params.descriptorType,				// VkDescriptorType					descriptorType;
				&descriptorImageInfo,					// const VkDescriptorImageInfo*		pImageInfo;
				DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo;
				DE_NULL									// const VkBufferView*				pTexelBufferView;
			};

			vector<VkWriteDescriptorSet> writeDescriptorSets;
			writeDescriptorSets.push_back(writeDescriptorSet);

			if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
			{
				// Sampler also needs an image.
				writeDescriptorSet.dstBinding++;
				writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
				writeDescriptorSets.push_back(writeDescriptorSet);
			}
			else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
			{
				// Image also needs a sampler.
				writeDescriptorSet.dstBinding++;
				writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
				writeDescriptorSets.push_back(writeDescriptorSet);
			}

			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, (deUint32)writeDescriptorSets.size(), writeDescriptorSets.data());
			m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
		}

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

PushDescriptorImageGraphicsTestInstance::~PushDescriptorImageGraphicsTestInstance (void)
{
}

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

	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());

	return verifyImage();
}

tcu::TestStatus PushDescriptorImageGraphicsTestInstance::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
	{
		vector<Vertex4RGBA>	refQuadsOuter	= createQuads(m_params.numCalls, 0.25f);
		vector<Vertex4RGBA>	refQuadsInner	= createQuads(m_params.numCalls, 0.25f * 0.8f);
		tcu::Vec4			outerColor[2];
		tcu::Vec4			innerColor[2];
		const bool			hasBorder		= m_params.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;

		if (hasBorder)
		{
			outerColor[0] = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
			innerColor[0] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
			if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
				outerColor[1] = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
			else
				outerColor[1] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
			if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
				innerColor[1] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
			else
				innerColor[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
		}
		else
		{
			outerColor[0] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
			outerColor[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
		}

		for (deUint32 quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
			for (deUint32 vertexIdx = 0; vertexIdx < 6; vertexIdx++)
			{
				const deUint32 idx = quadIdx * 6 + vertexIdx;
				refQuadsOuter[idx].color.xyzw() = outerColor[quadIdx];
				refQuadsInner[idx].color.xyzw() = innerColor[quadIdx];
			}

		if (hasBorder)
			refQuadsOuter.insert(refQuadsOuter.end(), refQuadsInner.begin(), refQuadsInner.end());

		refRenderer.draw(rr::RenderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits),
						 rr::PRIMITIVETYPE_TRIANGLES, refQuadsOuter);
	}

	// Compare result with reference image
	{
		de::MovePtr<tcu::TextureLevel> result = readColorAttachment(m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_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 PushDescriptorImageGraphicsTest : public vkt::TestCase
{
public:
						PushDescriptorImageGraphicsTest		(tcu::TestContext&	testContext,
															 const string&		name,
															 const string&		description,
															 const TestParams&	params);
						~PushDescriptorImageGraphicsTest	(void);
	void				initPrograms						(SourceCollections& sourceCollections) const;
	TestInstance*		createInstance						(Context& context) const;

protected:
	const TestParams	m_params;
};

PushDescriptorImageGraphicsTest::PushDescriptorImageGraphicsTest	(tcu::TestContext&	testContext,
																	const string&		name,
																	const string&		description,
																	const TestParams&	params)
	: vkt::TestCase	(testContext, name, description)
	, m_params		(params)
{
}

PushDescriptorImageGraphicsTest::~PushDescriptorImageGraphicsTest (void)
{
}

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

void PushDescriptorImageGraphicsTest::initPrograms (SourceCollections& sourceCollections) const
{
	const string	vertexSrc	=
		"#version 450\n"
		"layout(location = 0) in highp vec4 position;\n"
		"layout(location = 1) in highp vec4 texcoordVtx;\n"
		"layout(location = 0) out highp vec2 texcoordFrag;\n"
		"\n"
		"out gl_PerVertex { vec4 gl_Position; };\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_Position = position;\n"
		"	texcoordFrag = texcoordVtx.xy;\n"
		"}\n";

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

	if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
	{
		const string	fragmentSrc	=
			"#version 450\n"
			"layout(location = 0) in highp vec2 texcoordFrag;\n"
			"layout(location = 0) out highp vec4 fragColor;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform sampler2D combinedSampler;\n"
			"\n"
			"void main (void)\n"
			"{\n"
			"	fragColor = texture(combinedSampler, texcoordFrag);\n"
			"}\n";

		sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
	}
	else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
	{
		const string	fragmentSrc	=
			"#version 450\n"
			"layout(location = 0) in highp vec2 texcoordFrag;\n"
			"layout(location = 0) out highp vec4 fragColor;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform sampler texSampler;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") uniform texture2D texImage;\n"
			"\n"
			"void main (void)\n"
			"{\n"
			"	fragColor = texture(sampler2D(texImage, texSampler), texcoordFrag);\n"
			"}\n";

		sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
	}
	else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
	{
		const string	fragmentSrc	=
			"#version 450\n"
			"layout(location = 0) in highp vec2 texcoordFrag;\n"
			"layout(location = 0) out highp vec4 fragColor;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") uniform sampler texSampler;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform texture2D texImage;\n"
			"\n"
			"void main (void)\n"
			"{\n"
			"	fragColor = texture(sampler2D(texImage, texSampler), texcoordFrag);\n"
			"}\n";

		sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
	}
	else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
	{
		const string	fragmentSrc	=
			"#version 450\n"
			"layout(location = 0) in highp vec2 texcoordFrag;\n"
			"layout(location = 0) out highp vec4 fragColor;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding) + ", rgba8) uniform readonly image2D storageImage;\n"
			"\n"
			"void main (void)\n"
			"{\n"
			"	fragColor = imageLoad(storageImage, ivec2(0));\n"
			"}\n";

		sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
	}
	else
	{
		DE_FATAL("Unexpected descriptor type");
	}
}

class PushDescriptorImageComputeTestInstance : public vkt::TestInstance
{
public:
								PushDescriptorImageComputeTestInstance	(Context& context, const TestParams& params);
	virtual						~PushDescriptorImageComputeTestInstance	(void);
	void						init									(void);
	virtual tcu::TestStatus		iterate									(void);
	tcu::TestStatus				verifyOutput							(void);

private:
	const TestParams			m_params;
	const PlatformInterface&	m_vkp;
	const Extensions			m_instanceExtensions;
	const CustomInstance		m_instance;
	const InstanceDriver&		m_vki;
	const VkPhysicalDevice		m_physicalDevice;
	const deUint32				m_queueFamilyIndex;
	const Extensions			m_deviceExtensions;
	const Unique<VkDevice>		m_device;
	const DeviceDriver			m_vkd;
	const VkQueue				m_queue;
	SimpleAllocator				m_allocator;
	const tcu::UVec2			m_textureSize;
	const VkFormat				m_colorFormat;
	Move<VkShaderModule>		m_computeShaderModule;
	vector<VkImageSp>			m_textureImages;
	vector<AllocationSp>		m_textureImageAllocs;
	vector<VkImageViewSp>		m_textureViews;
	Move<VkSampler>				m_whiteBorderSampler;
	Move<VkSampler>				m_blackBorderSampler;
	Move<VkBuffer>				m_outputBuffer;
	de::MovePtr<Allocation>		m_outputBufferAlloc;
	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
	Move<VkPipelineLayout>		m_pipelineLayout;
	Move<VkPipeline>			m_computePipeline;
	Move<VkCommandPool>			m_cmdPool;
	Move<VkCommandBuffer>		m_cmdBuffer;
	deUint32					m_outputBufferBinding;
};

PushDescriptorImageComputeTestInstance::PushDescriptorImageComputeTestInstance (Context& context, const TestParams& params)
	: vkt::TestInstance		(context)
	, m_params				(params)
	, m_vkp					(context.getPlatformInterface())
	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
	, m_vki					(m_instance.getDriver())
	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT))
	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex))
	, m_vkd					(m_vkp, m_instance, *m_device)
	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
	, m_textureSize			(32, 32)
	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
	, m_outputBufferBinding	(0)
{
}

void PushDescriptorImageComputeTestInstance::init (void)
{
	const VkComponentMapping		componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };

	// Create texture images
	for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
	{
		VkImageUsageFlags			usageFlags			= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
		if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
			usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
		if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
			usageFlags |= VK_IMAGE_USAGE_STORAGE_BIT;

		const VkImageCreateInfo		textureImageParams	=
		{
			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_textureSize.x(), m_textureSize.y(), 1u },	// VkExtent3D				extent;
			1u,												// deUint32					mipLevels;
			1u,												// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
			usageFlags,										// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
			1u,												// deUint32					queueFamilyIndexCount;
			&m_queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED						// VkImageLayout			initialLayout;
		};

		m_textureImages.push_back(VkImageSp(new Unique<VkImage>(createImage(m_vkd, *m_device, &textureImageParams))));

		// Allocate and bind texture image memory
		m_textureImageAllocs.push_back(AllocationSp(m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, **m_textureImages.back()), MemoryRequirement::Any).release()));
		VK_CHECK(m_vkd.bindImageMemory(*m_device, **m_textureImages.back(), m_textureImageAllocs.back()->getMemory(), m_textureImageAllocs.back()->getOffset()));
	}

	// Create texture image views
	for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
	{
		const VkImageViewCreateInfo textureViewParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
			DE_NULL,										// const void*				pNext;
			0u,												// VkImageViewCreateFlags	flags;
			**m_textureImages[texIdx],						// 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_textureViews.push_back(VkImageViewSp(new Unique<VkImageView>(createImageView(m_vkd, *m_device, &textureViewParams))));
	}

	VkClearValue	clearValues[2];
	clearValues[0].color.float32[0] = 0.0f;
	clearValues[0].color.float32[1] = 1.0f;
	clearValues[0].color.float32[2] = 0.0f;
	clearValues[0].color.float32[3] = 1.0f;
	clearValues[1].color.float32[0] = 1.0f;
	clearValues[1].color.float32[1] = 0.0f;
	clearValues[1].color.float32[2] = 0.0f;
	clearValues[1].color.float32[3] = 1.0f;

	const VkImageLayout	textureImageLayout = (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ?
											  VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;

	// Clear textures
	for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
	{
		const VkImageAspectFlags		aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
		Move<VkCommandPool>				cmdPool;
		Move<VkCommandBuffer>			cmdBuffer;

		cmdPool		= createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
		cmdBuffer	= allocateCommandBuffer(m_vkd, *m_device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

		const VkImageMemoryBarrier preImageBarrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
			DE_NULL,								// const void*				pNext;
			0u,										// VkAccessFlags			srcAccessMask;
			VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
			**m_textureImages[texIdx],				// VkImage					image;
			{										// VkImageSubresourceRange	subresourceRange;
				aspectMask,							// VkImageAspect			aspect;
				0u,									// deUint32					baseMipLevel;
				1u,									// deUint32					mipLevels;
				0u,									// deUint32					baseArraySlice;
				1u									// deUint32					arraySize;
			}
		};

		const VkImageMemoryBarrier postImageBarrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
			VK_ACCESS_SHADER_READ_BIT,					// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
			textureImageLayout,							// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
			**m_textureImages[texIdx],					// VkImage					image;
			{											// VkImageSubresourceRange	subresourceRange;
				aspectMask,								// VkImageAspect			aspect;
				0u,										// deUint32					baseMipLevel;
				1u,										// deUint32					mipLevels;
				0u,										// deUint32					baseArraySlice;
				1u										// deUint32					arraySize;
			}
		};

		const VkImageSubresourceRange clearRange	=
		{
			aspectMask,	// VkImageAspectFlags	aspectMask;
			0u,			// deUint32				baseMipLevel;
			1u,			// deUint32				levelCount;
			0u,			// deUint32				baseArrayLayer;
			1u			// deUint32				layerCount;
		};

		beginCommandBuffer(m_vkd, *cmdBuffer);
		m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
		m_vkd.cmdClearColorImage(*cmdBuffer, **m_textureImages[texIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValues[texIdx].color, 1, &clearRange);
		m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
		endCommandBuffer(m_vkd, *cmdBuffer);

		submitCommandsAndWait(m_vkd, *m_device, m_queue, cmdBuffer.get());
	}

	// Create samplers: one with white and one with black border color to have a visible effect on switching the sampler
	{
		VkSamplerCreateInfo samplerParams =
		{
			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkSamplerCreateFlags	flags;
			VK_FILTER_NEAREST,							// VkFilter				magFilter;
			VK_FILTER_NEAREST,							// VkFilter				minFilter;
			VK_SAMPLER_MIPMAP_MODE_NEAREST,				// VkSamplerMipmapMode	mipmapMode;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,	// VkSamplerAddressMode	addressModeU;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,	// VkSamplerAddressMode	addressModeV;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,	// VkSamplerAddressMode	addressModeW;
			0.0f,										// float				mipLodBias;
			VK_FALSE,									// VkBool32				anisotropyEnable;
			0.0f,										// float				maxAnisotropy;
			VK_FALSE,									// VkBool32				compareEnable;
			VK_COMPARE_OP_NEVER,						// VkCompareOp			compareOp;
			0.0f,										// float				minLod;
			0.0f,										// float				maxLod;
			VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,			// VkBorderColor		borderColor;
			VK_FALSE									// VkBool32				unnormalizedCoordinates;
		};

		m_whiteBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
		samplerParams.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
		m_blackBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
	}

	// Create pipeline layout
	{
		// Create descriptor set layout
		vector<VkDescriptorSetLayoutBinding>	layoutBindings;

		switch(m_params.descriptorType)
		{
			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
				{
					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
					{
						m_params.binding,							// uint32_t				binding;
						VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	// VkDescriptorType		descriptorType;
						1u,											// uint32_t				descriptorCount;
						VK_SHADER_STAGE_COMPUTE_BIT,				// VkShaderStageFlags	stageFlags;
						DE_NULL										// const VkSampler*		pImmutableSamplers;
					};
					layoutBindings.push_back(descriptorSetLayoutBinding);
					m_outputBufferBinding = m_params.binding + 1;
				}
				break;

			case VK_DESCRIPTOR_TYPE_SAMPLER:
				{
					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingSampler	=
					{
						m_params.binding,				// uint32_t				binding;
						VK_DESCRIPTOR_TYPE_SAMPLER,		// VkDescriptorType		descriptorType;
						1u,								// uint32_t				descriptorCount;
						VK_SHADER_STAGE_COMPUTE_BIT,	// VkShaderStageFlags	stageFlags;
						DE_NULL							// const VkSampler*		pImmutableSamplers;
					};
					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingTex	=
					{
						m_params.binding + 1,				// uint32_t				binding;
						VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,	// VkDescriptorType		descriptorType;
						1u,									// uint32_t				descriptorCount;
						VK_SHADER_STAGE_COMPUTE_BIT,		// VkShaderStageFlags	stageFlags;
						DE_NULL								// const VkSampler*		pImmutableSamplers;
					};
					layoutBindings.push_back(descriptorSetLayoutBindingSampler);
					layoutBindings.push_back(descriptorSetLayoutBindingTex);
					m_outputBufferBinding = m_params.binding + 2;
				}
				break;

			case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
				{
					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingSampler	=
					{
						m_params.binding + 1,			// uint32_t				binding;
						VK_DESCRIPTOR_TYPE_SAMPLER,		// VkDescriptorType		descriptorType;
						1u,								// uint32_t				descriptorCount;
						VK_SHADER_STAGE_COMPUTE_BIT,	// VkShaderStageFlags	stageFlags;
						DE_NULL							// const VkSampler*		pImmutableSamplers;
					};
					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingTex	=
					{
						m_params.binding,					// uint32_t				binding;
						VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,	// VkDescriptorType		descriptorType;
						1u,									// uint32_t				descriptorCount;
						VK_SHADER_STAGE_COMPUTE_BIT,		// VkShaderStageFlags	stageFlags;
						DE_NULL								// const VkSampler*		pImmutableSamplers;
					};
					layoutBindings.push_back(descriptorSetLayoutBindingSampler);
					layoutBindings.push_back(descriptorSetLayoutBindingTex);
					m_outputBufferBinding = m_params.binding + 2;
				}
				break;

			case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
				{
					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
					{
						m_params.binding,					// uint32_t				binding;
						VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,	// VkDescriptorType		descriptorType;
						1u,									// uint32_t				descriptorCount;
						VK_SHADER_STAGE_COMPUTE_BIT,		// VkShaderStageFlags	stageFlags;
						DE_NULL								// const VkSampler*		pImmutableSamplers;
					};
					layoutBindings.push_back(descriptorSetLayoutBinding);
					m_outputBufferBinding = m_params.binding + 1;
				}
				break;

			default:
				DE_FATAL("unexpected descriptor type");
				break;
		};

		const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingOutputBuffer	=
		{
			m_outputBufferBinding,				// uint32_t				binding;
			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,	// VkDescriptorType		descriptorType;
			1u,									// uint32_t				descriptorCount;
			VK_SHADER_STAGE_COMPUTE_BIT,		// VkShaderStageFlags	stageFlags;
			DE_NULL								// const VkSampler*		pImmutableSamplers;
		};

		layoutBindings.push_back(descriptorSetLayoutBindingOutputBuffer);

		const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType;
			DE_NULL,													// const void*							pNext;
			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
			(deUint32)layoutBindings.size(),							// uint32_t								bindingCount;
			layoutBindings.data()										// const VkDescriptorSetLayoutBinding*	pBindings;
		};

		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);

		// 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;
			0u,												// deUint32						pushConstantRangeCount;
			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
		};

		m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
	}

	// Create output buffer
	{
		const VkBufferCreateInfo bufferCreateInfo =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			0u,										// VkBufferCreateFlags	flags
			64u,									// VkDeviceSize			size;
			VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,		// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
		};

		m_outputBuffer		= createBuffer(m_vkd, *m_device, &bufferCreateInfo);
		m_outputBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_outputBuffer), MemoryRequirement::HostVisible);
		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_outputBuffer, m_outputBufferAlloc->getMemory(), m_outputBufferAlloc->getOffset()));
	}

	// Create shader
	{
		m_computeShaderModule = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("compute"), 0u);
	}

	// Create pipeline
	{
		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_computePipeline = createComputePipeline(m_vkd, *m_device, (vk::VkPipelineCache)0u, &createInfo);
	}

	// Create command pool
	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);

	// Create command buffer
	{
		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
		m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);

		// Dispatch: Each dispatch switches the input image.
		// Output buffer is exposed as a 2 x vec4 sized window.
		for (deUint32 dispatchNdx = 0; dispatchNdx < m_params.numCalls; dispatchNdx++)
		{
			vector<VkSampler>	samplers;
			vector<VkImageView> imageViews;

			samplers.push_back(*m_whiteBorderSampler);
			if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
			{
				// Vary sampler between draws
				samplers.push_back(*m_blackBorderSampler);
			}
			else
			{
				// Usa a single sampler
				samplers.push_back(*m_whiteBorderSampler);
			}

			imageViews.push_back(**m_textureViews[0]);
			if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
			{
				// Vary image view between draws
				imageViews.push_back(**m_textureViews[1]);
			}
			else
			{
				// Usa a single image view
				imageViews.push_back(**m_textureViews[0]);
			}

			const VkDescriptorImageInfo	descriptorImageInfo	=
			{
				samplers[dispatchNdx],					// VkSampler		sampler;
				imageViews[dispatchNdx],				// VkImageView		imageView;
				textureImageLayout						// VkImageLayout	imageLayout;
			};

			VkWriteDescriptorSet	writeDescriptorSet		=
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
				DE_NULL,								// const void*						pNext;
				0u,										// VkDescriptorSet					dstSet;
				m_params.binding,						// uint32_t							dstBinding;
				0u,										// uint32_t							dstArrayElement;
				1u,										// uint32_t							descriptorCount;
				m_params.descriptorType,				// VkDescriptorType					descriptorType;
				&descriptorImageInfo,					// const VkDescriptorImageInfo*		pImageInfo;
				DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo;
				DE_NULL									// const VkBufferView*				pTexelBufferView;
			};

			vector<VkWriteDescriptorSet> writeDescriptorSets;
			writeDescriptorSets.push_back(writeDescriptorSet);

			if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
			{
				// Sampler also needs an image.
				writeDescriptorSet.dstBinding++;
				writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
				writeDescriptorSets.push_back(writeDescriptorSet);
			}
			else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
			{
				// Image also needs a sampler.
				writeDescriptorSet.dstBinding++;
				writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
				writeDescriptorSets.push_back(writeDescriptorSet);
			}

			const VkDescriptorBufferInfo descriptorBufferInfoOutput	=
			{
				*m_outputBuffer,	// VkBuffer		buffer;
				32u * dispatchNdx,	// VkDeviceSize	offset;
				32u					// VkDeviceSize	range;
			};

			// Write output buffer descriptor set
			const VkWriteDescriptorSet	writeDescriptorSetOutput	=
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
				DE_NULL,								// const void*						pNext;
				0u,										// VkDescriptorSet					dstSet;
				m_outputBufferBinding,					// uint32_t							dstBinding;
				0u,										// uint32_t							dstArrayElement;
				1u,										// uint32_t							descriptorCount;
				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,		// VkDescriptorType					descriptorType;
				DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
				&descriptorBufferInfoOutput,			// const VkDescriptorBufferInfo*	pBufferInfo;
				DE_NULL									// const VkBufferView*				pTexelBufferView;
			};

			writeDescriptorSets.push_back(writeDescriptorSetOutput);

			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, (deUint32)writeDescriptorSets.size(), writeDescriptorSets.data());
			m_vkd.cmdDispatch(*m_cmdBuffer, 1, 1, 1);
		}

		endCommandBuffer(m_vkd, *m_cmdBuffer);
	}
}

PushDescriptorImageComputeTestInstance::~PushDescriptorImageComputeTestInstance (void)
{
}

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

	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());

	return verifyOutput();
}

tcu::TestStatus PushDescriptorImageComputeTestInstance::verifyOutput (void)
{
	float ref[16];
	invalidateAlloc(m_vkd, *m_device, *m_outputBufferAlloc);

	switch(m_params.descriptorType)
	{
		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
			// Dispatch 1: inner & outer = green
			ref[0] = ref[4] = 0.0f;
			ref[1] = ref[5] = 1.0f;
			ref[2] = ref[6] = 0.0f;
			ref[3] = ref[7] = 1.0f;

			// Dispatch 2: inner & outer = red
			ref[8] = ref[12] = 1.0f;
			ref[9] = ref[13] = 0.0f;
			ref[10] = ref[14] = 0.0f;
			ref[11] = ref[15] = 1.0f;
			break;

		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
			// Dispatch 1: inner = green, outer = white
			ref[0] = 0.0f;
			ref[1] = 1.0f;
			ref[2] = 0.0f;
			ref[3] = 1.0f;

			ref[4] = 1.0f;
			ref[5] = 1.0f;
			ref[6] = 1.0f;
			ref[7] = 1.0f;

			// Dispatch 2: inner = red, outer = black
			ref[8] = 1.0f;
			ref[9] = 0.0f;
			ref[10] = 0.0f;
			ref[11] = 1.0f;

			ref[12] = 0.0f;
			ref[13] = 0.0f;
			ref[14] = 0.0f;
			ref[15] = 1.0f;
			break;

		case VK_DESCRIPTOR_TYPE_SAMPLER:
			// Dispatch 1: inner = green, outer = white
			ref[0] = 0.0f;
			ref[1] = 1.0f;
			ref[2] = 0.0f;
			ref[3] = 1.0f;

			ref[4] = 1.0f;
			ref[5] = 1.0f;
			ref[6] = 1.0f;
			ref[7] = 1.0f;

			// Dispatch 2: inner = green, outer = black
			ref[8] = 0.0f;
			ref[9] = 1.0f;
			ref[10] = 0.0f;
			ref[11] = 1.0f;

			ref[12] = 0.0f;
			ref[13] = 0.0f;
			ref[14] = 0.0f;
			ref[15] = 1.0f;
			break;

		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
			// Dispatch 1: inner = green, outer = white
			ref[0] = 0.0f;
			ref[1] = 1.0f;
			ref[2] = 0.0f;
			ref[3] = 1.0f;

			ref[4] = 1.0f;
			ref[5] = 1.0f;
			ref[6] = 1.0f;
			ref[7] = 1.0f;

			// Dispatch 2: inner = red, outer = white
			ref[8] = 1.0f;
			ref[9] = 0.0f;
			ref[10] = 0.0f;
			ref[11] = 1.0f;

			ref[12] = 1.0f;
			ref[13] = 1.0f;
			ref[14] = 1.0f;
			ref[15] = 1.0f;
			break;

		default:
			DE_FATAL("unexpected descriptor type");
			break;
	};

	// Verify result
	if (deMemCmp((void*)ref, m_outputBufferAlloc->getHostPtr(), (size_t)(32u * m_params.numCalls)))
	{
		const float* ptr = (float*)m_outputBufferAlloc->getHostPtr();
		std::string debugMsg = "Output buffer contents:\n";

		for (deUint32 i = 0; i < m_params.numCalls * 8; i++)
			debugMsg += de::toString(ptr[i]) + " vs " + de::toString(ref[i]) + "\n";

		m_context.getTestContext().getLog() << tcu::TestLog::Message << debugMsg << tcu::TestLog::EndMessage;
		return tcu::TestStatus::fail("Output mismatch");
	}
	return tcu::TestStatus::pass("Output matches expected values");
}

class PushDescriptorImageComputeTest : public vkt::TestCase
{
public:
						PushDescriptorImageComputeTest	(tcu::TestContext&	testContext,
														 const string&		name,
														 const string&		description,
														 const TestParams&	params);
						~PushDescriptorImageComputeTest	(void);
	void				initPrograms					(SourceCollections& sourceCollections) const;
	TestInstance*		createInstance					(Context& context) const;

protected:
	const TestParams	m_params;
};

PushDescriptorImageComputeTest::PushDescriptorImageComputeTest	(tcu::TestContext&	testContext,
																 const string&		name,
																 const string&		description,
																 const TestParams&	params)
	: vkt::TestCase	(testContext, name, description)
	, m_params		(params)
{
}

PushDescriptorImageComputeTest::~PushDescriptorImageComputeTest (void)
{
}

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

void PushDescriptorImageComputeTest::initPrograms (SourceCollections& sourceCollections) const
{
	if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
	{
		const string	computeSrc	=
			"#version 450\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform sampler2D combinedSampler;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
			"{\n"
			"	vec4 innerColor;\n"
			"	vec4 outerColor;\n"
			"} outData;\n"
			"\n"
			"void main()\n"
			"{\n"
			"	outData.innerColor = texture(combinedSampler, vec2(0.5));\n"
			"	outData.outerColor = texture(combinedSampler, vec2(-0.1));\n"
			"}\n";

		sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
	}
	else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
	{
		const string	computeSrc	=
			"#version 450\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform sampler texSampler;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") uniform texture2D texImage;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding + 2) + ") writeonly buffer Output\n"
			"{\n"
			"	vec4 innerColor;\n"
			"	vec4 outerColor;\n"
			"} outData;\n"
			"\n"
			"void main()\n"
			"{\n"
			"	outData.innerColor = texture(sampler2D(texImage, texSampler), vec2(0.5));\n"
			"	outData.outerColor = texture(sampler2D(texImage, texSampler), vec2(-0.1));\n"
			"}\n";

		sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
	}
	else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
	{
		const string	computeSrc	=
			"#version 450\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") uniform sampler texSampler;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform texture2D texImage;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding + 2) + ") writeonly buffer Output\n"
			"{\n"
			"	vec4 innerColor;\n"
			"	vec4 outerColor;\n"
			"} outData;\n"
			"\n"
			"void main()\n"
			"{\n"
			"	outData.innerColor = texture(sampler2D(texImage, texSampler), vec2(0.5));\n"
			"	outData.outerColor = texture(sampler2D(texImage, texSampler), vec2(-0.1));\n"
			"}\n";

		sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
	}
	else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
	{
		const string	computeSrc	=
			"#version 450\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding) + ", rgba8) uniform readonly image2D storageImage;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
			"{\n"
			"	vec4 innerColor;\n"
			"	vec4 outerColor;\n"
			"} outData;\n"
			"\n"
			"void main()\n"
			"{\n"
			"	outData.innerColor = imageLoad(storageImage, ivec2(0));\n"
			"	outData.outerColor = imageLoad(storageImage, ivec2(0));\n"
			"}\n";

		sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
	}
	else
	{
		DE_FATAL("Unexpected descriptor type");
	}
}

class PushDescriptorTexelBufferGraphicsTestInstance : public vkt::TestInstance
{
public:
								PushDescriptorTexelBufferGraphicsTestInstance	(Context& context, const TestParams& params);
	virtual						~PushDescriptorTexelBufferGraphicsTestInstance	(void);
	void						init											(void);
	virtual tcu::TestStatus		iterate											(void);
	tcu::TestStatus				verifyImage										(void);

private:
	const TestParams				m_params;
	const PlatformInterface&		m_vkp;
	const Extensions				m_instanceExtensions;
	const CustomInstance			m_instance;
	const InstanceDriver&			m_vki;
	const VkPhysicalDevice			m_physicalDevice;
	const deUint32					m_queueFamilyIndex;
	const Extensions				m_deviceExtensions;
	const Unique<VkDevice>			m_device;
	const DeviceDriver				m_vkd;
	const VkQueue					m_queue;
	SimpleAllocator					m_allocator;
	const tcu::UVec2				m_renderSize;
	const VkFormat					m_colorFormat;
	Move<VkImage>					m_colorImage;
	de::MovePtr<Allocation>			m_colorImageAlloc;
	Move<VkImageView>				m_colorAttachmentView;
	vector<VkBufferSp>				m_buffers;
	vector<AllocationSp>			m_bufferAllocs;
	vector<VkBufferViewSp>			m_bufferViews;
	const VkFormat					m_bufferFormat;
	Move<VkRenderPass>				m_renderPass;
	Move<VkFramebuffer>				m_framebuffer;
	Move<VkShaderModule>			m_vertexShaderModule;
	Move<VkShaderModule>			m_fragmentShaderModule;
	Move<VkBuffer>					m_vertexBuffer;
	de::MovePtr<Allocation>			m_vertexBufferAlloc;
	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
	Move<VkPipelineLayout>			m_pipelineLayout;
	Move<VkPipeline>				m_graphicsPipelines;
	Move<VkCommandPool>				m_cmdPool;
	Move<VkCommandBuffer>			m_cmdBuffer;
	vector<Vertex4RGBA>				m_vertices;
};

PushDescriptorTexelBufferGraphicsTestInstance::PushDescriptorTexelBufferGraphicsTestInstance (Context& context, const TestParams& params)
	: vkt::TestInstance		(context)
	, m_params				(params)
	, m_vkp					(context.getPlatformInterface())
	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
	, m_vki					(m_instance.getDriver())
	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex))
	, m_vkd					(m_vkp, m_instance, *m_device)
	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
	, m_renderSize			(32, 32)
	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
	, m_bufferFormat		(VK_FORMAT_R32G32B32A32_SFLOAT)
	, m_vertices			(createQuads(params.numCalls, 0.25f))
{
}

void PushDescriptorTexelBufferGraphicsTestInstance::init (void)
{
	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;
			&m_queueFamilyIndex,													// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED												// VkImageLayout			initialLayout;
		};

		m_colorImage			= createImage(m_vkd, *m_device, &colorImageParams);

		// Allocate and bind color image memory
		m_colorImageAlloc		= m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
		VK_CHECK(m_vkd.bindImageMemory(*m_device, *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(m_vkd, *m_device, &colorAttachmentViewParams);
	}

	// Create buffers
	for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
	{
		const VkBufferUsageFlags	usageFlags			= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ? VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;

		const VkBufferCreateInfo	bufferCreateInfo	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			0u,										// VkBufferCreateFlags	flags
			16u,									// VkDeviceSize			size;
			usageFlags,								// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
		};

		m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
		m_bufferAllocs.push_back(AllocationSp(m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]), MemoryRequirement::HostVisible).release()));
		VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(), m_bufferAllocs[bufIdx]->getOffset()));

		deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &defaultTestColors[bufIdx], 16u);
		flushAlloc(m_vkd, *m_device, *m_bufferAllocs[bufIdx]);
	}

	// Create buffer views
	for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
	{
		const VkBufferViewCreateInfo bufferViewParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,	// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			0u,											// VkBufferViewCreateFlags	flags;
			**m_buffers[bufIdx],						// VkBuffer					buffer;
			m_bufferFormat,								// VkFormat					format;
			0u,											// VkDeviceSize				offset;
			VK_WHOLE_SIZE								// VkDeviceSize				range;
		};

		m_bufferViews.push_back(VkBufferViewSp(new Unique<VkBufferView>(createBufferView(m_vkd, *m_device, &bufferViewParams))));
	}

	// Create render pass
	m_renderPass = makeRenderPass(m_vkd, *m_device, m_colorFormat);

	// Create framebuffer
	{
		const VkImageView				attachmentBindInfos[]	=
		{
			*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(m_vkd, *m_device, &framebufferParams);
	}

	// Create pipeline layout
	{
		const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
		{
			m_params.binding,				// uint32_t				binding;
			m_params.descriptorType,		// VkDescriptorType		descriptorType;
			1u,								// uint32_t				descriptorCount;
			VK_SHADER_STAGE_FRAGMENT_BIT,	// 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;
			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
			1u,															// uint32_t								bindingCount;
			&descriptorSetLayoutBinding									// const VkDescriptorSetLayoutBinding*	pBindings;
		};

		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);

		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;
			0u,												// deUint32						pushConstantRangeCount;
			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
		};

		m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
	}

	// Create shaders
	{
		m_vertexShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
		m_fragmentShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
	}

	// 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							= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;

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

		m_graphicsPipelines = makeGraphicsPipeline(m_vkd,						// const DeviceInterface&						vk
												   *m_device,					// const VkDevice								device
												   *m_pipelineLayout,			// 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
	{
		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;
			&m_queueFamilyIndex											// const deUint32*		pQueueFamilyIndices;
		};

		m_vertexBuffer		= createBuffer(m_vkd, *m_device, &vertexBufferParams);
		m_vertexBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *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(m_vkd, *m_device, *m_vertexBufferAlloc);
	}

	// Create command pool
	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);

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

		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
		beginRenderPass(m_vkd, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);
		m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
		m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);

		// Draw quads. Switch buffer view between draws.
		for (deUint32 quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
		{
			VkWriteDescriptorSet	writeDescriptorSet	=
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
				DE_NULL,								// const void*						pNext;
				0u,										// VkDescriptorSet					dstSet;
				m_params.binding,						// uint32_t							dstBinding;
				0u,										// uint32_t							dstArrayElement;
				1u,										// uint32_t							descriptorCount;
				m_params.descriptorType,				// VkDescriptorType					descriptorType;
				DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
				DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo;
				&m_bufferViews[quadNdx]->get()			// const VkBufferView*				pTexelBufferView;
			};

			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1u, &writeDescriptorSet);
			m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
		}

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

PushDescriptorTexelBufferGraphicsTestInstance::~PushDescriptorTexelBufferGraphicsTestInstance (void)
{
}

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

	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());

	return verifyImage();
}

tcu::TestStatus PushDescriptorTexelBufferGraphicsTestInstance::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
	{
		for (deUint32 quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
			for (deUint32 vertexIdx = 0; vertexIdx < 6; vertexIdx++)
				m_vertices[quadIdx * 6 + vertexIdx].color.xyzw() = defaultTestColors[quadIdx];

		refRenderer.draw(rr::RenderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits),
						 rr::PRIMITIVETYPE_TRIANGLES, m_vertices);
	}

	// Compare result with reference image
	{
		de::MovePtr<tcu::TextureLevel> result = readColorAttachment(m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_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 PushDescriptorTexelBufferGraphicsTest : public vkt::TestCase
{
public:
						PushDescriptorTexelBufferGraphicsTest	(tcu::TestContext&	testContext,
																 const string&		name,
																 const string&		description,
																 const TestParams&	params);
						~PushDescriptorTexelBufferGraphicsTest	(void);
	void				initPrograms						(SourceCollections& sourceCollections) const;
	TestInstance*		createInstance						(Context& context) const;

protected:
	const TestParams	m_params;
};

PushDescriptorTexelBufferGraphicsTest::PushDescriptorTexelBufferGraphicsTest	(tcu::TestContext&	testContext,
																				 const string&		name,
																				 const string&		description,
																				 const TestParams&	params)
	: vkt::TestCase	(testContext, name, description)
	, m_params		(params)
{
}

PushDescriptorTexelBufferGraphicsTest::~PushDescriptorTexelBufferGraphicsTest (void)
{
}

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

void PushDescriptorTexelBufferGraphicsTest::initPrograms (SourceCollections& sourceCollections) const
{
	const string	vertexSrc	=
		"#version 450\n"
		"layout(location = 0) in highp vec4 position;\n"
		"layout(location = 1) in highp vec4 texcoordVtx;\n"
		"layout(location = 0) out highp vec2 texcoordFrag;\n"
		"\n"
		"out gl_PerVertex { vec4 gl_Position; };\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_Position = position;\n"
		"	texcoordFrag = texcoordVtx.xy;\n"
		"}\n";

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

	if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
	{
		const string	fragmentSrc	=
			"#version 450\n"
			"layout(location = 0) in highp vec2 texcoordFrag;\n"
			"layout(location = 0) out highp vec4 fragColor;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform textureBuffer texelBuffer;\n"
			"\n"
			"void main (void)\n"
			"{\n"
			"	fragColor = texelFetch(texelBuffer, 0);\n"
			"}\n";

		sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
	}
	else
	{
		DE_ASSERT(m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
		const string	fragmentSrc	=
			"#version 450\n"
			"layout(location = 0) in highp vec2 texcoordFrag;\n"
			"layout(location = 0) out highp vec4 fragColor;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding) + ", rgba32f) uniform readonly imageBuffer texelBuffer;\n"
			"\n"
			"void main (void)\n"
			"{\n"
			"	fragColor = imageLoad(texelBuffer, 0);\n"
			"}\n";

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

class PushDescriptorTexelBufferComputeTestInstance : public vkt::TestInstance
{
public:
								PushDescriptorTexelBufferComputeTestInstance	(Context& context, const TestParams& params);
	virtual						~PushDescriptorTexelBufferComputeTestInstance	(void);
	void						init											(void);
	virtual tcu::TestStatus		iterate											(void);
	tcu::TestStatus				verifyOutput									(void);

private:
	const TestParams			m_params;
	const PlatformInterface&	m_vkp;
	const Extensions			m_instanceExtensions;
	const CustomInstance		m_instance;
	const InstanceDriver&		m_vki;
	const VkPhysicalDevice		m_physicalDevice;
	const deUint32				m_queueFamilyIndex;
	const Extensions			m_deviceExtensions;
	const Unique<VkDevice>		m_device;
	const DeviceDriver			m_vkd;
	const VkQueue				m_queue;
	SimpleAllocator				m_allocator;
	vector<VkBufferSp>			m_buffers;
	vector<AllocationSp>		m_bufferAllocs;
	vector<VkBufferViewSp>		m_bufferViews;
	const VkFormat				m_bufferFormat;
	Move<VkShaderModule>		m_computeShaderModule;
	Move<VkBuffer>				m_outputBuffer;
	de::MovePtr<Allocation>		m_outputBufferAlloc;
	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
	Move<VkPipelineLayout>		m_pipelineLayout;
	Move<VkPipeline>			m_computePipeline;
	Move<VkCommandPool>			m_cmdPool;
	Move<VkCommandBuffer>		m_cmdBuffer;
};

PushDescriptorTexelBufferComputeTestInstance::PushDescriptorTexelBufferComputeTestInstance (Context& context, const TestParams& params)
	: vkt::TestInstance		(context)
	, m_params				(params)
	, m_vkp					(context.getPlatformInterface())
	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
	, m_vki					(m_instance.getDriver())
	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_COMPUTE_BIT))
	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex))
	, m_vkd					(m_vkp, m_instance, *m_device)
	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
	, m_bufferFormat		(VK_FORMAT_R32G32B32A32_SFLOAT)
{
}

void PushDescriptorTexelBufferComputeTestInstance::init (void)
{
	// Create buffers
	for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
	{
		const VkBufferUsageFlags	usageFlags			= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ? VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;

		const VkBufferCreateInfo	bufferCreateInfo	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			0u,										// VkBufferCreateFlags	flags
			16u,									// VkDeviceSize			size;
			usageFlags,								// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
		};

		m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
		m_bufferAllocs.push_back(AllocationSp(m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]), MemoryRequirement::HostVisible).release()));
		VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(), m_bufferAllocs[bufIdx]->getOffset()));

		deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &defaultTestColors[bufIdx], 16u);
		flushAlloc(m_vkd, *m_device, *m_bufferAllocs[bufIdx]);
	}

	// Create buffer views
	for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
	{
		const VkBufferViewCreateInfo bufferViewParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,	// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			0u,											// VkBufferViewCreateFlags	flags;
			**m_buffers[bufIdx],						// VkBuffer					buffer;
			m_bufferFormat,								// VkFormat					format;
			0u,											// VkDeviceSize				offset;
			VK_WHOLE_SIZE								// VkDeviceSize				range;
		};

		m_bufferViews.push_back(VkBufferViewSp(new Unique<VkBufferView>(createBufferView(m_vkd, *m_device, &bufferViewParams))));
	}

	// Create pipeline layout
	{
		vector<VkDescriptorSetLayoutBinding>	layoutBindings;

		const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindings[]		=
		{
			{
				m_params.binding,				// uint32_t				binding;
				m_params.descriptorType,		// VkDescriptorType		descriptorType;
				1u,								// uint32_t				descriptorCount;
				VK_SHADER_STAGE_COMPUTE_BIT,	// VkShaderStageFlags	stageFlags;
				DE_NULL							// const VkSampler*		pImmutableSamplers;
			},
			{
				m_params.binding + 1,				// uint32_t				binding;
				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,	// VkDescriptorType		descriptorType;
				1u,									// uint32_t				descriptorCount;
				VK_SHADER_STAGE_COMPUTE_BIT,		// 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;
			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
			2u,															// uint32_t								bindingCount;
			descriptorSetLayoutBindings									// const VkDescriptorSetLayoutBinding*	pBindings;
		};

		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);

		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;
			0u,												// deUint32						pushConstantRangeCount;
			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
		};

		m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
	}

	// Create output buffer
	{
		const VkBufferCreateInfo bufferCreateInfo =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			0u,										// VkBufferCreateFlags	flags
			32u,									// VkDeviceSize			size;
			VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,		// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
		};

		m_outputBuffer		= createBuffer(m_vkd, *m_device, &bufferCreateInfo);
		m_outputBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_outputBuffer), MemoryRequirement::HostVisible);
		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_outputBuffer, m_outputBufferAlloc->getMemory(), m_outputBufferAlloc->getOffset()));
	}

	// Create shader
	{
		m_computeShaderModule = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("compute"), 0u);
	}

	// Create pipeline
	{
		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_computePipeline = createComputePipeline(m_vkd, *m_device, (vk::VkPipelineCache)0u, &createInfo);
	}

	// Create command pool
	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);

	// Create command buffer
	{
		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
		m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);

		// Dispatch: Each dispatch switches the input image.
		// Output buffer is exposed as a vec4 sized window.
		for (deUint32 dispatchNdx = 0; dispatchNdx < m_params.numCalls; dispatchNdx++)
		{
			VkWriteDescriptorSet	writeDescriptorSet	=
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
				DE_NULL,								// const void*						pNext;
				0u,										// VkDescriptorSet					dstSet;
				m_params.binding,						// uint32_t							dstBinding;
				0u,										// uint32_t							dstArrayElement;
				1u,										// uint32_t							descriptorCount;
				m_params.descriptorType,				// VkDescriptorType					descriptorType;
				DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
				DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo;
				&m_bufferViews[dispatchNdx]->get()		// const VkBufferView*				pTexelBufferView;
			};

			vector<VkWriteDescriptorSet> writeDescriptorSets;
			writeDescriptorSets.push_back(writeDescriptorSet);

			const VkDescriptorBufferInfo descriptorBufferInfoOutput	=
			{
				*m_outputBuffer,	// VkBuffer			buffer;
				16u * dispatchNdx,	// VkDeviceSize		offset;
				16u					// VkDeviceSize		range;
			};

			// Write output buffer descriptor set
			const VkWriteDescriptorSet	writeDescriptorSetOutput	=
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
				DE_NULL,								// const void*						pNext;
				0u,										// VkDescriptorSet					dstSet;
				m_params.binding + 1,					// uint32_t							dstBinding;
				0u,										// uint32_t							dstArrayElement;
				1u,										// uint32_t							descriptorCount;
				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,		// VkDescriptorType					descriptorType;
				DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
				&descriptorBufferInfoOutput,			// const VkDescriptorBufferInfo*	pBufferInfo;
				DE_NULL									// const VkBufferView*				pTexelBufferView;
			};

			writeDescriptorSets.push_back(writeDescriptorSetOutput);

			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, (deUint32)writeDescriptorSets.size(), writeDescriptorSets.data());
			m_vkd.cmdDispatch(*m_cmdBuffer, 1, 1, 1);
		}

		endCommandBuffer(m_vkd, *m_cmdBuffer);
	}
}

PushDescriptorTexelBufferComputeTestInstance::~PushDescriptorTexelBufferComputeTestInstance (void)
{
}

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

	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());

	return verifyOutput();
}

tcu::TestStatus PushDescriptorTexelBufferComputeTestInstance::verifyOutput (void)
{
	const float ref[8] = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f };
	invalidateAlloc(m_vkd, *m_device, *m_outputBufferAlloc);

	// Verify result
	if (deMemCmp((void*)ref, m_outputBufferAlloc->getHostPtr(), (size_t)(16u * m_params.numCalls)))
	{
		const float* ptr = (float*)m_outputBufferAlloc->getHostPtr();
		std::string debugMsg = "Output buffer contents:\n";

		for (deUint32 i = 0; i < m_params.numCalls * 4; i++)
			debugMsg += de::toString(ptr[i]) + " vs " + de::toString(ref[i]) + "\n";

		m_context.getTestContext().getLog() << tcu::TestLog::Message << debugMsg << tcu::TestLog::EndMessage;
		return tcu::TestStatus::fail("Output mismatch");
	}
	return tcu::TestStatus::pass("Output matches expected values");
}

class PushDescriptorTexelBufferComputeTest : public vkt::TestCase
{
public:
						PushDescriptorTexelBufferComputeTest	(tcu::TestContext&	testContext,
																 const string&		name,
																 const string&		description,
																 const TestParams&	params);
						~PushDescriptorTexelBufferComputeTest	(void);
	void				initPrograms							(SourceCollections& sourceCollections) const;
	TestInstance*		createInstance							(Context& context) const;

protected:
	const TestParams	m_params;
};

PushDescriptorTexelBufferComputeTest::PushDescriptorTexelBufferComputeTest	(tcu::TestContext&	testContext,
																			 const string&		name,
																			 const string&		description,
																			 const TestParams&	params)
	: vkt::TestCase	(testContext, name, description)
	, m_params		(params)
{
}

PushDescriptorTexelBufferComputeTest::~PushDescriptorTexelBufferComputeTest (void)
{
}

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

void PushDescriptorTexelBufferComputeTest::initPrograms (SourceCollections& sourceCollections) const
{
	if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
	{
		const string	computeSrc	=
			"#version 450\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform textureBuffer texelBuffer;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
			"{\n"
			"	vec4 color;\n"
			"} outData;\n"
			"\n"
			"void main()\n"
			"{\n"
			"	outData.color = texelFetch(texelBuffer, 0);\n"
			"}\n";

		sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
	}
	else
	{
		DE_ASSERT(m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);

		const string	computeSrc	=
			"#version 450\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding) + ", rgba32f) uniform readonly imageBuffer texelBuffer;\n"
			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
			"{\n"
			"	vec4 color;\n"
			"} outData;\n"
			"\n"
			"void main()\n"
			"{\n"
			"	outData.color = imageLoad(texelBuffer, 0);\n"
			"}\n";

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

class PushDescriptorInputAttachmentGraphicsTestInstance : public vkt::TestInstance
{
public:
								PushDescriptorInputAttachmentGraphicsTestInstance	(Context& context, const TestParams& params);
	virtual						~PushDescriptorInputAttachmentGraphicsTestInstance	(void);
	void						init												(void);
	virtual tcu::TestStatus		iterate												(void);
	tcu::TestStatus				verifyImage											(void);

private:
	const TestParams				m_params;
	const PlatformInterface&		m_vkp;
	const Extensions				m_instanceExtensions;
	const CustomInstance			m_instance;
	const InstanceDriver&			m_vki;
	const VkPhysicalDevice			m_physicalDevice;
	const deUint32					m_queueFamilyIndex;
	const Extensions				m_deviceExtensions;
	const Unique<VkDevice>			m_device;
	const DeviceDriver				m_vkd;
	const VkQueue					m_queue;
	SimpleAllocator					m_allocator;
	const tcu::UVec2				m_renderSize;
	const tcu::UVec2				m_textureSize;
	const VkFormat					m_colorFormat;
	Move<VkImage>					m_colorImage;
	de::MovePtr<Allocation>			m_colorImageAlloc;
	Move<VkImageView>				m_colorAttachmentView;
	vector<VkImageSp>				m_inputImages;
	vector<AllocationSp>			m_inputImageAllocs;
	vector<VkImageViewSp>			m_inputImageViews;
	vector<VkRenderPassSp>			m_renderPasses;
	vector<VkFramebufferSp>			m_framebuffers;
	Move<VkShaderModule>			m_vertexShaderModule;
	Move<VkShaderModule>			m_fragmentShaderModule;
	Move<VkBuffer>					m_vertexBuffer;
	de::MovePtr<Allocation>			m_vertexBufferAlloc;
	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
	Move<VkPipelineLayout>			m_pipelineLayout;
	vector<VkPipelineSp>			m_graphicsPipelines;
	Move<VkCommandPool>				m_cmdPool;
	Move<VkCommandBuffer>			m_cmdBuffer;
	vector<Vertex4Tex4>				m_vertices;
};

PushDescriptorInputAttachmentGraphicsTestInstance::PushDescriptorInputAttachmentGraphicsTestInstance (Context& context, const TestParams& params)
	: vkt::TestInstance		(context)
	, m_params				(params)
	, m_vkp					(context.getPlatformInterface())
	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
	, m_vki					(m_instance.getDriver())
	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex))
	, m_vkd					(m_vkp, m_instance, *m_device)
	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
	, m_renderSize			(32, 32)
	, m_textureSize			(32, 32)
	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
	, m_vertices			(createTexQuads(params.numCalls, 0.25f))
{
}

void PushDescriptorInputAttachmentGraphicsTestInstance::init (void)
{
	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;
			&m_queueFamilyIndex,													// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED												// VkImageLayout			initialLayout;
		};

		m_colorImage		= createImage(m_vkd, *m_device, &colorImageParams);

		// Allocate and bind color image memory
		m_colorImageAlloc	= m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
		VK_CHECK(m_vkd.bindImageMemory(*m_device, *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(m_vkd, *m_device, &colorAttachmentViewParams);
	}

	// Create input images
	for (deUint32 imageIdx = 0; imageIdx < 2; imageIdx++)
	{
		const VkImageUsageFlags		usageFlags			= VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;

		const VkImageCreateInfo		inputImageParams	=
		{
			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_textureSize.x(), m_textureSize.y(), 1u },	// VkExtent3D				extent;
			1u,												// deUint32					mipLevels;
			1u,												// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
			usageFlags,										// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
			1u,												// deUint32					queueFamilyIndexCount;
			&m_queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED						// VkImageLayout			initialLayout;
		};

		m_inputImages.push_back(VkImageSp(new Unique<VkImage>(createImage(m_vkd, *m_device, &inputImageParams))));

		// Allocate and bind image memory
		m_inputImageAllocs.push_back(AllocationSp(m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, **m_inputImages.back()), MemoryRequirement::Any).release()));
		VK_CHECK(m_vkd.bindImageMemory(*m_device, **m_inputImages.back(), m_inputImageAllocs.back()->getMemory(), m_inputImageAllocs.back()->getOffset()));
	}

	// Create texture image views
	for (deUint32 imageIdx = 0; imageIdx < 2; imageIdx++)
	{
		const VkImageViewCreateInfo textureViewParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
			DE_NULL,										// const void*				pNext;
			0u,												// VkImageViewCreateFlags	flags;
			**m_inputImages[imageIdx],						// 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_inputImageViews.push_back(VkImageViewSp(new Unique<VkImageView>(createImageView(m_vkd, *m_device, &textureViewParams))));
	}

	VkClearValue clearValues[2];
	clearValues[0].color.float32[0] = 0.0f;
	clearValues[0].color.float32[1] = 1.0f;
	clearValues[0].color.float32[2] = 0.0f;
	clearValues[0].color.float32[3] = 1.0f;
	clearValues[1].color.float32[0] = 1.0f;
	clearValues[1].color.float32[1] = 0.0f;
	clearValues[1].color.float32[2] = 0.0f;
	clearValues[1].color.float32[3] = 1.0f;

	// Clear input images
	for (deUint32 imageIdx = 0; imageIdx < 2; imageIdx++)
	{
		const VkImageAspectFlags	aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
		Move<VkCommandPool>			cmdPool;
		Move<VkCommandBuffer>		cmdBuffer;
		const VkAccessFlags			accessFlags	= VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;

		cmdPool		= createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
		cmdBuffer	= allocateCommandBuffer(m_vkd, *m_device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

		const VkImageMemoryBarrier preImageBarrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
			DE_NULL,								// const void*				pNext;
			0u,										// VkAccessFlags			srcAccessMask;
			VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
			**m_inputImages[imageIdx],				// VkImage					image;
			{										// VkImageSubresourceRange	subresourceRange;
				aspectMask,							// VkImageAspect			aspect;
				0u,									// deUint32					baseMipLevel;
				1u,									// deUint32					mipLevels;
				0u,									// deUint32					baseArraySlice;
				1u									// deUint32					arraySize;
			}
		};

		const VkImageMemoryBarrier postImageBarrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
			accessFlags,								// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,	// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
			**m_inputImages[imageIdx],					// VkImage					image;
			{											// VkImageSubresourceRange	subresourceRange;
				aspectMask,								// VkImageAspect			aspect;
				0u,										// deUint32					baseMipLevel;
				1u,										// deUint32					mipLevels;
				0u,										// deUint32					baseArraySlice;
				1u										// deUint32					arraySize;
			}
		};

		const VkImageSubresourceRange clearRange	=
		{
			aspectMask,	// VkImageAspectFlags	aspectMask;
			0u,			// deUint32				baseMipLevel;
			1u,			// deUint32				levelCount;
			0u,			// deUint32				baseArrayLayer;
			1u			// deUint32				layerCount;
		};

		beginCommandBuffer(m_vkd, *cmdBuffer);
		m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
		m_vkd.cmdClearColorImage(*cmdBuffer, **m_inputImages[imageIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValues[imageIdx].color, 1, &clearRange);
		m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
		endCommandBuffer(m_vkd, *cmdBuffer);

		submitCommandsAndWait(m_vkd, *m_device, m_queue, cmdBuffer.get());
	}

	// Create render passes
	for (deUint32 renderPassIdx = 0; renderPassIdx < 2; renderPassIdx++)
	{
		// The first pass clears the output image, and the second one draws on top of the first pass.
		const VkAttachmentLoadOp		loadOps[]					=
		{
			VK_ATTACHMENT_LOAD_OP_CLEAR,
			VK_ATTACHMENT_LOAD_OP_LOAD
		};

		const VkImageLayout				initialLayouts[]			=
		{
			VK_IMAGE_LAYOUT_UNDEFINED,
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
		};

		const VkAttachmentDescription	attachmentDescriptions[]	=
		{
			// Result attachment
			{
				(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags	flags
				VK_FORMAT_R8G8B8A8_UNORM,					// VkFormat						format
				VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits		samples
				loadOps[renderPassIdx],						// VkAttachmentLoadOp			loadOp
				VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp			storeOp
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp			stencilLoadOp
				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp			stencilStoreOp
				initialLayouts[renderPassIdx],				// VkImageLayout				initialLayout
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout				finalLayout
			},
			// Input attachment
			{
				(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags	flags
				VK_FORMAT_R8G8B8A8_UNORM,					// VkFormat						format
				VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits		samples
				VK_ATTACHMENT_LOAD_OP_LOAD,					// VkAttachmentLoadOp			loadOp
				VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp			storeOp
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp			stencilLoadOp
				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp			stencilStoreOp
				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,	// VkImageLayout				initialLayout
				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL	// VkImageLayout				finalLayout
			}
		};

		const VkAttachmentReference		resultAttachmentRef		=
		{
			0u,											// deUint32			attachment
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
		};

		const VkAttachmentReference		inputAttachmentRef		=
		{
			1u,											// deUint32			attachment
			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL	// VkImageLayout	layout
		};

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

		const VkSubpassDependency		subpassDependency		=
		{
			VK_SUBPASS_EXTERNAL,							// deUint32				srcSubpass
			0,												// deUint32				dstSubpass
			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,	// VkPipelineStageFlags	srcStageMask
			VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,			// VkPipelineStageFlags	dstStageMask
			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags		srcAccessMask
			VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT,	//	dstAccessMask
			VK_DEPENDENCY_BY_REGION_BIT						// VkDependencyFlags	dependencyFlags
		};

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

		m_renderPasses.push_back(VkRenderPassSp(new Unique<VkRenderPass>(createRenderPass(m_vkd, *m_device, &renderPassInfo))));
	}

	// Create framebuffers
	for (deUint32 framebufferIdx = 0; framebufferIdx < 2; framebufferIdx++)
	{
		const VkImageView				attachmentBindInfos[]	=
		{
			*m_colorAttachmentView,
			**m_inputImageViews[framebufferIdx],
		};

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

		m_framebuffers.push_back(VkFramebufferSp(new Unique<VkFramebuffer>(createFramebuffer(m_vkd, *m_device, &framebufferParams))));
	}

	// Create pipeline layout
	{
		// Create descriptor set layout
		const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
		{
			m_params.binding,						// uint32_t				binding;
			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	// VkDescriptorType		descriptorType;
			1u,										// uint32_t				descriptorCount;
			VK_SHADER_STAGE_FRAGMENT_BIT,			// 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;
			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
			1u,															// uint32_t								bindingCount;
			&descriptorSetLayoutBinding									// const VkDescriptorSetLayoutBinding*	pBindings;
		};

		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);

		// 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;
			0u,												// deUint32						pushConstantRangeCount;
			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
		};

		m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
	}

	// Create shaders
	{
		m_vertexShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
		m_fragmentShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
	}

	// Create pipelines
	for (deUint32 pipelineIdx = 0; pipelineIdx < 2; pipelineIdx++)
	{
		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
		{
			0u,							// deUint32					binding;
			sizeof(Vertex4Tex4),		// 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(Vertex4Tex4, texCoord),	// 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 vector<VkViewport>					viewports							(1, makeViewport(m_renderSize));
		const vector<VkRect2D>						scissors							(1, makeRect2D(m_renderSize));

		m_graphicsPipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(m_vkd,							// const DeviceInterface&						vk
																							   *m_device,						// const VkDevice								device
																							   *m_pipelineLayout,				// 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_renderPasses[pipelineIdx],	// 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
	{
		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;
			&m_queueFamilyIndex											// const deUint32*		pQueueFamilyIndices;
		};

		m_vertexBuffer		= createBuffer(m_vkd, *m_device, &vertexBufferParams);
		m_vertexBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));

		// Load vertices into vertex buffer
		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4Tex4));
		flushAlloc(m_vkd, *m_device, *m_vertexBufferAlloc);
	}

	// Create command pool
	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);

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

		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
		for (deUint32 quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
		{
			beginRenderPass(m_vkd, *m_cmdBuffer, **m_renderPasses[quadNdx], **m_framebuffers[quadNdx], makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);
			m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[quadNdx]);
			m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);

			VkDescriptorImageInfo	descriptorImageInfo	=
			{
				0,								// VkSampler		sampler;
				**m_inputImageViews[quadNdx],	// VkImageView		imageView;
				VK_IMAGE_LAYOUT_GENERAL			// VkImageLayout	imageLayout;
			};

			VkWriteDescriptorSet	writeDescriptorSet	=
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
				DE_NULL,								// const void*						pNext;
				0u,										// VkDescriptorSet					dstSet;
				m_params.binding,						// uint32_t							dstBinding;
				0u,										// uint32_t							dstArrayElement;
				1u,										// uint32_t							descriptorCount;
				m_params.descriptorType,				// VkDescriptorType					descriptorType;
				&descriptorImageInfo,					// const VkDescriptorImageInfo*		pImageInfo;
				DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo;
				DE_NULL									// const VkBufferView*				pTexelBufferView;
			};

			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &writeDescriptorSet);
			m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);

			endRenderPass(m_vkd, *m_cmdBuffer);
		}

		endCommandBuffer(m_vkd, *m_cmdBuffer);
	}
}

PushDescriptorInputAttachmentGraphicsTestInstance::~PushDescriptorInputAttachmentGraphicsTestInstance (void)
{
}

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

	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());

	return verifyImage();
}

tcu::TestStatus PushDescriptorInputAttachmentGraphicsTestInstance::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
	{
		vector<Vertex4RGBA>	refQuads = createQuads(m_params.numCalls, 0.25f);
		tcu::Vec4			colors[2];

		colors[0] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
		colors[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);

		for (deUint32 quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
			for (deUint32 vertexIdx = 0; vertexIdx < 6; vertexIdx++)
			{
				const deUint32 idx = quadIdx * 6 + vertexIdx;
				refQuads[idx].color.xyzw() = colors[quadIdx];
			}

		refRenderer.draw(rr::RenderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits),
						 rr::PRIMITIVETYPE_TRIANGLES, refQuads);
	}

	// Compare result with reference image
	{
		de::MovePtr<tcu::TextureLevel> result = readColorAttachment(m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_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 PushDescriptorInputAttachmentGraphicsTest : public vkt::TestCase
{
public:
						PushDescriptorInputAttachmentGraphicsTest		(tcu::TestContext&	testContext,
															 const string&		name,
															 const string&		description,
															 const TestParams&	params);
						~PushDescriptorInputAttachmentGraphicsTest	(void);
	void				initPrograms						(SourceCollections& sourceCollections) const;
	TestInstance*		createInstance						(Context& context) const;

protected:
	const TestParams	m_params;
};

PushDescriptorInputAttachmentGraphicsTest::PushDescriptorInputAttachmentGraphicsTest	(tcu::TestContext&	testContext,
																	const string&		name,
																	const string&		description,
																	const TestParams&	params)
	: vkt::TestCase	(testContext, name, description)
	, m_params		(params)
{
}

PushDescriptorInputAttachmentGraphicsTest::~PushDescriptorInputAttachmentGraphicsTest (void)
{
}

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

void PushDescriptorInputAttachmentGraphicsTest::initPrograms (SourceCollections& sourceCollections) const
{
	const string	vertexSrc	=
		"#version 450\n"
		"layout(location = 0) in highp vec4 position;\n"
		"layout(location = 1) in highp vec4 texcoordVtx;\n"
		"layout(location = 0) out highp vec2 texcoordFrag;\n"
		"\n"
		"out gl_PerVertex { vec4 gl_Position; };\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_Position = position;\n"
		"	texcoordFrag = texcoordVtx.xy;\n"
		"}\n";

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

	const string	fragmentSrc	=
		"#version 450\n"
		"layout(location = 0) in highp vec2 texcoordFrag;\n"
		"layout(location = 0) out highp vec4 fragColor;\n"
		"layout(input_attachment_index = 0, set = 0, binding = " + de::toString(m_params.binding) + ") uniform subpassInput inputColor;\n"
		"\n"
		"void main (void)\n"
		"{\n"
		"	fragColor = subpassLoad(inputColor);\n"
		"}\n";

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

} // anonymous

tcu::TestCaseGroup* createPushDescriptorTests (tcu::TestContext& testCtx)
{
	const TestParams params[] =
	{
		{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,			0u, 1u },
		{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,			0u, 2u },
		{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,			1u, 2u },
		{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,			3u, 2u },
		{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,			0u, 1u },
		{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,			0u, 2u },
		{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,			1u, 2u },
		{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,			3u, 2u },
		{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,			1u, 128u },
		{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	0u, 1u },
		{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	0u, 2u },
		{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	1u, 2u },
		{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	3u, 2u },
		{ VK_DESCRIPTOR_TYPE_SAMPLER,					0u, 1u },
		{ VK_DESCRIPTOR_TYPE_SAMPLER,					0u, 2u },
		{ VK_DESCRIPTOR_TYPE_SAMPLER,					1u, 2u },
		{ VK_DESCRIPTOR_TYPE_SAMPLER,					3u, 2u },
		{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,				0u, 1u },
		{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,				0u, 2u },
		{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,				1u, 2u },
		{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,				3u, 2u },
		{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,				0u, 1u },
		{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,				0u, 2u },
		{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,				1u, 2u },
		{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,				3u, 2u },
		{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,		0u, 1u },
		{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,		0u, 2u },
		{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,		1u, 2u },
		{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,		3u, 2u },
		{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,		0u, 1u },
		{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,		0u, 2u },
		{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,		1u, 2u },
		{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,		3u, 2u },
		{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			0u, 1u },
		{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			0u, 2u },
		{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			1u, 2u },
		{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			3u, 2u }
	};

	de::MovePtr<tcu::TestCaseGroup>	pushDescriptorTests	(new tcu::TestCaseGroup(testCtx, "push_descriptor", "Push descriptor tests"));

	de::MovePtr<tcu::TestCaseGroup>	graphicsTests		(new tcu::TestCaseGroup(testCtx, "graphics", "graphics pipeline"));
	de::MovePtr<tcu::TestCaseGroup>	computeTests		(new tcu::TestCaseGroup(testCtx, "compute", "compute pipeline"));

	for (deUint32 testIdx = 0; testIdx < DE_LENGTH_OF_ARRAY(params); testIdx++)
	{
		string testName;
		testName += "binding" + de::toString(params[testIdx].binding) + "_numcalls" + de::toString(params[testIdx].numCalls);
		switch(params[testIdx].descriptorType)
		{
			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
				testName += "_uniform_buffer";
				if (params[testIdx].numCalls <= 2)
					graphicsTests->addChild(new PushDescriptorBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
				computeTests->addChild(new PushDescriptorBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
				break;

			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
				testName += "_storage_buffer";
				if (params[testIdx].numCalls <= 2)
					graphicsTests->addChild(new PushDescriptorBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
				computeTests->addChild(new PushDescriptorBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
				break;

			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
				testName += "_combined_image_sampler";
				graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
				computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
				break;

			case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
				testName += "_sampled_image";
				graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
				computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
				break;

			case VK_DESCRIPTOR_TYPE_SAMPLER:
				testName += "_sampler";
				graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
				computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
				break;

			case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
				testName += "_storage_image";
				graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
				computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
				break;

			case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
				testName += "_uniform_texel_buffer";
				graphicsTests->addChild(new PushDescriptorTexelBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
				computeTests->addChild(new PushDescriptorTexelBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
				break;

			case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
				testName += "_storage_texel_buffer";
				graphicsTests->addChild(new PushDescriptorTexelBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
				computeTests->addChild(new PushDescriptorTexelBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
				break;

			case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
				testName += "_input_attachment";
				graphicsTests->addChild(new PushDescriptorInputAttachmentGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
				break;

			default:
				DE_FATAL("Unexpected descriptor type");
				break;
		};
	}

	pushDescriptorTests->addChild(graphicsTests.release());
	pushDescriptorTests->addChild(computeTests.release());

	return pushDescriptorTests.release();
}

} // pipeline
} // vkt
