/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2019 Google Inc.
 * Copyright (c) 2019 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *	  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Tests for descriptor copying
 *//*--------------------------------------------------------------------*/

#include "vktBindingDescriptorCopyTests.hpp"

#include "vkBufferWithMemory.hpp"
#include "vkImageWithMemory.hpp"
#include "vkQueryUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkObjUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCase.hpp"

#include "deDefs.h"
#include "deMath.h"
#include "deRandom.h"
#include "deSharedPtr.hpp"
#include "deString.h"

#include "tcuTestCase.hpp"
#include "tcuTestLog.hpp"

#include <string>
#include <sstream>

namespace vkt
{
namespace BindingModel
{
namespace
{
using namespace vk;
using namespace std;
using tcu::Vec4;
using tcu::Vec2;

enum PipelineType
{
	PIPELINE_TYPE_COMPUTE = 0,
	PIPELINE_TYPE_GRAPHICS = 1
};

struct DescriptorCopy
{
	deUint32	srcSet;
	deUint32	srcBinding;
	deUint32	srcArrayElement;
	deUint32	dstSet;
	deUint32	dstBinding;
	deUint32	dstArrayElement;
	deUint32	descriptorCount;
};

struct DescriptorData
{
	vector<deUint32>	data;		// The actual data. One element per dynamic offset.
	bool				written;	// Is the data written in descriptor update
	bool				copiedInto;	// Is the data being overwritten by a copy operation
};

typedef de::SharedPtr<ImageWithMemory>					ImageWithMemorySp;
typedef de::SharedPtr<Unique<VkImageView> >				VkImageViewSp;
typedef de::SharedPtr<Unique<VkBufferView> >			VkBufferViewSp;
typedef de::SharedPtr<Unique<VkSampler> >				VkSamplerSp;
typedef de::SharedPtr<Unique<VkDescriptorSetLayout> >	VkDescriptorSetLayoutSp;

const tcu::IVec2 renderSize(64, 64);

// Base class for descriptors
class Descriptor
{
public:
											Descriptor				(VkDescriptorType descriptorType, deUint32 arraySize = 1u, deUint32 writeStart = 0u, deUint32 elementsToWrite = 1u, deUint32 numDynamicAreas = 1u);
	virtual									~Descriptor				(void);
	VkDescriptorType						getType					(void) const { return m_descriptorType; }
	deUint32								getArraySize			(void) const { return m_arraySize; }
	virtual VkWriteDescriptorSet			getDescriptorWrite		(void) = 0;
	virtual string							getShaderDeclaration	(void) const = 0;
	virtual void							init					(Context& context, PipelineType pipelineType) = 0;
	virtual void							copyValue				(const Descriptor& src, deUint32 srcElement, deUint32 dstElement, deUint32 numElements);
	virtual void							invalidate				(Context& context) { DE_UNREF(context); }
	virtual vector<deUint32>				getData					(void) { DE_FATAL("Unexpected"); return vector<deUint32>(); }
	deUint32								getId					(void) const { return m_id; }
	virtual string							getShaderVerifyCode		(void) const = 0;
	string									getArrayString			(deUint32 index) const;
	deUint32								getFirstWrittenElement	(void) const;
	deUint32								getNumWrittenElements	(void) const;
	deUint32								getReferenceData		(deUint32 arrayIdx, deUint32 dynamicAreaIdx = 0) const { return m_data[arrayIdx].data[dynamicAreaIdx]; }
	virtual bool							isDynamic				(void) const { return false; }
	virtual void							setDynamicAreas			(vector<deUint32> dynamicAreas) { DE_UNREF(dynamicAreas); }
	virtual vector<VkImageViewSp>			getImageViews			(void) const { return vector<VkImageViewSp>(); }
	virtual vector<VkAttachmentReference>	getAttachmentReferences	(void) const { return vector<VkAttachmentReference>(); }

	static deUint32							s_nextId;
protected:
	VkDescriptorType						m_descriptorType;
	deUint32								m_arraySize;
	deUint32								m_id;
	vector<DescriptorData>					m_data;
	deUint32								m_numDynamicAreas;
};

typedef de::SharedPtr<Descriptor>	DescriptorSp;

// Base class for all buffer based descriptors
class BufferDescriptor : public Descriptor
{
public:
									BufferDescriptor		(VkDescriptorType type, deUint32 arraySize, deUint32 writeStart, deUint32 elementsToWrite, deUint32 numDynamicAreas = 1u);
	virtual							~BufferDescriptor		(void);
	void							init					(Context& context, PipelineType pipelineType);

	VkWriteDescriptorSet			getDescriptorWrite		(void);
	virtual string					getShaderDeclaration	(void) const = 0;
	void							invalidate				(Context& context);
	vector<deUint32>				getData					(void);
	virtual string					getShaderVerifyCode		(void) const = 0;
	virtual VkBufferUsageFlags		getBufferUsageFlags		(void) const = 0;
	virtual bool					usesBufferView			(void) { return false; }
private:
	vector<VkDescriptorBufferInfo>	m_descriptorBufferInfos;
	de::MovePtr<BufferWithMemory>	m_buffer;
	deUint32						m_bufferSize;
	vector<VkBufferViewSp>			m_bufferViews;
	vector<VkBufferView>			m_bufferViewHandles;
};

class UniformBufferDescriptor : public BufferDescriptor
{
public:
						UniformBufferDescriptor		(deUint32 arraySize = 1u, deUint32 writeStart = 0u, deUint32 elementsToWrite = 1u, deUint32 numDynamicAreas = 1u);
	virtual				~UniformBufferDescriptor	(void);

	string				getShaderDeclaration		(void) const;
	string				getShaderVerifyCode			(void) const;
	VkBufferUsageFlags	getBufferUsageFlags			(void) const { return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; }
private:
};

class DynamicUniformBufferDescriptor : public BufferDescriptor
{
public:
						DynamicUniformBufferDescriptor	(deUint32 arraySize, deUint32 writeStart, deUint32 elementsToWrite, deUint32 numDynamicAreas);
	virtual				~DynamicUniformBufferDescriptor	(void);

	string				getShaderDeclaration			(void) const;
	string				getShaderVerifyCode				(void) const;
	VkBufferUsageFlags	getBufferUsageFlags				(void) const { return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; }
	virtual void		setDynamicAreas					(vector<deUint32> dynamicAreas) { m_dynamicAreas = dynamicAreas; }
	virtual bool		isDynamic						(void) const { return true; }

private:
	vector<deUint32>	m_dynamicAreas;
};

class StorageBufferDescriptor : public BufferDescriptor
{
public:
						StorageBufferDescriptor		(deUint32 arraySize = 1u, deUint32 writeStart = 0u, deUint32 elementsToWrite = 1u, deUint32 numDynamicAreas = 1u);
	virtual				~StorageBufferDescriptor	(void);

	string				getShaderDeclaration		(void) const;
	string				getShaderVerifyCode			(void) const;
	VkBufferUsageFlags	getBufferUsageFlags			(void) const { return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; }
private:
};

class DynamicStorageBufferDescriptor : public BufferDescriptor
{
public:
						DynamicStorageBufferDescriptor	(deUint32 arraySize, deUint32 writeStart, deUint32 elementsToWrite, deUint32 numDynamicAreas);
	virtual				~DynamicStorageBufferDescriptor	(void);

	string				getShaderDeclaration			(void) const;
	string				getShaderVerifyCode				(void) const;
	VkBufferUsageFlags	getBufferUsageFlags				(void) const { return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; }
	virtual void		setDynamicAreas					(vector<deUint32> dynamicAreas) { m_dynamicAreas = dynamicAreas; }
	virtual bool		isDynamic						(void) const { return true; }

private:
	vector<deUint32>	m_dynamicAreas;
};

class UniformTexelBufferDescriptor : public BufferDescriptor
{
public:
						UniformTexelBufferDescriptor	(deUint32 arraySize = 1, deUint32 writeStart = 0, deUint32 elementsToWrite = 1, deUint32 numDynamicAreas = 1);
	virtual				~UniformTexelBufferDescriptor	(void);

	string				getShaderDeclaration			(void) const;
	string				getShaderVerifyCode				(void) const;
	VkBufferUsageFlags	getBufferUsageFlags				(void) const { return VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; }
	bool				usesBufferView					(void) { return true; }
private:
};

class StorageTexelBufferDescriptor : public BufferDescriptor
{
public:
						StorageTexelBufferDescriptor	(deUint32 arraySize = 1u, deUint32 writeStart = 0u, deUint32 elementsToWrite = 1u, deUint32 numDynamicAreas = 1u);
	virtual				~StorageTexelBufferDescriptor	(void);

	string				getShaderDeclaration			(void) const;
	string				getShaderVerifyCode				(void) const;
	VkBufferUsageFlags	getBufferUsageFlags				(void) const { return VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; }
	bool				usesBufferView					(void) { return true; }
private:
};

// Base class for all image based descriptors
class ImageDescriptor : public Descriptor
{
public:
									ImageDescriptor			(VkDescriptorType type, deUint32 arraySize, deUint32 writeStart, deUint32 elementsToWrite, deUint32 numDynamicAreas);
	virtual							~ImageDescriptor		(void);
	void							init					(Context& context, PipelineType pipelineType);

	VkWriteDescriptorSet			getDescriptorWrite		(void);
	virtual VkImageUsageFlags		getImageUsageFlags		(void) const = 0;
	virtual string					getShaderDeclaration	(void) const = 0;
	virtual string					getShaderVerifyCode		(void) const = 0;
	virtual VkAccessFlags			getAccessFlags			(void) const { return VK_ACCESS_SHADER_READ_BIT; }
	virtual VkImageLayout			getImageLayout			(void) const { return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; }

protected:
	vector<VkImageViewSp>			m_imageViews;

private:
	vector<ImageWithMemorySp>		m_images;
	vector<VkDescriptorImageInfo>	m_descriptorImageInfos;
	Move<VkSampler>					m_sampler;
};

class InputAttachmentDescriptor : public ImageDescriptor
{
public:
									InputAttachmentDescriptor	(deUint32 arraySize = 1u, deUint32 writeStart = 0u, deUint32 elementsToWrite = 1u, deUint32 numDynamicAreas = 1u);
	virtual							~InputAttachmentDescriptor	(void);

	VkImageUsageFlags				getImageUsageFlags			(void) const { return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; }
	string							getShaderDeclaration		(void) const;
	string							getShaderVerifyCode			(void) const;
	vector<VkImageViewSp>			getImageViews				(void) const { return m_imageViews; }
	void							copyValue					(const Descriptor& src, deUint32 srcElement, deUint32 dstElement, deUint32 numElements);
	VkAccessFlags					getAccessFlags				(void) const { return VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; }
	vector<VkAttachmentReference>	getAttachmentReferences		(void) const;
	static deUint32					s_nextAttachmentIndex;
private:
	vector<deUint32>				m_attachmentIndices;
	deUint32						m_originalAttachmentIndex;
};

class CombinedImageSamplerDescriptor : public ImageDescriptor
{
public:
						CombinedImageSamplerDescriptor	(deUint32 arraySize = 1u, deUint32 writeStart = 0u, deUint32 elementsToWrite = 1u, deUint32 numDynamicAreas = 1u);
	virtual				~CombinedImageSamplerDescriptor	(void);

	VkImageUsageFlags	getImageUsageFlags				(void) const { return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; }
	string				getShaderDeclaration			(void) const;
	string				getShaderVerifyCode				(void) const;
private:
};

class SamplerDescriptor;

class SampledImageDescriptor : public ImageDescriptor
{
public:
								SampledImageDescriptor	(deUint32 arraySize = 1u, deUint32 writeStart = 0u, deUint32 elementsToWrite = 1u, deUint32 numDynamicAreas = 1u);
	virtual						~SampledImageDescriptor	(void);

	VkImageUsageFlags			getImageUsageFlags		(void) const { return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; }
	string						getShaderDeclaration	(void) const;
	string						getShaderVerifyCode		(void) const;
	void						addSampler				(SamplerDescriptor* sampler, deUint32 count = 1u) { for (deUint32 i = 0; i < count; i++) m_samplers.push_back(sampler); }
private:
	vector<SamplerDescriptor*>	m_samplers;
};

class SamplerDescriptor : public Descriptor
{
public:
									SamplerDescriptor		(deUint32 arraySize = 1u, deUint32 writeStart = 0u, deUint32 elementsToWrite = 1u, deUint32 numDynamicAreas = 1u);
	virtual							~SamplerDescriptor		(void);
	void							init					(Context& context, PipelineType pipelineType);

