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, ¶m);
+ 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 &&