diff --git a/renderdoc/api/replay/data_types.h b/renderdoc/api/replay/data_types.h index 96eefdc7e..f3356f457 100644 --- a/renderdoc/api/replay/data_types.h +++ b/renderdoc/api/replay/data_types.h @@ -176,24 +176,30 @@ struct FetchDrawcall { eventID = 0; drawcallID = 0; + flags = 0; numIndices = 0; numInstances = 0; indexOffset = 0; vertexOffset = 0; instanceOffset = 0; - topology = eTopology_Unknown; + + dispatchDimension[0] = dispatchDimension[1] = dispatchDimension[2] = 0; + dispatchThreadsDimension[0] = dispatchThreadsDimension[1] = dispatchThreadsDimension[2] = 0; + indexByteWidth = 0; - flags = 0; + topology = eTopology_Unknown; + + copySource = ResourceId(); + copyDestination = ResourceId(); + context = ResourceId(); parent = 0; previous = 0; next = 0; - dispatchDimension[0] = dispatchDimension[1] = dispatchDimension[2] = 0; - dispatchThreadsDimension[0] = dispatchThreadsDimension[1] = dispatchThreadsDimension[2] = 0; - for(int i=0; i < 8; i++) outputs[i] = ResourceId(); + depthOut = ResourceId(); } uint32_t eventID, drawcallID; @@ -214,6 +220,9 @@ struct FetchDrawcall uint32_t indexByteWidth; PrimitiveTopology topology; + ResourceId copySource; + ResourceId copyDestination; + ResourceId context; int64_t parent; diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index bb4d89966..205a7538d 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -784,6 +784,9 @@ void Serialiser::Serialise(const char *name, FetchDrawcall &el) Serialise("", el.topology); Serialise("", el.context); + + Serialise("", el.copySource); + Serialise("", el.copyDestination); Serialise("", el.parent); Serialise("", el.previous); @@ -795,7 +798,7 @@ void Serialiser::Serialise(const char *name, FetchDrawcall &el) Serialise("", el.events); Serialise("", el.children); - SIZE_CHECK(FetchDrawcall, 192); + SIZE_CHECK(FetchDrawcall, 208); } template<> diff --git a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp index ea8457a32..b006ce392 100644 --- a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp @@ -4843,11 +4843,12 @@ bool WrappedID3D11DeviceContext::Serialise_CopySubresourceRegion( ID3D11Resource draw.name = name; draw.flags |= eDraw_Copy; - AddDrawcall(draw, true); - if(m_pDevice->GetResourceManager()->HasLiveResource(Destination) && m_pDevice->GetResourceManager()->HasLiveResource(Source)) { + draw.copySource = Source; + draw.copyDestination = Destination; + if(Destination == Source) { m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back(EventUsage(m_CurEventID, eUsage_Copy)); @@ -4858,6 +4859,8 @@ bool WrappedID3D11DeviceContext::Serialise_CopySubresourceRegion( ID3D11Resource m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Source)].push_back(EventUsage(m_CurEventID, eUsage_CopySrc)); } } + + AddDrawcall(draw, true); } return true; @@ -4974,11 +4977,12 @@ bool WrappedID3D11DeviceContext::Serialise_CopyResource(ID3D11Resource *pDstReso draw.name = name; draw.flags |= eDraw_Copy; - AddDrawcall(draw, true); - if(m_pDevice->GetResourceManager()->HasLiveResource(Destination) && m_pDevice->GetResourceManager()->HasLiveResource(Source)) { + draw.copySource = Source; + draw.copyDestination = Destination; + if(Destination == Source) { m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back(EventUsage(m_CurEventID, eUsage_Copy)); @@ -4989,6 +4993,8 @@ bool WrappedID3D11DeviceContext::Serialise_CopyResource(ID3D11Resource *pDstReso m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Source)].push_back(EventUsage(m_CurEventID, eUsage_CopySrc)); } } + + AddDrawcall(draw, true); } return true; @@ -5428,11 +5434,12 @@ bool WrappedID3D11DeviceContext::Serialise_ResolveSubresource(ID3D11Resource *pD draw.name = name; draw.flags |= eDraw_Resolve; - AddDrawcall(draw, true); - if(m_pDevice->GetResourceManager()->HasLiveResource(DestResource) && m_pDevice->GetResourceManager()->HasLiveResource(SourceResource)) { + draw.copySource = SourceResource; + draw.copyDestination = DestResource; + if(DestResource == SourceResource) { m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(DestResource)].push_back(EventUsage(m_CurEventID, eUsage_Resolve)); @@ -5443,6 +5450,8 @@ bool WrappedID3D11DeviceContext::Serialise_ResolveSubresource(ID3D11Resource *pD m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(SourceResource)].push_back(EventUsage(m_CurEventID, eUsage_ResolveSrc)); } } + + AddDrawcall(draw, true); } return true; diff --git a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp index 7ec7f52f8..a40e8cb54 100644 --- a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp @@ -1336,8 +1336,6 @@ bool WrappedOpenGL::Serialise_glBlitNamedFramebuffer(GLuint readFramebuffer, GLu draw.name = name; draw.flags |= eDraw_Resolve; - AddDrawcall(draw, true); - GLint numCols = 8; m_Real.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); @@ -1373,6 +1371,9 @@ bool WrappedOpenGL::Serialise_glBlitNamedFramebuffer(GLuint readFramebuffer, GLu dstid = GetResourceManager()->GetID(TextureRes(GetCtx(), dstattachment)); else dstid = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), dstattachment)); + + draw.copySource = GetResourceManager()->GetOriginalID(srcid); + draw.copyDestination = GetResourceManager()->GetOriginalID(dstid); // MS to non-MS is a resolve if((m_Textures[srcid].curType == eGL_TEXTURE_2D_MULTISAMPLE || @@ -1390,6 +1391,8 @@ bool WrappedOpenGL::Serialise_glBlitNamedFramebuffer(GLuint readFramebuffer, GLu } } } + + AddDrawcall(draw, true); } return true; diff --git a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp index e7bcb1c50..bbb814bee 100644 --- a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp @@ -791,6 +791,9 @@ bool WrappedOpenGL::Serialise_glCopyImageSubData(GLuint srcName, GLenum srcTarge draw.name = name; draw.flags |= eDraw_Copy; + draw.copySource = srcid; + draw.copyDestination = dstid; + AddDrawcall(draw, true); if(srcid == dstid) diff --git a/renderdocui/Code/CommonPipelineState.cs b/renderdocui/Code/CommonPipelineState.cs index a81cba179..e7cb2cff9 100644 --- a/renderdocui/Code/CommonPipelineState.cs +++ b/renderdocui/Code/CommonPipelineState.cs @@ -575,7 +575,43 @@ namespace renderdocui.Code } } - return null; + return new ResourceId[0]; + } + + public ResourceId[] GetReadWriteResources(ShaderStageType stage) + { + if (LogLoaded) + { + if (IsLogD3D11) + { + if (stage == ShaderStageType.Compute) + { + ResourceId[] ret = new ResourceId[m_D3D11.m_CS.UAVs.Length]; + for (int i = 0; i < m_D3D11.m_CS.UAVs.Length; i++) + ret[i] = m_D3D11.m_CS.UAVs[i].Resource; + + return ret; + } + else + { + ResourceId[] ret = new ResourceId[m_D3D11.m_OM.UAVs.Length]; + for (int i = 0; i < m_D3D11.m_OM.UAVs.Length; i++) + ret[i] = m_D3D11.m_OM.UAVs[i].Resource; + + return ret; + } + } + else if (IsLogGL) + { + ResourceId[] ret = new ResourceId[m_GL.Images.Length]; + for (int i = 0; i < m_GL.Images.Length; i++) + ret[i] = m_GL.Images[i].Resource; + + return ret; + } + } + + return new ResourceId[0]; } public ResourceId GetDepthTarget() @@ -604,31 +640,6 @@ namespace renderdocui.Code return ResourceId.Null; } - public ResourceId[] GetReadWriteResources() - { - if (LogLoaded) - { - if (IsLogD3D11) - { - ResourceId[] ret = new ResourceId[m_D3D11.m_OM.UAVs.Length]; - for (int i = 0; i < m_D3D11.m_OM.UAVs.Length; i++) - ret[i] = m_D3D11.m_OM.UAVs[i].Resource; - - return ret; - } - else if (IsLogGL) - { - ResourceId[] ret = new ResourceId[m_GL.Images.Length]; - for (int i = 0; i < m_GL.Images.Length; i++) - ret[i] = m_GL.Images[i].Resource; - - return ret; - } - } - - return null; - } - public ResourceId[] GetOutputTargets() { if (LogLoaded) @@ -655,7 +666,7 @@ namespace renderdocui.Code } } - return null; + return new ResourceId[0]; } public ResourceId OutputDepth diff --git a/renderdocui/Interop/Enums.cs b/renderdocui/Interop/Enums.cs index 0d8b97b41..0a9c72d1d 100644 --- a/renderdocui/Interop/Enums.cs +++ b/renderdocui/Interop/Enums.cs @@ -692,6 +692,36 @@ namespace renderdoc return stage.ToString(); } + public static string Abbrev(this ShaderStageType stage, APIPipelineStateType apitype) + { + if (apitype == APIPipelineStateType.D3D11) + { + switch (stage) + { + case ShaderStageType.Vertex: return "VS"; + case ShaderStageType.Hull: return "HS"; + case ShaderStageType.Domain: return "DS"; + case ShaderStageType.Geometry: return "GS"; + case ShaderStageType.Pixel: return "PS"; + case ShaderStageType.Compute: return "CS"; + } + } + else if (apitype == APIPipelineStateType.OpenGL) + { + switch (stage) + { + case ShaderStageType.Vertex: return "VS"; + case ShaderStageType.Tess_Control: return "TCS"; + case ShaderStageType.Tess_Eval: return "TES"; + case ShaderStageType.Geometry: return "GS"; + case ShaderStageType.Fragment: return "FS"; + case ShaderStageType.Compute: return "CS"; + } + } + + return "?S"; + } + public static string Str(this SystemAttribute systemValue) { switch (systemValue) diff --git a/renderdocui/Interop/FetchInfo.cs b/renderdocui/Interop/FetchInfo.cs index 5177a919e..0b7f4b31f 100644 --- a/renderdocui/Interop/FetchInfo.cs +++ b/renderdocui/Interop/FetchInfo.cs @@ -339,6 +339,9 @@ namespace renderdoc public UInt32 indexByteWidth; public PrimitiveTopology topology; + public ResourceId copySource; + public ResourceId copyDestination; + public ResourceId context; public Int64 parentDrawcall; diff --git a/renderdocui/Windows/TextureViewer.cs b/renderdocui/Windows/TextureViewer.cs index 40b1376e5..1cf021b9c 100644 --- a/renderdocui/Windows/TextureViewer.cs +++ b/renderdocui/Windows/TextureViewer.cs @@ -59,7 +59,7 @@ namespace renderdocui.Windows private int m_HighWaterStatusLength = 0; - public enum FollowType { OutputColour, OutputDepth, ReadWriteRes, PSResource } + public enum FollowType { OutputColour, OutputDepth, ReadWriteRes, InputResource } struct Following { public FollowType Type; @@ -85,9 +85,26 @@ namespace renderdocui.Windows } // todo, implement these better for GL :( + private static void GetDrawContext(Core core, out bool copy, out bool compute) + { + var curDraw = core.CurDrawcall; + copy = curDraw != null && (curDraw.flags & (DrawcallFlags.Copy | DrawcallFlags.Resolve)) != 0; + compute = curDraw != null && (curDraw.flags & DrawcallFlags.Dispatch) != 0 && + core.CurPipelineState.GetShader(ShaderStageType.Compute) != ResourceId.Null; + } public int GetHighestMip(Core core) { + var curDraw = core.CurDrawcall; + bool copy, compute; + GetDrawContext(core, out copy, out compute); + + // TODO find a way (without copy-pasting tons of code) + // to duplicate the logic of GetResourceId() but return + // different information + if (copy || compute) + return -1; + if (core.APIProps.pipelineType == APIPipelineStateType.D3D11) { D3D11PipelineState.ShaderStage.ResourceView view = null; @@ -105,7 +122,7 @@ namespace renderdocui.Windows if (index >= core.CurD3D11PipelineState.m_OM.UAVStartSlot) view = core.CurD3D11PipelineState.m_OM.UAVs[index]; } - else if (Type == FollowType.PSResource) + else if (Type == FollowType.InputResource) { view = core.CurD3D11PipelineState.m_PS.SRVs[index]; } @@ -133,6 +150,16 @@ namespace renderdocui.Windows public int GetFirstArraySlice(Core core) { + var curDraw = core.CurDrawcall; + bool copy, compute; + GetDrawContext(core, out copy, out compute); + + // TODO find a way (without copy-pasting tons of code) + // to duplicate the logic of GetResourceId() but return + // different information + if (copy || compute) + return -1; + if (core.APIProps.pipelineType == APIPipelineStateType.D3D11) { D3D11PipelineState.ShaderStage.ResourceView view = null; @@ -150,7 +177,7 @@ namespace renderdocui.Windows if (index >= core.CurD3D11PipelineState.m_OM.UAVStartSlot) view = core.CurD3D11PipelineState.m_OM.UAVs[index]; } - else if (Type == FollowType.PSResource) + else if (Type == FollowType.InputResource) { view = core.CurD3D11PipelineState.m_PS.SRVs[index]; } @@ -172,7 +199,7 @@ namespace renderdocui.Windows if(!core.CurGLPipelineState.Images[index].Layered) return (int)core.CurGLPipelineState.Images[index].Layer; } - else if (Type == FollowType.PSResource) + else if (Type == FollowType.InputResource) { return (int)core.CurGLPipelineState.Textures[index].FirstSlice; } @@ -187,31 +214,114 @@ namespace renderdocui.Windows if (Type == FollowType.OutputColour) { - var outputs = core.CurPipelineState.GetOutputTargets(); + var outputs = GetOutputTargets(core); if(index < outputs.Length) id = outputs[index]; } else if (Type == FollowType.OutputDepth) { - id = core.CurPipelineState.OutputDepth; + id = GetDepthTarget(core); } else if (Type == FollowType.ReadWriteRes) { - var rw = core.CurPipelineState.GetReadWriteResources(); + var rw = GetReadWriteResources(core); if (index < rw.Length) id = rw[index]; } - else if (Type == FollowType.PSResource) + else if (Type == FollowType.InputResource) { - var res = core.CurPipelineState.GetResources(ShaderStageType.Pixel); - if(res.Length > index) + var res = GetResources(core); + + if(index < res.Length) id = res[index]; } return id; } + + public static ResourceId[] GetReadWriteResources(Core core) + { + var curDraw = core.CurDrawcall; + bool copy, compute; + GetDrawContext(core, out copy, out compute); + + if (copy) + return new ResourceId[0]; + else if (compute) + return core.CurPipelineState.GetReadWriteResources(ShaderStageType.Compute); + else + return core.CurPipelineState.GetReadWriteResources(ShaderStageType.Pixel); + } + + public static ResourceId[] GetOutputTargets(Core core) + { + var curDraw = core.CurDrawcall; + bool copy, compute; + GetDrawContext(core, out copy, out compute); + + if (copy) + return new ResourceId[] { curDraw.copyDestination }; + else if(compute) + return new ResourceId[0]; + else + return core.CurPipelineState.GetOutputTargets(); + } + + public static ResourceId GetDepthTarget(Core core) + { + var curDraw = core.CurDrawcall; + bool copy, compute; + GetDrawContext(core, out copy, out compute); + + if (copy || compute) + return ResourceId.Null; + else + return core.CurPipelineState.GetDepthTarget(); + } + + public static ResourceId[] GetResources(Core core) + { + var curDraw = core.CurDrawcall; + bool copy, compute; + GetDrawContext(core, out copy, out compute); + + if (copy) + return new ResourceId[] { curDraw.copySource }; + else if (compute) + return core.CurPipelineState.GetResources(ShaderStageType.Compute); + else + return core.CurPipelineState.GetResources(ShaderStageType.Pixel); + } + + public static ShaderReflection GetReflection(Core core) + { + var curDraw = core.CurDrawcall; + bool copy, compute; + GetDrawContext(core, out copy, out compute); + + if (copy) + return null; + else if (compute) + return core.CurPipelineState.GetShaderReflection(ShaderStageType.Compute); + else + return core.CurPipelineState.GetShaderReflection(ShaderStageType.Pixel); + } + + public static ShaderBindpointMapping GetMapping(Core core) + { + var curDraw = core.CurDrawcall; + bool copy, compute; + GetDrawContext(core, out copy, out compute); + + if (copy) + return null; + else if (compute) + return core.CurPipelineState.GetBindpointMapping(ShaderStageType.Compute); + else + return core.CurPipelineState.GetBindpointMapping(ShaderStageType.Pixel); + } } private Following m_Following = new Following(FollowType.OutputColour, 0); @@ -313,7 +423,7 @@ namespace renderdocui.Windows dockPanel.ActiveDocumentChanged += new EventHandler(dockPanel_ActiveDocumentChanged); - var w3 = Helpers.WrapDockContent(dockPanel, texPanel, "PS Resources"); + var w3 = Helpers.WrapDockContent(dockPanel, texPanel, "Inputs"); w3.DockAreas &= ~DockAreas.Document; w3.DockState = DockState.DockRight; w3.Show(); @@ -321,7 +431,7 @@ namespace renderdocui.Windows w3.CloseButton = false; w3.CloseButtonVisible = false; - var w5 = Helpers.WrapDockContent(dockPanel, rtPanel, "OM Targets"); + var w5 = Helpers.WrapDockContent(dockPanel, rtPanel, "Outputs"); w5.DockAreas &= ~DockAreas.Document; w5.DockState = DockState.DockRight; w5.Show(w3.Pane, w3); @@ -971,30 +1081,16 @@ namespace renderdocui.Windows UI_OnTextureSelectionChanged(); - ResourceId[] RTs = m_Core.CurPipelineState.GetOutputTargets(); - ResourceId[] RWs = m_Core.CurPipelineState.GetReadWriteResources(); - ResourceId Depth = m_Core.CurPipelineState.OutputDepth; - ResourceId[] Texs = null; + ResourceId[] RTs = Following.GetOutputTargets(m_Core); + ResourceId[] RWs = Following.GetReadWriteResources(m_Core); + ResourceId Depth = Following.GetDepthTarget(m_Core); + ResourceId[] Texs = Following.GetResources(m_Core); - ShaderReflection details = null; - ShaderBindpointMapping mapping = null; + ShaderReflection details = Following.GetReflection(m_Core); + ShaderBindpointMapping mapping = Following.GetMapping(m_Core); var curDraw = m_Core.GetDrawcall(frameID, eventID); - - if (curDraw != null && (curDraw.flags & DrawcallFlags.Dispatch) != 0 && - m_Core.CurPipelineState.GetShader(ShaderStageType.Compute) != ResourceId.Null) - { - Texs = m_Core.CurPipelineState.GetResources(ShaderStageType.Compute); - details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Compute); - mapping = m_Core.CurPipelineState.GetBindpointMapping(ShaderStageType.Compute); - } - - if (details == null) - { - Texs = m_Core.CurPipelineState.GetResources(ShaderStageType.Pixel); - details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Pixel); - mapping = m_Core.CurPipelineState.GetBindpointMapping(ShaderStageType.Pixel); - } + bool copy = curDraw != null && (curDraw.flags & (DrawcallFlags.Copy|DrawcallFlags.Resolve)) != 0; if (m_Output == null) return; @@ -1003,7 +1099,12 @@ namespace renderdocui.Windows int i = 0; for(int rt=0; rt < RTs.Length; rt++) { - var prev = rtPanel.Thumbnails[i]; + ResourcePreview prev; + + if (i < rtPanel.Thumbnails.Length) + prev = rtPanel.Thumbnails[i]; + else + prev = UI_CreateThumbnail(rtPanel); if (RTs[rt] != ResourceId.Null) { @@ -1019,6 +1120,9 @@ namespace renderdocui.Windows string bindName = ""; + if (copy) + bindName = "Destination"; + if (tex != null) { prev.Init(!tex.customName && bindName.Length > 0 ? bindName : tex.name, tex.width, tex.height, tex.depth, tex.mips); @@ -1044,7 +1148,7 @@ namespace renderdocui.Windows } prev.Tag = new Following(FollowType.OutputColour, rt); - prev.SlotName = rt.ToString(); + prev.SlotName = copy ? "DST" : rt.ToString(); prev.Visible = true; } else if (prev.Selected) @@ -1067,7 +1171,12 @@ namespace renderdocui.Windows for (int rw = 0; rw < RWs.Length; rw++) { - var prev = rtPanel.Thumbnails[i]; + ResourcePreview prev; + + if (i < rtPanel.Thumbnails.Length) + prev = rtPanel.Thumbnails[i]; + else + prev = UI_CreateThumbnail(rtPanel); if (RWs[rw] != ResourceId.Null) { @@ -1140,12 +1249,27 @@ namespace renderdocui.Windows i++; } - for (; i < rtPanel.Thumbnails.Length; i++) + { - var prev = rtPanel.Thumbnails[i]; + ResourcePreview prev; // depth thumbnail is always the last one - if (i == rtPanel.Thumbnails.Length - 1 && Depth != ResourceId.Null) + if (i < rtPanel.Thumbnails.Length) + { + // hide others + for (; i < rtPanel.Thumbnails.Length - 1; i++) + { + rtPanel.Thumbnails[i].Init(); + rtPanel.Thumbnails[i].Visible = false; + } + prev = rtPanel.Thumbnails[rtPanel.Thumbnails.Length - 1]; + } + else + { + prev = UI_CreateThumbnail(rtPanel); + } + + if (Depth != ResourceId.Null) { FetchTexture tex = null; foreach (var t in m_Core.CurTextures) @@ -1181,6 +1305,7 @@ namespace renderdocui.Windows } prev.Tag = new Following(FollowType.OutputDepth, 0); + prev.SlotName = "D"; prev.Visible = true; } else if (prev.Selected) @@ -1200,12 +1325,16 @@ namespace renderdocui.Windows } rtPanel.RefreshLayout(); - + i = 0; - foreach (var prev in texPanel.Thumbnails) + for(; i < Texs.Length; i++) { - if (i >= Texs.Length) - break; + ResourcePreview prev; + + if (i < texPanel.Thumbnails.Length) + prev = texPanel.Thumbnails[i]; + else + prev = UI_CreateThumbnail(texPanel); bool used = false; @@ -1223,6 +1352,12 @@ namespace renderdocui.Windows } } + if (copy) + { + used = true; + bindName = "Source"; + } + // show if if (used || // it's referenced by the shader - regardless of empty or not (showDisabled.Checked && !used && Texs[i] != ResourceId.Null) || // it's bound, but not referenced, and we have "show disabled" @@ -1263,7 +1398,8 @@ namespace renderdocui.Windows prev.Init(); } - prev.Tag = new Following(FollowType.PSResource, i); + prev.Tag = new Following(FollowType.InputResource, i); + prev.SlotName = copy ? "SRC" : i.ToString(); prev.Visible = true; } else if (prev.Selected) @@ -1304,6 +1440,17 @@ namespace renderdocui.Windows #region Update UI state + private ResourcePreview UI_CreateThumbnail(ThumbnailStrip strip) + { + var prev = new ResourcePreview(m_Core, m_Output); + prev.Anchor = AnchorStyles.Top | AnchorStyles.Bottom; + prev.MouseClick += thumbsLayout_MouseClick; + prev.MouseDoubleClick += thumbsLayout_MouseDoubleClick; + prev.Visible = false; + strip.AddThumbnail(prev); + return prev; + } + private void UI_CreateThumbnails() { if (rtPanel.Thumbnails.Length > 0 || texPanel.Thumbnails.Length > 0) return; @@ -1311,43 +1458,17 @@ namespace renderdocui.Windows rtPanel.SuspendLayout(); texPanel.SuspendLayout(); - for (int i = 0; i < 128; i++) + // these will expand, but we make sure that there is a good set reserved + for (int i = 0; i < 9; i++) { - var prev = new ResourcePreview(m_Core, m_Output); - prev.Anchor = AnchorStyles.Top | AnchorStyles.Bottom; - prev.SlotName = i.ToString(); - prev.MouseClick += thumbsLayout_MouseClick; - prev.MouseDoubleClick += thumbsLayout_MouseDoubleClick; - rtPanel.AddThumbnail(prev); + var prev = UI_CreateThumbnail(rtPanel); if(i == 0) prev.Selected = true; } - { - var prev = new ResourcePreview(m_Core, m_Output); - prev.Anchor = AnchorStyles.Top | AnchorStyles.Bottom; - prev.SlotName = "D"; - prev.MouseClick += thumbsLayout_MouseClick; - prev.MouseDoubleClick += thumbsLayout_MouseDoubleClick; - rtPanel.AddThumbnail(prev); - } - for (int i = 0; i < 128; i++) - { - var prev = new ResourcePreview(m_Core, m_Output); - prev.Anchor = AnchorStyles.Top | AnchorStyles.Bottom; - prev.SlotName = i.ToString(); - prev.MouseClick += thumbsLayout_MouseClick; - prev.MouseDoubleClick += thumbsLayout_MouseDoubleClick; - texPanel.AddThumbnail(prev); - } - - foreach (var c in rtPanel.Thumbnails) - c.Visible = false; - - foreach (var c in texPanel.Thumbnails) - c.Visible = false; + UI_CreateThumbnail(texPanel); rtPanel.ResumeLayout(); texPanel.ResumeLayout(); @@ -1663,32 +1784,67 @@ namespace renderdocui.Windows ResourceId followID = m_Following.GetResourceId(m_Core); { - FetchTexture tex = null; - foreach (var t in m_Core.CurTextures) - if (t.ID == followID) - tex = t; + bool found = false; - if (tex != null) + string name = ""; + + foreach (var t in m_Core.CurTextures) + { + if (t.ID == followID) + { + name = t.name; + found = true; + } + } + + foreach (var b in m_Core.CurBuffers) + { + if (b.ID == followID) + { + name = b.name; + found = true; + } + } + + if (followID == ResourceId.Null) + { + m_PreviewPanel.Text = "Unbound"; + } + else if(found) { switch (m_Following.Type) { case FollowType.OutputColour: - m_PreviewPanel.Text = string.Format("Cur Colour Output {0} - {1}", m_Following.index, tex.name); + m_PreviewPanel.Text = string.Format("Cur Output {0} - {1}", m_Following.index, name); break; case FollowType.OutputDepth: - m_PreviewPanel.Text = string.Format("Cur Depth Output - {0}", tex.name); + m_PreviewPanel.Text = string.Format("Cur Depth Output - {0}", name); break; - case FollowType.PSResource: - m_PreviewPanel.Text = string.Format("Cur PS Resource {0} - {1}", m_Following.index, tex.name); + case FollowType.ReadWriteRes: + m_PreviewPanel.Text = string.Format("Cur RW Output - {0}", name); + break; + case FollowType.InputResource: + m_PreviewPanel.Text = string.Format("Cur Input {0} - {1}", m_Following.index, name); break; } } else { - m_PreviewPanel.Text = "Current"; - - if (followID == ResourceId.Null) - m_PreviewPanel.Text = "Unbound"; + switch (m_Following.Type) + { + case FollowType.OutputColour: + m_PreviewPanel.Text = string.Format("Cur Output {0}", m_Following.index); + break; + case FollowType.OutputDepth: + m_PreviewPanel.Text = string.Format("Cur Depth Output"); + break; + case FollowType.ReadWriteRes: + m_PreviewPanel.Text = string.Format("Cur RW Output"); + break; + case FollowType.InputResource: + m_PreviewPanel.Text = string.Format("Cur Input {0}", m_Following.index); + break; + } } }