Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to handle shader compilation errors #2130

Closed
Herschel opened this issue Oct 30, 2021 · 9 comments · Fixed by #5410
Closed

Unable to handle shader compilation errors #2130

Herschel opened this issue Oct 30, 2021 · 9 comments · Fixed by #5410
Labels
area: api Issues related to API surface type: enhancement New feature or request

Comments

@Herschel
Copy link
Contributor

wgpu currently has no API to inspect errors when compiling a shader module. On desktop, Device::create_shader_module will panic on error. On web, the different browsers will print out error info to the console, but execution continues, and errors will usually occur later during pipeline creation with the errored ShaderModule objects.

The WebGPU spec requires a GPUShaderModule.compilationInfo() method that should return any errors generated during compilation.

Ideally, either:

  • change Device::create_shader_module to idiomatically return a Result,
  • or match the spec and add a ShaderModule::compilation_info method. The user can then inspect this info and return an error as appropriate.
@kvark
Copy link
Member

kvark commented Oct 30, 2021

create_shader_module follows the same logic as all the other methods that could fail - it triggers the error on the device. The default handler panics, but you can set your own handler -

fn device_on_uncaptured_error(

compilation_info isn't implemented yet, and we definitely need this.

As for Result, we need to land @pythonesque work first and then see.

@kvark kvark added area: api Issues related to API surface type: enhancement New feature or request labels Oct 30, 2021
@Herschel
Copy link
Contributor Author

Thanks for the tip about onUncapturedError! Unfortunately looks like it's a TODO on wgpu web backend.

@michael-brennan2005
Copy link

Sorry if this isn't the right etiquette, but is there any current work being done to implement compilation_info? This is presenting an obstacle to the renderer I'm working on currently.

@Wumpf
Copy link
Member

Wumpf commented Aug 6, 2023

not that I know of no. But there's also some movement on the Naga side on how errors should be handled #4429

@stefnotch
Copy link
Contributor

I would love to take on this issue.

@stefnotch
Copy link
Contributor

stefnotch commented Apr 1, 2024

The PR for this is up at #5410, and am happily awaiting reviews

@nnmm
Copy link

nnmm commented Sep 4, 2024

What I'm using, based on the comments in this thread, is

    // Set up error handling. By using `on_uncaptured_error()`, create_shader_module()
    // will return instead of exiting.
    let shader_err: Arc<Mutex<Option<wgpu::Error>>> = Arc::new(Mutex::new(None));
    {
        let shader_err = Arc::clone(&shader_err);
        device.on_uncaptured_error(Box::new(move |err| {
            *shader_err.lock().unwrap() = Some(err);
        }));
    }
    let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
        label: Some(&shader_path.display().to_string()),
        source: wgpu::ShaderSource::Wgsl(Cow::Owned(shader_src)),
    });
    if let Some(err) = shader_err.lock().unwrap().take() {
        let comp_info = pollster::block_on(shader.get_compilation_info());
        Err(comp_info)
    } else {
        Ok(shader)
    }

This returns a Result<ShaderModule, CompilationInfo>. However, it's obviously not pretty, and I'm not sure how to reset the on_uncaptured_error() callback after I'm done handling the error that I care about.

@teoxoy
Copy link
Member

teoxoy commented Sep 4, 2024

However, it's obviously not pretty, and I'm not sure how to reset the on_uncaptured_error() callback after I'm done handling the error that I care about.

You should use push_error_scope & pop_error_scope.

@nnmm
Copy link

nnmm commented Sep 10, 2024

You should use push_error_scope & pop_error_scope.

I tried that, but it didn't work for me. It does work on the main thread, but not in the thread that calls a notify-rs callback. Edit: Seems related to #5375.

Code

    device.push_error_scope(wgpu::ErrorFilter::Validation);

    let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
        label: Some(&shader_path.display().to_string()),
        source: wgpu::ShaderSource::Wgsl(shader_src.into()),
    });

    if let Some(_) = pollster::block_on(device.pop_error_scope()) {
        let comp_info = pollster::block_on(shader.get_compilation_info());
        return Err(comp_info);
    }

Error message

[2024-09-10T20:16:10Z ERROR wgpu_core::device::global] Device::create_render_pipeline error: Error matching ShaderStages(FRAGMENT) shader requirements against the pipeline
[2024-09-10T20:16:10Z ERROR wgpu::backend::wgpu_core] Handling wgpu errors as fatal by default
thread 'notify-rs inotify loop' panicked at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-22.1.0/src/backend/wgpu_core.rs:3411:5:
wgpu error: Validation Error

Caused by:
  In Device::create_render_pipeline
    Error matching ShaderStages(FRAGMENT) shader requirements against the pipeline
      Unable to find entry point 'fs_main'


note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: api Issues related to API surface type: enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants