From e3f17bc9a017df730e6d9179f104b2c04210b773 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Thu, 2 May 2024 17:59:29 +0200 Subject: [PATCH] Library Forwarding/vulkan: Reload pointers for extension functions more aggressively Some applications create multiple Vulkan instances with different sets of extensions. We might hence miss some of these pointers during the initial function pointer query. --- ThunkLibs/libvulkan/Host.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/ThunkLibs/libvulkan/Host.cpp b/ThunkLibs/libvulkan/Host.cpp index 4579b59d6e..0ecb823dc4 100644 --- a/ThunkLibs/libvulkan/Host.cpp +++ b/ThunkLibs/libvulkan/Host.cpp @@ -37,7 +37,7 @@ static void DoSetupWithInstance(VkInstance instance) { std::abort(); } - // Query pointers for functions customized below + // Query pointers for non-EXT functions customized below (void*&)LDR_PTR(vkCreateDevice) = (void*)LDR_PTR(vkGetInstanceProcAddr)(instance, "vkCreateDevice"); // Only do this lookup once. @@ -240,6 +240,25 @@ static PFN_vkVoidFunction FEXFN_IMPL(vkGetInstanceProcAddr)(VkInstance a_0, cons // Check for functions with custom implementations first if (auto ptr = LookupCustomVulkanFunction(a_1)) { + // If this function belongs to an instance extension, requery its address. + // This ensures fexldr_ptr_* is valid if the application creates a minimal + // VkInstance with no extensions before creating its actual instance. + using namespace std::string_view_literals; + if (a_1 == "vkGetRandROutputDisplayEXT"sv && !LDR_PTR(vkGetRandROutputDisplayEXT)) { + (void*&)LDR_PTR(vkGetRandROutputDisplayEXT) = (void*)LDR_PTR(vkGetInstanceProcAddr)(a_0, "vkGetRandROutputDisplayEXT"); + } + if (a_1 == "vkAcquireXlibDisplayEXT"sv && !LDR_PTR(vkAcquireXlibDisplayEXT)) { + (void*&)LDR_PTR(vkAcquireXlibDisplayEXT) = (void*)LDR_PTR(vkGetInstanceProcAddr)(a_0, "vkAcquireXlibDisplayEXT"); + } + const char* XcbPresent = "vkGetPhysicalDeviceXcbPresentationSupportKHR"; + if (a_1 == std::string_view { XcbPresent } && !LDR_PTR(vkGetPhysicalDeviceXcbPresentationSupportKHR)) { + (void*&)LDR_PTR(vkGetPhysicalDeviceXcbPresentationSupportKHR) = (void*)LDR_PTR(vkGetInstanceProcAddr)(a_0, XcbPresent); + } + const char* XlibPresent = "vkGetPhysicalDeviceXlibPresentationSupportKHR"; + if (a_1 == std::string_view { XlibPresent } && !LDR_PTR(vkGetPhysicalDeviceXlibPresentationSupportKHR)) { + (void*&)LDR_PTR(vkGetPhysicalDeviceXlibPresentationSupportKHR) = (void*)LDR_PTR(vkGetInstanceProcAddr)(a_0, XlibPresent); + } + return ptr; }