14f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com//
22e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
34f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be
44f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com// found in the LICENSE file.
54f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com//
64f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
74f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com// mathutil.h: Math and bit manipulation functions.
84f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
94f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com#ifndef LIBGLESV2_MATHUTIL_H_
104f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com#define LIBGLESV2_MATHUTIL_H_
114f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
12c194d530aed3f79286209c8359ce7f89733f9b08shannonwoods@chromium.org#include <intrin.h>
13c194d530aed3f79286209c8359ce7f89733f9b08shannonwoods@chromium.org
14a9b96d0d3198152e195a97b0a8b0ac31fe436b5ashannon.woods@transgaming.com#include "common/system.h"
15b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.com#include "common/debug.h"
164f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
174f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.comnamespace gl
184f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
1960dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.orgstruct Vector4
2060dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org{
2160dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org    Vector4() {}
2260dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org    Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
2360dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org
2460dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org    float x;
2560dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org    float y;
2660dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org    float z;
2760dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org    float w;
2860dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org};
2960dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org
304f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.cominline bool isPow2(int x)
314f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
324f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    return (x & (x - 1)) == 0 && (x != 0);
334f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
344f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
354f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.cominline int log2(int x)
364f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
374f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    int r = 0;
38e2b2212912010fafc2675485f8ddd67c6b29130ddaniel@transgaming.com    while ((x >> r) > 1) r++;
394f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    return r;
404f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
414f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
4281655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.cominline unsigned int ceilPow2(unsigned int x)
4381655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com{
4481655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com    if (x != 0) x--;
4581655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com    x |= x >> 1;
4681655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com    x |= x >> 2;
4781655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com    x |= x >> 4;
4881655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com    x |= x >> 8;
4981655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com    x |= x >> 16;
5081655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com    x++;
5181655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com
5281655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com    return x;
5381655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com}
5481655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com
55b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.orgtemplate<typename T, typename MIN, typename MAX>
56b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.orginline T clamp(T x, MIN min, MAX max)
57b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.org{
5831c4f2354382991a2f199d2584ec17bd3db0ae8dshannon.woods@transgaming.com    // Since NaNs fail all comparison tests, a NaN value will default to min
5931c4f2354382991a2f199d2584ec17bd3db0ae8dshannon.woods@transgaming.com    return x > min ? (x > max ? max : x) : min;
60b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.org}
61b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.org
624f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.cominline float clamp01(float x)
634f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
64b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.org    return clamp(x, 0.0f, 1.0f);
654f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
664f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
674f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.comtemplate<const int n>
684f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.cominline unsigned int unorm(float x)
694f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com{
704f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    const unsigned int max = 0xFFFFFFFF >> (32 - n);
714f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
72e2b2212912010fafc2675485f8ddd67c6b29130ddaniel@transgaming.com    if (x > 1)
734f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    {
744f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com        return max;
754f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    }
76e2b2212912010fafc2675485f8ddd67c6b29130ddaniel@transgaming.com    else if (x < 0)
774f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    {
784f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com        return 0;
794f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    }
804f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    else
814f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    {
824f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com        return (unsigned int)(max * x + 0.5f);
834f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com    }
844f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
85b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.org
86f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.orginline bool supportsSSE2()
87f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org{
88f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org    static bool checked = false;
89f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org    static bool supports = false;
90f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org
91f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org    if (checked)
92f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org    {
93f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org        return supports;
94f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org    }
95f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org
96f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org    int info[4];
97f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org    __cpuid(info, 0);
98f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org
99f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org    if (info[0] >= 1)
100f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org    {
101f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org        __cpuid(info, 1);
102f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org
103f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org        supports = (info[3] >> 26) & 1;
104f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org    }
105f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org
106f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org    checked = true;
107f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org
108f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org    return supports;
109f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org}
110aa48067ac8125da0a96b10be3ea6e9df0fbaab43apatrick@chromium.org
1112e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.cominline unsigned short float32ToFloat16(float fp32)
1122e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com{
1132e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com    unsigned int fp32i = (unsigned int&)fp32;
1142e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com    unsigned int sign = (fp32i & 0x80000000) >> 16;
1152e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com    unsigned int abs = fp32i & 0x7FFFFFFF;
1162e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com
1172e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com    if(abs > 0x47FFEFFF)   // Infinity
1182e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com    {
1192e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com        return sign | 0x7FFF;
1202e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com    }
1212e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com    else if(abs < 0x38800000)   // Denormal
1222e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com    {
1232e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com        unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000;
1242e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com        int e = 113 - (abs >> 23);
1252e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com
1262e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com        if(e < 24)
1272e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com        {
1282e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com            abs = mantissa >> e;
1292e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com        }
1302e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com        else
1312e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com        {
1322e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com            abs = 0;
1332e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com        }
1342e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com
1352e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com        return sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13;
1362e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com    }
1372e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com    else
1382e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com    {
1392e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com        return sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13;
1402e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com    }
1412e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com}
1422e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com
143aa48067ac8125da0a96b10be3ea6e9df0fbaab43apatrick@chromium.orgfloat float16ToFloat32(unsigned short h);
144aa48067ac8125da0a96b10be3ea6e9df0fbaab43apatrick@chromium.org
1454f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com}
1464f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com
147b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.comnamespace rx
148b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.com{
149b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.com
150b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.comstruct Range
151b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.com{
152b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.com    Range() {}
153b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.com    Range(int lo, int hi) : start(lo), end(hi) { ASSERT(lo <= hi); }
154b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.com
155b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.com    int start;
156b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.com    int end;
157b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.com};
158b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.com
159b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.com}
160b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.com
1614f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com#endif   // LIBGLESV2_MATHUTIL_H_
162