Package: supertuxkart
Version: 0.9.1-2

This affects all intel graphics cards, which have at least OpenGL 3.x, with mesa >= 10.6. The reason of this bug is that with current drivers, the visual is not srgb-capable anymore. Here is more info:
https://github.com/supertuxkart/stk-code/issues/2190
https://bugs.freedesktop.org/show_bug.cgi?id=92759
http://patchwork.freedesktop.org/patch/67844/

It's not fixed in mesa yet, because the fix is not trivial and it causes another issues.

We made a workaround by setting WithAlphaChannel parameter to true, which forces to use proper format on mesa side.

Additionally I hid it inside a graphics restriction to avoid any modifications for other drivers. This is valid only for intel drivers. The radeon/nvidia drivers are not affected by this change.

It also checks if this workaround is really needed. If we already have srgb-capable visual, then we don't do anything.

The commits with this workaround are already applied upstream.

The diff is in attachment.

Regards,
Deve
diff --git a/data/graphical_restrictions.xml b/data/graphical_restrictions.xml
index 16bb607..b2480dc 100644
--- a/data/graphical_restrictions.xml
+++ b/data/graphical_restrictions.xml
@@ -4,6 +4,7 @@
   <card is="Intel(R) HD Graphics 3000" os="windows"                disable="AdvancedPipeline"/>
   <card is="Intel(R) HD Graphics 3000" os="windows"                disable="FramebufferSRGBWorking"/>
   <card contains="Intel"          os="osx"                         disable="GI"/>
+  <card contains="Intel"          os="linux"                       disable="FramebufferSRGBCapable"/>
   <card contains="Intel"                                           disable="TextureCompressionS3TC"/>
   <card contains="Intel"          os="windows"                     disable="HighDefinitionTextures"/>
   <card contains="NVIDIA"         os="windows"  version="<344.65"  disable="BufferStorage"/>
diff --git a/src/graphics/central_settings.cpp b/src/graphics/central_settings.cpp
index 719e7f4..2eace45 100644
--- a/src/graphics/central_settings.cpp
+++ b/src/graphics/central_settings.cpp
@@ -46,10 +46,11 @@ void CentralVideoSettings::init()
     hasTextureCompression = false;
     hasUBO = false;
     hasGS = false;
-    m_GI_has_artifact = false;
 
+    m_GI_has_artifact = false;
     m_need_rh_workaround = false;
     m_need_srgb_workaround = false;
+    m_need_srgb_visual_workaround = false;
 
     // Call to glGetIntegerv should not be made if --no-graphics is used
     if (!ProfileWorld::isNoGraphics())
@@ -179,6 +180,16 @@ void CentralVideoSettings::init()
             // Bindless textures are all treated RGB even sRGB one
             m_need_srgb_workaround = true;
         }
+
+        // Check if visual is sRGB-capable
+        if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_CAPABLE) &&
+            m_glsl == true)
+        {
+            GLint param = GL_SRGB;
+            glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_BACK_LEFT,
+                              GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &param);
+            m_need_srgb_visual_workaround = (param != GL_SRGB);
+        }
     }
 }
 
@@ -207,6 +218,11 @@ bool CentralVideoSettings::needsRGBBindlessWorkaround() const
     return m_need_srgb_workaround;
 }
 
