From 311661e4041e182e9bd6d8a6bd3d168901bb5c87 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 9 Feb 2019 22:21:57 +0100 Subject: [PATCH] [dxvk] Use vkCmdUpdateBuffer to clear tiny buffers While this might consume a few more CPU cycles, UpdateBuffer may be cheaper on the GPU for very small buffers, so we should use it instead. Also seems to fix rendering issues in Far Cry Primal for unknown reasons. --- src/dxvk/dxvk_context.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 8b10e889..2dd68fad 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -260,19 +260,32 @@ namespace dxvk { uint32_t value) { this->spillRenderPass(); - if (length == buffer->info().size) - length = align(length, 4); - + length = align(length, sizeof(uint32_t)); auto slice = buffer->getSliceHandle(offset, length); if (m_barriers.isBufferDirty(slice, DxvkAccess::Write)) m_barriers.recordCommands(m_cmd); - m_cmd->cmdFillBuffer( - slice.handle, - slice.offset, - slice.length, - value); + constexpr VkDeviceSize updateThreshold = 256; + + if (length <= updateThreshold * sizeof(uint32_t)) { + std::array data; + + for (uint32_t i = 0; i < length / sizeof(uint32_t); i++) + data[i] = value; + + m_cmd->cmdUpdateBuffer( + slice.handle, + slice.offset, + slice.length, + data.data()); + } else { + m_cmd->cmdFillBuffer( + slice.handle, + slice.offset, + slice.length, + value); + } m_barriers.accessBuffer(slice, VK_PIPELINE_STAGE_TRANSFER_BIT,