From dcd22abd1320520bd812e1acc4f025db50e4e127 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 30 Oct 2017 10:59:40 +0000 Subject: [PATCH] Update D3D12Replay and initialisation to new code & RDCFile based system --- renderdoc/driver/d3d12/d3d12_common.cpp | 23 +++++ renderdoc/driver/d3d12/d3d12_counters.cpp | 5 +- renderdoc/driver/d3d12/d3d12_debug.cpp | 29 +++--- renderdoc/driver/d3d12/d3d12_debug.h | 4 +- renderdoc/driver/d3d12/d3d12_device.cpp | 23 ----- renderdoc/driver/d3d12/d3d12_device.h | 30 ++++-- renderdoc/driver/d3d12/d3d12_replay.cpp | 110 +++++++++++++--------- renderdoc/driver/d3d12/d3d12_replay.h | 13 +-- 8 files changed, 135 insertions(+), 102 deletions(-) diff --git a/renderdoc/driver/d3d12/d3d12_common.cpp b/renderdoc/driver/d3d12/d3d12_common.cpp index 725b330d5..6defd03c2 100644 --- a/renderdoc/driver/d3d12/d3d12_common.cpp +++ b/renderdoc/driver/d3d12/d3d12_common.cpp @@ -98,6 +98,29 @@ void D3D12MarkerRegion::End(ID3D12CommandQueue *queue) queue->EndEvent(); } +D3D12InitParams::D3D12InitParams() +{ + MinimumFeatureLevel = D3D_FEATURE_LEVEL_11_0; +} + +bool D3D12InitParams::IsSupportedVersion(uint64_t ver) +{ + if(ver == CurrentVersion) + return true; + + // we can check other older versions we support here. + + return false; +} + +template +void DoSerialise(SerialiserType &ser, D3D12InitParams &el) +{ + SERIALISE_MEMBER(MinimumFeatureLevel); +} + +INSTANTIATE_SERIALISE_TYPE(D3D12InitParams); + TextureDim MakeTextureDim(D3D12_SRV_DIMENSION dim) { switch(dim) diff --git a/renderdoc/driver/d3d12/d3d12_counters.cpp b/renderdoc/driver/d3d12/d3d12_counters.cpp index 5e5c58129..91578c4ce 100644 --- a/renderdoc/driver/d3d12/d3d12_counters.cpp +++ b/renderdoc/driver/d3d12/d3d12_counters.cpp @@ -63,8 +63,9 @@ vector D3D12Replay::EnumerateCounters() return ret; } -void D3D12Replay::DescribeCounter(GPUCounter counterID, CounterDescription &desc) +CounterDescription D3D12Replay::DescribeCounter(GPUCounter counterID) { + CounterDescription desc; desc.counterID = counterID; // 0808CC9B-79DF-4549-81F7-85494E648F22 desc.uuid.bytes[0] = 0x0808CC9B; @@ -176,6 +177,8 @@ void D3D12Replay::DescribeCounter(GPUCounter counterID, CounterDescription &desc desc.unit = CounterUnit::Absolute; break; } + + return desc; } struct D3D12GPUTimerCallback : public D3D12DrawcallCallback diff --git a/renderdoc/driver/d3d12/d3d12_debug.cpp b/renderdoc/driver/d3d12/d3d12_debug.cpp index 5b703be69..c69a44663 100644 --- a/renderdoc/driver/d3d12/d3d12_debug.cpp +++ b/renderdoc/driver/d3d12/d3d12_debug.cpp @@ -3360,8 +3360,8 @@ void D3D12DebugManager::GetBufferData(ID3D12Resource *buffer, uint64_t offset, u m_DebugAlloc->Reset(); } -byte *D3D12DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize) +void D3D12DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data) { bool wasms = false; @@ -3370,8 +3370,7 @@ byte *D3D12DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 if(resource == NULL) { RDCERR("Trying to get texture data for unknown ID %llu!", tex); - dataSize = 0; - return new byte[0]; + return; } HRESULT hr = S_OK; @@ -3408,8 +3407,10 @@ byte *D3D12DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 ID3D12GraphicsCommandList *list = NULL; - if(params.remap) + if(params.remap != RemapTexture::NoRemap) { + RDCASSERT(params.remap == RemapTexture::RGBA8); + // force readback texture to RGBA8 unorm copyDesc.Format = IsSRGBFormat(copyDesc.Format) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM; @@ -3683,16 +3684,14 @@ byte *D3D12DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 m_WrappedDevice->FlushLists(); // map the buffer and copy to return buffer - D3D12_RANGE range = {0, dataSize}; byte *pData = NULL; - hr = readbackBuf->Map(0, &range, (void **)&pData); + hr = readbackBuf->Map(0, NULL, (void **)&pData); RDCASSERTEQUAL(hr, S_OK); RDCASSERT(pData != NULL); - dataSize = GetByteSize(layouts[0].Footprint.Width, layouts[0].Footprint.Height, - layouts[0].Footprint.Depth, copyDesc.Format, 0); - byte *ret = new byte[dataSize]; + data.resize(GetByteSize(layouts[0].Footprint.Width, layouts[0].Footprint.Height, + layouts[0].Footprint.Depth, copyDesc.Format, 0)); // for depth-stencil need to merge the planes pixel-wise if(isDepth && isStencil) @@ -3713,7 +3712,7 @@ byte *D3D12DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 uint8_t *sSrc = (uint8_t *)(pData + layouts[1].Offset + layouts[1].Footprint.RowPitch * row); - uint32_t *dDst = (uint32_t *)(ret + dstRowPitch * row); + uint32_t *dDst = (uint32_t *)(data.data() + dstRowPitch * row); uint32_t *sDst = dDst + 1; // interleaved, next pixel for(UINT i = 0; i < layouts[0].Footprint.Width; i++) @@ -3747,7 +3746,7 @@ byte *D3D12DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 uint8_t *sSrc = (uint8_t *)(pData + layouts[1].Offset + layouts[1].Footprint.RowPitch * row); - uint32_t *dst = (uint32_t *)(ret + dstRowPitch * row); + uint32_t *dst = (uint32_t *)(data.data() + dstRowPitch * row); for(UINT i = 0; i < layouts[0].Footprint.Width; i++) { @@ -3774,7 +3773,7 @@ byte *D3D12DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 UINT row = r + s * rowcounts[0]; byte *src = pData + layouts[0].Footprint.RowPitch * row; - byte *dst = ret + dstRowPitch * row; + byte *dst = data.data() + dstRowPitch * row; memcpy(dst, src, dstRowPitch); } @@ -3784,14 +3783,12 @@ byte *D3D12DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 SAFE_DELETE_ARRAY(layouts); SAFE_DELETE_ARRAY(rowcounts); - range.End = 0; + D3D12_RANGE range = {0, 0}; readbackBuf->Unmap(0, &range); // clean up temporary objects SAFE_RELEASE(readbackBuf); SAFE_RELEASE(tmpTexture); - - return ret; } void D3D12DebugManager::InitPostVSBuffers(uint32_t eventID) diff --git a/renderdoc/driver/d3d12/d3d12_debug.h b/renderdoc/driver/d3d12/d3d12_debug.h index fa2d059d4..18a333a75 100644 --- a/renderdoc/driver/d3d12/d3d12_debug.h +++ b/renderdoc/driver/d3d12/d3d12_debug.h @@ -104,8 +104,8 @@ public: void GetBufferData(ResourceId buff, uint64_t offset, uint64_t length, vector &retData); void GetBufferData(ID3D12Resource *buff, uint64_t offset, uint64_t length, vector &retData); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize); + void GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data); void BuildShader(string source, string entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, string *errors); diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index a8d8a6652..ea8d3e990 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -43,29 +43,6 @@ WRAPPED_POOL_INST(WrappedID3D12Device); -D3D12InitParams::D3D12InitParams() -{ - SerialiseVersion = D3D12_SERIALISE_VERSION; - MinimumFeatureLevel = D3D_FEATURE_LEVEL_11_0; -} - -ReplayStatus D3D12InitParams::Serialise() -{ - Serialiser *localSerialiser = GetSerialiser(); - - SERIALISE_ELEMENT(uint32_t, ver, D3D12_SERIALISE_VERSION); - SerialiseVersion = ver; - - if(ver != D3D12_SERIALISE_VERSION) - { - RDCERR("Incompatible D3D12 serialise version, expected %d got %d", D3D12_SERIALISE_VERSION, ver); - return ReplayStatus::APIIncompatibleVersion; - } - - localSerialiser->Serialise("MinimumFeatureLevel", MinimumFeatureLevel); - - return ReplayStatus::Succeeded; -} const char *WrappedID3D12Device::GetChunkName(uint32_t idx) { diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index a282703a0..1a861269d 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -40,19 +40,19 @@ struct IAmdExtD3DFactory; -struct D3D12InitParams : public RDCInitParams +struct D3D12InitParams { D3D12InitParams(); - ReplayStatus Serialise(); D3D_FEATURE_LEVEL MinimumFeatureLevel; - static const uint32_t D3D12_SERIALISE_VERSION = 0x0000001; - - // version number internal to d3d12 stream - uint32_t SerialiseVersion; + // check if a frame capture section version is supported + static const uint64_t CurrentVersion = 0x2; + static bool IsSupportedVersion(uint64_t ver); }; +DECLARE_REFLECTION_STRUCT(D3D12InitParams); + class WrappedID3D12Device; class WrappedID3D12Resource; @@ -285,6 +285,9 @@ private: vector m_DebugMessages; + SDFile *m_StructuredFile = NULL; + SDFile m_StoredStructuredData; + uint32_t m_FrameCounter; vector m_CapturedFrames; FrameRecord m_FrameRecord; @@ -297,6 +300,7 @@ private: LogState m_State; D3D12InitParams m_InitParams; + uint64_t m_SectionVersion; ID3D12InfoQueue *m_pInfoQueue; D3D12ResourceRecord *m_FrameCaptureRecord; @@ -383,7 +387,11 @@ public: const map &GetSubresourceStates() { return m_ResourceStates; } const map &GetBackbufferFormats() { return m_BackbufferFormat; } void SetLogFile(const char *logfile); - void SetLogVersion(uint32_t fileversion) { m_InitParams.SerialiseVersion = fileversion; } + void SetInitParams(const D3D12InitParams ¶ms, uint64_t sectionVersion) + { + m_InitParams = params; + m_SectionVersion = sectionVersion; + } D3D12Replay *GetReplay() { return &m_Replay; } WrappedID3D12CommandQueue *GetQueue() { return m_Queue; } ID3D12CommandAllocator *GetAlloc() { return m_Alloc; } @@ -455,9 +463,15 @@ public: bool Serialise_DynamicDescriptorCopies(Serialiser *localSerialiser, const std::vector *copies); - void ReadLogInitialisation(); + void ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers); void ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType); + void SetStructuredExport(uint64_t sectionVersion) + { + m_SectionVersion = sectionVersion; + m_State = CaptureState::StructuredExport; + } + SDFile &GetStructuredFile() { return *m_StructuredFile; } // interface for DXGI virtual IUnknown *GetRealIUnknown() { return GetReal(); } virtual IID GetBackbufferUUID() { return __uuidof(ID3D12Resource); } diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index 652bc9793..baec5ea35 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -26,6 +26,7 @@ #include "driver/dx/official/d3dcompiler.h" #include "driver/dxgi/dxgi_common.h" #include "driver/ihv/amd/amd_isa.h" +#include "serialise/rdcfile.h" #include "d3d12_command_queue.h" #include "d3d12_device.h" #include "d3d12_resources.h" @@ -58,9 +59,9 @@ void D3D12Replay::Shutdown() D3D12Replay::PostDeviceShutdownCounters(); } -void D3D12Replay::ReadLogInitialisation() +void D3D12Replay::ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers) { - m_pDevice->ReadLogInitialisation(); + m_pDevice->ReadLogInitialisation(rdc, storeStructuredBuffers); } APIProperties D3D12Replay::GetAPIProperties() @@ -80,6 +81,11 @@ void D3D12Replay::ReplayLog(uint32_t endEventID, ReplayLogType replayType) m_pDevice->ReplayLog(0, endEventID, replayType); } +const SDFile &D3D12Replay::GetStructuredFile() +{ + return m_pDevice->GetStructuredFile(); +} + vector D3D12Replay::GetBuffers() { vector ret; @@ -1556,21 +1562,6 @@ void D3D12Replay::FlipOutputWindow(uint64_t id) m_pDevice->GetDebugManager()->FlipOutputWindow(id); } -void D3D12Replay::InitCallstackResolver() -{ - m_pDevice->GetMainSerialiser()->InitCallstackResolver(); -} - -bool D3D12Replay::HasCallstacks() -{ - return m_pDevice->GetMainSerialiser()->HasCallstacks(); -} - -Callstack::StackResolver *D3D12Replay::GetCallstackResolver() -{ - return m_pDevice->GetMainSerialiser()->GetCallstackResolver(); -} - vector D3D12Replay::GetDebugMessages() { return m_pDevice->GetDebugMessages(); @@ -1680,10 +1671,10 @@ void D3D12Replay::RemoveReplacement(ResourceId id) } } -byte *D3D12Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize) +void D3D12Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data) { - return m_pDevice->GetDebugManager()->GetTextureData(tex, arrayIdx, mip, params, dataSize); + return m_pDevice->GetDebugManager()->GetTextureData(tex, arrayIdx, mip, params, data); } void D3D12Replay::BuildCustomShader(string source, string entry, @@ -1755,7 +1746,7 @@ extern "C" __declspec(dllexport) HRESULT void **ppDevice); ID3DDevice *GetD3D12DeviceIfAlloc(IUnknown *dev); -ReplayStatus D3D12_CreateReplayDevice(const char *logfile, IReplayDriver **driver) +ReplayStatus D3D12_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver) { RDCDEBUG("Creating a D3D12 replay device"); @@ -1783,20 +1774,46 @@ ReplayStatus D3D12_CreateReplayDevice(const char *logfile, IReplayDriver **drive } D3D12InitParams initParams; - RDCDriver driverFileType = RDC_D3D12; - string driverName = "D3D12"; - uint64_t machineIdent = 0; - if(logfile) - { - auto status = RenderDoc::Inst().FillInitParams(logfile, driverFileType, driverName, - machineIdent, (RDCInitParams *)&initParams); - if(status != ReplayStatus::Succeeded) - return status; - } - // initParams.SerialiseVersion is guaranteed to be valid/supported since otherwise the - // FillInitParams (which calls D3D12InitParams::Serialise) would have failed above, so no need to - // check it here. + uint64_t ver = D3D12InitParams::CurrentVersion; + + // if we have an RDCFile, open the frame capture section and serialise the init params. + // if not, we're creating a proxy-capable device so use default-initialised init params. + if(rdc) + { + int sectionIdx = rdc->SectionIndex(SectionType::FrameCapture); + + if(sectionIdx < 0) + return ReplayStatus::InternalError; + + ver = rdc->GetSectionProperties(sectionIdx).version; + + if(!D3D12InitParams::IsSupportedVersion(ver)) + { + RDCERR("Incompatible D3D11 serialise version %llu", ver); + return ReplayStatus::APIUnsupported; + } + + StreamReader *reader = rdc->ReadSection(sectionIdx); + + ReadSerialiser ser(reader, Ownership::Stream); + + SystemChunk chunk = ser.ReadChunk(); + + if(chunk != SystemChunk::DriverInit) + { + RDCERR("Expected to get a DriverInit chunk, instead got %u", chunk); + return ReplayStatus::FileCorrupted; + } + + SERIALISE_ELEMENT(initParams); + + if(ser.IsErrored()) + { + RDCERR("Failed reading driver init params."); + return ReplayStatus::FileIOFailed; + } + } if(initParams.MinimumFeatureLevel < D3D_FEATURE_LEVEL_11_0) initParams.MinimumFeatureLevel = D3D_FEATURE_LEVEL_11_0; @@ -1815,23 +1832,28 @@ ReplayStatus D3D12_CreateReplayDevice(const char *logfile, IReplayDriver **drive } WrappedID3D12Device *wrappedDev = (WrappedID3D12Device *)dev; - if(logfile) - wrappedDev->SetLogFile(logfile); - wrappedDev->SetLogVersion(initParams.SerialiseVersion); - - if(logfile && wrappedDev->GetMainSerialiser()->HasError()) - { - SAFE_RELEASE(wrappedDev); - return ReplayStatus::FileIOFailed; - } + wrappedDev->SetInitParams(initParams, ver); RDCLOG("Created device."); D3D12Replay *replay = wrappedDev->GetReplay(); - replay->SetProxy(logfile == NULL); + replay->SetProxy(rdc == NULL); *driver = (IReplayDriver *)replay; return ReplayStatus::Succeeded; } static DriverRegistration D3D12DriverRegistration(RDC_D3D12, "D3D12", &D3D12_CreateReplayDevice); + +void D3D12_ProcessStructured(RDCFile *rdc, SDFile &output) +{ + WrappedID3D12Device device(NULL, NULL); + + device.SetStructuredExport( + rdc->GetSectionProperties(rdc->SectionIndex(SectionType::FrameCapture)).version); + device.ReadLogInitialisation(rdc, true); + + device.GetStructuredFile().swap(output); +} + +static StructuredProcessRegistration D3D12ProcessRegistration(RDC_D3D12, &D3D12_ProcessStructured); diff --git a/renderdoc/driver/d3d12/d3d12_replay.h b/renderdoc/driver/d3d12/d3d12_replay.h index 0cc92780a..6b56a87a3 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.h +++ b/renderdoc/driver/d3d12/d3d12_replay.h @@ -71,8 +71,9 @@ public: void FreeTargetResource(ResourceId id); void FreeCustomShader(ResourceId id); - void ReadLogInitialisation(); + void ReadLogInitialisation(RDCFile *rdc, bool readStructuredBuffers); void ReplayLog(uint32_t endEventID, ReplayLogType replayType); + const SDFile &GetStructuredFile(); vector GetPassEvents(uint32_t eventID); @@ -107,8 +108,8 @@ public: MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize); + void GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data); void BuildTargetShader(string source, string entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, string *errors); @@ -116,7 +117,7 @@ public: void RemoveReplacement(ResourceId id); vector EnumerateCounters(); - void DescribeCounter(GPUCounter counterID, CounterDescription &desc); + CounterDescription DescribeCounter(GPUCounter counterID); vector FetchCounters(const vector &counters); ResourceId CreateProxyTexture(const TextureDescription &templateTex); @@ -163,10 +164,6 @@ public: bool IsRenderOutput(ResourceId id); void FileChanged() {} - void InitCallstackResolver(); - bool HasCallstacks(); - Callstack::StackResolver *GetCallstackResolver(); - // called before any device is created, to init any counters static void PreDeviceInitCounters(); // called after the device is created, to init any counters