/*-------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2017 Khronos Group
*
* 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 API Maintenance3 Check test - checks structs and function from VK_KHR_maintenance3
*//*--------------------------------------------------------------------*/

#include "tcuTestLog.hpp"

#include "vkQueryUtil.hpp"

#include "vktApiMaintenance3Check.hpp"
#include "vktTestCase.hpp"

#include <sstream>
#include <limits>
#include <utility>
#include <algorithm>
#include <map>
#include <set>

using namespace vk;

namespace vkt
{

namespace api
{

namespace
{
using ::std::string;
using ::std::vector;
using ::std::map;
using ::std::set;
using ::std::ostringstream;
using ::std::make_pair;

typedef vk::VkPhysicalDeviceProperties						DevProp1;
typedef vk::VkPhysicalDeviceProperties2						DevProp2;
typedef vk::VkPhysicalDeviceMaintenance3Properties			MaintDevProp3;
typedef vk::VkPhysicalDeviceFeatures2						DevFeat2;
typedef vk::VkPhysicalDeviceInlineUniformBlockFeaturesEXT	DevIubFeat;
typedef vk::VkPhysicalDeviceInlineUniformBlockPropertiesEXT	DevIubProp;

// These variables are equal to minimal values for maxMemoryAllocationSize and maxPerSetDescriptors
constexpr deUint32 maxMemoryAllocationSize			= 1073741824u;
constexpr deUint32 maxDescriptorsInSet				= 1024u;
constexpr deUint32 maxReasonableInlineUniformBlocks	= 64u;

using TypeSet		= set<vk::VkDescriptorType>;

// Structure representing an implementation limit, like maxPerStageDescriptorSamplers. It has a maximum value
// obtained at runtime and a remaining number of descriptors, which starts with the same count and decreases
// as we assign descriptor counts to the different types. A limit is affected by (or itself affects) one or more
// descriptor types. Note a type may be involved in several limits, and a limit may affect several types.
struct Limit
{
	Limit(const string& name_, deUint32 maxValue_, const TypeSet& affectedTypes_)
		: name(name_), maxValue(maxValue_), remaining(maxValue_), affectedTypes(affectedTypes_)
		{}

	const string	name;
	const deUint32	maxValue;
	deUint32		remaining;
	const TypeSet	affectedTypes;
};

// Structure representing how many descriptors have been assigned to the given type. The type is "alive" during
// descriptor count assignment if more descriptors can be added to the type without hitting any limit affected
// by the type. Once at least one of the limits is reached, no more descriptors can be assigned to the type and
// the type is no longer considered "alive".
struct TypeState
{
	TypeState(vk::VkDescriptorType type_)
		: type(type_), alive(true), count(0u)
		{}

