Skip to content

Clean up some OpenGL feature detection cruft #1698

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

Merged
merged 3 commits into from
Jul 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions src/engine/renderer/tr_image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -919,18 +919,6 @@ void R_UploadImage( const char *name, const byte **dataArray, int numLayers, int
format = GL_DEPTH_STENCIL;
internalFormat = GL_DEPTH24_STENCIL8;
}
else if ( image->bits & IF_RGBA16 )
{
if ( !glConfig2.textureRGBA16BlendAvailable )
{
Log::Warn("RGBA16 image '%s' cannot be blended", image->name );
internalFormat = GL_RGBA8;
}
else
{
internalFormat = GL_RGBA16;
}
}
else if ( image->bits & ( IF_RGBA16F | IF_RGBA32F | IF_TWOCOMP16F | IF_TWOCOMP32F | IF_ONECOMP16F | IF_ONECOMP32F ) )
{
if( !glConfig2.textureFloatAvailable ) {
Expand Down
32 changes: 6 additions & 26 deletions src/engine/renderer/tr_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,10 +968,8 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p
Log::Notice("Using OpenGL version %d.%d, requested: %d.%d", glConfig2.glMajor, glConfig2.glMinor, glConfig2.glRequestedMajor, glConfig2.glRequestedMinor );
}

if ( glConfig.driverType == glDriverType_t::GLDRV_OPENGL3 )
if ( std::make_pair( glConfig2.glMajor, glConfig2.glMinor ) >= std::make_pair( 3, 2 ) )
{
Log::Notice("%sUsing OpenGL 3.x context.", Color::ToString( Color::Green ) );

/* See https://www.khronos.org/opengl/wiki/OpenGL_Context
for information about core, compatibility and forward context. */

Expand All @@ -983,19 +981,15 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p
{
Log::Notice("%sUsing an OpenGL compatibility profile.", Color::ToString( Color::Red ) );
}
}

if ( glConfig2.glForwardCompatibleContext )
{
Log::Notice("OpenGL 3.x context is forward compatible.");
}
else
{
Log::Notice("OpenGL 3.x context is not forward compatible.");
}
if ( glConfig2.glForwardCompatibleContext )
{
Log::Notice("OpenGL context is forward compatible.");
}
else
{
Log::Notice("%sUsing OpenGL 2.x context.", Color::ToString( Color::Red ) );
Log::Notice("OpenGL context is not forward compatible.");
}

if ( glConfig2.glEnabledExtensionsString.length() != 0 )
Expand Down Expand Up @@ -1047,20 +1041,6 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p
Log::Notice("%sMissing GPU vertex skinning, models are not hardware-accelerated.", Color::ToString( Color::Red ) );
}

switch ( glConfig2.textureRGBA16BlendAvailable )
{
case 1:
Log::Notice( "%sUsing GL_RGBA16 with GL_FRAMEBUFFER_BLEND.", Color::ToString( Color::Green ) );
break;
case -1:
Log::Notice( "%sUsing GL_RGBA16 with GL_FRAMEBUFFER_BLEND (assumed to be available).", Color::ToString( Color::Yellow ) );
break;
default:
case 0:
Log::Notice( "%sMissing GL_RGBA16 with GL_FRAMEBUFFER_BLEND.", Color::ToString( Color::Red ) );
break;
}

