If we set at the top of the shader const bool USE_BRANCHLESS_DDA to false, then shader start renders correctly.
So an issue somewhere in those 3 lines, and the only one function which didn't use anywhere else in the code is "lessThanEqual". Maybe this one guilty? I will try to create some simple tests case with
So, on win32 it renders black screen + white lines on it, but on aos4/nova render just white screen and nothing else. Did you see anything obvious which may cause that?
You are pro to find out division by zero things, but not sure if there is one in such a small test case. Maybe issue with abs() ?
@Capehill With your suggestion about uninitialized "inout" fragcolor passed as an argument to the main image() deal with about other 5 bug reports and close them. Thanks!
Now I worry about some more important issue, which may related be to some similar issue we found with ^^ sometime ago, but with other operands.
In both of them they use their own "heavy" hash12() functions. And in both of them if i replace them on more simple versions like in the first bug repot for:
@kas1e You should be able to rule in / out whether the floatBitsToUint etc. are broken by taking almost any shader and then add the following as last line:
Without our bit/float functions, it renders as expected (slow change of colors on screen).
With them, as I post above, the screen is black, and just some green/blue lines fly around :) On win32 of course and original, and with your variant all renders as expected.
So the question is: is it only uintBitsToFloat or floatBitsToUint or both :)
I also check it on some random shader, like this one: https://www.shadertoy.com/view/4sSSzG, and with those, your test-lines added on win32 all still fine, but on os4 all colors broken.
EDIT: and seems the same issues with integer versions (floatBitsToInt and intBitsToFloat). I.e. this example produces the same issue on os4, but not on win32:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
// Output to screen
fragColor = vec4(col,1.0);
{
int n=floatBitsToInt(fragColor.r);
fragColor.r=intBitsToFloat(n);
n=floatBitsToInt(fragColor.g);
fragColor.g=intBitsToFloat(n);
n=floatBitsToInt(fragColor.b);
fragColor.b=intBitsToFloat(n);
}
}
So probably just 4 functions broken (or at least 2)
Tried to comment actual one and uncomment another one: also on win32 green, on nova red :)
ps. And does not matter also what values I uncomment: always red on nova, and always green on win32. Meaning it's even not values that cause issues, just the whole thing broken does not matter what values we convert.
Added all that info to bug-report, probably more than enough for Hans to see an issue.
@Daniel Maybe have an idea what can be wrong in BZ636 and what/where to check else: Capehill made some short example which I reduce today to the very simple one while still producing bug on os4 and works fine on win32, there is:
vec3 hexagon_pattern( vec2 p )
{
vec2 pi = floor(vec2 (p.x,p.y));
return vec3(0,1, floor(pi.x/pi.y) );
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 q = fragCoord/iResolution.xy * 5.0 ;
vec3 col = vec3(hexagon_pattern(q).z); // X and Y also broken ?
fragColor = vec4( col, 1.0 );
}
Capehill found that seems z, x, and y are broken on our side.
That how it looks like on win32:
And that how it looks like on os4:
I suspect it can be floor(). But of course not sure at moment. Maybe you have some idea how to test those things ?:) Thanks!
Edited by kas1e on 2020/12/12 6:12:33 Edited by kas1e on 2020/12/12 6:13:12 Edited by kas1e on 2020/12/12 6:39:32 Edited by kas1e on 2020/12/12 7:59:15 Edited by kas1e on 2020/12/12 8:05:27 Edited by kas1e on 2020/12/12 8:09:07 Edited by kas1e on 2020/12/12 8:21:09 Edited by kas1e on 2020/12/12 8:26:11 Edited by kas1e on 2020/12/12 8:37:16 Edited by kas1e on 2020/12/12 8:42:59
@kas1e As far as I can see the parameters to floor are always non-negative here. Therefore: what happens if you replace every "floor" by "trunc"?
If the output then looks like it should then this is proof that "floor" is broken. If the output is still broken in the same way then this either means that "trunc" is as broken as "floor" or that the problem is elsewhere.
@Daniel "trunc" gives the same issues on our side (while still ok on win32).
Capehill has an idea, that maybe there is division by zero issue in the shader itself: "when q.y (==p.y) is < 1.0 due to floor() but the visual issue seems to be on the upper right corner"
EDIT: well, seems nop. Capehill short the code even more (with division by zero protection) but that didn't help:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = floor(fragCoord/iResolution.xy * 5.0);
vec3 col = vec3(floor(uv.x/max(uv.y, 0.000001)));
fragColor = vec4( col, 1.0 );
}
That one still causes issues on our side. Same with trunc() replacement too.
But if I replace them on fract(), while being a different thing, then still it behave the same on both win32 and os4.
@Capehill, Daniel Any idea of how we need to report that last one? Seems issues happen even with floor replacement, meaning there more general problem.
Maybe something in the functions argument/calling/swaping/etc ?
It is same on my Win10/RadeonHD machine, in other words "broken" or different, than on your Win/Nvidia system. And this is without any obvious undefined behaviour in the code.
Torus works on my RadeonHD/Win box, but not on Nova side. My hexagon example works on my Win box, but not on Nova side. Your example is same on my Win box than on Nova.
@derfs, yep, it's a little bit odd. I would have thought that floor(3.0/3.0) produces 1.0f and not 0.0f. Am I missing something? Here is one more example with extra emphasis:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = floor(fragCoord/iResolution.xy * 5.0);
vec3 col = vec3(floor(uv.x/max(uv.y, 0.001)));
@all as soon as we find a Windows system which produces the same weird / undesired behaviour we should ignore the issue, especially if a Radeon is involved.
@Capehill Yes, I'd also expect floor(3.0/3.0) to result in 1, at least for IEEE 754 floats where X / X should result in 1.0. However, that's only the case if the two numbers are truely identical. In practice you have to deal with intermediate results etc. so what we might think is 3.0/3.0 is just almost 3.0/3.0, so the division may result in sth slightly below 1. And a == comparison doesn't necessarily have the expected outcome with floats neither.
To illustrate this, with a bit of tweaking you can get the expected result (looks identical on my X5000 and my Win10 NVidia setup now )