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:
Corentin Wallez 2020-02-24 15:08:18 +00:00 committed by Commit Bot service account
parent 33466973bc
commit 1249ada986
11 changed files with 90 additions and 65 deletions

View File

@ -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");

View File

@ -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;

View File

@ -41,12 +41,15 @@ namespace dawn_native { namespace vulkan {
return {};
}
#define GET_INSTANCE_PROC(name) \
name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(instance, "vk" #name)); \
if (name == nullptr) { \
return DAWN_DEVICE_LOST_ERROR(std::string("Couldn't get proc 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") + #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) {

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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,9 +141,8 @@ 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(
physicalDevice, &imageFormatInfo, &imageFormatProps));
VkResult result = VkResult::WrapUnsafe(mDevice->fn.GetPhysicalDeviceImageFormatProperties2(
physicalDevice, &imageFormatInfo, &imageFormatProps));
if (result != VK_SUCCESS) {
return false;
}

View File

@ -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) {

View File

@ -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

View File

@ -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);

View File

@ -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);