	void							addImage				(SampledImageDescriptor* image, deUint32 count = 1u) { for (deUint32 i = 0; i < count; i++ ) m_images.push_back(image); }
	VkWriteDescriptorSet			getDescriptorWrite		(void);
	string							getShaderDeclaration	(void) const;
	string							getShaderVerifyCode		(void) const;

private:
	vector<VkSamplerSp>				m_samplers;
	vector<VkDescriptorImageInfo>	m_descriptorImageInfos;
	vector<SampledImageDescriptor*>	m_images;
};

class StorageImageDescriptor : public ImageDescriptor
{
public:
						StorageImageDescriptor	(deUint32 arraySize = 1u, deUint32 writeStart = 0u, deUint32 elementsToWrite = 1u, deUint32 numDynamicAreas = 1u);
	virtual				~StorageImageDescriptor	(void);

	VkImageUsageFlags	getImageUsageFlags		(void) const { return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; }
	string				getShaderDeclaration	(void) const;
	string				getShaderVerifyCode		(void) const;
	VkImageLayout		getImageLayout			(void) const { return VK_IMAGE_LAYOUT_GENERAL; }
private:
};

class DescriptorSet
{
public:
								DescriptorSet	(void);
								~DescriptorSet	(void);
	void						addBinding		(DescriptorSp descriptor);
	const vector<DescriptorSp>	getBindings		(void) const { return m_bindings; }

private:
	vector<DescriptorSp>		m_bindings;
};

typedef de::SharedPtr<DescriptorSet> DescriptorSetSp;

// Class that handles descriptor sets and descriptors bound to those sets. Keeps track of copy operations.
class DescriptorCommands
{
public:
					DescriptorCommands			(PipelineType pipelineType);
					~DescriptorCommands			(void);
	void			addDescriptor				(DescriptorSp descriptor, deUint32 descriptorSet);
	void			copyDescriptor				(deUint32 srcSet, deUint32 srcBinding, deUint32	srcArrayElement, deUint32 dstSet, deUint32 dstBinding, deUint32 dstArrayElement, deUint32 descriptorCount);
	void			copyDescriptor				(deUint32 srcSet, deUint32 srcBinding, deUint32 dstSet, deUint32 dstBinding) { copyDescriptor(srcSet, srcBinding, 0u, dstSet, dstBinding, 0u, 1u); }
	string			getShaderDeclarations		(void) const;
	string			getDescriptorVerifications	(void) const;
	void			addResultBuffer				(void);
	deUint32		getResultBufferId			(void) const { return m_resultBuffer->getId(); }
	void			setDynamicAreas				(vector<deUint32> areas);
	bool			hasDynamicAreas				(void) const;
	PipelineType	getPipelineType				(void) const { return m_pipelineType; }

	tcu::TestStatus	run(Context& context);

private:
	PipelineType					m_pipelineType;
	vector<DescriptorSetSp>			m_descriptorSets;
	vector<DescriptorCopy>			m_descriptorCopies;
	vector<DescriptorSp>			m_descriptors;
	map<VkDescriptorType, deUint32>	m_descriptorCounts;
	DescriptorSp					m_resultBuffer;
	vector<deUint32>				m_dynamicAreas;
};

typedef de::SharedPtr<DescriptorCommands> DescriptorCommandsSp;

class DescriptorCopyTestInstance : public TestInstance
{
public:
							DescriptorCopyTestInstance	(Context& context, DescriptorCommandsSp commands);
							~DescriptorCopyTestInstance	(void);
	tcu::TestStatus			iterate						(void);
private:
	DescriptorCommandsSp	m_commands;
};

class DescriptorCopyTestCase : public TestCase
{
	public:
							DescriptorCopyTestCase	(tcu::TestContext& context, const char* name, const char* desc, DescriptorCommandsSp commands);
	virtual					~DescriptorCopyTestCase	(void);
	virtual	void			initPrograms			(SourceCollections& programCollection) const;
	virtual TestInstance*	createInstance			(Context& context) const;

private:
	DescriptorCommandsSp	m_commands;
};

deUint32 Descriptor::s_nextId = 0xabc; // Random starting point for ID counter
deUint32 InputAttachmentDescriptor::s_nextAttachmentIndex = 0;

Descriptor::Descriptor (VkDescriptorType	descriptorType,
						deUint32			arraySize,
						deUint32			writeStart,
						deUint32			elementsToWrite,
						deUint32			numDynamicAreas)
: m_descriptorType(descriptorType)
, m_arraySize(arraySize)
, m_id(s_nextId++)
, m_numDynamicAreas(numDynamicAreas)
{
	for (deUint32 arrayIdx = 0; arrayIdx < m_arraySize; arrayIdx++)
	{
		const bool				written			= arrayIdx >= writeStart && arrayIdx < writeStart + elementsToWrite;
		vector<deUint32>		data;

		for (deUint32 dynamicAreaIdx = 0; dynamicAreaIdx < m_numDynamicAreas; dynamicAreaIdx++)
			data.push_back(m_id + arrayIdx * m_numDynamicAreas + dynamicAreaIdx);

		const DescriptorData	descriptorData	=
		{
			data,		// vector<deUint32>	data
			written,	// bool				written
			false		// bool				copiedInto
		};

		m_data.push_back(descriptorData);
	}
}

Descriptor::~Descriptor (void)
{
}

// Copy refrence data from another descriptor
void Descriptor::copyValue (const Descriptor&	src,
							deUint32			srcElement,
							deUint32			dstElement,
							deUint32			numElements)
{
	for (deUint32 elementIdx = 0; elementIdx < numElements; elementIdx++)
	{
		DE_ASSERT(src.m_data[elementIdx + srcElement].written);

		for (deUint32 dynamicAreaIdx = 0; dynamicAreaIdx < de::min(m_numDynamicAreas, src.m_numDynamicAreas); dynamicAreaIdx++)
			m_data[elementIdx + dstElement].data[dynamicAreaIdx] = src.m_data[elementIdx + srcElement].data[dynamicAreaIdx];

		m_data[elementIdx + dstElement].copiedInto = true;
	}
}

string Descriptor::getArrayString (deUint32 index) const
{
	return m_arraySize > 1 ? (string("[") + de::toString(index) + "]") : "";
}

// Returns the first element to be written in descriptor update
deUint32 Descriptor::getFirstWrittenElement (void) const
{
	for (deUint32 i = 0; i < (deUint32)m_data.size(); i++)
		if (m_data[i].written)
			return i;

	return 0;
}

// Returns the number of array elements to be written for a descriptor array
deUint32 Descriptor::getNumWrittenElements (void) const
{
	deUint32	numElements = 0;

	for (deUint32 i = 0; i < (deUint32)m_data.size(); i++)
		if (m_data[i].written)
			numElements++;

	return numElements;
}

BufferDescriptor::BufferDescriptor (VkDescriptorType	type,
									deUint32			arraySize,
									deUint32			writeStart,
									deUint32			elementsToWrite,
									deUint32			numDynamicAreas)
: Descriptor(type, arraySize, writeStart, elementsToWrite, numDynamicAreas)
, m_bufferSize(256u * arraySize * numDynamicAreas)
{
}

BufferDescriptor::~BufferDescriptor (void)
{
}

void BufferDescriptor::init (Context&		context,
							 PipelineType	pipelineType)
{
	DE_UNREF(pipelineType);

	const DeviceInterface&		vk			= context.getDeviceInterface();
    const VkDevice				device		= context.getDevice();
    Allocator&					allocator	= context.getDefaultAllocator();

	// Create buffer
	{
		const VkBufferCreateInfo	bufferCreateInfo	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
			DE_NULL,								// const void*			pNext
			0u,										// VkBufferCreateFlags	flags
			m_bufferSize,							// VkDeviceSize			size
			getBufferUsageFlags(),					// VkBufferUsageFlags	usage
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
			0u,										// uint32_t				queueFamilyIndexCount
			DE_NULL									// const uint32_t*		pQueueFamilyIndices
		};

		m_buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
	}

	// Create descriptor buffer infos
	{
		for (deUint32 arrayIdx = 0; arrayIdx < m_arraySize; arrayIdx++)
		{
			const VkDescriptorBufferInfo bufferInfo =
			{
				m_buffer->get(),						// VkBuffer		buffer
				256u * m_numDynamicAreas * arrayIdx,	// VkDeviceSize	offset
				isDynamic() ? 256u : 4u					// VkDeviceSize	range
			};

			m_descriptorBufferInfos.push_back(bufferInfo);
		}
	}

	// Create buffer views
	if (usesBufferView())
	{
		for (deUint32 viewIdx = 0; viewIdx < m_arraySize; viewIdx++)
		{
			const VkBufferViewCreateInfo bufferViewCreateInfo =
			{
				VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,	// VkStructureType			sType
				DE_NULL,									// const void*				pNext
				0u,											// VkBufferViewCreateFlags	flags
				m_buffer->get(),							// VkBuffer					buffer
				VK_FORMAT_R32_SFLOAT,						// VkFormat					format
				256u * viewIdx,								// VkDeviceSize				offset
				4u											// VkDeviceSize				range
			};

			m_bufferViews.push_back(VkBufferViewSp(new Unique<VkBufferView>(createBufferView(vk, device, &bufferViewCreateInfo))));
			m_bufferViewHandles.push_back(**m_bufferViews[viewIdx]);
		}
	}

