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

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

namespace vkt
{
namespace pipeline
{

using namespace vk;
using namespace std;

namespace
{
typedef de::SharedPtr<Unique<VkBuffer> >		VkBufferSp;
typedef de::SharedPtr<Allocation>				AllocationSp;
typedef de::SharedPtr<Unique<VkCommandBuffer> >	VkCommandBufferSp;
typedef de::SharedPtr<Unique<VkRenderPass> >	VkRenderPassSp;
typedef de::SharedPtr<Unique<VkFramebuffer> >	VkFramebufferSp;
typedef de::SharedPtr<Unique<VkPipeline> >		VkPipelineSp;

enum class GroupingStrategy
{
	SINGLE_SET	= 0,
	MULTISET	= 1,
	ARRAYS		= 2,
};

struct TestParams
{
	VkDescriptorType	descriptorType;
	deUint32			numCmdBuffers;
	bool				reverseOrder;
	deUint32			numDescriptorSetBindings;
	deUint32			numDynamicBindings;
	deUint32			numNonDynamicBindings;
	GroupingStrategy	groupingStrategy;
};

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

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

		vertices.push_back(lowerLeftVertex);
		vertices.push_back(lowerRightVertex);
		vertices.push_back(UpperLeftVertex);
		vertices.push_back(UpperLeftVertex);
		vertices.push_back(lowerRightVertex);
		vertices.push_back(UpperRightVertex);
	}

	return vertices;
}

static const tcu::Vec4			testColors[]	=
{
	tcu::Vec4(0.3f, 0.0f, 0.0f, 1.0f),
	tcu::Vec4(0.0f, 0.3f, 0.0f, 1.0f),
	tcu::Vec4(0.0f, 0.0f, 0.3f, 1.0f),
	tcu::Vec4(0.3f, 0.3f, 0.0f, 1.0f),
	tcu::Vec4(0.0f, 0.3f, 0.3f, 1.0f),
	tcu::Vec4(0.3f, 0.0f, 0.3f, 1.0f)
};
static constexpr VkDeviceSize	kColorSize		= static_cast<VkDeviceSize>(sizeof(testColors[0]));
static constexpr deUint32		kNumTestColors	= static_cast<deUint32>(DE_LENGTH_OF_ARRAY(testColors));

class DynamicOffsetTestInstance : public vkt::TestInstance
{
public:
	DynamicOffsetTestInstance (Context& context, const TestParams& params)
		: vkt::TestInstance	(context)
		, m_params			(params)
		, m_memAlloc		(context.getDeviceInterface(), context.getDevice(), getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()))
		{}

protected:
	const TestParams	m_params;
	SimpleAllocator		m_memAlloc;
};

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

private:
	const tcu::UVec2					m_renderSize;
	const VkFormat						m_colorFormat;
	VkImageCreateInfo					m_colorImageCreateInfo;
	Move<VkImage>						m_colorImage;
	de::MovePtr<Allocation>				m_colorImageAlloc;
	Move<VkImageView>					m_colorAttachmentView;
	vector<VkRenderPassSp>				m_renderPasses;
	vector<VkFramebufferSp>				m_framebuffers;
	Move<VkShaderModule>				m_vertexShaderModule;
	Move<VkShaderModule>				m_fragmentShaderModule;
	Move<VkBuffer>						m_vertexBuffer;
	de::MovePtr<Allocation>				m_vertexBufferAlloc;
	Move<VkBuffer>						m_buffer;
	de::MovePtr<Allocation>				m_bufferAlloc;
	vector<Move<VkDescriptorSetLayout>>	m_descriptorSetLayouts;
	Move<VkDescriptorPool>				m_descriptorPool;
	vector<Move<VkDescriptorSet>>		m_descriptorSets;
	Move<VkPipelineLayout>				m_pipelineLayout;
	vector<VkPipelineSp>				m_graphicsPipelines;
	Move<VkCommandPool>					m_cmdPool;
	vector<VkCommandBufferSp>			m_cmdBuffers;
	vector<Vertex4RGBA>					m_vertices;
};

DynamicOffsetGraphicsTestInstance::DynamicOffsetGraphicsTestInstance (Context& context, const TestParams& params)
	: DynamicOffsetTestInstance	(context, params)
	, m_renderSize				(32, 32)
	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
	, m_vertices				(createQuads(m_params.numDescriptorSetBindings * m_params.numCmdBuffers, 0.25f))
{
}

void DynamicOffsetGraphicsTestInstance::init (void)
{
	const VkComponentMapping		componentMappingRGBA		= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
	const DeviceInterface&			vk							= m_context.getDeviceInterface();
	const VkDevice					vkDevice					= m_context.getDevice();
	const deUint32					queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
	const deUint32					numBindings					= m_params.numDynamicBindings + m_params.numNonDynamicBindings;
	deUint32						offset						= 0;
	deUint32						quadNdx						= 0;
	const VkPhysicalDeviceLimits	deviceLimits				= getPhysicalDeviceProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()).limits;
	const VkDeviceSize				alignment					= ((m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ? deviceLimits.minUniformBufferOffsetAlignment : deviceLimits.minStorageBufferOffsetAlignment);
	const VkDeviceSize				extraBytes					= kColorSize % alignment;
	const VkDeviceSize				colorBlockInputSize			= ((extraBytes == 0ull) ? kColorSize : (kColorSize + alignment - extraBytes));
	const VkDeviceSize				bufferSize					= colorBlockInputSize * kNumTestColors;
	const VkDeviceSize				bindingOffset				= bufferSize / numBindings;
	const VkDescriptorType			nonDynamicDescriptorType	= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;

	vector<VkDescriptorSetLayout>	descriptorSetLayoutsPlain;
	vector<VkDescriptorSet>			descriptorSetsPlain;

	// Create color image
	{

		const VkImageCreateInfo colorImageParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
			DE_NULL,																// const void*				pNext;
			0u,																		// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,														// VkImageType				imageType;
			m_colorFormat,															// VkFormat					format;
			{ m_renderSize.x(), m_renderSize.y(), 1u },								// VkExtent3D				extent;
			1u,																		// deUint32					mipLevels;
			1u,																		// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
			1u,																		// deUint32					queueFamilyIndexCount;
			&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout			initialLayout;
		};

		m_colorImageCreateInfo	= colorImageParams;
		m_colorImage			= createImage(vk, vkDevice, &m_colorImageCreateInfo);

		// Allocate and bind color image memory
		m_colorImageAlloc		= m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
	}

	// Create color attachment view
	{
		const VkImageViewCreateInfo colorAttachmentViewParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType				sType;
			DE_NULL,										// const void*					pNext;
			0u,												// VkImageViewCreateFlags		flags;
			*m_colorImage,									// VkImage						image;
			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType				viewType;
			m_colorFormat,									// VkFormat						format;
			componentMappingRGBA,							// VkChannelMapping				channels;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange		subresourceRange;
		};

		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
	}

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

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

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

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

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

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

		m_renderPasses.push_back(VkRenderPassSp(new Unique<VkRenderPass>(createRenderPass(vk, vkDevice, &renderPassInfo))));
	}

	// Create framebuffers
	for (deUint32 framebufferIdx = 0; framebufferIdx < m_params.numCmdBuffers; framebufferIdx++)
	{
		const VkImageView				attachmentBindInfos[]	=
		{
			*m_colorAttachmentView
		};

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

		m_framebuffers.push_back(VkFramebufferSp(new Unique<VkFramebuffer>(createFramebuffer(vk, vkDevice, &framebufferParams))));
	}

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

		for (deUint32 binding = 0; binding < numBindings; binding++)
		{
			const bool								dynamicDesc						= (binding < m_params.numDynamicBindings);
			const VkDescriptorType					descriptorType					= (dynamicDesc ? m_params.descriptorType : nonDynamicDescriptorType);
			const deUint32							bindingNumber					= (m_params.groupingStrategy == GroupingStrategy::SINGLE_SET ? binding : 0u);
			const deUint32							descriptorCount					= ((m_params.groupingStrategy == GroupingStrategy::ARRAYS) ? (dynamicDesc ? m_params.numDynamicBindings : m_params.numNonDynamicBindings) : 1u);
			const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
			{
				bindingNumber,				// uint32_t				binding;
				descriptorType,				// VkDescriptorType		descriptorType;
				descriptorCount,			// uint32_t				descriptorCount;
				VK_SHADER_STAGE_VERTEX_BIT,	// VkShaderStageFlags	stageFlags;
				DE_NULL						// const VkSampler*		pImmutableSamplers;
			};

			// Skip used descriptors in array mode.
			if (m_params.groupingStrategy == GroupingStrategy::ARRAYS)
				binding = (dynamicDesc ? m_params.numDynamicBindings - 1 : numBindings);

			descriptorSetLayoutBindings.push_back(descriptorSetLayoutBinding);
		}

		vector<VkDescriptorSetLayoutCreateInfo> descriptorSetLayoutCreateInfos;

		if (m_params.groupingStrategy == GroupingStrategy::SINGLE_SET)
		{
			const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
			{
				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType;
				DE_NULL,												// const void*							pNext;
				0u,														// VkDescriptorSetLayoutCreateFlags		flags;
				numBindings,											// uint32_t								bindingCount;
				descriptorSetLayoutBindings.data()						// const VkDescriptorSetLayoutBinding*	pBindings;
			};

			m_descriptorSetLayouts.push_back(createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutCreateInfo));
		}
		else
		{
			for (size_t i = 0; i < descriptorSetLayoutBindings.size(); ++i)
			{
				const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
				{
					VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType;
					DE_NULL,												// const void*							pNext;
					0u,														// VkDescriptorSetLayoutCreateFlags		flags;
					1u,														// uint32_t								bindingCount;
					&descriptorSetLayoutBindings[i]							// const VkDescriptorSetLayoutBinding*	pBindings;
				};

				m_descriptorSetLayouts.push_back(createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutCreateInfo));
			}
		}

		// Create pipeline layout
		descriptorSetLayoutsPlain.resize(m_descriptorSetLayouts.size());
		for (size_t i = 0; i < descriptorSetLayoutsPlain.size(); ++i)
			descriptorSetLayoutsPlain[i] = m_descriptorSetLayouts[i].get();

		const VkPipelineLayoutCreateInfo		pipelineLayoutParams			=
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// VkStructureType				sType;
			DE_NULL,													// const void*					pNext;
			0u,															// VkPipelineLayoutCreateFlags	flags;
			static_cast<deUint32>(descriptorSetLayoutsPlain.size()),	// deUint32						descriptorSetCount;
			descriptorSetLayoutsPlain.data(),							// const VkDescriptorSetLayout*	pSetLayouts;
			0u,															// deUint32						pushConstantRangeCount;
			DE_NULL														// const VkPushDescriptorRange*	pPushDescriptorRanges;
		};

		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
	}

	// Create buffer
	{
		vector<deUint8> hostBuffer((size_t)bufferSize, 0);
		for (deUint32 colorIdx = 0; colorIdx < kNumTestColors; colorIdx++)
			deMemcpy(&hostBuffer[(deUint32)colorBlockInputSize * colorIdx], &testColors[colorIdx], kColorSize);

		const VkBufferUsageFlags	usageFlags			= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;

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

		m_buffer = createBuffer(vk, vkDevice, &bufferCreateInfo);
		m_bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_buffer), MemoryRequirement::HostVisible);
		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_buffer, m_bufferAlloc->getMemory(), m_bufferAlloc->getOffset()));

		deMemcpy(m_bufferAlloc->getHostPtr(), hostBuffer.data(), (size_t)bufferSize);
		flushAlloc(vk, vkDevice, *m_bufferAlloc);
	}

	// Create descriptor pool
	{
		DescriptorPoolBuilder	poolBuilder;
		poolBuilder.addType(m_params.descriptorType, m_params.numDynamicBindings);
		poolBuilder.addType(nonDynamicDescriptorType, m_params.numNonDynamicBindings);
		m_descriptorPool = poolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, static_cast<deUint32>(m_descriptorSetLayouts.size()));
	}

	// Create descriptor sets
	{
		for (size_t i = 0; i < m_descriptorSetLayouts.size(); ++i)
		{
			const VkDescriptorSetAllocateInfo allocInfo =
			{
				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType					sType;
				DE_NULL,										// const void*						pNext;
				*m_descriptorPool,								// VkDescriptorPool					descriptorPool;
				1u,												// deUint32							setLayoutCount;
				&(m_descriptorSetLayouts[i].get()),				// const VkDescriptorSetLayout*		pSetLayouts;
			};
			m_descriptorSets.push_back(allocateDescriptorSet(vk, vkDevice, &allocInfo));
		}
	}

	descriptorSetsPlain.resize(m_descriptorSets.size());
	for (size_t i = 0; i < descriptorSetsPlain.size(); ++i)
		descriptorSetsPlain[i] = m_descriptorSets[i].get();

	// Update descriptor sets
	for (deUint32 binding = 0; binding < numBindings; ++binding)
	{
		const bool						dynamicDesc				= (binding < m_params.numDynamicBindings);
		const VkDescriptorType			descriptorType			= (dynamicDesc ? m_params.descriptorType : nonDynamicDescriptorType);
		const VkDescriptorBufferInfo	descriptorBufferInfo	=
		{
			*m_buffer,					// VkBuffer			buffer;
			bindingOffset * binding,	// VkDeviceSize		offset;
			kColorSize					// VkDeviceSize		range;
		};

		VkDescriptorSet	bindingSet;
		deUint32		bindingNumber;
		deUint32		dstArrayElement;

		if (m_params.groupingStrategy == GroupingStrategy::SINGLE_SET)
		{
			bindingSet		= m_descriptorSets[0].get();
			bindingNumber	= binding;
			dstArrayElement	= 0u;
		}
		else if (m_params.groupingStrategy == GroupingStrategy::MULTISET)
		{
			bindingSet		= m_descriptorSets[binding].get();
			bindingNumber	= 0u;
			dstArrayElement	= 0u;
		}
		else // GroupingStrategy::ARRAYS
		{
			bindingSet		= (dynamicDesc ? m_descriptorSets[0].get() : m_descriptorSets[1].get());
			bindingNumber	= 0u;
			dstArrayElement	= (dynamicDesc ? binding : (binding - m_params.numDynamicBindings));
		}

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

		vk.updateDescriptorSets(vkDevice, 1u, &writeDescriptorSet, 0u, DE_NULL);
	}

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

	// Create pipelines
	for (deUint32 pipelineIdx = 0; pipelineIdx < m_params.numCmdBuffers; pipelineIdx++)
	{
		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
		{
			0u,							// deUint32					binding;
			sizeof(Vertex4RGBA),		// deUint32					strideInBytes;
			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate;
		};

		const VkVertexInputAttributeDescription		vertexInputAttributeDescriptions[]	=
		{
			{
				0u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				0u									// deUint32	offsetInBytes;
			},
			{
				1u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
			}
		};

		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
			DE_NULL,													// const void*								pNext;
			0u,															// vkPipelineVertexInputStateCreateFlags	flags;
			1u,															// deUint32									bindingCount;
			&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
			2u,															// deUint32									attributeCount;
			vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
		};

		const VkPrimitiveTopology					topology							= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;

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

		m_graphicsPipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(vk,								// const DeviceInterface&						vk
																							   vkDevice,						// const VkDevice								device
																							   *m_pipelineLayout,				// const VkPipelineLayout						pipelineLayout
																							   *m_vertexShaderModule,			// const VkShaderModule							vertexShaderModule
																							   DE_NULL,							// const VkShaderModule							tessellationControlShaderModule
																							   DE_NULL,							// const VkShaderModule							tessellationEvalShaderModule
																							   DE_NULL,							// const VkShaderModule							geometryShaderModule
																							   *m_fragmentShaderModule,			// const VkShaderModule							fragmentShaderModule
																							   **m_renderPasses[pipelineIdx],	// const VkRenderPass							renderPass
																							   viewports,						// const std::vector<VkViewport>&				viewports
																							   scissors,						// const std::vector<VkRect2D>&					scissors
																							   topology,						// const VkPrimitiveTopology					topology
																							   0u,								// const deUint32								subpass
																							   0u,								// const deUint32								patchControlPoints
																							   &vertexInputStateParams))));		// const VkPipelineVertexInputStateCreateInfo*	vertexInputStateCreateInfo
	}

	// Create vertex buffer
	{
		const VkBufferCreateInfo vertexBufferParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,						// VkStructureType		sType;
			DE_NULL,													// const void*			pNext;
			0u,															// VkBufferCreateFlags	flags;
			(VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()),	// VkDeviceSize			size;
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,							// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,									// VkSharingMode		sharingMode;
			1u,															// deUint32				queueFamilyCount;
			&queueFamilyIndex											// const deUint32*		pQueueFamilyIndices;
		};

		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
		m_vertexBufferAlloc	= m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));

		// Load vertices into vertex buffer
		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
	}

	// Create command pool
	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);

	// Create command buffers
	for (deUint32 cmdBufferIdx = 0; cmdBufferIdx < m_params.numCmdBuffers; cmdBufferIdx++)
		m_cmdBuffers.push_back(VkCommandBufferSp(new Unique<VkCommandBuffer>(allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY))));

	for (deUint32 cmdBufferIdx = 0; cmdBufferIdx < m_params.numCmdBuffers; cmdBufferIdx++)
	{
		const VkClearValue	attachmentClearValue	= defaultClearValue(m_colorFormat);
		const VkDeviceSize	vertexBufferOffset		= 0;
		const deUint32		idx						= m_params.reverseOrder ? m_params.numCmdBuffers - cmdBufferIdx - 1 : cmdBufferIdx;

		beginCommandBuffer(vk, **m_cmdBuffers[idx], 0u);
		beginRenderPass(vk, **m_cmdBuffers[idx], **m_renderPasses[idx], **m_framebuffers[idx], makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);
		vk.cmdBindPipeline(**m_cmdBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[idx]);
		vk.cmdBindVertexBuffers(**m_cmdBuffers[idx], 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);

		for (deUint32 i = 0; i < m_params.numDescriptorSetBindings; i++)
		{
			vector<deUint32>	offsets;
			for (deUint32 dynamicBindingIdx = 0; dynamicBindingIdx < m_params.numDynamicBindings; dynamicBindingIdx++)
				offsets.push_back(offset + (deUint32)colorBlockInputSize * dynamicBindingIdx);

			vk.cmdBindDescriptorSets(**m_cmdBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, static_cast<deUint32>(descriptorSetsPlain.size()), descriptorSetsPlain.data(), m_params.numDynamicBindings, offsets.data());
			offset += (deUint32)colorBlockInputSize;

			// Draw quad
			vk.cmdDraw(**m_cmdBuffers[idx], 6, 1, 6 * quadNdx, 0);
			quadNdx++;
		}

		endRenderPass(vk, **m_cmdBuffers[idx]);
		endCommandBuffer(vk, **m_cmdBuffers[idx]);
	}
}

DynamicOffsetGraphicsTestInstance::~DynamicOffsetGraphicsTestInstance (void)
{
}

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

	for (deUint32 cmdBufferIdx = 0; cmdBufferIdx < m_params.numCmdBuffers; cmdBufferIdx++)
		submitCommandsAndWait(m_context.getDeviceInterface(), m_context.getDevice(), m_context.getUniversalQueue(), **m_cmdBuffers[cmdBufferIdx]);

	return verifyImage();
}

tcu::TestStatus DynamicOffsetGraphicsTestInstance::verifyImage (void)
{
	const tcu::TextureFormat	tcuColorFormat		= mapVkFormat(m_colorFormat);
	const tcu::TextureFormat	tcuDepthFormat		= tcu::TextureFormat();
	const ColorVertexShader		vertexShader;
	const ColorFragmentShader	fragmentShader		(tcuColorFormat, tcuDepthFormat);
	const rr::Program			program				(&vertexShader, &fragmentShader);
	ReferenceRenderer			refRenderer			(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
	bool						compareOk			= false;

	// Render reference image
	{
		const deUint32	numBindings		= m_params.numDynamicBindings + m_params.numNonDynamicBindings;
		const deUint32	bindingOffset	= kNumTestColors / numBindings;

		for (deUint32 quadIdx = 0; quadIdx < m_vertices.size() / 6; quadIdx++)
			for (deUint32 vertexIdx = 0; vertexIdx < 6; vertexIdx++)
			{
				tcu::Vec4 refColor(0.0f);

				for (deUint32 binding = 0; binding < m_params.numDynamicBindings; binding++)
					refColor += testColors[quadIdx + binding * bindingOffset + binding];
				for (deUint32 binding = 0; binding < m_params.numNonDynamicBindings; binding++)
					refColor += testColors[(m_params.numDynamicBindings + binding) * bindingOffset];
				refColor.w() = 1.0f;

				m_vertices[quadIdx * 6 + vertexIdx].color.xyzw() = refColor;
			}

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

	// Compare result with reference image
	{
		de::MovePtr<tcu::TextureLevel> result = readColorAttachment(
			m_context.getDeviceInterface(), m_context.getDevice(), m_context.getUniversalQueue(),
			m_context.getUniversalQueueFamilyIndex(), m_memAlloc, *m_colorImage, m_colorFormat, m_renderSize);

		compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
															  "IntImageCompare",
															  "Image comparison",
															  refRenderer.getAccess(),
															  result->getAccess(),
															  tcu::UVec4(2, 2, 2, 2),
															  tcu::IVec3(1, 1, 0),
															  true,
															  tcu::COMPARE_LOG_RESULT);
	}

	if (compareOk)
		return tcu::TestStatus::pass("Result image matches reference");
	else
		return tcu::TestStatus::fail("Image mismatch");
}

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

protected:
	const TestParams	m_params;
};

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

DynamicOffsetGraphicsTest::~DynamicOffsetGraphicsTest (void)
{
}

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

void DynamicOffsetGraphicsTest::initPrograms (SourceCollections& sourceCollections) const
{
	const deUint32	numBindings		= m_params.numDynamicBindings + m_params.numNonDynamicBindings;
	const string	bufferType		= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ? "uniform" : "readonly buffer";
	ostringstream	inputBlocks;
	ostringstream	inputSum;
	string			setAndBinding;
	string			blockSuffix;
	string			accessSuffix;
	bool			dynArrayDecl	= false;	// Dynamic descriptor block array declared?
	bool			nonDynArrayDecl	= false;	// Nondynamic descriptor block array declared?

	for (deUint32 b = 0; b < numBindings; b++)
	{
		const bool		dynBind	= (b < m_params.numDynamicBindings);
		const string	bStr	= de::toString(b);

		if (m_params.groupingStrategy == GroupingStrategy::SINGLE_SET)
		{
			setAndBinding	= "set = 0, binding = " + bStr;
			blockSuffix		= bStr;
			accessSuffix	= bStr;
		}
		else if (m_params.groupingStrategy == GroupingStrategy::MULTISET)
		{
			setAndBinding	= "set = " + bStr + ", binding = 0";
			blockSuffix		= bStr;
			accessSuffix	= bStr;
		}
		else // GroupingStrategy::ARRAYS
		{
			// In array mode, only two sets are declared, one with an array of dynamic descriptors and another one with an array of
			// nondynamic descriptors.
			setAndBinding	= "set = " + string(dynBind ? "0" : "1") + ", binding = 0";
			blockSuffix		= string(dynBind ? "Dyn" : "NonDyn") + "[" + (dynBind ? de::toString(m_params.numDynamicBindings) : de::toString(m_params.numNonDynamicBindings)) + "]";
			accessSuffix	= string(dynBind ? "Dyn" : "NonDyn") + "[" + (dynBind ? de::toString(b) : de::toString(b - m_params.numDynamicBindings)) + "]";
		}

		// In array mode, declare the input block only once per descriptor type.
		bool& arrayDeclFlag = (dynBind ? dynArrayDecl : nonDynArrayDecl);
		if (m_params.groupingStrategy != GroupingStrategy::ARRAYS || !arrayDeclFlag)
		{
			inputBlocks
				<< "layout(" << setAndBinding << ") " << bufferType << " Block" << bStr << "\n"
				<< "{\n"
				<< "    vec4 color;\n"
				<< "} inputData" << blockSuffix << ";\n"
				;
			arrayDeclFlag = true;
		}

		// But the sum always needs to be added once per descriptor.
		inputSum << "    vtxColor.rgb += inputData" << accessSuffix << ".color.rgb;\n";
	}

	const string	vertexSrc	=
		"#version 450\n"
		"layout(location = 0) in highp vec4 position;\n"
		"layout(location = 1) in highp vec4 color;\n"
		"layout(location = 0) out highp vec4 vtxColor;\n"
		+ inputBlocks.str() +
		"\n"
		"out gl_PerVertex { vec4 gl_Position; };\n"
		"\n"
		"void main()\n"
		"{\n"
		"    gl_Position = position;\n"
		"    vtxColor = vec4(0, 0, 0, 1);\n"
		+ inputSum.str() +
		"}\n";

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

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

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

private:
	const deUint32						m_numBindings;
	const deUint32						m_numOutputColors;
	const VkPhysicalDeviceLimits		m_deviceLimits;
	Move<VkShaderModule>				m_computeShaderModule;
	Move<VkBuffer>						m_buffer;
	de::MovePtr<Allocation>				m_bufferAlloc;
	vector<Move<VkDescriptorSetLayout>>	m_descriptorSetLayouts;
	Move<VkDescriptorPool>				m_descriptorPool;
	vector<Move<VkDescriptorSet>>		m_descriptorSets;
	Move<VkPipelineLayout>				m_pipelineLayout;
	Move<VkPipeline>					m_computePipeline;
	Move<VkBuffer>						m_outputBuffer;
	de::MovePtr<Allocation>				m_outputBufferAlloc;
	Move<VkCommandPool>					m_cmdPool;
	vector<VkCommandBufferSp>			m_cmdBuffers;
};

DynamicOffsetComputeTestInstance::DynamicOffsetComputeTestInstance (Context& context, const TestParams& params)
	: DynamicOffsetTestInstance	(context, params)
	, m_numBindings				(params.numDynamicBindings + params.numNonDynamicBindings)
	, m_numOutputColors			(params.numCmdBuffers * params.numDescriptorSetBindings)
	, m_deviceLimits			(getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice()).limits)
{
}

