/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2021 The Khronos Group Inc.
 * Copyright (c) 2021 Valve Corporation.
 *
 * 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 VK_VALVE_mutable_descriptor_type.
 *//*--------------------------------------------------------------------*/
#include "vktBindingValveMutableTests.hpp"
#include "vktTestCase.hpp"

#include "vkDefs.hpp"
#include "vkRefUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkImageWithMemory.hpp"
#include "vkBufferWithMemory.hpp"
#include "vkTypeUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkRayTracingUtil.hpp"

#include "deUniquePtr.hpp"
#include "deSTLUtil.hpp"
#include "deStringUtil.hpp"

#include <vector>
#include <algorithm>
#include <iterator>
#include <set>
#include <sstream>
#include <limits>

namespace vkt
{
namespace BindingModel
{

namespace
{

using namespace vk;

deUint32 getDescriptorNumericValue (deUint32 iteration, deUint32 bindingIdx, deUint32 descriptorIdx = 0u)
{
	// When assigning numeric values for the descriptor contents, each descriptor will get 0x5aIIBBDD. II is an octed containing the
	// iteration index. BB is an octet containing the binding index and DD is the descriptor index inside that binding.
	constexpr deUint32 kNumericValueBase = 0x5a000000u;

	return (kNumericValueBase | ((iteration & 0xFFu) << 16) | ((bindingIdx & 0xFFu) << 8) | (descriptorIdx & 0xFFu));
}

deUint16 getAccelerationStructureOffsetX (deUint32 descriptorNumericValue)
{
	// Keep the lowest 16 bits (binding and descriptor idx) as the offset.
	return static_cast<deUint16>(descriptorNumericValue);
}

// Value that will be stored in the output buffer to signal success reading values.
deUint32 getExpectedOutputBufferValue ()
{
	return 2u;
}

// This value will be stored in an image to be sampled when checking descriptors containing samplers alone.
deUint32 getExternalSampledImageValue ()
{
	return 0x41322314u;
}

// Value that will be ORed with the descriptor value before writing.
deUint32 getStoredValueMask ()
{
	return 0xFF000000u;
}

VkFormat getDescriptorImageFormat ()
{
	return VK_FORMAT_R32_UINT;
}

VkExtent3D getDefaultExtent ()
{
	return makeExtent3D(1u, 1u, 1u);
}

// Convert value to hexadecimal.
std::string toHex (deUint32 val)
{
	std::ostringstream s;
	s << "0x" << std::hex << val << "u";
	return s.str();
}

// Returns the list of descriptor types that cannot be part of a mutable descriptor.
std::vector<VkDescriptorType> getForbiddenMutableTypes ()
{
	return std::vector<VkDescriptorType>
		{
			VK_DESCRIPTOR_TYPE_MUTABLE_VALVE,
			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
			VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT,
		};
}

// Returns the list of descriptor types that are mandatory for the extension.
std::vector<VkDescriptorType> getMandatoryMutableTypes ()
{
	return std::vector<VkDescriptorType>
		{
			VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
			VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
			VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
			VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
		};
}

// This helps quickly transform a vector of descriptor types into a bitmask, which makes it easier to check some conditions.
enum DescriptorTypeFlagBits
{
	DTFB_SAMPLER                    = (1 << 0),
	DTFB_COMBINED_IMAGE_SAMPLER     = (1 << 1),
	DTFB_SAMPLED_IMAGE              = (1 << 2),
	DTFB_STORAGE_IMAGE              = (1 << 3),
	DTFB_UNIFORM_TEXEL_BUFFER       = (1 << 4),
	DTFB_STORAGE_TEXEL_BUFFER       = (1 << 5),
	DTFB_UNIFORM_BUFFER             = (1 << 6),
	DTFB_STORAGE_BUFFER             = (1 << 7),
	DTFB_UNIFORM_BUFFER_DYNAMIC     = (1 << 8),
	DTFB_STORAGE_BUFFER_DYNAMIC     = (1 << 9),
	DTFB_INPUT_ATTACHMENT           = (1 << 10),
	DTFB_INLINE_UNIFORM_BLOCK_EXT   = (1 << 11),
	DTFB_ACCELERATION_STRUCTURE_KHR = (1 << 12),
	DTFB_ACCELERATION_STRUCTURE_NV  = (1 << 13),
	DTFB_MUTABLE_VALVE              = (1 << 14),
};

using DescriptorTypeFlags = deUint32;

// Convert type to its corresponding flag bit.
DescriptorTypeFlagBits toDescriptorTypeFlagBit (VkDescriptorType descriptorType)
{
	switch (descriptorType)
	{
	case VK_DESCRIPTOR_TYPE_SAMPLER:                        return DTFB_SAMPLER;
	case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:         return DTFB_COMBINED_IMAGE_SAMPLER;
	case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:                  return DTFB_SAMPLED_IMAGE;
	case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:                  return DTFB_STORAGE_IMAGE;
	case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:           return DTFB_UNIFORM_TEXEL_BUFFER;
	case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:           return DTFB_STORAGE_TEXEL_BUFFER;
	case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:                 return DTFB_UNIFORM_BUFFER;
	case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:                 return DTFB_STORAGE_BUFFER;
	case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:         return DTFB_UNIFORM_BUFFER_DYNAMIC;
	case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:         return DTFB_STORAGE_BUFFER_DYNAMIC;
	case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:               return DTFB_INPUT_ATTACHMENT;
	case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:       return DTFB_INLINE_UNIFORM_BLOCK_EXT;
	case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:     return DTFB_ACCELERATION_STRUCTURE_KHR;
	case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV:      return DTFB_ACCELERATION_STRUCTURE_NV;
	case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE:                  return DTFB_MUTABLE_VALVE;
	default: break;
	}

	// Unreachable.
	DE_ASSERT(false);
	return DTFB_SAMPLER;
}

// Convert vector of descriptor types to a bitfield.
DescriptorTypeFlags toDescriptorTypeFlags (const std::vector<VkDescriptorType>& types)
{
	DescriptorTypeFlags result = 0u;
	for (const auto& t : types)
		result |= toDescriptorTypeFlagBit(t);
	return result;
}

// Convert bitfield to vector of descriptor types.
std::vector<VkDescriptorType> toDescriptorTypeVector (DescriptorTypeFlags bitfield)
{
	std::vector<VkDescriptorType> result;

	if (bitfield & DTFB_SAMPLER)                     result.push_back(VK_DESCRIPTOR_TYPE_SAMPLER);
	if (bitfield & DTFB_COMBINED_IMAGE_SAMPLER)      result.push_back(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
	if (bitfield & DTFB_SAMPLED_IMAGE)               result.push_back(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
	if (bitfield & DTFB_STORAGE_IMAGE)               result.push_back(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
	if (bitfield & DTFB_UNIFORM_TEXEL_BUFFER)        result.push_back(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
	if (bitfield & DTFB_STORAGE_TEXEL_BUFFER)        result.push_back(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
	if (bitfield & DTFB_UNIFORM_BUFFER)              result.push_back(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
	if (bitfield & DTFB_STORAGE_BUFFER)              result.push_back(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
	if (bitfield & DTFB_UNIFORM_BUFFER_DYNAMIC)      result.push_back(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
	if (bitfield & DTFB_STORAGE_BUFFER_DYNAMIC)      result.push_back(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
	if (bitfield & DTFB_INPUT_ATTACHMENT)            result.push_back(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
	if (bitfield & DTFB_INLINE_UNIFORM_BLOCK_EXT)    result.push_back(VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT);
	if (bitfield & DTFB_ACCELERATION_STRUCTURE_KHR)  result.push_back(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR);
	if (bitfield & DTFB_ACCELERATION_STRUCTURE_NV)   result.push_back(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV);
	if (bitfield & DTFB_MUTABLE_VALVE)               result.push_back(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE);

	return result;
}

// How to create the source set when copying descriptors from another set.
// * MUTABLE means to transform bindings into mutable bindings.
// * NONMUTABLE means to transform bindings into non-mutable bindings.
enum class SourceSetStrategy
{
	MUTABLE = 0,
	NONMUTABLE,
	NO_SOURCE,
};

enum class PoolMutableStrategy
{
	KEEP_TYPES = 0,
	EXPAND_TYPES,
	NO_TYPES,
};

// Type of information that's present in VkWriteDescriptorSet.
enum class WriteType
{
	IMAGE_INFO = 0,
	BUFFER_INFO,
	BUFFER_VIEW,
	ACCELERATION_STRUCTURE_INFO,
};

struct WriteInfo
{
	WriteType writeType;
	union
	{
		VkDescriptorImageInfo                           imageInfo;
		VkDescriptorBufferInfo                          bufferInfo;
		VkBufferView                                    bufferView;
		VkWriteDescriptorSetAccelerationStructureKHR    asInfo;
	};

	explicit WriteInfo (const VkDescriptorImageInfo& info_)
		: writeType(WriteType::IMAGE_INFO)
		, imageInfo(info_)
	{}

	explicit WriteInfo (const VkDescriptorBufferInfo& info_)
		: writeType(WriteType::BUFFER_INFO)
		, bufferInfo(info_)
	{}

	explicit WriteInfo (VkBufferView view_)
		: writeType(WriteType::BUFFER_VIEW)
		, bufferView(view_)
	{}

	explicit WriteInfo (const VkWriteDescriptorSetAccelerationStructureKHR& asInfo_)
		: writeType(WriteType::ACCELERATION_STRUCTURE_INFO)
		, asInfo(asInfo_)
	{}
};

// Resource backing up a single binding.
enum class ResourceType
{
	SAMPLER = 0,
	IMAGE,
	COMBINED_IMAGE_SAMPLER,
	BUFFER,
	BUFFER_VIEW,
	ACCELERATION_STRUCTURE,
};

// Type of resource backing up a particular descriptor type.
ResourceType toResourceType (VkDescriptorType descriptorType)
{
	ResourceType resourceType = ResourceType::SAMPLER;
	switch (descriptorType)
	{
	case VK_DESCRIPTOR_TYPE_SAMPLER:
		resourceType = ResourceType::SAMPLER;
		break;

	case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
		resourceType = ResourceType::COMBINED_IMAGE_SAMPLER;
		break;

	case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
	case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
	case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
		resourceType = ResourceType::IMAGE;
		break;

	case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
	case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
		resourceType = ResourceType::BUFFER_VIEW;
		break;

	case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
	case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
		resourceType = ResourceType::BUFFER;
		break;

	case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
		resourceType = ResourceType::ACCELERATION_STRUCTURE;
		break;

	default:
		DE_ASSERT(false);
		break;
	}

	return resourceType;
}

bool isShaderWritable (VkDescriptorType descriptorType)
{
	return (descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
	        descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
}

Move<VkSampler> makeDefaultSampler (const DeviceInterface& vkd, VkDevice device)
{
	const VkSamplerCreateInfo samplerCreateInfo = {
		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,  //  VkStructureType			sType;
		nullptr,                                //  const void*				pNext;
		0u,                                     //  VkSamplerCreateFlags	flags;
		VK_FILTER_NEAREST,                      //  VkFilter				magFilter;
		VK_FILTER_NEAREST,                      //  VkFilter				minFilter;
		VK_SAMPLER_MIPMAP_MODE_NEAREST,         //  VkSamplerMipmapMode		mipmapMode;
		VK_SAMPLER_ADDRESS_MODE_REPEAT,         //  VkSamplerAddressMode	addressModeU;
		VK_SAMPLER_ADDRESS_MODE_REPEAT,         //  VkSamplerAddressMode	addressModeV;
		VK_SAMPLER_ADDRESS_MODE_REPEAT,         //  VkSamplerAddressMode	addressModeW;
		0.f,                                    //  float					mipLodBias;
		VK_FALSE,                               //  VkBool32				anisotropyEnable;
		1.f,                                    //  float					maxAnisotropy;
		VK_FALSE,                               //  VkBool32				compareEnable;
		VK_COMPARE_OP_ALWAYS,                   //  VkCompareOp				compareOp;
		0.f,                                    //  float					minLod;
		0.f,                                    //  float					maxLod;
		VK_BORDER_COLOR_INT_TRANSPARENT_BLACK,  //  VkBorderColor			borderColor;
		VK_FALSE,                               //  VkBool32				unnormalizedCoordinates;
	};

	return createSampler(vkd, device, &samplerCreateInfo);
}

de::MovePtr<ImageWithMemory> makeDefaultImage (const DeviceInterface& vkd, VkDevice device, Allocator& alloc)
{
	const auto              extent     = makeExtent3D(1u, 1u, 1u);
	const VkImageUsageFlags usageFlags = (
		VK_IMAGE_USAGE_SAMPLED_BIT
		| VK_IMAGE_USAGE_STORAGE_BIT
		| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
		| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
		| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
		| VK_IMAGE_USAGE_TRANSFER_DST_BIT);

	const VkImageCreateInfo imageCreateInfo = {
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    //  VkStructureType			sType;
		nullptr,                                //  const void*				pNext;
		0u,                                     //  VkImageCreateFlags		flags;
		VK_IMAGE_TYPE_2D,                       //  VkImageType				imageType;
		getDescriptorImageFormat(),             //  VkFormat				format;
		extent,                                 //  VkExtent3D				extent;
		1u,                                     //  deUint32				mipLevels;
		1u,                                     //  deUint32				arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,                  //  VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,                //  VkImageTiling			tiling;
		usageFlags,                             //  VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,              //  VkSharingMode			sharingMode;
		0u,                                     //  deUint32				queueFamilyIndexCount;
		nullptr,                                //  const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,              //  VkImageLayout			initialLayout;
	};
	return de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, alloc, imageCreateInfo, MemoryRequirement::Any));
}

Move<VkImageView> makeDefaultImageView (const DeviceInterface& vkd, VkDevice device, VkImage image)
{
	const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	return makeImageView(vkd, device, image, VK_IMAGE_VIEW_TYPE_2D, getDescriptorImageFormat(), subresourceRange);
}

de::MovePtr<BufferWithMemory> makeDefaultBuffer (const DeviceInterface& vkd, VkDevice device, Allocator& alloc, deUint32 numElements = 1u)
{
	const VkBufferUsageFlags bufferUsage = (
		VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
		| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
		| VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
		| VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
		| VK_BUFFER_USAGE_TRANSFER_SRC_BIT
		| VK_BUFFER_USAGE_TRANSFER_DST_BIT);

	const auto bufferSize = static_cast<VkDeviceSize>(sizeof(deUint32) * static_cast<size_t>(numElements));

	const auto bufferCreateInfo = makeBufferCreateInfo(bufferSize, bufferUsage);

	return de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, alloc, bufferCreateInfo, MemoryRequirement::HostVisible));
}

Move<VkBufferView> makeDefaultBufferView (const DeviceInterface& vkd, VkDevice device, VkBuffer buffer)
{
	const auto bufferOffset = static_cast<VkDeviceSize>(0);
	const auto bufferSize   = static_cast<VkDeviceSize>(sizeof(deUint32));

	return makeBufferView(vkd, device, buffer, getDescriptorImageFormat(), bufferOffset, bufferSize);
}

struct AccelerationStructureData
{
	using TLASPtr = de::MovePtr<TopLevelAccelerationStructure>;
	using BLASPtr = de::MovePtr<BottomLevelAccelerationStructure>;

	TLASPtr tlas;
	BLASPtr blas;

	void swap (AccelerationStructureData& other)
	{
		auto myTlasPtr = tlas.release();
		auto myBlasPtr = blas.release();

		auto otherTlasPtr = other.tlas.release();
		auto otherBlasPtr = other.blas.release();

		tlas = TLASPtr(otherTlasPtr);
		blas = BLASPtr(otherBlasPtr);

		other.tlas = TLASPtr(myTlasPtr);
		other.blas = BLASPtr(myBlasPtr);
	}

	AccelerationStructureData () : tlas() , blas() {}

	AccelerationStructureData (AccelerationStructureData&& other)
		: AccelerationStructureData()
	{
		swap(other);
	}

	AccelerationStructureData& operator= (AccelerationStructureData&& other)
	{
		swap(other);
		return *this;
	}
};

AccelerationStructureData makeDefaultAccelerationStructure (const DeviceInterface& vkd, VkDevice device, VkCommandBuffer cmdBuffer, Allocator& alloc, bool triangles, deUint16 offsetX)
{
	AccelerationStructureData data;

	// Triangle around (offsetX, 0) with depth 5.0.
	const float middleX = static_cast<float>(offsetX);
	const float leftX   = middleX - 0.5f;
	const float rightX  = middleX + 0.5f;
	const float topY    = 0.5f;
	const float bottomY = -0.5f;
	const float depth   = 5.0f;

	std::vector<tcu::Vec3> vertices;

	if (triangles)
	{
		vertices.reserve(3u);
		vertices.emplace_back(middleX, topY, depth);
		vertices.emplace_back(rightX, bottomY, depth);
		vertices.emplace_back(leftX, bottomY, depth);
	}
	else
	{
		vertices.reserve(2u);
		vertices.emplace_back(leftX, bottomY, depth);
		vertices.emplace_back(rightX, topY, depth);
	}

	data.tlas = makeTopLevelAccelerationStructure();
	data.blas = makeBottomLevelAccelerationStructure();

	VkGeometryInstanceFlagsKHR instanceFlags = 0u;
	if (triangles)
		instanceFlags |= VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;

	data.blas->addGeometry(vertices, triangles, VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR);
	data.blas->createAndBuild(vkd, device, cmdBuffer, alloc);

	de::SharedPtr<BottomLevelAccelerationStructure> blasSharedPtr (data.blas.release());
	data.tlas->setInstanceCount(1u);
	data.tlas->addInstance(blasSharedPtr, identityMatrix3x4, 0u, 0xFFu, 0u, instanceFlags);
	data.tlas->createAndBuild(vkd, device, cmdBuffer, alloc);

	return data;
}

const auto kShaderAccess = (VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);

struct Resource
{
	VkDescriptorType              descriptorType;
	ResourceType                  resourceType;
	Move<VkSampler>               sampler;
	de::MovePtr<ImageWithMemory>  imageWithMemory;
	Move<VkImageView>             imageView;
	de::MovePtr<BufferWithMemory> bufferWithMemory;
	Move<VkBufferView>            bufferView;
	AccelerationStructureData     asData;
	deUint32                      initialValue;

	Resource (VkDescriptorType descriptorType_, const DeviceInterface& vkd, VkDevice device, Allocator& alloc, deUint32 qIndex, VkQueue queue, bool useAABBs, deUint32 initialValue_, deUint32 numElements = 1u)
		: descriptorType	(descriptorType_)
		, resourceType      (toResourceType(descriptorType))
		, sampler           ()
		, imageWithMemory   ()
		, imageView         ()
		, bufferWithMemory  ()
		, bufferView        ()
		, asData            ()
		, initialValue      (initialValue_)
	{
		if (numElements != 1u)
			DE_ASSERT(resourceType == ResourceType::BUFFER);

		switch (resourceType)
		{
		case ResourceType::SAMPLER:
			sampler = makeDefaultSampler(vkd, device);
			break;

		case ResourceType::IMAGE:
			imageWithMemory = makeDefaultImage(vkd, device, alloc);
			imageView       = makeDefaultImageView(vkd, device, imageWithMemory->get());
			break;

		case ResourceType::COMBINED_IMAGE_SAMPLER:
			sampler         = makeDefaultSampler(vkd, device);
			imageWithMemory = makeDefaultImage(vkd, device, alloc);
			imageView       = makeDefaultImageView(vkd, device, imageWithMemory->get());
			break;

		case ResourceType::BUFFER:
			bufferWithMemory = makeDefaultBuffer(vkd, device, alloc, numElements);
			break;

		case ResourceType::BUFFER_VIEW:
			bufferWithMemory = makeDefaultBuffer(vkd, device, alloc);
			bufferView       = makeDefaultBufferView(vkd, device, bufferWithMemory->get());
			break;

		case ResourceType::ACCELERATION_STRUCTURE:
			{
				const auto cmdPool      = makeCommandPool(vkd, device, qIndex);
				const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
				const auto cmdBuffer    = cmdBufferPtr.get();
				const bool triangles    = !useAABBs;

				beginCommandBuffer(vkd, cmdBuffer);
				asData = makeDefaultAccelerationStructure(vkd, device, cmdBuffer, alloc, triangles, getAccelerationStructureOffsetX(initialValue));
				endCommandBuffer(vkd, cmdBuffer);
				submitCommandsAndWait(vkd, device, queue, cmdBuffer);
			}
			break;

		default:
			DE_ASSERT(false);
			break;
		}

		if (imageWithMemory || bufferWithMemory)
		{
			const auto cmdPool      = makeCommandPool(vkd, device, qIndex);
			const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
			const auto cmdBuffer    = cmdBufferPtr.get();

			if (imageWithMemory)
			{
				// Prepare staging buffer.
				const auto               bufferSize        = static_cast<VkDeviceSize>(sizeof(initialValue));
				const VkBufferUsageFlags bufferUsage       = (VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
				const auto               stagingBufferInfo = makeBufferCreateInfo(bufferSize, bufferUsage);

				BufferWithMemory stagingBuffer(vkd, device, alloc, stagingBufferInfo, MemoryRequirement::HostVisible);
				auto& bufferAlloc = stagingBuffer.getAllocation();
				void* bufferData  = bufferAlloc.getHostPtr();

				deMemcpy(bufferData, &initialValue, sizeof(initialValue));
				flushAlloc(vkd, device, bufferAlloc);

				beginCommandBuffer(vkd, cmdBuffer);

				// Transition and copy image.
				const auto copyRegion         = makeBufferImageCopy(makeExtent3D(1u, 1u, 1u),
																	makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));

				// Switch image to TRANSFER_DST_OPTIMAL before copying data to it.
				const auto subresourceRange   = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);

				const auto preTransferBarrier = makeImageMemoryBarrier(
					0u, VK_ACCESS_TRANSFER_WRITE_BIT,
					VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
					imageWithMemory->get(), subresourceRange);

				vkd.cmdPipelineBarrier(
					cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
					0u, nullptr, 0u, nullptr, 1u, &preTransferBarrier);

				// Copy data to image.
				vkd.cmdCopyBufferToImage(cmdBuffer, stagingBuffer.get(), imageWithMemory->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);

				// Switch image to the GENERAL layout before reading or writing to it from shaders.
				const auto postTransferBarrier = makeImageMemoryBarrier(
					VK_ACCESS_TRANSFER_WRITE_BIT, kShaderAccess,
					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
					imageWithMemory->get(), subresourceRange);

				vkd.cmdPipelineBarrier(
					cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u,
					0u, nullptr, 0u, nullptr, 1u, &postTransferBarrier);

				endCommandBuffer(vkd, cmdBuffer);
				submitCommandsAndWait(vkd, device, queue, cmdBuffer);
			}

			if (bufferWithMemory)
			{
				auto& bufferAlloc = bufferWithMemory->getAllocation();
				void* bufferData  = bufferAlloc.getHostPtr();

				const std::vector<deUint32> bufferValues(numElements, initialValue);
				deMemcpy(bufferData, bufferValues.data(), de::dataSize(bufferValues));
				flushAlloc(vkd, device, bufferAlloc);

				beginCommandBuffer(vkd, cmdBuffer);

				// Make sure host writes happen before shader reads/writes. Note: this barrier is not needed in theory.
				const auto hostToShaderBarrier = makeMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, kShaderAccess);

				vkd.cmdPipelineBarrier(
					cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u,
					1u, &hostToShaderBarrier, 0u, nullptr, 0u, nullptr);

				endCommandBuffer(vkd, cmdBuffer);
				submitCommandsAndWait(vkd, device, queue, cmdBuffer);
			}
		}
	}

	// Remove problematic copy constructor.
	Resource (const Resource&) = delete;

	// Make it movable.
	Resource (Resource&& other) noexcept
		: descriptorType	(other.descriptorType)
		, resourceType      (other.resourceType)
		, sampler           (other.sampler)
		, imageWithMemory   (other.imageWithMemory.release())
		, imageView         (other.imageView)
		, bufferWithMemory  (other.bufferWithMemory.release())
		, bufferView        (other.bufferView)
		, asData			(std::move(other.asData))
		, initialValue      (other.initialValue)
	{}

	~Resource ()
	{}

	WriteInfo makeWriteInfo () const
	{
		using WriteInfoPtr = de::MovePtr<WriteInfo>;

		WriteInfoPtr writeInfo;

		switch (resourceType)
		{
		case ResourceType::SAMPLER:
			{
				const VkDescriptorImageInfo imageInfo = { sampler.get(), DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED };
				writeInfo = WriteInfoPtr (new WriteInfo(imageInfo));
			}
			break;

		case ResourceType::IMAGE:
			{
				const VkDescriptorImageInfo imageInfo = { DE_NULL, imageView.get(), VK_IMAGE_LAYOUT_GENERAL };
				writeInfo = WriteInfoPtr (new WriteInfo(imageInfo));
			}
			break;

		case ResourceType::COMBINED_IMAGE_SAMPLER:
			{
				const VkDescriptorImageInfo imageInfo = { sampler.get(), imageView.get(), VK_IMAGE_LAYOUT_GENERAL };
				writeInfo = WriteInfoPtr (new WriteInfo(imageInfo));
			}
			break;

		case ResourceType::BUFFER:
			{
				const VkDescriptorBufferInfo bufferInfo = { bufferWithMemory->get(), 0ull, static_cast<VkDeviceSize>(sizeof(deUint32)) };
				writeInfo = WriteInfoPtr (new WriteInfo(bufferInfo));
			}
			break;

		case ResourceType::BUFFER_VIEW:
			writeInfo = WriteInfoPtr (new WriteInfo(bufferView.get()));
			break;

		case ResourceType::ACCELERATION_STRUCTURE:
			{
				VkWriteDescriptorSetAccelerationStructureKHR asWrite = initVulkanStructure();
				asWrite.accelerationStructureCount = 1u;
				asWrite.pAccelerationStructures    = asData.tlas.get()->getPtr();
				writeInfo = WriteInfoPtr (new WriteInfo(asWrite));
			}
			break;

		default:
			DE_ASSERT(false);
			break;
		}

		return *writeInfo;
	}

	tcu::Maybe<deUint32> getStoredValue (const DeviceInterface& vkd, VkDevice device, Allocator& alloc, deUint32 qIndex, VkQueue queue, deUint32 position = 0u) const
	{
		if (position != 0u)
			DE_ASSERT(static_cast<bool>(bufferWithMemory));

		if (imageWithMemory || bufferWithMemory)
		{
			// Command pool and buffer.
			const auto cmdPool      = makeCommandPool(vkd, device, qIndex);
			const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
			const auto cmdBuffer    = cmdBufferPtr.get();

			if (imageWithMemory)
			{
				// Prepare staging buffer.
				deUint32                 result;
				const auto               bufferSize        = static_cast<VkDeviceSize>(sizeof(result));
				const VkBufferUsageFlags bufferUsage       = (VK_BUFFER_USAGE_TRANSFER_DST_BIT);
				const auto               stagingBufferInfo = makeBufferCreateInfo(bufferSize, bufferUsage);

				BufferWithMemory stagingBuffer(vkd, device, alloc, stagingBufferInfo, MemoryRequirement::HostVisible);
				auto& bufferAlloc = stagingBuffer.getAllocation();
				void* bufferData  = bufferAlloc.getHostPtr();

				// Copy image value to staging buffer.
				beginCommandBuffer(vkd, cmdBuffer);

				// Make sure shader accesses happen before transfers and prepare image for transfer.
				const auto colorResourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);

				const auto preTransferBarrier = makeImageMemoryBarrier(
					kShaderAccess, VK_ACCESS_TRANSFER_READ_BIT,
					VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
					imageWithMemory->get(), colorResourceRange);

				vkd.cmdPipelineBarrier(
					cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
					0u, nullptr, 0u, nullptr, 1u, &preTransferBarrier);

				// Copy image contents to staging buffer.
				const auto copyRegion = makeBufferImageCopy(makeExtent3D(1u, 1u, 1u),
															makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
				vkd.cmdCopyImageToBuffer(cmdBuffer, imageWithMemory->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingBuffer.get(), 1u, &copyRegion);

				// Make sure writes are visible from the host.
				const auto postTransferBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
				vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &postTransferBarrier, 0u, nullptr, 0u, nullptr);

				endCommandBuffer(vkd, cmdBuffer);
				submitCommandsAndWait(vkd, device, queue, cmdBuffer);

				// Get value from staging buffer.
				invalidateAlloc(vkd, device, bufferAlloc);
				deMemcpy(&result, bufferData, sizeof(result));
				return tcu::just(result);
			}

			if (bufferWithMemory)
			{
				auto&       bufferAlloc = bufferWithMemory->getAllocation();
				auto        bufferData  = reinterpret_cast<const char*>(bufferAlloc.getHostPtr());
				deUint32    result;

				// Make sure shader writes are visible from the host.
				beginCommandBuffer(vkd, cmdBuffer);

				const auto shaderToHostBarrier = makeMemoryBarrier(kShaderAccess, VK_ACCESS_HOST_READ_BIT);
				vkd.cmdPipelineBarrier(
					cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
					1u, &shaderToHostBarrier, 0u, nullptr, 0u, nullptr);

				endCommandBuffer(vkd, cmdBuffer);
				submitCommandsAndWait(vkd, device, queue, cmdBuffer);

				invalidateAlloc(vkd, device, bufferAlloc);
				deMemcpy(&result, bufferData + sizeof(deUint32) * static_cast<size_t>(position), sizeof(result));
				return tcu::just(result);
			}
		}

		return tcu::Nothing;
	}
};

struct BindingInterface
{
	virtual ~BindingInterface () {}

	// Minimum number of iterations to test all mutable types.
	virtual deUint32 maxTypes () const = 0;

	// Types that will be used by the binding at a given iteration.
	virtual std::vector<VkDescriptorType> typesAtIteration (deUint32 iteration) const = 0;

	// Binding's main type.
	virtual VkDescriptorType mainType () const = 0;

	// Binding's list of mutable types, if present.
	virtual std::vector<VkDescriptorType> mutableTypes () const = 0;

	// Descriptor count in the binding.
	virtual size_t size () const = 0;

	// Is the binding an array binding?
	virtual bool isArray () const = 0;

	// Is the binding an unbounded array?
	virtual bool isUnbounded () const = 0;

	// Will the binding use different descriptor types in a given iteration?
	virtual bool needsAliasing (deUint32 iteration) const
	{
		const auto                 typesVec = typesAtIteration(iteration);
		std::set<VkDescriptorType> descTypes(begin(typesVec), end(typesVec));
		return (descTypes.size() > 1u);
	}

	// Will the binding need aliasing on any iteration up to a given number?
	virtual bool needsAliasingUpTo (deUint32 numIterations) const
	{
		std::vector<bool> needsAliasingFlags;
		needsAliasingFlags.reserve(numIterations);

		for (deUint32 iter = 0u; iter < numIterations; ++iter)
			needsAliasingFlags.push_back(needsAliasing(iter));

		return std::any_of(begin(needsAliasingFlags), end(needsAliasingFlags), [] (bool f) { return f; });
	}

private:
	virtual bool hasDescriptorType (deUint32 iteration, VkDescriptorType descriptorType) const
	{
		const auto typesVec = typesAtIteration(iteration);
		return (std::find(begin(typesVec), end(typesVec), descriptorType) != end(typesVec));
	}

public:
	// Convert one particular binding to a mutable or non-mutable equivalent binding, returning the equivalent binding.
	virtual de::MovePtr<BindingInterface> toMutable (deUint32 iteration) const = 0;
	virtual de::MovePtr<BindingInterface> toNonMutable (deUint32 iteration) const = 0;

	// Create resources needed to back up this binding.
	virtual std::vector<Resource> createResources (
		const DeviceInterface& vkd, VkDevice device, Allocator& alloc, deUint32 qIndex, VkQueue queue,
		deUint32 iteration, bool useAABBs, deUint32 baseValue) const = 0;

	// Get GLSL binding declarations. Note: no array size means no array, if size is < 0 it means unbounded array.
	virtual std::string glslDeclarations (deUint32 iteration, deUint32 setNum, deUint32 bindingNum, deUint32 inputAttachmentIdx, tcu::Maybe<deInt32> arraySize) const = 0;

	// Get GLSL statements to check this binding.
	virtual std::string glslCheckStatements (deUint32 iteration, deUint32 setNum, deUint32 bindingNum, deUint32 baseValue, tcu::Maybe<deUint32> arrayIndex, bool usePushConstants) const = 0;
};

// Represents a single binding that will be used in a test.
class SingleBinding : public BindingInterface
{
private:
	VkDescriptorType              type;             // The descriptor type.
	std::vector<VkDescriptorType> mutableTypesVec;  // The types that will be used for each iteration of a test if mutable.

public:
	SingleBinding (VkDescriptorType type_, std::vector<VkDescriptorType> mutableTypes_)
		: type              (type_)
		, mutableTypesVec   (std::move(mutableTypes_))
	{
		static const auto kForbiddenMutableTypes = getForbiddenMutableTypes();
		const auto        kBeginForbidden        = begin(kForbiddenMutableTypes);
		const auto        kEndForbidden          = end(kForbiddenMutableTypes);

		// For release builds.
		DE_UNREF(kBeginForbidden);
		DE_UNREF(kEndForbidden);

		if (type != VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)
		{
			DE_ASSERT(mutableTypesVec.empty());
		}
		else
		{
			DE_ASSERT(!mutableTypesVec.empty());
			DE_ASSERT(std::none_of(begin(mutableTypesVec), end(mutableTypesVec),
			                       [&kBeginForbidden, &kEndForbidden] (VkDescriptorType t) -> bool {
				                       return std::find(kBeginForbidden, kEndForbidden, t) != kEndForbidden;
			                       }));
		}
	}

	deUint32 maxTypes () const override
	{
		if (type != VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)
			return 1u;
		const auto vecSize = mutableTypesVec.size();
		DE_ASSERT(vecSize <= std::numeric_limits<deUint32>::max());
		return static_cast<deUint32>(vecSize);
	}

	VkDescriptorType typeAtIteration (deUint32 iteration) const
	{
		return typesAtIteration(iteration)[0];
	}

	std::vector<VkDescriptorType> usedTypes () const
	{
		if (type != VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)
			return std::vector<VkDescriptorType>(1u, type);
		return mutableTypesVec;
	}

	std::vector<VkDescriptorType> typesAtIteration (deUint32 iteration) const override
	{
		const auto typesVec = usedTypes();
		return std::vector<VkDescriptorType>(1u, typesVec[static_cast<size_t>(iteration) % typesVec.size()]);
	}

	VkDescriptorType mainType () const override
	{
		return type;
	}

	std::vector<VkDescriptorType> mutableTypes () const override
	{
		return mutableTypesVec;
	}

	size_t size () const override
	{
		return size_t{1u};
	}

	bool isArray () const override
	{
		return false;
	}

	bool isUnbounded () const override
	{
		return false;
	}

	de::MovePtr<BindingInterface> toMutable (deUint32 iteration) const override
	{
		DE_UNREF(iteration);

		static const auto kMandatoryMutableTypeFlags = toDescriptorTypeFlags(getMandatoryMutableTypes());
		if (type == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)
		{
			const auto descFlags = (toDescriptorTypeFlags(mutableTypesVec) | kMandatoryMutableTypeFlags);
			return de::MovePtr<BindingInterface>(new SingleBinding(type, toDescriptorTypeVector(descFlags)));
		}

		// Make sure it's not a forbidden mutable type.
		static const auto kForbiddenMutableTypes = getForbiddenMutableTypes();
		DE_ASSERT(std::find(begin(kForbiddenMutableTypes), end(kForbiddenMutableTypes), type) == end(kForbiddenMutableTypes));

		// Convert the binding to mutable using a wider set of descriptor types if possible, including the binding type.
		const auto descFlags = (kMandatoryMutableTypeFlags | toDescriptorTypeFlagBit(type));

		return de::MovePtr<BindingInterface>(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, toDescriptorTypeVector(descFlags)));
	}

	de::MovePtr<BindingInterface> toNonMutable (deUint32 iteration) const override
	{
		return de::MovePtr<BindingInterface>(new SingleBinding(typeAtIteration(iteration), std::vector<VkDescriptorType>()));
	}

	std::vector<Resource> createResources (
		const DeviceInterface& vkd, VkDevice device, Allocator& alloc, deUint32 qIndex, VkQueue queue,
		deUint32 iteration, bool useAABBs, deUint32 baseValue) const override
	{
		const auto descriptorType = typeAtIteration(iteration);

		std::vector<Resource> resources;
		resources.emplace_back(descriptorType, vkd, device, alloc, qIndex, queue, useAABBs, baseValue);
		return resources;
	}

	std::string glslDeclarations (deUint32 iteration, deUint32 setNum, deUint32 bindingNum, deUint32 inputAttachmentIdx, tcu::Maybe<deInt32> arraySize) const override
	{
		const auto         descriptorType = typeAtIteration(iteration);
		const std::string  arraySuffix    = ((static_cast<bool>(arraySize)) ? ((arraySize.get() < 0) ? "[]" : ("[" + de::toString(arraySize.get()) + "]")) : "");
		const std::string  layoutAttribs  = "set=" + de::toString(setNum) + ", binding=" + de::toString(bindingNum);
		const std::string  bindingSuffix  = "_" + de::toString(setNum) + "_" + de::toString(bindingNum);
		const std::string  nameSuffix     = bindingSuffix + arraySuffix;
		std::ostringstream declarations;

		declarations << "layout (";

		switch (descriptorType)
		{
		case VK_DESCRIPTOR_TYPE_SAMPLER:
			declarations << layoutAttribs << ") uniform sampler sampler" << nameSuffix;
			break;

		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
			declarations << layoutAttribs << ") uniform usampler2D combinedSampler" << nameSuffix;
			break;

		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
			declarations << layoutAttribs << ") uniform utexture2D sampledImage" << nameSuffix;
			break;

		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
			declarations << layoutAttribs << ") uniform uboBlock" << bindingSuffix << " { uint val; } ubo" << nameSuffix;
			break;

		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
			declarations << layoutAttribs << ") buffer sboBlock" << bindingSuffix << " { uint val; } ssbo" << nameSuffix;
			break;

		case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
			declarations << layoutAttribs << ") uniform utextureBuffer uniformTexel" << nameSuffix;
			break;

		case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
			declarations << layoutAttribs << ", r32ui) uniform uimageBuffer storageTexel" << nameSuffix;
			break;

		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
			declarations << layoutAttribs << ", r32ui) uniform uimage2D storageImage" << nameSuffix;
			break;

		case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
			declarations << layoutAttribs << ", input_attachment_index=" << inputAttachmentIdx << ") uniform usubpassInput inputAttachment" << nameSuffix;
			break;

		case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
			declarations << layoutAttribs << ") uniform accelerationStructureEXT accelerationStructure" << nameSuffix;
			break;

		default:
			DE_ASSERT(false);
			break;
		}

		declarations << ";\n";

		return declarations.str();
	}

	std::string glslCheckStatements (deUint32 iteration, deUint32 setNum, deUint32 bindingNum, deUint32 baseValue_, tcu::Maybe<deUint32> arrayIndex, bool usePushConstants) const override
	{
		const auto        descriptorType = typeAtIteration(iteration);
		const std::string bindingSuffix  = "_" + de::toString(setNum) + "_" + de::toString(bindingNum);

		std::string indexSuffix;
		if (arrayIndex)
		{
			indexSuffix = de::toString(arrayIndex.get());
			if (usePushConstants)
				indexSuffix += " + pc.zero";
			indexSuffix = "[" + indexSuffix + "]";
		}

		const std::string nameSuffix         = bindingSuffix + indexSuffix;
		const std::string baseValue          = toHex(baseValue_);
		const std::string externalImageValue = toHex(getExternalSampledImageValue());
		const std::string mask               = toHex(getStoredValueMask());

		std::ostringstream checks;

		// Note: all of these depend on an external anyError uint variable.
		switch (descriptorType)
		{
		case VK_DESCRIPTOR_TYPE_SAMPLER:
			// Note this depends on an "externalSampledImage" binding.
			checks << "    {\n";
			checks << "      uint readValue = texture(usampler2D(externalSampledImage, sampler" << nameSuffix << "), vec2(0, 0)).r;\n";
			checks << "      debugPrintfEXT(\"iteration-" << iteration << nameSuffix << ": 0x%xu\\n\", readValue);\n";
			checks << "      anyError |= ((readValue == " << externalImageValue << ") ? 0u : 1u);\n";
			//checks << "      anyError = readValue;\n";
			checks << "    }\n";
			break;

		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
			checks << "    {\n";
			checks << "      uint readValue = texture(combinedSampler" << nameSuffix << ", vec2(0, 0)).r;\n";
			checks << "      debugPrintfEXT(\"iteration-" << iteration << nameSuffix << ": 0x%xu\\n\", readValue);\n";
			checks << "      anyError |= ((readValue == " << baseValue << ") ? 0u : 1u);\n";
			//checks << "      anyError = readValue;\n";
			checks << "    }\n";
			break;

		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
			// Note this depends on an "externalSampler" binding.
			checks << "    {\n";
			checks << "      uint readValue = texture(usampler2D(sampledImage" << nameSuffix << ", externalSampler), vec2(0, 0)).r;\n";
			checks << "      debugPrintfEXT(\"iteration-" << iteration << nameSuffix << ": 0x%xu\\n\", readValue);\n";
			checks << "      anyError |= ((readValue == " << baseValue << ") ? 0u : 1u);\n";
			//checks << "      anyError = readValue;\n";
			checks << "    }\n";
			break;

		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
			checks << "    {\n";
			checks << "      uint readValue = ubo" << nameSuffix << ".val;\n";
			checks << "      debugPrintfEXT(\"iteration-" << iteration << nameSuffix << ": 0x%xu\\n\", readValue);\n";
			checks << "      anyError |= ((readValue == " << baseValue << ") ? 0u : 1u);\n";
			//checks << "      anyError = readValue;\n";
			checks << "    }\n";
			break;

		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
			checks << "    {\n";
			checks << "      uint readValue = ssbo" << nameSuffix << ".val;\n";
			checks << "      debugPrintfEXT(\"iteration-" << iteration << nameSuffix << ": 0x%xu\\n\", readValue);\n";
			checks << "      anyError |= ((readValue == " << baseValue << ") ? 0u : 1u);\n";
			//checks << "      anyError = readValue;\n";
			// Check writes.
			checks << "      ssbo" << nameSuffix << ".val = (readValue | " << mask << ");\n";
			checks << "    }\n";
			break;

		case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
			checks << "    {\n";
			checks << "      uint readValue = texelFetch(uniformTexel" << nameSuffix << ", 0).x;\n";
			checks << "      debugPrintfEXT(\"iteration-" << iteration << nameSuffix << ": 0x%xu\\n\", readValue);\n";
			checks << "      anyError |= ((readValue == " << baseValue << ") ? 0u : 1u);\n";
			//checks << "      anyError = readValue;\n";
			checks << "    }\n";
			break;

		case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
			checks << "    {\n";
			checks << "      uint readValue = imageLoad(storageTexel" << nameSuffix << ", 0).x;\n";
			checks << "      debugPrintfEXT(\"iteration-" << iteration << nameSuffix << ": 0x%xu\\n\", readValue);\n";
			checks << "      anyError |= ((readValue == " << baseValue << ") ? 0u : 1u);\n";
			//checks << "      anyError = readValue;\n";
			checks << "      readValue |= " << mask << ";\n";
			// Check writes.
			checks << "      imageStore(storageTexel" << nameSuffix << ", 0, uvec4(readValue, 0, 0, 0));\n";
			checks << "    }\n";
			break;

		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
			checks << "    {\n";
			checks << "      uint readValue = imageLoad(storageImage" << nameSuffix << ", ivec2(0, 0)).x;\n";
			checks << "      debugPrintfEXT(\"iteration-" << iteration << nameSuffix << ": 0x%xu\\n\", readValue);\n";
			checks << "      anyError |= ((readValue == " << baseValue << ") ? 0u : 1u);\n";
			//checks << "      anyError = readValue;\n";
			checks << "      readValue |= " << mask << ";\n";
			// Check writes.
			checks << "      imageStore(storageImage" << nameSuffix << ", ivec2(0, 0), uvec4(readValue, 0, 0, 0));\n";
			checks << "    }\n";
			break;

		case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
			checks << "    {\n";
			checks << "      uint readValue = subpassLoad(inputAttachment" << nameSuffix << ").x;\n";
			checks << "      debugPrintfEXT(\"iteration-" << iteration << nameSuffix << ": 0x%xu\\n\", readValue);\n";
			checks << "      anyError |= ((readValue == " << baseValue << ") ? 0u : 1u);\n";
			//checks << "      anyError = readValue;\n";
			checks << "    }\n";
			break;

		case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
			checks << "    {\n";
			checks << "      const uint cullMask = 0xFF;\n";
			checks << "      const vec3 origin = vec3(" << getAccelerationStructureOffsetX(baseValue_) << ".0, 0.0, 0.0);\n";
			checks << "      const vec3 direction = vec3(0.0, 0.0, 1.0);\n";
			checks << "      const float tmin = 1.0;\n";
			checks << "      const float tmax = 10.0;\n";
			checks << "      uint candidateFound = 0u;\n";
			checks << "      rayQueryEXT rq;\n";
			checks << "      rayQueryInitializeEXT(rq, accelerationStructure" << nameSuffix << ", gl_RayFlagsNoneEXT, cullMask, origin, tmin, direction, tmax);\n";
			checks << "      while (rayQueryProceedEXT(rq)) {\n";
			checks << "        const uint candidateType = rayQueryGetIntersectionTypeEXT(rq, false);\n";
			checks << "        if (candidateType == gl_RayQueryCandidateIntersectionTriangleEXT || candidateType == gl_RayQueryCandidateIntersectionAABBEXT) {\n";
			checks << "          candidateFound = 1u;\n";
			checks << "        }\n";
			checks << "      }\n";
			checks << "      anyError |= ((candidateFound == 1u) ? 0u : 1u);\n";
			checks << "    }\n";
			break;

		default:
			DE_ASSERT(false);
			break;
		}

		return checks.str();
	}
};

// Represents an array of bindings. Individual bindings are stored as SingleBindings because each one of them may take a different
// type in each iteration (i.e. they can all have different descriptor type vectors).
class ArrayBinding : public BindingInterface
{
private:
	bool                       unbounded;
	std::vector<SingleBinding> bindings;

public:
	ArrayBinding (bool unbounded_, std::vector<SingleBinding> bindings_)
		: unbounded (unbounded_)
		, bindings  (std::move(bindings_))
	{
		// We need to check all single bindings have the same effective type, even if mutable descriptors have different orders.
		DE_ASSERT(!bindings.empty());

		std::set<VkDescriptorType>    basicTypes;
		std::set<DescriptorTypeFlags> bindingTypes;

		for (const auto& b : bindings)
		{
			basicTypes.insert(b.mainType());
			bindingTypes.insert(toDescriptorTypeFlags(b.usedTypes()));
		}

		DE_ASSERT(basicTypes.size() == 1u);
		DE_ASSERT(bindingTypes.size() == 1u);

		// For release builds.
		DE_UNREF(basicTypes);
		DE_UNREF(bindingTypes);
	}

	deUint32 maxTypes () const override
	{
		// Each binding may have the same effective type but a different number of iterations due to repeated types.
		std::vector<size_t> bindingSizes;
		bindingSizes.reserve(bindings.size());

		std::transform(begin(bindings), end(bindings), std::back_inserter(bindingSizes),
		               [] (const SingleBinding& b) { return b.usedTypes().size(); });

		const auto maxElement = std::max_element(begin(bindingSizes), end(bindingSizes));
		DE_ASSERT(maxElement != end(bindingSizes));
		DE_ASSERT(*maxElement <= std::numeric_limits<deUint32>::max());
		return static_cast<deUint32>(*maxElement);
	}

	std::vector<VkDescriptorType> typesAtIteration (deUint32 iteration) const override
	{
		std::vector<VkDescriptorType> result;
		result.reserve(bindings.size());

		for (const auto& b : bindings)
			result.push_back(b.typeAtIteration(iteration));

		return result;
	}

	VkDescriptorType mainType () const override
	{
		return bindings[0].mainType();
	}

	std::vector<VkDescriptorType> mutableTypes () const override
	{
		return bindings[0].mutableTypes();
	}

	size_t size () const override
	{
		return bindings.size();
	}

	bool isArray () const override
	{
		return true;
	}

	bool isUnbounded () const override
	{
		return unbounded;
	}

	de::MovePtr<BindingInterface> toMutable (deUint32 iteration) const override
	{
		// Replicate the first binding once converted, as all are equivalent.
		const auto                       firstBindingPtr = bindings[0].toMutable(iteration);
		const auto                       firstBinding    = *dynamic_cast<SingleBinding*>(firstBindingPtr.get());
		const std::vector<SingleBinding> newBindings     (bindings.size(), firstBinding);

		return de::MovePtr<BindingInterface>(new ArrayBinding(unbounded, newBindings));
	}

	de::MovePtr<BindingInterface> toNonMutable (deUint32 iteration) const override
	{
		// Make sure this binding can be converted to nonmutable for a given iteration.
		DE_ASSERT(!needsAliasing(iteration));

		// We could use each SingleBinding's toNonMutable(), but this is the same.
		const auto                       descType       = bindings[0].typeAtIteration(iteration);
		const SingleBinding              firstBinding   (descType, std::vector<VkDescriptorType>());
		const std::vector<SingleBinding> newBindings    (bindings.size(), firstBinding);

		return de::MovePtr<BindingInterface>(new ArrayBinding(unbounded, newBindings));
	}

	std::vector<Resource> createResources (
		const DeviceInterface& vkd, VkDevice device, Allocator& alloc, deUint32 qIndex, VkQueue queue,
		deUint32 iteration, bool useAABBs, deUint32 baseValue) const override
	{
		std::vector<Resource> resources;
		const auto            numBindings = static_cast<deUint32>(bindings.size());

		for (deUint32 i = 0u; i < numBindings; ++i)
		{
			auto resourceVec = bindings[i].createResources(vkd, device, alloc, qIndex, queue, iteration, useAABBs, baseValue + i);
			resources.emplace_back(std::move(resourceVec[0]));
		}

		return resources;
	}

	// We will ignore the array size parameter.
	std::string glslDeclarations (deUint32 iteration, deUint32 setNum, deUint32 bindingNum, deUint32 inputAttachmentIdx, tcu::Maybe<deInt32> arraySize) const override
	{
		const auto descriptorCount = bindings.size();
		const auto arraySizeVal    = (isUnbounded() ? tcu::just(deInt32{-1}) : tcu::just(static_cast<deInt32>(descriptorCount)));

		DE_UNREF(arraySize);
		DE_ASSERT(descriptorCount < static_cast<size_t>(std::numeric_limits<deInt32>::max()));

		// Maybe a single declaration is enough.
		if (!needsAliasing(iteration))
			return bindings[0].glslDeclarations(iteration, setNum, bindingNum, inputAttachmentIdx, arraySizeVal);

		// Aliasing needed. Avoid reusing types.
		const auto                 descriptorTypes = typesAtIteration(iteration);
		std::set<VkDescriptorType> usedTypes;
		std::ostringstream         declarations;

		for (size_t descriptorIdx = 0u; descriptorIdx < descriptorCount; ++descriptorIdx)
		{
			const auto& descriptorType = descriptorTypes[descriptorIdx];
			if (usedTypes.count(descriptorType) > 0)
				continue;

			usedTypes.insert(descriptorType);
			declarations << bindings[descriptorIdx].glslDeclarations(iteration, setNum, bindingNum, inputAttachmentIdx, arraySizeVal);
		}

		return declarations.str();
	}

	std::string glslCheckStatements (deUint32 iteration, deUint32 setNum, deUint32 bindingNum, deUint32 baseValue_, tcu::Maybe<deUint32> arrayIndex, bool usePushConstants) const override
	{
		DE_ASSERT(!arrayIndex);
		DE_UNREF(arrayIndex); // For release builds.

		std::ostringstream checks;
		const auto         numDescriptors = static_cast<deUint32>(bindings.size());

		for (deUint32 descriptorIdx  = 0u; descriptorIdx < numDescriptors; ++descriptorIdx)
		{
			const auto& binding = bindings[descriptorIdx];
			checks << binding.glslCheckStatements(iteration, setNum, bindingNum, baseValue_ + descriptorIdx, tcu::just(descriptorIdx), usePushConstants);
		}

		return checks.str();
	}
};

class DescriptorSet;

using DescriptorSetPtr = de::SharedPtr<DescriptorSet>;

class DescriptorSet
{
public:
	using BindingInterfacePtr   = de::MovePtr<BindingInterface>;
	using BindingPtrVector      = std::vector<BindingInterfacePtr>;

private:
	BindingPtrVector bindings;

public:
	explicit DescriptorSet (BindingPtrVector& bindings_)
		: bindings(std::move(bindings_))
	{
		DE_ASSERT(!bindings.empty());
	}

	size_t numBindings () const
	{
		return bindings.size();
	}

	const BindingInterface* getBinding (size_t bindingIdx) const
	{
		return bindings.at(bindingIdx).get();
	}

	// Maximum number of descriptor types used by any binding in the set.
	deUint32 maxTypes () const
	{
		std::vector<deUint32> maxSizes;
		maxSizes.reserve(bindings.size());

		std::transform(begin(bindings), end(bindings), std::back_inserter(maxSizes),
		               [] (const BindingInterfacePtr& b) { return b->maxTypes(); });

		const auto maxElement = std::max_element(begin(maxSizes), end(maxSizes));
		DE_ASSERT(maxElement != end(maxSizes));
		return *maxElement;
	}

	// Create another descriptor set that can be the source for copies when setting descriptor values.
	DescriptorSetPtr genSourceSet (SourceSetStrategy strategy, deUint32 iteration) const
	{
		BindingPtrVector newBindings;
		for (const auto& b : bindings)
		{
			if (strategy == SourceSetStrategy::MUTABLE)
				newBindings.push_back(b->toMutable(iteration));
			else
				newBindings.push_back(b->toNonMutable(iteration));
		}

		return DescriptorSetPtr(new DescriptorSet(newBindings));
	}

	// Makes a descriptor pool that can be used when allocating descriptors for this set.
	Move<VkDescriptorPool> makeDescriptorPool (const DeviceInterface& vkd, VkDevice device, PoolMutableStrategy strategy, VkDescriptorPoolCreateFlags flags) const
	{
		std::vector<VkDescriptorPoolSize>             poolSizes;
		std::vector<std::vector<VkDescriptorType>>    mutableTypesVec;
		std::vector<VkMutableDescriptorTypeListVALVE> mutableTypeLists;

		// Make vector element addresses stable.
		const auto bindingCount = numBindings();
		poolSizes.reserve(bindingCount);
		mutableTypesVec.reserve(bindingCount);
		mutableTypeLists.reserve(bindingCount);

		for (const auto& b : bindings)
		{
			const auto                 mainType = b->mainType();
			const VkDescriptorPoolSize poolSize = {
				mainType,
				static_cast<deUint32>(b->size()),
			};
			poolSizes.push_back(poolSize);

			if (strategy == PoolMutableStrategy::KEEP_TYPES || strategy == PoolMutableStrategy::EXPAND_TYPES)
			{
				if (mainType == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)
				{
					if (strategy == PoolMutableStrategy::KEEP_TYPES)
					{
						mutableTypesVec.emplace_back(b->mutableTypes());
					}
					else
					{
						// Expand the type list with the mandatory types.
						static const auto mandatoryTypesFlags = toDescriptorTypeFlags(getMandatoryMutableTypes());
						const auto        bindingTypes        = toDescriptorTypeVector(mandatoryTypesFlags | toDescriptorTypeFlags(b->mutableTypes()));

						mutableTypesVec.emplace_back(bindingTypes);
					}

					const auto& lastVec = mutableTypesVec.back();
					const VkMutableDescriptorTypeListVALVE typeList = { static_cast<deUint32>(lastVec.size()), de::dataOrNull(lastVec) };
					mutableTypeLists.push_back(typeList);
				}
				else
				{
					const VkMutableDescriptorTypeListVALVE typeList = { 0u, nullptr };
					mutableTypeLists.push_back(typeList);
				}
			}
			else if (strategy == PoolMutableStrategy::NO_TYPES)
				; // Do nothing, we will not use any type list.
			else
				DE_ASSERT(false);
		}

		VkDescriptorPoolCreateInfo poolCreateInfo = initVulkanStructure();

		poolCreateInfo.maxSets       = 1u;
		poolCreateInfo.flags         = flags;
		poolCreateInfo.poolSizeCount = static_cast<deUint32>(poolSizes.size());
		poolCreateInfo.pPoolSizes    = de::dataOrNull(poolSizes);

		VkMutableDescriptorTypeCreateInfoVALVE mutableInfo = initVulkanStructure();

		if (strategy == PoolMutableStrategy::KEEP_TYPES || strategy == PoolMutableStrategy::EXPAND_TYPES)
		{
			mutableInfo.mutableDescriptorTypeListCount = static_cast<deUint32>(mutableTypeLists.size());
			mutableInfo.pMutableDescriptorTypeLists    = de::dataOrNull(mutableTypeLists);
			poolCreateInfo.pNext                       = &mutableInfo;
		}

		return createDescriptorPool(vkd, device, &poolCreateInfo);
	}

private:
	// Building the descriptor set layout create info structure is cumbersome, so we'll reuse the same procedure to check support
	// and create the layout. This structure contains the result. "supported" is created as an enum to avoid the Move<> to bool
	// conversion cast in the contructors.
	struct DescriptorSetLayoutResult
	{
		enum class LayoutSupported { NO = 0, YES };

		LayoutSupported             supported;
		Move<VkDescriptorSetLayout> layout;

		explicit DescriptorSetLayoutResult (Move<VkDescriptorSetLayout>&& layout_)
			: supported (LayoutSupported::YES)
			, layout    (layout_)
		{}

		explicit DescriptorSetLayoutResult (LayoutSupported supported_)
			: supported (supported_)
			, layout    ()
		{}
	};

	DescriptorSetLayoutResult makeOrCheckDescriptorSetLayout (bool checkOnly, const DeviceInterface& vkd, VkDevice device, VkShaderStageFlags stageFlags, VkDescriptorSetLayoutCreateFlags createFlags) const
	{
		const auto                                    numIterations = maxTypes();
		std::vector<VkDescriptorSetLayoutBinding>     bindingsVec;
		std::vector<std::vector<VkDescriptorType>>    mutableTypesVec;
		std::vector<VkMutableDescriptorTypeListVALVE> mutableTypeLists;

		// Make vector element addresses stable.
		const auto bindingCount = numBindings();
		bindingsVec.reserve(bindingCount);
		mutableTypesVec.reserve(bindingCount);
		mutableTypeLists.reserve(bindingCount);

		for (size_t bindingIdx = 0u; bindingIdx < bindings.size(); ++bindingIdx)
		{
			const auto& binding = bindings[bindingIdx];
			const auto mainType = binding->mainType();

			const VkDescriptorSetLayoutBinding layoutBinding = {
				static_cast<deUint32>(bindingIdx),        //    deUint32			binding;
				mainType,                                 //    VkDescriptorType	descriptorType;
				static_cast<deUint32>(binding->size()),   //    deUint32			descriptorCount;
				stageFlags,                               //    VkShaderStageFlags	stageFlags;
				nullptr,                                  //    const VkSampler*	pImmutableSamplers;
			};
			bindingsVec.push_back(layoutBinding);

			// This list may be empty for non-mutable types, which is fine.
			mutableTypesVec.push_back(binding->mutableTypes());
			const auto& lastVec = mutableTypesVec.back();

			const VkMutableDescriptorTypeListVALVE typeList = {
				static_cast<deUint32>(lastVec.size()),  //  deUint32				descriptorTypeCount;
				de::dataOrNull(lastVec),                //  const VkDescriptorType*	pDescriptorTypes;
			};
			mutableTypeLists.push_back(typeList);
		}

		// Make sure to include the variable descriptor count and/or update after bind binding flags.
		const bool        updateAfterBind = ((createFlags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT) != 0u);
		bool              lastIsUnbounded = false;
		bool              aliasingNeded   = false;
		std::vector<bool> bindingNeedsAliasing(bindings.size(), false);

		for (size_t bindingIdx = 0; bindingIdx < bindings.size(); ++bindingIdx)
		{
			if (bindingIdx < bindings.size() - 1)
				DE_ASSERT(!bindings[bindingIdx]->isUnbounded());
			else
				lastIsUnbounded = bindings[bindingIdx]->isUnbounded();

			if (bindings[bindingIdx]->needsAliasingUpTo(numIterations))
			{
				bindingNeedsAliasing[bindingIdx] = true;
				aliasingNeded = true;
			}
		}

		using FlagsCreateInfoPtr = de::MovePtr<VkDescriptorSetLayoutBindingFlagsCreateInfo>;
		using BindingFlagsVecPtr = de::MovePtr<std::vector<VkDescriptorBindingFlags>>;

		FlagsCreateInfoPtr flagsCreateInfo;
		BindingFlagsVecPtr bindingFlagsVec;

		if (updateAfterBind || lastIsUnbounded || aliasingNeded)
		{
			flagsCreateInfo = FlagsCreateInfoPtr(new VkDescriptorSetLayoutBindingFlagsCreateInfo);
			*flagsCreateInfo = initVulkanStructure();

			bindingFlagsVec = BindingFlagsVecPtr(new std::vector<VkDescriptorBindingFlags>(bindingsVec.size(), (updateAfterBind ? VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT : 0)));
			if (lastIsUnbounded)
				bindingFlagsVec->back() |= VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT;

			for (size_t bindingIdx = 0; bindingIdx < bindings.size(); ++bindingIdx)
			{
				if (bindingNeedsAliasing[bindingIdx])
					bindingFlagsVec->at(bindingIdx) |= VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT;
			}

			flagsCreateInfo->bindingCount  = static_cast<deUint32>(bindingFlagsVec->size());
			flagsCreateInfo->pBindingFlags = de::dataOrNull(*bindingFlagsVec);
		}

		const VkMutableDescriptorTypeCreateInfoVALVE createInfoValve = {
			VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE,
			flagsCreateInfo.get(),
			static_cast<deUint32>(mutableTypeLists.size()),
			de::dataOrNull(mutableTypeLists),
		};

		const VkDescriptorSetLayoutCreateInfo layoutCreateInfo = {
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,    //  VkStructureType						sType;
			&createInfoValve,                                       //  const void*							pNext;
			createFlags,                                            //  VkDescriptorSetLayoutCreateFlags	flags;
			static_cast<deUint32>(bindingsVec.size()),              //  deUint32							bindingCount;
			de::dataOrNull(bindingsVec),                            //  const VkDescriptorSetLayoutBinding*	pBindings;
		};

		if (checkOnly)
		{
			VkDescriptorSetLayoutSupport support = initVulkanStructure();
			vkd.getDescriptorSetLayoutSupport(device, &layoutCreateInfo, &support);
			DescriptorSetLayoutResult result((support.supported == VK_TRUE) ? DescriptorSetLayoutResult::LayoutSupported::YES
			                                                                : DescriptorSetLayoutResult::LayoutSupported::NO);
			return result;
		}
		else
		{
			DescriptorSetLayoutResult result(createDescriptorSetLayout(vkd, device, &layoutCreateInfo));
			return result;
		}
	}

public:
	Move<VkDescriptorSetLayout> makeDescriptorSetLayout (const DeviceInterface& vkd, VkDevice device, VkShaderStageFlags stageFlags, VkDescriptorSetLayoutCreateFlags createFlags) const
	{
		return makeOrCheckDescriptorSetLayout(false /*checkOnly*/, vkd, device, stageFlags, createFlags).layout;
	}

	bool checkDescriptorSetLayout (const DeviceInterface& vkd, VkDevice device, VkShaderStageFlags stageFlags, VkDescriptorSetLayoutCreateFlags createFlags) const
	{
		return (makeOrCheckDescriptorSetLayout(true /*checkOnly*/, vkd, device, stageFlags, createFlags).supported == DescriptorSetLayoutResult::LayoutSupported::YES);
	}

	size_t numDescriptors () const
	{
		size_t total = 0;
		for (const auto& b : bindings)
			total += b->size();
		return total;
	}

	std::vector<Resource> createResources (const DeviceInterface& vkd, VkDevice device, Allocator& alloc, deUint32 qIndex, VkQueue queue, deUint32 iteration, bool useAABBs) const
	{
		// Create resources for each binding.
		std::vector<Resource> result;
		result.reserve(numDescriptors());

		const auto bindingsCount = static_cast<deUint32>(bindings.size());

		for (deUint32 bindingIdx = 0u; bindingIdx < bindingsCount; ++bindingIdx)
		{
			const auto& binding             = bindings[bindingIdx];
			auto        bindingResources    = binding->createResources(vkd, device, alloc, qIndex, queue, iteration, useAABBs, getDescriptorNumericValue(iteration, bindingIdx));

			for (auto& resource : bindingResources)
				result.emplace_back(std::move(resource));
		}

		return result;
	}

	// Updates a descriptor set with the given resources. Note: the set must have been created with a layout that's compatible with this object.
	void updateDescriptorSet (const DeviceInterface& vkd, VkDevice device, VkDescriptorSet set, deUint32 iteration, const std::vector<Resource>& resources) const
	{
		// Make sure the number of resources is correct.
		const auto numResources = resources.size();
		DE_ASSERT(numDescriptors() == numResources);

		std::vector<VkWriteDescriptorSet> descriptorWrites;
		descriptorWrites.reserve(numResources);

		std::vector<VkDescriptorImageInfo>                          imageInfoVec;
		std::vector<VkDescriptorBufferInfo>                         bufferInfoVec;
		std::vector<VkBufferView>                                   bufferViewVec;
		std::vector<VkWriteDescriptorSetAccelerationStructureKHR>   asWriteVec;
		size_t                                                      resourceIdx = 0;

		// We'll be storing pointers to elements of these vectors as we're appending elements, so we need their addresses to be stable.
		imageInfoVec.reserve(numResources);
		bufferInfoVec.reserve(numResources);
		bufferViewVec.reserve(numResources);
		asWriteVec.reserve(numResources);

		for (size_t bindingIdx = 0; bindingIdx < bindings.size(); ++bindingIdx)
		{
			const auto& binding         = bindings[bindingIdx];
			const auto  descriptorTypes = binding->typesAtIteration(iteration);

			for (size_t descriptorIdx = 0; descriptorIdx < binding->size(); ++descriptorIdx)
			{
				// Make sure the resource type matches the expected value.
				const auto& resource       = resources[resourceIdx];
				const auto& descriptorType = descriptorTypes[descriptorIdx];

				DE_ASSERT(resource.descriptorType == descriptorType);

				// Obtain the descriptor write info for the resource.
				const auto writeInfo = resource.makeWriteInfo();

				switch (writeInfo.writeType)
				{
				case WriteType::IMAGE_INFO:                  imageInfoVec.push_back(writeInfo.imageInfo);   break;
				case WriteType::BUFFER_INFO:                 bufferInfoVec.push_back(writeInfo.bufferInfo); break;
				case WriteType::BUFFER_VIEW:                 bufferViewVec.push_back(writeInfo.bufferView); break;
				case WriteType::ACCELERATION_STRUCTURE_INFO: asWriteVec.push_back(writeInfo.asInfo);        break;
				default: DE_ASSERT(false); break;
				}

				// Add a new VkWriteDescriptorSet struct or extend the last one with more info. This helps us exercise different implementation code paths.
				bool extended = false;

				if (!descriptorWrites.empty() && descriptorIdx > 0)
				{
					auto& last = descriptorWrites.back();
					if (last.dstSet == set /* this should always be true */ &&
					    last.dstBinding == bindingIdx && (last.dstArrayElement + last.descriptorCount) == descriptorIdx &&
					    last.descriptorType == descriptorType &&
					    writeInfo.writeType != WriteType::ACCELERATION_STRUCTURE_INFO)
					{
						// The new write should be in the same vector (imageInfoVec, bufferInfoVec or bufferViewVec) so increasing the count works.
						++last.descriptorCount;
						extended = true;
					}
				}

				if (!extended)
				{
					const VkWriteDescriptorSet write = {
						VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
						((writeInfo.writeType == WriteType::ACCELERATION_STRUCTURE_INFO) ? &asWriteVec.back() : nullptr),
						set,
						static_cast<deUint32>(bindingIdx),
						static_cast<deUint32>(descriptorIdx),
						1u,
						descriptorType,
						(writeInfo.writeType == WriteType::IMAGE_INFO  ? &imageInfoVec.back()  : nullptr),
						(writeInfo.writeType == WriteType::BUFFER_INFO ? &bufferInfoVec.back() : nullptr),
						(writeInfo.writeType == WriteType::BUFFER_VIEW ? &bufferViewVec.back() : nullptr),
					};
					descriptorWrites.push_back(write);
				}

				++resourceIdx;
			}
		}

		// Finally, update descriptor set with all the writes.
		vkd.updateDescriptorSets(device, static_cast<deUint32>(descriptorWrites.size()), de::dataOrNull(descriptorWrites), 0u, nullptr);
	}

	// Copies between descriptor sets. They must be compatible and related to this set.
	void copyDescriptorSet (const DeviceInterface& vkd, VkDevice device, VkDescriptorSet srcSet, VkDescriptorSet dstSet) const
	{
		std::vector<VkCopyDescriptorSet> copies;

		for (size_t bindingIdx = 0; bindingIdx < numBindings(); ++bindingIdx)
		{
			const auto& binding         = getBinding(bindingIdx);
			const auto  bindingNumber   = static_cast<deUint32>(bindingIdx);
			const auto  descriptorCount = static_cast<deUint32>(binding->size());

			const VkCopyDescriptorSet copy =
			{
				VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET,
				nullptr,
				// set, binding, array element.
				srcSet, bindingNumber, 0u,
				dstSet, bindingNumber, 0u,
				descriptorCount,
			};

			copies.push_back(copy);
		}

		vkd.updateDescriptorSets(device, 0u, nullptr, static_cast<deUint32>(copies.size()), de::dataOrNull(copies));
	}

	// Does any binding in the set need aliasing in a given iteration?
	bool needsAliasing (deUint32 iteration) const
	{
		std::vector<bool> aliasingNeededFlags;
		aliasingNeededFlags.reserve(bindings.size());

		std::transform(begin(bindings), end(bindings), std::back_inserter(aliasingNeededFlags),
		               [iteration] (const BindingInterfacePtr& b) { return b->needsAliasing(iteration); });
		return std::any_of(begin(aliasingNeededFlags), end(aliasingNeededFlags), [] (bool f) { return f; });
	}

	// Does any binding in the set need aliasing in any iteration?
	bool needsAnyAliasing () const
	{
		const auto        numIterations       = maxTypes();
		std::vector<bool> aliasingNeededFlags (numIterations, false);

		for (deUint32 iteration = 0; iteration < numIterations; ++iteration)
		    aliasingNeededFlags[iteration] = needsAliasing(iteration);

		return std::any_of(begin(aliasingNeededFlags), end(aliasingNeededFlags), [] (bool f) { return f; });
	}

	// Is the last binding an unbounded array?
	bool lastBindingIsUnbounded () const
	{
		if (bindings.empty())
			return false;
		return bindings.back()->isUnbounded();
	}

	// Get the variable descriptor count for the last binding if any.
	tcu::Maybe<deUint32> getVariableDescriptorCount () const
	{
		if (lastBindingIsUnbounded())
			return tcu::just(static_cast<deUint32>(bindings.back()->size()));
		return tcu::Nothing;
	}

	// Check if the set contains a descriptor type of the given type at the given iteration.
	bool containsTypeAtIteration (VkDescriptorType descriptorType, deUint32 iteration) const
	{
		return std::any_of(begin(bindings), end(bindings),
		                   [descriptorType, iteration] (const BindingInterfacePtr& b) {
			                   const auto types = b->typesAtIteration(iteration);
			                   return de::contains(begin(types), end(types), descriptorType);
		                   });
	}

	// Is any binding an array?
	bool hasArrays () const
	{
		return std::any_of(begin(bindings), end(bindings), [] (const BindingInterfacePtr& b) { return b->isArray(); });
	}
};

enum class UpdateType
{
	WRITE = 0,
	COPY,
};

enum class SourceSetType
{
	NORMAL = 0,
	HOST_ONLY,
	NO_SOURCE,
};

enum class UpdateMoment
{
	NORMAL = 0,
	UPDATE_AFTER_BIND,
};

enum class TestingStage
{
	COMPUTE = 0,
	VERTEX,
	TESS_EVAL,
	TESS_CONTROL,
	GEOMETRY,
	FRAGMENT,
	RAY_GEN,
	INTERSECTION,
	ANY_HIT,
	CLOSEST_HIT,
	MISS,
	CALLABLE,
};

enum class ArrayAccessType
{
	CONSTANT = 0,
	PUSH_CONSTANT,
	NO_ARRAY,
};

// Are we testing a ray tracing pipeline stage?
bool isRayTracingStage (TestingStage stage)
{
	switch (stage)
	{
	case TestingStage::RAY_GEN:
	case TestingStage::INTERSECTION:
	case TestingStage::ANY_HIT:
	case TestingStage::CLOSEST_HIT:
	case TestingStage::MISS:
	case TestingStage::CALLABLE:
		return true;
	default:
		break;
	}

	return false;
}

struct TestParams
{
	DescriptorSetPtr    descriptorSet;
	UpdateType          updateType;
	SourceSetStrategy   sourceSetStrategy;
	SourceSetType       sourceSetType;
	PoolMutableStrategy poolMutableStrategy;
	UpdateMoment        updateMoment;
	ArrayAccessType     arrayAccessType;
	TestingStage        testingStage;

	VkShaderStageFlags getStageFlags () const
	{
		VkShaderStageFlags flags = 0u;

		switch (testingStage)
		{
		case TestingStage::COMPUTE:			flags |= VK_SHADER_STAGE_COMPUTE_BIT;					break;
		case TestingStage::VERTEX:			flags |= VK_SHADER_STAGE_VERTEX_BIT;					break;
		case TestingStage::TESS_EVAL:		flags |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;	break;
		case TestingStage::TESS_CONTROL:	flags |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;		break;
		case TestingStage::GEOMETRY:		flags |= VK_SHADER_STAGE_GEOMETRY_BIT;					break;
		case TestingStage::FRAGMENT:		flags |= VK_SHADER_STAGE_FRAGMENT_BIT;					break;
		case TestingStage::RAY_GEN:			flags |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;				break;
		case TestingStage::INTERSECTION:	flags |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;			break;
		case TestingStage::ANY_HIT:			flags |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;				break;
		case TestingStage::CLOSEST_HIT:		flags |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;			break;
		case TestingStage::MISS:			flags |= VK_SHADER_STAGE_MISS_BIT_KHR;					break;
		case TestingStage::CALLABLE:		flags |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;				break;
		default:
			DE_ASSERT(false);
			break;
		}

		return flags;
	}

	VkPipelineStageFlags getPipelineWriteStage () const
	{
		VkPipelineStageFlags flags = 0u;

		switch (testingStage)
		{
		case TestingStage::COMPUTE:			flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;					break;
		case TestingStage::VERTEX:			flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;					break;
		case TestingStage::TESS_EVAL:		flags |= VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;	break;
		case TestingStage::TESS_CONTROL:	flags |= VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT;		break;
		case TestingStage::GEOMETRY:		flags |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;					break;
		case TestingStage::FRAGMENT:		flags |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;					break;
		case TestingStage::RAY_GEN:			// fallthrough
		case TestingStage::INTERSECTION:	// fallthrough
		case TestingStage::ANY_HIT:			// fallthrough
		case TestingStage::CLOSEST_HIT:		// fallthrough
		case TestingStage::MISS:			// fallthrough
		case TestingStage::CALLABLE:		flags |= VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR;			break;
		default:
			DE_ASSERT(false);
			break;
		}

		return flags;
	}

private:
	VkDescriptorSetLayoutCreateFlags getLayoutCreateFlags (bool isSourceSet) const
	{
		// UPDATE_AFTER_BIND cannot be used with HOST_ONLY sets.
		//DE_ASSERT(!(updateMoment == UpdateMoment::UPDATE_AFTER_BIND && sourceSetType == SourceSetType::HOST_ONLY));

		VkDescriptorSetLayoutCreateFlags createFlags = 0u;

		if ((!isSourceSet || sourceSetType != SourceSetType::HOST_ONLY) && updateMoment == UpdateMoment::UPDATE_AFTER_BIND)
			createFlags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;

		if (isSourceSet && sourceSetType == SourceSetType::HOST_ONLY)
			createFlags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE;

		return createFlags;
	}

public:
	VkDescriptorSetLayoutCreateFlags getSrcLayoutCreateFlags () const
	{
		return getLayoutCreateFlags(true);
	}

	VkDescriptorSetLayoutCreateFlags getDstLayoutCreateFlags () const
	{
		return getLayoutCreateFlags(false);
	}

private:
	VkDescriptorPoolCreateFlags getPoolCreateFlags (bool isSourceSet) const
	{
		// UPDATE_AFTER_BIND cannot be used with HOST_ONLY sets.
		//DE_ASSERT(!(updateMoment == UpdateMoment::UPDATE_AFTER_BIND && sourceSetType == SourceSetType::HOST_ONLY));

		VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;

		if ((!isSourceSet || sourceSetType != SourceSetType::HOST_ONLY) && updateMoment == UpdateMoment::UPDATE_AFTER_BIND)
			poolCreateFlags |= VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT;

		if (isSourceSet && sourceSetType == SourceSetType::HOST_ONLY)
			poolCreateFlags |= VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE;

		return poolCreateFlags;
	}

public:
	VkDescriptorPoolCreateFlags getSrcPoolCreateFlags () const
	{
		return getPoolCreateFlags(true);
	}

	VkDescriptorPoolCreateFlags getDstPoolCreateFlags () const
	{
		return getPoolCreateFlags(false);
	}

	VkPipelineBindPoint getBindPoint () const
	{
		if (testingStage == TestingStage::COMPUTE)
			return VK_PIPELINE_BIND_POINT_COMPUTE;
		if (isRayTracingStage(testingStage))
			return VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR;
		return VK_PIPELINE_BIND_POINT_GRAPHICS;
	}
};

class MutableTypesTest : public TestCase
{
public:
	MutableTypesTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
		: TestCase(testCtx, name, description)
		, m_params(params)
	{}

	~MutableTypesTest () override = default;

	void            initPrograms        (vk::SourceCollections& programCollection) const override;
	TestInstance*   createInstance      (Context& context) const override;
	void            checkSupport        (Context& context) const override;

private:
	TestParams      m_params;
};

class MutableTypesInstance : public TestInstance
{
public:
	MutableTypesInstance (Context& context, const TestParams& params)
		: TestInstance  (context)
		, m_params      (params)
	{}

	~MutableTypesInstance () override = default;

	tcu::TestStatus iterate () override;

private:
	TestParams      m_params;
};

// Check if a descriptor set contains a given descriptor type in any iteration up to maxTypes().
bool containsAnyDescriptorType (const DescriptorSet& descriptorSet, VkDescriptorType descriptorType)
{
	const auto numIterations = descriptorSet.maxTypes();

	for (deUint32 iter = 0u; iter < numIterations; ++iter)
	{
		if (descriptorSet.containsTypeAtIteration(descriptorType, iter))
			return true;
	}

	return false;
}

// Check if testing this descriptor set needs an external image (for sampler descriptors).
bool needsExternalImage (const DescriptorSet& descriptorSet)
{
	return containsAnyDescriptorType(descriptorSet, VK_DESCRIPTOR_TYPE_SAMPLER);
}

// Check if testing this descriptor set needs an external sampler (for sampled images).
bool needsExternalSampler (const DescriptorSet& descriptorSet)
{
	return containsAnyDescriptorType(descriptorSet, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
}

// Check if this descriptor set contains a input attachments.
bool usesInputAttachments (const DescriptorSet& descriptorSet)
{
	return containsAnyDescriptorType(descriptorSet, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
}

// Check if this descriptor set contains acceleration structures.
bool usesAccelerationStructures (const DescriptorSet& descriptorSet)
{
	return containsAnyDescriptorType(descriptorSet, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR);
}

std::string shaderName (deUint32 iteration)
{
	return ("iteration-" + de::toString(iteration));
}

void MutableTypesTest::initPrograms (vk::SourceCollections& programCollection) const
{
	const bool						usePushConstants      = (m_params.arrayAccessType == ArrayAccessType::PUSH_CONSTANT);
	const bool						useExternalImage      = needsExternalImage(*m_params.descriptorSet);
	const bool						useExternalSampler    = needsExternalSampler(*m_params.descriptorSet);
	const bool						rayQueries            = usesAccelerationStructures(*m_params.descriptorSet);
	const bool						rayTracing            = isRayTracingStage(m_params.testingStage);
	const auto						numIterations         = m_params.descriptorSet->maxTypes();
	const auto						numBindings           = m_params.descriptorSet->numBindings();
	const vk::ShaderBuildOptions	rtBuildOptions        (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);

	// Extra set and bindings for external resources.
	std::ostringstream extraSet;
	deUint32           extraBindings = 0u;

	extraSet << "layout (set=1, binding=" << extraBindings++ << ") buffer OutputBufferBlock { uint value[" << numIterations << "]; } outputBuffer;\n";
	if (useExternalImage)
		extraSet << "layout (set=1, binding=" << extraBindings++ << ") uniform utexture2D externalSampledImage;\n";
	if (useExternalSampler)
		extraSet << "layout (set=1, binding=" << extraBindings++ << ") uniform sampler externalSampler;\n";
	// The extra binding below will be declared in the "passthrough" ray generation shader.
#if 0
	if (rayTracing)
		extraSet << "layout (set=1, binding=" << extraBindings++ << ") uniform accelerationStructureEXT externalAS;\n";
#endif

	// Common vertex preamble.
	std::ostringstream vertexPreamble;
	vertexPreamble
			<< "vec2 vertexPositions[3] = vec2[](\n"
			<< "  vec2(0.0, -0.5),\n"
			<< "  vec2(0.5, 0.5),\n"
			<< "  vec2(-0.5, 0.5)\n"
			<< ");\n"
			;

	// Vertex shader body common statements.
	std::ostringstream vertexBodyCommon;
	vertexBodyCommon << "  gl_Position = vec4(vertexPositions[gl_VertexIndex], 0.0, 1.0);\n";

	// Common tessellation control preamble.
	std::ostringstream tescPreamble;
	tescPreamble
		<< "layout (vertices=3) out;\n"
		<< "in gl_PerVertex\n"
		<< "{\n"
		<< "  vec4 gl_Position;\n"
		<< "} gl_in[gl_MaxPatchVertices];\n"
		<< "out gl_PerVertex\n"
		<< "{\n"
		<< "  vec4 gl_Position;\n"
		<< "} gl_out[];\n"
		;

	// Common tessellation control body.
	std::ostringstream tescBodyCommon;
	tescBodyCommon
		<< "  gl_TessLevelInner[0] = 1.0;\n"
		<< "  gl_TessLevelInner[1] = 1.0;\n"
		<< "  gl_TessLevelOuter[0] = 1.0;\n"
		<< "  gl_TessLevelOuter[1] = 1.0;\n"
		<< "  gl_TessLevelOuter[2] = 1.0;\n"
		<< "  gl_TessLevelOuter[3] = 1.0;\n"
		<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
		;

	// Common tessellation evaluation preamble.
	std::ostringstream tesePreamble;
	tesePreamble
		<< "layout (triangles, fractional_odd_spacing, cw) in;\n"
		<< "in gl_PerVertex\n"
		<< "{\n"
		<< "  vec4 gl_Position;\n"
		<< "} gl_in[gl_MaxPatchVertices];\n"
		<< "out gl_PerVertex\n"
		<< "{\n"
		<< "  vec4 gl_Position;\n"
		<< "};\n"
		;

	// Common tessellation evaluation body.
	std::ostringstream teseBodyCommon;
	teseBodyCommon
		<< "  gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) +\n"
		<< "                (gl_TessCoord.y * gl_in[1].gl_Position) +\n"
		<< "                (gl_TessCoord.z * gl_in[2].gl_Position);\n"
		;

	// Shader preamble.
	std::ostringstream preamble;

	preamble
		<< "#version 460\n"
		<< "#extension GL_EXT_nonuniform_qualifier : enable\n"
		<< "#extension GL_EXT_debug_printf : enable\n"
		<< (rayTracing ? "#extension GL_EXT_ray_tracing : enable\n" : "")
		<< (rayQueries ? "#extension GL_EXT_ray_query : enable\n" : "")
		<< "\n"
		;

	if (m_params.testingStage == TestingStage::VERTEX)
	{
		preamble << vertexPreamble.str();
	}
	else if (m_params.testingStage == TestingStage::COMPUTE)
	{
		preamble
			<< "layout (local_size_x=1, local_size_y=1, local_size_z=1) in;\n"
			<< "\n"
			;
	}
	else if (m_params.testingStage == TestingStage::GEOMETRY)
	{
		preamble
			<< "layout (triangles) in;\n"
			<< "layout (triangle_strip, max_vertices=3) out;\n"
			<< "in gl_PerVertex\n"
			<< "{\n"
			<< "  vec4 gl_Position;\n"
			<< "} gl_in[3];\n"
			<< "out gl_PerVertex\n"
			<< "{\n"
			<< "  vec4 gl_Position;\n"
			<< "};\n"
			;
	}
	else if (m_params.testingStage == TestingStage::TESS_CONTROL)
	{
		preamble << tescPreamble.str();
	}
	else if (m_params.testingStage == TestingStage::TESS_EVAL)
	{
		preamble << tesePreamble.str();
	}
	else if (m_params.testingStage == TestingStage::CALLABLE)
	{
		preamble << "layout (location=0) callableDataInEXT float unusedCallableData;\n";
	}
	else if (m_params.testingStage == TestingStage::CLOSEST_HIT ||
			 m_params.testingStage == TestingStage::ANY_HIT ||
			 m_params.testingStage == TestingStage::MISS)
	{
		preamble << "layout (location=0) rayPayloadInEXT float unusedRayPayload;\n";
	}
	else if (m_params.testingStage == TestingStage::INTERSECTION)
	{
		preamble << "hitAttributeEXT vec3 hitAttribute;\n";
	}

	preamble << extraSet.str();
	if (usePushConstants)
		preamble << "layout (push_constant, std430) uniform PushConstantBlock { uint zero; } pc;\n";
	preamble << "\n";

	// We need to create a shader per iteration.
	for (deUint32 iter = 0u; iter < numIterations; ++iter)
	{
		// Shader preamble.
		std::ostringstream shader;
		shader << preamble.str();

		deUint32 inputAttachmentCount = 0u;

		// Descriptor declarations for this iteration.
		for (size_t bindingIdx = 0; bindingIdx < numBindings; ++bindingIdx)
		{
			DE_ASSERT(bindingIdx <= std::numeric_limits<deUint32>::max());

			const auto binding            = m_params.descriptorSet->getBinding(bindingIdx);
			const auto bindingTypes       = binding->typesAtIteration(iter);
			const auto hasInputAttachment = de::contains(begin(bindingTypes), end(bindingTypes), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
			const auto isArray            = binding->isArray();
			const auto isUnbounded        = binding->isUnbounded();
			const auto bindingSize        = binding->size();

			// If the binding is an input attachment, make sure it's not an array.
			DE_ASSERT(!hasInputAttachment || !isArray);

			// Make sure the descriptor count fits a deInt32 if needed.
			DE_ASSERT(!isArray || isUnbounded || bindingSize <= static_cast<size_t>(std::numeric_limits<deInt32>::max()));

			const auto arraySize = (isArray ? (isUnbounded ? tcu::just(deInt32{-1}) : tcu::just(static_cast<deInt32>(bindingSize)))
			                                : tcu::Nothing);

			shader << binding->glslDeclarations(iter, 0u, static_cast<deUint32>(bindingIdx), inputAttachmentCount, arraySize);

			if (hasInputAttachment)
				++inputAttachmentCount;
		}

		// Main body.
		shader
			<< "\n"
			<< "void main() {\n"
			// This checks if we are the first invocation to arrive here, so the checks are executed only once.
			<< "  const uint flag = atomicCompSwap(outputBuffer.value[" << iter << "], 0u, 1u);\n"
			<< "  if (flag == 0u) {\n"
			<< "    uint anyError = 0u;\n"
			;

		for (size_t bindingIdx = 0; bindingIdx < numBindings; ++bindingIdx)
		{
			const auto binding = m_params.descriptorSet->getBinding(bindingIdx);
			const auto idx32 = static_cast<deUint32>(bindingIdx);
			shader << binding->glslCheckStatements(iter, 0u, idx32, getDescriptorNumericValue(iter, idx32), tcu::Nothing, usePushConstants);
		}

		shader
			<< "    if (anyError == 0u) {\n"
			<< "      atomicAdd(outputBuffer.value[" << iter << "], 1u);\n"
			<< "    }\n"
			<< "  }\n" // Closes if (flag == 0u).
			;

		if (m_params.testingStage == TestingStage::VERTEX)
		{
			shader << vertexBodyCommon.str();
		}
		else if (m_params.testingStage == TestingStage::GEOMETRY)
		{
			shader
				<< "  gl_Position = gl_in[0].gl_Position; EmitVertex();\n"
				<< "  gl_Position = gl_in[1].gl_Position; EmitVertex();\n"
				<< "  gl_Position = gl_in[2].gl_Position; EmitVertex();\n"
				;
		}
		else if (m_params.testingStage == TestingStage::TESS_CONTROL)
		{
			shader << tescBodyCommon.str();
		}
		else if (m_params.testingStage == TestingStage::TESS_EVAL)
		{
			shader << teseBodyCommon.str();
		}

		shader
			<< "}\n" // End of main().
			;

		{
			const auto	shaderNameStr	= shaderName(iter);
			const auto	shaderStr		= shader.str();
			auto&		glslSource		= programCollection.glslSources.add(shaderNameStr);

			if (m_params.testingStage == TestingStage::COMPUTE)
				glslSource << glu::ComputeSource(shaderStr);
			else if (m_params.testingStage == TestingStage::VERTEX)
				glslSource << glu::VertexSource(shaderStr);
			else if (m_params.testingStage == TestingStage::FRAGMENT)
				glslSource << glu::FragmentSource(shaderStr);
			else if (m_params.testingStage == TestingStage::GEOMETRY)
				glslSource << glu::GeometrySource(shaderStr);
			else if (m_params.testingStage == TestingStage::TESS_CONTROL)
				glslSource << glu::TessellationControlSource(shaderStr);
			else if (m_params.testingStage == TestingStage::TESS_EVAL)
				glslSource << glu::TessellationEvaluationSource(shaderStr);
			else if (m_params.testingStage == TestingStage::RAY_GEN)
				glslSource << glu::RaygenSource(updateRayTracingGLSL(shaderStr));
			else if (m_params.testingStage == TestingStage::INTERSECTION)
				glslSource << glu::IntersectionSource(updateRayTracingGLSL(shaderStr));
			else if (m_params.testingStage == TestingStage::ANY_HIT)
				glslSource << glu::AnyHitSource(updateRayTracingGLSL(shaderStr));
			else if (m_params.testingStage == TestingStage::CLOSEST_HIT)
				glslSource << glu::ClosestHitSource(updateRayTracingGLSL(shaderStr));
			else if (m_params.testingStage == TestingStage::MISS)
				glslSource << glu::MissSource(updateRayTracingGLSL(shaderStr));
			else if (m_params.testingStage == TestingStage::CALLABLE)
				glslSource << glu::CallableSource(updateRayTracingGLSL(shaderStr));
			else
				DE_ASSERT(false);

			if (rayTracing || rayQueries)
				glslSource << rtBuildOptions;
		}
	}

	if (m_params.testingStage == TestingStage::FRAGMENT
		|| m_params.testingStage == TestingStage::GEOMETRY
		|| m_params.testingStage == TestingStage::TESS_CONTROL
		|| m_params.testingStage == TestingStage::TESS_EVAL)
	{
		// Add passthrough vertex shader that works for points.
		std::ostringstream vertPassthrough;
		vertPassthrough
			<< "#version 460\n"
			<< "out gl_PerVertex\n"
			<< "{\n"
			<< "  vec4 gl_Position;\n"
			<< "};\n"
			<< vertexPreamble.str()
			<< "void main() {\n"
			<< vertexBodyCommon.str()
			<< "}\n"
			;
		programCollection.glslSources.add("vert") << glu::VertexSource(vertPassthrough.str());
	}

	if (m_params.testingStage == TestingStage::TESS_CONTROL)
	{
		// Add passthrough tessellation evaluation shader.
		std::ostringstream tesePassthrough;
		tesePassthrough
			<< "#version 460\n"
			<< tesePreamble.str()
			<< "void main (void)\n"
			<< "{\n"
			<< teseBodyCommon.str()
			<< "}\n"
			;

		programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tesePassthrough.str());
	}

	if (m_params.testingStage == TestingStage::TESS_EVAL)
	{
		// Add passthrough tessellation control shader.
		std::ostringstream tescPassthrough;
		tescPassthrough
			<< "#version 460\n"
			<< tescPreamble.str()
			<< "void main (void)\n"
			<< "{\n"
			<< tescBodyCommon.str()
			<< "}\n"
			;

		programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tescPassthrough.str());
	}

	if (rayTracing && m_params.testingStage != TestingStage::RAY_GEN)
	{
		// Add a "passthrough" ray generation shader.
		std::ostringstream rgen;
		rgen
			<< "#version 460 core\n"
			<< "#extension GL_EXT_ray_tracing : require\n"
			<< "layout (set=1, binding=" << extraBindings << ") uniform accelerationStructureEXT externalAS;\n"
			<< ((m_params.testingStage == TestingStage::CALLABLE)
				? "layout (location=0) callableDataEXT float unusedCallableData;\n"
				: "layout (location=0) rayPayloadEXT float unusedRayPayload;\n")
			<< "\n"
			<< "void main()\n"
			<< "{\n"
			;

		if (m_params.testingStage == TestingStage::INTERSECTION
			|| m_params.testingStage == TestingStage::ANY_HIT
			|| m_params.testingStage == TestingStage::CLOSEST_HIT
			|| m_params.testingStage == TestingStage::MISS)
		{
			// We need to trace rays in this case to get hits or misses.
			const auto zDir = ((m_params.testingStage == TestingStage::MISS) ? "-1.0" : "1.0");

			rgen
				<< "  const uint cullMask = 0xFF;\n"
				<< "  const float tMin = 1.0;\n"
				<< "  const float tMax = 10.0;\n"
				<< "  const vec3 origin = vec3(0.0, 0.0, 0.0);\n"
				<< "  const vec3 direction = vec3(0.0, 0.0, " << zDir << ");\n"
				<< "  traceRayEXT(externalAS, gl_RayFlagsNoneEXT, cullMask, 0, 0, 0, origin, tMin, direction, tMax, 0);\n"
				;

		}
		else if (m_params.testingStage == TestingStage::CALLABLE)
		{
			rgen << "  executeCallableEXT(0, 0);\n";
		}

		// End of main().
		rgen << "}\n";

		programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << rtBuildOptions;

		// Intersection shaders will ignore the intersection, so we need a passthrough miss shader.
		if (m_params.testingStage == TestingStage::INTERSECTION)
		{
			std::ostringstream miss;
			miss
				<< "#version 460 core\n"
				<< "#extension GL_EXT_ray_tracing : require\n"
				<< "layout (location=0) rayPayloadEXT float unusedRayPayload;\n"
				<< "\n"
				<< "void main()\n"
				<< "{\n"
				<< "}\n"
				;

			programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(miss.str())) << rtBuildOptions;
		}
	}
}

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

void requirePartiallyBound (Context& context)
{
	context.requireDeviceFunctionality("VK_EXT_descriptor_indexing");
	const auto& indexingFeatures = context.getDescriptorIndexingFeatures();
	if (!indexingFeatures.descriptorBindingPartiallyBound)
		TCU_THROW(NotSupportedError, "Partially bound bindings not supported");
}

void requireVariableDescriptorCount (Context& context)
{
	context.requireDeviceFunctionality("VK_EXT_descriptor_indexing");
	const auto& indexingFeatures = context.getDescriptorIndexingFeatures();
	if (!indexingFeatures.descriptorBindingVariableDescriptorCount)
		TCU_THROW(NotSupportedError, "Variable descriptor count not supported");
}

// Calculates the set of used descriptor types for a given set and iteration count, for bindings matching a predicate.
std::set<VkDescriptorType> getUsedDescriptorTypes (const DescriptorSet& descriptorSet, deUint32 numIterations, bool (*predicate)(const BindingInterface* binding))
{
	std::set<VkDescriptorType> usedDescriptorTypes;

	for (size_t bindingIdx = 0; bindingIdx < descriptorSet.numBindings(); ++bindingIdx)
	{
		const auto bindingPtr = descriptorSet.getBinding(bindingIdx);
		if (predicate(bindingPtr))
		{
			for (deUint32 iter = 0u; iter < numIterations; ++iter)
			{
				const auto descTypes = bindingPtr->typesAtIteration(iter);
				usedDescriptorTypes.insert(begin(descTypes), end(descTypes));
			}
		}
	}

	return usedDescriptorTypes;
}

std::set<VkDescriptorType> getAllUsedDescriptorTypes (const DescriptorSet& descriptorSet, deUint32 numIterations)
{
	return getUsedDescriptorTypes(descriptorSet, numIterations, [] (const BindingInterface*) { return true; });
}

std::set<VkDescriptorType> getUsedArrayDescriptorTypes (const DescriptorSet& descriptorSet, deUint32 numIterations)
{
	return getUsedDescriptorTypes(descriptorSet, numIterations, [] (const BindingInterface* b) { return b->isArray(); });
}

// Are we testing a vertex pipeline stage?
bool isVertexStage (TestingStage stage)
{
	switch (stage)
	{
	case TestingStage::VERTEX:
	case TestingStage::TESS_CONTROL:
	case TestingStage::TESS_EVAL:
	case TestingStage::GEOMETRY:
		return true;
	default:
		break;
	}

	return false;
}

void MutableTypesTest::checkSupport (Context& context) const
{
	context.requireDeviceFunctionality("VK_VALVE_mutable_descriptor_type");

	// Check ray tracing if needed.
	const bool rayTracing = isRayTracingStage(m_params.testingStage);

	if (rayTracing)
	{
		context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
		context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
	}

	// Check if ray queries are needed. Ray queries are used to verify acceleration structure descriptors.
	const bool rayQueriesNeeded = usesAccelerationStructures(*m_params.descriptorSet);
	if (rayQueriesNeeded)
	{
		context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
		context.requireDeviceFunctionality("VK_KHR_ray_query");
	}

	// We'll use iterations to check each mutable type, as needed.
	const auto numIterations = m_params.descriptorSet->maxTypes();

	if (m_params.descriptorSet->lastBindingIsUnbounded())
		requireVariableDescriptorCount(context);

	for (deUint32 iter = 0u; iter < numIterations; ++iter)
	{
		if (m_params.descriptorSet->needsAliasing(iter))
		{
			requirePartiallyBound(context);
			break;
		}
	}

	if (m_params.updateMoment == UpdateMoment::UPDATE_AFTER_BIND)
	{
		// Check update after bind for each used descriptor type.
		const auto& usedDescriptorTypes = getAllUsedDescriptorTypes(*m_params.descriptorSet, numIterations);
		const auto& indexingFeatures    = context.getDescriptorIndexingFeatures();

		for (const auto& descType : usedDescriptorTypes)
		{
			switch (descType)
			{
			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
				if (!indexingFeatures.descriptorBindingUniformBufferUpdateAfterBind)
					TCU_THROW(NotSupportedError, "Update-after-bind not supported for uniform buffers");
				break;

			case VK_DESCRIPTOR_TYPE_SAMPLER:
			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
			case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
				if (!indexingFeatures.descriptorBindingSampledImageUpdateAfterBind)
					TCU_THROW(NotSupportedError, "Update-after-bind not supported for samplers and sampled images");
				break;

			case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
				if (!indexingFeatures.descriptorBindingStorageImageUpdateAfterBind)
					TCU_THROW(NotSupportedError, "Update-after-bind not supported for storage images");
				break;

			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
				if (!indexingFeatures.descriptorBindingStorageBufferUpdateAfterBind)
					TCU_THROW(NotSupportedError, "Update-after-bind not supported for storage buffers");
				break;

			case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
				if (!indexingFeatures.descriptorBindingUniformTexelBufferUpdateAfterBind)
					TCU_THROW(NotSupportedError, "Update-after-bind not supported for uniform texel buffers");
				break;

			case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
				if (!indexingFeatures.descriptorBindingStorageTexelBufferUpdateAfterBind)
					TCU_THROW(NotSupportedError, "Update-after-bind not supported for storage texel buffers");
				break;

			case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
				TCU_THROW(InternalError, "Tests do not support update-after-bind with input attachments");

			case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
				{
					// Just in case we ever mix some of these in.
					context.requireDeviceFunctionality("VK_EXT_inline_uniform_block");
					const auto& iubFeatures = context.getInlineUniformBlockFeatures();
					if (!iubFeatures.descriptorBindingInlineUniformBlockUpdateAfterBind)
						TCU_THROW(NotSupportedError, "Update-after-bind not supported for inline uniform blocks");
				}
				break;

			case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
				{
					// Just in case we ever mix some of these in.
					context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
					const auto& asFeatures = context.getAccelerationStructureFeatures();
					if (!asFeatures.descriptorBindingAccelerationStructureUpdateAfterBind)
						TCU_THROW(NotSupportedError, "Update-after-bind not supported for acceleration structures");
				}
				break;

			case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE:
				TCU_THROW(InternalError, "Found VK_DESCRIPTOR_TYPE_MUTABLE_VALVE in list of used descriptor types");

			default:
				TCU_THROW(InternalError, "Unexpected descriptor type found in list of used descriptor types: " + de::toString(descType));
			}
		}
	}

	if (m_params.arrayAccessType == ArrayAccessType::PUSH_CONSTANT)
	{
		// These require dynamically uniform indices.
		const auto& usedDescriptorTypes         = getUsedArrayDescriptorTypes(*m_params.descriptorSet, numIterations);
		const auto& features                    = context.getDeviceFeatures();
		const auto descriptorIndexingSupported  = context.isDeviceFunctionalitySupported("VK_EXT_descriptor_indexing");
		const auto& indexingFeatures            = context.getDescriptorIndexingFeatures();

		for (const auto& descType : usedDescriptorTypes)
		{
			switch (descType)
			{
			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
				if (!features.shaderUniformBufferArrayDynamicIndexing)
					TCU_THROW(NotSupportedError, "Dynamic indexing not supported for uniform buffers");
				break;

			case VK_DESCRIPTOR_TYPE_SAMPLER:
			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
			case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
				if (!features.shaderSampledImageArrayDynamicIndexing)
					TCU_THROW(NotSupportedError, "Dynamic indexing not supported for samplers and sampled images");
				break;

			case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
				if (!features.shaderStorageImageArrayDynamicIndexing)
					TCU_THROW(NotSupportedError, "Dynamic indexing not supported for storage images");
				break;

			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
				if (!features.shaderStorageBufferArrayDynamicIndexing)
					TCU_THROW(NotSupportedError, "Dynamic indexing not supported for storage buffers");
				break;

			case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
				if (!descriptorIndexingSupported || !indexingFeatures.shaderUniformTexelBufferArrayDynamicIndexing)
					TCU_THROW(NotSupportedError, "Dynamic indexing not supported for uniform texel buffers");
				break;

			case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
				if (!descriptorIndexingSupported || !indexingFeatures.shaderStorageTexelBufferArrayDynamicIndexing)
					TCU_THROW(NotSupportedError, "Dynamic indexing not supported for storage texel buffers");
				break;

			case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
				if (!descriptorIndexingSupported || !indexingFeatures.shaderInputAttachmentArrayDynamicIndexing)
					TCU_THROW(NotSupportedError, "Dynamic indexing not supported for input attachments");
				break;

			case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
				context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
				break;

			case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE:
				TCU_THROW(InternalError, "Found VK_DESCRIPTOR_TYPE_MUTABLE_VALVE in list of used array descriptor types");

			default:
				TCU_THROW(InternalError, "Unexpected descriptor type found in list of used descriptor types: " + de::toString(descType));
			}
		}
	}

	// Check layout support.
	{
		const auto& vkd               = context.getDeviceInterface();
		const auto  device            = context.getDevice();
		const auto  stageFlags        = m_params.getStageFlags();

		{
			const auto  layoutCreateFlags = m_params.getDstLayoutCreateFlags();
			const auto  supported         = m_params.descriptorSet->checkDescriptorSetLayout(vkd, device, stageFlags, layoutCreateFlags);

			if (!supported)
				TCU_THROW(NotSupportedError, "Required descriptor set layout not supported");
		}

		if (m_params.updateType == UpdateType::COPY)
		{
			const auto  layoutCreateFlags = m_params.getSrcLayoutCreateFlags();
			const auto  supported         = m_params.descriptorSet->checkDescriptorSetLayout(vkd, device, stageFlags, layoutCreateFlags);

			if (!supported)
				TCU_THROW(NotSupportedError, "Required descriptor set layout for source set not supported");

			// Check specific layouts for the different source sets are supported.
			for (deUint32 iter = 0u; iter < numIterations; ++iter)
			{
				const auto srcSet             = m_params.descriptorSet->genSourceSet(m_params.sourceSetStrategy, iter);
				const auto srcLayoutSupported = srcSet->checkDescriptorSetLayout(vkd, device, stageFlags, layoutCreateFlags);

				if (!srcLayoutSupported)
					TCU_THROW(NotSupportedError, "Descriptor set layout for source set at iteration " + de::toString(iter) + " not supported");
			}
		}
	}

	// Check supported stores and stages.
	const bool vertexStage   = isVertexStage(m_params.testingStage);
	const bool fragmentStage = (m_params.testingStage == TestingStage::FRAGMENT);
	const bool geometryStage = (m_params.testingStage == TestingStage::GEOMETRY);
	const bool tessellation  = (m_params.testingStage == TestingStage::TESS_CONTROL || m_params.testingStage == TestingStage::TESS_EVAL);

	const auto& features = context.getDeviceFeatures();

	if (vertexStage && !features.vertexPipelineStoresAndAtomics)
		TCU_THROW(NotSupportedError, "Vertex pipeline stores and atomics not supported");

	if (fragmentStage && !features.fragmentStoresAndAtomics)
		TCU_THROW(NotSupportedError, "Fragment shader stores and atomics not supported");

	if (geometryStage && !features.geometryShader)
		TCU_THROW(NotSupportedError, "Geometry shader not supported");

	if (tessellation && !features.tessellationShader)
		TCU_THROW(NotSupportedError, "Tessellation shaders not supported");
}

// What to do at each iteration step. Used to apply UPDATE_AFTER_BIND or not.
enum class Step
{
	UPDATE = 0,
	BIND,
};

// Create render pass.
Move<VkRenderPass> buildRenderPass (const DeviceInterface& vkd, VkDevice device, const std::vector<Resource>& resources)
{
	const auto imageFormat = getDescriptorImageFormat();

	std::vector<VkAttachmentDescription>    attachmentDescriptions;
	std::vector<VkAttachmentReference>      attachmentReferences;
	std::vector<deUint32>                   attachmentIndices;

	for (const auto& resource : resources)
	{
		if (resource.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
		{
			const auto nextIndex = static_cast<deUint32>(attachmentDescriptions.size());

			const VkAttachmentDescription description = {
				0u,                                 //  VkAttachmentDescriptionFlags	flags;
				imageFormat,                        //  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_GENERAL,            //  VkImageLayout					initialLayout;
				VK_IMAGE_LAYOUT_GENERAL,            //  VkImageLayout					finalLayout;
			};

			const VkAttachmentReference reference = { nextIndex, VK_IMAGE_LAYOUT_GENERAL };

			attachmentIndices.push_back(nextIndex);
			attachmentDescriptions.push_back(description);
			attachmentReferences.push_back(reference);
		}
	}

	const auto attachmentCount = static_cast<deUint32>(attachmentDescriptions.size());
	DE_ASSERT(attachmentCount == static_cast<deUint32>(attachmentIndices.size()));
	DE_ASSERT(attachmentCount == static_cast<deUint32>(attachmentReferences.size()));

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

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

	return createRenderPass(vkd, device, &renderPassCreateInfo);
}

// Create a graphics pipeline.
Move<VkPipeline> buildGraphicsPipeline (const DeviceInterface& vkd, VkDevice device, VkPipelineLayout pipelineLayout,
										VkShaderModule vertModule,
										VkShaderModule tescModule,
										VkShaderModule teseModule,
										VkShaderModule geomModule,
										VkShaderModule fragModule,
										VkRenderPass renderPass)
{
	const auto                    extent    = getDefaultExtent();
	const std::vector<VkViewport> viewports (1u, makeViewport(extent));
	const std::vector<VkRect2D>   scissors  (1u, makeRect2D(extent));
	const auto                    hasTess   = (tescModule != DE_NULL || teseModule != DE_NULL);
	const auto                    topology  = (hasTess ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);


	const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = initVulkanStructure();

	const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = {
		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    //  VkStructureType							sType;
		nullptr,                                                        //  const void*								pNext;
		0u,                                                             //  VkPipelineInputAssemblyStateCreateFlags	flags;
		topology,                                                       //  VkPrimitiveTopology						topology;
		VK_FALSE,                                                       //  VkBool32								primitiveRestartEnable;
	};

	const VkPipelineTessellationStateCreateInfo tessellationStateCreateInfo = {
		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,  //	VkStructureType							sType;
		nullptr,                                                    //	const void*								pNext;
		0u,                                                         //	VkPipelineTessellationStateCreateFlags	flags;
		(hasTess ? 3u : 0u),                                        //	deUint32								patchControlPoints;
	};

	const VkPipelineViewportStateCreateInfo viewportStateCreateInfo = {
		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  //  VkStructureType						sType;
		nullptr,                                                //  const void*							pNext;
		0u,                                                     //  VkPipelineViewportStateCreateFlags	flags;
		static_cast<deUint32>(viewports.size()),                //  deUint32							viewportCount;
		de::dataOrNull(viewports),                              //  const VkViewport*					pViewports;
		static_cast<deUint32>(scissors.size()),                 //  deUint32							scissorCount;
		de::dataOrNull(scissors),                               //  const VkRect2D*						pScissors;
	};

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

	const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo = {
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,   //  VkStructureType							sType;
		nullptr,                                                    //  const void*								pNext;
		0u,                                                         //  VkPipelineMultisampleStateCreateFlags	flags;
		VK_SAMPLE_COUNT_1_BIT,                                      //  VkSampleCountFlagBits					rasterizationSamples;
		VK_FALSE,                                                   //  VkBool32								sampleShadingEnable;
		1.0f,                                                       //  float									minSampleShading;
		nullptr,                                                    //  const VkSampleMask*						pSampleMask;
		VK_FALSE,                                                   //  VkBool32								alphaToCoverageEnable;
		VK_FALSE,                                                   //  VkBool32								alphaToOneEnable;
	};

	const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo = initVulkanStructure();

	const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = initVulkanStructure();

	return makeGraphicsPipeline(vkd, device, pipelineLayout,
	                            vertModule, tescModule, teseModule, geomModule, fragModule,
	                            renderPass, 0u, &vertexInputStateCreateInfo, &inputAssemblyStateCreateInfo,
	                            (hasTess ? &tessellationStateCreateInfo : nullptr), &viewportStateCreateInfo,
								&rasterizationStateCreateInfo, &multisampleStateCreateInfo,
	                            &depthStencilStateCreateInfo, &colorBlendStateCreateInfo, nullptr);
}

Move<VkFramebuffer> buildFramebuffer (const DeviceInterface& vkd, VkDevice device, VkRenderPass renderPass, const std::vector<Resource>& resources)
{
	const auto extent = getDefaultExtent();

	std::vector<VkImageView> inputAttachments;
	for (const auto& resource : resources)
	{
		if (resource.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
			inputAttachments.push_back(resource.imageView.get());
	}

	const VkFramebufferCreateInfo framebufferCreateInfo =
	{
		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		//	VkStructureType				sType;
		nullptr,										//	const void*					pNext;
		0u,												//	VkFramebufferCreateFlags	flags;
		renderPass,										//	VkRenderPass				renderPass;
		static_cast<deUint32>(inputAttachments.size()),	//	deUint32					attachmentCount;
		de:: dataOrNull(inputAttachments),				//	const VkImageView*			pAttachments;
		extent.width,									//	deUint32					width;
		extent.height,									//	deUint32					height;
		extent.depth,									//	deUint32					layers;
	};

	return createFramebuffer(vkd, device, &framebufferCreateInfo);
}

tcu::TestStatus MutableTypesInstance::iterate ()
{
	const auto device  = m_context.getDevice();
	const auto physDev = m_context.getPhysicalDevice();
	const auto qIndex  = m_context.getUniversalQueueFamilyIndex();
	const auto queue   = m_context.getUniversalQueue();

	const auto& vki      = m_context.getInstanceInterface();
	const auto& vkd      = m_context.getDeviceInterface();
	auto      & alloc    = m_context.getDefaultAllocator();
	const auto& paramSet = m_params.descriptorSet;

	const auto numIterations      = paramSet->maxTypes();
	const bool useExternalImage   = needsExternalImage(*m_params.descriptorSet);
	const bool useExternalSampler = needsExternalSampler(*m_params.descriptorSet);
	const auto stageFlags         = m_params.getStageFlags();
	const bool srcSetNeeded       = (m_params.updateType == UpdateType::COPY);
	const bool updateAfterBind    = (m_params.updateMoment == UpdateMoment::UPDATE_AFTER_BIND);
	const auto bindPoint          = m_params.getBindPoint();
	const bool rayTracing         = isRayTracingStage(m_params.testingStage);
	const bool useAABBs           = (m_params.testingStage == TestingStage::INTERSECTION);

	// Resources for each iteration.
	std::vector<std::vector<Resource>> allResources;
	allResources.reserve(numIterations);

	// Command pool.
	const auto cmdPool = makeCommandPool(vkd, device, qIndex);

	// Descriptor pool and set for the active (dst) descriptor set.
	const auto dstPoolFlags   = m_params.getDstPoolCreateFlags();
	const auto dstLayoutFlags = m_params.getDstLayoutCreateFlags();

	const auto dstPool   = paramSet->makeDescriptorPool(vkd, device, m_params.poolMutableStrategy, dstPoolFlags);
	const auto dstLayout = paramSet->makeDescriptorSetLayout(vkd, device, stageFlags, dstLayoutFlags);
	const auto varCount  = paramSet->getVariableDescriptorCount();

	using VariableCountInfoPtr = de::MovePtr<VkDescriptorSetVariableDescriptorCountAllocateInfo>;

	VariableCountInfoPtr dstVariableCountInfo;
	if (varCount)
	{
		dstVariableCountInfo = VariableCountInfoPtr(new VkDescriptorSetVariableDescriptorCountAllocateInfo);
		*dstVariableCountInfo = initVulkanStructure();

		dstVariableCountInfo->descriptorSetCount = 1u;
		dstVariableCountInfo->pDescriptorCounts  = &(varCount.get());
	}
	const auto dstSet = makeDescriptorSet(vkd, device, dstPool.get(), dstLayout.get(), dstVariableCountInfo.get());

	// Source pool and set (optional).
	const auto                  srcPoolFlags   = m_params.getSrcPoolCreateFlags();
	const auto                  srcLayoutFlags = m_params.getSrcLayoutCreateFlags();
	DescriptorSetPtr            iterationSrcSet;
	Move<VkDescriptorPool>      srcPool;
	Move<VkDescriptorSetLayout> srcLayout;
	Move<VkDescriptorSet>       srcSet;

	// Extra set for external resources and output buffer.
	std::vector<Resource> extraResources;
	extraResources.emplace_back(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vkd, device, alloc, qIndex, queue, useAABBs, 0u, numIterations);
	if (useExternalImage)
		extraResources.emplace_back(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vkd, device, alloc, qIndex, queue, useAABBs, getExternalSampledImageValue());
	if (useExternalSampler)
		extraResources.emplace_back(VK_DESCRIPTOR_TYPE_SAMPLER, vkd, device, alloc, qIndex, queue, useAABBs, 0u);
	if (rayTracing)
		extraResources.emplace_back(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, vkd, device, alloc, qIndex, queue, useAABBs, 0u);

	Move<VkDescriptorPool> extraPool;
	{
		DescriptorPoolBuilder poolBuilder;
		poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
		if (useExternalImage)
			poolBuilder.addType(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
		if (useExternalSampler)
			poolBuilder.addType(VK_DESCRIPTOR_TYPE_SAMPLER);
		if (rayTracing)
			poolBuilder.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR);
		extraPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
	}

	Move<VkDescriptorSetLayout> extraLayout;
	{
		DescriptorSetLayoutBuilder layoutBuilder;
		layoutBuilder.addBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, stageFlags, nullptr);
		if (useExternalImage)
			layoutBuilder.addBinding(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1u, stageFlags, nullptr);
		if (useExternalSampler)
			layoutBuilder.addBinding(VK_DESCRIPTOR_TYPE_SAMPLER, 1u, stageFlags, nullptr);
		if (rayTracing)
		{
			// The extra acceleration structure is used from the ray generation shader only.
			layoutBuilder.addBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1u, VK_SHADER_STAGE_RAYGEN_BIT_KHR, nullptr);
		}
		extraLayout = layoutBuilder.build(vkd, device);
	}

	const auto extraSet = makeDescriptorSet(vkd, device, extraPool.get(), extraLayout.get());

	// Update extra set.
	using DescriptorBufferInfoPtr = de::MovePtr<VkDescriptorBufferInfo>;
	using DescriptorImageInfoPtr  = de::MovePtr<VkDescriptorImageInfo>;
	using DescriptorASInfoPtr     = de::MovePtr<VkWriteDescriptorSetAccelerationStructureKHR>;

	deUint32                bindingCount = 0u;
	DescriptorBufferInfoPtr bufferInfoPtr;
	DescriptorImageInfoPtr  imageInfoPtr;
	DescriptorImageInfoPtr  samplerInfoPtr;
	DescriptorASInfoPtr     asWriteInfoPtr;

    const auto outputBufferSize = static_cast<VkDeviceSize>(sizeof(deUint32) * static_cast<size_t>(numIterations));
	bufferInfoPtr = DescriptorBufferInfoPtr(new VkDescriptorBufferInfo(makeDescriptorBufferInfo(extraResources[bindingCount++].bufferWithMemory->get(), 0ull, outputBufferSize)));
	if (useExternalImage)
		imageInfoPtr = DescriptorImageInfoPtr(new VkDescriptorImageInfo(makeDescriptorImageInfo(DE_NULL, extraResources[bindingCount++].imageView.get(), VK_IMAGE_LAYOUT_GENERAL)));
	if (useExternalSampler)
		samplerInfoPtr = DescriptorImageInfoPtr(new VkDescriptorImageInfo(makeDescriptorImageInfo(extraResources[bindingCount++].sampler.get(), DE_NULL, VK_IMAGE_LAYOUT_GENERAL)));
	if (rayTracing)
	{
		asWriteInfoPtr = DescriptorASInfoPtr(new VkWriteDescriptorSetAccelerationStructureKHR);
		*asWriteInfoPtr = initVulkanStructure();
		asWriteInfoPtr->accelerationStructureCount  = 1u;
		asWriteInfoPtr->pAccelerationStructures     = extraResources[bindingCount++].asData.tlas.get()->getPtr();
	}

	{
		bindingCount = 0u;
		DescriptorSetUpdateBuilder updateBuilder;
		updateBuilder.writeSingle(extraSet.get(), DescriptorSetUpdateBuilder::Location::binding(bindingCount++), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, bufferInfoPtr.get());
		if (useExternalImage)
			updateBuilder.writeSingle(extraSet.get(), DescriptorSetUpdateBuilder::Location::binding(bindingCount++), VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, imageInfoPtr.get());
		if (useExternalSampler)
			updateBuilder.writeSingle(extraSet.get(), DescriptorSetUpdateBuilder::Location::binding(bindingCount++), VK_DESCRIPTOR_TYPE_SAMPLER, samplerInfoPtr.get());
		if (rayTracing)
			updateBuilder.writeSingle(extraSet.get(), DescriptorSetUpdateBuilder::Location::binding(bindingCount++), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, asWriteInfoPtr.get());
		updateBuilder.update(vkd, device);
	}

	// Push constants.
	const deUint32            zero    = 0u;
	const VkPushConstantRange pcRange = {stageFlags, 0u /*offset*/, static_cast<deUint32>(sizeof(zero)) /*size*/ };

	// Needed for some test variants.
	Move<VkShaderModule> vertPassthrough;
	Move<VkShaderModule> tesePassthrough;
	Move<VkShaderModule> tescPassthrough;
	Move<VkShaderModule> rgenPassthrough;
	Move<VkShaderModule> missPassthrough;

	if (m_params.testingStage == TestingStage::FRAGMENT
		|| m_params.testingStage == TestingStage::GEOMETRY
		|| m_params.testingStage == TestingStage::TESS_CONTROL
		|| m_params.testingStage == TestingStage::TESS_EVAL)
	{
		vertPassthrough = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
	}

	if (m_params.testingStage == TestingStage::TESS_CONTROL)
	{
		tesePassthrough = createShaderModule(vkd, device, m_context.getBinaryCollection().get("tese"), 0u);
	}

	if (m_params.testingStage == TestingStage::TESS_EVAL)
	{
		tescPassthrough = createShaderModule(vkd, device, m_context.getBinaryCollection().get("tesc"), 0u);
	}

	if (m_params.testingStage == TestingStage::CLOSEST_HIT
		|| m_params.testingStage == TestingStage::ANY_HIT
		|| m_params.testingStage == TestingStage::INTERSECTION
		|| m_params.testingStage == TestingStage::MISS
		|| m_params.testingStage == TestingStage::CALLABLE)
	{
		rgenPassthrough = createShaderModule(vkd, device, m_context.getBinaryCollection().get("rgen"), 0u);
	}

	if (m_params.testingStage == TestingStage::INTERSECTION)
	{
		missPassthrough = createShaderModule(vkd, device, m_context.getBinaryCollection().get("miss"), 0u);
	}

	for (deUint32 iteration = 0u; iteration < numIterations; ++iteration)
	{
		// Generate source set for the current iteration.
		if (srcSetNeeded)
		{
			// Free previous descriptor set before rebuilding the pool.
			srcSet          = Move<VkDescriptorSet>();
			iterationSrcSet = paramSet->genSourceSet(m_params.sourceSetStrategy, iteration);
			srcPool         = iterationSrcSet->makeDescriptorPool(vkd, device, m_params.poolMutableStrategy, srcPoolFlags);
			srcLayout       = iterationSrcSet->makeDescriptorSetLayout(vkd, device, stageFlags, srcLayoutFlags);

			const auto srcVarCount = iterationSrcSet->getVariableDescriptorCount();
			VariableCountInfoPtr srcVariableCountInfo;

			if (srcVarCount)
			{
				srcVariableCountInfo = VariableCountInfoPtr(new VkDescriptorSetVariableDescriptorCountAllocateInfo);
				*srcVariableCountInfo = initVulkanStructure();

				srcVariableCountInfo->descriptorSetCount = 1u;
				srcVariableCountInfo->pDescriptorCounts = &(srcVarCount.get());
			}

			srcSet = makeDescriptorSet(vkd, device, srcPool.get(), srcLayout.get(), srcVariableCountInfo.get());
		}

		// Set layouts and sets used in the pipeline.
		const std::vector<VkDescriptorSetLayout> setLayouts = {dstLayout.get(), extraLayout.get()};
		const std::vector<VkDescriptorSet>       usedSets   = {dstSet.get(), extraSet.get()};

		// Create resources.
		allResources.emplace_back(paramSet->createResources(vkd, device, alloc, qIndex, queue, iteration, useAABBs));
		const auto& resources = allResources.back();

		// Make pipeline for the current iteration.
		const auto pipelineLayout = makePipelineLayout(vkd, device, static_cast<deUint32>(setLayouts.size()), de::dataOrNull(setLayouts), 1u, &pcRange);
		const auto moduleName     = shaderName(iteration);
		const auto shaderModule   = createShaderModule(vkd, device, m_context.getBinaryCollection().get(moduleName), 0u);

		Move<VkPipeline>     pipeline;
		Move<VkRenderPass>   renderPass;
		Move<VkFramebuffer>  framebuffer;

		deUint32 shaderGroupHandleSize		= 0u;
		deUint32 shaderGroupBaseAlignment	= 1u;

		de::MovePtr<BufferWithMemory>	raygenSBT;
		de::MovePtr<BufferWithMemory>	missSBT;
		de::MovePtr<BufferWithMemory>	hitSBT;
		de::MovePtr<BufferWithMemory>	callableSBT;

		VkStridedDeviceAddressRegionKHR	raygenSBTRegion		= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
		VkStridedDeviceAddressRegionKHR	missSBTRegion		= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
		VkStridedDeviceAddressRegionKHR	hitSBTRegion		= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
		VkStridedDeviceAddressRegionKHR	callableSBTRegion	= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);

		if (bindPoint == VK_PIPELINE_BIND_POINT_COMPUTE)
			pipeline = makeComputePipeline(vkd, device, pipelineLayout.get(), 0u, shaderModule.get(), 0u, nullptr);
		else if (bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS)
		{
			VkShaderModule vertModule = DE_NULL;
			VkShaderModule teseModule = DE_NULL;
			VkShaderModule tescModule = DE_NULL;
			VkShaderModule geomModule = DE_NULL;
			VkShaderModule fragModule = DE_NULL;

			if (m_params.testingStage == TestingStage::VERTEX)
				vertModule = shaderModule.get();
			else if (m_params.testingStage == TestingStage::FRAGMENT)
			{
				vertModule = vertPassthrough.get();
				fragModule = shaderModule.get();
			}
			else if (m_params.testingStage == TestingStage::GEOMETRY)
			{
				vertModule = vertPassthrough.get();
				geomModule = shaderModule.get();
			}
			else if (m_params.testingStage == TestingStage::TESS_CONTROL)
			{
				vertModule = vertPassthrough.get();
				teseModule = tesePassthrough.get();
				tescModule = shaderModule.get();
			}
			else if (m_params.testingStage == TestingStage::TESS_EVAL)
			{
				vertModule = vertPassthrough.get();
				tescModule = tescPassthrough.get();
				teseModule = shaderModule.get();
			}
			else
				DE_ASSERT(false);

			renderPass  = buildRenderPass(vkd, device, resources);
			pipeline    = buildGraphicsPipeline(vkd, device, pipelineLayout.get(), vertModule, tescModule, teseModule, geomModule, fragModule, renderPass.get());
			framebuffer = buildFramebuffer(vkd, device, renderPass.get(), resources);
		}
		else if (bindPoint == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR)
		{
			const auto rayTracingPipeline       = de::newMovePtr<RayTracingPipeline>();
			const auto rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physDev);
			shaderGroupHandleSize				= rayTracingPropertiesKHR->getShaderGroupHandleSize();
			shaderGroupBaseAlignment			= rayTracingPropertiesKHR->getShaderGroupBaseAlignment();

			VkShaderModule rgenModule = DE_NULL;
			VkShaderModule isecModule = DE_NULL;
			VkShaderModule ahitModule = DE_NULL;
			VkShaderModule chitModule = DE_NULL;
			VkShaderModule missModule = DE_NULL;
			VkShaderModule callModule = DE_NULL;

			const deUint32  rgenGroup   = 0u;
			deUint32        hitGroup    = 0u;
			deUint32        missGroup   = 0u;
			deUint32        callGroup   = 0u;

			if (m_params.testingStage == TestingStage::RAY_GEN)
			{
				rgenModule = shaderModule.get();
				rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, rgenModule, rgenGroup);
			}
			else if (m_params.testingStage == TestingStage::INTERSECTION)
			{
				hitGroup   = 1u;
				missGroup  = 2u;
				rgenModule = rgenPassthrough.get();
				missModule = missPassthrough.get();
				isecModule = shaderModule.get();
				rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, rgenModule, rgenGroup);
				rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR, isecModule, hitGroup);
				rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, missModule, missGroup);
			}
			else if (m_params.testingStage == TestingStage::ANY_HIT)
			{
				hitGroup   = 1u;
				rgenModule = rgenPassthrough.get();
				ahitModule = shaderModule.get();
				rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, rgenModule, rgenGroup);
				rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR, ahitModule, hitGroup);
			}
			else if (m_params.testingStage == TestingStage::CLOSEST_HIT)
			{
				hitGroup   = 1u;
				rgenModule = rgenPassthrough.get();
				chitModule = shaderModule.get();
				rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, rgenModule, rgenGroup);
				rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, chitModule, hitGroup);
			}
			else if (m_params.testingStage == TestingStage::MISS)
			{
				missGroup  = 1u;
				rgenModule = rgenPassthrough.get();
				missModule = shaderModule.get();
				rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, rgenModule, rgenGroup);
				rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, missModule, missGroup);
			}
			else if (m_params.testingStage == TestingStage::CALLABLE)
			{
				callGroup  = 1u;
				rgenModule = rgenPassthrough.get();
				callModule = shaderModule.get();
				rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, rgenModule, rgenGroup);
				rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, callModule, callGroup);
			}
			else
				DE_ASSERT(false);

			pipeline = rayTracingPipeline->createPipeline(vkd, device, pipelineLayout.get());

			raygenSBT = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, rgenGroup, 1u);
			raygenSBTRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenSBT->get(), 0ull), shaderGroupHandleSize, shaderGroupHandleSize);

			if (missGroup > 0u)
			{
				missSBT = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, missGroup, 1u);
				missSBTRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missSBT->get(), 0ull), shaderGroupHandleSize, shaderGroupHandleSize);
			}

			if (hitGroup > 0u)
			{
				hitSBT = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, hitGroup, 1u);
				hitSBTRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitSBT->get(), 0ull), shaderGroupHandleSize, shaderGroupHandleSize);
			}

			if (callGroup > 0u)
			{
				callableSBT = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, callGroup, 1u);
				callableSBTRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableSBT->get(), 0ull), shaderGroupHandleSize, shaderGroupHandleSize);
			}
		}
		else
			DE_ASSERT(false);

		// Command buffer for the current iteration.
		const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
		const auto cmdBuffer    = cmdBufferPtr.get();

		beginCommandBuffer(vkd, cmdBuffer);

		const Step steps[] = {
			(updateAfterBind ? Step::BIND : Step::UPDATE),
			(updateAfterBind ? Step::UPDATE : Step::BIND)
		};

		for (const auto& step : steps)
		{
			if (step == Step::BIND)
			{
				vkd.cmdBindPipeline(cmdBuffer, bindPoint, pipeline.get());
				vkd.cmdBindDescriptorSets(cmdBuffer, bindPoint, pipelineLayout.get(), 0u, static_cast<deUint32>(usedSets.size()), de::dataOrNull(usedSets), 0u, nullptr);
			}
			else // Step::UPDATE
			{
				if (srcSetNeeded)
				{
					// Note: these operations need to be called on paramSet and not iterationSrcSet. The latter is a compatible set
					// that's correct and contains compatible bindings but, when a binding has been changed from non-mutable to
					// mutable or to an extended mutable type, the list of descriptor types for the mutable bindings in
					// iterationSrcSet are not in iteration order like they are in the original set and must not be taken into
					// account to update or copy sets.
					paramSet->updateDescriptorSet(vkd, device, srcSet.get(), iteration, resources);
					paramSet->copyDescriptorSet(vkd, device, srcSet.get(), dstSet.get());
				}
				else
				{
					paramSet->updateDescriptorSet(vkd, device, dstSet.get(), iteration, resources);
				}
			}
		}

		// Run shader.
		vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), stageFlags, 0u, static_cast<deUint32>(sizeof(zero)), &zero);

		if (bindPoint == VK_PIPELINE_BIND_POINT_COMPUTE)
			vkd.cmdDispatch(cmdBuffer, 1u, 1u, 1u);
		else if (bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS)
		{
			const auto extent     = getDefaultExtent();
			const auto renderArea = makeRect2D(extent);

			beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), renderArea);
			vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
			endRenderPass(vkd, cmdBuffer);
		}
		else if (bindPoint == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR)
		{
			vkd.cmdTraceRaysKHR(cmdBuffer, &raygenSBTRegion, &missSBTRegion, &hitSBTRegion, &callableSBTRegion, 1u, 1u, 1u);
		}
		else
			DE_ASSERT(false);

		endCommandBuffer(vkd, cmdBuffer);
		submitCommandsAndWait(vkd, device, queue, cmdBuffer);

		// Verify output buffer.
		{
			const auto outputBufferVal = extraResources[0].getStoredValue(vkd, device, alloc, qIndex, queue, iteration);
			DE_ASSERT(static_cast<bool>(outputBufferVal));

			const auto expectedValue = getExpectedOutputBufferValue();
			if (outputBufferVal.get() != expectedValue)
			{
				std::ostringstream msg;
				msg << "Iteration " << iteration << ": unexpected value found in output buffer (expected " << expectedValue << " and found " << outputBufferVal.get() << ")";
				TCU_FAIL(msg.str());
			}
		}

		// Verify descriptor writes.
		{
			size_t     resourcesOffset = 0;
			const auto writeMask       = getStoredValueMask();
			const auto numBindings     = paramSet->numBindings();

			for (deUint32 bindingIdx = 0u; bindingIdx < numBindings; ++bindingIdx)
			{
				const auto binding = paramSet->getBinding(bindingIdx);
				const auto bindingTypes = binding->typesAtIteration(iteration);

				for (size_t descriptorIdx = 0; descriptorIdx < bindingTypes.size(); ++descriptorIdx)
				{
					const auto& descriptorType = bindingTypes[descriptorIdx];
					if (!isShaderWritable(descriptorType))
						continue;

					const auto& resource        = resources[resourcesOffset + descriptorIdx];
					const auto  initialValue    = resource.initialValue;
					const auto  storedValuePtr  = resource.getStoredValue(vkd, device, alloc, qIndex, queue);

					DE_ASSERT(static_cast<bool>(storedValuePtr));
					const auto storedValue   = storedValuePtr.get();
					const auto expectedValue = (initialValue | writeMask);
					if (expectedValue != storedValue)
					{
						std::ostringstream msg;
						msg << "Iteration " << iteration << ": descriptor at binding " << bindingIdx << " index " << descriptorIdx
						    << " with type " << de::toString(descriptorType) << " contains unexpected value " << std::hex
							<< storedValue << " (expected " << expectedValue << ")";
						TCU_FAIL(msg.str());
					}
				}

				resourcesOffset += bindingTypes.size();
			}
		}
	}

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

using GroupPtr = de::MovePtr<tcu::TestCaseGroup>;

void createMutableTestVariants (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGroup, const DescriptorSetPtr& descriptorSet, const std::vector<TestingStage>& stagesToTest)
{
	const struct
	{
		UpdateType  updateType;
		const char* name;
	} updateTypes[] = {
		{UpdateType::WRITE, "update_write"},
		{UpdateType::COPY,  "update_copy"},
	};

	const struct
	{
		SourceSetStrategy   sourceSetStrategy;
		const char*         name;
	} sourceStrategies[] = {
		{SourceSetStrategy::MUTABLE,    "mutable_source"},
		{SourceSetStrategy::NONMUTABLE, "nonmutable_source"},
		{SourceSetStrategy::NO_SOURCE,  "no_source"},
	};

	const struct
	{
		SourceSetType   sourceSetType;
		const char*     name;
	} sourceTypes[] = {
		{SourceSetType::NORMAL,    "normal_source"},
		{SourceSetType::HOST_ONLY, "host_only_source"},
		{SourceSetType::NO_SOURCE, "no_source"},
	};

	const struct
	{
		PoolMutableStrategy poolMutableStrategy;
		const char*         name;
	} poolStrategies[] = {
		{PoolMutableStrategy::KEEP_TYPES,   "pool_same_types"},
		{PoolMutableStrategy::NO_TYPES,     "pool_no_types"},
		{PoolMutableStrategy::EXPAND_TYPES, "pool_expand_types"},
	};

	const struct
	{
		UpdateMoment    updateMoment;
		const char*     name;
	} updateMoments[] = {
		{UpdateMoment::NORMAL,            "pre_update"},
		{UpdateMoment::UPDATE_AFTER_BIND, "update_after_bind"},
	};

	const struct
	{
		ArrayAccessType arrayAccessType;
		const char*     name;
	} arrayAccessTypes[] = {
		{ArrayAccessType::CONSTANT,      "index_constant"},
		{ArrayAccessType::PUSH_CONSTANT, "index_push_constant"},
		{ArrayAccessType::NO_ARRAY,      "no_array"},
	};

	const struct StageAndName
	{
		TestingStage    testingStage;
		const char*     name;
	} testStageList[] = {
		{TestingStage::COMPUTE,      "comp"},
		{TestingStage::VERTEX,       "vert"},
		{TestingStage::TESS_CONTROL, "tesc"},
		{TestingStage::TESS_EVAL,    "tese"},
		{TestingStage::GEOMETRY,     "geom"},
		{TestingStage::FRAGMENT,     "frag"},
		{TestingStage::RAY_GEN,      "rgen"},
		{TestingStage::INTERSECTION, "isec"},
		{TestingStage::ANY_HIT,      "ahit"},
		{TestingStage::CLOSEST_HIT,  "chit"},
		{TestingStage::MISS,         "miss"},
		{TestingStage::CALLABLE,     "call"},
	};

	const bool hasArrays           = descriptorSet->hasArrays();
	const bool hasInputAttachments = usesInputAttachments(*descriptorSet);

	for (const auto& ut : updateTypes)
	{
		GroupPtr updateGroup(new tcu::TestCaseGroup(testCtx, ut.name, ""));

		for (const auto& srcStrategy : sourceStrategies)
		{
			// Skip combinations that make no sense.
			if (ut.updateType == UpdateType::WRITE && srcStrategy.sourceSetStrategy != SourceSetStrategy::NO_SOURCE)
				continue;

			if (ut.updateType == UpdateType::COPY && srcStrategy.sourceSetStrategy == SourceSetStrategy::NO_SOURCE)
				continue;

			if (srcStrategy.sourceSetStrategy == SourceSetStrategy::NONMUTABLE && descriptorSet->needsAnyAliasing())
				continue;

			GroupPtr srcStrategyGroup(new tcu::TestCaseGroup(testCtx, srcStrategy.name, ""));

			for (const auto& srcType : sourceTypes)
			{
				// Skip combinations that make no sense.
				if (ut.updateType == UpdateType::WRITE && srcType.sourceSetType != SourceSetType::NO_SOURCE)
					continue;

				if (ut.updateType == UpdateType::COPY && srcType.sourceSetType == SourceSetType::NO_SOURCE)
					continue;

				GroupPtr srcTypeGroup(new tcu::TestCaseGroup(testCtx, srcType.name, ""));

				for (const auto& poolStrategy: poolStrategies)
				{
					GroupPtr poolStrategyGroup(new tcu::TestCaseGroup(testCtx, poolStrategy.name, ""));

					for (const auto& moment : updateMoments)
					{
						//if (moment.updateMoment == UpdateMoment::UPDATE_AFTER_BIND && srcType.sourceSetType == SourceSetType::HOST_ONLY)
						//	continue;

						if (moment.updateMoment == UpdateMoment::UPDATE_AFTER_BIND && hasInputAttachments)
							continue;

						GroupPtr momentGroup(new tcu::TestCaseGroup(testCtx, moment.name, ""));

						for (const auto& accessType : arrayAccessTypes)
						{
							// Skip combinations that make no sense.
							if (hasArrays && accessType.arrayAccessType == ArrayAccessType::NO_ARRAY)
								continue;

							if (!hasArrays && accessType.arrayAccessType != ArrayAccessType::NO_ARRAY)
								continue;

							GroupPtr accessTypeGroup(new tcu::TestCaseGroup(testCtx, accessType.name, ""));

							for (const auto& testStage : stagesToTest)
							{
								const auto beginItr = std::begin(testStageList);
								const auto endItr   = std::end(testStageList);
								const auto iter     = std::find_if(beginItr, endItr, [testStage] (const StageAndName& ts) { return ts.testingStage == testStage; });

								DE_ASSERT(iter != endItr);
								const auto& stage = *iter;

								if (hasInputAttachments && stage.testingStage != TestingStage::FRAGMENT)
									continue;

								TestParams params = {
									descriptorSet,
									ut.updateType,
									srcStrategy.sourceSetStrategy,
									srcType.sourceSetType,
									poolStrategy.poolMutableStrategy,
									moment.updateMoment,
									accessType.arrayAccessType,
									stage.testingStage,
								};

								accessTypeGroup->addChild(new MutableTypesTest(testCtx, stage.name, "", params));
							}

							momentGroup->addChild(accessTypeGroup.release());
						}

						poolStrategyGroup->addChild(momentGroup.release());
					}

					srcTypeGroup->addChild(poolStrategyGroup.release());
				}

				srcStrategyGroup->addChild(srcTypeGroup.release());
			}

			updateGroup->addChild(srcStrategyGroup.release());
		}

		parentGroup->addChild(updateGroup.release());
	}
}

}

