mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-22 22:46:41 +00:00
Handle NULL index buffer being bound for indexed draws better
This commit is contained in:
@@ -3952,6 +3952,11 @@ void D3D11DebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
|
||||
indices.insert(it, i32);
|
||||
}
|
||||
|
||||
// if we read out of bounds, we'll also have a 0 index being referenced
|
||||
// (as 0 is read)
|
||||
if(numIndices < drawcall->numIndices)
|
||||
indices.insert(indices.begin(), 0);
|
||||
|
||||
// An index buffer could be something like: 500, 501, 502, 501, 503, 502
|
||||
// in which case we can't use the existing index buffer without filling 499 slots of vertex
|
||||
// data with padding. Instead we rebase the indices based on the smallest vertex so it becomes
|
||||
@@ -3979,7 +3984,10 @@ void D3D11DebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
|
||||
D3D11_BUFFER_DESC desc = { UINT(sizeof(uint32_t)*indices.size()), D3D11_USAGE_IMMUTABLE, D3D11_BIND_INDEX_BUFFER, 0, 0, 0 };
|
||||
D3D11_SUBRESOURCE_DATA initData = { &indices[0], desc.ByteWidth, desc.ByteWidth };
|
||||
|
||||
m_pDevice->CreateBuffer(&desc, &initData, &idxBuf);
|
||||
if(!indices.empty())
|
||||
m_pDevice->CreateBuffer(&desc, &initData, &idxBuf);
|
||||
else
|
||||
idxBuf = NULL;
|
||||
|
||||
m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
m_pImmediateContext->IASetIndexBuffer(idxBuf, DXGI_FORMAT_R32_UINT, 0);
|
||||
@@ -4010,7 +4018,10 @@ void D3D11DebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
|
||||
initData.pSysMem = &idxdata[0];
|
||||
initData.SysMemPitch = initData.SysMemSlicePitch = desc.ByteWidth;
|
||||
|
||||
m_WrappedDevice->CreateBuffer(&desc, &initData, &idxBuf);
|
||||
if(desc.ByteWidth > 0)
|
||||
m_WrappedDevice->CreateBuffer(&desc, &initData, &idxBuf);
|
||||
else
|
||||
idxBuf = NULL;
|
||||
}
|
||||
|
||||
m_pImmediateContext->End(m_SOStatsQuery);
|
||||
@@ -4783,6 +4794,8 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, uint32_t eventID, const vec
|
||||
m_pImmediateContext->IASetVertexBuffers(0, 2, vbs, str, offs);
|
||||
if(ibuf)
|
||||
m_pImmediateContext->IASetIndexBuffer(ibuf, ifmt, ioffs);
|
||||
else
|
||||
m_pImmediateContext->IASetIndexBuffer(NULL, DXGI_FORMAT_UNKNOWN, NULL);
|
||||
|
||||
// draw solid shaded mode
|
||||
if(cfg.solidShadeMode != eShade_None && cfg.position.topo < eTopology_PatchList_1CPs)
|
||||
@@ -4811,7 +4824,7 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, uint32_t eventID, const vec
|
||||
m_pImmediateContext->GSSetShader(m_DebugRender.MeshGS, NULL, 0);
|
||||
}
|
||||
|
||||
if(ibuf)
|
||||
if(cfg.position.idxByteWidth)
|
||||
m_pImmediateContext->DrawIndexed(cfg.position.numVerts, 0, 0);
|
||||
else
|
||||
m_pImmediateContext->Draw(cfg.position.numVerts, 0);
|
||||
@@ -4841,7 +4854,7 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, uint32_t eventID, const vec
|
||||
else
|
||||
m_pImmediateContext->IASetPrimitiveTopology(topo);
|
||||
|
||||
if(ibuf)
|
||||
if(cfg.position.idxByteWidth)
|
||||
m_pImmediateContext->DrawIndexed(cfg.position.numVerts, 0, 0);
|
||||
else
|
||||
m_pImmediateContext->Draw(cfg.position.numVerts, 0);
|
||||
@@ -4907,7 +4920,7 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, uint32_t eventID, const vec
|
||||
|
||||
m_HighlightCache.data = GetBufferData(cfg.position.buf, 0, 0);
|
||||
|
||||
if(ibuf == NULL || stage == eMeshDataStage_GSOut)
|
||||
if(cfg.position.idxByteWidth == 0 || stage == eMeshDataStage_GSOut)
|
||||
{
|
||||
m_HighlightCache.indices.clear();
|
||||
m_HighlightCache.useidx = false;
|
||||
@@ -4916,7 +4929,9 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, uint32_t eventID, const vec
|
||||
{
|
||||
m_HighlightCache.useidx = true;
|
||||
|
||||
vector<byte> idxdata = GetBufferData(cfg.position.idxbuf, ioffs, cfg.position.numVerts*bytesize);
|
||||
vector<byte> idxdata;
|
||||
if(cfg.position.idxbuf != ResourceId())
|
||||
idxdata = GetBufferData(cfg.position.idxbuf, ioffs, cfg.position.numVerts*bytesize);
|
||||
|
||||
uint16_t *idx16 = (uint16_t *)&idxdata[0];
|
||||
uint32_t *idx32 = (uint32_t *)&idxdata[0];
|
||||
|
||||
@@ -1918,6 +1918,11 @@ void GLReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
|
||||
indices.insert(it, i32);
|
||||
}
|
||||
|
||||
// if we read out of bounds, we'll also have a 0 index being referenced
|
||||
// (as 0 is read)
|
||||
if(numIndices < drawcall->numIndices)
|
||||
indices.insert(indices.begin(), 0);
|
||||
|
||||
// An index buffer could be something like: 500, 501, 502, 501, 503, 502
|
||||
// in which case we can't use the existing index buffer without filling 499 slots of vertex
|
||||
// data with padding. Instead we rebase the indices based on the smallest vertex so it becomes
|
||||
@@ -1984,9 +1989,12 @@ void GLReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
|
||||
// make the index buffer that can be used to render this postvs data - the original
|
||||
// indices, rebased with minindex being 0 (since we transform feedback to the start
|
||||
// of our feedback buffer).
|
||||
gl.glGenBuffers(1, &idxBuf);
|
||||
gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, idxBuf);
|
||||
gl.glNamedBufferStorageEXT(idxBuf, (GLsizeiptr)idxdata.size(), &idxdata[0], 0);
|
||||
if(!idxdata.empty())
|
||||
{
|
||||
gl.glGenBuffers(1, &idxBuf);
|
||||
gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, idxBuf);
|
||||
gl.glNamedBufferStorageEXT(idxBuf, (GLsizeiptr)idxdata.size(), &idxdata[0], 0);
|
||||
}
|
||||
|
||||
// restore previous element array buffer binding
|
||||
gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer);
|
||||
@@ -2794,7 +2802,7 @@ void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshF
|
||||
|
||||
gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL);
|
||||
|
||||
if(cfg.position.idxbuf != ResourceId())
|
||||
if(cfg.position.idxByteWidth)
|
||||
{
|
||||
GLenum idxtype = eGL_UNSIGNED_BYTE;
|
||||
if(cfg.position.idxByteWidth == 2)
|
||||
@@ -2802,8 +2810,11 @@ void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshF
|
||||
else if(cfg.position.idxByteWidth == 4)
|
||||
idxtype = eGL_UNSIGNED_INT;
|
||||
|
||||
GLuint ib = m_pDriver->GetResourceManager()->GetCurrentResource(cfg.position.idxbuf).name;
|
||||
gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, ib);
|
||||
if(cfg.position.idxbuf != ResourceId())
|
||||
{
|
||||
GLuint ib = m_pDriver->GetResourceManager()->GetCurrentResource(cfg.position.idxbuf).name;
|
||||
gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, ib);
|
||||
}
|
||||
gl.glDrawElements(topo, cfg.position.numVerts, idxtype, (const void *)(cfg.position.idxoffs));
|
||||
}
|
||||
else
|
||||
@@ -2834,7 +2845,7 @@ void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshF
|
||||
|
||||
gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_LINE);
|
||||
|
||||
if(cfg.position.idxbuf != ResourceId())
|
||||
if(cfg.position.idxByteWidth)
|
||||
{
|
||||
GLenum idxtype = eGL_UNSIGNED_BYTE;
|
||||
if(cfg.position.idxByteWidth == 2)
|
||||
@@ -2842,8 +2853,11 @@ void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshF
|
||||
else if(cfg.position.idxByteWidth == 4)
|
||||
idxtype = eGL_UNSIGNED_INT;
|
||||
|
||||
GLuint ib = m_pDriver->GetResourceManager()->GetCurrentResource(cfg.position.idxbuf).name;
|
||||
gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, ib);
|
||||
if(cfg.position.idxbuf != ResourceId())
|
||||
{
|
||||
GLuint ib = m_pDriver->GetResourceManager()->GetCurrentResource(cfg.position.idxbuf).name;
|
||||
gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, ib);
|
||||
}
|
||||
gl.glDrawElements(topo != eGL_PATCHES ? topo : eGL_POINTS, cfg.position.numVerts, idxtype, (const void *)(cfg.position.idxoffs));
|
||||
}
|
||||
else
|
||||
@@ -2902,7 +2916,7 @@ void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshF
|
||||
|
||||
m_HighlightCache.data = GetBufferData(cfg.position.buf, 0, 0);
|
||||
|
||||
if(cfg.position.idxbuf == ResourceId() || stage == eMeshDataStage_GSOut)
|
||||
if(cfg.position.idxByteWidth == 0 || stage == eMeshDataStage_GSOut)
|
||||
{
|
||||
m_HighlightCache.indices.clear();
|
||||
m_HighlightCache.useidx = false;
|
||||
@@ -2911,7 +2925,9 @@ void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshF
|
||||
{
|
||||
m_HighlightCache.useidx = true;
|
||||
|
||||
vector<byte> idxdata = GetBufferData(cfg.position.idxbuf, cfg.position.idxoffs, cfg.position.numVerts*bytesize);
|
||||
vector<byte> idxdata;
|
||||
if(cfg.position.idxbuf != ResourceId())
|
||||
idxdata = GetBufferData(cfg.position.idxbuf, cfg.position.idxoffs, cfg.position.numVerts*bytesize);
|
||||
|
||||
uint8_t *idx8 = (uint8_t *)&idxdata[0];
|
||||
uint16_t *idx16 = (uint16_t *)&idxdata[0];
|
||||
|
||||
@@ -891,7 +891,7 @@ namespace renderdocui.Windows
|
||||
foreach (var f in input.BufferFormats)
|
||||
stride += f.ByteSize;
|
||||
|
||||
if (stride != 0)
|
||||
if (stride != 0 && (input.Drawcall.flags & DrawcallFlags.UseIBuffer) == 0)
|
||||
ret.IndexCount = Math.Min(ret.IndexCount, (uint)ret.Buffers[0].Length / stride);
|
||||
}
|
||||
|
||||
@@ -1585,7 +1585,8 @@ namespace renderdocui.Windows
|
||||
index = data.Indices[rowIdx];
|
||||
}
|
||||
}
|
||||
else if (input.Drawcall != null && (input.Drawcall.flags & DrawcallFlags.UseIBuffer) != 0 && state == m_VSIn)
|
||||
else if (input.Drawcall != null && (input.Drawcall.flags & DrawcallFlags.UseIBuffer) != 0 &&
|
||||
(state == m_VSIn || state == m_VSOut))
|
||||
{
|
||||
// no index buffer, but indexed drawcall
|
||||
index = 0;
|
||||
@@ -2296,7 +2297,7 @@ namespace renderdocui.Windows
|
||||
{
|
||||
m_MeshDisplay.position.idxbuf = ui.m_Data.PostVS.idxbuf;
|
||||
m_MeshDisplay.position.idxoffs = 0;
|
||||
m_MeshDisplay.position.idxByteWidth = ui.m_Data.PostVS.idxByteWidth;
|
||||
m_MeshDisplay.position.idxByteWidth = ui.m_Input.Drawcall.indexByteWidth;
|
||||
|
||||
m_MeshDisplay.position.buf = ui.m_Data.PostVS.buf;
|
||||
m_MeshDisplay.position.offset = ui.m_Data.PostVS.offset + pos.offset;
|
||||
@@ -2306,6 +2307,17 @@ namespace renderdocui.Windows
|
||||
m_MeshDisplay.position.numVerts = ui.m_Data.PostVS.numVerts;
|
||||
}
|
||||
|
||||
if ((ui.m_Input.Drawcall.flags & DrawcallFlags.UseIBuffer) == 0)
|
||||
{
|
||||
m_MeshDisplay.position.idxbuf = ResourceId.Null;
|
||||
m_MeshDisplay.position.idxoffs = 0;
|
||||
m_MeshDisplay.position.idxByteWidth = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MeshDisplay.position.idxByteWidth = Math.Max(1, m_MeshDisplay.position.idxByteWidth);
|
||||
}
|
||||
|
||||
m_MeshDisplay.position.unproject = false;
|
||||
// near and far plane handled elsewhere
|
||||
|
||||
|
||||
Reference in New Issue
Block a user