diff --git a/renderdoc/driver/d3d12/d3d12_command_list.h b/renderdoc/driver/d3d12/d3d12_command_list.h index 99f1abe81..9edd2e3ee 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list.h +++ b/renderdoc/driver/d3d12/d3d12_command_list.h @@ -33,10 +33,14 @@ struct IAmdExtD3DCommandListMarker; class WrappedID3D12GraphicsCommandList2; -struct WrappedID3D12DebugCommandList : public ID3D12DebugCommandList +// The inheritance is awful for these. See WrappedID3D12DebugDevice for why there are multiple +// parent classes +struct WrappedID3D12DebugCommandList : public ID3D12DebugCommandList2, public ID3D12DebugCommandList1 { WrappedID3D12GraphicsCommandList2 *m_pList; ID3D12DebugCommandList *m_pReal; + ID3D12DebugCommandList1 *m_pReal1; + ID3D12DebugCommandList2 *m_pReal2; WrappedID3D12DebugCommandList() : m_pList(NULL), m_pReal(NULL) {} ////////////////////////////// @@ -80,6 +84,31 @@ struct WrappedID3D12DebugCommandList : public ID3D12DebugCommandList return m_pReal->GetFeatureMask(); return D3D12_DEBUG_FEATURE_NONE; } + + ////////////////////////////// + // implement ID3D12DebugCommandList1 / ID3D12DebugCommandList2 + + virtual HRESULT STDMETHODCALLTYPE SetDebugParameter(D3D12_DEBUG_COMMAND_LIST_PARAMETER_TYPE Type, + _In_reads_bytes_(DataSize) const void *pData, + UINT DataSize) + { + if(m_pReal1) + return m_pReal1->SetDebugParameter(Type, pData, DataSize); + if(m_pReal2) + return m_pReal2->SetDebugParameter(Type, pData, DataSize); + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE GetDebugParameter(D3D12_DEBUG_COMMAND_LIST_PARAMETER_TYPE Type, + _Out_writes_bytes_(DataSize) void *pData, + UINT DataSize) + { + if(m_pReal1) + return m_pReal1->GetDebugParameter(Type, pData, DataSize); + if(m_pReal2) + return m_pReal2->GetDebugParameter(Type, pData, DataSize); + return S_OK; + } }; class WrappedID3D12GraphicsCommandList2 : public ID3D12GraphicsCommandList2 diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index 471bb5c36..9cb4718ed 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -785,6 +785,8 @@ WrappedID3D12GraphicsCommandList2::WrappedID3D12GraphicsCommandList2(ID3D12Graph if(m_pList) { m_pList->QueryInterface(__uuidof(ID3D12DebugCommandList), (void **)&m_WrappedDebug.m_pReal); + m_pList->QueryInterface(__uuidof(ID3D12DebugCommandList1), (void **)&m_WrappedDebug.m_pReal1); + m_pList->QueryInterface(__uuidof(ID3D12DebugCommandList2), (void **)&m_WrappedDebug.m_pReal2); m_pList1 = NULL; m_pList2 = NULL; @@ -862,6 +864,8 @@ WrappedID3D12GraphicsCommandList2::~WrappedID3D12GraphicsCommandList2() m_pDevice->GetResourceManager()->ReleaseCurrentResource(GetResourceID()); SAFE_RELEASE(m_WrappedDebug.m_pReal); + SAFE_RELEASE(m_WrappedDebug.m_pReal1); + SAFE_RELEASE(m_WrappedDebug.m_pReal2); SAFE_RELEASE(m_pList2); SAFE_RELEASE(m_pList1); SAFE_RELEASE(m_pList); diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index a2034ddb5..b74c9bf10 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -260,6 +260,8 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara { m_pDevice->QueryInterface(__uuidof(ID3D12InfoQueue), (void **)&m_pInfoQueue); m_pDevice->QueryInterface(__uuidof(ID3D12DebugDevice), (void **)&m_WrappedDebug.m_pDebug); + m_pDevice->QueryInterface(__uuidof(ID3D12DebugDevice1), (void **)&m_WrappedDebug.m_pDebug1); + m_pDevice->QueryInterface(__uuidof(ID3D12DebugDevice2), (void **)&m_WrappedDebug.m_pDebug2); } if(m_pInfoQueue) @@ -369,6 +371,8 @@ WrappedID3D12Device::~WrappedID3D12Device() SAFE_RELEASE(m_pInfoQueue); SAFE_RELEASE(m_WrappedDebug.m_pDebug); + SAFE_RELEASE(m_WrappedDebug.m_pDebug1); + SAFE_RELEASE(m_WrappedDebug.m_pDebug2); SAFE_RELEASE(m_pDevice); for(size_t i = 0; i < m_ThreadSerialisers.size(); i++) diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index 0ceecad82..12654f303 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -163,10 +163,16 @@ class WrappedID3D12Device; // We can pass through all calls to ID3D12DebugDevice without intercepting, this // struct isonly here so that we can intercept QueryInterface calls to return // ID3D11InfoQueue -struct WrappedID3D12DebugDevice : public ID3D12DebugDevice +// +// The inheritance is awful for these classes. ID3D12DebugDevice2 inherits from ID3D12DebugDevice +// but ID3D12DebugDevice1 is separate entirely, although its functions overlap with +// ID3D12DebugDevice2 and ID3D12DebugDevice +struct WrappedID3D12DebugDevice : public ID3D12DebugDevice2, public ID3D12DebugDevice1 { WrappedID3D12Device *m_pDevice; ID3D12DebugDevice *m_pDebug; + ID3D12DebugDevice1 *m_pDebug1; + ID3D12DebugDevice2 *m_pDebug2; WrappedID3D12DebugDevice() : m_pDevice(NULL), m_pDebug(NULL) {} ////////////////////////////// @@ -189,7 +195,32 @@ struct WrappedID3D12DebugDevice : public ID3D12DebugDevice virtual HRESULT STDMETHODCALLTYPE ReportLiveDeviceObjects(D3D12_RLDO_FLAGS Flags) { - return m_pDebug->ReportLiveDeviceObjects(Flags); + if(m_pDebug) + return m_pDebug->ReportLiveDeviceObjects(Flags); + else + return m_pDebug1->ReportLiveDeviceObjects(Flags); + } + + ////////////////////////////// + // implement ID3D12DebugDevice1 / ID3D12DebugDevice2 + virtual HRESULT STDMETHODCALLTYPE SetDebugParameter(D3D12_DEBUG_DEVICE_PARAMETER_TYPE Type, + _In_reads_bytes_(DataSize) const void *pData, + UINT DataSize) + { + if(m_pDebug1) + return m_pDebug1->SetDebugParameter(Type, pData, DataSize); + else + return m_pDebug2->SetDebugParameter(Type, pData, DataSize); + } + + virtual HRESULT STDMETHODCALLTYPE GetDebugParameter(D3D12_DEBUG_DEVICE_PARAMETER_TYPE Type, + _Out_writes_bytes_(DataSize) void *pData, + UINT DataSize) + { + if(m_pDebug1) + return m_pDebug1->GetDebugParameter(Type, pData, DataSize); + else + return m_pDebug2->GetDebugParameter(Type, pData, DataSize); } }; @@ -197,7 +228,10 @@ struct WrappedID3D12DebugDevice : public ID3D12DebugDevice // Same idea as DummyID3D12InfoQueue above, a dummy interface so that users // expecting a ID3D12DebugDevice don't get confused if we have turned off the debug // layer and can't return the real one. -struct DummyID3D12DebugDevice : public ID3D12DebugDevice +// +// The inheritance is awful for these. See WrappedID3D12DebugDevice for why there are multiple +// parent classes +struct DummyID3D12DebugDevice : public ID3D12DebugDevice2, public ID3D12DebugDevice1 { WrappedID3D12Device *m_pDevice; @@ -217,6 +251,21 @@ struct DummyID3D12DebugDevice : public ID3D12DebugDevice } virtual HRESULT STDMETHODCALLTYPE ReportLiveDeviceObjects(D3D12_RLDO_FLAGS Flags) { return S_OK; } + ////////////////////////////// + // implement ID3D12DebugDevice1 / ID3D12DebugDevice2 + virtual HRESULT STDMETHODCALLTYPE SetDebugParameter(D3D12_DEBUG_DEVICE_PARAMETER_TYPE Type, + _In_reads_bytes_(DataSize) const void *pData, + UINT DataSize) + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE GetDebugParameter(D3D12_DEBUG_DEVICE_PARAMETER_TYPE Type, + _Out_writes_bytes_(DataSize) void *pData, + UINT DataSize) + { + return S_OK; + } }; class WrappedID3D12CommandQueue; diff --git a/renderdoc/driver/d3d12/d3d12_hooks.cpp b/renderdoc/driver/d3d12/d3d12_hooks.cpp index ceeb587c1..d00e56cc8 100644 --- a/renderdoc/driver/d3d12/d3d12_hooks.cpp +++ b/renderdoc/driver/d3d12/d3d12_hooks.cpp @@ -53,7 +53,13 @@ ID3DDevice *GetD3D12DeviceIfAlloc(IUnknown *dev) } // dummy class to present to the user, while we maintain control -class WrappedID3D12Debug : public RefCounter12, public ID3D12Debug, public ID3D12Debug1 +// +// The inheritance is awful for these. See WrappedID3D12DebugDevice for why there are multiple +// parent classes +class WrappedID3D12Debug : public RefCounter12, + public ID3D12Debug3, + public ID3D12Debug1, + public ID3D12Debug2 { public: WrappedID3D12Debug() : RefCounter12(NULL) {} @@ -82,17 +88,33 @@ public: AddRef(); return S_OK; } + if(riid == __uuidof(ID3D12Debug2)) + { + *ppvObject = (ID3D12Debug2 *)this; + AddRef(); + return S_OK; + } + if(riid == __uuidof(ID3D12Debug3)) + { + *ppvObject = (ID3D12Debug3 *)this; + AddRef(); + return S_OK; + } return E_NOINTERFACE; } ////////////////////////////// - // Implement ID3D12Debug + // Implement ID3D12Debug / ID3D12Debug1 virtual void STDMETHODCALLTYPE EnableDebugLayer() {} ////////////////////////////// - // Implement ID3D12Debug1 + // Implement ID3D12Debug1 / ID3D12Debug3 virtual void STDMETHODCALLTYPE SetEnableGPUBasedValidation(BOOL Enable) {} virtual void STDMETHODCALLTYPE SetEnableSynchronizedCommandQueueValidation(BOOL Enable) {} + // Implement ID3D12Debug2 / ID3D12Debug3 + virtual void STDMETHODCALLTYPE SetGPUBasedValidationFlags(D3D12_GPU_BASED_VALIDATION_FLAGS Flags) + { + } }; class D3D12Hook : LibraryHook @@ -291,6 +313,26 @@ private: static HRESULT WINAPI D3D12GetDebugInterface_hook(REFIID riid, void **ppvDebug) { if(riid != __uuidof(ID3D12Debug)) + { + *ppvDebug = (ID3D12Debug *)(new WrappedID3D12Debug()); + return S_OK; + } + else if(riid != __uuidof(ID3D12Debug1)) + { + *ppvDebug = (ID3D12Debug1 *)(new WrappedID3D12Debug()); + return S_OK; + } + else if(riid != __uuidof(ID3D12Debug2)) + { + *ppvDebug = (ID3D12Debug2 *)(new WrappedID3D12Debug()); + return S_OK; + } + else if(riid != __uuidof(ID3D12Debug3)) + { + *ppvDebug = (ID3D12Debug3 *)(new WrappedID3D12Debug()); + return S_OK; + } + else { IUnknown *releaseme = NULL; HRESULT real = d3d12hooks.GetDebugInterface()(riid, (void **)&releaseme); @@ -303,9 +345,6 @@ private: return E_NOINTERFACE; } - - *ppvDebug = (ID3D12Debug *)(new WrappedID3D12Debug()); - return S_OK; } };