if ( glConfig.smpActive )
{
Log::Notice("Using dual processor acceleration." );
Expand Down
1 change: 0 additions & 1 deletion src/engine/renderer/tr_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,6 @@ enum class ssaoMode {
IF_DEPTH32 = BIT( 11 ),
IF_PACKED_DEPTH24_STENCIL8 = BIT( 12 ),
IF_LIGHTMAP = BIT( 13 ),
IF_RGBA16 = BIT( 14 ),
IF_RGBE = BIT( 15 ),
IF_ALPHATEST = BIT( 16 ), // FIXME: this is unused
IF_ALPHA = BIT( 17 ),
Expand Down
2 changes: 0 additions & 2 deletions src/engine/renderer/tr_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,8 @@ struct glconfig2_t
int maxTexIndirections;

bool drawBuffersAvailable;
bool internalFormatQuery2Available;
bool textureHalfFloatAvailable;
bool textureFloatAvailable;
int textureRGBA16BlendAvailable;
bool textureIntegerAvailable;
bool textureRGAvailable;
bool computeShaderAvailable;
Expand Down
15 changes: 4 additions & 11 deletions src/engine/renderer/tr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,20 +251,13 @@ enum class textureCompression_t
TC_EXT_COMP_S3TC
};

// Keep the list in sdl_glimp.c:reportDriverType in sync with this
// TODO(0.56): remove.
enum class glDriverType_t
{
GLDRV_UNKNOWN = -1,
GLDRV_ICD, // driver is integrated with window system
// WARNING: there are tests that check for
// > GLDRV_ICD for minidriverness, so this
// should always be the lowest value in this
// enum set
GLDRV_STANDALONE, // driver is a non-3Dfx standalone driver

// XreaL BEGIN
GLDRV_OPENGL3, // new driver system
// XreaL END
GLDRV_ICD,
GLDRV_STANDALONE,
GLDRV_OPENGL3,
};

// Keep the list in sdl_glimp.c:reportHardwareType in sync with this
Expand Down
158 changes: 21 additions & 137 deletions src/engine/sys/sdl_glimp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ static Cvar::Modified<Cvar::Cvar<bool>> r_noBorder(
static Cvar::Modified<Cvar::Range<Cvar::Cvar<int>>> r_swapInterval(
"r_swapInterval", "enable vsync on every Nth frame, negative for apdative", Cvar::ARCHIVE, 0, -5, 5 );

static Cvar::Cvar<std::string> r_glForceDriver(
"r_glForceDriver", "treat the OpenGL driver type as: 'icd' 'standalone' or 'opengl3'", Cvar::NONE, "");
static Cvar::Cvar<std::string> r_glForceHardware(
"r_glForceHardware", "treat the GPU type as: 'r300' or 'generic'", Cvar::NONE, "");

Expand Down Expand Up @@ -135,10 +133,6 @@ static Cvar::Cvar<bool> workaround_glDriver_amd_oglp_disableBindlessTexture(
"workaround.glDriver.amd.oglp.disableBindlessTexture",
"Disable ARB_bindless_texture on AMD OGLP driver",
Cvar::NONE, true );
static Cvar::Cvar<bool> workaround_glDriver_mesa_ati_rv300_disableRgba16Blend(
"workaround.glDriver.mesa.ati.rv300.disableRgba16Blend",
"Disable misdetected RGBA16 on Mesa driver on RV300 hardware",
Cvar::NONE, true );
static Cvar::Cvar<bool> workaround_glDriver_mesa_ati_rv300_useFloatVertex(
"workaround.glDriver.mesa.ati.rv300.useFloatVertex",
"Use float vertex instead of supported-but-slower half-float vertex on Mesa driver on ATI RV300 hardware",
Expand Down Expand Up @@ -1381,7 +1375,19 @@ static void GLimp_RegisterConfiguration( const glConfiguration& highestConfigura
}
}

if ( requestedConfiguration.profile == glProfile::CORE )
{
int GLmajor, GLminor;
if ( 2 != sscanf( ( const char * ) glGetString( GL_VERSION ), "%d.%d", &GLmajor, &GLminor ) )
{
Sys::Error( "Indecipherable GL_VERSION" );
}

glConfig2.glMajor = GLmajor;
glConfig2.glMinor = GLminor;
}

// CONTEXT_FLAGS and forward compatibility were added in OpenGL 3.0
if ( glConfig2.glMajor >= 3 )
{
// Check if context is forward compatible.
int contextFlags;
Expand All @@ -1391,26 +1397,18 @@ static void GLimp_RegisterConfiguration( const glConfiguration& highestConfigura

if ( glConfig2.glForwardCompatibleContext )
{
logger.Debug( "Provided OpenGL core context is forward compatible." );
logger.Debug( "Provided OpenGL context is forward compatible." );
}
else
{
logger.Debug( "Provided OpenGL core context is not forward compatible." );
logger.Debug( "Provided OpenGL context is not forward compatible." );
}
}
else
{
glConfig2.glForwardCompatibleContext = false;
}

{
int GLmajor, GLminor;
sscanf( ( const char * ) glGetString( GL_VERSION ), "%d.%d", &GLmajor, &GLminor );

glConfig2.glMajor = GLmajor;
glConfig2.glMinor = GLminor;
}

// Get our config strings.
Q_strncpyz( glConfig.vendor_string, ( char * ) glGetString( GL_VENDOR ), sizeof( glConfig.vendor_string ) );
Q_strncpyz( glConfig.renderer_string, ( char * ) glGetString( GL_RENDERER ), sizeof( glConfig.renderer_string ) );
Expand Down Expand Up @@ -1467,17 +1465,6 @@ static rserr_t GLimp_CheckOpenGLVersion( const glConfiguration &requestedConfigu
return rserr_t::RSERR_OLD_GL;
}

if ( glConfig2.glMajor < 3 || ( glConfig2.glMajor == 3 && glConfig2.glMinor < 2 ) )
{
// Shaders are supported, but not all OpenGL 3.x features
logger.Notice("Using GL3 Renderer in OpenGL 2.x mode..." );
}
else
{
logger.Notice("Using GL3 Renderer in OpenGL 3.x mode..." );
glConfig.driverType = glDriverType_t::GLDRV_OPENGL3;
}

return rserr_t::RSERR_OK;
}

Expand Down Expand Up @@ -2108,75 +2095,6 @@ static void GLimp_InitExtensions()
// made required in OpenGL 3.0
glConfig2.textureFloatAvailable = LOAD_EXTENSION_WITH_TEST( ExtFlag_CORE, ARB_texture_float, r_ext_texture_float.Get() );

glConfig2.internalFormatQuery2Available = LOAD_EXTENSION_WITH_TEST( ExtFlag_NONE, ARB_internalformat_query2, r_arb_internalformat_query2.Get() );

if ( glConfig2.internalFormatQuery2Available )
{
GLint64 param;
glGetInternalformati64v( GL_TEXTURE_2D, GL_RGBA16, GL_FRAMEBUFFER_BLEND, 1, &param );

if ( param == GL_FULL_SUPPORT || param == GL_TRUE )
{
/* There is a discrepancy between OpenGL specification and OpenGL reference pages.

The OpenGL 4.3 Core specification says the query should return either GL_FULL_SUPPORT,
GL_CAVEAT_SUPPORT, or GL_NONE:

- https://registry.khronos.org/OpenGL/specs/gl/glspec43.core.pdf#page=517

The ARB_internalformat_query2 document says the same:

- https://registry.khronos.org/OpenGL/extensions/ARB/ARB_internalformat_query2.txt

The OpenGL wiki page for glGetInternalformat says the same:

- https://www.khronos.org/opengl/wiki/GLAPI/glGetInternalformat

But the glGetInternalformat reference page says the query should return GL_TRUE
or GL_FALSE:

- https://registry.khronos.org/OpenGL-Refpages/gl4/html/glGetInternalformat.xhtml

The meaning of GL_CAVEAT_SUPPORT as a return of a GL_FRAMEBUFFER_BLEND query is
unknown. See this thread for details:

- https://github.com/KhronosGroup/OpenGL-Refpages/issues/157

Because of this discrepancy in documentation, drivers may have implemented
either GL_FULL_SUPPORT or GL_TRUE as a return for feature availability. */
glConfig2.textureRGBA16BlendAvailable = 1;
}
else if ( param == GL_CAVEAT_SUPPORT || param == GL_NONE )
{
/* Older Mesa versions were mistakenly reporting full support for every driver on
every hardware. A return that is not GL_FULL_SUPPORT and not GL_TRUE is the only
value we can trust. See those threads for details:

- https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30612
- https://gitlab.freedesktop.org/mesa/mesa/-/issues/11669#note_2521403

GL_FALSE has same value as GL_NONE. */
glConfig2.textureRGBA16BlendAvailable = 0;
}
}
else
{
/* Assume this is an old driver without the query extension but the RGBA16 blending is
available, as the feature is much older than the extension to check for it, the feature
is very likely supported. */
glConfig2.textureRGBA16BlendAvailable = -1;
}

/* Workaround for drivers not implementing the feature query or wrongly reporting the feature
to be supported, for various reasons. */
if ( workaround_glDriver_mesa_ati_rv300_disableRgba16Blend.Get() )
{
if ( glConfig2.textureRGBA16BlendAvailable != 0 && glConfig.hardwareType == glHardwareType_t::GLHW_R300 )
{
glConfig2.textureRGBA16BlendAvailable = 0;
}
}

bool gpuShader4Enabled = r_ext_gpu_shader4.Get();

if ( gpuShader4Enabled
Expand Down Expand Up @@ -2663,19 +2581,6 @@ static const int R_MODE_FALLBACK = 3; // 640 * 480

/* Support code for GLimp_Init */

static void reportDriverType( bool force )
{
static const char *const drivers[] = {
"integrated", "stand-alone", "OpenGL 3+", "Mesa"
};
if (glConfig.driverType > glDriverType_t::GLDRV_UNKNOWN && (unsigned) glConfig.driverType < ARRAY_LEN( drivers ) )
{
logger.Notice("%s graphics driver class '%s'",
force ? "User has forced" : "Detected",
drivers[Util::ordinal(glConfig.driverType)] );
}
}

static void reportHardwareType( bool force )
{
static const char *const hardware[] = {
Expand All @@ -2699,7 +2604,7 @@ of OpenGL
*/
bool GLimp_Init()
{
glConfig.driverType = glDriverType_t::GLDRV_ICD;
glConfig.driverType = glDriverType_t::GLDRV_OPENGL3;

r_sdlDriver = Cvar_Get( "r_sdlDriver", "", CVAR_ROM );
r_allowResize = Cvar_Get( "r_allowResize", "0", CVAR_LATCH );
Expand All @@ -2708,7 +2613,6 @@ bool GLimp_Init()

Cvar::Latch( workaround_glDriver_amd_adrenalin_disableBindlessTexture );
Cvar::Latch( workaround_glDriver_amd_oglp_disableBindlessTexture );
Cvar::Latch( workaround_glDriver_mesa_ati_rv300_disableRgba16Blend );
Cvar::Latch( workaround_glDriver_mesa_ati_rv300_useFloatVertex );
Cvar::Latch( workaround_glDriver_mesa_ati_rv600_disableHyperZ );
Cvar::Latch( workaround_glDriver_mesa_broadcom_vc4_useFloatVertex );
Expand Down Expand Up @@ -2828,10 +2732,11 @@ bool GLimp_Init()

glConfig2.glExtensionsString = std::string();

if ( glConfig.driverType == glDriverType_t::GLDRV_OPENGL3 )
if ( glConfig2.glMajor >= 3 )
{
GLint numExts, i;

// NUM_EXTENSIONS and glGetStringi( GL_EXTENSIONS, i ) were added in OpenGL 3.0
glGetIntegerv( GL_NUM_EXTENSIONS, &numExts );

logger.Debug( "Found %d OpenGL extensions.", numExts );
Expand Down Expand Up @@ -2869,6 +2774,7 @@ bool GLimp_Init()
}
else
{
// glGetString( GL_EXTENSIONS ) was deprecated in OpenGL 3.0
char* extensions_string = ( char * ) glGetString( GL_EXTENSIONS );

if ( extensions_string == nullptr )
Expand All @@ -2889,34 +2795,18 @@ bool GLimp_Init()
}
}

if ( glConfig2.hardwareVendor == glHardwareVendor_t::ATI
&& glConfig.driverType != glDriverType_t::GLDRV_OPENGL3 )
if ( glConfig2.hardwareVendor == glHardwareVendor_t::ATI &&
std::make_pair( glConfig2.glMajor, glConfig2.glMinor ) < std::make_pair( 3, 2 ) )
{
glConfig.hardwareType = glHardwareType_t::GLHW_R300;
}

reportDriverType( false );
reportHardwareType( false );

{ // allow overriding where the user really does know better
Cvar::Latch( r_glForceDriver );
Cvar::Latch( r_glForceHardware );
glDriverType_t driverType = glDriverType_t::GLDRV_UNKNOWN;
glHardwareType_t hardwareType = glHardwareType_t::GLHW_UNKNOWN;

if ( Str::IsIEqual( r_glForceDriver.Get(), "icd" ) )
{
driverType = glDriverType_t::GLDRV_ICD;
}
else if ( Str::IsIEqual( r_glForceDriver.Get(), "standalone" ) )
{
driverType = glDriverType_t::GLDRV_STANDALONE;
}
else if ( Str::IsIEqual( r_glForceDriver.Get(), "opengl3" ) )
{
driverType = glDriverType_t::GLDRV_OPENGL3;
}

if ( Str::IsIEqual( r_glForceHardware.Get(), "generic" ) )
{
hardwareType = glHardwareType_t::GLHW_GENERIC;
Expand All @@ -2926,12 +2816,6 @@ bool GLimp_Init()
hardwareType = glHardwareType_t::GLHW_R300;
}

if ( driverType != glDriverType_t::GLDRV_UNKNOWN )
{
glConfig.driverType = driverType;
reportDriverType( true );
}

if ( hardwareType != glHardwareType_t::GLHW_UNKNOWN )
{
glConfig.hardwareType = hardwareType;
Expand Down