mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 01:20:42 +00:00
Handle arrays of uniform buffers in descriptor slots
This commit is contained in:
@@ -604,7 +604,21 @@ namespace renderdocui.Code
|
||||
return null;
|
||||
}
|
||||
|
||||
public void GetConstantBuffer(ShaderStageType stage, uint BufIdx, out ResourceId buf, out ulong ByteOffset, out ulong ByteSize)
|
||||
public bool SupportsResourceArrays
|
||||
{
|
||||
get
|
||||
{
|
||||
if (LogLoaded)
|
||||
{
|
||||
if (IsLogVK)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetConstantBuffer(ShaderStageType stage, uint BufIdx, uint ArrayIdx, out ResourceId buf, out ulong ByteOffset, out ulong ByteSize)
|
||||
{
|
||||
if (LogLoaded)
|
||||
{
|
||||
@@ -685,8 +699,7 @@ namespace renderdocui.Code
|
||||
{
|
||||
var bind = s.BindpointMapping.ConstantBlocks[s.ShaderDetails.ConstantBlocks[BufIdx].bindPoint];
|
||||
|
||||
// VKTODOLOW do we need to worry about arrays of uniform buffers?
|
||||
var descriptorBind = pipe.DescSets[bind.bindset].bindings[bind.bind].binds[0];
|
||||
var descriptorBind = pipe.DescSets[bind.bindset].bindings[bind.bind].binds[ArrayIdx];
|
||||
|
||||
buf = descriptorBind.res;
|
||||
ByteOffset = descriptorBind.offset;
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace TreelistView
|
||||
bool m_expanded = false;
|
||||
Image m_image = null;
|
||||
Image m_hoverImage = null;
|
||||
int m_treeColumn = -1;
|
||||
int m_id = -1;
|
||||
object m_tag = null;
|
||||
bool m_bold = false;
|
||||
@@ -70,6 +71,11 @@ namespace TreelistView
|
||||
get { return m_hoverImage != null ? m_hoverImage : m_image; }
|
||||
set { m_hoverImage = value; }
|
||||
}
|
||||
public int TreeColumn
|
||||
{
|
||||
get { return m_treeColumn; }
|
||||
set { m_treeColumn = value; }
|
||||
}
|
||||
public virtual NodeCollection Owner
|
||||
{
|
||||
get { return m_owner; }
|
||||
|
||||
@@ -98,6 +98,7 @@ namespace TreelistView.TreeList
|
||||
int m_indent = 16;
|
||||
bool m_showLine = true;
|
||||
bool m_showPlusMinus = true;
|
||||
bool m_padForPlusMinus = true;
|
||||
bool m_showGridLines = true;
|
||||
bool m_rearrangeableColumns = false;
|
||||
bool m_hoverHand = true;
|
||||
@@ -137,6 +138,18 @@ namespace TreelistView.TreeList
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Behavior")]
|
||||
[DefaultValue(typeof(bool), "True")]
|
||||
public bool PadForPlusMinus
|
||||
{
|
||||
get { return m_padForPlusMinus; }
|
||||
set
|
||||
{
|
||||
m_padForPlusMinus = value;
|
||||
m_owner.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Behavior")]
|
||||
[DefaultValue(typeof(bool), "True")]
|
||||
|
||||
@@ -137,6 +137,14 @@ namespace TreelistView
|
||||
}
|
||||
}
|
||||
|
||||
private int GetTreeColumn(Node n)
|
||||
{
|
||||
if (n != null && n.TreeColumn >= 0)
|
||||
return n.TreeColumn;
|
||||
|
||||
return m_treeColumn;
|
||||
}
|
||||
|
||||
[Category("Behavior")]
|
||||
[DefaultValue(typeof(bool), "False")]
|
||||
public bool AlwaysDisplayVScroll
|
||||
@@ -560,15 +568,18 @@ namespace TreelistView
|
||||
{
|
||||
int clickedRow = CalcHitRow(mousePoint);
|
||||
Rectangle glyphRect = Rectangle.Empty;
|
||||
if (m_treeColumn >= 0)
|
||||
glyphRect = GetPlusMinusRectangle(clickedNode, Columns[m_treeColumn], clickedRow);
|
||||
|
||||
int treeColumn = GetTreeColumn(clickedNode);
|
||||
|
||||
if (treeColumn >= 0)
|
||||
glyphRect = GetPlusMinusRectangle(clickedNode, Columns[treeColumn], clickedRow);
|
||||
if (clickedNode.HasChildren && glyphRect != Rectangle.Empty && glyphRect.Contains(mousePoint))
|
||||
clickedNode.Expanded = !clickedNode.Expanded;
|
||||
|
||||
var columnHit = CalcColumnHit(mousePoint);
|
||||
|
||||
if (glyphRect == Rectangle.Empty && columnHit.Column != null &&
|
||||
columnHit.Column.Index == m_treeColumn && GetNodeBitmap(clickedNode) != null)
|
||||
columnHit.Column.Index == treeColumn && GetNodeBitmap(clickedNode) != null)
|
||||
{
|
||||
OnNodeClicked(clickedNode);
|
||||
}
|
||||
@@ -685,7 +696,10 @@ namespace TreelistView
|
||||
|
||||
if ((int)(info.HitType & HitInfo.eHitType.kColumnHeaderResize) > 0)
|
||||
Cursor = Cursors.VSplit;
|
||||
else if (info.Column != null && info.Column.Index == m_treeColumn && GetNodeBitmap(clickedNode) != null && m_viewSetting.HoverHandTreeColumn)
|
||||
else if (info.Column != null &&
|
||||
info.Column.Index == GetTreeColumn(clickedNode) &&
|
||||
GetNodeBitmap(clickedNode) != null &&
|
||||
m_viewSetting.HoverHandTreeColumn)
|
||||
Cursor = Cursors.Hand;
|
||||
else
|
||||
Cursor = Cursors.Arrow;
|
||||
@@ -971,7 +985,7 @@ namespace TreelistView
|
||||
|
||||
dc.SetClip(cellRect);
|
||||
|
||||
if (col.Index == m_treeColumn)
|
||||
if (col.Index == GetTreeColumn(node))
|
||||
{
|
||||
int lineindet = 10;
|
||||
// add left margin
|
||||
@@ -987,9 +1001,10 @@ namespace TreelistView
|
||||
cellRect.X += lineindet;
|
||||
cellRect.Width -= lineindet;
|
||||
|
||||
Rectangle glyphRect = GetPlusMinusRectangle(node, col, visibleRowIndex);
|
||||
Rectangle glyphRect = GetPlusMinusRectangle(node, col, visibleRowIndex);
|
||||
Rectangle plusminusRect = glyphRect;
|
||||
|
||||
if (!ViewOptions.ShowLine && !ViewOptions.ShowPlusMinus)
|
||||
if (!ViewOptions.ShowLine && (!ViewOptions.ShowPlusMinus || (!ViewOptions.PadForPlusMinus && plusminusRect == Rectangle.Empty)))
|
||||
{
|
||||
cellRect.X -= (lineindet + 5);
|
||||
cellRect.Width += (lineindet + 5);
|
||||
@@ -1000,8 +1015,6 @@ namespace TreelistView
|
||||
|
||||
Image icon = hoverNode != null && hoverNode == node ? GetHoverNodeBitmap(node) : GetNodeBitmap(node);
|
||||
|
||||
Rectangle plusminusRect = glyphRect;
|
||||
|
||||
PaintCellBackground(dc, cellRect, node, col);
|
||||
|
||||
if (SelectedImage != null && (NodesSelection.Contains(node) || FocusedNode == node))
|
||||
|
||||
@@ -43,19 +43,20 @@ namespace renderdocui.Controls
|
||||
{
|
||||
private Core m_Core;
|
||||
|
||||
public ConstantBufferPreviewer(Core c, ShaderStageType stage, UInt32 slot)
|
||||
public ConstantBufferPreviewer(Core c, ShaderStageType stage, UInt32 slot, UInt32 idx)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
m_Core = c;
|
||||
Stage = stage;
|
||||
Slot = slot;
|
||||
ArrayIdx = idx;
|
||||
shader = m_Core.CurPipelineState.GetShader(stage);
|
||||
UpdateLabels();
|
||||
|
||||
ulong offs = 0;
|
||||
ulong size = 0;
|
||||
m_Core.CurPipelineState.GetConstantBuffer(Stage, Slot, out cbuffer, out offs, out size);
|
||||
m_Core.CurPipelineState.GetConstantBuffer(Stage, Slot, ArrayIdx, out cbuffer, out offs, out size);
|
||||
|
||||
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
|
||||
{
|
||||
@@ -67,11 +68,11 @@ namespace renderdocui.Controls
|
||||
|
||||
private static List<ConstantBufferPreviewer> m_Docks = new List<ConstantBufferPreviewer>();
|
||||
|
||||
public static DockContent Has(ShaderStageType stage, UInt32 slot)
|
||||
public static DockContent Has(ShaderStageType stage, UInt32 slot, UInt32 idx)
|
||||
{
|
||||
foreach (var cb in m_Docks)
|
||||
{
|
||||
if(cb.Stage == stage && cb.Slot == slot)
|
||||
if(cb.Stage == stage && cb.Slot == slot && cb.ArrayIdx == idx)
|
||||
return cb as DockContent;
|
||||
}
|
||||
|
||||
@@ -180,7 +181,7 @@ namespace renderdocui.Controls
|
||||
{
|
||||
ulong offs = 0;
|
||||
ulong size = 0;
|
||||
m_Core.CurPipelineState.GetConstantBuffer(Stage, Slot, out cbuffer, out offs, out size);
|
||||
m_Core.CurPipelineState.GetConstantBuffer(Stage, Slot, ArrayIdx, out cbuffer, out offs, out size);
|
||||
|
||||
shader = m_Core.CurPipelineState.GetShader(Stage);
|
||||
var reflection = m_Core.CurPipelineState.GetShaderReflection(Stage);
|
||||
@@ -215,6 +216,7 @@ namespace renderdocui.Controls
|
||||
private ResourceId shader;
|
||||
private ShaderStageType Stage;
|
||||
private UInt32 Slot = 0;
|
||||
private UInt32 ArrayIdx = 0;
|
||||
|
||||
public override string Text
|
||||
{
|
||||
@@ -224,10 +226,15 @@ namespace renderdocui.Controls
|
||||
if (m_Core != null && m_Core.APIProps != null)
|
||||
pipeType = m_Core.APIProps.pipelineType;
|
||||
|
||||
return String.Format("{0} {1} {2}",
|
||||
string ret = String.Format("{0} {1} {2}",
|
||||
Stage.Str(pipeType),
|
||||
pipeType == APIPipelineStateType.D3D11 ? "CB" : "UBO",
|
||||
Slot);
|
||||
|
||||
if (m_Core != null && m_Core.CurPipelineState.SupportsResourceArrays)
|
||||
ret += String.Format(" [{0}]", ArrayIdx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2140,14 +2140,14 @@ namespace renderdocui.Windows.PipelineState
|
||||
return;
|
||||
}
|
||||
|
||||
var existing = ConstantBufferPreviewer.Has(stage.stage, slot);
|
||||
var existing = ConstantBufferPreviewer.Has(stage.stage, slot, 0);
|
||||
if (existing != null)
|
||||
{
|
||||
existing.Show();
|
||||
return;
|
||||
}
|
||||
|
||||
var prev = new ConstantBufferPreviewer(m_Core, stage.stage, slot);
|
||||
var prev = new ConstantBufferPreviewer(m_Core, stage.stage, slot, 0);
|
||||
|
||||
prev.ShowDock(m_DockContent.Pane, DockAlignment.Right, 0.3);
|
||||
}
|
||||
|
||||
@@ -1935,14 +1935,14 @@ namespace renderdocui.Windows.PipelineState
|
||||
|
||||
private void ShowCBuffer(GLPipelineState.ShaderStage stage, UInt32 slot)
|
||||
{
|
||||
var existing = ConstantBufferPreviewer.Has(stage.stage, slot);
|
||||
var existing = ConstantBufferPreviewer.Has(stage.stage, slot, 0);
|
||||
if (existing != null)
|
||||
{
|
||||
existing.Show();
|
||||
return;
|
||||
}
|
||||
|
||||
var prev = new ConstantBufferPreviewer(m_Core, stage.stage, slot);
|
||||
var prev = new ConstantBufferPreviewer(m_Core, stage.stage, slot, 0);
|
||||
|
||||
prev.ShowDock(m_DockContent.Pane, DockAlignment.Right, 0.3);
|
||||
}
|
||||
|
||||
+426
-402
File diff suppressed because it is too large
Load Diff
@@ -55,6 +55,13 @@ namespace renderdocui.Windows.PipelineState
|
||||
public TreelistView.Node node = null;
|
||||
};
|
||||
|
||||
class CBufferTag
|
||||
{
|
||||
public CBufferTag(UInt32 s, UInt32 i) { slotIdx = s; arrayIdx = i; }
|
||||
public UInt32 slotIdx;
|
||||
public UInt32 arrayIdx;
|
||||
};
|
||||
|
||||
private Dictionary<TreelistView.Node, TreelistView.Node> m_CombinedImageSamplers = new Dictionary<TreelistView.Node, TreelistView.Node>();
|
||||
|
||||
public VulkanPipelineStateViewer(Core core, DockContent c)
|
||||
@@ -586,59 +593,91 @@ namespace renderdocui.Windows.PipelineState
|
||||
cbuffers.Nodes.Clear();
|
||||
if(stage.ShaderDetails != null)
|
||||
{
|
||||
UInt32 i = 0;
|
||||
UInt32 slot = 0;
|
||||
foreach (var b in shaderDetails.ConstantBlocks)
|
||||
{
|
||||
BindpointMap bindMap = stage.BindpointMapping.ConstantBlocks[b.bindPoint];
|
||||
|
||||
// VKTODOMED need to handle arrays
|
||||
var descriptorBind = pipe.DescSets[bindMap.bindset].bindings[bindMap.bind].binds[0];
|
||||
|
||||
bool filledSlot = (descriptorBind.res != ResourceId.Null);
|
||||
bool usedSlot = bindMap.used;
|
||||
|
||||
var slotBinds = pipe.DescSets[bindMap.bindset].bindings[bindMap.bind].binds;
|
||||
|
||||
// consider it filled if any array element is filled
|
||||
bool filledSlot = false;
|
||||
for (UInt32 idx = 0; idx < bindMap.arraySize; idx++)
|
||||
filledSlot |= slotBinds[idx].res != ResourceId.Null;
|
||||
|
||||
// show if
|
||||
if (usedSlot || // it's referenced by the shader - regardless of empty or not
|
||||
(showDisabled.Checked && !usedSlot && filledSlot) || // it's bound, but not referenced, and we have "show disabled"
|
||||
(showEmpty.Checked && !filledSlot) // it's empty, and we have "show empty"
|
||||
)
|
||||
{
|
||||
string name = "Constant Buffer " + descriptorBind.res.ToString();
|
||||
UInt64 length = descriptorBind.size;
|
||||
int numvars = b.variables.Length;
|
||||
TreelistView.NodeCollection parentNodes = cbuffers.Nodes;
|
||||
|
||||
if (!filledSlot)
|
||||
{
|
||||
name = "Empty";
|
||||
length = 0;
|
||||
}
|
||||
|
||||
for (int t = 0; t < bufs.Length; t++)
|
||||
if (bufs[t].ID == descriptorBind.res)
|
||||
name = bufs[t].name;
|
||||
|
||||
if (name == "")
|
||||
name = "Constant Buffer " + descriptorBind.res.ToString();
|
||||
string setname = bindMap.bindset.ToString();
|
||||
|
||||
string slotname = bindMap.bind.ToString();
|
||||
slotname += ": " + b.name;
|
||||
|
||||
string sizestr = String.Format("{0} Variables, {1} bytes", numvars, length);
|
||||
string vecrange = String.Format("{0} - {1}", descriptorBind.offset, descriptorBind.offset + descriptorBind.size);
|
||||
// for arrays, add a parent element that we add the real cbuffers below
|
||||
if (bindMap.arraySize > 1)
|
||||
{
|
||||
var node = parentNodes.Add(new object[] { "", setname, slotname, String.Format("Array[{0}]", bindMap.arraySize), "", "" });
|
||||
|
||||
var node = cbuffers.Nodes.Add(new object[] { bindMap.bindset, slotname, name, vecrange, sizestr });
|
||||
node.TreeColumn = 0;
|
||||
|
||||
node.Image = global::renderdocui.Properties.Resources.action;
|
||||
node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
|
||||
node.Tag = i;
|
||||
if (!filledSlot)
|
||||
EmptyRow(node);
|
||||
|
||||
if (!filledSlot)
|
||||
EmptyRow(node);
|
||||
if (!usedSlot)
|
||||
InactiveRow(node);
|
||||
|
||||
if (!usedSlot)
|
||||
InactiveRow(node);
|
||||
parentNodes = node.Nodes;
|
||||
}
|
||||
|
||||
for (UInt32 idx = 0; idx < bindMap.arraySize; idx++)
|
||||
{
|
||||
var descriptorBind = slotBinds[idx];
|
||||
|
||||
if (bindMap.arraySize > 1)
|
||||
slotname = String.Format("{0}[{1}]", b.name, idx);
|
||||
|
||||
string name = "Constant Buffer " + descriptorBind.res.ToString();
|
||||
UInt64 length = descriptorBind.size;
|
||||
int numvars = b.variables.Length;
|
||||
|
||||
if (!filledSlot)
|
||||
{
|
||||
name = "Empty";
|
||||
length = 0;
|
||||
}
|
||||
|
||||
for (int t = 0; t < bufs.Length; t++)
|
||||
if (bufs[t].ID == descriptorBind.res)
|
||||
name = bufs[t].name;
|
||||
|
||||
if (name == "")
|
||||
name = "Constant Buffer " + descriptorBind.res.ToString();
|
||||
|
||||
string sizestr = String.Format("{0} Variables, {1} bytes", numvars, length);
|
||||
string vecrange = String.Format("{0} - {1}", descriptorBind.offset, descriptorBind.offset + descriptorBind.size);
|
||||
|
||||
var node = parentNodes.Add(new object[] { "", setname, slotname, name, vecrange, sizestr });
|
||||
|
||||
node.Image = global::renderdocui.Properties.Resources.action;
|
||||
node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
|
||||
node.Tag = new CBufferTag(slot, idx);
|
||||
|
||||
if (!filledSlot)
|
||||
EmptyRow(node);
|
||||
|
||||
if (!usedSlot)
|
||||
InactiveRow(node);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
cbuffers.EndUpdate();
|
||||
@@ -1706,20 +1745,22 @@ namespace renderdocui.Windows.PipelineState
|
||||
sv.Show(m_DockContent.DockPanel);
|
||||
}
|
||||
|
||||
private void ShowCBuffer(VulkanPipelineState.ShaderStage stage, UInt32 slot)
|
||||
private void ShowCBuffer(VulkanPipelineState.ShaderStage stage, CBufferTag tag)
|
||||
{
|
||||
if (tag == null) return;
|
||||
|
||||
VulkanPipelineState.Pipeline pipe = m_Core.CurVulkanPipelineState.graphics;
|
||||
if(stage.stage == ShaderStageType.Compute)
|
||||
pipe = m_Core.CurVulkanPipelineState.compute;
|
||||
|
||||
var existing = ConstantBufferPreviewer.Has(stage.stage, slot);
|
||||
var existing = ConstantBufferPreviewer.Has(stage.stage, tag.slotIdx, tag.arrayIdx);
|
||||
if (existing != null)
|
||||
{
|
||||
existing.Show();
|
||||
return;
|
||||
}
|
||||
|
||||
var prev = new ConstantBufferPreviewer(m_Core, stage.stage, slot);
|
||||
var prev = new ConstantBufferPreviewer(m_Core, stage.stage, tag.slotIdx, tag.arrayIdx);
|
||||
|
||||
prev.ShowDock(m_DockContent.Pane, DockAlignment.Right, 0.3);
|
||||
}
|
||||
@@ -1728,22 +1769,16 @@ namespace renderdocui.Windows.PipelineState
|
||||
{
|
||||
VulkanPipelineState.ShaderStage stage = GetStageForSender(node.OwnerView);
|
||||
|
||||
if (stage != null && node.Tag is UInt32)
|
||||
{
|
||||
ShowCBuffer(stage, (UInt32)node.Tag);
|
||||
}
|
||||
if (stage != null)
|
||||
ShowCBuffer(stage, node.Tag as CBufferTag);
|
||||
}
|
||||
|
||||
private void CBuffers_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
VulkanPipelineState.ShaderStage stage = GetStageForSender(sender);
|
||||
|
||||
object tag = ((DataGridView)sender).Rows[e.RowIndex].Tag;
|
||||
|
||||
if (stage != null && tag is UInt32)
|
||||
{
|
||||
ShowCBuffer(stage, (UInt32)tag);
|
||||
}
|
||||
if (stage != null)
|
||||
ShowCBuffer(stage, ((DataGridView)sender).Rows[e.RowIndex].Tag as CBufferTag);
|
||||
}
|
||||
|
||||
private string FormatMembers(int indent, string nameprefix, ShaderConstant[] vars)
|
||||
|
||||
Reference in New Issue
Block a user