1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/************************************************************************** 266c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org * 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved. 566c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org * 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 1366c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software. 1766c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org * 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2566c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org * 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/ 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Math utilities and approximations for common math functions. 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Reduced precision is usually acceptable in shaders... 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "fast" is used in the names of functions which are low-precision, 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or at least lower-precision than the normal C lib functions. 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef U_MATH_H 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define U_MATH_H 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_compiler.h" 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_debug.h" 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __cplusplus 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" { 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <math.h> 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdarg.h> 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef PIPE_OS_UNIX 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <strings.h> /* for ffs */ 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef M_SQRT2 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define M_SQRT2 1.41421356237309504880 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 6466c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org#if defined(_MSC_VER) 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if _MSC_VER < 1400 && !defined(__cplusplus) 6766c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org 6866c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float cosf( float f ) 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (float) cos( (double) f ); 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 7366c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float sinf( float f ) 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (float) sin( (double) f ); 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 7866c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float ceilf( float f ) 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (float) ceil( (double) f ); 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 8366c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float floorf( float f ) 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (float) floor( (double) f ); 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 8866c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float powf( float f, float g ) 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (float) pow( (double) f, (double) g ); 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 9366c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float sqrtf( float f ) 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (float) sqrt( (double) f ); 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 9866c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float fabsf( float f ) 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (float) fabs( (double) f ); 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 10366c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float logf( float f ) 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (float) log( (double) f ); 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Work-around an extra semi-colon in VS 2005 logf definition */ 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef logf 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef logf 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define logf(x) ((float)log((double)(x))) 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* logf */ 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 115e510ef026f853574a76ff832d27b8292c03c707bhans@chromium.org#if _MSC_VER < 1800 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define isfinite(x) _finite((double)(x)) 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define isnan(x) _isnan((double)(x)) 118e510ef026f853574a76ff832d27b8292c03c707bhans@chromium.org#endif /* _MSC_VER < 1800 */ 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* _MSC_VER < 1400 && !defined(__cplusplus) */ 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 121e510ef026f853574a76ff832d27b8292c03c707bhans@chromium.org#if _MSC_VER < 1800 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE double log2( double x ) 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const double invln2 = 1.442695041; 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return log( x ) * invln2; 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE double 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orground(double x) 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return x >= 0.0 ? floor(x + 0.5) : ceil(x - 0.5); 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgroundf(float x) 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f); 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 139e510ef026f853574a76ff832d27b8292c03c707bhans@chromium.org#endif 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* _MSC_VER */ 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define POW2_TABLE_SIZE_LOG2 9 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define POW2_TABLE_SIZE (1 << POW2_TABLE_SIZE_LOG2) 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define POW2_TABLE_OFFSET (POW2_TABLE_SIZE/2) 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define POW2_TABLE_SCALE ((float)(POW2_TABLE_SIZE/2)) 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern float pow2_table[POW2_TABLE_SIZE]; 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Initialize math module. This should be called before using any 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * other functions in this module. 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern void 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_init_math(void); 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunion fi { 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float f; 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int32_t i; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint32_t ui; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunion di { 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org double d; 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int64_t i; 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint64_t ui; 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fast version of 2^x 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Identity: exp2(a + b) = exp2(a) * exp2(b) 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Let ipart = int(x) 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Let fpart = x - ipart; 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * So, exp2(x) = exp2(ipart) * exp2(fpart) 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute exp2(ipart) with i << ipart 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute exp2(fpart) with lookup table. 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_fast_exp2(float x) 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int32_t ipart; 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float fpart, mpart; 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org union fi epart; 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(x > 129.00000f) 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 3.402823466e+38f; 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (x < -126.99999f) 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0.0f; 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ipart = (int32_t) x; 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fpart = x - (float) ipart; 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* same as 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * epart.f = (float) (1 << ipart) 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * but faster and without integer overflow for ipart > 31 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org epart.i = (ipart + 127 ) << 23; 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mpart = pow2_table[POW2_TABLE_OFFSET + (int)(fpart * POW2_TABLE_SCALE)]; 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return epart.f * mpart; 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fast approximation to exp(x). 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_fast_exp(float x) 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const float k = 1.44269f; /* = log2(e) */ 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return util_fast_exp2(k * x); 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LOG2_TABLE_SIZE_LOG2 16 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LOG2_TABLE_SCALE (1 << LOG2_TABLE_SIZE_LOG2) 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LOG2_TABLE_SIZE (LOG2_TABLE_SCALE + 1) 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern float log2_table[LOG2_TABLE_SIZE]; 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fast approximation to log2(x). 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_fast_log2(float x) 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org union fi num; 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float epart, mpart; 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num.f = x; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org epart = (float)(((num.i & 0x7f800000) >> 23) - 127); 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* mpart = log2_table[mantissa*LOG2_TABLE_SCALE + 0.5] */ 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mpart = log2_table[((num.i & 0x007fffff) + (1 << (22 - LOG2_TABLE_SIZE_LOG2))) >> (23 - LOG2_TABLE_SIZE_LOG2)]; 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return epart + mpart; 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fast approximation to x^y. 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_fast_pow(float x, float y) 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return util_fast_exp2(util_fast_log2(x) * y); 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Note that this counts zero as a power of two. 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_power_of_two( unsigned v ) 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (v & (v-1)) == 0; 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Floor(x), returned as int. 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_ifloor(float f) 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int ai, bi; 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org double af, bf; 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org union fi u; 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org af = (3 << 22) + 0.5 + (double) f; 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bf = (3 << 22) + 0.5 - (double) f; 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org u.f = (float) af; ai = u.i; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org u.f = (float) bf; bi = u.i; 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (ai - bi) >> 1; 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Round float to nearest int. 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_iround(float f) 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 28366c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86) 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int r; 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st"); 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return r; 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int r; 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _asm { 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fld f 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fistp r 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return r; 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (f >= 0.0f) 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (int) (f + 0.5f); 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (int) (f - 0.5f); 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Approximate floating point comparison 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_approx(float a, float b, float tol) 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return fabs(b - a) <= tol; 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * util_is_X_inf_or_nan = test if x is NaN or +/- Inf 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * util_is_X_nan = test if x is NaN 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * util_X_inf_sign = return +1 for +Inf, -1 for -Inf, or 0 for not Inf 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NaN can be checked with x != x, however this fails with the fast math flag 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **/ 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Single-float 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_inf_or_nan(float x) 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org union fi tmp; 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp.f = x; 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (tmp.ui & 0x7f800000) == 0x7f800000; 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_nan(float x) 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org union fi tmp; 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp.f = x; 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (tmp.ui & 0x7fffffff) > 0x7f800000; 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_inf_sign(float x) 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org union fi tmp; 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp.f = x; 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((tmp.ui & 0x7fffffff) != 0x7f800000) { 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (x < 0) ? -1 : 1; 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Double-float 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_double_inf_or_nan(double x) 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org union di tmp; 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp.d = x; 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (tmp.ui & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL; 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_double_nan(double x) 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org union di tmp; 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp.d = x; 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (tmp.ui & 0x7fffffffffffffffULL) > 0x7ff0000000000000ULL; 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_double_inf_sign(double x) 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org union di tmp; 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp.d = x; 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((tmp.ui & 0x7fffffffffffffffULL) != 0x7ff0000000000000ULL) { 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (x < 0) ? -1 : 1; 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Half-float 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_half_inf_or_nan(int16_t x) 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (x & 0x7c00) == 0x7c00; 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_half_nan(int16_t x) 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (x & 0x7fff) > 0x7c00; 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_half_inf_sign(int16_t x) 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((x & 0x7fff) != 0x7c00) { 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (x < 0) ? -1 : 1; 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Find first bit set in word. Least significant bit is 1. 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return 0 if no bits set. 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef FFS_DEFINED 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define FFS_DEFINED 1 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(_MSC_VER) && _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64) 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned char _BitScanForward(unsigned long* Index, unsigned long Mask); 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#pragma intrinsic(_BitScanForward) 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned long ffs( unsigned long u ) 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned long i; 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_BitScanForward(&i, u)) 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return i + 1; 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned ffs( unsigned u ) 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (u == 0) { 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org __asm bsf eax, [u] 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org __asm inc eax 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org __asm mov [i], eax 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return i; 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(__MINGW32__) || defined(PIPE_OS_ANDROID) 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define ffs __builtin_ffs 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* FFS_DEFINED */ 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Find last bit set in a word. The least significant bit is 1. 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return 0 if no bits are set. 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned util_last_bit(unsigned u) 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned r = 0; 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (u) { 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r++; 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org u >>= 1; 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return r; 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Destructively loop over all of the bits in a mask as in: 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * while (mymask) { 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * int i = u_bit_scan(&mymask); 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ... process element i 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * } 48066c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org * 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int u_bit_scan(unsigned *mask) 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i = ffs(*mask) - 1; 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *mask &= ~(1 << i); 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return i; 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return float bits. 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfui( float f ) 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org union fi fi; 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fi.f = f; 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return fi.ui; 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert ubyte to float in [0, 1]. 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * XXX a 256-entry lookup table would be slightly faster. 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgubyte_to_float(ubyte ub) 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (float) ub * (1.0f / 255.0f); 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert float in [0,1] to ubyte in [0,255] with clamping. 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE ubyte 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfloat_to_ubyte(float f) 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const int ieee_0996 = 0x3f7f0000; /* 0.996 or so */ 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org union fi tmp; 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp.f = f; 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmp.i < 0) { 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (ubyte) 0; 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (tmp.i >= ieee_0996) { 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (ubyte) 255; 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp.f = tmp.f * (255.0f/256.0f) + 32768.0f; 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (ubyte) tmp.i; 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbyte_to_float_tex(int8_t b) 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (b == -128) ? -1.0F : b * 1.0F / 127.0F; 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int8_t 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfloat_to_byte_tex(float f) 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (int8_t) (127.0F * f); 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Calc log base 2 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_logbase2(unsigned n) 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 304) 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ((sizeof(unsigned) * 8 - 1) - __builtin_clz(n | 1)); 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned pos = 0; 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (n >= 1<<16) { n >>= 16; pos += 16; } 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (n >= 1<< 8) { n >>= 8; pos += 8; } 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (n >= 1<< 4) { n >>= 4; pos += 4; } 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (n >= 1<< 2) { n >>= 2; pos += 2; } 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (n >= 1<< 1) { pos += 1; } 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return pos; 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Returns the smallest power of two >= x 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_next_power_of_two(unsigned x) 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 304) 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (x <= 1) 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1))); 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned val = x; 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (x <= 1) 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (util_is_power_of_two(x)) 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return x; 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org val--; 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org val = (val >> 1) | val; 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org val = (val >> 2) | val; 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org val = (val >> 4) | val; 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org val = (val >> 8) | val; 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org val = (val >> 16) | val; 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org val++; 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return val; 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return number of bits set in n. 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_bitcount(unsigned n) 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 304) 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return __builtin_popcount(n); 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* K&R classic bitcount. 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * For each iteration, clear the LSB from the bitfield. 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Requires only one iteration per set bit, instead of 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * one iteration per bit less than highest set bit. 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned bits = 0; 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (bits; n; bits++) { 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org n &= n - 1; 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return bits; 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert from little endian to CPU byte order. 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef PIPE_ARCH_BIG_ENDIAN 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define util_le32_to_cpu(x) util_bswap32(x) 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define util_le16_to_cpu(x) util_bswap16(x) 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define util_le32_to_cpu(x) (x) 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define util_le16_to_cpu(x) (x) 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Reverse byte order of a 32 bit word. 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE uint32_t 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_bswap32(uint32_t n) 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 403) 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return __builtin_bswap32(n); 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (n >> 24) | 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ((n >> 8) & 0x0000ff00) | 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ((n << 8) & 0x00ff0000) | 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (n << 24); 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Reverse byte order of a 16 bit word. 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE uint16_t 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_bswap16(uint16_t n) 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (n >> 8) | 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (n << 8); 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Clamp X to [MIN, MAX]. 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is a macro to allow float, int, uint, etc. types. 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C)) 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C)) 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MIN4( A, B, C, D ) ((A) < (B) ? MIN3(A, C, D) : MIN3(B, C, D)) 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX4( A, B, C, D ) ((A) > (B) ? MAX3(A, C, D) : MAX3(B, C, D)) 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Align a value, only works pot alignemnts. 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgalign(int value, int alignment) 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (value + alignment - 1) & ~(alignment - 1); 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Works like align but on npot alignments. 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE size_t 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_align_npot(size_t value, size_t alignment) 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (value % alignment) 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return value + (alignment - (value % alignment)); 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return value; 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgu_minify(unsigned value, unsigned levels) 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return MAX2(1, value >> levels); 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef COPY_4V 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define COPY_4V( DST, SRC ) \ 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo { \ 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (DST)[0] = (SRC)[0]; \ 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (DST)[1] = (SRC)[1]; \ 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (DST)[2] = (SRC)[2]; \ 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (DST)[3] = (SRC)[3]; \ 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} while (0) 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef COPY_4FV 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define COPY_4FV( DST, SRC ) COPY_4V(DST, SRC) 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef ASSIGN_4V 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define ASSIGN_4V( DST, V0, V1, V2, V3 ) \ 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo { \ 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (DST)[0] = (V0); \ 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (DST)[1] = (V1); \ 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (DST)[2] = (V2); \ 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (DST)[3] = (V3); \ 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} while (0) 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE uint32_t util_unsigned_fixed(float value, unsigned frac_bits) 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return value < 0 ? 0 : (uint32_t)(value * (1<<frac_bits)); 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int32_t util_signed_fixed(float value, unsigned frac_bits) 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (int32_t)(value * (1<<frac_bits)); 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __cplusplus 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* U_MATH_H */ 750