PDA

View Full Version : Inconsistent negated if-statement outcome



_x57_
08-25-2014, 02:58 PM
Hi all,

i do some computations in a fragment shader (GPGPU stuff, i spare you the details) where i accumulate some values in the floating point framebuffer like accum=accum+delta and now i want to check in the FS wether delta is large enough to actually change accum and thereby accum != accum+delta. I put up an if statement for the test and it didn't work out. So i put up a negated if statement inside the first one to double-check what was happening and both seem to hold true - which can't be. (or maybe i am too tired to see the obvious)

Anyway, please have look at:


#version 420 compatibility
#pragma optimize(off) //testing, doesn't help
...
flat in vec4 VSresult;
out vec4 result;
uniform sampler2D loopIn_result;
...
vec4 accum = texture2D(loopIn_result, gl_FragCoord.xy/bufSize); //get old accumulated value
float testMachineEpsilon = accum.r+VSresult.b; // if this now equals accum.r again, then VSresult.b is too small to make a difference

if (((accum.r - testMachineEpsilon) != 0.0f) && (VSresult.r != 0.0f) && (VSresult.b > 0.0f)) // ensure the "delta" VSresult.b makes a difference
{

if ((accum.r - testMachineEpsilon) == 0.0f ) // if it makes no difference...
{
result.r = 5000; // indicate fail
} else {
result.r = 1; //ensure output written in any case
}

} else {
result.r = 1; //ensure output written in any case
}
...


As you might have guessed from my question, the outcome is 5000 all the time, indicating that (accum.r - testMachineEpsilon) equals and does not equal 0 at the same time. Why is that?



Also note, that it seems to work if i drop the second and third term in the outer if statement and just state

if (((accum.r - testMachineEpsilon) != 0.0f))

or - alternatively - it also works when i precompute


precise float test = (accum.r+VSresult.b) - accum.r;

before each if statement and then just compare test!=0 or test==0.

It seems the subtraction together with the logical &&'s in the first statement don't work.

Dark Photon
08-25-2014, 04:07 PM
I would buzz out your component values with isnan() and isinf(), just to make sure we don't have any funny business going on.

Could be a driver bug.

Also, typically when you want to fetch an image value using gl_FragCoord.xy (without interpolation) you'd use texelFetch( tex, ivec2( gl_FragCoord.xy )[, sample] )

_x57_
08-26-2014, 03:57 AM
I would buzz out your component values with isnan() and isinf(), just to make sure we don't have any funny business going on.

Could be a driver bug.

Also, typically when you want to fetch an image value using gl_FragCoord.xy (without interpolation) you'd use texelFetch( tex, ivec2( gl_FragCoord.xy )[, sample] )


Good idea, but i cannot find any nan or inf values.

Looks like checking machine epsilon this way might not be a good idea due to different outcomes and i maybe rather check every delta against float machine epsilon or sth slightly larger to be sure (~1.192e-7). I will test this later.

Also i will consider your texelFetch, thanks.