From 23e870d3113df8dba28ceb29d4c298959bc6611f Mon Sep 17 00:00:00 2001 From: Try Date: Sun, 7 Jul 2024 20:14:47 +0200 Subject: [PATCH] dx12: cleanup draw-indirect PR #54 --- Engine/gapi/abstractgraphicsapi.cpp | 9 ++++ Engine/gapi/abstractgraphicsapi.h | 3 +- Engine/gapi/directx12/dxcommandbuffer.cpp | 57 +++++++++-------------- Engine/gapi/directx12/dxcommandbuffer.h | 6 +-- Engine/gapi/directx12/dxdevice.cpp | 10 ++-- Engine/gapi/vulkan/vcommandbuffer.cpp | 4 +- 6 files changed, 43 insertions(+), 46 deletions(-) diff --git a/Engine/gapi/abstractgraphicsapi.cpp b/Engine/gapi/abstractgraphicsapi.cpp index 60a50762..42b90323 100644 --- a/Engine/gapi/abstractgraphicsapi.cpp +++ b/Engine/gapi/abstractgraphicsapi.cpp @@ -83,6 +83,15 @@ void AbstractGraphicsApi::CommandBuffer::barrier(Texture& tex, ResourceAccess pr barrier(&b,1); } +void AbstractGraphicsApi::CommandBuffer::barrier(const Buffer& buf, ResourceAccess prev, ResourceAccess next) { + AbstractGraphicsApi::BarrierDesc b; + b.buffer = &buf; + b.prev = prev; + b.next = next; + b.discard = (prev==ResourceAccess::None); + barrier(&b,1); + } + void AbstractGraphicsApi::CommandBuffer::begin(bool tranfer) { begin(); } diff --git a/Engine/gapi/abstractgraphicsapi.h b/Engine/gapi/abstractgraphicsapi.h index 317c9928..40a5530c 100644 --- a/Engine/gapi/abstractgraphicsapi.h +++ b/Engine/gapi/abstractgraphicsapi.h @@ -528,7 +528,7 @@ namespace Tempest { void ssboBarriers(Detail::ResourceState&,PipelineStage){} }; struct BarrierDesc { - Buffer* buffer = nullptr; + const Buffer* buffer = nullptr; Texture* texture = nullptr; Swapchain* swapchain = nullptr; uint32_t swId = 0; @@ -550,6 +550,7 @@ namespace Tempest { virtual void barrier(const BarrierDesc* desc, size_t cnt) = 0; virtual void barrier(Texture& tex, ResourceAccess prev, ResourceAccess next, uint32_t mipId); + virtual void barrier(const Buffer& buf, ResourceAccess prev, ResourceAccess next); virtual void generateMipmap(Texture& image, uint32_t texWidth, uint32_t texHeight, uint32_t mipLevels) = 0; virtual void copy(Buffer& dest, size_t offset, Texture& src, uint32_t width, uint32_t height, uint32_t mip) = 0; diff --git a/Engine/gapi/directx12/dxcommandbuffer.cpp b/Engine/gapi/directx12/dxcommandbuffer.cpp index 9d55f3b0..7421b55a 100644 --- a/Engine/gapi/directx12/dxcommandbuffer.cpp +++ b/Engine/gapi/directx12/dxcommandbuffer.cpp @@ -115,7 +115,7 @@ static ID3D12Resource* toDxResource(const AbstractGraphicsApi::BarrierDesc& b) { } if(b.buffer!=nullptr) { - DxBuffer& buf = *reinterpret_cast(b.buffer); + auto& buf = *reinterpret_cast(b.buffer); return buf.impl.get(); } @@ -620,8 +620,8 @@ void DxCommandBuffer::implSetUniforms(AbstractGraphicsApi::Desc& u, bool isCompu } void DxCommandBuffer::restoreIndirect() { - for(auto& i:indirectCmd) { - issueExplicitIndirectToCommonStateTransition(i); + for(auto i:indirectCmd) { + barrier(*i, ResourceAccess::Indirect, ResourceAccess::UavReadWriteAll); } indirectCmd.clear(); } @@ -642,9 +642,17 @@ void DxCommandBuffer::barrier(const AbstractGraphicsApi::BarrierDesc* desc, size barrier.UAV.pResource = nullptr; } else if(b.buffer!=nullptr) { - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; - barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - barrier.UAV.pResource = toDxResource(b); + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = toDxResource(b); + barrier.Transition.StateBefore = ::nativeFormat(b.prev); + barrier.Transition.StateAfter = ::nativeFormat(b.next); + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + if(barrier.Transition.StateBefore==barrier.Transition.StateAfter) { + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.UAV.pResource = toDxResource(b); + } } else { barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; @@ -743,9 +751,10 @@ void DxCommandBuffer::drawIndirect(const AbstractGraphicsApi::Buffer& indirect, resState.onUavUsage(ind.nonUniqId, NonUniqResId::I_None, PipelineStage::S_Indirect); //resState.flush(*this); - if(true && indirectCmd.find(ind.impl.get())==indirectCmd.end()) { - indirectCmd.insert(ind.impl.get()); - issueExplicitCommonToIndirectStateTransition(ind.impl.get()); + if(indirectCmd.find(&ind)==indirectCmd.end()) { + indirectCmd.insert(&ind); + // UNORDERED_ACCESS to INDIRECT_ARGUMENT (the UMD can assume the UAV writes occurred before the Render Pass) + barrier(indirect, ResourceAccess::UavReadWriteAll, ResourceAccess::Indirect); } impl->ExecuteIndirect(sign, 1, ind.impl.get(), UINT64(offset), nullptr, 0); @@ -761,10 +770,12 @@ void DxCommandBuffer::dispatchMeshIndirect(const AbstractGraphicsApi::Buffer& in // block future writers resState.onUavUsage(ind.nonUniqId, NonUniqResId::I_None, PipelineStage::S_Indirect); + //resState.setLayout(indirect, ResourceAccess::Indirect); - if(true && indirectCmd.find(ind.impl.get())==indirectCmd.end()) { - indirectCmd.insert(ind.impl.get()); - issueExplicitCommonToIndirectStateTransition(ind.impl.get()); + if(indirectCmd.find(&ind)==indirectCmd.end()) { + indirectCmd.insert(&ind); + // UNORDERED_ACCESS to INDIRECT_ARGUMENT (the UMD can assume the UAV writes occurred before the Render Pass) + barrier(indirect, ResourceAccess::UavReadWriteAll, ResourceAccess::Indirect); } impl->ExecuteIndirect(sign, 1, ind.impl.get(), UINT64(offset), nullptr, 0); } @@ -969,28 +980,6 @@ void DxCommandBuffer::copyNative(AbstractGraphicsApi::Buffer& dstBuf, size_t off impl->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr); } -void DxCommandBuffer::issueExplicitResourceStateTransition(ID3D12Resource* buf, D3D12_RESOURCE_STATES stateBefore, D3D12_RESOURCE_STATES stateAfter) -{ - D3D12_RESOURCE_BARRIER barrier; - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - barrier.Transition.pResource = buf; - barrier.Transition.StateAfter = stateAfter; - barrier.Transition.StateBefore = stateBefore; - barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - impl->ResourceBarrier(1, &barrier); - } - -void DxCommandBuffer::issueExplicitCommonToIndirectStateTransition(ID3D12Resource* buf) -{ - issueExplicitResourceStateTransition(buf, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT); - } - -void DxCommandBuffer::issueExplicitIndirectToCommonStateTransition(ID3D12Resource* buf) -{ - issueExplicitResourceStateTransition(buf, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT, D3D12_RESOURCE_STATE_COMMON); - } - #endif diff --git a/Engine/gapi/directx12/dxcommandbuffer.h b/Engine/gapi/directx12/dxcommandbuffer.h index fa8f9a46..6940215e 100644 --- a/Engine/gapi/directx12/dxcommandbuffer.h +++ b/Engine/gapi/directx12/dxcommandbuffer.h @@ -124,7 +124,7 @@ class DxCommandBuffer:public AbstractGraphicsApi::CommandBuffer { struct FillUAV; Stage* stageResources = nullptr; - std::unordered_set indirectCmd; + std::unordered_set indirectCmd; void pushChunk(); void newChunk(); @@ -134,10 +134,6 @@ class DxCommandBuffer:public AbstractGraphicsApi::CommandBuffer { void pushStage(Stage* cmd); void implSetUniforms(AbstractGraphicsApi::Desc& u, bool isCompute); void restoreIndirect(); - - void issueExplicitResourceStateTransition(ID3D12Resource* buf, D3D12_RESOURCE_STATES stateBefore, D3D12_RESOURCE_STATES stateAfter); - void issueExplicitCommonToIndirectStateTransition(ID3D12Resource* buf); - void issueExplicitIndirectToCommonStateTransition(ID3D12Resource* buf); }; } diff --git a/Engine/gapi/directx12/dxdevice.cpp b/Engine/gapi/directx12/dxdevice.cpp index e087e7fe..82ffa173 100644 --- a/Engine/gapi/directx12/dxdevice.cpp +++ b/Engine/gapi/directx12/dxdevice.cpp @@ -91,15 +91,17 @@ DxDevice::DxDevice(IDXGIAdapter1& adapter, const ApiEntry& dllApi) { D3D12_INDIRECT_ARGUMENT_DESC arg = {}; D3D12_COMMAND_SIGNATURE_DESC desc = {}; - desc.ByteStride = sizeof(D3D12_DRAW_ARGUMENTS); - desc.NumArgumentDescs = 1; desc.pArgumentDescs = &arg; - arg.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW; + desc.ByteStride = sizeof(D3D12_DRAW_ARGUMENTS); + desc.NumArgumentDescs = 1; + arg.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW; dxAssert(device->CreateCommandSignature(&desc, nullptr, uuid(), reinterpret_cast(&drawIndirectSgn))); if(props.meshlets.meshShader) { - arg.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH; + desc.ByteStride = sizeof(D3D12_DISPATCH_MESH_ARGUMENTS); + desc.NumArgumentDescs = 1; + arg.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH; dxAssert(device->CreateCommandSignature(&desc, nullptr, uuid(), reinterpret_cast(&drawMeshIndirectSgn))); } diff --git a/Engine/gapi/vulkan/vcommandbuffer.cpp b/Engine/gapi/vulkan/vcommandbuffer.cpp index 2b224809..196a6296 100644 --- a/Engine/gapi/vulkan/vcommandbuffer.cpp +++ b/Engine/gapi/vulkan/vcommandbuffer.cpp @@ -173,7 +173,7 @@ static VkImage toVkResource(const AbstractGraphicsApi::BarrierDesc& b) { } if(b.buffer!=nullptr) { - VBuffer& buf = *reinterpret_cast(b.buffer); + auto& buf = *reinterpret_cast(b.buffer); return buf.impl; } @@ -880,7 +880,7 @@ void VCommandBuffer::barrier(const AbstractGraphicsApi::BarrierDesc* desc, size_ bx.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR; bx.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; bx.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - bx.buffer = reinterpret_cast(*b.buffer).impl; + bx.buffer = reinterpret_cast(*b.buffer).impl; bx.offset = 0; bx.size = VK_WHOLE_SIZE;