From abcfcfd8a4847d0592b02d0e45fc4c21c75cfe7d Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 16 Jun 2017 15:59:39 +0100 Subject: [PATCH] Display resolve attachments with other framebuffer outputs in UI --- .../Code/Interface/CommonPipelineState.cpp | 25 +++++++++++++--- .../VulkanPipelineStateViewer.cpp | 23 ++++++++++++-- renderdoc/api/replay/vk_pipestate.h | 2 ++ renderdoc/core/replay_proxy.cpp | 5 ++-- renderdoc/driver/vulkan/vk_info.cpp | 2 ++ renderdoc/driver/vulkan/vk_info.h | 1 + renderdoc/driver/vulkan/vk_replay.cpp | 2 ++ renderdocui/Code/CommonPipelineState.cs | 30 +++++++++++++++---- renderdocui/Interop/VulkanPipelineState.cs | 2 ++ .../VulkanPipelineStateViewer.Designer.cs | 2 +- .../VulkanPipelineStateViewer.cs | 11 +++++-- 11 files changed, 88 insertions(+), 17 deletions(-) diff --git a/qrenderdoc/Code/Interface/CommonPipelineState.cpp b/qrenderdoc/Code/Interface/CommonPipelineState.cpp index febed0c1a..edc0c2e81 100644 --- a/qrenderdoc/Code/Interface/CommonPipelineState.cpp +++ b/qrenderdoc/Code/Interface/CommonPipelineState.cpp @@ -1306,16 +1306,33 @@ QVector CommonPipelineState::GetOutputTargets() const auto &rp = m_Vulkan->Pass.renderpass; const auto &fb = m_Vulkan->Pass.framebuffer; + int idx = 0; + ret.resize(rp.colorAttachments.count); for(int i = 0; i < rp.colorAttachments.count; i++) { if(rp.colorAttachments[i] < (uint32_t)fb.attachments.count) { - ret[i].Id = fb.attachments[rp.colorAttachments[i]].img; - ret[i].HighestMip = (int)fb.attachments[rp.colorAttachments[i]].baseMip; - ret[i].FirstSlice = (int)fb.attachments[rp.colorAttachments[i]].baseLayer; - ret[i].typeHint = fb.attachments[rp.colorAttachments[i]].viewfmt.compType; + ret[idx].Id = fb.attachments[rp.colorAttachments[i]].img; + ret[idx].HighestMip = (int)fb.attachments[rp.colorAttachments[i]].baseMip; + ret[idx].FirstSlice = (int)fb.attachments[rp.colorAttachments[i]].baseLayer; + ret[idx].typeHint = fb.attachments[rp.colorAttachments[i]].viewfmt.compType; } + + idx++; + } + + for(int i = 0; i < rp.resolveAttachments.count; i++) + { + if(rp.resolveAttachments[i] < (uint32_t)fb.attachments.count) + { + ret[idx].Id = fb.attachments[rp.resolveAttachments[i]].img; + ret[idx].HighestMip = (int)fb.attachments[rp.resolveAttachments[i]].baseMip; + ret[idx].FirstSlice = (int)fb.attachments[rp.resolveAttachments[i]].baseLayer; + ret[idx].typeHint = fb.attachments[rp.resolveAttachments[i]].viewfmt.compType; + } + + idx++; } } } diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index 4a3a3e6ec..6c0b1d393 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -1771,9 +1771,19 @@ void VulkanPipelineStateViewer::setState() break; } } + int resIdx = -1; + for(int c = 0; c < state.Pass.renderpass.resolveAttachments.count; c++) + { + if(state.Pass.renderpass.resolveAttachments[c] == (uint)i) + { + resIdx = c; + break; + } + } bool filledSlot = (p.img != ResourceId()); - bool usedSlot = (colIdx >= 0 || state.Pass.renderpass.depthstencilAttachment == i); + bool usedSlot = + (colIdx >= 0 || resIdx >= 0 || state.Pass.renderpass.depthstencilAttachment == i); if(showNode(usedSlot, filledSlot)) { @@ -1825,8 +1835,17 @@ void VulkanPipelineStateViewer::setState() .arg(ToQStr(p.swizzle[3])); } + QString slotname; + + if(colIdx >= 0) + slotname = QFormatStr("Color %1").arg(i); + else if(resIdx >= 0) + slotname = QFormatStr("Resolve %1").arg(i); + else + slotname = lit("Depth"); + RDTreeWidgetItem *node = - new RDTreeWidgetItem({i, name, typeName, w, h, d, a, format, QString()}); + new RDTreeWidgetItem({slotname, name, typeName, w, h, d, a, format, QString()}); if(tex) node->setTag(QVariant::fromValue(p.img)); diff --git a/renderdoc/api/replay/vk_pipestate.h b/renderdoc/api/replay/vk_pipestate.h index a0006b03f..917e7d8c5 100644 --- a/renderdoc/api/replay/vk_pipestate.h +++ b/renderdoc/api/replay/vk_pipestate.h @@ -447,6 +447,8 @@ struct RenderPass rdctype::array inputAttachments; DOCUMENT("A list of indices into the framebuffer attachments for color attachments."); rdctype::array colorAttachments; + DOCUMENT("A list of indices into the framebuffer attachments for resolve attachments."); + rdctype::array resolveAttachments; DOCUMENT(R"(An index into the framebuffer attachments for the depth-stencil attachment. If there is no depth-stencil attachment, this index is ``-1``. diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index fcbbc3990..5f5f31e1a 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -1175,6 +1175,7 @@ void Serialiser::Serialise(const char *name, VKPipe::CurrentPass &el) Serialise("", el.renderpass.obj); Serialise("", el.renderpass.inputAttachments); Serialise("", el.renderpass.colorAttachments); + Serialise("", el.renderpass.resolveAttachments); Serialise("", el.renderpass.depthstencilAttachment); Serialise("", el.framebuffer.obj); @@ -1185,7 +1186,7 @@ void Serialiser::Serialise(const char *name, VKPipe::CurrentPass &el) Serialise("", el.renderArea); - SIZE_CHECK(104); + SIZE_CHECK(120); } template <> @@ -1236,7 +1237,7 @@ void Serialiser::Serialise(const char *name, VKPipe::State &el) Serialise("", el.images); - SIZE_CHECK(1336); + SIZE_CHECK(1352); } #pragma endregion Vulkan pipeline state diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index db18e55e2..f8710480e 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -463,9 +463,11 @@ void VulkanCreationInfo::RenderPass::Init(VulkanResourceManager *resourceMan, } dst.colorAttachments.resize(src.colorAttachmentCount); + dst.resolveAttachments.resize(src.colorAttachmentCount); dst.colorLayouts.resize(src.colorAttachmentCount); for(uint32_t i = 0; i < src.colorAttachmentCount; i++) { + dst.resolveAttachments[i] = src.pResolveAttachments ? src.pResolveAttachments[i].attachment : ~0U; dst.colorAttachments[i] = src.pColorAttachments[i].attachment; dst.colorLayouts[i] = src.pColorAttachments[i].layout; } diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index 081105a01..57d79413f 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -222,6 +222,7 @@ struct VulkanCreationInfo // rarely used but the indices are often used vector inputAttachments; vector colorAttachments; + vector resolveAttachments; int32_t depthstencilAttachment; vector inputLayouts; diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index a6f91fdc5..d2a7aea4b 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -3059,6 +3059,8 @@ void VulkanReplay::SavePipelineState() c.m_RenderPass[state.renderPass].subpasses[state.subpass].inputAttachments; m_VulkanPipelineState.Pass.renderpass.colorAttachments = c.m_RenderPass[state.renderPass].subpasses[state.subpass].colorAttachments; + m_VulkanPipelineState.Pass.renderpass.resolveAttachments = + c.m_RenderPass[state.renderPass].subpasses[state.subpass].resolveAttachments; m_VulkanPipelineState.Pass.renderpass.depthstencilAttachment = c.m_RenderPass[state.renderPass].subpasses[state.subpass].depthstencilAttachment; } diff --git a/renderdocui/Code/CommonPipelineState.cs b/renderdocui/Code/CommonPipelineState.cs index 80b5eface..6b3f5818b 100644 --- a/renderdocui/Code/CommonPipelineState.cs +++ b/renderdocui/Code/CommonPipelineState.cs @@ -1461,18 +1461,36 @@ namespace renderdocui.Code var rp = m_Vulkan.Pass.renderpass; var fb = m_Vulkan.Pass.framebuffer; - BoundResource[] ret = new BoundResource[rp.colorAttachments.Length]; + int idx = 0; + + BoundResource[] ret = new BoundResource[rp.colorAttachments.Length*2]; for (int i = 0; i < rp.colorAttachments.Length; i++) { - ret[i] = new BoundResource(); + ret[idx] = new BoundResource(); if(rp.colorAttachments[i] < fb.attachments.Length) { - ret[i].Id = fb.attachments[rp.colorAttachments[i]].img; - ret[i].HighestMip = (int)fb.attachments[rp.colorAttachments[i]].baseMip; - ret[i].FirstSlice = (int)fb.attachments[rp.colorAttachments[i]].baseLayer; - ret[i].typeHint = fb.attachments[rp.colorAttachments[i]].viewfmt.compType; + ret[idx].Id = fb.attachments[rp.colorAttachments[i]].img; + ret[idx].HighestMip = (int)fb.attachments[rp.colorAttachments[i]].baseMip; + ret[idx].FirstSlice = (int)fb.attachments[rp.colorAttachments[i]].baseLayer; + ret[idx].typeHint = fb.attachments[rp.colorAttachments[i]].viewfmt.compType; } + + idx++; + } + for (int i = 0; i < rp.resolveAttachments.Length; i++) + { + ret[idx] = new BoundResource(); + + if (rp.resolveAttachments[i] < fb.attachments.Length) + { + ret[idx].Id = fb.attachments[rp.resolveAttachments[i]].img; + ret[idx].HighestMip = (int)fb.attachments[rp.resolveAttachments[i]].baseMip; + ret[idx].FirstSlice = (int)fb.attachments[rp.resolveAttachments[i]].baseLayer; + ret[idx].typeHint = fb.attachments[rp.resolveAttachments[i]].viewfmt.compType; + } + + idx++; } return ret; diff --git a/renderdocui/Interop/VulkanPipelineState.cs b/renderdocui/Interop/VulkanPipelineState.cs index fcc2ad81f..3894096cc 100644 --- a/renderdocui/Interop/VulkanPipelineState.cs +++ b/renderdocui/Interop/VulkanPipelineState.cs @@ -350,6 +350,8 @@ namespace renderdoc public UInt32[] inputAttachments; [CustomMarshalAs(CustomUnmanagedType.TemplatedArray)] public UInt32[] colorAttachments; + [CustomMarshalAs(CustomUnmanagedType.TemplatedArray)] + public UInt32[] resolveAttachments; public Int32 depthstencilAttachment; }; [CustomMarshalAs(CustomUnmanagedType.CustomClass)] diff --git a/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.Designer.cs b/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.Designer.cs index 868c5a05b..eb205e8c1 100644 --- a/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.Designer.cs +++ b/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.Designer.cs @@ -2918,7 +2918,7 @@ // targetOutputs // treeListColumn103.AutoSizeMinSize = 0; - treeListColumn103.Width = 50; + treeListColumn103.Width = 70; treeListColumn104.AutoSize = true; treeListColumn104.AutoSizeMinSize = 150; treeListColumn104.Width = 50; diff --git a/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.cs b/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.cs index 943aa10bd..5a0c882fe 100644 --- a/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.cs +++ b/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.cs @@ -1536,9 +1536,10 @@ namespace renderdocui.Windows.PipelineState foreach (var p in state.Pass.framebuffer.attachments) { int colIdx = Array.IndexOf(state.Pass.renderpass.colorAttachments, (uint)i); + int resIdx = Array.IndexOf(state.Pass.renderpass.resolveAttachments, (uint)i); bool filledSlot = (p.img != ResourceId.Null); - bool usedSlot = (colIdx >= 0 || state.Pass.renderpass.depthstencilAttachment == i); + bool usedSlot = (colIdx >= 0 || resIdx >= 0 || state.Pass.renderpass.depthstencilAttachment == i); // show if if (usedSlot || // it's referenced by the shader - regardless of empty or not @@ -1605,7 +1606,13 @@ namespace renderdocui.Windows.PipelineState p.swizzle[3].Str()); } - var node = targetOutputs.Nodes.Add(new object[] { i, name, typename, w, h, d, a, format }); + string slotname = String.Format("Color {0}", i); + if (resIdx >= 0) + slotname = String.Format("Resolve {0}", i); + else if (colIdx < 0) + slotname = "Depth"; + + var node = targetOutputs.Nodes.Add(new object[] { slotname, name, typename, w, h, d, a, format }); node.Image = global::renderdocui.Properties.Resources.action; node.HoverImage = global::renderdocui.Properties.Resources.action_hover;