Skip to content

Vertex shaders with derivative functions in dead code fail to compile on WebGL #4368

Closed
@johanhelsing

Description

@johanhelsing

Description

If a wgsl shader contains a function with fwidth, dpdx or dpdy in it and that shader file is used as both a vertex and a fragment shader (just with different entry points), the shader fails in validation on WebGL even if the function is not used from the vertex shader.

i.e.

[[stage(vertex)]]
fn vertex(vertex: Vertex) -> VertexOutput {
    var out: VertexOutput;
    out.clip_position = view.view_proj * mesh.model * vec4<f32>(vertex.position, 1.0);
    out.color = vertex.color;
    return out;
}
struct FragmentInput {
    [[location(0)]] color: vec4<f32>;
};
// compiler errors when vertex shader compiles
fn fwidth_wrapper(color: vec3<f32>) -> vec3<f32> {
    return fwidth(color.rgb);
}
[[stage(fragment)]]
fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
    // return vec4<f32>(fwidth(in.color.rgb), in.color.a); // <-- this works
    return vec4<f32>(fwidth_wrapper(in.color.rgb), in.color.a);
}

Repro steps

  1. Install wasm toolchain
  2. Check out https://github.com/johanhelsing/bevy/tree/wasm-fwidth-repro
  3. cargo install wasm-server-runner
  4. CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasm-server-runner cargo run --target wasm32-unknown-unknown --example mesh2d_manual
  5. Open browser link and observe console log output

Expected behavior

I'd expect to see a pretty dark star (with some color on it) in the middle of the browser window.

Observed behavior

No star,

panicked at 'wgpu error: Validation Error

Caused by:
    In Device::create_render_pipeline
    Internal error in VERTEX shader: ERROR: 0:44: 'fwidth' : no matching overloaded function found
ERROR: 0:803: 'fwidth' : no matching overloaded function found

Extra materials

For what it's worth, it works fine on native (cargo run --example mesh2d_manual)

I don't understand the stack that well, but I assume this could be worked around by at some level trying to figure out whether fwidth and friends is called from a function that is unreachable by the entry point and in that case skip it.

Platform

  • WebGL, Firefox 97.0.1 Windows
  • wgpu v0.12.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: naga back-endOutputs of naga shader conversionlang: GLSLOpenGL Shading LanguagenagaShader Translatortype: bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions