简体   繁体   中英

SFML 2.5.1 - Geometry shaders are not supported, Ubuntu 22.04, NVIDIA GeForce RTX Mobile

After changing the operating system, I could no longer use the SFML geometry shader and always got the following error:

Failed to create a shader: your system doesn't support geometry shaders 
(you should test Shader::isGeometryAvailable() before trying to use geometry shader

Oddly enough, the isAvailable() function, which checks if the system supports shaders at all, returned true and got me thinking that my system really doesn't support geometry shaders.

Although I knew that my system supports this kind of shaders. To prove this, one can type the command glxinfo and search for some kind of geometry shader. If the command is not recognized, you can install it with:

$ sudo apt-get install mesa-utils

Finally, when I grep the information for something like "geometry", I get the following output.

$ glxinfo | grep geometry
GL_EXT_float_blend, GL_EXT_frag_depth, GL_EXT_geometry_point_size, 
GL_EXT_geometry_shader, GL_EXT_gpu_shader5, GL_EXT_map_buffer_range, 
GL_OES_geometry_point_size, GL_OES_geometry_shader,

Here you can see that the geometry shader is indeed supported by my system and there is no driver error or something not installed, as my Ubuntu drivers are already all up to date:

$ ubuntu-drivers autoinstall
All the available drivers are already installed.

So it must indeed be an SFML 2.5.1 problem, since other people such as. @mabel have stumbled over this problem.

The final workaround I found out was indeed a bug or rather an upward compatibility issue with SFML 2.5.1. As stated above glxinfo only returned the geometry shader GL_EXT_gpu_shader5 .

The version is importatnt then since in the SFML Shader Code in the file located in src/SFML/Graphics/Shader.cpp it can be observed the follwogin code snippet:

bool Shader::isGeometryAvailable()
{
    std::lock_guard lock(isAvailableMutex);

    static bool checked   = false;
    static bool available = false;

    if (!checked)
    {
        checked = true;

        TransientContextLock contextLock;

        // Make sure that extensions are initialized
        sf::priv::ensureExtensionsInit();

        available = isAvailable() && (GLEXT_geometry_shader4 || GLEXT_GL_VERSION_3_2);
    }

    return available;
}

Here you can clearly see that only the macro of GLEXT_geometry_shader4 and GLEXT_GL_VERSION_3_2 is checked. Therefore, the geometry shader version I used is not checked at all and the function eventually returns false , leading to the exit of the program in the following code snippet:

// Make sure we can use geometry shaders
if (geometryShaderCode && !isGeometryAvailable())
{
  err() << "Failed to create a shader: your system doesn't support geometry shaders "
        << "(you should test Shader::isGeometryAvailable() before trying to use geometry shaders)" << std::endl;
  return false;
}

Finally I removed the last part of the line wich checks if the geometry shader is available, resulting in:

available = isAvailable();

Attention! This is just a workaround I just found and want to share with you. It's not an unversal solution and can get you into trouble if your system really doesn't support geometry shaders.

After changing this line of code, I recreated SFML for myself using CMake. So the very normal procedure:

$ cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Release
$ cmake --build build/
$ sudo cmake --install build/

Then it was finally possible to link the SFML libraries to my executable without getting the mentioned error. For further use, this should be an update to make systems using only GL_EXT_gpu_shader5 compatible with SFML.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM