diff --git a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp index f6f83b583..eaabc5ae3 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp @@ -32,12 +32,12 @@ HRESULT WrappedID3D12GraphicsCommandList::Close() HRESULT WrappedID3D12GraphicsCommandList::Reset(ID3D12CommandAllocator *pAllocator, ID3D12PipelineState *pInitialState) { - return m_pReal->Reset(pAllocator, pInitialState); + return m_pReal->Reset(Unwrap(pAllocator), Unwrap(pInitialState)); } void WrappedID3D12GraphicsCommandList::ClearState(ID3D12PipelineState *pPipelineState) { - m_pReal->ClearState(pPipelineState); + m_pReal->ClearState(Unwrap(pPipelineState)); } void WrappedID3D12GraphicsCommandList::DrawInstanced(UINT VertexCountPerInstance, @@ -130,7 +130,7 @@ void WrappedID3D12GraphicsCommandList::OMSetStencilRef(UINT StencilRef) void WrappedID3D12GraphicsCommandList::SetPipelineState(ID3D12PipelineState *pPipelineState) { - m_pReal->SetPipelineState(pPipelineState); + m_pReal->SetPipelineState(Unwrap(pPipelineState)); } void WrappedID3D12GraphicsCommandList::ResourceBarrier(UINT NumBarriers, diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index 1f415c079..0763edc35 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -103,6 +103,8 @@ WrappedID3D12CommandQueue::WrappedID3D12CommandQueue(ID3D12CommandQueue *real, m_pSerialiser->SetDebugText(true); } + m_pSerialiser->SetUserData(m_pDevice->GetResourceManager()); + // create a temporary and grab its resource ID m_ResourceID = ResourceIDGen::GetNewUniqueID(); @@ -191,6 +193,8 @@ WrappedID3D12GraphicsCommandList::WrappedID3D12GraphicsCommandList(ID3D12Graphic m_pSerialiser->SetDebugText(true); } + m_pSerialiser->SetUserData(m_pDevice->GetResourceManager()); + // create a temporary and grab its resource ID m_ResourceID = ResourceIDGen::GetNewUniqueID(); diff --git a/renderdoc/driver/d3d12/d3d12_common.cpp b/renderdoc/driver/d3d12/d3d12_common.cpp index 5e355b30c..53d2c3edc 100644 --- a/renderdoc/driver/d3d12/d3d12_common.cpp +++ b/renderdoc/driver/d3d12/d3d12_common.cpp @@ -24,6 +24,22 @@ #include "d3d12_common.h" #include "driver/dxgi/dxgi_wrapped.h" +#include "d3d12_manager.h" +#include "d3d12_resources.h" + +// we know the object will be a non-dispatchable object type +#define SerialiseObject(type, name, obj) \ + { \ + D3D12ResourceManager *rm = (D3D12ResourceManager *)GetUserData(); \ + ResourceId id; \ + if(m_Mode >= WRITING) \ + id = GetResID(obj); \ + Serialise(name, id); \ + if(m_Mode < WRITING) \ + obj = (id == ResourceId() || !rm->HasLiveResource(id)) \ + ? NULL \ + : Unwrap((type *)rm->GetLiveResource(id)); \ + } template <> void Serialiser::Serialise(const char *name, D3D12_RESOURCE_DESC &el) @@ -53,6 +69,462 @@ void Serialiser::Serialise(const char *name, D3D12_COMMAND_QUEUE_DESC &el) Serialise("NodeMask", el.NodeMask); } +template <> +void Serialiser::Serialise(const char *name, D3D12_SHADER_BYTECODE &el) +{ + ScopedContext scope(this, name, "D3D12_SHADER_BYTECODE", 0, true); + + uint64_t dataSize = el.BytecodeLength; + Serialise("BytecodeLength", dataSize); + size_t sz = (size_t)dataSize; + if(m_Mode == READING) + { + el.pShaderBytecode = NULL; + el.BytecodeLength = sz; + } + SerialiseBuffer("pShaderBytecode", (byte *&)el.pShaderBytecode, sz); +} + +template <> +void Serialiser::Deserialise(const D3D12_SHADER_BYTECODE *const el) const +{ + if(m_Mode == READING) + delete[](byte *)(el->pShaderBytecode); +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_SO_DECLARATION_ENTRY &el) +{ + ScopedContext scope(this, name, "D3D12_SO_DECLARATION_ENTRY", 0, true); + + Serialise("Stream", el.Stream); + + { + string s = ""; + if(m_Mode == WRITING && el.SemanticName) + s = el.SemanticName; + + Serialise("SemanticName", s); + + if(m_Mode == READING) + { + m_StringDB.insert(s); + el.SemanticName = m_StringDB.find(s)->c_str(); + } + } + + Serialise("SemanticIndex", el.SemanticIndex); + Serialise("StartComponent", el.StartComponent); + Serialise("ComponentCount", el.ComponentCount); + Serialise("OutputSlot", el.OutputSlot); +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_STREAM_OUTPUT_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_STREAM_OUTPUT_DESC", 0, true); + + if(m_Mode == READING) + { + el.pSODeclaration = NULL; + el.pBufferStrides = NULL; + } + + SerialiseComplexArray("pSODeclaration", (D3D12_SO_DECLARATION_ENTRY *&)el.pSODeclaration, + el.NumEntries); + SerialisePODArray("pBufferStrides", (UINT *&)el.pBufferStrides, el.NumStrides); + Serialise("RasterizedStream", el.RasterizedStream); +} + +template <> +void Serialiser::Deserialise(const D3D12_STREAM_OUTPUT_DESC *const el) const +{ + if(m_Mode == READING) + { + delete[] el->pSODeclaration; + delete[] el->pBufferStrides; + } +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_RENDER_TARGET_BLEND_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_RENDER_TARGET_BLEND_DESC", 0, true); + + Serialise("BlendEnable", el.BlendEnable); + Serialise("LogicOpEnable", el.LogicOpEnable); + Serialise("SrcBlend", el.SrcBlend); + Serialise("DestBlend", el.DestBlend); + Serialise("BlendOp", el.BlendOp); + Serialise("SrcBlendAlpha", el.SrcBlendAlpha); + Serialise("DestBlendAlpha", el.DestBlendAlpha); + Serialise("BlendOpAlpha", el.BlendOpAlpha); + Serialise("LogicOp", el.LogicOp); + Serialise("RenderTargetWriteMask", el.RenderTargetWriteMask); +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_BLEND_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_BLEND_DESC", 0, true); + + Serialise("AlphaToCoverageEnable", el.AlphaToCoverageEnable); + Serialise("IndependentBlendEnable", el.IndependentBlendEnable); + for(int i = 0; i < 8; i++) + { + ScopedContext targetscope(this, name, "D3D11_RENDER_TARGET_BLEND_DESC", 0, true); + + bool enable = el.RenderTarget[i].BlendEnable == TRUE; + Serialise("BlendEnable", enable); + el.RenderTarget[i].BlendEnable = enable; + + enable = el.RenderTarget[i].LogicOpEnable == TRUE; + Serialise("LogicOpEnable", enable); + el.RenderTarget[i].LogicOpEnable = enable; + + Serialise("SrcBlend", el.RenderTarget[i].SrcBlend); + Serialise("DestBlend", el.RenderTarget[i].DestBlend); + Serialise("BlendOp", el.RenderTarget[i].BlendOp); + Serialise("SrcBlendAlpha", el.RenderTarget[i].SrcBlendAlpha); + Serialise("DestBlendAlpha", el.RenderTarget[i].DestBlendAlpha); + Serialise("BlendOpAlpha", el.RenderTarget[i].BlendOpAlpha); + Serialise("LogicOp", el.RenderTarget[i].LogicOp); + Serialise("RenderTargetWriteMask", el.RenderTarget[i].RenderTargetWriteMask); + } +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_RASTERIZER_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_RASTERIZER_DESC", 0, true); + + Serialise("FillMode", el.FillMode); + Serialise("CullMode", el.CullMode); + Serialise("FrontCounterClockwise", el.FrontCounterClockwise); + Serialise("DepthBias", el.DepthBias); + Serialise("DepthBiasClamp", el.DepthBiasClamp); + Serialise("SlopeScaledDepthBias", el.SlopeScaledDepthBias); + Serialise("DepthClipEnable", el.DepthClipEnable); + Serialise("MultisampleEnable", el.MultisampleEnable); + Serialise("AntialiasedLineEnable", el.AntialiasedLineEnable); + Serialise("ForcedSampleCount", el.ForcedSampleCount); + Serialise("ConservativeRaster", el.ConservativeRaster); +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_DEPTH_STENCILOP_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_DEPTH_STENCILOP_DESC", 0, true); + + Serialise("StencilFailOp", el.StencilFailOp); + Serialise("StencilDepthFailOp", el.StencilDepthFailOp); + Serialise("StencilPassOp", el.StencilPassOp); + Serialise("StencilFunc", el.StencilFunc); +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_DEPTH_STENCIL_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_DEPTH_STENCIL_DESC", 0, true); + + Serialise("DepthEnable", el.DepthEnable); + Serialise("DepthWriteMask", el.DepthWriteMask); + Serialise("DepthFunc", el.DepthFunc); + Serialise("StencilEnable", el.StencilEnable); + Serialise("StencilReadMask", el.StencilReadMask); + Serialise("StencilWriteMask", el.StencilWriteMask); + Serialise("FrontFace", el.FrontFace); + Serialise("BackFace", el.BackFace); +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_INPUT_ELEMENT_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_INPUT_ELEMENT_DESC", 0, true); + + { + string s = ""; + if(m_Mode == WRITING && el.SemanticName) + s = el.SemanticName; + + Serialise("SemanticName", s); + + if(m_Mode == READING) + { + m_StringDB.insert(s); + el.SemanticName = m_StringDB.find(s)->c_str(); + } + } + + Serialise("SemanticIndex", el.SemanticIndex); + Serialise("Format", el.Format); + Serialise("InputSlot", el.InputSlot); + Serialise("AlignedByteOffset", el.AlignedByteOffset); + Serialise("InputSlotClass", el.InputSlotClass); + Serialise("InstanceDataStepRate", el.InstanceDataStepRate); +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_INPUT_LAYOUT_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_INPUT_LAYOUT_DESC", 0, true); + + SerialiseComplexArray("pInputElementDescs", (D3D12_INPUT_ELEMENT_DESC *&)el.pInputElementDescs, + el.NumElements); +} + +template <> +void Serialiser::Deserialise(const D3D12_INPUT_LAYOUT_DESC *const el) const +{ + if(m_Mode == READING) + delete[] el->pInputElementDescs; +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_GRAPHICS_PIPELINE_STATE_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_GRAPHICS_PIPELINE_STATE_DESC", 0, true); + + SerialiseObject(ID3D12RootSignature, "pRootSignature", el.pRootSignature); + Serialise("VS", el.VS); + Serialise("PS", el.PS); + Serialise("DS", el.DS); + Serialise("HS", el.HS); + Serialise("GS", el.GS); + Serialise("StreamOutput", el.StreamOutput); + Serialise("BlendState", el.BlendState); + Serialise("SampleMask", el.SampleMask); + Serialise("RasterizerState", el.RasterizerState); + Serialise("DepthStencilState", el.DepthStencilState); + Serialise("InputLayout", el.InputLayout); + Serialise("IBStripCutValue", el.IBStripCutValue); + Serialise("PrimitiveTopologyType", el.PrimitiveTopologyType); + Serialise("NumRenderTargets", el.NumRenderTargets); + SerialisePODArray<8>("RTVFormats", el.RTVFormats); + Serialise("DSVFormat", el.DSVFormat); + Serialise("SampleDesc", el.SampleDesc); + Serialise("NodeMask", el.NodeMask); + Serialise("Flags", el.Flags); + + if(m_Mode == READING) + { + el.CachedPSO.CachedBlobSizeInBytes = 0; + el.CachedPSO.pCachedBlob = NULL; + } +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_COMPUTE_PIPELINE_STATE_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_COMPUTE_PIPELINE_STATE_DESC", 0, true); + + SerialiseObject(ID3D12RootSignature, "pRootSignature", el.pRootSignature); + Serialise("CS", el.CS); + Serialise("NodeMask", el.NodeMask); + Serialise("Flags", el.Flags); + + if(m_Mode == READING) + { + el.CachedPSO.CachedBlobSizeInBytes = 0; + el.CachedPSO.pCachedBlob = NULL; + } +} + +string ToStrHelper::Get(const D3D12_BLEND &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_BLEND_ZERO) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_ONE) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_SRC_COLOR) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_INV_SRC_COLOR) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_SRC_ALPHA) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_INV_SRC_ALPHA) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_DEST_ALPHA) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_INV_DEST_ALPHA) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_DEST_COLOR) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_INV_DEST_COLOR) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_SRC_ALPHA_SAT) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_BLEND_FACTOR) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_INV_BLEND_FACTOR) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_SRC1_COLOR) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_INV_SRC1_COLOR) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_SRC1_ALPHA) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_INV_SRC1_ALPHA) + default: break; + } + + return StringFormat::Fmt("D3D12_BLEND<%d>", el); +} + +string ToStrHelper::Get(const D3D12_BLEND_OP &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_BLEND_OP_ADD) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_OP_SUBTRACT) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_OP_REV_SUBTRACT) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_OP_MIN) + TOSTR_CASE_STRINGIZE(D3D12_BLEND_OP_MAX) + default: break; + } + + return StringFormat::Fmt("D3D12_BLEND_OP<%d>", el); +} + +string ToStrHelper::Get(const D3D12_LOGIC_OP &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_CLEAR) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_SET) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_COPY) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_COPY_INVERTED) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_NOOP) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_INVERT) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_AND) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_NAND) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_OR) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_NOR) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_XOR) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_EQUIV) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_AND_REVERSE) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_AND_INVERTED) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_OR_REVERSE) + TOSTR_CASE_STRINGIZE(D3D12_LOGIC_OP_OR_INVERTED) + default: break; + } + + return StringFormat::Fmt("D3D12_LOGIC_OP<%d>", el); +} + +string ToStrHelper::Get(const D3D12_FILL_MODE &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_FILL_MODE_WIREFRAME) + TOSTR_CASE_STRINGIZE(D3D12_FILL_MODE_SOLID) + default: break; + } + + return StringFormat::Fmt("D3D12_FILL_MODE<%d>", el); +} + +string ToStrHelper::Get(const D3D12_CULL_MODE &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_CULL_MODE_NONE) + TOSTR_CASE_STRINGIZE(D3D12_CULL_MODE_FRONT) + TOSTR_CASE_STRINGIZE(D3D12_CULL_MODE_BACK) + default: break; + } + + return StringFormat::Fmt("D3D12_CULL_MODE<%d>", el); +} + +string ToStrHelper::Get( + const D3D12_CONSERVATIVE_RASTERIZATION_MODE &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF) + TOSTR_CASE_STRINGIZE(D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON) + default: break; + } + + return StringFormat::Fmt("D3D12_CONSERVATIVE_RASTERIZATION_MODE<%d>", el); +} + +string ToStrHelper::Get(const D3D12_COMPARISON_FUNC &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_COMPARISON_FUNC_NEVER) + TOSTR_CASE_STRINGIZE(D3D12_COMPARISON_FUNC_LESS) + TOSTR_CASE_STRINGIZE(D3D12_COMPARISON_FUNC_EQUAL) + TOSTR_CASE_STRINGIZE(D3D12_COMPARISON_FUNC_LESS_EQUAL) + TOSTR_CASE_STRINGIZE(D3D12_COMPARISON_FUNC_GREATER) + TOSTR_CASE_STRINGIZE(D3D12_COMPARISON_FUNC_NOT_EQUAL) + TOSTR_CASE_STRINGIZE(D3D12_COMPARISON_FUNC_GREATER_EQUAL) + TOSTR_CASE_STRINGIZE(D3D12_COMPARISON_FUNC_ALWAYS) + default: break; + } + + return StringFormat::Fmt("D3D12_COMPARISON_FUNC<%d>", el); +} + +string ToStrHelper::Get(const D3D12_DEPTH_WRITE_MASK &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_DEPTH_WRITE_MASK_ZERO) + TOSTR_CASE_STRINGIZE(D3D12_DEPTH_WRITE_MASK_ALL) + default: break; + } + + return StringFormat::Fmt("D3D12_DEPTH_WRITE_MASK<%d>", el); +} + +string ToStrHelper::Get(const D3D12_STENCIL_OP &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_STENCIL_OP_KEEP) + TOSTR_CASE_STRINGIZE(D3D12_STENCIL_OP_ZERO) + TOSTR_CASE_STRINGIZE(D3D12_STENCIL_OP_REPLACE) + TOSTR_CASE_STRINGIZE(D3D12_STENCIL_OP_INCR_SAT) + TOSTR_CASE_STRINGIZE(D3D12_STENCIL_OP_DECR_SAT) + TOSTR_CASE_STRINGIZE(D3D12_STENCIL_OP_INVERT) + TOSTR_CASE_STRINGIZE(D3D12_STENCIL_OP_INCR) + TOSTR_CASE_STRINGIZE(D3D12_STENCIL_OP_DECR) + default: break; + } + + return StringFormat::Fmt("D3D12_STENCIL_OP<%d>", el); +} + +string ToStrHelper::Get(const D3D12_INPUT_CLASSIFICATION &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA) + TOSTR_CASE_STRINGIZE(D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA) + default: break; + } + + return StringFormat::Fmt("D3D12_INPUT_CLASSIFICATION<%d>", el); +} + +string ToStrHelper::Get( + const D3D12_INDEX_BUFFER_STRIP_CUT_VALUE &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED) + TOSTR_CASE_STRINGIZE(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF) + TOSTR_CASE_STRINGIZE(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF) + default: break; + } + + return StringFormat::Fmt("D3D12_INDEX_BUFFER_STRIP_CUT_VALUE<%d>", el); +} + +string ToStrHelper::Get(const D3D12_PRIMITIVE_TOPOLOGY_TYPE &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED) + TOSTR_CASE_STRINGIZE(D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT) + TOSTR_CASE_STRINGIZE(D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE) + TOSTR_CASE_STRINGIZE(D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE) + TOSTR_CASE_STRINGIZE(D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH) + default: break; + } + + return StringFormat::Fmt("D3D12_PRIMITIVE_TOPOLOGY_TYPE<%d>", el); +} + string ToStrHelper::Get(const D3D12_COMMAND_LIST_TYPE &el) { switch(el) @@ -96,6 +568,19 @@ string ToStrHelper::Get(const D3D12_TEXTURE_LAYOUT return StringFormat::Fmt("D3D12_TEXTURE_LAYOUT<%d>", el); } +string ToStrHelper::Get(const D3D12_PIPELINE_STATE_FLAGS &el) +{ + string ret; + + if(el & D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG) + ret += " | D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG"; + + if(!ret.empty()) + ret = ret.substr(3); + + return ret; +} + string ToStrHelper::Get(const D3D12_RESOURCE_FLAGS &el) { string ret; diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index b9b07b256..092ffbe89 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -112,34 +112,49 @@ template <> void Serialiser::Serialise(const char *name, D3D12_RESOURCE_DESC &el); template <> void Serialiser::Serialise(const char *name, D3D12_COMMAND_QUEUE_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D12_SHADER_BYTECODE &el); +template <> +void Serialiser::Serialise(const char *name, D3D12_GRAPHICS_PIPELINE_STATE_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D12_COMPUTE_PIPELINE_STATE_DESC &el); #pragma region Chunks +#define D3D12_CHUNKS \ + D3D12_CHUNK_MACRO(DEVICE_INIT = FIRST_CHUNK_ID, "ID3D12Device::Initialisation") \ + D3D12_CHUNK_MACRO(SET_RESOURCE_NAME, "ID3D12Object::SetName") \ + D3D12_CHUNK_MACRO(RELEASE_RESOURCE, "IUnknown::Release") \ + D3D12_CHUNK_MACRO(CREATE_SWAP_BUFFER, "IDXGISwapChain::GetBuffer") \ + \ + D3D12_CHUNK_MACRO(CAPTURE_SCOPE, "Capture") \ + \ + D3D12_CHUNK_MACRO(PUSH_EVENT, "BeginEvent") \ + D3D12_CHUNK_MACRO(SET_MARKER, "SetMarker") \ + D3D12_CHUNK_MACRO(POP_EVENT, "EndEvent") \ + \ + D3D12_CHUNK_MACRO(DEBUG_MESSAGES, "DebugMessageList") \ + \ + D3D12_CHUNK_MACRO(CONTEXT_CAPTURE_HEADER, "ContextBegin") \ + D3D12_CHUNK_MACRO(CONTEXT_CAPTURE_FOOTER, "ContextEnd") \ + \ + D3D12_CHUNK_MACRO(SET_SHADER_DEBUG_PATH, "SetShaderDebugPath") \ + \ + D3D12_CHUNK_MACRO(CREATE_COMMAND_QUEUE, "WrappedID3D12Device::CreateCommandQueue") \ + D3D12_CHUNK_MACRO(CREATE_COMMAND_ALLOCATOR, "WrappedID3D12Device::CreateCommandAllocator") \ + D3D12_CHUNK_MACRO(CREATE_COMMAND_LIST, "WrappedID3D12Device::CreateCommandList") \ + \ + D3D12_CHUNK_MACRO(CREATE_GRAPHICS_PIPE, "WrappedID3D12Device::CreateGraphicsPipeline") \ + D3D12_CHUNK_MACRO(CREATE_COMPUTE_PIPE, "WrappedID3D12Device::CreateComputePipeline") \ + \ + D3D12_CHUNK_MACRO(NUM_D3D12_CHUNKS, "") + enum D3D12ChunkType { - DEVICE_INIT = FIRST_CHUNK_ID, - SET_RESOURCE_NAME, - RELEASE_RESOURCE, - CREATE_SWAP_BUFFER, +#undef D3D12_CHUNK_MACRO +#define D3D12_CHUNK_MACRO(enum, string) enum, - CAPTURE_SCOPE, - - PUSH_EVENT, - SET_MARKER, - POP_EVENT, - - DEBUG_MESSAGES, - - CONTEXT_CAPTURE_HEADER, // chunk at beginning of context's chunk stream - CONTEXT_CAPTURE_FOOTER, // chunk at end of context's chunk stream - - SET_SHADER_DEBUG_PATH, - - CREATE_COMMAND_QUEUE, - CREATE_COMMAND_ALLOCATOR, - CREATE_COMMAND_LIST, - - NUM_D3D12_CHUNKS, + D3D12_CHUNKS }; #pragma endregion Chunks diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 50e2981c5..70a4d12df 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -36,28 +36,10 @@ WRAPPED_POOL_INST(WrappedID3D12Device); const char *D3D12ChunkNames[] = { - "ID3D12Device::Initialisation", - "ID3D12Object::SetName", - "IUnknown::Release", - "IDXGISwapChain::GetBuffer", +#undef D3D12_CHUNK_MACRO +#define D3D12_CHUNK_MACRO(enum, string) string, - "Capture", - - "BeginEvent", - "SetMarker", - "EndEvent", - - "DebugMessageList", - - "ContextBegin", - "ContextEnd", - - "SetShaderDebugPath", - - "WrappedID3D12Device::CreateCommandQueue", - "WrappedID3D12Device::CreateCommandAllocator", - "WrappedID3D12Device::CreateCommandList", -}; + D3D12_CHUNKS}; D3D12InitParams::D3D12InitParams() { @@ -210,6 +192,8 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara m_ResourceManager = new D3D12ResourceManager(m_State, m_pSerialiser, this); + m_pSerialiser->SetUserData(m_ResourceManager); + if(m_pSerialiser) m_pSerialiser->SetChunkNameLookup(&GetChunkName); @@ -269,7 +253,7 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara ////////////////////////////////////////////////////////////////////////// // Compile time asserts - RDCCOMPILE_ASSERT(ARRAY_COUNT(D3D12ChunkNames) == NUM_D3D12_CHUNKS - FIRST_CHUNK_ID, + RDCCOMPILE_ASSERT(ARRAY_COUNT(D3D12ChunkNames) == NUM_D3D12_CHUNKS - FIRST_CHUNK_ID + 1, "Not right number of chunk names"); } diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp index d0450d45c..324556c6e 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp @@ -87,10 +87,64 @@ HRESULT WrappedID3D12Device::CreateCommandQueue(const D3D12_COMMAND_QUEUE_DESC * return ret; } +bool WrappedID3D12Device::Serialise_CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type, + REFIID riid, void **ppCommandAllocator) +{ + SERIALISE_ELEMENT(D3D12_COMMAND_LIST_TYPE, ListType, type); + SERIALISE_ELEMENT(IID, guid, riid); + SERIALISE_ELEMENT(ResourceId, Alloc, + ((WrappedID3D12CommandAllocator *)*ppCommandAllocator)->GetResourceID()); + + if(m_State == READING) + { + ID3D12CommandAllocator *ret = NULL; + HRESULT hr = m_pDevice->CreateCommandAllocator(ListType, guid, (void **)&ret); + + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D12CommandAllocator(ret, this); + + GetResourceManager()->AddLiveResource(Alloc, ret); + } + } + + return true; +} + HRESULT WrappedID3D12Device::CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type, REFIID riid, void **ppCommandAllocator) { - return m_pDevice->CreateCommandAllocator(type, riid, ppCommandAllocator); + if(ppCommandAllocator == NULL) + return m_pDevice->CreateCommandAllocator(type, riid, NULL); + + if(riid != __uuidof(ID3D12CommandAllocator)) + return E_NOINTERFACE; + + ID3D12CommandAllocator *real = NULL; + HRESULT ret = m_pDevice->CreateCommandAllocator(type, riid, (void **)&real); + + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); + + WrappedID3D12CommandAllocator *wrapped = new WrappedID3D12CommandAllocator(real, this); + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_COMMAND_ALLOCATOR); + Serialise_CreateCommandAllocator(type, riid, (void **)&wrapped); + + m_DeviceRecord->AddChunk(scope.Get()); + } + + *ppCommandAllocator = (ID3D12CommandAllocator *)wrapped; + } + + return ret; } bool WrappedID3D12Device::Serialise_CreateCommandList(UINT nodeMask, D3D12_COMMAND_LIST_TYPE type, @@ -136,14 +190,15 @@ HRESULT WrappedID3D12Device::CreateCommandList(UINT nodeMask, D3D12_COMMAND_LIST void **ppCommandList) { if(ppCommandList == NULL) - return m_pDevice->CreateCommandList(nodeMask, type, pCommandAllocator, pInitialState, riid, NULL); + return m_pDevice->CreateCommandList(nodeMask, type, Unwrap(pCommandAllocator), pInitialState, + riid, NULL); if(riid != __uuidof(ID3D12GraphicsCommandList)) return E_NOINTERFACE; ID3D12GraphicsCommandList *real = NULL; - HRESULT ret = m_pDevice->CreateCommandList(nodeMask, type, pCommandAllocator, pInitialState, riid, - (void **)&real); + HRESULT ret = m_pDevice->CreateCommandList(nodeMask, type, Unwrap(pCommandAllocator), + pInitialState, riid, (void **)&real); if(SUCCEEDED(ret)) { @@ -167,16 +222,124 @@ HRESULT WrappedID3D12Device::CreateCommandList(UINT nodeMask, D3D12_COMMAND_LIST return ret; } +bool WrappedID3D12Device::Serialise_CreateGraphicsPipelineState( + const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, REFIID riid, void **ppPipelineState) +{ + SERIALISE_ELEMENT_PTR(D3D12_GRAPHICS_PIPELINE_STATE_DESC, Descriptor, pDesc); + SERIALISE_ELEMENT(IID, guid, riid); + SERIALISE_ELEMENT(ResourceId, Queue, + ((WrappedID3D12PipelineState *)*ppPipelineState)->GetResourceID()); + + if(m_State == READING) + { + ID3D12PipelineState *ret = NULL; + HRESULT hr = m_pDevice->CreateGraphicsPipelineState(&Descriptor, guid, (void **)&ret); + + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D12PipelineState(ret, this); + + GetResourceManager()->AddLiveResource(Queue, ret); + } + } + + return true; +} + HRESULT WrappedID3D12Device::CreateGraphicsPipelineState(const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, REFIID riid, void **ppPipelineState) { - return m_pDevice->CreateGraphicsPipelineState(pDesc, riid, ppPipelineState); + if(ppPipelineState == NULL) + return m_pDevice->CreateGraphicsPipelineState(pDesc, riid, NULL); + + if(riid != __uuidof(ID3D12PipelineState)) + return E_NOINTERFACE; + + ID3D12PipelineState *real = NULL; + HRESULT ret = m_pDevice->CreateGraphicsPipelineState(pDesc, riid, (void **)&real); + + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); + + WrappedID3D12PipelineState *wrapped = new WrappedID3D12PipelineState(real, this); + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_GRAPHICS_PIPE); + Serialise_CreateGraphicsPipelineState(pDesc, riid, (void **)&wrapped); + + m_DeviceRecord->AddChunk(scope.Get()); + } + + *ppPipelineState = (ID3D12PipelineState *)wrapped; + } + + return ret; +} + +bool WrappedID3D12Device::Serialise_CreateComputePipelineState( + const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, REFIID riid, void **ppPipelineState) +{ + SERIALISE_ELEMENT_PTR(D3D12_COMPUTE_PIPELINE_STATE_DESC, Descriptor, pDesc); + SERIALISE_ELEMENT(IID, guid, riid); + SERIALISE_ELEMENT(ResourceId, Queue, + ((WrappedID3D12PipelineState *)*ppPipelineState)->GetResourceID()); + + if(m_State == READING) + { + ID3D12PipelineState *ret = NULL; + HRESULT hr = m_pDevice->CreateComputePipelineState(&Descriptor, guid, (void **)&ret); + + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D12PipelineState(ret, this); + + GetResourceManager()->AddLiveResource(Queue, ret); + } + } + + return true; } HRESULT WrappedID3D12Device::CreateComputePipelineState(const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, REFIID riid, void **ppPipelineState) { - return m_pDevice->CreateComputePipelineState(pDesc, riid, ppPipelineState); + if(ppPipelineState == NULL) + return m_pDevice->CreateComputePipelineState(pDesc, riid, NULL); + + if(riid != __uuidof(ID3D12PipelineState)) + return E_NOINTERFACE; + + ID3D12PipelineState *real = NULL; + HRESULT ret = m_pDevice->CreateComputePipelineState(pDesc, riid, (void **)&real); + + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); + + WrappedID3D12PipelineState *wrapped = new WrappedID3D12PipelineState(real, this); + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_COMPUTE_PIPE); + Serialise_CreateComputePipelineState(pDesc, riid, (void **)&wrapped); + + m_DeviceRecord->AddChunk(scope.Get()); + } + + *ppPipelineState = (ID3D12PipelineState *)wrapped; + } + + return ret; } HRESULT WrappedID3D12Device::CreateDescriptorHeap(const D3D12_DESCRIPTOR_HEAP_DESC *pDescriptorHeapDesc,