From 5878cb35ece00497ba97cbdede63caea8a5a9371 Mon Sep 17 00:00:00 2001 From: vlj Date: Thu, 28 Aug 2014 21:59:55 +0200 Subject: [PATCH] Implement runtime detection of srgb bindless fix --- data/shaders/detailledobject_pass2.frag | 2 ++ data/shaders/grass_pass2.frag | 2 ++ data/shaders/instanced_detailledobject_pass2.frag | 2 ++ data/shaders/instanced_grass_pass2.frag | 2 ++ data/shaders/instanced_object_pass2.frag | 5 ++++- data/shaders/instanced_object_unlit.frag | 2 ++ data/shaders/instanced_objectpass_spheremap.frag | 2 ++ data/shaders/instanced_objectref_pass2.frag | 2 ++ data/shaders/object_pass2.frag | 5 ++++- data/shaders/object_unlit.frag | 2 ++ data/shaders/objectpass_spheremap.frag | 2 ++ data/shaders/objectref_pass2.frag | 2 ++ data/shaders/splatting.frag | 2 ++ src/graphics/glwrap.cpp | 2 ++ src/graphics/irr_driver.cpp | 5 +++++ src/graphics/irr_driver.hpp | 6 ++++++ 16 files changed, 43 insertions(+), 2 deletions(-) diff --git a/data/shaders/detailledobject_pass2.frag b/data/shaders/detailledobject_pass2.frag index 18372dfab..a426b6935 100644 --- a/data/shaders/detailledobject_pass2.frag +++ b/data/shaders/detailledobject_pass2.frag @@ -22,7 +22,9 @@ void main(void) { vec4 color = texture(Albedo, uv); #ifdef GL_ARB_bindless_texture +#ifdef SRGBBindlessFix color.xyz = pow(color.xyz, vec3(2.2)); +#endif #endif vec4 detail = texture(Detail, uv_bis); color *= detail; diff --git a/data/shaders/grass_pass2.frag b/data/shaders/grass_pass2.frag index b8e5e256c..408e78365 100644 --- a/data/shaders/grass_pass2.frag +++ b/data/shaders/grass_pass2.frag @@ -33,7 +33,9 @@ void main(void) vec4 color = texture(Albedo, uv); #ifdef GL_ARB_bindless_texture +#ifdef SRGBBindlessFix color.xyz = pow(color.xyz, vec3(2.2)); +#endif #endif if (color.a < 0.5) discard; vec3 LightFactor = (scattering * 0.3) + getLightFactor(1.); diff --git a/data/shaders/instanced_detailledobject_pass2.frag b/data/shaders/instanced_detailledobject_pass2.frag index 4e06686aa..18ff5aa20 100644 --- a/data/shaders/instanced_detailledobject_pass2.frag +++ b/data/shaders/instanced_detailledobject_pass2.frag @@ -17,7 +17,9 @@ void main(void) { #ifdef GL_ARB_bindless_texture vec4 color = texture(handle, uv); +#ifdef SRGBBindlessFix color.xyz = pow(color.xyz, vec3(2.2)); +#endif vec4 detail = texture(secondhandle, uv_bis); #else vec4 color = texture(Albedo, uv); diff --git a/data/shaders/instanced_grass_pass2.frag b/data/shaders/instanced_grass_pass2.frag index f3134047d..b297a4c88 100644 --- a/data/shaders/instanced_grass_pass2.frag +++ b/data/shaders/instanced_grass_pass2.frag @@ -35,7 +35,9 @@ void main(void) #ifdef GL_ARB_bindless_texture vec4 color = texture(handle, uv); +#ifdef SRGBBindlessFix color.xyz = pow(color.xyz, vec3(2.2)); +#endif #else vec4 color = texture(Albedo, uv); #endif diff --git a/data/shaders/instanced_object_pass2.frag b/data/shaders/instanced_object_pass2.frag index 6cb4296a8..76176ba37 100644 --- a/data/shaders/instanced_object_pass2.frag +++ b/data/shaders/instanced_object_pass2.frag @@ -14,7 +14,10 @@ vec3 getLightFactor(float specMapValue); void main(void) { #ifdef GL_ARB_bindless_texture - vec4 col = pow(texture(handle, uv), vec4(2.2)); + vec4 col = texture(handle, uv); +#ifdef SRGBBindlessFix + col.xyz = pow(col.xyz, vec3(2.2)); +#endif #else vec4 col = texture(Albedo, uv); #endif diff --git a/data/shaders/instanced_object_unlit.frag b/data/shaders/instanced_object_unlit.frag index 8875371fe..4e90c0fc4 100644 --- a/data/shaders/instanced_object_unlit.frag +++ b/data/shaders/instanced_object_unlit.frag @@ -14,7 +14,9 @@ void main(void) { #ifdef GL_ARB_bindless_texture vec4 col = texture(handle, uv); +#ifdef SRGBBindlessFix col.xyz = pow(col.xyz, vec3(2.2)); +#endif #else vec4 col = texture(tex, uv); #endif diff --git a/data/shaders/instanced_objectpass_spheremap.frag b/data/shaders/instanced_objectpass_spheremap.frag index 888e20320..5365dd7ef 100644 --- a/data/shaders/instanced_objectpass_spheremap.frag +++ b/data/shaders/instanced_objectpass_spheremap.frag @@ -23,7 +23,9 @@ void main() { r.y = - r.y; #ifdef GL_ARB_bindless_texture vec4 detail0 = texture(handle, r.xy / m + .5); +#ifdef SRGBBindlessFix detail0.xyz = pow(detail0.xyz, vec3(2.2)); +#endif #else vec4 detail0 = texture(tex, r.xy / m + .5); #endif diff --git a/data/shaders/instanced_objectref_pass2.frag b/data/shaders/instanced_objectref_pass2.frag index 27d1bd03d..201f610a1 100644 --- a/data/shaders/instanced_objectref_pass2.frag +++ b/data/shaders/instanced_objectref_pass2.frag @@ -15,7 +15,9 @@ void main(void) { #ifdef GL_ARB_bindless_texture vec4 col = texture(handle, uv); +#ifdef SRGBBindlessFix col.xyz = pow(col.xyz, vec3(2.2)); +#endif #else vec4 col = texture(Albedo, uv); #endif diff --git a/data/shaders/object_pass2.frag b/data/shaders/object_pass2.frag index f1b2200ad..047f0a192 100644 --- a/data/shaders/object_pass2.frag +++ b/data/shaders/object_pass2.frag @@ -13,7 +13,10 @@ vec3 getLightFactor(float specMapValue); void main(void) { #ifdef GL_ARB_bindless_texture - vec4 col = pow(texture(Albedo, uv), vec4(2.2)); + vec4 col = texture(Albedo, uv); +#ifdef SRGBBindlessFix + col.xyz = pow(col.xyz, vec3(2.2)); +#endif #else vec4 col = texture(Albedo, uv); #endif diff --git a/data/shaders/object_unlit.frag b/data/shaders/object_unlit.frag index f13fc0812..6f38a27be 100644 --- a/data/shaders/object_unlit.frag +++ b/data/shaders/object_unlit.frag @@ -12,7 +12,9 @@ void main(void) { vec4 col = texture(tex, uv); #ifdef GL_ARB_bindless_texture +#ifdef SRGBBindlessFix col.xyz = pow(col.xyz, vec3(2.2)); +#endif #endif col.xyz *= pow(color.xyz, vec3(2.2)); if (col.a < 0.5) discard; diff --git a/data/shaders/objectpass_spheremap.frag b/data/shaders/objectpass_spheremap.frag index 025151184..8e4e0f4fc 100644 --- a/data/shaders/objectpass_spheremap.frag +++ b/data/shaders/objectpass_spheremap.frag @@ -26,7 +26,9 @@ void main() { r.y = - r.y; vec4 detail0 = texture(tex, r.xy / m + .5); #ifdef GL_ARB_bindless_texture +#ifdef SRGBBindlessFix detail0.xyz = pow(detail0.xyz, vec3(2.2)); +#endif #endif vec3 LightFactor = getLightFactor(1.); diff --git a/data/shaders/objectref_pass2.frag b/data/shaders/objectref_pass2.frag index 7ee2d3de0..13ff676f8 100644 --- a/data/shaders/objectref_pass2.frag +++ b/data/shaders/objectref_pass2.frag @@ -14,7 +14,9 @@ void main(void) { vec4 col = texture(Albedo, uv); #ifdef GL_ARB_bindless_texture +#ifdef SRGBBindlessFix col.xyz = pow(col.xyz, vec3(2.2)); +#endif #endif col.xyz *= pow(color.xyz, vec3(2.2)); if (col.a * color.a < 0.5) discard; diff --git a/data/shaders/splatting.frag b/data/shaders/splatting.frag index ccb957cd7..d302908d2 100644 --- a/data/shaders/splatting.frag +++ b/data/shaders/splatting.frag @@ -33,10 +33,12 @@ void main() { vec4 detail3 = texture(tex_detail3, uv); vec4 detail4 = vec4(0.0); #ifdef GL_ARB_bindless_texture +#ifdef SRGBBindlessFix detail0.xyz = pow(detail0.xyz, vec3(2.2)); detail1.xyz = pow(detail1.xyz, vec3(2.2)); detail2.xyz = pow(detail2.xyz, vec3(2.2)); detail3.xyz = pow(detail3.xyz, vec3(2.2)); +#endif #endif vec4 splatted = splatting.r * detail0 + diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index cef2d2b51..15c674841 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -333,6 +333,8 @@ GLuint LoadShader(const char * file, unsigned type) Code += "#define UBO_DISABLED\n"; if (irr_driver->hasVSLayerExtension()) Code += "#define VSLayer\n"; + if (irr_driver->needsRGBBindlessWorkaround()) + Code += "#define SRGBBindlessFix\n"; Code += LoadHeader(); if (Stream.is_open()) { diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index b40d279d5..3e84a703e 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -470,6 +470,7 @@ void IrrDriver::initDevice() m_need_ubo_workaround = false; m_need_rh_workaround = false; + m_need_srgb_workaround = false; #ifdef WIN32 // Fix for Intel Sandy Bridge on Windows which supports GL up to 3.1 only if (strstr((const char *)glGetString(GL_VENDOR), "Intel") != NULL && (GLMajorVersion == 3 && GLMinorVersion == 1)) @@ -478,6 +479,10 @@ void IrrDriver::initDevice() // Fix for Nvidia and instanced RH if (strstr((const char *)glGetString(GL_VENDOR), "NVIDIA") != NULL) m_need_rh_workaround = true; + + // Fix for AMD and bindless sRGB textures + if (strstr((const char *)glGetString(GL_VENDOR), "AMD") != NULL) + m_need_srgb_workaround = true; } m_glsl = (GLMajorVersion > 3 || (GLMajorVersion == 3 && GLMinorVersion >= 1)); diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index dec484903..5dceba6c2 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -202,6 +202,7 @@ private: bool hasBaseInstance; bool m_need_ubo_workaround; bool m_need_rh_workaround; + bool m_need_srgb_workaround; /** The irrlicht device. */ IrrlichtDevice *m_device; /** Irrlicht scene manager. */ @@ -294,6 +295,11 @@ public: return m_need_rh_workaround; } + bool needsRGBBindlessWorkaround() const + { + return m_need_srgb_workaround; + } + bool hasARB_base_instance() const { return hasBaseInstance;