mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-21 14:06:45 +00:00
Add support for capturing programs using new D3D12 DLL selection API
* We also use it for replay when available instead of self-function-hooking
This commit is contained in:
@@ -256,22 +256,46 @@ void BarrierSet::Unapply(ID3D12GraphicsCommandListX *list)
|
||||
RDCASSERT(newToOldBarriers.empty());
|
||||
}
|
||||
|
||||
bool EnableD3D12DebugLayer(PFN_D3D12_GET_DEBUG_INTERFACE getDebugInterface)
|
||||
bool EnableD3D12DebugLayer(D3D12DevConfiguration *devConfig,
|
||||
PFN_D3D12_GET_DEBUG_INTERFACE getDebugInterface)
|
||||
{
|
||||
if(!getDebugInterface)
|
||||
getDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)GetProcAddress(GetModuleHandleA("d3d12.dll"),
|
||||
"D3D12GetDebugInterface");
|
||||
|
||||
if(!getDebugInterface)
|
||||
ID3D12Debug *debug = NULL;
|
||||
if(devConfig)
|
||||
{
|
||||
RDCERR("Couldn't find D3D12GetDebugInterface!");
|
||||
return false;
|
||||
if(devConfig->debug)
|
||||
{
|
||||
debug = devConfig->debug;
|
||||
debug->AddRef();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!getDebugInterface)
|
||||
getDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)GetProcAddress(
|
||||
GetModuleHandleA("d3d12.dll"), "D3D12GetDebugInterface");
|
||||
|
||||
if(!getDebugInterface)
|
||||
{
|
||||
RDCERR("Couldn't find D3D12GetDebugInterface!");
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT hr = getDebugInterface(__uuidof(ID3D12Debug), (void **)&debug);
|
||||
|
||||
if(FAILED(hr))
|
||||
SAFE_RELEASE(debug);
|
||||
|
||||
if(hr == DXGI_ERROR_SDK_COMPONENT_MISSING)
|
||||
{
|
||||
RDCWARN("Debug layer not available: DXGI_ERROR_SDK_COMPONENT_MISSING");
|
||||
}
|
||||
else if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Couldn't enable debug layer: %x", hr);
|
||||
}
|
||||
}
|
||||
|
||||
ID3D12Debug *debug = NULL;
|
||||
HRESULT hr = getDebugInterface(__uuidof(ID3D12Debug), (void **)&debug);
|
||||
|
||||
if(SUCCEEDED(hr) && debug)
|
||||
if(debug)
|
||||
{
|
||||
debug->EnableDebugLayer();
|
||||
|
||||
@@ -298,14 +322,6 @@ bool EnableD3D12DebugLayer(PFN_D3D12_GET_DEBUG_INTERFACE getDebugInterface)
|
||||
|
||||
return true;
|
||||
}
|
||||
else if(hr == DXGI_ERROR_SDK_COMPONENT_MISSING)
|
||||
{
|
||||
RDCWARN("Debug layer not available: DXGI_ERROR_SDK_COMPONENT_MISSING");
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Couldn't enable debug layer: %x", hr);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -56,11 +56,21 @@ struct D3D12MarkerRegion
|
||||
ID3D12CommandQueue *queue = NULL;
|
||||
};
|
||||
|
||||
bool EnableD3D12DebugLayer(PFN_D3D12_GET_DEBUG_INTERFACE getDebugInterface = NULL);
|
||||
struct D3D12DevConfiguration
|
||||
{
|
||||
ID3D12SDKConfiguration1 *sdkconfig = NULL;
|
||||
ID3D12DeviceFactory *devfactory = NULL;
|
||||
ID3D12DeviceConfiguration *devconfig = NULL;
|
||||
ID3D12Debug *debug = NULL;
|
||||
};
|
||||
|
||||
bool EnableD3D12DebugLayer(D3D12DevConfiguration *devConfig,
|
||||
PFN_D3D12_GET_DEBUG_INTERFACE getDebugInterface);
|
||||
HRESULT EnumAdapterByLuid(IDXGIFactory1 *factory, LUID luid, IDXGIAdapter **pAdapter);
|
||||
|
||||
void D3D12_PrepareReplaySDKVersion(bool untrustedCapture, UINT SDKVersion, bytebuf d3d12core,
|
||||
bytebuf d3d12sdklayers, HMODULE d3d12lib);
|
||||
D3D12DevConfiguration *D3D12_PrepareReplaySDKVersion(bool untrustedCapture, UINT SDKVersion,
|
||||
bytebuf d3d12core, bytebuf d3d12sdklayers,
|
||||
HMODULE d3d12lib);
|
||||
void D3D12_CleanupReplaySDK();
|
||||
|
||||
inline void SetObjName(ID3D12Object *obj, const rdcstr &utf8name)
|
||||
@@ -335,6 +345,87 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class WrappedID3D12DeviceConfiguration : public ID3D12DeviceConfiguration
|
||||
{
|
||||
private:
|
||||
ID3D12DeviceConfiguration *m_pReal = NULL;
|
||||
IUnknown *wrappedParent = NULL;
|
||||
public:
|
||||
WrappedID3D12DeviceConfiguration(IUnknown *real, IUnknown *wrapped)
|
||||
{
|
||||
wrappedParent = wrapped;
|
||||
|
||||
if(real)
|
||||
{
|
||||
HRESULT hr = real->QueryInterface(__uuidof(ID3D12DeviceConfiguration), (void **)&m_pReal);
|
||||
if(FAILED(hr))
|
||||
SAFE_RELEASE(m_pReal);
|
||||
}
|
||||
}
|
||||
|
||||
~WrappedID3D12DeviceConfiguration() { SAFE_RELEASE(m_pReal); }
|
||||
|
||||
bool IsValid() { return m_pReal != NULL; }
|
||||
|
||||
//////////////////////////////
|
||||
// Implement IUnknown
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return wrappedParent->AddRef(); }
|
||||
ULONG STDMETHODCALLTYPE Release() { return wrappedParent->Release(); }
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(IUnknown))
|
||||
{
|
||||
*ppvObject = (IUnknown *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
if(riid == __uuidof(ID3D12DeviceConfiguration) && m_pReal)
|
||||
{
|
||||
*ppvObject = (ID3D12DeviceConfiguration *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return wrappedParent->QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Implement ID3D12DeviceConfiguration
|
||||
#if defined(_MSC_VER) || !defined(_WIN32)
|
||||
virtual D3D12_DEVICE_CONFIGURATION_DESC STDMETHODCALLTYPE GetDesc(void)
|
||||
{
|
||||
return m_pReal->GetDesc();
|
||||
}
|
||||
#else
|
||||
virtual D3D12_DEVICE_CONFIGURATION_DESC *STDMETHODCALLTYPE
|
||||
GetDesc(D3D12_DEVICE_CONFIGURATION_DESC *RetVal)
|
||||
{
|
||||
return m_pReal->GetDesc(RetVal);
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetEnabledExperimentalFeatures(_Out_writes_(NumGuids)
|
||||
GUID *pGuids,
|
||||
UINT NumGuids)
|
||||
{
|
||||
return m_pReal->GetEnabledExperimentalFeatures(pGuids, NumGuids);
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SerializeVersionedRootSignature(
|
||||
_In_ const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *pDesc, _COM_Outptr_ ID3DBlob **ppResult,
|
||||
_Always_(_Outptr_opt_result_maybenull_) ID3DBlob **ppError)
|
||||
{
|
||||
return m_pReal->SerializeVersionedRootSignature(pDesc, ppResult, ppError);
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE
|
||||
CreateVersionedRootSignatureDeserializer(_In_reads_bytes_(Size) const void *pBlob, SIZE_T Size,
|
||||
REFIID riid, _COM_Outptr_ void **ppvDeserializer)
|
||||
{
|
||||
return m_pReal->CreateVersionedRootSignatureDeserializer(pBlob, Size, riid, ppvDeserializer);
|
||||
}
|
||||
};
|
||||
|
||||
struct D3D12RootSignatureParameter : D3D12_ROOT_PARAMETER1
|
||||
{
|
||||
D3D12RootSignatureParameter()
|
||||
|
||||
@@ -65,6 +65,13 @@ rdcstr WrappedID3D12Device::GetChunkName(uint32_t idx)
|
||||
return ToStr((D3D12Chunk)idx);
|
||||
}
|
||||
|
||||
D3D12ShaderCache *WrappedID3D12Device::GetShaderCache()
|
||||
{
|
||||
if(m_ShaderCache == NULL)
|
||||
m_ShaderCache = new D3D12ShaderCache(this);
|
||||
return m_ShaderCache;
|
||||
}
|
||||
|
||||
D3D12DebugManager *WrappedID3D12Device::GetDebugManager()
|
||||
{
|
||||
return m_Replay->GetDebugManager();
|
||||
@@ -504,6 +511,7 @@ BOOL STDMETHODCALLTYPE WrappedAGS12::ExtensionsSupported()
|
||||
WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitParams params,
|
||||
bool enabledDebugLayer)
|
||||
: m_RefCounter(realDevice, false),
|
||||
m_DevConfig(realDevice, this),
|
||||
m_SoftRefCounter(NULL, false),
|
||||
m_pDevice(realDevice),
|
||||
m_debugLayerEnabled(enabledDebugLayer),
|
||||
@@ -1222,6 +1230,17 @@ HRESULT WrappedID3D12Device::QueryInterface(REFIID riid, void **ppvObject)
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12DeviceConfiguration))
|
||||
{
|
||||
if(m_DevConfig.IsValid())
|
||||
{
|
||||
*ppvObject = (ID3D12DeviceConfiguration *)&m_DevConfig;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12DeviceDownlevel))
|
||||
{
|
||||
if(m_pDownlevel)
|
||||
@@ -4116,8 +4135,7 @@ void WrappedID3D12Device::CreateInternalResources()
|
||||
|
||||
m_GPUSyncCounter = 0;
|
||||
|
||||
if(m_ShaderCache == NULL)
|
||||
m_ShaderCache = new D3D12ShaderCache(this);
|
||||
GetShaderCache()->SetDevConfiguration(m_Replay->GetDevConfiguration());
|
||||
|
||||
if(m_TextRenderer == NULL)
|
||||
m_TextRenderer = new D3D12TextRenderer(this);
|
||||
|
||||
@@ -606,6 +606,8 @@ private:
|
||||
ID3D12Device12 *m_pDevice12;
|
||||
ID3D12DeviceDownlevel *m_pDownlevel;
|
||||
|
||||
WrappedID3D12DeviceConfiguration m_DevConfig;
|
||||
|
||||
// list of all queues being captured
|
||||
rdcarray<WrappedID3D12CommandQueue *> m_Queues;
|
||||
rdcarray<ID3D12Fence *> m_QueueFences;
|
||||
@@ -886,7 +888,7 @@ public:
|
||||
ID3D12Device9 *GetReal9() const { return m_pDevice9; }
|
||||
static rdcstr GetChunkName(uint32_t idx);
|
||||
D3D12ResourceManager *GetResourceManager() { return m_ResourceManager; }
|
||||
D3D12ShaderCache *GetShaderCache() { return m_ShaderCache; }
|
||||
D3D12ShaderCache *GetShaderCache();
|
||||
D3D12DebugManager *GetDebugManager();
|
||||
ResourceId GetResourceID() { return m_ResourceID; }
|
||||
Threading::RWLock &GetCapTransitionLock() { return m_CapTransitionLock; }
|
||||
|
||||
@@ -192,6 +192,297 @@ public:
|
||||
virtual void STDMETHODCALLTYPE SetForceLegacyBarrierValidation(BOOL Enable) {}
|
||||
};
|
||||
|
||||
class WrappedID3D12Tools : public RefCounter12<ID3D12Tools>, public ID3D12Tools
|
||||
{
|
||||
BOOL m_Instrumentation = FALSE;
|
||||
public:
|
||||
WrappedID3D12Tools() : RefCounter12(NULL) {}
|
||||
virtual ~WrappedID3D12Tools() {}
|
||||
//////////////////////////////
|
||||
// Implement IUnknown
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return RefCounter12::AddRef(); }
|
||||
ULONG STDMETHODCALLTYPE Release() { return RefCounter12::Release(); }
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(IUnknown))
|
||||
{
|
||||
*ppvObject = (IUnknown *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
if(riid == __uuidof(ID3D12Tools))
|
||||
{
|
||||
*ppvObject = (ID3D12Tools *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Implement ID3D12Tools
|
||||
virtual void STDMETHODCALLTYPE EnableShaderInstrumentation(BOOL bEnable)
|
||||
{
|
||||
m_Instrumentation = bEnable;
|
||||
}
|
||||
|
||||
virtual BOOL STDMETHODCALLTYPE ShaderInstrumentationEnabled(void) { return m_Instrumentation; }
|
||||
};
|
||||
|
||||
class WrappedID3D12DeviceRemovedExtendedData : public RefCounter12<ID3D12DeviceRemovedExtendedData1>,
|
||||
public ID3D12DeviceRemovedExtendedData1
|
||||
{
|
||||
public:
|
||||
WrappedID3D12DeviceRemovedExtendedData() : RefCounter12(NULL) {}
|
||||
virtual ~WrappedID3D12DeviceRemovedExtendedData() {}
|
||||
//////////////////////////////
|
||||
// Implement IUnknown
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return RefCounter12::AddRef(); }
|
||||
ULONG STDMETHODCALLTYPE Release() { return RefCounter12::Release(); }
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(IUnknown))
|
||||
{
|
||||
*ppvObject = (IUnknown *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
if(riid == __uuidof(ID3D12DeviceRemovedExtendedData))
|
||||
{
|
||||
*ppvObject = (ID3D12DeviceRemovedExtendedData *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
if(riid == __uuidof(ID3D12DeviceRemovedExtendedData1))
|
||||
{
|
||||
*ppvObject = (ID3D12DeviceRemovedExtendedData1 *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Implement ID3D12DeviceRemovedExtendedData
|
||||
virtual HRESULT STDMETHODCALLTYPE
|
||||
GetAutoBreadcrumbsOutput(_Out_ D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT *pOutput)
|
||||
{
|
||||
return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE
|
||||
GetPageFaultAllocationOutput(_Out_ D3D12_DRED_PAGE_FAULT_OUTPUT *pOutput)
|
||||
{
|
||||
return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Implement ID3D12DeviceRemovedExtendedData1
|
||||
virtual HRESULT STDMETHODCALLTYPE
|
||||
GetAutoBreadcrumbsOutput1(_Out_ D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT1 *pOutput)
|
||||
{
|
||||
return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE
|
||||
GetPageFaultAllocationOutput1(_Out_ D3D12_DRED_PAGE_FAULT_OUTPUT1 *pOutput)
|
||||
{
|
||||
return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
|
||||
}
|
||||
};
|
||||
|
||||
class WrappedID3D12DeviceFactory : public RefCounter12<ID3D12DeviceFactory>, public ID3D12DeviceFactory
|
||||
{
|
||||
WrappedID3D12DeviceConfiguration config;
|
||||
public:
|
||||
WrappedID3D12DeviceFactory(ID3D12DeviceFactory *real) : RefCounter12(real), config(real, this) {}
|
||||
|
||||
virtual ~WrappedID3D12DeviceFactory() {}
|
||||
//////////////////////////////
|
||||
// Implement IUnknown
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return RefCounter12::AddRef(); }
|
||||
ULONG STDMETHODCALLTYPE Release() { return RefCounter12::Release(); }
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(IUnknown))
|
||||
{
|
||||
*ppvObject = (IUnknown *)(ID3D12DeviceFactory *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
if(riid == __uuidof(ID3D12DeviceFactory))
|
||||
{
|
||||
*ppvObject = (ID3D12DeviceFactory *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
if(riid == __uuidof(ID3D12DeviceConfiguration) && config.IsValid())
|
||||
{
|
||||
*ppvObject = (ID3D12DeviceConfiguration *)&config;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Implement ID3D12DeviceFactory
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE InitializeFromGlobalState(void)
|
||||
{
|
||||
return m_pReal->InitializeFromGlobalState();
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE ApplyToGlobalState(void)
|
||||
{
|
||||
return m_pReal->ApplyToGlobalState();
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetFlags(D3D12_DEVICE_FACTORY_FLAGS flags)
|
||||
{
|
||||
return m_pReal->SetFlags(flags);
|
||||
}
|
||||
|
||||
virtual D3D12_DEVICE_FACTORY_FLAGS STDMETHODCALLTYPE GetFlags(void)
|
||||
{
|
||||
return m_pReal->GetFlags();
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetConfigurationInterface(REFCLSID clsid, REFIID iid,
|
||||
_COM_Outptr_ void **ppv);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE
|
||||
EnableExperimentalFeatures(UINT NumFeatures, _In_reads_(NumFeatures) const IID *pIIDs,
|
||||
_In_reads_opt_(NumFeatures) void *pConfigurationStructs,
|
||||
_In_reads_opt_(NumFeatures) UINT *pConfigurationStructSizes)
|
||||
{
|
||||
rdcarray<IID> allowedIIDs;
|
||||
|
||||
// allow enabling unsigned DXIL.
|
||||
for(UINT i = 0; i < NumFeatures; i++)
|
||||
{
|
||||
if(pIIDs[i] == D3D12ExperimentalShaderModels)
|
||||
allowedIIDs.push_back(D3D12ExperimentalShaderModels);
|
||||
}
|
||||
|
||||
// there's no "partially successful" error code, so we just lie to the application and pretend
|
||||
// that any filtered IIDs also succeeded
|
||||
if(!allowedIIDs.empty())
|
||||
return m_pReal->EnableExperimentalFeatures((UINT)allowedIIDs.size(), allowedIIDs.data(), NULL,
|
||||
NULL);
|
||||
|
||||
// header says "The call returns E_NOINTERFACE if an unrecognized feature is passed in or
|
||||
// Windows Developer mode is not on." so this is the most appropriate error for if no IIDs are
|
||||
// allowed.
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateDevice(_In_opt_ IUnknown *adapter,
|
||||
D3D_FEATURE_LEVEL FeatureLevel, REFIID riid,
|
||||
_COM_Outptr_opt_ void **ppvDevice)
|
||||
{
|
||||
if(RenderDoc::Inst().GetCaptureOptions().apiValidation)
|
||||
{
|
||||
D3D12DevConfiguration tmpConfig = {};
|
||||
HRESULT hr = m_pReal->GetConfigurationInterface(CLSID_D3D12Debug, __uuidof(ID3D12Debug),
|
||||
(void **)&tmpConfig.debug);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
EnableD3D12DebugLayer(&tmpConfig, NULL);
|
||||
SAFE_RELEASE(tmpConfig.debug);
|
||||
}
|
||||
}
|
||||
|
||||
return CreateD3D12_Internal(
|
||||
[this](IUnknown *pAdapter, D3D_FEATURE_LEVEL MinimumFeatureLevel, REFIID riid,
|
||||
void **ppDevice) {
|
||||
return m_pReal->CreateDevice(pAdapter, MinimumFeatureLevel, riid, ppDevice);
|
||||
},
|
||||
adapter, FeatureLevel, riid, ppvDevice);
|
||||
}
|
||||
};
|
||||
|
||||
class WrappedID3D12SDKConfiguration : public RefCounter12<ID3D12SDKConfiguration>,
|
||||
public ID3D12SDKConfiguration1
|
||||
{
|
||||
ID3D12SDKConfiguration1 *m_pReal1 = NULL;
|
||||
public:
|
||||
WrappedID3D12SDKConfiguration(ID3D12SDKConfiguration *real, ID3D12SDKConfiguration1 *real1)
|
||||
: RefCounter12(real)
|
||||
{
|
||||
if(!real1)
|
||||
real->QueryInterface(__uuidof(ID3D12SDKConfiguration1), (void **)&real1);
|
||||
m_pReal1 = real1;
|
||||
}
|
||||
virtual ~WrappedID3D12SDKConfiguration()
|
||||
{
|
||||
SAFE_RELEASE(m_pReal);
|
||||
SAFE_RELEASE(m_pReal1);
|
||||
}
|
||||
//////////////////////////////
|
||||
// Implement IUnknown
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return RefCounter12::AddRef(); }
|
||||
ULONG STDMETHODCALLTYPE Release() { return RefCounter12::Release(); }
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(IUnknown))
|
||||
{
|
||||
*ppvObject = (IUnknown *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
if(riid == __uuidof(ID3D12SDKConfiguration))
|
||||
{
|
||||
*ppvObject = (ID3D12SDKConfiguration *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
if(riid == __uuidof(ID3D12SDKConfiguration1))
|
||||
{
|
||||
*ppvObject = (ID3D12SDKConfiguration1 *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Implement ID3D12SDKConfiguration
|
||||
virtual HRESULT STDMETHODCALLTYPE SetSDKVersion(UINT SDKVersion, _In_z_ LPCSTR SDKPath)
|
||||
{
|
||||
return m_pReal->SetSDKVersion(SDKVersion, SDKPath);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Implement ID3D12SDKConfiguration1
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateDeviceFactory(UINT SDKVersion, _In_ LPCSTR SDKPath,
|
||||
REFIID riid, _COM_Outptr_ void **ppvFactory)
|
||||
{
|
||||
if(riid != __uuidof(ID3D12DeviceFactory))
|
||||
{
|
||||
RDCERR("Unexpected uuid to CreateDeviceFactory: %s", ToStr(riid).c_str());
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ID3D12DeviceFactory *realFactory = NULL;
|
||||
HRESULT hr = m_pReal1->CreateDeviceFactory(SDKVersion, SDKPath, riid, (void **)&realFactory);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
RDCASSERT(realFactory);
|
||||
*ppvFactory = (ID3D12DeviceFactory *)(new WrappedID3D12DeviceFactory(realFactory));
|
||||
return hr;
|
||||
}
|
||||
SAFE_RELEASE(realFactory);
|
||||
return hr;
|
||||
}
|
||||
|
||||
virtual void STDMETHODCALLTYPE FreeUnusedSDKs(void) { return m_pReal1->FreeUnusedSDKs(); }
|
||||
};
|
||||
|
||||
class D3D12Hook : LibraryHook
|
||||
{
|
||||
public:
|
||||
@@ -212,6 +503,7 @@ public:
|
||||
|
||||
CreateDevice.Register("d3d12.dll", "D3D12CreateDevice", D3D12CreateDevice_hook);
|
||||
GetDebugInterface.Register("d3d12.dll", "D3D12GetDebugInterface", D3D12GetDebugInterface_hook);
|
||||
GetInterface.Register("d3d12.dll", "D3D12GetInterface", D3D12GetInterface_hook);
|
||||
EnableExperimentalFeatures.Register("d3d12.dll", "D3D12EnableExperimentalFeatures",
|
||||
D3D12EnableExperimentalFeatures_hook);
|
||||
GetD3D11On12On7.Register("d3d11on12.dll", "GetD3D11On12On7Interface",
|
||||
@@ -221,10 +513,99 @@ public:
|
||||
Threading::SetTLSValue(m_RecurseSlot, NULL);
|
||||
}
|
||||
|
||||
static HRESULT GetWrappedInterface(IUnknown *realUnk, REFIID riid, void **ppvInterface)
|
||||
{
|
||||
if(riid == __uuidof(ID3D12Debug))
|
||||
{
|
||||
*ppvInterface = (ID3D12Debug *)(new WrappedID3D12Debug());
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12Debug1))
|
||||
{
|
||||
*ppvInterface = (ID3D12Debug1 *)(new WrappedID3D12Debug());
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12Debug2))
|
||||
{
|
||||
*ppvInterface = (ID3D12Debug2 *)(new WrappedID3D12Debug());
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12Debug3))
|
||||
{
|
||||
*ppvInterface = (ID3D12Debug3 *)(new WrappedID3D12Debug());
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12Debug4))
|
||||
{
|
||||
*ppvInterface = (ID3D12Debug4 *)(new WrappedID3D12Debug());
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12Debug5))
|
||||
{
|
||||
*ppvInterface = (ID3D12Debug5 *)(new WrappedID3D12Debug());
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12Debug6))
|
||||
{
|
||||
*ppvInterface = (ID3D12Debug6 *)(new WrappedID3D12Debug());
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12Tools))
|
||||
{
|
||||
*ppvInterface = (ID3D12Tools *)(new WrappedID3D12Tools());
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12DeviceRemovedExtendedData))
|
||||
{
|
||||
*ppvInterface =
|
||||
(ID3D12DeviceRemovedExtendedData *)(new WrappedID3D12DeviceRemovedExtendedData());
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12DeviceRemovedExtendedData1))
|
||||
{
|
||||
*ppvInterface =
|
||||
(ID3D12DeviceRemovedExtendedData1 *)(new WrappedID3D12DeviceRemovedExtendedData());
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12DeviceRemovedExtendedData2))
|
||||
{
|
||||
*ppvInterface =
|
||||
(ID3D12DeviceRemovedExtendedData2 *)(new WrappedID3D12DeviceRemovedExtendedData());
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12SDKConfiguration))
|
||||
{
|
||||
ID3D12SDKConfiguration *real = (ID3D12SDKConfiguration *)realUnk;
|
||||
if(real)
|
||||
{
|
||||
// take a reference ourselves, realUnk is a transient pointer and will be released after this function returns
|
||||
real->AddRef();
|
||||
*ppvInterface = (ID3D12SDKConfiguration *)(new WrappedID3D12SDKConfiguration(real, NULL));
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12SDKConfiguration1))
|
||||
{
|
||||
ID3D12SDKConfiguration1 *real1 = (ID3D12SDKConfiguration1 *)realUnk;
|
||||
if(real1)
|
||||
{
|
||||
// take a reference ourselves, realUnk is a transient pointer and will be released after this function returns
|
||||
real1->AddRef();
|
||||
ID3D12SDKConfiguration *real = NULL;
|
||||
real1->QueryInterface(__uuidof(ID3D12SDKConfiguration), (void **)&real);
|
||||
*ppvInterface = (ID3D12SDKConfiguration1 *)(new WrappedID3D12SDKConfiguration(real, real1));
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
private:
|
||||
static D3D12Hook d3d12hooks;
|
||||
|
||||
HookedFunction<PFN_D3D12_GET_DEBUG_INTERFACE> GetDebugInterface;
|
||||
HookedFunction<PFN_D3D12_GET_INTERFACE> GetInterface;
|
||||
HookedFunction<PFN_D3D12_CREATE_DEVICE> CreateDevice;
|
||||
HookedFunction<PFN_D3D12_ENABLE_EXPERIMENTAL_FEATURES> EnableExperimentalFeatures;
|
||||
HookedFunction<PFNGetD3D11On12On7Interface> GetD3D11On12On7;
|
||||
@@ -276,7 +657,7 @@ private:
|
||||
bool EnableDebugLayer = false;
|
||||
|
||||
if(RenderDoc::Inst().GetCaptureOptions().apiValidation)
|
||||
EnableDebugLayer = EnableD3D12DebugLayer(GetDebugInterface());
|
||||
EnableDebugLayer = EnableD3D12DebugLayer(NULL, GetDebugInterface());
|
||||
|
||||
RDCDEBUG("Calling real createdevice...");
|
||||
|
||||
@@ -460,54 +841,40 @@ 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 if(riid == __uuidof(ID3D12Debug4))
|
||||
{
|
||||
*ppvDebug = (ID3D12Debug4 *)(new WrappedID3D12Debug());
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12Debug5))
|
||||
{
|
||||
*ppvDebug = (ID3D12Debug5 *)(new WrappedID3D12Debug());
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12Debug6))
|
||||
{
|
||||
*ppvDebug = (ID3D12Debug6 *)(new WrappedID3D12Debug());
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
IUnknown *releaseme = NULL;
|
||||
HRESULT real = d3d12hooks.GetDebugInterface()(riid, (void **)&releaseme);
|
||||
IUnknown *realUnk = NULL;
|
||||
HRESULT real = d3d12hooks.GetDebugInterface()(riid, (void **)&realUnk);
|
||||
|
||||
if(releaseme)
|
||||
releaseme->Release();
|
||||
HRESULT hr = GetWrappedInterface(realUnk, riid, ppvDebug);
|
||||
|
||||
RDCWARN("Unknown UUID passed to D3D12GetDebugInterface: %s. Real call %s succeed (%x).",
|
||||
ToStr(riid).c_str(), SUCCEEDED(real) ? "did" : "did not", real);
|
||||
if(realUnk)
|
||||
realUnk->Release();
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
if(SUCCEEDED(hr))
|
||||
return hr;
|
||||
|
||||
RDCWARN("Unknown UUID passed to D3D12GetDebugInterface: %s. Real call %s succeed (%x).",
|
||||
ToStr(riid).c_str(), SUCCEEDED(real) ? "did" : "did not", real);
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI D3D12GetInterface_hook(REFCLSID rclsid, REFIID riid, void **ppvDebug)
|
||||
{
|
||||
IUnknown *realUnk = NULL;
|
||||
HRESULT real = d3d12hooks.GetInterface()(rclsid, riid, (void **)&realUnk);
|
||||
|
||||
HRESULT hr = GetWrappedInterface(realUnk, riid, ppvDebug);
|
||||
|
||||
if(realUnk)
|
||||
realUnk->Release();
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
return hr;
|
||||
|
||||
RDCWARN("Unknown UUID passed to D3D12GetInterface: %s (clsid %s). Real call %s succeed (%x).",
|
||||
ToStr(riid).c_str(), ToStr(rclsid).c_str(), SUCCEEDED(real) ? "did" : "did not", real);
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -518,3 +885,23 @@ HRESULT CreateD3D12_Internal(RealD3D12CreateFunction real, IUnknown *pAdapter,
|
||||
{
|
||||
return D3D12Hook::d3d12hooks.Create_Internal(real, pAdapter, MinimumFeatureLevel, riid, ppDevice);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedID3D12DeviceFactory::GetConfigurationInterface(
|
||||
REFCLSID clsid, REFIID iid, _COM_Outptr_ void **ppv)
|
||||
{
|
||||
IUnknown *realUnk = NULL;
|
||||
HRESULT real = m_pReal->GetConfigurationInterface(clsid, iid, (void **)&realUnk);
|
||||
|
||||
HRESULT hr = D3D12Hook::GetWrappedInterface(realUnk, iid, ppv);
|
||||
|
||||
if(realUnk)
|
||||
realUnk->Release();
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
return hr;
|
||||
|
||||
RDCWARN("Unknown UUID passed to D3D12GetDebugInterface: %s. Real call %s succeed (%x).",
|
||||
ToStr(iid).c_str(), SUCCEEDED(real) ? "did" : "did not", real);
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
@@ -73,6 +73,18 @@ void D3D12Replay::Shutdown()
|
||||
|
||||
SAFE_DELETE(m_RGP);
|
||||
|
||||
if(m_DevConfig)
|
||||
{
|
||||
SAFE_RELEASE(m_DevConfig->debug);
|
||||
SAFE_RELEASE(m_DevConfig->devconfig);
|
||||
SAFE_RELEASE(m_DevConfig->devfactory);
|
||||
|
||||
m_DevConfig->sdkconfig->FreeUnusedSDKs();
|
||||
SAFE_DELETE(m_DevConfig->sdkconfig);
|
||||
SAFE_DELETE(m_DevConfig);
|
||||
}
|
||||
|
||||
// this destroys the replay object
|
||||
m_pDevice->Release();
|
||||
|
||||
// the this pointer is free'd after this point
|
||||
@@ -90,9 +102,10 @@ void D3D12Replay::Shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12Replay::Initialise(IDXGIFactory1 *factory)
|
||||
void D3D12Replay::Initialise(IDXGIFactory1 *factory, D3D12DevConfiguration *config)
|
||||
{
|
||||
m_pFactory = factory;
|
||||
m_DevConfig = config;
|
||||
|
||||
RDCEraseEl(m_DriverInfo);
|
||||
|
||||
@@ -4557,8 +4570,8 @@ RDResult D3D12_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, IRepl
|
||||
if(initParams.MinimumFeatureLevel < D3D_FEATURE_LEVEL_11_0)
|
||||
initParams.MinimumFeatureLevel = D3D_FEATURE_LEVEL_11_0;
|
||||
|
||||
D3D12_PrepareReplaySDKVersion(rdc && rdc->IsUntrusted(), initParams.SDKVersion, D3D12Core,
|
||||
D3D12SDKLayers, D3D12Lib);
|
||||
D3D12DevConfiguration *config = D3D12_PrepareReplaySDKVersion(
|
||||
rdc && rdc->IsUntrusted(), initParams.SDKVersion, D3D12Core, D3D12SDKLayers, D3D12Lib);
|
||||
|
||||
const bool isProxy = (rdc == NULL);
|
||||
|
||||
@@ -4648,7 +4661,7 @@ RDResult D3D12_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, IRepl
|
||||
|
||||
if(shouldEnableDebugLayer)
|
||||
{
|
||||
debugLayerEnabled = EnableD3D12DebugLayer();
|
||||
debugLayerEnabled = EnableD3D12DebugLayer(config, NULL);
|
||||
|
||||
if(!debugLayerEnabled && !isProxy)
|
||||
{
|
||||
@@ -4659,7 +4672,11 @@ RDResult D3D12_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, IRepl
|
||||
}
|
||||
|
||||
ID3D12Device *dev = NULL;
|
||||
hr = createDevice(adapter, initParams.MinimumFeatureLevel, __uuidof(ID3D12Device), (void **)&dev);
|
||||
if(config)
|
||||
hr = config->devfactory->CreateDevice(adapter, initParams.MinimumFeatureLevel,
|
||||
__uuidof(ID3D12Device), (void **)&dev);
|
||||
else
|
||||
hr = createDevice(adapter, initParams.MinimumFeatureLevel, __uuidof(ID3D12Device), (void **)&dev);
|
||||
|
||||
if((FAILED(hr) || !dev) && adapter)
|
||||
{
|
||||
@@ -4668,7 +4685,12 @@ RDResult D3D12_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, IRepl
|
||||
RDCWARN("Couldn't replay on selected adapter, falling back to default adapter");
|
||||
|
||||
SAFE_RELEASE(adapter);
|
||||
hr = createDevice(adapter, initParams.MinimumFeatureLevel, __uuidof(ID3D12Device), (void **)&dev);
|
||||
if(config)
|
||||
hr = config->devfactory->CreateDevice(adapter, initParams.MinimumFeatureLevel,
|
||||
__uuidof(ID3D12Device), (void **)&dev);
|
||||
else
|
||||
hr = createDevice(adapter, initParams.MinimumFeatureLevel, __uuidof(ID3D12Device),
|
||||
(void **)&dev);
|
||||
}
|
||||
|
||||
SAFE_RELEASE(adapter);
|
||||
@@ -4723,7 +4745,7 @@ RDResult D3D12_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, IRepl
|
||||
replay->SetProxy(isProxy);
|
||||
replay->SetRGP(rgp);
|
||||
|
||||
replay->Initialise(factory);
|
||||
replay->Initialise(factory, config);
|
||||
|
||||
*driver = (IReplayDriver *)replay;
|
||||
return ResultCode::Succeeded;
|
||||
|
||||
@@ -94,12 +94,14 @@ class D3D12Replay : public IReplayDriver
|
||||
public:
|
||||
D3D12Replay(WrappedID3D12Device *d);
|
||||
|
||||
D3D12DevConfiguration *GetDevConfiguration() { return m_DevConfig; }
|
||||
|
||||
D3D12DebugManager *GetDebugManager() { return m_DebugManager; }
|
||||
void SetRGP(AMDRGPControl *rgp) { m_RGP = rgp; }
|
||||
void Set12On7(bool d3d12on7) { m_D3D12On7 = d3d12on7; }
|
||||
void SetProxy(bool proxy) { m_Proxy = proxy; }
|
||||
bool IsRemoteProxy() { return m_Proxy; }
|
||||
void Initialise(IDXGIFactory1 *factory);
|
||||
void Initialise(IDXGIFactory1 *factory, D3D12DevConfiguration *config);
|
||||
void Shutdown();
|
||||
|
||||
RDResult FatalErrorCheck();
|
||||
@@ -561,6 +563,8 @@ private:
|
||||
|
||||
D3D12DebugManager *m_DebugManager = NULL;
|
||||
|
||||
D3D12DevConfiguration *m_DevConfig = NULL;
|
||||
|
||||
IDXGIFactory1 *m_pFactory = NULL;
|
||||
HMODULE m_D3D12Lib = NULL;
|
||||
|
||||
|
||||
@@ -314,11 +314,14 @@ bool IsSignedByMicrosoft(const rdcstr &filename, rdcstr &signer)
|
||||
return IsSignatureValid;
|
||||
}
|
||||
|
||||
void D3D12_PrepareReplaySDKVersion(bool untrustedCapture, UINT SDKVersion, bytebuf d3d12core_file,
|
||||
bytebuf d3d12sdklayers_file, HMODULE d3d12lib)
|
||||
D3D12DevConfiguration *D3D12_PrepareReplaySDKVersion(bool untrustedCapture, UINT SDKVersion,
|
||||
bytebuf d3d12core_file,
|
||||
bytebuf d3d12sdklayers_file, HMODULE d3d12lib)
|
||||
{
|
||||
// D3D12Core shouldn't be loaded at this point, but it might be due to bugs. If it is, we can't do
|
||||
// anything to change it anymore so we have to just handle what we have
|
||||
// D3D12Core shouldn't be loaded at this point, but it might be due to bugs. If it is, we don't do
|
||||
// anything to change it anymore so we have to just handle what we have.
|
||||
// In theory it might be possible to load multiple d3d12cores using the new dll selection API, but
|
||||
// that's probably not stable/reliable so we don't use it.
|
||||
HMODULE D3D12Core = GetModuleHandleA("D3D12Core.dll");
|
||||
if(D3D12Core != NULL)
|
||||
{
|
||||
@@ -326,7 +329,7 @@ void D3D12_PrepareReplaySDKVersion(bool untrustedCapture, UINT SDKVersion, byteb
|
||||
|
||||
// if the core that's loaded is sufficient, don't show any warnings
|
||||
if(ver_ptr && SDKVersion <= *ver_ptr)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
RDCWARN(
|
||||
"D3D12Core.dll was already loaded before replay started. This may be caused by a D3D12 "
|
||||
@@ -339,7 +342,7 @@ void D3D12_PrepareReplaySDKVersion(bool untrustedCapture, UINT SDKVersion, byteb
|
||||
RDCWARN("The existing D3D12Core.dll had an unknown version, this capture requires version %u",
|
||||
SDKVersion);
|
||||
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool core_fetched = false, hooks_applied = false;
|
||||
@@ -389,7 +392,7 @@ void D3D12_PrepareReplaySDKVersion(bool untrustedCapture, UINT SDKVersion, byteb
|
||||
// if the system doesn't have a core DLL we can't intercept and point to our own runtime, so just
|
||||
// abort here before doing anything potentially dangerous below.
|
||||
if(SystemCoreVersion == 0)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
// similarly, if the system version is enough then the user didn't use a new runtime (or they used
|
||||
// what was at the time a new runtime but is now available in the system...), so also abort.
|
||||
@@ -397,31 +400,13 @@ void D3D12_PrepareReplaySDKVersion(bool untrustedCapture, UINT SDKVersion, byteb
|
||||
// The only exception is if the user has configured a force override, in which case we always use
|
||||
// it.
|
||||
if(SDKVersion <= SystemCoreVersion && D3D12_D3D12CoreDirPath().empty())
|
||||
return;
|
||||
|
||||
// finally we're at a point where we will hook to force the library we want.
|
||||
|
||||
if(!hooks_applied)
|
||||
{
|
||||
hooks_applied = true;
|
||||
|
||||
Win32_RegisterManualModuleHooking();
|
||||
|
||||
D3D12GetInterface_Core_hook.Register("d3d12core.dll", "D3D12GetInterface",
|
||||
Hooked_Core_D3D12GetInterface);
|
||||
D3D12GetInterface_SDKLayers_hook.Register("d3d12sdklayers.dll", "D3D12GetInterface",
|
||||
Hooked_SDKLayers_D3D12GetInterface);
|
||||
|
||||
Win32_InterceptLibraryLoads(Hooked_D3D12LoadLibrary);
|
||||
}
|
||||
|
||||
// we do this always, even if the hooks are already applied, because this module has possibly been
|
||||
// reloaded and needs to be re-hooked each time
|
||||
Win32_ManualHookModule("d3d12.dll", d3d12lib);
|
||||
return NULL;
|
||||
|
||||
// *always* use the user's path if it exists
|
||||
D3D12Core_Override_Path = D3D12_D3D12CoreDirPath();
|
||||
|
||||
DWORD OverrideDllVersion = 0;
|
||||
|
||||
if(D3D12Core_Override_Path.empty() || !FileIO::exists(D3D12Core_Override_Path.c_str()))
|
||||
{
|
||||
if(d3d12core_file.empty())
|
||||
@@ -430,7 +415,7 @@ void D3D12_PrepareReplaySDKVersion(bool untrustedCapture, UINT SDKVersion, byteb
|
||||
"No D3D12Core.dll embedded in capture but we need a newer one (version %u) to properly "
|
||||
"replay this capture",
|
||||
SDKVersion);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// find an appropriate spot to write this file. Other instances of RenderDoc might be running so
|
||||
@@ -557,6 +542,118 @@ void D3D12_PrepareReplaySDKVersion(bool untrustedCapture, UINT SDKVersion, byteb
|
||||
FreeLibrary(ret);
|
||||
}
|
||||
}
|
||||
|
||||
if(FileIO::exists(D3D12Core_Override_Path.c_str()))
|
||||
{
|
||||
UINT prevErrorMode = GetErrorMode();
|
||||
SetErrorMode(prevErrorMode | SEM_FAILCRITICALERRORS);
|
||||
HMODULE ret =
|
||||
LoadLibraryW(StringFormat::UTF82Wide(D3D12Core_Override_Path + "/d3d12core.dll").c_str());
|
||||
|
||||
SetErrorMode(prevErrorMode);
|
||||
|
||||
DWORD *ver_ptr = (DWORD *)GetProcAddress(ret, "D3D12SDKVersion");
|
||||
|
||||
if(ver_ptr)
|
||||
OverrideDllVersion = *ver_ptr;
|
||||
|
||||
FreeLibrary(ret);
|
||||
}
|
||||
|
||||
RDCLOG("Loading D3D12 runtime from %s which is version %u", D3D12Core_Override_Path.c_str(),
|
||||
OverrideDllVersion);
|
||||
|
||||
// see if we can use the new proper D3D12 dll selection API
|
||||
{
|
||||
HMODULE d3d12Lib = GetModuleHandleA("d3d12.dll");
|
||||
PFN_D3D12_GET_INTERFACE getD3D12Interface = NULL;
|
||||
|
||||
if(d3d12Lib)
|
||||
getD3D12Interface = (PFN_D3D12_GET_INTERFACE)GetProcAddress(d3d12Lib, "D3D12GetInterface");
|
||||
|
||||
if(getD3D12Interface)
|
||||
{
|
||||
ID3D12SDKConfiguration *config = NULL;
|
||||
HRESULT hr = getD3D12Interface(CLSID_D3D12SDKConfiguration, __uuidof(ID3D12SDKConfiguration),
|
||||
(void **)&config);
|
||||
|
||||
if(SUCCEEDED(hr) && config)
|
||||
{
|
||||
ID3D12SDKConfiguration1 *config1 = NULL;
|
||||
ID3D12DeviceFactory *devfactory = NULL;
|
||||
hr = config->QueryInterface(__uuidof(ID3D12SDKConfiguration1), (void **)&config1);
|
||||
if(SUCCEEDED(hr) && config1)
|
||||
{
|
||||
config1->CreateDeviceFactory(OverrideDllVersion, D3D12Core_Override_Path.c_str(),
|
||||
__uuidof(ID3D12DeviceFactory), (void **)&devfactory);
|
||||
}
|
||||
SAFE_RELEASE(config);
|
||||
|
||||
if(devfactory)
|
||||
{
|
||||
ID3D12Debug *debug = NULL;
|
||||
hr = devfactory->GetConfigurationInterface(CLSID_D3D12Debug, __uuidof(ID3D12Debug),
|
||||
(void **)&debug);
|
||||
if(FAILED(hr))
|
||||
SAFE_RELEASE(debug);
|
||||
ID3D12DeviceConfiguration *devConfig = NULL;
|
||||
hr = devfactory->QueryInterface(__uuidof(ID3D12DeviceConfiguration), (void **)&devConfig);
|
||||
if(FAILED(hr))
|
||||
SAFE_RELEASE(devConfig);
|
||||
|
||||
// we got what we need, return the interfaces to use
|
||||
D3D12DevConfiguration *ret = new D3D12DevConfiguration;
|
||||
ret->devfactory = devfactory;
|
||||
ret->sdkconfig = config1;
|
||||
ret->debug = debug;
|
||||
ret->devconfig = devConfig;
|
||||
|
||||
RDCLOG("Accessing D3D12 dll via SDK configuration API");
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCLOG("Couldn't get device factory");
|
||||
}
|
||||
|
||||
SAFE_RELEASE(config1);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCLOG("Couldn't get SDK configuration interface");
|
||||
}
|
||||
SAFE_RELEASE(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCLOG("Couldn't get D3D12 interface query");
|
||||
}
|
||||
}
|
||||
|
||||
RDCLOG("Accessing D3D12 dll via hooks");
|
||||
|
||||
// finally we're at a point where we will hook to force the library we want.
|
||||
|
||||
if(!hooks_applied)
|
||||
{
|
||||
hooks_applied = true;
|
||||
|
||||
Win32_RegisterManualModuleHooking();
|
||||
|
||||
D3D12GetInterface_Core_hook.Register("d3d12core.dll", "D3D12GetInterface",
|
||||
Hooked_Core_D3D12GetInterface);
|
||||
D3D12GetInterface_SDKLayers_hook.Register("d3d12sdklayers.dll", "D3D12GetInterface",
|
||||
Hooked_SDKLayers_D3D12GetInterface);
|
||||
|
||||
Win32_InterceptLibraryLoads(Hooked_D3D12LoadLibrary);
|
||||
}
|
||||
|
||||
// we do this always, even if the hooks are already applied, because this module has possibly been
|
||||
// reloaded and needs to be re-hooked each time
|
||||
Win32_ManualHookModule("d3d12.dll", d3d12lib);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void D3D12_CleanupReplaySDK()
|
||||
|
||||
@@ -767,8 +767,14 @@ D3D12RootSignature D3D12ShaderCache::GetRootSig(const void *data, size_t dataSiz
|
||||
}
|
||||
|
||||
ID3D12VersionedRootSignatureDeserializer *deser = NULL;
|
||||
HRESULT hr = deserializeRootSig(
|
||||
data, dataSize, __uuidof(ID3D12VersionedRootSignatureDeserializer), (void **)&deser);
|
||||
HRESULT hr;
|
||||
|
||||
if(m_DevConfig)
|
||||
hr = m_DevConfig->devconfig->CreateVersionedRootSignatureDeserializer(
|
||||
data, dataSize, __uuidof(ID3D12VersionedRootSignatureDeserializer), (void **)&deser);
|
||||
else
|
||||
hr = deserializeRootSig(data, dataSize, __uuidof(ID3D12VersionedRootSignatureDeserializer),
|
||||
(void **)&deser);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
@@ -966,7 +972,12 @@ ID3DBlob *D3D12ShaderCache::MakeRootSig(const rdcarray<D3D12_ROOT_PARAMETER1> &p
|
||||
|
||||
ID3DBlob *ret = NULL;
|
||||
ID3DBlob *errBlob = NULL;
|
||||
HRESULT hr = serializeRootSig(&verdesc, &ret, &errBlob);
|
||||
HRESULT hr;
|
||||
|
||||
if(m_DevConfig && m_DevConfig->devconfig)
|
||||
hr = m_DevConfig->devconfig->SerializeVersionedRootSignature(&verdesc, &ret, &errBlob);
|
||||
else
|
||||
hr = serializeRootSig(&verdesc, &ret, &errBlob);
|
||||
SAFE_RELEASE(errBlob);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
@@ -981,7 +992,10 @@ ID3DBlob *D3D12ShaderCache::MakeRootSig(const rdcarray<D3D12_ROOT_PARAMETER1> &p
|
||||
oldSamplers[i] = Downconvert(StaticSamplers[i]);
|
||||
desc11.pStaticSamplers = oldSamplers.data();
|
||||
|
||||
hr = serializeRootSig(&verdesc, &ret, &errBlob);
|
||||
if(m_DevConfig && m_DevConfig->devconfig)
|
||||
hr = m_DevConfig->devconfig->SerializeVersionedRootSignature(&verdesc, &ret, &errBlob);
|
||||
else
|
||||
hr = serializeRootSig(&verdesc, &ret, &errBlob);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
|
||||
void LoadDXC();
|
||||
|
||||
void SetDevConfiguration(D3D12DevConfiguration *config) { m_DevConfig = config; }
|
||||
void SetCaching(bool enabled) { m_CacheShaders = enabled; }
|
||||
private:
|
||||
static const uint32_t m_ShaderCacheMagic = 0xf000baba;
|
||||
@@ -71,6 +72,8 @@ private:
|
||||
bool m_ShaderCacheDirty = false, m_CacheShaders = false;
|
||||
std::map<uint32_t, ID3DBlob *> m_ShaderCache;
|
||||
|
||||
D3D12DevConfiguration *m_DevConfig = NULL;
|
||||
|
||||
D3D12_STATIC_SAMPLER_DESC1 Upconvert(const D3D12_STATIC_SAMPLER_DESC &StaticSampler);
|
||||
D3D12_STATIC_SAMPLER_DESC Downconvert(const D3D12_STATIC_SAMPLER_DESC1 &StaticSampler);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user