Defer state object compilation on D3D12

This commit is contained in:
baldurk
2024-08-27 16:25:41 +01:00
parent d7f3f194da
commit 282e76a2f5
4 changed files with 301 additions and 167 deletions
+140 -80
View File
@@ -23,9 +23,77 @@
******************************************************************************/
#include "d3d12_device.h"
#include "core/settings.h"
#include "driver/dxgi/dxgi_common.h"
#include "d3d12_resources.h"
RDOC_EXTERN_CONFIG(bool, Replay_Debug_SingleThreadedCompilation);
static RDResult DeferredStateObjCompile(ID3D12Device5 *device5,
const D3D12_STATE_OBJECT_DESC &Descriptor,
WrappedID3D12StateObject *wrappedObj)
{
rdcarray<ID3D12RootSignature *> rootSigs;
rdcarray<ID3D12StateObject *> collections;
// unwrap the referenced objects in place
const D3D12_STATE_SUBOBJECT *subs = Descriptor.pSubobjects;
for(UINT i = 0; i < Descriptor.NumSubobjects; i++)
{
if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE ||
subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE)
{
// both structs are the same
D3D12_GLOBAL_ROOT_SIGNATURE *global = (D3D12_GLOBAL_ROOT_SIGNATURE *)subs[i].pDesc;
rootSigs.push_back(global->pGlobalRootSignature);
global->pGlobalRootSignature = Unwrap(global->pGlobalRootSignature);
}
else if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION)
{
D3D12_EXISTING_COLLECTION_DESC *coll = (D3D12_EXISTING_COLLECTION_DESC *)subs[i].pDesc;
collections.push_back(coll->pExistingCollection);
// wait for any jobs for existing collections to complete
WrappedID3D12StateObject *wrapped = GetWrapped(coll->pExistingCollection);
coll->pExistingCollection = wrapped->GetReal();
}
}
ID3D12StateObject *realObj;
HRESULT hr =
device5->CreateStateObject(&Descriptor, __uuidof(ID3D12StateObject), (void **)&realObj);
// rewrap the objects for PopulateDatabase below
for(UINT i = 0, r = 0, c = 0; i < Descriptor.NumSubobjects; i++)
{
if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE ||
subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE)
{
D3D12_GLOBAL_ROOT_SIGNATURE *global = (D3D12_GLOBAL_ROOT_SIGNATURE *)subs[i].pDesc;
// the same order as above, we can consume the rootSigs in order
global->pGlobalRootSignature = rootSigs[r++];
}
else if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION)
{
D3D12_EXISTING_COLLECTION_DESC *coll = (D3D12_EXISTING_COLLECTION_DESC *)subs[i].pDesc;
coll->pExistingCollection = collections[c++];
}
}
wrappedObj->SetNewReal(realObj);
wrappedObj->exports->SetObjectProperties(wrappedObj->GetProperties());
wrappedObj->exports->PopulateDatabase(Descriptor.NumSubobjects, subs);
if(FAILED(hr))
{
RETURN_ERROR_RESULT(ResultCode::APIReplayFailed, "Failed creating state object, HRESULT: %s",
ToStr(hr).c_str());
}
return ResultCode::Succeeded;
}
HRESULT WrappedID3D12Device::CreateLifetimeTracker(_In_ ID3D12LifetimeOwner *pOwner, REFIID riid,
_COM_Outptr_ void **ppvTracker)
{
@@ -89,98 +157,89 @@ bool WrappedID3D12Device::Serialise_CreateStateObject(SerialiserType &ser,
if(IsReplayingAndReading())
{
ID3D12StateObject *ret = NULL;
HRESULT hr = E_NOINTERFACE;
// unwrap the subobjects that need unwrapping in-place. We'll undo these after creating the
// object - this is probably better than unwrapping to a separate object since that requires
// rebasing all the associations etc
rdcarray<ID3D12RootSignature *> rootSigs;
rdcarray<ID3D12StateObject *> collections;
const D3D12_STATE_SUBOBJECT *subs = Descriptor.pSubobjects;
for(UINT i = 0; i < Descriptor.NumSubobjects; i++)
{
if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE ||
subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE)
{
// both structs are the same
D3D12_GLOBAL_ROOT_SIGNATURE *global = (D3D12_GLOBAL_ROOT_SIGNATURE *)subs[i].pDesc;
rootSigs.push_back(global->pGlobalRootSignature);
global->pGlobalRootSignature = Unwrap(global->pGlobalRootSignature);
}
else if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION)
{
D3D12_EXISTING_COLLECTION_DESC *coll = (D3D12_EXISTING_COLLECTION_DESC *)subs[i].pDesc;
collections.push_back(coll->pExistingCollection);
coll->pExistingCollection = Unwrap(coll->pExistingCollection);
}
}
// we steal the serialised descriptor here so we can pass it to jobs without its contents and
// all of the allocated structures and arrays being deserialised. We add a job which waits on
// the compiles then deserialises this manually.
D3D12_STATE_OBJECT_DESC OrigDescriptor = Descriptor;
Descriptor = {};
m_UsedDXIL = true;
if(m_pDevice5)
{
hr = m_pDevice5->CreateStateObject(&Descriptor, guid, (void **)&ret);
}
else
if(!m_pDevice5)
{
SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
"Capture requires ID3D12Device5 which isn't available");
return false;
}
if(FAILED(hr))
WrappedID3D12StateObject *wrapped = new WrappedID3D12StateObject(
GetResourceManager()->CreateDeferredHandle<ID3D12StateObject>(), true, this);
wrapped->exports = new D3D12ShaderExportDatabase(
pStateObject, GetResourceManager()->GetRaytracingResourceAndUtilHandler());
// TODO: Apply m_GlobalEXTUAV, m_GlobalEXTUAVSpace for processing extensions in the DXBC files?
AddResource(pStateObject, ResourceType::PipelineState, "State Object");
rdcarray<Threading::JobSystem::Job *> parents;
const D3D12_STATE_SUBOBJECT *subs = OrigDescriptor.pSubobjects;
for(UINT i = 0; i < OrigDescriptor.NumSubobjects; i++)
{
SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed,
"Failed creating state object, HRESULT: %s", ToStr(hr).c_str());
return false;
if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE ||
subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE)
{
// both structs are the same
D3D12_GLOBAL_ROOT_SIGNATURE *global = (D3D12_GLOBAL_ROOT_SIGNATURE *)subs[i].pDesc;
DerivedResource(global->pGlobalRootSignature, pStateObject);
}
else if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION)
{
D3D12_EXISTING_COLLECTION_DESC *coll = (D3D12_EXISTING_COLLECTION_DESC *)subs[i].pDesc;
DerivedResource(coll->pExistingCollection, pStateObject);
if(!Replay_Debug_SingleThreadedCompilation())
{
parents.push_back(GetWrapped(coll->pExistingCollection)->deferredJob);
}
}
}
if(Replay_Debug_SingleThreadedCompilation())
{
RDResult res = DeferredStateObjCompile(m_pDevice5, OrigDescriptor, wrapped);
Deserialise(OrigDescriptor);
if(res != ResultCode::Succeeded)
{
m_FailedReplayResult = res;
return false;
}
}
else
{
for(UINT i = 0, r = 0, c = 0; i < Descriptor.NumSubobjects; i++)
{
if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE ||
subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE)
{
D3D12_GLOBAL_ROOT_SIGNATURE *global = (D3D12_GLOBAL_ROOT_SIGNATURE *)subs[i].pDesc;
// the same order as above, we can consume the rootSigs in order
global->pGlobalRootSignature = rootSigs[r++];
}
else if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION)
{
D3D12_EXISTING_COLLECTION_DESC *coll = (D3D12_EXISTING_COLLECTION_DESC *)subs[i].pDesc;
coll->pExistingCollection = collections[c++];
}
}
wrapped->deferredJob = Threading::JobSystem::AddJob(
[wrappedD3D12 = this, device5 = m_pDevice5, OrigDescriptor, wrapped]() {
PerformanceTimer timer;
wrappedD3D12->CheckDeferredResult(
DeferredStateObjCompile(device5, OrigDescriptor, wrapped));
wrappedD3D12->AddDeferredTime(timer.GetMilliseconds());
WrappedID3D12StateObject *wrapped = new WrappedID3D12StateObject(ret, this);
// TODO: Apply m_GlobalEXTUAV, m_GlobalEXTUAVSpace for processing extensions in the DXBC files?
wrapped->exports = new D3D12ShaderExportDatabase(
pStateObject, GetResourceManager()->GetRaytracingResourceAndUtilHandler(),
wrapped->GetProperties());
wrapped->exports->PopulateDatabase(Descriptor.NumSubobjects, subs);
AddResource(pStateObject, ResourceType::PipelineState, "State Object");
for(ID3D12RootSignature *rootSig : rootSigs)
DerivedResource(rootSig, pStateObject);
for(ID3D12StateObject *coll : collections)
DerivedResource(coll, pStateObject);
// if this shader was initialised with nvidia's dynamic UAV, pull in that chunk as one of ours
// and unset it (there will be one for each create that actually used vendor extensions)
if(m_VendorEXT == GPUVendor::nVidia && m_GlobalEXTUAV != ~0U)
{
GetResourceDesc(pStateObject)
.initialisationChunks.push_back((uint32_t)m_StructuredFile->chunks.size() - 2);
m_GlobalEXTUAV = ~0U;
}
GetResourceManager()->AddLiveResource(pStateObject, wrapped);
Deserialise(OrigDescriptor);
},
parents);
}
// if this shader was initialised with nvidia's dynamic UAV, pull in that chunk as one of ours
// and unset it (there will be one for each create that actually used vendor extensions)
if(m_VendorEXT == GPUVendor::nVidia && m_GlobalEXTUAV != ~0U)
{
GetResourceDesc(pStateObject)
.initialisationChunks.push_back((uint32_t)m_StructuredFile->chunks.size() - 2);
m_GlobalEXTUAV = ~0U;
}
GetResourceManager()->AddLiveResource(pStateObject, wrapped);
}
return true;
@@ -207,7 +266,7 @@ WrappedID3D12Device::CreateStateObject(const D3D12_STATE_OBJECT_DESC *pDesc, REF
if(SUCCEEDED(ret))
{
WrappedID3D12StateObject *wrapped = new WrappedID3D12StateObject(real, this);
WrappedID3D12StateObject *wrapped = new WrappedID3D12StateObject(real, false, this);
if(IsCaptureMode(m_State))
{
@@ -228,8 +287,9 @@ WrappedID3D12Device::CreateStateObject(const D3D12_STATE_OBJECT_DESC *pDesc, REF
Serialise_CreateStateObject(ser, pDesc, riid, (void **)&wrapped);
wrapped->exports = new D3D12ShaderExportDatabase(
wrapped->GetResourceID(), GetResourceManager()->GetRaytracingResourceAndUtilHandler(),
wrapped->GetProperties());
wrapped->GetResourceID(), GetResourceManager()->GetRaytracingResourceAndUtilHandler());
wrapped->exports->SetObjectProperties(wrapped->GetProperties());
wrapped->exports->PopulateDatabase(pDesc->NumSubobjects, pDesc->pSubobjects);
+145 -81
View File
@@ -23,9 +23,79 @@
******************************************************************************/
#include "d3d12_device.h"
#include "core/settings.h"
#include "driver/dxgi/dxgi_common.h"
#include "d3d12_resources.h"
RDOC_EXTERN_CONFIG(bool, Replay_Debug_SingleThreadedCompilation);
static RDResult DeferredStateObjGrow(ID3D12Device7 *device7,
const D3D12_STATE_OBJECT_DESC &Descriptor,
ID3D12StateObject *pStateObjectToGrowFrom,
WrappedID3D12StateObject *wrappedObj)
{
rdcarray<ID3D12RootSignature *> rootSigs;
rdcarray<ID3D12StateObject *> collections;
// unwrap the referenced objects in place
const D3D12_STATE_SUBOBJECT *subs = Descriptor.pSubobjects;
for(UINT i = 0; i < Descriptor.NumSubobjects; i++)
{
if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE ||
subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE)
{
// both structs are the same
D3D12_GLOBAL_ROOT_SIGNATURE *global = (D3D12_GLOBAL_ROOT_SIGNATURE *)subs[i].pDesc;
rootSigs.push_back(global->pGlobalRootSignature);
global->pGlobalRootSignature = Unwrap(global->pGlobalRootSignature);
}
else if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION)
{
D3D12_EXISTING_COLLECTION_DESC *coll = (D3D12_EXISTING_COLLECTION_DESC *)subs[i].pDesc;
collections.push_back(coll->pExistingCollection);
// wait for any jobs for existing collections to complete
WrappedID3D12StateObject *wrapped = GetWrapped(coll->pExistingCollection);
coll->pExistingCollection = wrapped->GetReal();
}
}
ID3D12StateObject *realObj;
HRESULT hr = device7->AddToStateObject(&Descriptor, Unwrap(pStateObjectToGrowFrom),
__uuidof(ID3D12StateObject), (void **)&realObj);
// rewrap the objects for PopulateDatabase below
for(UINT i = 0, r = 0, c = 0; i < Descriptor.NumSubobjects; i++)
{
if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE ||
subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE)
{
D3D12_GLOBAL_ROOT_SIGNATURE *global = (D3D12_GLOBAL_ROOT_SIGNATURE *)subs[i].pDesc;
// the same order as above, we can consume the rootSigs in order
global->pGlobalRootSignature = rootSigs[r++];
}
else if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION)
{
D3D12_EXISTING_COLLECTION_DESC *coll = (D3D12_EXISTING_COLLECTION_DESC *)subs[i].pDesc;
coll->pExistingCollection = collections[c++];
}
}
wrappedObj->SetNewReal(realObj);
wrappedObj->exports->SetObjectProperties(wrappedObj->GetProperties());
wrappedObj->exports->GrowFrom(GetWrapped(pStateObjectToGrowFrom)->exports);
wrappedObj->exports->PopulateDatabase(Descriptor.NumSubobjects, subs);
if(FAILED(hr))
{
RETURN_ERROR_RESULT(ResultCode::APIReplayFailed, "Failed creating state object, HRESULT: %s",
ToStr(hr).c_str());
}
return ResultCode::Succeeded;
}
template <typename SerialiserType>
bool WrappedID3D12Device::Serialise_AddToStateObject(SerialiserType &ser,
const D3D12_STATE_OBJECT_DESC *pAddition,
@@ -44,100 +114,93 @@ bool WrappedID3D12Device::Serialise_AddToStateObject(SerialiserType &ser,
if(IsReplayingAndReading())
{
ID3D12StateObject *ret = NULL;
HRESULT hr = E_NOINTERFACE;
// unwrap the subobjects that need unwrapping in-place. We'll undo these after creating the
// object - this is probably better than unwrapping to a separate object since that requires
// rebasing all the associations etc
rdcarray<ID3D12RootSignature *> rootSigs;
rdcarray<ID3D12StateObject *> collections;
const D3D12_STATE_SUBOBJECT *subs = Addition.pSubobjects;
for(UINT i = 0; i < Addition.NumSubobjects; i++)
{
if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE ||
subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE)
{
// both structs are the same
D3D12_GLOBAL_ROOT_SIGNATURE *global = (D3D12_GLOBAL_ROOT_SIGNATURE *)subs[i].pDesc;
rootSigs.push_back(global->pGlobalRootSignature);
global->pGlobalRootSignature = Unwrap(global->pGlobalRootSignature);
}
else if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION)
{
D3D12_EXISTING_COLLECTION_DESC *coll = (D3D12_EXISTING_COLLECTION_DESC *)subs[i].pDesc;
collections.push_back(coll->pExistingCollection);
coll->pExistingCollection = Unwrap(coll->pExistingCollection);
}
}
// we steal the serialised descriptor here so we can pass it to jobs without its contents and
// all of the allocated structures and arrays being deserialised. We add a job which waits on
// the compiles then deserialises this manually.
D3D12_STATE_OBJECT_DESC OrigAddition = Addition;
Addition = {};
m_UsedDXIL = true;
if(m_pDevice7)
{
hr = m_pDevice7->AddToStateObject(&Addition, Unwrap(pStateObjectToGrowFrom), guid,
(void **)&ret);
}
else
if(!m_pDevice7)
{
SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
"Capture requires ID3D12Device7 which isn't available");
return false;
}
if(FAILED(hr))
WrappedID3D12StateObject *wrapped = new WrappedID3D12StateObject(
GetResourceManager()->CreateDeferredHandle<ID3D12StateObject>(), true, this);
// TODO: Apply m_GlobalEXTUAV, m_GlobalEXTUAVSpace for processing extensions in the DXBC files?
wrapped->exports = new D3D12ShaderExportDatabase(
pNewStateObject, GetResourceManager()->GetRaytracingResourceAndUtilHandler());
AddResource(pNewStateObject, ResourceType::PipelineState, "State Object");
DerivedResource(pStateObjectToGrowFrom, pNewStateObject);
rdcarray<Threading::JobSystem::Job *> parents;
const D3D12_STATE_SUBOBJECT *subs = OrigAddition.pSubobjects;
for(UINT i = 0; i < OrigAddition.NumSubobjects; i++)
{
SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed,
"Failed creating state object, HRESULT: %s", ToStr(hr).c_str());
return false;
if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE ||
subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE)
{
// both structs are the same
D3D12_GLOBAL_ROOT_SIGNATURE *global = (D3D12_GLOBAL_ROOT_SIGNATURE *)subs[i].pDesc;
DerivedResource(global->pGlobalRootSignature, pNewStateObject);
}
else if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION)
{
D3D12_EXISTING_COLLECTION_DESC *coll = (D3D12_EXISTING_COLLECTION_DESC *)subs[i].pDesc;
DerivedResource(coll->pExistingCollection, pNewStateObject);
if(!Replay_Debug_SingleThreadedCompilation())
{
parents.push_back(GetWrapped(coll->pExistingCollection)->deferredJob);
}
}
}
if(Replay_Debug_SingleThreadedCompilation())
{
RDResult res = DeferredStateObjGrow(m_pDevice7, OrigAddition, pStateObjectToGrowFrom, wrapped);
Deserialise(OrigAddition);
if(res != ResultCode::Succeeded)
{
m_FailedReplayResult = res;
return false;
}
}
else
{
for(UINT i = 0, r = 0, c = 0; i < Addition.NumSubobjects; i++)
{
if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE ||
subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE)
{
D3D12_GLOBAL_ROOT_SIGNATURE *global = (D3D12_GLOBAL_ROOT_SIGNATURE *)subs[i].pDesc;
// the same order as above, we can consume the rootSigs in order
global->pGlobalRootSignature = rootSigs[r++];
}
else if(subs[i].Type == D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION)
{
D3D12_EXISTING_COLLECTION_DESC *coll = (D3D12_EXISTING_COLLECTION_DESC *)subs[i].pDesc;
coll->pExistingCollection = collections[c++];
}
}
// first wait on the parent
parents.push_back(GetWrapped(pStateObjectToGrowFrom)->deferredJob);
WrappedID3D12StateObject *wrapped = new WrappedID3D12StateObject(ret, this);
wrapped->deferredJob = Threading::JobSystem::AddJob(
[wrappedD3D12 = this, device7 = m_pDevice7, OrigAddition, pStateObjectToGrowFrom, wrapped]() {
PerformanceTimer timer;
wrappedD3D12->CheckDeferredResult(
DeferredStateObjGrow(device7, OrigAddition, pStateObjectToGrowFrom, wrapped));
wrappedD3D12->AddDeferredTime(timer.GetMilliseconds());
// TODO: Apply m_GlobalEXTUAV, m_GlobalEXTUAVSpace for processing extensions in the DXBC files?
wrapped->exports = new D3D12ShaderExportDatabase(
pNewStateObject, GetResourceManager()->GetRaytracingResourceAndUtilHandler(),
wrapped->GetProperties());
wrapped->exports->GrowFrom(((WrappedID3D12StateObject *)pStateObjectToGrowFrom)->exports);
wrapped->exports->PopulateDatabase(Addition.NumSubobjects, subs);
AddResource(pNewStateObject, ResourceType::PipelineState, "State Object");
for(ID3D12RootSignature *rootSig : rootSigs)
DerivedResource(rootSig, pNewStateObject);
for(ID3D12StateObject *coll : collections)
DerivedResource(coll, pNewStateObject);
// if this shader was initialised with nvidia's dynamic UAV, pull in that chunk as one of ours
// and unset it (there will be one for each create that actually used vendor extensions)
if(m_VendorEXT == GPUVendor::nVidia && m_GlobalEXTUAV != ~0U)
{
GetResourceDesc(pNewStateObject)
.initialisationChunks.push_back((uint32_t)m_StructuredFile->chunks.size() - 2);
m_GlobalEXTUAV = ~0U;
}
GetResourceManager()->AddLiveResource(pNewStateObject, wrapped);
Deserialise(OrigAddition);
},
parents);
}
// if this shader was initialised with nvidia's dynamic UAV, pull in that chunk as one of ours
// and unset it (there will be one for each create that actually used vendor extensions)
if(m_VendorEXT == GPUVendor::nVidia && m_GlobalEXTUAV != ~0U)
{
GetResourceDesc(pNewStateObject)
.initialisationChunks.push_back((uint32_t)m_StructuredFile->chunks.size() - 2);
m_GlobalEXTUAV = ~0U;
}
GetResourceManager()->AddLiveResource(pNewStateObject, wrapped);
}
return true;
@@ -167,7 +230,7 @@ HRESULT STDMETHODCALLTYPE WrappedID3D12Device::AddToStateObject(
if(SUCCEEDED(ret))
{
WrappedID3D12StateObject *wrapped = new WrappedID3D12StateObject(real, this);
WrappedID3D12StateObject *wrapped = new WrappedID3D12StateObject(real, false, this);
if(IsCaptureMode(m_State))
{
@@ -188,8 +251,9 @@ HRESULT STDMETHODCALLTYPE WrappedID3D12Device::AddToStateObject(
Serialise_AddToStateObject(ser, pAddition, pStateObjectToGrowFrom, riid, (void **)&wrapped);
wrapped->exports = new D3D12ShaderExportDatabase(
wrapped->GetResourceID(), GetResourceManager()->GetRaytracingResourceAndUtilHandler(),
wrapped->GetProperties());
wrapped->GetResourceID(), GetResourceManager()->GetRaytracingResourceAndUtilHandler());
wrapped->exports->SetObjectProperties(wrapped->GetProperties());
wrapped->exports->GrowFrom(((WrappedID3D12StateObject *)pStateObjectToGrowFrom)->exports);
wrapped->exports->PopulateDatabase(pAddition->NumSubobjects, pAddition->pSubobjects);
+2 -3
View File
@@ -840,9 +840,8 @@ void WrappedID3D12PipelineState::ProcessDescriptorAccess()
}
D3D12ShaderExportDatabase::D3D12ShaderExportDatabase(ResourceId id,
D3D12RaytracingResourceAndUtilHandler *rayManager,
ID3D12StateObjectProperties *obj)
: RefCounter12(NULL), objectOriginalId(id), m_RayManager(rayManager), m_StateObjectProps(obj)
D3D12RaytracingResourceAndUtilHandler *rayManager)
: RefCounter12(NULL), objectOriginalId(id), m_RayManager(rayManager)
{
m_RayManager->RegisterExportDatabase(this);
}
+14 -3
View File
@@ -1036,10 +1036,11 @@ typedef WrappedID3D12PipelineState::ShaderEntry WrappedID3D12Shader;
struct D3D12ShaderExportDatabase : public RefCounter12<IUnknown>
{
public:
D3D12ShaderExportDatabase(ResourceId id, D3D12RaytracingResourceAndUtilHandler *rayManager,
ID3D12StateObjectProperties *obj);
D3D12ShaderExportDatabase(ResourceId id, D3D12RaytracingResourceAndUtilHandler *rayManager);
~D3D12ShaderExportDatabase();
void SetObjectProperties(ID3D12StateObjectProperties *obj) { m_StateObjectProps = obj; }
ResourceId GetResourceId() { return objectOriginalId; }
void GrowFrom(D3D12ShaderExportDatabase *existing) { InheritAllCollectionExports(existing); }
@@ -1167,16 +1168,26 @@ public:
D3D12ShaderExportDatabase *exports = NULL;
Threading::JobSystem::Job *deferredJob = NULL;
enum
{
TypeEnum = Resource_StateObject,
};
WrappedID3D12StateObject(ID3D12StateObject *real, WrappedID3D12Device *device)
WrappedID3D12StateObject(ID3D12StateObject *real, bool deferredHandle, WrappedID3D12Device *device)
: WrappedDeviceChild12(real, device)
{
if(!deferredHandle)
SetNewReal(real);
}
void SetNewReal(ID3D12StateObject *real)
{
m_pReal = real;
real->QueryInterface(__uuidof(ID3D12StateObjectProperties), (void **)&properties);
}
virtual ~WrappedID3D12StateObject()
{
SAFE_RELEASE(properties);