/*------------------------------------------------------------------------
 * 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 "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 <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 (vector<string>::const_iterator requiredExtName = requiredExtensions.begin(); requiredExtName != requiredExtensions.end(); ++requiredExtName)
	{
		if (!isExtensionSupported(supportedExtensions, RequiredExtension(*requiredExtName)))
			TCU_THROW(NotSupportedError, (*requiredExtName + " is not supported").c_str());
	}
}

Move<VkInstance> createInstanceWithGetPhysicalDeviceProperties2 (const PlatformInterface&	vkp,
																 deUint32					version,
																 const Extensions&			supportedExtensions)
{
	vector<string> extensions;

	if (!isCoreInstanceExtension(version, "VK_KHR_get_physical_device_properties2"))
		extensions.push_back("VK_KHR_get_physical_device_properties2");

	checkAllSupported(supportedExtensions, extensions);

	return createDefaultInstance(vkp, version, vector<string>(), extensions);
}

Move<VkDevice> createDeviceWithPushDescriptor (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));

	const char* const				extensions[]	=
	{
		"VK_KHR_push_descriptor"
	};

	const VkDeviceCreateInfo		deviceParams    =
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
		DE_NULL,
		(VkDeviceCreateFlags)0,
		1u,
		&queueInfo,
		0u,
		DE_NULL,
		1u,
		extensions,
		&features
	};

	if (!isExtensionSupported(supportedExtensions, RequiredExtension(extensions[0])))
		TCU_THROW(NotSupportedError, (string(extensions[0]) + " is not supported").c_str());

	return createDevice(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 Unique<VkInstance>	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(m_vkp, context.getUsedApiVersion(), m_instanceExtensions))
	, m_vki					(m_vkp, *m_instance)
	, 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(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()), 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" : "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 Unique<VkInstance>	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(m_vkp, context.getUsedApiVersion(), m_instanceExtensions))
	, m_vki					(m_vkp, *m_instance)
	, 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(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 Unique<VkInstance>		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(m_vkp, context.getUsedApiVersion(), m_instanceExtensions))
	, m_vki					(m_vkp, *m_instance)
	, 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(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()), 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 Unique<VkInstance>	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(m_vkp, context.getUsedApiVersion(), m_instanceExtensions))
	, m_vki					(m_vkp, *m_instance)
	, 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(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 Unique<VkInstance>		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(m_vkp, context.getUsedApiVersion(), m_instanceExtensions))
	, m_vki					(m_vkp, *m_instance)
	, 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(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()), 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 Unique<VkInstance>	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(m_vkp, context.getUsedApiVersion(), m_instanceExtensions))
	, m_vki					(m_vkp, *m_instance)
	, 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(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 Unique<VkInstance>		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(m_vkp, context.getUsedApiVersion(), m_instanceExtensions))
	, m_vki					(m_vkp, *m_instance)
	, 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(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()), 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
