diff --git a/src/dawn_native/BindGroupLayout.cpp b/src/dawn_native/BindGroupLayout.cpp index f63fb71728..fce8b90329 100644 --- a/src/dawn_native/BindGroupLayout.cpp +++ b/src/dawn_native/BindGroupLayout.cpp @@ -141,18 +141,22 @@ namespace dawn_native { MaybeError ValidateBindingCanBeMultisampled(wgpu::BindingType bindingType, wgpu::TextureViewDimension viewDimension) { switch (bindingType) { - case wgpu::BindingType::ReadonlyStorageTexture: - case wgpu::BindingType::WriteonlyStorageTexture: - return DAWN_VALIDATION_ERROR("Storage textures may not be multisampled"); - case wgpu::BindingType::SampledTexture: break; + case wgpu::BindingType::ReadonlyStorageTexture: + case wgpu::BindingType::WriteonlyStorageTexture: + return DAWN_VALIDATION_ERROR("Storage texture bindings may not be multisampled"); + case wgpu::BindingType::StorageBuffer: case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::ReadonlyStorageBuffer: + return DAWN_VALIDATION_ERROR("Buffer bindings may not be multisampled"); + case wgpu::BindingType::Sampler: case wgpu::BindingType::ComparisonSampler: + return DAWN_VALIDATION_ERROR("Sampler bindings may not be multisampled"); + case wgpu::BindingType::StorageTexture: default: UNREACHABLE(); @@ -164,14 +168,14 @@ namespace dawn_native { break; case wgpu::TextureViewDimension::e2DArray: - return DAWN_VALIDATION_ERROR("2D array textures may not be multisampled"); + return DAWN_VALIDATION_ERROR("2D array texture bindings may not be multisampled"); case wgpu::TextureViewDimension::Cube: case wgpu::TextureViewDimension::CubeArray: - return DAWN_VALIDATION_ERROR("Cube textures may not be multisampled"); + return DAWN_VALIDATION_ERROR("Cube texture bindings may not be multisampled"); case wgpu::TextureViewDimension::e3D: - return DAWN_VALIDATION_ERROR("3D textures may not be multisampled"); + return DAWN_VALIDATION_ERROR("3D texture bindings may not be multisampled"); case wgpu::TextureViewDimension::e1D: case wgpu::TextureViewDimension::Undefined: diff --git a/src/tests/unittests/validation/BindGroupValidationTests.cpp b/src/tests/unittests/validation/BindGroupValidationTests.cpp index 4f8d783875..a3bd47c4ae 100644 --- a/src/tests/unittests/validation/BindGroupValidationTests.cpp +++ b/src/tests/unittests/validation/BindGroupValidationTests.cpp @@ -727,6 +727,7 @@ TEST_F(BindGroupLayoutValidationTest, DynamicBufferNumberLimit) { } } +// Test that multisampled textures must be 2D sampled textures TEST_F(BindGroupLayoutValidationTest, MultisampledTextures) { // Multisampled 2D texture works. utils::MakeBindGroupLayout( @@ -742,6 +743,13 @@ TEST_F(BindGroupLayoutValidationTest, MultisampledTextures) { wgpu::TextureViewDimension::Undefined}, }); + // Multisampled 2D storage texture is invalid. + ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout( + device, { + {0, wgpu::ShaderStage::Compute, wgpu::BindingType::ReadonlyStorageTexture, + false, true, wgpu::TextureViewDimension::e2D}, + })); + // Multisampled 2D array texture is invalid. ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout( device, { @@ -771,6 +779,34 @@ TEST_F(BindGroupLayoutValidationTest, MultisampledTextures) { })); } +// Test that it is an error to pass multisampled=true for non-texture bindings +TEST_F(BindGroupLayoutValidationTest, MultisampledMustBeTexture) { + // Base: Multisampled 2D texture works. + utils::MakeBindGroupLayout( + device, { + {0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, true, + wgpu::TextureViewDimension::e2D}, + }); + + // Multisampled uniform buffer binding is invalid + ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout( + device, { + {0, wgpu::ShaderStage::Compute, wgpu::BindingType::UniformBuffer, false, true}, + })); + + // Multisampled storage buffer binding is invalid + ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout( + device, { + {0, wgpu::ShaderStage::Compute, wgpu::BindingType::StorageBuffer, false, true}, + })); + + // Multisampled sampler binding is invalid + ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout( + device, { + {0, wgpu::ShaderStage::Compute, wgpu::BindingType::Sampler, false, true}, + })); +} + constexpr uint64_t kBufferSize = 3 * kMinDynamicBufferOffsetAlignment + 8; constexpr uint32_t kBindingSize = 9;