Skip to content

Commit

Permalink
[dxvk] Fix initializing buffers with non-dword sizes
Browse files Browse the repository at this point in the history
Fixes #4641. This should be very rare in general though.
  • Loading branch information
doitsujin committed Feb 5, 2025
1 parent cf946eb commit 0434b23
Showing 1 changed file with 34 additions and 3 deletions.
37 changes: 34 additions & 3 deletions src/dxvk/dxvk_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1038,9 +1038,40 @@ namespace dxvk {
const Rc<DxvkBuffer>& buffer) {
auto slice = buffer->getSliceHandle();

m_cmd->cmdFillBuffer(DxvkCmdBuffer::InitBuffer,
slice.handle, slice.offset,
dxvk::align(slice.length, 4), 0);
// Buffer size may be misaligned, in which case we have
// to use a plain buffer copy to fill the last few bytes.
constexpr VkDeviceSize MinCopyAndFillSize = 1u << 20;

VkDeviceSize copySize = slice.length & 3u;
VkDeviceSize fillSize = slice.length - copySize;

// If the buffer is small, just dispatch one single copy
if (copySize && slice.length < MinCopyAndFillSize) {
copySize = slice.length;
fillSize = 0u;
}

if (fillSize) {
m_cmd->cmdFillBuffer(DxvkCmdBuffer::InitBuffer,
slice.handle, slice.offset, fillSize, 0u);
}

if (copySize) {
auto zero = createZeroBuffer(copySize)->getSliceHandle();

VkBufferCopy2 copyRegion = { VK_STRUCTURE_TYPE_BUFFER_COPY_2 };
copyRegion.srcOffset = zero.offset;
copyRegion.dstOffset = slice.offset + fillSize;
copyRegion.size = copySize;

VkCopyBufferInfo2 copyInfo = { VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 };
copyInfo.srcBuffer = zero.handle;
copyInfo.dstBuffer = slice.handle;
copyInfo.regionCount = 1;
copyInfo.pRegions = &copyRegion;

m_cmd->cmdCopyBuffer(DxvkCmdBuffer::InitBuffer, &copyInfo);
}

accessMemory(DxvkCmdBuffer::InitBuffer,
VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT,
Expand Down

0 comments on commit 0434b23

Please sign in to comment.