From 2eaff162c34a315e61d0cfc720715f0a20ebdc51 Mon Sep 17 00:00:00 2001 From: Try Date: Thu, 1 Feb 2024 22:28:44 +0100 Subject: [PATCH] DX12: indirect draw initial #54 --- Engine/gapi/directx12/dxcommandbuffer.cpp | 63 ++++++++++++++++++----- Engine/gapi/directx12/dxcommandbuffer.h | 3 ++ Engine/gapi/directx12/dxdevice.cpp | 14 ++++- Engine/gapi/directx12/dxdevice.h | 2 + Engine/gapi/directx12/guid.h | 5 ++ 5 files changed, 73 insertions(+), 14 deletions(-) diff --git a/Engine/gapi/directx12/dxcommandbuffer.cpp b/Engine/gapi/directx12/dxcommandbuffer.cpp index 0468f744..27f3d8e5 100644 --- a/Engine/gapi/directx12/dxcommandbuffer.cpp +++ b/Engine/gapi/directx12/dxcommandbuffer.cpp @@ -37,36 +37,63 @@ static D3D12_RENDER_PASS_ENDING_ACCESS_TYPE mkStoreOp(const AccessOp op) { return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS; } -static D3D12_RESOURCE_STATES nativeFormat(ResourceAccess f) { +static D3D12_RESOURCE_STATES nativeFormat(ResourceAccess rs) { uint32_t st = 0; - if(f==ResourceAccess::None) + if(rs==ResourceAccess::None) return D3D12_RESOURCE_STATE_COMMON; - if((f&ResourceAccess::TransferSrc)==ResourceAccess::TransferSrc) + if((rs&ResourceAccess::TransferSrc)==ResourceAccess::TransferSrc) st |= D3D12_RESOURCE_STATE_COPY_SOURCE; - if((f&ResourceAccess::TransferDst)==ResourceAccess::TransferDst) + if((rs&ResourceAccess::TransferDst)==ResourceAccess::TransferDst) st |= D3D12_RESOURCE_STATE_COPY_DEST; + if((rs&ResourceAccess::TransferHost)==ResourceAccess::TransferHost) + st |= D3D12_RESOURCE_STATE_COPY_SOURCE; - if((f&ResourceAccess::Sampler)==ResourceAccess::Sampler) - st |= D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE|D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + if((rs&ResourceAccess::Present)==ResourceAccess::Present) + st |= D3D12_RESOURCE_STATE_COMMON; - if((f&ResourceAccess::ColorAttach)==ResourceAccess::ColorAttach) + if((rs&ResourceAccess::Sampler)==ResourceAccess::Sampler) + st |= D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE|D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + if((rs&ResourceAccess::ColorAttach)==ResourceAccess::ColorAttach) st |= D3D12_RESOURCE_STATE_RENDER_TARGET; - if((f&ResourceAccess::DepthAttach)==ResourceAccess::DepthAttach) + if((rs&ResourceAccess::DepthAttach)==ResourceAccess::DepthAttach) st |= D3D12_RESOURCE_STATE_DEPTH_WRITE; - if((f&ResourceAccess::DepthReadOnly)==ResourceAccess::DepthReadOnly) + if((rs&ResourceAccess::DepthReadOnly)==ResourceAccess::DepthReadOnly) st |= D3D12_RESOURCE_STATE_DEPTH_READ; - if((f&ResourceAccess::Vertex)==ResourceAccess::Vertex) + if((rs&ResourceAccess::Vertex)==ResourceAccess::Vertex) st |= D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER; - if((f&ResourceAccess::Index)==ResourceAccess::Index) + if((rs&ResourceAccess::Index)==ResourceAccess::Index) st |= D3D12_RESOURCE_STATE_INDEX_BUFFER; - if((f&ResourceAccess::Uniform)==ResourceAccess::Uniform) + if((rs&ResourceAccess::Uniform)==ResourceAccess::Uniform) st |= D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER; + if((rs&ResourceAccess::Indirect)==ResourceAccess::Indirect) + st |= D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT; + + if(true) { + if((rs&ResourceAccess::RtAsRead)==ResourceAccess::RtAsRead) { + st |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + } + if((rs&ResourceAccess::RtAsWrite)==ResourceAccess::RtAsWrite) { + st |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + } + } + + // memory barriers + if((rs&ResourceAccess::UavReadGr)==ResourceAccess::UavReadGr) { + st |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + } + if((rs&ResourceAccess::UavWriteGr)==ResourceAccess::UavWriteGr) { + st |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + } - if((f&ResourceAccess::UavReadWriteAll)!=ResourceAccess::None) + if((rs&ResourceAccess::UavReadComp)==ResourceAccess::UavReadComp) { + st |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + } + if((rs&ResourceAccess::UavWriteComp)==ResourceAccess::UavWriteComp) { st |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + } return D3D12_RESOURCE_STATES(st); } @@ -642,6 +669,16 @@ void DxCommandBuffer::drawIndexed(const AbstractGraphicsApi::Buffer& ivbo, size_ impl->DrawIndexedInstanced(UINT(isize),UINT(instanceCount),UINT(ioffset),INT(voffset),UINT(firstInstance)); } +void DxCommandBuffer::drawIndirect(const AbstractGraphicsApi::Buffer& indirect, size_t offset) { + const DxBuffer& ind = reinterpret_cast(indirect); + auto& sign = dev.drawIndirectSgn.get(); + + // block future writers + resState.onUavUsage(ind.nonUniqId, NonUniqResId::I_None, PipelineStage::S_Graphics); + //resState.flush(*this); + impl->ExecuteIndirect(sign, 1, ind.impl.get(), UINT64(offset), nullptr, 0); + } + void DxCommandBuffer::dispatchMesh(size_t x, size_t y, size_t z) { impl->DispatchMesh(UINT(x),UINT(y),UINT(z)); } diff --git a/Engine/gapi/directx12/dxcommandbuffer.h b/Engine/gapi/directx12/dxcommandbuffer.h index 4e6626db..d5f40658 100644 --- a/Engine/gapi/directx12/dxcommandbuffer.h +++ b/Engine/gapi/directx12/dxcommandbuffer.h @@ -64,6 +64,9 @@ class DxCommandBuffer:public AbstractGraphicsApi::CommandBuffer { void drawIndexed (const AbstractGraphicsApi::Buffer& vbo, size_t stride, size_t voffset, const AbstractGraphicsApi::Buffer& ibo, Detail::IndexClass cls, size_t ioffset, size_t isize, size_t firstInstance, size_t instanceCount) override; + + void drawIndirect(const AbstractGraphicsApi::Buffer& indirect, size_t offset) override; + void dispatchMesh(size_t x, size_t y, size_t z) override; void dispatch (size_t x, size_t y, size_t z) override; diff --git a/Engine/gapi/directx12/dxdevice.cpp b/Engine/gapi/directx12/dxdevice.cpp index 9d5194fe..38b9393f 100644 --- a/Engine/gapi/directx12/dxdevice.cpp +++ b/Engine/gapi/directx12/dxdevice.cpp @@ -52,6 +52,18 @@ DxDevice::DxDevice(IDXGIAdapter1& adapter, const ApiEntry& dllApi) queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; dxAssert(device->CreateCommandQueue(&queueDesc, uuid(), reinterpret_cast(&cmdQueue))); + { + D3D12_INDIRECT_ARGUMENT_DESC args[1] = {}; + args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW; + + D3D12_COMMAND_SIGNATURE_DESC desc = {}; + desc.ByteStride = sizeof(D3D12_DRAW_ARGUMENTS); + desc.NumArgumentDescs = 1; + desc.pArgumentDescs = args; + + dxAssert(device->CreateCommandSignature(&desc, nullptr, uuid(), reinterpret_cast(&drawIndirectSgn))); + } + allocator.setDevice(*this); descAlloc.setDevice(*this); @@ -219,7 +231,7 @@ void DxDevice::getProp(DXGI_ADAPTER_DESC1& desc, ID3D12Device& dev, AbstractGrap D3D12_FEATURE_DATA_D3D12_OPTIONS feature0 = {}; if(SUCCEEDED(dev.CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &feature0, sizeof(feature0)))) { - prop.descriptors.nonUniformIndexing = true; // SM5.1 + prop.descriptors.nonUniformIndexing = true; // SM5.1, mandatory in DX12 switch(feature0.ResourceBindingTier) { case D3D12_RESOURCE_BINDING_TIER_1: prop.descriptors.maxSamplers = 16; diff --git a/Engine/gapi/directx12/dxdevice.h b/Engine/gapi/directx12/dxdevice.h index ab36e8a3..82ac3825 100644 --- a/Engine/gapi/directx12/dxdevice.h +++ b/Engine/gapi/directx12/dxdevice.h @@ -333,6 +333,8 @@ class DxDevice : public AbstractGraphicsApi::Device { SpinLock syncCmdQueue; ComPtr cmdQueue; + ComPtr drawIndirectSgn; + DxAllocator allocator; DxDescriptorAllocator descAlloc; diff --git a/Engine/gapi/directx12/guid.h b/Engine/gapi/directx12/guid.h index 12d46a3b..aacf4c07 100644 --- a/Engine/gapi/directx12/guid.h +++ b/Engine/gapi/directx12/guid.h @@ -115,5 +115,10 @@ inline GUID uuid(){ return GUID{0x58346CDA, 0xDDE7, 0x4497, {0x94,0x61,0x6f,0x87,0xaf,0x5e,0x06,0x59}}; } +template<> +inline GUID uuid(){ + return GUID{0xC36A797C, 0xEC80, 0x4F0A, {0x89,0x85,0xa7,0xB2,0x47,0x50,0x82,0xD1}}; + } + } }