From 649534072a49197fe0719a77e4b30fb9993f8728 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 9 Dec 2019 16:38:34 +0000 Subject: [PATCH] Fix implementation of GetPhysicalDeviceProcAddr --- renderdoc/driver/vulkan/vk_hookset_defs.h | 75 ++++++++++++++++ renderdoc/driver/vulkan/vk_layer.cpp | 105 ++++++++++++++++++---- 2 files changed, 162 insertions(+), 18 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_hookset_defs.h b/renderdoc/driver/vulkan/vk_hookset_defs.h index 43e652c97..9c01e80e6 100644 --- a/renderdoc/driver/vulkan/vk_hookset_defs.h +++ b/renderdoc/driver/vulkan/vk_hookset_defs.h @@ -37,6 +37,10 @@ HookInitExtension(VK_KHR_win32_surface, GetPhysicalDeviceWin32PresentationSupportKHR); \ HookInitExtension(VK_EXT_full_screen_exclusive, GetPhysicalDeviceSurfacePresentModes2EXT); +#define HookInitInstance_PlatformSpecific_PhysDev() \ + HookInitExtension(VK_KHR_win32_surface, GetPhysicalDeviceWin32PresentationSupportKHR); \ + HookInitExtension(VK_EXT_full_screen_exclusive, GetPhysicalDeviceSurfacePresentModes2EXT); + #define HookInitDevice_PlatformSpecific() \ HookInitExtension(VK_NV_win32_keyed_mutex, GetMemoryWin32HandleNV); \ HookInitExtension(VK_KHR_external_memory_win32, GetMemoryWin32HandleKHR); \ @@ -120,6 +124,7 @@ #define HookInitInstance_PlatformSpecific() \ HookInitInstance_PlatformSpecific_MVK(); \ HookInitInstance_PlatformSpecific_EXT(); +#define HookInitInstance_PlatformSpecific_PhysDev() #define HookDefine_PlatformSpecific() \ HookDefine_PlatformSpecific_MVK(); \ @@ -131,6 +136,7 @@ #define HookInitInstance_PlatformSpecific() \ HookInitExtension(VK_KHR_android_surface, CreateAndroidSurfaceKHR); +#define HookInitInstance_PlatformSpecific_PhysDev() #define HookInitDevice_PlatformSpecific() @@ -143,6 +149,7 @@ #define HookInitInstance_PlatformSpecific() \ HookInitExtension(VK_GGP_stream_descriptor_surface, CreateStreamDescriptorSurfaceGGP); +#define HookInitInstance_PlatformSpecific_PhysDev() #define HookInitDevice_PlatformSpecific() @@ -158,6 +165,8 @@ #define HookInitInstance_PlatformSpecific_Xcb() \ HookInitExtension(VK_KHR_xcb_surface, CreateXcbSurfaceKHR); \ HookInitExtension(VK_KHR_xcb_surface, GetPhysicalDeviceXcbPresentationSupportKHR); +#define HookInitInstance_PlatformSpecific_Xcb_PhysDev() \ + HookInitExtension(VK_KHR_xcb_surface, GetPhysicalDeviceXcbPresentationSupportKHR); #define HookDefine_PlatformSpecific_Xcb() \ HookDefine4(VkResult, vkCreateXcbSurfaceKHR, VkInstance, instance, \ @@ -170,6 +179,7 @@ #else #define HookInitInstance_PlatformSpecific_Xcb() +#define HookInitInstance_PlatformSpecific_Xcb_PhysDev() #define HookDefine_PlatformSpecific_Xcb() #endif @@ -179,6 +189,8 @@ #define HookInitInstance_PlatformSpecific_Wayland() \ HookInitExtension(VK_KHR_wayland_surface, CreateWaylandSurfaceKHR); \ HookInitExtension(VK_KHR_wayland_surface, GetPhysicalDeviceWaylandPresentationSupportKHR); +#define HookInitInstance_PlatformSpecific_Wayland_PhysDev() \ + HookInitExtension(VK_KHR_wayland_surface, GetPhysicalDeviceWaylandPresentationSupportKHR); #define HookDefine_PlatformSpecific_Wayland() \ HookDefine4(VkResult, vkCreateWaylandSurfaceKHR, VkInstance, instance, \ @@ -190,6 +202,7 @@ #else #define HookInitInstance_PlatformSpecific_Wayland() +#define HookInitInstance_PlatformSpecific_Wayland_PhysDev() #define HookDefine_PlatformSpecific_Wayland() #endif @@ -201,6 +214,10 @@ HookInitExtension(VK_KHR_xlib_surface, GetPhysicalDeviceXlibPresentationSupportKHR); \ HookInitExtension(VK_EXT_acquire_xlib_display, AcquireXlibDisplayEXT); \ HookInitExtension(VK_EXT_acquire_xlib_display, GetRandROutputDisplayEXT); +#define HookInitInstance_PlatformSpecific_XLib_PhysDev() \ + HookInitExtension(VK_KHR_xlib_surface, GetPhysicalDeviceXlibPresentationSupportKHR); \ + HookInitExtension(VK_EXT_acquire_xlib_display, AcquireXlibDisplayEXT); \ + HookInitExtension(VK_EXT_acquire_xlib_display, GetRandROutputDisplayEXT); #define HookDefine_PlatformSpecific_Xlib() \ HookDefine4(VkResult, vkCreateXlibSurfaceKHR, VkInstance, instance, \ @@ -217,12 +234,16 @@ #define HookInitInstance_PlatformSpecific_Xlib() #define HookDefine_PlatformSpecific_Xlib() +#define HookInitInstance_PlatformSpecific_XLib_PhysDev() #endif #define HookInitInstance_PlatformSpecific() \ HookInitInstance_PlatformSpecific_Xcb() HookInitInstance_PlatformSpecific_Xlib() \ HookInitInstance_PlatformSpecific_Wayland() +#define HookInitInstance_PlatformSpecific_PhysDev() \ + HookInitInstance_PlatformSpecific_Xcb_PhysDev() HookInitInstance_PlatformSpecific_Xlib_PhysDev() \ + HookInitInstance_PlatformSpecific_Wayland_PhysDev() #define HookInitDevice_PlatformSpecific() #define HookDefine_PlatformSpecific() \ @@ -243,6 +264,15 @@ HookInit(GetPhysicalDeviceQueueFamilyProperties); \ HookInit(GetPhysicalDeviceMemoryProperties); +#define HookInitVulkanInstance_PhysDev() \ + HookInit(GetPhysicalDeviceFeatures); \ + HookInit(GetPhysicalDeviceImageFormatProperties); \ + HookInit(GetPhysicalDeviceFormatProperties); \ + HookInit(GetPhysicalDeviceSparseImageFormatProperties); \ + HookInit(GetPhysicalDeviceProperties); \ + HookInit(GetPhysicalDeviceQueueFamilyProperties); \ + HookInit(GetPhysicalDeviceMemoryProperties); + #define HookInitVulkanDevice() \ HookInit(CreateDevice); \ HookInit(DestroyDevice); \ @@ -545,6 +575,51 @@ CheckExt(KHR_performance_query, VKXX); \ CheckExt(KHR_buffer_device_address, VKXX); +#define HookInitVulkanInstanceExts_PhysDev() \ + HookInitExtension(KHR_surface, GetPhysicalDeviceSurfaceSupportKHR); \ + HookInitExtension(KHR_surface, GetPhysicalDeviceSurfaceCapabilitiesKHR); \ + HookInitExtension(KHR_surface, GetPhysicalDeviceSurfaceFormatsKHR); \ + HookInitExtension(KHR_surface, GetPhysicalDeviceSurfacePresentModesKHR); \ + HookInitExtension(KHR_display, GetPhysicalDeviceDisplayPropertiesKHR); \ + HookInitExtension(KHR_display, GetPhysicalDeviceDisplayPlanePropertiesKHR); \ + HookInitExtension(KHR_display, GetDisplayPlaneSupportedDisplaysKHR); \ + HookInitExtension(KHR_display, GetDisplayModePropertiesKHR); \ + HookInitExtension(KHR_display, CreateDisplayModeKHR); \ + HookInitExtension(KHR_display, GetDisplayPlaneCapabilitiesKHR); \ + HookInitExtension(NV_external_memory_capabilities, \ + GetPhysicalDeviceExternalImageFormatPropertiesNV); \ + HookInitPromotedExtension(KHR_get_physical_device_properties2, GetPhysicalDeviceFeatures2, KHR); \ + HookInitPromotedExtension(KHR_get_physical_device_properties2, GetPhysicalDeviceProperties2, KHR); \ + HookInitPromotedExtension(KHR_get_physical_device_properties2, \ + GetPhysicalDeviceFormatProperties2, KHR); \ + HookInitPromotedExtension(KHR_get_physical_device_properties2, \ + GetPhysicalDeviceImageFormatProperties2, KHR); \ + HookInitPromotedExtension(KHR_get_physical_device_properties2, \ + GetPhysicalDeviceQueueFamilyProperties2, KHR); \ + HookInitPromotedExtension(KHR_get_physical_device_properties2, \ + GetPhysicalDeviceMemoryProperties2, KHR); \ + HookInitPromotedExtension(KHR_get_physical_device_properties2, \ + GetPhysicalDeviceSparseImageFormatProperties2, KHR); \ + HookInitExtension(EXT_direct_mode_display, ReleaseDisplayEXT); \ + HookInitExtension(EXT_display_surface_counter, GetPhysicalDeviceSurfaceCapabilities2EXT); \ + HookInitPromotedExtension(KHR_external_memory_capabilities, \ + GetPhysicalDeviceExternalBufferProperties, KHR); \ + HookInitPromotedExtension(KHR_external_semaphore_capabilities, \ + GetPhysicalDeviceExternalSemaphoreProperties, KHR); \ + HookInitPromotedExtension(KHR_external_fence_capabilities, \ + GetPhysicalDeviceExternalFenceProperties, KHR); \ + HookInitExtension(KHR_device_group_creation &&KHR_surface, GetPhysicalDevicePresentRectanglesKHR); \ + HookInitExtension(KHR_get_surface_capabilities2, GetPhysicalDeviceSurfaceFormats2KHR); \ + HookInitExtension(KHR_get_surface_capabilities2, GetPhysicalDeviceSurfaceCapabilities2KHR); \ + HookInitExtension(KHR_get_display_properties2, GetPhysicalDeviceDisplayProperties2KHR); \ + HookInitExtension(KHR_get_display_properties2, GetPhysicalDeviceDisplayPlaneProperties2KHR); \ + HookInitExtension(EXT_sample_locations, GetPhysicalDeviceMultisamplePropertiesEXT); \ + HookInitExtension(EXT_calibrated_timestamps, GetPhysicalDeviceCalibrateableTimeDomainsEXT); \ + HookInitExtension(KHR_performance_query, \ + EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR); \ + HookInitExtension(KHR_performance_query, GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR); \ + HookInitInstance_PlatformSpecific_PhysDev() + #define HookInitVulkanInstanceExts() \ HookInitExtension(KHR_surface, DestroySurfaceKHR); \ HookInitExtension(KHR_surface, GetPhysicalDeviceSurfaceSupportKHR); \ diff --git a/renderdoc/driver/vulkan/vk_layer.cpp b/renderdoc/driver/vulkan/vk_layer.cpp index bfc0ac158..c4eb42b06 100644 --- a/renderdoc/driver/vulkan/vk_layer.cpp +++ b/renderdoc/driver/vulkan/vk_layer.cpp @@ -337,24 +337,8 @@ VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr(VkDevice device, const char *pName) return GetDeviceDispatchTable(device)->GetDeviceProcAddr(Unwrap(device), pName); } -VKAPI_ATTR VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL -VK_LAYER_RENDERDOC_Capture_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char *pName) -{ - if(instance == VK_NULL_HANDLE) - return NULL; - - if(GetInstanceDispatchTable(instance)->GetInstanceProcAddr == NULL) - return NULL; - - PFN_vkGetInstanceProcAddr GPDA = - (PFN_vkGetInstanceProcAddr)GetInstanceDispatchTable(instance)->GetInstanceProcAddr( - Unwrap(instance), "vk_layerGetPhysicalDeviceProcAddr"); - - if(GPDA == NULL) - return NULL; - - return GPDA(Unwrap(instance), pName); -} +VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL +VK_LAYER_RENDERDOC_Capture_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char *pName); VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr(VkInstance instance, const char *pName) @@ -420,6 +404,91 @@ VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr(VkInstance instance, const char *p return GetInstanceDispatchTable(instance)->GetInstanceProcAddr(Unwrap(instance), pName); } +VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL +VK_LAYER_RENDERDOC_Capture_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char *pName) +{ + // GetPhysicalDeviceProcAddr acts like GetInstanceProcAddr but it returns NULL for any functions + // which aren't physical device functions + if(!strcmp("vkGetInstanceProcAddr", pName)) + return NULL; + if(!strcmp("vk_layerGetPhysicalDeviceProcAddr", pName)) + return (PFN_vkVoidFunction)&VK_LAYER_RENDERDOC_Capture_layerGetPhysicalDeviceProcAddr; + if(!strcmp("vkEnumerateDeviceLayerProperties", pName)) + return (PFN_vkVoidFunction)&VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties; + if(!strcmp("vkEnumerateDeviceExtensionProperties", pName)) + return (PFN_vkVoidFunction)&VK_LAYER_RENDERDOC_CaptureEnumerateDeviceExtensionProperties; + if(!strcmp("vkEnumerateInstanceExtensionProperties", pName)) + return NULL; + if(!strcmp("vkGetDeviceProcAddr", pName)) + return NULL; + if(!strcmp("vkCreateDevice", pName)) + return (PFN_vkVoidFunction)&hooked_vkCreateDevice; + if(!strcmp("vkDestroyDevice", pName)) + return NULL; + + HookInitVulkanInstance_PhysDev(); + +// any remaining functions that are known, we must return NULL for +#undef HookInit +#define HookInit(function) \ + if(!strcmp(pName, STRINGIZE(CONCAT(vk, function)))) \ + return NULL; + + HookInitVulkanInstance(); + HookInitVulkanDevice(); + + if(instance == VK_NULL_HANDLE) + return NULL; + + InstanceDeviceInfo *instDevInfo = NULL; + + if(WrappedVkInstance::IsAlloc(instance)) + instDevInfo = GetRecord(instance)->instDevInfo; + else + RDCERR( + "GetPhysicalDeviceProcAddr passed invalid instance for %s! Possibly broken loader. " + "Working around by assuming all extensions are enabled - WILL CAUSE SPEC-BROKEN BEHAVIOUR", + pName); + + DeclExts(); + + CheckInstanceExts(); + CheckDeviceExts(); + + // any extensions that are known to be physical device functions, return here + HookInitVulkanInstanceExts_PhysDev(); + +// any remaining functions that are known, we must return NULL for +#undef HookInitExtension +#define HookInitExtension(cond, function) \ + if(!strcmp(pName, STRINGIZE(CONCAT(vk, function)))) \ + return NULL; + +#undef HookInitPromotedExtension +#define HookInitPromotedExtension(cond, function, suffix) \ + if(!strcmp(pName, STRINGIZE(CONCAT(vk, function))) || \ + !strcmp(pName, STRINGIZE(CONCAT(vk, CONCAT(function, suffix))))) \ + return NULL; + + HookInitVulkanInstanceExts(); + HookInitVulkanDeviceExts(); + + // if we got here we don't recognise the function at all. Shouldn't be possible as we whitelist + // extensions, but follow the spec and pass along + + if(GetInstanceDispatchTable(instance)->GetInstanceProcAddr == NULL) + return NULL; + + PFN_vkGetInstanceProcAddr GPDA = + (PFN_vkGetInstanceProcAddr)GetInstanceDispatchTable(instance)->GetInstanceProcAddr( + Unwrap(instance), "vk_layerGetPhysicalDeviceProcAddr"); + + if(GPDA == NULL) + return NULL; + + return GPDA(Unwrap(instance), pName); +} + // layer interface negotation (new interface) VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL VK_LAYER_RENDERDOC_CaptureNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct)