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