[dawn] Fix backends not consuming data of empty WriteBuffer commands Fixed: 500090141 Change-Id: I3ceb070c59cc9c865c1d5bcc0451c80d25b50d4a Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/304675 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Auto-Submit: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Loko Kung <lokokung@google.com>
diff --git a/src/dawn/native/Commands.cpp b/src/dawn/native/Commands.cpp index 05d9afa..f131c97 100644 --- a/src/dawn/native/Commands.cpp +++ b/src/dawn/native/Commands.cpp
@@ -422,9 +422,7 @@ case Command::WriteBuffer: { auto cmd = commands->NextCommand<WriteBufferCmd>(); - if (cmd->size > 0) { - commands->NextData<uint8_t>(cmd->size); - } + commands->NextData<uint8_t>(cmd->size); break; }
diff --git a/src/dawn/native/d3d11/CommandBufferD3D11.cpp b/src/dawn/native/d3d11/CommandBufferD3D11.cpp index ee935cd..c74bb8e 100644 --- a/src/dawn/native/d3d11/CommandBufferD3D11.cpp +++ b/src/dawn/native/d3d11/CommandBufferD3D11.cpp
@@ -502,6 +502,8 @@ case Command::WriteBuffer: { WriteBufferCmd* cmd = mCommands.NextCommand<WriteBufferCmd>(); + uint8_t* data = mCommands.NextData<uint8_t>(cmd->size); + if (cmd->size == 0) { // Skip no-op writes. continue; @@ -509,7 +511,6 @@ Buffer* dstBuffer = ToBackend(cmd->buffer.Get()); DAWN_TRY(dstBuffer->TrackUsage(commandContext, pendingSerial)); - uint8_t* data = mCommands.NextData<uint8_t>(cmd->size); DAWN_TRY(dstBuffer->Write(commandContext, cmd->offset, data, cmd->size)); break;
diff --git a/src/dawn/native/d3d12/CommandBufferD3D12.cpp b/src/dawn/native/d3d12/CommandBufferD3D12.cpp index 2d6c6b4..28f9822 100644 --- a/src/dawn/native/d3d12/CommandBufferD3D12.cpp +++ b/src/dawn/native/d3d12/CommandBufferD3D12.cpp
@@ -1389,12 +1389,13 @@ WriteBufferCmd* write = mCommands.NextCommand<WriteBufferCmd>(); const uint64_t offset = write->offset; const uint64_t size = write->size; + uint8_t* data = mCommands.NextData<uint8_t>(size); + if (size == 0) { continue; } Buffer* dstBuffer = ToBackend(write->buffer.Get()); - uint8_t* data = mCommands.NextData<uint8_t>(size); DAWN_TRY(device->GetDynamicUploader()->WithUploadReservation( size, kCopyBufferToBufferOffsetAlignment,
diff --git a/src/dawn/native/metal/CommandBufferMTL.mm b/src/dawn/native/metal/CommandBufferMTL.mm index a8db888..ed8b4a4 100644 --- a/src/dawn/native/metal/CommandBufferMTL.mm +++ b/src/dawn/native/metal/CommandBufferMTL.mm
@@ -1513,12 +1513,13 @@ WriteBufferCmd* write = mCommands.NextCommand<WriteBufferCmd>(); const uint64_t offset = write->offset; const uint64_t size = write->size; + uint8_t* data = mCommands.NextData<uint8_t>(size); + if (size == 0) { continue; } Buffer* dstBuffer = ToBackend(write->buffer.Get()); - uint8_t* data = mCommands.NextData<uint8_t>(size); Device* device = ToBackend(GetDevice()); DAWN_TRY(device->GetDynamicUploader()->WithUploadReservation(
diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp index 06d2d6b..6d14648 100644 --- a/src/dawn/native/opengl/CommandBufferGL.cpp +++ b/src/dawn/native/opengl/CommandBufferGL.cpp
@@ -1139,12 +1139,13 @@ WriteBufferCmd* write = mCommands.NextCommand<WriteBufferCmd>(); uint64_t offset = write->offset; uint64_t size = write->size; + uint8_t* data = mCommands.NextData<uint8_t>(size); + if (size == 0) { continue; } Buffer* dstBuffer = ToBackend(write->buffer.Get()); - uint8_t* data = mCommands.NextData<uint8_t>(size); DAWN_TRY(dstBuffer->EnsureDataInitializedAsDestination(offset, size)); DAWN_GL_TRY(gl, BindBuffer(GL_ARRAY_BUFFER, dstBuffer->GetHandle()));
diff --git a/src/dawn/native/vulkan/CommandBufferVk.cpp b/src/dawn/native/vulkan/CommandBufferVk.cpp index f726da9..60438f4 100644 --- a/src/dawn/native/vulkan/CommandBufferVk.cpp +++ b/src/dawn/native/vulkan/CommandBufferVk.cpp
@@ -1455,12 +1455,13 @@ WriteBufferCmd* write = mCommands.NextCommand<WriteBufferCmd>(); const uint64_t offset = write->offset; const uint64_t size = write->size; + uint8_t* data = mCommands.NextData<uint8_t>(size); + if (size == 0) { continue; } Buffer* dstBuffer = ToBackend(write->buffer.Get()); - uint8_t* data = mCommands.NextData<uint8_t>(size); DAWN_TRY(device->GetDynamicUploader()->WithUploadReservation( size, kCopyBufferToBufferOffsetAlignment,
diff --git a/src/dawn/tests/end2end/CommandEncoderTests.cpp b/src/dawn/tests/end2end/CommandEncoderTests.cpp index 94be114..258f5ae 100644 --- a/src/dawn/tests/end2end/CommandEncoderTests.cpp +++ b/src/dawn/tests/end2end/CommandEncoderTests.cpp
@@ -61,6 +61,21 @@ EXPECT_BUFFER_U32_EQ(0, bufferC, 3 * sizeof(uint32_t)); } +// Tests an empty WriteBuffer commands. +TEST_P(CommandEncoderTests, EmptyWriteBuffer) { + wgpu::Buffer buffer = + utils::CreateBufferFromData(device, wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::CopySrc, + { + 42, + }); + + wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); + encoder.WriteBuffer(buffer, 0, nullptr, 0); + wgpu::CommandBuffer commands = encoder.Finish(); + queue.Submit(1, &commands); + + EXPECT_BUFFER_U32_EQ(42, buffer, 0); +} DAWN_INSTANTIATE_TEST(CommandEncoderTests, D3D11Backend(), D3D12Backend(),