Support querying for Vulkan11 properties

Vulkan 1.2 added VkPhysicalDeviceVulkan11Properties, which allows users
to query support for several other device properties all together. We
can use templated static functions to make sure these properties are
only ever set in one place, similar to what we do for device features.

The only struct this doesn't work for is
VkPhysicalDeviceSubgroupProperties, because the names in that struct
and the Vulkan11 struct differ. So the Vulkan11 struct manually copies
the data from the getProperties(*) function for the subgroup properties.

Bug: b/176248217
Change-Id: I30e9e05ecbdb9a40fc3a59df6bd9b8ab9022c9fc
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/51388
Tested-by: Sean Risser <srisser@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Commit-Queue: Sean Risser <srisser@google.com>
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp
index cd879c9..f09addf 100644
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -530,7 +530,8 @@
 	return properties;
 }
 
-void PhysicalDevice::getProperties(VkPhysicalDeviceIDProperties *properties) const
+template<typename T>
+static void getIdProperties(T *properties)
 {
 	memset(properties->deviceUUID, 0, VK_UUID_SIZE);
 	memset(properties->driverUUID, 0, VK_UUID_SIZE);
@@ -543,28 +544,57 @@
 	properties->deviceLUIDValid = VK_FALSE;
 }
 
-void PhysicalDevice::getProperties(VkPhysicalDeviceMaintenance3Properties *properties) const
+void PhysicalDevice::getProperties(VkPhysicalDeviceIDProperties *properties) const
+{
+	getIdProperties(properties);
+}
+
+template<typename T>
+static void getMaintenance3Properties(T *properties)
 {
 	properties->maxMemoryAllocationSize = MAX_MEMORY_ALLOCATION_SIZE;
 	properties->maxPerSetDescriptors = 1024;
 }
 
-void PhysicalDevice::getProperties(VkPhysicalDeviceMultiviewProperties *properties) const
+void PhysicalDevice::getProperties(VkPhysicalDeviceMaintenance3Properties *properties) const
+{
+	getMaintenance3Properties(properties);
+}
+
+template<typename T>
+static void getMultiviewProperties(T *properties)
 {
 	properties->maxMultiviewViewCount = 6;
 	properties->maxMultiviewInstanceIndex = 1u << 27;
 }
 
-void PhysicalDevice::getProperties(VkPhysicalDevicePointClippingProperties *properties) const
+void PhysicalDevice::getProperties(VkPhysicalDeviceMultiviewProperties *properties) const
+{
+	getMultiviewProperties(properties);
+}
+
+template<typename T>
+static void getPointClippingProperties(T *properties)
 {
 	properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
 }
 
-void PhysicalDevice::getProperties(VkPhysicalDeviceProtectedMemoryProperties *properties) const
+void PhysicalDevice::getProperties(VkPhysicalDevicePointClippingProperties *properties) const
+{
+	getPointClippingProperties(properties);
+}
+
+template<typename T>
+static void getProtectedMemoryProperties(T *properties)
 {
 	properties->protectedNoFault = VK_FALSE;
 }
 
+void PhysicalDevice::getProperties(VkPhysicalDeviceProtectedMemoryProperties *properties) const
+{
+	getProtectedMemoryProperties(properties);
+}
+
 void PhysicalDevice::getProperties(VkPhysicalDeviceSubgroupProperties *properties) const
 {
 	properties->subgroupSize = sw::SIMD::Width;
@@ -579,6 +609,26 @@
 	properties->quadOperationsInAllStages = VK_FALSE;
 }
 
+void PhysicalDevice::getProperties(VkPhysicalDeviceVulkan11Properties *properties) const
+{
+	getIdProperties(properties);
+
+	// We can't use templated functions for Vulkan11 & subgroup properties. The names of the
+	// variables in VkPhysicalDeviceSubgroupProperties differ from the names in the Vulkan11
+	// struct.
+	VkPhysicalDeviceSubgroupProperties subgroupProperties = {};
+	getProperties(&subgroupProperties);
+	properties->subgroupSize = subgroupProperties.subgroupSize;
+	properties->subgroupSupportedStages = subgroupProperties.supportedStages;
+	properties->subgroupSupportedOperations = subgroupProperties.supportedOperations;
+	properties->subgroupQuadOperationsInAllStages = subgroupProperties.quadOperationsInAllStages;
+
+	getPointClippingProperties(properties);
+	getMultiviewProperties(properties);
+	getProtectedMemoryProperties(properties);
+	getMaintenance3Properties(properties);
+}
+
 void PhysicalDevice::getProperties(const VkExternalMemoryHandleTypeFlagBits *handleType, VkExternalImageFormatProperties *properties) const
 {
 	VkExternalMemoryProperties *extMemProperties = &properties->externalMemoryProperties;
diff --git a/src/Vulkan/VkPhysicalDevice.hpp b/src/Vulkan/VkPhysicalDevice.hpp
index 8ff2abd..525f742 100644
--- a/src/Vulkan/VkPhysicalDevice.hpp
+++ b/src/Vulkan/VkPhysicalDevice.hpp
@@ -65,6 +65,7 @@
 	void getProperties(VkPhysicalDeviceVulkan12Properties *properties) const;
 	void getProperties(VkPhysicalDeviceDescriptorIndexingProperties *properties) const;
 	void getProperties(VkPhysicalDeviceDepthStencilResolveProperties *properties) const;
+	void getProperties(VkPhysicalDeviceVulkan11Properties *properties) const;
 
 	static void GetFormatProperties(Format format, VkFormatProperties *pFormatProperties);
 	void getImageFormatProperties(Format format, VkImageType type, VkImageTiling tiling,
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index 7be1f7b..39c82f0 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -2999,6 +2999,12 @@
 				vk::Cast(physicalDevice)->getProperties(properties);
 			}
 			break;
+			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES:
+			{
+				auto properties = reinterpret_cast<VkPhysicalDeviceVulkan11Properties *>(extensionProperties);
+				vk::Cast(physicalDevice)->getProperties(properties);
+			}
+			break;
 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES:
 			{
 				auto properties = reinterpret_cast<VkPhysicalDeviceSamplerFilterMinmaxProperties *>(extensionProperties);