mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-12 18:47:07 +00:00
Patch ExecuteIndirect call data to point to replayed GPU addresses
This commit is contained in:
@@ -409,6 +409,9 @@ public:
|
||||
|
||||
IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, EndEvent());
|
||||
|
||||
void PatchedExecuteIndirect(ID3D12GraphicsCommandList *list, ResourceId sig, UINT maxCount,
|
||||
ResourceId arg, UINT64 argOffs, ResourceId countbuf, UINT64 countOffs);
|
||||
|
||||
IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE,
|
||||
ExecuteIndirect(ID3D12CommandSignature *pCommandSignature,
|
||||
UINT MaxCommandCount, ID3D12Resource *pArgumentBuffer,
|
||||
|
||||
@@ -2638,6 +2638,137 @@ void WrappedID3D12GraphicsCommandList::ExecuteBundle(ID3D12GraphicsCommandList *
|
||||
m_pReal->ExecuteBundle(Unwrap(pCommandList));
|
||||
}
|
||||
|
||||
void WrappedID3D12GraphicsCommandList::PatchedExecuteIndirect(ID3D12GraphicsCommandList *list,
|
||||
ResourceId sig, UINT maxCount,
|
||||
ResourceId arg, UINT64 argOffs,
|
||||
ResourceId countbuf, UINT64 countOffs)
|
||||
{
|
||||
WrappedID3D12CommandSignature *comSig =
|
||||
GetResourceManager()->GetLiveAs<WrappedID3D12CommandSignature>(sig);
|
||||
ID3D12Resource *argBuf = GetResourceManager()->GetLiveAs<ID3D12Resource>(arg);
|
||||
ID3D12Resource *countBuf = GetResourceManager()->GetLiveAs<ID3D12Resource>(countbuf);
|
||||
|
||||
uint32_t count = maxCount;
|
||||
|
||||
vector<byte> data;
|
||||
if(countBuf)
|
||||
{
|
||||
m_pDevice->GetDebugManager()->GetBufferData(countBuf, countOffs, 4, data);
|
||||
count = RDCMIN(count, *(uint32_t *)&data[0]);
|
||||
}
|
||||
|
||||
m_pDevice->GetDebugManager()->GetBufferData(argBuf, argOffs, count * comSig->sig.ByteStride, data);
|
||||
|
||||
ID3D12Resource *indirectBuf = m_pDevice->GetDebugManager()->GetIndirectBuffer(data.size());
|
||||
|
||||
D3D12_RANGE range = {};
|
||||
byte *mapPtr = NULL;
|
||||
indirectBuf->Map(0, &range, (void **)&mapPtr);
|
||||
|
||||
byte *dataPtr = &data[0];
|
||||
|
||||
for(uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
byte *dst = mapPtr;
|
||||
byte *src = dataPtr;
|
||||
mapPtr += comSig->sig.ByteStride;
|
||||
dataPtr += comSig->sig.ByteStride;
|
||||
|
||||
for(size_t a = 0; a < comSig->sig.arguments.size(); a++)
|
||||
{
|
||||
const D3D12_INDIRECT_ARGUMENT_DESC &arg = comSig->sig.arguments[a];
|
||||
|
||||
switch(arg.Type)
|
||||
{
|
||||
case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW:
|
||||
memcpy(dst, src, sizeof(D3D12_DRAW_ARGUMENTS));
|
||||
dst += sizeof(D3D12_DRAW_ARGUMENTS);
|
||||
src += sizeof(D3D12_DRAW_ARGUMENTS);
|
||||
break;
|
||||
case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED:
|
||||
memcpy(dst, src, sizeof(D3D12_DRAW_INDEXED_ARGUMENTS));
|
||||
dst += sizeof(D3D12_DRAW_INDEXED_ARGUMENTS);
|
||||
src += sizeof(D3D12_DRAW_INDEXED_ARGUMENTS);
|
||||
break;
|
||||
case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH:
|
||||
memcpy(dst, src, sizeof(D3D12_DISPATCH_ARGUMENTS));
|
||||
dst += sizeof(D3D12_DISPATCH_ARGUMENTS);
|
||||
src += sizeof(D3D12_DISPATCH_ARGUMENTS);
|
||||
break;
|
||||
case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT:
|
||||
memcpy(dst, src, sizeof(uint32_t));
|
||||
dst += sizeof(uint32_t);
|
||||
src += sizeof(uint32_t);
|
||||
break;
|
||||
case D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW:
|
||||
{
|
||||
D3D12_VERTEX_BUFFER_VIEW *srcVB = (D3D12_VERTEX_BUFFER_VIEW *)src;
|
||||
D3D12_VERTEX_BUFFER_VIEW *dstVB = (D3D12_VERTEX_BUFFER_VIEW *)dst;
|
||||
|
||||
ResourceId id;
|
||||
uint64_t offs;
|
||||
m_pDevice->GetResIDFromAddr(srcVB->BufferLocation, id, offs);
|
||||
|
||||
ID3D12Resource *res = GetResourceManager()->GetLiveAs<ID3D12Resource>(id);
|
||||
if(res)
|
||||
dstVB->BufferLocation = res->GetGPUVirtualAddress() + offs;
|
||||
|
||||
dstVB->SizeInBytes = srcVB->SizeInBytes;
|
||||
dstVB->StrideInBytes = srcVB->StrideInBytes;
|
||||
|
||||
dst += sizeof(D3D12_VERTEX_BUFFER_VIEW);
|
||||
src += sizeof(D3D12_VERTEX_BUFFER_VIEW);
|
||||
break;
|
||||
}
|
||||
case D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW:
|
||||
{
|
||||
D3D12_INDEX_BUFFER_VIEW *srcIB = (D3D12_INDEX_BUFFER_VIEW *)src;
|
||||
D3D12_INDEX_BUFFER_VIEW *dstIB = (D3D12_INDEX_BUFFER_VIEW *)dst;
|
||||
|
||||
ResourceId id;
|
||||
uint64_t offs;
|
||||
m_pDevice->GetResIDFromAddr(srcIB->BufferLocation, id, offs);
|
||||
|
||||
ID3D12Resource *res = GetResourceManager()->GetLiveAs<ID3D12Resource>(id);
|
||||
if(res)
|
||||
dstIB->BufferLocation = res->GetGPUVirtualAddress() + offs;
|
||||
|
||||
dstIB->SizeInBytes = srcIB->SizeInBytes;
|
||||
dstIB->Format = srcIB->Format;
|
||||
|
||||
dst += sizeof(D3D12_INDEX_BUFFER_VIEW);
|
||||
src += sizeof(D3D12_INDEX_BUFFER_VIEW);
|
||||
break;
|
||||
}
|
||||
case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW:
|
||||
case D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW:
|
||||
case D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW:
|
||||
{
|
||||
D3D12_GPU_VIRTUAL_ADDRESS *srcAddr = (D3D12_GPU_VIRTUAL_ADDRESS *)src;
|
||||
D3D12_GPU_VIRTUAL_ADDRESS *dstAddr = (D3D12_GPU_VIRTUAL_ADDRESS *)dst;
|
||||
|
||||
ResourceId id;
|
||||
uint64_t offs;
|
||||
m_pDevice->GetResIDFromAddr(*srcAddr, id, offs);
|
||||
|
||||
ID3D12Resource *res = GetResourceManager()->GetLiveAs<ID3D12Resource>(id);
|
||||
if(res)
|
||||
*dstAddr = res->GetGPUVirtualAddress() + offs;
|
||||
|
||||
dst += sizeof(D3D12_GPU_VIRTUAL_ADDRESS);
|
||||
src += sizeof(D3D12_GPU_VIRTUAL_ADDRESS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
range.End = data.size();
|
||||
indirectBuf->Unmap(0, &range);
|
||||
|
||||
list->ExecuteIndirect(comSig->GetReal(), count, Unwrap(indirectBuf), 0, NULL, 0);
|
||||
}
|
||||
|
||||
bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect(
|
||||
ID3D12CommandSignature *pCommandSignature, UINT MaxCommandCount, ID3D12Resource *pArgumentBuffer,
|
||||
UINT64 ArgumentBufferOffset, ID3D12Resource *pCountBuffer, UINT64 CountBufferOffset)
|
||||
@@ -2647,7 +2778,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect(
|
||||
SERIALISE_ELEMENT(UINT, maxCount, MaxCommandCount);
|
||||
SERIALISE_ELEMENT(ResourceId, arg, GetResID(pArgumentBuffer));
|
||||
SERIALISE_ELEMENT(UINT64, argOffs, ArgumentBufferOffset);
|
||||
SERIALISE_ELEMENT(ResourceId, count, GetResID(pCountBuffer));
|
||||
SERIALISE_ELEMENT(ResourceId, countbuf, GetResID(pCountBuffer));
|
||||
SERIALISE_ELEMENT(UINT64, countOffs, CountBufferOffset);
|
||||
|
||||
if(m_State < WRITING)
|
||||
@@ -2655,32 +2786,23 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect(
|
||||
|
||||
if(m_State == EXECUTING)
|
||||
{
|
||||
pCommandSignature = GetResourceManager()->GetLiveAs<ID3D12CommandSignature>(sig);
|
||||
pArgumentBuffer = GetResourceManager()->GetLiveAs<ID3D12Resource>(arg);
|
||||
pCountBuffer = GetResourceManager()->GetLiveAs<ID3D12Resource>(count);
|
||||
|
||||
if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList))
|
||||
{
|
||||
ID3D12GraphicsCommandList *list = m_Cmd->RerecordCmdList(CommandList);
|
||||
|
||||
Unwrap(list)->ExecuteIndirect(Unwrap(pCommandSignature), maxCount, Unwrap(pArgumentBuffer),
|
||||
argOffs, Unwrap(pCountBuffer), countOffs);
|
||||
PatchedExecuteIndirect(Unwrap(list), sig, maxCount, arg, argOffs, countbuf, countOffs);
|
||||
}
|
||||
}
|
||||
else if(m_State == READING)
|
||||
{
|
||||
pCommandSignature = GetResourceManager()->GetLiveAs<ID3D12CommandSignature>(sig);
|
||||
pArgumentBuffer = GetResourceManager()->GetLiveAs<ID3D12Resource>(arg);
|
||||
pCountBuffer = GetResourceManager()->GetLiveAs<ID3D12Resource>(count);
|
||||
|
||||
GetList(CommandList)
|
||||
->ExecuteIndirect(Unwrap(pCommandSignature), maxCount, Unwrap(pArgumentBuffer), argOffs,
|
||||
Unwrap(pCountBuffer), countOffs);
|
||||
WrappedID3D12CommandSignature *comSig =
|
||||
GetResourceManager()->GetLiveAs<WrappedID3D12CommandSignature>(sig);
|
||||
|
||||
const string desc = m_pSerialiser->GetDebugStr();
|
||||
|
||||
m_Cmd->AddEvent(EXEC_INDIRECT, desc);
|
||||
string name = "ExecuteIndirect(...)";
|
||||
string name = StringFormat::Fmt("ExecuteIndirect(%u arguments, maxCommands = %u)",
|
||||
comSig->sig.arguments.size(), maxCount);
|
||||
|
||||
FetchDrawcall draw;
|
||||
draw.name = name;
|
||||
@@ -2692,9 +2814,12 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect(
|
||||
D3D12DrawcallTreeNode &drawNode = m_Cmd->GetDrawcallStack().back()->children.back();
|
||||
|
||||
drawNode.resourceUsage.push_back(std::make_pair(
|
||||
GetResID(pArgumentBuffer), EventUsage(drawNode.draw.eventID, eUsage_Indirect)));
|
||||
GetResourceManager()->GetLiveID(arg), EventUsage(drawNode.draw.eventID, eUsage_Indirect)));
|
||||
drawNode.resourceUsage.push_back(
|
||||
std::make_pair(GetResID(pCountBuffer), EventUsage(drawNode.draw.eventID, eUsage_Indirect)));
|
||||
std::make_pair(GetResourceManager()->GetLiveID(countbuf),
|
||||
EventUsage(drawNode.draw.eventID, eUsage_Indirect)));
|
||||
|
||||
PatchedExecuteIndirect(GetList(CommandList), sig, maxCount, arg, argOffs, countbuf, countOffs);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -169,6 +169,12 @@ struct D3D12RootSignature
|
||||
vector<D3D12_STATIC_SAMPLER_DESC> samplers;
|
||||
};
|
||||
|
||||
struct D3D12CommandSignature
|
||||
{
|
||||
UINT ByteStride;
|
||||
vector<D3D12_INDIRECT_ARGUMENT_DESC> arguments;
|
||||
};
|
||||
|
||||
#define IMPLEMENT_IUNKNOWN_WITH_REFCOUNTER_CUSTOMQUERY \
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return RefCounter12::AddRef(); } \
|
||||
ULONG STDMETHODCALLTYPE Release() { return RefCounter12::Release(); }
|
||||
|
||||
@@ -228,8 +228,30 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
|
||||
RDCERR("Failed to create readback buffer, HRESULT: 0x%08x", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = m_WrappedDevice->CreateCommandAllocator(
|
||||
D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void **)&m_ReadbackAlloc);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to create readback command allocator, HRESULT: 0x%08x", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = m_WrappedDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_ReadbackAlloc,
|
||||
NULL, __uuidof(ID3D12GraphicsCommandList),
|
||||
(void **)&m_ReadbackList);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to create readback command list, HRESULT: 0x%08x", hr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_IndirectBuffer = NULL;
|
||||
m_IndirectSize = 0;
|
||||
|
||||
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.2f);
|
||||
|
||||
// create fixed samplers, point and linear
|
||||
@@ -723,6 +745,10 @@ D3D12DebugManager::~D3D12DebugManager()
|
||||
SAFE_RELEASE(m_TexResource);
|
||||
|
||||
SAFE_RELEASE(m_ReadbackBuffer);
|
||||
SAFE_RELEASE(m_ReadbackAlloc);
|
||||
SAFE_RELEASE(m_ReadbackList);
|
||||
|
||||
SAFE_RELEASE(m_IndirectBuffer);
|
||||
|
||||
m_WrappedDevice->InternalRelease();
|
||||
|
||||
@@ -1832,7 +1858,7 @@ void D3D12DebugManager::GetBufferData(ID3D12Resource *buffer, uint64_t offset, u
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList *list = m_WrappedDevice->GetNewList();
|
||||
m_ReadbackList->Reset(m_ReadbackAlloc, NULL);
|
||||
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
|
||||
@@ -1840,18 +1866,20 @@ void D3D12DebugManager::GetBufferData(ID3D12Resource *buffer, uint64_t offset, u
|
||||
barrier.Transition.StateBefore = m_WrappedDevice->GetSubresourceStates(GetResID(buffer))[0];
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
|
||||
|
||||
list->ResourceBarrier(1, &barrier);
|
||||
m_ReadbackList->ResourceBarrier(1, &barrier);
|
||||
|
||||
while(length > 0)
|
||||
{
|
||||
uint64_t chunkSize = RDCMIN(length, m_ReadbackSize);
|
||||
|
||||
list->CopyBufferRegion(m_ReadbackBuffer, 0, buffer, offset, chunkSize);
|
||||
m_ReadbackList->CopyBufferRegion(m_ReadbackBuffer, 0, buffer, offset, chunkSize);
|
||||
|
||||
list->Close();
|
||||
m_ReadbackList->Close();
|
||||
|
||||
m_WrappedDevice->ExecuteLists();
|
||||
m_WrappedDevice->FlushLists();
|
||||
ID3D12CommandList *l = m_ReadbackList;
|
||||
m_WrappedDevice->GetQueue()->ExecuteCommandLists(1, &l);
|
||||
m_WrappedDevice->GPUSync();
|
||||
m_ReadbackAlloc->Reset();
|
||||
|
||||
D3D12_RANGE range = {0, (size_t)chunkSize};
|
||||
|
||||
@@ -1874,12 +1902,50 @@ void D3D12DebugManager::GetBufferData(ID3D12Resource *buffer, uint64_t offset, u
|
||||
|
||||
outOffs += chunkSize;
|
||||
length -= chunkSize;
|
||||
|
||||
if(length > 0)
|
||||
list = m_WrappedDevice->GetNewList();
|
||||
}
|
||||
}
|
||||
|
||||
ID3D12Resource *D3D12DebugManager::GetIndirectBuffer(size_t size)
|
||||
{
|
||||
if(m_IndirectSize && size <= m_IndirectSize)
|
||||
{
|
||||
return m_IndirectBuffer;
|
||||
}
|
||||
|
||||
m_IndirectSize = RDCMAX(size, (size_t)128 * 1024);
|
||||
|
||||
SAFE_RELEASE(m_IndirectBuffer);
|
||||
|
||||
D3D12_RESOURCE_DESC indirectDesc;
|
||||
indirectDesc.Alignment = 0;
|
||||
indirectDesc.DepthOrArraySize = 1;
|
||||
indirectDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
indirectDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
indirectDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
indirectDesc.Height = 1;
|
||||
indirectDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
indirectDesc.MipLevels = 1;
|
||||
indirectDesc.SampleDesc.Count = 1;
|
||||
indirectDesc.SampleDesc.Quality = 0;
|
||||
indirectDesc.Width = m_IndirectSize;
|
||||
|
||||
D3D12_HEAP_PROPERTIES heapProps;
|
||||
heapProps.Type = D3D12_HEAP_TYPE_CUSTOM;
|
||||
heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE;
|
||||
heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_L0;
|
||||
heapProps.CreationNodeMask = 1;
|
||||
heapProps.VisibleNodeMask = 1;
|
||||
|
||||
HRESULT hr = m_WrappedDevice->CreateCommittedResource(
|
||||
&heapProps, D3D12_HEAP_FLAG_NONE, &indirectDesc, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT, NULL,
|
||||
__uuidof(ID3D12Resource), (void **)&m_IndirectBuffer);
|
||||
|
||||
if(FAILED(hr))
|
||||
RDCERR("Failed to create indirect buffer, HRESULT: 0x%08x", hr);
|
||||
|
||||
return m_IndirectBuffer;
|
||||
}
|
||||
|
||||
void D3D12DebugManager::RenderHighlightBox(float w, float h, float scale)
|
||||
{
|
||||
OutputWindow &outw = m_OutputWindows[m_CurrentOutputWindow];
|
||||
|
||||
@@ -83,6 +83,8 @@ public:
|
||||
void GetBufferData(ResourceId buff, uint64_t offset, uint64_t length, vector<byte> &retData);
|
||||
void GetBufferData(ID3D12Resource *buff, uint64_t offset, uint64_t length, vector<byte> &retData);
|
||||
|
||||
ID3D12Resource *GetIndirectBuffer(size_t size);
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE AllocRTV();
|
||||
void FreeRTV(D3D12_CPU_DESCRIPTOR_HANDLE handle);
|
||||
|
||||
@@ -187,8 +189,13 @@ private:
|
||||
ID3D12Resource *m_PickPixelTex;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE m_PickPixelRTV;
|
||||
|
||||
ID3D12GraphicsCommandList *m_ReadbackList;
|
||||
ID3D12CommandAllocator *m_ReadbackAlloc;
|
||||
ID3D12Resource *m_ReadbackBuffer;
|
||||
|
||||
ID3D12Resource *m_IndirectBuffer;
|
||||
size_t m_IndirectSize;
|
||||
|
||||
ID3D12Resource *m_TexResource;
|
||||
|
||||
static const uint64_t m_ReadbackSize = 16 * 1024 * 1024;
|
||||
|
||||
@@ -1838,6 +1838,23 @@ ID3D12GraphicsCommandList *WrappedID3D12Device::GetNewList()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::ExecuteList(ID3D12GraphicsCommandList *list)
|
||||
{
|
||||
ID3D12CommandList *l = list;
|
||||
GetQueue()->ExecuteCommandLists(1, &l);
|
||||
|
||||
for(auto it = m_InternalCmds.pendingcmds.begin(); it != m_InternalCmds.pendingcmds.end(); ++it)
|
||||
{
|
||||
if(list == *it)
|
||||
{
|
||||
m_InternalCmds.pendingcmds.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_InternalCmds.submittedcmds.push_back(list);
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::ExecuteLists()
|
||||
{
|
||||
// nothing to do
|
||||
@@ -1869,7 +1886,8 @@ void WrappedID3D12Device::FlushLists(bool forceSync)
|
||||
m_InternalCmds.submittedcmds.end());
|
||||
m_InternalCmds.submittedcmds.clear();
|
||||
|
||||
m_Alloc->Reset();
|
||||
if(m_InternalCmds.pendingcmds.empty())
|
||||
m_Alloc->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -296,6 +296,8 @@ private:
|
||||
std::vector<DynamicDescriptorCopy> m_DynamicDescriptorCopies;
|
||||
std::vector<DynamicDescriptorWrite> m_DynamicDescriptorWrites;
|
||||
|
||||
std::vector<GPUAddressRange> m_GPUAddresses;
|
||||
|
||||
void FlushPendingDescriptorWrites();
|
||||
|
||||
// used both on capture and replay side to track resource states. Only locked
|
||||
@@ -368,6 +370,11 @@ public:
|
||||
ID3D12CommandAllocator *GetAlloc() { return m_Alloc; }
|
||||
void ApplyBarriers(vector<D3D12_RESOURCE_BARRIER> &barriers);
|
||||
|
||||
void GetResIDFromAddr(D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id, UINT64 &offs)
|
||||
{
|
||||
GPUAddressRange::GetResIDFromAddr(m_GPUAddresses, addr, id, offs);
|
||||
}
|
||||
|
||||
bool IsCubemap(ResourceId id) { return m_Cubemaps.find(id) != m_Cubemaps.end(); }
|
||||
// returns thread-local temporary memory
|
||||
byte *GetTempMemory(size_t s);
|
||||
@@ -395,6 +402,7 @@ public:
|
||||
} m_InternalCmds;
|
||||
|
||||
ID3D12GraphicsCommandList *GetNewList();
|
||||
void ExecuteList(ID3D12GraphicsCommandList *list);
|
||||
void ExecuteLists();
|
||||
void FlushLists(bool forceSync = false);
|
||||
|
||||
|
||||
@@ -871,10 +871,23 @@ bool WrappedID3D12Device::Serialise_CreateCommittedResource(
|
||||
SERIALISE_ELEMENT(IID, guid, riidResource);
|
||||
SERIALISE_ELEMENT(ResourceId, Res, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID());
|
||||
|
||||
SERIALISE_ELEMENT(uint64_t, gpuAddress,
|
||||
((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddress());
|
||||
|
||||
if(m_State == READING)
|
||||
{
|
||||
pOptimizedClearValue = HasClearValue ? &clearVal : NULL;
|
||||
|
||||
if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
{
|
||||
GPUAddressRange range;
|
||||
range.start = gpuAddress;
|
||||
range.end = gpuAddress + desc.Width;
|
||||
range.id = Res;
|
||||
|
||||
GPUAddressRange::AddTo(m_GPUAddresses, range);
|
||||
}
|
||||
|
||||
ID3D12Resource *ret = NULL;
|
||||
HRESULT hr = m_pDevice->CreateCommittedResource(&props, flags, &desc, state,
|
||||
pOptimizedClearValue, guid, (void **)&ret);
|
||||
@@ -1046,11 +1059,24 @@ bool WrappedID3D12Device::Serialise_CreatePlacedResource(
|
||||
SERIALISE_ELEMENT(IID, guid, riid);
|
||||
SERIALISE_ELEMENT(ResourceId, Res, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID());
|
||||
|
||||
SERIALISE_ELEMENT(uint64_t, gpuAddress,
|
||||
((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddress());
|
||||
|
||||
if(m_State == READING)
|
||||
{
|
||||
pHeap = GetResourceManager()->GetLiveAs<ID3D12Heap>(Heap);
|
||||
pOptimizedClearValue = HasClearValue ? &clearVal : NULL;
|
||||
|
||||
if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
{
|
||||
GPUAddressRange range;
|
||||
range.start = gpuAddress;
|
||||
range.end = gpuAddress + desc.Width;
|
||||
range.id = Res;
|
||||
|
||||
GPUAddressRange::AddTo(m_GPUAddresses, range);
|
||||
}
|
||||
|
||||
ID3D12Resource *ret = NULL;
|
||||
HRESULT hr = m_pDevice->CreatePlacedResource(Unwrap(pHeap), Offset, &desc, state,
|
||||
pOptimizedClearValue, guid, (void **)&ret);
|
||||
@@ -1304,7 +1330,8 @@ bool WrappedID3D12Device::Serialise_CreateCommandSignature(Serialiser *localSeri
|
||||
pRootSignature = GetResourceManager()->GetLiveAs<ID3D12RootSignature>(RootSig);
|
||||
|
||||
ID3D12CommandSignature *ret = NULL;
|
||||
HRESULT hr = m_pDevice->CreateCommandSignature(&desc, pRootSignature, guid, (void **)&ret);
|
||||
HRESULT hr =
|
||||
m_pDevice->CreateCommandSignature(&desc, Unwrap(pRootSignature), guid, (void **)&ret);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
@@ -1312,7 +1339,13 @@ bool WrappedID3D12Device::Serialise_CreateCommandSignature(Serialiser *localSeri
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = new WrappedID3D12CommandSignature(ret, this);
|
||||
WrappedID3D12CommandSignature *wrapped = new WrappedID3D12CommandSignature(ret, this);
|
||||
|
||||
wrapped->sig.ByteStride = desc.ByteStride;
|
||||
wrapped->sig.arguments.insert(wrapped->sig.arguments.begin(), desc.pArgumentDescs,
|
||||
desc.pArgumentDescs + desc.NumArgumentDescs);
|
||||
|
||||
ret = wrapped;
|
||||
|
||||
GetResourceManager()->AddLiveResource(CommandSig, ret);
|
||||
}
|
||||
|
||||
@@ -220,6 +220,9 @@ void D3D12Descriptor::Create(D3D12_DESCRIPTOR_HEAP_TYPE heapType, WrappedID3D12D
|
||||
if(nonsamp.resource == NULL)
|
||||
counter = NULL;
|
||||
|
||||
if(counter == NULL && desc && desc->ViewDimension == D3D12_UAV_DIMENSION_BUFFER)
|
||||
desc->Buffer.CounterOffsetInBytes = 0;
|
||||
|
||||
dev->CreateUnorderedAccessView(nonsamp.resource, counter, desc, handle);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include "api/replay/renderdoc_replay.h"
|
||||
#include "common/wrapped_pool.h"
|
||||
#include "core/core.h"
|
||||
@@ -281,6 +282,60 @@ struct CmdListRecordingInfo
|
||||
|
||||
class WrappedID3D12Resource;
|
||||
|
||||
struct GPUAddressRange
|
||||
{
|
||||
D3D12_GPU_VIRTUAL_ADDRESS start, end;
|
||||
ResourceId id;
|
||||
|
||||
bool operator<(const D3D12_GPU_VIRTUAL_ADDRESS &o) const
|
||||
{
|
||||
if(o < start)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void AddTo(std::vector<GPUAddressRange> &addresses, GPUAddressRange range)
|
||||
{
|
||||
auto it = std::lower_bound(addresses.begin(), addresses.end(), range.start);
|
||||
RDCASSERT(it == addresses.begin() || it == addresses.end() || range.start < it->start ||
|
||||
range.start >= it->end);
|
||||
|
||||
addresses.insert(it, range);
|
||||
}
|
||||
|
||||
static void RemoveFrom(std::vector<GPUAddressRange> &addresses, D3D12_GPU_VIRTUAL_ADDRESS baseAddr)
|
||||
{
|
||||
auto it = std::lower_bound(addresses.begin(), addresses.end(), baseAddr);
|
||||
RDCASSERT(it != addresses.end() && baseAddr >= it->start && baseAddr < it->end);
|
||||
|
||||
addresses.erase(it);
|
||||
}
|
||||
|
||||
static void GetResIDFromAddr(std::vector<GPUAddressRange> &addresses,
|
||||
D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id, UINT64 &offs)
|
||||
{
|
||||
id = ResourceId();
|
||||
offs = 0;
|
||||
|
||||
if(addr == 0)
|
||||
return;
|
||||
|
||||
if(addresses.empty())
|
||||
return;
|
||||
|
||||
auto it = std::lower_bound(addresses.begin(), addresses.end(), addr);
|
||||
if(it == addresses.end())
|
||||
return;
|
||||
|
||||
if(addr < it->start || addr >= it->end)
|
||||
return;
|
||||
|
||||
id = it->id;
|
||||
offs = addr - it->start;
|
||||
}
|
||||
};
|
||||
|
||||
struct MapState
|
||||
{
|
||||
WrappedID3D12Resource *res;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "d3d12_command_list.h"
|
||||
#include "d3d12_command_queue.h"
|
||||
|
||||
std::vector<WrappedID3D12Resource::AddressRange> WrappedID3D12Resource::m_Addresses;
|
||||
std::vector<GPUAddressRange> WrappedID3D12Resource::m_Addresses;
|
||||
std::map<ResourceId, WrappedID3D12Resource *> WrappedID3D12Resource::m_List;
|
||||
|
||||
std::map<WrappedID3D12PipelineState::DXBCKey, WrappedID3D12PipelineState::ShaderEntry *>
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include "driver/shaders/dxbc/dxbc_inspect.h"
|
||||
#include "d3d12_device.h"
|
||||
#include "d3d12_manager.h"
|
||||
@@ -299,6 +298,8 @@ class WrappedID3D12CommandSignature : public WrappedDeviceChild12<ID3D12CommandS
|
||||
public:
|
||||
ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D12CommandSignature);
|
||||
|
||||
D3D12CommandSignature sig;
|
||||
|
||||
enum
|
||||
{
|
||||
TypeEnum = Resource_CommandSignature,
|
||||
@@ -635,21 +636,7 @@ public:
|
||||
|
||||
class WrappedID3D12Resource : public WrappedDeviceChild12<ID3D12Resource>
|
||||
{
|
||||
struct AddressRange
|
||||
{
|
||||
D3D12_GPU_VIRTUAL_ADDRESS start, end;
|
||||
ResourceId id;
|
||||
|
||||
bool operator<(const D3D12_GPU_VIRTUAL_ADDRESS &o) const
|
||||
{
|
||||
if(o < start)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
static std::vector<AddressRange> m_Addresses;
|
||||
static std::vector<GPUAddressRange> m_Addresses;
|
||||
|
||||
bool resident;
|
||||
|
||||
@@ -660,24 +647,7 @@ public:
|
||||
|
||||
static void GetResIDFromAddr(D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id, UINT64 &offs)
|
||||
{
|
||||
id = ResourceId();
|
||||
offs = 0;
|
||||
|
||||
if(addr == 0)
|
||||
return;
|
||||
|
||||
if(m_Addresses.empty())
|
||||
return;
|
||||
|
||||
auto it = std::lower_bound(m_Addresses.begin(), m_Addresses.end(), addr);
|
||||
if(it == m_Addresses.end())
|
||||
return;
|
||||
|
||||
if(addr < it->start || addr >= it->end)
|
||||
return;
|
||||
|
||||
id = it->id;
|
||||
offs = addr - it->start;
|
||||
GPUAddressRange::GetResIDFromAddr(m_Addresses, addr, id, offs);
|
||||
}
|
||||
|
||||
// overload to just return the id in case the offset isn't needed
|
||||
@@ -707,16 +677,12 @@ public:
|
||||
{
|
||||
D3D12_GPU_VIRTUAL_ADDRESS addr = m_pReal->GetGPUVirtualAddress();
|
||||
|
||||
auto it = std::lower_bound(m_Addresses.begin(), m_Addresses.end(), addr);
|
||||
RDCASSERT(it == m_Addresses.begin() || it == m_Addresses.end() || addr < it->start ||
|
||||
addr >= it->end);
|
||||
|
||||
AddressRange range;
|
||||
GPUAddressRange range;
|
||||
range.start = addr;
|
||||
range.end = addr + m_pReal->GetDesc().Width;
|
||||
range.id = GetResourceID();
|
||||
|
||||
m_Addresses.insert(it, range);
|
||||
GPUAddressRange::AddTo(m_Addresses, range);
|
||||
}
|
||||
}
|
||||
virtual ~WrappedID3D12Resource()
|
||||
@@ -725,14 +691,7 @@ public:
|
||||
|
||||
// assuming only valid for buffers
|
||||
if(m_pReal->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
{
|
||||
D3D12_GPU_VIRTUAL_ADDRESS addr = m_pReal->GetGPUVirtualAddress();
|
||||
|
||||
auto it = std::lower_bound(m_Addresses.begin(), m_Addresses.end(), addr);
|
||||
RDCASSERT(it != m_Addresses.end() && addr >= it->start && addr < it->end);
|
||||
|
||||
m_Addresses.erase(it);
|
||||
}
|
||||
GPUAddressRange::RemoveFrom(m_Addresses, m_pReal->GetGPUVirtualAddress());
|
||||
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user