summaryrefslogtreecommitdiff
path: root/vulkan/libvulkan/api.cpp
diff options
context:
space:
mode:
authorPeiyong Lin <lpy@google.com>2020-03-11 17:43:28 -0700
committerPeiyong Lin <lpy@google.com>2020-03-17 20:20:51 -0700
commit8f4435a3370ec3a7ad56ecb3721d29a0292c06a9 (patch)
treefea1fa93888d652c9a1d224e0296776470c46d26 /vulkan/libvulkan/api.cpp
parent1032fac2f76b0eb83ddf0f22784e994547824c6a (diff)
[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
Diffstat (limited to 'vulkan/libvulkan/api.cpp')
-rw-r--r--vulkan/libvulkan/api.cpp65
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,