diff options
Diffstat (limited to 'vulkan/libvulkan/api.cpp')
-rw-r--r-- | vulkan/libvulkan/api.cpp | 65 |
1 files changed, 62 insertions, 3 deletions
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 <algorithm> #include <mutex> #include <new> +#include <string> +#include <unordered_set> #include <utility> #include <android-base/strings.h> @@ -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<VkExtensionProperties> properties; + std::unordered_set<std::string> extensionNames; + + // Expose extensions from implicitly enabled layers. + const std::string layersSetting = + android::GraphicsEnv::getInstance().getDebugLayers(); + if (!layersSetting.empty()) { + std::vector<std::string> 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<VkExtensionProperties> 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, |