1d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// 3d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Licensed under the Apache License, Version 2.0 (the "License"); 4d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// you may not use this file except in compliance with the License. 5d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// You may obtain a copy of the License at 6d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// 7d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// http://www.apache.org/licenses/LICENSE-2.0 8d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// 9d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Unless required by applicable law or agreed to in writing, software 10d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// distributed under the License is distributed on an "AS IS" BASIS, 11d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// See the License for the specific language governing permissions and 13d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// limitations under the License. 14d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 15d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#ifndef sw_Math_hpp 16d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#define sw_Math_hpp 17d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 18d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#include "Types.hpp" 19d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 20d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#include <cmath> 21d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#if defined(_MSC_VER) 22d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens #include <intrin.h> 23d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#endif 24d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 25d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capensnamespace sw 26d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens{ 27d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens using std::abs; 28d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 29d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens #undef min 30d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens #undef max 31d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 32d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens template<class T> 33d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline T max(T a, T b) 34d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 35d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return a > b ? a : b; 36d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 37d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 38d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens template<class T> 39d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline T min(T a, T b) 40d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 41d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return a < b ? a : b; 42d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 43d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 44d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens template<class T> 45d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline T max(T a, T b, T c) 46d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 47d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return max(max(a, b), c); 48d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 49d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 50d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens template<class T> 51d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline T min(T a, T b, T c) 52d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 53d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return min(min(a, b), c); 54d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 55d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 56d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens template<class T> 57d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline T max(T a, T b, T c, T d) 58d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 59d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return max(max(a, b), max(c, d)); 60d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 61d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 62d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens template<class T> 63d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline T min(T a, T b, T c, T d) 64d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 65d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return min(min(a, b), min(c, d)); 66d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 67d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 68d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens template<class T> 69d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline void swap(T &a, T &b) 70d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 71d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens T t = a; 72d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens a = b; 73d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens b = t; 74d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 75d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 76d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int iround(float x) 77d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 78d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return (int)floor(x + 0.5f); 79d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // return _mm_cvtss_si32(_mm_load_ss(&x)); // FIXME: Demands SSE support 80d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 81d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 82d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int ifloor(float x) 83d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 84d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return (int)floor(x); 85d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 86d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 87d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int ceilFix4(int x) 88d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 89d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return (x + 0xF) & 0xFFFFFFF0; 90d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 91d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 92d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int ceilInt4(int x) 93d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 94d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return (x + 0xF) >> 4; 95d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 96d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 97d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens #define BITS(x) ( \ 98d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0x80000000) + \ 99d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xC0000000) + \ 100d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xE0000000) + \ 101d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xF0000000) + \ 102d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xF8000000) + \ 103d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFC000000) + \ 104d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFE000000) + \ 105d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFF000000) + \ 106d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFF800000) + \ 107d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFC00000) + \ 108d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFE00000) + \ 109d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFF00000) + \ 110d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFF80000) + \ 111d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFC0000) + \ 112d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFE0000) + \ 113d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFF0000) + \ 114d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFF8000) + \ 115d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFC000) + \ 116d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFE000) + \ 117d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFF000) + \ 118d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFF800) + \ 119d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFFC00) + \ 120d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFFE00) + \ 121d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFFF00) + \ 122d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFFF80) + \ 123d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFFFC0) + \ 124d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFFFE0) + \ 125d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFFFF0) + \ 126d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFFFF8) + \ 127d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFFFFC) + \ 128d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFFFFE) + \ 129d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens !!((x) & 0xFFFFFFFF)) 130d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 131d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens #define MAX(x, y) ((x) > (y) ? (x) : (y)) 132d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens #define MIN(x, y) ((x) < (y) ? (x) : (y)) 133d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 134d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline float exp2(float x) 135d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 136d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return exp2f(x); 137d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 138d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 139d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int exp2(int x) 140d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 141d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return 1 << x; 142d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 143d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 144d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline unsigned long log2(int x) 145d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 146d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens #if defined(_MSC_VER) 147d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned long y; 148d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens _BitScanReverse(&y, x); 149d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return y; 150d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens #else 151d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return 31 - __builtin_clz(x); 152d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens #endif 153d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 154d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 155d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int ilog2(float x) 156d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 157d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int y = *(unsigned int*)&x; 158d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 159d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return ((y & 0x7F800000) >> 23) - 127; 160d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 161d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 162d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline float log2(float x) 163d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 164d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return logf(x) * 1.44269504f; // 1.0 / log[e](2) 165d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 166d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 167d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline bool isPow2(int x) 168d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 169d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return (x & -x) == x; 170d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 171d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 172d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens template<class T> 173d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline T clamp(T x, T a, T b) 174d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 175d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(x < a) x = a; 176d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(x > b) x = b; 177d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 178d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return x; 179d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 180d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 181d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline float clamp01(float x) 182d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 183d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return clamp(x, 0.0f, 1.0f); 184d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 185d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 186d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int ceilPow2(int x) 187d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 188d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens int i = 1; 189d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 190d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens while(i < x) 191d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 192d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens i <<= 1; 193d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 194d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 195d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return i; 196d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 197d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 198d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int floorDiv(int a, int b) 199d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 200d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return a / b + ((a % b) >> 31); 201d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 202d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 203d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int floorMod(int a, int b) 204d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 205d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens int r = a % b; 206d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return r + ((r >> 31) & b); 207d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 208d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 209d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int ceilDiv(int a, int b) 210d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 211d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return a / b - (-(a % b) >> 31); 212d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 213d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 214d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int ceilMod(int a, int b) 215d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 216d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens int r = a % b; 217d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return r - ((-r >> 31) & b); 218d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 219d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 220d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens template<const int n> 221d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline unsigned int unorm(float x) 222d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 223d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static const unsigned int max = 0xFFFFFFFF >> (32 - n); 224d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static const float maxf = static_cast<float>(max); 225d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 226d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(x >= 1.0f) 227d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 228d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return max; 229d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 230d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else if(x <= 0.0f) 231d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 232d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return 0; 233d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 234d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 235d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 236d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return static_cast<unsigned int>(maxf * x + 0.5f); 237d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 238d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 239d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 240d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens template<const int n> 241d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int snorm(float x) 242d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 243d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static const unsigned int min = 0x80000000 >> (32 - n); 244d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static const unsigned int max = 0xFFFFFFFF >> (32 - n + 1); 245d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static const float maxf = static_cast<float>(max); 246d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static const unsigned int range = 0xFFFFFFFF >> (32 - n); 247d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 248d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(x >= 0.0f) 249d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 250d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(x >= 1.0f) 251d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 252d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return max; 253d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 254d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 255d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 256d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return static_cast<int>(maxf * x + 0.5f); 257d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 258d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 259d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 260d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 261d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(x <= -1.0f) 262d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 263d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return min; 264d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 265d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 266d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 267d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return static_cast<int>(maxf * x - 0.5f) & range; 268d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 269d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 270d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 271d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 272d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens template<const int n> 273d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline unsigned int ucast(float x) 274d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 275d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static const unsigned int max = 0xFFFFFFFF >> (32 - n); 276d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static const float maxf = static_cast<float>(max); 277d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 278d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(x >= maxf) 279d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 280d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return max; 281d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 282d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else if(x <= 0.0f) 283d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 284d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return 0; 285d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 286d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 287d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 288d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return static_cast<unsigned int>(x + 0.5f); 289d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 290d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 291d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 292d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens template<const int n> 293d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int scast(float x) 294d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 295d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static const unsigned int min = 0x80000000 >> (32 - n); 296d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static const unsigned int max = 0xFFFFFFFF >> (32 - n + 1); 297d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static const float maxf = static_cast<float>(max); 298d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static const unsigned int range = 0xFFFFFFFF >> (32 - n); 299d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 300d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(x > 0.0f) 301d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 302d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(x >= maxf) 303d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 304d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return max; 305d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 306d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 307d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 308d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return static_cast<int>(maxf * x + 0.5f); 309d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 310d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 311d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 312d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 313d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(x <= -1.0f) 314d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 315d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return min; 316d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 317d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 318d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 319d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return static_cast<int>(maxf * x - 0.5f) & range; 320d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 321d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 322d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 323d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 324d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline float sRGBtoLinear(float c) 325d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 326d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(c <= 0.04045f) 327d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 328d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return c * 0.07739938f; // 1.0f / 12.92f; 329d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 330d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 331d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 332d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return powf((c + 0.055f) * 0.9478673f, 2.4f); // 1.0f / 1.055f 333d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 334d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 335d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 336d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline float linearToSRGB(float c) 337d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 338d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(c <= 0.0031308f) 339d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 340d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return c * 12.92f; 341d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 342d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 343d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 344d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return 1.055f * powf(c, 0.4166667f) - 0.055f; // 1.0f / 2.4f 345d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 346d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 347d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 348d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned char sRGB8toLinear8(unsigned char value); 349d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 350d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens uint64_t FNV_1a(const unsigned char *data, int size); // Fowler-Noll-Vo hash function 351d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 352d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // Round up to the next multiple of alignment 353d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline unsigned int align(unsigned int value, unsigned int alignment) 354d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 355d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return ((value + alignment - 1) / alignment) * alignment; 356d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 357d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 358d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens inline int clampToSignedInt(unsigned int x) 359d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 360d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return static_cast<int>(min(x, 0x7FFFFFFFu)); 361d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 362d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 363d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens class RGB9E5Data 364d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 365d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int R : 9; 366d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int G : 9; 367d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int B : 9; 368d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int E : 5; 369d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 370d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens public: 371d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void toRGBFloats(float* rgb) const 372d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 373d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static const float Offset = -24.0f; // Exponent Bias (15) + Number of mantissa bits per component (9) = 24 374d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 375d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens const float factor = powf(2.0f, static_cast<float>(E) + Offset); 376d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens rgb[0] = static_cast<float>(R) * factor; 377d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens rgb[1] = static_cast<float>(G) * factor; 378d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens rgb[2] = static_cast<float>(B) * factor; 379d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 380d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens }; 381d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 382d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens class R11G11B10FData 383d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 384d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int R : 11; 385d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int G : 11; 386d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int B : 10; 387d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 388d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static inline float float11ToFloat32(unsigned short fp11) 389d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 390d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned short exponent = (fp11 >> 6) & 0x1F; 391d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned short mantissa = fp11 & 0x3F; 392d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 393d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int output; 394d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(exponent == 0x1F) 395d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 396d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // INF or NAN 397d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens output = 0x7f800000 | (mantissa << 17); 398d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 399d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 400d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 401d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(exponent != 0) 402d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 403d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // normalized 404d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 405d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else if(mantissa != 0) 406d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 407d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // The value is denormalized 408d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens exponent = 1; 409d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 410d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens do 411d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 412d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens exponent--; 413d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens mantissa <<= 1; 414d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } while((mantissa & 0x40) == 0); 415d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 416d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens mantissa = mantissa & 0x3F; 417d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 418d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else // The value is zero 419d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 420d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens exponent = static_cast<unsigned short>(-112); 421d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 422d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 423d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens output = ((exponent + 112) << 23) | (mantissa << 17); 424d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 425d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 426d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return *(float*)(&output); 427d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 428d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 429d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens static inline float float10ToFloat32(unsigned short fp10) 430d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 431d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned short exponent = (fp10 >> 5) & 0x1F; 432d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned short mantissa = fp10 & 0x1F; 433d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 434d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int output; 435d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(exponent == 0x1F) 436d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 437d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // INF or NAN 438d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens output = 0x7f800000 | (mantissa << 17); 439d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 440d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 441d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 442d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(exponent != 0) 443d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 444d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // normalized 445d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 446d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else if(mantissa != 0) 447d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 448d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // The value is denormalized 449d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens exponent = 1; 450d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 451d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens do 452d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 453d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens exponent--; 454d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens mantissa <<= 1; 455d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } while((mantissa & 0x20) == 0); 456d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 457d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens mantissa = mantissa & 0x1F; 458d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 459d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else // The value is zero 460d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 461d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens exponent = static_cast<unsigned short>(-112); 462d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 463d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 464d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens output = ((exponent + 112) << 23) | (mantissa << 18); 465d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 466d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 467d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return *(float*)(&output); 468d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 469d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 470d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens public: 471d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void toRGBFloats(float* rgb) const 472d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 473d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens rgb[0] = float11ToFloat32(R); 474d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens rgb[1] = float11ToFloat32(G); 475d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens rgb[2] = float10ToFloat32(B); 476d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 477d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens }; 478d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens} 479d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 480d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#endif // sw_Math_hpp 481