Vulkan: correctly expose Vulkan entry points
This change fixes the advertisement of core Vulkan entry points as below:
1. GIPA returns a valid checked_proc for 1.1 core device APIs.
2. GDPA returns NULL for 1.1 core device APIs on a 1.0 physical device.
Bug: 134185757
Bug: 142266108
Test: dEQP-VK.memory.binding on 1.1 loader and 1.0 device ICD
Test: dEQP-VK.api.info.instance on 1.1 loader and 1.0 instance ICD
Change-Id: I0a3e06dc04bade4f36a7e68ee2f53979c656ee4e
diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp
index 48f26e7..1578d9f 100644
--- a/vulkan/libvulkan/api.cpp
+++ b/vulkan/libvulkan/api.cpp
@@ -519,7 +519,11 @@
get_device_proc_addr_(nullptr),
driver_extensions_(nullptr),
driver_extension_count_(0) {
- enabled_extensions_.set(driver::ProcHook::EXTENSION_CORE);
+ // advertise the loader supported core Vulkan API version at vulkan::api
+ for (uint32_t i = driver::ProcHook::EXTENSION_CORE_1_0;
+ i != driver::ProcHook::EXTENSION_COUNT; ++i) {
+ enabled_extensions_.set(i);
+ }
}
LayerChain::~LayerChain() {
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index b413ac9..c3c19ec 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -99,6 +99,7 @@
VkResult Validate();
void DowngradeApiVersion();
+ void UpgradeDeviceCoreApiVersion(uint32_t api_version);
const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
@@ -328,8 +329,12 @@
physical_dev_(VK_NULL_HANDLE),
instance_info_(create_info),
extension_filter_() {
- hook_extensions_.set(ProcHook::EXTENSION_CORE);
- hal_extensions_.set(ProcHook::EXTENSION_CORE);
+ // instance core versions need to match the loader api version
+ for (uint32_t i = ProcHook::EXTENSION_CORE_1_0;
+ i != ProcHook::EXTENSION_COUNT; ++i) {
+ hook_extensions_.set(i);
+ hal_extensions_.set(i);
+ }
}
CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
@@ -340,8 +345,9 @@
physical_dev_(physical_dev),
dev_info_(create_info),
extension_filter_() {
- hook_extensions_.set(ProcHook::EXTENSION_CORE);
- hal_extensions_.set(ProcHook::EXTENSION_CORE);
+ // initialize with baseline core API version
+ hook_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
+ hal_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
}
CreateInfoWrapper::~CreateInfoWrapper() {
@@ -540,7 +546,8 @@
case ProcHook::ANDROID_external_memory_android_hardware_buffer:
case ProcHook::ANDROID_native_buffer:
case ProcHook::GOOGLE_display_timing:
- case ProcHook::EXTENSION_CORE:
+ case ProcHook::EXTENSION_CORE_1_0:
+ case ProcHook::EXTENSION_CORE_1_1:
case ProcHook::EXTENSION_COUNT:
// Device and meta extensions. If we ever get here it's a bug in
// our code. But enumerating them lets us avoid having a default
@@ -588,7 +595,8 @@
case ProcHook::EXT_debug_report:
case ProcHook::EXT_swapchain_colorspace:
case ProcHook::ANDROID_native_buffer:
- case ProcHook::EXTENSION_CORE:
+ case ProcHook::EXTENSION_CORE_1_0:
+ case ProcHook::EXTENSION_CORE_1_1:
case ProcHook::EXTENSION_COUNT:
// Instance and meta extensions. If we ever get here it's a bug
// in our code. But enumerating them lets us avoid having a
@@ -636,6 +644,31 @@
}
}
+void CreateInfoWrapper::UpgradeDeviceCoreApiVersion(uint32_t api_version) {
+ ALOG_ASSERT(!is_instance_, "Device only API called by instance wrapper.");
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wold-style-cast"
+ api_version ^= VK_VERSION_PATCH(api_version);
+#pragma clang diagnostic pop
+
+ // cap the API version to the loader supported highest version
+ if (api_version > VK_API_VERSION_1_1)
+ api_version = VK_API_VERSION_1_1;
+
+ switch (api_version) {
+ case VK_API_VERSION_1_1:
+ hook_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
+ hal_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
+ [[clang::fallthrough]];
+ case VK_API_VERSION_1_0:
+ break;
+ default:
+ ALOGD("Unknown upgrade API version[%u]", api_version);
+ break;
+ }
+}
+
VKAPI_ATTR void* DefaultAllocate(void*,
size_t size,
size_t alignment,
@@ -771,7 +804,7 @@
: nullptr;
break;
case ProcHook::DEVICE:
- proc = (hook->extension == ProcHook::EXTENSION_CORE)
+ proc = (hook->extension == ProcHook::EXTENSION_CORE_1_0)
? hook->proc
: hook->checked_proc;
break;
@@ -1117,6 +1150,13 @@
if (!data)
return VK_ERROR_OUT_OF_HOST_MEMORY;
+ VkPhysicalDeviceProperties properties;
+ ATRACE_BEGIN("driver.GetPhysicalDeviceProperties");
+ instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
+ &properties);
+ ATRACE_END();
+
+ wrapper.UpgradeDeviceCoreApiVersion(properties.apiVersion);
data->hook_extensions |= wrapper.GetHookExtensions();
// call into the driver
@@ -1161,12 +1201,6 @@
return VK_ERROR_INCOMPATIBLE_DRIVER;
}
- VkPhysicalDeviceProperties properties;
- ATRACE_BEGIN("driver.GetPhysicalDeviceProperties");
- instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
- &properties);
- ATRACE_END();
-
if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
// Log that the app is hitting software Vulkan implementation
android::GraphicsEnv::getInstance().setTargetStats(
diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h
index f058c47..61e1818 100644
--- a/vulkan/libvulkan/driver.h
+++ b/vulkan/libvulkan/driver.h
@@ -67,9 +67,7 @@
: opaque_api_data(),
allocator(alloc),
driver(),
- get_device_proc_addr(nullptr) {
- hook_extensions.set(ProcHook::EXTENSION_CORE);
- }
+ get_device_proc_addr(nullptr) {}
api::InstanceData opaque_api_data;
@@ -89,9 +87,7 @@
: opaque_api_data(),
allocator(alloc),
debug_report_callbacks(debug_report_callbacks_),
- driver() {
- hook_extensions.set(ProcHook::EXTENSION_CORE);
- }
+ driver() {}
api::DeviceData opaque_api_data;
diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp
index f676573..52205e9 100644
--- a/vulkan/libvulkan/driver_gen.cpp
+++ b/vulkan/libvulkan/driver_gen.cpp
@@ -74,6 +74,15 @@
}
}
+VKAPI_ATTR VkResult checkedBindImageMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos) {
+ if (GetData(device).hook_extensions[ProcHook::EXTENSION_CORE_1_1]) {
+ return BindImageMemory2(device, bindInfoCount, pBindInfos);
+ } else {
+ Logger(device).Err(device, "VK_VERSION_1_1 not enabled. vkBindImageMemory2 not executed.");
+ return VK_SUCCESS;
+ }
+}
+
VKAPI_ATTR VkResult checkedBindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos) {
if (GetData(device).hook_extensions[ProcHook::KHR_bind_memory2]) {
return BindImageMemory2KHR(device, bindInfoCount, pBindInfos);
@@ -145,6 +154,14 @@
}
}
+VKAPI_ATTR void checkedGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo, VkQueue* pQueue) {
+ if (GetData(device).hook_extensions[ProcHook::EXTENSION_CORE_1_1]) {
+ GetDeviceQueue2(device, pQueueInfo, pQueue);
+ } else {
+ Logger(device).Err(device, "VK_VERSION_1_1 not enabled. vkGetDeviceQueue2 not executed.");
+ }
+}
+
// clang-format on
const ProcHook g_proc_hooks[] = {
@@ -173,16 +190,16 @@
{
"vkAllocateCommandBuffers",
ProcHook::DEVICE,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_0,
reinterpret_cast<PFN_vkVoidFunction>(AllocateCommandBuffers),
nullptr,
},
{
"vkBindImageMemory2",
ProcHook::DEVICE,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_1,
reinterpret_cast<PFN_vkVoidFunction>(BindImageMemory2),
- nullptr,
+ reinterpret_cast<PFN_vkVoidFunction>(checkedBindImageMemory2),
},
{
"vkBindImageMemory2KHR",
@@ -208,14 +225,14 @@
{
"vkCreateDevice",
ProcHook::INSTANCE,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_0,
reinterpret_cast<PFN_vkVoidFunction>(CreateDevice),
nullptr,
},
{
"vkCreateInstance",
ProcHook::GLOBAL,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_0,
reinterpret_cast<PFN_vkVoidFunction>(CreateInstance),
nullptr,
},
@@ -243,14 +260,14 @@
{
"vkDestroyDevice",
ProcHook::DEVICE,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_0,
reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice),
nullptr,
},
{
"vkDestroyInstance",
ProcHook::INSTANCE,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_0,
reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance),
nullptr,
},
@@ -271,28 +288,28 @@
{
"vkEnumerateDeviceExtensionProperties",
ProcHook::INSTANCE,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_0,
reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties),
nullptr,
},
{
"vkEnumerateInstanceExtensionProperties",
ProcHook::GLOBAL,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_0,
reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties),
nullptr,
},
{
"vkEnumeratePhysicalDeviceGroups",
ProcHook::INSTANCE,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_1,
reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDeviceGroups),
nullptr,
},
{
"vkEnumeratePhysicalDevices",
ProcHook::INSTANCE,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_0,
reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices),
nullptr,
},
@@ -313,28 +330,28 @@
{
"vkGetDeviceProcAddr",
ProcHook::DEVICE,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_0,
reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr),
nullptr,
},
{
"vkGetDeviceQueue",
ProcHook::DEVICE,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_0,
reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue),
nullptr,
},
{
"vkGetDeviceQueue2",
ProcHook::DEVICE,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_1,
reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue2),
- nullptr,
+ reinterpret_cast<PFN_vkVoidFunction>(checkedGetDeviceQueue2),
},
{
"vkGetInstanceProcAddr",
ProcHook::INSTANCE,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_0,
reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr),
nullptr,
},
@@ -446,7 +463,7 @@
{
"vkQueueSubmit",
ProcHook::DEVICE,
- ProcHook::EXTENSION_CORE,
+ ProcHook::EXTENSION_CORE_1_0,
reinterpret_cast<PFN_vkVoidFunction>(QueueSubmit),
nullptr,
},
diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h
index cd7d8f8..43c4d14 100644
--- a/vulkan/libvulkan/driver_gen.h
+++ b/vulkan/libvulkan/driver_gen.h
@@ -49,7 +49,8 @@
KHR_bind_memory2,
KHR_get_physical_device_properties2,
- EXTENSION_CORE, // valid bit
+ EXTENSION_CORE_1_0,
+ EXTENSION_CORE_1_1,
EXTENSION_COUNT,
EXTENSION_UNKNOWN,
};