From 1249ada986fc62a95439b8c8ec805fd3dff1e46d Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Mon, 24 Feb 2020 15:08:18 +0000 Subject: [PATCH] Vulkan: Load promoted extensions or core entrypoint as needed Previously we would always assume that if the driver supported a Vulkan version it would also support extensions that were promoted in that version. This is not a spec requirement, so instead try to load the core entrypoints, and only if the version is not available, load the extension entrypoints. Also renames VulkanFunction members that are from promoted extension to not have a vendor prefix. Also tag the promoted extensions that are the same in a core version as available when that core version is available. This simplifies checking for features in the Vulkan backend. Bug: Change-Id: I0817c01b8838ba26070858abb0cbed030e3291df Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/16040 Commit-Queue: Corentin Wallez Reviewed-by: David Turner --- src/dawn_native/vulkan/AdapterVk.cpp | 3 +- src/dawn_native/vulkan/BackendVk.cpp | 39 ++++++++------ src/dawn_native/vulkan/VulkanFunctions.cpp | 53 ++++++++++++------- src/dawn_native/vulkan/VulkanFunctions.h | 31 +++++------ src/dawn_native/vulkan/VulkanInfo.cpp | 6 +++ src/dawn_native/vulkan/VulkanInfo.h | 2 +- .../external_memory/MemoryServiceDmaBuf.cpp | 9 ++-- .../external_memory/MemoryServiceOpaqueFD.cpp | 6 +-- .../MemoryServiceZirconHandle.cpp | 2 +- .../SemaphoreServiceOpaqueFD.cpp | 2 +- .../SemaphoreServiceZirconHandle.cpp | 2 +- 11 files changed, 90 insertions(+), 65 deletions(-) diff --git a/src/dawn_native/vulkan/AdapterVk.cpp b/src/dawn_native/vulkan/AdapterVk.cpp index 004ba23e0b..14c5b27ef3 100644 --- a/src/dawn_native/vulkan/AdapterVk.cpp +++ b/src/dawn_native/vulkan/AdapterVk.cpp @@ -39,8 +39,7 @@ namespace dawn_native { namespace vulkan { MaybeError Adapter::Initialize() { DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this)); - if (!mDeviceInfo.maintenance1 && - mDeviceInfo.properties.apiVersion < VK_MAKE_VERSION(1, 1, 0)) { + if (!mDeviceInfo.maintenance1) { return DAWN_DEVICE_LOST_ERROR( "Dawn requires Vulkan 1.1 or Vulkan 1.0 with KHR_Maintenance1 in order to support " "viewport flipY"); diff --git a/src/dawn_native/vulkan/BackendVk.cpp b/src/dawn_native/vulkan/BackendVk.cpp index d2745cb5e5..ab797df8ab 100644 --- a/src/dawn_native/vulkan/BackendVk.cpp +++ b/src/dawn_native/vulkan/BackendVk.cpp @@ -190,29 +190,16 @@ namespace dawn_native { namespace vulkan { } } + // Always request all extensions used to create VkSurfaceKHR objects so that they are + // always available for embedders looking to create VkSurfaceKHR on our VkInstance. if (mGlobalInfo.fuchsiaImagePipeSwapchain) { layersToRequest.push_back(kLayerNameFuchsiaImagePipeSwapchain); usedKnobs.fuchsiaImagePipeSwapchain = true; } - - // Always request all extensions used to create VkSurfaceKHR objects so that they are - // always available for embedders looking to create VkSurfaceKHR on our VkInstance. if (mGlobalInfo.macosSurface) { extensionsToRequest.push_back(kExtensionNameMvkMacosSurface); usedKnobs.macosSurface = true; } - if (mGlobalInfo.externalMemoryCapabilities) { - extensionsToRequest.push_back(kExtensionNameKhrExternalMemoryCapabilities); - usedKnobs.externalMemoryCapabilities = true; - } - if (mGlobalInfo.externalSemaphoreCapabilities) { - extensionsToRequest.push_back(kExtensionNameKhrExternalSemaphoreCapabilities); - usedKnobs.externalSemaphoreCapabilities = true; - } - if (mGlobalInfo.getPhysicalDeviceProperties2) { - extensionsToRequest.push_back(kExtensionNameKhrGetPhysicalDeviceProperties2); - usedKnobs.getPhysicalDeviceProperties2 = true; - } if (mGlobalInfo.surface) { extensionsToRequest.push_back(kExtensionNameKhrSurface); usedKnobs.surface = true; @@ -238,6 +225,28 @@ namespace dawn_native { namespace vulkan { usedKnobs.fuchsiaImagePipeSurface = true; } + // Mark the promoted extensions as present if the core version in which they were promoted + // is used. This allows having a single boolean that checks if the functionality from that + // extension is available (instead of checking extension || coreVersion). + if (mGlobalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) { + usedKnobs.getPhysicalDeviceProperties2 = true; + usedKnobs.externalMemoryCapabilities = true; + usedKnobs.externalSemaphoreCapabilities = true; + } else { + if (mGlobalInfo.externalMemoryCapabilities) { + extensionsToRequest.push_back(kExtensionNameKhrExternalMemoryCapabilities); + usedKnobs.externalMemoryCapabilities = true; + } + if (mGlobalInfo.externalSemaphoreCapabilities) { + extensionsToRequest.push_back(kExtensionNameKhrExternalSemaphoreCapabilities); + usedKnobs.externalSemaphoreCapabilities = true; + } + if (mGlobalInfo.getPhysicalDeviceProperties2) { + extensionsToRequest.push_back(kExtensionNameKhrGetPhysicalDeviceProperties2); + usedKnobs.getPhysicalDeviceProperties2 = true; + } + } + VkApplicationInfo appInfo; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pNext = nullptr; diff --git a/src/dawn_native/vulkan/VulkanFunctions.cpp b/src/dawn_native/vulkan/VulkanFunctions.cpp index 5cec83a2b9..5d17fae398 100644 --- a/src/dawn_native/vulkan/VulkanFunctions.cpp +++ b/src/dawn_native/vulkan/VulkanFunctions.cpp @@ -41,12 +41,15 @@ namespace dawn_native { namespace vulkan { return {}; } -#define GET_INSTANCE_PROC(name) \ - name = reinterpret_cast(GetInstanceProcAddr(instance, "vk" #name)); \ - if (name == nullptr) { \ - return DAWN_DEVICE_LOST_ERROR(std::string("Couldn't get proc vk") + #name); \ +#define GET_INSTANCE_PROC_BASE(name, procName) \ + name = reinterpret_cast(GetInstanceProcAddr(instance, "vk" #procName)); \ + if (name == nullptr) { \ + return DAWN_DEVICE_LOST_ERROR(std::string("Couldn't get proc vk") + #procName); \ } +#define GET_INSTANCE_PROC(name) GET_INSTANCE_PROC_BASE(name, name) +#define GET_INSTANCE_PROC_VENDOR(name, vendor) GET_INSTANCE_PROC_BASE(name, name##vendor) + MaybeError VulkanFunctions::LoadInstanceProcs(VkInstance instance, const VulkanGlobalInfo& globalInfo) { // Load this proc first so that we can destroy the instance even if some other @@ -73,26 +76,36 @@ namespace dawn_native { namespace vulkan { GET_INSTANCE_PROC(DestroyDebugReportCallbackEXT); } - // Vulkan 1.1 is not required to report promoted extensions from 1.0 - if (globalInfo.externalMemoryCapabilities || - globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) { - GET_INSTANCE_PROC(GetPhysicalDeviceExternalBufferPropertiesKHR); + // Vulkan 1.1 is not required to report promoted extensions from 1.0 and is not required to + // support the vendor entrypoint in GetProcAddress. + if (globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) { + GET_INSTANCE_PROC(GetPhysicalDeviceExternalBufferProperties); + } else if (globalInfo.externalMemoryCapabilities) { + GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceExternalBufferProperties, KHR); } - if (globalInfo.externalSemaphoreCapabilities || - globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) { - GET_INSTANCE_PROC(GetPhysicalDeviceExternalSemaphorePropertiesKHR); + if (globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) { + GET_INSTANCE_PROC(GetPhysicalDeviceExternalSemaphoreProperties); + } else if (globalInfo.externalSemaphoreCapabilities) { + GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceExternalSemaphoreProperties, KHR); } - if (globalInfo.getPhysicalDeviceProperties2 || - globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) { - GET_INSTANCE_PROC(GetPhysicalDeviceFeatures2KHR); - GET_INSTANCE_PROC(GetPhysicalDeviceProperties2KHR); - GET_INSTANCE_PROC(GetPhysicalDeviceFormatProperties2KHR); - GET_INSTANCE_PROC(GetPhysicalDeviceImageFormatProperties2KHR); - GET_INSTANCE_PROC(GetPhysicalDeviceQueueFamilyProperties2KHR); - GET_INSTANCE_PROC(GetPhysicalDeviceMemoryProperties2KHR); - GET_INSTANCE_PROC(GetPhysicalDeviceSparseImageFormatProperties2KHR); + if (globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) { + GET_INSTANCE_PROC(GetPhysicalDeviceFeatures2); + GET_INSTANCE_PROC(GetPhysicalDeviceProperties2); + GET_INSTANCE_PROC(GetPhysicalDeviceFormatProperties2); + GET_INSTANCE_PROC(GetPhysicalDeviceImageFormatProperties2); + GET_INSTANCE_PROC(GetPhysicalDeviceQueueFamilyProperties2); + GET_INSTANCE_PROC(GetPhysicalDeviceMemoryProperties2); + GET_INSTANCE_PROC(GetPhysicalDeviceSparseImageFormatProperties2); + } else if (globalInfo.getPhysicalDeviceProperties2) { + GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceFeatures2, KHR); + GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceProperties2, KHR); + GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceFormatProperties2, KHR); + GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceImageFormatProperties2, KHR); + GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceQueueFamilyProperties2, KHR); + GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceMemoryProperties2, KHR); + GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceSparseImageFormatProperties2, KHR); } if (globalInfo.surface) { diff --git a/src/dawn_native/vulkan/VulkanFunctions.h b/src/dawn_native/vulkan/VulkanFunctions.h index cb6960c049..e59ac09ad6 100644 --- a/src/dawn_native/vulkan/VulkanFunctions.h +++ b/src/dawn_native/vulkan/VulkanFunctions.h @@ -84,27 +84,28 @@ namespace dawn_native { namespace vulkan { PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR = nullptr; - // Core Vulkan 1.1 promoted extensions + // Core Vulkan 1.1 promoted extensions, set if either the core version or the extension is + // present. // VK_KHR_external_memory_capabilities - PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR - GetPhysicalDeviceExternalBufferPropertiesKHR = nullptr; + PFN_vkGetPhysicalDeviceExternalBufferProperties GetPhysicalDeviceExternalBufferProperties = + nullptr; // VK_KHR_external_semaphore_capabilities - PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR - GetPhysicalDeviceExternalSemaphorePropertiesKHR = nullptr; + PFN_vkGetPhysicalDeviceExternalSemaphoreProperties + GetPhysicalDeviceExternalSemaphoreProperties = nullptr; // VK_KHR_get_physical_device_properties2 - PFN_vkGetPhysicalDeviceFeatures2KHR GetPhysicalDeviceFeatures2KHR = nullptr; - PFN_vkGetPhysicalDeviceProperties2KHR GetPhysicalDeviceProperties2KHR = nullptr; - PFN_vkGetPhysicalDeviceFormatProperties2KHR GetPhysicalDeviceFormatProperties2KHR = nullptr; - PFN_vkGetPhysicalDeviceImageFormatProperties2KHR - GetPhysicalDeviceImageFormatProperties2KHR = nullptr; - PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR - GetPhysicalDeviceQueueFamilyProperties2KHR = nullptr; - PFN_vkGetPhysicalDeviceMemoryProperties2KHR GetPhysicalDeviceMemoryProperties2KHR = nullptr; - PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR - GetPhysicalDeviceSparseImageFormatProperties2KHR = nullptr; + PFN_vkGetPhysicalDeviceFeatures2 GetPhysicalDeviceFeatures2 = nullptr; + PFN_vkGetPhysicalDeviceProperties2 GetPhysicalDeviceProperties2 = nullptr; + PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysicalDeviceFormatProperties2 = nullptr; + PFN_vkGetPhysicalDeviceImageFormatProperties2 GetPhysicalDeviceImageFormatProperties2 = + nullptr; + PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysicalDeviceQueueFamilyProperties2 = + nullptr; + PFN_vkGetPhysicalDeviceMemoryProperties2 GetPhysicalDeviceMemoryProperties2 = nullptr; + PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 + GetPhysicalDeviceSparseImageFormatProperties2 = nullptr; #ifdef VK_USE_PLATFORM_FUCHSIA // FUCHSIA_image_pipe_surface diff --git a/src/dawn_native/vulkan/VulkanInfo.cpp b/src/dawn_native/vulkan/VulkanInfo.cpp index 0ac551422f..9bc68ee0cb 100644 --- a/src/dawn_native/vulkan/VulkanInfo.cpp +++ b/src/dawn_native/vulkan/VulkanInfo.cpp @@ -14,6 +14,7 @@ #include "dawn_native/vulkan/VulkanInfo.h" +#include "common/Log.h" #include "dawn_native/vulkan/AdapterVk.h" #include "dawn_native/vulkan/BackendVk.h" #include "dawn_native/vulkan/VulkanError.h" @@ -313,6 +314,11 @@ namespace dawn_native { namespace vulkan { } } + // Mark the extensions promoted to Vulkan 1.1 as available. + if (info.properties.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) { + info.maintenance1 = true; + } + // TODO(cwallez@chromium.org): gather info about formats return info; diff --git a/src/dawn_native/vulkan/VulkanInfo.h b/src/dawn_native/vulkan/VulkanInfo.h index ac64af0b4f..13a0fdd270 100644 --- a/src/dawn_native/vulkan/VulkanInfo.h +++ b/src/dawn_native/vulkan/VulkanInfo.h @@ -86,7 +86,7 @@ namespace dawn_native { namespace vulkan { struct VulkanDeviceKnobs { VkPhysicalDeviceFeatures features; - // Extensions + // Extensions, promoted extensions are set to true if their core version is supported. bool debugMarker = false; bool externalMemory = false; bool externalMemoryFD = false; diff --git a/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp b/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp index ea84d5edc4..7c5c82da02 100644 --- a/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp +++ b/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp @@ -41,13 +41,13 @@ namespace dawn_native { namespace vulkan { namespace external_memory { formatProps.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; formatProps.pNext = &formatModifierPropsList; - fn.GetPhysicalDeviceFormatProperties2KHR(physicalDevice, format, &formatProps); + fn.GetPhysicalDeviceFormatProperties2(physicalDevice, format, &formatProps); uint32_t modifierCount = formatModifierPropsList.drmFormatModifierCount; std::vector formatModifierProps(modifierCount); formatModifierPropsList.pDrmFormatModifierProperties = formatModifierProps.data(); - fn.GetPhysicalDeviceFormatProperties2KHR(physicalDevice, format, &formatProps); + fn.GetPhysicalDeviceFormatProperties2(physicalDevice, format, &formatProps); for (const auto& props : formatModifierProps) { if (props.drmFormatModifier == modifier) { uint32_t count = props.drmFormatModifierPlaneCount; @@ -141,9 +141,8 @@ namespace dawn_native { namespace vulkan { namespace external_memory { imageFormatProps.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2; imageFormatProps.pNext = &externalImageFormatProps; - VkResult result = - VkResult::WrapUnsafe(mDevice->fn.GetPhysicalDeviceImageFormatProperties2KHR( - physicalDevice, &imageFormatInfo, &imageFormatProps)); + VkResult result = VkResult::WrapUnsafe(mDevice->fn.GetPhysicalDeviceImageFormatProperties2( + physicalDevice, &imageFormatInfo, &imageFormatProps)); if (result != VK_SUCCESS) { return false; } diff --git a/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp b/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp index a8bc1819dd..872432410a 100644 --- a/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp +++ b/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp @@ -66,10 +66,8 @@ namespace dawn_native { namespace vulkan { namespace external_memory { formatProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR; formatProperties.pNext = &externalFormatProperties; - VkResult result = - VkResult::WrapUnsafe(mDevice->fn.GetPhysicalDeviceImageFormatProperties2KHR( - ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &formatInfo, - &formatProperties)); + VkResult result = VkResult::WrapUnsafe(mDevice->fn.GetPhysicalDeviceImageFormatProperties2( + ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &formatInfo, &formatProperties)); // If handle not supported, result == VK_ERROR_FORMAT_NOT_SUPPORTED if (result != VK_SUCCESS) { diff --git a/src/dawn_native/vulkan/external_memory/MemoryServiceZirconHandle.cpp b/src/dawn_native/vulkan/external_memory/MemoryServiceZirconHandle.cpp index 09a5b71e69..10b99555e5 100644 --- a/src/dawn_native/vulkan/external_memory/MemoryServiceZirconHandle.cpp +++ b/src/dawn_native/vulkan/external_memory/MemoryServiceZirconHandle.cpp @@ -66,7 +66,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory { formatProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR; formatProperties.pNext = &externalFormatProperties; - VkResult result = mDevice->fn.GetPhysicalDeviceImageFormatProperties2KHR( + VkResult result = mDevice->fn.GetPhysicalDeviceImageFormatProperties2( ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &formatInfo, &formatProperties); // If handle not supported, result == VK_ERROR_FORMAT_NOT_SUPPORTED diff --git a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp index 3e1d3f0141..e79288a996 100644 --- a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp +++ b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp @@ -43,7 +43,7 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore { semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR; semaphoreProperties.pNext = nullptr; - mDevice->fn.GetPhysicalDeviceExternalSemaphorePropertiesKHR( + mDevice->fn.GetPhysicalDeviceExternalSemaphoreProperties( ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &semaphoreInfo, &semaphoreProperties); diff --git a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp index 5ea53f7545..fd10076e9e 100644 --- a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp +++ b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp @@ -43,7 +43,7 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore { semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR; semaphoreProperties.pNext = nullptr; - mDevice->fn.GetPhysicalDeviceExternalSemaphorePropertiesKHR( + mDevice->fn.GetPhysicalDeviceExternalSemaphoreProperties( ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &semaphoreInfo, &semaphoreProperties);