Skip to content

Command encoding validation should not emit errors before CommandEncoder::finish #7391

@ErichDonGubler

Description

@ErichDonGubler
Member

Many WebGPU CTS tests exercise validation of command encoders with error scopes used this way:

  1. Set up a device and a command encoder.
  2. Do something invalid during command encoding, like using an occlusion query in a GPURenderPassDescriptor.timestampWrites.
  3. Push an error scope, finish the command encoder, and pop an error scope to check if there was a validation error.

WGPU emits errors for validation during command encoding before calling CommandEncoder::finish, and it shouldn't. It's difficult to cite spec. text that is not present, but the easiest way to summarize is that "generate a validation error" does not show up in the validation steps performed by the various methods of GPUCommandEncoder and {Compute,Render}PassEncoder except for GPUCommandEncoder.finish.

Steps to reproduce

[package]
name = "wgpu-cmd-enc-finish-validation-bruh"
version = "0.1.0"
edition = "2024"

[dependencies]
pollster = "0.4.0"
wgpu = { git = "https://github.com/gfx-rs/wgpu", rev = "1e172b2e1461724eb7ded00b6520732db1c5ae92" }
use pollster::FutureExt as _;

fn main() {
    let instance = wgpu::Instance::new(&Default::default());
    let adapter = instance
        .request_adapter(&Default::default())
        .block_on()
        .unwrap();
    let (device, queue) = adapter
        .request_device(&Default::default())
        .block_on()
        .unwrap();

    let occlusion_query = device.create_query_set(&wgpu::QuerySetDescriptor {
        label: None,
        ty: wgpu::QueryType::Occlusion,
        count: 1,
    });

    let mut command_encoder = device.create_command_encoder(&Default::default());

    {
        let mut _render_pass = command_encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
            timestamp_writes: Some(wgpu::RenderPassTimestampWrites {
                query_set: &occlusion_query,
                beginning_of_pass_write_index: Some(0),
                end_of_pass_write_index: Some(1),
            }),
            ..Default::default()
        });
    }

    device.push_error_scope(wgpu::ErrorFilter::Validation);
    let _cmd_buf = command_encoder.finish();
    device.pop_error_scope().block_on().unwrap();

    queue.submit([_cmd_buf]);
}

Suggested implementation design

  1. The MVP for this is to stop emitting validation errors on CommandEncoder, RenderPassEncoder, and ComputePassEncoder methods. These methods already invalidate the associated CommandEncoder and other objects when failing validation, so no action should be needed there.
  2. The above loses some significant diagnostic quality. We'll probably want to store the first validation error a command encoder encounters, to counter this.

This issue is likely to become a meta issue, since the API surface to which this issue applies is pretty broad.

Activity

removed their assignment
on Apr 7, 2025
teoxoy

teoxoy commented on Apr 14, 2025

@teoxoy
Member

For DestroyedResourceError, we also need to accumulate those and only report them on queue.submit().

sagudev

sagudev commented on Apr 14, 2025

@sagudev
Collaborator

In servo we have hashmap of encoders and their errors:
https://github.com/servo/servo/blob/440739090f85a6d5ba2e26978ad9c77771e7f4af/components/webgpu/wgpu_thread.rs#L102-L105
so we store errors and raise them in finish. It's ugly, but that's what we've been using way before I touched webgpu.

Related bug is #5854.

added
type: bugSomething isn't working
area: validationIssues related to validation, diagnostics, and error handling
on Apr 16, 2025
andyleiserson

andyleiserson commented on Jun 9, 2025

@andyleiserson
Contributor

To give a sense of what I am planning, here is the changelog entry I have drafted for this:

To bring wgpu's error reporting into compliance with the WebGPU specification, the error type returned from some functions has changed, and some errors may be raised at a different time than they were previously.

  • The error type returned by many methods on CommandEncoder, RenderPassEncoder, ComputePassEncoder, and RenderBundleEncoder has changed to EncoderStateError or PassStateError. These functions will return the Ended variant of these errors if called on an encoder that is no longer active. Reporting of all other errors is deferred until a call to finish().
  • Variants holding a CommandEncoderError in the error enums ClearError, ComputePassErrorInner, QueryError, and RenderPassErrorInner have been replaced with variants holding an EncoderStateError.
  • The definition of enum CommandEncoderError has changed significantly, to reflect which errors can be raised CommandEncoder.finish(). There are also some errors that no longer appear directly in CommandEncoderError, and instead appear nested within the RenderPass or ComputePass variants.
  • CopyError has been removed. Errors that were previously a CopyError are now a CommandEncoderError returned by finish(). (The detailed reasons for copies to fail were and still are described by TransferError, which was previously a variant of CopyError, and is now a variant of CommandEncoderError).

4 remaining items

andyleiserson

andyleiserson commented on Jun 10, 2025

@andyleiserson
Contributor

This branch has most of the upcoming error reporting changes (I still need to do render bundles). Note that link has w=1 to suppress whitespace in the diff, which makes it a lot smaller. I don't see a suppress whitespace option in the UI for GitHub's non-PR compare view; I added w=1 to the URL manually.

moved this from Todo to In Progress in WebGPU for Firefoxon Jun 11, 2025
moved this from In Progress to Done in WebGPU for Firefoxon Jun 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area: validationIssues related to validation, diagnostics, and error handlingtype: bugSomething isn't working

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @ErichDonGubler@cwfitzgerald@sagudev@teoxoy@andyleiserson

    Issue actions

      Command encoding validation should not emit errors before `CommandEncoder::finish` · Issue #7391 · gfx-rs/wgpu