	// Initialize buffer memory
	{
		deUint32* hostPtr = (deUint32*)m_buffer->getAllocation().getHostPtr();

		for (deUint32 arrayIdx = 0; arrayIdx < m_arraySize; arrayIdx++)
		{
			for (deUint32 dynamicAreaIdx = 0; dynamicAreaIdx < m_numDynamicAreas; dynamicAreaIdx++)
			{
				union BufferValue
				{
					deUint32	uintValue;
					float		floatValue;
				} bufferValue;

				bufferValue.uintValue = m_id + (arrayIdx * m_numDynamicAreas) + dynamicAreaIdx;

				if (usesBufferView())
					bufferValue.floatValue = (float)bufferValue.uintValue;

				hostPtr[(256 / 4) * (m_numDynamicAreas * arrayIdx + dynamicAreaIdx)] = bufferValue.uintValue;
			}
		}

		flushMappedMemoryRange(vk, device, m_buffer->getAllocation().getMemory(), m_buffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
	}
}

VkWriteDescriptorSet BufferDescriptor::getDescriptorWrite (void)
{
	const deUint32				firstElement	= getFirstWrittenElement();

	// Set and binding will be overwritten later
	const VkWriteDescriptorSet	descriptorWrite	=
	{
		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,									// VkStructureType					sType
		DE_NULL,																// const void*						pNext
		(VkDescriptorSet)0u,													// VkDescriptorSet					dstSet
		0u,																		// deUint32							dstBinding
		firstElement,															// deUint32							dstArrayElement
		getNumWrittenElements(),												// deUint32							descriptorCount
		getType(),																// VkDescriptorType					descriptorType
		DE_NULL,																// const VkDescriptorImageInfo		pImageInfo
		usesBufferView() ? DE_NULL : &m_descriptorBufferInfos[firstElement],	// const VkDescriptorBufferInfo*	pBufferInfo
		usesBufferView() ? &m_bufferViewHandles[firstElement] : DE_NULL			// const VkBufferView*				pTexelBufferView
	};

	return descriptorWrite;
}

void BufferDescriptor::invalidate (Context& context)
{
	const DeviceInterface&	vk		= context.getDeviceInterface();
    const VkDevice			device	= context.getDevice();

	invalidateMappedMemoryRange(vk, device, m_buffer->getAllocation().getMemory(), m_buffer->getAllocation().getOffset(), m_bufferSize);
}

// Returns the buffer data as a vector
vector<deUint32> BufferDescriptor::getData (void)
{
	vector<deUint32>	data;
	deInt32*			hostPtr = (deInt32*)m_buffer->getAllocation().getHostPtr();

	for (deUint32 i = 0; i < m_arraySize; i++)
		data.push_back(hostPtr[i]);

	return data;
}

UniformBufferDescriptor::UniformBufferDescriptor (deUint32	arraySize,
												  deUint32	writeStart,
												  deUint32	elementsToWrite,
												  deUint32	numDynamicAreas)
: BufferDescriptor(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, arraySize, writeStart, elementsToWrite, 1u)
{
	DE_UNREF(numDynamicAreas);
}

UniformBufferDescriptor::~UniformBufferDescriptor (void)
{
}

string UniformBufferDescriptor::getShaderDeclaration (void) const
{
	return string(
		") uniform UniformBuffer" + de::toString(m_id) + "\n"
		"{\n"
		"	int data;\n"
		"} uniformBuffer" + de::toString(m_id) + getArrayString(m_arraySize) +  ";\n");
}

string UniformBufferDescriptor::getShaderVerifyCode (void) const
{
	string ret;

	for (deUint32 i = 0; i < m_arraySize; i++)
	{
		if (m_data[i].written || m_data[i].copiedInto)
			ret += string("if (uniformBuffer") + de::toString(m_id) + getArrayString(i) + ".data != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
	}

	return ret;
}

DynamicUniformBufferDescriptor::DynamicUniformBufferDescriptor (deUint32	arraySize,
																deUint32	writeStart,
																deUint32	elementsToWrite,
																deUint32	numDynamicAreas)
: BufferDescriptor(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, arraySize, writeStart, elementsToWrite, numDynamicAreas)
{
}

DynamicUniformBufferDescriptor::~DynamicUniformBufferDescriptor (void)
{
}

string DynamicUniformBufferDescriptor::getShaderDeclaration (void) const
{
	return string(
		") uniform UniformBuffer" + de::toString(m_id) + "\n"
		"{\n"
		"	int data;\n"
		"} dynamicUniformBuffer" + de::toString(m_id) + getArrayString(m_arraySize) +  ";\n");
}

string DynamicUniformBufferDescriptor::getShaderVerifyCode (void) const
{
	string ret;

	for (deUint32 arrayIdx = 0; arrayIdx < m_arraySize; arrayIdx++)
	{
		if (m_data[arrayIdx].written || m_data[arrayIdx].copiedInto)
			ret += string("if (dynamicUniformBuffer") + de::toString(m_id) + getArrayString(arrayIdx) + ".data != " + de::toString(m_data[arrayIdx].data[m_dynamicAreas[arrayIdx]]) + ") result = 0;\n";
	}

	return ret;
}

StorageBufferDescriptor::StorageBufferDescriptor (deUint32	arraySize,
												  deUint32	writeStart,
												  deUint32	elementsToWrite,
												  deUint32	numDynamicAreas)
: BufferDescriptor(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, arraySize, writeStart, elementsToWrite, 1u)
{
	DE_UNREF(numDynamicAreas);
}

StorageBufferDescriptor::~StorageBufferDescriptor (void)
{
}

string StorageBufferDescriptor::getShaderDeclaration (void) const
{
	return string(
		") buffer StorageBuffer" + de::toString(m_id) + "\n"
		"{\n"
		"	int data;\n"
		"} storageBuffer" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
}

string StorageBufferDescriptor::getShaderVerifyCode (void) const
{
	string ret;

	for (deUint32 i = 0; i < m_arraySize; i++)
	{
		if (m_data[i].written || m_data[i].copiedInto)
			ret += string("if (storageBuffer") + de::toString(m_id) + getArrayString(i) + ".data != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
	}

	return ret;
}

DynamicStorageBufferDescriptor::DynamicStorageBufferDescriptor (deUint32	arraySize,
																deUint32	writeStart,
																deUint32	elementsToWrite,
																deUint32	numDynamicAreas)
: BufferDescriptor(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, arraySize, writeStart, elementsToWrite, numDynamicAreas)
{
}

DynamicStorageBufferDescriptor::~DynamicStorageBufferDescriptor (void)
{
}

string DynamicStorageBufferDescriptor::getShaderDeclaration (void) const
{
	return string(
		") buffer StorageBuffer" + de::toString(m_id) + "\n"
		"{\n"
		"	int data;\n"
		"} dynamicStorageBuffer" + de::toString(m_id) + getArrayString(m_arraySize) +  ";\n");
}

string DynamicStorageBufferDescriptor::getShaderVerifyCode (void) const
{
	string ret;

	for (deUint32 arrayIdx = 0; arrayIdx < m_arraySize; arrayIdx++)
	{
		if (m_data[arrayIdx].written || m_data[arrayIdx].copiedInto)
			ret += string("if (dynamicStorageBuffer") + de::toString(m_id) + getArrayString(arrayIdx) + ".data != " + de::toString(m_data[arrayIdx].data[m_dynamicAreas[arrayIdx]]) + ") result = 0;\n";
	}

	return ret;
}

UniformTexelBufferDescriptor::UniformTexelBufferDescriptor (deUint32	arraySize,
															deUint32	writeStart,
															deUint32	elementsToWrite,
															deUint32	numDynamicAreas)
: BufferDescriptor(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, arraySize, writeStart, elementsToWrite, 1u)
{
	DE_UNREF(numDynamicAreas);
}

UniformTexelBufferDescriptor::~UniformTexelBufferDescriptor (void)
{
}

string UniformTexelBufferDescriptor::getShaderDeclaration (void) const
{
	return string(") uniform textureBuffer uniformTexelBuffer" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
}

string UniformTexelBufferDescriptor::getShaderVerifyCode (void) const
{
	string ret;

	for (deUint32 i = 0; i < m_arraySize; i++)
	{
		if (m_data[i].written || m_data[i].copiedInto)
			ret += string("if (texelFetch(uniformTexelBuffer") + de::toString(m_id) + getArrayString(i) + ", 0).x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
	}

	return ret;
}

StorageTexelBufferDescriptor::StorageTexelBufferDescriptor (deUint32	arraySize,
															deUint32	writeStart,
															deUint32	elementsToWrite,
															deUint32	numDynamicAreas)
: BufferDescriptor(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, arraySize, writeStart, elementsToWrite, 1u)
{
	DE_UNREF(numDynamicAreas);
}

StorageTexelBufferDescriptor::~StorageTexelBufferDescriptor (void)
{
}

string StorageTexelBufferDescriptor::getShaderDeclaration (void) const
{
	return string(", r32f) uniform imageBuffer storageTexelBuffer" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
}

string StorageTexelBufferDescriptor::getShaderVerifyCode (void) const
{
	string ret;

	for (deUint32 i = 0; i < m_arraySize; i++)
	{
		if (m_data[i].written || m_data[i].copiedInto)
			ret += string("if (imageLoad(storageTexelBuffer") + de::toString(m_id) + getArrayString(i) + ", 0).x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
	}

	return ret;
}

ImageDescriptor::ImageDescriptor (VkDescriptorType	type,
								  deUint32			arraySize,
								  deUint32			writeStart,
								  deUint32			elementsToWrite,
								  deUint32			numDynamicAreas)
: Descriptor(type, arraySize, writeStart, elementsToWrite, 1u)
{
	DE_UNREF(numDynamicAreas);
}

ImageDescriptor::~ImageDescriptor (void)
{
}

void ImageDescriptor::init (Context&		context,
							PipelineType	pipelineType)
{
	const DeviceInterface&			vk					= context.getDeviceInterface();
    const VkDevice					device				= context.getDevice();
    Allocator&						allocator			= context.getDefaultAllocator();
	const VkQueue					queue				= context.getUniversalQueue();
	deUint32						queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	const VkFormat					format				= VK_FORMAT_R32_SFLOAT;
	const VkComponentMapping		componentMapping	= makeComponentMappingRGBA();

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

	// Create sampler
	{
		const tcu::Sampler			sampler			= tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
		const tcu::TextureFormat	texFormat		= mapVkFormat(format);
		const VkSamplerCreateInfo	samplerParams	= mapSampler(sampler, texFormat);

		m_sampler = createSampler(vk, device, &samplerParams);
	}

	// Create images
	for (deUint32 imageIdx = 0; imageIdx < m_arraySize; imageIdx++)
	{
		const VkImageCreateInfo imageCreateInfo =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,						// VkStructureType			stype
			DE_NULL,													// const void*				pNext
			0u,															// VkImageCreateFlags		flags
			VK_IMAGE_TYPE_2D,											// VkImageType				imageType
			format,														// VkFormat					format
			{ (deUint32)renderSize.x(), (deUint32)renderSize.y(), 1 },	// VkExtent3D				extent
			1u,															// deUint32					mipLevels
			1u,															// deUint32					arrayLayers
			VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits	samples
			VK_IMAGE_TILING_OPTIMAL,									// VkImageTiling			tiling
			getImageUsageFlags(),										// VkImageUsageFlags		usage
			VK_SHARING_MODE_EXCLUSIVE,									// VkSharingMode			sharingMode
			1u,															// deUint32					queueFamilyIndexCount
			&queueFamilyIndex,											// const deUint32*			pQueueFamilyIndices
			VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout			initialLayout
		};

		m_images.push_back(ImageWithMemorySp(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any)));
	}

	// Create image views
	for (deUint32 imageIdx = 0; imageIdx < m_arraySize; imageIdx++)
	{
		const VkImageViewCreateInfo imageViewCreateInfo =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0u,											// VkImageViewCreateFlags	flags
			**m_images[imageIdx],						// VkImage					image
			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
			format,										// VkFormat					format
			componentMapping,							// VkComponentMapping		components
			subresourceRange							// VkImageSubresourceRange	subresourceRange
		};

		m_imageViews.push_back(VkImageViewSp(new Unique<VkImageView>(createImageView(vk, device, &imageViewCreateInfo))));
	}

	// Create descriptor image infos
	{
		for (deUint32 i = 0; i < m_arraySize; i++)
		{
			const VkDescriptorImageInfo imageInfo =
			{
				*m_sampler,			// VkSampler		sampler
				**m_imageViews[i],	// VkImageView		imageView
				getImageLayout()	// VkImageLayout	imageLayout
			};

			m_descriptorImageInfos.push_back(imageInfo);
		}
	}

	// Clear images to reference value
	for (deUint32 imageIdx = 0; imageIdx < m_arraySize; imageIdx++)
	{
		const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
		const Unique<VkCommandBuffer>	cmdBuffer			(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

		const float						clearValue			= (float)(m_id + imageIdx);
		const VkClearValue				clearColor			= makeClearValueColorF32(clearValue, clearValue, clearValue, clearValue);

		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
			queueFamilyIndex,							// deUint32					srcQueueFamilyIndex
			queueFamilyIndex,							// deUint32					dstQueueFamilyIndex
			**m_images[imageIdx],						// VkImage					image
			subresourceRange							// VkImageSubresourceRange	subresourceRange
		};

		const VkImageMemoryBarrier		postImageBarrier	=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask
			getAccessFlags(),							// VkAccessFlags			dstAccessMask
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout
			getImageLayout(),							// VkImageLayout			newLayout
			queueFamilyIndex,							// deUint32					srcQueueFamilyIndex
			queueFamilyIndex,							// deUint32					dstQueueFamilyIndex
			**m_images[imageIdx],						// VkImage					image
			subresourceRange							// VkImageSubresourceRange	subresourceRange
		};

		beginCommandBuffer(vk, *cmdBuffer);
		vk.cmdPipelineBarrier(*cmdBuffer,
							  VK_PIPELINE_STAGE_HOST_BIT,
							  VK_PIPELINE_STAGE_TRANSFER_BIT,
							  (VkDependencyFlags)0u,
							  0u, (const VkMemoryBarrier*)DE_NULL,
							  0u, (const VkBufferMemoryBarrier*)DE_NULL,
							  1u, &preImageBarrier);
		vk.cmdClearColorImage(*cmdBuffer, **m_images[imageIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor.color, 1, &subresourceRange);
		vk.cmdPipelineBarrier(*cmdBuffer,
							  VK_PIPELINE_STAGE_TRANSFER_BIT,
							  pipelineType == PIPELINE_TYPE_COMPUTE ? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT : VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
							  (VkDependencyFlags)0u,
							  0u, (const VkMemoryBarrier*)DE_NULL,
							  0u, (const VkBufferMemoryBarrier*)DE_NULL,
							  1u, &postImageBarrier);
		endCommandBuffer(vk, *cmdBuffer);
		submitCommandsAndWait(vk, device, queue, *cmdBuffer);
	}
}

VkWriteDescriptorSet ImageDescriptor::getDescriptorWrite (void)
{
	const deUint32				firstElement	= getFirstWrittenElement();

	// Set and binding will be overwritten later
	const VkWriteDescriptorSet	descriptorWrite	=
	{
		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType
		DE_NULL,								// const void*						pNext
		(VkDescriptorSet)0u,					// VkDescriptorSet					dstSet
		0u,										// deUint32							dstBinding
		firstElement,							// deUint32							dstArrayElement
		getNumWrittenElements(),				// deUint32							descriptorCount
		getType(),								// VkDescriptorType					descriptorType
		&m_descriptorImageInfos[firstElement],	// const VkDescriptorImageInfo		pImageInfo
		DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo
		DE_NULL									// const VkBufferView*				pTexelBufferView
	};

	return descriptorWrite;
}

InputAttachmentDescriptor::InputAttachmentDescriptor (deUint32	arraySize,
													  deUint32	writeStart,
													  deUint32	elementsToWrite,
													  deUint32	numDynamicAreas)
: ImageDescriptor(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, arraySize, writeStart, elementsToWrite, 1u)
, m_originalAttachmentIndex(s_nextAttachmentIndex)
{
	DE_UNREF(numDynamicAreas);

	for (deUint32 i = 0; i < m_arraySize; i++)
		m_attachmentIndices.push_back(s_nextAttachmentIndex++);
}

InputAttachmentDescriptor::~InputAttachmentDescriptor (void)
{
}

string InputAttachmentDescriptor::getShaderDeclaration (void) const
{
	return string(", input_attachment_index=" + de::toString(m_originalAttachmentIndex) + ") uniform subpassInput inputAttachment" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
}

string InputAttachmentDescriptor::getShaderVerifyCode (void) const
{
	string ret;

	for (deUint32 i = 0; i < m_arraySize; i++)
	{
		if (m_data[i].written || m_data[i].copiedInto)
			ret += string("if (subpassLoad(inputAttachment") + de::toString(m_id) + getArrayString(i) + ").x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
	}

	return ret;
}

void InputAttachmentDescriptor::copyValue (const Descriptor&	src,
										   deUint32				srcElement,
										   deUint32				dstElement,
										   deUint32				numElements)
{
	Descriptor::copyValue(src, srcElement, dstElement, numElements);

	for (deUint32 elementIdx = 0; elementIdx < numElements; elementIdx++)
	{
		m_attachmentIndices[elementIdx + dstElement] = reinterpret_cast<const InputAttachmentDescriptor&>(src).m_attachmentIndices[elementIdx + srcElement];
	}
}

vector<VkAttachmentReference> InputAttachmentDescriptor::getAttachmentReferences (void) const
{
	vector<VkAttachmentReference> references;
	for (deUint32 i = 0; i < m_arraySize; i++)
	{
		const VkAttachmentReference attachmentReference =
		{
			// The first attachment is the color buffer, thus +1
			m_attachmentIndices[i] + 1,	// deUint32			attachment
			getImageLayout()			// VkImageLayout	layout
		};

		references.push_back(attachmentReference);
	}

	return references;
}

CombinedImageSamplerDescriptor::CombinedImageSamplerDescriptor (deUint32	arraySize,
																deUint32	writeStart,
																deUint32	elementsToWrite,
																deUint32	numDynamicAreas)
: ImageDescriptor(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, arraySize, writeStart, elementsToWrite, 1u)
{
	DE_UNREF(numDynamicAreas);
}

CombinedImageSamplerDescriptor::~CombinedImageSamplerDescriptor (void)
{
}

string CombinedImageSamplerDescriptor::getShaderDeclaration (void) const
{
	return string(") uniform sampler2D texSampler" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
}

string CombinedImageSamplerDescriptor::getShaderVerifyCode (void) const
{
	string ret;

	for (deUint32 i = 0; i < m_arraySize; i++)
	{
		if (m_data[i].written || m_data[i].copiedInto)
			ret += string("if (texture(texSampler") + de::toString(m_id) + getArrayString(i) + ", vec2(0)).x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
	}

	return ret;
}

SampledImageDescriptor::SampledImageDescriptor (deUint32	arraySize,
												deUint32	writeStart,
												deUint32	elementsToWrite,
												deUint32	numDynamicAreas)
: ImageDescriptor(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, arraySize, writeStart, elementsToWrite, 1u)
{
	DE_UNREF(numDynamicAreas);
}

SampledImageDescriptor::~SampledImageDescriptor (void)
{
}

string SampledImageDescriptor::getShaderDeclaration (void) const
{
	return string(") uniform texture2D sampledImage" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
}

string SampledImageDescriptor::getShaderVerifyCode (void) const
{
	string ret;

	for (deUint32 i = 0; i < m_arraySize; i++)
	{
		if ((m_data[i].written || m_data[i].copiedInto) && m_samplers.size() > i)
		{
			ret += string("if (texture(sampler2D(sampledImage") + de::toString(m_id) + getArrayString(i) + ", sampler" + de::toString(m_samplers[i]->getId()) + "), vec2(0)).x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
		}
	}

	return ret;
}

StorageImageDescriptor::StorageImageDescriptor (deUint32	arraySize,
												deUint32	writeStart,
												deUint32	elementsToWrite,
												deUint32	numDynamicAreas)
: ImageDescriptor(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, arraySize, writeStart, elementsToWrite, 1u)
{
	DE_UNREF(numDynamicAreas);
}

StorageImageDescriptor::~StorageImageDescriptor (void)
{
}

string StorageImageDescriptor::getShaderDeclaration (void) const
{
	return string(", r32f) readonly uniform image2D image" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
}

string StorageImageDescriptor::getShaderVerifyCode (void) const
{
	string ret;

	for (deUint32 i = 0; i < m_arraySize; i++)
	{
		if (m_data[i].written || m_data[i].copiedInto)
			ret += string("if (imageLoad(image") + de::toString(m_id) + getArrayString(i) + ", ivec2(0)).x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
	}

	return ret;
}

SamplerDescriptor::SamplerDescriptor (deUint32	arraySize,
									  deUint32	writeStart,
									  deUint32	elementsToWrite,
									  deUint32	numDynamicAreas)
: Descriptor(VK_DESCRIPTOR_TYPE_SAMPLER, arraySize, writeStart, elementsToWrite, 1u)
{
	DE_UNREF(numDynamicAreas);
}

SamplerDescriptor::~SamplerDescriptor (void)
{
}

void SamplerDescriptor::init (Context&		context,
							  PipelineType	pipelineType)
{
	DE_UNREF(pipelineType);

	const DeviceInterface&	vk		= context.getDeviceInterface();
    const VkDevice			device	= context.getDevice();
	const VkFormat			format	= VK_FORMAT_R32_SFLOAT;

	// Create samplers
	for (deUint32 i = 0; i < m_arraySize; i++)
	{
		const float					borderValue		= (float)((m_id + i) % 2);
		const tcu::Sampler			sampler			= tcu::Sampler(tcu::Sampler::CLAMP_TO_BORDER, tcu::Sampler::CLAMP_TO_BORDER, tcu::Sampler::CLAMP_TO_BORDER, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST, 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0, Vec4(borderValue));
		const tcu::TextureFormat	texFormat		= mapVkFormat(format);
		const VkSamplerCreateInfo	samplerParams	= mapSampler(sampler, texFormat);

		m_samplers.push_back(VkSamplerSp(new Unique<VkSampler>(createSampler(vk, device, &samplerParams))));
	}

	// Create descriptor image infos
	for (deUint32 i = 0; i < m_arraySize; i++)
	{
		const VkDescriptorImageInfo imageInfo =
		{
			**m_samplers[i],			// VkSampler		sampler
			DE_NULL,					// VkImageView		imageView
			VK_IMAGE_LAYOUT_UNDEFINED	// VkImageLayout	imageLayout
		};

		m_descriptorImageInfos.push_back(imageInfo);
	}
}

VkWriteDescriptorSet SamplerDescriptor::getDescriptorWrite (void)
{
	const deUint32 firstElement = getFirstWrittenElement();

	// Set and binding will be overwritten later
	const VkWriteDescriptorSet	descriptorWrite	=
	{
		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType
		DE_NULL,								// const void*						pNext
		(VkDescriptorSet)0u,					// VkDescriptorSet					dstSet
		0u,										// deUint32							dstBinding
		firstElement,							// deUint32							dstArrayElement
		getNumWrittenElements(),				// deUint32							descriptorCount
		getType(),								// VkDescriptorType					descriptorType
		&m_descriptorImageInfos[firstElement],	// const VkDescriptorImageInfo		pImageInfo
		DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo
		DE_NULL									// const VkBufferView*				pTexelBufferView
	};

	return descriptorWrite;
}

string SamplerDescriptor::getShaderDeclaration (void) const
{
	return string(") uniform sampler sampler" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
}

string SamplerDescriptor::getShaderVerifyCode (void) const
{
	string ret;

	for (deUint32 i = 0; i < m_arraySize; i++)
	{
		if ((m_data[i].written || m_data[i].copiedInto) && m_images.size() > i)
		{
			// Sample from (-1, -1) to get border color.
			ret += string("if (texture(sampler2D(sampledImage") + de::toString(m_images[i]->getId()) + ", sampler" + de::toString(m_id) + getArrayString(i) + "), vec2(-1)).x != " + de::toString(m_data[i].data[0] % 2) + ") result = 0;\n";
		}
	}

	return ret;
}

DescriptorSet::DescriptorSet (void)
{
}

DescriptorSet::~DescriptorSet (void)
{
}

void DescriptorSet::addBinding (DescriptorSp descriptor)
{
	m_bindings.push_back(descriptor);
}

DescriptorCommands::DescriptorCommands (PipelineType pipelineType)
: m_pipelineType(pipelineType)
{
	// Reset counters
	Descriptor::s_nextId = 0xabc;
	InputAttachmentDescriptor::s_nextAttachmentIndex = 0;
}

DescriptorCommands::~DescriptorCommands (void)
{
}

void DescriptorCommands::addDescriptor (DescriptorSp	descriptor,
										deUint32		descriptorSet)
{
	const VkDescriptorType type = descriptor->getType();

	// Create descriptor set objects until one with the given index exists
	while (m_descriptorSets.size() <= descriptorSet)
		m_descriptorSets.push_back(DescriptorSetSp(new DescriptorSet()));

	m_descriptorSets[descriptorSet]->addBinding(descriptor);

	// Keep track of how many descriptors of each type is needed
	if (m_descriptorCounts.find(type) != m_descriptorCounts.end())
		m_descriptorCounts[type] += descriptor->getArraySize();
	else
		m_descriptorCounts[type] = descriptor->getArraySize();

	// Keep descriptors also in a flat list for easier iteration
	m_descriptors.push_back(descriptor);
}

void DescriptorCommands::copyDescriptor (deUint32	srcSet,
										 deUint32	srcBinding,
										 deUint32	srcArrayElement,
										 deUint32	dstSet,
										 deUint32	dstBinding,
										 deUint32	dstArrayElement,
										 deUint32	descriptorCount)
{
	const DescriptorCopy descriptorCopy = { srcSet, srcBinding, srcArrayElement, dstSet, dstBinding, dstArrayElement, descriptorCount };
	m_descriptorCopies.push_back(descriptorCopy);
	m_descriptorSets[descriptorCopy.dstSet]->getBindings()[descriptorCopy.dstBinding]->copyValue(*m_descriptorSets[descriptorCopy.srcSet]->getBindings()[descriptorCopy.srcBinding], srcArrayElement, dstArrayElement, descriptorCount);
}

// Generates shader source code for declarations of all descriptors
string DescriptorCommands::getShaderDeclarations (void) const
{
	string ret;

	for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
	{
		const vector<DescriptorSp> bindings = m_descriptorSets[descriptorSetIdx]->getBindings();

		for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
		{
			ret += "layout (set=" + de::toString(descriptorSetIdx) + ", binding=" + de::toString(bindingIdx) + bindings[bindingIdx]->getShaderDeclaration();
		}
	}

	return ret;
}

// Generates shader source code for verification of all descriptor data
string DescriptorCommands::getDescriptorVerifications (void) const
{
	string ret;

	for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
	{
		const vector<DescriptorSp> bindings = m_descriptorSets[descriptorSetIdx]->getBindings();

		for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
		{
			if (m_pipelineType == PIPELINE_TYPE_COMPUTE && descriptorSetIdx == 0 && bindingIdx == bindings.size() - 1) continue; // Skip the result buffer which is always the last descriptor of set 0
			ret += bindings[bindingIdx]->getShaderVerifyCode();
		}
	}

	return ret;
}

void DescriptorCommands::addResultBuffer (void)
{
	// Add result buffer if using compute pipeline
	if (m_pipelineType == PIPELINE_TYPE_COMPUTE)
	{
		m_resultBuffer = DescriptorSp(new StorageBufferDescriptor());
		addDescriptor(m_resultBuffer, 0u);
	}
}

// Sets the list of dynamic areas selected for each dynamic descriptor when running the verification shader
void DescriptorCommands::setDynamicAreas (vector<deUint32> areas)
{
	m_dynamicAreas = areas;
	deUint32 areaIdx = 0;

	for (vector<DescriptorSp>::iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
	{
		if ((*desc)->isDynamic())
		{
			vector<deUint32> dynamicAreas;

			for (deUint32 elementIdx = 0; elementIdx < (*desc)->getArraySize(); elementIdx++)
				dynamicAreas.push_back(areas[areaIdx++]);

			(*desc)->setDynamicAreas(dynamicAreas);
		}
	}
}

bool DescriptorCommands::hasDynamicAreas (void) const
{
	for (vector<DescriptorSp>::const_iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
		if ((*desc)->isDynamic())
			return true;

	return false;
}

tcu::TestStatus DescriptorCommands::run (Context& context)
{
	const DeviceInterface&					vk					= context.getDeviceInterface();
    const VkDevice							device				= context.getDevice();
	const VkQueue							queue				= context.getUniversalQueue();
	const VkPhysicalDeviceLimits			limits				= getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice()).limits;
	const deUint32							queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
    Allocator&								allocator			= context.getDefaultAllocator();
	tcu::TestLog&							log					= context.getTestContext().getLog();
	const Unique<VkCommandPool>				commandPool			(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>			commandBuffer		(allocateCommandBuffer(vk, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const VkShaderStageFlags				shaderStage			= m_pipelineType == PIPELINE_TYPE_COMPUTE ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_FRAGMENT_BIT;
	const VkFormat							resultFormat		= VK_FORMAT_R8G8B8A8_UNORM;
	de::MovePtr<ImageWithMemory>			resultImage;
	de::MovePtr<BufferWithMemory>			resultImageBuffer;
	Move<VkImageView>						resultImageView;
	Move<VkRenderPass>						renderPass;
	Move<VkFramebuffer>						framebuffer;
	Move<VkDescriptorPool>					descriptorPool;
	vector<VkDescriptorSetLayoutSp>			descriptorSetLayouts;
	vector<VkDescriptorSet>					descriptorSets;
	Move<VkPipelineLayout>					pipelineLayout;
	Move<VkPipeline>						pipeline;
	vector<VkAttachmentReference>			inputAttachments;
	vector<VkAttachmentDescription>			attachmentDescriptions;
	vector<VkImageView>						imageViews;

	if(limits.maxBoundDescriptorSets <= m_descriptorSets.size())
		TCU_THROW(NotSupportedError, "Maximum bound descriptor sets limit exceeded.");

	// Check physical device limits of per stage and per desriptor set descriptor count
	{
		deUint32	numPerStageSamplers			= 0;
		deUint32	numPerStageUniformBuffers	= 0;
		deUint32	numPerStageStorageBuffers	= 0;
		deUint32	numPerStageSampledImages	= 0;
		deUint32	numPerStageStorageImages	= 0;
		deUint32	numPerStageInputAttachments	= 0;
		deUint32	numPerStageTotalResources	= 0;

		for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
		{
			deUint32					numSamplers					= 0;
			deUint32					numUniformBuffers			= 0;
			deUint32					numUniformBuffersDynamic	= 0;
			deUint32					numStorageBuffers			= 0;
			deUint32					numStorageBuffersDynamic	= 0;
			deUint32					numSampledImages			= 0;
			deUint32					numStorageImages			= 0;
			deUint32					numInputAttachments			= 0;
			deUint32					numTotalResources			= m_pipelineType == PIPELINE_TYPE_GRAPHICS ? 1u : 0u; // Color buffer counts as a resource.

			const vector<DescriptorSp>&	bindings					= m_descriptorSets[descriptorSetIdx]->getBindings();

			for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
			{
				const deUint32 arraySize = bindings[bindingIdx]->getArraySize();

				numTotalResources += arraySize;

				switch (bindings[bindingIdx]->getType())
				{
					case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
						numUniformBuffers += arraySize;
						break;

					case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
						numUniformBuffers += arraySize;
						numUniformBuffersDynamic += arraySize;
						break;

					case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
						numStorageBuffers += arraySize;
						break;

					case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
						numStorageBuffers += arraySize;
						numStorageBuffersDynamic += arraySize;
						break;

					case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
						numSamplers += arraySize;
						numSampledImages += arraySize;
						break;

					case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
					case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
						numStorageImages += arraySize;
						break;

					case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
						numInputAttachments += arraySize;
						break;

					case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
					case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
						numSampledImages += arraySize;
						break;

					case VK_DESCRIPTOR_TYPE_SAMPLER:
						numSamplers += arraySize;
						break;

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

			if (numSamplers > limits.maxDescriptorSetSamplers)
				TCU_THROW(NotSupportedError, "Maximum per descriptor set sampler limit exceeded.");

			if (numUniformBuffers > limits.maxDescriptorSetUniformBuffers)
				TCU_THROW(NotSupportedError, "Maximum per descriptor set uniform buffer limit exceeded.");

			if (numUniformBuffersDynamic > limits.maxDescriptorSetUniformBuffersDynamic)
				TCU_THROW(NotSupportedError, "Maximum per descriptor set uniform buffer dynamic limit exceeded.");

			if (numStorageBuffers > limits.maxDescriptorSetStorageBuffers)
				TCU_THROW(NotSupportedError, "Maximum per descriptor set storage buffer limit exceeded.");

			if (numStorageBuffersDynamic > limits.maxDescriptorSetStorageBuffersDynamic)
				TCU_THROW(NotSupportedError, "Maximum per descriptor set storage buffer dynamic limit exceeded.");

			if (numSampledImages > limits.maxDescriptorSetSampledImages)
				TCU_THROW(NotSupportedError, "Maximum per descriptor set sampled image limit exceeded.");

			if (numStorageImages > limits.maxDescriptorSetStorageImages)
				TCU_THROW(NotSupportedError, "Maximum per descriptor set storage image limit exceeded.");

			if (numInputAttachments > limits.maxDescriptorSetInputAttachments)
				TCU_THROW(NotSupportedError, "Maximum per descriptor set input attachment limit exceeded.");

			numPerStageSamplers			+= numSamplers;
			numPerStageUniformBuffers	+= numUniformBuffers;
			numPerStageStorageBuffers	+= numStorageBuffers;
			numPerStageSampledImages	+= numSampledImages;
			numPerStageStorageImages	+= numStorageImages;
			numPerStageInputAttachments	+= numInputAttachments;
			numPerStageTotalResources	+= numTotalResources;
		}

		if (numPerStageTotalResources > limits.maxPerStageResources)
			TCU_THROW(NotSupportedError, "Maximum per stage total resource limit exceeded.");

		if (numPerStageSamplers > limits.maxPerStageDescriptorSamplers)
			TCU_THROW(NotSupportedError, "Maximum per stage sampler limit exceeded.");

		if (numPerStageUniformBuffers > limits.maxPerStageDescriptorUniformBuffers)
			TCU_THROW(NotSupportedError, "Maximum per stage uniform buffer limit exceeded.");

		if (numPerStageStorageBuffers > limits.maxPerStageDescriptorStorageBuffers)
			TCU_THROW(NotSupportedError, "Maximum per stage storage buffer limit exceeded.");

		if (numPerStageSampledImages > limits.maxPerStageDescriptorSampledImages)
			TCU_THROW(NotSupportedError, "Maximum per stage sampled image limit exceeded.");

		if (numPerStageStorageImages > limits.maxPerStageDescriptorStorageImages)
			TCU_THROW(NotSupportedError, "Maximum per stage storage image limit exceeded.");

		if (numPerStageInputAttachments > limits.maxPerStageDescriptorInputAttachments)
			TCU_THROW(NotSupportedError, "Maximum per stage input attachment limit exceeded.");
	}

	// Initialize all descriptors
	for (vector<DescriptorSp>::iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
		(*desc)->init(context, m_pipelineType);

	// Create descriptor pool
	{
		vector<VkDescriptorPoolSize>		poolSizes;

		for (map<VkDescriptorType, deUint32>::iterator i = m_descriptorCounts.begin(); i != m_descriptorCounts.end(); i++)
		{
			const VkDescriptorPoolSize	poolSize	=
			{
				i->first,	// VkDescriptorType	type
				i->second	// deUint32			descriptorCount
			};

			poolSizes.push_back(poolSize);
		}

		const VkDescriptorPoolCreateInfo	descriptorPoolCreateInfo	=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,		// VkStructureType				sType
			DE_NULL,											// const void*					pNext
			VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,	// VkDescriptorPoolCreateFlags	flags
			(deUint32)m_descriptorSets.size(),					// deUint32						maxSets
			(deUint32)poolSizes.size(),							// deUint32						poolSizeCount
			poolSizes.data(),									// const VkDescriptorPoolSize*	pPoolSizes
		};

		descriptorPool = createDescriptorPool(vk, device, &descriptorPoolCreateInfo);
	}

	// Create descriptor set layouts. One for each descriptor set used in this test.
	{
		for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
		{
			vector<VkDescriptorSetLayoutBinding>	layoutBindings;
			const vector<DescriptorSp>&				bindings	= m_descriptorSets[descriptorSetIdx]->getBindings();

			for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
			{
				const VkDescriptorSetLayoutBinding	layoutBinding	=
				{
					(deUint32)bindingIdx,					// deUint32				binding
					bindings[bindingIdx]->getType(),		// VkDescriptorType		descriptorType
					bindings[bindingIdx]->getArraySize(),	// deUint32				descriptorCount
					shaderStage,							// VkShaderStageFlags	stageFlags
					DE_NULL									// const VkSampler*		pImmutableSamplers
				};

				layoutBindings.push_back(layoutBinding);
			}

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

			descriptorSetLayouts.push_back(VkDescriptorSetLayoutSp(new Unique<VkDescriptorSetLayout>(createDescriptorSetLayout(vk, device, &descriptorSetLayoutCreateInfo, DE_NULL))));
		}
	}

	// Create descriptor sets
	{
		for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
		{
			const VkDescriptorSetAllocateInfo	descriptorSetAllocateInfo	=
			{
				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType
				DE_NULL,											// const void*					pNext
				*descriptorPool,									// VkDescriptorPool				descriptorPool
				1u,													// deUint32						descriptorSetCount
				&(descriptorSetLayouts[descriptorSetIdx]->get())	// const VkDescriptorSetLayout*	pSetLayouts
			};

			VkDescriptorSet descriptorSet = 0;
			VK_CHECK(vk.allocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet));
			descriptorSets.push_back(descriptorSet);
		}
	}

	// Descriptor writes and updates
	{
		vector<VkWriteDescriptorSet>	descriptorWrites;
		vector<VkCopyDescriptorSet>		descriptorCopies;

		// Write descriptors that are marked as needing initialization
		for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
		{
			const vector<DescriptorSp>& bindings = m_descriptorSets[descriptorSetIdx]->getBindings();

			for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
			{
				VkWriteDescriptorSet descriptorWrite = bindings[bindingIdx]->getDescriptorWrite();

				descriptorWrite.dstSet		= descriptorSets[descriptorSetIdx];
				descriptorWrite.dstBinding	= (deUint32)bindingIdx;

				if (descriptorWrite.descriptorCount > 0)
					descriptorWrites.push_back(descriptorWrite);
			}
		}

		for (size_t copyIdx = 0; copyIdx < m_descriptorCopies.size(); copyIdx++)
		{
			const DescriptorCopy		indices	= m_descriptorCopies[copyIdx];
			const VkCopyDescriptorSet	copy	=
			{
				VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET,	// VkStructureType	sType
				DE_NULL,								// const void*		pNext
				descriptorSets[indices.srcSet],			// VkDescriptorSet	srcSet
				indices.srcBinding,						// deUint32			srcBinding
				indices.srcArrayElement,				// deUint32			srcArrayElement
				descriptorSets[indices.dstSet],			// VkDescriptorSet	dstSet
				indices.dstBinding,						// deUint32			dstBinding
				indices.dstArrayElement,				// deUint32			dstArrayElement
				indices.descriptorCount					// deUint32			descriptorCount
			};

			descriptorCopies.push_back(copy);
		}

		// Update descriptors with writes and copies
		vk.updateDescriptorSets(device, (deUint32)descriptorWrites.size(), descriptorWrites.data(), (deUint32)descriptorCopies.size(), descriptorCopies.data());
	}

	// Create pipeline layout
	{
		vector<VkDescriptorSetLayout>		descriptorSetLayoutHandles;

		for (size_t i = 0; i < descriptorSetLayouts.size(); i++)
			descriptorSetLayoutHandles.push_back(descriptorSetLayouts[i]->get());

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

		pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
	}

	if (m_pipelineType == PIPELINE_TYPE_COMPUTE)
	{
		// Create compute pipeline
		{
			const Unique<VkShaderModule>			shaderModule	(createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0u));
			const VkPipelineShaderStageCreateInfo	shaderStageInfo	=
			{
				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType
				DE_NULL,												// const void*						pNext
				(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags	flags
				VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage
				*shaderModule,											// VkShaderModule					module
				"main",													// const char*						pName
				DE_NULL													// const VkSpecializationInfo*		pSpecializationInfo
			};

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

			pipeline = createComputePipeline(vk, device, DE_NULL, &pipelineInfo);
		}
	}
	else
	{
		// Create result image
		{
			const VkImageCreateInfo imageCreateInfo =
			{
				VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,						// VkStructureType			stype
				DE_NULL,													// const void*				pNext
				0u,															// VkImageCreateFlags		flags
				VK_IMAGE_TYPE_2D,											// VkImageType				imageType
				resultFormat,												// VkFormat					format
				{ (deUint32)renderSize.x(), (deUint32)renderSize.y(), 1 },	// VkExtent3D				extent
				1u,															// deUint32					mipLevels
				1u,															// deUint32					arrayLayers
				VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits	samples
				VK_IMAGE_TILING_OPTIMAL,									// VkImageTiling			tiling
				VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
				| VK_IMAGE_USAGE_TRANSFER_SRC_BIT,							// VkImageUsageFlags		usage
				VK_SHARING_MODE_EXCLUSIVE,									// VkSharingMode			sharingMode
				1u,															// deUint32					queueFamilyIndexCount
				&queueFamilyIndex,											// const deUint32*			pQueueFamilyIndices
				VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout			initialLayout
			};

			resultImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
		}

		// Create result image view
		{
			const VkComponentMapping		componentMapping	= makeComponentMappingRGBA();

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

			const VkImageViewCreateInfo		imageViewCreateInfo	=
			{
				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
				DE_NULL,									// const void*				pNext
				0u,											// VkImageViewCreateFlags	flags
				**resultImage,								// VkImage					image
				VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
				resultFormat,								// VkFormat					format
				componentMapping,							// VkComponentMapping		components
				subresourceRange							// VkImageSubresourceRange	subresourceRange
			};

			resultImageView = createImageView(vk, device, &imageViewCreateInfo);
		}

		// Create result buffer
		{
			const VkDeviceSize			bufferSize			= renderSize.x() * renderSize.y() * tcu::getPixelSize(mapVkFormat(resultFormat));
			const VkBufferCreateInfo	bufferCreateInfo	=
			{
				VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
				DE_NULL,								// const void*			pNext
				0u,										// VkBufferCreateFlags	flags
				bufferSize,								// VkDeviceSize			size
				VK_BUFFER_USAGE_TRANSFER_DST_BIT,		// VkBufferUsageFlags	usage
				VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
				0u,										// uint32_t				queueFamilyIndexCount
				DE_NULL									// const uint32_t*		pQueueFamilyIndices
			};

			resultImageBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
		}

		// Create render pass
		{
			const VkAttachmentReference		colorAttachmentRef		=
			{
				0u,											// deUint32			attachment
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
			};

			for (vector<DescriptorSp>::const_iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
			{
				vector<VkAttachmentReference> references = (*desc)->getAttachmentReferences();
				inputAttachments.insert(inputAttachments.end(), references.begin(), references.end());
			}

			const VkAttachmentDescription	colorAttachmentDesc		=
			{
				0u,											// 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
			};

			attachmentDescriptions.push_back(colorAttachmentDesc);

			const VkAttachmentDescription	inputAttachmentDesc		=
			{
				0u,											// VkAttachmentDescriptionFlags	flags
				VK_FORMAT_R32_SFLOAT,						// VkFormat						format
				VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits		samples
				VK_ATTACHMENT_LOAD_OP_LOAD,					// VkAttachmentLoadOp			loadOp
				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// 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
			};

			for (size_t inputAttachmentIdx = 0; inputAttachmentIdx < inputAttachments.size(); inputAttachmentIdx++)
				attachmentDescriptions.push_back(inputAttachmentDesc);

			const VkSubpassDescription		subpassDescription		=
			{
				0u,																// VkSubpassDescriptionFlags	flags
				VK_PIPELINE_BIND_POINT_GRAPHICS,								// VkPipelineBindPoint			pipelineBindPoint
				(deUint32)inputAttachments.size(),								// deUint32						inputAttachmentCount
				inputAttachments.empty() ? DE_NULL : inputAttachments.data(),	// const VkAttachmentReference*	pInputAttachments
				1u,																// deUint32						colorAttachmentCount
				&colorAttachmentRef,											// const VkAttachmentReference*	pColorAttachments
				DE_NULL,														// const VkAttachmentReference*	pResolveAttachments
				DE_NULL,														// const VkAttachmentReference*	pDepthStencilAttachment
				0u,																// deUint32						preserveAttachmentCount
				DE_NULL															// const deUint32*				pPreserveAttachments
			};

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

			renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
		}

		// Create framebuffer
		{
			imageViews.push_back(*resultImageView);

			// Add input attachment image views
			for (vector<DescriptorSp>::const_iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
			{
				vector<VkImageViewSp> inputAttachmentViews = (*desc)->getImageViews();

				for (size_t imageViewIdx = 0; imageViewIdx < inputAttachmentViews.size(); imageViewIdx++)
					imageViews.push_back(**inputAttachmentViews[imageViewIdx]);
			}

			const VkFramebufferCreateInfo	framebufferCreateInfo	=
			{
				VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType             sType
				DE_NULL,									// const void*                 pNext
				0u,											// VkFramebufferCreateFlags    flags
				*renderPass,								// VkRenderPass                renderPass
				(deUint32)imageViews.size(),				// deUint32                    attachmentCount
				imageViews.data(),							// const VkImageView*          pAttachments
				(deUint32)renderSize.x(),					// deUint32                    width
				(deUint32)renderSize.y(),					// deUint32                    height
				1u,											// deUint32                    layers
			};

			framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
		}

		// Create graphics pipeline
		{
			const Unique<VkShaderModule>					vertexShaderModule		(createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0u));
			const Unique<VkShaderModule>					fragmentShaderModule	(createShaderModule(vk, device, context.getBinaryCollection().get("fragment"), 0u));

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

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

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

	// Run verification shader
	{
		const VkPipelineBindPoint	pipelineBindPoint	= m_pipelineType == PIPELINE_TYPE_COMPUTE ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
		vector<deUint32>			offsets;

		if (hasDynamicAreas())
		{
			for (size_t areaIdx = 0; areaIdx < m_dynamicAreas.size(); areaIdx++)
				offsets.push_back(m_dynamicAreas[areaIdx] * 256u);
		}

		beginCommandBuffer(vk, *commandBuffer);

		if (m_pipelineType == PIPELINE_TYPE_GRAPHICS)
		{
			const VkRect2D  renderArea  = makeRect2D(renderSize);
			const tcu::Vec4 clearColor  (1.0f, 0.0f, 0.0f, 1.0f);

			beginRenderPass(vk, *commandBuffer, *renderPass, *framebuffer, renderArea, clearColor);
		}

		vk.cmdBindPipeline(*commandBuffer, pipelineBindPoint, *pipeline);
		vk.cmdBindDescriptorSets(*commandBuffer, pipelineBindPoint, *pipelineLayout, 0u, (deUint32)descriptorSets.size(), descriptorSets.data(), (deUint32)offsets.size(), offsets.empty() ? DE_NULL : offsets.data());

		if (m_pipelineType == PIPELINE_TYPE_COMPUTE)
		{
			vk.cmdDispatch(*commandBuffer, 1u, 1u, 1u);
		}
		else
		{
			vk.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
			endRenderPass(vk, *commandBuffer);
			copyImageToBuffer(vk, *commandBuffer, **resultImage, resultImageBuffer->get(), renderSize);
		}

		endCommandBuffer(vk, *commandBuffer);
		submitCommandsAndWait(vk, device, queue, *commandBuffer);
	}

	if (m_pipelineType == PIPELINE_TYPE_COMPUTE)
	{
		// Invalidate result buffer
		m_resultBuffer->invalidate(context);

		// Verify result data
		if (m_resultBuffer->getData()[0] == 1)
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Data validation failed");
	}
	else
	{
		invalidateAlloc(vk, device, resultImageBuffer->getAllocation());

		// Verify result image
		tcu::ConstPixelBufferAccess	resultBufferAccess(mapVkFormat(resultFormat), renderSize.x(), renderSize.y(), 1, resultImageBuffer->getAllocation().getHostPtr());

		for (deInt32 y = 0; y < renderSize.y(); y++)
			for (deInt32 x = 0; x < renderSize.x(); x++)
			{
				Vec4 pixel = resultBufferAccess.getPixel(x, y, 0);

				if (pixel.x() != 0.0f || pixel.y() != 1.0f || pixel.z() != 0.0f || pixel.w() != 1.0f)
				{
					// Log result image before failing.
					log << tcu::TestLog::ImageSet("Result", "") << tcu::TestLog::Image("Rendered", "Rendered image", resultBufferAccess) << tcu::TestLog::EndImageSet;
					return tcu::TestStatus::fail("Result image validation failed");
				}
			}

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

DescriptorCopyTestInstance::DescriptorCopyTestInstance (Context&				context,
														DescriptorCommandsSp	commands)
: vkt::TestInstance	(context)
, m_commands		(commands)
{
}

DescriptorCopyTestInstance::~DescriptorCopyTestInstance (void)
{
}

DescriptorCopyTestCase::DescriptorCopyTestCase (tcu::TestContext&		context,
												const char*				name,
												const char*				desc,
												DescriptorCommandsSp	commands)
: vkt::TestCase	(context, name, desc)
, m_commands	(commands)
{
}

DescriptorCopyTestCase::~DescriptorCopyTestCase (void)
{
}

void DescriptorCopyTestCase::initPrograms (SourceCollections& programCollection) const
{
	if (m_commands->getPipelineType() == PIPELINE_TYPE_COMPUTE)
	{
		string computeSrc =
			"#version 430\n"
			"\n"
			+ m_commands->getShaderDeclarations() +
			"\n"
			"void main()\n"
			"{\n"
			"int result = 1;\n"
			+ m_commands->getDescriptorVerifications() +
			"storageBuffer" + de::toString(m_commands->getResultBufferId()) + ".data = result;\n"
			"}\n";

		programCollection.glslSources.add("compute") << glu::ComputeSource(computeSrc);
	}
	else
	{
		// Produce quad vertices using vertex index
		string vertexSrc =
			"#version 450\n"
			"out gl_PerVertex\n"
			"{\n"
			"    vec4 gl_Position;\n"
			"};\n"
			"void main()\n"
			"{\n"
			"    gl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
			"                       ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
			"}\n";

		programCollection.glslSources.add("vertex") << glu::VertexSource(vertexSrc);

		string fragmentSrc =
			"#version 430\n"
			"\n"
			+ m_commands->getShaderDeclarations() +
			"layout (location = 0) out vec4 outColor;\n"
			"\n"
			"void main()\n"
			"{\n"
			"int result = 1;\n"
			+ m_commands->getDescriptorVerifications() +
			"if (result == 1) outColor = vec4(0, 1, 0, 1);\n"
			"else outColor = vec4(1, 0, 1, 0);\n"
			"}\n";

		programCollection.glslSources.add("fragment") << glu::FragmentSource(fragmentSrc);
	}
}

TestInstance* DescriptorCopyTestCase::createInstance (Context& context) const
{
	return new DescriptorCopyTestInstance(context, m_commands);
}

tcu::TestStatus DescriptorCopyTestInstance::iterate (void)
{
	return m_commands->run(m_context);
}

template<class T>
void addDescriptorCopyTests (tcu::TestContext&					testCtx,
							 de::MovePtr<tcu::TestCaseGroup>&	group,
							 string								name,
							 PipelineType						pipelineType)
{
	// Simple test copying inside the same set.
	{
		DescriptorCommandsSp commands (new DescriptorCommands(pipelineType));
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 0u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 0u);

		commands->copyDescriptor(0u, 0u,	// from
								 0u, 1u);	// to

		vector<deUint32> dynamicAreas;
		dynamicAreas.push_back(2u);
		dynamicAreas.push_back(1u);
		commands->setDynamicAreas(dynamicAreas);

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_0").c_str(), "", commands));
	}

	// Simple test copying between different sets.
	{
		DescriptorCommandsSp commands (new DescriptorCommands(pipelineType));
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 0u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 4u)), 1u);

		commands->copyDescriptor(0u, 0u,	// from
								 1u, 0u);	// to

		vector<deUint32> dynamicAreas;
		dynamicAreas.push_back(0u);
		dynamicAreas.push_back(1u);
		commands->setDynamicAreas(dynamicAreas);

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_1").c_str(), "", commands));
	}

	// Simple test copying between different sets. Destination not updated.
	{
		DescriptorCommandsSp commands (new DescriptorCommands(pipelineType));
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 0u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 0u, 1u)), 1u);

		commands->copyDescriptor(0u, 0u,	// from
								 1u, 0u);	// to

		vector<deUint32> dynamicAreas;
		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(0u);
		commands->setDynamicAreas(dynamicAreas);

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_2").c_str(), "", commands));
	}

	// Five sets and several copies.
	{
		DescriptorCommandsSp commands (new DescriptorCommands(pipelineType));
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 0u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 4u)), 0u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 1u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 1u)), 1u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 1u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 5u)), 4u);

		commands->copyDescriptor(4u, 0u,	// from
								 0u, 0u);	// to

		commands->copyDescriptor(0u, 1u,	// from
								 1u, 2u);	// to

		commands->copyDescriptor(0u, 1u,	// from
								 1u, 1u);	// to

		vector<deUint32> dynamicAreas;
		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(0u);
		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(0u);
		dynamicAreas.push_back(0u);
		dynamicAreas.push_back(4u);
		commands->setDynamicAreas(dynamicAreas);

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_3").c_str(), "", commands));
	}

	// Several identical copies
	{
		DescriptorCommandsSp commands (new DescriptorCommands(pipelineType));
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 0u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 4u)), 1u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 1u);

		for (deUint32 i = 0; i < 100; i++)
		{
			commands->copyDescriptor(0u, 0u,	// from
									 1u, 0u);	// to
		}

		commands->copyDescriptor(1u, 1u,	// from
								 0u, 0u);	// to

		for (deUint32 i = 0; i < 100; i++)
		{
			commands->copyDescriptor(1u, 0u,	// from
									 1u, 1u);	// to
		}

		vector<deUint32> dynamicAreas;
		dynamicAreas.push_back(0u);
		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(1u);
		commands->setDynamicAreas(dynamicAreas);

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_4").c_str(), "", commands));
	}

	// Copy descriptors back and forth
	{
		DescriptorCommandsSp commands (new DescriptorCommands(pipelineType));
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 0u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 1u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 1u);

		commands->copyDescriptor(0u, 0u,	// from
								 1u, 0u);	// to

		commands->copyDescriptor(1u, 0u,	// from
								 0u, 0u);	// to

		commands->copyDescriptor(1u, 1u,	// from
								 0u, 0u);	// to

		commands->copyDescriptor(1u, 1u,	// from
								 0u, 0u);	// to

		commands->copyDescriptor(1u, 0u,	// from
								 1u, 1u);	// to

		vector<deUint32> dynamicAreas;
		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(0u);
		dynamicAreas.push_back(0u);
		commands->setDynamicAreas(dynamicAreas);

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_5").c_str(), "", commands));
	}

