Fix a bug for multi-writes in ResourceUsageTrackingTests.cpp

It is valid to have race condition for multiple writes on the same
resource in some situations in render pass. These situations are:
1) multple storage buffer bindings on the same buffer,
2) multiple writeonly storage texture bindings on the same texture.

This change fixed a bug in tests and added a new test, in order to
make sure that validation code in Dawn allows this kind race condition.

Bug: dawn:407

Change-Id: I42332418bea5b6e608f6730e42f60c1c12b0b025
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/21361
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Yunchao He <yunchao.he@intel.com>
This commit is contained in:
Yunchao He 2020-05-11 19:12:12 +00:00 committed by Commit Bot service account
parent 5ffded3956
commit c2542cde3e
1 changed files with 27 additions and 15 deletions

View File

@ -183,8 +183,7 @@ namespace {
} }
} }
// Test that it is invalid to use the same buffer as multiple writable usages in the same // Test using multiple writable usages on the same buffer in a single pass/dispatch
// render pass. It is invalid in the same dispatch in compute pass.
TEST_F(ResourceUsageTrackingTest, BufferWithMultipleWriteUsage) { TEST_F(ResourceUsageTrackingTest, BufferWithMultipleWriteUsage) {
// Create buffer and bind group // Create buffer and bind group
wgpu::Buffer buffer = CreateBuffer(512, wgpu::BufferUsage::Storage); wgpu::Buffer buffer = CreateBuffer(512, wgpu::BufferUsage::Storage);
@ -199,14 +198,13 @@ namespace {
// test render pass // test render pass
{ {
// It is invalid to use the buffer as multiple writeable usages in render pass // It is valid to use multiple storage usages on the same buffer in render pass
wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
DummyRenderPass dummyRenderPass(device); DummyRenderPass dummyRenderPass(device);
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass); wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
pass.SetIndexBuffer(buffer);
pass.SetBindGroup(0, bg); pass.SetBindGroup(0, bg);
pass.EndPass(); pass.EndPass();
ASSERT_DEVICE_ERROR(encoder.Finish()); encoder.Finish();
} }
// test compute pass // test compute pass
@ -967,8 +965,7 @@ namespace {
} }
} }
// Test that it is invalid to use the same texture as multiple writable usages in the same // Test using multiple writable usages on the same texture in a single pass/dispatch
// render pass. It is invalid in the same dispatch in compute pass.
TEST_F(ResourceUsageTrackingTest, TextureWithMultipleWriteUsage) { TEST_F(ResourceUsageTrackingTest, TextureWithMultipleWriteUsage) {
// Test render pass // Test render pass
{ {
@ -986,16 +983,31 @@ namespace {
kFormat}}); kFormat}});
wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}}); wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}});
// Create a bind group to use the texture as render target
utils::ComboRenderPassDescriptor renderPass({view});
// It is invalid to use the texture as both writeonly storage and render target in // It is invalid to use the texture as both writeonly storage and render target in
// the same pass // the same pass
wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); {
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass); utils::ComboRenderPassDescriptor renderPass({view});
pass.SetBindGroup(0, bg);
pass.EndPass(); wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
ASSERT_DEVICE_ERROR(encoder.Finish()); wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
pass.SetBindGroup(0, bg);
pass.EndPass();
ASSERT_DEVICE_ERROR(encoder.Finish());
}
// It is valid to use multiple writeonly storage usages on the same texture in render
// pass
{
wgpu::BindGroup bg1 = utils::MakeBindGroup(device, bgl, {{0, view}});
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
DummyRenderPass dummyRenderPass(device);
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
pass.SetBindGroup(0, bg);
pass.SetBindGroup(1, bg1);
pass.EndPass();
encoder.Finish();
}
} }
// Test compute pass // Test compute pass