From 15b4126c748ff1f58c67cf07ca0a71099a107286 Mon Sep 17 00:00:00 2001 From: Friedrich Vock Date: Mon, 9 Dec 2024 20:03:03 +0100 Subject: [PATCH 1/2] Enable RT pipeline capture/replay feature alongside RT pipelines Required for using capture/replay shader handles. --- .../driver/vulkan/wrappers/vk_device_funcs.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index 89752c239a..9ecec42b52 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -3364,6 +3364,19 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi VkPhysicalDeviceProperties2 availPropsBase = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2}; availPropsBase.pNext = &rayProps; ObjDisp(physicalDevice)->GetPhysicalDeviceProperties2(Unwrap(physicalDevice), &availPropsBase); + + if(ext->rayTracingPipeline && !avail.rayTracingPipelineShaderGroupHandleCaptureReplay) + { + SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, + "Capture requires rayTracingPipeline support, which is available, but " + "rayTracingPipelineShaderGroupHandleCaptureReplay support is not " + "available which is required to replay\n" + "\n%s", + GetPhysDeviceCompatString(false, false).c_str()); + return false; + } + if(ext->rayTracingPipeline) + ext->rayTracingPipelineShaderGroupHandleCaptureReplay = VK_TRUE; } END_PHYS_EXT_CHECK(); } From 3b9b5ad4ecf6477f1ecfb00133ef1dc33123ddde Mon Sep 17 00:00:00 2001 From: Friedrich Vock Date: Mon, 9 Dec 2024 20:01:44 +0100 Subject: [PATCH 2/2] Always pass CAPTURE_REPLAY RT pipeline create flags This is required for RT pipelines when capture/replay handles are used, both during capture and replay. --- .../vulkan/wrappers/vk_shader_funcs.cpp | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp index fa69c4c5e5..9410b715e3 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp @@ -1464,14 +1464,29 @@ VkResult WrappedVulkan::vkCreateRayTracingPipelinesKHR( { VkResult ret; - // to be extra sure just in case the driver doesn't, set pipelines to VK_NULL_HANDLE first. + VkRayTracingPipelineCreateInfoKHR *unwrappedCreateInfos = + UnwrapInfos(m_State, pCreateInfos, createInfoCount); + for(uint32_t i = 0; i < createInfoCount; i++) + { + // to be extra sure just in case the driver doesn't, set pipelines to VK_NULL_HANDLE first. pPipelines[i] = VK_NULL_HANDLE; + // Patch in capture/replay creation flags + VkPipelineCreateFlags2CreateInfoKHR *flagsInfo = + (VkPipelineCreateFlags2CreateInfoKHR *)FindNextStruct( + &unwrappedCreateInfos[i], VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO_KHR); + if(flagsInfo) + flagsInfo->flags |= VK_PIPELINE_CREATE_2_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR; + else + unwrappedCreateInfos[i].flags |= + VK_PIPELINE_CREATE_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR; + } + // deferred operations are currently not wrapped SERIALISE_TIME_CALL(ret = ObjDisp(device)->CreateRayTracingPipelinesKHR( Unwrap(device), VK_NULL_HANDLE, Unwrap(pipelineCache), createInfoCount, - UnwrapInfos(m_State, pCreateInfos, createInfoCount), NULL, pPipelines)); + unwrappedCreateInfos, NULL, pPipelines)); if(ret == VK_SUCCESS || ret == VK_PIPELINE_COMPILE_REQUIRED) { @@ -1491,25 +1506,24 @@ VkResult WrappedVulkan::vkCreateRayTracingPipelinesKHR( { CACHE_THREAD_SERIALISER(); - VkRayTracingPipelineCreateInfoKHR modifiedCreateInfo; - const VkRayTracingPipelineCreateInfoKHR *createInfo = &pCreateInfos[i]; + VkRayTracingPipelineCreateInfoKHR modifiedCreateInfo = pCreateInfos[i]; + modifiedCreateInfo.flags |= + VK_PIPELINE_CREATE_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR; - if(createInfo->flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT) + if(pCreateInfos[i].flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT) { // since we serialise one by one, we need to fixup basePipelineIndex - if(createInfo->basePipelineIndex != -1 && createInfo->basePipelineIndex < (int)i) + if(pCreateInfos[i].basePipelineIndex != -1 && pCreateInfos[i].basePipelineIndex < (int)i) { - modifiedCreateInfo = *createInfo; modifiedCreateInfo.basePipelineHandle = pPipelines[modifiedCreateInfo.basePipelineIndex]; modifiedCreateInfo.basePipelineIndex = -1; - createInfo = &modifiedCreateInfo; } } SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCreateRayTracingPipelinesKHR); Serialise_vkCreateRayTracingPipelinesKHR(ser, device, deferredOperation, pipelineCache, 1, - createInfo, NULL, &pPipelines[i]); + &modifiedCreateInfo, NULL, &pPipelines[i]); chunk = scope.Get(); }