| // SwiftShader Software Renderer |
| // |
| // Copyright(c) 2005-2011 TransGaming Inc. |
| // |
| // All rights reserved. No part of this software may be copied, distributed, transmitted, |
| // transcribed, stored in a retrieval system, translated into any human or computer |
| // language by any means, or disclosed to third parties without the explicit written |
| // agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express |
| // or implied, including but not limited to any patent rights, are granted to you. |
| // |
| |
| #ifndef sw_Math_hpp |
| #define sw_Math_hpp |
| |
| #include "Types.hpp" |
| |
| #include <math.h> |
| #include <intrin.h> |
| |
| namespace sw |
| { |
| extern const float M_PI; |
| extern const float M_PI_180; |
| extern const float M_180_PI; |
| extern const float M_2PI; |
| extern const float M_PI_2; |
| |
| inline float rad(float deg) |
| { |
| return deg * M_PI_180; |
| } |
| |
| inline float deg(float rad) |
| { |
| return rad * M_180_PI; |
| } |
| |
| inline float sin(float x) |
| { |
| return sinf(x); |
| } |
| |
| inline float asin(float x) |
| { |
| return asinf(x); |
| } |
| |
| inline float sinh(float x) |
| { |
| return sinhf(x); |
| } |
| |
| inline float cos(float x) |
| { |
| return cosf(x); |
| } |
| |
| inline float acos(float x) |
| { |
| return acosf(x); |
| } |
| |
| inline float cosh(float x) |
| { |
| return coshf(x); |
| } |
| |
| inline float tan(float x) |
| { |
| return tanf(x); |
| } |
| |
| inline float cot(float x) |
| { |
| return 1.0f / tan(x); |
| } |
| |
| inline float atan(float x) |
| { |
| return atanf(x); |
| } |
| |
| inline float tanh(float x) |
| { |
| return tanhf(x); |
| } |
| |
| inline float sqrt(float x) |
| { |
| return sqrtf(x); |
| } |
| |
| inline float exp(float x) |
| { |
| return expf(x); |
| } |
| |
| inline float exp2(float x) |
| { |
| static const float ln2 = logf(2); |
| |
| return exp(ln2 * x); |
| } |
| |
| inline float pow(float x, float y) |
| { |
| return powf(x, y); |
| } |
| |
| inline float pow2(float x) |
| { |
| return x * x; |
| } |
| |
| inline float abs(float x) |
| { |
| return fabsf(x); |
| } |
| |
| #undef min |
| #undef max |
| |
| inline float max(float a, float b) |
| { |
| return a > b ? a : b; |
| } |
| |
| inline float min(float a, float b) |
| { |
| return a < b ? a : b; |
| } |
| |
| inline float max(float a, float b, float c) |
| { |
| return max(max(a, b), c); |
| } |
| |
| inline float min(float a, float b, float c) |
| { |
| return min(min(a, b), c); |
| } |
| |
| inline float max(float a, float b, float c, float d) |
| { |
| return max(max(a, b), max(c, d)); |
| } |
| |
| inline float min(float a, float b, float c, float d) |
| { |
| return min(min(a, b), min(c, d)); |
| } |
| |
| inline int max(int a, int b) |
| { |
| return a > b ? a : b; |
| } |
| |
| inline int min(int a, int b) |
| { |
| return a < b ? a : b; |
| } |
| |
| inline int max(int a, int b, int c) |
| { |
| return max(max(a, b), c); |
| } |
| |
| inline int min(int a, int b, int c) |
| { |
| return min(min(a, b), c); |
| } |
| |
| inline int max(int a, int b, int c, int d) |
| { |
| return max(max(a, b), max(c, d)); |
| } |
| |
| inline int min(int a, int b, int c, int d) |
| { |
| return min(min(a, b), min(c, d)); |
| } |
| |
| template<class T> |
| inline void swap(T &a, T &b) |
| { |
| T t = a; |
| a = b; |
| b = t; |
| } |
| |
| inline int iround(float x) |
| { |
| return (int)floor(x + 0.5f); |
| // return _mm_cvtss_si32(_mm_load_ss(&x)); // FIXME: Demands SSE support |
| } |
| |
| inline int ifloor(float x) |
| { |
| return (int)floor(x); |
| } |
| |
| inline int ceilFix4(int x) |
| { |
| return (x + 0xF) & 0xFFFFFFF0; |
| } |
| |
| inline int ceilInt4(int x) |
| { |
| return (x + 0xF) >> 4; |
| } |
| |
| #define BITS(x) ( \ |
| !!(x & 0x80000000) + \ |
| !!(x & 0xC0000000) + \ |
| !!(x & 0xE0000000) + \ |
| !!(x & 0xF0000000) + \ |
| !!(x & 0xF8000000) + \ |
| !!(x & 0xFC000000) + \ |
| !!(x & 0xFE000000) + \ |
| !!(x & 0xFF000000) + \ |
| !!(x & 0xFF800000) + \ |
| !!(x & 0xFFC00000) + \ |
| !!(x & 0xFFE00000) + \ |
| !!(x & 0xFFF00000) + \ |
| !!(x & 0xFFF80000) + \ |
| !!(x & 0xFFFC0000) + \ |
| !!(x & 0xFFFE0000) + \ |
| !!(x & 0xFFFF0000) + \ |
| !!(x & 0xFFFF8000) + \ |
| !!(x & 0xFFFFC000) + \ |
| !!(x & 0xFFFFE000) + \ |
| !!(x & 0xFFFFF000) + \ |
| !!(x & 0xFFFFF800) + \ |
| !!(x & 0xFFFFFC00) + \ |
| !!(x & 0xFFFFFE00) + \ |
| !!(x & 0xFFFFFF00) + \ |
| !!(x & 0xFFFFFF80) + \ |
| !!(x & 0xFFFFFFC0) + \ |
| !!(x & 0xFFFFFFE0) + \ |
| !!(x & 0xFFFFFFF0) + \ |
| !!(x & 0xFFFFFFF8) + \ |
| !!(x & 0xFFFFFFFC) + \ |
| !!(x & 0xFFFFFFFE) + \ |
| !!(x & 0xFFFFFFFF)) |
| |
| inline int exp2(int x) |
| { |
| return 1 << x; |
| } |
| |
| inline unsigned long log2(int x) |
| { |
| unsigned long y; |
| |
| _BitScanReverse(&y, x); |
| |
| return y; |
| } |
| |
| inline int ilog2(float x) |
| { |
| unsigned int y = *(unsigned int*)&x; |
| |
| return ((y & 0x7F800000) >> 23) - 127; |
| } |
| |
| inline float log2(float x) |
| { |
| unsigned int y = (*(unsigned int*)&x); |
| |
| return (float)((y & 0x7F800000) >> 23) - 127 + (float)((*(unsigned int*)&x) & 0x007FFFFF) / 16777216.0f; |
| } |
| |
| inline bool isPow2(int x) |
| { |
| return (x & -x) == x; |
| } |
| |
| template<class T> |
| inline T clamp(T x, T a, T b) |
| { |
| if(x < a) x = a; |
| if(x > b) x = b; |
| |
| return x; |
| } |
| |
| inline int ceilPow2(int x) |
| { |
| int i = 1; |
| |
| while(i < x) |
| { |
| i <<= 1; |
| } |
| |
| return i; |
| } |
| |
| inline int floorDiv(int a, int b) |
| { |
| return a / b + ((a % b) >> 31); |
| } |
| |
| inline int floorMod(int a, int b) |
| { |
| int r = a % b; |
| return r + ((r >> 31) & b); |
| } |
| |
| inline int ceilDiv(int a, int b) |
| { |
| return a / b - (-(a % b) >> 31); |
| } |
| |
| inline int ceilMod(int a, int b) |
| { |
| int r = a % b; |
| return r - ((-r >> 31) & b); |
| } |
| |
| template<const int n> |
| inline unsigned int unorm(float x) |
| { |
| const unsigned int max = 0xFFFFFFFF >> (32 - n); |
| |
| if(x > 1) |
| { |
| return max; |
| } |
| else if(x < 0) |
| { |
| return 0; |
| } |
| else |
| { |
| return (unsigned int)(max * x + 0.5f); |
| } |
| } |
| |
| template<const int n> |
| inline int snorm(float x) |
| { |
| const unsigned int min = 0x80000000 >> (32 - n); |
| const unsigned int max = 0xFFFFFFFF >> (32 - n + 1); |
| const unsigned int range = 0xFFFFFFFF >> (32 - n); |
| |
| if(x > 0) |
| { |
| if(x > 1) |
| { |
| return max; |
| } |
| else |
| { |
| return (int)(max * x + 0.5f); |
| } |
| } |
| else |
| { |
| if(x < -1) |
| { |
| return min; |
| } |
| else |
| { |
| return (int)(max * x - 0.5f) & range; |
| } |
| } |
| } |
| |
| inline float sRGBtoLinear(float c) |
| { |
| if(c <= 0.04045f) |
| { |
| return c * 0.07739938f; // 1.0f / 12.92f; |
| } |
| else |
| { |
| return powf((c + 0.055f) * 0.9478673f, 2.4f); // 1.0f / 1.055f |
| } |
| } |
| |
| inline float linearToSRGB(float c) |
| { |
| if(c <= 0.0031308f) |
| { |
| return c * 12.92f; |
| } |
| else |
| { |
| return 1.055f * powf(c, 0.4166667f) - 0.055f; // 1.0f / 2.4f |
| } |
| } |
| |
| int64_t FNV_1(const unsigned char *data, int size); // Fowler-Noll-Vo hash function |
| } |
| |
| #endif // sw_Math_hpp |