123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #ifndef CRY_HALF_INL
- #define CRY_HALF_INL
- #pragma once
- typedef uint16 CryHalf;
- typedef union floatint_union
- {
- float f;
- uint32 i;
- } floatint_union;
- __forceinline CryHalf CryConvertFloatToHalf(const float Value)
- {
- #if defined(LINUX) || defined(MAC)
- asm volatile("" ::: "memory");
- #endif
- unsigned int Result;
- unsigned int IValue = ((unsigned int*)(&Value))[0];
- unsigned int Sign = (IValue & 0x80000000U) >> 16U;
- IValue = IValue & 0x7FFFFFFFU; // Hack off the sign
- if (IValue > 0x47FFEFFFU)
- {
- // The number is too large to be represented as a half. Saturate to infinity.
- Result = 0x7FFFU;
- }
- else
- {
- if (IValue < 0x38800000U)
- {
- // The number is too small to be represented as a normalized half.
- // Convert it to a denormalized value.
- unsigned int Shift = 113U - (IValue >> 23U);
- IValue = (0x800000U | (IValue & 0x7FFFFFU)) >> Shift;
- }
- else
- {
- // Rebias the exponent to represent the value as a normalized half.
- IValue += 0xC8000000U;
- }
- Result = ((IValue + 0x0FFFU + ((IValue >> 13U) & 1U)) >> 13U) & 0x7FFFU;
- }
- return (CryHalf)(Result | Sign);
- }
- __forceinline float CryConvertHalfToFloat(const CryHalf Value)
- {
- #if defined(LINUX) || defined(MAC)
- asm volatile("" ::: "memory");
- #endif
- unsigned int Mantissa;
- unsigned int Exponent;
- unsigned int Result;
- Mantissa = (unsigned int)(Value & 0x03FF);
- if ((Value & 0x7C00) != 0) // The value is normalized
- {
- Exponent = (unsigned int)((Value >> 10) & 0x1F);
- }
- else if (Mantissa != 0) // The value is denormalized
- {
- // Normalize the value in the resulting float
- Exponent = 1;
- do
- {
- Exponent--;
- Mantissa <<= 1;
- } while ((Mantissa & 0x0400) == 0);
- Mantissa &= 0x03FF;
- }
- else // The value is zero
- {
- Exponent = (unsigned int)-112;
- }
- Result = ((Value & 0x8000) << 16) | // Sign
- ((Exponent + 112) << 23) | // Exponent
- (Mantissa << 13); // Mantissa
- return *(float*)&Result;
- }
- struct CryHalf2
- {
- CryHalf x;
- CryHalf y;
- CryHalf2()
- {
- }
- CryHalf2(CryHalf _x, CryHalf _y)
- : x(_x)
- , y(_y)
- {
- }
- CryHalf2(const CryHalf* const __restrict pArray)
- {
- x = pArray[0];
- y = pArray[1];
- }
- CryHalf2(float _x, float _y)
- {
- x = CryConvertFloatToHalf(_x);
- y = CryConvertFloatToHalf(_y);
- }
- CryHalf2(const float* const __restrict pArray)
- {
- x = CryConvertFloatToHalf(pArray[0]);
- y = CryConvertFloatToHalf(pArray[1]);
- }
- CryHalf2& operator= (const CryHalf2& Half2)
- {
- x = Half2.x;
- y = Half2.y;
- return *this;
- }
- bool operator !=(const CryHalf2& rhs) const
- {
- return x != rhs.x || y != rhs.y;
- }
- };
- struct CryHalf4
- {
- CryHalf x;
- CryHalf y;
- CryHalf z;
- CryHalf w;
- CryHalf4()
- {
- }
- CryHalf4(CryHalf _x, CryHalf _y, CryHalf _z, CryHalf _w)
- : x(_x)
- , y(_y)
- , z(_z)
- , w(_w)
- {
- }
- CryHalf4(const CryHalf* const __restrict pArray)
- {
- x = pArray[0];
- y = pArray[1];
- z = pArray[2];
- w = pArray[3];
- }
- CryHalf4(float _x, float _y, float _z, float _w)
- {
- x = CryConvertFloatToHalf(_x);
- y = CryConvertFloatToHalf(_y);
- z = CryConvertFloatToHalf(_z);
- w = CryConvertFloatToHalf(_w);
- }
- CryHalf4(const float* const __restrict pArray)
- {
- x = CryConvertFloatToHalf(pArray[0]);
- y = CryConvertFloatToHalf(pArray[1]);
- z = CryConvertFloatToHalf(pArray[2]);
- w = CryConvertFloatToHalf(pArray[3]);
- }
- CryHalf4& operator= (const CryHalf4& Half4)
- {
- x = Half4.x;
- y = Half4.y;
- z = Half4.z;
- w = Half4.w;
- return *this;
- }
- bool operator !=(const CryHalf4& rhs) const
- {
- return x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w;
- }
- };
- #endif // #ifndef CRY_HALF_INL
|