BsBitwise.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsPrerequisitesUtil.h"
  5. namespace bs
  6. {
  7. /** @addtogroup General
  8. * @{
  9. */
  10. /** Floating point number broken down into components for easier access. */
  11. union Float754
  12. {
  13. UINT32 raw;
  14. float value;
  15. struct {
  16. #if BS_ENDIAN == BS_ENDIAN_BIG
  17. UINT32 negative : 1;
  18. UINT32 exponent : 8;
  19. UINT32 mantissa : 23;
  20. #else
  21. UINT32 mantissa : 23;
  22. UINT32 exponent : 8;
  23. UINT32 negative : 1;
  24. #endif
  25. } field;
  26. };
  27. /** Class for manipulating bit patterns. */
  28. class Bitwise
  29. {
  30. public:
  31. /** Returns the most significant bit set in a value. */
  32. static UINT32 mostSignificantBitSet(unsigned int value)
  33. {
  34. UINT32 result = 0;
  35. while (value != 0) {
  36. ++result;
  37. value >>= 1;
  38. }
  39. return result-1;
  40. }
  41. /** Returns the power-of-two number greater or equal to the provided value. */
  42. static UINT32 nextPow2(UINT32 n)
  43. {
  44. --n;
  45. n |= n >> 16;
  46. n |= n >> 8;
  47. n |= n >> 4;
  48. n |= n >> 2;
  49. n |= n >> 1;
  50. ++n;
  51. return n;
  52. }
  53. /** Returns the power-of-two number closest to the provided value. */
  54. static UINT32 closestPow2(UINT32 n)
  55. {
  56. UINT32 next = nextPow2(n);
  57. UINT32 prev = next >> 1;
  58. if (n - prev < next - n)
  59. return prev;
  60. return next;
  61. }
  62. /** Determines whether the number is power-of-two or not. */
  63. template<typename T>
  64. static bool isPow2(T n)
  65. {
  66. return (n & (n-1)) == 0;
  67. }
  68. /** Returns the number of bits a pattern must be shifted right by to remove right-hand zeros. */
  69. template<typename T>
  70. static unsigned int getBitShift(T mask)
  71. {
  72. if (mask == 0)
  73. return 0;
  74. unsigned int result = 0;
  75. while ((mask & 1) == 0) {
  76. ++result;
  77. mask >>= 1;
  78. }
  79. return result;
  80. }
  81. /** Takes a value with a given src bit mask, and produces another value with a desired bit mask. */
  82. template<typename SrcT, typename DestT>
  83. static DestT convertBitPattern(SrcT srcValue, SrcT srcBitMask, DestT destBitMask)
  84. {
  85. // Mask off irrelevant source value bits (if any)
  86. srcValue = srcValue & srcBitMask;
  87. // Shift source down to bottom of DWORD
  88. const unsigned int srcBitShift = getBitShift(srcBitMask);
  89. srcValue >>= srcBitShift;
  90. // Get max value possible in source from srcMask
  91. const SrcT srcMax = srcBitMask >> srcBitShift;
  92. // Get max available in dest
  93. const unsigned int destBitShift = getBitShift(destBitMask);
  94. const DestT destMax = destBitMask >> destBitShift;
  95. // Scale source value into destination, and shift back
  96. DestT destValue = (srcValue * destMax) / srcMax;
  97. return (destValue << destBitShift);
  98. }
  99. /**
  100. * Convert N bit colour channel value to P bits. It fills P bits with the bit pattern repeated.
  101. * (this is /((1<<n)-1) in fixed point).
  102. */
  103. static unsigned int fixedToFixed(UINT32 value, unsigned int n, unsigned int p)
  104. {
  105. if(n > p)
  106. {
  107. // Less bits required than available; this is easy
  108. value >>= n-p;
  109. }
  110. else if(n < p)
  111. {
  112. // More bits required than are there, do the fill
  113. // Use old fashioned division, probably better than a loop
  114. if(value == 0)
  115. value = 0;
  116. else if(value == (static_cast<unsigned int>(1)<<n)-1)
  117. value = (1<<p)-1;
  118. else value = value*(1<<p)/((1<<n)-1);
  119. }
  120. return value;
  121. }
  122. /**
  123. * Convert floating point color channel value between 0.0 and 1.0 (otherwise clamped) to integer of a certain
  124. * number of bits. Works for any value of bits between 0 and 31.
  125. */
  126. static unsigned int floatToFixed(const float value, const unsigned int bits)
  127. {
  128. if(value <= 0.0f) return 0;
  129. else if (value >= 1.0f) return (1<<bits)-1;
  130. else return (unsigned int)(value * (1<<bits));
  131. }
  132. /** Fixed point to float. */
  133. static float fixedToFloat(unsigned value, unsigned int bits)
  134. {
  135. return (float)value/(float)((1<<bits)-1);
  136. }
  137. /** Write a n*8 bits integer value to memory in native endian. */
  138. static void intWrite(void *dest, const int n, const unsigned int value)
  139. {
  140. switch(n) {
  141. case 1:
  142. ((UINT8*)dest)[0] = (UINT8)value;
  143. break;
  144. case 2:
  145. ((UINT16*)dest)[0] = (UINT16)value;
  146. break;
  147. case 3:
  148. #if BS_ENDIAN == BS_ENDIAN_BIG
  149. ((UINT8*)dest)[0] = (UINT8)((value >> 16) & 0xFF);
  150. ((UINT8*)dest)[1] = (UINT8)((value >> 8) & 0xFF);
  151. ((UINT8*)dest)[2] = (UINT8)(value & 0xFF);
  152. #else
  153. ((UINT8*)dest)[2] = (UINT8)((value >> 16) & 0xFF);
  154. ((UINT8*)dest)[1] = (UINT8)((value >> 8) & 0xFF);
  155. ((UINT8*)dest)[0] = (UINT8)(value & 0xFF);
  156. #endif
  157. break;
  158. case 4:
  159. ((UINT32*)dest)[0] = (UINT32)value;
  160. break;
  161. }
  162. }
  163. /** Read a n*8 bits integer value to memory in native endian. */
  164. static unsigned int intRead(const void *src, int n) {
  165. switch(n) {
  166. case 1:
  167. return ((UINT8*)src)[0];
  168. case 2:
  169. return ((UINT16*)src)[0];
  170. case 3:
  171. #if BS_ENDIAN == BS_ENDIAN_BIG
  172. return ((UINT32)((UINT8*)src)[0]<<16)|
  173. ((UINT32)((UINT8*)src)[1]<<8)|
  174. ((UINT32)((UINT8*)src)[2]);
  175. #else
  176. return ((UINT32)((UINT8*)src)[0])|
  177. ((UINT32)((UINT8*)src)[1]<<8)|
  178. ((UINT32)((UINT8*)src)[2]<<16);
  179. #endif
  180. case 4:
  181. return ((UINT32*)src)[0];
  182. }
  183. return 0; // ?
  184. }
  185. /** Convert a float32 to a float16 (NV_half_float). */
  186. static UINT16 floatToHalf(float i)
  187. {
  188. union { float f; UINT32 i; } v;
  189. v.f = i;
  190. return floatToHalfI(v.i);
  191. }
  192. /** Converts float in UINT32 format to a a half in UINT16 format. */
  193. static UINT16 floatToHalfI(UINT32 i)
  194. {
  195. int s = (i >> 16) & 0x00008000;
  196. int e = ((i >> 23) & 0x000000ff) - (127 - 15);
  197. int m = i & 0x007fffff;
  198. if (e <= 0)
  199. {
  200. if (e < -10)
  201. {
  202. return 0;
  203. }
  204. m = (m | 0x00800000) >> (1 - e);
  205. return static_cast<UINT16>(s | (m >> 13));
  206. }
  207. else if (e == 0xff - (127 - 15))
  208. {
  209. if (m == 0) // Inf
  210. {
  211. return static_cast<UINT16>(s | 0x7c00);
  212. }
  213. else // NAN
  214. {
  215. m >>= 13;
  216. return static_cast<UINT16>(s | 0x7c00 | m | (m == 0));
  217. }
  218. }
  219. else
  220. {
  221. if (e > 30) // Overflow
  222. {
  223. return static_cast<UINT16>(s | 0x7c00);
  224. }
  225. return static_cast<UINT16>(s | (e << 10) | (m >> 13));
  226. }
  227. }
  228. /** Convert a float16 (NV_half_float) to a float32. */
  229. static float halfToFloat(UINT16 y)
  230. {
  231. union { float f; UINT32 i; } v;
  232. v.i = halfToFloatI(y);
  233. return v.f;
  234. }
  235. /** Converts a half in UINT16 format to a float in UINT32 format. */
  236. static UINT32 halfToFloatI(UINT16 y)
  237. {
  238. int s = (y >> 15) & 0x00000001;
  239. int e = (y >> 10) & 0x0000001f;
  240. int m = y & 0x000003ff;
  241. if (e == 0)
  242. {
  243. if (m == 0) // Plus or minus zero
  244. {
  245. return s << 31;
  246. }
  247. else // Denormalized number -- renormalize it
  248. {
  249. while (!(m & 0x00000400))
  250. {
  251. m <<= 1;
  252. e -= 1;
  253. }
  254. e += 1;
  255. m &= ~0x00000400;
  256. }
  257. }
  258. else if (e == 31)
  259. {
  260. if (m == 0) // Inf
  261. {
  262. return (s << 31) | 0x7f800000;
  263. }
  264. else // NaN
  265. {
  266. return (s << 31) | 0x7f800000 | (m << 13);
  267. }
  268. }
  269. e = e + (127 - 15);
  270. m = m << 13;
  271. return (s << 31) | (e << 23) | m;
  272. }
  273. /** Converts a 32-bit float to a 10-bit float according to OpenGL packed_float extension. */
  274. static UINT32 floatToFloat10(float v)
  275. {
  276. Float754 f;
  277. f.value = v;
  278. if (f.field.exponent == 0xFF)
  279. {
  280. // NAN or INF
  281. if (f.field.mantissa > 0)
  282. return 0x3E0 | (((f.raw >> 18) | (f.raw >> 13) | (f.raw >> 3) | f.raw) & 0x1F);
  283. else if (f.field.negative)
  284. return 0; // Negative infinity clamped to 0
  285. else
  286. return 0x3E0; // Positive infinity
  287. }
  288. else if (f.field.negative)
  289. return 0; // Negative clamped to 0, no negatives allowed
  290. else if (f.raw > 0x477C0000)
  291. return 0x3DF; // Too large, clamp to max value
  292. else
  293. {
  294. UINT32 val;
  295. if (f.raw < 0x38800000U)
  296. {
  297. // Too small to be represented as a normalized float, convert to denormalized value
  298. UINT32 shift = 113 - f.field.exponent;
  299. val = (0x800000U | f.field.mantissa) >> shift;
  300. }
  301. else
  302. {
  303. // Rebias exponent
  304. val = f.raw + 0xC8000000;
  305. }
  306. return ((val + 0x1FFFFU + ((val >> 18) & 1)) >> 18) & 0x3FF;
  307. }
  308. }
  309. /** Converts a 32-bit float to a 11-bit float according to OpenGL packed_float extension. */
  310. static UINT32 floatToFloat11(float v)
  311. {
  312. Float754 f;
  313. f.value = v;
  314. if (f.field.exponent == 0xFF)
  315. {
  316. // NAN or INF
  317. if (f.field.mantissa > 0)
  318. return 0x7C0 | (((f.raw >> 17) | (f.raw >> 11) | (f.raw >> 6) | f.raw) & 0x3F);
  319. else if (f.field.negative)
  320. return 0; // Negative infinity clamped to 0
  321. else
  322. return 0x7C0; // Positive infinity
  323. }
  324. else if (f.field.negative)
  325. return 0; // Negative clamped to 0, no negatives allowed
  326. else if (f.raw > 0x477E0000)
  327. return 0x7BF; // Too large, clamp to max value
  328. else
  329. {
  330. UINT32 val;
  331. if(f.raw < 0x38800000U)
  332. {
  333. // Too small to be represented as a normalized float, convert to denormalized value
  334. UINT32 shift = 113 - f.field.exponent;
  335. val = (0x800000U | f.field.mantissa) >> shift;
  336. }
  337. else
  338. {
  339. // Rebias exponent
  340. val = f.raw + 0xC8000000;
  341. }
  342. return ((val + 0xFFFFU + ((val >> 17) & 1)) >> 17) & 0x7FF;
  343. }
  344. }
  345. };
  346. /** @} */
  347. }