From 201914d7cc23dcf7447fb9075f602ae0d95e052c Mon Sep 17 00:00:00 2001 From: Dennis Tsiang Date: Tue, 25 Mar 2025 12:24:01 +0000 Subject: [PATCH 1/3] Make layer require VK_KHR_bind_memory2 extension and intercept KHR Enables the layer to intercept vkBindImageMemory2KHR, and by requiring the extension we ensure we can always call the entrypoint down the chain as well. Signed-off-by: Dennis Tsiang Change-Id: I1ec5f8c6ba648151e08101549cb795e990c84aeb --- layer/layer.cpp | 8 ++++++++ wsi/wsi_factory.cpp | 1 + 2 files changed, 9 insertions(+) diff --git a/layer/layer.cpp b/layer/layer.cpp index 3b59760..4878a11 100644 --- a/layer/layer.cpp +++ b/layer/layer.cpp @@ -523,6 +523,7 @@ wsi_layer_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VWL_VKAPI_CALL(PFN_vkVoidFunction) wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName) VWL_API_POST { + uint64_t api_version = layer::device_private_data::get(device).instance_data.api_version; if (layer::device_private_data::get(device).is_device_extension_enabled(VK_KHR_SWAPCHAIN_EXTENSION_NAME)) { GET_PROC_ADDR(vkCreateSwapchainKHR); @@ -553,6 +554,13 @@ wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName) VWL_API_POS GET_PROC_ADDR(vkCreateImage); GET_PROC_ADDR(vkBindImageMemory2); + if (!strcmp(funcName, "vkBindImageMemory2KHR") && + layer::device_private_data::get(device).disp.get_user_enabled_entrypoint(device, api_version, funcName) != + nullptr) + { + return (PFN_vkVoidFunction)&wsi_layer_vkBindImageMemory2; + } + /* VK_EXT_swapchain_maintenance1 */ if (layer::device_private_data::get(device).is_device_extension_enabled( VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME)) diff --git a/wsi/wsi_factory.cpp b/wsi/wsi_factory.cpp index fb7ec43..8fdc93b 100644 --- a/wsi/wsi_factory.cpp +++ b/wsi/wsi_factory.cpp @@ -171,6 +171,7 @@ VkResult add_device_extensions_required_by_layer(VkPhysicalDevice phys_dev, #if ENABLE_INSTRUMENTATION VK_EXT_FRAME_BOUNDARY_EXTENSION_NAME, #endif + VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, }; for (auto extension : optional_extensions) From 928514385b781daaed2d7d8f6ed57fc29a092636 Mon Sep 17 00:00:00 2001 From: Dennis Tsiang Date: Thu, 27 Mar 2025 10:51:54 +0000 Subject: [PATCH 2/3] Make layer use non-KHR commands for promoted entrypoints Some entrypoints when promoted lose the KHR suffix. Some ICDs only provide the non-KHR versions and the KHR versions are unavailable unless the associated extension is explicitly enabled. This change makes the layer's dispatch table internally convert any promoted KHR entrypoint calls to the non-KHR version when the the Vulkan API is of sufficient level. Signed-off-by: Dennis Tsiang Change-Id: I556c9071b738e15ef5fd2f970a8443b1c5215b16 --- layer/layer.cpp | 8 +- layer/private_data.cpp | 35 ++++-- layer/private_data.hpp | 258 ++++++++++++++++++++++------------------- 3 files changed, 165 insertions(+), 136 deletions(-) diff --git a/layer/layer.cpp b/layer/layer.cpp index 4878a11..a379459 100644 --- a/layer/layer.cpp +++ b/layer/layer.cpp @@ -192,12 +192,12 @@ VKAPI_ATTR VkResult create_instance(const VkInstanceCreateInfo *pCreateInfo, con return VK_ERROR_OUT_OF_HOST_MEMORY; } - TRY_LOG_CALL(table->populate(*pInstance, fpGetInstanceProcAddr)); - table->set_user_enabled_extensions(pCreateInfo->ppEnabledExtensionNames, pCreateInfo->enabledExtensionCount); - uint32_t api_version = pCreateInfo->pApplicationInfo != nullptr ? pCreateInfo->pApplicationInfo->apiVersion : VK_API_VERSION_1_3; + TRY_LOG_CALL(table->populate(*pInstance, fpGetInstanceProcAddr, api_version)); + table->set_user_enabled_extensions(pCreateInfo->ppEnabledExtensionNames, pCreateInfo->enabledExtensionCount); + TRY_LOG_CALL(instance_private_data::associate(*pInstance, std::move(*table), loader_callback, layer_platforms_to_enable, api_version, instance_allocator)); @@ -328,7 +328,7 @@ VKAPI_ATTR VkResult create_device(VkPhysicalDevice physicalDevice, const VkDevic return VK_ERROR_OUT_OF_HOST_MEMORY; } - VkResult result = table->populate(*pDevice, fpGetDeviceProcAddr); + VkResult result = table->populate(*pDevice, fpGetDeviceProcAddr, inst_data.api_version); if (result != VK_SUCCESS) { fn_destroy_device(*pDevice, pAllocator); diff --git a/layer/private_data.cpp b/layer/private_data.cpp index f77f606..a9cf3b1 100644 --- a/layer/private_data.cpp +++ b/layer/private_data.cpp @@ -44,17 +44,17 @@ static std::mutex g_data_lock; static util::unordered_map g_instance_data{ util::allocator::get_generic() }; static util::unordered_map g_device_data{ util::allocator::get_generic() }; -VkResult instance_dispatch_table::populate(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc) +VkResult instance_dispatch_table::populate(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc, + uint32_t instance_api_version) { static constexpr entrypoint entrypoints_init[] = { -#define DISPATCH_TABLE_ENTRY(name, ext_name, api_version, required) \ - { "vk" #name, ext_name, nullptr, api_version, false, required }, +#define DISPATCH_TABLE_ENTRY(name, ext_name, api_version, required, alias) \ + { "vk" #name, ext_name, nullptr, api_version, false, required, "vk" #alias }, INSTANCE_ENTRYPOINTS_LIST(DISPATCH_TABLE_ENTRY) #undef DISPATCH_TABLE_ENTRY }; static constexpr auto num_entrypoints = std::distance(std::begin(entrypoints_init), std::end(entrypoints_init)); - for (size_t i = 0; i < num_entrypoints; i++) { const entrypoint *entrypoint = &entrypoints_init[i]; @@ -67,6 +67,12 @@ VkResult instance_dispatch_table::populate(VkInstance instance, PFN_vkGetInstanc e.fn = ret; e.user_visible = false; + if (entrypoint->alias != nullptr && strcmp(entrypoint->alias, "vk") != 0 && + instance_api_version >= entrypoint->api_version) + { + e.fn = get_proc(instance, entrypoint->alias); + } + if (!m_entrypoints->try_insert(std::make_pair(e.name, e)).has_value()) { WSI_LOG_ERROR("Failed to allocate memory for instance dispatch table entry."); @@ -113,11 +119,12 @@ PFN_vkVoidFunction instance_dispatch_table::get_user_enabled_entrypoint(VkInstan return GetInstanceProcAddr(instance, fn_name).value_or(nullptr); } -VkResult device_dispatch_table::populate(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc_fn) +VkResult device_dispatch_table::populate(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc_fn, + uint32_t instance_api_version) { static constexpr entrypoint entrypoints_init[] = { -#define DISPATCH_TABLE_ENTRY(name, ext_name, api_version, required) \ - { "vk" #name, ext_name, nullptr, api_version, false, required }, +#define DISPATCH_TABLE_ENTRY(name, ext_name, api_version, required, alias) \ + { "vk" #name, ext_name, nullptr, api_version, false, required, "vk" #alias }, DEVICE_ENTRYPOINTS_LIST(DISPATCH_TABLE_ENTRY) #undef DISPATCH_TABLE_ENTRY }; @@ -125,16 +132,22 @@ VkResult device_dispatch_table::populate(VkDevice dev, PFN_vkGetDeviceProcAddr g for (size_t i = 0; i < num_entrypoints; i++) { - const entrypoint entrypoint = entrypoints_init[i]; - PFN_vkVoidFunction ret = get_proc_fn(dev, entrypoint.name); - if (!ret && entrypoint.required) + const entrypoint *entrypoint = &entrypoints_init[i]; + PFN_vkVoidFunction ret = get_proc_fn(dev, entrypoint->name); + if (!ret && entrypoint->required) { return VK_ERROR_INITIALIZATION_FAILED; } - struct entrypoint e = entrypoint; + struct entrypoint e = *entrypoint; e.fn = ret; e.user_visible = false; + if (entrypoint->alias != nullptr && strcmp(entrypoint->alias, "vk") != 0 && + instance_api_version >= entrypoint->api_version) + { + e.fn = get_proc_fn(dev, entrypoint->alias); + } + if (!m_entrypoints->try_insert(std::make_pair(e.name, e)).has_value()) { WSI_LOG_ERROR("Failed to allocate memory for device dispatch table entry."); diff --git a/layer/private_data.hpp b/layer/private_data.hpp index 4159e63..83b1dd2 100644 --- a/layer/private_data.hpp +++ b/layer/private_data.hpp @@ -65,6 +65,7 @@ struct entrypoint uint32_t api_version; bool user_visible; bool required; + const char *alias; }; /** @@ -211,54 +212,56 @@ static constexpr uint32_t API_VERSION_MAX = UINT32_MAX; * api_version: Vulkan API version where the entrypoint is part of the core specification, or API_VERSION_MAX. * required: Boolean to indicate whether the entrypoint is required by the WSI layer or optional. */ -#define INSTANCE_ENTRYPOINTS_LIST(EP) \ - /* Vulkan 1.0 */ \ - EP(GetInstanceProcAddr, "", VK_API_VERSION_1_0, true) \ - EP(DestroyInstance, "", VK_API_VERSION_1_0, true) \ - EP(GetPhysicalDeviceProperties, "", VK_API_VERSION_1_0, true) \ - EP(GetPhysicalDeviceImageFormatProperties, "", VK_API_VERSION_1_0, true) \ - EP(EnumerateDeviceExtensionProperties, "", VK_API_VERSION_1_0, true) \ - /* VK_KHR_surface */ \ - EP(DestroySurfaceKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false) \ - EP(GetPhysicalDeviceSurfaceCapabilitiesKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false) \ - EP(GetPhysicalDeviceSurfaceFormatsKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false) \ - EP(GetPhysicalDeviceSurfacePresentModesKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false) \ - EP(GetPhysicalDeviceSurfaceSupportKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false) \ - /* VK_EXT_headless_surface */ \ - EP(CreateHeadlessSurfaceEXT, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false) \ - /* VK_KHR_wayland_surface */ \ - EP(CreateWaylandSurfaceKHR, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false) \ - /* VK_KHR_display */ \ - EP(CreateDisplayPlaneSurfaceKHR, VK_KHR_DISPLAY_EXTENSION_NAME, API_VERSION_MAX, false) \ - /* VK_KHR_get_surface_capabilities2 */ \ - EP(GetPhysicalDeviceSurfaceCapabilities2KHR, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, API_VERSION_MAX, \ - false) \ - EP(GetPhysicalDeviceSurfaceFormats2KHR, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, API_VERSION_MAX, false) \ - /* VK_KHR_get_physical_device_properties2 or */ \ - /* 1.1 (without KHR suffix) */ \ - EP(GetPhysicalDeviceImageFormatProperties2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ - VK_API_VERSION_1_1, false) \ - EP(GetPhysicalDeviceFormatProperties2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ - VK_API_VERSION_1_1, false) \ - EP(GetPhysicalDeviceFeatures2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_API_VERSION_1_1, \ - false) \ - EP(GetPhysicalDeviceProperties2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_API_VERSION_1_1, \ - false) \ - EP(GetPhysicalDeviceQueueFamilyProperties2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ - VK_API_VERSION_1_1, false) \ - EP(GetPhysicalDeviceMemoryProperties2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ - VK_API_VERSION_1_1, false) \ - EP(GetPhysicalDeviceSparseImageFormatProperties2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ - VK_API_VERSION_1_1, false) \ - /* VK_KHR_device_group + VK_KHR_surface or */ \ - /* 1.1 with VK_KHR_swapchain */ \ - EP(GetPhysicalDevicePresentRectanglesKHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ - /* VK_KHR_external_fence_capabilities or */ \ - /* 1.1 (without KHR suffix) */ \ - EP(GetPhysicalDeviceExternalFencePropertiesKHR, VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, \ - VK_API_VERSION_1_1, false) \ - EP(GetPhysicalDeviceExternalBufferPropertiesKHR, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, \ - VK_API_VERSION_1_1, false) +#define INSTANCE_ENTRYPOINTS_LIST(EP) \ + /* Vulkan 1.0 */ \ + EP(GetInstanceProcAddr, "", VK_API_VERSION_1_0, true, ) \ + EP(DestroyInstance, "", VK_API_VERSION_1_0, true, ) \ + EP(GetPhysicalDeviceProperties, "", VK_API_VERSION_1_0, true, ) \ + EP(GetPhysicalDeviceImageFormatProperties, "", VK_API_VERSION_1_0, true, ) \ + EP(EnumerateDeviceExtensionProperties, "", VK_API_VERSION_1_0, true, ) \ + /* VK_KHR_surface */ \ + EP(DestroySurfaceKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(GetPhysicalDeviceSurfaceCapabilitiesKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(GetPhysicalDeviceSurfaceFormatsKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(GetPhysicalDeviceSurfacePresentModesKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(GetPhysicalDeviceSurfaceSupportKHR, VK_KHR_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + /* VK_EXT_headless_surface */ \ + EP(CreateHeadlessSurfaceEXT, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + /* VK_KHR_wayland_surface */ \ + EP(CreateWaylandSurfaceKHR, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + /* VK_KHR_display */ \ + EP(CreateDisplayPlaneSurfaceKHR, VK_KHR_DISPLAY_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + /* VK_KHR_get_surface_capabilities2 */ \ + EP(GetPhysicalDeviceSurfaceCapabilities2KHR, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, API_VERSION_MAX, \ + false, ) \ + EP(GetPhysicalDeviceSurfaceFormats2KHR, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + /* VK_KHR_get_physical_device_properties2 or 1.1 (without KHR suffix) */ \ + /* Not all of these entrypoints are used by the layer but need to be listed here to hide them from the application. */ \ + EP(GetPhysicalDeviceImageFormatProperties2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ + VK_API_VERSION_1_1, false, GetPhysicalDeviceImageFormatProperties2) \ + EP(GetPhysicalDeviceFormatProperties2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ + VK_API_VERSION_1_1, false, GetPhysicalDeviceFormatProperties2) \ + EP(GetPhysicalDeviceFeatures2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_API_VERSION_1_1, \ + false, GetPhysicalDeviceFeatures2) \ + EP(GetPhysicalDeviceProperties2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_API_VERSION_1_1, \ + false, GetPhysicalDeviceProperties2) \ + EP(GetPhysicalDeviceQueueFamilyProperties2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ + VK_API_VERSION_1_1, false, GetPhysicalDeviceQueueFamilyProperties2) \ + EP(GetPhysicalDeviceMemoryProperties2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ + VK_API_VERSION_1_1, false, GetPhysicalDeviceMemoryProperties2) \ + EP(GetPhysicalDeviceSparseImageFormatProperties2KHR, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ + VK_API_VERSION_1_1, false, GetPhysicalDeviceSparseImageFormatProperties2) \ + /* VK_KHR_device_group + VK_KHR_surface or */ \ + /* 1.1 with VK_KHR_swapchain */ \ + EP(GetPhysicalDevicePresentRectanglesKHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, false, ) \ + /* VK_KHR_external_fence_capabilities or 1.1 (without KHR suffix) */ \ + EP(GetPhysicalDeviceExternalFencePropertiesKHR, VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, \ + VK_API_VERSION_1_1, false, GetPhysicalDeviceExternalFenceProperties) \ + /* VK_KHR_external_memory_capabilities or 1.1 (without KHR suffix) */ \ + /* The layer does not use these entrypoints directly but does use VkExternalImageFormatPropertiesKHR introduced by */ \ + /* this extension. These are listed here in order to hide them from the application. */ \ + EP(GetPhysicalDeviceExternalBufferPropertiesKHR, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, \ + VK_API_VERSION_1_1, false, GetPhysicalDeviceExternalBufferProperties) /** * @brief Struct representing the instance dispatch table. @@ -284,9 +287,10 @@ public: * * @param instance The instance for which the dispatch table will be populated. * @param get_proc The pointer to vkGetInstanceProcAddr function. + * @param api_version The Vulkan API version being used. * @return VkResult VK_SUCCESS if successful, otherwise an error. */ - VkResult populate(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc); + VkResult populate(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc, uint32_t api_version); /** * @brief Get the user enabled instance extension entrypoint by name @@ -304,7 +308,7 @@ public: * disp.GetInstanceProcAddr(instance, fn_name); * The result type will be matching the function signature, so there is no need for casting. */ -#define DISPATCH_TABLE_SHORTCUT(name, unused1, unused2, unused3) \ +#define DISPATCH_TABLE_SHORTCUT(name, unused1, unused2, unused3, unused4) \ template \ auto name(Args &&...args) const \ { \ @@ -343,10 +347,10 @@ private: */ #if VULKAN_WSI_LAYER_EXPERIMENTAL -#define DEVICE_ENTRYPOINTS_LIST_EXPERIMENTAL(EP) \ - EP(GetSwapchainTimeDomainPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false) \ - EP(GetSwapchainTimingPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false) \ - EP(SetSwapchainPresentTimingQueueSizeEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false) +#define DEVICE_ENTRYPOINTS_LIST_EXPERIMENTAL(EP) \ + EP(GetSwapchainTimeDomainPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(GetSwapchainTimingPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(SetSwapchainPresentTimingQueueSizeEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) #else #define DEVICE_ENTRYPOINTS_LIST_EXPERIMENTAL(EP) #endif @@ -354,71 +358,82 @@ private: /* Define a list of custom entrypoints that might rely on preprocessor conditions and similar */ #define DEVICE_ENTRYPOINTS_LIST_EXPANSION(EP) DEVICE_ENTRYPOINTS_LIST_EXPERIMENTAL(EP) -#define DEVICE_ENTRYPOINTS_LIST(EP) \ - /* Vulkan 1.0 */ \ - EP(GetDeviceProcAddr, "", VK_API_VERSION_1_0, true) \ - EP(GetDeviceQueue, "", VK_API_VERSION_1_0, true) \ - EP(QueueSubmit, "", VK_API_VERSION_1_0, true) \ - EP(QueueWaitIdle, "", VK_API_VERSION_1_0, true) \ - EP(CreateCommandPool, "", VK_API_VERSION_1_0, true) \ - EP(DestroyCommandPool, "", VK_API_VERSION_1_0, true) \ - EP(AllocateCommandBuffers, "", VK_API_VERSION_1_0, true) \ - EP(FreeCommandBuffers, "", VK_API_VERSION_1_0, true) \ - EP(ResetCommandBuffer, "", VK_API_VERSION_1_0, true) \ - EP(BeginCommandBuffer, "", VK_API_VERSION_1_0, true) \ - EP(EndCommandBuffer, "", VK_API_VERSION_1_0, true) \ - EP(CreateImage, "", VK_API_VERSION_1_0, true) \ - EP(DestroyImage, "", VK_API_VERSION_1_0, true) \ - EP(GetImageMemoryRequirements, "", VK_API_VERSION_1_0, true) \ - EP(BindImageMemory, "", VK_API_VERSION_1_0, true) \ - EP(AllocateMemory, "", VK_API_VERSION_1_0, true) \ - EP(FreeMemory, "", VK_API_VERSION_1_0, true) \ - EP(CreateFence, "", VK_API_VERSION_1_0, true) \ - EP(DestroyFence, "", VK_API_VERSION_1_0, true) \ - EP(CreateSemaphore, "", VK_API_VERSION_1_0, true) \ - EP(DestroySemaphore, "", VK_API_VERSION_1_0, true) \ - EP(ResetFences, "", VK_API_VERSION_1_0, true) \ - EP(WaitForFences, "", VK_API_VERSION_1_0, true) \ - EP(DestroyDevice, "", VK_API_VERSION_1_0, true) \ - /* VK_KHR_swapchain */ \ - EP(CreateSwapchainKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \ - EP(DestroySwapchainKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \ - EP(GetSwapchainImagesKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \ - EP(AcquireNextImageKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \ - EP(QueuePresentKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \ - /* VK_KHR_shared_presentable_image */ \ - EP(GetSwapchainStatusKHR, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, API_VERSION_MAX, false) \ - /* VK_KHR_device_group + VK_KHR_swapchain or */ /* 1.1 with VK_KHR_swapchain */ \ - EP(AcquireNextImage2KHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ - /* VK_KHR_device_group + VK_KHR_surface or */ /* 1.1 with VK_KHR_swapchain */ \ - EP(GetDeviceGroupSurfacePresentModesKHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ - EP(GetDeviceGroupPresentCapabilitiesKHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, \ - false) /* VK_KHR_external_memory_fd */ \ - EP(GetMemoryFdKHR, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, API_VERSION_MAX, false) \ - EP(GetMemoryFdPropertiesKHR, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, API_VERSION_MAX, false) \ - /* VK_KHR_bind_memory2 or */ /* 1.1 (without KHR suffix) */ \ - EP(BindImageMemory2KHR, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ - EP(BindBufferMemory2KHR, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_API_VERSION_1_1, \ - false) /* VK_KHR_external_fence_fd */ \ - EP(GetFenceFdKHR, VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME, API_VERSION_MAX, false) \ - EP(ImportFenceFdKHR, VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME, API_VERSION_MAX, \ - false) /* VK_KHR_external_semaphore_fd */ \ - EP(ImportSemaphoreFdKHR, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, API_VERSION_MAX, false) \ - EP(GetSemaphoreFdKHR, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, API_VERSION_MAX, \ - false) /* VK_KHR_image_drm_format_modifier */ \ - EP(GetImageDrmFormatModifierPropertiesEXT, VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, API_VERSION_MAX, \ - false) /* VK_KHR_sampler_ycbcr_conversion */ \ - EP(CreateSamplerYcbcrConversionKHR, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ - EP(DestroySamplerYcbcrConversionKHR, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_API_VERSION_1_1, \ - false) /* VK_KHR_maintenance1 */ \ - EP(TrimCommandPoolKHR, VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_API_VERSION_1_1, \ - false) /* VK_KHR_get_memory_requirements2 */ \ - EP(GetImageMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ - EP(GetBufferMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ - EP(GetImageSparseMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, \ - false) \ - EP(ReleaseSwapchainImagesEXT, VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ - /* Custom entrypoints */ \ +#define DEVICE_ENTRYPOINTS_LIST(EP) \ + /* Vulkan 1.0 */ \ + EP(GetDeviceProcAddr, "", VK_API_VERSION_1_0, true, ) \ + EP(GetDeviceQueue, "", VK_API_VERSION_1_0, true, ) \ + EP(QueueSubmit, "", VK_API_VERSION_1_0, true, ) \ + EP(QueueWaitIdle, "", VK_API_VERSION_1_0, true, ) \ + EP(CreateCommandPool, "", VK_API_VERSION_1_0, true, ) \ + EP(DestroyCommandPool, "", VK_API_VERSION_1_0, true, ) \ + EP(AllocateCommandBuffers, "", VK_API_VERSION_1_0, true, ) \ + EP(FreeCommandBuffers, "", VK_API_VERSION_1_0, true, ) \ + EP(ResetCommandBuffer, "", VK_API_VERSION_1_0, true, ) \ + EP(BeginCommandBuffer, "", VK_API_VERSION_1_0, true, ) \ + EP(EndCommandBuffer, "", VK_API_VERSION_1_0, true, ) \ + EP(CreateImage, "", VK_API_VERSION_1_0, true, ) \ + EP(DestroyImage, "", VK_API_VERSION_1_0, true, ) \ + EP(GetImageMemoryRequirements, "", VK_API_VERSION_1_0, true, ) \ + EP(BindImageMemory, "", VK_API_VERSION_1_0, true, ) \ + EP(AllocateMemory, "", VK_API_VERSION_1_0, true, ) \ + EP(FreeMemory, "", VK_API_VERSION_1_0, true, ) \ + EP(CreateFence, "", VK_API_VERSION_1_0, true, ) \ + EP(DestroyFence, "", VK_API_VERSION_1_0, true, ) \ + EP(CreateSemaphore, "", VK_API_VERSION_1_0, true, ) \ + EP(DestroySemaphore, "", VK_API_VERSION_1_0, true, ) \ + EP(ResetFences, "", VK_API_VERSION_1_0, true, ) \ + EP(WaitForFences, "", VK_API_VERSION_1_0, true, ) \ + EP(DestroyDevice, "", VK_API_VERSION_1_0, true, ) \ + /* VK_KHR_swapchain */ \ + EP(CreateSwapchainKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(DestroySwapchainKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(GetSwapchainImagesKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(AcquireNextImageKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(QueuePresentKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + /* VK_KHR_shared_presentable_image */ \ + EP(GetSwapchainStatusKHR, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + /* VK_KHR_device_group + VK_KHR_swapchain or 1.1 with VK_KHR_swapchain */ \ + EP(AcquireNextImage2KHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, false, ) \ + /* VK_KHR_device_group + VK_KHR_surface or 1.1 with VK_KHR_swapchain */ \ + EP(GetDeviceGroupSurfacePresentModesKHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, false, ) \ + EP(GetDeviceGroupPresentCapabilitiesKHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, false, ) \ + /* VK_KHR_external_memory_fd */ \ + EP(GetMemoryFdKHR, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(GetMemoryFdPropertiesKHR, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + /* VK_KHR_bind_memory2 or 1.1 (without KHR suffix) */ \ + EP(BindImageMemory2KHR, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_API_VERSION_1_1, false, BindImageMemory2) \ + EP(BindBufferMemory2KHR, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_API_VERSION_1_1, false, BindBufferMemory2) \ + /* VK_KHR_external_fence_fd */ \ + EP(GetFenceFdKHR, VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(ImportFenceFdKHR, VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + /* VK_KHR_external_semaphore_fd */ \ + EP(ImportSemaphoreFdKHR, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + EP(GetSemaphoreFdKHR, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + /* VK_EXT_image_drm_format_modifier */ \ + /* Note the layer doesn't use these entrypoints directly but does use the structures introduced */ \ + /* by this extension. These entrypoints are listed to hide the entrypoints from the application. */ \ + EP(GetImageDrmFormatModifierPropertiesEXT, VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, API_VERSION_MAX, \ + false, ) \ + /* VK_KHR_sampler_ycbcr_conversion (promoted in 1.1 with KHR suffix removed but the samplerYcbcrConversion capability */ \ + /* is still optional). */ \ + /* Note the layer doesn't use these entrypoints directly but does use VK_IMAGE_CREATE_DISJOINT_BIT_KHR introduced */ \ + /* by this extension. These entrypoints are listed to hide the entrypoints from the application. */ \ + EP(CreateSamplerYcbcrConversionKHR, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_API_VERSION_1_1, false, ) \ + EP(DestroySamplerYcbcrConversionKHR, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_API_VERSION_1_1, false, ) \ + /* VK_KHR_maintenance1 */ \ + /* This extension is not used directly by the layer but is a dependency of VK_KHR_sampler_ycbcr_conversion */ \ + EP(TrimCommandPoolKHR, VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_API_VERSION_1_1, false, ) \ + /* VK_KHR_get_memory_requirements2 or 1.1 (without KHR suffix) \ + * This extension is not used directly by the layer but is a dependency of VK_KHR_sampler_ycbcr_conversion */ \ + EP(GetImageMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, false, \ + GetImageMemoryRequirements2) \ + EP(GetBufferMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, false, \ + GetBufferMemoryRequirements2) \ + EP(GetImageSparseMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, \ + false, GetImageSparseMemoryRequirements2KHR) \ + /* VK_EXT_swapchain_maintenance1 */ \ + EP(ReleaseSwapchainImagesEXT, VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME, VK_API_VERSION_1_1, false, ) \ + /* Custom entrypoints */ \ DEVICE_ENTRYPOINTS_LIST_EXPANSION(EP) /** @@ -445,9 +460,10 @@ public: * * @param device The device for which the dispatch table will be populated. * @param get_proc The pointer to vkGetDeviceProcAddr function. + * @param api_version The Vulkan API version being used. * @return VkResult VK_SUCCESS if successful, otherwise an error. */ - VkResult populate(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc); + VkResult populate(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc, uint32_t api_version); /** * @brief Get the user enabled device extension entrypoint by name @@ -465,7 +481,7 @@ public: * disp.GetDeviceProcAddr(instance, fn_name); * The result type will be matching the function signature, so there is no need for casting. */ -#define DISPATCH_TABLE_SHORTCUT(name, unused1, unused2, unused3) \ +#define DISPATCH_TABLE_SHORTCUT(name, unused1, unused2, unused3, unused4) \ template \ auto name(Args &&...args) const \ { \ From bd54fc460b25ed9a3f95080468c7adfe54dd6269 Mon Sep 17 00:00:00 2001 From: Dennis Tsiang Date: Thu, 3 Apr 2025 11:55:02 +0100 Subject: [PATCH 3/3] Update entrypoint list documentation with the alias parameter The comment explaining the format for the entrypoint entries are updated to include the new alias parameter. Signed-off-by: Dennis Tsiang Change-Id: I34b0d1247a010b0e60b19bb284bb6bdaf32eab23 --- layer/private_data.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/layer/private_data.hpp b/layer/private_data.hpp index 83b1dd2..733a600 100644 --- a/layer/private_data.hpp +++ b/layer/private_data.hpp @@ -211,6 +211,7 @@ static constexpr uint32_t API_VERSION_MAX = UINT32_MAX; * extension_name: Name of the extension that provides the entrypoint. * api_version: Vulkan API version where the entrypoint is part of the core specification, or API_VERSION_MAX. * required: Boolean to indicate whether the entrypoint is required by the WSI layer or optional. + * alias: Name of the promoted entrypoint alias if different to entrypoint_name. */ #define INSTANCE_ENTRYPOINTS_LIST(EP) \ /* Vulkan 1.0 */ \ @@ -344,6 +345,7 @@ private: * extension_name: Name of the extension that provides the entrypoint. * api_version: Vulkan API version where the entrypoint is part of the core specification, or API_VERSION_MAX. * required: Boolean to indicate whether the entrypoint is required by the WSI layer or optional. + * alias: Name of the promoted entrypoint alias if different to entrypoint_name. */ #if VULKAN_WSI_LAYER_EXPERIMENTAL