core_func_integer.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////
  2. // OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
  3. ///////////////////////////////////////////////////////////////////////////////////////////////////
  4. // Created : 2011-05-03
  5. // Updated : 2011-05-03
  6. // Licence : This source is under MIT licence
  7. // File : test/core/func_integer.cpp
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////
  9. #include <glm/integer.hpp>
  10. #include <glm/gtc/vec1.hpp>
  11. #include <vector>
  12. #include <ctime>
  13. #include <cstdio>
  14. enum result
  15. {
  16. SUCCESS,
  17. FAIL,
  18. ASSERT,
  19. STATIC_ASSERT
  20. };
  21. namespace bitfieldInsert
  22. {
  23. template <typename genType, typename sizeType>
  24. struct type
  25. {
  26. genType Base;
  27. genType Insert;
  28. sizeType Offset;
  29. sizeType Bits;
  30. genType Return;
  31. };
  32. typedef type<glm::uint, glm::uint> typeU32;
  33. typeU32 const Data32[] =
  34. {
  35. {0xff000000, 0x0000ff00, 8, 8, 0xff00ff00},
  36. {0xffff0000, 0x0000ffff, 16, 16, 0x00000000},
  37. {0x0000ffff, 0xffff0000, 16, 16, 0xffffffff},
  38. {0x00000000, 0xffffffff, 0, 32, 0xffffffff},
  39. {0x00000000, 0xffffffff, 0, 0, 0x00000000}
  40. };
  41. int test()
  42. {
  43. int Error = 0;
  44. glm::uint count = sizeof(Data32) / sizeof(typeU32);
  45. for(glm::uint i = 0; i < count; ++i)
  46. {
  47. glm::uint Return = glm::bitfieldInsert(
  48. Data32[i].Base,
  49. Data32[i].Insert,
  50. Data32[i].Offset,
  51. Data32[i].Bits);
  52. Error += Data32[i].Return == Return ? 0 : 1;
  53. }
  54. return Error;
  55. }
  56. }//bitfieldInsert
  57. namespace bitfieldExtract
  58. {
  59. template <typename genType, typename sizeType>
  60. struct type
  61. {
  62. genType Value;
  63. sizeType Offset;
  64. sizeType Bits;
  65. genType Return;
  66. result Result;
  67. };
  68. typedef type<glm::uint, glm::uint> typeU32;
  69. typeU32 const Data32[] =
  70. {
  71. {0xffffffff, 0,32, 0xffffffff, SUCCESS},
  72. {0xffffffff, 8, 0, 0x00000000, SUCCESS},
  73. {0x00000000, 0,32, 0x00000000, SUCCESS},
  74. {0x0f0f0f0f, 0,32, 0x0f0f0f0f, SUCCESS},
  75. {0x00000000, 8, 0, 0x00000000, SUCCESS},
  76. {0x80000000,31, 1, 0x00000001, SUCCESS},
  77. {0x7fffffff,31, 1, 0x00000000, SUCCESS},
  78. {0x00000300, 8, 8, 0x00000003, SUCCESS},
  79. {0x0000ff00, 8, 8, 0x000000ff, SUCCESS},
  80. {0xfffffff0, 0, 5, 0x00000010, SUCCESS},
  81. {0x000000ff, 1, 3, 0x00000007, SUCCESS},
  82. {0x000000ff, 0, 3, 0x00000007, SUCCESS},
  83. {0x00000000, 0, 2, 0x00000000, SUCCESS},
  84. {0xffffffff, 0, 8, 0x000000ff, SUCCESS},
  85. {0xffff0000,16,16, 0x0000ffff, SUCCESS},
  86. {0xfffffff0, 0, 8, 0x00000000, FAIL},
  87. {0xffffffff,16,16, 0x00000000, FAIL},
  88. //{0xffffffff,32, 1, 0x00000000, ASSERT}, // Throw an assert
  89. //{0xffffffff, 0,33, 0x00000000, ASSERT}, // Throw an assert
  90. //{0xffffffff,16,16, 0x00000000, ASSERT}, // Throw an assert
  91. };
  92. int test()
  93. {
  94. int Error = 0;
  95. glm::uint count = sizeof(Data32) / sizeof(typeU32);
  96. for(glm::uint i = 0; i < count; ++i)
  97. {
  98. glm::uint Return = glm::bitfieldExtract(
  99. Data32[i].Value,
  100. Data32[i].Offset,
  101. Data32[i].Bits);
  102. bool Compare = Data32[i].Return == Return;
  103. if(Data32[i].Result == SUCCESS && Compare)
  104. continue;
  105. else if(Data32[i].Result == FAIL && !Compare)
  106. continue;
  107. Error += 1;
  108. }
  109. return Error;
  110. }
  111. }//extractField
  112. namespace bitfieldReverse
  113. {
  114. template <typename genType>
  115. struct type
  116. {
  117. genType Value;
  118. genType Return;
  119. result Result;
  120. };
  121. typedef type<glm::uint> typeU32;
  122. typeU32 const Data32[] =
  123. {
  124. {0xffffffff, 0xffffffff, SUCCESS},
  125. {0x00000000, 0x00000000, SUCCESS},
  126. {0xf0000000, 0x0000000f, SUCCESS},
  127. };
  128. typedef type<glm::uint64> typeU64;
  129. #if(((GLM_COMPILER & GLM_COMPILER_GCC) == GLM_COMPILER_GCC) && (GLM_COMPILER < GLM_COMPILER_GCC44))
  130. typeU64 const Data64[] =
  131. {
  132. {0xffffffffffffffffLLU, 0xffffffffffffffffLLU, SUCCESS},
  133. {0x0000000000000000LLU, 0x0000000000000000LLU, SUCCESS},
  134. {0xf000000000000000LLU, 0x000000000000000fLLU, SUCCESS},
  135. };
  136. #else
  137. typeU64 const Data64[] =
  138. {
  139. {0xffffffffffffffff, 0xffffffffffffffff, SUCCESS},
  140. {0x0000000000000000, 0x0000000000000000, SUCCESS},
  141. {0xf000000000000000, 0x000000000000000f, SUCCESS},
  142. };
  143. #endif
  144. int test32()
  145. {
  146. glm::uint count = sizeof(Data32) / sizeof(typeU32);
  147. for(glm::uint i = 0; i < count; ++i)
  148. {
  149. glm::uint Return = glm::bitfieldReverse(
  150. Data32[i].Value);
  151. bool Compare = Data32[i].Return == Return;
  152. if(Data32[i].Result == SUCCESS && Compare)
  153. continue;
  154. else if(Data32[i].Result == FAIL && !Compare)
  155. continue;
  156. printf("glm::bitfieldReverse test fail on test %d\n", i);
  157. return 1;
  158. }
  159. return 0;
  160. }
  161. int test64()
  162. {
  163. glm::uint32 count = sizeof(Data64) / sizeof(typeU64);
  164. for(glm::uint32 i = 0; i < count; ++i)
  165. {
  166. glm::uint64 Return = glm::bitfieldReverse(
  167. Data64[i].Value);
  168. bool Compare = Data64[i].Return == Return;
  169. if(Data64[i].Result == SUCCESS && Compare)
  170. continue;
  171. else if(Data64[i].Result == FAIL && !Compare)
  172. continue;
  173. printf("glm::extractfield test fail on test %d\n", i);
  174. return 1;
  175. }
  176. return 0;
  177. }
  178. int test()
  179. {
  180. int Error = 0;
  181. Error += test32();
  182. Error += test64();
  183. return Error;
  184. }
  185. }//bitfieldReverse
  186. namespace findMSB
  187. {
  188. template <typename genType>
  189. struct type
  190. {
  191. genType Value;
  192. genType Return;
  193. };
  194. type<int> const DataI32[] =
  195. {
  196. {0x00000000, -1},
  197. {0x00000001, 0},
  198. {0x00000002, 1},
  199. {0x00000003, 1},
  200. {0x00000004, 2},
  201. {0x00000005, 2},
  202. {0x00000007, 2},
  203. {0x00000008, 3},
  204. {0x00000010, 4},
  205. {0x00000020, 5},
  206. {0x00000040, 6},
  207. {0x00000080, 7},
  208. {0x00000100, 8},
  209. {0x00000200, 9},
  210. {0x00000400, 10},
  211. {0x00000800, 11},
  212. {0x00001000, 12},
  213. {0x00002000, 13},
  214. {0x00004000, 14},
  215. {0x00008000, 15},
  216. {0x00010000, 16},
  217. {0x00020000, 17},
  218. {0x00040000, 18},
  219. {0x00080000, 19},
  220. {0x00100000, 20},
  221. {0x00200000, 21},
  222. {0x00400000, 22},
  223. {0x00800000, 23},
  224. {0x01000000, 24},
  225. {0x02000000, 25},
  226. {0x04000000, 26},
  227. {0x08000000, 27},
  228. {0x10000000, 28},
  229. {0x20000000, 29},
  230. {0x40000000, 30}
  231. };
  232. int test()
  233. {
  234. int Error(0);
  235. for(std::size_t i = 0; i < sizeof(DataI32) / sizeof(type<int>); ++i)
  236. {
  237. int Result = glm::findMSB(DataI32[i].Value);
  238. Error += DataI32[i].Return == Result ? 0 : 1;
  239. assert(!Error);
  240. }
  241. return Error;
  242. }
  243. }//findMSB
  244. namespace findLSB
  245. {
  246. template <typename genType>
  247. struct type
  248. {
  249. genType Value;
  250. genType Return;
  251. };
  252. type<int> const DataI32[] =
  253. {
  254. {0x00000001, 0},
  255. {0x00000003, 0},
  256. {0x00000002, 1}
  257. };
  258. int test()
  259. {
  260. int Error(0);
  261. for(std::size_t i = 0; i < sizeof(DataI32) / sizeof(type<int>); ++i)
  262. {
  263. int Result = glm::findLSB(DataI32[i].Value);
  264. Error += DataI32[i].Return == Result ? 0 : 1;
  265. assert(!Error);
  266. }
  267. return Error;
  268. }
  269. }//findLSB
  270. namespace uaddCarry
  271. {
  272. int test()
  273. {
  274. int Error(0);
  275. {
  276. glm::uint x = 16;
  277. glm::uint y = 17;
  278. glm::uint Carry = 0;
  279. glm::uint Result = glm::uaddCarry(x, y, Carry);
  280. Error += Carry == 1 ? 0 : 1;
  281. Error += Result == 33 ? 0 : 1;
  282. }
  283. {
  284. glm::uvec1 x(16);
  285. glm::uvec1 y(17);
  286. glm::uvec1 Carry(0);
  287. glm::uvec1 Result(glm::uaddCarry(x, y, Carry));
  288. Error += glm::all(glm::equal(Carry, glm::uvec1(1))) ? 0 : 1;
  289. Error += glm::all(glm::equal(Result, glm::uvec1(33))) ? 0 : 1;
  290. }
  291. {
  292. glm::uvec2 x(16);
  293. glm::uvec2 y(17);
  294. glm::uvec2 Carry(0);
  295. glm::uvec2 Result(glm::uaddCarry(x, y, Carry));
  296. Error += glm::all(glm::equal(Carry, glm::uvec2(1))) ? 0 : 1;
  297. Error += glm::all(glm::equal(Result, glm::uvec2(33))) ? 0 : 1;
  298. }
  299. {
  300. glm::uvec3 x(16);
  301. glm::uvec3 y(17);
  302. glm::uvec3 Carry(0);
  303. glm::uvec3 Result(glm::uaddCarry(x, y, Carry));
  304. Error += glm::all(glm::equal(Carry, glm::uvec3(1))) ? 0 : 1;
  305. Error += glm::all(glm::equal(Result, glm::uvec3(33))) ? 0 : 1;
  306. }
  307. {
  308. glm::uvec4 x(16);
  309. glm::uvec4 y(17);
  310. glm::uvec4 Carry(0);
  311. glm::uvec4 Result(glm::uaddCarry(x, y, Carry));
  312. Error += glm::all(glm::equal(Carry, glm::uvec4(1))) ? 0 : 1;
  313. Error += glm::all(glm::equal(Result, glm::uvec4(33))) ? 0 : 1;
  314. }
  315. return Error;
  316. }
  317. }//namespace uaddCarry
  318. namespace usubBorrow
  319. {
  320. int test()
  321. {
  322. int Error(0);
  323. {
  324. glm::uint x = 16;
  325. glm::uint y = 17;
  326. glm::uint Borrow = 0;
  327. glm::uint Result = glm::usubBorrow(x, y, Borrow);
  328. Error += Borrow == 1 ? 0 : 1;
  329. Error += Result == 1 ? 0 : 1;
  330. }
  331. {
  332. glm::uvec1 x(16);
  333. glm::uvec1 y(17);
  334. glm::uvec1 Borrow(0);
  335. glm::uvec1 Result(glm::usubBorrow(x, y, Borrow));
  336. Error += glm::all(glm::equal(Borrow, glm::uvec1(1))) ? 0 : 1;
  337. Error += glm::all(glm::equal(Result, glm::uvec1(1))) ? 0 : 1;
  338. }
  339. {
  340. glm::uvec2 x(16);
  341. glm::uvec2 y(17);
  342. glm::uvec2 Borrow(0);
  343. glm::uvec2 Result(glm::usubBorrow(x, y, Borrow));
  344. Error += glm::all(glm::equal(Borrow, glm::uvec2(1))) ? 0 : 1;
  345. Error += glm::all(glm::equal(Result, glm::uvec2(1))) ? 0 : 1;
  346. }
  347. {
  348. glm::uvec3 x(16);
  349. glm::uvec3 y(17);
  350. glm::uvec3 Borrow(0);
  351. glm::uvec3 Result(glm::usubBorrow(x, y, Borrow));
  352. Error += glm::all(glm::equal(Borrow, glm::uvec3(1))) ? 0 : 1;
  353. Error += glm::all(glm::equal(Result, glm::uvec3(1))) ? 0 : 1;
  354. }
  355. {
  356. glm::uvec4 x(16);
  357. glm::uvec4 y(17);
  358. glm::uvec4 Borrow(0);
  359. glm::uvec4 Result(glm::usubBorrow(x, y, Borrow));
  360. Error += glm::all(glm::equal(Borrow, glm::uvec4(1))) ? 0 : 1;
  361. Error += glm::all(glm::equal(Result, glm::uvec4(1))) ? 0 : 1;
  362. }
  363. return Error;
  364. }
  365. }//namespace usubBorrow
  366. namespace umulExtended
  367. {
  368. int test()
  369. {
  370. int Error(0);
  371. {
  372. glm::uint x = 2;
  373. glm::uint y = 3;
  374. glm::uint msb = 0;
  375. glm::uint lsb = 0;
  376. glm::umulExtended(x, y, msb, lsb);
  377. Error += msb == 0 ? 0 : 1;
  378. Error += lsb == 6 ? 0 : 1;
  379. }
  380. {
  381. glm::uvec1 x(2);
  382. glm::uvec1 y(3);
  383. glm::uvec1 msb(0);
  384. glm::uvec1 lsb(0);
  385. glm::umulExtended(x, y, msb, lsb);
  386. Error += glm::all(glm::equal(msb, glm::uvec1(0))) ? 0 : 1;
  387. Error += glm::all(glm::equal(lsb, glm::uvec1(6))) ? 0 : 1;
  388. }
  389. {
  390. glm::uvec2 x(2);
  391. glm::uvec2 y(3);
  392. glm::uvec2 msb(0);
  393. glm::uvec2 lsb(0);
  394. glm::umulExtended(x, y, msb, lsb);
  395. Error += glm::all(glm::equal(msb, glm::uvec2(0))) ? 0 : 1;
  396. Error += glm::all(glm::equal(lsb, glm::uvec2(6))) ? 0 : 1;
  397. }
  398. {
  399. glm::uvec3 x(2);
  400. glm::uvec3 y(3);
  401. glm::uvec3 msb(0);
  402. glm::uvec3 lsb(0);
  403. glm::umulExtended(x, y, msb, lsb);
  404. Error += glm::all(glm::equal(msb, glm::uvec3(0))) ? 0 : 1;
  405. Error += glm::all(glm::equal(lsb, glm::uvec3(6))) ? 0 : 1;
  406. }
  407. {
  408. glm::uvec4 x(2);
  409. glm::uvec4 y(3);
  410. glm::uvec4 msb(0);
  411. glm::uvec4 lsb(0);
  412. glm::umulExtended(x, y, msb, lsb);
  413. Error += glm::all(glm::equal(msb, glm::uvec4(0))) ? 0 : 1;
  414. Error += glm::all(glm::equal(lsb, glm::uvec4(6))) ? 0 : 1;
  415. }
  416. return Error;
  417. }
  418. }//namespace umulExtended
  419. namespace imulExtended
  420. {
  421. int test()
  422. {
  423. int Error(0);
  424. {
  425. int x = 2;
  426. int y = 3;
  427. int msb = 0;
  428. int lsb = 0;
  429. glm::imulExtended(x, y, msb, lsb);
  430. Error += msb == 0 ? 0 : 1;
  431. Error += lsb == 6 ? 0 : 1;
  432. }
  433. {
  434. glm::ivec1 x(2);
  435. glm::ivec1 y(3);
  436. glm::ivec1 msb(0);
  437. glm::ivec1 lsb(0);
  438. glm::imulExtended(x, y, msb, lsb);
  439. Error += glm::all(glm::equal(msb, glm::ivec1(0))) ? 0 : 1;
  440. Error += glm::all(glm::equal(lsb, glm::ivec1(6))) ? 0 : 1;
  441. }
  442. {
  443. glm::ivec2 x(2);
  444. glm::ivec2 y(3);
  445. glm::ivec2 msb(0);
  446. glm::ivec2 lsb(0);
  447. glm::imulExtended(x, y, msb, lsb);
  448. Error += glm::all(glm::equal(msb, glm::ivec2(0))) ? 0 : 1;
  449. Error += glm::all(glm::equal(lsb, glm::ivec2(6))) ? 0 : 1;
  450. }
  451. {
  452. glm::ivec3 x(2);
  453. glm::ivec3 y(3);
  454. glm::ivec3 msb(0);
  455. glm::ivec3 lsb(0);
  456. glm::imulExtended(x, y, msb, lsb);
  457. Error += glm::all(glm::equal(msb, glm::ivec3(0))) ? 0 : 1;
  458. Error += glm::all(glm::equal(lsb, glm::ivec3(6))) ? 0 : 1;
  459. }
  460. {
  461. glm::ivec4 x(2);
  462. glm::ivec4 y(3);
  463. glm::ivec4 msb(0);
  464. glm::ivec4 lsb(0);
  465. glm::imulExtended(x, y, msb, lsb);
  466. Error += glm::all(glm::equal(msb, glm::ivec4(0))) ? 0 : 1;
  467. Error += glm::all(glm::equal(lsb, glm::ivec4(6))) ? 0 : 1;
  468. }
  469. return Error;
  470. }
  471. }//namespace imulExtended
  472. namespace bitCount
  473. {
  474. template <typename genType>
  475. struct type
  476. {
  477. genType Value;
  478. genType Return;
  479. };
  480. type<int> const DataI32[] =
  481. {
  482. {0x00000001, 1},
  483. {0x00000003, 2},
  484. {0x00000002, 1},
  485. {0x7fffffff, 31},
  486. {0x00000000, 0}
  487. };
  488. template <typename T>
  489. inline int bitCount_if(T v)
  490. {
  491. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitCount' only accept integer values");
  492. int Count(0);
  493. for(T i = 0, n = static_cast<T>(sizeof(T) * 8); i < n; ++i)
  494. {
  495. if(v & static_cast<T>(1 << i))
  496. ++Count;
  497. }
  498. return Count;
  499. }
  500. template <typename T>
  501. inline int bitCount_vec(T v)
  502. {
  503. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitCount' only accept integer values");
  504. int Count(0);
  505. for(T i = 0, n = static_cast<T>(sizeof(T) * 8); i < n; ++i)
  506. {
  507. Count += static_cast<int>((v >> i) & static_cast<T>(1));
  508. }
  509. return Count;
  510. }
  511. int perf()
  512. {
  513. int Error(0);
  514. std::size_t Size = 10000000;
  515. std::vector<int> v;
  516. v.resize(Size);
  517. std::vector<glm::ivec4> w;
  518. w.resize(Size);
  519. std::clock_t TimestampsA = std::clock();
  520. // bitCount - TimeIf
  521. {
  522. for(std::size_t i = 0, n = v.size(); i < n; ++i)
  523. v[i] = bitCount_if(i);
  524. }
  525. std::clock_t TimestampsB = std::clock();
  526. // bitCount - TimeVec
  527. {
  528. for(std::size_t i = 0, n = v.size(); i < n; ++i)
  529. v[i] = bitCount_vec(i);
  530. }
  531. std::clock_t TimestampsC = std::clock();
  532. // bitCount - TimeDefault
  533. {
  534. for(std::size_t i = 0, n = v.size(); i < n; ++i)
  535. v[i] = glm::bitCount(i);
  536. }
  537. std::clock_t TimestampsD = std::clock();
  538. // bitCount - TimeVec4
  539. {
  540. for(std::size_t i = 0, n = v.size(); i < n; ++i)
  541. w[i] = glm::bitCount(glm::ivec4(i));
  542. }
  543. std::clock_t TimestampsE = std::clock();
  544. std::clock_t TimeIf = TimestampsB - TimestampsA;
  545. std::clock_t TimeVec = TimestampsC - TimestampsB;
  546. std::clock_t TimeDefault = TimestampsD - TimestampsC;
  547. std::clock_t TimeVec4 = TimestampsE - TimestampsD;
  548. printf("bitCount - TimeIf %d\n", TimeIf);
  549. printf("bitCount - TimeVec %d\n", TimeVec);
  550. printf("bitCount - TimeDefault %d\n", TimeDefault);
  551. printf("bitCount - TimeVec4 %d\n", TimeVec4);
  552. return Error;
  553. }
  554. int test()
  555. {
  556. int Error(0);
  557. for(std::size_t i = 0, n = sizeof(DataI32) / sizeof(type<int>); i < n; ++i)
  558. {
  559. int Result = glm::bitCount(DataI32[i].Value);
  560. Error += DataI32[i].Return == Result ? 0 : 1;
  561. assert(!Error);
  562. }
  563. return Error;
  564. }
  565. }//bitCount
  566. int main()
  567. {
  568. int Error = 0;
  569. Error += ::umulExtended::test();
  570. Error += ::imulExtended::test();
  571. Error += ::uaddCarry::test();
  572. Error += ::usubBorrow::test();
  573. Error += ::bitfieldInsert::test();
  574. Error += ::bitfieldExtract::test();
  575. Error += ::bitfieldReverse::test();
  576. Error += ::bitCount::test();
  577. Error += ::bitCount::perf();
  578. Error += ::findMSB::test();
  579. Error += ::findLSB::test();
  580. return Error;
  581. }