floooh / sokol

minimal cross-platform standalone C headers
https://floooh.github.io/sokol-html5
zlib License
6.88k stars 486 forks source link

GL_VERTEX_ATTRIBUTE_NOT_FOUND_IN_SHADER: vertex attribute not found in shader (gl) #940

Open pseregiet opened 10 months ago

pseregiet commented 10 months ago

I have this shader

@ctype vec2 HMM_Vec2
@ctype vec3 HMM_Vec3
@ctype vec4 HMM_Vec4
@ctype mat4 HMM_Mat4

@vs vs_particle
in vec2 apos;
in vec2 auv;

in vec4 amodel1;
in vec4 amodel2;
in vec4 amodel3_lmao; //changed the name for testing
in vec4 amodel4;
in vec2 auv_offset;
in float atransparency;

out INTERFACE {
    vec2 uv;
    vec2 uv_offset;
    float trans;
} inter;

uniform vs_particle_slow {
    mat4 uvp;
};

void main() {
    mat4 model = mat4(amodel1, amodel2, amodel3_lmao, amodel4);

    inter.uv = auv;
    inter.uv_offset = auv_offset;
    inter.trans = atransparency;
    gl_Position = uvp * model * vec4(apos, 0.0, 1.0);
}
@end
...

which sokol-shdc turns into this

/*
    #version 330

    uniform vec4 vs_particle_slow[4];
    layout(location = 2) in vec4 amodel1;
    layout(location = 3) in vec4 amodel2;
    layout(location = 4) in vec4 amodel3_lmao;
    layout(location = 5) in vec4 amodel4;
    out INTERFACE
    {
        vec2 uv;
        vec2 uv_offset;
        float trans;
    } inter;

    layout(location = 1) in vec2 auv;
    layout(location = 6) in vec2 auv_offset;
    layout(location = 7) in float atransparency;
    layout(location = 0) in vec2 apos;

    void main()
    {
        inter.uv = auv;
        inter.uv_offset = auv_offset;
        inter.trans = atransparency;
        gl_Position = (mat4(vs_particle_slow[0], vs_particle_slow[1], vs_particle_slow[2], vs_particle_slow[3]) * mat4(amodel1, amodel2, amodel3_lmao, amodel4)) * vec4(apos, 0.0, 1.0);
    }

*/

Clearly the attribute 'amodel3_lmao' is used. I create a pipeline for this shader like this:

void particle_pipeline(pipelines *pipes)
{
    pipes->particle_shd = sg_make_shader(shdparticle_shader_desc(SG_BACKEND_GLCORE33));

    sg_pipeline_desc desc = {0};
    desc.shader = pipes->particle_shd;
    desc.color_count = 1;
    desc.colors[0] = {
        .write_mask = SG_COLORMASK_RGBA,
        .blend = {
            .enabled = true,
            .src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
            .dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
        }
    };
    desc.layout.attrs[ATTR_vs_particle_apos]    = {
        .buffer_index = 0,
        .format = SG_VERTEXFORMAT_USHORT2N,
    };
    desc.layout.attrs[ATTR_vs_particle_auv]    = {
        .buffer_index = 0,
        .format = SG_VERTEXFORMAT_USHORT2N,
    };
    desc.layout.attrs[ATTR_vs_particle_amodel1]    = {
        .buffer_index = 1,
        .format = SG_VERTEXFORMAT_FLOAT4,
    };
    desc.layout.attrs[ATTR_vs_particle_amodel2]    = {
        .buffer_index = 1,
        .format = SG_VERTEXFORMAT_FLOAT4,
    };
    desc.layout.attrs[ATTR_vs_particle_amodel3_lmao]    = {
        .buffer_index = 1,
        .format = SG_VERTEXFORMAT_FLOAT4,
    };
    desc.layout.attrs[ATTR_vs_particle_amodel4]    = {
        .buffer_index = 1,
        .format = SG_VERTEXFORMAT_FLOAT4,
    };
    desc.layout.attrs[ATTR_vs_particle_auv_offset] = {
        .buffer_index = 1,
        .format = SG_VERTEXFORMAT_USHORT2N,
    };
    desc.layout.attrs[ATTR_vs_particle_atransparency] = {
        .buffer_index = 1,
        .format = SG_VERTEXFORMAT_FLOAT,
    };
    desc.layout.buffers[0] = { .step_func = SG_VERTEXSTEP_PER_VERTEX };
    desc.layout.buffers[1] = { .step_func = SG_VERTEXSTEP_PER_INSTANCE };
    desc.depth = {
        .compare = SG_COMPAREFUNC_LESS_EQUAL,
        .write_enabled = false,
    };
    desc.cull_mode = SG_CULLMODE_NONE;
    desc.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP;

    pipes->particle = sg_make_pipeline(&desc);
}

Desprite that I get this error when this pipeline is created:

[sg][error][id:7] ./3rdparty/sokol/sokol_gfx.h:7509:0:
    GL_VERTEX_ATTRIBUTE_NOT_FOUND_IN_SHADER: vertex attribute not found in shader (gl)

[sg][info][id:7] ./3rdparty/sokol/sokol_gfx.h:7510:0:
    amodel3_lmao

EDIT: After some looking around I guess this is not sokol specific issue, but an OpenGL issue. Still if you have any tips for this that would be appreciated. amodel3 is clearly used for creating the mat4 so how can it be optimised ? If i use it for some other random calculation (for example uv *= amodel3.xz) then it stays.

floooh commented 10 months ago

That's indeed weird. The info you posted looks good as far as I can see.

Also, what GPU and driver version do you have?

If i use it for some other random calculation (for example uv *= amodel3.xz) then it stays.

This is also crazy... I had some problems in the past with glslangValidator and or SPIRVCross to strip unused attributes, but I haven't seen this sort of behaviour from GL drivers so far.

If it turns out that GL drivers are allowed to remove "unused" attributes then I guess the sokol_gfx.h GL backend needs to be a bit more flexible (I'm not sure if it is already enough to just turn the error into a warning, theoretically the vertex attribute should then be disabled, and skipped in _sg_gl_apply_bindings(), might be worth a try though)

https://github.com/floooh/sokol/blob/5b6b743ab055361052ad8c67387d51e6d809de02/sokol_gfx.h#L8876-L8923

pseregiet commented 10 months ago

That's indeed weird. The info you posted looks good as far as I can see.

Also, what GPU and driver version do you have?

If i use it for some other random calculation (for example uv *= amodel3.xz) then it stays.

This is also crazy... I had some problems in the past with glslangValidator and or SPIRVCross to strip unused attributes, but I haven't seen this sort of behaviour from GL drivers so far.

If it turns out that GL drivers are allowed to remove "unused" attributes then I guess the sokol_gfx.h GL backend needs to be a bit more flexible (I'm not sure if it is already enough to just turn the error into a warning, theoretically the vertex attribute should then be disabled, and skipped in _sg_gl_apply_bindings(), might be worth a try though)

https://github.com/floooh/sokol/blob/5b6b743ab055361052ad8c67387d51e6d809de02/sokol_gfx.h#L8876-L8923

I'll just add that despite this attribute being apparently optimised out my code still runs fine. If a whole line of a matrix was gone it would surely produce a bogus transformation matrix. RenderDoc's Mesh View shows the attribute is gone: image

pseregiet commented 10 months ago

Oh and my driver is

OpenGL vendor string: AMD
OpenGL renderer string: AMD Radeon RX 590 Series (polaris10, LLVM 16.0.6, DRM 3.54, 6.5.9-zen2-1-zen)
OpenGL core profile version string: 4.6 (Core Profile) Mesa 23.2.1-arch1.2
OpenGL core profile shading language version string: 4.60
Interrupt commented 3 months ago

I just ran into this when compiling a Zig app that loads a mesh but only has a basic shader that does not use the normals or tangents passed in. When I remove those vertex attributes from the layout, the mesh loads and renders fine.

alichraghi commented 2 months ago

it seems like the problem is shdc ignores unused variables (uniform/in/out) so the information never get added into shader descriptor

floooh commented 2 months ago

Unfortunately this stripping of unused uniforms is something that's out of my control. It may happen in the first compile pass from GLSL to SPIRV, and I also had it happen as secondary effect of the SPIRV-Tools dead code elimination (although I disabled all optimizer passes I could find which involve DCE).

Even at runtime, the GLSL compilers in GL drivers are free to remove unused uniforms so that they don't show up in glGetUniformLocation.

pseregiet commented 2 months ago

it seems like the problem is shdc ignores unused variables (uniform/in/out) so the information never get added into shader descriptor

The fact openGL strips unused uniforms or attributes is not strange. What is weird is that if you look at my original code the attributes that was "removed" is clearly used. And at the same time all rendering looks correct as if it was present. The attribute that was removed was part of a matrix, so if it was gone, undefined, filed with random data I would surely have corrupted transformations.