std::string descriptorTypeStr (VkDescriptorType descriptorType)
{
	static const auto prefixLen = std::string("VK_DESCRIPTOR_TYPE_").size();
	return de::toLower(de::toString(descriptorType).substr(prefixLen));
}

tcu::TestCaseGroup* createDescriptorValveMutableTests (tcu::TestContext& testCtx)
{
	GroupPtr mainGroup(new tcu::TestCaseGroup(testCtx, "mutable_descriptor", "Tests for VK_VALVE_mutable_descriptor_type"));

	const VkDescriptorType basicDescriptorTypes[] = {
		VK_DESCRIPTOR_TYPE_SAMPLER,
		VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
		VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
		VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
		VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
		VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
		VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
		VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
		VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
		VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
	};

	static const auto mandatoryTypes = getMandatoryMutableTypes();

	using StageVec = std::vector<TestingStage>;

	const StageVec allStages =
	{
		TestingStage::COMPUTE,
		TestingStage::VERTEX,
		TestingStage::TESS_CONTROL,
		TestingStage::TESS_EVAL,
		TestingStage::GEOMETRY,
		TestingStage::FRAGMENT,
		TestingStage::RAY_GEN,
		TestingStage::INTERSECTION,
		TestingStage::ANY_HIT,
		TestingStage::CLOSEST_HIT,
		TestingStage::MISS,
		TestingStage::CALLABLE,
	};

	const StageVec reducedStages =
	{
		TestingStage::COMPUTE,
		TestingStage::VERTEX,
		TestingStage::FRAGMENT,
		TestingStage::RAY_GEN,
	};

	const StageVec computeOnly =
	{
		TestingStage::COMPUTE,
	};

	// Basic tests with a single mutable descriptor.
	{
		GroupPtr singleCases(new tcu::TestCaseGroup(testCtx, "single", "Basic mutable descriptor tests with a single mutable descriptor"));

		for (const auto& descriptorType : basicDescriptorTypes)
		{
			const auto                          groupName = descriptorTypeStr(descriptorType);
			const std::vector<VkDescriptorType> actualTypes(1u, descriptorType);

			DescriptorSetPtr setPtr;
			{
				DescriptorSet::BindingPtrVector setBindings;
				setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, actualTypes));
				setPtr = DescriptorSetPtr(new DescriptorSet(setBindings));
			}

			GroupPtr subGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), ""));
			createMutableTestVariants(testCtx, subGroup.get(), setPtr, allStages);

			singleCases->addChild(subGroup.release());
		}

		// Case with a single descriptor that iterates several types.
		{
			DescriptorSetPtr setPtr;
			{
				DescriptorSet::BindingPtrVector setBindings;
				setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, mandatoryTypes));
				setPtr = DescriptorSetPtr(new DescriptorSet(setBindings));
			}

			GroupPtr subGroup(new tcu::TestCaseGroup(testCtx, "all_mandatory", ""));
			createMutableTestVariants(testCtx, subGroup.get(), setPtr, reducedStages);

			singleCases->addChild(subGroup.release());
		}

		// Cases that try to verify switching from any descriptor type to any other is possible.
		{
			GroupPtr subGroup(new tcu::TestCaseGroup(testCtx, "switches", "Test switching from one to another descriptor type works as expected"));

			for (const auto& initialDescriptorType : basicDescriptorTypes)
			{
				for (const auto& finalDescriptorType : basicDescriptorTypes)
				{
					if (initialDescriptorType == finalDescriptorType)
						continue;

					const std::vector<VkDescriptorType> mutableTypes { initialDescriptorType, finalDescriptorType };
					DescriptorSet::BindingPtrVector setBindings;
					setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, mutableTypes));

					DescriptorSetPtr setPtr = DescriptorSetPtr(new DescriptorSet(setBindings));

					const auto groupName = descriptorTypeStr(initialDescriptorType) + "_" + descriptorTypeStr(finalDescriptorType);
					GroupPtr combinationGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), ""));
					createMutableTestVariants(testCtx, combinationGroup.get(), setPtr, reducedStages);
					subGroup->addChild(combinationGroup.release());
				}
			}

			singleCases->addChild(subGroup.release());
		}

		mainGroup->addChild(singleCases.release());
	}

	// Cases with a single non-mutable descriptor. This provides some basic checks to verify copying to non-mutable bindings works.
	{
		GroupPtr singleNonMutableGroup (new tcu::TestCaseGroup(testCtx, "single_nonmutable", "Tests using a single non-mutable descriptor"));

		for (const auto& descriptorType : basicDescriptorTypes)
		{
			DescriptorSet::BindingPtrVector bindings;
			bindings.emplace_back(new SingleBinding(descriptorType, std::vector<VkDescriptorType>()));
			DescriptorSetPtr descriptorSet (new DescriptorSet(bindings));

			const auto groupName = descriptorTypeStr(descriptorType);
			GroupPtr descGroup (new tcu::TestCaseGroup(testCtx, groupName.c_str(), ""));

			createMutableTestVariants(testCtx, descGroup.get(), descriptorSet, reducedStages);
			singleNonMutableGroup->addChild(descGroup.release());
		}

		mainGroup->addChild(singleNonMutableGroup.release());
	}

	const struct {
		bool unbounded;
		const char* name;
	} unboundedCases[] = {
		{false, "constant_size"},
		{true,  "unbounded"},
	};

	const struct {
		bool aliasing;
		const char* name;
	} aliasingCases[] = {
		{false, "noaliasing"},
		{true,  "aliasing"},
	};

	const struct {
		bool oneArrayOnly;
		bool mixNonMutable;
		const char* groupName;
		const char* groupDesc;
	} arrayCountGroups[] = {
		{true,  false, "one_array",             "Tests using an array of mutable descriptors"},
		{false, false, "multiple_arrays",       "Tests using multiple arrays of mutable descriptors"},
		{false, true,  "multiple_arrays_mixed", "Tests using multiple arrays of mutable descriptors mixed with arrays of nonmutable ones"},
	};

	for (const auto& variant : arrayCountGroups)
	{
		GroupPtr arrayGroup(new tcu::TestCaseGroup(testCtx, variant.groupName, variant.groupDesc));

		for (const auto& unboundedCase : unboundedCases)
		{
			GroupPtr unboundedGroup(new tcu::TestCaseGroup(testCtx, unboundedCase.name, ""));

			for (const auto& aliasingCase : aliasingCases)
			{
				GroupPtr aliasingGroup(new tcu::TestCaseGroup(testCtx, aliasingCase.name, ""));

				DescriptorSet::BindingPtrVector setBindings;

				// Prepare descriptors for this test variant.
				for (size_t mandatoryTypesRotation = 0; mandatoryTypesRotation < mandatoryTypes.size(); ++mandatoryTypesRotation)
				{
					const bool isLastBinding = (variant.oneArrayOnly || mandatoryTypesRotation == mandatoryTypes.size() - 1u);
					const bool isUnbounded   = (unboundedCase.unbounded && isLastBinding);

					// Create a rotation of the mandatory types for each mutable array binding.
					auto mandatoryTypesVector = mandatoryTypes;
					{
						const auto beginPtr = &mandatoryTypesVector[0];
						const auto endPtr   = beginPtr + mandatoryTypesVector.size();
						std::rotate(beginPtr, &mandatoryTypesVector[mandatoryTypesRotation], endPtr);
					}

					std::vector<SingleBinding> arrayBindings;

					if (aliasingCase.aliasing)
					{
						// With aliasing, the descriptor types rotate in each descriptor.
						for (size_t typeIdx = 0; typeIdx < mandatoryTypesVector.size(); ++typeIdx)
						{
							auto       rotatedTypes = mandatoryTypesVector;
							const auto beginPtr     = &rotatedTypes[0];
							const auto endPtr       = beginPtr + rotatedTypes.size();

							std::rotate(beginPtr, &rotatedTypes[typeIdx], endPtr);

							arrayBindings.emplace_back(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, rotatedTypes);
						}
					}
					else
					{
						// Without aliasing, all descriptors use the same type at the same time.
						const SingleBinding noAliasingBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, mandatoryTypesVector);
						arrayBindings.resize(mandatoryTypesVector.size(), noAliasingBinding);
					}

					setBindings.emplace_back(new ArrayBinding(isUnbounded, arrayBindings));

					if (variant.mixNonMutable && !isUnbounded)
					{
						// Create a non-mutable array binding interleaved with the other ones.
						const SingleBinding nonMutableBinding(mandatoryTypes[mandatoryTypesRotation], std::vector<VkDescriptorType>());
						std::vector<SingleBinding> nonMutableBindings(mandatoryTypes.size(), nonMutableBinding);
						setBindings.emplace_back(new ArrayBinding(false, nonMutableBindings));
					}

					if (variant.oneArrayOnly)
						break;
				}

				DescriptorSetPtr descriptorSet(new DescriptorSet(setBindings));
				createMutableTestVariants(testCtx, aliasingGroup.get(), descriptorSet, computeOnly);

				unboundedGroup->addChild(aliasingGroup.release());
			}

			arrayGroup->addChild(unboundedGroup.release());
		}

		mainGroup->addChild(arrayGroup.release());
	}

	// Cases with a single mutable binding followed by an array of mutable bindings.
	// The array will use a single type beyond the mandatory ones.
	{
		GroupPtr singleAndArrayGroup(new tcu::TestCaseGroup(testCtx, "single_and_array", "Tests using a single mutable binding followed by a mutable array binding"));

		for (const auto& descriptorType : basicDescriptorTypes)
		{
			// Input attachments will not use arrays.
			if (descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
				continue;

			if (de::contains(begin(mandatoryTypes), end(mandatoryTypes), descriptorType))
				continue;

			const auto groupName = descriptorTypeStr(descriptorType);
			GroupPtr descTypeGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), ""));

			for (const auto& aliasingCase : aliasingCases)
			{
				GroupPtr aliasingGroup(new tcu::TestCaseGroup(testCtx, aliasingCase.name, ""));

				DescriptorSet::BindingPtrVector setBindings;
				std::vector<SingleBinding> arrayBindings;

				// Single mutable descriptor as the first binding.
				setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, mandatoryTypes));

				// Descriptor array as the second binding.
				auto arrayBindingDescTypes = mandatoryTypes;
				arrayBindingDescTypes.push_back(descriptorType);

				if (aliasingCase.aliasing)
				{
					// With aliasing, the descriptor types rotate in each descriptor.
					for (size_t typeIdx = 0; typeIdx < arrayBindingDescTypes.size(); ++typeIdx)
					{
						auto       rotatedTypes = arrayBindingDescTypes;
						const auto beginPtr     = &rotatedTypes[0];
						const auto endPtr       = beginPtr + rotatedTypes.size();

						std::rotate(beginPtr, &rotatedTypes[typeIdx], endPtr);

						arrayBindings.emplace_back(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, rotatedTypes);
					}
				}
				else
				{
					// Without aliasing, all descriptors use the same type at the same time.
					const SingleBinding noAliasingBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, arrayBindingDescTypes);
					arrayBindings.resize(arrayBindingDescTypes.size(), noAliasingBinding);
				}

				// Second binding: array binding.
				setBindings.emplace_back(new ArrayBinding(false/*unbounded*/, arrayBindings));

				// Create set and test variants.
				DescriptorSetPtr descriptorSet(new DescriptorSet(setBindings));
				createMutableTestVariants(testCtx, aliasingGroup.get(), descriptorSet, computeOnly);

				descTypeGroup->addChild(aliasingGroup.release());
			}

			singleAndArrayGroup->addChild(descTypeGroup.release());
		}

		mainGroup->addChild(singleAndArrayGroup.release());
	}

	// Cases with several mutable non-array bindings.
	{
		GroupPtr multipleGroup    (new tcu::TestCaseGroup(testCtx, "multiple", "Tests using multiple mutable bindings"));
		GroupPtr mutableOnlyGroup (new tcu::TestCaseGroup(testCtx, "mutable_only", "Tests using only mutable descriptors"));
		GroupPtr mixedGroup       (new tcu::TestCaseGroup(testCtx, "mixed", "Tests mixing mutable descriptors an non-mutable descriptors"));

		// Each descriptor will have a different type in every iteration, like in the one_array aliasing case.
		for (int groupIdx = 0; groupIdx < 2; ++groupIdx)
		{
			const bool mixed = (groupIdx == 1);
			DescriptorSet::BindingPtrVector setBindings;

			for (size_t typeIdx = 0; typeIdx < mandatoryTypes.size(); ++typeIdx)
			{
				auto       rotatedTypes = mandatoryTypes;
				const auto beginPtr     = &rotatedTypes[0];
				const auto endPtr       = beginPtr + rotatedTypes.size();

				std::rotate(beginPtr, &rotatedTypes[typeIdx], endPtr);
				setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, rotatedTypes));

				// Additional non-mutable binding interleaved with the mutable ones.
				if (mixed)
					setBindings.emplace_back(new SingleBinding(rotatedTypes[0], std::vector<VkDescriptorType>()));
			}
			DescriptorSetPtr descriptorSet(new DescriptorSet(setBindings));

			const auto dstGroup = (mixed ? mixedGroup.get() : mutableOnlyGroup.get());
			createMutableTestVariants(testCtx, dstGroup, descriptorSet, computeOnly);
		}

		multipleGroup->addChild(mutableOnlyGroup.release());
		multipleGroup->addChild(mixedGroup.release());
		mainGroup->addChild(multipleGroup.release());
	}

	return mainGroup.release();
}

} // BindingModel
} // vkt
