Vulkan: Enumerate instance & device extensions provided by layers
Add instance & device extensions provided by layers prior to running
VerifyExtensionsPresent() so that we won't abort when required extensions
are provided in a layer. This happens particularly on Fuchsia as the
swapchain extension is implemented in a layer.
BUG=angleproject:2475
TEST=angle_end2end_tests on Fuchsia
Change-Id: I30385dfe55b14783a20d1410f1209d3e3ad10632
Reviewed-on: https://chromium-review.googlesource.com/c/1456487
Reviewed-by: Ian Elliott <ianelliott@google.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Courtney Goeltzenleuchter <courtneygo@google.com>
Commit-Queue: Michael Spang <spang@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp
index 2184322..5c0c847 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -613,6 +613,22 @@
instanceLayerProps.data()));
}
+ VulkanLayerVector enabledInstanceLayerNames;
+ if (mEnableValidationLayers)
+ {
+ bool layersRequested =
+ (attribs.get(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE, EGL_DONT_CARE) == EGL_TRUE);
+ mEnableValidationLayers = GetAvailableValidationLayers(instanceLayerProps, layersRequested,
+ &enabledInstanceLayerNames);
+ }
+
+ if (wsiLayer)
+ {
+ enabledInstanceLayerNames.push_back(wsiLayer);
+ }
+
+ // Enumerate instance extensions that are provided by the vulkan
+ // implementation and implicit layers.
uint32_t instanceExtensionCount = 0;
ANGLE_VK_TRY(displayVk,
vkEnumerateInstanceExtensionProperties(nullptr, &instanceExtensionCount, nullptr));
@@ -625,18 +641,17 @@
instanceExtensionProps.data()));
}
- VulkanLayerVector enabledLayerNames;
- if (mEnableValidationLayers)
+ // Enumerate instance extensions that are provided by explicit layers.
+ for (const char *layerName : enabledInstanceLayerNames)
{
- bool layersRequested =
- (attribs.get(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE, EGL_DONT_CARE) == EGL_TRUE);
- mEnableValidationLayers =
- GetAvailableValidationLayers(instanceLayerProps, layersRequested, &enabledLayerNames);
- }
-
- if (wsiLayer)
- {
- enabledLayerNames.push_back(wsiLayer);
+ uint32_t previousExtensionCount = instanceExtensionProps.size();
+ uint32_t instanceLayerExtensionCount = 0;
+ ANGLE_VK_TRY(displayVk, vkEnumerateInstanceExtensionProperties(
+ layerName, &instanceLayerExtensionCount, nullptr));
+ instanceExtensionProps.resize(previousExtensionCount + instanceLayerExtensionCount);
+ ANGLE_VK_TRY(displayVk, vkEnumerateInstanceExtensionProperties(
+ layerName, &instanceLayerExtensionCount,
+ instanceExtensionProps.data() + previousExtensionCount));
}
std::vector<const char *> enabledInstanceExtensions;
@@ -700,8 +715,8 @@
instanceInfo.enabledExtensionCount = static_cast<uint32_t>(enabledInstanceExtensions.size());
instanceInfo.ppEnabledExtensionNames =
enabledInstanceExtensions.empty() ? nullptr : enabledInstanceExtensions.data();
- instanceInfo.enabledLayerCount = enabledLayerNames.size();
- instanceInfo.ppEnabledLayerNames = enabledLayerNames.data();
+ instanceInfo.enabledLayerCount = enabledInstanceLayerNames.size();
+ instanceInfo.ppEnabledLayerNames = enabledInstanceLayerNames.data();
ANGLE_VK_TRY(displayVk, vkCreateInstance(&instanceInfo, nullptr, &mInstance));
@@ -815,6 +830,21 @@
deviceLayerProps.data()));
}
+ VulkanLayerVector enabledDeviceLayerNames;
+ if (mEnableValidationLayers)
+ {
+ mEnableValidationLayers =
+ GetAvailableValidationLayers(deviceLayerProps, false, &enabledDeviceLayerNames);
+ }
+
+ const char *wsiLayer = displayVk->getWSILayer();
+ if (wsiLayer)
+ {
+ enabledDeviceLayerNames.push_back(wsiLayer);
+ }
+
+ // Enumerate device extensions that are provided by the vulkan
+ // implementation and implicit layers.
uint32_t deviceExtensionCount = 0;
ANGLE_VK_TRY(displayVk, vkEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr,
&deviceExtensionCount, nullptr));
@@ -827,11 +857,18 @@
deviceExtensionProps.data()));
}
- VulkanLayerVector enabledLayerNames;
- if (mEnableValidationLayers)
+ // Enumerate device extensions that are provided by explicit layers.
+ for (const char *layerName : enabledDeviceLayerNames)
{
- mEnableValidationLayers =
- GetAvailableValidationLayers(deviceLayerProps, false, &enabledLayerNames);
+ uint32_t previousExtensionCount = deviceExtensionProps.size();
+ uint32_t deviceLayerExtensionCount = 0;
+ ANGLE_VK_TRY(displayVk,
+ vkEnumerateDeviceExtensionProperties(mPhysicalDevice, layerName,
+ &deviceLayerExtensionCount, nullptr));
+ deviceExtensionProps.resize(previousExtensionCount + deviceLayerExtensionCount);
+ ANGLE_VK_TRY(displayVk, vkEnumerateDeviceExtensionProperties(
+ mPhysicalDevice, layerName, &deviceLayerExtensionCount,
+ deviceExtensionProps.data() + previousExtensionCount));
}
std::vector<const char *> enabledDeviceExtensions;
@@ -875,8 +912,8 @@
createInfo.flags = 0;
createInfo.queueCreateInfoCount = 1;
createInfo.pQueueCreateInfos = &queueCreateInfo;
- createInfo.enabledLayerCount = enabledLayerNames.size();
- createInfo.ppEnabledLayerNames = enabledLayerNames.data();
+ createInfo.enabledLayerCount = enabledDeviceLayerNames.size();
+ createInfo.ppEnabledLayerNames = enabledDeviceLayerNames.data();
createInfo.enabledExtensionCount = static_cast<uint32_t>(enabledDeviceExtensions.size());
createInfo.ppEnabledExtensionNames =
enabledDeviceExtensions.empty() ? nullptr : enabledDeviceExtensions.data();