vulkan: Driver device extension enumeration and filtering
- Return VK_ERROR_EXTENSION_NOT_PRESENT if a requested device
extension is not supported by the loader, driver, or any enabled
device layer.
- Filter out device extensions not supported by the driver when
creating the driver device.
- Enumerate device extensions supported by the driver or loader.
Change-Id: I538e37bc74cc7f0eb27b1211b9324fb3b8a06e14
(cherry picked from commit 35873021f4f79ded0f584e433076c2675c6aed69)
diff --git a/vulkan/libvulkan/layers_extensions.cpp b/vulkan/libvulkan/layers_extensions.cpp
index f2fbf31..3e7fbec 100644
--- a/vulkan/libvulkan/layers_extensions.cpp
+++ b/vulkan/libvulkan/layers_extensions.cpp
@@ -28,6 +28,12 @@
using namespace vulkan;
+// TODO(jessehall): The whole way we deal with extensions is pretty hokey, and
+// not a good long-term solution. Having a hard-coded enum of extensions is
+// bad, of course. Representing sets of extensions (requested, supported, etc.)
+// as a bitset isn't necessarily bad, if the mapping from extension to bit were
+// dynamic. Need to rethink this completely when there's a little more time.
+
// TODO(jessehall): This file currently builds up global data structures as it
// loads, and never cleans them up. This means we're doing heap allocations
// without going through an app-provided allocator, but worse, we'll leak those
@@ -184,7 +190,7 @@
}
g_instance_layers.push_back(layer);
- ALOGV("added instance layer '%s'", props.layerName);
+ ALOGV(" added instance layer '%s'", props.layerName);
}
for (size_t i = 0; i < num_device_layers; i++) {
const VkLayerProperties& props = properties[num_instance_layers + i];
@@ -226,7 +232,7 @@
}
g_device_layers.push_back(layer);
- ALOGV("added device layer '%s'", props.layerName);
+ ALOGV(" added device layer '%s'", props.layerName);
}
dlclose(dlhandle);
@@ -396,6 +402,13 @@
: nullptr;
}
+bool LayerRef::SupportsExtension(const char* name) const {
+ return std::find_if(layer_->extensions.cbegin(), layer_->extensions.cend(),
+ [=](const VkExtensionProperties& ext) {
+ return strcmp(ext.extensionName, name) == 0;
+ }) != layer_->extensions.cend();
+}
+
InstanceExtension InstanceExtensionFromName(const char* name) {
if (strcmp(name, VK_KHR_SURFACE_EXTENSION_NAME) == 0)
return kKHR_surface;
@@ -406,4 +419,12 @@
return kInstanceExtensionCount;
}
+DeviceExtension DeviceExtensionFromName(const char* name) {
+ if (strcmp(name, VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0)
+ return kKHR_swapchain;
+ if (strcmp(name, VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) == 0)
+ return kANDROID_native_buffer;
+ return kDeviceExtensionCount;
+}
+
} // namespace vulkan