diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index cdafe6fac..27564875a 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -1718,6 +1718,10 @@ void VulkanReplay::CreateResources() m_Histogram.Init(m_pDriver, m_General.DescriptorPool); + RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.9f); + + m_ShaderDebugData.Init(m_pDriver, m_General.DescriptorPool); + RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 1.0f); GPA_vkContextOpenInfo context = {Unwrap(m_pDriver->GetInstance()), @@ -2750,3 +2754,147 @@ void VulkanReplay::Feedback::Destroy(WrappedVulkan *driver) { FeedbackBuffer.Destroy(); } + +void ShaderDebugData::Init(WrappedVulkan *driver, VkDescriptorPool descriptorPool) +{ + // should match the enum ShaderDebugBind + CREATE_OBJECT( + DescSetLayout, + { + {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, NULL}, + {2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, NULL}, + {3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, NULL}, + {4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, NULL}, + {5, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, NULL}, + {6, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, NULL}, + }); + + CREATE_OBJECT(PipeLayout, DescSetLayout, 0); + + CREATE_OBJECT(DescSet, descriptorPool, DescSetLayout); + + VkResult vkr = VK_SUCCESS; + + VkImageCreateInfo imInfo = { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + NULL, + 0, + VK_IMAGE_TYPE_2D, + VK_FORMAT_R32G32B32A32_SFLOAT, + {1, 1, 1}, + 1, + 1, + VK_SAMPLE_COUNT_1_BIT, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL, + VK_IMAGE_LAYOUT_UNDEFINED, + }; + + vkr = driver->vkCreateImage(driver->GetDev(), &imInfo, NULL, &Image); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkMemoryRequirements mrq = {0}; + driver->vkGetImageMemoryRequirements(driver->GetDev(), Image, &mrq); + + // allocate readback memory + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + driver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = driver->vkAllocateMemory(driver->GetDev(), &allocInfo, NULL, &ImageMemory); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = driver->vkBindImageMemory(driver->GetDev(), Image, ImageMemory, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkImageViewCreateInfo viewInfo = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + NULL, + 0, + Image, + VK_IMAGE_VIEW_TYPE_2D, + VK_FORMAT_R32G32B32A32_SFLOAT, + {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY}, + { + VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1, + }, + }; + + vkr = driver->vkCreateImageView(driver->GetDev(), &viewInfo, NULL, &ImageView); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkAttachmentDescription attDesc = { + 0, + VK_FORMAT_R32G32B32A32_SFLOAT, + VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_CLEAR, + VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_GENERAL, + }; + + VkAttachmentReference attRef = {0, VK_IMAGE_LAYOUT_GENERAL}; + + VkSubpassDescription sub = { + 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, NULL, 1, &attRef, + }; + + VkSubpassDependency deps[2] = { + { + VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0, + }, + { + 0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_TRANSFER_READ_BIT, 0, + }, + }; + + VkRenderPassCreateInfo rpinfo = { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, NULL, 0, 1, &attDesc, 1, &sub, 2, deps, + }; + + vkr = driver->vkCreateRenderPass(driver->GetDev(), &rpinfo, NULL, &RenderPass); + if(vkr != VK_SUCCESS) + RDCERR("Failed to create shader debug render pass: %s", ToStr(vkr).c_str()); + + // create framebuffer + VkFramebufferCreateInfo fbinfo = { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, NULL, 0, RenderPass, 1, &ImageView, 1, 1, 1, + }; + + vkr = driver->vkCreateFramebuffer(driver->GetDev(), &fbinfo, NULL, &Framebuffer); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // don't need to ring this, as we hard-sync for readback anyway + ReadbackBuffer.Create(driver, driver->GetDev(), sizeof(Vec4f), 1, GPUBuffer::eGPUBufferReadback); +} + +void ShaderDebugData::Destroy(WrappedVulkan *driver) +{ + ReadbackBuffer.Destroy(); + + driver->vkDestroyDescriptorSetLayout(driver->GetDev(), DescSetLayout, NULL); + driver->vkDestroyPipelineLayout(driver->GetDev(), PipeLayout, NULL); + + driver->vkDestroyImage(driver->GetDev(), Image, NULL); + driver->vkFreeMemory(driver->GetDev(), ImageMemory, NULL); + driver->vkDestroyImageView(driver->GetDev(), ImageView, NULL); + driver->vkDestroyFramebuffer(driver->GetDev(), Framebuffer, NULL); + driver->vkDestroyRenderPass(driver->GetDev(), RenderPass, NULL); + + // one module each for float, uint, sint. + driver->vkDestroyShaderModule(driver->GetDev(), Module[0], NULL); + driver->vkDestroyShaderModule(driver->GetDev(), Module[1], NULL); + driver->vkDestroyShaderModule(driver->GetDev(), Module[2], NULL); +} diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index 2e0ef6acf..00ca7d29c 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -215,6 +215,26 @@ enum TexDisplayFlags eTexDisplay_RemapSInt = 0x80, }; +struct ShaderDebugData +{ + void Init(WrappedVulkan *driver, VkDescriptorPool descriptorPool); + void Destroy(WrappedVulkan *driver); + + VkDescriptorSetLayout DescSetLayout = VK_NULL_HANDLE; + VkPipelineLayout PipeLayout = VK_NULL_HANDLE; + VkDescriptorSet DescSet = VK_NULL_HANDLE; + + VkImage Image = VK_NULL_HANDLE; + VkImageView ImageView = VK_NULL_HANDLE; + VkDeviceMemory ImageMemory = VK_NULL_HANDLE; + VkFramebuffer Framebuffer = VK_NULL_HANDLE; + VkRenderPass RenderPass = VK_NULL_HANDLE; + + VkShaderModule Module[3] = {}; + + GPUBuffer ReadbackBuffer; +}; + class VulkanReplay : public IReplayDriver { public: @@ -249,6 +269,7 @@ public: rdcarray GetUsage(ResourceId id); + ShaderDebugData &GetShaderDebugData() { return m_ShaderDebugData; } FrameRecord &WriteFrameRecord() { return m_FrameRecord; } FrameRecord GetFrameRecord() { return m_FrameRecord; } rdcarray GetDebugMessages(); @@ -671,6 +692,8 @@ private: std::map Usage; } m_BindlessFeedback; + ShaderDebugData m_ShaderDebugData; + rdcarray m_Resources; std::map m_ResourceIdx; diff --git a/renderdoc/driver/vulkan/vk_shaderdebug.cpp b/renderdoc/driver/vulkan/vk_shaderdebug.cpp index f825eeadc..d70922ef1 100644 --- a/renderdoc/driver/vulkan/vk_shaderdebug.cpp +++ b/renderdoc/driver/vulkan/vk_shaderdebug.cpp @@ -42,7 +42,10 @@ RDOC_DEBUG_CONFIG(bool, Vulkan_Debug_DisableBufferDeviceAddress, false, class VulkanAPIWrapper : public rdcspv::DebugAPIWrapper { public: - VulkanAPIWrapper(WrappedVulkan *vk) { m_pDriver = vk; } + VulkanAPIWrapper(WrappedVulkan *vk) : m_DebugData(vk->GetReplay()->GetShaderDebugData()) + { + m_pDriver = vk; + } virtual void AddDebugMessage(MessageCategory c, MessageSeverity sv, MessageSource src, rdcstr d) override { @@ -133,6 +136,7 @@ public: private: WrappedVulkan *m_pDriver = NULL; + ShaderDebugData &m_DebugData; }; enum StorageMode