From 265fb062be9b61e8f5760fcf0e3ae8904c59742c Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Thu, 11 Jun 2020 17:35:26 +0000 Subject: [PATCH] Vulkan: handle Device extensions more programmatically Similarly to the CL for Instance extensions, it makes each device extension linked to an enum class and a bitset. Logic surrounding device extensions is changed to take advantage of this to be more programmatic and less error prone when adding support for a new extension. Bug: dawn:457 Change-Id: Iecf623c40b890b7e00ba972d5eac0712866692b5 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/22941 Reviewed-by: Corentin Wallez Commit-Queue: Corentin Wallez --- src/dawn_native/vulkan/AdapterVk.cpp | 6 +- src/dawn_native/vulkan/CommandBufferVk.cpp | 12 +- src/dawn_native/vulkan/DeviceVk.cpp | 79 +++------ src/dawn_native/vulkan/VulkanExtensions.cpp | 151 ++++++++++++++++++ src/dawn_native/vulkan/VulkanExtensions.h | 56 +++++++ src/dawn_native/vulkan/VulkanFunctions.cpp | 12 +- src/dawn_native/vulkan/VulkanInfo.cpp | 129 +++++---------- src/dawn_native/vulkan/VulkanInfo.h | 34 +--- .../external_memory/MemoryServiceDmaBuf.cpp | 8 +- .../external_memory/MemoryServiceOpaqueFD.cpp | 8 +- .../MemoryServiceZirconHandle.cpp | 8 +- .../SemaphoreServiceOpaqueFD.cpp | 8 +- .../SemaphoreServiceZirconHandle.cpp | 8 +- 13 files changed, 285 insertions(+), 234 deletions(-) diff --git a/src/dawn_native/vulkan/AdapterVk.cpp b/src/dawn_native/vulkan/AdapterVk.cpp index c220a8e937..43ed6acbc2 100644 --- a/src/dawn_native/vulkan/AdapterVk.cpp +++ b/src/dawn_native/vulkan/AdapterVk.cpp @@ -39,7 +39,7 @@ namespace dawn_native { namespace vulkan { MaybeError Adapter::Initialize() { DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this)); - if (!mDeviceInfo.maintenance1) { + if (!mDeviceInfo.HasExt(DeviceExt::Maintenance1)) { return DAWN_INTERNAL_ERROR( "Dawn requires Vulkan 1.1 or Vulkan 1.0 with KHR_Maintenance1 in order to support " "viewport flipY"); @@ -74,9 +74,9 @@ namespace dawn_native { namespace vulkan { mSupportedExtensions.EnableExtension(Extension::TextureCompressionBC); } - if (mDeviceInfo.shaderFloat16Int8 && + if (mDeviceInfo.HasExt(DeviceExt::ShaderFloat16Int8) && mDeviceInfo.shaderFloat16Int8Features.shaderFloat16 == VK_TRUE && - mDeviceInfo._16BitStorage && + mDeviceInfo.HasExt(DeviceExt::_16BitStorage) && mDeviceInfo._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess == VK_TRUE) { mSupportedExtensions.EnableExtension(Extension::ShaderFloat16); } diff --git a/src/dawn_native/vulkan/CommandBufferVk.cpp b/src/dawn_native/vulkan/CommandBufferVk.cpp index ccd04eaf93..f1e3e46948 100644 --- a/src/dawn_native/vulkan/CommandBufferVk.cpp +++ b/src/dawn_native/vulkan/CommandBufferVk.cpp @@ -665,7 +665,7 @@ namespace dawn_native { namespace vulkan { } case Command::InsertDebugMarker: { - if (device->GetDeviceInfo().debugMarker) { + if (device->GetDeviceInfo().HasExt(DeviceExt::DebugMarker)) { InsertDebugMarkerCmd* cmd = mCommands.NextCommand(); const char* label = mCommands.NextData(cmd->length + 1); VkDebugMarkerMarkerInfoEXT markerInfo; @@ -685,7 +685,7 @@ namespace dawn_native { namespace vulkan { } case Command::PopDebugGroup: { - if (device->GetDeviceInfo().debugMarker) { + if (device->GetDeviceInfo().HasExt(DeviceExt::DebugMarker)) { mCommands.NextCommand(); device->fn.CmdDebugMarkerEndEXT(commands); } else { @@ -695,7 +695,7 @@ namespace dawn_native { namespace vulkan { } case Command::PushDebugGroup: { - if (device->GetDeviceInfo().debugMarker) { + if (device->GetDeviceInfo().HasExt(DeviceExt::DebugMarker)) { PushDebugGroupCmd* cmd = mCommands.NextCommand(); const char* label = mCommands.NextData(cmd->length + 1); VkDebugMarkerMarkerInfoEXT markerInfo; @@ -812,7 +812,7 @@ namespace dawn_native { namespace vulkan { } case Command::InsertDebugMarker: { - if (device->GetDeviceInfo().debugMarker) { + if (device->GetDeviceInfo().HasExt(DeviceExt::DebugMarker)) { InsertDebugMarkerCmd* cmd = iter->NextCommand(); const char* label = iter->NextData(cmd->length + 1); VkDebugMarkerMarkerInfoEXT markerInfo; @@ -832,7 +832,7 @@ namespace dawn_native { namespace vulkan { } case Command::PopDebugGroup: { - if (device->GetDeviceInfo().debugMarker) { + if (device->GetDeviceInfo().HasExt(DeviceExt::DebugMarker)) { iter->NextCommand(); device->fn.CmdDebugMarkerEndEXT(commands); } else { @@ -842,7 +842,7 @@ namespace dawn_native { namespace vulkan { } case Command::PushDebugGroup: { - if (device->GetDeviceInfo().debugMarker) { + if (device->GetDeviceInfo().HasExt(DeviceExt::DebugMarker)) { PushDebugGroupCmd* cmd = iter->NextCommand(); const char* label = iter->NextData(cmd->length + 1); VkDebugMarkerMarkerInfoEXT markerInfo; diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp index fb116a10ae..bb16f84ed6 100644 --- a/src/dawn_native/vulkan/DeviceVk.cpp +++ b/src/dawn_native/vulkan/DeviceVk.cpp @@ -268,54 +268,17 @@ namespace dawn_native { namespace vulkan { ResultOrError Device::CreateDevice(VkPhysicalDevice physicalDevice) { VulkanDeviceKnobs usedKnobs = {}; - float zero = 0.0f; - std::vector layersToRequest; - std::vector extensionsToRequest; - std::vector queuesToRequest; + // Default to asking for all avilable known extensions. + usedKnobs.extensions = mDeviceInfo.extensions; - if (mDeviceInfo.debugMarker) { - extensionsToRequest.push_back(kExtensionNameExtDebugMarker); - usedKnobs.debugMarker = true; - } - if (mDeviceInfo.externalMemory) { - extensionsToRequest.push_back(kExtensionNameKhrExternalMemory); - usedKnobs.externalMemory = true; - } - if (mDeviceInfo.externalMemoryFD) { - extensionsToRequest.push_back(kExtensionNameKhrExternalMemoryFD); - usedKnobs.externalMemoryFD = true; - } - if (mDeviceInfo.externalMemoryDmaBuf) { - extensionsToRequest.push_back(kExtensionNameExtExternalMemoryDmaBuf); - usedKnobs.externalMemoryDmaBuf = true; - } - if (mDeviceInfo.imageDrmFormatModifier) { - extensionsToRequest.push_back(kExtensionNameExtImageDrmFormatModifier); - usedKnobs.imageDrmFormatModifier = true; - } - if (mDeviceInfo.externalMemoryZirconHandle) { - extensionsToRequest.push_back(kExtensionNameFuchsiaExternalMemory); - usedKnobs.externalMemoryZirconHandle = true; - } - if (mDeviceInfo.externalSemaphore) { - extensionsToRequest.push_back(kExtensionNameKhrExternalSemaphore); - usedKnobs.externalSemaphore = true; - } - if (mDeviceInfo.externalSemaphoreFD) { - extensionsToRequest.push_back(kExtensionNameKhrExternalSemaphoreFD); - usedKnobs.externalSemaphoreFD = true; - } - if (mDeviceInfo.externalSemaphoreZirconHandle) { - extensionsToRequest.push_back(kExtensionNameFuchsiaExternalSemaphore); - usedKnobs.externalSemaphoreZirconHandle = true; - } - if (mDeviceInfo.swapchain) { - extensionsToRequest.push_back(kExtensionNameKhrSwapchain); - usedKnobs.swapchain = true; - } - if (mDeviceInfo.maintenance1) { - extensionsToRequest.push_back(kExtensionNameKhrMaintenance1); - usedKnobs.maintenance1 = true; + // However only request the extensions that haven't been promoted in the device's apiVersion + std::vector extensionNames; + for (uint32_t ext : IterateBitSet(usedKnobs.extensions.extensionBitSet)) { + const DeviceExtInfo& info = GetDeviceExtInfo(static_cast(ext)); + + if (info.versionPromoted > mDeviceInfo.properties.apiVersion) { + extensionNames.push_back(info.name); + } } // Always require independentBlend because it is a core Dawn feature @@ -333,21 +296,13 @@ namespace dawn_native { namespace vulkan { if (IsExtensionEnabled(Extension::ShaderFloat16)) { const VulkanDeviceInfo& deviceInfo = ToBackend(GetAdapter())->GetDeviceInfo(); - ASSERT(deviceInfo.shaderFloat16Int8 && + ASSERT(deviceInfo.HasExt(DeviceExt::ShaderFloat16Int8) && deviceInfo.shaderFloat16Int8Features.shaderFloat16 == VK_TRUE && - deviceInfo._16BitStorage && + deviceInfo.HasExt(DeviceExt::_16BitStorage) && deviceInfo._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess == VK_TRUE); - usedKnobs.shaderFloat16Int8 = true; usedKnobs.shaderFloat16Int8Features.shaderFloat16 = VK_TRUE; - extensionsToRequest.push_back(kExtensionNameKhrShaderFloat16Int8); - - usedKnobs._16BitStorage = true; usedKnobs._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess = VK_TRUE; - // VK_KHR_16bit_storage is promoted to Vulkan 1.1. - if (deviceInfo.properties.apiVersion < VK_MAKE_VERSION(1, 1, 0)) { - extensionsToRequest.push_back(kExtensionNameKhr16BitStorage); - } } // Find a universal queue family @@ -370,6 +325,8 @@ namespace dawn_native { namespace vulkan { } // Choose to create a single universal queue + std::vector queuesToRequest; + float zero = 0.0f; { VkDeviceQueueCreateInfo queueCreateInfo; queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; @@ -388,10 +345,10 @@ namespace dawn_native { namespace vulkan { createInfo.flags = 0; createInfo.queueCreateInfoCount = static_cast(queuesToRequest.size()); createInfo.pQueueCreateInfos = queuesToRequest.data(); - createInfo.enabledLayerCount = static_cast(layersToRequest.size()); - createInfo.ppEnabledLayerNames = layersToRequest.data(); - createInfo.enabledExtensionCount = static_cast(extensionsToRequest.size()); - createInfo.ppEnabledExtensionNames = extensionsToRequest.data(); + createInfo.enabledLayerCount = 0; + createInfo.ppEnabledLayerNames = nullptr; + createInfo.enabledExtensionCount = static_cast(extensionNames.size()); + createInfo.ppEnabledExtensionNames = extensionNames.data(); createInfo.pEnabledFeatures = &usedKnobs.features; DAWN_TRY(CheckVkSuccess(fn.CreateDevice(physicalDevice, &createInfo, nullptr, &mVkDevice), diff --git a/src/dawn_native/vulkan/VulkanExtensions.cpp b/src/dawn_native/vulkan/VulkanExtensions.cpp index ea0ccabbd1..353f087802 100644 --- a/src/dawn_native/vulkan/VulkanExtensions.cpp +++ b/src/dawn_native/vulkan/VulkanExtensions.cpp @@ -23,6 +23,7 @@ namespace dawn_native { namespace vulkan { static constexpr uint32_t VulkanVersion_1_1 = VK_MAKE_VERSION(1, 1, 0); + static constexpr uint32_t VulkanVersion_1_2 = VK_MAKE_VERSION(1, 2, 0); static constexpr uint32_t NeverPromoted = std::numeric_limits::max(); // A static array for InstanceExtInfo that can be indexed with InstanceExts. @@ -132,4 +133,154 @@ namespace dawn_native { namespace vulkan { } } + static constexpr size_t kDeviceExtCount = static_cast(DeviceExt::EnumCount); + static constexpr std::array sDeviceExtInfos{{ + // + {DeviceExt::Maintenance1, "VK_KHR_maintenance1", VulkanVersion_1_1}, + {DeviceExt::ExternalMemory, "VK_KHR_external_memory", VulkanVersion_1_1}, + {DeviceExt::ExternalSemaphore, "VK_KHR_external_semaphore", VulkanVersion_1_1}, + {DeviceExt::_16BitStorage, "VK_KHR_16bit_storage", VulkanVersion_1_1}, + + {DeviceExt::ShaderFloat16Int8, "VK_KHR_shader_float16_int8", VulkanVersion_1_2}, + + {DeviceExt::ExternalMemoryFD, "VK_KHR_external_memory_fd", NeverPromoted}, + {DeviceExt::ExternalMemoryDmaBuf, "VK_EXT_external_memory_dma_buf", NeverPromoted}, + {DeviceExt::ExternalMemoryZirconHandle, "VK_FUCHSIA_external_memory", NeverPromoted}, + {DeviceExt::ExternalSemaphoreFD, "VK_KHR_external_semaphore_fd", NeverPromoted}, + {DeviceExt::ExternalSemaphoreZirconHandle, "VK_FUCHSIA_external_semaphore", NeverPromoted}, + + {DeviceExt::DebugMarker, "VK_EXT_debug_marker", NeverPromoted}, + {DeviceExt::ImageDrmFormatModifier, "VK_EXT_image_drm_format_modifier", NeverPromoted}, + {DeviceExt::Swapchain, "VK_KHR_swapchain", NeverPromoted}, + // + }}; + + void DeviceExtSet::Set(DeviceExt extension, bool enabled) { + extensionBitSet.set(static_cast(extension), enabled); + } + + bool DeviceExtSet::Has(DeviceExt extension) const { + return extensionBitSet[static_cast(extension)]; + } + + const DeviceExtInfo& GetDeviceExtInfo(DeviceExt ext) { + uint32_t index = static_cast(ext); + ASSERT(index < sDeviceExtInfos.size()); + ASSERT(sDeviceExtInfos[index].index == ext); + return sDeviceExtInfos[index]; + } + + std::unordered_map CreateDeviceExtNameMap() { + std::unordered_map result; + for (const DeviceExtInfo& info : sDeviceExtInfos) { + result[info.name] = info.index; + } + return result; + } + + DeviceExtSet EnsureDependencies(const DeviceExtSet& advertisedExts, + const InstanceExtSet& instanceExts) { + // This is very similar to EnsureDependencies for instanceExtSet. See comment there for + // an explanation of what happens. + DeviceExtSet visitedSet; + DeviceExtSet trimmedSet; + + auto HasDep = [&](DeviceExt ext) -> bool { + ASSERT(visitedSet.Has(ext)); + return trimmedSet.Has(ext); + }; + + for (uint32_t i = 0; i < sDeviceExtInfos.size(); i++) { + DeviceExt ext = static_cast(i); + + bool hasDependencies = false; + switch (ext) { + case DeviceExt::DebugMarker: + // TODO(cwallez@chromium.org): VK_KHR_debug_report is deprecated, switch to + // using VK_KHR_debug_utils instead. + hasDependencies = instanceExts.Has(InstanceExt::DebugReport); + break; + + case DeviceExt::ImageDrmFormatModifier: + // TODO(cwallez@chromium.org): ImageDrmFormatModifier actually requires: + // - VK_KHR_bind_memory2 + // - VK_KHR_image_format_list + // - VK_KHR_sampler_ycbcr_conversion + // + // Also switch to using DeviceExt::GetPhysicalDeviceProperties2 when we decouple + // Instance / Device physical device extensions. + hasDependencies = instanceExts.Has(InstanceExt::GetPhysicalDeviceProperties2); + break; + + case DeviceExt::Swapchain: + hasDependencies = instanceExts.Has(InstanceExt::Surface); + break; + + case DeviceExt::Maintenance1: + hasDependencies = true; + break; + + case DeviceExt::ShaderFloat16Int8: + // TODO(cwallez@chromium.org): switch to using + // DeviceExt::GetPhysicalDeviceProperties2 when we decouple Instance / Device + // physical device extensions. + hasDependencies = instanceExts.Has(InstanceExt::GetPhysicalDeviceProperties2); + break; + + case DeviceExt::ExternalMemory: + // TODO(cwallez@chromium.org): switch to using + // DeviceExt::ExternalMemoryCapabilities when we decouple Instance / Device + // physical device extensions. + hasDependencies = instanceExts.Has(InstanceExt::ExternalMemoryCapabilities); + break; + + case DeviceExt::ExternalSemaphore: + // TODO(cwallez@chromium.org): switch to using + // DeviceExt::ExternalSemaphoreCapabilities when we decouple Instance / Device + // physical device extensions. + hasDependencies = instanceExts.Has(InstanceExt::ExternalSemaphoreCapabilities); + break; + + case DeviceExt::_16BitStorage: + // TODO(cwallez@chromium.org): switch to using + // DeviceExt::GetPhysicalDeviceProperties2 when we decouple Instance / Device + // physical device extensions. + // Also depends on VK_KHR_storage_buffer_storage_class + hasDependencies = instanceExts.Has(InstanceExt::GetPhysicalDeviceProperties2); + break; + + case DeviceExt::ExternalMemoryFD: + case DeviceExt::ExternalMemoryZirconHandle: + hasDependencies = HasDep(DeviceExt::ExternalMemory); + break; + + case DeviceExt::ExternalMemoryDmaBuf: + hasDependencies = HasDep(DeviceExt::ExternalMemoryFD); + break; + + case DeviceExt::ExternalSemaphoreFD: + case DeviceExt::ExternalSemaphoreZirconHandle: + hasDependencies = HasDep(DeviceExt::ExternalSemaphore); + break; + + default: + UNREACHABLE(); + break; + } + + trimmedSet.Set(ext, hasDependencies && advertisedExts.Has(ext)); + visitedSet.Set(ext, true); + } + + return trimmedSet; + } + + void MarkPromotedExtensions(DeviceExtSet* extensions, uint32_t version) { + for (const DeviceExtInfo& info : sDeviceExtInfos) { + if (info.versionPromoted <= version) { + extensions->Set(info.index, true); + } + } + } + }} // namespace dawn_native::vulkan diff --git a/src/dawn_native/vulkan/VulkanExtensions.h b/src/dawn_native/vulkan/VulkanExtensions.h index a604faa224..184df0b32d 100644 --- a/src/dawn_native/vulkan/VulkanExtensions.h +++ b/src/dawn_native/vulkan/VulkanExtensions.h @@ -70,6 +70,62 @@ namespace dawn_native { namespace vulkan { // extensions that don't have all their transitive dependencies in advertisedExts. InstanceExtSet EnsureDependencies(const InstanceExtSet& advertisedExts); + // The list of known device extensions. They must be in dependency order (this is checked + // inside EnsureDependencies) + enum class DeviceExt { + // Promoted to 1.1 + Maintenance1, + ExternalMemory, + ExternalSemaphore, + _16BitStorage, + + // Promoted to 1.2 + ShaderFloat16Int8, + + // External* extensions + ExternalMemoryFD, + ExternalMemoryDmaBuf, + ExternalMemoryZirconHandle, + ExternalSemaphoreFD, + ExternalSemaphoreZirconHandle, + + // Others + DebugMarker, + ImageDrmFormatModifier, + Swapchain, + + EnumCount, + }; + + // A bitset wrapper that is indexed with DeviceExt. + struct DeviceExtSet { + std::bitset(DeviceExt::EnumCount)> extensionBitSet; + void Set(DeviceExt extension, bool enabled); + bool Has(DeviceExt extension) const; + }; + + // A bitset wrapper that is indexed with DeviceExt. + struct DeviceExtInfo { + DeviceExt index; + const char* name; + // The version in which this extension was promoted as built with VK_MAKE_VERSION, + // or NeverPromoted if it was never promoted. + uint32_t versionPromoted; + }; + + // Returns the information about a known DeviceExt + const DeviceExtInfo& GetDeviceExtInfo(DeviceExt ext); + // Returns a map that maps a Vulkan extension name to its DeviceExt. + std::unordered_map CreateDeviceExtNameMap(); + + // Sets entries in `extensions` to true if that entry was promoted in Vulkan version `version` + void MarkPromotedExtensions(DeviceExtSet* extensions, uint32_t version); + // From a set of extensions advertised as supported by the device (or promoted), remove all + // extensions that don't have all their transitive dependencies in advertisedExts or in + // instanceExts. + DeviceExtSet EnsureDependencies(const DeviceExtSet& advertisedExts, + const InstanceExtSet& instanceExts); + }} // namespace dawn_native::vulkan #endif // DAWNNATIVE_VULKAN_VULKANEXTENSIONS_H_ diff --git a/src/dawn_native/vulkan/VulkanFunctions.cpp b/src/dawn_native/vulkan/VulkanFunctions.cpp index e31f464df4..cc070f236c 100644 --- a/src/dawn_native/vulkan/VulkanFunctions.cpp +++ b/src/dawn_native/vulkan/VulkanFunctions.cpp @@ -278,35 +278,35 @@ namespace dawn_native { namespace vulkan { GET_DEVICE_PROC(UpdateDescriptorSets); GET_DEVICE_PROC(WaitForFences); - if (deviceInfo.debugMarker) { + if (deviceInfo.HasExt(DeviceExt::DebugMarker)) { GET_DEVICE_PROC(CmdDebugMarkerBeginEXT); GET_DEVICE_PROC(CmdDebugMarkerEndEXT); GET_DEVICE_PROC(CmdDebugMarkerInsertEXT); } - if (deviceInfo.externalMemoryFD) { + if (deviceInfo.HasExt(DeviceExt::ExternalMemoryFD)) { GET_DEVICE_PROC(GetMemoryFdKHR); GET_DEVICE_PROC(GetMemoryFdPropertiesKHR); } - if (deviceInfo.externalSemaphoreFD) { + if (deviceInfo.HasExt(DeviceExt::ExternalSemaphoreFD)) { GET_DEVICE_PROC(ImportSemaphoreFdKHR); GET_DEVICE_PROC(GetSemaphoreFdKHR); } #if VK_USE_PLATFORM_FUCHSIA - if (deviceInfo.externalMemoryZirconHandle) { + if (deviceInfo.HasExt(DeviceExt::ExternalMemoryZirconHandle)) { GET_DEVICE_PROC(GetMemoryZirconHandleFUCHSIA); GET_DEVICE_PROC(GetMemoryZirconHandlePropertiesFUCHSIA); } - if (deviceInfo.externalSemaphoreZirconHandle) { + if (deviceInfo.HasExt(DeviceExt::ExternalSemaphoreZirconHandle)) { GET_DEVICE_PROC(ImportSemaphoreZirconHandleFUCHSIA); GET_DEVICE_PROC(GetSemaphoreZirconHandleFUCHSIA); } #endif - if (deviceInfo.swapchain) { + if (deviceInfo.HasExt(DeviceExt::Swapchain)) { GET_DEVICE_PROC(CreateSwapchainKHR); GET_DEVICE_PROC(DestroySwapchainKHR); GET_DEVICE_PROC(GetSwapchainImagesKHR); diff --git a/src/dawn_native/vulkan/VulkanInfo.cpp b/src/dawn_native/vulkan/VulkanInfo.cpp index e713ba6cb4..6b2346e1da 100644 --- a/src/dawn_native/vulkan/VulkanInfo.cpp +++ b/src/dawn_native/vulkan/VulkanInfo.cpp @@ -28,10 +28,6 @@ namespace dawn_native { namespace vulkan { return strncmp(layer.layerName, name, VK_MAX_EXTENSION_NAME_SIZE) == 0; } - bool IsExtensionName(const VkExtensionProperties& extension, const char* name) { - return strncmp(extension.extensionName, name, VK_MAX_EXTENSION_NAME_SIZE) == 0; - } - bool EnumerateInstanceExtensions(const char* layerName, const dawn_native::vulkan::VulkanFunctions& vkFunctions, std::vector* extensions) { @@ -54,30 +50,14 @@ namespace dawn_native { namespace vulkan { const char kLayerNameRenderDocCapture[] = "VK_LAYER_RENDERDOC_Capture"; const char kLayerNameFuchsiaImagePipeSwapchain[] = "VK_LAYER_FUCHSIA_imagepipe_swapchain"; - const char kExtensionNameExtDebugMarker[] = "VK_EXT_debug_marker"; - const char kExtensionNameKhrExternalMemory[] = "VK_KHR_external_memory"; - const char kExtensionNameKhrExternalMemoryCapabilities[] = - "VK_KHR_external_memory_capabilities"; - const char kExtensionNameKhrExternalMemoryFD[] = "VK_KHR_external_memory_fd"; - const char kExtensionNameExtExternalMemoryDmaBuf[] = "VK_EXT_external_memory_dma_buf"; - const char kExtensionNameExtImageDrmFormatModifier[] = "VK_EXT_image_drm_format_modifier"; - const char kExtensionNameFuchsiaExternalMemory[] = "VK_FUCHSIA_external_memory"; - const char kExtensionNameKhrExternalSemaphore[] = "VK_KHR_external_semaphore"; - const char kExtensionNameKhrExternalSemaphoreCapabilities[] = - "VK_KHR_external_semaphore_capabilities"; - const char kExtensionNameKhrExternalSemaphoreFD[] = "VK_KHR_external_semaphore_fd"; - const char kExtensionNameFuchsiaExternalSemaphore[] = "VK_FUCHSIA_external_semaphore"; - const char kExtensionNameKhrGetPhysicalDeviceProperties2[] = - "VK_KHR_get_physical_device_properties2"; - const char kExtensionNameKhrSwapchain[] = "VK_KHR_swapchain"; - const char kExtensionNameKhrMaintenance1[] = "VK_KHR_maintenance1"; - const char kExtensionNameKhrShaderFloat16Int8[] = "VK_KHR_shader_float16_int8"; - const char kExtensionNameKhr16BitStorage[] = "VK_KHR_16bit_storage"; - bool VulkanGlobalKnobs::HasExt(InstanceExt ext) const { return extensions.Has(ext); } + bool VulkanDeviceKnobs::HasExt(DeviceExt ext) const { + return extensions.Has(ext); + } + ResultOrError GatherGlobalInfo(const Backend& backend) { VulkanGlobalInfo info = {}; const VulkanFunctions& vkFunctions = backend.GetFunctions(); @@ -248,82 +228,47 @@ namespace dawn_native { namespace vulkan { return DAWN_INTERNAL_ERROR("vkEnumerateDeviceExtensionProperties"); } - info.extensions.resize(count); - DAWN_TRY(CheckVkSuccess(vkFunctions.EnumerateDeviceExtensionProperties( - physicalDevice, nullptr, &count, info.extensions.data()), - "vkEnumerateDeviceExtensionProperties")); + std::vector extensionsProperties; + extensionsProperties.resize(count); + DAWN_TRY( + CheckVkSuccess(vkFunctions.EnumerateDeviceExtensionProperties( + physicalDevice, nullptr, &count, extensionsProperties.data()), + "vkEnumerateDeviceExtensionProperties")); - for (const auto& extension : info.extensions) { - if (IsExtensionName(extension, kExtensionNameExtDebugMarker)) { - info.debugMarker = true; - } - if (IsExtensionName(extension, kExtensionNameKhrExternalMemory)) { - info.externalMemory = true; - } - if (IsExtensionName(extension, kExtensionNameKhrExternalMemoryFD)) { - info.externalMemoryFD = true; - } - if (IsExtensionName(extension, kExtensionNameExtExternalMemoryDmaBuf)) { - info.externalMemoryDmaBuf = true; - } - if (IsExtensionName(extension, kExtensionNameExtImageDrmFormatModifier)) { - info.imageDrmFormatModifier = true; - } - if (IsExtensionName(extension, kExtensionNameFuchsiaExternalMemory)) { - info.externalMemoryZirconHandle = true; - } - if (IsExtensionName(extension, kExtensionNameKhrExternalSemaphore)) { - info.externalSemaphore = true; - } - if (IsExtensionName(extension, kExtensionNameKhrExternalSemaphoreFD)) { - info.externalSemaphoreFD = true; - } - if (IsExtensionName(extension, kExtensionNameFuchsiaExternalSemaphore)) { - info.externalSemaphoreZirconHandle = true; - } - if (IsExtensionName(extension, kExtensionNameKhrSwapchain)) { - info.swapchain = true; - } - if (IsExtensionName(extension, kExtensionNameKhrMaintenance1)) { - info.maintenance1 = true; - } - if (IsExtensionName(extension, kExtensionNameKhrShaderFloat16Int8) && - globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2)) { - info.shaderFloat16Int8 = true; - info.shaderFloat16Int8Features.sType = - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR; + std::unordered_map knownExts = CreateDeviceExtNameMap(); - VkPhysicalDeviceFeatures2KHR physicalDeviceFeatures2 = {}; - physicalDeviceFeatures2.sType = - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; - physicalDeviceFeatures2.pNext = &info.shaderFloat16Int8Features; - vkFunctions.GetPhysicalDeviceFeatures2(physicalDevice, - &physicalDeviceFeatures2); - } - if (IsExtensionName(extension, kExtensionNameKhr16BitStorage) && - globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2)) { - info._16BitStorage = true; + for (const VkExtensionProperties& extension : extensionsProperties) { + auto it = knownExts.find(extension.extensionName); + if (it != knownExts.end()) { + info.extensions.Set(it->second, true); } } + + MarkPromotedExtensions(&info.extensions, info.properties.apiVersion); + info.extensions = EnsureDependencies(info.extensions, globalInfo.extensions); } - // Mark the extensions promoted to Vulkan 1.1 as available. - if (info.properties.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) { - info.maintenance1 = true; - } + // Gather additional information for some of the extensions + { + if (info.extensions.Has(DeviceExt::ShaderFloat16Int8)) { + info.shaderFloat16Int8Features.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR; - // VK_KHR_16bit_storage is promoted to Vulkan 1.1, so gather information if either is - // present, and mark the extension as available. - if (info._16BitStorage || info.properties.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) { - ASSERT(globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2)); - info._16BitStorage = true; - info._16BitStorageFeatures.sType = - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES; + VkPhysicalDeviceFeatures2KHR physicalDeviceFeatures2 = {}; + physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; + physicalDeviceFeatures2.pNext = &info.shaderFloat16Int8Features; + vkFunctions.GetPhysicalDeviceFeatures2(physicalDevice, &physicalDeviceFeatures2); + } - VkPhysicalDeviceFeatures2 physicalDeviceFeatures2 = {}; - physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; - physicalDeviceFeatures2.pNext = &info._16BitStorageFeatures; - vkFunctions.GetPhysicalDeviceFeatures2(physicalDevice, &physicalDeviceFeatures2); + if (info.extensions.Has(DeviceExt::_16BitStorage)) { + info._16BitStorageFeatures.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES; + + VkPhysicalDeviceFeatures2 physicalDeviceFeatures2 = {}; + physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; + physicalDeviceFeatures2.pNext = &info._16BitStorageFeatures; + vkFunctions.GetPhysicalDeviceFeatures2(physicalDevice, &physicalDeviceFeatures2); + } } // TODO(cwallez@chromium.org): gather info about formats diff --git a/src/dawn_native/vulkan/VulkanInfo.h b/src/dawn_native/vulkan/VulkanInfo.h index a9d081822a..6d0a756fc0 100644 --- a/src/dawn_native/vulkan/VulkanInfo.h +++ b/src/dawn_native/vulkan/VulkanInfo.h @@ -31,23 +31,6 @@ namespace dawn_native { namespace vulkan { extern const char kLayerNameRenderDocCapture[]; extern const char kLayerNameFuchsiaImagePipeSwapchain[]; - extern const char kExtensionNameExtDebugMarker[]; - extern const char kExtensionNameKhrExternalMemory[]; - extern const char kExtensionNameKhrExternalMemoryCapabilities[]; - extern const char kExtensionNameKhrExternalMemoryFD[]; - extern const char kExtensionNameExtExternalMemoryDmaBuf[]; - extern const char kExtensionNameExtImageDrmFormatModifier[]; - extern const char kExtensionNameFuchsiaExternalMemory[]; - extern const char kExtensionNameKhrExternalSemaphore[]; - extern const char kExtensionNameKhrExternalSemaphoreCapabilities[]; - extern const char kExtensionNameKhrExternalSemaphoreFD[]; - extern const char kExtensionNameFuchsiaExternalSemaphore[]; - extern const char kExtensionNameKhrGetPhysicalDeviceProperties2[]; - extern const char kExtensionNameKhrSwapchain[]; - extern const char kExtensionNameKhrMaintenance1[]; - extern const char kExtensionNameKhrShaderFloat16Int8[]; - extern const char kExtensionNameKhr16BitStorage[]; - // Global information - gathered before the instance is created struct VulkanGlobalKnobs { // Layers @@ -72,20 +55,8 @@ namespace dawn_native { namespace vulkan { VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shaderFloat16Int8Features; VkPhysicalDevice16BitStorageFeaturesKHR _16BitStorageFeatures; - // Extensions, promoted extensions are set to true if their core version is supported. - bool debugMarker = false; - bool externalMemory = false; - bool externalMemoryFD = false; - bool externalMemoryDmaBuf = false; - bool imageDrmFormatModifier = false; - bool externalMemoryZirconHandle = false; - bool externalSemaphore = false; - bool externalSemaphoreFD = false; - bool externalSemaphoreZirconHandle = false; - bool swapchain = false; - bool maintenance1 = false; - bool shaderFloat16Int8 = false; - bool _16BitStorage = false; + bool HasExt(DeviceExt ext) const; + DeviceExtSet extensions; }; struct VulkanDeviceInfo : VulkanDeviceKnobs { @@ -96,7 +67,6 @@ namespace dawn_native { namespace vulkan { std::vector memoryHeaps; std::vector layers; - std::vector extensions; // TODO(cwallez@chromium.org): layer instance extensions }; diff --git a/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp b/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp index 240c6fe06e..4129745dc5 100644 --- a/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp +++ b/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp @@ -61,13 +61,9 @@ namespace dawn_native { namespace vulkan { namespace external_memory { Service::Service(Device* device) : mDevice(device) { const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo(); - const VulkanGlobalInfo& globalInfo = - ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo(); - mSupported = globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2) && - globalInfo.HasExt(InstanceExt::ExternalMemoryCapabilities) && - deviceInfo.externalMemory && deviceInfo.externalMemoryFD && - deviceInfo.externalMemoryDmaBuf && deviceInfo.imageDrmFormatModifier; + mSupported = deviceInfo.HasExt(DeviceExt::ExternalMemoryFD) && + deviceInfo.HasExt(DeviceExt::ImageDrmFormatModifier); } Service::~Service() = default; diff --git a/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp b/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp index 57b74af22c..99057771f6 100644 --- a/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp +++ b/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp @@ -23,13 +23,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory { Service::Service(Device* device) : mDevice(device) { - const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo(); - const VulkanGlobalInfo& globalInfo = - ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo(); - - mSupported = globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2) && - globalInfo.HasExt(InstanceExt::ExternalMemoryCapabilities) && - deviceInfo.externalMemory && deviceInfo.externalMemoryFD; + mSupported = device->GetDeviceInfo().HasExt(DeviceExt::ExternalMemoryFD); } Service::~Service() = default; diff --git a/src/dawn_native/vulkan/external_memory/MemoryServiceZirconHandle.cpp b/src/dawn_native/vulkan/external_memory/MemoryServiceZirconHandle.cpp index ab87a7f848..08d8d63004 100644 --- a/src/dawn_native/vulkan/external_memory/MemoryServiceZirconHandle.cpp +++ b/src/dawn_native/vulkan/external_memory/MemoryServiceZirconHandle.cpp @@ -23,13 +23,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory { Service::Service(Device* device) : mDevice(device) { - const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo(); - const VulkanGlobalInfo& globalInfo = - ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo(); - - mSupported = globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2) && - globalInfo.HasExt(InstanceExt::ExternalMemoryCapabilities) && - deviceInfo.externalMemory && deviceInfo.externalMemoryFD; + mSupported = device->GetDeviceInfo().HasExt(DeviceExt::ExternalMemoryZirconHandle); } Service::~Service() = default; diff --git a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp index 222fcbbaaf..aecc893500 100644 --- a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp +++ b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp @@ -21,13 +21,7 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore { Service::Service(Device* device) : mDevice(device) { - const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo(); - const VulkanGlobalInfo& globalInfo = - ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo(); - - mSupported = globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2) && - globalInfo.HasExt(InstanceExt::ExternalSemaphoreCapabilities) && - deviceInfo.externalSemaphore && deviceInfo.externalSemaphoreFD; + mSupported = device->GetDeviceInfo().HasExt(DeviceExt::ExternalSemaphoreFD); // Early out before we try using extension functions if (!mSupported) { diff --git a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp index 985cf4f221..b4e3a62e5e 100644 --- a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp +++ b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp @@ -21,13 +21,7 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore { Service::Service(Device* device) : mDevice(device) { - const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo(); - const VulkanGlobalInfo& globalInfo = - ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo(); - - mSupported = globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2) && - globalInfo.HasExt(InstanceExt::ExternalSemaphoreCapabilities) && - deviceInfo.externalSemaphore && deviceInfo.externalSemaphoreFD; + mSupported = device->GetDeviceInfo().hasExt(DeviceExt::ExternalSemaphoreZirconHandle); // Early out before we try using extension functions if (!mSupported) {