mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-26 16:36:31 +00:00
Fix handling of primitive restart with a vertex offset
This commit is contained in:
@@ -334,7 +334,7 @@ struct BufferData
|
||||
size_t stride;
|
||||
};
|
||||
|
||||
uint32_t CalcIndex(BufferData *data, uint32_t vertID, int32_t baseVertex)
|
||||
uint32_t CalcIndex(BufferData *data, uint32_t vertID, int32_t baseVertex, uint32_t primRestart)
|
||||
{
|
||||
byte *idxData = data->data + vertID * sizeof(uint32_t);
|
||||
if(idxData + sizeof(uint32_t) > data->end)
|
||||
@@ -342,6 +342,10 @@ uint32_t CalcIndex(BufferData *data, uint32_t vertID, int32_t baseVertex)
|
||||
|
||||
uint32_t idx = *(uint32_t *)idxData;
|
||||
|
||||
// check for primitive restart *before* adding base vertex
|
||||
if(primRestart && idx == primRestart)
|
||||
return idx;
|
||||
|
||||
// apply base vertex but clamp to 0 if subtracting
|
||||
if(baseVertex < 0)
|
||||
{
|
||||
@@ -595,7 +599,7 @@ public:
|
||||
|
||||
if(indices && indices->data)
|
||||
{
|
||||
idx = CalcIndex(indices, row, baseVertex);
|
||||
idx = CalcIndex(indices, row, baseVertex, primRestart);
|
||||
|
||||
if(primRestart && idx == primRestart)
|
||||
return col == 1 ? lit("--") : lit(" Restart");
|
||||
@@ -608,7 +612,7 @@ public:
|
||||
{
|
||||
// if we have separate displayIndices, fetch that for display instead
|
||||
if(displayIndices && displayIndices->data)
|
||||
idx = CalcIndex(displayIndices, row, displayBaseVertex);
|
||||
idx = CalcIndex(displayIndices, row, displayBaseVertex, primRestart);
|
||||
|
||||
if(idx == ~0U)
|
||||
return outOfBounds();
|
||||
@@ -1697,7 +1701,7 @@ void BufferViewer::RT_FetchMeshData(IReplayController *r)
|
||||
}
|
||||
else if(draw->indexByteWidth == 4)
|
||||
{
|
||||
uint16_t primRestart = m_ModelVSIn->primRestart;
|
||||
uint32_t primRestart = m_ModelVSIn->primRestart;
|
||||
|
||||
memcpy(indices, idata.data(), qMin(idata.size(), draw->numIndices * sizeof(uint32_t)));
|
||||
|
||||
@@ -1753,7 +1757,7 @@ void BufferViewer::RT_FetchMeshData(IReplayController *r)
|
||||
offset = draw->vertexOffset;
|
||||
|
||||
if(draw->baseVertex > 0)
|
||||
maxIdx += (uint32_t)draw->baseVertex;
|
||||
maxIdx = qMax(maxIdx, maxIdx + (uint32_t)draw->baseVertex);
|
||||
}
|
||||
|
||||
if(pi && pv)
|
||||
@@ -1764,7 +1768,7 @@ void BufferViewer::RT_FetchMeshData(IReplayController *r)
|
||||
if(used)
|
||||
{
|
||||
bytebuf bufdata = r->GetBufferData(vb.resourceId, vb.byteOffset + offset * vb.byteStride,
|
||||
(maxIdx + 1) * vb.byteStride + maxAttrOffset);
|
||||
qMax(maxIdx, maxIdx + 1) * vb.byteStride + maxAttrOffset);
|
||||
|
||||
buf->data = new byte[bufdata.size()];
|
||||
memcpy(buf->data, bufdata.data(), bufdata.size());
|
||||
@@ -1896,6 +1900,7 @@ void BufferViewer::RT_FetchMeshData(IReplayController *r)
|
||||
bbox->input[i].buffers = models[i]->buffers;
|
||||
bbox->input[i].indices = models[i]->indices;
|
||||
bbox->input[i].baseVertex = models[i]->baseVertex;
|
||||
bbox->input[i].primRestart = models[i]->primRestart;
|
||||
|
||||
bbox->input[i].count = models[i]->numRows;
|
||||
|
||||
@@ -1953,9 +1958,9 @@ void BufferViewer::calcBoundingData(CalcBoundingBoxData &bbox)
|
||||
|
||||
if(s.indices && s.indices->data)
|
||||
{
|
||||
idx = CalcIndex(s.indices, row, s.baseVertex);
|
||||
idx = CalcIndex(s.indices, row, s.baseVertex, s.primRestart);
|
||||
|
||||
if(idx == ~0U)
|
||||
if(idx == ~0U || (s.primRestart && idx == s.primRestart))
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3286,7 +3291,7 @@ void BufferViewer::exportData(const BufferExport ¶ms)
|
||||
|
||||
if(model->indices && model->indices->data)
|
||||
{
|
||||
idx = CalcIndex(model->indices, i, model->baseVertex);
|
||||
idx = CalcIndex(model->indices, i, model->baseVertex, model->primRestart);
|
||||
|
||||
// completely omit primitive restart indices
|
||||
if(model->primRestart && idx == model->primRestart)
|
||||
|
||||
@@ -177,6 +177,7 @@ private:
|
||||
uint32_t count;
|
||||
BufferData *indices = NULL;
|
||||
int32_t baseVertex;
|
||||
uint32_t primRestart;
|
||||
QList<BufferData *> buffers;
|
||||
} input[3];
|
||||
|
||||
|
||||
@@ -287,6 +287,17 @@ FloatVector HighlightCache::InterpretVertex(const byte *data, uint32_t vert, con
|
||||
}
|
||||
|
||||
vert = indices[vert];
|
||||
|
||||
if(IsStrip(cfg.position.topology))
|
||||
{
|
||||
if((cfg.position.indexByteStride == 1 && vert == 0xff) ||
|
||||
(cfg.position.indexByteStride == 2 && vert == 0xffff) ||
|
||||
(cfg.position.indexByteStride == 4 && vert == 0xffffffff))
|
||||
{
|
||||
valid = false;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HighlightCache::InterpretVertex(data, vert, cfg.position.vertexByteStride,
|
||||
|
||||
@@ -78,6 +78,19 @@ struct Primitive_Restart : D3D11GraphicsTest
|
||||
|
||||
ID3D11BufferPtr ib = MakeBuffer().Index().Data(idx);
|
||||
|
||||
uint16_t idx2[] = {
|
||||
// strip 0
|
||||
10, 11, 12, 13, 14, 15, 16, 17,
|
||||
|
||||
// restart
|
||||
0xffff,
|
||||
|
||||
// strip 1
|
||||
18, 19, 20, 21, 22, 23, 24, 25,
|
||||
};
|
||||
|
||||
ID3D11BufferPtr ib2 = MakeBuffer().Index().Data(idx2);
|
||||
|
||||
while(Running())
|
||||
{
|
||||
ClearRenderTargetView(bbRTV, {0.4f, 0.5f, 0.6f, 1.0f});
|
||||
@@ -96,6 +109,13 @@ struct Primitive_Restart : D3D11GraphicsTest
|
||||
|
||||
ctx->DrawIndexed(17, 0, 0);
|
||||
|
||||
ClearRenderTargetView(bbRTV, {0.4f, 0.5f, 0.6f, 1.0f});
|
||||
|
||||
ctx->IASetIndexBuffer(ib2, DXGI_FORMAT_R16_UINT, 0);
|
||||
|
||||
// should get identical results with the vertex offset
|
||||
ctx->DrawIndexed(17, 0, -10);
|
||||
|
||||
Present();
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ void main()
|
||||
{Vec3f(0.5f, 0.0f, 0.0f), Vec4f(1.0f, 0.1f, 1.0f, 1.0f), Vec2f(1.0f, 0.0f)},
|
||||
};
|
||||
|
||||
AllocatedBuffer vb1(allocator, vkh::BufferCreateInfo(sizeof(DefaultA2V) * 50,
|
||||
AllocatedBuffer vb1(allocator, vkh::BufferCreateInfo(sizeof(DefaultA2V) * 66000,
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
||||
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
||||
@@ -165,6 +165,8 @@ void main()
|
||||
DefaultA2V *src = (DefaultA2V *)vertData;
|
||||
DefaultA2V *dst = (DefaultA2V *)vb1.map();
|
||||
|
||||
memset(dst, 0x5c, sizeof(DefaultA2V) * 66000);
|
||||
|
||||
// up-pointing triangle to offset 0
|
||||
memcpy(dst + 0, src + 1, sizeof(DefaultA2V));
|
||||
memcpy(dst + 1, src + 2, sizeof(DefaultA2V));
|
||||
@@ -250,7 +252,7 @@ void main()
|
||||
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
||||
|
||||
{
|
||||
uint32_t *dst = (uint32_t *)ib1.map();
|
||||
uint16_t *dst = (uint16_t *)ib1.map();
|
||||
|
||||
memset(dst, 0, sizeof(uint32_t) * 100);
|
||||
|
||||
@@ -279,7 +281,7 @@ void main()
|
||||
dst[44] = 32;
|
||||
dst[45] = 33;
|
||||
dst[46] = 34;
|
||||
dst[47] = 0xffffffff;
|
||||
dst[47] = 0xffff;
|
||||
dst[48] = 36;
|
||||
dst[49] = 37;
|
||||
dst[50] = 38;
|
||||
@@ -287,6 +289,19 @@ void main()
|
||||
dst[52] = 40;
|
||||
dst[53] = 41;
|
||||
|
||||
dst[54] = 130;
|
||||
dst[55] = 131;
|
||||
dst[56] = 132;
|
||||
dst[57] = 133;
|
||||
dst[58] = 134;
|
||||
dst[59] = 0xffff;
|
||||
dst[60] = 136;
|
||||
dst[61] = 137;
|
||||
dst[62] = 138;
|
||||
dst[63] = 139;
|
||||
dst[64] = 140;
|
||||
dst[65] = 141;
|
||||
|
||||
ib1.unmap();
|
||||
}
|
||||
|
||||
@@ -346,35 +361,35 @@ void main()
|
||||
// basic test
|
||||
vkCmdSetViewport(cmd, 0, 1, &vp);
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb1.buffer}, {0});
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdDrawIndexed(cmd, 3, 1, 0, 0, 0);
|
||||
vp.x += vp.width;
|
||||
|
||||
// test with first index
|
||||
vkCmdSetViewport(cmd, 0, 1, &vp);
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb1.buffer}, {0});
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdDrawIndexed(cmd, 3, 1, 5, 0, 0);
|
||||
vp.x += vp.width;
|
||||
|
||||
// test with first index and vertex offset
|
||||
vkCmdSetViewport(cmd, 0, 1, &vp);
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb1.buffer}, {0});
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdDrawIndexed(cmd, 3, 1, 13, -50, 0);
|
||||
vp.x += vp.width;
|
||||
|
||||
// test with first index and vertex offset and vbuffer offset
|
||||
vkCmdSetViewport(cmd, 0, 1, &vp);
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb1.buffer}, {10 * sizeof(DefaultA2V)});
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdDrawIndexed(cmd, 3, 1, 23, -100, 0);
|
||||
vp.x += vp.width;
|
||||
|
||||
// test with first index and vertex offset and vbuffer offset and ibuffer offset
|
||||
vkCmdSetViewport(cmd, 0, 1, &vp);
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb1.buffer}, {19 * sizeof(DefaultA2V)});
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 14 * sizeof(uint32_t), VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 14 * sizeof(uint16_t), VK_INDEX_TYPE_UINT16);
|
||||
vkCmdDrawIndexed(cmd, 3, 1, 23, -100, 0);
|
||||
vp.x += vp.width;
|
||||
|
||||
@@ -383,10 +398,17 @@ void main()
|
||||
// indexed strip with primitive restart
|
||||
vkCmdSetViewport(cmd, 0, 1, &vp);
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb1.buffer}, {0});
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdDrawIndexed(cmd, 12, 1, 42, 0, 0);
|
||||
vp.x += vp.width;
|
||||
|
||||
// indexed strip with primitive restart and vertex offset
|
||||
vkCmdSetViewport(cmd, 0, 1, &vp);
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb1.buffer}, {0});
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdDrawIndexed(cmd, 12, 1, 54, -100, 0);
|
||||
vp.x += vp.width;
|
||||
|
||||
// adjust to next row
|
||||
vp.x = 0.0f;
|
||||
vp.y += vp.height;
|
||||
@@ -425,21 +447,21 @@ void main()
|
||||
// basic test
|
||||
vkCmdSetViewport(cmd, 0, 1, &vp);
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb1.buffer, vb2.buffer}, {0, 0});
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdDrawIndexed(cmd, 3, 2, 5, 0, 0);
|
||||
vp.x += vp.width;
|
||||
|
||||
// basic test with first instance
|
||||
vkCmdSetViewport(cmd, 0, 1, &vp);
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb1.buffer, vb2.buffer}, {0, 0});
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdDrawIndexed(cmd, 3, 2, 13, -50, 5);
|
||||
vp.x += vp.width;
|
||||
|
||||
// basic test with first instance and instance buffer offset
|
||||
vkCmdSetViewport(cmd, 0, 1, &vp);
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb1.buffer, vb2.buffer}, {0, 8 * sizeof(Vec4f)});
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindIndexBuffer(cmd, ib1.buffer, 0, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdDrawIndexed(cmd, 3, 2, 23, -80, 5);
|
||||
vp.x += vp.width;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user