mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-24 23:46:41 +00:00
Serialise D3D12 buffer initial contents less memory-intensivesly
This commit is contained in:
@@ -102,6 +102,10 @@ void STDMETHODCALLTYPE WrappedID3D12CommandQueue::UpdateTileMappings(
|
||||
// register this heap as having been used for sparse binding
|
||||
m_pDevice->AddSparseHeap(GetResID(pHeap));
|
||||
|
||||
// mark the heap as dirty if this is a buffer resource
|
||||
if(pResource->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
GetResourceManager()->MarkDirtyResource(GetResID(pHeap));
|
||||
|
||||
// define macros to help provide the defaults for NULL arrays
|
||||
#define REGION_START(i) \
|
||||
(pResourceRegionStartCoordinates ? pResourceRegionStartCoordinates[i] \
|
||||
|
||||
@@ -537,6 +537,10 @@ bool D3D12InitParams::IsSupportedVersion(uint64_t ver)
|
||||
if(ver == 0x12)
|
||||
return true;
|
||||
|
||||
// 0x13 -> 0x14 - Reserved/placed buffers are serialised via their heaps not per-buffer
|
||||
if(ver == 0x13)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ struct D3D12InitParams
|
||||
UINT SDKVersion = 0;
|
||||
|
||||
// check if a frame capture section version is supported
|
||||
static const uint64_t CurrentVersion = 0x13;
|
||||
static const uint64_t CurrentVersion = 0x14;
|
||||
|
||||
static bool IsSupportedVersion(uint64_t ver);
|
||||
};
|
||||
|
||||
@@ -257,6 +257,7 @@ bool WrappedID3D12Device::Serialise_CreateResource(
|
||||
case D3D12Chunk::Device_CreateReservedResource2:
|
||||
APIProps.SparseResources = true;
|
||||
m_SparseResources.insert(GetResID(ret));
|
||||
m_ModResources.insert(GetResID(ret));
|
||||
default: break;
|
||||
}
|
||||
|
||||
@@ -601,7 +602,20 @@ HRESULT WrappedID3D12Device::CreateResource(
|
||||
if(pHeap)
|
||||
record->AddParent(GetRecord(pHeap));
|
||||
|
||||
// all resources are marked dirty here, but we will skip the bytes of initial contents for
|
||||
// sparse buffers (only the sparse tables get serialised) and initial contents entirely for
|
||||
// placed buffer resources. It would be slightly better to never mark placed buffer resources
|
||||
// dirty but the logic for dirtying resources with write references is generic and it's not much
|
||||
// cost to skip them at initial contents prepare time.
|
||||
GetResourceManager()->MarkDirtyResource(wrapped->GetResourceID());
|
||||
|
||||
// for placed buffers resources, the resource itself is not going to be serialised but the heap
|
||||
// underlying is. Sparse resources mark the heap dirty when first bound to pages
|
||||
if(desc0.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && pHeap)
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(GetResID(pHeap));
|
||||
GetResourceManager()->AddPlacedResource(wrapped->GetResourceID(), GetResID(pHeap));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -102,37 +102,65 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
SetInitialContents(heap->GetResourceID(), initContents);
|
||||
return true;
|
||||
}
|
||||
else if(type == Resource_Resource)
|
||||
else if(type == Resource_Resource || type == Resource_Heap)
|
||||
{
|
||||
WrappedID3D12Resource *r = (WrappedID3D12Resource *)res;
|
||||
ID3D12Pageable *unwrappedPageable = r->UnwrappedResidencyPageable();
|
||||
WrappedID3D12Resource *wrappedResource = (WrappedID3D12Resource *)res;
|
||||
ID3D12Resource *unwrappedResource = NULL;
|
||||
ID3D12Pageable *unwrappedPageable = NULL;
|
||||
|
||||
bool nonresident = false;
|
||||
if(!r->IsResident())
|
||||
nonresident = true;
|
||||
if(type == Resource_Heap)
|
||||
{
|
||||
wrappedResource = NULL;
|
||||
unwrappedResource = ((WrappedID3D12Heap *)res)->GetUnwrappedWholeMemBuffer();
|
||||
}
|
||||
else
|
||||
{
|
||||
unwrappedResource = wrappedResource->GetReal();
|
||||
unwrappedPageable = wrappedResource->UnwrappedResidencyPageable();
|
||||
|
||||
D3D12_RESOURCE_DESC desc = r->GetDesc();
|
||||
if(!wrappedResource->IsResident())
|
||||
nonresident = true;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_DESC desc = unwrappedResource->GetDesc();
|
||||
|
||||
D3D12InitialContents initContents;
|
||||
|
||||
Sparse::PageTable *sparseTable = NULL;
|
||||
|
||||
if(GetRecord(r)->sparseTable)
|
||||
sparseTable = new Sparse::PageTable(*GetRecord(r)->sparseTable);
|
||||
if(wrappedResource && GetRecord(wrappedResource)->sparseTable)
|
||||
sparseTable = new Sparse::PageTable(*GetRecord(wrappedResource)->sparseTable);
|
||||
|
||||
if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
{
|
||||
if(r->IsAccelerationStructureResource())
|
||||
if(type == Resource_Resource && wrappedResource->IsAccelerationStructureResource())
|
||||
{
|
||||
initContents = D3D12InitialContents(D3D12InitialContents::AccelerationStructure, NULL);
|
||||
SetInitialContents(GetResID(r), initContents);
|
||||
SetInitialContents(GetResID(res), initContents);
|
||||
return true;
|
||||
}
|
||||
|
||||
// if this is a sparse buffer, we don't serialise its contents so just save the sparse table itself
|
||||
if(sparseTable)
|
||||
{
|
||||
initContents = D3D12InitialContents(D3D12InitialContents::SparseOnly, NULL);
|
||||
initContents.sparseTable = sparseTable;
|
||||
|
||||
SetInitialContents(GetResID(res), initContents);
|
||||
return true;
|
||||
}
|
||||
|
||||
// placed buffer resources do not serialise initial contents
|
||||
if(type == Resource_Resource && wrappedResource->GetHeap())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
D3D12_HEAP_PROPERTIES heapProps = {};
|
||||
|
||||
if(sparseTable == NULL)
|
||||
r->GetHeapProperties(&heapProps, NULL);
|
||||
unwrappedResource->GetHeapProperties(&heapProps, NULL);
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
@@ -144,21 +172,21 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
byte *buffer = AllocAlignedBuffer(RDCMAX(desc.Width, 64ULL));
|
||||
|
||||
byte *bufData = NULL;
|
||||
hr = r->GetReal()->Map(0, NULL, (void **)&bufData);
|
||||
hr = unwrappedResource->Map(0, NULL, (void **)&bufData);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
memcpy(buffer, bufData, size);
|
||||
|
||||
D3D12_RANGE range = {};
|
||||
r->GetReal()->Unmap(0, &range);
|
||||
unwrappedResource->Unmap(0, &range);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Couldn't map directly readback buffer: HRESULT: %s", ToStr(hr).c_str());
|
||||
}
|
||||
|
||||
SetInitialContents(GetResID(r), D3D12InitialContents(buffer, size));
|
||||
SetInitialContents(GetResID(res), D3D12InitialContents(buffer, size));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -172,20 +200,23 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
if(nonresident)
|
||||
m_Device->GetReal()->MakeResident(1, &unwrappedPageable);
|
||||
|
||||
const SubresourceStateVector &states = m_Device->GetSubresourceStates(GetResID(res));
|
||||
RDCASSERT(states.size() == 1);
|
||||
const SubresourceStateVector empty;
|
||||
const SubresourceStateVector &states =
|
||||
type == Resource_Heap ? empty : m_Device->GetSubresourceStates(GetResID(res));
|
||||
RDCASSERT(type == Resource_Heap || states.size() == 1);
|
||||
|
||||
D3D12_RESOURCE_BARRIER barrier;
|
||||
// upload heap resources can't be transitioned, and any resources in the new layouts don't
|
||||
// need to either since each submit does a big flush
|
||||
const bool needsTransition = !isUploadHeap && states[0].IsStates() &&
|
||||
const bool needsTransition = type == Resource_Resource && !isUploadHeap &&
|
||||
states[0].IsStates() &&
|
||||
(states[0].ToStates() & D3D12_RESOURCE_STATE_COPY_SOURCE) == 0;
|
||||
|
||||
if(needsTransition)
|
||||
{
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.Transition.pResource = r->GetReal();
|
||||
barrier.Transition.pResource = unwrappedResource;
|
||||
barrier.Transition.Subresource = (UINT)0;
|
||||
barrier.Transition.StateBefore = states[0].ToStates();
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
|
||||
@@ -199,7 +230,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
list->CopyResource(copyDst, r->GetReal());
|
||||
list->CopyResource(copyDst, unwrappedResource);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -238,7 +269,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
|
||||
ID3D12Resource *arrayTexture = NULL;
|
||||
BarrierSet::AccessType accessType = BarrierSet::CopySourceAccess;
|
||||
ID3D12Resource *unwrappedCopySource = r->GetReal();
|
||||
ID3D12Resource *unwrappedCopySource = unwrappedResource;
|
||||
|
||||
bool isDepth =
|
||||
IsDepthFormat(desc.Format) || (desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) != 0;
|
||||
@@ -279,7 +310,8 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
|
||||
BarrierSet barriers;
|
||||
|
||||
barriers.Configure(r, m_Device->GetSubresourceStates(GetResID(r)), accessType);
|
||||
barriers.Configure(wrappedResource, m_Device->GetSubresourceStates(GetResID(wrappedResource)),
|
||||
accessType);
|
||||
barriers.Apply(list);
|
||||
|
||||
if(arrayTexture)
|
||||
@@ -291,7 +323,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
m_Device->FlushLists();
|
||||
|
||||
// expand multisamples out to array
|
||||
m_Device->GetDebugManager()->CopyTex2DMSToArray(NULL, arrayTexture, r->GetReal());
|
||||
m_Device->GetDebugManager()->CopyTex2DMSToArray(NULL, arrayTexture, unwrappedResource);
|
||||
|
||||
// open the initial state list again for the remainder of the work
|
||||
list = m_Device->GetInitialStateList();
|
||||
@@ -431,7 +463,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
|
||||
initContents.sparseTable = sparseTable;
|
||||
|
||||
SetInitialContents(GetResID(r), initContents);
|
||||
SetInitialContents(GetResID(res), initContents);
|
||||
return true;
|
||||
}
|
||||
else if(type == Resource_AccelerationStructure)
|
||||
@@ -857,7 +889,7 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI
|
||||
SetInitialContents(id, D3D12InitialContents(copyheap));
|
||||
}
|
||||
}
|
||||
else if(type == Resource_Resource)
|
||||
else if(type == Resource_Resource || type == Resource_Heap)
|
||||
{
|
||||
byte *ResourceContents = NULL;
|
||||
uint64_t ContentsLength = 0;
|
||||
@@ -868,7 +900,10 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI
|
||||
|
||||
if(IsReplayingAndReading())
|
||||
{
|
||||
liveRes = (ID3D12Resource *)GetLiveResource(id);
|
||||
ID3D12DeviceChild *live = GetLiveResource(id);
|
||||
liveRes = (ID3D12Resource *)live;
|
||||
if(type == Resource_Heap)
|
||||
liveRes = ((WrappedID3D12Heap *)live)->GetUnwrappedWholeMemBuffer();
|
||||
}
|
||||
|
||||
SparseBinds *sparseBinds = NULL;
|
||||
@@ -906,7 +941,8 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI
|
||||
|
||||
mappedBuffer = (ID3D12Resource *)initial->resource;
|
||||
|
||||
if(initial->tag == D3D12InitialContents::AccelerationStructure)
|
||||
if(initial->tag == D3D12InitialContents::AccelerationStructure ||
|
||||
initial->tag == D3D12InitialContents::SparseOnly)
|
||||
{
|
||||
mappedBuffer = NULL;
|
||||
}
|
||||
@@ -943,7 +979,7 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI
|
||||
D3D12_RESOURCE_DESC resDesc = liveRes->GetDesc();
|
||||
|
||||
D3D12_HEAP_PROPERTIES heapProps = {};
|
||||
if(!m_Device->IsSparseResource(GetResID(liveRes)))
|
||||
if(!m_Device->IsSparseResource(GetLiveID(id)))
|
||||
liveRes->GetHeapProperties(&heapProps, NULL);
|
||||
|
||||
const bool isCPUCopyHeap =
|
||||
@@ -952,13 +988,25 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI
|
||||
heapProps.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE) &&
|
||||
heapProps.MemoryPoolPreference == D3D12_MEMORY_POOL_L0;
|
||||
|
||||
if(((WrappedID3D12Resource *)liveRes)->IsAccelerationStructureResource())
|
||||
if(type == Resource_Resource &&
|
||||
((WrappedID3D12Resource *)liveRes)->IsAccelerationStructureResource())
|
||||
{
|
||||
mappedBuffer = NULL;
|
||||
|
||||
D3D12InitialContents initContents(D3D12InitialContents::AccelerationStructure, NULL);
|
||||
SetInitialContents(id, initContents);
|
||||
}
|
||||
// from verison 0x14 onwards we don't serialise the contents of sparse resources
|
||||
else if(type == Resource_Resource && sparseBinds && ser.VersionAtLeast(0x14) &&
|
||||
ContentsLength == 0)
|
||||
{
|
||||
mappedBuffer = NULL;
|
||||
|
||||
D3D12InitialContents initContents(D3D12InitialContents::SparseOnly, NULL);
|
||||
initContents.sparseBinds = sparseBinds;
|
||||
|
||||
SetInitialContents(id, initContents);
|
||||
}
|
||||
else if(heapProps.Type == D3D12_HEAP_TYPE_UPLOAD || isCPUCopyHeap)
|
||||
{
|
||||
// if destination is on the upload heap, it's impossible to copy via the device,
|
||||
@@ -968,7 +1016,7 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI
|
||||
|
||||
D3D12InitialContents initContents(D3D12InitialContents::Copy, type);
|
||||
ResourceContents = initContents.srcData = AllocAlignedBuffer(RDCMAX(ContentsLength, 64ULL));
|
||||
initContents.resourceType = Resource_Resource;
|
||||
initContents.resourceType = type;
|
||||
SetInitialContents(id, initContents);
|
||||
}
|
||||
else
|
||||
@@ -1044,7 +1092,7 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI
|
||||
if(IsReplayingAndReading() && mappedBuffer)
|
||||
{
|
||||
D3D12InitialContents initContents(D3D12InitialContents::Copy, type);
|
||||
initContents.resourceType = Resource_Resource;
|
||||
initContents.resourceType = type;
|
||||
initContents.resource = mappedBuffer;
|
||||
|
||||
initContents.sparseBinds = sparseBinds;
|
||||
@@ -1066,7 +1114,7 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI
|
||||
else
|
||||
{
|
||||
D3D12_HEAP_PROPERTIES heapProps = {};
|
||||
if(!m_Device->IsSparseResource(GetResID(liveRes)))
|
||||
if(!m_Device->IsSparseResource(GetLiveID(id)))
|
||||
liveRes->GetHeapProperties(&heapProps, NULL);
|
||||
|
||||
// if the resource is sparse, create on default heap
|
||||
@@ -1657,24 +1705,39 @@ void D3D12ResourceManager::Create_InitialState(ResourceId id, ID3D12DeviceChild
|
||||
// it all entirely undefined.
|
||||
SetInitialContents(id, D3D12InitialContents((ID3D12DescriptorHeap *)NULL));
|
||||
}
|
||||
else if(type == Resource_Resource)
|
||||
else if(type == Resource_Resource || type == Resource_Heap)
|
||||
{
|
||||
ID3D12Resource *res = ((ID3D12Resource *)live);
|
||||
|
||||
WrappedID3D12Resource *wrappedResource = (WrappedID3D12Resource *)res;
|
||||
|
||||
if(wrappedResource->IsAccelerationStructureResource())
|
||||
D3D12_HEAP_PROPERTIES heapProps = {};
|
||||
D3D12_RESOURCE_DESC resDesc = {};
|
||||
if(type == Resource_Heap)
|
||||
{
|
||||
wrappedResource = NULL;
|
||||
res = NULL;
|
||||
resDesc = ((WrappedID3D12Heap *)live)->GetUnwrappedWholeMemBuffer()->GetDesc();
|
||||
heapProps = ((WrappedID3D12Heap *)live)->GetDesc().Properties;
|
||||
}
|
||||
else if(wrappedResource->IsAccelerationStructureResource())
|
||||
{
|
||||
SetInitialContents(id, D3D12InitialContents(D3D12InitialContents::AccelerationStructure,
|
||||
(ID3D12Resource *)NULL));
|
||||
return;
|
||||
}
|
||||
else if(wrappedResource->GetHeap())
|
||||
{
|
||||
// don't create initial states for placed resources
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
resDesc = res->GetDesc();
|
||||
|
||||
D3D12_RESOURCE_DESC resDesc = res->GetDesc();
|
||||
|
||||
D3D12_HEAP_PROPERTIES heapProps = {};
|
||||
if(!m_Device->IsSparseResource(GetResID(live)))
|
||||
res->GetHeapProperties(&heapProps, NULL);
|
||||
if(!m_Device->IsSparseResource(GetResID(live)))
|
||||
res->GetHeapProperties(&heapProps, NULL);
|
||||
}
|
||||
|
||||
const bool isCPUCopyHeap = heapProps.Type == D3D12_HEAP_TYPE_CUSTOM &&
|
||||
(heapProps.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK ||
|
||||
@@ -1727,7 +1790,7 @@ void D3D12ResourceManager::Create_InitialState(ResourceId id, ID3D12DeviceChild
|
||||
else
|
||||
{
|
||||
D3D12InitialContents initContents(D3D12InitialContents::ForceCopy, type);
|
||||
initContents.resourceType = Resource_Resource;
|
||||
initContents.resourceType = type;
|
||||
initContents.resource = copy;
|
||||
|
||||
if(m_Device->IsSparseResource(GetResID(live)))
|
||||
@@ -1768,7 +1831,7 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, D3D12Init
|
||||
srcheap->GetCPUDescriptorHandleForHeapStart(), srcheap->GetDesc().Type);
|
||||
}
|
||||
}
|
||||
else if(type == Resource_Resource)
|
||||
else if(type == Resource_Resource || type == Resource_Heap)
|
||||
{
|
||||
if(data.tag == D3D12InitialContents::AccelerationStructure)
|
||||
return;
|
||||
@@ -1778,13 +1841,32 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, D3D12Init
|
||||
if(IsActiveReplaying(m_State) && m_Device->IsReadOnlyResource(id))
|
||||
{
|
||||
}
|
||||
else if(data.tag == D3D12InitialContents::SparseOnly)
|
||||
{
|
||||
if(IsLoading(m_State) || m_Device->GetQueue()->IsSparseUpdatedResource(GetResID(live)))
|
||||
data.sparseBinds->Apply(m_Device, (ID3D12Resource *)live);
|
||||
|
||||
if(m_Device->HasFatalError())
|
||||
return;
|
||||
}
|
||||
else if(data.tag == D3D12InitialContents::Copy || data.tag == D3D12InitialContents::ForceCopy)
|
||||
{
|
||||
ID3D12Resource *copyDst = (ID3D12Resource *)live;
|
||||
ID3D12Resource *wrappedCopyDst = NULL;
|
||||
ID3D12Resource *unwrappedCopyDst = NULL;
|
||||
|
||||
if(!copyDst)
|
||||
if(type == Resource_Heap)
|
||||
{
|
||||
RDCERR("Missing copy destination in initial state apply (%p)", copyDst);
|
||||
unwrappedCopyDst = ((WrappedID3D12Heap *)live)->GetUnwrappedWholeMemBuffer();
|
||||
}
|
||||
else
|
||||
{
|
||||
wrappedCopyDst = (ID3D12Resource *)live;
|
||||
unwrappedCopyDst = Unwrap(wrappedCopyDst);
|
||||
}
|
||||
|
||||
if(!unwrappedCopyDst)
|
||||
{
|
||||
RDCERR("Missing copy destination in initial state apply (%p)", unwrappedCopyDst);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1799,7 +1881,7 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, D3D12Init
|
||||
}
|
||||
else
|
||||
{
|
||||
copyDst->GetHeapProperties(&heapProps, NULL);
|
||||
unwrappedCopyDst->GetHeapProperties(&heapProps, NULL);
|
||||
}
|
||||
|
||||
const bool isCPUCopyHeap =
|
||||
@@ -1823,11 +1905,11 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, D3D12Init
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
D3D12_RESOURCE_DESC desc = copyDst->GetDesc();
|
||||
D3D12_RESOURCE_DESC desc = unwrappedCopyDst->GetDesc();
|
||||
|
||||
if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
{
|
||||
hr = Unwrap(copyDst)->Map(0, NULL, (void **)&dst);
|
||||
hr = unwrappedCopyDst->Map(0, NULL, (void **)&dst);
|
||||
CHECK_HR(m_Device, hr);
|
||||
|
||||
if(FAILED(hr))
|
||||
@@ -1837,10 +1919,10 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, D3D12Init
|
||||
}
|
||||
|
||||
if(src && dst)
|
||||
memcpy(dst, src, (size_t)copyDst->GetDesc().Width);
|
||||
memcpy(dst, src, (size_t)unwrappedCopyDst->GetDesc().Width);
|
||||
|
||||
if(dst)
|
||||
Unwrap(copyDst)->Unmap(0, NULL);
|
||||
unwrappedCopyDst->Unmap(0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1859,9 +1941,9 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, D3D12Init
|
||||
for(UINT i = 0; i < numSubresources; i++)
|
||||
{
|
||||
if(desc.Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN)
|
||||
hr = Unwrap(copyDst)->Map(i, NULL, NULL);
|
||||
hr = unwrappedCopyDst->Map(i, NULL, NULL);
|
||||
else
|
||||
hr = Unwrap(copyDst)->Map(i, NULL, (void **)&dst);
|
||||
hr = unwrappedCopyDst->Map(i, NULL, (void **)&dst);
|
||||
CHECK_HR(m_Device, hr);
|
||||
|
||||
if(FAILED(hr))
|
||||
@@ -1889,8 +1971,8 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, D3D12Init
|
||||
if(texPtr)
|
||||
memcpy(bufPtr, texPtr, (size_t)rowsizes[i]);
|
||||
else
|
||||
copyDst->WriteToSubresource(i, &box, bufPtr, (UINT)rowsizes[i],
|
||||
(UINT)rowsizes[i]);
|
||||
unwrappedCopyDst->WriteToSubresource(i, &box, bufPtr, (UINT)rowsizes[i],
|
||||
(UINT)rowsizes[i]);
|
||||
|
||||
bufPtr += layouts[i].Footprint.RowPitch;
|
||||
if(texPtr)
|
||||
@@ -1906,7 +1988,7 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, D3D12Init
|
||||
}
|
||||
|
||||
if(dst)
|
||||
Unwrap(copyDst)->Unmap(i, NULL);
|
||||
unwrappedCopyDst->Unmap(i, NULL);
|
||||
}
|
||||
|
||||
delete[] layouts;
|
||||
@@ -1931,26 +2013,31 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, D3D12Init
|
||||
|
||||
BarrierSet barriers;
|
||||
|
||||
barriers.Configure(copyDst, m_Device->GetSubresourceStates(GetResID(live)),
|
||||
BarrierSet::CopyDestAccess);
|
||||
barriers.Apply(list);
|
||||
if(type != Resource_Heap)
|
||||
{
|
||||
barriers.Configure(wrappedCopyDst, m_Device->GetSubresourceStates(GetResID(live)),
|
||||
BarrierSet::CopyDestAccess);
|
||||
barriers.Apply(list);
|
||||
}
|
||||
|
||||
if(copyDst->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
if(unwrappedCopyDst->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
{
|
||||
D3D12_RESOURCE_DESC srcDesc = copySrc->GetDesc();
|
||||
D3D12_RESOURCE_DESC dstDesc = copyDst->GetDesc();
|
||||
D3D12_RESOURCE_DESC dstDesc = unwrappedCopyDst->GetDesc();
|
||||
|
||||
list->CopyBufferRegion(copyDst, 0, copySrc, 0, RDCMIN(srcDesc.Width, dstDesc.Width));
|
||||
Unwrap(list)->CopyBufferRegion(unwrappedCopyDst, 0, Unwrap(copySrc), 0,
|
||||
RDCMIN(srcDesc.Width, dstDesc.Width));
|
||||
}
|
||||
else if(copyDst->GetDesc().SampleDesc.Count > 1 || data.tag == D3D12InitialContents::ForceCopy)
|
||||
else if(unwrappedCopyDst->GetDesc().SampleDesc.Count > 1 ||
|
||||
data.tag == D3D12InitialContents::ForceCopy)
|
||||
{
|
||||
// MSAA texture was pre-uploaded and decoded, just copy the texture.
|
||||
// Similarly for created initial states
|
||||
list->CopyResource(copyDst, copySrc);
|
||||
Unwrap(list)->CopyResource(unwrappedCopyDst, Unwrap(copySrc));
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc = copyDst->GetDesc();
|
||||
D3D12_RESOURCE_DESC desc = unwrappedCopyDst->GetDesc();
|
||||
|
||||
UINT numSubresources = desc.MipLevels;
|
||||
if(desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D)
|
||||
@@ -1995,11 +2082,11 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, D3D12Init
|
||||
D3D12_TEXTURE_COPY_LOCATION dst, src;
|
||||
|
||||
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dst.pResource = copyDst;
|
||||
dst.pResource = unwrappedCopyDst;
|
||||
dst.SubresourceIndex = i;
|
||||
|
||||
src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
src.pResource = copySrc;
|
||||
src.pResource = Unwrap(copySrc);
|
||||
|
||||
m_Device->GetCopyableFootprints(&desc, i, 1, offset, &src.PlacedFootprint, NULL, NULL,
|
||||
&subSize);
|
||||
@@ -2010,7 +2097,7 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, D3D12Init
|
||||
continue;
|
||||
}
|
||||
|
||||
list->CopyTextureRegion(&dst, 0, 0, 0, &src, NULL);
|
||||
Unwrap(list)->CopyTextureRegion(&dst, 0, 0, 0, &src, NULL);
|
||||
|
||||
offset += subSize;
|
||||
offset = AlignUp<UINT64>(offset, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
|
||||
@@ -2025,7 +2112,10 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, D3D12Init
|
||||
}
|
||||
}
|
||||
|
||||
barriers.Unapply(list);
|
||||
if(type != Resource_Heap)
|
||||
{
|
||||
barriers.Unapply(list);
|
||||
}
|
||||
|
||||
if(D3D12_Debug_SingleSubmitFlushing())
|
||||
{
|
||||
|
||||
@@ -717,7 +717,9 @@ struct D3D12InitialContents
|
||||
// for created initial states we always have an identical resource
|
||||
ForceCopy,
|
||||
// for handling acceleration structures
|
||||
AccelerationStructure
|
||||
AccelerationStructure,
|
||||
// for sparse buffers with no contents
|
||||
SparseOnly,
|
||||
};
|
||||
D3D12InitialContents(D3D12Descriptor *d, uint32_t n) : D3D12InitialContents()
|
||||
{
|
||||
@@ -1486,6 +1488,44 @@ public:
|
||||
|
||||
D3D12GpuBufferAllocator &GetGPUBufferAllocator() { return m_GPUBufferAllocator; }
|
||||
|
||||
void AddPlacedResource(ResourceId resId, ResourceId heapId)
|
||||
{
|
||||
SCOPED_LOCK(m_PlacedLock);
|
||||
m_PlacedHeapForResource[resId] = heapId;
|
||||
}
|
||||
|
||||
void RemovePlacedResource(ResourceId resId)
|
||||
{
|
||||
SCOPED_LOCK(m_PlacedLock);
|
||||
m_PlacedHeapForResource.erase(resId);
|
||||
}
|
||||
|
||||
ResourceId GetPlacedHeapForResource(ResourceId resId)
|
||||
{
|
||||
SCOPED_LOCK(m_PlacedLock);
|
||||
auto it = m_PlacedHeapForResource.find(resId);
|
||||
if(it == m_PlacedHeapForResource.end())
|
||||
return ResourceId();
|
||||
return it->second;
|
||||
}
|
||||
|
||||
template <typename Compose>
|
||||
void MarkResourceFrameReferenced(ResourceId id, FrameRefType refType, Compose comp)
|
||||
{
|
||||
ResourceManager::MarkResourceFrameReferenced(id, refType, comp);
|
||||
ResourceId id2 = GetPlacedHeapForResource(id);
|
||||
if(id2 != ResourceId())
|
||||
ResourceManager::MarkResourceFrameReferenced(id2, refType, comp);
|
||||
}
|
||||
|
||||
inline void MarkResourceFrameReferenced(ResourceId id, FrameRefType refType)
|
||||
{
|
||||
ResourceManager::MarkResourceFrameReferenced(id, refType);
|
||||
ResourceId id2 = GetPlacedHeapForResource(id);
|
||||
if(id2 != ResourceId())
|
||||
ResourceManager::MarkResourceFrameReferenced(id2, refType);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void SerialiseResourceStates(SerialiserType &ser, BarrierSet &barriers,
|
||||
std::map<ResourceId, SubresourceStateVector> &states,
|
||||
@@ -1517,6 +1557,9 @@ private:
|
||||
D3D12RTManager *m_RTManager;
|
||||
D3D12GpuBufferAllocator m_GPUBufferAllocator;
|
||||
|
||||
Threading::CriticalSection m_PlacedLock;
|
||||
std::unordered_map<ResourceId, ResourceId> m_PlacedHeapForResource;
|
||||
|
||||
// dummy handle to use - starting from near highest valid pointer to minimise risk of overlap with real handles
|
||||
static const uint64_t FirstDummyHandle = UINTPTR_MAX - 1024;
|
||||
uint64_t m_DummyHandle = FirstDummyHandle;
|
||||
|
||||
@@ -159,6 +159,38 @@ D3D12AccelerationStructure::~D3D12AccelerationStructure()
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
WrappedID3D12Heap::WrappedID3D12Heap(ID3D12Heap *real, WrappedID3D12Device *device)
|
||||
: WrappedDeviceChild12(real, device)
|
||||
{
|
||||
D3D12_HEAP_DESC desc = GetDesc();
|
||||
if((desc.Flags & D3D12_HEAP_FLAG_DENY_BUFFERS) == 0)
|
||||
{
|
||||
D3D12_RESOURCE_DESC resDesc = {};
|
||||
resDesc.Width = GetDesc().SizeInBytes;
|
||||
resDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
resDesc.Height = 1;
|
||||
resDesc.DepthOrArraySize = 1;
|
||||
resDesc.MipLevels = 1;
|
||||
resDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
resDesc.SampleDesc.Count = 1;
|
||||
|
||||
if(desc.Flags & D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER)
|
||||
resDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER;
|
||||
|
||||
D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_COMMON;
|
||||
if(desc.Properties.Type == D3D12_HEAP_TYPE_UPLOAD)
|
||||
state = D3D12_RESOURCE_STATE_GENERIC_READ;
|
||||
else if(desc.Properties.Type == D3D12_HEAP_TYPE_READBACK)
|
||||
state = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
|
||||
HRESULT hr =
|
||||
device->GetReal()->CreatePlacedResource(real, 0, &resDesc, D3D12_RESOURCE_STATE_COMMON, NULL,
|
||||
__uuidof(ID3D12Resource), (void **)&m_WholeMem);
|
||||
|
||||
RDCASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
}
|
||||
|
||||
bool WrappedID3D12Resource::CreateAccStruct(D3D12BufferOffset bufferOffset,
|
||||
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE type,
|
||||
UINT64 byteSize, ResourceId id,
|
||||
@@ -216,6 +248,8 @@ WrappedID3D12Resource::~WrappedID3D12Resource()
|
||||
SAFE_RELEASE(it->second);
|
||||
}
|
||||
|
||||
m_pDevice->GetResourceManager()->RemovePlacedResource(GetResourceID());
|
||||
|
||||
if(IsReplayMode(m_pDevice->GetState()))
|
||||
m_pDevice->RemoveReplayResource(GetResourceID());
|
||||
|
||||
|
||||
@@ -721,6 +721,8 @@ class WrappedID3D12Heap : public WrappedDeviceChild12<ID3D12Heap, ID3D12Heap1>,
|
||||
public ID3D12PageableTools
|
||||
{
|
||||
ID3D12PageableTools *m_Pageable = NULL;
|
||||
|
||||
ID3D12Resource *m_WholeMem = NULL;
|
||||
public:
|
||||
ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D12Heap);
|
||||
|
||||
@@ -729,12 +731,12 @@ public:
|
||||
TypeEnum = Resource_Heap,
|
||||
};
|
||||
|
||||
WrappedID3D12Heap(ID3D12Heap *real, WrappedID3D12Device *device)
|
||||
: WrappedDeviceChild12(real, device)
|
||||
{
|
||||
}
|
||||
ID3D12Resource *GetUnwrappedWholeMemBuffer() { return m_WholeMem; }
|
||||
|
||||
WrappedID3D12Heap(ID3D12Heap *real, WrappedID3D12Device *device);
|
||||
virtual ~WrappedID3D12Heap()
|
||||
{
|
||||
SAFE_RELEASE(m_WholeMem);
|
||||
SAFE_RELEASE(m_Pageable);
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user