diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index 7f98eba220..e4b33bdb62 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -999,6 +999,15 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p Log::Notice("%sMissing OpenGL extensions: %s", Color::ToString( Color::Red ), glConfig2.glMissingExtensionsString ); } + if ( glConfig2.halfFloatVertexAvailable ) + { + Log::Notice("%sUsing half-float vertex format.", Color::ToString( Color::Green )); + } + else + { + Log::Notice("%sMissing half-float vertex format.", Color::ToString( Color::Red )); + } + if ( glConfig.hardwareType == glHardwareType_t::GLHW_R300 ) { Log::Notice("%sUsing ATI R300 approximations.", Color::ToString( Color::Red )); diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index 8691d47c4f..f540fad2d5 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -137,10 +137,18 @@ static Cvar::Cvar 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 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", + Cvar::NONE, true ); static Cvar::Cvar workaround_glDriver_mesa_ati_rv600_disableHyperZ( "workaround.glDriver.mesa.ati.rv600.disableHyperZ", "Disable Hyper-Z on Mesa driver on RV600 hardware", Cvar::NONE, true ); +static Cvar::Cvar workaround_glDriver_mesa_broadcom_vc4_useFloatVertex( + "workaround.glDriver.mesa.broadcom.vc4.useFloatVertex", + "Use float vertex instead of supported-but-slower half-float vertex on Mesa driver on Broadcom VC4 hardware", + Cvar::NONE, true ); static Cvar::Cvar workaround_glDriver_mesa_forceS3tc( "workaround.glDriver.mesa.forceS3tc", "Enable S3TC on Mesa even when libtxc-dxtn is not available", @@ -2210,10 +2218,78 @@ static void GLimp_InitExtensions() glConfig2.textureAnisotropy = std::max( std::min( r_ext_texture_filter_anisotropic.Get(), glConfig2.maxTextureAnisotropy ), 1.0f ); } - // VAO and VBO - // made required in OpenGL 3.0 - glConfig2.halfFloatVertexAvailable = LOAD_EXTENSION_WITH_TEST( - ExtFlag_CORE, ARB_half_float_vertex, r_arb_half_float_vertex.Get() ); + /* We call RV300 the first generation of R300 cards, to make a difference + with RV400 and RV500 cards that are also supported by the Mesa r300 driver. + + Mesa r300 implements half-float vertex for the RV300 hardware generation, + but it is likely emulated and it is very slow. We better use float vertex + instead. */ + { + bool halfFloatVertexEnabled = r_arb_half_float_vertex.Get(); + + if ( halfFloatVertexEnabled && glConfig2.driverVendor == glDriverVendor_t::MESA ) + { + if ( glConfig2.hardwareVendor == glHardwareVendor_t::ATI ) + { + bool foundRv300 = false; + + std::string cardName = ""; + + static const std::string codenames[] = { + "R300", "R350", "R360", + "RV350", "RV360", "RV370", "RV380", + }; + + for ( auto& codename : codenames ) + { + cardName = Str::Format( "ATI %s", codename ); + + if ( Str::IsPrefix( cardName, glConfig.renderer_string ) ) + { + foundRv300 = true; + break; + } + } + + /* The RV300 generation only has 64 ALU instructions while RV400 and RV500 + have 512 of them, so we can also use that value to detect RV300. */ + if ( !foundRv300 ) + { + if ( glConfig.hardwareType == glHardwareType_t::GLHW_R300 + && glConfig2.maxAluInstructions == 64 ) + { + cardName = "unknown ATI RV3xx"; + foundRv300 = true; + } + } + + if ( foundRv300 && workaround_glDriver_mesa_ati_rv300_useFloatVertex.Get() ) + { + logger.Notice( "Found slow Mesa half-float vertex implementation with %s hardware, disabling ARB_half_float_vertex.", cardName ); + halfFloatVertexEnabled = false; + } + } + else if ( glConfig2.hardwareVendor == glHardwareVendor_t::BROADCOM ) + { + bool foundVc4 = Str::IsPrefix( "VC4 ", glConfig.renderer_string ); + + if ( foundVc4 && workaround_glDriver_mesa_broadcom_vc4_useFloatVertex.Get() ) + { + logger.Notice( "Found slow Mesa half-float vertex implementation with Broadcom VC4 hardware, disabling ARB_half_float_vertex." ); + halfFloatVertexEnabled = false; + } + } + } + + // VAO and VBO + // made required in OpenGL 3.0 + glConfig2.halfFloatVertexAvailable = LOAD_EXTENSION_WITH_TEST( ExtFlag_CORE, ARB_half_float_vertex, halfFloatVertexEnabled ); + + if ( !halfFloatVertexEnabled ) + { + logger.Notice( "Missing half-float vertex, using float vertex instead." ); + } + } if ( !workaround_glExtension_missingArbFbo_useExtFbo.Get() ) { @@ -2536,7 +2612,9 @@ 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 ); Cvar::Latch( workaround_glDriver_mesa_forceS3tc ); Cvar::Latch( workaround_glDriver_mesa_intel_gma3_forceFragmentShader ); Cvar::Latch( workaround_glDriver_mesa_intel_gma3_stubOcclusionQuery );