Advertisement

How to make C++ and HLSL produce the same floating point results?

Started by September 15, 2019 04:14 PM
5 comments, last by NikiTo 5 years ago

Hi!
I am outputting debug data from a shader in HLSL. The computations in the shader are done in float.
Then C++ reads that data and checks it for errors.
The very same computations(copy-pasted) in C++ using floats, produce result that differs in the 8th digit after the comma.
And my error-checking code fails.

How to make it work?

Float only has 7 digits (23bits) precision. C++ double 52(?)biuts. Sounds like everything's fine ...

Advertisement
1 minute ago, Green_Baron said:

Float only has 7 digits precision.

When i print it, i set the precision to 20 digits for visualizing purposes.

I compare the results for equal float vs float. Not string-of-a-float vs string-of-a-float.
The comparison fails.

The float, i take it from the shader in this way:

float insideHLSLvar = some computation.
outputDebugResource.Store(address, asuint(insideHLSLvar));

inside C++ I use union to emulate the "asfloat" of HLSL.

What you're asking for is nigh on impossible.

You may get closer by enabling IEEE strictness on your shaders and disabling any fast-math optimisations on your C++ compiler, but only certain floating point operations are guaranteed to give the same result across architectures (e.g. +, -, *, /). You can try enabling IEEE strictness using the /Gis compiler flag, but I don't think it'll get anything other than "close, but not quite".

Try giving this blog post from Bruce Dawson a read: https://randomascii.wordpress.com/2013/07/16/floating-point-determinism/

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

5 hours ago, NikiTo said:

And my error-checking code fails.

How to make it work?

Never compare floats for an exact match. Always compare with tolerance. Even though you might have written the same code in the shader and in C++, the compiler might rearrange terms to optimize it an a*b + a*c is usually not exactly the same as a*(b+c) in the world of floating-point arithmetics. 

Greetings

Thanks, all!
I decided to not check HLSL result in C++.

This topic is closed to new replies.

Advertisement