GPU: Math: Add floatBitsToOrderedInt and orderedIntBitsToFloat
These allow the usage of `atomicMin` and `atomicMax` function with float values as there is no overload for these types in GLSL. This also allows signed 0 preservation.
This commit is contained in:
parent
945d108ab8
commit
28db19433e
|
@ -93,4 +93,23 @@ uvec4 unpackUvec4x8(uint data)
|
|||
return (uvec4(data) >> uvec4(0u, 8u, 16u, 24u)) & uvec4(0xFFu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from float representation to ordered int allowing min/max atomic operation.
|
||||
* Based on: https://stackoverflow.com/a/31010352
|
||||
*/
|
||||
int floatBitsToOrderedInt(float value)
|
||||
{
|
||||
/* Floats can be sorted using their bits interpreted as integers for positive values.
|
||||
* Negative values do not follow int's two's complement ordering which is reversed.
|
||||
* So we have to XOR all bits except the sign bits in order to reverse the ordering.
|
||||
* Note that this is highly hardware dependent, but there seems to be no case of GPU where the
|
||||
* ints ares not two's complement. */
|
||||
int int_value = floatBitsToInt(value);
|
||||
return (int_value < 0) ? (int_value ^ 0x7FFFFFFF) : int_value;
|
||||
}
|
||||
float orderedIntBitsToFloat(int int_value)
|
||||
{
|
||||
return intBitsToFloat((int_value < 0) ? (int_value ^ 0x7FFFFFFF) : int_value);
|
||||
}
|
||||
|
||||
#endif /* GPU_SHADER_UTILDEFINES_GLSL */
|
||||
|
|
|
@ -287,4 +287,19 @@ void main()
|
|||
vec4(0.0f, 0.0f, -1.0f, 1.0f)));
|
||||
EXPECT_NEAR(pers2, expect, 1e-4);
|
||||
}
|
||||
|
||||
TEST(math_matrix, OrderedInt)
|
||||
{
|
||||
/* Identity. */
|
||||
EXPECT_EQ(orderedIntBitsToFloat(floatBitsToOrderedInt(0.5)), 0.5);
|
||||
EXPECT_EQ(orderedIntBitsToFloat(floatBitsToOrderedInt(-0.5)), -0.5);
|
||||
EXPECT_EQ(orderedIntBitsToFloat(floatBitsToOrderedInt(0.0)), 0.0);
|
||||
EXPECT_EQ(orderedIntBitsToFloat(floatBitsToOrderedInt(-0.0)), -0.0);
|
||||
|
||||
EXPECT_GE(floatBitsToOrderedInt(-0.5), floatBitsToOrderedInt(-1.0));
|
||||
EXPECT_LE(floatBitsToOrderedInt(0.5), floatBitsToOrderedInt(1.0));
|
||||
EXPECT_LE(floatBitsToOrderedInt(-0.5), floatBitsToOrderedInt(1.0));
|
||||
EXPECT_GE(floatBitsToOrderedInt(0.5), floatBitsToOrderedInt(-1.0));
|
||||
EXPECT_LE(floatBitsToOrderedInt(-0.0), floatBitsToOrderedInt(0.0));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue