summaryrefslogtreecommitdiff
path: root/vulkan/libvulkan/api.cpp
diff options
context:
space:
mode:
author Peiyong Lin <lpy@google.com> 2020-03-25 15:44:28 -0700
committer Peiyong Lin <lpy@google.com> 2020-03-25 15:47:19 -0700
commit27800499ab20551a2b2e64d360c5e2130c881dd2 (patch)
tree51c308b9e7ef9786ad87ef6e3fbcfdad01b04a2e /vulkan/libvulkan/api.cpp
parent134a699e8dc8fab48182f8575ca95c49af8428e5 (diff)
[Vulkan] Expose device extensions from implicit layers.
Previously the vulkan loader only exposes device extensions from the driver implementation when the layer name is not specified. Per vkEnumerateDeviceExtensionProperties spec the loader must also advertise device extensions from implicitly enabled layers. Bug: b/143293104 Test: atest android.gputools.cts.CtsRootlessGpuDebugHostTest Change-Id: Iaf5786ba7e371a290ecd1764af69b5298371cfdd
Diffstat (limited to 'vulkan/libvulkan/api.cpp')
-rw-r--r--vulkan/libvulkan/api.cpp100
1 files changed, 77 insertions, 23 deletions
diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp
index e607b058eb..5b9affd03a 100644
--- a/vulkan/libvulkan/api.cpp
+++ b/vulkan/libvulkan/api.cpp
@@ -1196,6 +1196,23 @@ bool EnsureInitialized() {
return initialized;
}
+template <typename Functor>
+void ForEachLayerFromSettings(Functor functor) {
+ 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;
+ }
+ functor(layer);
+ }
+ }
+}
+
} // anonymous namespace
VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
@@ -1291,28 +1308,18 @@ VkResult EnumerateInstanceExtensionProperties(
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]);
- }
+ ForEachLayerFromSettings([&](const Layer* layer) {
+ 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
@@ -1393,10 +1400,57 @@ VkResult EnumerateDeviceExtensionProperties(
return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
}
- // TODO(b/143293104): expose extensions from implicitly enabled layers
- const InstanceData& data = GetData(physicalDevice);
- return data.dispatch.EnumerateDeviceExtensionProperties(
- physicalDevice, nullptr, pPropertyCount, pProperties);
+ // If the pLayerName is nullptr, we must advertise all device 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.
+ ForEachLayerFromSettings([&](const Layer* layer) {
+ uint32_t count = 0;
+ const VkExtensionProperties* props =
+ GetLayerDeviceExtensions(*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.
+ {
+ const InstanceData& data = GetData(physicalDevice);
+ uint32_t count = 0;
+ VkResult result = data.dispatch.EnumerateDeviceExtensionProperties(
+ physicalDevice, nullptr, &count, nullptr);
+ if (result == VK_SUCCESS && count > 0) {
+ std::vector<VkExtensionProperties> props(count);
+ result = data.dispatch.EnumerateDeviceExtensionProperties(
+ physicalDevice, 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 EnumerateInstanceVersion(uint32_t* pApiVersion) {