mesa: add EXT_dsa glClientAttribDefaultEXT / glPushClientAttribDefaultEXT
[mesa.git] / src / mesa / main / format_utils.h
index ae7926e0c7515400b6c14c0da53c7130f32abf02..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
@@ -208,10 +222,17 @@ _mesa_format_to_array(mesa_format, GLenum *type, int *num_components,
                       uint8_t swizzle[4], bool *normalized);
 
 void
-_mesa_swizzle_and_convert(void *dst, GLenum dst_type, int num_dst_channels,
-                          const void *src, GLenum src_type, int num_src_channels,
+_mesa_swizzle_and_convert(void *dst,
+                          enum mesa_array_format_datatype dst_type,
+                          int num_dst_channels,
+                          const void *src,
+                          enum mesa_array_format_datatype src_type,
+                          int num_src_channels,
                           const uint8_t swizzle[4], bool normalized, int count);
 
+bool
+_mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat, uint8_t *map);
+
 void
 _mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride,
                      void *void_src, uint32_t src_format, size_t src_stride,