Handle descriptors as if they are volatile and track mid-capture updates

This commit is contained in:
baldurk
2016-10-14 11:56:33 +02:00
parent c37ee2bb03
commit f436c4a6bf
8 changed files with 360 additions and 22 deletions
@@ -347,6 +347,9 @@ void WrappedID3D12CommandQueue::ProcessChunk(uint64_t offset, D3D12ChunkType chu
m_ReplayList->Serialise_SetComputeRootUnorderedAccessView(0, D3D12_GPU_VIRTUAL_ADDRESS());
break;
case DYN_DESC_WRITE: m_pDevice->Serialise_DynamicDescriptorWrite(NULL); break;
case DYN_DESC_COPIES: m_pDevice->Serialise_DynamicDescriptorCopies(NULL); break;
case EXECUTE_CMD_LISTS: Serialise_ExecuteCommandLists(0, NULL); break;
case SIGNAL: Serialise_Signal(NULL, 0); break;
case CONTEXT_CAPTURE_FOOTER:
+2 -1
View File
@@ -494,7 +494,8 @@ void Serialiser::Serialise(const char *name, D3D12Descriptor &el)
PortableHandle handle;
if(m_Mode >= WRITING)
handle = PortableHandle(el.samp.heap->GetResourceID(), el.samp.idx);
handle =
PortableHandle(el.samp.heap ? el.samp.heap->GetResourceID() : ResourceId(), el.samp.idx);
Serialise("handle", handle);
+3
View File
@@ -330,6 +330,9 @@ void Serialiser::Serialise(const char *name, D3D12Descriptor &el);
D3D12_CHUNK_MACRO(SET_COMP_ROOT_UAV, \
"ID3D12GraphicsCommandList::SetComputeRootUnorderedAccessView") \
\
D3D12_CHUNK_MACRO(DYN_DESC_WRITE, "Dynamic descriptor write") \
D3D12_CHUNK_MACRO(DYN_DESC_COPIES, "Dynamic descriptor copies") \
\
D3D12_CHUNK_MACRO(EXECUTE_CMD_LISTS, "ID3D12GraphicsCommandQueue::ExecuteCommandLists") \
D3D12_CHUNK_MACRO(SIGNAL, "ID3D12GraphicsCommandQueue::Signal") \
\
+20
View File
@@ -1223,6 +1223,8 @@ bool WrappedID3D12Device::EndFrameCapture(void *dev, void *wnd)
GetResourceManager()->FlushPendingDirty();
FlushPendingDescriptorWrites();
return true;
}
@@ -1252,6 +1254,24 @@ void WrappedID3D12Device::ReleaseResource(ID3D12DeviceChild *res)
}
}
void WrappedID3D12Device::FlushPendingDescriptorWrites()
{
std::vector<DynamicDescriptorWrite> writes;
std::vector<DynamicDescriptorCopy> copies;
{
SCOPED_LOCK(m_D3DLock);
writes.swap(m_DynamicDescriptorWrites);
copies.swap(m_DynamicDescriptorCopies);
}
for(size_t i = 0; i < writes.size(); i++)
writes[i].dest->CopyFrom(writes[i].desc);
for(size_t i = 0; i < copies.size(); i++)
copies[i].dst->CopyFrom(*copies[i].src);
}
bool WrappedID3D12Device::Serialise_SetShaderDebugPath(ID3D12DeviceChild *res, const char *p)
{
SERIALISE_ELEMENT(ResourceId, resource, GetResID(res));
+8
View File
@@ -269,6 +269,11 @@ private:
ResourceId m_ResourceID;
D3D12ResourceRecord *m_DeviceRecord;
std::vector<DynamicDescriptorCopy> m_DynamicDescriptorCopies;
std::vector<DynamicDescriptorWrite> m_DynamicDescriptorWrites;
void FlushPendingDescriptorWrites();
// used both on capture and replay side to track resource states. Only locked
// in capture
map<ResourceId, SubresourceStateVector> m_ResourceStates;
@@ -362,6 +367,9 @@ public:
bool Serialise_BeginCaptureFrame(bool applyInitialState);
bool Serialise_DynamicDescriptorWrite(const DynamicDescriptorWrite *write);
bool Serialise_DynamicDescriptorCopies(const std::vector<DynamicDescriptorCopy> *copies);
void ReadLogInitialisation();
void ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType);
+271 -11
View File
@@ -559,10 +559,61 @@ HRESULT WrappedID3D12Device::CreateRootSignature(UINT nodeMask, const void *pBlo
return ret;
}
bool WrappedID3D12Device::Serialise_DynamicDescriptorWrite(const DynamicDescriptorWrite *write)
{
SERIALISE_ELEMENT(D3D12Descriptor, desc, write->desc);
SERIALISE_ELEMENT(PortableHandle, dst, ToPortableHandle(write->dest));
if(m_State <= EXECUTING)
{
WrappedID3D12DescriptorHeap *heap =
GetResourceManager()->GetLiveAs<WrappedID3D12DescriptorHeap>(dst.heap);
if(heap)
{
// get the wrapped handle
D3D12_CPU_DESCRIPTOR_HANDLE handle = heap->GetCPUDescriptorHandleForHeapStart();
handle.ptr += dst.index * sizeof(D3D12Descriptor);
// safe to pass an invalid heap type to Create() as these descriptors will by definition not
// be undefined
RDCASSERT(desc.GetType() != D3D12Descriptor::TypeUndefined);
desc.Create(D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES, this, handle);
}
}
return true;
}
void WrappedID3D12Device::CreateConstantBufferView(const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc,
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
{
GetWrapped(DestDescriptor)->Init(pDesc);
// assume descriptors are volatile
if(m_State == WRITING_CAPFRAME)
{
SCOPED_LOCK(m_D3DLock);
DynamicDescriptorWrite write;
write.desc.samp.heap = NULL;
write.desc.samp.idx = 0;
write.desc.Init(pDesc);
write.dest = GetWrapped(DestDescriptor);
m_DynamicDescriptorWrites.push_back(write);
{
SCOPED_SERIALISE_CONTEXT(DYN_DESC_WRITE);
Serialise_DynamicDescriptorWrite(&write);
m_FrameCaptureRecord->AddChunk(scope.Get());
}
GetResourceManager()->MarkResourceFrameReferenced(
WrappedID3D12Resource::GetResIDFromAddr(pDesc->BufferLocation), eFrameRef_Read);
}
else
{
GetWrapped(DestDescriptor)->Init(pDesc);
}
return m_pDevice->CreateConstantBufferView(pDesc, Unwrap(DestDescriptor));
}
@@ -570,7 +621,31 @@ void WrappedID3D12Device::CreateShaderResourceView(ID3D12Resource *pResource,
const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc,
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
{
GetWrapped(DestDescriptor)->Init(pResource, pDesc);
// assume descriptors are volatile
if(m_State == WRITING_CAPFRAME)
{
SCOPED_LOCK(m_D3DLock);
DynamicDescriptorWrite write;
write.desc.samp.heap = NULL;
write.desc.samp.idx = 0;
write.desc.Init(pResource, pDesc);
write.dest = GetWrapped(DestDescriptor);
m_DynamicDescriptorWrites.push_back(write);
{
SCOPED_SERIALISE_CONTEXT(DYN_DESC_WRITE);
Serialise_DynamicDescriptorWrite(&write);
m_FrameCaptureRecord->AddChunk(scope.Get());
}
GetResourceManager()->MarkResourceFrameReferenced(GetResID(pResource), eFrameRef_Read);
}
else
{
GetWrapped(DestDescriptor)->Init(pResource, pDesc);
}
return m_pDevice->CreateShaderResourceView(Unwrap(pResource), pDesc, Unwrap(DestDescriptor));
}
@@ -579,7 +654,33 @@ void WrappedID3D12Device::CreateUnorderedAccessView(ID3D12Resource *pResource,
const D3D12_UNORDERED_ACCESS_VIEW_DESC *pDesc,
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
{
GetWrapped(DestDescriptor)->Init(pResource, pCounterResource, pDesc);
// assume descriptors are volatile
if(m_State == WRITING_CAPFRAME)
{
SCOPED_LOCK(m_D3DLock);
DynamicDescriptorWrite write;
write.desc.samp.heap = NULL;
write.desc.samp.idx = 0;
write.desc.Init(pResource, pCounterResource, pDesc);
write.dest = GetWrapped(DestDescriptor);
m_DynamicDescriptorWrites.push_back(write);
{
SCOPED_SERIALISE_CONTEXT(DYN_DESC_WRITE);
Serialise_DynamicDescriptorWrite(&write);
m_FrameCaptureRecord->AddChunk(scope.Get());
}
GetResourceManager()->MarkResourceFrameReferenced(GetResID(pResource), eFrameRef_Write);
if(pCounterResource)
GetResourceManager()->MarkResourceFrameReferenced(GetResID(pCounterResource), eFrameRef_Write);
}
else
{
GetWrapped(DestDescriptor)->Init(pResource, pCounterResource, pDesc);
}
return m_pDevice->CreateUnorderedAccessView(Unwrap(pResource), Unwrap(pCounterResource), pDesc,
Unwrap(DestDescriptor));
}
@@ -588,7 +689,31 @@ void WrappedID3D12Device::CreateRenderTargetView(ID3D12Resource *pResource,
const D3D12_RENDER_TARGET_VIEW_DESC *pDesc,
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
{
GetWrapped(DestDescriptor)->Init(pResource, pDesc);
// assume descriptors are volatile
if(m_State == WRITING_CAPFRAME)
{
SCOPED_LOCK(m_D3DLock);
DynamicDescriptorWrite write;
write.desc.samp.heap = NULL;
write.desc.samp.idx = 0;
write.desc.Init(pResource, pDesc);
write.dest = GetWrapped(DestDescriptor);
m_DynamicDescriptorWrites.push_back(write);
{
SCOPED_SERIALISE_CONTEXT(DYN_DESC_WRITE);
Serialise_DynamicDescriptorWrite(&write);
m_FrameCaptureRecord->AddChunk(scope.Get());
}
GetResourceManager()->MarkResourceFrameReferenced(GetResID(pResource), eFrameRef_Write);
}
else
{
GetWrapped(DestDescriptor)->Init(pResource, pDesc);
}
return m_pDevice->CreateRenderTargetView(Unwrap(pResource), pDesc, Unwrap(DestDescriptor));
}
@@ -596,14 +721,60 @@ void WrappedID3D12Device::CreateDepthStencilView(ID3D12Resource *pResource,
const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc,
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
{
GetWrapped(DestDescriptor)->Init(pResource, pDesc);
// assume descriptors are volatile
if(m_State == WRITING_CAPFRAME)
{
SCOPED_LOCK(m_D3DLock);
DynamicDescriptorWrite write;
write.desc.samp.heap = NULL;
write.desc.samp.idx = 0;
write.desc.Init(pResource, pDesc);
write.dest = GetWrapped(DestDescriptor);
m_DynamicDescriptorWrites.push_back(write);
{
SCOPED_SERIALISE_CONTEXT(DYN_DESC_WRITE);
Serialise_DynamicDescriptorWrite(&write);
m_FrameCaptureRecord->AddChunk(scope.Get());
}
GetResourceManager()->MarkResourceFrameReferenced(GetResID(pResource), eFrameRef_Write);
}
else
{
GetWrapped(DestDescriptor)->Init(pResource, pDesc);
}
return m_pDevice->CreateDepthStencilView(Unwrap(pResource), pDesc, Unwrap(DestDescriptor));
}
void WrappedID3D12Device::CreateSampler(const D3D12_SAMPLER_DESC *pDesc,
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
{
GetWrapped(DestDescriptor)->Init(pDesc);
// assume descriptors are volatile
if(m_State == WRITING_CAPFRAME)
{
SCOPED_LOCK(m_D3DLock);
DynamicDescriptorWrite write;
write.desc.samp.heap = NULL;
write.desc.samp.idx = 0;
write.desc.Init(pDesc);
write.dest = GetWrapped(DestDescriptor);
m_DynamicDescriptorWrites.push_back(write);
{
SCOPED_SERIALISE_CONTEXT(DYN_DESC_WRITE);
Serialise_DynamicDescriptorWrite(&write);
m_DeviceRecord->AddChunk(scope.Get());
}
}
else
{
GetWrapped(DestDescriptor)->Init(pDesc);
}
return m_pDevice->CreateSampler(pDesc, Unwrap(DestDescriptor));
}
@@ -1133,6 +1304,32 @@ HRESULT WrappedID3D12Device::CreateSharedHandle(ID3D12DeviceChild *pObject,
return m_pDevice->CreateSharedHandle(Unwrap(pObject), pAttributes, Access, Name, pHandle);
}
bool WrappedID3D12Device::Serialise_DynamicDescriptorCopies(
const std::vector<DynamicDescriptorCopy> *copies)
{
SERIALISE_ELEMENT(uint32_t, numCopies, (uint32_t)copies->size());
const DynamicDescriptorCopy *descCopies = copies ? &(*copies)[0] : NULL;
// not optimal, but simple for now
for(uint32_t i = 0; i < numCopies; i++)
{
SERIALISE_ELEMENT(PortableHandle, dst, ToPortableHandle(descCopies[i].dst));
SERIALISE_ELEMENT(PortableHandle, src, ToPortableHandle(descCopies[i].src));
SERIALISE_ELEMENT(D3D12_DESCRIPTOR_HEAP_TYPE, type, descCopies[i].type);
if(m_State <= EXECUTING)
{
D3D12_CPU_DESCRIPTOR_HANDLE dsthandle = CPUHandleFromPortableHandle(GetResourceManager(), dst);
D3D12_CPU_DESCRIPTOR_HANDLE srchandle = CPUHandleFromPortableHandle(GetResourceManager(), src);
m_pDevice->CopyDescriptorsSimple(1, dsthandle, srchandle, type);
}
}
return true;
}
void WrappedID3D12Device::CopyDescriptors(
UINT NumDestDescriptorRanges, const D3D12_CPU_DESCRIPTOR_HANDLE *pDestDescriptorRangeStarts,
const UINT *pDestDescriptorRangeSizes, UINT NumSrcDescriptorRanges,
@@ -1158,15 +1355,28 @@ void WrappedID3D12Device::CopyDescriptors(
D3D12Descriptor *src = GetWrapped(pSrcDescriptorRangeStarts[0]);
D3D12Descriptor *dst = GetWrapped(pDestDescriptorRangeStarts[0]);
std::vector<DynamicDescriptorCopy> copies;
for(; srcRange < NumSrcDescriptorRanges && dstRange < NumDestDescriptorRanges;)
{
dst[dstIdx].CopyFrom(src[srcIdx]);
const UINT srcSize = pSrcDescriptorRangeSizes ? pSrcDescriptorRangeSizes[srcRange] : 1;
const UINT dstSize = pDestDescriptorRangeSizes ? pDestDescriptorRangeSizes[dstRange] : 1;
// just in case a size is specified as 0, check here
if(srcIdx < srcSize && dstIdx < dstSize)
{
// assume descriptors are volatile
if(m_State == WRITING_CAPFRAME)
copies.push_back(DynamicDescriptorCopy(&dst[dstIdx], &src[srcIdx], DescriptorHeapsType));
else
dst[dstIdx].CopyFrom(src[srcIdx]);
}
srcIdx++;
dstIdx++;
// move source onto the next range
if(srcIdx >= pSrcDescriptorRangeSizes[srcRange])
if(srcIdx >= srcSize)
{
srcRange++;
srcIdx = 0;
@@ -1176,7 +1386,7 @@ void WrappedID3D12Device::CopyDescriptors(
src = GetWrapped(pSrcDescriptorRangeStarts[srcRange]);
}
if(dstIdx >= pDestDescriptorRangeSizes[dstRange])
if(dstIdx >= dstSize)
{
dstRange++;
dstIdx = 0;
@@ -1186,6 +1396,33 @@ void WrappedID3D12Device::CopyDescriptors(
}
}
if(m_State == WRITING_CAPFRAME && !copies.empty())
{
SCOPED_LOCK(m_D3DLock);
// reference all the individual heaps
for(UINT i = 0; i < NumSrcDescriptorRanges; i++)
{
D3D12Descriptor *desc = GetWrapped(pSrcDescriptorRangeStarts[i]);
GetResourceManager()->MarkResourceFrameReferenced(GetResID(desc->samp.heap), eFrameRef_Read);
}
for(UINT i = 0; i < NumDestDescriptorRanges; i++)
{
D3D12Descriptor *desc = GetWrapped(pDestDescriptorRangeStarts[i]);
GetResourceManager()->MarkResourceFrameReferenced(GetResID(desc->samp.heap), eFrameRef_Read);
}
m_DynamicDescriptorCopies.insert(m_DynamicDescriptorCopies.end(), copies.begin(), copies.end());
{
SCOPED_SERIALISE_CONTEXT(DYN_DESC_COPIES);
Serialise_DynamicDescriptorCopies(&copies);
m_FrameCaptureRecord->AddChunk(scope.Get());
}
}
SAFE_DELETE_ARRAY(dstStarts);
SAFE_DELETE_ARRAY(srcStarts);
}
@@ -1201,8 +1438,31 @@ void WrappedID3D12Device::CopyDescriptorsSimple(UINT NumDescriptors,
D3D12Descriptor *src = GetWrapped(SrcDescriptorRangeStart);
D3D12Descriptor *dst = GetWrapped(DestDescriptorRangeStart);
for(UINT i = 0; i < NumDescriptors; i++)
dst[i].CopyFrom(src[i]);
// assume descriptors are volatile
if(m_State == WRITING_CAPFRAME)
{
std::vector<DynamicDescriptorCopy> copies;
copies.reserve(NumDescriptors);
for(UINT i = 0; i < NumDescriptors; i++)
copies.push_back(DynamicDescriptorCopy(&dst[i], &src[i], DescriptorHeapsType));
{
SCOPED_LOCK(m_D3DLock);
m_DynamicDescriptorCopies.insert(m_DynamicDescriptorCopies.end(), copies.begin(), copies.end());
{
SCOPED_SERIALISE_CONTEXT(DYN_DESC_COPIES);
Serialise_DynamicDescriptorCopies(&copies);
m_FrameCaptureRecord->AddChunk(scope.Get());
}
}
}
else
{
for(UINT i = 0; i < NumDescriptors; i++)
dst[i].CopyFrom(src[i]);
}
}
HRESULT WrappedID3D12Device::OpenSharedHandle(HANDLE NTHandle, REFIID riid, void **ppvObj)
+30 -10
View File
@@ -253,13 +253,30 @@ void D3D12Descriptor::CopyFrom(const D3D12Descriptor &src)
samp.idx = index;
}
D3D12_CPU_DESCRIPTOR_HANDLE UnwrapCPU(D3D12Descriptor *handle)
{
D3D12_CPU_DESCRIPTOR_HANDLE ret = {};
if(handle == NULL)
return ret;
return handle->samp.heap->GetCPU(handle->samp.idx);
}
D3D12_GPU_DESCRIPTOR_HANDLE UnwrapGPU(D3D12Descriptor *handle)
{
D3D12_GPU_DESCRIPTOR_HANDLE ret = {};
if(handle == NULL)
return ret;
return handle->samp.heap->GetGPU(handle->samp.idx);
}
D3D12_CPU_DESCRIPTOR_HANDLE Unwrap(D3D12_CPU_DESCRIPTOR_HANDLE handle)
{
if(handle.ptr == 0)
return handle;
D3D12Descriptor *desc = GetWrapped(handle);
return desc->samp.heap->GetCPU(desc->samp.idx);
return UnwrapCPU(GetWrapped(handle));
}
D3D12_GPU_DESCRIPTOR_HANDLE Unwrap(D3D12_GPU_DESCRIPTOR_HANDLE handle)
@@ -267,8 +284,15 @@ D3D12_GPU_DESCRIPTOR_HANDLE Unwrap(D3D12_GPU_DESCRIPTOR_HANDLE handle)
if(handle.ptr == 0)
return handle;
D3D12Descriptor *desc = GetWrapped(handle);
return desc->samp.heap->GetGPU(desc->samp.idx);
return UnwrapGPU(GetWrapped(handle));
}
PortableHandle ToPortableHandle(D3D12Descriptor *desc)
{
if(desc == NULL)
return PortableHandle(0);
return PortableHandle(GetResID(desc->samp.heap), desc->samp.idx);
}
PortableHandle ToPortableHandle(D3D12_CPU_DESCRIPTOR_HANDLE handle)
@@ -276,9 +300,7 @@ PortableHandle ToPortableHandle(D3D12_CPU_DESCRIPTOR_HANDLE handle)
if(handle.ptr == 0)
return PortableHandle(0);
D3D12Descriptor *desc = GetWrapped(handle);
return PortableHandle(GetResID(desc->samp.heap), desc->samp.idx);
return ToPortableHandle(GetWrapped(handle));
}
PortableHandle ToPortableHandle(D3D12_GPU_DESCRIPTOR_HANDLE handle)
@@ -286,9 +308,7 @@ PortableHandle ToPortableHandle(D3D12_GPU_DESCRIPTOR_HANDLE handle)
if(handle.ptr == 0)
return PortableHandle(0);
D3D12Descriptor *desc = GetWrapped(handle);
return PortableHandle(GetResID(desc->samp.heap), desc->samp.idx);
return ToPortableHandle(GetWrapped(handle));
}
D3D12_CPU_DESCRIPTOR_HANDLE CPUHandleFromPortableHandle(D3D12ResourceManager *manager,
+23
View File
@@ -204,6 +204,8 @@ inline D3D12Descriptor *GetWrapped(D3D12_GPU_DESCRIPTOR_HANDLE handle)
D3D12_CPU_DESCRIPTOR_HANDLE Unwrap(D3D12_CPU_DESCRIPTOR_HANDLE handle);
D3D12_GPU_DESCRIPTOR_HANDLE Unwrap(D3D12_GPU_DESCRIPTOR_HANDLE handle);
D3D12_CPU_DESCRIPTOR_HANDLE UnwrapCPU(D3D12Descriptor *handle);
D3D12_GPU_DESCRIPTOR_HANDLE UnwrapGPU(D3D12Descriptor *handle);
struct PortableHandle
{
@@ -216,6 +218,7 @@ struct PortableHandle
class D3D12ResourceManager;
PortableHandle ToPortableHandle(D3D12Descriptor *handle);
PortableHandle ToPortableHandle(D3D12_CPU_DESCRIPTOR_HANDLE handle);
PortableHandle ToPortableHandle(D3D12_GPU_DESCRIPTOR_HANDLE handle);
D3D12_CPU_DESCRIPTOR_HANDLE CPUHandleFromPortableHandle(D3D12ResourceManager *manager,
@@ -223,6 +226,26 @@ D3D12_CPU_DESCRIPTOR_HANDLE CPUHandleFromPortableHandle(D3D12ResourceManager *ma
D3D12_GPU_DESCRIPTOR_HANDLE GPUHandleFromPortableHandle(D3D12ResourceManager *manager,
PortableHandle handle);
struct DynamicDescriptorWrite
{
D3D12Descriptor desc;
D3D12Descriptor *dest;
};
struct DynamicDescriptorCopy
{
DynamicDescriptorCopy() : dst(NULL), src(NULL), type(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) {}
DynamicDescriptorCopy(D3D12Descriptor *d, D3D12Descriptor *s, D3D12_DESCRIPTOR_HEAP_TYPE t)
: dst(d), src(s), type(t)
{
}
D3D12Descriptor *dst;
D3D12Descriptor *src;
D3D12_DESCRIPTOR_HEAP_TYPE type;
};
struct D3D12ResourceRecord;
struct CmdListRecordingInfo