Handle arrays of uniform buffers in descriptor slots

This commit is contained in:
baldurk
2016-02-07 18:46:35 +01:00
parent be289dbec2
commit 8a6d2ebf30
10 changed files with 581 additions and 469 deletions
@@ -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);
}
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)