libvulkan: Fix dEQP-VK.api.device_init.create_instance_unsupported_extensions
The existing check was only executed if the driver reported at least
one instance extension, because it was part of filtering the extension
list down to just the ones supported by the driver. Now do it
separately, and before we do anything else.
Also changed the null driver to not report any extensions; reporting
an extension masked the bug for me when I ran this test before.
Change-Id: I2b62229c6acbc9406c036f1f1b766a21c03922d4
(cherry picked from commit 1f7e9e0e771ac4045c5f669290dc01b01dd01342)
diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp
index 68ca3c2..04705b7 100644
--- a/vulkan/libvulkan/loader.cpp
+++ b/vulkan/libvulkan/loader.cpp
@@ -515,50 +515,62 @@
Instance& instance = GetDispatchParent(*vkinstance);
VkResult result;
+ // Check that all enabled extensions are supported
+ InstanceExtensionSet enabled_extensions;
+ uint32_t num_driver_extensions = 0;
+ for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
+ const char* name = create_info->ppEnabledExtensionNames[i];
+ InstanceExtension id = InstanceExtensionFromName(name);
+ if (id != kInstanceExtensionCount) {
+ if (g_driver_instance_extensions[id]) {
+ num_driver_extensions++;
+ enabled_extensions.set(id);
+ continue;
+ }
+ if (id == kKHR_surface || id == kKHR_android_surface ||
+ id == kEXT_debug_report) {
+ enabled_extensions.set(id);
+ continue;
+ }
+ }
+ bool supported = false;
+ for (const auto& layer : instance.active_layers) {
+ if (layer.SupportsExtension(name))
+ supported = true;
+ }
+ if (!supported) {
+ ALOGE(
+ "requested instance extension '%s' not supported by "
+ "loader, driver, or any active layers",
+ name);
+ DestroyInstance_Bottom(instance.handle, allocator);
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+ }
+
VkInstanceCreateInfo driver_create_info = *create_info;
driver_create_info.enabledLayerCount = 0;
driver_create_info.ppEnabledLayerNames = nullptr;
-
- InstanceExtensionSet enabled_extensions;
driver_create_info.enabledExtensionCount = 0;
driver_create_info.ppEnabledExtensionNames = nullptr;
- size_t max_names =
- std::min(static_cast<size_t>(create_info->enabledExtensionCount),
- g_driver_instance_extensions.count());
- if (max_names > 0) {
- const char** names =
- static_cast<const char**>(alloca(max_names * sizeof(char*)));
+ if (num_driver_extensions > 0) {
+ const char** names = static_cast<const char**>(
+ alloca(num_driver_extensions * sizeof(char*)));
for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
const char* name = create_info->ppEnabledExtensionNames[i];
InstanceExtension id = InstanceExtensionFromName(name);
if (id != kInstanceExtensionCount) {
if (g_driver_instance_extensions[id]) {
names[driver_create_info.enabledExtensionCount++] = name;
- enabled_extensions.set(id);
continue;
}
- if (id == kKHR_surface || id == kKHR_android_surface ||
- id == kEXT_debug_report) {
- enabled_extensions.set(id);
- continue;
- }
- }
-
- bool supported = false;
- for (const auto& layer : instance.active_layers) {
- if (layer.SupportsExtension(name))
- supported = true;
- }
- if (!supported) {
- ALOGE(
- "requested instance extension '%s' not supported by "
- "loader, driver, or any active layers",
- name);
- DestroyInstance_Bottom(instance.handle, allocator);
- return VK_ERROR_EXTENSION_NOT_PRESENT;
}
}
driver_create_info.ppEnabledExtensionNames = names;
+ ALOG_ASSERT(
+ driver_create_info.enabledExtensionCount == num_driver_extensions,
+ "counted enabled driver instance extensions twice and got "
+ "different answers!");
}
result = g_hwdevice->CreateInstance(&driver_create_info, instance.alloc,
diff --git a/vulkan/nulldrv/null_driver.cpp b/vulkan/nulldrv/null_driver.cpp
index e12409c..b4e21db 100644
--- a/vulkan/nulldrv/null_driver.cpp
+++ b/vulkan/nulldrv/null_driver.cpp
@@ -214,10 +214,15 @@
"Driver vkEnumerateInstanceExtensionProperties shouldn't be called "
"with a layer name ('%s')",
layer_name);
- *count = 0;
- return VK_SUCCESS;
}
+// NOTE: Change this to zero to report and extension, which can be useful
+// for testing changes to the loader.
+#if 1
+ (void)properties; // unused
+ *count = 0;
+ return VK_SUCCESS;
+#else
const VkExtensionProperties kExtensions[] = {
{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}};
const uint32_t kExtensionsCount =
@@ -228,6 +233,7 @@
if (properties)
std::copy(kExtensions, kExtensions + *count, properties);
return *count < kExtensionsCount ? VK_INCOMPLETE : VK_SUCCESS;
+#endif
}
VKAPI_ATTR