From df903cd19120cc773e13c436bc4a635897c28603 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 21 Oct 2016 14:15:53 +0200 Subject: [PATCH] Allocate indirect buffers for storing immutable patched copies of args --- renderdoc/driver/d3d12/d3d12_commands.cpp | 49 +++++++++++++++++++++++ renderdoc/driver/d3d12/d3d12_commands.h | 6 +++ 2 files changed, 55 insertions(+) diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index 73fdcb0ac..1b2c8d59f 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -185,6 +185,9 @@ WrappedID3D12CommandQueue::WrappedID3D12CommandQueue(ID3D12CommandQueue *real, WrappedID3D12CommandQueue::~WrappedID3D12CommandQueue() { + for(size_t i = 0; i < m_Cmd.m_IndirectBuffers.size(); i++) + SAFE_RELEASE(m_Cmd.m_IndirectBuffers[i]); + SAFE_RELEASE(m_WrappedDebug.m_pReal); SAFE_RELEASE(m_pReal); } @@ -713,6 +716,52 @@ D3D12CommandData::D3D12CommandData() m_RootDrawcallStack.push_back(&m_ParentDrawcall); } +void D3D12CommandData::GetIndirectBuffer(size_t size, ID3D12Resource **buf, uint64_t *offs) +{ + // check if we need to allocate a new buffer + if(m_IndirectBuffers.empty() || m_IndirectOffset + size > m_IndirectSize) + { + 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; + + // create a custom heap that sits in CPU memory and is mappable, but we can + // use for indirect args (unlike upload and readback). + 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; + + ID3D12Resource *buf = NULL; + + HRESULT hr = m_pDevice->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &indirectDesc, + D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT, NULL, + __uuidof(ID3D12Resource), (void **)&buf); + + if(FAILED(hr)) + RDCERR("Failed to create indirect buffer, HRESULT: 0x%08x", hr); + + m_IndirectBuffers.push_back(buf); + m_IndirectOffset = 0; + } + + *buf = m_IndirectBuffers.back(); + *offs = m_IndirectOffset; + + m_IndirectOffset = AlignUp16(m_IndirectOffset + size); +} + uint32_t D3D12CommandData::HandlePreCallback(ID3D12GraphicsCommandList *list, bool dispatch, uint32_t multiDrawOffset) { diff --git a/renderdoc/driver/d3d12/d3d12_commands.h b/renderdoc/driver/d3d12/d3d12_commands.h index 7f2ae0180..be0386958 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.h +++ b/renderdoc/driver/d3d12/d3d12_commands.h @@ -181,6 +181,10 @@ struct D3D12CommandData ID3D12CommandAllocator *m_CrackedAllocators[4]; + vector m_IndirectBuffers; + static const uint64_t m_IndirectSize = 4 * 1024 * 1024; + uint64_t m_IndirectOffset; + map m_BakedCmdListInfo; D3D12RenderState m_RenderState; @@ -300,6 +304,8 @@ struct D3D12CommandData return m_RootDrawcallStack; } + void GetIndirectBuffer(size_t size, ID3D12Resource **buf, uint64_t *offs); + // util function to handle fetching the right eventID, calling any // aliases then calling PreDraw/PreDispatch. uint32_t HandlePreCallback(ID3D12GraphicsCommandList *list, bool dispatch = false,