Fix erroneous validation logic for BindGroupLayoutEntry https://dawn-review.googlesource.com/c/dawn/+/34921 introduced a couple of bugs. This CL fixes them and tests to ensure that the new validation logic is working correctly. BUG=dawn:527 Change-Id: Ief01dfda0b97a202bf12ff6aeb0e7a3b84b4b81c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/35700 Commit-Queue: Brandon Jones <bajones@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/dawn.json b/dawn.json index 9e63583..3ec8b76 100644 --- a/dawn.json +++ b/dawn.json
@@ -168,7 +168,7 @@ {"name": "binding", "type": "uint32_t"}, {"name": "visibility", "type": "shader stage"}, - {"name": "type", "type": "binding type"}, + {"name": "type", "type": "binding type", "default": "undefined"}, {"name": "has dynamic offset", "type": "bool", "default": "false"}, {"name": "min buffer binding size", "type": "uint64_t", "default": "0"}, {"name": "view dimension", "type": "texture view dimension", "default": "undefined"},
diff --git a/src/dawn_native/BindGroupLayout.cpp b/src/dawn_native/BindGroupLayout.cpp index dec0a2c..4f34921 100644 --- a/src/dawn_native/BindGroupLayout.cpp +++ b/src/dawn_native/BindGroupLayout.cpp
@@ -85,19 +85,19 @@ const BufferBindingLayout& buffer = entry.buffer; DAWN_TRY(ValidateBufferBindingType(buffer.type)); - // TODO(dawn:527): ReadOnlyStorage should have the same limits as Storage - // regarding use with Vertex shaders. if (buffer.type == wgpu::BufferBindingType::Storage) { allowedStages &= ~wgpu::ShaderStage::Vertex; + } - // Dynamic storage buffers aren't bounds checked properly in D3D12. Disallow - // them as unsafe until the bounds checks are implemented. - if (device->IsToggleEnabled(Toggle::DisallowUnsafeAPIs) && - buffer.hasDynamicOffset) { - return DAWN_VALIDATION_ERROR( - "Dynamic storage buffers are disallowed because they aren't secure " - "yet. See https://crbug.com/dawn/429"); - } + // Dynamic storage buffers aren't bounds checked properly in D3D12. Disallow them as + // unsafe until the bounds checks are implemented. + if (device->IsToggleEnabled(Toggle::DisallowUnsafeAPIs) && + buffer.hasDynamicOffset && + (buffer.type == wgpu::BufferBindingType::Storage || + buffer.type == wgpu::BufferBindingType::ReadOnlyStorage)) { + return DAWN_VALIDATION_ERROR( + "Dynamic storage buffers are disallowed because they aren't secure yet. " + "See https://crbug.com/dawn/429"); } } if (entry.sampler.type != wgpu::SamplerBindingType::Undefined) { @@ -151,7 +151,7 @@ return DAWN_VALIDATION_ERROR( "Only one of buffer, sampler, texture, or storageTexture may be set for each " "BindGroupLayoutEntry"); - } else if (bindingMemberCount > 1) { + } else if (bindingMemberCount == 1) { if (entry.type != wgpu::BindingType::Undefined) { return DAWN_VALIDATION_ERROR( "BindGroupLayoutEntry type must be undefined if any of buffer, sampler, "
diff --git a/src/tests/end2end/DeprecatedAPITests.cpp b/src/tests/end2end/DeprecatedAPITests.cpp index 0119ac9..9855619 100644 --- a/src/tests/end2end/DeprecatedAPITests.cpp +++ b/src/tests/end2end/DeprecatedAPITests.cpp
@@ -48,6 +48,63 @@ pass.EndPass(); } +// Test that BindGroupLayoutEntry cannot have a type if buffer, sampler, texture, or storageTexture +// are defined. +TEST_P(DeprecationTests, BindGroupLayoutEntryTypeConflict) { + wgpu::BindGroupLayoutEntry binding; + binding.binding = 0; + binding.visibility = wgpu::ShaderStage::Vertex; + + wgpu::BindGroupLayoutDescriptor descriptor; + descriptor.entryCount = 1; + descriptor.entries = &binding; + + // Succeeds with only a type. + // Will soon emit a deprecation warning. + binding.type = wgpu::BindingType::UniformBuffer; + device.CreateBindGroupLayout(&descriptor); + + binding.type = wgpu::BindingType::Undefined; + + // Succeeds with only a buffer.type. + binding.buffer.type = wgpu::BufferBindingType::Uniform; + device.CreateBindGroupLayout(&descriptor); + // Fails when both type and a buffer.type are specified. + binding.type = wgpu::BindingType::UniformBuffer; + ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&descriptor)); + + binding.buffer.type = wgpu::BufferBindingType::Undefined; + binding.type = wgpu::BindingType::Undefined; + + // Succeeds with only a sampler.type. + binding.sampler.type = wgpu::SamplerBindingType::Filtering; + device.CreateBindGroupLayout(&descriptor); + // Fails when both type and a sampler.type are specified. + binding.type = wgpu::BindingType::Sampler; + ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&descriptor)); + + binding.sampler.type = wgpu::SamplerBindingType::Undefined; + binding.type = wgpu::BindingType::Undefined; + + // Succeeds with only a texture.sampleType. + binding.texture.sampleType = wgpu::TextureSampleType::Float; + device.CreateBindGroupLayout(&descriptor); + // Fails when both type and a texture.sampleType are specified. + binding.type = wgpu::BindingType::SampledTexture; + ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&descriptor)); + + binding.texture.sampleType = wgpu::TextureSampleType::Undefined; + binding.type = wgpu::BindingType::Undefined; + + // Succeeds with only a storageTexture.access. + binding.storageTexture.access = wgpu::StorageTextureAccess::ReadOnly; + binding.storageTexture.format = wgpu::TextureFormat::RGBA8Unorm; + device.CreateBindGroupLayout(&descriptor); + // Fails when both type and a storageTexture.access are specified. + binding.type = wgpu::BindingType::ReadonlyStorageTexture; + ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&descriptor)); +} + DAWN_INSTANTIATE_TEST(DeprecationTests, D3D12Backend(), MetalBackend(),