From 8f4435a3370ec3a7ad56ecb3721d29a0292c06a9 Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Wed, 11 Mar 2020 17:43:28 -0700 Subject: [Vulkan] Expose instance extensions from implicit layers. Previously the vulkan loader only exposes instance extensions from the driver implementation. Per vkEnumerateInstanceExtensionProperties spec the loader must also advertise instance extensions from implicitly enabled layers. Bug: b/143293104 Test: vkEnumerateInstanceExtensionProperties returns the instance extensions from implicit layers. Change-Id: I17f4ce370bf5f4bba295165a28836e2b7c03a318 --- vulkan/libvulkan/api.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 3 deletions(-) (limited to 'vulkan/libvulkan/api.cpp') diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp index aae72db0fe..e607b058eb 100644 --- a/vulkan/libvulkan/api.cpp +++ b/vulkan/libvulkan/api.cpp @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include @@ -1280,9 +1282,66 @@ VkResult EnumerateInstanceExtensionProperties( return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS; } - // TODO(b/143293104): expose extensions from implicitly enabled layers - return vulkan::driver::EnumerateInstanceExtensionProperties( - nullptr, pPropertyCount, pProperties); + // If the pLayerName is nullptr, we must advertise all instance extensions + // from all implicitly enabled layers and the driver implementation. If + // there are duplicates among layers and the driver implementation, always + // only preserve the top layer closest to the application regardless of the + // spec version. + std::vector properties; + std::unordered_set extensionNames; + + // Expose extensions from implicitly enabled layers. + const std::string layersSetting = + android::GraphicsEnv::getInstance().getDebugLayers(); + if (!layersSetting.empty()) { + std::vector layers = + android::base::Split(layersSetting, ":"); + for (uint32_t i = 0; i < layers.size(); i++) { + const Layer* layer = FindLayer(layers[i].c_str()); + if (!layer) { + continue; + } + uint32_t count = 0; + const VkExtensionProperties* props = + GetLayerInstanceExtensions(*layer, count); + if (count > 0) { + for (uint32_t i = 0; i < count; ++i) { + if (extensionNames.emplace(props[i].extensionName).second) { + properties.push_back(props[i]); + } + } + } + } + } + + // TODO(b/143293104): Parse debug.vulkan.layers properties + + // Expose extensions from driver implementation. + { + uint32_t count = 0; + VkResult result = vulkan::driver::EnumerateInstanceExtensionProperties( + nullptr, &count, nullptr); + if (result == VK_SUCCESS && count > 0) { + std::vector props(count); + result = vulkan::driver::EnumerateInstanceExtensionProperties( + nullptr, &count, props.data()); + for (auto prop : props) { + if (extensionNames.emplace(prop.extensionName).second) { + properties.push_back(prop); + } + } + } + } + + uint32_t totalCount = properties.size(); + if (!pProperties || *pPropertyCount > totalCount) { + *pPropertyCount = totalCount; + } + if (pProperties) { + std::copy(properties.data(), properties.data() + *pPropertyCount, + pProperties); + } + return *pPropertyCount < totalCount ? VK_INCOMPLETE : VK_SUCCESS; } VkResult EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, -- cgit v1.2.3-59-g8ed1b