floooh / sokol-tools

Command line tools for use with sokol headers
MIT License
219 stars 54 forks source link

Sokol-shdc segfaults with glsl:100 because of variable shadowing #95

Closed creikey closed 5 months ago

creikey commented 1 year ago

The shader:

@module threedee

@vs vs
in vec3 pos_in;
in vec2 uv_in;

out vec3 pos;
out vec2 uv;
out vec4 light_space_fragment_position;

uniform vs_params {
    mat4 model;
    mat4 view;
    mat4 projection;
    mat4 directional_light_space_matrix;    
};

void main() {
    pos = pos_in;
    uv = uv_in;

    vec4 frag_pos = view * model * vec4(pos_in, 1.0);
    gl_Position = projection * frag_pos;

    light_space_fragment_position = directional_light_space_matrix * frag_pos;
}
@end

@fs fs
uniform sampler2D tex;
uniform sampler2D shadow_map;

in vec3 pos;
in vec2 uv;
in vec4 light_space_fragment_position;

out vec4 frag_color;

float decodeDepth(vec4 rgba) {
    return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
}

float calculate_shadow_factor(sampler2D shadowMap, vec4 light_space_fragment_position) {
    float shadow = 1.0;

    vec3 projected_coords = light_space_fragment_position.xyz / light_space_fragment_position.w;

    if(projected_coords.z > 1.0)
        return shadow;

    projected_coords = projected_coords * 0.5f + 0.5f;

    float current_depth = projected_coords.z;

    vec2 shadow_map_size = textureSize(shadow_map, 0);
    vec2 uv = projected_coords.xy * shadow_map_size;

    shadow = decodeDepth(texture(shadowMap, uv));

    return shadow;
}

void main() {
    vec4 col = texture(tex, uv);
    if(col.a < 0.5)
    {
        discard;
    }
    else
    {
        vec3 light_dir = normalize(vec3(1, -1, 0));

        float shadow_factor = 1.0;//In percentage of light remaining, i.e. 1.0 full-bright, 0.0 fully shadowed
        shadow_factor = calculate_shadow_factor(shadow_map, light_space_fragment_position);

        frag_color = vec4(col.rgb*shadow_factor, 1.0);
    }
}
@end

@program program vs fs
creikey commented 1 year ago

The issue is in shadowing the uv variable, causing a segfault

floooh commented 1 year ago

I was running into a similar (but unrelated) thing yesterday. The reason is most likely an internal error reported by SPIRVCross, but the error handling in SPIRVCross in release mode and with C++ exceptions disabled just silently aborts (which then looks like a regular crash on most systems I'm aware of - at least it looked like that on macOS).

https://github.com/KhronosGroup/SPIRV-Cross/blob/b8e742c91ba47eb3238c939ee11ec9ba2ba247bf/spirv_cross_error_handling.hpp#L48-L58

TL;DR: I need to find a way to report such internal compiler errors from SPIRVCross - for instance by enabling and then catching exceptions from out of SPIRVCross (at least as first step, the next problem will be that those messages won't be very useful in many cases).

floooh commented 1 year ago

PS: wrote a SPIRCross ticket here, but independently from whether that's fixed or not I'll need to find a workaround.

https://github.com/KhronosGroup/SPIRV-Cross/issues/2177

floooh commented 1 year ago

PS: this was the problem I was running into, also looked like a "silent crash", but was actually a SPIRCross error:

https://github.com/floooh/sokol-tools/issues/94

...and this ticket is similar:

https://github.com/floooh/sokol-tools/issues/86

floooh commented 5 months ago

Once branch storage-buffer is merged, this type of problems (internal SPIRVCross compiler errors) will produce a proper error message. Interestingly I cannot reproduce the problem anymore with your shader though (I just did some small changes for the new separate texture/sampler stuff). Maybe updating the Khronos dependencies helped. Closing this ticket, even though the fix (better error message) isn't in master yet.