Vulkan: handle Device extensions more programmatically
Similarly to the CL for Instance extensions, it makes each device
extension linked to an enum class and a bitset. Logic surrounding device
extensions is changed to take advantage of this to be more programmatic
and less error prone when adding support for a new extension.
Bug: dawn:457
Change-Id: Iecf623c40b890b7e00ba972d5eac0712866692b5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/22941
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/vulkan/AdapterVk.cpp b/src/dawn_native/vulkan/AdapterVk.cpp
index c220a8e..43ed6ac 100644
--- a/src/dawn_native/vulkan/AdapterVk.cpp
+++ b/src/dawn_native/vulkan/AdapterVk.cpp
@@ -39,7 +39,7 @@
MaybeError Adapter::Initialize() {
DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this));
- if (!mDeviceInfo.maintenance1) {
+ if (!mDeviceInfo.HasExt(DeviceExt::Maintenance1)) {
return DAWN_INTERNAL_ERROR(
"Dawn requires Vulkan 1.1 or Vulkan 1.0 with KHR_Maintenance1 in order to support "
"viewport flipY");
@@ -74,9 +74,9 @@
mSupportedExtensions.EnableExtension(Extension::TextureCompressionBC);
}
- if (mDeviceInfo.shaderFloat16Int8 &&
+ if (mDeviceInfo.HasExt(DeviceExt::ShaderFloat16Int8) &&
mDeviceInfo.shaderFloat16Int8Features.shaderFloat16 == VK_TRUE &&
- mDeviceInfo._16BitStorage &&
+ mDeviceInfo.HasExt(DeviceExt::_16BitStorage) &&
mDeviceInfo._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess == VK_TRUE) {
mSupportedExtensions.EnableExtension(Extension::ShaderFloat16);
}
diff --git a/src/dawn_native/vulkan/CommandBufferVk.cpp b/src/dawn_native/vulkan/CommandBufferVk.cpp
index ccd04ea..f1e3e46 100644
--- a/src/dawn_native/vulkan/CommandBufferVk.cpp
+++ b/src/dawn_native/vulkan/CommandBufferVk.cpp
@@ -665,7 +665,7 @@
}
case Command::InsertDebugMarker: {
- if (device->GetDeviceInfo().debugMarker) {
+ if (device->GetDeviceInfo().HasExt(DeviceExt::DebugMarker)) {
InsertDebugMarkerCmd* cmd = mCommands.NextCommand<InsertDebugMarkerCmd>();
const char* label = mCommands.NextData<char>(cmd->length + 1);
VkDebugMarkerMarkerInfoEXT markerInfo;
@@ -685,7 +685,7 @@
}
case Command::PopDebugGroup: {
- if (device->GetDeviceInfo().debugMarker) {
+ if (device->GetDeviceInfo().HasExt(DeviceExt::DebugMarker)) {
mCommands.NextCommand<PopDebugGroupCmd>();
device->fn.CmdDebugMarkerEndEXT(commands);
} else {
@@ -695,7 +695,7 @@
}
case Command::PushDebugGroup: {
- if (device->GetDeviceInfo().debugMarker) {
+ if (device->GetDeviceInfo().HasExt(DeviceExt::DebugMarker)) {
PushDebugGroupCmd* cmd = mCommands.NextCommand<PushDebugGroupCmd>();
const char* label = mCommands.NextData<char>(cmd->length + 1);
VkDebugMarkerMarkerInfoEXT markerInfo;
@@ -812,7 +812,7 @@
}
case Command::InsertDebugMarker: {
- if (device->GetDeviceInfo().debugMarker) {
+ if (device->GetDeviceInfo().HasExt(DeviceExt::DebugMarker)) {
InsertDebugMarkerCmd* cmd = iter->NextCommand<InsertDebugMarkerCmd>();
const char* label = iter->NextData<char>(cmd->length + 1);
VkDebugMarkerMarkerInfoEXT markerInfo;
@@ -832,7 +832,7 @@
}
case Command::PopDebugGroup: {
- if (device->GetDeviceInfo().debugMarker) {
+ if (device->GetDeviceInfo().HasExt(DeviceExt::DebugMarker)) {
iter->NextCommand<PopDebugGroupCmd>();
device->fn.CmdDebugMarkerEndEXT(commands);
} else {
@@ -842,7 +842,7 @@
}
case Command::PushDebugGroup: {
- if (device->GetDeviceInfo().debugMarker) {
+ if (device->GetDeviceInfo().HasExt(DeviceExt::DebugMarker)) {
PushDebugGroupCmd* cmd = iter->NextCommand<PushDebugGroupCmd>();
const char* label = iter->NextData<char>(cmd->length + 1);
VkDebugMarkerMarkerInfoEXT markerInfo;
diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp
index fb116a1..bb16f84 100644
--- a/src/dawn_native/vulkan/DeviceVk.cpp
+++ b/src/dawn_native/vulkan/DeviceVk.cpp
@@ -268,54 +268,17 @@
ResultOrError<VulkanDeviceKnobs> Device::CreateDevice(VkPhysicalDevice physicalDevice) {
VulkanDeviceKnobs usedKnobs = {};
- float zero = 0.0f;
- std::vector<const char*> layersToRequest;
- std::vector<const char*> extensionsToRequest;
- std::vector<VkDeviceQueueCreateInfo> queuesToRequest;
+ // Default to asking for all avilable known extensions.
+ usedKnobs.extensions = mDeviceInfo.extensions;
- if (mDeviceInfo.debugMarker) {
- extensionsToRequest.push_back(kExtensionNameExtDebugMarker);
- usedKnobs.debugMarker = true;
- }
- if (mDeviceInfo.externalMemory) {
- extensionsToRequest.push_back(kExtensionNameKhrExternalMemory);
- usedKnobs.externalMemory = true;
- }
- if (mDeviceInfo.externalMemoryFD) {
- extensionsToRequest.push_back(kExtensionNameKhrExternalMemoryFD);
- usedKnobs.externalMemoryFD = true;
- }
- if (mDeviceInfo.externalMemoryDmaBuf) {
- extensionsToRequest.push_back(kExtensionNameExtExternalMemoryDmaBuf);
- usedKnobs.externalMemoryDmaBuf = true;
- }
- if (mDeviceInfo.imageDrmFormatModifier) {
- extensionsToRequest.push_back(kExtensionNameExtImageDrmFormatModifier);
- usedKnobs.imageDrmFormatModifier = true;
- }
- if (mDeviceInfo.externalMemoryZirconHandle) {
- extensionsToRequest.push_back(kExtensionNameFuchsiaExternalMemory);
- usedKnobs.externalMemoryZirconHandle = true;
- }
- if (mDeviceInfo.externalSemaphore) {
- extensionsToRequest.push_back(kExtensionNameKhrExternalSemaphore);
- usedKnobs.externalSemaphore = true;
- }
- if (mDeviceInfo.externalSemaphoreFD) {
- extensionsToRequest.push_back(kExtensionNameKhrExternalSemaphoreFD);
- usedKnobs.externalSemaphoreFD = true;
- }
- if (mDeviceInfo.externalSemaphoreZirconHandle) {
- extensionsToRequest.push_back(kExtensionNameFuchsiaExternalSemaphore);
- usedKnobs.externalSemaphoreZirconHandle = true;
- }
- if (mDeviceInfo.swapchain) {
- extensionsToRequest.push_back(kExtensionNameKhrSwapchain);
- usedKnobs.swapchain = true;
- }
- if (mDeviceInfo.maintenance1) {
- extensionsToRequest.push_back(kExtensionNameKhrMaintenance1);
- usedKnobs.maintenance1 = true;
+ // However only request the extensions that haven't been promoted in the device's apiVersion
+ std::vector<const char*> extensionNames;
+ for (uint32_t ext : IterateBitSet(usedKnobs.extensions.extensionBitSet)) {
+ const DeviceExtInfo& info = GetDeviceExtInfo(static_cast<DeviceExt>(ext));
+
+ if (info.versionPromoted > mDeviceInfo.properties.apiVersion) {
+ extensionNames.push_back(info.name);
+ }
}
// Always require independentBlend because it is a core Dawn feature
@@ -333,21 +296,13 @@
if (IsExtensionEnabled(Extension::ShaderFloat16)) {
const VulkanDeviceInfo& deviceInfo = ToBackend(GetAdapter())->GetDeviceInfo();
- ASSERT(deviceInfo.shaderFloat16Int8 &&
+ ASSERT(deviceInfo.HasExt(DeviceExt::ShaderFloat16Int8) &&
deviceInfo.shaderFloat16Int8Features.shaderFloat16 == VK_TRUE &&
- deviceInfo._16BitStorage &&
+ deviceInfo.HasExt(DeviceExt::_16BitStorage) &&
deviceInfo._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess == VK_TRUE);
- usedKnobs.shaderFloat16Int8 = true;
usedKnobs.shaderFloat16Int8Features.shaderFloat16 = VK_TRUE;
- extensionsToRequest.push_back(kExtensionNameKhrShaderFloat16Int8);
-
- usedKnobs._16BitStorage = true;
usedKnobs._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess = VK_TRUE;
- // VK_KHR_16bit_storage is promoted to Vulkan 1.1.
- if (deviceInfo.properties.apiVersion < VK_MAKE_VERSION(1, 1, 0)) {
- extensionsToRequest.push_back(kExtensionNameKhr16BitStorage);
- }
}
// Find a universal queue family
@@ -370,6 +325,8 @@
}
// Choose to create a single universal queue
+ std::vector<VkDeviceQueueCreateInfo> queuesToRequest;
+ float zero = 0.0f;
{
VkDeviceQueueCreateInfo queueCreateInfo;
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
@@ -388,10 +345,10 @@
createInfo.flags = 0;
createInfo.queueCreateInfoCount = static_cast<uint32_t>(queuesToRequest.size());
createInfo.pQueueCreateInfos = queuesToRequest.data();
- createInfo.enabledLayerCount = static_cast<uint32_t>(layersToRequest.size());
- createInfo.ppEnabledLayerNames = layersToRequest.data();
- createInfo.enabledExtensionCount = static_cast<uint32_t>(extensionsToRequest.size());
- createInfo.ppEnabledExtensionNames = extensionsToRequest.data();
+ createInfo.enabledLayerCount = 0;
+ createInfo.ppEnabledLayerNames = nullptr;
+ createInfo.enabledExtensionCount = static_cast<uint32_t>(extensionNames.size());
+ createInfo.ppEnabledExtensionNames = extensionNames.data();
createInfo.pEnabledFeatures = &usedKnobs.features;
DAWN_TRY(CheckVkSuccess(fn.CreateDevice(physicalDevice, &createInfo, nullptr, &mVkDevice),
diff --git a/src/dawn_native/vulkan/VulkanExtensions.cpp b/src/dawn_native/vulkan/VulkanExtensions.cpp
index ea0ccab..353f087 100644
--- a/src/dawn_native/vulkan/VulkanExtensions.cpp
+++ b/src/dawn_native/vulkan/VulkanExtensions.cpp
@@ -23,6 +23,7 @@
namespace dawn_native { namespace vulkan {
static constexpr uint32_t VulkanVersion_1_1 = VK_MAKE_VERSION(1, 1, 0);
+ static constexpr uint32_t VulkanVersion_1_2 = VK_MAKE_VERSION(1, 2, 0);
static constexpr uint32_t NeverPromoted = std::numeric_limits<uint32_t>::max();
// A static array for InstanceExtInfo that can be indexed with InstanceExts.
@@ -132,4 +133,154 @@
}
}
+ static constexpr size_t kDeviceExtCount = static_cast<size_t>(DeviceExt::EnumCount);
+ static constexpr std::array<DeviceExtInfo, kDeviceExtCount> sDeviceExtInfos{{
+ //
+ {DeviceExt::Maintenance1, "VK_KHR_maintenance1", VulkanVersion_1_1},
+ {DeviceExt::ExternalMemory, "VK_KHR_external_memory", VulkanVersion_1_1},
+ {DeviceExt::ExternalSemaphore, "VK_KHR_external_semaphore", VulkanVersion_1_1},
+ {DeviceExt::_16BitStorage, "VK_KHR_16bit_storage", VulkanVersion_1_1},
+
+ {DeviceExt::ShaderFloat16Int8, "VK_KHR_shader_float16_int8", VulkanVersion_1_2},
+
+ {DeviceExt::ExternalMemoryFD, "VK_KHR_external_memory_fd", NeverPromoted},
+ {DeviceExt::ExternalMemoryDmaBuf, "VK_EXT_external_memory_dma_buf", NeverPromoted},
+ {DeviceExt::ExternalMemoryZirconHandle, "VK_FUCHSIA_external_memory", NeverPromoted},
+ {DeviceExt::ExternalSemaphoreFD, "VK_KHR_external_semaphore_fd", NeverPromoted},
+ {DeviceExt::ExternalSemaphoreZirconHandle, "VK_FUCHSIA_external_semaphore", NeverPromoted},
+
+ {DeviceExt::DebugMarker, "VK_EXT_debug_marker", NeverPromoted},
+ {DeviceExt::ImageDrmFormatModifier, "VK_EXT_image_drm_format_modifier", NeverPromoted},
+ {DeviceExt::Swapchain, "VK_KHR_swapchain", NeverPromoted},
+ //
+ }};
+
+ void DeviceExtSet::Set(DeviceExt extension, bool enabled) {
+ extensionBitSet.set(static_cast<uint32_t>(extension), enabled);
+ }
+
+ bool DeviceExtSet::Has(DeviceExt extension) const {
+ return extensionBitSet[static_cast<uint32_t>(extension)];
+ }
+
+ const DeviceExtInfo& GetDeviceExtInfo(DeviceExt ext) {
+ uint32_t index = static_cast<uint32_t>(ext);
+ ASSERT(index < sDeviceExtInfos.size());
+ ASSERT(sDeviceExtInfos[index].index == ext);
+ return sDeviceExtInfos[index];
+ }
+
+ std::unordered_map<std::string, DeviceExt> CreateDeviceExtNameMap() {
+ std::unordered_map<std::string, DeviceExt> result;
+ for (const DeviceExtInfo& info : sDeviceExtInfos) {
+ result[info.name] = info.index;
+ }
+ return result;
+ }
+
+ DeviceExtSet EnsureDependencies(const DeviceExtSet& advertisedExts,
+ const InstanceExtSet& instanceExts) {
+ // This is very similar to EnsureDependencies for instanceExtSet. See comment there for
+ // an explanation of what happens.
+ DeviceExtSet visitedSet;
+ DeviceExtSet trimmedSet;
+
+ auto HasDep = [&](DeviceExt ext) -> bool {
+ ASSERT(visitedSet.Has(ext));
+ return trimmedSet.Has(ext);
+ };
+
+ for (uint32_t i = 0; i < sDeviceExtInfos.size(); i++) {
+ DeviceExt ext = static_cast<DeviceExt>(i);
+
+ bool hasDependencies = false;
+ switch (ext) {
+ case DeviceExt::DebugMarker:
+ // TODO(cwallez@chromium.org): VK_KHR_debug_report is deprecated, switch to
+ // using VK_KHR_debug_utils instead.
+ hasDependencies = instanceExts.Has(InstanceExt::DebugReport);
+ break;
+
+ case DeviceExt::ImageDrmFormatModifier:
+ // TODO(cwallez@chromium.org): ImageDrmFormatModifier actually requires:
+ // - VK_KHR_bind_memory2
+ // - VK_KHR_image_format_list
+ // - VK_KHR_sampler_ycbcr_conversion
+ //
+ // Also switch to using DeviceExt::GetPhysicalDeviceProperties2 when we decouple
+ // Instance / Device physical device extensions.
+ hasDependencies = instanceExts.Has(InstanceExt::GetPhysicalDeviceProperties2);
+ break;
+
+ case DeviceExt::Swapchain:
+ hasDependencies = instanceExts.Has(InstanceExt::Surface);
+ break;
+
+ case DeviceExt::Maintenance1:
+ hasDependencies = true;
+ break;
+
+ case DeviceExt::ShaderFloat16Int8:
+ // TODO(cwallez@chromium.org): switch to using
+ // DeviceExt::GetPhysicalDeviceProperties2 when we decouple Instance / Device
+ // physical device extensions.
+ hasDependencies = instanceExts.Has(InstanceExt::GetPhysicalDeviceProperties2);
+ break;
+
+ case DeviceExt::ExternalMemory:
+ // TODO(cwallez@chromium.org): switch to using
+ // DeviceExt::ExternalMemoryCapabilities when we decouple Instance / Device
+ // physical device extensions.
+ hasDependencies = instanceExts.Has(InstanceExt::ExternalMemoryCapabilities);
+ break;
+
+ case DeviceExt::ExternalSemaphore:
+ // TODO(cwallez@chromium.org): switch to using
+ // DeviceExt::ExternalSemaphoreCapabilities when we decouple Instance / Device
+ // physical device extensions.
+ hasDependencies = instanceExts.Has(InstanceExt::ExternalSemaphoreCapabilities);
+ break;
+
+ case DeviceExt::_16BitStorage:
+ // TODO(cwallez@chromium.org): switch to using
+ // DeviceExt::GetPhysicalDeviceProperties2 when we decouple Instance / Device
+ // physical device extensions.
+ // Also depends on VK_KHR_storage_buffer_storage_class
+ hasDependencies = instanceExts.Has(InstanceExt::GetPhysicalDeviceProperties2);
+ break;
+
+ case DeviceExt::ExternalMemoryFD:
+ case DeviceExt::ExternalMemoryZirconHandle:
+ hasDependencies = HasDep(DeviceExt::ExternalMemory);
+ break;
+
+ case DeviceExt::ExternalMemoryDmaBuf:
+ hasDependencies = HasDep(DeviceExt::ExternalMemoryFD);
+ break;
+
+ case DeviceExt::ExternalSemaphoreFD:
+ case DeviceExt::ExternalSemaphoreZirconHandle:
+ hasDependencies = HasDep(DeviceExt::ExternalSemaphore);
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ trimmedSet.Set(ext, hasDependencies && advertisedExts.Has(ext));
+ visitedSet.Set(ext, true);
+ }
+
+ return trimmedSet;
+ }
+
+ void MarkPromotedExtensions(DeviceExtSet* extensions, uint32_t version) {
+ for (const DeviceExtInfo& info : sDeviceExtInfos) {
+ if (info.versionPromoted <= version) {
+ extensions->Set(info.index, true);
+ }
+ }
+ }
+
}} // namespace dawn_native::vulkan
diff --git a/src/dawn_native/vulkan/VulkanExtensions.h b/src/dawn_native/vulkan/VulkanExtensions.h
index a604faa..184df0b 100644
--- a/src/dawn_native/vulkan/VulkanExtensions.h
+++ b/src/dawn_native/vulkan/VulkanExtensions.h
@@ -70,6 +70,62 @@
// extensions that don't have all their transitive dependencies in advertisedExts.
InstanceExtSet EnsureDependencies(const InstanceExtSet& advertisedExts);
+ // The list of known device extensions. They must be in dependency order (this is checked
+ // inside EnsureDependencies)
+ enum class DeviceExt {
+ // Promoted to 1.1
+ Maintenance1,
+ ExternalMemory,
+ ExternalSemaphore,
+ _16BitStorage,
+
+ // Promoted to 1.2
+ ShaderFloat16Int8,
+
+ // External* extensions
+ ExternalMemoryFD,
+ ExternalMemoryDmaBuf,
+ ExternalMemoryZirconHandle,
+ ExternalSemaphoreFD,
+ ExternalSemaphoreZirconHandle,
+
+ // Others
+ DebugMarker,
+ ImageDrmFormatModifier,
+ Swapchain,
+
+ EnumCount,
+ };
+
+ // A bitset wrapper that is indexed with DeviceExt.
+ struct DeviceExtSet {
+ std::bitset<static_cast<size_t>(DeviceExt::EnumCount)> extensionBitSet;
+ void Set(DeviceExt extension, bool enabled);
+ bool Has(DeviceExt extension) const;
+ };
+
+ // A bitset wrapper that is indexed with DeviceExt.
+ struct DeviceExtInfo {
+ DeviceExt index;
+ const char* name;
+ // The version in which this extension was promoted as built with VK_MAKE_VERSION,
+ // or NeverPromoted if it was never promoted.
+ uint32_t versionPromoted;
+ };
+
+ // Returns the information about a known DeviceExt
+ const DeviceExtInfo& GetDeviceExtInfo(DeviceExt ext);
+ // Returns a map that maps a Vulkan extension name to its DeviceExt.
+ std::unordered_map<std::string, DeviceExt> CreateDeviceExtNameMap();
+
+ // Sets entries in `extensions` to true if that entry was promoted in Vulkan version `version`
+ void MarkPromotedExtensions(DeviceExtSet* extensions, uint32_t version);
+ // From a set of extensions advertised as supported by the device (or promoted), remove all
+ // extensions that don't have all their transitive dependencies in advertisedExts or in
+ // instanceExts.
+ DeviceExtSet EnsureDependencies(const DeviceExtSet& advertisedExts,
+ const InstanceExtSet& instanceExts);
+
}} // namespace dawn_native::vulkan
#endif // DAWNNATIVE_VULKAN_VULKANEXTENSIONS_H_
diff --git a/src/dawn_native/vulkan/VulkanFunctions.cpp b/src/dawn_native/vulkan/VulkanFunctions.cpp
index e31f464..cc070f2 100644
--- a/src/dawn_native/vulkan/VulkanFunctions.cpp
+++ b/src/dawn_native/vulkan/VulkanFunctions.cpp
@@ -278,35 +278,35 @@
GET_DEVICE_PROC(UpdateDescriptorSets);
GET_DEVICE_PROC(WaitForFences);
- if (deviceInfo.debugMarker) {
+ if (deviceInfo.HasExt(DeviceExt::DebugMarker)) {
GET_DEVICE_PROC(CmdDebugMarkerBeginEXT);
GET_DEVICE_PROC(CmdDebugMarkerEndEXT);
GET_DEVICE_PROC(CmdDebugMarkerInsertEXT);
}
- if (deviceInfo.externalMemoryFD) {
+ if (deviceInfo.HasExt(DeviceExt::ExternalMemoryFD)) {
GET_DEVICE_PROC(GetMemoryFdKHR);
GET_DEVICE_PROC(GetMemoryFdPropertiesKHR);
}
- if (deviceInfo.externalSemaphoreFD) {
+ if (deviceInfo.HasExt(DeviceExt::ExternalSemaphoreFD)) {
GET_DEVICE_PROC(ImportSemaphoreFdKHR);
GET_DEVICE_PROC(GetSemaphoreFdKHR);
}
#if VK_USE_PLATFORM_FUCHSIA
- if (deviceInfo.externalMemoryZirconHandle) {
+ if (deviceInfo.HasExt(DeviceExt::ExternalMemoryZirconHandle)) {
GET_DEVICE_PROC(GetMemoryZirconHandleFUCHSIA);
GET_DEVICE_PROC(GetMemoryZirconHandlePropertiesFUCHSIA);
}
- if (deviceInfo.externalSemaphoreZirconHandle) {
+ if (deviceInfo.HasExt(DeviceExt::ExternalSemaphoreZirconHandle)) {
GET_DEVICE_PROC(ImportSemaphoreZirconHandleFUCHSIA);
GET_DEVICE_PROC(GetSemaphoreZirconHandleFUCHSIA);
}
#endif
- if (deviceInfo.swapchain) {
+ if (deviceInfo.HasExt(DeviceExt::Swapchain)) {
GET_DEVICE_PROC(CreateSwapchainKHR);
GET_DEVICE_PROC(DestroySwapchainKHR);
GET_DEVICE_PROC(GetSwapchainImagesKHR);
diff --git a/src/dawn_native/vulkan/VulkanInfo.cpp b/src/dawn_native/vulkan/VulkanInfo.cpp
index e713ba6..6b2346e 100644
--- a/src/dawn_native/vulkan/VulkanInfo.cpp
+++ b/src/dawn_native/vulkan/VulkanInfo.cpp
@@ -28,10 +28,6 @@
return strncmp(layer.layerName, name, VK_MAX_EXTENSION_NAME_SIZE) == 0;
}
- bool IsExtensionName(const VkExtensionProperties& extension, const char* name) {
- return strncmp(extension.extensionName, name, VK_MAX_EXTENSION_NAME_SIZE) == 0;
- }
-
bool EnumerateInstanceExtensions(const char* layerName,
const dawn_native::vulkan::VulkanFunctions& vkFunctions,
std::vector<VkExtensionProperties>* extensions) {
@@ -54,30 +50,14 @@
const char kLayerNameRenderDocCapture[] = "VK_LAYER_RENDERDOC_Capture";
const char kLayerNameFuchsiaImagePipeSwapchain[] = "VK_LAYER_FUCHSIA_imagepipe_swapchain";
- const char kExtensionNameExtDebugMarker[] = "VK_EXT_debug_marker";
- const char kExtensionNameKhrExternalMemory[] = "VK_KHR_external_memory";
- const char kExtensionNameKhrExternalMemoryCapabilities[] =
- "VK_KHR_external_memory_capabilities";
- const char kExtensionNameKhrExternalMemoryFD[] = "VK_KHR_external_memory_fd";
- const char kExtensionNameExtExternalMemoryDmaBuf[] = "VK_EXT_external_memory_dma_buf";
- const char kExtensionNameExtImageDrmFormatModifier[] = "VK_EXT_image_drm_format_modifier";
- const char kExtensionNameFuchsiaExternalMemory[] = "VK_FUCHSIA_external_memory";
- const char kExtensionNameKhrExternalSemaphore[] = "VK_KHR_external_semaphore";
- const char kExtensionNameKhrExternalSemaphoreCapabilities[] =
- "VK_KHR_external_semaphore_capabilities";
- const char kExtensionNameKhrExternalSemaphoreFD[] = "VK_KHR_external_semaphore_fd";
- const char kExtensionNameFuchsiaExternalSemaphore[] = "VK_FUCHSIA_external_semaphore";
- const char kExtensionNameKhrGetPhysicalDeviceProperties2[] =
- "VK_KHR_get_physical_device_properties2";
- const char kExtensionNameKhrSwapchain[] = "VK_KHR_swapchain";
- const char kExtensionNameKhrMaintenance1[] = "VK_KHR_maintenance1";
- const char kExtensionNameKhrShaderFloat16Int8[] = "VK_KHR_shader_float16_int8";
- const char kExtensionNameKhr16BitStorage[] = "VK_KHR_16bit_storage";
-
bool VulkanGlobalKnobs::HasExt(InstanceExt ext) const {
return extensions.Has(ext);
}
+ bool VulkanDeviceKnobs::HasExt(DeviceExt ext) const {
+ return extensions.Has(ext);
+ }
+
ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const Backend& backend) {
VulkanGlobalInfo info = {};
const VulkanFunctions& vkFunctions = backend.GetFunctions();
@@ -248,82 +228,47 @@
return DAWN_INTERNAL_ERROR("vkEnumerateDeviceExtensionProperties");
}
- info.extensions.resize(count);
- DAWN_TRY(CheckVkSuccess(vkFunctions.EnumerateDeviceExtensionProperties(
- physicalDevice, nullptr, &count, info.extensions.data()),
- "vkEnumerateDeviceExtensionProperties"));
+ std::vector<VkExtensionProperties> extensionsProperties;
+ extensionsProperties.resize(count);
+ DAWN_TRY(
+ CheckVkSuccess(vkFunctions.EnumerateDeviceExtensionProperties(
+ physicalDevice, nullptr, &count, extensionsProperties.data()),
+ "vkEnumerateDeviceExtensionProperties"));
- for (const auto& extension : info.extensions) {
- if (IsExtensionName(extension, kExtensionNameExtDebugMarker)) {
- info.debugMarker = true;
- }
- if (IsExtensionName(extension, kExtensionNameKhrExternalMemory)) {
- info.externalMemory = true;
- }
- if (IsExtensionName(extension, kExtensionNameKhrExternalMemoryFD)) {
- info.externalMemoryFD = true;
- }
- if (IsExtensionName(extension, kExtensionNameExtExternalMemoryDmaBuf)) {
- info.externalMemoryDmaBuf = true;
- }
- if (IsExtensionName(extension, kExtensionNameExtImageDrmFormatModifier)) {
- info.imageDrmFormatModifier = true;
- }
- if (IsExtensionName(extension, kExtensionNameFuchsiaExternalMemory)) {
- info.externalMemoryZirconHandle = true;
- }
- if (IsExtensionName(extension, kExtensionNameKhrExternalSemaphore)) {
- info.externalSemaphore = true;
- }
- if (IsExtensionName(extension, kExtensionNameKhrExternalSemaphoreFD)) {
- info.externalSemaphoreFD = true;
- }
- if (IsExtensionName(extension, kExtensionNameFuchsiaExternalSemaphore)) {
- info.externalSemaphoreZirconHandle = true;
- }
- if (IsExtensionName(extension, kExtensionNameKhrSwapchain)) {
- info.swapchain = true;
- }
- if (IsExtensionName(extension, kExtensionNameKhrMaintenance1)) {
- info.maintenance1 = true;
- }
- if (IsExtensionName(extension, kExtensionNameKhrShaderFloat16Int8) &&
- globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2)) {
- info.shaderFloat16Int8 = true;
- info.shaderFloat16Int8Features.sType =
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
+ std::unordered_map<std::string, DeviceExt> knownExts = CreateDeviceExtNameMap();
- VkPhysicalDeviceFeatures2KHR physicalDeviceFeatures2 = {};
- physicalDeviceFeatures2.sType =
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
- physicalDeviceFeatures2.pNext = &info.shaderFloat16Int8Features;
- vkFunctions.GetPhysicalDeviceFeatures2(physicalDevice,
- &physicalDeviceFeatures2);
- }
- if (IsExtensionName(extension, kExtensionNameKhr16BitStorage) &&
- globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2)) {
- info._16BitStorage = true;
+ for (const VkExtensionProperties& extension : extensionsProperties) {
+ auto it = knownExts.find(extension.extensionName);
+ if (it != knownExts.end()) {
+ info.extensions.Set(it->second, true);
}
}
+
+ MarkPromotedExtensions(&info.extensions, info.properties.apiVersion);
+ info.extensions = EnsureDependencies(info.extensions, globalInfo.extensions);
}
- // Mark the extensions promoted to Vulkan 1.1 as available.
- if (info.properties.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
- info.maintenance1 = true;
- }
+ // Gather additional information for some of the extensions
+ {
+ if (info.extensions.Has(DeviceExt::ShaderFloat16Int8)) {
+ info.shaderFloat16Int8Features.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
- // VK_KHR_16bit_storage is promoted to Vulkan 1.1, so gather information if either is
- // present, and mark the extension as available.
- if (info._16BitStorage || info.properties.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
- ASSERT(globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2));
- info._16BitStorage = true;
- info._16BitStorageFeatures.sType =
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
+ VkPhysicalDeviceFeatures2KHR physicalDeviceFeatures2 = {};
+ physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
+ physicalDeviceFeatures2.pNext = &info.shaderFloat16Int8Features;
+ vkFunctions.GetPhysicalDeviceFeatures2(physicalDevice, &physicalDeviceFeatures2);
+ }
- VkPhysicalDeviceFeatures2 physicalDeviceFeatures2 = {};
- physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
- physicalDeviceFeatures2.pNext = &info._16BitStorageFeatures;
- vkFunctions.GetPhysicalDeviceFeatures2(physicalDevice, &physicalDeviceFeatures2);
+ if (info.extensions.Has(DeviceExt::_16BitStorage)) {
+ info._16BitStorageFeatures.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
+
+ VkPhysicalDeviceFeatures2 physicalDeviceFeatures2 = {};
+ physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+ physicalDeviceFeatures2.pNext = &info._16BitStorageFeatures;
+ vkFunctions.GetPhysicalDeviceFeatures2(physicalDevice, &physicalDeviceFeatures2);
+ }
}
// TODO(cwallez@chromium.org): gather info about formats
diff --git a/src/dawn_native/vulkan/VulkanInfo.h b/src/dawn_native/vulkan/VulkanInfo.h
index a9d0818..6d0a756f 100644
--- a/src/dawn_native/vulkan/VulkanInfo.h
+++ b/src/dawn_native/vulkan/VulkanInfo.h
@@ -31,23 +31,6 @@
extern const char kLayerNameRenderDocCapture[];
extern const char kLayerNameFuchsiaImagePipeSwapchain[];
- extern const char kExtensionNameExtDebugMarker[];
- extern const char kExtensionNameKhrExternalMemory[];
- extern const char kExtensionNameKhrExternalMemoryCapabilities[];
- extern const char kExtensionNameKhrExternalMemoryFD[];
- extern const char kExtensionNameExtExternalMemoryDmaBuf[];
- extern const char kExtensionNameExtImageDrmFormatModifier[];
- extern const char kExtensionNameFuchsiaExternalMemory[];
- extern const char kExtensionNameKhrExternalSemaphore[];
- extern const char kExtensionNameKhrExternalSemaphoreCapabilities[];
- extern const char kExtensionNameKhrExternalSemaphoreFD[];
- extern const char kExtensionNameFuchsiaExternalSemaphore[];
- extern const char kExtensionNameKhrGetPhysicalDeviceProperties2[];
- extern const char kExtensionNameKhrSwapchain[];
- extern const char kExtensionNameKhrMaintenance1[];
- extern const char kExtensionNameKhrShaderFloat16Int8[];
- extern const char kExtensionNameKhr16BitStorage[];
-
// Global information - gathered before the instance is created
struct VulkanGlobalKnobs {
// Layers
@@ -72,20 +55,8 @@
VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shaderFloat16Int8Features;
VkPhysicalDevice16BitStorageFeaturesKHR _16BitStorageFeatures;
- // Extensions, promoted extensions are set to true if their core version is supported.
- bool debugMarker = false;
- bool externalMemory = false;
- bool externalMemoryFD = false;
- bool externalMemoryDmaBuf = false;
- bool imageDrmFormatModifier = false;
- bool externalMemoryZirconHandle = false;
- bool externalSemaphore = false;
- bool externalSemaphoreFD = false;
- bool externalSemaphoreZirconHandle = false;
- bool swapchain = false;
- bool maintenance1 = false;
- bool shaderFloat16Int8 = false;
- bool _16BitStorage = false;
+ bool HasExt(DeviceExt ext) const;
+ DeviceExtSet extensions;
};
struct VulkanDeviceInfo : VulkanDeviceKnobs {
@@ -96,7 +67,6 @@
std::vector<VkMemoryHeap> memoryHeaps;
std::vector<VkLayerProperties> layers;
- std::vector<VkExtensionProperties> extensions;
// TODO(cwallez@chromium.org): layer instance extensions
};
diff --git a/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp b/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp
index 240c6fe..4129745 100644
--- a/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp
+++ b/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp
@@ -61,13 +61,9 @@
Service::Service(Device* device) : mDevice(device) {
const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo();
- const VulkanGlobalInfo& globalInfo =
- ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo();
- mSupported = globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2) &&
- globalInfo.HasExt(InstanceExt::ExternalMemoryCapabilities) &&
- deviceInfo.externalMemory && deviceInfo.externalMemoryFD &&
- deviceInfo.externalMemoryDmaBuf && deviceInfo.imageDrmFormatModifier;
+ mSupported = deviceInfo.HasExt(DeviceExt::ExternalMemoryFD) &&
+ deviceInfo.HasExt(DeviceExt::ImageDrmFormatModifier);
}
Service::~Service() = default;
diff --git a/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp b/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp
index 57b74af..9905777 100644
--- a/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp
+++ b/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp
@@ -23,13 +23,7 @@
namespace dawn_native { namespace vulkan { namespace external_memory {
Service::Service(Device* device) : mDevice(device) {
- const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo();
- const VulkanGlobalInfo& globalInfo =
- ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo();
-
- mSupported = globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2) &&
- globalInfo.HasExt(InstanceExt::ExternalMemoryCapabilities) &&
- deviceInfo.externalMemory && deviceInfo.externalMemoryFD;
+ mSupported = device->GetDeviceInfo().HasExt(DeviceExt::ExternalMemoryFD);
}
Service::~Service() = default;
diff --git a/src/dawn_native/vulkan/external_memory/MemoryServiceZirconHandle.cpp b/src/dawn_native/vulkan/external_memory/MemoryServiceZirconHandle.cpp
index ab87a7f..08d8d63 100644
--- a/src/dawn_native/vulkan/external_memory/MemoryServiceZirconHandle.cpp
+++ b/src/dawn_native/vulkan/external_memory/MemoryServiceZirconHandle.cpp
@@ -23,13 +23,7 @@
namespace dawn_native { namespace vulkan { namespace external_memory {
Service::Service(Device* device) : mDevice(device) {
- const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo();
- const VulkanGlobalInfo& globalInfo =
- ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo();
-
- mSupported = globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2) &&
- globalInfo.HasExt(InstanceExt::ExternalMemoryCapabilities) &&
- deviceInfo.externalMemory && deviceInfo.externalMemoryFD;
+ mSupported = device->GetDeviceInfo().HasExt(DeviceExt::ExternalMemoryZirconHandle);
}
Service::~Service() = default;
diff --git a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp
index 222fcbb..aecc893 100644
--- a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp
+++ b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp
@@ -21,13 +21,7 @@
namespace dawn_native { namespace vulkan { namespace external_semaphore {
Service::Service(Device* device) : mDevice(device) {
- const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo();
- const VulkanGlobalInfo& globalInfo =
- ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo();
-
- mSupported = globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2) &&
- globalInfo.HasExt(InstanceExt::ExternalSemaphoreCapabilities) &&
- deviceInfo.externalSemaphore && deviceInfo.externalSemaphoreFD;
+ mSupported = device->GetDeviceInfo().HasExt(DeviceExt::ExternalSemaphoreFD);
// Early out before we try using extension functions
if (!mSupported) {
diff --git a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp
index 985cf4f..b4e3a62 100644
--- a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp
+++ b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp
@@ -21,13 +21,7 @@
namespace dawn_native { namespace vulkan { namespace external_semaphore {
Service::Service(Device* device) : mDevice(device) {
- const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo();
- const VulkanGlobalInfo& globalInfo =
- ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo();
-
- mSupported = globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2) &&
- globalInfo.HasExt(InstanceExt::ExternalSemaphoreCapabilities) &&
- deviceInfo.externalSemaphore && deviceInfo.externalSemaphoreFD;
+ mSupported = device->GetDeviceInfo().hasExt(DeviceExt::ExternalSemaphoreZirconHandle);
// Early out before we try using extension functions
if (!mSupported) {