From 97e36a8defe2d104c9c13740a3cac8b349256561 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 7 Jul 2016 17:03:04 +0300 Subject: [PATCH] Track initial contents, with things treated as default dirty. * For now, only descriptor heap initial contents are tracked. --- renderdoc/driver/d3d11/d3d11_common.cpp | 18 +- .../driver/d3d12/d3d12_command_list_wrap.cpp | 1 + renderdoc/driver/d3d12/d3d12_commands.cpp | 2 + renderdoc/driver/d3d12/d3d12_common.cpp | 618 +++++++++++++++++- renderdoc/driver/d3d12/d3d12_common.h | 16 + renderdoc/driver/d3d12/d3d12_device.cpp | 2 + renderdoc/driver/d3d12/d3d12_device_wrap.cpp | 23 + renderdoc/driver/d3d12/d3d12_manager.cpp | 183 +++++- renderdoc/driver/d3d12/d3d12_manager.h | 24 +- renderdoc/driver/d3d12/d3d12_resources.cpp | 7 +- renderdoc/driver/d3d12/d3d12_resources.h | 51 +- 11 files changed, 874 insertions(+), 71 deletions(-) diff --git a/renderdoc/driver/d3d11/d3d11_common.cpp b/renderdoc/driver/d3d11/d3d11_common.cpp index f14085bc8..b74af6771 100644 --- a/renderdoc/driver/d3d11/d3d11_common.cpp +++ b/renderdoc/driver/d3d11/d3d11_common.cpp @@ -1281,17 +1281,17 @@ string ToStrHelper::Get(const D3D11_FILTER &el) case D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT: return "MIN_MAG_LINEAR_MIP_POINT"; case D3D11_FILTER_MIN_MAG_MIP_LINEAR: return "MIN_MAG_MIP_LINEAR"; case D3D11_FILTER_ANISOTROPIC: return "ANISOTROPIC"; - case D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT: return "CMP_MIN_MAG_MIP_POINT"; - case D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR: return "CMP_MIN_MAG_POINT_MIP_LINEAR"; + case D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT: return "CMP:MIN_MAG_MIP_POINT"; + case D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR: return "CMP:MIN_MAG_POINT_MIP_LINEAR"; case D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT: - return "CMP_MIN_POINT_MAG_LINEAR_MIP_POINT"; - case D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR: return "CMP_MIN_POINT_MAG_MIP_LINEAR"; - case D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT: return "CMP_MIN_LINEAR_MAG_MIP_POINT"; + return "CMP:MIN_POINT_MAG_LINEAR_MIP_POINT"; + case D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR: return "CMP:MIN_POINT_MAG_MIP_LINEAR"; + case D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT: return "CMP:MIN_LINEAR_MAG_MIP_POINT"; case D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR: - return "CMP_MIN_LINEAR_MAG_POINT_MIP_LINEAR"; - case D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT: return "CMP_MIN_MAG_LINEAR_MIP_POINT"; - case D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR: return "CMP_MIN_MAG_MIP_LINEAR"; - case D3D11_FILTER_COMPARISON_ANISOTROPIC: return "CMP_ANISOTROPIC"; + return "CMP:MIN_LINEAR_MAG_POINT_MIP_LINEAR"; + case D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT: return "CMP:MIN_MAG_LINEAR_MIP_POINT"; + case D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR: return "CMP:MIN_MAG_MIP_LINEAR"; + case D3D11_FILTER_COMPARISON_ANISOTROPIC: return "CMP:ANISOTROPIC"; default: break; } diff --git a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp index 17553d7b6..e07625f7b 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp @@ -105,6 +105,7 @@ HRESULT WrappedID3D12GraphicsCommandList::Reset(ID3D12CommandAllocator *pAllocat m_ListRecord->bakedCommands = GetResourceManager()->AddResourceRecord(ResourceIDGen::GetNewUniqueID()); + m_ListRecord->bakedCommands->type = Resource_GraphicsCommandList; m_ListRecord->bakedCommands->SpecialResource = true; m_ListRecord->bakedCommands->cmdInfo = new CmdListRecordingInfo(); diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index 5e424e50f..e875685bc 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -165,6 +165,7 @@ WrappedID3D12CommandQueue::WrappedID3D12CommandQueue(ID3D12CommandQueue *real, if(!RenderDoc::Inst().IsReplayApp()) { m_QueueRecord = m_pDevice->GetResourceManager()->AddResourceRecord(m_ResourceID); + m_QueueRecord->type = Resource_CommandQueue; m_QueueRecord->DataInSerialiser = false; m_QueueRecord->SpecialResource = true; m_QueueRecord->Length = 0; @@ -260,6 +261,7 @@ WrappedID3D12GraphicsCommandList::WrappedID3D12GraphicsCommandList(ID3D12Graphic if(!RenderDoc::Inst().IsReplayApp()) { m_ListRecord = m_pDevice->GetResourceManager()->AddResourceRecord(m_ResourceID); + m_ListRecord->type = Resource_GraphicsCommandList; m_ListRecord->DataInSerialiser = false; m_ListRecord->SpecialResource = true; m_ListRecord->Length = 0; diff --git a/renderdoc/driver/d3d12/d3d12_common.cpp b/renderdoc/driver/d3d12/d3d12_common.cpp index f7b2897cd..3638f9bbc 100644 --- a/renderdoc/driver/d3d12/d3d12_common.cpp +++ b/renderdoc/driver/d3d12/d3d12_common.cpp @@ -41,20 +41,122 @@ string ToStrHelper::Get(const D3D12Resou return ToStr::Get(uint32_t(el)); } -// 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)); \ +enum D3D12ComponentMapping +{ +}; + +string ToStrHelper::Get(const D3D12ComponentMapping &el) +{ + string ret; + + uint32_t swizzle = (uint32_t)el; + + uint32_t shift = 0; + uint32_t mask = D3D12_SHADER_COMPONENT_MAPPING_MASK; + for(int i = 0; i < 4; i++) + { + // value should always be <= 5, see D3D12_SHADER_COMPONENT_MAPPING + char mapping[] = {'R', 'G', 'B', 'A', '0', '1', '?', '?'}; + + ret += mapping[(swizzle & mask) >> shift]; + + shift += D3D12_SHADER_COMPONENT_MAPPING_SHIFT; + mask <<= D3D12_SHADER_COMPONENT_MAPPING_SHIFT; } + return ret; +} + +#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(rm->GetLiveAs(id)); \ + } + +template <> +void Serialiser::Serialise(const char *name, D3D12Descriptor &el) +{ + ScopedContext scope(this, name, "D3D12Descriptor", 0, true); + + D3D12Descriptor::DescriptorType type = el.GetType(); + Serialise("type", type); + + // we serialise the heap by hand because we want to keep it wrapped + { + D3D12ResourceManager *rm = (D3D12ResourceManager *)GetUserData(); + + PortableHandle handle; + + if(m_Mode >= WRITING) + handle = PortableHandle(el.samp.heap->GetResourceID(), el.samp.idx); + + Serialise("handle", handle); + + if(m_Mode < WRITING) + { + el.samp.heap = (handle.heap == ResourceId() || !rm->HasLiveResource(handle.heap)) + ? NULL + : rm->GetLiveAs(handle.heap); + el.samp.idx = handle.index; + } + } + + switch(type) + { + case D3D12Descriptor::TypeSampler: + { + Serialise("Descriptor", el.samp.desc); + break; + } + case D3D12Descriptor::TypeCBV: + { + SerialiseObject(ID3D12Resource, "Resource", el.nonsamp.resource); + Serialise("Descriptor", el.nonsamp.cbv); + break; + } + case D3D12Descriptor::TypeSRV: + { + SerialiseObject(ID3D12Resource, "Resource", el.nonsamp.resource); + Serialise("Descriptor", el.nonsamp.srv); + break; + } + case D3D12Descriptor::TypeRTV: + { + SerialiseObject(ID3D12Resource, "Resource", el.nonsamp.resource); + Serialise("Descriptor", el.nonsamp.rtv); + break; + } + case D3D12Descriptor::TypeDSV: + { + SerialiseObject(ID3D12Resource, "Resource", el.nonsamp.resource); + Serialise("Descriptor", el.nonsamp.dsv); + break; + } + case D3D12Descriptor::TypeUAV: + { + SerialiseObject(ID3D12Resource, "Resource", el.nonsamp.resource); + SerialiseObject(ID3D12Resource, "CounterResource", el.nonsamp.uav.counterResource); + + // special case because of extra resource and squeezed descriptor + D3D12_UNORDERED_ACCESS_VIEW_DESC desc = el.nonsamp.uav.desc.AsDesc(); + Serialise("Descriptor", desc); + el.nonsamp.uav.desc.Init(desc); + break; + } + case D3D12Descriptor::TypeUndefined: + { + el.nonsamp.type = type; + break; + } + } +} + template <> void Serialiser::Serialise(const char *name, D3D12_RESOURCE_DESC &el) { @@ -186,7 +288,7 @@ void Serialiser::Serialise(const char *name, D3D12_BLEND_DESC &el) Serialise("IndependentBlendEnable", el.IndependentBlendEnable); for(int i = 0; i < 8; i++) { - ScopedContext targetscope(this, name, "D3D11_RENDER_TARGET_BLEND_DESC", 0, true); + ScopedContext targetscope(this, name, "D3D12_RENDER_TARGET_BLEND_DESC", 0, true); bool enable = el.RenderTarget[i].BlendEnable == TRUE; Serialise("BlendEnable", enable); @@ -398,6 +500,234 @@ void Serialiser::Serialise(const char *name, D3D12_INDEX_BUFFER_VIEW &el) Serialise("Format", el.Format); } +template <> +void Serialiser::Serialise(const char *name, D3D12_CONSTANT_BUFFER_VIEW_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_CONSTANT_BUFFER_VIEW_DESC", 0, true); + + D3D12ResourceManager *rm = (D3D12ResourceManager *)GetUserData(); + + ResourceId buffer; + + if(m_Mode == WRITING) + buffer = GetResID(el.BufferLocation); + + Serialise("BufferLocation", buffer); + + if(m_Mode == READING) + { + ID3D12Resource *res = rm->GetLiveAs(buffer); + if(res) + el.BufferLocation = Unwrap(res->GetGPUVirtualAddress()); + else + el.BufferLocation = 0; + } + + Serialise("SizeInBytes", el.SizeInBytes); +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_SHADER_RESOURCE_VIEW_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_SHADER_RESOURCE_VIEW_DESC", 0, true); + + Serialise("Format", el.Format); + Serialise("ViewDimension", el.ViewDimension); + // cast to a special enum so we print nicely + Serialise("Shader4ComponentMapping", (D3D12ComponentMapping &)el.Shader4ComponentMapping); + + switch(el.ViewDimension) + { + case D3D12_SRV_DIMENSION_BUFFER: + Serialise("Buffer.FirstElement", el.Buffer.FirstElement); + Serialise("Buffer.NumElements", el.Buffer.NumElements); + Serialise("Buffer.StructureByteStride", el.Buffer.StructureByteStride); + Serialise("Buffer.Flags", el.Buffer.Flags); + break; + case D3D12_SRV_DIMENSION_TEXTURE1D: + Serialise("Texture1D.MostDetailedMip", el.Texture1D.MostDetailedMip); + Serialise("Texture1D.MipLevels", el.Texture1D.MipLevels); + Serialise("Texture1D.ResourceMinLODClamp", el.Texture1D.ResourceMinLODClamp); + break; + case D3D12_SRV_DIMENSION_TEXTURE1DARRAY: + Serialise("Texture1DArray.MostDetailedMip", el.Texture1DArray.MostDetailedMip); + Serialise("Texture1DArray.MipLevels", el.Texture1DArray.MipLevels); + Serialise("Texture1DArray.FirstArraySlice", el.Texture1DArray.FirstArraySlice); + Serialise("Texture1DArray.ArraySize", el.Texture1DArray.ArraySize); + Serialise("Texture1DArray.ResourceMinLODClamp", el.Texture1DArray.ResourceMinLODClamp); + break; + case D3D12_SRV_DIMENSION_TEXTURE2D: + Serialise("Texture2D.MostDetailedMip", el.Texture2D.MostDetailedMip); + Serialise("Texture2D.MipLevels", el.Texture2D.MipLevels); + Serialise("Texture2D.PlaneSlice", el.Texture2D.PlaneSlice); + Serialise("Texture2D.ResourceMinLODClamp", el.Texture2D.ResourceMinLODClamp); + break; + case D3D12_SRV_DIMENSION_TEXTURE2DARRAY: + Serialise("Texture2DArray.MostDetailedMip", el.Texture2DArray.MostDetailedMip); + Serialise("Texture2DArray.MipLevels", el.Texture2DArray.MipLevels); + Serialise("Texture2DArray.FirstArraySlice", el.Texture2DArray.FirstArraySlice); + Serialise("Texture2DArray.ArraySize", el.Texture2DArray.ArraySize); + Serialise("Texture2DArray.PlaneSlice", el.Texture2DArray.PlaneSlice); + Serialise("Texture2DArray.ResourceMinLODClamp", el.Texture2DArray.ResourceMinLODClamp); + break; + case D3D12_SRV_DIMENSION_TEXTURE2DMS: + // el.Texture2DMS.UnusedField_NothingToDefine + break; + case D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY: + Serialise("Texture2DMSArray.FirstArraySlice", el.Texture2DMSArray.FirstArraySlice); + Serialise("Texture2DMSArray.ArraySize", el.Texture2DMSArray.ArraySize); + break; + case D3D12_SRV_DIMENSION_TEXTURE3D: + Serialise("Texture3D.MipLevels", el.Texture3D.MipLevels); + Serialise("Texture3D.MostDetailedMip", el.Texture3D.MostDetailedMip); + Serialise("Texture3D.ResourceMinLODClamp", el.Texture3D.ResourceMinLODClamp); + break; + case D3D12_SRV_DIMENSION_TEXTURECUBE: + Serialise("TextureCube.MostDetailedMip", el.TextureCube.MostDetailedMip); + Serialise("TextureCube.MipLevels", el.TextureCube.MipLevels); + Serialise("TextureCube.ResourceMinLODClamp", el.TextureCube.ResourceMinLODClamp); + break; + case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY: + Serialise("TextureCubeArray.MostDetailedMip", el.TextureCubeArray.MostDetailedMip); + Serialise("TextureCubeArray.MipLevels", el.TextureCubeArray.MipLevels); + Serialise("TextureCubeArray.First2DArrayFace", el.TextureCubeArray.First2DArrayFace); + Serialise("TextureCubeArray.NumCubes", el.TextureCubeArray.NumCubes); + Serialise("TextureCubeArray.ResourceMinLODClamp", el.TextureCubeArray.ResourceMinLODClamp); + break; + default: RDCERR("Unrecognised SRV Dimension %d", el.ViewDimension); break; + } +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_RENDER_TARGET_VIEW_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_RENDER_TARGET_VIEW_DESC", 0, true); + + Serialise("Format", el.Format); + Serialise("ViewDimension", el.ViewDimension); + + switch(el.ViewDimension) + { + case D3D12_RTV_DIMENSION_BUFFER: + Serialise("Buffer.FirstElement", el.Buffer.FirstElement); + Serialise("Buffer.NumElements", el.Buffer.NumElements); + break; + case D3D12_RTV_DIMENSION_TEXTURE1D: + Serialise("Texture1D.MipSlice", el.Texture1D.MipSlice); + break; + case D3D12_RTV_DIMENSION_TEXTURE1DARRAY: + Serialise("Texture1DArray.MipSlice", el.Texture1DArray.MipSlice); + Serialise("Texture1DArray.FirstArraySlice", el.Texture1DArray.FirstArraySlice); + Serialise("Texture1DArray.ArraySize", el.Texture1DArray.ArraySize); + break; + case D3D12_RTV_DIMENSION_TEXTURE2D: + Serialise("Texture2D.MipSlice", el.Texture2D.MipSlice); + Serialise("Texture2D.PlaneSlice", el.Texture2D.PlaneSlice); + break; + case D3D12_RTV_DIMENSION_TEXTURE2DARRAY: + Serialise("Texture2DArray.MipSlice", el.Texture2DArray.MipSlice); + Serialise("Texture2DArray.FirstArraySlice", el.Texture2DArray.FirstArraySlice); + Serialise("Texture2DArray.ArraySize", el.Texture2DArray.ArraySize); + Serialise("Texture2DArray.PlaneSlice", el.Texture2DArray.PlaneSlice); + break; + case D3D12_RTV_DIMENSION_TEXTURE2DMS: + // el.Texture2DMS.UnusedField_NothingToDefine + break; + case D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY: + Serialise("Texture2DMSArray.FirstArraySlice", el.Texture2DMSArray.FirstArraySlice); + Serialise("Texture2DMSArray.ArraySize", el.Texture2DMSArray.ArraySize); + break; + case D3D12_RTV_DIMENSION_TEXTURE3D: + Serialise("Texture3D.MipSlice", el.Texture3D.MipSlice); + Serialise("Texture3D.FirstWSlice", el.Texture3D.FirstWSlice); + Serialise("Texture3D.WSize", el.Texture3D.WSize); + break; + default: RDCERR("Unrecognised RTV Dimension %d", el.ViewDimension); break; + } +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_DEPTH_STENCIL_VIEW_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_DEPTH_STENCIL_VIEW_DESC", 0, true); + + Serialise("Format", el.Format); + Serialise("Flags", el.Flags); + Serialise("ViewDimension", el.ViewDimension); + + switch(el.ViewDimension) + { + case D3D12_DSV_DIMENSION_TEXTURE1D: + Serialise("Texture1D.MipSlice", el.Texture1D.MipSlice); + break; + case D3D12_DSV_DIMENSION_TEXTURE1DARRAY: + Serialise("Texture1DArray.MipSlice", el.Texture1DArray.MipSlice); + Serialise("Texture1DArray.FirstArraySlice", el.Texture1DArray.FirstArraySlice); + Serialise("Texture1DArray.ArraySize", el.Texture1DArray.ArraySize); + break; + case D3D12_DSV_DIMENSION_TEXTURE2D: + Serialise("Texture2D.MipSlice", el.Texture2D.MipSlice); + break; + case D3D12_DSV_DIMENSION_TEXTURE2DARRAY: + Serialise("Texture2DArray.MipSlice", el.Texture2DArray.MipSlice); + Serialise("Texture2DArray.FirstArraySlice", el.Texture2DArray.FirstArraySlice); + Serialise("Texture2DArray.ArraySize", el.Texture2DArray.ArraySize); + break; + case D3D12_DSV_DIMENSION_TEXTURE2DMS: + // el.Texture2DMS.UnusedField_NothingToDefine + break; + case D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY: + Serialise("Texture2DMSArray.FirstArraySlice", el.Texture2DMSArray.FirstArraySlice); + Serialise("Texture2DMSArray.ArraySize", el.Texture2DMSArray.ArraySize); + break; + default: RDCERR("Unrecognised DSV Dimension %d", el.ViewDimension); break; + } +} + +template <> +void Serialiser::Serialise(const char *name, D3D12_UNORDERED_ACCESS_VIEW_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_UNORDERED_ACCESS_VIEW_DESC", 0, true); + + Serialise("Format", el.Format); + Serialise("ViewDimension", el.ViewDimension); + + switch(el.ViewDimension) + { + case D3D12_UAV_DIMENSION_BUFFER: + Serialise("Buffer.FirstElement", el.Buffer.FirstElement); + Serialise("Buffer.NumElements", el.Buffer.NumElements); + Serialise("Buffer.StructureByteStride", el.Buffer.StructureByteStride); + Serialise("Buffer.CounterOffsetInBytes", el.Buffer.CounterOffsetInBytes); + Serialise("Buffer.Flags", el.Buffer.Flags); + break; + case D3D12_UAV_DIMENSION_TEXTURE1D: + Serialise("Texture1D.MipSlice", el.Texture1D.MipSlice); + break; + case D3D12_UAV_DIMENSION_TEXTURE1DARRAY: + Serialise("Texture1DArray.MipSlice", el.Texture1DArray.MipSlice); + Serialise("Texture1DArray.FirstArraySlice", el.Texture1DArray.FirstArraySlice); + Serialise("Texture1DArray.ArraySize", el.Texture1DArray.ArraySize); + break; + case D3D12_UAV_DIMENSION_TEXTURE2D: + Serialise("Texture2D.MipSlice", el.Texture2D.MipSlice); + Serialise("Texture2D.PlaneSlice", el.Texture2D.PlaneSlice); + break; + case D3D12_UAV_DIMENSION_TEXTURE2DARRAY: + Serialise("Texture2DArray.MipSlice", el.Texture2DArray.MipSlice); + Serialise("Texture2DArray.FirstArraySlice", el.Texture2DArray.FirstArraySlice); + Serialise("Texture2DArray.ArraySize", el.Texture2DArray.ArraySize); + Serialise("Texture2DArray.PlaneSlice", el.Texture2DArray.PlaneSlice); + break; + case D3D12_UAV_DIMENSION_TEXTURE3D: + Serialise("Texture3D.MipSlice", el.Texture3D.MipSlice); + Serialise("Texture3D.FirstWSlice", el.Texture3D.FirstWSlice); + Serialise("Texture3D.WSize", el.Texture3D.WSize); + break; + default: RDCERR("Unrecognised RTV Dimension %d", el.ViewDimension); break; + } +} + template <> void Serialiser::Serialise(const char *name, D3D12_RESOURCE_BARRIER &el) { @@ -475,12 +805,80 @@ void Serialiser::Serialise(const char *name, D3D12_CLEAR_VALUE &el) } } +template <> +void Serialiser::Serialise(const char *name, D3D12_SAMPLER_DESC &el) +{ + ScopedContext scope(this, name, "D3D12_SAMPLER_DESC", 0, true); + + Serialise("Filter", el.Filter); + Serialise("AddressU", el.AddressU); + Serialise("AddressV", el.AddressV); + Serialise("AddressW", el.AddressW); + Serialise("MipLODBias", el.MipLODBias); + Serialise("MaxAnisotropy", el.MaxAnisotropy); + Serialise("ComparisonFunc", el.ComparisonFunc); + SerialisePODArray<4>("BorderColor", el.BorderColor); + Serialise("MinLOD", el.MinLOD); + Serialise("MaxLOD", el.MaxLOD); +} + string ToStrHelper::Get(const D3D12_VIEWPORT &el) { return StringFormat::Fmt("Viewport<%.0fx%.0f+%.0f+%.0f z=%f->%f>", el.Width, el.Height, el.TopLeftX, el.TopLeftY, el.MinDepth, el.MaxDepth); } +string ToStrHelper::Get(const PortableHandle &el) +{ + if(el.heap == ResourceId()) + return "NULL"; + + return StringFormat::Fmt("D3D12_CPU_DESCRIPTOR_HANDLE(%s, %u)", ToStr::Get(el.heap).c_str(), + el.index); +} + +string ToStrHelper::Get(const D3D12Descriptor::DescriptorType &el) +{ + switch(el) + { + case D3D12Descriptor::TypeCBV: return "CBV"; + case D3D12Descriptor::TypeSRV: return "SRV"; + case D3D12Descriptor::TypeUAV: return "UAV"; + case D3D12Descriptor::TypeRTV: return "RTV"; + case D3D12Descriptor::TypeDSV: return "DSV"; + case D3D12Descriptor::TypeUndefined: return "Undefined"; + default: break; + } + + if((uint32_t)el < D3D12Descriptor::TypeCBV) + return "Sampler"; + + return StringFormat::Fmt("DescriptorType<%d>", el); +} + +string ToStrHelper::Get(const D3D12ResourceType &el) +{ + switch(el) + { + case Resource_Device: return "Device"; + case Resource_Unknown: return "Unknown"; + case Resource_CommandAllocator: return "Command Allocator"; + case Resource_CommandQueue: return "Command Queue"; + case Resource_CommandSignature: return "Command Signature"; + case Resource_DescriptorHeap: return "Descriptor Heap"; + case Resource_Fence: return "Fence"; + case Resource_Heap: return "Heap"; + case Resource_PipelineState: return "Pipeline State"; + case Resource_QueryHeap: return "Query Heap"; + case Resource_Resource: return "Resource"; + case Resource_GraphicsCommandList: return "Graphics CommandList"; + case Resource_RootSignature: return "Root Signature"; + default: break; + } + + return StringFormat::Fmt("D3D12ResourceType<%d>", el); +} + string ToStrHelper::Get(const D3D12_HEAP_TYPE &el) { switch(el) @@ -549,6 +947,150 @@ string ToStrHelper::Get(const D3D12_RESOURCE return StringFormat::Fmt("D3D12_RESOURCE_BARRIER_TYPE<%d>", el); } +string ToStrHelper::Get(const D3D12_SRV_DIMENSION &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_SRV_DIMENSION_UNKNOWN) + TOSTR_CASE_STRINGIZE(D3D12_SRV_DIMENSION_BUFFER) + TOSTR_CASE_STRINGIZE(D3D12_SRV_DIMENSION_TEXTURE1D) + TOSTR_CASE_STRINGIZE(D3D12_SRV_DIMENSION_TEXTURE1DARRAY) + TOSTR_CASE_STRINGIZE(D3D12_SRV_DIMENSION_TEXTURE2D) + TOSTR_CASE_STRINGIZE(D3D12_SRV_DIMENSION_TEXTURE2DARRAY) + TOSTR_CASE_STRINGIZE(D3D12_SRV_DIMENSION_TEXTURE2DMS) + TOSTR_CASE_STRINGIZE(D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY) + TOSTR_CASE_STRINGIZE(D3D12_SRV_DIMENSION_TEXTURE3D) + TOSTR_CASE_STRINGIZE(D3D12_SRV_DIMENSION_TEXTURECUBE) + TOSTR_CASE_STRINGIZE(D3D12_SRV_DIMENSION_TEXTURECUBEARRAY) + default: break; + } + + return StringFormat::Fmt("D3D12_SRV_DIMENSION<%d>", el); +} + +string ToStrHelper::Get(const D3D12_RTV_DIMENSION &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_RTV_DIMENSION_UNKNOWN) + TOSTR_CASE_STRINGIZE(D3D12_RTV_DIMENSION_BUFFER) + TOSTR_CASE_STRINGIZE(D3D12_RTV_DIMENSION_TEXTURE1D) + TOSTR_CASE_STRINGIZE(D3D12_RTV_DIMENSION_TEXTURE1DARRAY) + TOSTR_CASE_STRINGIZE(D3D12_RTV_DIMENSION_TEXTURE2D) + TOSTR_CASE_STRINGIZE(D3D12_RTV_DIMENSION_TEXTURE2DARRAY) + TOSTR_CASE_STRINGIZE(D3D12_RTV_DIMENSION_TEXTURE2DMS) + TOSTR_CASE_STRINGIZE(D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY) + TOSTR_CASE_STRINGIZE(D3D12_RTV_DIMENSION_TEXTURE3D) + default: break; + } + + return StringFormat::Fmt("D3D12_RTV_DIMENSION<%d>", el); +} + +string ToStrHelper::Get(const D3D12_UAV_DIMENSION &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_UAV_DIMENSION_BUFFER) + TOSTR_CASE_STRINGIZE(D3D12_UAV_DIMENSION_TEXTURE1D) + TOSTR_CASE_STRINGIZE(D3D12_UAV_DIMENSION_TEXTURE1DARRAY) + TOSTR_CASE_STRINGIZE(D3D12_UAV_DIMENSION_TEXTURE2D) + TOSTR_CASE_STRINGIZE(D3D12_UAV_DIMENSION_TEXTURE2DARRAY) + TOSTR_CASE_STRINGIZE(D3D12_UAV_DIMENSION_TEXTURE3D) + default: break; + } + + return StringFormat::Fmt("D3D12_UAV_DIMENSION<%d>", el); +} + +string ToStrHelper::Get(const D3D12_DSV_DIMENSION &el) +{ + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D12_DSV_DIMENSION_UNKNOWN) + TOSTR_CASE_STRINGIZE(D3D12_DSV_DIMENSION_TEXTURE1D) + TOSTR_CASE_STRINGIZE(D3D12_DSV_DIMENSION_TEXTURE1DARRAY) + TOSTR_CASE_STRINGIZE(D3D12_DSV_DIMENSION_TEXTURE2D) + TOSTR_CASE_STRINGIZE(D3D12_DSV_DIMENSION_TEXTURE2DARRAY) + TOSTR_CASE_STRINGIZE(D3D12_DSV_DIMENSION_TEXTURE2DMS) + TOSTR_CASE_STRINGIZE(D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY) + default: break; + } + + return StringFormat::Fmt("D3D12_DSV_DIMENSION<%d>", el); +} + +string ToStrHelper::Get(const D3D12_FILTER &el) +{ + switch(el) + { + case D3D12_FILTER_MIN_MAG_MIP_POINT: return "MIN_MAG_MIP_POINT"; + case D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR: return "MIN_MAG_POINT_MIP_LINEAR"; + case D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT: return "MIN_POINT_MAG_LINEAR_MIP_POINT"; + case D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR: return "MIN_POINT_MAG_MIP_LINEAR"; + case D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT: return "MIN_LINEAR_MAG_MIP_POINT"; + case D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR: return "MIN_LINEAR_MAG_POINT_MIP_LINEAR"; + case D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT: return "MIN_MAG_LINEAR_MIP_POINT"; + case D3D12_FILTER_MIN_MAG_MIP_LINEAR: return "MIN_MAG_MIP_LINEAR"; + case D3D12_FILTER_ANISOTROPIC: return "ANISOTROPIC"; + + case D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT: return "CMP:MIN_MAG_MIP_POINT"; + case D3D12_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR: return "CMP:MIN_MAG_POINT_MIP_LINEAR"; + case D3D12_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT: + return "CMP:MIN_POINT_MAG_LINEAR_MIP_POINT"; + case D3D12_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR: return "CMP:MIN_POINT_MAG_MIP_LINEAR"; + case D3D12_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT: return "CMP:MIN_LINEAR_MAG_MIP_POINT"; + case D3D12_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR: + return "CMP:MIN_LINEAR_MAG_POINT_MIP_LINEAR"; + case D3D12_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT: return "CMP:MIN_MAG_LINEAR_MIP_POINT"; + case D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR: return "CMP:MIN_MAG_MIP_LINEAR"; + case D3D12_FILTER_COMPARISON_ANISOTROPIC: return "CMP:ANISOTROPIC"; + + case D3D12_FILTER_MINIMUM_MIN_MAG_MIP_POINT: return "MIN:MIN_MAG_MIP_POINT"; + case D3D12_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR: return "MIN:MIN_MAG_POINT_MIP_LINEAR"; + case D3D12_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT: + return "MIN:MIN_POINT_MAG_LINEAR_MIP_POINT"; + case D3D12_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR: return "MIN:MIN_POINT_MAG_MIP_LINEAR"; + case D3D12_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT: return "MIN:MIN_LINEAR_MAG_MIP_POINT"; + case D3D12_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR: + return "MIN:MIN_LINEAR_MAG_POINT_MIP_LINEAR"; + case D3D12_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT: return "MIN:MIN_MAG_LINEAR_MIP_POINT"; + case D3D12_FILTER_MINIMUM_MIN_MAG_MIP_LINEAR: return "MIN:MIN_MAG_MIP_LINEAR"; + case D3D12_FILTER_MINIMUM_ANISOTROPIC: return "MIN:ANISOTROPIC"; + + case D3D12_FILTER_MAXIMUM_MIN_MAG_MIP_POINT: return "MAX:MIN_MAG_MIP_POINT"; + case D3D12_FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR: return "MAX:MIN_MAG_POINT_MIP_LINEAR"; + case D3D12_FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT: + return "MAX:MIN_POINT_MAG_LINEAR_MIP_POINT"; + case D3D12_FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR: return "MAX:MIN_POINT_MAG_MIP_LINEAR"; + case D3D12_FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT: return "MAX:MIN_LINEAR_MAG_MIP_POINT"; + case D3D12_FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR: + return "MAX:MIN_LINEAR_MAG_POINT_MIP_LINEAR"; + case D3D12_FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT: return "MAX:MIN_MAG_LINEAR_MIP_POINT"; + case D3D12_FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR: return "MAX:MIN_MAG_MIP_LINEAR"; + case D3D12_FILTER_MAXIMUM_ANISOTROPIC: return "MAX:ANISOTROPIC"; + + default: break; + } + + return StringFormat::Fmt("D3D12_FILTER<%d>", el); +} + +string ToStrHelper::Get(const D3D12_TEXTURE_ADDRESS_MODE &el) +{ + switch(el) + { + case D3D12_TEXTURE_ADDRESS_MODE_WRAP: return "WRAP"; + case D3D12_TEXTURE_ADDRESS_MODE_MIRROR: return "MIRROR"; + case D3D12_TEXTURE_ADDRESS_MODE_CLAMP: return "CLAMP"; + case D3D12_TEXTURE_ADDRESS_MODE_BORDER: return "BORDER"; + case D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE: return "MIRROR_ONCE"; + default: break; + } + + return StringFormat::Fmt("D3D12_TEXTURE_ADDRESS_MODE<%d>", el); +} + string ToStrHelper::Get(const D3D12_BLEND &el) { switch(el) @@ -787,6 +1329,56 @@ string ToStrHelper::Get(const D3D12_TEXTURE_LAYOUT return StringFormat::Fmt("D3D12_TEXTURE_LAYOUT<%d>", el); } +string ToStrHelper::Get(const D3D12_BUFFER_SRV_FLAGS &el) +{ + string ret; + + if(el == D3D12_BUFFER_SRV_FLAG_NONE) + return "D3D12_BUFFER_SRV_FLAG_NONE"; + + if(el & D3D12_BUFFER_SRV_FLAG_RAW) + ret += " | D3D12_BUFFER_SRV_FLAG_RAW"; + + if(!ret.empty()) + ret = ret.substr(3); + + return ret; +} + +string ToStrHelper::Get(const D3D12_DSV_FLAGS &el) +{ + string ret; + + if(el == D3D12_DSV_FLAG_NONE) + return "D3D12_DSV_FLAG_NONE"; + + if(el & D3D12_DSV_FLAG_READ_ONLY_DEPTH) + ret += " | D3D12_DSV_FLAG_READ_ONLY_DEPTH"; + if(el & D3D12_DSV_FLAG_READ_ONLY_STENCIL) + ret += " | D3D12_DSV_FLAG_READ_ONLY_STENCIL"; + + if(!ret.empty()) + ret = ret.substr(3); + + return ret; +} + +string ToStrHelper::Get(const D3D12_BUFFER_UAV_FLAGS &el) +{ + string ret; + + if(el == D3D12_BUFFER_UAV_FLAG_NONE) + return "D3D12_BUFFER_UAV_FLAG_NONE"; + + if(el & D3D12_BUFFER_UAV_FLAG_RAW) + ret += " | D3D12_BUFFER_UAV_FLAG_RAW"; + + if(!ret.empty()) + ret = ret.substr(3); + + return ret; +} + string ToStrHelper::Get(const D3D12_HEAP_FLAGS &el) { string ret; diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index 50a022bea..f37aa6a0b 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -129,8 +129,24 @@ void Serialiser::Serialise(const char *name, D3D12_HEAP_PROPERTIES &el); template <> void Serialiser::Serialise(const char *name, D3D12_DESCRIPTOR_HEAP_DESC &el); template <> +void Serialiser::Serialise(const char *name, D3D12_SAMPLER_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D12_CONSTANT_BUFFER_VIEW_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D12_SHADER_RESOURCE_VIEW_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D12_RENDER_TARGET_VIEW_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D12_DEPTH_STENCIL_VIEW_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D12_UNORDERED_ACCESS_VIEW_DESC &el); +template <> void Serialiser::Serialise(const char *name, D3D12_CLEAR_VALUE &el); +struct D3D12Descriptor; +template <> +void Serialiser::Serialise(const char *name, D3D12Descriptor &el); + #pragma region Chunks #define D3D12_CHUNKS \ diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 20193daa8..7025a293c 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -222,6 +222,7 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara if(!RenderDoc::Inst().IsReplayApp()) { m_DeviceRecord = GetResourceManager()->AddResourceRecord(m_ResourceID); + m_DeviceRecord->type = Resource_Device; m_DeviceRecord->DataInSerialiser = false; m_DeviceRecord->SpecialResource = true; m_DeviceRecord->Length = 0; @@ -548,6 +549,7 @@ IUnknown *WrappedID3D12Device::WrapSwapchainBuffer(WrappedIDXGISwapChain3 *swap, if(m_State >= WRITING) { D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->type = Resource_Resource; record->DataInSerialiser = false; record->SpecialResource = true; record->Length = 0; diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp index 8a48ed914..3ea79d832 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp @@ -145,6 +145,7 @@ HRESULT WrappedID3D12Device::CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type Serialise_CreateCommandAllocator(type, riid, (void **)&wrapped); D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->type = Resource_CommandAllocator; record->Length = 0; wrapped->SetResourceRecord(record); @@ -285,6 +286,7 @@ HRESULT WrappedID3D12Device::CreateGraphicsPipelineState(const D3D12_GRAPHICS_PI Serialise_CreateGraphicsPipelineState(pDesc, riid, (void **)&wrapped); D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->type = Resource_PipelineState; record->Length = 0; wrapped->SetResourceRecord(record); @@ -351,6 +353,7 @@ HRESULT WrappedID3D12Device::CreateComputePipelineState(const D3D12_COMPUTE_PIPE Serialise_CreateComputePipelineState(pDesc, riid, (void **)&wrapped); D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->type = Resource_PipelineState; record->Length = 0; wrapped->SetResourceRecord(record); @@ -417,10 +420,19 @@ HRESULT WrappedID3D12Device::CreateDescriptorHeap(const D3D12_DESCRIPTOR_HEAP_DE Serialise_CreateDescriptorHeap(pDescriptorHeapDesc, riid, (void **)&wrapped); D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->type = Resource_DescriptorHeap; record->Length = 0; wrapped->SetResourceRecord(record); record->AddChunk(scope.Get()); + + { + SCOPED_LOCK(m_CapTransitionLock); + if(m_State != WRITING_CAPFRAME) + GetResourceManager()->MarkDirtyResource(wrapped->GetResourceID()); + else + GetResourceManager()->MarkPendingDirty(wrapped->GetResourceID()); + } } *ppvHeap = (ID3D12DescriptorHeap *)wrapped; @@ -490,6 +502,7 @@ HRESULT WrappedID3D12Device::CreateRootSignature(UINT nodeMask, const void *pBlo (void **)&wrapped); D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->type = Resource_RootSignature; record->Length = 0; wrapped->SetResourceRecord(record); @@ -631,10 +644,19 @@ HRESULT WrappedID3D12Device::CreateCommittedResource(const D3D12_HEAP_PROPERTIES (void **)&wrapped); D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->type = Resource_Resource; record->Length = 0; wrapped->SetResourceRecord(record); record->AddChunk(scope.Get()); + + { + SCOPED_LOCK(m_CapTransitionLock); + if(m_State != WRITING_CAPFRAME) + GetResourceManager()->MarkDirtyResource(wrapped->GetResourceID()); + else + GetResourceManager()->MarkPendingDirty(wrapped->GetResourceID()); + } } *ppvResource = (ID3D12Resource *)wrapped; @@ -719,6 +741,7 @@ HRESULT WrappedID3D12Device::CreateFence(UINT64 InitialValue, D3D12_FENCE_FLAGS Serialise_CreateFence(InitialValue, Flags, riid, (void **)&wrapped); D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->type = Resource_Resource; record->Length = 0; wrapped->SetResourceRecord(record); diff --git a/renderdoc/driver/d3d12/d3d12_manager.cpp b/renderdoc/driver/d3d12/d3d12_manager.cpp index 2f5b76a13..8f71f28b5 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.cpp +++ b/renderdoc/driver/d3d12/d3d12_manager.cpp @@ -86,6 +86,10 @@ void D3D12Descriptor::Init(ID3D12Resource *pResource, const D3D12_DEPTH_STENCIL_ RDCEraseEl(nonsamp.dsv); } +void D3D12Descriptor::Create(ID3D12Device *dev, D3D12_CPU_DESCRIPTOR_HANDLE handle) +{ +} + D3D12_CPU_DESCRIPTOR_HANDLE Unwrap(D3D12_CPU_DESCRIPTOR_HANDLE handle) { if(handle.ptr == 0) @@ -127,15 +131,6 @@ D3D12_CPU_DESCRIPTOR_HANDLE FromPortableHandle(D3D12ResourceManager *manager, Po return D3D12_CPU_DESCRIPTOR_HANDLE(); } -string ToStrHelper::Get(const PortableHandle &el) -{ - if(el.heap == ResourceId()) - return "NULL"; - - return StringFormat::Fmt("D3D12_CPU_DESCRIPTOR_HANDLE(%s, %u)", ToStr::Get(el.heap).c_str(), - el.index); -} - bool D3D12ResourceManager::SerialisableResource(ResourceId id, D3D12ResourceRecord *record) { if(record->SpecialResource) @@ -169,22 +164,182 @@ bool D3D12ResourceManager::Need_InitialStateChunk(ID3D12DeviceChild *res) bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) { + ResourceId id = GetResID(res); + D3D12ResourceType type = IdentifyTypeByPtr(res); + + if(type == Resource_DescriptorHeap) + { + WrappedID3D12DescriptorHeap *heap = (WrappedID3D12DescriptorHeap *)res; + + UINT numElems = heap->GetDesc().NumDescriptors; + + D3D12Descriptor *descs = + (D3D12Descriptor *)Serialiser::AllocAlignedBuffer(sizeof(D3D12Descriptor) * numElems); + + memcpy(descs, heap->GetDescriptors(), sizeof(D3D12Descriptor) * numElems); + + SetInitialContents(heap->GetResourceID(), + D3D12ResourceManager::InitialContentData(NULL, numElems, (byte *)descs)); + return true; + } + else if(type == Resource_Resource) + { + ID3D12Resource *r = (ID3D12Resource *)res; + + D3D12_RESOURCE_DESC desc = r->GetDesc(); + + (void)desc; + + D3D12NOTIMP("resource init states"); + return true; + } + RDCUNIMPLEMENTED("init states"); return false; } -bool D3D12ResourceManager::Serialise_InitialState(ResourceId id, ID3D12DeviceChild *res) +bool D3D12ResourceManager::Serialise_InitialState(ResourceId resid, ID3D12DeviceChild *) { - RDCUNIMPLEMENTED("init states"); - return false; + D3D12ResourceRecord *record = NULL; + if(m_State >= WRITING) + record = GetResourceRecord(resid); + + SERIALISE_ELEMENT(ResourceId, id, resid); + SERIALISE_ELEMENT(D3D12ResourceType, type, record->type); + + if(m_State >= WRITING) + { + D3D12ResourceManager::InitialContentData initContents = GetInitialContents(id); + + if(type == Resource_DescriptorHeap) + { + D3D12Descriptor *descs = (D3D12Descriptor *)initContents.blob; + uint32_t numElems = initContents.num; + + m_pSerialiser->SerialiseComplexArray("Descriptors", descs, numElems); + } + else if(type == Resource_Resource) + { + ID3D12Resource *r = (ID3D12Resource *)GetCurrentResource(id); + + D3D12_RESOURCE_DESC desc = r->GetDesc(); + + (void)desc; + + D3D12NOTIMP("resource init states"); + return true; + } + else + { + RDCUNIMPLEMENTED("init states"); + return false; + } + } + else + { + ID3D12DeviceChild *res = GetLiveResource(id); + + RDCASSERT(res != NULL); + + ResourceId liveid = GetLiveID(id); + + if(type == Resource_DescriptorHeap) + { + WrappedID3D12DescriptorHeap *heap = (WrappedID3D12DescriptorHeap *)res; + + uint32_t numElems = 0; + D3D12Descriptor *descs = NULL; + + m_pSerialiser->SerialiseComplexArray("Descriptors", descs, numElems); + + D3D12_DESCRIPTOR_HEAP_DESC desc = heap->GetDesc(); + + // this heap doesn't have to be shader visible, we just use it to copy from + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + + ID3D12DescriptorHeap *copyheap = NULL; + HRESULT hr = m_Device->GetReal()->CreateDescriptorHeap(&desc, __uuidof(ID3D12DescriptorHeap), + (void **)©heap); + + if(FAILED(hr)) + { + RDCERR("Failed to create CPU descriptor heap for initial state: 0x%08x", hr); + return false; + } + + D3D12_CPU_DESCRIPTOR_HANDLE handle = copyheap->GetCPUDescriptorHandleForHeapStart(); + + UINT increment = m_Device->GetDescriptorHandleIncrementSize(desc.Type); + + for(uint32_t i = 0; i < numElems; i++) + { + descs[i].Create(m_Device->GetReal(), handle); + + handle.ptr += increment; + } + + SAFE_DELETE_ARRAY(descs); + + SetInitialContents(id, D3D12ResourceManager::InitialContentData(copyheap, 0, NULL)); + } + else if(type == Resource_Resource) + { + D3D12NOTIMP("resource init states"); + return true; + } + else + { + RDCUNIMPLEMENTED("init states"); + return false; + } + } + + return true; } void D3D12ResourceManager::Create_InitialState(ResourceId id, ID3D12DeviceChild *live, bool hasData) { - RDCUNIMPLEMENTED("init states"); + D3D12ResourceType type = IdentifyTypeByPtr(live); + + if(type == Resource_DescriptorHeap) + { + // set a NULL heap, if there are no initial contents for a descriptor heap we just leave + // it all entirely undefined. + SetInitialContents(id, D3D12ResourceManager::InitialContentData(NULL, 1, NULL)); + } + else if(type == Resource_Resource) + { + D3D12NOTIMP("resource init states"); + } + else + { + RDCUNIMPLEMENTED("init states"); + } } void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, InitialContentData data) { - RDCUNIMPLEMENTED("init states"); + D3D12ResourceType type = IdentifyTypeByPtr(live); + + if(type == Resource_DescriptorHeap) + { + ID3D12DescriptorHeap *dstheap = Unwrap((ID3D12DescriptorHeap *)live); + ID3D12DescriptorHeap *srcheap = (ID3D12DescriptorHeap *)data.resource; + + if(srcheap) + { + // copy the whole heap + m_Device->CopyDescriptorsSimple( + srcheap->GetDesc().NumDescriptors, dstheap->GetCPUDescriptorHandleForHeapStart(), + srcheap->GetCPUDescriptorHandleForHeapStart(), srcheap->GetDesc().Type); + } + } + else if(type == Resource_Resource) + { + D3D12NOTIMP("resource init states"); + } + else + { + RDCUNIMPLEMENTED("init states"); + } } diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index 6e1162671..d5bf5243c 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -31,6 +31,23 @@ #include "driver/d3d12/d3d12_common.h" #include "serialise/serialiser.h" +enum D3D12ResourceType +{ + Resource_Unknown = 0, + Resource_Device, + Resource_CommandAllocator, + Resource_CommandQueue, + Resource_CommandSignature, + Resource_DescriptorHeap, + Resource_Fence, + Resource_Heap, + Resource_PipelineState, + Resource_QueryHeap, + Resource_Resource, + Resource_GraphicsCommandList, + Resource_RootSignature, +}; + class WrappedID3D12DescriptorHeap; // squeeze the descriptor a bit so that the below struct fits in 64 bytes @@ -110,6 +127,7 @@ struct D3D12Descriptor TypeUAV, TypeRTV, TypeDSV, + TypeUndefined, }; DescriptorType GetType() @@ -130,6 +148,8 @@ struct D3D12Descriptor void Init(ID3D12Resource *pResource, const D3D12_RENDER_TARGET_VIEW_DESC *pDesc); void Init(ID3D12Resource *pResource, const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc); + void Create(ID3D12Device *dev, D3D12_CPU_DESCRIPTOR_HANDLE handle); + union { // keep the sampler outside as it's the largest descriptor @@ -217,7 +237,8 @@ struct D3D12ResourceRecord : public ResourceRecord NullResource = NULL }; - D3D12ResourceRecord(ResourceId id) : ResourceRecord(id, true), cmdInfo(NULL), bakedCommands(NULL) + D3D12ResourceRecord(ResourceId id) + : ResourceRecord(id, true), type(Resource_Unknown), cmdInfo(NULL), bakedCommands(NULL) { } ~D3D12ResourceRecord() {} @@ -248,6 +269,7 @@ struct D3D12ResourceRecord : public ResourceRecord recordlist.insert(m_Chunks.begin(), m_Chunks.end()); } + D3D12ResourceType type; D3D12ResourceRecord *bakedCommands; CmdListRecordingInfo *cmdInfo; }; diff --git a/renderdoc/driver/d3d12/d3d12_resources.cpp b/renderdoc/driver/d3d12/d3d12_resources.cpp index db3e87d19..4efa48d77 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.cpp +++ b/renderdoc/driver/d3d12/d3d12_resources.cpp @@ -31,7 +31,7 @@ ALL_D3D12_TYPES; -ResourceType IdentifyTypeByPtr(ID3D12DeviceChild *ptr) +D3D12ResourceType IdentifyTypeByPtr(ID3D12DeviceChild *ptr) { if(ptr == NULL) return Resource_Unknown; @@ -163,6 +163,11 @@ WrappedID3D12DescriptorHeap::WrappedID3D12DescriptorHeap(ID3D12DescriptorHeap *r // only need to set this once, it's aliased between samp and nonsamp descriptors[i].samp.heap = this; descriptors[i].samp.idx = i; + + // initially descriptors are undefined. This way we just fill them with + // some null SRV descriptor so it's safe to copy around etc but is no + // less undefined for the application to use + descriptors[i].nonsamp.type = D3D12Descriptor::TypeUndefined; } } diff --git a/renderdoc/driver/d3d12/d3d12_resources.h b/renderdoc/driver/d3d12/d3d12_resources.h index 6b7f3e6d6..e66f63dac 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.h +++ b/renderdoc/driver/d3d12/d3d12_resources.h @@ -28,22 +28,6 @@ #include "d3d12_device.h" #include "d3d12_manager.h" -enum ResourceType -{ - Resource_Unknown = 0, - Resource_CommandAllocator, - Resource_CommandQueue, - Resource_CommandSignature, - Resource_DescriptorHeap, - Resource_Fence, - Resource_Heap, - Resource_PipelineState, - Resource_QueryHeap, - Resource_Resource, - Resource_GraphicsCommandList, - Resource_RootSignature, -}; - class TrackedResource { public: @@ -338,6 +322,7 @@ public: const D3D12_DESCRIPTOR_HEAP_DESC &desc); virtual ~WrappedID3D12DescriptorHeap(); + const D3D12Descriptor *GetDescriptors() { return descriptors; } ////////////////////////////// // implement ID3D12DescriptorHeap @@ -552,27 +537,27 @@ struct UnwrapHelper }; #undef D3D12_TYPE_MACRO -#define D3D12_TYPE_MACRO(iface) \ - template <> \ - struct UnwrapHelper \ - { \ - typedef CONCAT(Wrapped, iface) Outer; \ - static bool IsAlloc(void *ptr) { return Outer::IsAlloc(ptr); } \ - static ResourceType GetTypeEnum() { return (ResourceType)Outer::TypeEnum; } \ - static Outer *FromHandle(iface *wrapped) { return (Outer *)wrapped; } \ - }; \ - template <> \ - struct UnwrapHelper \ - { \ - typedef CONCAT(Wrapped, iface) Outer; \ - static bool IsAlloc(void *ptr) { return Outer::IsAlloc(ptr); } \ - static ResourceType GetTypeEnum() { return (ResourceType)Outer::TypeEnum; } \ - static Outer *FromHandle(iface *wrapped) { return (Outer *)wrapped; } \ +#define D3D12_TYPE_MACRO(iface) \ + template <> \ + struct UnwrapHelper \ + { \ + typedef CONCAT(Wrapped, iface) Outer; \ + static bool IsAlloc(void *ptr) { return Outer::IsAlloc(ptr); } \ + static D3D12ResourceType GetTypeEnum() { return (D3D12ResourceType)Outer::TypeEnum; } \ + static Outer *FromHandle(iface *wrapped) { return (Outer *)wrapped; } \ + }; \ + template <> \ + struct UnwrapHelper \ + { \ + typedef CONCAT(Wrapped, iface) Outer; \ + static bool IsAlloc(void *ptr) { return Outer::IsAlloc(ptr); } \ + static D3D12ResourceType GetTypeEnum() { return (D3D12ResourceType)Outer::TypeEnum; } \ + static Outer *FromHandle(iface *wrapped) { return (Outer *)wrapped; } \ }; ALL_D3D12_TYPES; -ResourceType IdentifyTypeByPtr(ID3D12DeviceChild *ptr); +D3D12ResourceType IdentifyTypeByPtr(ID3D12DeviceChild *ptr); #define WRAPPING_DEBUG 0