Implement tests for VK_KHR_maintenance3

Commit intrduce tests for:

- maxPerSetDescriptors
- maxMemoryAllocationSize
- vkGetDescriptorSetLayoutSupportKHR

New test:

dEQP-VK.api.maintenance3_check.*

Components: Vulkan

VK-GL-CTS issue: 664

Change-Id: I069540c795361c0de9155dfb9be834c162800ffb
(cherry picked from commit cd9ca7e88a6429d33210ecf158fda66f9b3f3d70)
diff --git a/AndroidGen.mk b/AndroidGen.mk
index 16d946a..862beff 100644
--- a/AndroidGen.mk
+++ b/AndroidGen.mk
@@ -67,6 +67,7 @@
 	external/vulkancts/modules/vulkan/api/vktApiGetMemoryCommitment.cpp \
 	external/vulkancts/modules/vulkan/api/vktApiGranularityTests.cpp \
 	external/vulkancts/modules/vulkan/api/vktApiImageClearingTests.cpp \
+	external/vulkancts/modules/vulkan/api/vktApiMaintenance3Check.cpp \
 	external/vulkancts/modules/vulkan/api/vktApiNullHandleTests.cpp \
 	external/vulkancts/modules/vulkan/api/vktApiObjectManagementTests.cpp \
 	external/vulkancts/modules/vulkan/api/vktApiSmokeTests.cpp \
diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt
index ff5160b..8274f9c 100755
--- a/android/cts/master/vk-master.txt
+++ b/android/cts/master/vk-master.txt
@@ -71426,6 +71426,8 @@
 dEQP-VK.api.external.fence.opaque_win32_kmt.signal_wait_import_permanent
 dEQP-VK.api.external.fence.opaque_win32_kmt.export_signal_import_wait_permanent
 dEQP-VK.api.external.fence.opaque_win32_kmt.export_import_signal_wait_permanent
+dEQP-VK.api.maintenance3_check.maintenance3_properties
+dEQP-VK.api.maintenance3_check.descriptor_set
 dEQP-VK.memory.allocation.basic.size_64.forward.count_1
 dEQP-VK.memory.allocation.basic.size_64.forward.count_10
 dEQP-VK.memory.allocation.basic.size_64.forward.count_100
diff --git a/external/vulkancts/framework/vulkan/vkSupportedExtensions.inl b/external/vulkancts/framework/vulkan/vkSupportedExtensions.inl
index 9aa6ef0..85d2bc5 100644
--- a/external/vulkancts/framework/vulkan/vkSupportedExtensions.inl
+++ b/external/vulkancts/framework/vulkan/vkSupportedExtensions.inl
@@ -23,6 +23,7 @@
 		dst.push_back("VK_KHR_get_memory_requirements2");
 		dst.push_back("VK_KHR_sampler_ycbcr_conversion");
 		dst.push_back("VK_KHR_bind_memory2");
+		dst.push_back("VK_KHR_maintenance3");
 	}
 }
 
diff --git a/external/vulkancts/modules/vulkan/api/CMakeLists.txt b/external/vulkancts/modules/vulkan/api/CMakeLists.txt
index 0edc561..a86d134 100644
--- a/external/vulkancts/modules/vulkan/api/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/api/CMakeLists.txt
@@ -45,6 +45,8 @@
 	vktApiExternalMemoryTests.hpp
 	vktApiBufferAndImageAllocationUtil.hpp
 	vktApiBufferAndImageAllocationUtil.cpp
+	vktApiMaintenance3Check.hpp
+	vktApiMaintenance3Check.cpp
 	)
 
 set(DEQP_VK_API_LIBS
diff --git a/external/vulkancts/modules/vulkan/api/vktApiMaintenance3Check.cpp b/external/vulkancts/modules/vulkan/api/vktApiMaintenance3Check.cpp
new file mode 100644
index 0000000..c810b94
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/api/vktApiMaintenance3Check.cpp
@@ -0,0 +1,301 @@
+/*-------------------------------------------------------------------------
+* 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"
+
+using namespace vk;
+
+namespace vkt
+{
+
+namespace api
+{
+
+namespace
+{
+using ::std::string;
+using ::std::vector;
+
+typedef vk::VkPhysicalDeviceProperties DevProp1;
+typedef vk::VkPhysicalDeviceProperties2  DevProp2;
+typedef vk::VkPhysicalDeviceMaintenance3Properties MainDevProp3;
+
+
+void										checkSupport							(const Context& m_context)
+{
+	const vector<string>					extensions								= m_context.getDeviceExtensions();
+
+	if (!isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_KHR_maintenance3"))
+		TCU_THROW(NotSupportedError, "VK_KHR_maintenance3 extension is not supported");
+}
+
+class Maintenance3StructTestInstance : public TestInstance
+{
+public:
+											Maintenance3StructTestInstance			(Context& ctx)
+												: TestInstance						(ctx)
+	{}
+	virtual tcu::TestStatus					iterate									(void)
+	{
+		checkSupport(m_context);
+		tcu::TestLog&						log										= m_context.getTestContext().getLog();
+
+		// these variables are equal to minimal values for maxMemoryAllocationSize and maxPerSetDescriptors
+		const deUint32						maxMemoryAllocationSize					= 1073741824u;
+		const deUint32						maxDescriptorsInSet						= 1024u;
+
+		MainDevProp3 mainProp3 =
+		{
+			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES,				//VkStructureType						sType;
+			DE_NULL,																//void*									pNext;
+			maxDescriptorsInSet,													//deUint32								maxPerSetDescriptors;
+			maxMemoryAllocationSize													//VkDeviceSize							maxMemoryAllocationSize;
+		};
+
+		DevProp2 prop2 =
+		{
+			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,							//VkStructureType						sType;
+			&mainProp3,																//void*									pNext;
+			VkPhysicalDeviceProperties()											//VkPhysicalDeviceProperties			properties;
+		};
+
+		m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &prop2);
+
+		if (mainProp3.maxMemoryAllocationSize < maxMemoryAllocationSize)
+			return tcu::TestStatus::fail("Fail");
+
+		if (mainProp3.maxPerSetDescriptors < maxDescriptorsInSet)
+			return tcu::TestStatus::fail("Fail");
+
+		if (mainProp3.maxMemoryAllocationSize == maxMemoryAllocationSize)
+			return tcu::TestStatus::fail("Fail");
+
+		if (mainProp3.maxPerSetDescriptors == maxDescriptorsInSet)
+			return tcu::TestStatus::fail("Fail");
+
+		log << tcu::TestLog::Message << "maxMemoryAllocationSize: "	<< mainProp3.maxMemoryAllocationSize	<< tcu::TestLog::EndMessage;
+		log << tcu::TestLog::Message << "maxPerSetDescriptors: "	<< mainProp3.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 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)
+	{
+		checkSupport(m_context);
+
+		// these variables are equal to minimal values for maxMemoryAllocationSize and maxPerSetDescriptors
+		const deUint32						maxMemoryAllocationSize					= 1073741824u;
+		const deUint32						maxDescriptorsInSet						= 1024u;
+
+		MainDevProp3						mainProp3								=
+		{
+			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES,				//VkStructureType						sType;
+			DE_NULL,																//void*									pNext;
+			maxDescriptorsInSet,													//deUint32								maxPerSetDescriptors;
+			maxMemoryAllocationSize													//VkDeviceSize							maxMemoryAllocationSize;
+		};
+
+		DevProp2							prop2									=
+		{
+			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,							//VkStructureType						sType;
+			&mainProp3,																//void*									pNext;
+			VkPhysicalDeviceProperties()											//VkPhysicalDeviceProperties			properties;
+		};
+
+		DevProp1							prop1;
+
+		m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &prop1);
+		m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &prop2);
+
+		// setup for descriptors sets
+		VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding[VK_DESCRIPTOR_TYPE_LAST];
+
+		for (deUint32 ndx = 0u; ndx < VK_DESCRIPTOR_TYPE_LAST; ++ndx)
+		{
+			descriptorSetLayoutBinding[ndx].binding									= ndx;
+			descriptorSetLayoutBinding[ndx].descriptorType							= static_cast<VkDescriptorType>(ndx);
+			descriptorSetLayoutBinding[ndx].descriptorCount							= mainProp3.maxPerSetDescriptors;
+			descriptorSetLayoutBinding[ndx].stageFlags								= VK_SHADER_STAGE_ALL;
+			descriptorSetLayoutBinding[ndx].pImmutableSamplers						= DE_NULL;
+		}
+
+		// VkDescriptorSetLayoutCreateInfo setup
+		vk::VkDescriptorSetLayoutCreateInfo	pCreateInfo								=
+		{
+			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,					//VkStructureType						sType;
+			DE_NULL,																//const void*							pNext;
+			0u,																		//VkDescriptorSetLayoutCreateFlags		flags;
+			1u,																		//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 for single descriptors
+		for (deUint32 ndx = 0u; ndx < VK_DESCRIPTOR_TYPE_LAST; ++ndx)
+		{
+			pCreateInfo.pBindings = &descriptorSetLayoutBinding[ndx];
+			m_context.getDeviceInterface().getDescriptorSetLayoutSupport(m_context.getDevice(), &pCreateInfo, &pSupport);
+
+			if(extraLimitCheck(descriptorSetLayoutBinding, ndx, pCreateInfo.bindingCount, prop1))
+			{
+				if (pSupport.supported == VK_FALSE)
+					return tcu::TestStatus::fail("fail");
+			}
+		}
+
+		// check for accumulated descriptors (all eleven types)
+
+		pCreateInfo.pBindings = &descriptorSetLayoutBinding[0u];
+		pCreateInfo.bindingCount = static_cast<deUint32>(VK_DESCRIPTOR_TYPE_LAST);
+
+		deUint32 fraction = mainProp3.maxPerSetDescriptors / static_cast<deUint32>(VK_DESCRIPTOR_TYPE_LAST);
+		deUint32 rest = mainProp3.maxPerSetDescriptors % static_cast<deUint32>(VK_DESCRIPTOR_TYPE_LAST);
+
+		for (deUint32 ndx = 0u; ndx < VK_DESCRIPTOR_TYPE_LAST; ++ndx)
+			descriptorSetLayoutBinding[ndx].descriptorCount = fraction;
+		descriptorSetLayoutBinding[0u].descriptorCount += rest;
+
+		m_context.getDeviceInterface().getDescriptorSetLayoutSupport(m_context.getDevice(), &pCreateInfo, &pSupport);
+
+		if (extraLimitCheck(descriptorSetLayoutBinding, 0u, pCreateInfo.bindingCount, prop1))
+		{
+			if (pSupport.supported == VK_FALSE)
+				return tcu::TestStatus::fail("fail");
+		}
+
+		return tcu::TestStatus::pass("Pass");
+	}
+
+private:
+	bool									extraLimitCheck							(const VkDescriptorSetLayoutBinding* descriptorSetLayoutBinding, const deUint32& curNdx, const deUint32& size, const DevProp1& prop1)
+	{
+		deUint32							maxPerStageDescriptorSamplers			= 0u;
+		deUint32							maxPerStageDescriptorUniformBuffers		= 0u;
+		deUint32							maxPerStageDescriptorStorageBuffers		= 0u;
+		deUint32							maxPerStageDescriptorSampledImages		= 0u;
+		deUint32							maxPerStageDescriptorStorageImages		= 0u;
+
+		for(deUint32 ndx = curNdx; ndx < curNdx + size; ++ndx)
+		{
+			if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
+				(descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER))
+				maxPerStageDescriptorSamplers += descriptorSetLayoutBinding->descriptorCount;
+
+			if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
+					(descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC))
+				maxPerStageDescriptorUniformBuffers += descriptorSetLayoutBinding->descriptorCount;
+
+			if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
+					(descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC))
+				maxPerStageDescriptorStorageBuffers += descriptorSetLayoutBinding->descriptorCount;
+
+			if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)	||
+					(descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)		||
+					(descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER))
+				maxPerStageDescriptorSampledImages += descriptorSetLayoutBinding->descriptorCount;
+
+			if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
+					(descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER))
+				maxPerStageDescriptorStorageImages += descriptorSetLayoutBinding->descriptorCount;
+		}
+
+		if (prop1.limits.maxPerStageDescriptorSamplers < maxPerStageDescriptorSamplers)
+			return false;
+		if (prop1.limits.maxPerStageDescriptorUniformBuffers < maxPerStageDescriptorUniformBuffers)
+			return false;
+		if (prop1.limits.maxPerStageDescriptorStorageBuffers < maxPerStageDescriptorStorageBuffers)
+			return false;
+		if (prop1.limits.maxPerStageDescriptorSampledImages < maxPerStageDescriptorSampledImages)
+			return false;
+		if (prop1.limits.maxPerStageDescriptorStorageBuffers < maxPerStageDescriptorStorageBuffers)
+			return false;
+
+		return true;
+	}
+};
+
+class Maintenance3DescriptorTestCase : public TestCase
+{
+
+public:
+											Maintenance3DescriptorTestCase			(tcu::TestContext&	testCtx)
+												: TestCase(testCtx, "descriptor_set", "tests vkGetDescriptorSetLayoutSupport struct")
+	{}
+	virtual									~Maintenance3DescriptorTestCase			(void)
+	{}
+	virtual TestInstance*					createInstance							(Context&	ctx) const
+	{
+		return new Maintenance3DescriptorTestInstance(ctx);
+	}
+
+private:
+};
+
+} // 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
diff --git a/external/vulkancts/modules/vulkan/api/vktApiMaintenance3Check.hpp b/external/vulkancts/modules/vulkan/api/vktApiMaintenance3Check.hpp
new file mode 100644
index 0000000..f43fb24
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/api/vktApiMaintenance3Check.hpp
@@ -0,0 +1,43 @@
+#ifndef _VKTAPIMAINTENANCE3CHECK_HPP
+#define _VKTAPIMAINTENANCE3CHECK_HPP
+/*-------------------------------------------------------------------------
+* 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 Version Check test - checks structs and function from VK_KHR_maintenance3
+*//*--------------------------------------------------------------------*/
+
+namespace tcu
+{
+	class TestCaseGroup;
+	class TestContext;
+}
+
+namespace vkt
+{
+
+namespace api
+{
+
+	tcu::TestCaseGroup*	createMaintenance3Tests	(tcu::TestContext& testCtx);
+
+} // api
+} // vkt
+
+#endif // _VKTAPIMAINTENANCE3CHECK_HPP
diff --git a/external/vulkancts/modules/vulkan/api/vktApiTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiTests.cpp
index b57e672..88a70f8 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiTests.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiTests.cpp
@@ -41,6 +41,7 @@
 #include "vktApiGetMemoryCommitment.hpp"
 #include "vktApiExternalMemoryTests.hpp"
 #include "vktApiVersionCheck.hpp"
+#include "vktApiMaintenance3Check.hpp"
 
 namespace vkt
 {
@@ -78,6 +79,7 @@
 	apiTests->addChild(createGranularityQueryTests		(testCtx));
 	apiTests->addChild(createMemoryCommitmentTests		(testCtx));
 	apiTests->addChild(createExternalMemoryTests		(testCtx));
+	apiTests->addChild(createMaintenance3Tests			(testCtx));
 }
 
 } // anonymous
