1848b8605Smrg/** 2848b8605Smrg * \file format_utils.h 3848b8605Smrg * A collection of format conversion utility functions. 4848b8605Smrg */ 5848b8605Smrg 6848b8605Smrg/* 7848b8605Smrg * Mesa 3-D graphics library 8848b8605Smrg * 9848b8605Smrg * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 10848b8605Smrg * Copyright (C) 2014 Intel Corporation All Rights Reserved. 11848b8605Smrg * 12848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 13848b8605Smrg * copy of this software and associated documentation files (the "Software"), 14848b8605Smrg * to deal in the Software without restriction, including without limitation 15848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 16848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 17848b8605Smrg * Software is furnished to do so, subject to the following conditions: 18848b8605Smrg * 19848b8605Smrg * The above copyright notice and this permission notice shall be included 20848b8605Smrg * in all copies or substantial portions of the Software. 21848b8605Smrg * 22848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 23848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 25848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 26848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 27848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 29848b8605Smrg */ 30848b8605Smrg 31848b8605Smrg#ifndef FORMAT_UTILS_H 32848b8605Smrg#define FORMAT_UTILS_H 33848b8605Smrg 34b8e80941Smrg#include "formats.h" 35848b8605Smrg#include "imports.h" 36b8e80941Smrg#include "macros.h" 37b8e80941Smrg#include "util/rounding.h" 38b8e80941Smrg#include "util/half_float.h" 39b8e80941Smrg 40b8e80941Smrgextern const mesa_array_format RGBA32_FLOAT; 41b8e80941Smrgextern const mesa_array_format RGBA8_UBYTE; 42b8e80941Smrgextern const mesa_array_format RGBA32_UINT; 43b8e80941Smrgextern const mesa_array_format RGBA32_INT; 44b8e80941Smrg 45b8e80941Smrg/* Only guaranteed to work for BITS <= 32 */ 46b8e80941Smrg#define MAX_UINT(BITS) ((BITS) == 32 ? UINT32_MAX : ((1u << (BITS)) - 1)) 47b8e80941Smrg#define MAX_INT(BITS) ((int)MAX_UINT((BITS) - 1)) 48b8e80941Smrg#define MIN_INT(BITS) ((BITS) == 32 ? INT32_MIN : (-(1 << (BITS - 1)))) 49b8e80941Smrg 50b8e80941Smrg/* Extends an integer of size SRC_BITS to one of size DST_BITS linearly */ 51b8e80941Smrg#define EXTEND_NORMALIZED_INT(X, SRC_BITS, DST_BITS) \ 52b8e80941Smrg (((X) * (int)(MAX_UINT(DST_BITS) / MAX_UINT(SRC_BITS))) + \ 53b8e80941Smrg ((DST_BITS % SRC_BITS) ? ((X) >> (SRC_BITS - DST_BITS % SRC_BITS)) : 0)) 54b8e80941Smrg 55b8e80941Smrgstatic inline float 56b8e80941Smrg_mesa_unorm_to_float(unsigned x, unsigned src_bits) 57b8e80941Smrg{ 58b8e80941Smrg return x * (1.0f / (float)MAX_UINT(src_bits)); 59b8e80941Smrg} 60b8e80941Smrg 61b8e80941Smrgstatic inline float 62b8e80941Smrg_mesa_snorm_to_float(int x, unsigned src_bits) 63b8e80941Smrg{ 64b8e80941Smrg if (x <= -MAX_INT(src_bits)) 65b8e80941Smrg return -1.0f; 66b8e80941Smrg else 67b8e80941Smrg return x * (1.0f / (float)MAX_INT(src_bits)); 68b8e80941Smrg} 69b8e80941Smrg 70b8e80941Smrgstatic inline uint16_t 71b8e80941Smrg_mesa_unorm_to_half(unsigned x, unsigned src_bits) 72b8e80941Smrg{ 73b8e80941Smrg return _mesa_float_to_half(_mesa_unorm_to_float(x, src_bits)); 74b8e80941Smrg} 75b8e80941Smrg 76b8e80941Smrgstatic inline uint16_t 77b8e80941Smrg_mesa_snorm_to_half(int x, unsigned src_bits) 78b8e80941Smrg{ 79b8e80941Smrg return _mesa_float_to_half(_mesa_snorm_to_float(x, src_bits)); 80b8e80941Smrg} 81b8e80941Smrg 82b8e80941Smrgstatic inline unsigned 83b8e80941Smrg_mesa_float_to_unorm(float x, unsigned dst_bits) 84b8e80941Smrg{ 85b8e80941Smrg if (x < 0.0f) 86b8e80941Smrg return 0; 87b8e80941Smrg else if (x > 1.0f) 88b8e80941Smrg return MAX_UINT(dst_bits); 89b8e80941Smrg else 90b8e80941Smrg return _mesa_i64roundevenf(x * MAX_UINT(dst_bits)); 91b8e80941Smrg} 92b8e80941Smrg 93b8e80941Smrgstatic inline unsigned 94b8e80941Smrg_mesa_half_to_unorm(uint16_t x, unsigned dst_bits) 95b8e80941Smrg{ 96b8e80941Smrg return _mesa_float_to_unorm(_mesa_half_to_float(x), dst_bits); 97b8e80941Smrg} 98b8e80941Smrg 99b8e80941Smrgstatic inline unsigned 100b8e80941Smrg_mesa_unorm_to_unorm(unsigned x, unsigned src_bits, unsigned dst_bits) 101b8e80941Smrg{ 102b8e80941Smrg if (src_bits < dst_bits) { 103b8e80941Smrg return EXTEND_NORMALIZED_INT(x, src_bits, dst_bits); 104b8e80941Smrg } else if (src_bits > dst_bits) { 105b8e80941Smrg unsigned src_half = (1 << (src_bits - 1)) - 1; 106b8e80941Smrg 107b8e80941Smrg if (src_bits + dst_bits > sizeof(x) * 8) { 108b8e80941Smrg assert(src_bits + dst_bits <= sizeof(uint64_t) * 8); 109b8e80941Smrg return (((uint64_t) x * MAX_UINT(dst_bits) + src_half) / 110b8e80941Smrg MAX_UINT(src_bits)); 111b8e80941Smrg } else { 112b8e80941Smrg return (x * MAX_UINT(dst_bits) + src_half) / MAX_UINT(src_bits); 113b8e80941Smrg } 114b8e80941Smrg } else { 115b8e80941Smrg return x; 116b8e80941Smrg } 117b8e80941Smrg} 118b8e80941Smrg 119b8e80941Smrgstatic inline unsigned 120b8e80941Smrg_mesa_snorm_to_unorm(int x, unsigned src_bits, unsigned dst_bits) 121b8e80941Smrg{ 122b8e80941Smrg if (x < 0) 123b8e80941Smrg return 0; 124b8e80941Smrg else 125b8e80941Smrg return _mesa_unorm_to_unorm(x, src_bits - 1, dst_bits); 126b8e80941Smrg} 127b8e80941Smrg 128b8e80941Smrgstatic inline int 129b8e80941Smrg_mesa_float_to_snorm(float x, unsigned dst_bits) 130b8e80941Smrg{ 131b8e80941Smrg if (x < -1.0f) 132b8e80941Smrg return -MAX_INT(dst_bits); 133b8e80941Smrg else if (x > 1.0f) 134b8e80941Smrg return MAX_INT(dst_bits); 135b8e80941Smrg else 136b8e80941Smrg return _mesa_lroundevenf(x * MAX_INT(dst_bits)); 137b8e80941Smrg} 138b8e80941Smrg 139b8e80941Smrgstatic inline int 140b8e80941Smrg_mesa_half_to_snorm(uint16_t x, unsigned dst_bits) 141b8e80941Smrg{ 142b8e80941Smrg return _mesa_float_to_snorm(_mesa_half_to_float(x), dst_bits); 143b8e80941Smrg} 144b8e80941Smrg 145b8e80941Smrgstatic inline int 146b8e80941Smrg_mesa_unorm_to_snorm(unsigned x, unsigned src_bits, unsigned dst_bits) 147b8e80941Smrg{ 148b8e80941Smrg return _mesa_unorm_to_unorm(x, src_bits, dst_bits - 1); 149b8e80941Smrg} 150b8e80941Smrg 151b8e80941Smrgstatic inline int 152b8e80941Smrg_mesa_snorm_to_snorm(int x, unsigned src_bits, unsigned dst_bits) 153b8e80941Smrg{ 154b8e80941Smrg if (x < -MAX_INT(src_bits)) 155b8e80941Smrg return -MAX_INT(dst_bits); 156b8e80941Smrg else if (src_bits < dst_bits) 157b8e80941Smrg return EXTEND_NORMALIZED_INT(x, src_bits - 1, dst_bits - 1); 158b8e80941Smrg else 159b8e80941Smrg return x >> (src_bits - dst_bits); 160b8e80941Smrg} 161b8e80941Smrg 162b8e80941Smrgstatic inline unsigned 163b8e80941Smrg_mesa_unsigned_to_unsigned(unsigned src, unsigned dst_size) 164b8e80941Smrg{ 165b8e80941Smrg return MIN2(src, MAX_UINT(dst_size)); 166b8e80941Smrg} 167b8e80941Smrg 168b8e80941Smrgstatic inline int 169b8e80941Smrg_mesa_unsigned_to_signed(unsigned src, unsigned dst_size) 170b8e80941Smrg{ 171b8e80941Smrg return MIN2(src, (unsigned)MAX_INT(dst_size)); 172b8e80941Smrg} 173b8e80941Smrg 174b8e80941Smrgstatic inline int 175b8e80941Smrg_mesa_signed_to_signed(int src, unsigned dst_size) 176b8e80941Smrg{ 177b8e80941Smrg return CLAMP(src, MIN_INT(dst_size), MAX_INT(dst_size)); 178b8e80941Smrg} 179b8e80941Smrg 180b8e80941Smrgstatic inline unsigned 181b8e80941Smrg_mesa_signed_to_unsigned(int src, unsigned dst_size) 182b8e80941Smrg{ 183b8e80941Smrg return CLAMP(src, 0, MAX_UINT(dst_size)); 184b8e80941Smrg} 185b8e80941Smrg 186b8e80941Smrgstatic inline unsigned 187b8e80941Smrg_mesa_float_to_unsigned(float src, unsigned dst_bits) 188b8e80941Smrg{ 189b8e80941Smrg if (src < 0.0f) 190b8e80941Smrg return 0; 191b8e80941Smrg if (src > (float)MAX_UINT(dst_bits)) 192b8e80941Smrg return MAX_UINT(dst_bits); 193b8e80941Smrg return _mesa_signed_to_unsigned(src, dst_bits); 194b8e80941Smrg} 195b8e80941Smrg 196b8e80941Smrgstatic inline unsigned 197b8e80941Smrg_mesa_float_to_signed(float src, unsigned dst_bits) 198b8e80941Smrg{ 199b8e80941Smrg if (src < (float)(-MAX_INT(dst_bits))) 200b8e80941Smrg return -MAX_INT(dst_bits); 201b8e80941Smrg if (src > (float)MAX_INT(dst_bits)) 202b8e80941Smrg return MAX_INT(dst_bits); 203b8e80941Smrg return _mesa_signed_to_signed(src, dst_bits); 204b8e80941Smrg} 205b8e80941Smrg 206b8e80941Smrgstatic inline unsigned 207b8e80941Smrg_mesa_half_to_unsigned(uint16_t src, unsigned dst_bits) 208b8e80941Smrg{ 209b8e80941Smrg if (_mesa_half_is_negative(src)) 210b8e80941Smrg return 0; 211b8e80941Smrg return _mesa_unsigned_to_unsigned(_mesa_float_to_half(src), dst_bits); 212b8e80941Smrg} 213b8e80941Smrg 214b8e80941Smrgstatic inline unsigned 215b8e80941Smrg_mesa_half_to_signed(uint16_t src, unsigned dst_bits) 216b8e80941Smrg{ 217b8e80941Smrg return _mesa_float_to_signed(_mesa_half_to_float(src), dst_bits); 218b8e80941Smrg} 219848b8605Smrg 220848b8605Smrgbool 221848b8605Smrg_mesa_format_to_array(mesa_format, GLenum *type, int *num_components, 222848b8605Smrg uint8_t swizzle[4], bool *normalized); 223848b8605Smrg 224848b8605Smrgvoid 225b8e80941Smrg_mesa_swizzle_and_convert(void *dst, 226b8e80941Smrg enum mesa_array_format_datatype dst_type, 227b8e80941Smrg int num_dst_channels, 228b8e80941Smrg const void *src, 229b8e80941Smrg enum mesa_array_format_datatype src_type, 230b8e80941Smrg int num_src_channels, 231848b8605Smrg const uint8_t swizzle[4], bool normalized, int count); 232848b8605Smrg 233b8e80941Smrgbool 234b8e80941Smrg_mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat, uint8_t *map); 235b8e80941Smrg 236b8e80941Smrgvoid 237b8e80941Smrg_mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride, 238b8e80941Smrg void *void_src, uint32_t src_format, size_t src_stride, 239b8e80941Smrg size_t width, size_t height, uint8_t *rebase_swizzle); 240b8e80941Smrg 241848b8605Smrg#endif 242