+bool CentralVideoSettings::needsSRGBCapableVisualWorkaround() const
+{
+    return m_need_srgb_visual_workaround;
+}
+
 bool CentralVideoSettings::isARBGeometryShader4Usable() const
 {
     return hasGS;
diff --git a/src/graphics/central_settings.hpp b/src/graphics/central_settings.hpp
index dbde9c6..c9a5bbe 100644
--- a/src/graphics/central_settings.hpp
+++ b/src/graphics/central_settings.hpp
@@ -43,6 +43,7 @@ private:
 
     bool m_need_rh_workaround;
     bool m_need_srgb_workaround;
+    bool m_need_srgb_visual_workaround;
     bool m_GI_has_artifact;
 public:
     void init();
@@ -52,6 +53,7 @@ public:
     // Needs special handle ?
     bool needRHWorkaround() const;
     bool needsRGBBindlessWorkaround() const;
+    bool needsSRGBCapableVisualWorkaround() const;
 
     // Extension is available and safe to use
     bool isARBUniformBufferObjectUsable() const;
diff --git a/src/graphics/graphics_restrictions.cpp b/src/graphics/graphics_restrictions.cpp
index 7d132ea..83c6ded 100644
--- a/src/graphics/graphics_restrictions.cpp
+++ b/src/graphics/graphics_restrictions.cpp
@@ -59,6 +59,7 @@ namespace GraphicsRestrictions
             "HighDefinitionTextures",
             "AdvancedPipeline",
             "FramebufferSRGBWorking",
+            "FramebufferSRGBCapable",
             "GI",
         };
     }   // namespace Private
diff --git a/src/graphics/graphics_restrictions.hpp b/src/graphics/graphics_restrictions.hpp
index ab44ce9..faf5151 100644
--- a/src/graphics/graphics_restrictions.hpp
+++ b/src/graphics/graphics_restrictions.hpp
@@ -53,6 +53,7 @@ namespace GraphicsRestrictions
         GR_HIGHDEFINITION_TEXTURES,
         GR_ADVANCED_PIPELINE,
         GR_FRAMEBUFFER_SRGB_WORKING,
+        GR_FRAMEBUFFER_SRGB_CAPABLE,
         GR_GI,
         GR_COUNT  /** MUST be last entry. */
     } ;
diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp
index e736293..8bbb3c3 100644
--- a/src/graphics/irr_driver.cpp
+++ b/src/graphics/irr_driver.cpp
@@ -344,6 +344,8 @@ void IrrDriver::createListOfVideoModes()
  */
 void IrrDriver::initDevice()
 {
+    SIrrlichtCreationParameters params;
+    
     // If --no-graphics option was used, the null device can still be used.
     if (!ProfileWorld::isNoGraphics())
     {
@@ -426,7 +428,6 @@ void IrrDriver::initDevice()
         m_device->drop();
         m_device  = NULL;
 
-        SIrrlichtCreationParameters params;
         params.ForceLegacyDevice = (UserConfigParams::m_force_legacy_device || 
             UserConfigParams::m_gamepad_visualisation);
 
@@ -505,6 +506,30 @@ void IrrDriver::initDevice()
     {
         Log::fatal("irr_driver", "Couldn't initialise irrlicht device. Quitting.\n");
     }
+    
+    CVS->init();
+                    
+    // This is the ugly hack for intel driver on linux, which doesn't
+    // use sRGB-capable visual, even if we request it. This causes
+    // the screen to be darker than expected. It affects mesa 10.6 and newer. 
+    // Though we are able to force to use the proper format on mesa side by 
+    // setting WithAlphaChannel parameter.
+    if (!ProfileWorld::isNoGraphics() && CVS->needsSRGBCapableVisualWorkaround())
+    {
+        Log::warn("irr_driver", "Created visual is not sRGB-capable. "
+                                "Re-creating device to workaround the issue.");
+        m_device->closeDevice();
+        m_device->drop();
+
+        params.WithAlphaChannel = true;
+        
+        m_device = createDeviceEx(params);
+        
+        if(!m_device)
+        {
+            Log::fatal("irr_driver", "Couldn't initialise irrlicht device. Quitting.\n");
+        }
+    }
 
     m_scene_manager = m_device->getSceneManager();
     m_gui_env       = m_device->getGUIEnvironment();
@@ -513,8 +538,6 @@ void IrrDriver::initDevice()
 
     m_actual_screen_size = m_video_driver->getCurrentRenderTargetSize();
 
-    CVS->init();
-
     m_spherical_harmonics = new SphericalHarmonics(m_scene_manager->getAmbientLight().toSColor());
 
     if (UserConfigParams::m_shadows_resolution != 0 &&

Reply via email to