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

Examples won't start #32

Open
global667 opened this issue Jan 21, 2022 · 10 comments
Open

Examples won't start #32

global667 opened this issue Jan 21, 2022 · 10 comments

Comments

@global667
Copy link

Hello,

Get the error

$ cd examples/9_Scene
$ make all
g++ -std=c++17 main.cpp -Wfatal-errors -O -I/usr/local/include -L/usr/local/lib -lTinyEngine -lX11 -lGL -lpthread -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lGLEW -lboost_system -lboost_filesystem -o main
$ ./main
Window could not be created! SDL_Error: Couldn't find matching GLX visual
Failed to launch visual interface.
Adres-eraro(nekropsio elŝutita) = "Segmentation fault" in esperanto

and

$ export SDL_VIDEO_X11_VISUALID=0x179
$ ./main
Adres-eraro(nekropsio elŝutita) = "Segmentation fault" in esperanto

for all examples on Fedora and Win11/WSL/Ubunutu Jammy. It seems something with the gui-system, I use wayland.

Greets and thanks for this program!

@weigert
Copy link
Owner

weigert commented Jan 27, 2022

Hi! Sorry for the alte reply. This is an issue that I have encountered before, and I believe it has to do with your available versions of OpenGL. Have you tried compiling with compatibility mode?

@the-brickster
Copy link

I was running into the seg faults as well on ubuntu with MESA drivers. Switching over to proprietary drivers seemed to made the error go away. I did notice when using the MESA drivers opengl never got initialized while debugging through the code.

@weigert
Copy link
Owner

weigert commented Feb 3, 2022

Hi @the-brickster, do you know which version of the MESA drivers you were using when it wasn't working? This is interesting. Apparently there are frequent problems with driver mismatch issues and I want to locate what versions fail.

@the-brickster
Copy link

Hello @weigert this was the version of MESA drivers I was running:

Extended renderer info (GLX_MESA_query_renderer):
    Vendor: Mesa/X.org (0xffffffff)
    Device: llvmpipe (LLVM 13.0.0, 256 bits) (0xffffffff)
    Version: 21.3.4
    Accelerated: no
    Video memory: 25616MB
    Unified memory: no
    Preferred profile: core (0x1)
    Max core profile version: 4.5
    Max compat profile version: 4.5
    Max GLES1 profile version: 1.1
    Max GLES[23] profile version: 3.2

@clort81
Copy link

clort81 commented Jan 20, 2023

At least on linux + wayland, one thing to compare is output between a run of 0.0_Empty with export SDL_VIDEODRIVER=x11

(gdb) run
Starting program: /media/sd/Projects/TermFun/VoxelSpace/TinyEngine/examples/0.0_Empty/main 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
[Detaching after fork from child process 259202]
Window could not be created! SDL_Error: Couldn't find matching GLX visual
Failed to launch visual interface.

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in  ()
#1  0x0000aaaaaaaac084 in View::target(glm::vec<3, float, (glm::qualifier)0>, bool, bool) ()
#2  0x0000aaaaaaaa7020 in std::_Function_handler<void (), main::{lambda()#3}>::_M_invoke(std::_Any_data const&)
    ()
#3  0x0000aaaaaaaac010 in View::render() ()
#4  0x0000aaaaaaaa8d2c in main ()
(gdb) 

and
SDL_VIDEODRIVER=wayland

(gdb) run
Starting program: /media/sd/Projects/TermFun/VoxelSpace/TinyEngine/examples/0.0_Empty/main 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
[Detaching after fork from child process 259220]
Window could not be created! SDL_Error: Couldn't find matching EGL config (call to eglChooseConfig failed, reporting an error of EGL_SUCCESS)
Failed to launch visual interface.

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in  ()
#1  0x0000aaaaaaaac084 in View::target(glm::vec<3, float, (glm::qualifier)0>, bool, bool) ()
#2  0x0000aaaaaaaa7020 in std::_Function_handler<void (), main::{lambda()#3}>::_M_invoke(std::_Any_data const&)
    ()
#3  0x0000aaaaaaaac010 in View::render() ()
#4  0x0000aaaaaaaa8d2c in main ()
(gdb) 

Looking at include/view.cpp around SDL_CreateWindow
maybe we're missing some SDL_GL_* setup. I see other programs doing stuff like:

SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
SDL_GL_SetAttribute(SDL_GL_CONTEXT_NO_ERROR, 1); // Requires OpenGL 2.0
SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);

I see ArxLibertatis is running with SDL driver x11
[I] SDL2Window:489 Window: X11 r:8 g:8 b:8 a:0 depth:24 aa:4x doublebuffer:1

so let's check out their src/window/SDL2Window.cpp


        arx_assert(!m_displayModes.empty());

        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

        #if ARX_PLATFORM == ARX_PLATFORM_WIN32
        // Used on Windows to prevent software opengl fallback.
        // The linux situation:
        // Causes SDL to require visuals without caveats.
        // On linux some drivers only supply multisample capable GLX Visuals
        // with a GLX_NON_CONFORMANT_VISUAL_EXT caveat.
        // see: https://www.opengl.org/registry/specs/EXT/visual_rating.txt
        SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
        #endif

        bool autoRenderer = (config.video.renderer == "auto");
        
        gldebug::Mode debugMode = gldebug::mode();
        
        int samples = 0;
        for(int api = 0; api < 2 && samples == 0; api++) {
                bool first = (api == 0);
                
                bool matched = false;
                
                if(samples == 0 && first == (autoRenderer || config.video.renderer == "OpenGL")) {
                        matched = true;
                        
                        for(int type = 0; type < ((debugMode == gldebug::Enabled) ? 2 : 1) && samples == 0; type++) {
                                
                                int flags = 0;
                                if(debugMode == gldebug::Enabled && type == 0) {
                                        flags |= SDL_GL_CONTEXT_DEBUG_FLAG;
                                }
                                SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, flags);
                                
                                // TODO core profile are not supported yet
                                #if SDL_VERSION_ATLEAST(2, 0, 6)
                                if(debugMode == gldebug::NoError) {
                                        // Set SDL_GL_CONTEXT_PROFILE_MASK to != 0 so SDL won't ignore SDL_GL_CONTEXT_NO_ERROR
                                        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
                                        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
                                        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
                                        SDL_GL_SetAttribute(SDL_GL_CONTEXT_NO_ERROR, 1); // Requires OpenGL 2.0
                                        samples = createWindowAndGLContext("Desktop OpenGL");
                                }
                                #endif
                                if(samples == 0) {
                                        // Set SDL_GL_CONTEXT_PROFILE_MASK to 0 so SDL will try the legacy glXCreateContext() path
                                        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
                                        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
                                        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5);
                                        #if SDL_VERSION_ATLEAST(2, 0, 6)
                                        SDL_GL_SetAttribute(SDL_GL_CONTEXT_NO_ERROR, 0);
                                        #endif
                                        samples = createWindowAndGLContext("Desktop OpenGL");
                                }
                                
                        }
                        
                }
               
                #if ARX_HAVE_EPOXY
                if(samples == 0 && first == (autoRenderer || config.video.renderer == "OpenGL ES")) {
                        matched = true;
                        
                        for(int type = 0; type < ((debugMode == gldebug::Enabled) ? 2 : 1) && samples == 0; type++) {
                                
                                int flags = 0;
                                if(debugMode == gldebug::Enabled && type == 0) {
                                        flags |= SDL_GL_CONTEXT_DEBUG_FLAG;
                                }
                                SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, flags);
                        
                                // TODO OpenGL ES 2.0+ is not supported yet
                                SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
                                SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
                                SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
                                // SDL_GL_CONTEXT_NO_ERROR requires OpenGL ES 2.0
                                samples = createWindowAndGLContext("OpenGL ES");
                                
                        }
                        
                }
                #endif
                
                if(first && !matched) {
                        LogError << "Unknown renderer: " << config.video.renderer;
                }
        }
        
        if(samples == 0) {
                return false;
        }
        
        // All good
        {
                const char * windowSystem = "(unknown)";
                {
                  ARX_SDL_SysWMinfo info;
                        info.version.major = 2;
                        info.version.minor = 0;
                        info.version.patch = 6;
                        if(SDL_GetWindowWMInfo(m_window, reinterpret_cast<SDL_SysWMinfo *>(&info))) {
                                m_sdlSubsystem = info.subsystem;
                                switch(info.subsystem) {
                                        case ARX_SDL_SYSWM_UNKNOWN:   break;
                                        case ARX_SDL_SYSWM_WINDOWS:   windowSystem = "Windows"; break;
                                        case ARX_SDL_SYSWM_X11:       windowSystem = "X11"; break;
                                        case ARX_SDL_SYSWM_DIRECTFB:  windowSystem = "DirectFB"; break;
                                        case ARX_SDL_SYSWM_COCOA:     windowSystem = "Cocoa"; break;
                                        case ARX_SDL_SYSWM_UIKIT:     windowSystem = "UIKit"; break;
                                        case ARX_SDL_SYSWM_WAYLAND:   windowSystem = "Wayland"; break;
                                        case ARX_SDL_SYSWM_MIR:       windowSystem = "Mir"; break;
                                        case ARX_SDL_SYSWM_WINRT:     windowSystem = "WinRT"; break;
                                        case ARX_SDL_SYSWM_ANDROID:   windowSystem = "Android"; break;
                                        case ARX_SDL_SYSWM_VIVANTE:   windowSystem = "Vivante"; break;
                                        case ARX_SDL_SYSWM_OS2:       windowSystem = "OS2"; break;
                                        default: LogWarning << "Unknown SDL video backend: " << int(info.subsystem);
                                }
                                #if ARX_PLATFORM != ARX_PLATFORM_WIN32 && ARX_PLATFORM != ARX_PLATFORM_MACOS
                                #if ARX_HAVE_EPOXY
                                const char * wrangler = "libepoxy";
                                #else
                                const char * wrangler = "GLEW";
                                #endif
                                switch(info.subsystem) {
                                        case ARX_SDL_SYSWM_X11: {
                                                if(m_sdlVersion < SDL_VERSIONNUM(2, 0, 9)) {
                                                        // Work around a bug causing dbus-daemon memory usage to continually rise while AL is running
                                                        // if the org.gnome.ScreenSaver service does not exist.
                                                        if(m_allowScreensaver != AlwaysDisabled && m_allowScreensaver != AlwaysEnabled) {
                                                                SDL_EnableScreenSaver();
                                                                m_allowScreensaver = AlwaysEnabled;
                                                        }                                                                                                                                              
                                                }
                                                #if ARX_HAVE_GL_STATIC || !ARX_HAVE_DLSYM || !defined(RTLD_DEFAULT)
                                                const bool haveGLX = ARX_HAVE_GLX;
                                                #elif ARX_HAVE_EPOXY
                                                const bool haveGLX = (dlsym(RTLD_DEFAULT, "epoxy_has_glx") != NULL);
                                                #else
                                                const bool haveGLX = (dlsym(RTLD_DEFAULT, "glxewInit") != NULL);
                                                #endif
                                                if(!haveGLX) {
                                                        LogWarning << "SDL is using the X11 video backend but " << wrangler
                                                                   << " was built without GLX support";
                                                        LogWarning << "Try setting the SDL_VIDEODRIVER=wayland environment variable";
                                                }
                                                break;
                                        }
                                        case ARX_SDL_SYSWM_WAYLAND:
                                        case ARX_SDL_SYSWM_MIR: {
                                                #if ARX_HAVE_GL_STATIC || !ARX_HAVE_DLSYM || !defined(RTLD_DEFAULT)
                                                const bool haveEGL = ARX_HAVE_EGL;
                                                #elif ARX_HAVE_EPOXY
                                                const bool haveEGL = (dlsym(RTLD_DEFAULT, "epoxy_has_egl") != NULL);
                                                #else
                                                const bool haveEGL = (dlsym(RTLD_DEFAULT, "eglewInit") != NULL);
                                                #endif
                                                if(!haveEGL) {
                                                        LogWarning << "SDL is using the " << windowSystem << " video backend but " << wrangler
                                                                   << " was built without EGL support";
                                                        LogWarning << "Try setting the SDL_VIDEODRIVER=x11 environment variable";
                                                }
                                                break;
                                        }
                                        default: break;
                                }
                                #endif
                        }
                }
                
                int red = 0, green = 0, blue = 0, alpha = 0, depth = 0, doublebuffer = 0;
                SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &red);
                SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &green);
                SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blue);
                SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alpha);
                SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth);
                SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &doublebuffer);
                LogInfo << "Window: " << windowSystem << " r:" << red << " g:" << green << " b:" << blue
                        << " a:" << alpha << " depth:" << depth << " aa:" << samples << "x"
                        << " doublebuffer:" << doublebuffer;
        }
        // Use the executable icon for the window
        u64 nativeWindow = 0;
        #if ARX_PLATFORM == ARX_PLATFORM_WIN32
        if(!nativeWindow) {
                SDL_SysWMinfo info;
                SDL_VERSION(&info.version);
                if(SDL_GetWindowWMInfo(m_window, &info) && info.subsystem == SDL_SYSWM_WINDOWS) {
                        nativeWindow = u64(info.info.win.window);
                        platform::WideString filename;
                        filename.allocate(filename.capacity());
                        while(true) {
                                DWORD size = GetModuleFileNameW(NULL, filename.data(), filename.size());
                                if(size < filename.size()) {
                                        filename.resize(size);
                                        break;
                                }
                                filename.allocate(filename.size() * 2);
                        }
                        HICON largeIcon = 0;
                        HICON smallIcon = 0;
                        ExtractIconExW(filename, 0, &largeIcon, &smallIcon, 1);
                        if(smallIcon) {
                                SendMessage(info.info.win.window, WM_SETICON, ICON_SMALL, LPARAM(smallIcon));
                        }
                        if(largeIcon) {
                                SendMessage(info.info.win.window, WM_SETICON, ICON_BIG, LPARAM(largeIcon));
                        }
                }
        }
        #endif
        #if ARX_HAVE_SDL2_X11
        if(!nativeWindow) {
                nativeWindow = SDL2X11_getNativeWindowHandle(m_window);
        }
        #endif
        CrashHandler::setWindow(nativeWindow);
        
        setVSync(m_vsync);
        
        SDL_ShowWindow(m_window);
        SDL_ShowCursor(SDL_DISABLE);
        
        setGamma(m_gamma);
        
        m_renderer->initialize();
        
        onCreate();
        onToggleFullscreen(m_fullscreen);
        updateSize(true);
        
        onShow(true);
        onFocus(true);
        
        return true;
}

