From 4042dcab68ab99d5bad41fd8be969638927f3128 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 11 Oct 2018 12:18:48 +0100 Subject: [PATCH] Use StructuredSerialiser to create fake objects for indirect calls --- .../driver/d3d12/d3d12_command_list_wrap.cpp | 501 +++++++----------- renderdoc/driver/d3d12/d3d12_commands.cpp | 4 + renderdoc/driver/d3d12/d3d12_common.h | 3 + renderdoc/driver/d3d12/d3d12_serialise.cpp | 32 +- renderdoc/driver/gl/gl_common.cpp | 23 + renderdoc/driver/gl/gl_common.h | 4 + .../driver/gl/wrappers/gl_draw_funcs.cpp | 90 +--- .../driver/vulkan/wrappers/vk_draw_funcs.cpp | 97 ++-- 8 files changed, 313 insertions(+), 441 deletions(-) diff --git a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp index 1b338956f..b5f477dde 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp @@ -3449,354 +3449,213 @@ void WrappedID3D12GraphicsCommandList2::PatchExecuteIndirect(BakedCmdListInfo &i } SDChunk *fakeChunk = new SDChunk(""); - fakeChunk->metadata.chunkID = (uint32_t)D3D12Chunk::List_IndirectSubCommand; - // just copy the metadata fakeChunk->metadata = baseChunk->metadata; - - fakeChunk->AddChild(makeSDObject("CommandIndex", i)); - fakeChunk->AddChild(makeSDObject("ArgumentIndex", a)); - - SDObject *argsig = new SDObject("ArgumentSignature", "D3D12_INDIRECT_ARGUMENT_DESC"); - - argsig->type.basetype = SDBasic::Struct; - argsig->type.byteSize = sizeof(D3D12_INDIRECT_ARGUMENT_DESC); + fakeChunk->metadata.chunkID = (uint32_t)D3D12Chunk::List_IndirectSubCommand; { - SDObject *argtype = new SDObject("Type", "D3D12_INDIRECT_ARGUMENT_TYPE"); + StructuredSerialiser structuriser(fakeChunk, &GetChunkName); + structuriser.SetUserData(GetResourceManager()); - argtype->type.basetype = SDBasic::Enum; - argtype->type.byteSize = 4; - argtype->type.flags = SDTypeFlags::HasCustomString; + structuriser.Serialise("CommandIndex", i); + structuriser.Serialise("ArgumentIndex", a); + structuriser.Serialise("ArgumentSignature", arg); - argtype->data.basic.u = (uint32_t)arg.Type; - argtype->data.str = ToStr(arg.Type); - - argsig->AddChild(argtype); - } - - switch(arg.Type) - { - case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW: - case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED: - case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH: - case D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW: - // no extra data in the argument descriptor - break; - case D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW: - argsig->AddChild(makeSDObject("Slot", arg.VertexBuffer.Slot)); - break; - case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT: - argsig->AddChild(makeSDObject("RootParameterIndex", arg.Constant.RootParameterIndex)); - argsig->AddChild( - makeSDObject("DestOffsetIn32BitValues", arg.Constant.DestOffsetIn32BitValues)); - argsig->AddChild(makeSDObject("Num32BitValuesToSet", arg.Constant.Num32BitValuesToSet)); - break; - case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW: - argsig->AddChild( - makeSDObject("RootParameterIndex", arg.ConstantBufferView.RootParameterIndex)); - break; - case D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW: - argsig->AddChild( - makeSDObject("RootParameterIndex", arg.ShaderResourceView.RootParameterIndex)); - break; - case D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW: - argsig->AddChild( - makeSDObject("RootParameterIndex", arg.UnorderedAccessView.RootParameterIndex)); - break; - } - - fakeChunk->AddChild(argsig); - - switch(arg.Type) - { - case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW: + switch(arg.Type) { - D3D12_DRAW_ARGUMENTS *args = (D3D12_DRAW_ARGUMENTS *)data; - data += sizeof(D3D12_DRAW_ARGUMENTS); - - curDraw.drawIndex = a; - curDraw.numIndices = args->VertexCountPerInstance; - curDraw.numInstances = args->InstanceCount; - curDraw.vertexOffset = args->StartVertexLocation; - curDraw.instanceOffset = args->StartInstanceLocation; - curDraw.flags |= DrawFlags::Drawcall | DrawFlags::Instanced | DrawFlags::Indirect; - curDraw.name = StringFormat::Fmt("[%u] arg%u: IndirectDraw(<%u, %u>)", i, a, - curDraw.numIndices, curDraw.numInstances); - - fakeChunk->name = curDraw.name; - - SDObject *command = new SDObject("ArgumentData", "D3D12_DRAW_ARGUMENTS"); - - command->type.basetype = SDBasic::Struct; - command->type.byteSize = sizeof(D3D12_DRAW_ARGUMENTS); - - command->AddChild(makeSDObject("VertexCountPerInstance", curDraw.numIndices)); - command->AddChild(makeSDObject("InstanceCount", curDraw.numInstances)); - command->AddChild(makeSDObject("StartVertexLocation", curDraw.vertexOffset)); - command->AddChild(makeSDObject("StartInstanceLocation", curDraw.instanceOffset)); - - fakeChunk->AddChild(command); - - // if this is the first draw of the indirect, we could have picked up previous - // non-indirect events in this drawcall, so the EID will be higher than we expect. Just - // assign the draw's EID - eid = curDraw.eventId; - - m_Cmd->AddUsage(draws[idx]); - - // advance - idx++; - eid++; - - break; - } - case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED: - { - D3D12_DRAW_INDEXED_ARGUMENTS *args = (D3D12_DRAW_INDEXED_ARGUMENTS *)data; - data += sizeof(D3D12_DRAW_INDEXED_ARGUMENTS); - - curDraw.drawIndex = a; - curDraw.numIndices = args->IndexCountPerInstance; - curDraw.numInstances = args->InstanceCount; - curDraw.baseVertex = args->BaseVertexLocation; - curDraw.vertexOffset = args->StartIndexLocation; - curDraw.instanceOffset = args->StartInstanceLocation; - curDraw.flags |= - DrawFlags::Drawcall | DrawFlags::Instanced | DrawFlags::Indexed | DrawFlags::Indirect; - curDraw.name = StringFormat::Fmt("[%u] arg%u: IndirectDrawIndexed(<%u, %u>)", i, a, - curDraw.numIndices, curDraw.numInstances); - - fakeChunk->name = curDraw.name; - - SDObject *command = new SDObject("ArgumentData", "D3D12_DRAW_INDEXED_ARGUMENTS"); - - command->type.basetype = SDBasic::Struct; - command->type.byteSize = sizeof(D3D12_DRAW_INDEXED_ARGUMENTS); - - command->AddChild(makeSDObject("IndexCountPerInstance", curDraw.numIndices)); - command->AddChild(makeSDObject("InstanceCount", curDraw.numInstances)); - command->AddChild(makeSDObject("BaseVertexLocation", curDraw.baseVertex)); - command->AddChild(makeSDObject("StartIndexLocation", curDraw.vertexOffset)); - command->AddChild(makeSDObject("StartInstanceLocation", curDraw.instanceOffset)); - - fakeChunk->AddChild(command); - - // if this is the first draw of the indirect, we could have picked up previous - // non-indirect events in this drawcall, so the EID will be higher than we expect. Just - // assign the draw's EID - eid = curDraw.eventId; - - m_Cmd->AddUsage(draws[idx]); - - // advance - idx++; - eid++; - - break; - } - case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH: - { - D3D12_DISPATCH_ARGUMENTS *args = (D3D12_DISPATCH_ARGUMENTS *)data; - data += sizeof(D3D12_DISPATCH_ARGUMENTS); - - curDraw.dispatchDimension[0] = args->ThreadGroupCountX; - curDraw.dispatchDimension[1] = args->ThreadGroupCountY; - curDraw.dispatchDimension[2] = args->ThreadGroupCountZ; - curDraw.flags |= DrawFlags::Dispatch | DrawFlags::Indirect; - curDraw.name = StringFormat::Fmt( - "[%u] arg%u: IndirectDispatch(<%u, %u, %u>)", i, a, curDraw.dispatchDimension[0], - curDraw.dispatchDimension[1], curDraw.dispatchDimension[2]); - - fakeChunk->name = curDraw.name; - - SDObject *command = new SDObject("ArgumentData", "D3D12_DISPATCH_ARGUMENTS"); - - command->type.basetype = SDBasic::Struct; - command->type.byteSize = sizeof(D3D12_DISPATCH_ARGUMENTS); - - command->AddChild(makeSDObject("ThreadGroupCountX", curDraw.dispatchDimension[0])); - command->AddChild(makeSDObject("ThreadGroupCountY", curDraw.dispatchDimension[1])); - command->AddChild(makeSDObject("ThreadGroupCountZ", curDraw.dispatchDimension[2])); - - fakeChunk->AddChild(command); - - // if this is the first draw of the indirect, we could have picked up previous - // non-indirect events in this drawcall, so the EID will be higher than we expect. Just - // assign the draw's EID - eid = curDraw.eventId; - - m_Cmd->AddUsage(draws[idx]); - - // advance - idx++; - eid++; - - break; - } - case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT: - { - size_t argSize = sizeof(uint32_t) * arg.Constant.Num32BitValuesToSet; - uint32_t *data32 = (uint32_t *)data; - data += argSize; - - fakeChunk->name = StringFormat::Fmt("[%u] arg%u: IndirectSetRoot32BitConstants()", i, a); - - SDObject *values = new SDObject("Values", "uint32_t"); - - values->type.basetype = SDBasic::Array; - values->type.byteSize = argSize; - - for(UINT v = 0; v < arg.Constant.Num32BitValuesToSet; v++) - values->AddChild(makeSDObject("$el", data32[v])); - - fakeChunk->AddChild(values); - - // advance only the EID, since we're still in the same draw - eid++; - - break; - } - case D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW: - { - D3D12_VERTEX_BUFFER_VIEW *vb = (D3D12_VERTEX_BUFFER_VIEW *)data; - data += sizeof(D3D12_VERTEX_BUFFER_VIEW); - - ResourceId id; - uint64_t offs = 0; - m_pDevice->GetResIDFromAddr(vb->BufferLocation, id, offs); - - ID3D12Resource *res = GetResourceManager()->GetLiveAs(id); - RDCASSERT(res); - if(res) - vb->BufferLocation = res->GetGPUVirtualAddress() + offs; - - fakeChunk->name = StringFormat::Fmt("[%u] arg%u: IndirectIASetVertexBuffer()", i, a); - - SDObject *command = new SDObject("ArgumentData", "D3D12_VERTEX_BUFFER_VIEW"); - - command->type.basetype = SDBasic::Struct; - command->type.byteSize = sizeof(D3D12_VERTEX_BUFFER_VIEW); - + case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW: { - SDObject *buf = new SDObject("BufferLocation", "D3D12BufferLocation"); + D3D12_DRAW_ARGUMENTS *args = (D3D12_DRAW_ARGUMENTS *)data; + data += sizeof(D3D12_DRAW_ARGUMENTS); - buf->type.basetype = SDBasic::Struct; - buf->type.byteSize = sizeof(D3D12BufferLocation); + curDraw.drawIndex = a; + curDraw.numIndices = args->VertexCountPerInstance; + curDraw.numInstances = args->InstanceCount; + curDraw.vertexOffset = args->StartVertexLocation; + curDraw.instanceOffset = args->StartInstanceLocation; + curDraw.flags |= DrawFlags::Drawcall | DrawFlags::Instanced | DrawFlags::Indirect; + curDraw.name = StringFormat::Fmt("[%u] arg%u: IndirectDraw(<%u, %u>)", i, a, + curDraw.numIndices, curDraw.numInstances); - buf->AddChild(makeSDObject("Buffer", id)); - buf->AddChild(makeSDObject("Offset", offs)); + fakeChunk->name = curDraw.name; - buf->data.children[0]->type.flags |= SDTypeFlags::HasCustomString; - buf->data.children[0]->data.str = ToStr(GetResourceManager()->GetOriginalID(id)); + structuriser.Serialise("ArgumentData", *args); - command->AddChild(buf); + // if this is the first draw of the indirect, we could have picked up previous + // non-indirect events in this drawcall, so the EID will be higher than we expect. Just + // assign the draw's EID + eid = curDraw.eventId; + + m_Cmd->AddUsage(draws[idx]); + + // advance + idx++; + eid++; + + break; } - - command->AddChild(makeSDObject("SizeInBytes", vb->SizeInBytes)); - command->AddChild(makeSDObject("StrideInBytes", vb->StrideInBytes)); - - fakeChunk->AddChild(command); - - // advance only the EID, since we're still in the same draw - eid++; - - break; - } - case D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW: - { - D3D12_INDEX_BUFFER_VIEW *ib = (D3D12_INDEX_BUFFER_VIEW *)data; - data += sizeof(D3D12_INDEX_BUFFER_VIEW); - - ResourceId id; - uint64_t offs = 0; - m_pDevice->GetResIDFromAddr(ib->BufferLocation, id, offs); - - ID3D12Resource *res = GetResourceManager()->GetLiveAs(id); - RDCASSERT(res); - if(res) - ib->BufferLocation = res->GetGPUVirtualAddress() + offs; - - fakeChunk->name = StringFormat::Fmt("[%u] arg%u: IndirectIASetIndexBuffer()", i, a); - - SDObject *command = new SDObject("ArgumentData", "D3D12_INDEX_BUFFER_VIEW"); - - command->type.basetype = SDBasic::Struct; - command->type.byteSize = sizeof(D3D12_INDEX_BUFFER_VIEW); - + case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED: { - SDObject *buf = new SDObject("BufferLocation", "D3D12BufferLocation"); + D3D12_DRAW_INDEXED_ARGUMENTS *args = (D3D12_DRAW_INDEXED_ARGUMENTS *)data; + data += sizeof(D3D12_DRAW_INDEXED_ARGUMENTS); - buf->type.basetype = SDBasic::Struct; - buf->type.byteSize = sizeof(D3D12BufferLocation); + curDraw.drawIndex = a; + curDraw.numIndices = args->IndexCountPerInstance; + curDraw.numInstances = args->InstanceCount; + curDraw.baseVertex = args->BaseVertexLocation; + curDraw.vertexOffset = args->StartIndexLocation; + curDraw.instanceOffset = args->StartInstanceLocation; + curDraw.flags |= DrawFlags::Drawcall | DrawFlags::Instanced | DrawFlags::Indexed | + DrawFlags::Indirect; + curDraw.name = StringFormat::Fmt("[%u] arg%u: IndirectDrawIndexed(<%u, %u>)", i, a, + curDraw.numIndices, curDraw.numInstances); - buf->AddChild(makeSDObject("Buffer", id)); - buf->AddChild(makeSDObject("Offset", offs)); + fakeChunk->name = curDraw.name; - buf->data.children[0]->type.flags |= SDTypeFlags::HasCustomString; - buf->data.children[0]->data.str = ToStr(GetResourceManager()->GetOriginalID(id)); + structuriser.Serialise("ArgumentData", *args); - command->AddChild(buf); + // if this is the first draw of the indirect, we could have picked up previous + // non-indirect events in this drawcall, so the EID will be higher than we expect. Just + // assign the draw's EID + eid = curDraw.eventId; + + m_Cmd->AddUsage(draws[idx]); + + // advance + idx++; + eid++; + + break; } - - command->AddChild(makeSDObject("SizeInBytes", ib->SizeInBytes)); - command->AddChild(makeSDObject("Format", ib->Format)); - - fakeChunk->AddChild(command); - - // advance only the EID, since we're still in the same draw - eid++; - - break; - } - case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW: - case D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW: - case D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW: - { - D3D12_GPU_VIRTUAL_ADDRESS *addr = (D3D12_GPU_VIRTUAL_ADDRESS *)data; - data += sizeof(D3D12_GPU_VIRTUAL_ADDRESS); - - ResourceId id; - uint64_t offs = 0; - m_pDevice->GetResIDFromAddr(*addr, id, offs); - - ID3D12Resource *res = GetResourceManager()->GetLiveAs(id); - RDCASSERT(res); - if(res) - *addr = res->GetGPUVirtualAddress() + offs; - - const char *viewTypeStr = "?"; - - if(arg.Type == D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW) - viewTypeStr = "ConstantBuffer"; - else if(arg.Type == D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW) - viewTypeStr = "ShaderResource"; - else if(arg.Type == D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW) - viewTypeStr = "UnorderedAccess"; - - fakeChunk->name = - StringFormat::Fmt("[%u] arg%u: IndirectSetRoot%sView()", i, a, viewTypeStr); - + case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH: { - SDObject *buf = new SDObject("BufferLocation", "D3D12BufferLocation"); + D3D12_DISPATCH_ARGUMENTS *args = (D3D12_DISPATCH_ARGUMENTS *)data; + data += sizeof(D3D12_DISPATCH_ARGUMENTS); - buf->type.basetype = SDBasic::Struct; - buf->type.byteSize = sizeof(D3D12BufferLocation); + curDraw.dispatchDimension[0] = args->ThreadGroupCountX; + curDraw.dispatchDimension[1] = args->ThreadGroupCountY; + curDraw.dispatchDimension[2] = args->ThreadGroupCountZ; + curDraw.flags |= DrawFlags::Dispatch | DrawFlags::Indirect; + curDraw.name = StringFormat::Fmt( + "[%u] arg%u: IndirectDispatch(<%u, %u, %u>)", i, a, curDraw.dispatchDimension[0], + curDraw.dispatchDimension[1], curDraw.dispatchDimension[2]); - buf->AddChild(makeSDObject("Buffer", id)); - buf->AddChild(makeSDObject("Offset", offs)); + fakeChunk->name = curDraw.name; - buf->data.children[0]->type.flags |= SDTypeFlags::HasCustomString; - buf->data.children[0]->data.str = ToStr(GetResourceManager()->GetOriginalID(id)); + structuriser.Serialise("ArgumentData", *args); - fakeChunk->AddChild(buf); + // if this is the first draw of the indirect, we could have picked up previous + // non-indirect events in this drawcall, so the EID will be higher than we expect. Just + // assign the draw's EID + eid = curDraw.eventId; + + m_Cmd->AddUsage(draws[idx]); + + // advance + idx++; + eid++; + + break; } + case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT: + { + size_t argSize = sizeof(uint32_t) * arg.Constant.Num32BitValuesToSet; + uint32_t *data32 = (uint32_t *)data; + data += argSize; - // advance only the EID, since we're still in the same draw - eid++; + fakeChunk->name = StringFormat::Fmt("[%u] arg%u: IndirectSetRoot32BitConstants()", i, a); - break; + structuriser.Serialise("Values", data32, arg.Constant.Num32BitValuesToSet); + + // advance only the EID, since we're still in the same draw + eid++; + + break; + } + case D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW: + { + D3D12_VERTEX_BUFFER_VIEW *vb = (D3D12_VERTEX_BUFFER_VIEW *)data; + data += sizeof(D3D12_VERTEX_BUFFER_VIEW); + + ResourceId id; + uint64_t offs = 0; + m_pDevice->GetResIDFromAddr(vb->BufferLocation, id, offs); + + ID3D12Resource *res = GetResourceManager()->GetLiveAs(id); + RDCASSERT(res); + if(res) + vb->BufferLocation = res->GetGPUVirtualAddress() + offs; + + fakeChunk->name = StringFormat::Fmt("[%u] arg%u: IndirectIASetVertexBuffer()", i, a); + + structuriser.Serialise("ArgumentData", *vb); + + // advance only the EID, since we're still in the same draw + eid++; + + break; + } + case D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW: + { + D3D12_INDEX_BUFFER_VIEW *ib = (D3D12_INDEX_BUFFER_VIEW *)data; + data += sizeof(D3D12_INDEX_BUFFER_VIEW); + + ResourceId id; + uint64_t offs = 0; + m_pDevice->GetResIDFromAddr(ib->BufferLocation, id, offs); + + ID3D12Resource *res = GetResourceManager()->GetLiveAs(id); + RDCASSERT(res); + if(res) + ib->BufferLocation = res->GetGPUVirtualAddress() + offs; + + fakeChunk->name = StringFormat::Fmt("[%u] arg%u: IndirectIASetIndexBuffer()", i, a); + + structuriser.Serialise("ArgumentData", *ib); + + // advance only the EID, since we're still in the same draw + eid++; + + break; + } + case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW: + case D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW: + case D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW: + { + D3D12_GPU_VIRTUAL_ADDRESS *addr = (D3D12_GPU_VIRTUAL_ADDRESS *)data; + data += sizeof(D3D12_GPU_VIRTUAL_ADDRESS); + + ResourceId id; + uint64_t offs = 0; + m_pDevice->GetResIDFromAddr(*addr, id, offs); + + ID3D12Resource *res = GetResourceManager()->GetLiveAs(id); + RDCASSERT(res); + if(res) + *addr = res->GetGPUVirtualAddress() + offs; + + const char *viewTypeStr = "?"; + + if(arg.Type == D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW) + viewTypeStr = "ConstantBuffer"; + else if(arg.Type == D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW) + viewTypeStr = "ShaderResource"; + else if(arg.Type == D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW) + viewTypeStr = "UnorderedAccess"; + + fakeChunk->name = + StringFormat::Fmt("[%u] arg%u: IndirectSetRoot%sView()", i, a, viewTypeStr); + + D3D12BufferLocation buf = *addr; + + structuriser.Serialise("ArgumentData", buf); + + // advance only the EID, since we're still in the same draw + eid++; + + break; + } + default: RDCERR("Unexpected argument type! %d", arg.Type); break; } - default: RDCERR("Unexpected argument type! %d", arg.Type); break; } m_Cmd->m_StructuredFile->chunks.push_back(fakeChunk); diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index 115919f9d..471bb5c36 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -541,6 +541,10 @@ bool WrappedID3D12CommandQueue::ProcessChunk(ReadSerialiser &ser, D3D12Chunk chu case D3D12Chunk::Resource_WriteToSubresource: ret = m_pDevice->Serialise_WriteToSubresource(ser, NULL, 0, NULL, NULL, 0, 0); break; + case D3D12Chunk::List_IndirectSubCommand: + // this is a fake chunk generated at runtime as part of indirect draws. + // Just in case it gets exported and imported, completely ignore it. + return true; default: { diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index dc729565c..9c7033289 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -686,6 +686,9 @@ DECLARE_REFLECTION_STRUCT(D3D12_SAMPLE_POSITION); DECLARE_REFLECTION_STRUCT(D3D12_RANGE_UINT64); DECLARE_REFLECTION_STRUCT(D3D12_SUBRESOURCE_RANGE_UINT64); DECLARE_REFLECTION_STRUCT(D3D12_WRITEBUFFERIMMEDIATE_PARAMETER); +DECLARE_REFLECTION_STRUCT(D3D12_DRAW_ARGUMENTS); +DECLARE_REFLECTION_STRUCT(D3D12_DRAW_INDEXED_ARGUMENTS); +DECLARE_REFLECTION_STRUCT(D3D12_DISPATCH_ARGUMENTS); DECLARE_DESERIALISE_TYPE(D3D12_DISCARD_REGION); DECLARE_DESERIALISE_TYPE(D3D12_GRAPHICS_PIPELINE_STATE_DESC); diff --git a/renderdoc/driver/d3d12/d3d12_serialise.cpp b/renderdoc/driver/d3d12/d3d12_serialise.cpp index 115182575..6b929ab5d 100644 --- a/renderdoc/driver/d3d12/d3d12_serialise.cpp +++ b/renderdoc/driver/d3d12/d3d12_serialise.cpp @@ -1259,6 +1259,33 @@ void DoSerialise(SerialiserType &ser, D3D12_WRITEBUFFERIMMEDIATE_PARAMETER &el) SERIALISE_MEMBER(Value); } +template +void DoSerialise(SerialiserType &ser, D3D12_DRAW_ARGUMENTS &el) +{ + SERIALISE_MEMBER(VertexCountPerInstance); + SERIALISE_MEMBER(InstanceCount); + SERIALISE_MEMBER(StartVertexLocation); + SERIALISE_MEMBER(StartInstanceLocation); +} + +template +void DoSerialise(SerialiserType &ser, D3D12_DRAW_INDEXED_ARGUMENTS &el) +{ + SERIALISE_MEMBER(IndexCountPerInstance); + SERIALISE_MEMBER(InstanceCount); + SERIALISE_MEMBER(StartIndexLocation); + SERIALISE_MEMBER(BaseVertexLocation); + SERIALISE_MEMBER(StartInstanceLocation); +} + +template +void DoSerialise(SerialiserType &ser, D3D12_DISPATCH_ARGUMENTS &el) +{ + SERIALISE_MEMBER(ThreadGroupCountX); + SERIALISE_MEMBER(ThreadGroupCountY); + SERIALISE_MEMBER(ThreadGroupCountZ); +} + INSTANTIATE_SERIALISE_TYPE(PortableHandle); INSTANTIATE_SERIALISE_TYPE(D3D12_CPU_DESCRIPTOR_HANDLE); INSTANTIATE_SERIALISE_TYPE(D3D12_GPU_DESCRIPTOR_HANDLE); @@ -1304,4 +1331,7 @@ INSTANTIATE_SERIALISE_TYPE(D3D12_DEPTH_STENCIL_DESC1); INSTANTIATE_SERIALISE_TYPE(D3D12_VIEW_INSTANCING_DESC); INSTANTIATE_SERIALISE_TYPE(D3D12_SAMPLE_POSITION); INSTANTIATE_SERIALISE_TYPE(D3D12_SUBRESOURCE_RANGE_UINT64); -INSTANTIATE_SERIALISE_TYPE(D3D12_WRITEBUFFERIMMEDIATE_PARAMETER); \ No newline at end of file +INSTANTIATE_SERIALISE_TYPE(D3D12_WRITEBUFFERIMMEDIATE_PARAMETER); +INSTANTIATE_SERIALISE_TYPE(D3D12_DRAW_ARGUMENTS); +INSTANTIATE_SERIALISE_TYPE(D3D12_DRAW_INDEXED_ARGUMENTS); +INSTANTIATE_SERIALISE_TYPE(D3D12_DISPATCH_ARGUMENTS); diff --git a/renderdoc/driver/gl/gl_common.cpp b/renderdoc/driver/gl/gl_common.cpp index 7d33a950e..b1109ed91 100644 --- a/renderdoc/driver/gl/gl_common.cpp +++ b/renderdoc/driver/gl/gl_common.cpp @@ -1152,6 +1152,29 @@ void DoSerialise(SerialiserType &ser, GLInitParams &el) INSTANTIATE_SERIALISE_TYPE(GLInitParams); +template +void DoSerialise(SerialiserType &ser, DrawElementsIndirectCommand &el) +{ + SERIALISE_MEMBER(count); + SERIALISE_MEMBER(instanceCount); + SERIALISE_MEMBER(firstIndex); + SERIALISE_MEMBER(baseVertex); + SERIALISE_MEMBER(baseInstance); +} + +INSTANTIATE_SERIALISE_TYPE(DrawElementsIndirectCommand); + +template +void DoSerialise(SerialiserType &ser, DrawArraysIndirectCommand &el) +{ + SERIALISE_MEMBER(count); + SERIALISE_MEMBER(instanceCount); + SERIALISE_MEMBER(first); + SERIALISE_MEMBER(baseInstance); +} + +INSTANTIATE_SERIALISE_TYPE(DrawArraysIndirectCommand); + size_t BufferIdx(GLenum buf) { switch(buf) diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 6c6b965d7..68e941880 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -785,6 +785,8 @@ struct DrawElementsIndirectCommand uint32_t baseInstance; }; +DECLARE_REFLECTION_STRUCT(DrawElementsIndirectCommand); + struct DrawArraysIndirectCommand { uint32_t count; @@ -793,6 +795,8 @@ struct DrawArraysIndirectCommand uint32_t baseInstance; }; +DECLARE_REFLECTION_STRUCT(DrawArraysIndirectCommand); + enum class GLChunk : uint32_t { DeviceInitialisation = (uint32_t)SystemChunk::FirstDriverChunk, diff --git a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp index ccce717ef..dcb7aaf5a 100644 --- a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp @@ -2465,24 +2465,16 @@ bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirect(SerialiserType &ser, GLe // add a fake chunk for this individual indirect draw SDChunk *fakeChunk = new SDChunk(multidraw.name.c_str()); - fakeChunk->metadata.chunkID = (uint32_t)GLChunk::glIndirectSubCommand; - // just copy the metadata fakeChunk->metadata = baseChunk->metadata; + fakeChunk->metadata.chunkID = (uint32_t)GLChunk::glIndirectSubCommand; - fakeChunk->AddChild(makeSDObject("drawIndex", (uint32_t)i)); - fakeChunk->AddChild(makeSDObject("offset", (uint64_t)offs)); + { + StructuredSerialiser structuriser(fakeChunk, ser.GetChunkLookup()); - SDObject *command = new SDObject("command", "DrawArraysIndirectCommand"); - - command->type.basetype = SDBasic::Struct; - command->type.byteSize = sizeof(DrawArraysIndirectCommand); - - command->AddChild(makeSDObject("count", params.count)); - command->AddChild(makeSDObject("instanceCount", params.instanceCount)); - command->AddChild(makeSDObject("first", params.first)); - command->AddChild(makeSDObject("baseInstance", params.baseInstance)); - - fakeChunk->AddChild(command); + structuriser.Serialise("drawIndex", i); + structuriser.Serialise("offset", offs); + structuriser.Serialise("command", params); + } m_StructuredFile->chunks.push_back(fakeChunk); @@ -2691,25 +2683,16 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirect(SerialiserType &ser, G // add a fake chunk for this individual indirect draw SDChunk *fakeChunk = new SDChunk(multidraw.name.c_str()); - fakeChunk->metadata.chunkID = (uint32_t)GLChunk::glIndirectSubCommand; - // just copy the metadata fakeChunk->metadata = baseChunk->metadata; + fakeChunk->metadata.chunkID = (uint32_t)GLChunk::glIndirectSubCommand; - fakeChunk->AddChild(makeSDObject("drawIndex", (uint32_t)i)); - fakeChunk->AddChild(makeSDObject("offset", (uint64_t)offs)); + { + StructuredSerialiser structuriser(fakeChunk, ser.GetChunkLookup()); - SDObject *command = new SDObject("command", "DrawElementsIndirectCommand"); - - command->type.basetype = SDBasic::Struct; - command->type.byteSize = sizeof(DrawElementsIndirectCommand); - - command->AddChild(makeSDObject("count", params.count)); - command->AddChild(makeSDObject("instanceCount", params.instanceCount)); - command->AddChild(makeSDObject("firstIndex", params.firstIndex)); - command->AddChild(makeSDObject("baseVertex", params.baseVertex)); - command->AddChild(makeSDObject("baseInstance", params.baseInstance)); - - fakeChunk->AddChild(command); + structuriser.Serialise("drawIndex", i); + structuriser.Serialise("offset", offs); + structuriser.Serialise("command", params); + } m_StructuredFile->chunks.push_back(fakeChunk); @@ -2918,24 +2901,16 @@ bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirectCount(SerialiserType &ser // add a fake chunk for this individual indirect draw SDChunk *fakeChunk = new SDChunk(multidraw.name.c_str()); - fakeChunk->metadata.chunkID = (uint32_t)GLChunk::glIndirectSubCommand; - // just copy the metadata fakeChunk->metadata = baseChunk->metadata; + fakeChunk->metadata.chunkID = (uint32_t)GLChunk::glIndirectSubCommand; - fakeChunk->AddChild(makeSDObject("drawIndex", (uint32_t)i)); - fakeChunk->AddChild(makeSDObject("offset", (uint64_t)offs)); + { + StructuredSerialiser structuriser(fakeChunk, ser.GetChunkLookup()); - SDObject *command = new SDObject("command", "DrawArraysIndirectCommand"); - - command->type.basetype = SDBasic::Struct; - command->type.byteSize = sizeof(DrawArraysIndirectCommand); - - command->AddChild(makeSDObject("count", params.count)); - command->AddChild(makeSDObject("instanceCount", params.instanceCount)); - command->AddChild(makeSDObject("first", params.first)); - command->AddChild(makeSDObject("baseInstance", params.baseInstance)); - - fakeChunk->AddChild(command); + structuriser.Serialise("drawIndex", i); + structuriser.Serialise("offset", offs); + structuriser.Serialise("command", params); + } m_StructuredFile->chunks.push_back(fakeChunk); @@ -3156,25 +3131,16 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirectCount(SerialiserType &s // add a fake chunk for this individual indirect draw SDChunk *fakeChunk = new SDChunk(multidraw.name.c_str()); - fakeChunk->metadata.chunkID = (uint32_t)GLChunk::glIndirectSubCommand; - // just copy the metadata fakeChunk->metadata = baseChunk->metadata; + fakeChunk->metadata.chunkID = (uint32_t)GLChunk::glIndirectSubCommand; - fakeChunk->AddChild(makeSDObject("drawIndex", (uint32_t)i)); - fakeChunk->AddChild(makeSDObject("offset", (uint64_t)offs)); + { + StructuredSerialiser structuriser(fakeChunk, ser.GetChunkLookup()); - SDObject *command = new SDObject("command", "DrawElementsIndirectCommand"); - - command->type.basetype = SDBasic::Struct; - command->type.byteSize = sizeof(DrawElementsIndirectCommand); - - command->AddChild(makeSDObject("count", params.count)); - command->AddChild(makeSDObject("instanceCount", params.instanceCount)); - command->AddChild(makeSDObject("firstIndex", params.firstIndex)); - command->AddChild(makeSDObject("baseVertex", params.baseVertex)); - command->AddChild(makeSDObject("baseInstance", params.baseInstance)); - - fakeChunk->AddChild(command); + structuriser.Serialise("drawIndex", i); + structuriser.Serialise("offset", offs); + structuriser.Serialise("command", params); + } m_StructuredFile->chunks.push_back(fakeChunk); diff --git a/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp index d2fd483ee..97b500f20 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp @@ -579,25 +579,16 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndirect(SerialiserType &ser, VkCommandBu // add a fake chunk for this individual indirect draw SDChunk *fakeChunk = new SDChunk("Indirect sub-command"); - fakeChunk->metadata.chunkID = (uint32_t)VulkanChunk::vkCmdIndirectSubCommand; - // just copy the metadata fakeChunk->metadata = baseChunk->metadata; + fakeChunk->metadata.chunkID = (uint32_t)VulkanChunk::vkCmdIndirectSubCommand; - fakeChunk->AddChild(makeSDObject("drawIndex", 0)); - fakeChunk->AddChild(makeSDObject("offset", offset)); + { + StructuredSerialiser structuriser(fakeChunk, ser.GetChunkLookup()); - SDObject *command = new SDObject("command", "VkDrawIndirectCommand"); - - command->type.basetype = SDBasic::Struct; - command->type.byteSize = sizeof(VkDrawIndirectCommand); - - // these get filled in at patch time - command->AddChild(makeSDUInt32("vertexCount", 0)); - command->AddChild(makeSDUInt32("instanceCount", 0)); - command->AddChild(makeSDUInt32("firstVertex", 0)); - command->AddChild(makeSDUInt32("firstInstance", 0)); - - fakeChunk->AddChild(command); + structuriser.Serialise("drawIndex", 0U); + structuriser.Serialise("offset", offset); + structuriser.Serialise("command", VkDrawIndirectCommand()); + } m_StructuredFile->chunks.push_back(fakeChunk); @@ -633,8 +624,6 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndirect(SerialiserType &ser, VkCommandBu m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID++; - VkDeviceSize cmdOffs = offset; - for(uint32_t i = 0; i < count; i++) { DrawcallDescription multi; @@ -646,25 +635,16 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndirect(SerialiserType &ser, VkCommandBu // add a fake chunk for this individual indirect draw SDChunk *fakeChunk = new SDChunk("Indirect sub-command"); - fakeChunk->metadata.chunkID = (uint32_t)VulkanChunk::vkCmdIndirectSubCommand; - // just copy the metadata fakeChunk->metadata = baseChunk->metadata; + fakeChunk->metadata.chunkID = (uint32_t)VulkanChunk::vkCmdIndirectSubCommand; - fakeChunk->AddChild(makeSDObject("drawIndex", i)); - fakeChunk->AddChild(makeSDObject("offset", cmdOffs)); + { + StructuredSerialiser structuriser(fakeChunk, ser.GetChunkLookup()); - SDObject *command = new SDObject("command", "VkDrawIndirectCommand"); - - command->type.basetype = SDBasic::Struct; - command->type.byteSize = sizeof(VkDrawIndirectCommand); - - // these get filled in at patch time - command->AddChild(makeSDUInt32("vertexCount", 0)); - command->AddChild(makeSDUInt32("instanceCount", 0)); - command->AddChild(makeSDUInt32("firstVertex", 0)); - command->AddChild(makeSDUInt32("firstInstance", 0)); - - fakeChunk->AddChild(command); + structuriser.Serialise("drawIndex", 0U); + structuriser.Serialise("offset", offset); + structuriser.Serialise("command", VkDrawIndirectCommand()); + } m_StructuredFile->chunks.push_back(fakeChunk); @@ -947,6 +927,8 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirect(SerialiserType &ser, "buffer without RENDER_PASS_CONTINUE_BIT"); } + SDChunk *baseChunk = m_StructuredFile->chunks.back(); + // for 'single' draws, don't do complex multi-draw just inline it if(count <= 1) { @@ -954,6 +936,23 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirect(SerialiserType &ser, AddEvent(); + // add a fake chunk for this individual indirect draw + SDChunk *fakeChunk = new SDChunk("Indirect sub-command"); + fakeChunk->metadata = baseChunk->metadata; + fakeChunk->metadata.chunkID = (uint32_t)VulkanChunk::vkCmdIndirectSubCommand; + + { + StructuredSerialiser structuriser(fakeChunk, ser.GetChunkLookup()); + + structuriser.Serialise("drawIndex", 0U); + structuriser.Serialise("offset", offset); + structuriser.Serialise("command", VkDrawIndexedIndirectCommand()); + } + + m_StructuredFile->chunks.push_back(fakeChunk); + + AddEvent(); + draw.name = name; draw.flags = DrawFlags::Drawcall | DrawFlags::Instanced | DrawFlags::Indexed | DrawFlags::Indirect; @@ -985,10 +984,6 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirect(SerialiserType &ser, m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID++; - VkDeviceSize cmdOffs = offset; - - SDChunk *baseChunk = m_StructuredFile->chunks.back(); - for(uint32_t i = 0; i < count; i++) { DrawcallDescription multi; @@ -1001,26 +996,16 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirect(SerialiserType &ser, // add a fake chunk for this individual indirect draw SDChunk *fakeChunk = new SDChunk("Indirect sub-command"); - fakeChunk->metadata.chunkID = (uint32_t)VulkanChunk::vkCmdIndirectSubCommand; - // just copy the metadata fakeChunk->metadata = baseChunk->metadata; + fakeChunk->metadata.chunkID = (uint32_t)VulkanChunk::vkCmdIndirectSubCommand; - fakeChunk->AddChild(makeSDObject("drawIndex", i)); - fakeChunk->AddChild(makeSDObject("offset", cmdOffs)); + { + StructuredSerialiser structuriser(fakeChunk, ser.GetChunkLookup()); - SDObject *command = new SDObject("command", "VkDrawIndexedIndirectCommand"); - - command->type.basetype = SDBasic::Struct; - command->type.byteSize = sizeof(VkDrawIndexedIndirectCommand); - - // these get filled in at patch time - command->AddChild(makeSDUInt32("indexCount", 0)); - command->AddChild(makeSDUInt32("instanceCount", 0)); - command->AddChild(makeSDUInt32("firstIndex", 0)); - command->AddChild(makeSDInt32("vertexOffset", 0)); - command->AddChild(makeSDUInt32("firstInstance", 0)); - - fakeChunk->AddChild(command); + structuriser.Serialise("drawIndex", 0U); + structuriser.Serialise("offset", offset); + structuriser.Serialise("command", VkDrawIndexedIndirectCommand()); + } m_StructuredFile->chunks.push_back(fakeChunk); @@ -1028,8 +1013,6 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirect(SerialiserType &ser, AddDrawcall(multi, true); m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID++; - - cmdOffs += stride; } draw.name = name;