	// Copy between non-consecutive descriptor sets
	{
		DescriptorCommandsSp commands (new DescriptorCommands(pipelineType));
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 0u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 5u);
		commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 5u);

		commands->copyDescriptor(0u, 0u,	// from
								 5u, 1u);	// to

		vector<deUint32> dynamicAreas;
		dynamicAreas.push_back(2u);
		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(1u);
		commands->setDynamicAreas(dynamicAreas);

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_6").c_str(), "", commands));
	}

	// Simple 3 sized array to 3 sized array inside the same set.
	{
		DescriptorCommandsSp commands (new DescriptorCommands(pipelineType));
		commands->addDescriptor(DescriptorSp(new T(3u, 0u, 3u, 3u)), 0u);
		commands->addDescriptor(DescriptorSp(new T(3u, 0u, 3u, 4u)), 0u);

		commands->copyDescriptor(0u, 0u, 0u,	// from
								 0u, 1u, 0u,	// to
								 3u);			// num descriptors


		vector<deUint32> dynamicAreas;
		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(0u);
		dynamicAreas.push_back(2u);

		dynamicAreas.push_back(2u);
		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(0u);
		commands->setDynamicAreas(dynamicAreas);

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_array0").c_str(), "", commands));
	}

	// Simple 2 sized array to 3 sized array into different set.
	{
		DescriptorCommandsSp commands (new DescriptorCommands(pipelineType));
		commands->addDescriptor(DescriptorSp(new T(2u, 0u, 2u, 2u)), 0u);
		commands->addDescriptor(DescriptorSp(new T(3u, 0u, 3u, 5u)), 1u);

		commands->copyDescriptor(0u, 0u, 0u,	// from
								 1u, 0u, 0u,	// to
								 2u);			// num descriptors

		vector<deUint32> dynamicAreas;
		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(0u);

		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(0u);
		dynamicAreas.push_back(1u);
		commands->setDynamicAreas(dynamicAreas);

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_array1").c_str(), "", commands));
	}

	// Update array partially with writes and partially with a copy
	{
		DescriptorCommandsSp commands (new DescriptorCommands(pipelineType));
		commands->addDescriptor(DescriptorSp(new T(4u, 0u, 4u, 3u)), 0u);
		commands->addDescriptor(DescriptorSp(new T(8u, 0u, 5u, 4u)), 0u);

		commands->copyDescriptor(0u, 0u, 1u,	// from
								 0u, 1u, 5u,	// to
								 3u);			// num descriptors

		vector<deUint32> dynamicAreas;
		dynamicAreas.push_back(2u);
		dynamicAreas.push_back(0u);
		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(1u);

		dynamicAreas.push_back(2u);
		dynamicAreas.push_back(0u);
		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(2u);
		dynamicAreas.push_back(0u);
		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(1u);
		dynamicAreas.push_back(2u);
		commands->setDynamicAreas(dynamicAreas);

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_array2").c_str(), "", commands));
	}
}

