michael@0: // michael@0: // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: // michael@0: michael@0: // mathutil.h: Math and bit manipulation functions. michael@0: michael@0: #ifndef LIBGLESV2_MATHUTIL_H_ michael@0: #define LIBGLESV2_MATHUTIL_H_ michael@0: michael@0: #include michael@0: michael@0: #include "common/system.h" michael@0: #include "common/debug.h" michael@0: michael@0: namespace gl michael@0: { michael@0: struct Vector4 michael@0: { michael@0: Vector4() {} michael@0: Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {} michael@0: michael@0: float x; michael@0: float y; michael@0: float z; michael@0: float w; michael@0: }; michael@0: michael@0: inline bool isPow2(int x) michael@0: { michael@0: return (x & (x - 1)) == 0 && (x != 0); michael@0: } michael@0: michael@0: inline int log2(int x) michael@0: { michael@0: int r = 0; michael@0: while ((x >> r) > 1) r++; michael@0: return r; michael@0: } michael@0: michael@0: inline unsigned int ceilPow2(unsigned int x) michael@0: { michael@0: if (x != 0) x--; michael@0: x |= x >> 1; michael@0: x |= x >> 2; michael@0: x |= x >> 4; michael@0: x |= x >> 8; michael@0: x |= x >> 16; michael@0: x++; michael@0: michael@0: return x; michael@0: } michael@0: michael@0: template michael@0: inline T clamp(T x, MIN min, MAX max) michael@0: { michael@0: // Since NaNs fail all comparison tests, a NaN value will default to min michael@0: return x > min ? (x > max ? max : x) : min; michael@0: } michael@0: michael@0: inline float clamp01(float x) michael@0: { michael@0: return clamp(x, 0.0f, 1.0f); michael@0: } michael@0: michael@0: template michael@0: inline unsigned int unorm(float x) michael@0: { michael@0: const unsigned int max = 0xFFFFFFFF >> (32 - n); michael@0: michael@0: if (x > 1) michael@0: { michael@0: return max; michael@0: } michael@0: else if (x < 0) michael@0: { michael@0: return 0; michael@0: } michael@0: else michael@0: { michael@0: return (unsigned int)(max * x + 0.5f); michael@0: } michael@0: } michael@0: michael@0: inline bool supportsSSE2() michael@0: { michael@0: static bool checked = false; michael@0: static bool supports = false; michael@0: michael@0: if (checked) michael@0: { michael@0: return supports; michael@0: } michael@0: michael@0: int info[4]; michael@0: __cpuid(info, 0); michael@0: michael@0: if (info[0] >= 1) michael@0: { michael@0: __cpuid(info, 1); michael@0: michael@0: supports = (info[3] >> 26) & 1; michael@0: } michael@0: michael@0: checked = true; michael@0: michael@0: return supports; michael@0: } michael@0: michael@0: inline unsigned short float32ToFloat16(float fp32) michael@0: { michael@0: unsigned int fp32i = (unsigned int&)fp32; michael@0: unsigned int sign = (fp32i & 0x80000000) >> 16; michael@0: unsigned int abs = fp32i & 0x7FFFFFFF; michael@0: michael@0: if(abs > 0x47FFEFFF) // Infinity michael@0: { michael@0: return sign | 0x7FFF; michael@0: } michael@0: else if(abs < 0x38800000) // Denormal michael@0: { michael@0: unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000; michael@0: int e = 113 - (abs >> 23); michael@0: michael@0: if(e < 24) michael@0: { michael@0: abs = mantissa >> e; michael@0: } michael@0: else michael@0: { michael@0: abs = 0; michael@0: } michael@0: michael@0: return sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13; michael@0: } michael@0: else michael@0: { michael@0: return sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13; michael@0: } michael@0: } michael@0: michael@0: float float16ToFloat32(unsigned short h); michael@0: michael@0: } michael@0: michael@0: namespace rx michael@0: { michael@0: michael@0: struct Range michael@0: { michael@0: Range() {} michael@0: Range(int lo, int hi) : start(lo), end(hi) { ASSERT(lo <= hi); } michael@0: michael@0: int start; michael@0: int end; michael@0: }; michael@0: michael@0: } michael@0: michael@0: #endif // LIBGLESV2_MATHUTIL_H_