From 1d8ab38ce55f8b013ed42ca7b7af80cd7a297c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 23 Oct 2022 22:05:33 +0200 Subject: [PATCH] Vulkan: Use v2 feature checks, and add check for multiview features. Extracted from the multiview PR, and renamed some stuff. --- Common/GPU/Vulkan/VulkanContext.cpp | 41 +++++++++++++++++++++-------- Common/GPU/Vulkan/VulkanContext.h | 9 +++++-- Common/GPU/Vulkan/thin3d_vulkan.cpp | 25 ++++++++++-------- GPU/Vulkan/GPU_Vulkan.cpp | 6 ++--- 4 files changed, 54 insertions(+), 27 deletions(-) diff --git a/Common/GPU/Vulkan/VulkanContext.cpp b/Common/GPU/Vulkan/VulkanContext.cpp index 937276d10f..a3bbf1f0ea 100644 --- a/Common/GPU/Vulkan/VulkanContext.cpp +++ b/Common/GPU/Vulkan/VulkanContext.cpp @@ -585,22 +585,32 @@ void VulkanContext::ChooseDevice(int physical_device) { // Optional features if (extensionsLookup_.KHR_get_physical_device_properties2) { VkPhysicalDeviceFeatures2 features2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR}; + // Add to chain even if not supported, GetPhysicalDeviceFeatures is supposed to ignore unknown structs. + VkPhysicalDeviceMultiviewFeatures multiViewFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES }; + features2.pNext = &multiViewFeatures; vkGetPhysicalDeviceFeatures2KHR(physical_devices_[physical_device_], &features2); - deviceFeatures_.available = features2.features; + deviceFeatures_.available.standard = features2.features; + deviceFeatures_.available.multiview = multiViewFeatures; } else { - vkGetPhysicalDeviceFeatures(physical_devices_[physical_device_], &deviceFeatures_.available); + vkGetPhysicalDeviceFeatures(physical_devices_[physical_device_], &deviceFeatures_.available.standard); + deviceFeatures_.available.multiview = {}; } deviceFeatures_.enabled = {}; // Enable a few safe ones if they are available. - deviceFeatures_.enabled.dualSrcBlend = deviceFeatures_.available.dualSrcBlend; - deviceFeatures_.enabled.logicOp = deviceFeatures_.available.logicOp; - deviceFeatures_.enabled.depthClamp = deviceFeatures_.available.depthClamp; - deviceFeatures_.enabled.depthBounds = deviceFeatures_.available.depthBounds; - deviceFeatures_.enabled.samplerAnisotropy = deviceFeatures_.available.samplerAnisotropy; - deviceFeatures_.enabled.shaderClipDistance = deviceFeatures_.available.shaderClipDistance; - deviceFeatures_.enabled.shaderCullDistance = deviceFeatures_.available.shaderCullDistance; - deviceFeatures_.enabled.geometryShader = deviceFeatures_.available.geometryShader; + deviceFeatures_.enabled.standard.dualSrcBlend = deviceFeatures_.available.standard.dualSrcBlend; + deviceFeatures_.enabled.standard.logicOp = deviceFeatures_.available.standard.logicOp; + deviceFeatures_.enabled.standard.depthClamp = deviceFeatures_.available.standard.depthClamp; + deviceFeatures_.enabled.standard.depthBounds = deviceFeatures_.available.standard.depthBounds; + deviceFeatures_.enabled.standard.samplerAnisotropy = deviceFeatures_.available.standard.samplerAnisotropy; + deviceFeatures_.enabled.standard.shaderClipDistance = deviceFeatures_.available.standard.shaderClipDistance; + deviceFeatures_.enabled.standard.shaderCullDistance = deviceFeatures_.available.standard.shaderCullDistance; + deviceFeatures_.enabled.standard.geometryShader = deviceFeatures_.available.standard.geometryShader; + + deviceFeatures_.enabled.multiview = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES }; + // Don't yet enable these. + // deviceFeatures_.enabled.multiview.multiview = deviceFeatures_.available.multiview.multiview; + // deviceFeatures_.enabled.multiview.multiviewGeometryShader = deviceFeatures_.available.multiview.multiviewGeometryShader; GetDeviceLayerExtensionList(nullptr, device_extension_properties_); @@ -671,6 +681,8 @@ VkResult VulkanContext::CreateDevice() { extensionsLookup_.EXT_fragment_shader_interlock = EnableDeviceExtension(VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME); extensionsLookup_.ARM_rasterization_order_attachment_access = EnableDeviceExtension(VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME); + VkPhysicalDeviceFeatures2 features2{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 }; + VkDeviceCreateInfo device_info{ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO }; device_info.queueCreateInfoCount = 1; device_info.pQueueCreateInfos = &queue_info; @@ -678,7 +690,14 @@ VkResult VulkanContext::CreateDevice() { device_info.ppEnabledLayerNames = device_info.enabledLayerCount ? device_layer_names_.data() : nullptr; device_info.enabledExtensionCount = (uint32_t)device_extensions_enabled_.size(); device_info.ppEnabledExtensionNames = device_info.enabledExtensionCount ? device_extensions_enabled_.data() : nullptr; - device_info.pEnabledFeatures = &deviceFeatures_.enabled; + + if (extensionsLookup_.KHR_get_physical_device_properties2) { + device_info.pNext = &features2; + features2.features = deviceFeatures_.enabled.standard; + features2.pNext = &deviceFeatures_.enabled.multiview; + } else { + device_info.pEnabledFeatures = &deviceFeatures_.enabled.standard; + } VkResult res = vkCreateDevice(physical_devices_[physical_device_], &device_info, nullptr, &device_); if (res != VK_SUCCESS) { diff --git a/Common/GPU/Vulkan/VulkanContext.h b/Common/GPU/Vulkan/VulkanContext.h index fb98b5a0db..60ef6d373e 100644 --- a/Common/GPU/Vulkan/VulkanContext.h +++ b/Common/GPU/Vulkan/VulkanContext.h @@ -252,6 +252,11 @@ public: VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalMemoryHostProperties; }; + struct AllPhysicalDeviceFeatures { + VkPhysicalDeviceFeatures standard; + VkPhysicalDeviceMultiviewFeatures multiview; + }; + const PhysicalDeviceProps &GetPhysicalDeviceProperties(int i = -1) const { if (i < 0) i = GetCurrentPhysicalDeviceIndex(); @@ -276,8 +281,8 @@ public: } struct PhysicalDeviceFeatures { - VkPhysicalDeviceFeatures available{}; - VkPhysicalDeviceFeatures enabled{}; + AllPhysicalDeviceFeatures available{}; + AllPhysicalDeviceFeatures enabled{}; }; const PhysicalDeviceFeatures &GetDeviceFeatures() const { return deviceFeatures_; } diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index adfe90d14c..cedb21b49f 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -777,14 +777,14 @@ VKContext::VKContext(VulkanContext *vulkan) VkFormat depthStencilFormat = vulkan->GetDeviceInfo().preferredDepthStencilFormat; - caps_.anisoSupported = vulkan->GetDeviceFeatures().enabled.samplerAnisotropy != 0; - caps_.geometryShaderSupported = vulkan->GetDeviceFeatures().enabled.geometryShader != 0; - caps_.tesselationShaderSupported = vulkan->GetDeviceFeatures().enabled.tessellationShader != 0; - caps_.multiViewport = vulkan->GetDeviceFeatures().enabled.multiViewport != 0; - caps_.dualSourceBlend = vulkan->GetDeviceFeatures().enabled.dualSrcBlend != 0; - caps_.depthClampSupported = vulkan->GetDeviceFeatures().enabled.depthClamp != 0; - caps_.clipDistanceSupported = vulkan->GetDeviceFeatures().enabled.shaderClipDistance != 0; - caps_.cullDistanceSupported = vulkan->GetDeviceFeatures().enabled.shaderCullDistance != 0; + caps_.anisoSupported = vulkan->GetDeviceFeatures().enabled.standard.samplerAnisotropy != 0; + caps_.geometryShaderSupported = vulkan->GetDeviceFeatures().enabled.standard.geometryShader != 0; + caps_.tesselationShaderSupported = vulkan->GetDeviceFeatures().enabled.standard.tessellationShader != 0; + caps_.multiViewport = vulkan->GetDeviceFeatures().enabled.standard.multiViewport != 0; + caps_.dualSourceBlend = vulkan->GetDeviceFeatures().enabled.standard.dualSrcBlend != 0; + caps_.depthClampSupported = vulkan->GetDeviceFeatures().enabled.standard.depthClamp != 0; + caps_.clipDistanceSupported = vulkan->GetDeviceFeatures().enabled.standard.shaderClipDistance != 0; + caps_.cullDistanceSupported = vulkan->GetDeviceFeatures().enabled.standard.shaderCullDistance != 0; caps_.framebufferBlitSupported = true; caps_.framebufferCopySupported = true; caps_.framebufferDepthBlitSupported = vulkan->GetDeviceInfo().canBlitToPreferredDepthStencilFormat; @@ -798,7 +798,7 @@ VKContext::VKContext(VulkanContext *vulkan) caps_.textureNPOTFullySupported = true; caps_.fragmentShaderDepthWriteSupported = true; caps_.blendMinMaxSupported = true; - caps_.logicOpSupported = vulkan->GetDeviceFeatures().enabled.logicOp != 0; + caps_.logicOpSupported = vulkan->GetDeviceFeatures().enabled.standard.logicOp != 0; auto deviceProps = vulkan->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDeviceIndex()).properties; @@ -1414,8 +1414,8 @@ void AddFeature(std::vector &features, const char *name, VkBool32 a } std::vector VKContext::GetFeatureList() const { - const VkPhysicalDeviceFeatures &available = vulkan_->GetDeviceFeatures().available; - const VkPhysicalDeviceFeatures &enabled = vulkan_->GetDeviceFeatures().enabled; + const VkPhysicalDeviceFeatures &available = vulkan_->GetDeviceFeatures().available.standard; + const VkPhysicalDeviceFeatures &enabled = vulkan_->GetDeviceFeatures().enabled.standard; std::vector features; AddFeature(features, "dualSrcBlend", available.dualSrcBlend, enabled.dualSrcBlend); @@ -1434,6 +1434,9 @@ std::vector VKContext::GetFeatureList() const { AddFeature(features, "occlusionQueryPrecise", available.occlusionQueryPrecise, enabled.occlusionQueryPrecise); AddFeature(features, "multiDrawIndirect", available.multiDrawIndirect, enabled.multiDrawIndirect); + AddFeature(features, "multiview", vulkan_->GetDeviceFeatures().available.multiview.multiview, vulkan_->GetDeviceFeatures().enabled.multiview.multiview); + AddFeature(features, "multiviewGeometryShader", vulkan_->GetDeviceFeatures().available.multiview.multiviewGeometryShader, vulkan_->GetDeviceFeatures().enabled.multiview.multiviewGeometryShader); + features.emplace_back(std::string("Preferred depth buffer format: ") + VulkanFormatToString(vulkan_->GetDeviceInfo().preferredDepthStencilFormat)); return features; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index fbc31a90e3..c46b8b2812 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -227,7 +227,7 @@ u32 GPU_Vulkan::CheckGPUFeatures() const { features |= GPU_USE_VERTEX_TEXTURE_FETCH; features |= GPU_USE_TEXTURE_FLOAT; - auto &enabledFeatures = vulkan->GetDeviceFeatures().enabled; + auto &enabledFeatures = vulkan->GetDeviceFeatures().enabled.standard; if (enabledFeatures.depthClamp) { features |= GPU_USE_DEPTH_CLAMP; } @@ -325,9 +325,9 @@ void GPU_Vulkan::EndHostFrame() { void GPU_Vulkan::BuildReportingInfo() { VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); const auto &props = vulkan->GetPhysicalDeviceProperties().properties; - const auto &features = vulkan->GetDeviceFeatures().available; + const auto &available = vulkan->GetDeviceFeatures().available; -#define CHECK_BOOL_FEATURE(n) do { if (features.n) { featureNames += ", " #n; } } while (false) +#define CHECK_BOOL_FEATURE(n) do { if (available.standard.n) { featureNames += ", " #n; } } while (false) std::string featureNames = ""; CHECK_BOOL_FEATURE(robustBufferAccess);