192b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org// 292b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. 392b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org// Use of this source code is governed by a BSD-style license that can be 492b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org// found in the LICENSE file. 592b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org// 692b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 792b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org// mathutil.cpp: Math and bit manipulation functions. 892b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 992b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org#include "common/mathutil.h" 100b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang 1117732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include <algorithm> 124f26786863c81244acdd5b36738ae25e2c56b312Jamie Madill#include <math.h> 1392b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 1492b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.orgnamespace gl 1592b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org{ 1692b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 1792b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.orgstruct RGB9E5Data 1892b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org{ 1992b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org unsigned int R : 9; 2092b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org unsigned int G : 9; 2192b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org unsigned int B : 9; 2292b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org unsigned int E : 5; 2392b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org}; 2492b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 2592b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org// B is the exponent bias (15) 2692b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.orgstatic const int g_sharedexp_bias = 15; 2792b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 2892b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org// N is the number of mantissa bits per component (9) 2992b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.orgstatic const int g_sharedexp_mantissabits = 9; 3092b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 3192b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org// Emax is the maximum allowed biased exponent value (31) 3292b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.orgstatic const int g_sharedexp_maxexponent = 31; 3392b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 3492b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.orgstatic const float g_sharedexp_max = ((pow(2.0f, g_sharedexp_mantissabits) - 1) / 3592b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org pow(2.0f, g_sharedexp_mantissabits)) * 3692b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org pow(2.0f, g_sharedexp_maxexponent - g_sharedexp_bias); 3792b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 3892b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.orgunsigned int convertRGBFloatsTo999E5(float red, float green, float blue) 3992b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org{ 4092b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org const float red_c = std::max<float>(0, std::min(g_sharedexp_max, red)); 4192b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org const float green_c = std::max<float>(0, std::min(g_sharedexp_max, green)); 4292b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org const float blue_c = std::max<float>(0, std::min(g_sharedexp_max, blue)); 4392b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 4492b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org const float max_c = std::max<float>(std::max<float>(red_c, green_c), blue_c); 4592b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org const float exp_p = std::max<float>(-g_sharedexp_bias - 1, floor(log(max_c))) + 1 + g_sharedexp_bias; 4692b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org const int max_s = floor((max_c / (pow(2.0f, exp_p - g_sharedexp_bias - g_sharedexp_mantissabits))) + 0.5f); 4792b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org const int exp_s = (max_s < pow(2.0f, g_sharedexp_mantissabits)) ? exp_p : exp_p + 1; 4892b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 4992b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org RGB9E5Data output; 5092b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org output.R = floor((red_c / (pow(2.0f, exp_s - g_sharedexp_bias - g_sharedexp_mantissabits))) + 0.5f); 5192b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org output.G = floor((green_c / (pow(2.0f, exp_s - g_sharedexp_bias - g_sharedexp_mantissabits))) + 0.5f); 5292b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org output.B = floor((blue_c / (pow(2.0f, exp_s - g_sharedexp_bias - g_sharedexp_mantissabits))) + 0.5f); 5392b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org output.E = exp_s; 5492b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 5592b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org return *reinterpret_cast<unsigned int*>(&output); 5692b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org} 5792b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 5892b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.orgvoid convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue) 5992b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org{ 6092b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org const RGB9E5Data *inputData = reinterpret_cast<const RGB9E5Data*>(&input); 6192b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 6292b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org *red = inputData->R * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits); 6392b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org *green = inputData->G * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits); 6492b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org *blue = inputData->B * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits); 6592b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org} 6692b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 6792b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org} 68