mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-21 05:05:44 +00:00
Minimal possible residency handling code
* We unwrap objects and track residency state, and when preparing init states if necessary then we make those resources resident and sync the list execute so we can evict them again immediately afterwards. * On replay, all resources are created and left as resident, which could go over the budget available. If a frame uses close to or more than its total budget over the course of a frame this could fail. One fix to that would be to track referenced resources in command lists at replay time, and only make resident what we need for each list and execute them in isolation, then evict right after (so all frame resources are 'default evicted').
This commit is contained in:
@@ -901,6 +901,9 @@ void WrappedID3D12Device::StartFrameCapture(void *dev, void *wnd)
|
||||
SCOPED_LOCK(m_CapTransitionLock);
|
||||
GetResourceManager()->PrepareInitialContents();
|
||||
|
||||
ExecuteLists();
|
||||
FlushLists();
|
||||
|
||||
RDCDEBUG("Attempting capture");
|
||||
m_FrameCaptureRecord->DeleteChunks();
|
||||
|
||||
|
||||
@@ -1594,14 +1594,80 @@ HRESULT WrappedID3D12Device::OpenSharedHandleByName(LPCWSTR Name, DWORD Access,
|
||||
|
||||
HRESULT WrappedID3D12Device::MakeResident(UINT NumObjects, ID3D12Pageable *const *ppObjects)
|
||||
{
|
||||
RDCUNIMPLEMENTED("MakeResident"); // need to unwrap objects
|
||||
return m_pDevice->MakeResident(NumObjects, ppObjects);
|
||||
ID3D12Pageable **unwrapped = GetTempArray<ID3D12Pageable *>(NumObjects);
|
||||
|
||||
for(UINT i = 0; i < NumObjects; i++)
|
||||
{
|
||||
if(WrappedID3D12DescriptorHeap::IsAlloc(ppObjects[i]))
|
||||
{
|
||||
WrappedID3D12DescriptorHeap *heap = (WrappedID3D12DescriptorHeap *)ppObjects[i];
|
||||
heap->SetResident(true);
|
||||
unwrapped[i] = heap->GetReal();
|
||||
}
|
||||
else if(WrappedID3D12Resource::IsAlloc(ppObjects[i]))
|
||||
{
|
||||
WrappedID3D12Resource *res = (WrappedID3D12Resource *)ppObjects[i];
|
||||
res->SetResident(true);
|
||||
unwrapped[i] = res->GetReal();
|
||||
}
|
||||
else
|
||||
{
|
||||
unwrapped[i] = (ID3D12Pageable *)Unwrap((ID3D12DeviceChild *)ppObjects[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool capframe = false;
|
||||
|
||||
{
|
||||
SCOPED_LOCK(m_CapTransitionLock);
|
||||
capframe = (m_State == WRITING_CAPFRAME);
|
||||
}
|
||||
|
||||
if(capframe)
|
||||
{
|
||||
// serialise
|
||||
}
|
||||
|
||||
return m_pDevice->MakeResident(NumObjects, unwrapped);
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::Evict(UINT NumObjects, ID3D12Pageable *const *ppObjects)
|
||||
{
|
||||
RDCUNIMPLEMENTED("Evict"); // need to unwrap objects
|
||||
return m_pDevice->Evict(NumObjects, ppObjects);
|
||||
ID3D12Pageable **unwrapped = GetTempArray<ID3D12Pageable *>(NumObjects);
|
||||
|
||||
for(UINT i = 0; i < NumObjects; i++)
|
||||
{
|
||||
if(WrappedID3D12DescriptorHeap::IsAlloc(ppObjects[i]))
|
||||
{
|
||||
WrappedID3D12DescriptorHeap *heap = (WrappedID3D12DescriptorHeap *)ppObjects[i];
|
||||
heap->SetResident(false);
|
||||
unwrapped[i] = heap->GetReal();
|
||||
}
|
||||
else if(WrappedID3D12Resource::IsAlloc(ppObjects[i]))
|
||||
{
|
||||
WrappedID3D12Resource *res = (WrappedID3D12Resource *)ppObjects[i];
|
||||
res->SetResident(false);
|
||||
unwrapped[i] = res->GetReal();
|
||||
}
|
||||
else
|
||||
{
|
||||
unwrapped[i] = (ID3D12Pageable *)Unwrap((ID3D12DeviceChild *)ppObjects[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool capframe = false;
|
||||
|
||||
{
|
||||
SCOPED_LOCK(m_CapTransitionLock);
|
||||
capframe = (m_State == WRITING_CAPFRAME);
|
||||
}
|
||||
|
||||
if(capframe)
|
||||
{
|
||||
// serialise
|
||||
}
|
||||
|
||||
return m_pDevice->Evict(NumObjects, unwrapped);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -483,13 +483,19 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
}
|
||||
else if(type == Resource_Resource)
|
||||
{
|
||||
ID3D12Resource *r = (ID3D12Resource *)res;
|
||||
WrappedID3D12Resource *r = (WrappedID3D12Resource *)res;
|
||||
ID3D12Pageable *pageable = r;
|
||||
|
||||
bool nonresident = false;
|
||||
if(!r->Resident())
|
||||
nonresident = true;
|
||||
|
||||
D3D12_RESOURCE_DESC desc = r->GetDesc();
|
||||
|
||||
if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D && desc.SampleDesc.Count > 1)
|
||||
{
|
||||
D3D12NOTIMP("Multisampled initial contents");
|
||||
|
||||
SetInitialContents(GetResID(r), D3D12ResourceManager::InitialContentData(NULL, 2, NULL));
|
||||
return true;
|
||||
}
|
||||
@@ -518,11 +524,14 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_COPY_DEST, NULL,
|
||||
__uuidof(ID3D12Resource), (void **)©Dst);
|
||||
|
||||
if(nonresident)
|
||||
m_Device->MakeResident(1, &pageable);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
ID3D12GraphicsCommandList *list = Unwrap(m_Device->GetNewList());
|
||||
|
||||
list->CopyResource(copyDst, Unwrap(r));
|
||||
list->CopyResource(copyDst, r->GetReal());
|
||||
|
||||
list->Close();
|
||||
}
|
||||
@@ -531,6 +540,14 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
RDCERR("Couldn't create readback buffer: 0x%08x", hr);
|
||||
}
|
||||
|
||||
if(nonresident)
|
||||
{
|
||||
m_Device->ExecuteLists();
|
||||
m_Device->FlushLists();
|
||||
|
||||
m_Device->Evict(1, &pageable);
|
||||
}
|
||||
|
||||
SetInitialContents(GetResID(r), D3D12ResourceManager::InitialContentData(copyDst, 0, NULL));
|
||||
return true;
|
||||
}
|
||||
@@ -572,6 +589,9 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
&heapProps, D3D12_HEAP_FLAG_NONE, &bufDesc, D3D12_RESOURCE_STATE_COPY_DEST, NULL,
|
||||
__uuidof(ID3D12Resource), (void **)©Dst);
|
||||
|
||||
if(nonresident)
|
||||
m_Device->MakeResident(1, &pageable);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
ID3D12GraphicsCommandList *list = Unwrap(m_Device->GetNewList());
|
||||
@@ -590,7 +610,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
D3D12_RESOURCE_BARRIER barrier;
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.Transition.pResource = Unwrap(r);
|
||||
barrier.Transition.pResource = r->GetReal();
|
||||
barrier.Transition.Subresource = (UINT)i;
|
||||
barrier.Transition.StateBefore = states[i];
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
|
||||
@@ -607,7 +627,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
D3D12_TEXTURE_COPY_LOCATION dst, src;
|
||||
|
||||
src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
src.pResource = Unwrap(r);
|
||||
src.pResource = r->GetReal();
|
||||
src.SubresourceIndex = i;
|
||||
|
||||
dst.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
@@ -631,6 +651,14 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
RDCERR("Couldn't create readback buffer: 0x%08x", hr);
|
||||
}
|
||||
|
||||
if(nonresident)
|
||||
{
|
||||
m_Device->ExecuteLists();
|
||||
m_Device->FlushLists();
|
||||
|
||||
m_Device->Evict(1, &pageable);
|
||||
}
|
||||
|
||||
SAFE_DELETE_ARRAY(layouts);
|
||||
|
||||
SetInitialContents(GetResID(r), D3D12ResourceManager::InitialContentData(copyDst, 0, NULL));
|
||||
|
||||
@@ -264,6 +264,8 @@ WrappedID3D12DescriptorHeap::WrappedID3D12DescriptorHeap(ID3D12DescriptorHeap *r
|
||||
realCPUBase = real->GetCPUDescriptorHandleForHeapStart();
|
||||
realGPUBase = real->GetGPUDescriptorHandleForHeapStart();
|
||||
|
||||
SetResident(true);
|
||||
|
||||
increment = device->GetUnwrappedDescriptorIncrement(desc.Type);
|
||||
numDescriptors = desc.NumDescriptors;
|
||||
|
||||
|
||||
@@ -316,7 +316,8 @@ class WrappedID3D12DescriptorHeap : public WrappedDeviceChild12<ID3D12Descriptor
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE realCPUBase;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE realGPUBase;
|
||||
|
||||
UINT increment;
|
||||
UINT increment : 24;
|
||||
UINT resident : 8;
|
||||
UINT numDescriptors;
|
||||
|
||||
D3D12Descriptor *descriptors;
|
||||
@@ -335,6 +336,8 @@ public:
|
||||
|
||||
const D3D12Descriptor *GetDescriptors() { return descriptors; }
|
||||
UINT GetNumDescriptors() { return numDescriptors; }
|
||||
bool Resident() { return resident != 0; }
|
||||
void SetResident(bool r) { resident = r ? 1 : 0; }
|
||||
//////////////////////////////
|
||||
// implement ID3D12DescriptorHeap
|
||||
|
||||
@@ -646,6 +649,8 @@ class WrappedID3D12Resource : public WrappedDeviceChild12<ID3D12Resource>
|
||||
|
||||
static std::vector<AddressRange> m_Addresses;
|
||||
|
||||
bool resident;
|
||||
|
||||
public:
|
||||
ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D12Resource);
|
||||
|
||||
@@ -690,6 +695,7 @@ public:
|
||||
: WrappedDeviceChild12(real, device)
|
||||
{
|
||||
m_List[GetResourceID()] = this;
|
||||
SetResident(true);
|
||||
|
||||
// assuming only valid for buffers
|
||||
if(m_pReal->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
@@ -725,6 +731,9 @@ public:
|
||||
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool Resident() { return resident; }
|
||||
void SetResident(bool r) { resident = r; }
|
||||
//////////////////////////////
|
||||
// implement ID3D12Resource
|
||||
|
||||
|
||||
Reference in New Issue
Block a user