Validate effective storage or read-only storage buffer size be multiple of 4

This patch adds a validation that the effective buffer size must be a multiple
of 4 when the binding type is storage or read-only storage to match the latest
WebGPU SPEC.

This patch also fixes some typos in BindGroupValidationTests.

Bug: dawn:1542
Test: dawn_unittest
Change-Id: I30234bcf718be0d82d4a09b9980127a98ebe8172
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/105101
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Jiawei Shao 2022-10-12 00:55:37 +00:00 committed by Dawn LUCI CQ
parent a44e3d8bea
commit 75a8574b29
4 changed files with 135 additions and 73 deletions

View File

@ -49,30 +49,6 @@ MaybeError ValidateBufferBinding(const DeviceBase* device,
ASSERT(bindingInfo.bindingType == BindingInfoType::Buffer);
wgpu::BufferUsage requiredUsage;
uint64_t maxBindingSize;
uint64_t requiredBindingAlignment;
switch (bindingInfo.buffer.type) {
case wgpu::BufferBindingType::Uniform:
requiredUsage = wgpu::BufferUsage::Uniform;
maxBindingSize = device->GetLimits().v1.maxUniformBufferBindingSize;
requiredBindingAlignment = device->GetLimits().v1.minUniformBufferOffsetAlignment;
break;
case wgpu::BufferBindingType::Storage:
case wgpu::BufferBindingType::ReadOnlyStorage:
requiredUsage = wgpu::BufferUsage::Storage;
maxBindingSize = device->GetLimits().v1.maxStorageBufferBindingSize;
requiredBindingAlignment = device->GetLimits().v1.minStorageBufferOffsetAlignment;
break;
case kInternalStorageBufferBinding:
requiredUsage = kInternalStorageBuffer;
maxBindingSize = device->GetLimits().v1.maxStorageBufferBindingSize;
requiredBindingAlignment = device->GetLimits().v1.minStorageBufferOffsetAlignment;
break;
case wgpu::BufferBindingType::Undefined:
UNREACHABLE();
}
uint64_t bufferSize = entry.buffer->GetSize();
// Handle wgpu::WholeSize, avoiding overflows.
@ -95,6 +71,33 @@ MaybeError ValidateBufferBinding(const DeviceBase* device,
"Binding range (offset: %u, size: %u) doesn't fit in the size (%u) of %s.",
entry.offset, bufferSize, bindingSize, entry.buffer);
wgpu::BufferUsage requiredUsage;
uint64_t maxBindingSize;
uint64_t requiredBindingAlignment;
switch (bindingInfo.buffer.type) {
case wgpu::BufferBindingType::Uniform:
requiredUsage = wgpu::BufferUsage::Uniform;
maxBindingSize = device->GetLimits().v1.maxUniformBufferBindingSize;
requiredBindingAlignment = device->GetLimits().v1.minUniformBufferOffsetAlignment;
break;
case wgpu::BufferBindingType::Storage:
case wgpu::BufferBindingType::ReadOnlyStorage:
requiredUsage = wgpu::BufferUsage::Storage;
maxBindingSize = device->GetLimits().v1.maxStorageBufferBindingSize;
requiredBindingAlignment = device->GetLimits().v1.minStorageBufferOffsetAlignment;
DAWN_INVALID_IF(bindingSize % 4 != 0,
"Binding size (%u) isn't a multiple of 4 when binding type is (%s).",
bindingSize, bindingInfo.buffer.type);
break;
case kInternalStorageBufferBinding:
requiredUsage = kInternalStorageBuffer;
maxBindingSize = device->GetLimits().v1.maxStorageBufferBindingSize;
requiredBindingAlignment = device->GetLimits().v1.minStorageBufferOffsetAlignment;
break;
case wgpu::BufferBindingType::Undefined:
UNREACHABLE();
}
DAWN_INVALID_IF(!IsAligned(entry.offset, requiredBindingAlignment),
"Offset (%u) does not satisfy the minimum %s alignment (%u).", entry.offset,
bindingInfo.buffer.type, requiredBindingAlignment);

View File

@ -1041,7 +1041,7 @@ TEST_F(BindGroupValidationTest, MaxStorageBufferBindingSize) {
// Success case, this is one less than the limit (check it is not an alignment constraint)
utils::MakeBindGroup(device, uniformLayout,
{{0, buffer, 0, supportedLimits.maxStorageBufferBindingSize - 1}});
{{0, buffer, 0, supportedLimits.maxStorageBufferBindingSize - 4}});
wgpu::BindGroupLayout doubleUniformLayout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage},
@ -1055,7 +1055,51 @@ TEST_F(BindGroupValidationTest, MaxStorageBufferBindingSize) {
// Error case, this is above the limit
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(
device, uniformLayout, {{0, buffer, 0, supportedLimits.maxStorageBufferBindingSize + 1}}));
device, uniformLayout, {{0, buffer, 0, supportedLimits.maxStorageBufferBindingSize + 4}}));
}
// Test constraints to be sure the effective storage and read-only storage buffer binding size must
// be a multiple of 4.
TEST_F(BindGroupValidationTest, EffectiveStorageBufferBindingSize) {
wgpu::BufferDescriptor descriptor;
descriptor.size = 262;
descriptor.usage = wgpu::BufferUsage::Storage;
wgpu::Buffer buffer = device.CreateBuffer(&descriptor);
constexpr std::array<wgpu::BufferBindingType, 2> kStorageBufferBindingTypes = {
{wgpu::BufferBindingType::Storage, wgpu::BufferBindingType::ReadOnlyStorage}};
for (wgpu::BufferBindingType bufferBindingType : kStorageBufferBindingTypes) {
wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, bufferBindingType}});
// Error case, as the effective buffer binding size (262) isn't a multiple of 4.
{
constexpr uint32_t kOffset = 0;
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, buffer, kOffset}}));
}
// Error case, as the effective buffer binding size (6) isn't a multiple of 4.
{
constexpr uint32_t kOffset = 256;
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, buffer, kOffset}}));
}
// Error case, as the effective buffer binding size (2) isn't a multiple of 4.
{
constexpr uint32_t kOffset = 0;
constexpr uint32_t kBindingSize = 2;
ASSERT_DEVICE_ERROR(
utils::MakeBindGroup(device, layout, {{0, buffer, kOffset, kBindingSize}}));
}
// Success case, as the effective buffer binding size (4) is a multiple of 4.
{
constexpr uint32_t kOffset = 0;
constexpr uint32_t kBindingSize = 4;
utils::MakeBindGroup(device, layout, {{0, buffer, kOffset, kBindingSize}});
}
}
}
// Test what happens when the layout is an error.
@ -1626,7 +1670,7 @@ TEST_F(BindGroupLayoutValidationTest, MultisampledTextureSampleType) {
});
}
constexpr uint32_t kBindingSize = 9;
constexpr uint32_t kBindingSize = 8;
class SetBindGroupValidationTest : public ValidationTest {
public:
@ -1919,17 +1963,19 @@ TEST_F(SetBindGroupValidationTest, OffsetOutOfBoundDynamicStorageBuffer) {
// Test cases that test dynamic uniform buffer out of bound situation because of binding size.
TEST_F(SetBindGroupValidationTest, BindingSizeOutOfBoundDynamicUniformBuffer) {
// Set up bind group, but binding size is larger than
// Set up bind group, but binding size is larger than (mBufferSize - DynamicOffset).
wgpu::Buffer uniformBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Uniform);
wgpu::Buffer storageBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Storage);
wgpu::Buffer readonlyStorageBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Storage);
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, mBindGroupLayout,
{{0, uniformBuffer, 0, kBindingSize},
{1, uniformBuffer, 0, kBindingSize},
{2, storageBuffer, 0, kBindingSize},
{3, readonlyStorageBuffer, 0, kBindingSize}});
constexpr uint32_t kLargeBindingSize = kBindingSize + 4u;
wgpu::BindGroup bindGroup =
utils::MakeBindGroup(device, mBindGroupLayout,
{{0, uniformBuffer, 0, kLargeBindingSize},
{1, uniformBuffer, 0, kLargeBindingSize},
{2, storageBuffer, 0, kLargeBindingSize},
{3, readonlyStorageBuffer, 0, kLargeBindingSize}});
// Dynamic offset + offset isn't larger than buffer size.
// c + offset isn't larger than buffer size.
// But with binding size, it will trigger OOB error.
std::array<uint32_t, 3> offsets = {768, 256, 0};
@ -1943,11 +1989,13 @@ TEST_F(SetBindGroupValidationTest, BindingSizeOutOfBoundDynamicStorageBuffer) {
wgpu::Buffer uniformBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Uniform);
wgpu::Buffer storageBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Storage);
wgpu::Buffer readonlyStorageBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Storage);
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, mBindGroupLayout,
{{0, uniformBuffer, 0, kBindingSize},
{1, uniformBuffer, 0, kBindingSize},
{2, storageBuffer, 0, kBindingSize},
{3, readonlyStorageBuffer, 0, kBindingSize}});
constexpr uint32_t kLargeBindingSize = kBindingSize + 4u;
wgpu::BindGroup bindGroup =
utils::MakeBindGroup(device, mBindGroupLayout,
{{0, uniformBuffer, 0, kLargeBindingSize},
{1, uniformBuffer, 0, kLargeBindingSize},
{2, storageBuffer, 0, kLargeBindingSize},
{3, readonlyStorageBuffer, 0, kLargeBindingSize}});
// Dynamic offset + offset isn't larger than buffer size.
// But with binding size, it will trigger OOB error.
std::array<uint32_t, 3> offsets = {0, 256, 768};
@ -2593,7 +2641,7 @@ TEST_F(BindingsValidationTest, PipelineLayoutWithMoreBindingsThanPipeline) {
// Test that it is invalid to set a pipeline layout that doesn't have all necessary bindings
// required by the pipeline.
TEST_F(BindingsValidationTest, PipelineLayoutWithLessBindingsThanPipeline) {
TEST_F(BindingsValidationTest, PipelineLayoutWithFewerBindingsThanPipeline) {
// Set up bind group layout.
wgpu::BindGroupLayout bgl0 = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
@ -2672,7 +2720,7 @@ TEST_F(BindingsValidationTest, BindGroupsWithMoreBindingsThanPipelineLayout) {
// Test that it is invalid to set bind groups that don't have all necessary bindings required
// by the pipeline layout. Note that both pipeline layout and bind group have enough bindings for
// pipeline in the following test.
TEST_F(BindingsValidationTest, BindGroupsWithLessBindingsThanPipelineLayout) {
TEST_F(BindingsValidationTest, BindGroupsWithFewerBindingsThanPipelineLayout) {
// Set up bind group layouts, buffers, bind groups, pipeline layouts and pipelines.
std::array<wgpu::BindGroupLayout, kBindingNum> bgl;
std::array<wgpu::BindGroup, kBindingNum> bg;

View File

@ -55,18 +55,19 @@ void WithEachSizeOffsetBy(int64_t offset, const std::vector<uint64_t>& originalS
template <typename F>
void CheckSizeBounds(const std::vector<uint64_t>& correctSizes, F func) {
// To validate size:
// Check invalid with bind group with one less
// Check invalid with bind group with 4 less (the effective storage / read-only storage buffer
// size must be a multiple of 4).
// Check valid with bind group with correct size
// Make sure (every size - 1) produces an error
WithEachSizeOffsetBy(-1, correctSizes,
// Make sure (every size - 4) produces an error
WithEachSizeOffsetBy(-4, correctSizes,
[&](const std::vector<uint64_t>& sizes) { func(sizes, false); });
// Make sure correct sizes work
func(correctSizes, true);
// Make sure (every size + 1) works
WithEachSizeOffsetBy(1, correctSizes,
// Make sure (every size + 4) works
WithEachSizeOffsetBy(4, correctSizes,
[&](const std::vector<uint64_t>& sizes) { func(sizes, true); });
}
@ -324,8 +325,8 @@ class MinBufferSizePipelineCreationTests : public MinBufferSizeTestsBase {};
// Pipeline can be created if minimum buffer size in layout is specified as 0
TEST_F(MinBufferSizePipelineCreationTests, ZeroMinBufferSize) {
std::vector<BindingDescriptor> bindings = {{0, 0, "a : f32, b : f32,", "f32", "a", 8},
{0, 1, "c : f32,", "f32", "c", 4}};
std::vector<BindingDescriptor> bindings = {{0, 0, "a : f32, b : f32, c : f32", "f32", "a", 12},
{0, 1, "d : f32, e : f32", "f32", "d", 8}};
std::string computeShader = CreateComputeShaderWithBindings(bindings);
std::string vertexShader = CreateVertexShaderWithBindings({});
@ -338,14 +339,14 @@ TEST_F(MinBufferSizePipelineCreationTests, ZeroMinBufferSize) {
// Fail if layout given has non-zero minimum sizes smaller than shader requirements
TEST_F(MinBufferSizePipelineCreationTests, LayoutSizesTooSmall) {
std::vector<BindingDescriptor> bindings = {{0, 0, "a : f32, b : f32,", "f32", "a", 8},
{0, 1, "c : f32,", "f32", "c", 4}};
std::vector<BindingDescriptor> bindings = {{0, 0, "a : f32, b : f32, c: f32", "f32", "a", 12},
{0, 1, "d : f32, e : f32", "f32", "d", 8}};
std::string computeShader = CreateComputeShaderWithBindings(bindings);
std::string vertexShader = CreateVertexShaderWithBindings({});
std::string fragShader = CreateFragmentShaderWithBindings(bindings);
CheckSizeBounds({8, 4}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
CheckSizeBounds({12, 8}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
wgpu::BindGroupLayout layout = CreateBindGroupLayout(bindings, sizes);
if (expectation) {
CreateRenderPipeline({layout}, vertexShader, fragShader);
@ -359,18 +360,19 @@ TEST_F(MinBufferSizePipelineCreationTests, LayoutSizesTooSmall) {
// Fail if layout given has non-zero minimum sizes smaller than shader requirements
TEST_F(MinBufferSizePipelineCreationTests, LayoutSizesTooSmallMultipleGroups) {
std::vector<BindingDescriptor> bg0Bindings = {{0, 0, "a : f32, b : f32,", "f32", "a", 8},
{0, 1, "c : f32,", "f32", "c", 4}};
std::vector<BindingDescriptor> bg0Bindings = {
{0, 0, "a : f32, b : f32, c : f32", "f32", "a", 12},
{0, 1, "d : f32, e : f32", "f32", "d", 8}};
std::vector<BindingDescriptor> bg1Bindings = {
{1, 0, "d : f32, e : f32, f : f32,", "f32", "e", 12},
{1, 1, "g : mat2x2<f32>,", "mat2x2<f32>", "g", 16}};
{1, 0, "f : f32, g : f32, h : f32,", "f32", "f", 12},
{1, 1, "i : mat2x2<f32>,", "mat2x2<f32>", "i", 16}};
std::vector<BindingDescriptor> bindings = CombineBindings({bg0Bindings, bg1Bindings});
std::string computeShader = CreateComputeShaderWithBindings(bindings);
std::string vertexShader = CreateVertexShaderWithBindings({});
std::string fragShader = CreateFragmentShaderWithBindings(bindings);
CheckSizeBounds({8, 4, 12, 16}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
CheckSizeBounds({12, 8, 12, 16}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
wgpu::BindGroupLayout layout0 = CreateBindGroupLayout(bg0Bindings, {sizes[0], sizes[1]});
wgpu::BindGroupLayout layout1 = CreateBindGroupLayout(bg1Bindings, {sizes[2], sizes[3]});
if (expectation) {
@ -388,11 +390,11 @@ class MinBufferSizeBindGroupCreationTests : public MinBufferSizeTestsBase {};
// Fail if a binding is smaller than minimum buffer size
TEST_F(MinBufferSizeBindGroupCreationTests, BindingTooSmall) {
std::vector<BindingDescriptor> bindings = {{0, 0, "a : f32, b : f32,", "f32", "a", 8},
{0, 1, "c : f32,", "f32", "c", 4}};
wgpu::BindGroupLayout layout = CreateBindGroupLayout(bindings, {8, 4});
std::vector<BindingDescriptor> bindings = {{0, 0, "a : f32, b : f32, c : f32", "f32", "a", 12},
{0, 1, "d : f32, e : f32", "f32", "d", 8}};
wgpu::BindGroupLayout layout = CreateBindGroupLayout(bindings, {12, 8});
CheckSizeBounds({8, 4}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
CheckSizeBounds({12, 8}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
if (expectation) {
CreateBindGroup(layout, bindings, sizes);
} else {
@ -422,8 +424,8 @@ class MinBufferSizeDrawTimeValidationTests : public MinBufferSizeTestsBase {};
// Fail if binding sizes are too small at draw time
TEST_F(MinBufferSizeDrawTimeValidationTests, ZeroMinSizeAndTooSmallBinding) {
std::vector<BindingDescriptor> bindings = {{0, 0, "a : f32, b : f32,", "f32", "a", 8},
{0, 1, "c : f32,", "f32", "c", 4}};
std::vector<BindingDescriptor> bindings = {{0, 0, "a : f32, b : f32, c : f32", "f32", "a", 12},
{0, 1, "d : f32, e : f32", "f32", "d", 8}};
std::string computeShader = CreateComputeShaderWithBindings(bindings);
std::string vertexShader = CreateVertexShaderWithBindings({});
@ -434,7 +436,7 @@ TEST_F(MinBufferSizeDrawTimeValidationTests, ZeroMinSizeAndTooSmallBinding) {
wgpu::ComputePipeline computePipeline = CreateComputePipeline({layout}, computeShader);
wgpu::RenderPipeline renderPipeline = CreateRenderPipeline({layout}, vertexShader, fragShader);
CheckSizeBounds({8, 4}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
CheckSizeBounds({12, 8}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
wgpu::BindGroup bindGroup = CreateBindGroup(layout, bindings, sizes);
TestDispatch(computePipeline, {bindGroup}, expectation);
TestDraw(renderPipeline, {bindGroup}, expectation);
@ -445,8 +447,8 @@ TEST_F(MinBufferSizeDrawTimeValidationTests, ZeroMinSizeAndTooSmallBinding) {
TEST_F(MinBufferSizeDrawTimeValidationTests, UnorderedBindings) {
std::vector<BindingDescriptor> bindings = {
{0, 2, "a : f32, b : f32,", "f32", "a", 8},
{0, 0, "c : f32,", "f32", "c", 4},
{0, 4, "d : f32, e : f32, f : f32,", "f32", "e", 12}};
{0, 0, "c : f32, d : f32, e : f32", "f32", "c", 12},
{0, 4, "f : f32, g : f32, h : f32, i : f32", "f32", "f", 16}};
std::string computeShader = CreateComputeShaderWithBindings(bindings);
std::string vertexShader = CreateVertexShaderWithBindings({});
@ -457,7 +459,7 @@ TEST_F(MinBufferSizeDrawTimeValidationTests, UnorderedBindings) {
wgpu::ComputePipeline computePipeline = CreateComputePipeline({layout}, computeShader);
wgpu::RenderPipeline renderPipeline = CreateRenderPipeline({layout}, vertexShader, fragShader);
CheckSizeBounds({8, 4, 12}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
CheckSizeBounds({8, 12, 16}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
wgpu::BindGroup bindGroup = CreateBindGroup(layout, bindings, sizes);
TestDispatch(computePipeline, {bindGroup}, expectation);
TestDraw(renderPipeline, {bindGroup}, expectation);
@ -466,11 +468,12 @@ TEST_F(MinBufferSizeDrawTimeValidationTests, UnorderedBindings) {
// Draw time validation works for multiple bind groups
TEST_F(MinBufferSizeDrawTimeValidationTests, MultipleGroups) {
std::vector<BindingDescriptor> bg0Bindings = {{0, 0, "a : f32, b : f32,", "f32", "a", 8},
{0, 1, "c : f32,", "f32", "c", 4}};
std::vector<BindingDescriptor> bg0Bindings = {
{0, 0, "a : f32, b : f32, c : f32", "f32", "a", 12},
{0, 1, "d : f32, e : f32", "f32", "d", 8}};
std::vector<BindingDescriptor> bg1Bindings = {
{1, 0, "d : f32, e : f32, f : f32,", "f32", "e", 12},
{1, 1, "g : mat2x2<f32>,", "mat2x2<f32>", "g", 16}};
{1, 0, "f : f32, g : f32, h : f32,", "f32", "f", 12},
{1, 1, "i : mat2x2<f32>,", "mat2x2<f32>", "i", 16}};
std::vector<BindingDescriptor> bindings = CombineBindings({bg0Bindings, bg1Bindings});
std::string computeShader = CreateComputeShaderWithBindings(bindings);
@ -485,7 +488,7 @@ TEST_F(MinBufferSizeDrawTimeValidationTests, MultipleGroups) {
wgpu::RenderPipeline renderPipeline =
CreateRenderPipeline({layout0, layout1}, vertexShader, fragShader);
CheckSizeBounds({8, 4, 12, 16}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
CheckSizeBounds({12, 8, 12, 16}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
wgpu::BindGroup bindGroup0 = CreateBindGroup(layout0, bg0Bindings, {sizes[0], sizes[1]});
wgpu::BindGroup bindGroup1 = CreateBindGroup(layout0, bg0Bindings, {sizes[2], sizes[3]});
TestDispatch(computePipeline, {bindGroup0, bindGroup1}, expectation);

View File

@ -769,6 +769,16 @@ crbug.com/1357206 [ nvidia-0x2184 win10 ] worker_webgpu:api,validation,buffer,ma
################################################################################
crbug.com/dawn/1539 [ ubuntu ] webgpu:api,validation,render_pipeline,fragment_state:pipeline_output_targets:isAsync=true;* [ Failure ]
################################################################################
# storage buffer binding size failures
################################################################################
crbug.com/dawn/1542 webgpu:api,validation,createBindGroup:buffer,resource_binding_size:type="read-only-storage" [ Failure ]
crbug.com/dawn/1542 webgpu:api,validation,createBindGroup:buffer,resource_binding_size:type="storage" [ Failure ]
crbug.com/dawn/1542 webgpu:api,validation,createBindGroup:minBindingSize: [ Failure ]
crbug.com/dawn/1542 webgpu:api,validation,encoding,cmds,setBindGroup:buffer_dynamic_offsets:type="read-only-storage";* [ Failure ]
crbug.com/dawn/1542 webgpu:api,validation,encoding,cmds,setBindGroup:buffer_dynamic_offsets:type="storage";* [ Failure ]
crbug.com/dawn/1542 webgpu:api,validation,encoding,cmds,setBindGroup:dynamic_offsets_match_expectations_in_pass_encoder:* [ Failure ]
################################################################################
# untriaged failures
# KEEP
@ -788,8 +798,6 @@ crbug.com/dawn/0000 [ dawn-backend-validation nvidia-0x2184 target-cpu-64 win10
# New failures. Please triage:
crbug.com/dawn/0000 [ intel-gen-9 win10 ] webgpu:api,operation,command_buffer,image_copy:mip_levels:initMethod="WriteTexture";checkMethod="PartialCopyT2B";format="rgba32uint";dimension="2d" [ Failure ]
crbug.com/dawn/0000 webgpu:api,validation,compute_pipeline:overrides,workgroup_size,limits,* [ Failure ]
crbug.com/dawn/0000 [ win10 ] webgpu:api,validation,createBindGroup:buffer,resource_binding_size:type="read-only-storage" [ Failure ]
crbug.com/dawn/0000 [ win10 ] webgpu:api,validation,createBindGroup:buffer,resource_binding_size:type="storage" [ Failure ]
crbug.com/dawn/0000 webgpu:api,validation,createBindGroupLayout:multisampled_validation:viewDimension="2d" [ Failure ]
crbug.com/dawn/0000 webgpu:api,validation,createBindGroupLayout:multisampled_validation:viewDimension="_undef_" [ Failure ]
crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-32 webgpu-adapter-default win10 ] webgpu:shader,execution,shader_io,compute_builtins:inputs:method="mixed";dispatch="indirect";groupSize={"x":1,"y":1,"z":1};numGroups={"x":1,"y":1,"z":1} [ Failure ]