	const vk::VkDescriptorType	type;
	bool						alive;
	deUint32					count;
};

using TypeCounts	= map<vk::VkDescriptorType, TypeState>;
using LimitsVector	= vector<Limit>;

// Get the subset of alive types from the given map.
TypeSet getAliveTypes (const TypeCounts& typeCounts)
{
	TypeSet aliveTypes;
	for (const auto& typeCount : typeCounts)
	{
		if (typeCount.second.alive)
			aliveTypes.insert(typeCount.first);
	}
	return aliveTypes;
}

// Get the subset of alive types for a specific limit, among the set of types affected by the limit.
TypeSet getAliveTypesForLimit (const Limit& limit, const TypeSet& aliveTypes)
{
	TypeSet subset;
	for (const auto& type : limit.affectedTypes)
	{
		if (aliveTypes.find(type) != aliveTypes.end())
			subset.insert(type);
	}
	return subset;
}

// Distribute descriptor counts as evenly as possible among the given set of types, taking into account the
// given limits.
void distributeCounts (LimitsVector& limits, TypeCounts& typeCounts)
{
	using IncrementsMap = map<vk::VkDescriptorType, deUint32>;
	TypeSet aliveTypes;

	while ((aliveTypes = getAliveTypes(typeCounts)).size() > 0u)
	{
		// Calculate the maximum increment per alive descriptor type. This involves iterating over the limits and
		// finding out how many more descriptors can be distributed among the affected types that are still alive
		// for the limit. For each type, remember the lowest possible increment.
		IncrementsMap increments;
		for (const auto& type : aliveTypes)
			increments[type] = std::numeric_limits<deUint32>::max();

		TypeSet aliveTypesForLimit;

		for (const auto& limit : limits)
		{
			if (limit.remaining == 0u)
				continue;

			aliveTypesForLimit = getAliveTypesForLimit(limit, aliveTypes);
			if (aliveTypesForLimit.empty())
				continue;

			// Distribute remaining count evenly among alive types.
			deUint32 maxIncrement = limit.remaining / static_cast<deUint32>(aliveTypesForLimit.size());
			if (maxIncrement == 0u)
			{
				// More types than remaining descriptors. Assign 1 to the first affected types and 0 to the rest.
				deUint32 remaining = limit.remaining;
				for (const auto& type : aliveTypesForLimit)
				{
					if (remaining > 0u && increments[type] > 0u)
					{
						increments[type] = 1u;
						--remaining;
					}
					else
					{
						increments[type] = 0u;
					}
				}
			}
			else
			{
				// Find the lowest possible increment taking into account all limits.
				for (const auto& type : aliveTypesForLimit)
				{
					if (increments[type] > maxIncrement)
						increments[type] = maxIncrement;
				}
			}
		}

		// Apply the calculated increments per descriptor type, decreasing the remaining descriptors for each
		// limit affected by the type, and switching types to the not-alive state when a limit is hit.
		for (const auto& inc : increments)
		{
			const vk::VkDescriptorType& type = inc.first;
			const deUint32& increment = inc.second;

			// Increase type count.
			auto iter = typeCounts.find(type);
			DE_ASSERT(iter != typeCounts.end());
			iter->second.count += increment;

			for (auto& limit : limits)
			{
				// Decrease remaining descriptors for affected limits.
				if (limit.affectedTypes.find(type) != limit.affectedTypes.end())
				{
					DE_ASSERT(increment <= limit.remaining);
					limit.remaining -= increment;
				}
				if (limit.remaining == 0u)
				{
					// Limit hit, switch affected types to not-alive.
					for (const auto& affectedType : limit.affectedTypes)
					{
						auto tc = typeCounts.find(affectedType);
						if (tc != typeCounts.end())
							tc->second.alive = false;
					}
				}
			}
		}
	}
}

// Create a limits vector based on runtime limit information for the device.
LimitsVector buildLimitsVector (const DevProp1& prop1, const DevIubProp& iubProp, const MaintDevProp3& maintProp3)
{
	static const TypeSet samplerTypes				= { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_DESCRIPTOR_TYPE_SAMPLER };
	static const TypeSet sampledImageTypes			= { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER };
	static const TypeSet uniformBufferTypes			= { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC };
	static const TypeSet storageBufferTypes			= { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC };
	static const TypeSet storageImageTypes			= { vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER };
	static const TypeSet inputAttachmentTypes		= { vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT };
	static const TypeSet inlineUniformBlockTypes	= { vk::VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT };
	static const TypeSet dynamicUniformBuffer		= { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC };
	static const TypeSet dynamicStorageBuffer		= { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC };
	static const TypeSet allTypesButIUB				= {
														vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
														vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
														vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
														vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
														vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
														vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
														vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
														vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
														vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
														vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
													};
	static const TypeSet allTypes					= {
														vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
														vk::VK_DESCRIPTOR_TYPE_SAMPLER,
														vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
														vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
														vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
														vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
														vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
														vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
														vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
														vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
														vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
														vk::VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT,
													};

	LimitsVector limits = {
		{
			"maxPerStageDescriptorSamplers",
			prop1.limits.maxPerStageDescriptorSamplers,
			samplerTypes
		},
		{
			"maxDescriptorSetSamplers",
			prop1.limits.maxDescriptorSetSamplers,
			samplerTypes
		},
		{
			"maxPerStageDescriptorSampledImages",
			prop1.limits.maxPerStageDescriptorSampledImages,
			sampledImageTypes
		},
		{
			"maxDescriptorSetSampledImages",
			prop1.limits.maxDescriptorSetSampledImages,
			sampledImageTypes
		},
		{
			"maxPerStageDescriptorUniformBuffers",
			prop1.limits.maxPerStageDescriptorUniformBuffers,
			uniformBufferTypes
		},
		{
			"maxDescriptorSetUniformBuffers",
			prop1.limits.maxDescriptorSetUniformBuffers,
			uniformBufferTypes
		},
		{
			"maxPerStageDescriptorStorageBuffers",
			prop1.limits.maxPerStageDescriptorStorageBuffers,
			storageBufferTypes
		},
		{
			"maxDescriptorSetStorageBuffers",
			prop1.limits.maxDescriptorSetStorageBuffers,
			storageBufferTypes
		},
		{
			"maxPerStageDescriptorStorageImages",
			prop1.limits.maxPerStageDescriptorStorageImages,
			storageImageTypes
		},
		{
			"maxDescriptorSetStorageImages",
			prop1.limits.maxDescriptorSetStorageImages,
			storageImageTypes
		},
		{
			"maxPerStageDescriptorInputAttachments",
			prop1.limits.maxPerStageDescriptorInputAttachments,
			inputAttachmentTypes
		},
		{
			"maxDescriptorSetInputAttachments",
			prop1.limits.maxDescriptorSetInputAttachments,
			inputAttachmentTypes
		},
		{
			"maxDescriptorSetUniformBuffersDynamic",
			prop1.limits.maxDescriptorSetUniformBuffersDynamic,
			dynamicUniformBuffer
		},
		{
			"maxDescriptorSetStorageBuffersDynamic",
			prop1.limits.maxDescriptorSetStorageBuffersDynamic,
			dynamicStorageBuffer
		},
		{
			"maxPerStageDescriptorInlineUniformBlocks",
			iubProp.maxPerStageDescriptorInlineUniformBlocks,
			inlineUniformBlockTypes
		},
		{
			"maxDescriptorSetInlineUniformBlocks",
			iubProp.maxDescriptorSetInlineUniformBlocks,
			inlineUniformBlockTypes
		},
		{
			"maxPerStageResources",
			prop1.limits.maxPerStageResources,
			allTypesButIUB
		},
		{
			"maxPerSetDescriptors",
			maintProp3.maxPerSetDescriptors,
			allTypes
		},
	};

	return limits;
}

// Create a vector of bindings by constructing the system limits and distributing descriptor counts.
vector<vk::VkDescriptorSetLayoutBinding> calculateBindings(const DevProp1& prop1, const DevIubProp& iubProp, const MaintDevProp3& maintProp3, const vector<vk::VkDescriptorType> &types)
{
	LimitsVector limits = buildLimitsVector(prop1, iubProp, maintProp3);
	TypeCounts typeCounts;

	for (const auto& type : types)
		typeCounts.emplace(make_pair(type, TypeState(type)));

	distributeCounts(limits, typeCounts);

	deUint32 bindingNumber = 0u;
	vector<vk::VkDescriptorSetLayoutBinding> bindings;
	for (const auto& tc : typeCounts)
	{
		if (tc.first != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
		{
			vk::VkDescriptorSetLayoutBinding b;
			b.binding = bindingNumber;
			b.descriptorCount = tc.second.count;
			b.descriptorType = tc.first;
			b.pImmutableSamplers = DE_NULL;
			b.stageFlags = vk::VK_SHADER_STAGE_ALL;

			bindings.push_back(b);
		}
		else
		{
			// Inline uniform blocks are special because descriptorCount represents the size of that block.
			// The only way of creating several blocks is by adding more structures to the list instead of creating an array.
			size_t firstAdded = bindings.size();
			bindings.resize(firstAdded + tc.second.count);
			for (deUint32 i = 0u; i < tc.second.count; ++i)
			{
				vk::VkDescriptorSetLayoutBinding& b = bindings[firstAdded + i];
				b.binding = bindingNumber + i;
				b.descriptorCount = 4u;	// For inline uniform blocks, this must be a multiple of 4 according to the spec.
				b.descriptorType = tc.first;
				b.pImmutableSamplers = DE_NULL;
				b.stageFlags = vk::VK_SHADER_STAGE_ALL;
			}
		}
		bindingNumber += tc.second.count;
	}

	return bindings;
}

// Get a textual description with descriptor counts per type.
string getBindingsDescription (const vector<VkDescriptorSetLayoutBinding>& bindings)
{
	map<vk::VkDescriptorType, deUint32> typeCount;
	deUint32 totalCount = 0u;
	deUint32 count;
	for (const auto& b : bindings)
	{
		auto iter = typeCount.find(b.descriptorType);
		if (iter == typeCount.end())
			iter = typeCount.insert(make_pair(b.descriptorType, (deUint32)0)).first;
		count = ((b.descriptorType == vk::VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) ? 1u : b.descriptorCount);
		iter->second += count;
		totalCount += count;
	}

	deUint32 i = 0;
	ostringstream combStr;

	combStr << "{ Descriptors: " << totalCount << ", [";
	for (const auto& tc : typeCount)
		combStr << (i++ ? ", " : " ") << tc.first << ": " << tc.second;
	combStr << " ] }";

	return combStr.str();
}

class Maintenance3StructTestInstance : public TestInstance
{
public:
											Maintenance3StructTestInstance			(Context& ctx)
												: TestInstance						(ctx)
	{}
	virtual tcu::TestStatus					iterate									(void)
	{
		tcu::TestLog&						log										= m_context.getTestContext().getLog();

		// set values to be a bit smaller than required minimum values
		MaintDevProp3 maintProp3 =
		{
			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES,				//VkStructureType						sType;
			DE_NULL,																//void*									pNext;
			maxDescriptorsInSet - 1u,												//deUint32								maxPerSetDescriptors;
			maxMemoryAllocationSize - 1u											//VkDeviceSize							maxMemoryAllocationSize;
		};

		DevProp2 prop2;
		deMemset(&prop2, 0, sizeof(prop2)); // zero the structure
		prop2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
		prop2.pNext = &maintProp3;

		m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &prop2);

		if (maintProp3.maxMemoryAllocationSize < maxMemoryAllocationSize)
			return tcu::TestStatus::fail("Fail");

		if (maintProp3.maxPerSetDescriptors < maxDescriptorsInSet)
			return tcu::TestStatus::fail("Fail");

		log << tcu::TestLog::Message << "maxMemoryAllocationSize: "	<< maintProp3.maxMemoryAllocationSize	<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "maxPerSetDescriptors: "	<< maintProp3.maxPerSetDescriptors		<< tcu::TestLog::EndMessage;
		return tcu::TestStatus::pass("Pass");
	}
};

class Maintenance3StructTestCase : public TestCase
{
public:
											Maintenance3StructTestCase				(tcu::TestContext&	testCtx)
												: TestCase(testCtx, "maintenance3_properties", "tests VkPhysicalDeviceMaintenance3Properties struct")
	{}