diff --git a/external/vulkancts/mustpass/1.1.0/vk-default.txt b/external/vulkancts/mustpass/1.1.0/vk-default.txt
index d65642b..13bd952 100755
--- a/external/vulkancts/mustpass/1.1.0/vk-default.txt
+++ b/external/vulkancts/mustpass/1.1.0/vk-default.txt
@@ -71423,6 +71423,8 @@
 dEQP-VK.api.external.fence.opaque_win32_kmt.signal_wait_import_permanent
 dEQP-VK.api.external.fence.opaque_win32_kmt.export_signal_import_wait_permanent
 dEQP-VK.api.external.fence.opaque_win32_kmt.export_import_signal_wait_permanent
+dEQP-VK.api.maintenance3_check.maintenance3_properties
+dEQP-VK.api.maintenance3_check.descriptor_set
 dEQP-VK.memory.allocation.basic.size_64.forward.count_1
 dEQP-VK.memory.allocation.basic.size_64.forward.count_10
 dEQP-VK.memory.allocation.basic.size_64.forward.count_100
diff --git a/external/vulkancts/scripts/src/vulkan.h.in b/external/vulkancts/scripts/src/vulkan.h.in
index 1a7d6ed..23ddaa5 100644
--- a/external/vulkancts/scripts/src/vulkan.h.in
+++ b/external/vulkancts/scripts/src/vulkan.h.in
@@ -5986,6 +5986,7 @@
 #define VK_KHR_MAINTENANCE3_EXTENSION_NAME "VK_KHR_maintenance3"
 #define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES
 #define VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT
+//VK_KHR_maintenance3 DEVICE 1_1_0
 
 typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSupportKHR)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport);