BsBitwise.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "Prerequisites/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 color 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. * Converts floating point value in range [0, 1] to an unsigned integer of a certain number of bits. Works for any
  152. * value of bits between 0 and 31.
  153. */
  154. static unsigned int unormToUint(float value, 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. /**
  161. * Converts floating point value in range [-1, 1] to an unsigned integer of a certain number of bits. Works for any
  162. * value of bits between 0 and 31.
  163. */
  164. static unsigned int snormToUint(float value, unsigned int bits)
  165. {
  166. return unormToUint((value + 1.0f) * 0.5f, bits);
  167. }
  168. /** Converts an unsigned integer to a floating point in range [0, 1]. */
  169. static float uintToUnorm(unsigned value, unsigned int bits)
  170. {
  171. return (float)value / (float)((1 << bits) - 1);
  172. }
  173. /** Converts an unsigned integer to a floating point in range [-1, 1]. */
  174. static float uintToSnorm(unsigned value, unsigned int bits)
  175. {
  176. return uintToUnorm(value, bits) * 2.0f - 1.0f;
  177. }
  178. /** Write a n*8 bits integer value to memory in native endian. */
  179. static void intWrite(void *dest, const int n, const unsigned int value)
  180. {
  181. switch(n) {
  182. case 1:
  183. ((UINT8*)dest)[0] = (UINT8)value;
  184. break;
  185. case 2:
  186. ((UINT16*)dest)[0] = (UINT16)value;
  187. break;
  188. case 3:
  189. #if BS_ENDIAN == BS_ENDIAN_BIG
  190. ((UINT8*)dest)[0] = (UINT8)((value >> 16) & 0xFF);
  191. ((UINT8*)dest)[1] = (UINT8)((value >> 8) & 0xFF);
  192. ((UINT8*)dest)[2] = (UINT8)(value & 0xFF);
  193. #else
  194. ((UINT8*)dest)[2] = (UINT8)((value >> 16) & 0xFF);
  195. ((UINT8*)dest)[1] = (UINT8)((value >> 8) & 0xFF);
  196. ((UINT8*)dest)[0] = (UINT8)(value & 0xFF);
  197. #endif
  198. break;
  199. case 4:
  200. ((UINT32*)dest)[0] = (UINT32)value;
  201. break;
  202. }
  203. }
  204. /** Read a n*8 bits integer value to memory in native endian. */
  205. static unsigned int intRead(const void *src, int n) {
  206. switch(n) {
  207. case 1:
  208. return ((UINT8*)src)[0];
  209. case 2:
  210. return ((UINT16*)src)[0];
  211. case 3:
  212. #if BS_ENDIAN == BS_ENDIAN_BIG
  213. return ((UINT32)((UINT8*)src)[0]<<16)|
  214. ((UINT32)((UINT8*)src)[1]<<8)|
  215. ((UINT32)((UINT8*)src)[2]);
  216. #else
  217. return ((UINT32)((UINT8*)src)[0])|
  218. ((UINT32)((UINT8*)src)[1]<<8)|
  219. ((UINT32)((UINT8*)src)[2]<<16);
  220. #endif
  221. case 4:
  222. return ((UINT32*)src)[0];
  223. }
  224. return 0; // ?
  225. }
  226. /** Convert a float32 to a float16 (NV_half_float). */
  227. static UINT16 floatToHalf(float i)
  228. {
  229. union { float f; UINT32 i; } v;
  230. v.f = i;
  231. return floatToHalfI(v.i);
  232. }
  233. /** Converts float in UINT32 format to a a half in UINT16 format. */
  234. static UINT16 floatToHalfI(UINT32 i)
  235. {
  236. int s = (i >> 16) & 0x00008000;
  237. int e = ((i >> 23) & 0x000000ff) - (127 - 15);
  238. int m = i & 0x007fffff;
  239. if (e <= 0)
  240. {
  241. if (e < -10)
  242. {
  243. return 0;
  244. }
  245. m = (m | 0x00800000) >> (1 - e);
  246. return static_cast<UINT16>(s | (m >> 13));
  247. }
  248. else if (e == 0xff - (127 - 15))
  249. {
  250. if (m == 0) // Inf
  251. {
  252. return static_cast<UINT16>(s | 0x7c00);
  253. }
  254. else // NAN
  255. {
  256. m >>= 13;
  257. return static_cast<UINT16>(s | 0x7c00 | m | (m == 0));
  258. }
  259. }
  260. else
  261. {
  262. if (e > 30) // Overflow
  263. {
  264. return static_cast<UINT16>(s | 0x7c00);
  265. }
  266. return static_cast<UINT16>(s | (e << 10) | (m >> 13));
  267. }
  268. }
  269. /** Convert a float16 (NV_half_float) to a float32. */
  270. static float halfToFloat(UINT16 y)
  271. {
  272. union { float f; UINT32 i; } v;
  273. v.i = halfToFloatI(y);
  274. return v.f;
  275. }
  276. /** Converts a half in UINT16 format to a float in UINT32 format. */
  277. static UINT32 halfToFloatI(UINT16 y)
  278. {
  279. int s = (y >> 15) & 0x00000001;
  280. int e = (y >> 10) & 0x0000001f;
  281. int m = y & 0x000003ff;
  282. if (e == 0)
  283. {
  284. if (m == 0) // Plus or minus zero
  285. {
  286. return s << 31;
  287. }
  288. else // Denormalized number -- renormalize it
  289. {
  290. while (!(m & 0x00000400))
  291. {
  292. m <<= 1;
  293. e -= 1;
  294. }
  295. e += 1;
  296. m &= ~0x00000400;
  297. }
  298. }
  299. else if (e == 31)
  300. {
  301. if (m == 0) // Inf
  302. {
  303. return (s << 31) | 0x7f800000;
  304. }
  305. else // NaN
  306. {
  307. return (s << 31) | 0x7f800000 | (m << 13);
  308. }
  309. }
  310. e = e + (127 - 15);
  311. m = m << 13;
  312. return (s << 31) | (e << 23) | m;
  313. }
  314. /** Converts a 32-bit float to a 10-bit float according to OpenGL packed_float extension. */
  315. static UINT32 floatToFloat10(float v)
  316. {
  317. Float754 f;
  318. f.value = v;
  319. if (f.field.exponent == 0xFF)
  320. {
  321. // NAN or INF
  322. if (f.field.mantissa > 0)
  323. return 0x3E0 | (((f.raw >> 18) | (f.raw >> 13) | (f.raw >> 3) | f.raw) & 0x1F);
  324. else if (f.field.negative)
  325. return 0; // Negative infinity clamped to 0
  326. else
  327. return 0x3E0; // Positive infinity
  328. }
  329. else if (f.field.negative)
  330. return 0; // Negative clamped to 0, no negatives allowed
  331. else if (f.raw > 0x477C0000)
  332. return 0x3DF; // Too large, clamp to max value
  333. else
  334. {
  335. UINT32 val;
  336. if (f.raw < 0x38800000U)
  337. {
  338. // Too small to be represented as a normalized float, convert to denormalized value
  339. UINT32 shift = 113 - f.field.exponent;
  340. val = (0x800000U | f.field.mantissa) >> shift;
  341. }
  342. else
  343. {
  344. // Rebias exponent
  345. val = f.raw + 0xC8000000;
  346. }
  347. return ((val + 0x1FFFFU + ((val >> 18) & 1)) >> 18) & 0x3FF;
  348. }
  349. }
  350. /** Converts a 32-bit float to a 11-bit float according to OpenGL packed_float extension. */
  351. static UINT32 floatToFloat11(float v)
  352. {
  353. Float754 f;
  354. f.value = v;
  355. if (f.field.exponent == 0xFF)
  356. {
  357. // NAN or INF
  358. if (f.field.mantissa > 0)
  359. return 0x7C0 | (((f.raw >> 17) | (f.raw >> 11) | (f.raw >> 6) | f.raw) & 0x3F);
  360. else if (f.field.negative)
  361. return 0; // Negative infinity clamped to 0
  362. else
  363. return 0x7C0; // Positive infinity
  364. }
  365. else if (f.field.negative)
  366. return 0; // Negative clamped to 0, no negatives allowed
  367. else if (f.raw > 0x477E0000)
  368. return 0x7BF; // Too large, clamp to max value
  369. else
  370. {
  371. UINT32 val;
  372. if(f.raw < 0x38800000U)
  373. {
  374. // Too small to be represented as a normalized float, convert to denormalized value
  375. UINT32 shift = 113 - f.field.exponent;
  376. val = (0x800000U | f.field.mantissa) >> shift;
  377. }
  378. else
  379. {
  380. // Rebias exponent
  381. val = f.raw + 0xC8000000;
  382. }
  383. return ((val + 0xFFFFU + ((val >> 17) & 1)) >> 17) & 0x7FF;
  384. }
  385. }
  386. /** Converts a 10-bit float to a 32-bit float according to OpenGL packed_float extension. */
  387. static float float10ToFloat(UINT32 v)
  388. {
  389. Float10 f;
  390. f.raw = v;
  391. UINT32 output;
  392. if (f.field.exponent == 0x1F) // INF or NAN
  393. {
  394. output = 0x7f800000 | (f.field.mantissa << 17);
  395. }
  396. else
  397. {
  398. UINT32 exponent;
  399. UINT32 mantissa = f.field.mantissa;
  400. if (f.field.exponent != 0) // The value is normalized
  401. exponent = f.field.exponent;
  402. else if (mantissa != 0) // The value is denormalized
  403. {
  404. // Normalize the value in the resulting float
  405. exponent = 1;
  406. do
  407. {
  408. exponent--;
  409. mantissa <<= 1;
  410. } while ((mantissa & 0x20) == 0);
  411. mantissa &= 0x1F;
  412. }
  413. else // The value is zero
  414. exponent = (UINT32)-112;
  415. output = ((exponent + 112) << 23) | (mantissa << 18);
  416. }
  417. return *(float*)&output;
  418. }
  419. /** Converts a 11-bit float to a 32-bit float according to OpenGL packed_float extension. */
  420. static float float11ToFloat(UINT32 v)
  421. {
  422. Float11 f;
  423. f.raw = v;
  424. UINT32 output;
  425. if (f.field.exponent == 0x1F) // INF or NAN
  426. {
  427. output = 0x7f800000 | (f.field.mantissa << 17);
  428. }
  429. else
  430. {
  431. UINT32 exponent;
  432. UINT32 mantissa = f.field.mantissa;
  433. if (f.field.exponent != 0) // The value is normalized
  434. exponent = f.field.exponent;
  435. else if (mantissa != 0) // The value is denormalized
  436. {
  437. // Normalize the value in the resulting float
  438. exponent = 1;
  439. do
  440. {
  441. exponent--;
  442. mantissa <<= 1;
  443. } while ((mantissa & 0x40) == 0);
  444. mantissa &= 0x3F;
  445. }
  446. else // The value is zero
  447. exponent = (UINT32)-112;
  448. output = ((exponent + 112) << 23) | (mantissa << 17);
  449. }
  450. return *(float*)&output;
  451. }
  452. /** Converts a float in range [-1,1] into an unsigned 8-bit integer. */
  453. static UINT8 quantize8BitSigned(float v)
  454. {
  455. return quantize8BitUnsigned(v * 0.5f + 0.5f);
  456. }
  457. /** Converts a float in range [0,1] into an unsigned 8-bit integer. */
  458. static UINT8 quantize8BitUnsigned(float v)
  459. {
  460. return (UINT8)(v * 255.999f);
  461. }
  462. };
  463. /** @} */
  464. }