Tested on Nvidia 750 and Nvidia 960 bug works on both.
Driver version:
Linux 460.56
Windows 461.40
Bug:
Arrays ruined at some point in large code(100+ lines) with unpredictable result.
Only way to fix it is completely remove arrays from GLSL code.
Maybe this is similar to this bug OpenGL3+ out/in mat4 broken on many Nvidia videocards in Vertex shader, shader code included but there I think it Nvidia GLSL compiler bug, when this one maybe not…
Bug does work in SPIR-V shaders compiled by glslang compiler, and OpenGL shaders that compiled by Nvidia driver.
Test bug your self:
Bug result - not Purple color. (Bug is white color, no bug is Purple)
OpenGL test:
if you on Windows then launch Chrome in OpenGL mode
chrome.exe --use-angle=gl
then open this link https://www.shadertoy.com/view/NslGR4
Vulkan bug test:
launch this linked above shadertoy shader in Vulkan in your application
or download my exe with this shader bug_nvidia_arrays.zip
Bug shader code:
(copy from linked shadertoy)
// to test that code correct
//#define is_TRUE true
//#define is_ZER0 0.
#define is_TRUE (iTime > -1.)
#define is_ZER0 min(iTime, 0.)
// self https://www.shadertoy.com/view/NslGR4
// RESULT:
// BUG - white screen color
// NO BUG - purple screen color
// Bug does not work same on every videocard, some part of code can be removed depends of videocard
// length(rd) alway * is_ZER0
// ro unused
// and magic function magic_mat3
// this magic mat3 needed to trigger bug (but can be removed in OpenGL or some GPUs)
mat3 magic_mat3()
{
return mat3(vec3(is_ZER0, is_ZER0, 0.0), vec3(is_ZER0, is_ZER0, 0.0), vec3(1.0));
}
vec4 bug(in vec3 ro, in vec3 rd)
{
vec3 col = vec3(0.);
vec4[3] colx = vec4[3](vec4(0.), vec4(0.), vec4(0.));
int[3] order = int[3](0, 1, 2);
for (int i = 0; i < 3; i++)
{
// removing any of this lines (ro unused in this code) make bug not work (depends of GPU)
if (length(rd) * is_ZER0 > 1.) // this false
{
ro *= magic_mat3();
rd *= magic_mat3();
}
float tnew = 1. + length(rd) * is_ZER0;
{
if (tnew > 0.)
{
vec4 tcol = vec4(0.);
tcol = vec4(0., 1., 0., 1.);
if (tcol.a > 0.0)
{
colx[i] = tcol;
colx[i].rgb = vec3(1., 0., 1.);
}
}
}
}
return vec4(colx[order[0 + int(is_ZER0)]]);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
vec2 uv = fragCoord / iResolution.xy;
vec3 rd = vec3(uv, 1.);
vec3 ro = vec3(1.);
fragColor = vec4(0.);
if (is_TRUE)
{
vec4[2] colo = vec4[2](vec4(0.), vec4(0.));
for (int j = 0; j < 2; j++)
{
{
vec4 tcol = bug(ro, rd);
if (is_TRUE)
{
colo[j] = tcol;
}
}
}
// this does work in OpenGL and Vulkan
vec3 col = colo[0].rgb + colo[1].rgb * is_ZER0;
// in Vulkan it also result bug color, when in OpenGL its not
//vec3 col = colo[0].rgb;
fragColor = vec4(col, 1.);
}
}