Skip to content

Commit

Permalink
[d3d11] Embed UpdateBuffer data in CS chunk
Browse files Browse the repository at this point in the history
Tiny optimization that gets rid of a copy and also lets us use chunk
memory more efficiently.
  • Loading branch information
doitsujin committed Mar 2, 2025
1 parent 5b68884 commit 416f9c5
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions src/d3d11/d3d11_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5507,19 +5507,25 @@ namespace dxvk {
if (Length <= MaxDirectUpdateSize && !((Offset | Length) & 0x3)) {
// The backend has special code paths for small buffer updates,
// however both offset and size must be aligned to four bytes.
std::array<char, MaxDirectUpdateSize> data;
std::memcpy(data.data(), pSrcData, Length);
// Write the data directly to the CS chunk.
uint32_t dwordCount = Length / sizeof(uint32_t);

EmitCs([
cBufferData = data,
EmitCsCmd<uint32_t>(D3D11CmdType::None, dwordCount, [
cBufferSlice = std::move(bufferSlice)
] (DxvkContext* ctx) {
] (DxvkContext* ctx, const uint32_t* data, size_t) {
ctx->updateBuffer(
cBufferSlice.buffer(),
cBufferSlice.offset(),
cBufferSlice.length(),
cBufferData.data());
cBufferSlice.length(), data);
});

// Compiler should be able to vectorize here, but GCC only does
// if we cast the destination pointer to the correct type first
auto src = reinterpret_cast<const uint32_t*>(pSrcData);
auto dst = reinterpret_cast<uint32_t*>(m_csData->first());

for (uint32_t i = 0; i < dwordCount; i++)
new (dst + i) uint32_t(src[i]);
} else {
// Write directly to a staging buffer and dispatch a copy
DxvkBufferSlice stagingSlice = AllocStagingBuffer(Length);
Expand Down

0 comments on commit 416f9c5

Please sign in to comment.