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>
This commit is contained in:
parent
2532a718c5
commit
265fb062be
|
@ -39,7 +39,7 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
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 @@ namespace dawn_native { namespace vulkan {
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -665,7 +665,7 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
|
||||
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 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
|
||||
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 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
|
||||
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 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
|
||||
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 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
|
||||
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 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -268,54 +268,17 @@ namespace dawn_native { namespace vulkan {
|
|||
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 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
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 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
|
||||
// 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 @@ namespace dawn_native { namespace vulkan {
|
|||
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),
|
||||
|
|
|
@ -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 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -70,6 +70,62 @@ namespace dawn_native { namespace vulkan {
|
|||
// 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_
|
||||
|
|
|
@ -278,35 +278,35 @@ namespace dawn_native { namespace vulkan {
|
|||
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);
|
||||
|
|
|
@ -28,10 +28,6 @@ namespace dawn_native { namespace vulkan {
|
|||
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 @@ namespace dawn_native { namespace vulkan {
|
|||
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 @@ namespace dawn_native { namespace vulkan {
|
|||
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
|
||||
|
|
|
@ -31,23 +31,6 @@ namespace dawn_native { namespace vulkan {
|
|||
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 @@ namespace dawn_native { namespace vulkan {
|
|||
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 @@ namespace dawn_native { namespace vulkan {
|
|||
std::vector<VkMemoryHeap> memoryHeaps;
|
||||
|
||||
std::vector<VkLayerProperties> layers;
|
||||
std::vector<VkExtensionProperties> extensions;
|
||||
// TODO(cwallez@chromium.org): layer instance extensions
|
||||
};
|
||||
|
||||
|
|
|
@ -61,13 +61,9 @@ 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 &&
|
||||
deviceInfo.externalMemoryDmaBuf && deviceInfo.imageDrmFormatModifier;
|
||||
mSupported = deviceInfo.HasExt(DeviceExt::ExternalMemoryFD) &&
|
||||
deviceInfo.HasExt(DeviceExt::ImageDrmFormatModifier);
|
||||
}
|
||||
|
||||
Service::~Service() = default;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue