From c406804d24007b0b4ca137254511a784bb54fc20 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 10 Nov 2014 17:53:31 +0000 Subject: [PATCH] Bump D3D11 serialise version for ce0a67e8, and add backwards compat * This is the first attempt at backwards logfile compatibility. Since most captures are fairly ephemeral I don't know to what degree I'll go in future to support old captures, but since this was a fairly trivial example (just skip serialising a bit of data if it's an old version without it), I'll test this out. --- renderdoc/driver/d3d11/d3d11_context.cpp | 3 ++- renderdoc/driver/d3d11/d3d11_device.cpp | 30 +++++++++++++++++++----- renderdoc/driver/d3d11/d3d11_device.h | 10 ++++++-- renderdoc/driver/d3d11/d3d11_replay.cpp | 13 +++++----- renderdoc/hooks/d3d11_hooks.cpp | 14 +++++------ 5 files changed, 47 insertions(+), 23 deletions(-) diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index 3986986d7..adc46eaea 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -319,7 +319,8 @@ bool WrappedID3D11DeviceContext::Serialise_BeginCaptureFrame(bool applyInitialSt } } } - else + // version 5 added this set of data, we can assume for older logs there's just no counters + else if(m_pDevice->GetLogVersion() >= 0x000005) { // read in the known stream-out counters at the start of the frame. // any stream-out that happens in the captured frame will be replayed diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index 41c0efbe0..7dcbfc6e8 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -200,14 +200,34 @@ D3D11InitParams::D3D11InitParams() RDCEraseEl(FeatureLevels); } +// handling for these versions is scattered throughout the code (as relevant to enable/disable bits of serialisation +// and set some defaults if necessary). +// Here we list which non-current versions we support, and what changed +const uint32_t D3D11InitParams::D3D11_OLD_VERSIONS[D3D11InitParams::D3D11_NUM_SUPPORTED_OLD_VERSIONS] = { + 0x0000004, // from 0x4 to 0x5, we added the stream-out hidden counters in the context's Serialise_BeginCaptureFrame +}; + ReplayCreateStatus D3D11InitParams::Serialise() { SERIALISE_ELEMENT(uint32_t, ver, D3D11_SERIALISE_VERSION); SerialiseVersion = ver; if(ver != D3D11_SERIALISE_VERSION) { - RDCERR("Incompatible D3D11 serialise version, expected %d got %d", D3D11_SERIALISE_VERSION, ver); - return eReplayCreate_APIIncompatibleVersion; + bool oldsupported = false; + for(uint32_t i=0; i < D3D11_NUM_SUPPORTED_OLD_VERSIONS; i++) + { + if(ver == D3D11_OLD_VERSIONS[i]) + { + oldsupported = true; + RDCWARN("Old D3D11 serialise version %d, latest is %d. Loading with possibly degraded features/support.", ver, D3D11_SERIALISE_VERSION); + } + } + + if(!oldsupported) + { + RDCERR("Incompatible D3D11 serialise version, expected %d got %d", D3D11_SERIALISE_VERSION, ver); + return eReplayCreate_APIIncompatibleVersion; + } } SERIALISE_ELEMENT(D3D_DRIVER_TYPE, driverType, DriverType); DriverType = driverType; @@ -358,7 +378,7 @@ WrappedID3D11Device::WrappedID3D11Device(ID3D11Device* realDevice, D3D11InitPara RDCDEBUG("Couldn't get ID3D11InfoQueue."); } - m_InitParams = params; + m_InitParams = *params; SetContextFilter(ResourceId(), 0, 0); @@ -386,8 +406,6 @@ WrappedID3D11Device::WrappedID3D11Device(ID3D11Device* realDevice, D3D11InitPara WrappedID3D11Device::~WrappedID3D11Device() { - SAFE_DELETE(m_InitParams); - if(m_pCurrentWrappedDevice == this) m_pCurrentWrappedDevice = NULL; @@ -2669,7 +2687,7 @@ bool WrappedID3D11Device::EndFrameCapture(void *wnd) } } - Serialiser *m_pFileSerialiser = RenderDoc::Inst().OpenWriteSerialiser(m_FrameCounter, m_InitParams, jpgbuf, len, thwidth, thheight); + Serialiser *m_pFileSerialiser = RenderDoc::Inst().OpenWriteSerialiser(m_FrameCounter, &m_InitParams, jpgbuf, len, thwidth, thheight); SAFE_DELETE_ARRAY(jpgbuf); SAFE_DELETE(thpixels); diff --git a/renderdoc/driver/d3d11/d3d11_device.h b/renderdoc/driver/d3d11/d3d11_device.h index 5a5247848..2c98a00e0 100644 --- a/renderdoc/driver/d3d11/d3d11_device.h +++ b/renderdoc/driver/d3d11/d3d11_device.h @@ -63,7 +63,11 @@ struct D3D11InitParams : public RDCInitParams UINT NumFeatureLevels; D3D_FEATURE_LEVEL FeatureLevels[16]; - static const uint32_t D3D11_SERIALISE_VERSION = 0x0000004; + static const uint32_t D3D11_SERIALISE_VERSION = 0x0000005; + + // backwards compatibility for old logs described at the declaration of this array + static const uint32_t D3D11_NUM_SUPPORTED_OLD_VERSIONS = 1; + static const uint32_t D3D11_OLD_VERSIONS[D3D11_NUM_SUPPORTED_OLD_VERSIONS]; // version number internal to d3d11 stream uint32_t SerialiseVersion; @@ -159,7 +163,7 @@ private: D3D11DebugManager *m_DebugManager; D3D11ResourceManager *m_ResourceManager; - RDCInitParams *m_InitParams; + D3D11InitParams m_InitParams; ID3D11Device* m_pDevice; #if defined(INCLUDE_D3D_11_1) @@ -213,6 +217,8 @@ public: WrappedID3D11Device(ID3D11Device* realDevice, D3D11InitParams *params); void SetLogFile(const wchar_t *logfile); + void SetLogVersion(uint32_t fileversion) { m_InitParams.SerialiseVersion = fileversion; } + uint32_t GetLogVersion() { return m_InitParams.SerialiseVersion; } virtual ~WrappedID3D11Device(); //////////////////////////////////////////////////////////////// diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index d2ec01bad..f56fbeb92 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -1641,11 +1641,8 @@ ReplayCreateStatus D3D11_CreateReplayDevice(const wchar_t *logfile, IReplayDrive return status; } - if(initParams.SerialiseVersion != D3D11InitParams::D3D11_SERIALISE_VERSION) - { - RDCERR("Incompatible D3D11 serialise version, expected %d got %d", D3D11InitParams::D3D11_SERIALISE_VERSION, initParams.SerialiseVersion); - return eReplayCreate_APIIncompatibleVersion; - } + // initParams.SerialiseVersion is guaranteed to be valid/supported since otherwise the FillInitParams + // (which calls D3D11InitParams::Serialise) would have failed above, so no need to check it here. if(initParams.SDKVersion != D3D11_SDK_VERSION) { @@ -1699,10 +1696,12 @@ ReplayCreateStatus D3D11_CreateReplayDevice(const wchar_t *logfile, IReplayDrive if(SUCCEEDED(hr)) { - if(logfile) ((WrappedID3D11Device *)device)->SetLogFile(logfile); + WrappedID3D11Device *wrappedDev = (WrappedID3D11Device *)device; + if(logfile) wrappedDev->SetLogFile(logfile); + wrappedDev->SetLogVersion(initParams.SerialiseVersion); RDCLOG("Created device."); - D3D11Replay *replay = ((WrappedID3D11Device *)device)->GetReplay(); + D3D11Replay *replay = wrappedDev->GetReplay(); replay->SetProxy(logfile == NULL); diff --git a/renderdoc/hooks/d3d11_hooks.cpp b/renderdoc/hooks/d3d11_hooks.cpp index 8a31ad083..48274cde3 100644 --- a/renderdoc/hooks/d3d11_hooks.cpp +++ b/renderdoc/hooks/d3d11_hooks.cpp @@ -228,15 +228,15 @@ private: if(!WrappedID3D11Device::IsAlloc(*ppDevice)) { - D3D11InitParams *params = new D3D11InitParams; - params->DriverType = DriverType; - params->Flags = Flags; - params->SDKVersion = SDKVersion; - params->NumFeatureLevels = FeatureLevels; + D3D11InitParams params; + params.DriverType = DriverType; + params.Flags = Flags; + params.SDKVersion = SDKVersion; + params.NumFeatureLevels = FeatureLevels; if(FeatureLevels > 0) - memcpy(params->FeatureLevels, pFeatureLevels, sizeof(D3D_FEATURE_LEVEL)*FeatureLevels); + memcpy(params.FeatureLevels, pFeatureLevels, sizeof(D3D_FEATURE_LEVEL)*FeatureLevels); - WrappedID3D11Device *wrap = new WrappedID3D11Device(*ppDevice, params); + WrappedID3D11Device *wrap = new WrappedID3D11Device(*ppDevice, ¶ms); RDCDEBUG("created wrapped device.");