Implement floating-point conversion to the nearest representable integer.
Bug 20724899
Change-Id: I35f63709b5773c2cefe8bf2376e6d9236dfd81f9
Reviewed-on: https://swiftshader-review.googlesource.com/5090
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index 4732c52..ec21154 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -3121,7 +3121,7 @@
{
if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
{
- params[i] = es2::floatToInt(floatParams[i]);
+ params[i] = convert_float_int(floatParams[i]);
}
else
{
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index efa16c1..f20c893 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -1872,7 +1872,7 @@
{
if(target == GL_DEPTH_RANGE || target == GL_COLOR_CLEAR_VALUE || target == GL_DEPTH_CLEAR_VALUE || target == GL_BLEND_COLOR)
{
- data[i] = es2::floatToInt(floatParams[i]);
+ data[i] = convert_float_int(floatParams[i]);
}
else
{
@@ -3210,7 +3210,7 @@
{
if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
{
- data[i] = (GLint64)(es2::floatToInt(floatParams[i]));
+ data[i] = (GLint64)(convert_float_int(floatParams[i]));
}
else
{
@@ -3282,7 +3282,7 @@
{
if(target == GL_DEPTH_RANGE || target == GL_COLOR_CLEAR_VALUE || target == GL_DEPTH_CLEAR_VALUE || target == GL_BLEND_COLOR)
{
- data[i] = (GLint64)(es2::floatToInt(floatParams[i]));
+ data[i] = (GLint64)(convert_float_int(floatParams[i]));
}
else
{
diff --git a/src/OpenGL/libGLESv2/mathutil.h b/src/OpenGL/libGLESv2/mathutil.h
index 0fbd709..62b6a1c 100644
--- a/src/OpenGL/libGLESv2/mathutil.h
+++ b/src/OpenGL/libGLESv2/mathutil.h
@@ -69,6 +69,26 @@
return (unsigned int)(max * x + 0.5f);
}
}
+
+// Converts floating-point values to the nearest representable integer
+inline int convert_float_int(float x)
+{
+ // The largest positive integer value that is exactly representable in IEEE 754 binary32 is 0x7FFFFF80.
+ // The next floating-point value is 128 larger and thus needs clamping to 0x7FFFFFFF.
+ static_assert(std::numeric_limits<float>::is_iec559, "Unsupported floating-point format");
+
+ if(x > 0x7FFFFF80)
+ {
+ return 0x7FFFFFFF;
+ }
+
+ if(x < (signed)0x80000000)
+ {
+ return 0x80000000;
+ }
+
+ return static_cast<int>(roundf(x));
+}
}
#endif // LIBGLESV2_MATHUTIL_H_
diff --git a/src/OpenGL/libGLESv2/utilities.cpp b/src/OpenGL/libGLESv2/utilities.cpp
index 850c1e2..9d22290 100644
--- a/src/OpenGL/libGLESv2/utilities.cpp
+++ b/src/OpenGL/libGLESv2/utilities.cpp
@@ -464,11 +464,6 @@
return -1;
}
- GLint floatToInt(GLfloat value)
- {
- return static_cast<GLint>((static_cast<GLfloat>(0xFFFFFFFF) * value - 1.0f) * 0.5f);
- }
-
bool IsCompressed(GLenum format, GLint clientVersion)
{
return ValidateCompressedFormat(format, clientVersion, true) == GL_NONE;
diff --git a/src/OpenGL/libGLESv2/utilities.h b/src/OpenGL/libGLESv2/utilities.h
index d2d9084..918fffa 100644
--- a/src/OpenGL/libGLESv2/utilities.h
+++ b/src/OpenGL/libGLESv2/utilities.h
@@ -41,8 +41,6 @@
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
- GLint floatToInt(GLfloat value);
-
bool IsCompressed(GLenum format, GLint clientVersion);
GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type);
GLenum ValidateCompressedFormat(GLenum format, GLint clientVersion, bool expectCompressedFormats);