Allow one texture as write-only storage and sampled in one compute pass

This patch enables one texture to be used as both write-only storage
texture and sampled texture in one compute pass.

Note that while we don't need to check the usage scope of a texture in
the whole compute pass scope, we still need to verify one texture cannot
be bound to multiple bindings that are used in one dispatch at the same
time. This check will be added in the following patches.

This patch also adds tests to ensure a texture can be used as the
following binding types in one compute pass:
- read-only storage + sampled
- write-only storage + sampled
- read-only storage + write-only storage

BUG=dawn:267
TEST=dawn_unittests

Change-Id: Ibff2b005a5269a0bfa254e0417de4920758add39
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/20120
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Jiawei Shao
2020-04-22 00:55:43 +00:00
committed by Commit Bot service account
parent c133cab158
commit 64fcf3909a
10 changed files with 92 additions and 15 deletions

View File

@@ -974,7 +974,7 @@ TEST_F(StorageTextureValidationTests, StorageTextureAndOutputAttachmentInOneRend
// Verify it is invalid to use a a texture as both read-only storage texture and write-only storage
// texture in one render pass.
TEST_F(StorageTextureValidationTests, ReadOnlyStorageTextureAndWriteOnlyStorageTexture) {
TEST_F(StorageTextureValidationTests, ReadOnlyAndWriteOnlyStorageTextureInOneRenderPass) {
constexpr wgpu::TextureFormat kFormat = wgpu::TextureFormat::RGBA8Unorm;
wgpu::Texture storageTexture = CreateTexture(wgpu::TextureUsage::Storage, kFormat);
@@ -993,7 +993,7 @@ TEST_F(StorageTextureValidationTests, ReadOnlyStorageTextureAndWriteOnlyStorageT
utils::MakeBindGroup(device, bindGroupLayout,
{{0, storageTexture.CreateView()}, {1, storageTexture.CreateView()}});
// It is invalid to use a a texture as both read-only storage texture and write-only storage
// It is invalid to use a texture as both read-only storage texture and write-only storage
// texture in one render pass.
wgpu::Texture outputAttachment = CreateTexture(wgpu::TextureUsage::OutputAttachment, kFormat);
utils::ComboRenderPassDescriptor renderPassDescriptor({outputAttachment.CreateView()});
@@ -1003,3 +1003,66 @@ TEST_F(StorageTextureValidationTests, ReadOnlyStorageTextureAndWriteOnlyStorageT
renderPassEncoder.EndPass();
ASSERT_DEVICE_ERROR(encoder.Finish());
}
// Verify it is valid to use a texture as both storage texture (read-only or write-only) and
// sampled texture in one compute pass.
TEST_F(StorageTextureValidationTests, StorageTextureAndSampledTextureInOneComputePass) {
constexpr wgpu::TextureFormat kFormat = wgpu::TextureFormat::RGBA8Unorm;
wgpu::Texture storageTexture =
CreateTexture(wgpu::TextureUsage::Storage | wgpu::TextureUsage::Sampled, kFormat);
for (wgpu::BindingType storageTextureType : kSupportedStorageTextureBindingTypes) {
// Create a bind group that binds the same texture as both storage texture and sampled
// texture.
wgpu::BindGroupLayout bindGroupLayout =
utils::MakeBindGroupLayout(device, {{.binding = 0,
.visibility = wgpu::ShaderStage::Compute,
.type = storageTextureType,
.storageTextureFormat = kFormat},
{.binding = 1,
.visibility = wgpu::ShaderStage::Compute,
.type = wgpu::BindingType::SampledTexture,
.storageTextureFormat = kFormat}});
wgpu::BindGroup bindGroup = utils::MakeBindGroup(
device, bindGroupLayout,
{{0, storageTexture.CreateView()}, {1, storageTexture.CreateView()}});
// It is valid to use a a texture as both storage texture (read-only or write-only) and
// sampled texture in one compute pass.
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
wgpu::ComputePassEncoder computePassEncoder = encoder.BeginComputePass();
computePassEncoder.SetBindGroup(0, bindGroup);
computePassEncoder.EndPass();
encoder.Finish();
}
}
// Verify it is valid to use a texture as both read-only storage texture and write-only storage
// texture in one compute pass.
TEST_F(StorageTextureValidationTests, ReadOnlyAndWriteOnlyStorageTextureInOneComputePass) {
constexpr wgpu::TextureFormat kFormat = wgpu::TextureFormat::RGBA8Unorm;
wgpu::Texture storageTexture = CreateTexture(wgpu::TextureUsage::Storage, kFormat);
// Create a bind group that uses the same texture as both read-only and write-only storage
// texture.
wgpu::BindGroupLayout bindGroupLayout =
utils::MakeBindGroupLayout(device, {{.binding = 0,
.visibility = wgpu::ShaderStage::Compute,
.type = wgpu::BindingType::ReadonlyStorageTexture,
.storageTextureFormat = kFormat},
{.binding = 1,
.visibility = wgpu::ShaderStage::Compute,
.type = wgpu::BindingType::WriteonlyStorageTexture,
.storageTextureFormat = kFormat}});
wgpu::BindGroup bindGroup =
utils::MakeBindGroup(device, bindGroupLayout,
{{0, storageTexture.CreateView()}, {1, storageTexture.CreateView()}});
// It is valid to use a texture as both read-only storage texture and write-only storage
// texture in one compute pass.
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
wgpu::ComputePassEncoder computePassEncoder = encoder.BeginComputePass();
computePassEncoder.SetBindGroup(0, bindGroup);
computePassEncoder.EndPass();
encoder.Finish();
}