mesa: add EXT_dsa glClientAttribDefaultEXT / glPushClientAttribDefaultEXT
[mesa.git] / src / mesa / main / format_utils.h
index b588695de0c4505a52fb5b9f487e12175d20e9b6..3a528ceb3db613c820dc85923d45c6115daad08d 100644 (file)
 #ifndef FORMAT_UTILS_H
 #define FORMAT_UTILS_H
 
+#include "formats.h"
 #include "imports.h"
 #include "macros.h"
+#include "util/rounding.h"
+#include "util/half_float.h"
 
-extern const mesa_array_format RGBA8888_FLOAT;
-extern const mesa_array_format RGBA8888_UBYTE;
-extern const mesa_array_format RGBA8888_UINT;
-extern const mesa_array_format RGBA8888_INT;
+extern const mesa_array_format RGBA32_FLOAT;
+extern const mesa_array_format RGBA8_UBYTE;
+extern const mesa_array_format RGBA32_UINT;
+extern const mesa_array_format RGBA32_INT;
 
 /* Only guaranteed to work for BITS <= 32 */
 #define MAX_UINT(BITS) ((BITS) == 32 ? UINT32_MAX : ((1u << (BITS)) - 1))
@@ -84,7 +87,7 @@ _mesa_float_to_unorm(float x, unsigned dst_bits)
    else if (x > 1.0f)
       return MAX_UINT(dst_bits);
    else
-      return F_TO_I(x * MAX_UINT(dst_bits));
+      return _mesa_i64roundevenf(x * MAX_UINT(dst_bits));
 }
 
 static inline unsigned
@@ -96,10 +99,21 @@ _mesa_half_to_unorm(uint16_t x, unsigned dst_bits)
 static inline unsigned
 _mesa_unorm_to_unorm(unsigned x, unsigned src_bits, unsigned dst_bits)
 {
-   if (src_bits < dst_bits)
+   if (src_bits < dst_bits) {
       return EXTEND_NORMALIZED_INT(x, src_bits, dst_bits);
-   else
-      return x >> (src_bits - dst_bits);
+   } else if (src_bits > dst_bits) {
+      unsigned src_half = (1 << (src_bits - 1)) - 1;
+
+      if (src_bits + dst_bits > sizeof(x) * 8) {
+         assert(src_bits + dst_bits <= sizeof(uint64_t) * 8);
+         return (((uint64_t) x * MAX_UINT(dst_bits) + src_half) /
+                 MAX_UINT(src_bits));
+      } else {
+         return (x * MAX_UINT(dst_bits) + src_half) / MAX_UINT(src_bits);
+      }
+   } else {
+      return x;
+   }
 }
 
 static inline unsigned
@@ -119,7 +133,7 @@ _mesa_float_to_snorm(float x, unsigned dst_bits)
    else if (x > 1.0f)
       return MAX_INT(dst_bits);
    else
-      return F_TO_I(x * MAX_INT(dst_bits));
+      return _mesa_lroundevenf(x * MAX_INT(dst_bits));
 }
 
 static inline int
@@ -154,7 +168,7 @@ _mesa_unsigned_to_unsigned(unsigned src, unsigned dst_size)
 static inline int
 _mesa_unsigned_to_signed(unsigned src, unsigned dst_size)
 {
-   return MIN2(src, MAX_INT(dst_size));
+   return MIN2(src, (unsigned)MAX_INT(dst_size));
 }
 
 static inline int