void DynamicOffsetComputeTestInstance::init (void)
{
	const DeviceInterface&			vk							= m_context.getDeviceInterface();
	const VkDevice					vkDevice					= m_context.getDevice();
	const deUint32					queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
	const VkDeviceSize				inputAlignment				= ((m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ? m_deviceLimits.minUniformBufferOffsetAlignment : m_deviceLimits.minStorageBufferOffsetAlignment);
	const VkDeviceSize				inputExtraBytes				= kColorSize % inputAlignment;
	const VkDeviceSize				colorBlockInputSize			= ((inputExtraBytes == 0ull) ? kColorSize : (kColorSize + inputAlignment - inputExtraBytes));
	const deUint32					colorBlockInputSizeU32		= static_cast<deUint32>(colorBlockInputSize);
	const VkDeviceSize				outputExtraBytes			= kColorSize % m_deviceLimits.minStorageBufferOffsetAlignment;
	const VkDeviceSize				colorBlockOutputSize		= ((outputExtraBytes == 0ull) ? kColorSize : (kColorSize + m_deviceLimits.minStorageBufferOffsetAlignment - outputExtraBytes));
	const deUint32					colorBlockOutputSizeU32		= static_cast<deUint32>(colorBlockOutputSize);
	const VkDeviceSize				bufferSize					= colorBlockInputSize * kNumTestColors;
	const VkDeviceSize				bindingOffset				= bufferSize / m_numBindings;
	const VkDescriptorType			nonDynamicDescriptorType	= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
	const VkDeviceSize				outputBufferSize			= colorBlockOutputSize * m_numOutputColors;

	vector<VkDescriptorSetLayout>	descriptorSetLayoutsPlain;
	vector<VkDescriptorSet>			descriptorSetsPlain;

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

		for (deUint32 binding = 0; binding < m_numBindings; binding++)
		{
			const bool								dynamicDesc					= (binding < m_params.numDynamicBindings);
			const VkDescriptorType					descriptorType				= (dynamicDesc ? m_params.descriptorType : nonDynamicDescriptorType);
			const deUint32							bindingNumber				= (m_params.groupingStrategy == GroupingStrategy::SINGLE_SET ? binding : 0u);
			const deUint32							descriptorCount				= ((m_params.groupingStrategy == GroupingStrategy::ARRAYS) ? (dynamicDesc ? m_params.numDynamicBindings : m_params.numNonDynamicBindings) : 1u);
			const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding	=
			{
				bindingNumber,					// uint32_t				binding;
				descriptorType,					// VkDescriptorType		descriptorType;
				descriptorCount,				// uint32_t				descriptorCount;
				VK_SHADER_STAGE_COMPUTE_BIT,	// VkShaderStageFlags	stageFlags;
				DE_NULL							// const VkSampler*		pImmutableSamplers;
			};

			// Skip used descriptors in array mode.
			if (m_params.groupingStrategy == GroupingStrategy::ARRAYS)
				binding = (dynamicDesc ? m_params.numDynamicBindings - 1 : m_numBindings);

			descriptorSetLayoutBindings.push_back(descriptorSetLayoutBinding);
		}

		const deUint32							bindingNumberOutput					= (m_params.groupingStrategy == GroupingStrategy::SINGLE_SET ? m_numBindings : 0u);
		const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingOutput	=
		{
			bindingNumberOutput,						// uint32_t				binding;
			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,	// VkDescriptorType		descriptorType;
			1u,											// uint32_t				descriptorCount;
			VK_SHADER_STAGE_COMPUTE_BIT,				// VkShaderStageFlags	stageFlags;
			DE_NULL										// const VkSampler*		pImmutableSamplers;
		};

		descriptorSetLayoutBindings.push_back(descriptorSetLayoutBindingOutput);

		if (m_params.groupingStrategy == GroupingStrategy::SINGLE_SET)
		{
			const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
			{
				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType;
				DE_NULL,												// const void*							pNext;
				0u,														// VkDescriptorSetLayoutCreateFlags		flags;
				m_numBindings + 1,										// uint32_t								bindingCount;
				descriptorSetLayoutBindings.data()						// const VkDescriptorSetLayoutBinding*	pBindings;
			};

			m_descriptorSetLayouts.push_back(createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutCreateInfo, DE_NULL));
		}
		else
		{
			for (size_t i = 0; i < descriptorSetLayoutBindings.size(); ++i)
			{
				const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
				{
					VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType;
					DE_NULL,												// const void*							pNext;
					0u,														// VkDescriptorSetLayoutCreateFlags		flags;
					1u,														// uint32_t								bindingCount;
					&descriptorSetLayoutBindings[i]							// const VkDescriptorSetLayoutBinding*	pBindings;
				};

				m_descriptorSetLayouts.push_back(createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutCreateInfo, DE_NULL));
			}
		}

		// Create pipeline layout
		descriptorSetLayoutsPlain.resize(m_descriptorSetLayouts.size());
		for (size_t i = 0; i < descriptorSetLayoutsPlain.size(); ++i)
			descriptorSetLayoutsPlain[i] = m_descriptorSetLayouts[i].get();

		const VkPipelineLayoutCreateInfo		pipelineLayoutParams			=
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// VkStructureType				sType;
			DE_NULL,													// const void*					pNext;
			0u,															// VkPipelineLayoutCreateFlags	flags;
			static_cast<deUint32>(descriptorSetLayoutsPlain.size()),	// deUint32						descriptorSetCount;
			descriptorSetLayoutsPlain.data(),							// const VkDescriptorSetLayout*	pSetLayouts;
			0u,															// deUint32						pushConstantRangeCount;
			DE_NULL														// const VkPushDescriptorRange*	pPushDescriptorRanges;
		};

		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
	}

	// Create buffer
	{
		vector<deUint8> hostBuffer((deUint32)bufferSize, 0);
		for (deUint32 colorIdx = 0; colorIdx < kNumTestColors; colorIdx++)
			deMemcpy(&hostBuffer[colorBlockInputSizeU32 * colorIdx], &testColors[colorIdx], kColorSize);

		const VkBufferUsageFlags	usageFlags			= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;

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

		m_buffer = createBuffer(vk, vkDevice, &bufferCreateInfo);
		m_bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_buffer), MemoryRequirement::HostVisible);
		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_buffer, m_bufferAlloc->getMemory(), m_bufferAlloc->getOffset()));

		deMemcpy(m_bufferAlloc->getHostPtr(), hostBuffer.data(), (size_t)bufferSize);
		flushAlloc(vk, vkDevice, *m_bufferAlloc);
	}

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

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

	// Create descriptor pool
	{
		DescriptorPoolBuilder	poolBuilder;
		poolBuilder.addType(m_params.descriptorType, m_params.numDynamicBindings);
		poolBuilder.addType(nonDynamicDescriptorType, m_params.numNonDynamicBindings);
		poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1u);
		m_descriptorPool = poolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, static_cast<deUint32>(m_descriptorSetLayouts.size()));
	}

	// Create descriptor sets
	{
		for (size_t i = 0; i < m_descriptorSetLayouts.size(); ++i)
		{
			const VkDescriptorSetAllocateInfo allocInfo =
			{
				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType				sType;
				DE_NULL,										// const void*					pNext;
				*m_descriptorPool,								// VkDescriptorPool				descriptorPool;
				1u,												// deUint32						setLayoutCount;
				&(m_descriptorSetLayouts[i].get()),				// const VkDescriptorSetLayout*	pSetLayouts;
			};
			m_descriptorSets.push_back(allocateDescriptorSet(vk, vkDevice, &allocInfo));
		}
	}

	descriptorSetsPlain.resize(m_descriptorSets.size());
	for (size_t i = 0; i < descriptorSetsPlain.size(); ++i)
		descriptorSetsPlain[i] = m_descriptorSets[i].get();

	// Update input buffer descriptors
	for (deUint32 binding = 0; binding < m_numBindings; ++binding)
	{
		const bool						dynamicDesc				= (binding < m_params.numDynamicBindings);
		const VkDescriptorType			descriptorType			= dynamicDesc ? m_params.descriptorType : nonDynamicDescriptorType;
		const VkDescriptorBufferInfo	descriptorBufferInfo	=
		{
			*m_buffer,					// VkBuffer			buffer;
			bindingOffset * binding,	// VkDeviceSize		offset;
			kColorSize					// VkDeviceSize		range;
		};

		VkDescriptorSet	bindingSet;
		deUint32		bindingNumber;
		deUint32		dstArrayElement;

		if (m_params.groupingStrategy == GroupingStrategy::SINGLE_SET)
		{
			bindingSet		= m_descriptorSets[0].get();
			bindingNumber	= binding;
			dstArrayElement	= 0u;
		}
		else if (m_params.groupingStrategy == GroupingStrategy::MULTISET)
		{
			bindingSet		= m_descriptorSets[binding].get();
			bindingNumber	= 0u;
			dstArrayElement	= 0u;
		}
		else // GroupingStrategy::ARRAYS
		{
			bindingSet		= (dynamicDesc ? m_descriptorSets[0].get() : m_descriptorSets[1].get());
			bindingNumber	= 0u;
			dstArrayElement	= (dynamicDesc ? binding : (binding - m_params.numDynamicBindings));
		}

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

		vk.updateDescriptorSets(vkDevice, 1u, &writeDescriptorSet, 0u, DE_NULL);
	}

	// Update output buffer descriptor
	{
		const VkDescriptorBufferInfo	descriptorBufferInfo	=
		{
			*m_outputBuffer,	// VkBuffer			buffer;
			0u,					// VkDeviceSize		offset;
			kColorSize			// VkDeviceSize		range;
		};

		VkDescriptorSet	bindingSet;
		deUint32		bindingNumber;

		if (m_params.groupingStrategy == GroupingStrategy::SINGLE_SET)
		{
			bindingSet		= m_descriptorSets[0].get();
			bindingNumber	= m_numBindings;
		}
		else if (m_params.groupingStrategy == GroupingStrategy::MULTISET)
		{
			bindingSet		= m_descriptorSets.back().get();
			bindingNumber	= 0u;
		}
		else // GroupingStrategy::ARRAYS
		{
			bindingSet		= m_descriptorSets.back().get();
			bindingNumber	= 0u;
		}

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

		vk.updateDescriptorSets(vkDevice, 1u, &writeDescriptorSet, 0u, DE_NULL);
	}

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

	// Create pipeline
	{
		const VkPipelineShaderStageCreateInfo	stageCreateInfo	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
			DE_NULL,												// const void*							pNext;
			0u,														// VkPipelineShaderStageCreateFlags		flags;
			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
			*m_computeShaderModule,									// VkShaderModule						module;
			"main",													// const char*							pName;
			DE_NULL													// const VkSpecializationInfo*			pSpecializationInfo;
		};

		const VkComputePipelineCreateInfo		createInfo		=
		{
			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			// VkStructureType					sType;
			DE_NULL,												// const void*						pNext;
			0u,														// VkPipelineCreateFlags			flags;
			stageCreateInfo,										// VkPipelineShaderStageCreateInfo	stage;
			*m_pipelineLayout,										// VkPipelineLayout					layout;
			(VkPipeline)0,											// VkPipeline						basePipelineHandle;
			0u,														// int32_t							basePipelineIndex;
		};

		m_computePipeline = createComputePipeline(vk, vkDevice, (vk::VkPipelineCache)0u, &createInfo);
	}

	// Create command pool
	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);

	// Create command buffers
	for (deUint32 cmdBufferIdx = 0; cmdBufferIdx < m_params.numCmdBuffers; cmdBufferIdx++)
		m_cmdBuffers.push_back(VkCommandBufferSp(new Unique<VkCommandBuffer>(allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY))));

	deUint32 inputOffset	= 0u;
	deUint32 outputOffset	= 0u;

	for (deUint32 cmdBufferIdx = 0; cmdBufferIdx < m_params.numCmdBuffers; cmdBufferIdx++)
	{
		const deUint32 idx = m_params.reverseOrder ? m_params.numCmdBuffers - cmdBufferIdx - 1 : cmdBufferIdx;

		beginCommandBuffer(vk, **m_cmdBuffers[idx], 0u);
		vk.cmdBindPipeline(**m_cmdBuffers[idx], VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);

		for (deUint32 i = 0; i < m_params.numDescriptorSetBindings; i++)
		{
			vector<deUint32> offsets;

			// Offsets for input buffers
			for (deUint32 dynamicBindingIdx = 0; dynamicBindingIdx < m_params.numDynamicBindings; dynamicBindingIdx++)
				offsets.push_back(inputOffset + colorBlockInputSizeU32 * dynamicBindingIdx);
			inputOffset += colorBlockInputSizeU32;

			// Offset for output buffer
			offsets.push_back(outputOffset);
			outputOffset += colorBlockOutputSizeU32;

			vk.cmdBindDescriptorSets(**m_cmdBuffers[idx], VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, static_cast<deUint32>(descriptorSetsPlain.size()), descriptorSetsPlain.data(), (deUint32)offsets.size(), offsets.data());

			// Dispatch
			vk.cmdDispatch(**m_cmdBuffers[idx], 1, 1, 1);
		}

		endCommandBuffer(vk, **m_cmdBuffers[idx]);
	}
}

