grid_soa_intersector1.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "grid_soa.h"
  5. #include "../common/ray.h"
  6. #include "triangle_intersector_pluecker.h"
  7. namespace embree
  8. {
  9. namespace isa
  10. {
  11. class GridSOAIntersector1
  12. {
  13. public:
  14. typedef void Primitive;
  15. class Precalculations
  16. {
  17. public:
  18. __forceinline Precalculations (const Ray& ray, const void* ptr)
  19. : grid(nullptr) {}
  20. public:
  21. GridSOA* grid;
  22. int itime;
  23. float ftime;
  24. };
  25. template<typename Loader>
  26. static __forceinline void intersect(RayHit& ray,
  27. RayQueryContext* context,
  28. const float* const grid_x,
  29. const size_t line_offset,
  30. const size_t lines,
  31. Precalculations& pre)
  32. {
  33. typedef typename Loader::vfloat vfloat;
  34. const size_t dim_offset = pre.grid->dim_offset;
  35. const float* const grid_y = grid_x + 1 * dim_offset;
  36. const float* const grid_z = grid_x + 2 * dim_offset;
  37. const float* const grid_uv = grid_x + 3 * dim_offset;
  38. Vec3<vfloat> v0, v1, v2;
  39. Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,v0,v1,v2);
  40. GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
  41. PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
  42. intersector.intersect(ray,v0,v1,v2,mapUV,Intersect1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
  43. };
  44. template<typename Loader>
  45. static __forceinline bool occluded(Ray& ray,
  46. RayQueryContext* context,
  47. const float* const grid_x,
  48. const size_t line_offset,
  49. const size_t lines,
  50. Precalculations& pre)
  51. {
  52. typedef typename Loader::vfloat vfloat;
  53. const size_t dim_offset = pre.grid->dim_offset;
  54. const float* const grid_y = grid_x + 1 * dim_offset;
  55. const float* const grid_z = grid_x + 2 * dim_offset;
  56. const float* const grid_uv = grid_x + 3 * dim_offset;
  57. Vec3<vfloat> v0, v1, v2;
  58. Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,v0,v1,v2);
  59. GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
  60. PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
  61. return intersector.intersect(ray,v0,v1,v2,mapUV,Occluded1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
  62. }
  63. /*! Intersect a ray with the primitive. */
  64. static __forceinline void intersect(Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
  65. {
  66. const size_t line_offset = pre.grid->width;
  67. const size_t lines = pre.grid->height;
  68. const float* const grid_x = pre.grid->decodeLeaf(0,prim);
  69. #if defined(__AVX__)
  70. intersect<GridSOA::Gather3x3>( ray, context, grid_x, line_offset, lines, pre);
  71. #else
  72. intersect<GridSOA::Gather2x3>(ray, context, grid_x , line_offset, lines, pre);
  73. if (likely(lines > 2))
  74. intersect<GridSOA::Gather2x3>(ray, context, grid_x+line_offset, line_offset, lines, pre);
  75. #endif
  76. }
  77. /*! Test if the ray is occluded by the primitive */
  78. static __forceinline bool occluded(Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
  79. {
  80. const size_t line_offset = pre.grid->width;
  81. const size_t lines = pre.grid->height;
  82. const float* const grid_x = pre.grid->decodeLeaf(0,prim);
  83. #if defined(__AVX__)
  84. return occluded<GridSOA::Gather3x3>( ray, context, grid_x, line_offset, lines, pre);
  85. #else
  86. if (occluded<GridSOA::Gather2x3>(ray, context, grid_x , line_offset, lines, pre)) return true;
  87. if (likely(lines > 2))
  88. if (occluded<GridSOA::Gather2x3>(ray, context, grid_x+line_offset, line_offset, lines, pre)) return true;
  89. #endif
  90. return false;
  91. }
  92. };
  93. class GridSOAMBIntersector1
  94. {
  95. public:
  96. typedef void Primitive;
  97. typedef GridSOAIntersector1::Precalculations Precalculations;
  98. template<typename Loader>
  99. static __forceinline void intersect(RayHit& ray, const float ftime,
  100. RayQueryContext* context,
  101. const float* const grid_x,
  102. const size_t line_offset,
  103. const size_t lines,
  104. Precalculations& pre)
  105. {
  106. typedef typename Loader::vfloat vfloat;
  107. const size_t dim_offset = pre.grid->dim_offset;
  108. const size_t grid_offset = pre.grid->gridBytes >> 2;
  109. const float* const grid_y = grid_x + 1 * dim_offset;
  110. const float* const grid_z = grid_x + 2 * dim_offset;
  111. const float* const grid_uv = grid_x + 3 * dim_offset;
  112. Vec3<vfloat> a0, a1, a2;
  113. Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,a0,a1,a2);
  114. Vec3<vfloat> b0, b1, b2;
  115. Loader::gather(grid_x+grid_offset,grid_y+grid_offset,grid_z+grid_offset,line_offset,lines,b0,b1,b2);
  116. Vec3<vfloat> v0 = lerp(a0,b0,vfloat(ftime));
  117. Vec3<vfloat> v1 = lerp(a1,b1,vfloat(ftime));
  118. Vec3<vfloat> v2 = lerp(a2,b2,vfloat(ftime));
  119. GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
  120. PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
  121. intersector.intersect(ray,v0,v1,v2,mapUV,Intersect1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
  122. };
  123. template<typename Loader>
  124. static __forceinline bool occluded(Ray& ray, const float ftime,
  125. RayQueryContext* context,
  126. const float* const grid_x,
  127. const size_t line_offset,
  128. const size_t lines,
  129. Precalculations& pre)
  130. {
  131. typedef typename Loader::vfloat vfloat;
  132. const size_t dim_offset = pre.grid->dim_offset;
  133. const size_t grid_offset = pre.grid->gridBytes >> 2;
  134. const float* const grid_y = grid_x + 1 * dim_offset;
  135. const float* const grid_z = grid_x + 2 * dim_offset;
  136. const float* const grid_uv = grid_x + 3 * dim_offset;
  137. Vec3<vfloat> a0, a1, a2;
  138. Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,a0,a1,a2);
  139. Vec3<vfloat> b0, b1, b2;
  140. Loader::gather(grid_x+grid_offset,grid_y+grid_offset,grid_z+grid_offset,line_offset,lines,b0,b1,b2);
  141. Vec3<vfloat> v0 = lerp(a0,b0,vfloat(ftime));
  142. Vec3<vfloat> v1 = lerp(a1,b1,vfloat(ftime));
  143. Vec3<vfloat> v2 = lerp(a2,b2,vfloat(ftime));
  144. GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
  145. PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
  146. return intersector.intersect(ray,v0,v1,v2,mapUV,Occluded1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
  147. }
  148. /*! Intersect a ray with the primitive. */
  149. static __forceinline void intersect(Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
  150. {
  151. const size_t line_offset = pre.grid->width;
  152. const size_t lines = pre.grid->height;
  153. const float* const grid_x = pre.grid->decodeLeaf(pre.itime,prim);
  154. #if defined(__AVX__)
  155. intersect<GridSOA::Gather3x3>( ray, pre.ftime, context, grid_x, line_offset, lines, pre);
  156. #else
  157. intersect<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x, line_offset, lines, pre);
  158. if (likely(lines > 2))
  159. intersect<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x+line_offset, line_offset, lines, pre);
  160. #endif
  161. }
  162. /*! Test if the ray is occluded by the primitive */
  163. static __forceinline bool occluded(Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
  164. {
  165. const size_t line_offset = pre.grid->width;
  166. const size_t lines = pre.grid->height;
  167. const float* const grid_x = pre.grid->decodeLeaf(pre.itime,prim);
  168. #if defined(__AVX__)
  169. return occluded<GridSOA::Gather3x3>( ray, pre.ftime, context, grid_x, line_offset, lines, pre);
  170. #else
  171. if (occluded<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x , line_offset, lines, pre)) return true;
  172. if (likely(lines > 2))
  173. if (occluded<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x+line_offset, line_offset, lines, pre)) return true;
  174. #endif
  175. return false;
  176. }
  177. };
  178. }
  179. }