Vulkan: Load promoted extensions or core entrypoint as needed
Previously we would always assume that if the driver supported a Vulkan version it would also support extensions that were promoted in that version. This is not a spec requirement, so instead try to load the core entrypoints, and only if the version is not available, load the extension entrypoints. Also renames VulkanFunction members that are from promoted extension to not have a vendor prefix. Also tag the promoted extensions that are the same in a core version as available when that core version is available. This simplifies checking for features in the Vulkan backend. Bug: Change-Id: I0817c01b8838ba26070858abb0cbed030e3291df Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/16040 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: David Turner <digit@google.com>
This commit is contained in:
parent
33466973bc
commit
1249ada986
|
@ -39,8 +39,7 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
MaybeError Adapter::Initialize() {
|
||||
DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this));
|
||||
if (!mDeviceInfo.maintenance1 &&
|
||||
mDeviceInfo.properties.apiVersion < VK_MAKE_VERSION(1, 1, 0)) {
|
||||
if (!mDeviceInfo.maintenance1) {
|
||||
return DAWN_DEVICE_LOST_ERROR(
|
||||
"Dawn requires Vulkan 1.1 or Vulkan 1.0 with KHR_Maintenance1 in order to support "
|
||||
"viewport flipY");
|
||||
|
|
|
@ -190,29 +190,16 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
}
|
||||
|
||||
// Always request all extensions used to create VkSurfaceKHR objects so that they are
|
||||
// always available for embedders looking to create VkSurfaceKHR on our VkInstance.
|
||||
if (mGlobalInfo.fuchsiaImagePipeSwapchain) {
|
||||
layersToRequest.push_back(kLayerNameFuchsiaImagePipeSwapchain);
|
||||
usedKnobs.fuchsiaImagePipeSwapchain = true;
|
||||
}
|
||||
|
||||
// Always request all extensions used to create VkSurfaceKHR objects so that they are
|
||||
// always available for embedders looking to create VkSurfaceKHR on our VkInstance.
|
||||
if (mGlobalInfo.macosSurface) {
|
||||
extensionsToRequest.push_back(kExtensionNameMvkMacosSurface);
|
||||
usedKnobs.macosSurface = true;
|
||||
}
|
||||
if (mGlobalInfo.externalMemoryCapabilities) {
|
||||
extensionsToRequest.push_back(kExtensionNameKhrExternalMemoryCapabilities);
|
||||
usedKnobs.externalMemoryCapabilities = true;
|
||||
}
|
||||
if (mGlobalInfo.externalSemaphoreCapabilities) {
|
||||
extensionsToRequest.push_back(kExtensionNameKhrExternalSemaphoreCapabilities);
|
||||
usedKnobs.externalSemaphoreCapabilities = true;
|
||||
}
|
||||
if (mGlobalInfo.getPhysicalDeviceProperties2) {
|
||||
extensionsToRequest.push_back(kExtensionNameKhrGetPhysicalDeviceProperties2);
|
||||
usedKnobs.getPhysicalDeviceProperties2 = true;
|
||||
}
|
||||
if (mGlobalInfo.surface) {
|
||||
extensionsToRequest.push_back(kExtensionNameKhrSurface);
|
||||
usedKnobs.surface = true;
|
||||
|
@ -238,6 +225,28 @@ namespace dawn_native { namespace vulkan {
|
|||
usedKnobs.fuchsiaImagePipeSurface = true;
|
||||
}
|
||||
|
||||
// Mark the promoted extensions as present if the core version in which they were promoted
|
||||
// is used. This allows having a single boolean that checks if the functionality from that
|
||||
// extension is available (instead of checking extension || coreVersion).
|
||||
if (mGlobalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
|
||||
usedKnobs.getPhysicalDeviceProperties2 = true;
|
||||
usedKnobs.externalMemoryCapabilities = true;
|
||||
usedKnobs.externalSemaphoreCapabilities = true;
|
||||
} else {
|
||||
if (mGlobalInfo.externalMemoryCapabilities) {
|
||||
extensionsToRequest.push_back(kExtensionNameKhrExternalMemoryCapabilities);
|
||||
usedKnobs.externalMemoryCapabilities = true;
|
||||
}
|
||||
if (mGlobalInfo.externalSemaphoreCapabilities) {
|
||||
extensionsToRequest.push_back(kExtensionNameKhrExternalSemaphoreCapabilities);
|
||||
usedKnobs.externalSemaphoreCapabilities = true;
|
||||
}
|
||||
if (mGlobalInfo.getPhysicalDeviceProperties2) {
|
||||
extensionsToRequest.push_back(kExtensionNameKhrGetPhysicalDeviceProperties2);
|
||||
usedKnobs.getPhysicalDeviceProperties2 = true;
|
||||
}
|
||||
}
|
||||
|
||||
VkApplicationInfo appInfo;
|
||||
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
appInfo.pNext = nullptr;
|
||||
|
|
|
@ -41,12 +41,15 @@ namespace dawn_native { namespace vulkan {
|
|||
return {};
|
||||
}
|
||||
|
||||
#define GET_INSTANCE_PROC(name) \
|
||||
name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(instance, "vk" #name)); \
|
||||
#define GET_INSTANCE_PROC_BASE(name, procName) \
|
||||
name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(instance, "vk" #procName)); \
|
||||
if (name == nullptr) { \
|
||||
return DAWN_DEVICE_LOST_ERROR(std::string("Couldn't get proc vk") + #name); \
|
||||
return DAWN_DEVICE_LOST_ERROR(std::string("Couldn't get proc vk") + #procName); \
|
||||
}
|
||||
|
||||
#define GET_INSTANCE_PROC(name) GET_INSTANCE_PROC_BASE(name, name)
|
||||
#define GET_INSTANCE_PROC_VENDOR(name, vendor) GET_INSTANCE_PROC_BASE(name, name##vendor)
|
||||
|
||||
MaybeError VulkanFunctions::LoadInstanceProcs(VkInstance instance,
|
||||
const VulkanGlobalInfo& globalInfo) {
|
||||
// Load this proc first so that we can destroy the instance even if some other
|
||||
|
@ -73,26 +76,36 @@ namespace dawn_native { namespace vulkan {
|
|||
GET_INSTANCE_PROC(DestroyDebugReportCallbackEXT);
|
||||
}
|
||||
|
||||
// Vulkan 1.1 is not required to report promoted extensions from 1.0
|
||||
if (globalInfo.externalMemoryCapabilities ||
|
||||
globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceExternalBufferPropertiesKHR);
|
||||
// Vulkan 1.1 is not required to report promoted extensions from 1.0 and is not required to
|
||||
// support the vendor entrypoint in GetProcAddress.
|
||||
if (globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceExternalBufferProperties);
|
||||
} else if (globalInfo.externalMemoryCapabilities) {
|
||||
GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceExternalBufferProperties, KHR);
|
||||
}
|
||||
|
||||
if (globalInfo.externalSemaphoreCapabilities ||
|
||||
globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceExternalSemaphorePropertiesKHR);
|
||||
if (globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceExternalSemaphoreProperties);
|
||||
} else if (globalInfo.externalSemaphoreCapabilities) {
|
||||
GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceExternalSemaphoreProperties, KHR);
|
||||
}
|
||||
|
||||
if (globalInfo.getPhysicalDeviceProperties2 ||
|
||||
globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceFeatures2KHR);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceProperties2KHR);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceFormatProperties2KHR);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceImageFormatProperties2KHR);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceQueueFamilyProperties2KHR);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceMemoryProperties2KHR);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceSparseImageFormatProperties2KHR);
|
||||
if (globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceFeatures2);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceProperties2);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceFormatProperties2);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceImageFormatProperties2);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceQueueFamilyProperties2);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceMemoryProperties2);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceSparseImageFormatProperties2);
|
||||
} else if (globalInfo.getPhysicalDeviceProperties2) {
|
||||
GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceFeatures2, KHR);
|
||||
GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceProperties2, KHR);
|
||||
GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceFormatProperties2, KHR);
|
||||
GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceImageFormatProperties2, KHR);
|
||||
GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceQueueFamilyProperties2, KHR);
|
||||
GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceMemoryProperties2, KHR);
|
||||
GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceSparseImageFormatProperties2, KHR);
|
||||
}
|
||||
|
||||
if (globalInfo.surface) {
|
||||
|
|
|
@ -84,27 +84,28 @@ namespace dawn_native { namespace vulkan {
|
|||
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR =
|
||||
nullptr;
|
||||
|
||||
// Core Vulkan 1.1 promoted extensions
|
||||
// Core Vulkan 1.1 promoted extensions, set if either the core version or the extension is
|
||||
// present.
|
||||
|
||||
// VK_KHR_external_memory_capabilities
|
||||
PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR
|
||||
GetPhysicalDeviceExternalBufferPropertiesKHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceExternalBufferProperties GetPhysicalDeviceExternalBufferProperties =
|
||||
nullptr;
|
||||
|
||||
// VK_KHR_external_semaphore_capabilities
|
||||
PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR
|
||||
GetPhysicalDeviceExternalSemaphorePropertiesKHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceExternalSemaphoreProperties
|
||||
GetPhysicalDeviceExternalSemaphoreProperties = nullptr;
|
||||
|
||||
// VK_KHR_get_physical_device_properties2
|
||||
PFN_vkGetPhysicalDeviceFeatures2KHR GetPhysicalDeviceFeatures2KHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceProperties2KHR GetPhysicalDeviceProperties2KHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceFormatProperties2KHR GetPhysicalDeviceFormatProperties2KHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceImageFormatProperties2KHR
|
||||
GetPhysicalDeviceImageFormatProperties2KHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR
|
||||
GetPhysicalDeviceQueueFamilyProperties2KHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceMemoryProperties2KHR GetPhysicalDeviceMemoryProperties2KHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR
|
||||
GetPhysicalDeviceSparseImageFormatProperties2KHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceFeatures2 GetPhysicalDeviceFeatures2 = nullptr;
|
||||
PFN_vkGetPhysicalDeviceProperties2 GetPhysicalDeviceProperties2 = nullptr;
|
||||
PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysicalDeviceFormatProperties2 = nullptr;
|
||||
PFN_vkGetPhysicalDeviceImageFormatProperties2 GetPhysicalDeviceImageFormatProperties2 =
|
||||
nullptr;
|
||||
PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysicalDeviceQueueFamilyProperties2 =
|
||||
nullptr;
|
||||
PFN_vkGetPhysicalDeviceMemoryProperties2 GetPhysicalDeviceMemoryProperties2 = nullptr;
|
||||
PFN_vkGetPhysicalDeviceSparseImageFormatProperties2
|
||||
GetPhysicalDeviceSparseImageFormatProperties2 = nullptr;
|
||||
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
// FUCHSIA_image_pipe_surface
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "dawn_native/vulkan/VulkanInfo.h"
|
||||
|
||||
#include "common/Log.h"
|
||||
#include "dawn_native/vulkan/AdapterVk.h"
|
||||
#include "dawn_native/vulkan/BackendVk.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
|
@ -313,6 +314,11 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
}
|
||||
|
||||
// Mark the extensions promoted to Vulkan 1.1 as available.
|
||||
if (info.properties.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
|
||||
info.maintenance1 = true;
|
||||
}
|
||||
|
||||
// TODO(cwallez@chromium.org): gather info about formats
|
||||
|
||||
return info;
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace dawn_native { namespace vulkan {
|
|||
struct VulkanDeviceKnobs {
|
||||
VkPhysicalDeviceFeatures features;
|
||||
|
||||
// Extensions
|
||||
// Extensions, promoted extensions are set to true if their core version is supported.
|
||||
bool debugMarker = false;
|
||||
bool externalMemory = false;
|
||||
bool externalMemoryFD = false;
|
||||
|
|
|
@ -41,13 +41,13 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
|||
formatProps.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
|
||||
formatProps.pNext = &formatModifierPropsList;
|
||||
|
||||
fn.GetPhysicalDeviceFormatProperties2KHR(physicalDevice, format, &formatProps);
|
||||
fn.GetPhysicalDeviceFormatProperties2(physicalDevice, format, &formatProps);
|
||||
|
||||
uint32_t modifierCount = formatModifierPropsList.drmFormatModifierCount;
|
||||
std::vector<VkDrmFormatModifierPropertiesEXT> formatModifierProps(modifierCount);
|
||||
formatModifierPropsList.pDrmFormatModifierProperties = formatModifierProps.data();
|
||||
|
||||
fn.GetPhysicalDeviceFormatProperties2KHR(physicalDevice, format, &formatProps);
|
||||
fn.GetPhysicalDeviceFormatProperties2(physicalDevice, format, &formatProps);
|
||||
for (const auto& props : formatModifierProps) {
|
||||
if (props.drmFormatModifier == modifier) {
|
||||
uint32_t count = props.drmFormatModifierPlaneCount;
|
||||
|
@ -141,8 +141,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
|||
imageFormatProps.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
|
||||
imageFormatProps.pNext = &externalImageFormatProps;
|
||||
|
||||
VkResult result =
|
||||
VkResult::WrapUnsafe(mDevice->fn.GetPhysicalDeviceImageFormatProperties2KHR(
|
||||
VkResult result = VkResult::WrapUnsafe(mDevice->fn.GetPhysicalDeviceImageFormatProperties2(
|
||||
physicalDevice, &imageFormatInfo, &imageFormatProps));
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
|
|
|
@ -66,10 +66,8 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
|||
formatProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR;
|
||||
formatProperties.pNext = &externalFormatProperties;
|
||||
|
||||
VkResult result =
|
||||
VkResult::WrapUnsafe(mDevice->fn.GetPhysicalDeviceImageFormatProperties2KHR(
|
||||
ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &formatInfo,
|
||||
&formatProperties));
|
||||
VkResult result = VkResult::WrapUnsafe(mDevice->fn.GetPhysicalDeviceImageFormatProperties2(
|
||||
ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &formatInfo, &formatProperties));
|
||||
|
||||
// If handle not supported, result == VK_ERROR_FORMAT_NOT_SUPPORTED
|
||||
if (result != VK_SUCCESS) {
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
|||
formatProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR;
|
||||
formatProperties.pNext = &externalFormatProperties;
|
||||
|
||||
VkResult result = mDevice->fn.GetPhysicalDeviceImageFormatProperties2KHR(
|
||||
VkResult result = mDevice->fn.GetPhysicalDeviceImageFormatProperties2(
|
||||
ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &formatInfo, &formatProperties);
|
||||
|
||||
// If handle not supported, result == VK_ERROR_FORMAT_NOT_SUPPORTED
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
|||
semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR;
|
||||
semaphoreProperties.pNext = nullptr;
|
||||
|
||||
mDevice->fn.GetPhysicalDeviceExternalSemaphorePropertiesKHR(
|
||||
mDevice->fn.GetPhysicalDeviceExternalSemaphoreProperties(
|
||||
ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &semaphoreInfo,
|
||||
&semaphoreProperties);
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
|||
semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR;
|
||||
semaphoreProperties.pNext = nullptr;
|
||||
|
||||
mDevice->fn.GetPhysicalDeviceExternalSemaphorePropertiesKHR(
|
||||
mDevice->fn.GetPhysicalDeviceExternalSemaphoreProperties(
|
||||
ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &semaphoreInfo,
|
||||
&semaphoreProperties);
|
||||
|
||||
|
|
Loading…
Reference in New Issue