From 14781e4287c18fef91887dfb53c2c56ac3e3005b Mon Sep 17 00:00:00 2001 From: baldurk Date: Sun, 17 Apr 2016 17:50:45 +0200 Subject: [PATCH] Handle invalid vulkan vertex input setup, and display better in pipeview --- renderdocui/Code/CommonPipelineState.cs | 14 ++- renderdocui/Windows/BufferViewer.cs | 86 +++++++++++++++---- .../VulkanPipelineStateViewer.cs | 25 +++++- 3 files changed, 101 insertions(+), 24 deletions(-) diff --git a/renderdocui/Code/CommonPipelineState.cs b/renderdocui/Code/CommonPipelineState.cs index 44c1123d2..09627d6e9 100644 --- a/renderdocui/Code/CommonPipelineState.cs +++ b/renderdocui/Code/CommonPipelineState.cs @@ -711,7 +711,10 @@ namespace renderdocui.Code { int attrib = -1; if (m_Vulkan.VS.BindpointMapping != null && m_Vulkan.VS.ShaderDetails != null) - attrib = m_Vulkan.VS.BindpointMapping.InputAttributes[attrs[i].location]; + { + if(attrs[i].location < m_Vulkan.VS.BindpointMapping.InputAttributes.Length) + attrib = m_Vulkan.VS.BindpointMapping.InputAttributes[attrs[i].location]; + } else attrib = i; @@ -727,14 +730,19 @@ namespace renderdocui.Code ret[a].GenericValue = null; ret[a].VertexBuffer = (int)attrs[i].binding; ret[a].RelativeByteOffset = attrs[i].byteoffset; - ret[a].PerInstance = m_Vulkan.VI.binds[attrs[i].binding].perInstance; + ret[a].PerInstance = false; + if(attrs[i].binding < m_Vulkan.VI.binds.Length) + ret[a].PerInstance = m_Vulkan.VI.binds[attrs[i].binding].perInstance; ret[a].InstanceRate = 1; ret[a].Format = attrs[i].format; ret[a].Used = true; if (m_Vulkan.VS.BindpointMapping != null && m_Vulkan.VS.ShaderDetails != null) { - int attrib = m_Vulkan.VS.BindpointMapping.InputAttributes[attrs[i].location]; + int attrib = -1; + + if (attrs[i].location < m_Vulkan.VS.BindpointMapping.InputAttributes.Length) + attrib = m_Vulkan.VS.BindpointMapping.InputAttributes[attrs[i].location]; if (attrib >= 0 && attrib < m_Vulkan.VS.ShaderDetails.InputSig.Length) ret[a].Name = m_Vulkan.VS.ShaderDetails.InputSig[attrib].varName; diff --git a/renderdocui/Windows/BufferViewer.cs b/renderdocui/Windows/BufferViewer.cs index c0dd5799a..8314d3b1f 100644 --- a/renderdocui/Windows/BufferViewer.cs +++ b/renderdocui/Windows/BufferViewer.cs @@ -1430,7 +1430,7 @@ namespace renderdocui.Windows foreach (var el in bufferFormats) { - if (state.m_Stream[el.buffer] == null) + if (el.buffer < state.m_Stream.Length && state.m_Stream[el.buffer] == null) { if (d[el.buffer] == null) { @@ -1566,9 +1566,18 @@ namespace renderdocui.Windows try { - byte[] bytedata = d[bufferFormats[el].buffer]; - Stream strm = state.m_Stream[bufferFormats[el].buffer]; - BinaryReader read = state.m_Reader[bufferFormats[el].buffer]; + byte[] bytedata = null; + Stream strm = null; + BinaryReader read = null; + uint stride = 0; + + if (bufferFormats[el].buffer < d.Length) + { + bytedata = d[bufferFormats[el].buffer]; + strm = state.m_Stream[bufferFormats[el].buffer]; + read = state.m_Reader[bufferFormats[el].buffer]; + stride = input.Strides[bufferFormats[el].buffer]; + } uint instIdx = 0; // for instancing, need to handle instance rate being 0 (every instance takes index 0 in that case) @@ -1577,7 +1586,6 @@ namespace renderdocui.Windows else instIdx = index; - uint stride = input.Strides[bufferFormats[el].buffer]; if (data.PostVS.stride != 0) stride = data.PostVS.stride; @@ -1585,7 +1593,13 @@ namespace renderdocui.Windows bool outofBounds = false; - if (bytedata == null) + if (bufferFormats[el].buffer >= d.Length) + { + outofBounds = true; + strm = null; + read = new BinaryReader(new MemoryStream(m_Zeroes)); + } + else if (bytedata == null) { strm.Seek(0, SeekOrigin.Begin); } @@ -1925,9 +1939,18 @@ namespace renderdocui.Windows try { - byte[] bytedata = d[bufferFormats[el].buffer]; - Stream strm = state.m_Stream[bufferFormats[el].buffer]; - BinaryReader read = state.m_Reader[bufferFormats[el].buffer]; + byte[] bytedata = null; + Stream strm = null; + BinaryReader read = null; + uint stride = 0; + + if (bufferFormats[el].buffer < d.Length) + { + bytedata = d[bufferFormats[el].buffer]; + strm = state.m_Stream[bufferFormats[el].buffer]; + read = state.m_Reader[bufferFormats[el].buffer]; + stride = input.Strides[bufferFormats[el].buffer]; + } uint instIdx = 0; // for instancing, need to handle instance rate being 0 (every instance takes index 0 in that case) @@ -1936,13 +1959,20 @@ namespace renderdocui.Windows else instIdx = dataIndex; - uint stride = input.Strides[bufferFormats[el].buffer]; if (data.PostVS.stride != 0) stride = data.PostVS.stride; uint offs = stride * instIdx + bufferFormats[el].offset; - if (bytedata == null) + if (bufferFormats[el].buffer >= d.Length) + { + for (int i = 0; i < bufferFormats[el].format.compCount; i++, x++) + { + rowdata[x] = "-"; + } + continue; + } + else if (bytedata == null) { strm.Seek(0, SeekOrigin.Begin); } @@ -2776,10 +2806,19 @@ namespace renderdocui.Windows m_MeshDisplay.position.idxByteWidth = ui.m_Input.Drawcall.indexByteWidth; m_MeshDisplay.position.baseVertex = ui.m_Input.Drawcall.baseVertex; - m_MeshDisplay.position.buf = m_VSIn.m_Input.Buffers[pos.buffer]; - m_MeshDisplay.position.offset = pos.offset + ui.m_Input.Offsets[pos.buffer] + - ui.m_Input.Drawcall.vertexOffset * ui.m_Input.Strides[pos.buffer]; - m_MeshDisplay.position.stride = ui.m_Input.Strides[pos.buffer]; + if (pos.buffer < m_VSIn.m_Input.Buffers.Length) + { + m_MeshDisplay.position.buf = m_VSIn.m_Input.Buffers[pos.buffer]; + m_MeshDisplay.position.offset = pos.offset + ui.m_Input.Offsets[pos.buffer] + + ui.m_Input.Drawcall.vertexOffset * ui.m_Input.Strides[pos.buffer]; + m_MeshDisplay.position.stride = ui.m_Input.Strides[pos.buffer]; + } + else + { + m_MeshDisplay.position.buf = ResourceId.Null; + m_MeshDisplay.position.offset = 0; + m_MeshDisplay.position.stride = 0; + } m_MeshDisplay.position.topo = ui.m_Input.Drawcall.topology; m_MeshDisplay.position.numVerts = ui.m_Input.Drawcall.numIndices; @@ -2861,10 +2900,19 @@ namespace renderdocui.Windows if (ui.m_Stage == MeshDataStage.VSIn && ui.m_Input.Drawcall != null) { - m_MeshDisplay.secondary.buf = m_VSIn.m_Input.Buffers[tex.buffer]; - m_MeshDisplay.secondary.offset = tex.offset + ui.m_Input.Offsets[tex.buffer] + - ui.m_Input.Drawcall.vertexOffset * m_MeshDisplay.position.stride; - m_MeshDisplay.secondary.stride = ui.m_Input.Strides[tex.buffer]; + if (tex.buffer < m_VSIn.m_Input.Buffers.Length) + { + m_MeshDisplay.secondary.buf = m_VSIn.m_Input.Buffers[tex.buffer]; + m_MeshDisplay.secondary.offset = tex.offset + ui.m_Input.Offsets[tex.buffer] + + ui.m_Input.Drawcall.vertexOffset * m_MeshDisplay.position.stride; + m_MeshDisplay.secondary.stride = ui.m_Input.Strides[tex.buffer]; + } + else + { + m_MeshDisplay.secondary.buf = ResourceId.Null; + m_MeshDisplay.secondary.offset = 0; + m_MeshDisplay.secondary.stride = 0; + } } else if (ui.m_Stage != MeshDataStage.VSIn && ui.m_Data != null && ui.m_Data.PostVS.buf != ResourceId.Null) { diff --git a/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.cs b/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.cs index c6ff0806a..3932b4148 100644 --- a/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.cs +++ b/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.cs @@ -1099,7 +1099,9 @@ namespace renderdocui.Windows.PipelineState if (state.VS.Shader != ResourceId.Null) { - int attrib = state.VS.BindpointMapping.InputAttributes[a.location]; + int attrib = -1; + if(a.location < state.VS.BindpointMapping.InputAttributes.Length) + attrib = state.VS.BindpointMapping.InputAttributes[a.location]; if (attrib >= 0 && attrib < state.VS.ShaderDetails.InputSig.Length) { @@ -1243,7 +1245,8 @@ namespace renderdocui.Windows.PipelineState if (state.VI.vbuffers != null) { - for(int i=0; i < Math.Max(state.VI.vbuffers.Length, state.VI.binds.Length); i++) + int i = 0; + for(; i < Math.Max(state.VI.vbuffers.Length, state.VI.binds.Length); i++) { var vbuff = (i < state.VI.vbuffers.Length ? state.VI.vbuffers[i] : null); VulkanPipelineState.VertexInput.Binding bind = null; @@ -1314,6 +1317,24 @@ namespace renderdocui.Windows.PipelineState m_VBNodes.Add(node); } } + + for (; i < usedBindings.Length; i++) + { + if (usedBindings[i]) + { + TreelistView.Node node = viBuffers.Nodes.Add(new object[] { i, "No Binding", "-", "-", "-", "-" }); + + node.Image = global::renderdocui.Properties.Resources.action; + node.HoverImage = global::renderdocui.Properties.Resources.action_hover; + node.Tag = new IABufferTag(ResourceId.Null, 0); + + EmptyRow(node); + + InactiveRow(node); + + m_VBNodes.Add(node); + } + } } viBuffers.NodesSelection.Clear(); viBuffers.EndUpdate();