DynamicOffsetComputeTestInstance::~DynamicOffsetComputeTestInstance (void)
{
}

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

	for (deUint32 cmdBufferIdx = 0; cmdBufferIdx < m_params.numCmdBuffers; cmdBufferIdx++)
		submitCommandsAndWait(m_context.getDeviceInterface(), m_context.getDevice(), m_context.getUniversalQueue(), **m_cmdBuffers[cmdBufferIdx]);

	return verifyOutput();
}

tcu::TestStatus DynamicOffsetComputeTestInstance::verifyOutput (void)
{
	const deUint32		bindingOffset			= kNumTestColors / m_numBindings;
	const deUint32		colorBlockOutputSize	= static_cast<deUint32>(de::max(kColorSize, m_deviceLimits.minStorageBufferOffsetAlignment));
	vector<tcu::Vec4>	refColors				(m_numOutputColors);
	vector<tcu::Vec4>	outColors				(m_numOutputColors);

	for (deUint32 i = 0; i < m_numOutputColors; i++)
	{
		tcu::Vec4 refColor(0.0f);

		for (deUint32 binding = 0; binding < m_params.numDynamicBindings; binding++)
			refColor += testColors[i + binding * bindingOffset + binding];
		for (deUint32 binding = 0; binding < m_params.numNonDynamicBindings; binding++)
			refColor += testColors[(m_params.numDynamicBindings + binding) * bindingOffset];
		refColor.w() = 1.0f;

		refColors[i] = refColor;
	}

	invalidateAlloc(m_context.getDeviceInterface(), m_context.getDevice(), *m_outputBufferAlloc);

	// Grab the output results using offset alignment
	for (deUint32 i = 0; i < m_numOutputColors; i++)
		outColors[i] = *(tcu::Vec4*)((deUint8*)m_outputBufferAlloc->getHostPtr() + colorBlockOutputSize * i);

	// Verify results
	for (deUint32 i = 0; i < m_numOutputColors; i++)
		if (outColors[i] != refColors[i])
			return tcu::TestStatus::fail("Output mismatch");

	return tcu::TestStatus::pass("Output matches expected values");
}

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

