Skip to content

SDL software renderer fails with Floating Point Exception #56

@bunnylin

Description

@bunnylin

This is mostly for visibility - I'm not sure where this would be best fixed.

It seems any SDL application compiled with Pascal will crash if trying to use software renderer video output, on Linux. To verify, run any SDL application with the environment variable LIBGL_ALWAYS_SOFTWARE=1 set. The failure happens either immediately on SDL_InitSubSystem(SDL_INIT_VIDEO), or when calling SDL_CreateRenderer. The error that appears can be EInvalidOp: Invalid floating point operation or EDivByZero: Division by zero depending on environment.

Doing this through GDB, I got this callstack pointing at the LLVMpipe software rasterizer:

lp_build_tgsi_info () from /usr/lib64/dri/swrast_dri.so
llvmpipe_create_fs_state () from /usr/lib64/dri/swrast_dri.so
ureg_create_shader () from /usr/lib64/dri/swrast_dri.so
util_make_fragment_tex_shader_writemask () from /usr/lib64/dri/swrast_dri.so
util_make_fragment_tex_shader () from /usr/lib64/dri/swrast_dri.so
blitter_get_fs_texfetch_col () from /usr/lib64/dri/swrast_dri.so
util_blitter_cache_all_shaders () from /usr/lib64/dri/swrast_dri.so
llvmpipe_create_context () from /usr/lib64/dri/swrast_dri.so
st_api_create_context () from /usr/lib64/dri/swrast_dri.so
dri_create_context () from /usr/lib64/dri/swrast_dri.so
driCreateContextAttribs () from /usr/lib64/dri/swrast_dri.so
drisw_create_context_attribs () from /lib64/libGLX_mesa.so.0
dri_common_create_context () from /lib64/libGLX_mesa.so.0
CreateContext () from /lib64/libGLX_mesa.so.0
glXCreateContext () from /lib64/libGLX_mesa.so.0
glXCreateContext () from /lib64/libGLX.so.0
X11_GL_LoadLibrary.part.0 () from /lib64/libSDL2-2.0.so.0

So it's a problem in Mesa. This doesn't affect Pascal/SDL programs on Windows since users don't normally run Mesa there. An internet search turned up this bug: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3096

They say the FPE should normally not be enabled in the first place, and the caller should just disable the exception mode. A commenter notes that the affected software was made with Delphi, which suggests to me that Free Pascal and Delphi are both deliberately keeping this FPE enabled (and are unlikely to change that because it would break compatibility).

As a workaround, it's simple to disable the exception by applying a mask, via the Math unit:

uses Math, SDL2;
var m : TFPUExceptionMask;
        window : PSDL_Window;
        renderer : PSDL_Renderer;
begin
        m := GetExceptionMask;
        include(m, exInvalidOp);
        SetExceptionMask(m); // <-- comment out this and it breaks again

        writeln(SDL_InitSubSystem(SDL_INIT_VIDEO));
        window := SDL_CreateWindow(NIL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                640, 400, SDL_WINDOW_SHOWN);
        if window = NIL then writeln('failed to create window: ' + SDL_GetError);
        renderer := SDL_CreateRenderer(window, -1, 0);
        if renderer = NIL then writeln('failed to get renderer: ' + SDL_GetError);
        writeln('no crash, all ok!');
end.

Metadata

Metadata

Assignees

No one assigned

    Labels

    waiting 3rd partyWaiting for other project to fix something

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions