diff --git a/renderdoc/driver/vulkan/vk_layer.cpp b/renderdoc/driver/vulkan/vk_layer.cpp index 2b13c0b24..515f272bd 100644 --- a/renderdoc/driver/vulkan/vk_layer.cpp +++ b/renderdoc/driver/vulkan/vk_layer.cpp @@ -437,9 +437,8 @@ VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr(VkDevice device, const char *pName) HookInitVulkanInstanceExts(); } - if(GetDeviceDispatchTable(device)->GetDeviceProcAddr == NULL) - return NULL; - return GetDeviceDispatchTable(device)->GetDeviceProcAddr(Unwrap(device), pName); + // unknown or not-enabled functions must return NULL + return NULL; } VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL @@ -448,6 +447,12 @@ VK_LAYER_RENDERDOC_Capture_layerGetPhysicalDeviceProcAddr(VkInstance instance, c VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr(VkInstance instance, const char *pName) { + // if name is NULL undefined is returned, let's return NULL + if(pName == NULL) + return NULL; + + // a NULL instance can return vkGetInstanceProcAddr or a global function, handle that here + if(!strcmp("vkGetInstanceProcAddr", pName)) return (PFN_vkVoidFunction)&VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr; if(!strcmp("vkEnumerateInstanceExtensionProperties", pName)) @@ -455,6 +460,9 @@ VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr(VkInstance instance, const char *p if(!strcmp("vk_layerGetPhysicalDeviceProcAddr", pName)) return (PFN_vkVoidFunction)&VK_LAYER_RENDERDOC_Capture_layerGetPhysicalDeviceProcAddr; + // don't implement vkEnumerateInstanceLayerProperties or vkEnumerateInstanceVersion, the loader + // will do that + HookInit(CreateInstance); if(instance == VK_NULL_HANDLE) @@ -471,6 +479,9 @@ VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr(VkInstance instance, const char *p if(!strcmp("vkDestroyDevice", pName)) return (PFN_vkVoidFunction)&hooked_vkDestroyDevice; + // we should only return a function pointer for functions that are either from a supported core + // version, an enabled instance extension or an _available_ device extension + HookInitVulkanInstance(); InstanceDeviceInfo *instDevInfo = NULL; @@ -509,16 +520,17 @@ VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr(VkInstance instance, const char *p HookInitVulkanInstanceExts_PhysDev(); - if(GetInstanceDispatchTable(instance)->GetInstanceProcAddr == NULL) - return NULL; - return GetInstanceDispatchTable(instance)->GetInstanceProcAddr(Unwrap(instance), pName); + // all other functions must return NULL so that GIPA can be used with NULL checks sensibly for + // missing functionality + + return NULL; } 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 + // which are known but aren't physical device functions if(!strcmp("vkGetInstanceProcAddr", pName)) return NULL; if(!strcmp("vk_layerGetPhysicalDeviceProcAddr", pName)) @@ -589,14 +601,14 @@ VK_LAYER_RENDERDOC_Capture_layerGetPhysicalDeviceProcAddr(VkInstance instance, c if(GetInstanceDispatchTable(instance)->GetInstanceProcAddr == NULL) return NULL; - PFN_vkGetInstanceProcAddr GPDA = + PFN_vkGetInstanceProcAddr GPDPA = (PFN_vkGetInstanceProcAddr)GetInstanceDispatchTable(instance)->GetInstanceProcAddr( Unwrap(instance), "vk_layerGetPhysicalDeviceProcAddr"); - if(GPDA == NULL) + if(GPDPA == NULL) return NULL; - return GPDA(Unwrap(instance), pName); + return GPDPA(Unwrap(instance), pName); } // layer interface negotation (new interface)