2
0

BsBitwise.h 13 KB

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