Home | History | Annotate | Download | only in main
      1 /**
      2  * \file format_utils.h
      3  * A collection of format conversion utility functions.
      4  */
      5 
      6 /*
      7  * Mesa 3-D graphics library
      8  *
      9  * Copyright (C) 1999-2006  Brian Paul  All Rights Reserved.
     10  * Copyright (C) 2014  Intel Corporation  All Rights Reserved.
     11  *
     12  * Permission is hereby granted, free of charge, to any person obtaining a
     13  * copy of this software and associated documentation files (the "Software"),
     14  * to deal in the Software without restriction, including without limitation
     15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     16  * and/or sell copies of the Software, and to permit persons to whom the
     17  * Software is furnished to do so, subject to the following conditions:
     18  *
     19  * The above copyright notice and this permission notice shall be included
     20  * in all copies or substantial portions of the Software.
     21  *
     22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     26  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     27  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     28  * OTHER DEALINGS IN THE SOFTWARE.
     29  */
     30 
     31 #ifndef FORMAT_UTILS_H
     32 #define FORMAT_UTILS_H
     33 
     34 #include "imports.h"
     35 #include "macros.h"
     36 #include "util/rounding.h"
     37 #include "util/half_float.h"
     38 
     39 extern const mesa_array_format RGBA32_FLOAT;
     40 extern const mesa_array_format RGBA8_UBYTE;
     41 extern const mesa_array_format RGBA32_UINT;
     42 extern const mesa_array_format RGBA32_INT;
     43 
     44 /* Only guaranteed to work for BITS <= 32 */
     45 #define MAX_UINT(BITS) ((BITS) == 32 ? UINT32_MAX : ((1u << (BITS)) - 1))
     46 #define MAX_INT(BITS) ((int)MAX_UINT((BITS) - 1))
     47 #define MIN_INT(BITS) ((BITS) == 32 ? INT32_MIN : (-(1 << (BITS - 1))))
     48 
     49 /* Extends an integer of size SRC_BITS to one of size DST_BITS linearly */
     50 #define EXTEND_NORMALIZED_INT(X, SRC_BITS, DST_BITS) \
     51       (((X) * (int)(MAX_UINT(DST_BITS) / MAX_UINT(SRC_BITS))) + \
     52        ((DST_BITS % SRC_BITS) ? ((X) >> (SRC_BITS - DST_BITS % SRC_BITS)) : 0))
     53 
     54 static inline float
     55 _mesa_unorm_to_float(unsigned x, unsigned src_bits)
     56 {
     57    return x * (1.0f / (float)MAX_UINT(src_bits));
     58 }
     59 
     60 static inline float
     61 _mesa_snorm_to_float(int x, unsigned src_bits)
     62 {
     63    if (x <= -MAX_INT(src_bits))
     64       return -1.0f;
     65    else
     66       return x * (1.0f / (float)MAX_INT(src_bits));
     67 }
     68 
     69 static inline uint16_t
     70 _mesa_unorm_to_half(unsigned x, unsigned src_bits)
     71 {
     72    return _mesa_float_to_half(_mesa_unorm_to_float(x, src_bits));
     73 }
     74 
     75 static inline uint16_t
     76 _mesa_snorm_to_half(int x, unsigned src_bits)
     77 {
     78    return _mesa_float_to_half(_mesa_snorm_to_float(x, src_bits));
     79 }
     80 
     81 static inline unsigned
     82 _mesa_float_to_unorm(float x, unsigned dst_bits)
     83 {
     84    if (x < 0.0f)
     85       return 0;
     86    else if (x > 1.0f)
     87       return MAX_UINT(dst_bits);
     88    else
     89       return _mesa_lroundevenf(x * MAX_UINT(dst_bits));
     90 }
     91 
     92 static inline unsigned
     93 _mesa_half_to_unorm(uint16_t x, unsigned dst_bits)
     94 {
     95    return _mesa_float_to_unorm(_mesa_half_to_float(x), dst_bits);
     96 }
     97 
     98 static inline unsigned
     99 _mesa_unorm_to_unorm(unsigned x, unsigned src_bits, unsigned dst_bits)
    100 {
    101    if (src_bits < dst_bits) {
    102       return EXTEND_NORMALIZED_INT(x, src_bits, dst_bits);
    103    } else if (src_bits > dst_bits) {
    104       unsigned src_half = (1 << (src_bits - 1)) - 1;
    105 
    106       if (src_bits + dst_bits > sizeof(x) * 8) {
    107          assert(src_bits + dst_bits <= sizeof(uint64_t) * 8);
    108          return (((uint64_t) x * MAX_UINT(dst_bits) + src_half) /
    109                  MAX_UINT(src_bits));
    110       } else {
    111          return (x * MAX_UINT(dst_bits) + src_half) / MAX_UINT(src_bits);
    112       }
    113    } else {
    114       return x;
    115    }
    116 }
    117 
    118 static inline unsigned
    119 _mesa_snorm_to_unorm(int x, unsigned src_bits, unsigned dst_bits)
    120 {
    121    if (x < 0)
    122       return 0;
    123    else
    124       return _mesa_unorm_to_unorm(x, src_bits - 1, dst_bits);
    125 }
    126 
    127 static inline int
    128 _mesa_float_to_snorm(float x, unsigned dst_bits)
    129 {
    130    if (x < -1.0f)
    131       return -MAX_INT(dst_bits);
    132    else if (x > 1.0f)
    133       return MAX_INT(dst_bits);
    134    else
    135       return _mesa_lroundevenf(x * MAX_INT(dst_bits));
    136 }
    137 
    138 static inline int
    139 _mesa_half_to_snorm(uint16_t x, unsigned dst_bits)
    140 {
    141    return _mesa_float_to_snorm(_mesa_half_to_float(x), dst_bits);
    142 }
    143 
    144 static inline int
    145 _mesa_unorm_to_snorm(unsigned x, unsigned src_bits, unsigned dst_bits)
    146 {
    147    return _mesa_unorm_to_unorm(x, src_bits, dst_bits - 1);
    148 }
    149 
    150 static inline int
    151 _mesa_snorm_to_snorm(int x, unsigned src_bits, unsigned dst_bits)
    152 {
    153    if (x < -MAX_INT(src_bits))
    154       return -MAX_INT(dst_bits);
    155    else if (src_bits < dst_bits)
    156       return EXTEND_NORMALIZED_INT(x, src_bits - 1, dst_bits - 1);
    157    else
    158       return x >> (src_bits - dst_bits);
    159 }
    160 
    161 static inline unsigned
    162 _mesa_unsigned_to_unsigned(unsigned src, unsigned dst_size)
    163 {
    164    return MIN2(src, MAX_UINT(dst_size));
    165 }
    166 
    167 static inline int
    168 _mesa_unsigned_to_signed(unsigned src, unsigned dst_size)
    169 {
    170    return MIN2(src, (unsigned)MAX_INT(dst_size));
    171 }
    172 
    173 static inline int
    174 _mesa_signed_to_signed(int src, unsigned dst_size)
    175 {
    176    return CLAMP(src, MIN_INT(dst_size), MAX_INT(dst_size));
    177 }
    178 
    179 static inline unsigned
    180 _mesa_signed_to_unsigned(int src, unsigned dst_size)
    181 {
    182    return CLAMP(src, 0, MAX_UINT(dst_size));
    183 }
    184 
    185 static inline unsigned
    186 _mesa_float_to_unsigned(float src, unsigned dst_bits)
    187 {
    188    if (src < 0.0f)
    189       return 0;
    190    if (src > (float)MAX_UINT(dst_bits))
    191        return MAX_UINT(dst_bits);
    192    return _mesa_signed_to_unsigned(src, dst_bits);
    193 }
    194 
    195 static inline unsigned
    196 _mesa_float_to_signed(float src, unsigned dst_bits)
    197 {
    198    if (src < (float)(-MAX_INT(dst_bits)))
    199       return -MAX_INT(dst_bits);
    200    if (src > (float)MAX_INT(dst_bits))
    201        return MAX_INT(dst_bits);
    202    return _mesa_signed_to_signed(src, dst_bits);
    203 }
    204 
    205 static inline unsigned
    206 _mesa_half_to_unsigned(uint16_t src, unsigned dst_bits)
    207 {
    208    if (_mesa_half_is_negative(src))
    209       return 0;
    210    return _mesa_unsigned_to_unsigned(_mesa_float_to_half(src), dst_bits);
    211 }
    212 
    213 static inline unsigned
    214 _mesa_half_to_signed(uint16_t src, unsigned dst_bits)
    215 {
    216    return _mesa_float_to_signed(_mesa_half_to_float(src), dst_bits);
    217 }
    218 
    219 bool
    220 _mesa_format_to_array(mesa_format, GLenum *type, int *num_components,
    221                       uint8_t swizzle[4], bool *normalized);
    222 
    223 void
    224 _mesa_swizzle_and_convert(void *dst,
    225                           enum mesa_array_format_datatype dst_type,
    226                           int num_dst_channels,
    227                           const void *src,
    228                           enum mesa_array_format_datatype src_type,
    229                           int num_src_channels,
    230                           const uint8_t swizzle[4], bool normalized, int count);
    231 
    232 bool
    233 _mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat, uint8_t *map);
    234 
    235 void
    236 _mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride,
    237                      void *void_src, uint32_t src_format, size_t src_stride,
    238                      size_t width, size_t height, uint8_t *rebase_swizzle);
    239 
    240 #endif
    241