protected:
	const TestParams	m_params;
};

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

DynamicOffsetComputeTest::~DynamicOffsetComputeTest (void)
{
}

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

void DynamicOffsetComputeTest::initPrograms (SourceCollections& sourceCollections) const
{
	const deUint32	numBindings		= m_params.numDynamicBindings + m_params.numNonDynamicBindings;
	const string	bufferType		= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ? "uniform" : "buffer";
	ostringstream	inputBlocks;
	ostringstream	inputSum;
	string			setAndBinding;
	string			blockSuffix;
	string			accessSuffix;
	bool			dynArrayDecl	= false;	// Dynamic descriptor block array declared?
	bool			nonDynArrayDecl	= false;	// Nondynamic descriptor block array declared?
	string			bStr;

	for (deUint32 b = 0; b < numBindings; b++)
	{
		const bool dynBind	= (b < m_params.numDynamicBindings);
		bStr				= de::toString(b);

		if (m_params.groupingStrategy == GroupingStrategy::SINGLE_SET)
		{
			setAndBinding = "set = 0, binding = " + bStr;
			blockSuffix		= bStr;
			accessSuffix	= bStr;
		}
		else if (m_params.groupingStrategy == GroupingStrategy::MULTISET)
		{
			setAndBinding = "set = " + bStr + ", binding = 0";
			blockSuffix		= bStr;
			accessSuffix	= bStr;
		}
		else // GroupingStrategy::ARRAYS
		{
			// In array mode, only two sets are declared, one with an array of dynamic descriptors and another one with an array of
			// nondynamic descriptors.
			setAndBinding	= "set = " + string(dynBind ? "0" : "1") + ", binding = 0";
			blockSuffix		= string(dynBind ? "Dyn" : "NonDyn") + "[" + (dynBind ? de::toString(m_params.numDynamicBindings) : de::toString(m_params.numNonDynamicBindings)) + "]";
			accessSuffix	= string(dynBind ? "Dyn" : "NonDyn") + "[" + (dynBind ? de::toString(b) : de::toString(b - m_params.numDynamicBindings)) + "]";
		}

		// In array mode, declare the input block only once per descriptor type.
		bool& arrayDeclFlag = (dynBind ? dynArrayDecl : nonDynArrayDecl);
		if (m_params.groupingStrategy != GroupingStrategy::ARRAYS || !arrayDeclFlag)
		{
			inputBlocks
				<< "layout(" << setAndBinding << ") " << bufferType << " Block" << bStr << "\n"
				<< "{\n"
				<< "    vec4 color;\n"
				<< "} inputData" << blockSuffix << ";\n"
				;
			arrayDeclFlag = true;
		}

		// But the sum always needs to be added once per descriptor.
		inputSum << "    outData.color.rgb += inputData" << accessSuffix << ".color.rgb;\n";
	}

	bStr = de::toString(numBindings);
	if (m_params.groupingStrategy == GroupingStrategy::SINGLE_SET)
	{
		setAndBinding = "set = 0, binding = " + bStr;
	}
	else if (m_params.groupingStrategy == GroupingStrategy::MULTISET)
	{
		setAndBinding = "set = " + bStr + ", binding = 0";
	}
	else // GroupingStrategy::ARRAYS
	{
		// The output buffer goes to a separate set.
		deUint32 usedSets = 0u;
		if (dynArrayDecl)		++usedSets;
		if (nonDynArrayDecl)	++usedSets;

		setAndBinding = "set = " + de::toString(usedSets) + ", binding = 0";
	}

	const string	computeSrc	=
		"#version 450\n"
		+ inputBlocks.str() +
		"layout(" + setAndBinding + ") writeonly buffer Output\n"
		"{\n"
		"	vec4 color;\n"
		"} outData;\n"
		"\n"
		"void main()\n"
		"{\n"
		"    outData.color = vec4(0, 0, 0, 1);\n"
		+ inputSum.str() +
		"}\n";

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

} // anonymous

tcu::TestCaseGroup* createDynamicOffsetTests (tcu::TestContext& testCtx)
{
	const char*	pipelineTypes[]			= { "graphics", "compute" };

	struct
	{
		const char*				name;
		const GroupingStrategy	strategy;
	}
	const groupingTypes[]				=
	{
		{ "single_set",		GroupingStrategy::SINGLE_SET	},
		{ "multiset",		GroupingStrategy::MULTISET		},
		{ "arrays",			GroupingStrategy::ARRAYS		},
	};

	struct
	{
		const char*			name;
		VkDescriptorType	type;
	}
	const descriptorTypes[]				=
	{
		{	"uniform_buffer",	VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC	},
		{	"storage_buffer",	VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC	}
	};

	struct
	{
		const char*		name;
		deUint32		num;
	}
	const numCmdBuffers[]				=
	{
		{	"numcmdbuffers_1",	1u	},
		{	"numcmdbuffers_2",	2u	}
	};

	struct
	{
		const char*		name;
		bool			reverse;
	}
	const reverseOrders[]				=
	{
		{	"reverseorder",	true	},
		{	"sameorder",	false	}
	};

	struct
	{
		const char*		name;
		deUint32		num;
	}
	const numDescriptorSetBindings[]	=
	{
		{	"numdescriptorsetbindings_1",	1u	},
		{	"numdescriptorsetbindings_2",	2u	}
	};

	struct
	{
		const char*		name;
		deUint32		num;
	}
	const numDynamicBindings[]			=
	{
		{	"numdynamicbindings_1",	1u	},
		{	"numdynamicbindings_2",	2u	}
	};

	struct
	{
		const char*		name;
		deUint32		num;
	}
	const numNonDynamicBindings[]		=
	{
		{	"numnondynamicbindings_0",	0u	},
		{	"numnondynamicbindings_1",	1u	}
	};

	de::MovePtr<tcu::TestCaseGroup>	dynamicOffsetTests	(new tcu::TestCaseGroup(testCtx, "dynamic_offset", "Dynamic offset tests"));

	for (deUint32 pipelineTypeIdx = 0; pipelineTypeIdx < DE_LENGTH_OF_ARRAY(pipelineTypes); pipelineTypeIdx++)
	{
		de::MovePtr<tcu::TestCaseGroup>	pipelineTypeGroup	(new tcu::TestCaseGroup(testCtx, pipelineTypes[pipelineTypeIdx], ""));

		for (deUint32 groupingTypeIdx = 0; groupingTypeIdx < DE_LENGTH_OF_ARRAY(groupingTypes); ++groupingTypeIdx)
		{
			de::MovePtr<tcu::TestCaseGroup> groupingTypeGroup (new tcu::TestCaseGroup(testCtx, groupingTypes[groupingTypeIdx].name, ""));

			for (deUint32 descriptorTypeIdx = 0; descriptorTypeIdx < DE_LENGTH_OF_ARRAY(descriptorTypes); descriptorTypeIdx++)
			{
				de::MovePtr<tcu::TestCaseGroup>	descriptorTypeGroup	(new tcu::TestCaseGroup(testCtx, descriptorTypes[descriptorTypeIdx].name, ""));

				for (deUint32 numCmdBuffersIdx = 0; numCmdBuffersIdx < DE_LENGTH_OF_ARRAY(numCmdBuffers); numCmdBuffersIdx++)
				{
					de::MovePtr<tcu::TestCaseGroup>	numCmdBuffersGroup	(new tcu::TestCaseGroup(testCtx, numCmdBuffers[numCmdBuffersIdx].name, ""));

					for (deUint32 reverseOrderIdx = 0; reverseOrderIdx < DE_LENGTH_OF_ARRAY(reverseOrders); reverseOrderIdx++)
					{
						if (numCmdBuffers[numCmdBuffersIdx].num < 2 && reverseOrders[reverseOrderIdx].reverse)
							continue;

						de::MovePtr<tcu::TestCaseGroup>	reverseOrderGroup	(new tcu::TestCaseGroup(testCtx, reverseOrders[reverseOrderIdx].name, ""));

						for (deUint32 numDescriptorSetBindingsIdx = 0; numDescriptorSetBindingsIdx < DE_LENGTH_OF_ARRAY(numDescriptorSetBindings); numDescriptorSetBindingsIdx++)
						{
							if (numCmdBuffers[numCmdBuffersIdx].num > 1 && numDescriptorSetBindings[numDescriptorSetBindingsIdx].num > 1)
								continue;

							de::MovePtr<tcu::TestCaseGroup>	numDescriptorSetBindingsGroup	(new tcu::TestCaseGroup(testCtx, numDescriptorSetBindings[numDescriptorSetBindingsIdx].name, ""));
							for (deUint32 numDynamicBindingsIdx = 0; numDynamicBindingsIdx < DE_LENGTH_OF_ARRAY(numDynamicBindings); numDynamicBindingsIdx++)
							{
								de::MovePtr<tcu::TestCaseGroup>	numDynamicBindingsGroup	(new tcu::TestCaseGroup(testCtx, numDynamicBindings[numDynamicBindingsIdx].name, ""));

								for (deUint32 numNonDynamicBindingsIdx = 0; numNonDynamicBindingsIdx < DE_LENGTH_OF_ARRAY(numNonDynamicBindings); numNonDynamicBindingsIdx++)
								{
									TestParams params;
									params.descriptorType			= descriptorTypes[descriptorTypeIdx].type;
									params.numCmdBuffers			= numCmdBuffers[numCmdBuffersIdx].num;
									params.reverseOrder				= reverseOrders[reverseOrderIdx].reverse;
									params.numDescriptorSetBindings	= numDescriptorSetBindings[numDescriptorSetBindingsIdx].num;
									params.numDynamicBindings		= numDynamicBindings[numDynamicBindingsIdx].num;
									params.numNonDynamicBindings	= numNonDynamicBindings[numNonDynamicBindingsIdx].num;
									params.groupingStrategy			= groupingTypes[groupingTypeIdx].strategy;

									if (strcmp(pipelineTypes[pipelineTypeIdx], "graphics") == 0)
										numDynamicBindingsGroup->addChild(new DynamicOffsetGraphicsTest(testCtx, numNonDynamicBindings[numNonDynamicBindingsIdx].name, "", params));
									else
										numDynamicBindingsGroup->addChild(new DynamicOffsetComputeTest(testCtx, numNonDynamicBindings[numNonDynamicBindingsIdx].name, "", params));
								}

								numDescriptorSetBindingsGroup->addChild(numDynamicBindingsGroup.release());
							}

							reverseOrderGroup->addChild(numDescriptorSetBindingsGroup.release());
						}

						numCmdBuffersGroup->addChild(reverseOrderGroup.release());
					}

					descriptorTypeGroup->addChild(numCmdBuffersGroup.release());
				}

				groupingTypeGroup->addChild(descriptorTypeGroup.release());
			}

			pipelineTypeGroup->addChild(groupingTypeGroup.release());
		}

		dynamicOffsetTests->addChild(pipelineTypeGroup.release());
	}

	return dynamicOffsetTests.release();
}

} // pipeline
} // vkt