void addSamplerCopyTests (tcu::TestContext&					testCtx,
						  de::MovePtr<tcu::TestCaseGroup>&	group,
						  PipelineType						pipelineType)
{
	// Simple copy between two samplers in the same set
	{
		DescriptorCommandsSp	commands	(new DescriptorCommands(pipelineType));
		SamplerDescriptor*		sampler0	(new SamplerDescriptor());
		SamplerDescriptor*		sampler1	(new SamplerDescriptor());
		SampledImageDescriptor*	image		(new SampledImageDescriptor());
		sampler0->addImage(image);
		sampler1->addImage(image);

		commands->addDescriptor(DescriptorSp(sampler0), 0u);
		commands->addDescriptor(DescriptorSp(sampler1), 0u);
		commands->addDescriptor(DescriptorSp(image), 0u);

		commands->copyDescriptor(0u, 0u,	// from
								 0u, 1u);	// to

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, "sampler_0", "", commands));
	}

	// Simple 3 sized array to 3 sized array inside the same set.
	{
		DescriptorCommandsSp	commands	(new DescriptorCommands(pipelineType));
		SamplerDescriptor*		sampler0	(new SamplerDescriptor(3u, 0u, 3u));
		// One sampler in between to get the border colors to originally mismatch between sampler0 and sampler1.
		SamplerDescriptor*		sampler1	(new SamplerDescriptor());
		SamplerDescriptor*		sampler2	(new SamplerDescriptor(3u, 0u, 3u));
		SampledImageDescriptor*	image		(new SampledImageDescriptor());

		sampler0->addImage(image, 3u);
		sampler2->addImage(image, 3u);

		commands->addDescriptor(DescriptorSp(sampler0), 0u);
		commands->addDescriptor(DescriptorSp(sampler1), 0u);
		commands->addDescriptor(DescriptorSp(sampler2), 0u);
		commands->addDescriptor(DescriptorSp(image), 0u);

		commands->copyDescriptor(0u, 0u, 0u,	// from
								 0u, 2u, 0u,	// to
								 3u);			// num descriptors

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, "sampler_array0", "", commands));
	}

	// Simple 2 sized array to 3 sized array into different set.
	{
		DescriptorCommandsSp	commands	(new DescriptorCommands(pipelineType));
		SamplerDescriptor*		sampler0	(new SamplerDescriptor(2u, 0u, 2u));
		SamplerDescriptor*		sampler1	(new SamplerDescriptor(3u, 0u, 3u));
		SampledImageDescriptor*	image		(new SampledImageDescriptor());

		sampler0->addImage(image, 2u);
		sampler1->addImage(image, 3u);

		commands->addDescriptor(DescriptorSp(sampler0), 0u);
		commands->addDescriptor(DescriptorSp(sampler1), 1u);
		commands->addDescriptor(DescriptorSp(image), 0u);

		commands->copyDescriptor(0u, 0u, 0u,	// from
								 1u, 0u, 1u,	// to
								 2u);			// num descriptors

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, "sampler_array1", "", commands));
	}
}

void addSampledImageCopyTests (tcu::TestContext&				testCtx,
							   de::MovePtr<tcu::TestCaseGroup>&	group,
							   PipelineType						pipelineType)
{
	// Simple copy between two images in the same set
	{
		DescriptorCommandsSp	commands	(new DescriptorCommands(pipelineType));
		SamplerDescriptor*		sampler		(new SamplerDescriptor());
		SampledImageDescriptor*	image0		(new SampledImageDescriptor());
		SampledImageDescriptor*	image1		(new SampledImageDescriptor());
		image0->addSampler(sampler);
		image1->addSampler(sampler);

		commands->addDescriptor(DescriptorSp(image0), 0u);
		commands->addDescriptor(DescriptorSp(image1), 0u);
		commands->addDescriptor(DescriptorSp(sampler), 0u);

		commands->copyDescriptor(0u, 0u,	// from
								 0u, 1u);	// to

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, "sampled_image_0", "", commands));
	}

	// Simple 3 sized array to 3 sized array inside the same set.
	{
		DescriptorCommandsSp	commands	(new DescriptorCommands(pipelineType));
		SamplerDescriptor*		sampler		(new SamplerDescriptor());
		SampledImageDescriptor*	image0		(new SampledImageDescriptor(3u, 0u, 3u));
		SampledImageDescriptor*	image1		(new SampledImageDescriptor(3u, 0u, 3u));
		image0->addSampler(sampler, 3u);
		image1->addSampler(sampler, 3u);

		commands->addDescriptor(DescriptorSp(sampler), 0u);
		commands->addDescriptor(DescriptorSp(image0), 0u);
		commands->addDescriptor(DescriptorSp(image1), 0u);

		commands->copyDescriptor(0u, 1u, 0u,	// from
								 0u, 2u, 0u,	// to
								 3u);			// num descriptors

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, "sampled_image_array0", "", commands));
	}
}

// Mixture of different descriptors in the same test
void addMixedDescriptorCopyTests (tcu::TestContext&					testCtx,
								  de::MovePtr<tcu::TestCaseGroup>&	group,
								  PipelineType						pipelineType)
{
	{
		DescriptorCommandsSp		commands		(new DescriptorCommands(pipelineType));
		SamplerDescriptor*			sampler0		(new SamplerDescriptor());
		SamplerDescriptor*			sampler1		(new SamplerDescriptor());
		SampledImageDescriptor*		image0			(new SampledImageDescriptor());
		SampledImageDescriptor*		image1			(new SampledImageDescriptor());
		StorageBufferDescriptor*	storageBuffer0	(new StorageBufferDescriptor());
		StorageBufferDescriptor*	storageBuffer1	(new StorageBufferDescriptor());
		StorageBufferDescriptor*	storageBuffer2	= new StorageBufferDescriptor();
		sampler0->addImage(image0);
		sampler1->addImage(image1);

		commands->addDescriptor(DescriptorSp(sampler0), 0u);		// Set 0, binding 0
		commands->addDescriptor(DescriptorSp(storageBuffer0), 0u);	// Set 0, binding 1
		commands->addDescriptor(DescriptorSp(image0), 0u);			// Set 0, binding 2
		commands->addDescriptor(DescriptorSp(storageBuffer1), 0u);	// Set 0, binding 3
		commands->addDescriptor(DescriptorSp(sampler1), 1u);		// Set 1, binding 0
		commands->addDescriptor(DescriptorSp(image1), 1u);			// Set 1, binding 1
		commands->addDescriptor(DescriptorSp(storageBuffer2), 1u);	// Set 1, binding 2

		// image1 to image0
		commands->copyDescriptor(1u, 1u,	// from
								 0u, 2u);	// to

		// storageBuffer0 to storageBuffer1
		commands->copyDescriptor(0u, 1u,	// from
								 0u, 3u);	// to

		// storageBuffer1 to storageBuffer2
		commands->copyDescriptor(0u, 3u,	// from
								 1u, 2u);	// to

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, "mix_0", "", commands));
	}

	{
		DescriptorCommandsSp			commands				(new DescriptorCommands(pipelineType));
		StorageTexelBufferDescriptor*	storageTexelBuffer0		(new StorageTexelBufferDescriptor());
		StorageTexelBufferDescriptor*	storageTexelBuffer1		(new StorageTexelBufferDescriptor());
		UniformBufferDescriptor*		uniformBuffer0			(new UniformBufferDescriptor());
		UniformBufferDescriptor*		uniformBuffer1			(new UniformBufferDescriptor());
		UniformBufferDescriptor*		uniformBuffer2			(new UniformBufferDescriptor());
		DynamicStorageBufferDescriptor*	dynamicStorageBuffer0	(new DynamicStorageBufferDescriptor(1u, 0u, 1u, 3u));
		DynamicStorageBufferDescriptor*	dynamicStorageBuffer1	(new DynamicStorageBufferDescriptor(1u, 0u, 1u, 4u));

		commands->addDescriptor(DescriptorSp(storageTexelBuffer0), 0u);		// Set 0, binding 0
		commands->addDescriptor(DescriptorSp(uniformBuffer0), 0u);			// Set 0, binding 1
		commands->addDescriptor(DescriptorSp(dynamicStorageBuffer0), 0u);	// Set 0, binding 2
		commands->addDescriptor(DescriptorSp(uniformBuffer1), 0u);			// Set 0, binding 3
		commands->addDescriptor(DescriptorSp(dynamicStorageBuffer1), 1u);	// Set 1, binding 0
		commands->addDescriptor(DescriptorSp(storageTexelBuffer1), 1u);		// Set 1, binding 1
		commands->addDescriptor(DescriptorSp(uniformBuffer2), 1u);			// Set 1, binding 2

		vector<deUint32> dynamicAreas;
		dynamicAreas.push_back(2u);
		dynamicAreas.push_back(1u);
		commands->setDynamicAreas(dynamicAreas);

		// uniformBuffer0 to uniformBuffer2
		commands->copyDescriptor(0u, 1u,	// from
								 1u, 2u);	// to

		// uniformBuffer1 to uniformBuffer2
		commands->copyDescriptor(0u, 3u,	// from
								 1u, 2u);	// to

		// storageTexelBuffer1 to storageTexelBuffer0
		commands->copyDescriptor(1u, 1u,	// from
								 0u, 0u);	// to

		// dynamicStorageBuffer0 to dynamicStorageBuffer1
		commands->copyDescriptor(0u, 2u,	// from
								 1u, 0u);	// to

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, "mix_1", "", commands));
	}

	if (pipelineType == PIPELINE_TYPE_GRAPHICS)
	{
		// Mixture of descriptors, including input attachment.
		DescriptorCommandsSp			commands				(new DescriptorCommands(pipelineType));
		InputAttachmentDescriptor*		inputAttachment0		(new InputAttachmentDescriptor());
		InputAttachmentDescriptor*		inputAttachment1		(new InputAttachmentDescriptor());
		CombinedImageSamplerDescriptor*	combinedImageSampler0	(new CombinedImageSamplerDescriptor());
		CombinedImageSamplerDescriptor*	combinedImageSampler1	(new CombinedImageSamplerDescriptor());
		UniformTexelBufferDescriptor*	uniformTexelBuffer0		(new UniformTexelBufferDescriptor(5u, 0u, 5u));
		UniformTexelBufferDescriptor*	uniformTexelBuffer1		(new UniformTexelBufferDescriptor(3u, 1u, 1u));

		commands->addDescriptor(DescriptorSp(combinedImageSampler0), 0u);	// Set 0, binding 0
		commands->addDescriptor(DescriptorSp(inputAttachment0), 0u);		// Set 0, binding 1
		commands->addDescriptor(DescriptorSp(uniformTexelBuffer0), 0u);		// Set 0, binding 2
		commands->addDescriptor(DescriptorSp(combinedImageSampler1), 1u);	// Set 1, binding 0
		commands->addDescriptor(DescriptorSp(inputAttachment1), 1u);		// Set 1, binding 1
		commands->addDescriptor(DescriptorSp(uniformTexelBuffer1), 1u);		// Set 1, binding 2

		// uniformTexelBuffer0[1..3] to uniformTexelBuffer1[0..2]
		commands->copyDescriptor(0u, 2u, 1u,	// from
								 1u, 2u, 0u,	// to
								 3u);			// num descriptors

		// inputAttachment0 to inputAttachment1
		commands->copyDescriptor(0u, 1u,	// from
								 1u, 1u);	// to

		// combinedImageSampler0 to combinedImageSampler1
		commands->copyDescriptor(0u, 0u,	// from
								 1u, 0u);	// to

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, "mix_2", "", commands));
	}

	// Mixture of descriptors using descriptor arrays
	{
		DescriptorCommandsSp			commands				(new DescriptorCommands(pipelineType));
		CombinedImageSamplerDescriptor*	combinedImageSampler0	(new CombinedImageSamplerDescriptor(3u, 0u, 3u));
		CombinedImageSamplerDescriptor*	combinedImageSampler1	(new CombinedImageSamplerDescriptor(4u, 0u, 2u));
		CombinedImageSamplerDescriptor*	combinedImageSampler2	(new CombinedImageSamplerDescriptor(3u, 0u, 3u));
		StorageImageDescriptor*			storageImage0			(new StorageImageDescriptor(5u, 0u, 5u));
		StorageImageDescriptor*			storageImage1			(new StorageImageDescriptor(3u, 0u, 0u));
		StorageBufferDescriptor*		storageBuffer0			(new StorageBufferDescriptor(2u, 0u, 1u));
		StorageBufferDescriptor*		storageBuffer1			(new StorageBufferDescriptor(3u, 0u, 3u));

		commands->addDescriptor(DescriptorSp(combinedImageSampler0), 0u);	// Set 0, binding 0
		commands->addDescriptor(DescriptorSp(storageImage0), 0u);			// Set 0, binding 1
		commands->addDescriptor(DescriptorSp(combinedImageSampler1), 0u);	// Set 0, binding 2
		commands->addDescriptor(DescriptorSp(storageBuffer0), 0u);			// Set 0, binding 3
		commands->addDescriptor(DescriptorSp(storageBuffer1), 0u);			// Set 0, binding 4
		commands->addDescriptor(DescriptorSp(storageImage1), 1u);			// Set 1, binding 0
		commands->addDescriptor(DescriptorSp(combinedImageSampler2), 1u);	// Set 1, binding 1

		// combinedImageSampler0[1..2] to combinedImageSampler1[2..3]
		commands->copyDescriptor(0u, 0u, 1u,	// from
								 0u, 2u, 2u,	// to
								 2u);			// num descriptors

		// storageImage0[2..4] to storageImage1[0..2]
		commands->copyDescriptor(0u, 1u, 2u,	// from
								 1u, 0u, 0u,	// to
								 3u);			// num descriptors

		// storageBuffer1[1..2] to storageBuffer0[0..1]
		commands->copyDescriptor(0u, 4u, 1u,	// from
								 0u, 3u, 0u,	// to
								 2u);			// num descriptors

		commands->addResultBuffer();

		group->addChild(new DescriptorCopyTestCase(testCtx, "mix_array0", "", commands));
	}
}

} // anonymous

tcu::TestCaseGroup*	createDescriptorCopyTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> descriptorCopyGroup(new tcu::TestCaseGroup(testCtx, "descriptor_copy", "Descriptor copy tests"));

	de::MovePtr<tcu::TestCaseGroup> computeGroup(new tcu::TestCaseGroup(testCtx, "compute", "Compute tests"));
	de::MovePtr<tcu::TestCaseGroup> graphicsGroup(new tcu::TestCaseGroup(testCtx, "graphics", "Graphics tests"));

	// Compute tests
	addDescriptorCopyTests<UniformBufferDescriptor>(testCtx, computeGroup, "uniform_buffer", PIPELINE_TYPE_COMPUTE);
	addDescriptorCopyTests<StorageBufferDescriptor>(testCtx, computeGroup, "storage_buffer", PIPELINE_TYPE_COMPUTE);
	addDescriptorCopyTests<CombinedImageSamplerDescriptor>(testCtx, computeGroup, "combined_image_sampler", PIPELINE_TYPE_COMPUTE);
	addDescriptorCopyTests<StorageImageDescriptor>(testCtx, computeGroup, "storage_image", PIPELINE_TYPE_COMPUTE);
	addDescriptorCopyTests<UniformTexelBufferDescriptor>(testCtx, computeGroup, "uniform_texel_buffer", PIPELINE_TYPE_COMPUTE);
	addDescriptorCopyTests<StorageTexelBufferDescriptor>(testCtx, computeGroup, "storage_texel_buffer", PIPELINE_TYPE_COMPUTE);
	addDescriptorCopyTests<DynamicUniformBufferDescriptor>(testCtx, computeGroup, "uniform_buffer_dynamic", PIPELINE_TYPE_COMPUTE);
	addDescriptorCopyTests<DynamicStorageBufferDescriptor>(testCtx, computeGroup, "storage_buffer_dynamic", PIPELINE_TYPE_COMPUTE);
	addSamplerCopyTests(testCtx, computeGroup, PIPELINE_TYPE_COMPUTE);
	addSampledImageCopyTests(testCtx, computeGroup, PIPELINE_TYPE_COMPUTE);
	addMixedDescriptorCopyTests(testCtx, computeGroup, PIPELINE_TYPE_COMPUTE);

	// Graphics tests
	addDescriptorCopyTests<UniformBufferDescriptor>(testCtx, graphicsGroup, "uniform_buffer", PIPELINE_TYPE_GRAPHICS);
	addDescriptorCopyTests<StorageBufferDescriptor>(testCtx, graphicsGroup, "storage_buffer", PIPELINE_TYPE_GRAPHICS);
	addDescriptorCopyTests<CombinedImageSamplerDescriptor>(testCtx, graphicsGroup, "combined_image_sampler", PIPELINE_TYPE_GRAPHICS);
	addDescriptorCopyTests<StorageImageDescriptor>(testCtx, graphicsGroup, "storage_image", PIPELINE_TYPE_GRAPHICS);
	addDescriptorCopyTests<InputAttachmentDescriptor>(testCtx, graphicsGroup, "input_attachment", PIPELINE_TYPE_GRAPHICS);
	addDescriptorCopyTests<UniformTexelBufferDescriptor>(testCtx, graphicsGroup, "uniform_texel_buffer", PIPELINE_TYPE_GRAPHICS);
	addDescriptorCopyTests<StorageTexelBufferDescriptor>(testCtx, graphicsGroup, "storage_texel_buffer", PIPELINE_TYPE_GRAPHICS);
	addDescriptorCopyTests<DynamicUniformBufferDescriptor>(testCtx, graphicsGroup, "uniform_buffer_dynamic", PIPELINE_TYPE_GRAPHICS);
	addDescriptorCopyTests<DynamicStorageBufferDescriptor>(testCtx, graphicsGroup, "storage_buffer_dynamic", PIPELINE_TYPE_GRAPHICS);
	addSamplerCopyTests(testCtx, graphicsGroup, PIPELINE_TYPE_GRAPHICS);
	addSampledImageCopyTests(testCtx, graphicsGroup, PIPELINE_TYPE_GRAPHICS);
	addMixedDescriptorCopyTests(testCtx, graphicsGroup, PIPELINE_TYPE_GRAPHICS);

	descriptorCopyGroup->addChild(computeGroup.release());
	descriptorCopyGroup->addChild(graphicsGroup.release());

	return descriptorCopyGroup.release();
}

}	// BindingModel
}	// vkt
