This content has been marked as final. Show 9 replies
awesome find! We're on it!
This might be caused by the normalize(v2 - v1) in f2. normalize doesn't like zero length vectors as input. Maybe it helps if you try to check for a length of zero before calling it.
I'll try that when I'm next on that computer, but if I understand things rightly that difference should never be zero: in f1(), v1.z != 0 and v2 = -2. * v1 + v1, so v2 should equal -v1, neither of them should be zero length because v1.z is nonzero, and normalize(v2 - v1) should be the same as normalize(-2 * v1).
Of course actually changing any of those totally alters the result on that system, so maybe it does have to do with the normalize and some kind of floating point inaccuracy or something resulting in zero. I don't have experience with shaders. I'm thinking it has to do with the length of the whole compiled kernel, though, because when I removed a few of the calls to f1(v) everything would work fine.
I think I did manage to get my original kernel working by changing repeated calls of a function into one call inside of a for loop.
One thing to point out is that behaviour of division by zero is undefined in GLSL and will vary from driver to driver and card to card.
The 1600x has a pretty high instruction count. I don't think your filter above would be too long. I'll see if I can take a look on a similar system.
Adding "if (v2 != v1)" prior to the normalize changes the output significantly but does not alter the corruption (blocks of color that jump around as I drag the view).
I wasn't sure checking for v2 != v1 would ensure that v2 - v1 != 0., so I tried "if (v2 - v1 != 0.)" and "v2 = v2 - v1; if (v2 != 0.)" -- either of these causes a popup, "Error! This kernel is too complex for your graphics card". The kernel will not render in this case.
"if (length(v2 - v1) != 0.)" runs fine, along with a few other permutations using length() to check for zero, but the corruption is still present. If I do "v2 = v2 - v1; if (length(v2) != 0.) v2 /= length(v2);" instead of "normalize(v2 - v1);", then AIF Toolkit crashes to the desktop.
If I remove the call to normalize all together, the corruption goes away. The same seems true for any other individual function call.
To me this seems related to the complexity of the kernel, and it is not a big problem, only affecting one machine I've used. I have just been trying to report crashes and inconsistencies in the hopes they may be gone in a later version, but perhaps that is more useful when the product is more mature.
I also noticed the behavior of a number of functions is different on the GPU than on the CPU, e.g. mod of negative numbers and atan.
Edit: Details on this card from System Profiler attached
Could you send me (privately if you want) the kernel you are working with, so we can try to reproduce/fix the crash on our side?
The kernel code attached to my first post in this thread causes this image corruption, on OSX 10.5.2 with the card mentioned. Among many other potential modifications, I experienced a crash when I replaced in f2():
normalize(v2 - v1);
v2 = v2 - v1; if (length(v2) != 0.) v2 /= length(v2);
in the kernel code in the first post in this thread. These problems only occurred on that system.
Attached is the original kernel I was developing when I found this. I don't recall for sure, and don't have access to the machine in question again, but I believe this code experienced the image corruption in the reflection of the sphere when antialiasing was done by repeatedly calling trace in the comments at the bottom of the kernel, rather than using a for loop. I think I have changed how antialiasing works since then, so uncommenting those may not work.
I'm afraid my home computer runs linux, so I do not often have chance to use AIF toolkit, and cannot get this kernel into a state to reproduce the error right now. Really, though, the kernel I posted in the first post in this thread demonstrates the problem much better than this attached kernel did.
zazzo9, you genius!
that filter is freaking awesome zazzo9! You should post it on the exchange