	virtual									~Maintenance3StructTestCase				(void)
	{}
	virtual void							checkSupport							(Context&	ctx) const
	{
		ctx.requireDeviceExtension("VK_KHR_maintenance3");
	}
	virtual TestInstance*					createInstance							(Context&	ctx) const
	{
		return new Maintenance3StructTestInstance(ctx);
	}

private:
};

class Maintenance3DescriptorTestInstance : public TestInstance
{
public:
											Maintenance3DescriptorTestInstance		(Context&	ctx)
												: TestInstance(ctx)
	{}
	virtual tcu::TestStatus					iterate									(void)
	{
		const auto& vki				= m_context.getInstanceInterface();
		const auto& vkd				= m_context.getDeviceInterface();
		const auto& physicalDevice	= m_context.getPhysicalDevice();
		const auto&	device			= m_context.getDevice();
		auto&		log				= m_context.getTestContext().getLog();
		bool		iubSupported	= false;
		bool		iubExtSupported	= isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_EXT_inline_uniform_block");

		if (iubExtSupported)
		{
			DevIubFeat	iubFeatures	=
			{
				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT,
				DE_NULL,
				0u,
				0u
			};

			DevFeat2	features2	=
			{
				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
				&iubFeatures,
				VkPhysicalDeviceFeatures()
			};

			vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
			iubSupported = (iubFeatures.inlineUniformBlock == VK_TRUE);
		}

		DevIubProp							devIubProp								=
		{
			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT,	// VkStructureType	sType;
			DE_NULL,																// void*			pNext;
			0u,																		// deUint32			maxInlineUniformBlockSize;
			0u,																		// deUint32			maxPerStageDescriptorInlineUniformBlocks;
			0u,																		// deUint32			maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks;
			0u,																		// deUint32			maxDescriptorSetInlineUniformBlocks;
			0u																		// deUint32			maxDescriptorSetUpdateAfterBindInlineUniformBlocks;
		};

		MaintDevProp3						maintProp3								=
		{
			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES,				//VkStructureType						sType;
			(iubSupported ? &devIubProp : DE_NULL),									//void*									pNext;
			maxDescriptorsInSet,													//deUint32								maxPerSetDescriptors;
			maxMemoryAllocationSize													//VkDeviceSize							maxMemoryAllocationSize;
		};

		DevProp2							prop2									=
		{
			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,							//VkStructureType						sType;
			&maintProp3,															//void*									pNext;
			VkPhysicalDeviceProperties()											//VkPhysicalDeviceProperties			properties;
		};

		vki.getPhysicalDeviceProperties2(physicalDevice, &prop2);

		vector<VkDescriptorType> descriptorTypes = {
			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_UNIFORM_BUFFER_DYNAMIC,
			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
		};
		if (iubSupported)
			descriptorTypes.push_back(VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT);

		// VkDescriptorSetLayoutCreateInfo setup
		vk::VkDescriptorSetLayoutCreateInfo	pCreateInfo								=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,					//VkStructureType						sType;
			DE_NULL,																//const void*							pNext;
			0u,																		//VkDescriptorSetLayoutCreateFlags		flags;
			0u,																		//deUint32								bindingCount;
			DE_NULL																	//const VkDescriptorSetLayoutBinding*	pBindings;
		};

		// VkDescriptorSetLayoutSupport setup
		vk::VkDescriptorSetLayoutSupport	pSupport								=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT,						//VkStructureType						sType;
			DE_NULL,																//void*									pNext;
			VK_FALSE																//VkBool32								supported;
		};

		// Check every combination maximizing descriptor counts.
		for (size_t combSize = 1; combSize <= descriptorTypes.size(); ++combSize)
		{
			// Create a vector of selectors with combSize elements set to true.
			vector<bool> selectors(descriptorTypes.size(), false);
			std::fill(begin(selectors), begin(selectors) + combSize, true);

			// Iterate over every permutation of selectors for that combination size.
			do
			{
				vector<vk::VkDescriptorType> types;
				for (size_t i = 0; i < selectors.size(); ++i)
				{
					if (selectors[i])
						types.push_back(descriptorTypes[i]);
				}

				// Due to inline uniform blocks being unable to form arrays and each one of them needing its own
				// VkDescriptorSetLayoutBinding structure, we will limit when to test them.
				if (std::find(begin(types), end(types), VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) != types.end() &&
					devIubProp.maxPerStageDescriptorInlineUniformBlocks > maxReasonableInlineUniformBlocks &&
					combSize > 1u && combSize < descriptorTypes.size())
				{
					continue;
				}

				vector<vk::VkDescriptorSetLayoutBinding> bindings = calculateBindings(prop2.properties, devIubProp, maintProp3, types);

				string description = getBindingsDescription(bindings);
				log << tcu::TestLog::Message << "Testing combination: " << description << tcu::TestLog::EndMessage;

				pCreateInfo.bindingCount = static_cast<deUint32>(bindings.size());
				pCreateInfo.pBindings = bindings.data();

				vkd.getDescriptorSetLayoutSupport(device, &pCreateInfo, &pSupport);
				if (pSupport.supported == VK_FALSE)
				{
					ostringstream msg;
					msg << "Failed to use the following descriptor type counts: " << description;
					return tcu::TestStatus::fail(msg.str());
				}
			} while (std::prev_permutation(begin(selectors), end(selectors)));
		}

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

};

class Maintenance3DescriptorTestCase : public TestCase
{

public:
											Maintenance3DescriptorTestCase			(tcu::TestContext&	testCtx)
												: TestCase(testCtx, "descriptor_set", "tests vkGetDescriptorSetLayoutSupport struct")
	{}
	virtual									~Maintenance3DescriptorTestCase			(void)
	{}
	virtual void							checkSupport							(Context&	ctx) const
	{
		ctx.requireDeviceExtension("VK_KHR_maintenance3");
	}
	virtual TestInstance*					createInstance							(Context&	ctx) const
	{
		return new Maintenance3DescriptorTestInstance(ctx);
	}
};

} // anonymous

tcu::TestCaseGroup*							createMaintenance3Tests					(tcu::TestContext&	testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>	main3Tests(new tcu::TestCaseGroup(testCtx, "maintenance3_check", "Maintenance3 Tests"));
	main3Tests->addChild(new Maintenance3StructTestCase(testCtx));
	main3Tests->addChild(new Maintenance3DescriptorTestCase(testCtx));

	return main3Tests.release();
}

} // api
} // vkt
