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

[wgsl-in] 'unpackUnorm4x8' : no matching overloaded function found #4525

Open
ghost opened this issue Jul 12, 2022 · 10 comments
Open

[wgsl-in] 'unpackUnorm4x8' : no matching overloaded function found #4525

ghost opened this issue Jul 12, 2022 · 10 comments
Labels
area: naga back-end Outputs of naga shader conversion lang: GLSL OpenGL Shading Language naga Shader Translator type: bug Something isn't working

Comments

@ghost
Copy link

ghost commented Jul 12, 2022

Hi!

On wgpu 0.13 (naga 0.9), I receive the following panic message:

panicked at 'wgpu error: Validation Error

Caused by:
    In Device::create_render_pipeline
    Internal error in VERTEX shader: ERROR: 0:52: 'unpackUnorm4x8' : no matching overloaded function found
ERROR: 0:52: '=' : dimension mismatch
ERROR: 0:52: 'assign' : cannot convert from 'const mediump float' to 'highp 4-component vector of float'


'

Here's the offending code:

struct Output {
    @builtin(position)
    pos: vec4<f32>,
    @location(0) @interpolate(flat)
    flags: u32,
    @location(1) @interpolate(perspective, center)
    color: vec4<f32>,
    @location(2) @interpolate(perspective, center)
    tex_pos: vec2<f32>,
    @location(3) @interpolate(flat)
    pal_pos: vec2<u32>,
    @location(4) @interpolate(flat)
    tex_page_x: u32
}

fn make_tex_coord(coord: u32, max: f32) -> f32 {
    return f32(coord) / max;
}

fn make_tex_pos(pos: vec2<u32>, bounds: vec2<f32>) -> vec2<f32> {
    return vec2<f32>(
        make_tex_coord(pos.x, bounds.x),
        make_tex_coord(pos.y, bounds.y),
    );
}

fn make_ndc(coord: u32, max: f32) -> f32 {
    return (2.0 * make_tex_coord(coord, max)) - 1.0;
}

@vertex
fn main(
    @location(0) pos: vec2<u32>,
    @location(1) packed: vec2<u32>,
    @location(2) color: u32,
    @location(3) tex_pos: vec2<u32>,
    @location(4) pal_pos: vec2<u32>,
) -> Output {
    let vram_bounds = vec2<f32>(1024.0, 512.0);

    var out: Output;
    out.pos = vec4<f32>(
        // [0, 1024) -> [-1.0, 1.0].
        make_ndc(pos.x, vram_bounds.x),
        // [0, 512)  -> [-1.0, 1.0].
        make_ndc(pos.y, vram_bounds.y) * -1.0,
        0.0,
        1.0,
    );
    out.flags = packed.x;
    out.color = unpack4x8unorm(color);
    out.tex_pos = vec2<f32>(tex_pos);
    out.pal_pos = pal_pos;
    out.tex_page_x = packed.y;
    return out;
}

...of which line 52 is out.tex_pos = vec2<f32>(tex_pos);. That doesn't seem to be where the error is, though. (One-off bug?) Line 51 reads out.color = unpack4x8unorm(color);, which is where I think the error arises. I think my code is correct according to the spec, though; color is a u32, and out.color is a vec4<f32>, which matches the unpack4x8unorm function signature.

For what it's worth, my shader code was previously validated correctly on wgpu 0.12 (naga 0.8).

@ghost
Copy link
Author

ghost commented Jul 18, 2022

Nevermind about the "one-off" bug. What I think is happening here is that naga is transpiling my code to GLSL, and compiling the resultant GLSL fails. Thus, the error message seems to be from OpenGL—not naga—so the referenced line number is probably correct w.r.t the GLSL code.

To see what's actually happening, I'll try transpiling manually with the naga CLI and inspecting the GLSL output.

@ghost
Copy link
Author

ghost commented Jul 18, 2022

Here's the GLSL output:

#version 310 es

precision highp float;
precision highp int;

struct Output {
    vec4 pos;
    uint flags;
    vec4 color;
    vec2 tex_pos;
    uvec2 pal_pos;
    uint tex_page_x;
};
layout(location = 0) in uvec2 _p2vs_location0;
layout(location = 1) in uvec2 _p2vs_location1;
layout(location = 2) in uint _p2vs_location2;
layout(location = 3) in uvec2 _p2vs_location3;
layout(location = 4) in uvec2 _p2vs_location4;
layout(location = 0) flat out uint _vs2fs_location0;
layout(location = 1) smooth out vec4 _vs2fs_location1;
layout(location = 2) smooth out vec2 _vs2fs_location2;
layout(location = 3) flat out uvec2 _vs2fs_location3;
layout(location = 4) flat out uint _vs2fs_location4;

float make_tex_coord(uint coord, float max) {
    return (float(coord) / max);
}

vec2 make_tex_pos(uvec2 pos_1, vec2 bounds) {
    float _e4 = make_tex_coord(pos_1.x, bounds.x);
    float _e7 = make_tex_coord(pos_1.y, bounds.y);
    return vec2(_e4, _e7);
}

float make_ndc(uint coord_1, float max_1) {
    float _e3 = make_tex_coord(coord_1, max_1);
    return ((2.0 * _e3) - 1.0);
}

void main() {
    uvec2 pos = _p2vs_location0;
    uvec2 packed = _p2vs_location1;
    uint color = _p2vs_location2;
    uvec2 tex_pos = _p2vs_location3;
    uvec2 pal_pos = _p2vs_location4;
    Output out_ = Output(vec4(0.0), 0u, vec4(0.0), vec2(0.0), uvec2(0u), 0u);
    vec2 vram_bounds = vec2(1024.0, 512.0);
    float _e12 = make_ndc(pos.x, vram_bounds.x);
    float _e15 = make_ndc(pos.y, vram_bounds.y);
    out_.pos = vec4(_e12, (_e15 * -1.0), 0.0, 1.0);
    out_.flags = packed.x;
    out_.color = unpackUnorm4x8(color);
    out_.tex_pos = vec2(tex_pos);
    out_.pal_pos = pal_pos;
    out_.tex_page_x = packed.y;
    Output _e30 = out_;
    gl_Position = _e30.pos;
    _vs2fs_location0 = _e30.flags;
    _vs2fs_location1 = _e30.color;
    _vs2fs_location2 = _e30.tex_pos;
    _vs2fs_location3 = _e30.pal_pos;
    _vs2fs_location4 = _e30.tex_page_x;
    gl_Position.yz = vec2(-gl_Position.y, gl_Position.z * 2.0 - gl_Position.w);
    return;
}

Line 52 is out_.color = unpackUnorm4x8(color);.

@JCapucho JCapucho added area: naga back-end Outputs of naga shader conversion lang: GLSL OpenGL Shading Language labels Aug 6, 2022
@JCapucho
Copy link
Collaborator

JCapucho commented Aug 6, 2022

The code looks perfectly fine and glslangValidator agrees, can we get some more information about the platform you're trying to run this in, and can you also test if it happens in others?

@VincentJousse
Copy link
Contributor

Hello,
same problem here, I use wgpu and I target wasm, so WebGL.

@ghost
Copy link
Author

ghost commented Oct 3, 2022

The code looks perfectly fine and glslangValidator agrees, can we get some more information about the platform you're trying to run this in, and can you also test if it happens in others?

Sorry; I forgot to respond. Yes, I also encountered this while targeting WASM. I will look at this later today.

@Wumpf
Copy link
Member

Wumpf commented Oct 22, 2022

Isn't the actual issue here that OpenGL ES 3.0 / WebGL2 flavored GLSL doesn't have unpackUnorm4x8 and friends?
According to this they are introduced in 4.00 whereas, ES3/WebGL2 are based on 3.30
https://registry.khronos.org/OpenGL-Refpages/gl4/html/unpackUnorm.xhtml

(EDITS: Had some misconceptions about shader & webgl version matching)

@bconnorwhite
Copy link

@Wumpf I'm able to use unpack2x16unorm and unpack2x16snorm despite the Kronos page showing them as not in 3.3. Only unpack4x8unorm and unpack4x8snorm give the error

@cwfitzgerald cwfitzgerald transferred this issue from gfx-rs/naga Oct 25, 2023
@teoxoy
Copy link
Member

teoxoy commented Nov 3, 2023

  • packUnorm4x8
  • packSnorm4x8
  • unpackUnorm4x8
  • unpackSnorm4x8

are only available starting with GLSL ES 3.10, so WebGL 2 won't have these.

We should error in this case ourselves to avoid confusion.

Links

https://registry.khronos.org/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf
https://registry.khronos.org/OpenGL/specs/es/3.1/GLSL_ES_Specification_3.10.pdf

@teoxoy teoxoy added type: bug Something isn't working and removed resolution: invalid labels Nov 3, 2023
@cwfitzgerald
Copy link
Member

Shouldn't we polyfill them, these are already some of the ones that we polyfill for hlsl, and they're trivially polyfillable.

@wainwrightmark
Copy link

Just for reference I'm having a similar issue trying to use extractbits

I get the error message 'bitfieldExtract' : no matching overloaded function found when targeting wasm (it works fine otherwise).

I imagine this would be easy to polyfill.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: naga back-end Outputs of naga shader conversion lang: GLSL OpenGL Shading Language naga Shader Translator type: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants