diff --git a/Source/Engine/Graphics/GPUContext.h b/Source/Engine/Graphics/GPUContext.h index 721bd406a..c00f0852a 100644 --- a/Source/Engine/Graphics/GPUContext.h +++ b/Source/Engine/Graphics/GPUContext.h @@ -198,12 +198,26 @@ public: API_FUNCTION() virtual void ClearDepth(GPUTextureView* depthBuffer, float depthValue = 1.0f) = 0; /// - /// Clears an unordered access resource with a float value. + /// Clears an unordered access buffer with a float value. /// /// The buffer to clear. /// The clear value. API_FUNCTION() virtual void ClearUA(GPUBuffer* buf, const Vector4& value) = 0; + /// + /// Clears an unordered access buffer with a unsigned value. + /// + /// The buffer to clear. + /// The clear value. + virtual void ClearUA(GPUBuffer* buf, const uint32 value[4]) = 0; + + /// + /// Clears an unordered access texture with a unsigned value. + /// + /// The texture to clear. + /// The clear value. + virtual void ClearUA(GPUTexture* texture, const uint32 value[4]) = 0; + public: /// diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.cpp index 7221ee05b..8dafb51b9 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.cpp @@ -170,12 +170,24 @@ void GPUContextDX11::ClearDepth(GPUTextureView* depthBuffer, float depthValue) void GPUContextDX11::ClearUA(GPUBuffer* buf, const Vector4& value) { ASSERT(buf != nullptr && buf->IsUnorderedAccess()); - auto uav = ((GPUBufferViewDX11*)buf->View())->UAV(); - _context->ClearUnorderedAccessViewFloat(uav, value.Raw); } +void GPUContextDX11::ClearUA(GPUBuffer* buf, const uint32 value[4]) +{ + ASSERT(buf != nullptr && buf->IsUnorderedAccess()); + auto uav = ((GPUBufferViewDX11*)buf->View())->UAV(); + _context->ClearUnorderedAccessViewUint(uav, value); +} + +void GPUContextDX11::ClearUA(GPUTexture* texture, const uint32 value[4]) +{ + ASSERT(texture != nullptr && texture->IsUnorderedAccess()); + auto uav = ((GPUTextureViewDX11*)texture->View())->UAV(); + _context->ClearUnorderedAccessViewUint(uav, value); +} + void GPUContextDX11::ResetRenderTarget() { if (_rtCount != 0 || _rtDepth) diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.h b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.h index 76b91f26e..81ae2d86d 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.h @@ -108,6 +108,8 @@ public: void Clear(GPUTextureView* rt, const Color& color) override; void ClearDepth(GPUTextureView* depthBuffer, float depthValue) override; void ClearUA(GPUBuffer* buf, const Vector4& value) override; + void ClearUA(GPUBuffer* buf, const uint32 value[4]) override; + void ClearUA(GPUTexture* texture, const uint32 value[4]) override; void ResetRenderTarget() override; void SetRenderTarget(GPUTextureView* rt) override; void SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt) override; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp index 45df37e4d..e29df4150 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp @@ -727,6 +727,34 @@ void GPUContextDX12::ClearUA(GPUBuffer* buf, const Vector4& value) _commandList->ClearUnorderedAccessViewFloat(desc.GPU, uav, bufDX12->GetResource(), value.Raw, 0, nullptr); } +void GPUContextDX12::ClearUA(GPUBuffer* buf, const uint32 value[4]) +{ + ASSERT(buf != nullptr && buf->IsUnorderedAccess()); + auto bufDX12 = reinterpret_cast(buf); + + SetResourceState(bufDX12, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + flushRBs(); + + auto uav = ((GPUBufferViewDX12*)bufDX12->View())->UAV(); + Descriptor desc; + GetActiveHeapDescriptor(uav, desc); + _commandList->ClearUnorderedAccessViewUint(desc.GPU, uav, bufDX12->GetResource(), value, 0, nullptr); +} + +void GPUContextDX12::ClearUA(GPUTexture* texture, const uint32 value[4]) +{ + ASSERT(texture != nullptr && texture->IsUnorderedAccess()); + auto texDX12 = reinterpret_cast(texture); + + SetResourceState(texDX12, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + flushRBs(); + + auto uav = ((GPUTextureViewDX12*)texDX12->View(0))->UAV(); + Descriptor desc; + GetActiveHeapDescriptor(uav, desc); + _commandList->ClearUnorderedAccessViewUint(desc.GPU, uav, texDX12->GetResource(), value, 0, nullptr); +} + void GPUContextDX12::ResetRenderTarget() { if (_rtDepth || _rtCount != 0) diff --git a/Source/Engine/GraphicsDevice/Null/GPUContextNull.h b/Source/Engine/GraphicsDevice/Null/GPUContextNull.h index 5d47b51bc..72c59529a 100644 --- a/Source/Engine/GraphicsDevice/Null/GPUContextNull.h +++ b/Source/Engine/GraphicsDevice/Null/GPUContextNull.h @@ -56,6 +56,14 @@ public: { } + void ClearUA(GPUBuffer* buf, const uint32 value[4]) override + { + } + + void ClearUA(GPUTexture* texture, const uint32 value[4]) override + { + } + void ResetRenderTarget() override { } diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp index 42b93ca4c..9dc21cf73 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp @@ -831,18 +831,49 @@ void GPUContextVulkan::ClearDepth(GPUTextureView* depthBuffer, float depthValue) void GPUContextVulkan::ClearUA(GPUBuffer* buf, const Vector4& value) { const auto bufVulkan = static_cast(buf); - if (bufVulkan) { const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer(); if (cmdBuffer->IsInsideRenderPass()) EndRenderPass(); + // TODO: add support for other components if buffer has them uint32_t* data = (uint32_t*)&value; vkCmdFillBuffer(cmdBuffer->GetHandle(), bufVulkan->GetHandle(), 0, bufVulkan->GetSize(), *data); } } +void GPUContextVulkan::ClearUA(GPUBuffer* buf, const uint32 value[4]) +{ + const auto bufVulkan = static_cast(buf); + if (bufVulkan) + { + const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer(); + if (cmdBuffer->IsInsideRenderPass()) + EndRenderPass(); + + // TODO: add support for other components if buffer has them + vkCmdFillBuffer(cmdBuffer->GetHandle(), bufVulkan->GetHandle(), 0, bufVulkan->GetSize(), value[0]); + } +} + +void GPUContextVulkan::ClearUA(GPUTexture* texture, const uint32 value[4]) +{ + const auto texVulkan = static_cast(texture); + if (texVulkan) + { + auto rtVulkan = static_cast(texVulkan->View(0)); + const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer(); + if (cmdBuffer->IsInsideRenderPass()) + EndRenderPass(); + + AddImageBarrier(rtVulkan, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + FlushBarriers(); + + vkCmdClearColorImage(cmdBuffer->GetHandle(), rtVulkan->Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (const VkClearColorValue*)value, 1, &rtVulkan->Info.subresourceRange); + } +} + void GPUContextVulkan::ResetRenderTarget() { if (_rtDepth || _rtCount != 0) diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h index 0d1d5ae56..d4ac93882 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h @@ -174,6 +174,8 @@ public: void Clear(GPUTextureView* rt, const Color& color) override; void ClearDepth(GPUTextureView* depthBuffer, float depthValue) override; void ClearUA(GPUBuffer* buf, const Vector4& value) override; + void ClearUA(GPUBuffer* buf, const uint32 value[4]) override; + void ClearUA(GPUTexture* texture, const uint32 value[4]) override; void ResetRenderTarget() override; void SetRenderTarget(GPUTextureView* rt) override; void SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt) override;