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;