That's a lot of stuff to learn and digest, beyond my time allocatable atm.

@clort81
Copy link

clort81 commented Jan 20, 2023

Had a bit more time and made a simple SDL2 opengl window without error:

include <iostream>

#include <SDL2/SDL.h>


void sdl_exception(std::string operation) {
    std::cout << operation << ": " << SDL_GetError() << std::endl;
    std::exit(1);
}

int main() {
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        sdl_exception("SDL_Init");
    }

    auto window = SDL_CreateWindow(
            "Simple",
            SDL_WINDOWPOS_UNDEFINED,
            SDL_WINDOWPOS_UNDEFINED,
            1366,
            768,
            SDL_WINDOW_OPENGL  | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE                                                            
    );
    if (window == nullptr) {
        sdl_exception("SDL_CreateWindow");
    }

    auto renderer = SDL_CreateRenderer(
            window,
            -1,
            SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
    );
    if (renderer == nullptr) {
        sdl_exception("SDL_CreateRenderer");
    }

    auto running = true;

    while (running) {
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_KEYDOWN and event.key.keysym.sym == SDLK_ESCAPE) {
                running = false;
            }
        }
        if (SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0) < 0) {
            sdl_exception("SDL_SetRenderDrawColor");
        }
        if (SDL_RenderClear(renderer) < 0) {
            sdl_exception("SDL_RenderClear");
        }
        SDL_RenderPresent(renderer);
    }

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

@clort81
Copy link

clort81 commented Jan 20, 2023

i don't see where SDL_Init() is being called, come to think of it. Very confused now.

@ghost
Copy link

ghost commented Mar 3, 2023

It's a shame that we can't use this awesome library, any fixes 2 months later?
I believe it has something to do with the View class and ImGUI.

@weigert
Copy link
Owner

weigert commented Mar 8, 2023

Hi guys!

I am really sorry for the late reply and that you can't run TinyEngine.

It's really difficult for me to debug this because it appears to be an issue only on specific hardware.

I can break-down the initialization procedure for you if you like @clort81

Note in TinyEngine.h, that calling Tiny::window launches SDL and finally calls view::init. Note that this creates an SDL_GL_Context, and not a renderer. I believe that this is where the hardware differences appear.

All of the "SDL_GL" setup stuff you mentioned before, I also do appropriately.

The stack trace you posted above that gets caught in view::target appears to give a segfault because it failed to initialize the OpenGL context and that is usually the first function call which attempts to actively alter OpenGL context state.

So it still appears to be a driver issue. The best thing would be for you to post your mesa driver version, cpu / gpu version / general hardware specs, so we can try to see if there is a pattern.

And just as an absolute sanity check, make sure SDL and all that good stuff is up to date.

Maybe if I get GitHub actions set up, we can guarantee builds for different architectures.

@ghost
Copy link

ghost commented Mar 8, 2023

Here's the output of glxinfo:
glxinfo-out.txt
Running on Debian Bullseye.
@weigert It feels like it's more of a system compatability issue more than a hardware issue. It's been tested on MacOS, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants