Workaround for UpdateSubresource1 16-byte alignment
In case of misalignment, we write to a temp staging buffer first, and then copy to the dest buffer using CopySubresourceRegion. Bug: dawn:1776 Bug: dawn:1705 Change-Id: Iba44dd79d9ee4b02f8cc83263bcfc911e1cce136 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/130140 Reviewed-by: Austin Eng <enga@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Jie A Chen <jie.a.chen@intel.com>
This commit is contained in:
parent
642a4f1d8c
commit
1b01b665d7
|
@ -445,23 +445,51 @@ MaybeError Buffer::WriteInternal(CommandRecordingContext* commandContext,
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11_BOX dstBox;
|
D3D11_BOX box;
|
||||||
dstBox.left = offset;
|
box.left = offset;
|
||||||
dstBox.right = offset + size;
|
box.right = offset + size;
|
||||||
dstBox.top = 0;
|
box.top = 0;
|
||||||
dstBox.bottom = 1;
|
box.bottom = 1;
|
||||||
dstBox.front = 0;
|
box.front = 0;
|
||||||
dstBox.back = 1;
|
box.back = 1;
|
||||||
|
|
||||||
// TODO(dawn:1739): check whether driver supports partial update of uniform buffer.
|
|
||||||
if ((GetUsage() & wgpu::BufferUsage::Uniform)) {
|
if ((GetUsage() & wgpu::BufferUsage::Uniform)) {
|
||||||
d3d11DeviceContext1->UpdateSubresource1(GetD3D11Buffer(), /*DstSubresource=*/0, &dstBox,
|
if (!IsAligned(box.left, 16) || !IsAligned(box.right, 16)) {
|
||||||
|
// Create a temp staging buffer to workaround the alignment issue.
|
||||||
|
BufferDescriptor descriptor;
|
||||||
|
descriptor.size = box.right - box.left;
|
||||||
|
DAWN_ASSERT(IsAligned(descriptor.size, 4));
|
||||||
|
descriptor.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc;
|
||||||
|
descriptor.mappedAtCreation = false;
|
||||||
|
descriptor.label = "temp staging buffer";
|
||||||
|
Ref<BufferBase> stagingBufferBase;
|
||||||
|
DAWN_TRY_ASSIGN(stagingBufferBase, GetDevice()->CreateBuffer(&descriptor));
|
||||||
|
Ref<Buffer> stagingBuffer;
|
||||||
|
stagingBuffer = ToBackend(std::move(stagingBufferBase));
|
||||||
|
{
|
||||||
|
ScopedMap scopedMap;
|
||||||
|
DAWN_TRY_ASSIGN(scopedMap, ScopedMap::Create(stagingBuffer.Get()));
|
||||||
|
uint8_t* mappedData = scopedMap.GetMappedData();
|
||||||
|
DAWN_ASSERT(mappedData);
|
||||||
|
memcpy(mappedData, data, size);
|
||||||
|
}
|
||||||
|
box.left = 0;
|
||||||
|
box.right = descriptor.size;
|
||||||
|
commandContext->GetD3D11DeviceContext()->CopySubresourceRegion(
|
||||||
|
GetD3D11Buffer(), /*DstSubresource=*/0, /*DstX=*/offset,
|
||||||
|
/*DstY=*/0,
|
||||||
|
/*DstZ=*/0, stagingBuffer->GetD3D11Buffer(), /*SrcSubresource=*/0, &box);
|
||||||
|
stagingBuffer = nullptr;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// TODO(dawn:1739): check whether driver supports partial update of uniform buffer.
|
||||||
|
d3d11DeviceContext1->UpdateSubresource1(GetD3D11Buffer(), /*DstSubresource=*/0, &box,
|
||||||
data,
|
data,
|
||||||
/*SrcRowPitch=*/0,
|
/*SrcRowPitch=*/0,
|
||||||
/*SrcDepthPitch*/ 0, D3D11_COPY_NO_OVERWRITE);
|
/*SrcDepthPitch*/ 0, D3D11_COPY_NO_OVERWRITE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
d3d11DeviceContext1->UpdateSubresource(GetD3D11Buffer(), /*DstSubresource=*/0, &dstBox,
|
d3d11DeviceContext1->UpdateSubresource(GetD3D11Buffer(), /*DstSubresource=*/0, &box, data,
|
||||||
data,
|
|
||||||
/*SrcRowPitch=*/0,
|
/*SrcRowPitch=*/0,
|
||||||
/*SrcDepthPitch*/ 0);
|
/*SrcDepthPitch*/ 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -994,9 +994,6 @@ TEST_P(BindGroupTests, DrawThenChangePipelineTwiceAndBindGroup) {
|
||||||
// Regression test for crbug.com/dawn/408 where dynamic offsets were applied in the wrong order.
|
// Regression test for crbug.com/dawn/408 where dynamic offsets were applied in the wrong order.
|
||||||
// Dynamic offsets should be applied in increasing order of binding number.
|
// Dynamic offsets should be applied in increasing order of binding number.
|
||||||
TEST_P(BindGroupTests, DynamicOffsetOrder) {
|
TEST_P(BindGroupTests, DynamicOffsetOrder) {
|
||||||
// TODO(dawn:1776): Fix the UpdateSubresource1 16-byte alignment.
|
|
||||||
DAWN_SUPPRESS_TEST_IF(IsD3D11());
|
|
||||||
|
|
||||||
// We will put the following values and the respective offsets into a buffer.
|
// We will put the following values and the respective offsets into a buffer.
|
||||||
// The test will ensure that the correct dynamic offset is applied to each buffer by reading the
|
// The test will ensure that the correct dynamic offset is applied to each buffer by reading the
|
||||||
// value from an offset binding.
|
// value from an offset binding.
|
||||||
|
@ -1082,9 +1079,6 @@ TEST_P(BindGroupTests, DynamicAndNonDynamicBindingsDoNotConflictAfterRemapping)
|
||||||
// // TODO(crbug.com/dawn/1106): Test output is wrong on D3D12 using WARP.
|
// // TODO(crbug.com/dawn/1106): Test output is wrong on D3D12 using WARP.
|
||||||
DAWN_SUPPRESS_TEST_IF(IsWARP());
|
DAWN_SUPPRESS_TEST_IF(IsWARP());
|
||||||
|
|
||||||
// TODO(dawn:1776): Fix the UpdateSubresource1 16-byte alignment.
|
|
||||||
DAWN_SUPPRESS_TEST_IF(IsD3D11());
|
|
||||||
|
|
||||||
auto RunTestWith = [&](bool dynamicBufferFirst) {
|
auto RunTestWith = [&](bool dynamicBufferFirst) {
|
||||||
uint32_t dynamicBufferBindingNumber = dynamicBufferFirst ? 0 : 1;
|
uint32_t dynamicBufferBindingNumber = dynamicBufferFirst ? 0 : 1;
|
||||||
uint32_t bufferBindingNumber = dynamicBufferFirst ? 1 : 0;
|
uint32_t bufferBindingNumber = dynamicBufferFirst ? 1 : 0;
|
||||||
|
|
Loading…
Reference in New Issue