diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 4012b62e3..6c1074842 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -292,6 +292,8 @@ WrappedVulkan::WrappedVulkan(const char *logFilename) m_DrawcallStack.push_back(&m_ParentDrawcall); + m_SetDeviceLoaderData = NULL; + m_ResourceManager = new VulkanResourceManager(m_State, m_pSerialiser, this); m_pSerialiser->SetUserData(m_ResourceManager); @@ -368,7 +370,10 @@ VkCommandBuffer WrappedVulkan::GetNextCmd() VkCommandBufferAllocateInfo cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, NULL, Unwrap(m_InternalCmds.cmdpool), VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1 }; VkResult vkr = ObjDisp(m_Device)->AllocateCommandBuffers(Unwrap(m_Device), &cmdInfo, &ret); - SetDispatchTableOverMagicNumber(m_Device, ret); + if(m_SetDeviceLoaderData) + m_SetDeviceLoaderData(m_Device, ret); + else + SetDispatchTableOverMagicNumber(m_Device, ret); RDCASSERTEQUAL(vkr, VK_SUCCESS); diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index e1e56366b..dc028168a 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -256,6 +256,8 @@ private: VkPhysicalDeviceMemoryProperties memProps; VkFormatProperties fmtprops[VK_FORMAT_RANGE_SIZE]; }; + + PFN_vkSetDeviceLoaderData m_SetDeviceLoaderData; VkInstance m_Instance; // the instance corresponding to this WrappedVulkan VkDebugReportCallbackEXT m_DbgMsgCallback; // the instance's dbg msg callback handle diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index 99bbbe3f7..822773d9c 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -507,13 +507,6 @@ void SetDispatchTableOverMagicNumber(VkDevice parent, RealType obj) wrapped->loaderTable = GetWrapped(parent)->loaderTable; } -template -void SetMagicNumberOverDispatchTable(RealType obj) -{ - typename UnwrapHelper::Outer *wrapped = GetWrapped(obj); - wrapped->loaderTable = 0x01CDC0DE; -} - template WrappedVulkan *CoreDisp(RealType obj) { diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index f89d0ed1d..1dac20b41 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -231,12 +231,17 @@ VkResult WrappedVulkan::vkAllocateCommandBuffers( { for(uint32_t i=0; i < unwrappedInfo.commandBufferCount; i++) { - SetDispatchTableOverMagicNumber(device, pCommandBuffers[i]); + VkCommandBuffer unwrappedReal = pCommandBuffers[i]; ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), pCommandBuffers[i]); - - // loader expects command buffers to have the magic number in them - SetMagicNumberOverDispatchTable(pCommandBuffers[i]); + + // we set this *after* wrapping, so that the wrapped resource copies the 'uninitialised' + // loader table, since the loader expects to set the dispatch table onto an existing magic + // number in the trampoline function at the start of the chain. + if(m_SetDeviceLoaderData) + m_SetDeviceLoaderData(device, unwrappedReal); + else + SetDispatchTableOverMagicNumber(device, unwrappedReal); if(m_State >= WRITING) { diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index 6559e3a4e..b6f568286 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -174,13 +174,9 @@ VkResult WrappedVulkan::vkCreateInstance( layerCreateInfo->function != VK_LAYER_LINK_INFO) ) { - // we don't handle any pNext elements other than this create info struct - RDCASSERT(layerCreateInfo->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO); layerCreateInfo = (VkLayerInstanceCreateInfo *)layerCreateInfo->pNext; } RDCASSERT(layerCreateInfo); - // make sure there are no elements after this, that we don't handle - RDCASSERT(layerCreateInfo->pNext == NULL); PFN_vkGetInstanceProcAddr gpa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr; // move chain on for next layer @@ -850,15 +846,10 @@ VkResult WrappedVulkan::vkCreateDevice( layerCreateInfo->function != VK_LAYER_LINK_INFO) ) { - // we don't handle any pNext elements other than this create info struct - RDCASSERT(layerCreateInfo->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO); layerCreateInfo = (VkLayerDeviceCreateInfo *)layerCreateInfo->pNext; } RDCASSERT(layerCreateInfo); - // make sure there are no elements after this, that we don't handle - RDCASSERT(layerCreateInfo->pNext == NULL); - PFN_vkGetDeviceProcAddr gdpa = layerCreateInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr; PFN_vkGetInstanceProcAddr gipa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr; // move chain on for next layer @@ -866,6 +857,27 @@ VkResult WrappedVulkan::vkCreateDevice( PFN_vkCreateDevice createFunc = (PFN_vkCreateDevice)gipa(VK_NULL_HANDLE, "vkCreateDevice"); + // now search again through for the loader data callback (if it exists) + layerCreateInfo = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext; + + // step through the chain of pNext + while(layerCreateInfo && + (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO || + layerCreateInfo->function != VK_LOADER_DATA_CALLBACK) + ) + { + layerCreateInfo = (VkLayerDeviceCreateInfo *)layerCreateInfo->pNext; + } + + // if we found one (we might not - on old loaders), then store the func ptr for + // use instead of SetDispatchTableOverMagicNumber + if(layerCreateInfo) + { + RDCASSERT(m_SetDeviceLoaderData == layerCreateInfo->u.pfnSetDeviceLoaderData || m_SetDeviceLoaderData == NULL, + m_SetDeviceLoaderData, layerCreateInfo->u.pfnSetDeviceLoaderData); + m_SetDeviceLoaderData = layerCreateInfo->u.pfnSetDeviceLoaderData; + } + VkResult ret = createFunc(Unwrap(physicalDevice), &createInfo, pAllocator, pDevice); // don't serialise out any of the pNext stuff for layer initialisation diff --git a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp index e8bca4cfe..d0785d6d5 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp @@ -66,8 +66,11 @@ void WrappedVulkan::vkGetDeviceQueue( VkQueue* pQueue) { ObjDisp(device)->GetDeviceQueue(Unwrap(device), queueFamilyIndex, queueIndex, pQueue); - - SetDispatchTableOverMagicNumber(device, *pQueue); + + if(m_SetDeviceLoaderData) + m_SetDeviceLoaderData(m_Device, *pQueue); + else + SetDispatchTableOverMagicNumber(device, *pQueue); RDCASSERT(m_State >= WRITING);