Browse Source

workaround for nvidia shader compiler bug on very old windows drivers.

Sasha Szpakowski 1 year ago
parent
commit
36fa78f392

+ 5 - 0
src/modules/graphics/Graphics.h

@@ -905,6 +905,9 @@ public:
 		return (T *) scratchBuffer.data();
 		return (T *) scratchBuffer.data();
 	}
 	}
 
 
+	// Workaround for some very old nvidia drivers that aren't compliant with the GLSL 3.30 spec.
+	bool isUsingNoTextureCubeShadowBiasHack() const { return usingNoTextureCubeShadowBiasHack; }
+
 	static Graphics *createInstance();
 	static Graphics *createInstance();
 
 
 	STRINGMAP_CLASS_DECLARE(DrawMode);
 	STRINGMAP_CLASS_DECLARE(DrawMode);
@@ -1086,6 +1089,8 @@ protected:
 
 
 	Deprecations deprecations;
 	Deprecations deprecations;
 
 
+	bool usingNoTextureCubeShadowBiasHack = false;
+
 	static const size_t MAX_USER_STACK_DEPTH = 128;
 	static const size_t MAX_USER_STACK_DEPTH = 128;
 	static const int MAX_TEMPORARY_RESOURCE_UNUSED_FRAMES = 16;
 	static const int MAX_TEMPORARY_RESOURCE_UNUSED_FRAMES = 16;
 
 

+ 5 - 0
src/modules/graphics/Shader.cpp

@@ -143,8 +143,10 @@ float Texel(sampler2DArrayShadow s, highp vec4 c) { return texture(s, c); }
 	uvec4 Texel(usampler2DArray s, highp vec3 c, float b) { return texture(s, c, b); }
 	uvec4 Texel(usampler2DArray s, highp vec3 c, float b) { return texture(s, c, b); }
 
 
 	float Texel(sampler2DShadow s, highp vec3 c, float b) { return texture(s, c, b); }
 	float Texel(sampler2DShadow s, highp vec3 c, float b) { return texture(s, c, b); }
+#ifndef LOVE_NO_TEXTURECUBESHADOWBIAS_HACK
 	float Texel(samplerCubeShadow s, highp vec4 c, float b) { return texture(s, c, b); }
 	float Texel(samplerCubeShadow s, highp vec4 c, float b) { return texture(s, c, b); }
 #endif
 #endif
+#endif
 
 
 uniform mediump float deprecatedTextureCall;
 uniform mediump float deprecatedTextureCall;
 
 
@@ -613,6 +615,9 @@ std::string Shader::createShaderStageCode(Graphics *gfx, ShaderStageType stage,
 	if (info.usesMRT)
 	if (info.usesMRT)
 		ss << "#define LOVE_MULTI_RENDER_TARGETS 1\n";
 		ss << "#define LOVE_MULTI_RENDER_TARGETS 1\n";
 
 
+	if (gfx->isUsingNoTextureCubeShadowBiasHack())
+		ss << "#define LOVE_NO_TEXTURECUBESHADOWBIAS_HACK 1\n";
+
 	for (const auto &def : options.defines)
 	for (const auto &def : options.defines)
 		ss << "#define " + def.first + " " + def.second + "\n";
 		ss << "#define " + def.first + " " + def.second + "\n";
 
 

+ 19 - 1
src/modules/graphics/opengl/Graphics.cpp

@@ -383,7 +383,25 @@ bool Graphics::setMode(void */*context*/, int width, int height, int pixelwidth,
 			Shader::CompileOptions opts;
 			Shader::CompileOptions opts;
 			stages.push_back(Shader::getDefaultCode(stype, SHADERSTAGE_VERTEX));
 			stages.push_back(Shader::getDefaultCode(stype, SHADERSTAGE_VERTEX));
 			stages.push_back(Shader::getDefaultCode(stype, SHADERSTAGE_PIXEL));
 			stages.push_back(Shader::getDefaultCode(stype, SHADERSTAGE_PIXEL));
-			Shader::standardShaders[i] = newShader(stages, opts);
+
+			try
+			{
+				Shader::standardShaders[i] = newShader(stages, opts);
+			}
+			catch (love::Exception &)
+			{
+				// Attempted workaround for nvidia driver bug affecting old GPUs
+				// on Windows (e.g. the 300 series).
+				if (!isUsingNoTextureCubeShadowBiasHack())
+				{
+					usingNoTextureCubeShadowBiasHack = true;
+					Shader::standardShaders[i] = newShader(stages, opts);
+				}
+				else
+				{
+					throw;
+				}
+			}
 		}
 		}
 	}
 	}