stack_item.h 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #pragma once
  17. #include "default.h"
  18. namespace embree
  19. {
  20. /*! An item on the stack holds the node ID and distance of that node. */
  21. template<typename T>
  22. struct __aligned(16) StackItemT
  23. {
  24. /*! assert that the xchg function works */
  25. static_assert(sizeof(T) <= 12, "sizeof(T) <= 12 failed");
  26. /*! use SSE instructions to swap stack items */
  27. __forceinline static void xchg(StackItemT& a, StackItemT& b)
  28. {
  29. const vfloat4 sse_a = vfloat4::load((float*)&a);
  30. const vfloat4 sse_b = vfloat4::load((float*)&b);
  31. vfloat4::store(&a,sse_b);
  32. vfloat4::store(&b,sse_a);
  33. }
  34. /*! Sort 2 stack items. */
  35. __forceinline friend void sort(StackItemT& s1, StackItemT& s2) {
  36. if (s2.dist < s1.dist) xchg(s2,s1);
  37. }
  38. /*! Sort 3 stack items. */
  39. __forceinline friend void sort(StackItemT& s1, StackItemT& s2, StackItemT& s3)
  40. {
  41. if (s2.dist < s1.dist) xchg(s2,s1);
  42. if (s3.dist < s2.dist) xchg(s3,s2);
  43. if (s2.dist < s1.dist) xchg(s2,s1);
  44. }
  45. /*! Sort 4 stack items. */
  46. __forceinline friend void sort(StackItemT& s1, StackItemT& s2, StackItemT& s3, StackItemT& s4)
  47. {
  48. if (s2.dist < s1.dist) xchg(s2,s1);
  49. if (s4.dist < s3.dist) xchg(s4,s3);
  50. if (s3.dist < s1.dist) xchg(s3,s1);
  51. if (s4.dist < s2.dist) xchg(s4,s2);
  52. if (s3.dist < s2.dist) xchg(s3,s2);
  53. }
  54. /*! Sort N stack items. */
  55. __forceinline friend void sort(StackItemT* begin, StackItemT* end)
  56. {
  57. for (StackItemT* i = begin+1; i != end; ++i)
  58. {
  59. const vfloat4 item = vfloat4::load((float*)i);
  60. const unsigned dist = i->dist;
  61. StackItemT* j = i;
  62. while ((j != begin) && ((j-1)->dist < dist))
  63. {
  64. vfloat4::store(j, vfloat4::load((float*)(j-1)));
  65. --j;
  66. }
  67. vfloat4::store(j, item);
  68. }
  69. }
  70. public:
  71. T ptr;
  72. unsigned dist;
  73. };
  74. }