ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / bvh / bvh_params.h
1 /*
2  * Adapted from code copyright 2009-2010 NVIDIA Corporation
3  * Modifications Copyright 2011, Blender Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #ifndef __BVH_PARAMS_H__
19 #define __BVH_PARAMS_H__
20
21 #include "util/util_boundbox.h"
22
23 #include "kernel/kernel_types.h"
24
25 CCL_NAMESPACE_BEGIN
26
27 /* Layout of BVH tree.
28  *
29  * For example, how wide BVH tree is, in terms of number of children
30  * per node.
31  */
32 typedef KernelBVHLayout BVHLayout;
33
34 /* Names bitflag type to denote which BVH layouts are supported by
35  * particular area.
36  *
37  * Bitflags are the BVH_LAYOUT_* values.
38  */
39 typedef int BVHLayoutMask;
40
41 /* Get human readable name of BVH layout. */
42 const char *bvh_layout_name(BVHLayout layout);
43
44 /* BVH Parameters */
45
46 class BVHParams {
47  public:
48   /* spatial split area threshold */
49   bool use_spatial_split;
50   float spatial_split_alpha;
51
52   /* Unaligned nodes creation threshold */
53   float unaligned_split_threshold;
54
55   /* SAH costs */
56   float sah_node_cost;
57   float sah_primitive_cost;
58
59   /* number of primitives in leaf */
60   int min_leaf_size;
61   int max_triangle_leaf_size;
62   int max_motion_triangle_leaf_size;
63   int max_curve_leaf_size;
64   int max_motion_curve_leaf_size;
65
66   /* object or mesh level bvh */
67   bool top_level;
68
69   /* BVH layout to be built. */
70   BVHLayout bvh_layout;
71
72   /* Mask of primitives to be included into the BVH. */
73   int primitive_mask;
74
75   /* Use unaligned bounding boxes.
76    * Only used for curves BVH.
77    */
78   bool use_unaligned_nodes;
79
80   /* Split time range to this number of steps and create leaf node for each
81    * of this time steps.
82    *
83    * Speeds up rendering of motion curve primitives in the cost of higher
84    * memory usage.
85    */
86   int num_motion_curve_steps;
87
88   /* Same as above, but for triangle primitives. */
89   int num_motion_triangle_steps;
90
91   /* Same as in SceneParams. */
92   int bvh_type;
93
94   /* These are needed for Embree. */
95   int curve_flags;
96   int curve_subdivisions;
97
98   /* fixed parameters */
99   enum { MAX_DEPTH = 64, MAX_SPATIAL_DEPTH = 48, NUM_SPATIAL_BINS = 32 };
100
101   BVHParams()
102   {
103     use_spatial_split = true;
104     spatial_split_alpha = 1e-5f;
105
106     unaligned_split_threshold = 0.7f;
107
108     /* todo: see if splitting up primitive cost to be separate for triangles
109      * and curves can help. so far in tests it doesn't help, but why? */
110     sah_node_cost = 1.0f;
111     sah_primitive_cost = 1.0f;
112
113     min_leaf_size = 1;
114     max_triangle_leaf_size = 8;
115     max_motion_triangle_leaf_size = 8;
116     max_curve_leaf_size = 1;
117     max_motion_curve_leaf_size = 4;
118
119     top_level = false;
120     bvh_layout = BVH_LAYOUT_BVH2;
121     use_unaligned_nodes = false;
122
123     primitive_mask = PRIMITIVE_ALL;
124
125     num_motion_curve_steps = 0;
126     num_motion_triangle_steps = 0;
127
128     bvh_type = 0;
129
130     curve_flags = 0;
131     curve_subdivisions = 4;
132   }
133
134   /* SAH costs */
135   __forceinline float cost(int num_nodes, int num_primitives) const
136   {
137     return node_cost(num_nodes) + primitive_cost(num_primitives);
138   }
139
140   __forceinline float primitive_cost(int n) const
141   {
142     return n * sah_primitive_cost;
143   }
144
145   __forceinline float node_cost(int n) const
146   {
147     return n * sah_node_cost;
148   }
149
150   __forceinline bool small_enough_for_leaf(int size, int level)
151   {
152     return (size <= min_leaf_size || level >= MAX_DEPTH);
153   }
154
155   /* Gets best matching BVH.
156    *
157    * If the requested layout is supported by the device, it will be used.
158    * Otherwise, widest supported layout below that will be used.
159    */
160   static BVHLayout best_bvh_layout(BVHLayout requested_layout, BVHLayoutMask supported_layouts);
161 };
162
163 /* BVH Reference
164  *
165  * Reference to a primitive. Primitive index and object are sneakily packed
166  * into BoundBox to reduce memory usage and align nicely */
167
168 class BVHReference {
169  public:
170   __forceinline BVHReference()
171   {
172   }
173
174   __forceinline BVHReference(const BoundBox &bounds_,
175                              int prim_index_,
176                              int prim_object_,
177                              int prim_type,
178                              float time_from = 0.0f,
179                              float time_to = 1.0f)
180       : rbounds(bounds_), time_from_(time_from), time_to_(time_to)
181   {
182     rbounds.min.w = __int_as_float(prim_index_);
183     rbounds.max.w = __int_as_float(prim_object_);
184     type = prim_type;
185   }
186
187   __forceinline const BoundBox &bounds() const
188   {
189     return rbounds;
190   }
191   __forceinline int prim_index() const
192   {
193     return __float_as_int(rbounds.min.w);
194   }
195   __forceinline int prim_object() const
196   {
197     return __float_as_int(rbounds.max.w);
198   }
199   __forceinline int prim_type() const
200   {
201     return type;
202   }
203   __forceinline float time_from() const
204   {
205     return time_from_;
206   }
207   __forceinline float time_to() const
208   {
209     return time_to_;
210   }
211
212   BVHReference &operator=(const BVHReference &arg)
213   {
214     if (&arg != this) {
215       /* TODO(sergey): Check if it is still faster to memcpy() with
216        * modern compilers.
217        */
218       memcpy((void *)this, &arg, sizeof(BVHReference));
219     }
220     return *this;
221   }
222
223  protected:
224   BoundBox rbounds;
225   uint type;
226   float time_from_, time_to_;
227 };
228
229 /* BVH Range
230  *
231  * Build range used during construction, to indicate the bounds and place in
232  * the reference array of a subset of primitives Again uses trickery to pack
233  * integers into BoundBox for alignment purposes. */
234
235 class BVHRange {
236  public:
237   __forceinline BVHRange()
238   {
239     rbounds.min.w = __int_as_float(0);
240     rbounds.max.w = __int_as_float(0);
241   }
242
243   __forceinline BVHRange(const BoundBox &bounds_, int start_, int size_) : rbounds(bounds_)
244   {
245     rbounds.min.w = __int_as_float(start_);
246     rbounds.max.w = __int_as_float(size_);
247   }
248
249   __forceinline BVHRange(const BoundBox &bounds_, const BoundBox &cbounds_, int start_, int size_)
250       : rbounds(bounds_), cbounds(cbounds_)
251   {
252     rbounds.min.w = __int_as_float(start_);
253     rbounds.max.w = __int_as_float(size_);
254   }
255
256   __forceinline void set_start(int start_)
257   {
258     rbounds.min.w = __int_as_float(start_);
259   }
260
261   __forceinline const BoundBox &bounds() const
262   {
263     return rbounds;
264   }
265   __forceinline const BoundBox &cent_bounds() const
266   {
267     return cbounds;
268   }
269   __forceinline int start() const
270   {
271     return __float_as_int(rbounds.min.w);
272   }
273   __forceinline int size() const
274   {
275     return __float_as_int(rbounds.max.w);
276   }
277   __forceinline int end() const
278   {
279     return start() + size();
280   }
281
282  protected:
283   BoundBox rbounds;
284   BoundBox cbounds;
285 };
286
287 /* BVH Spatial Bin */
288
289 struct BVHSpatialBin {
290   BoundBox bounds;
291   int enter;
292   int exit;
293
294   __forceinline BVHSpatialBin()
295   {
296   }
297 };
298
299 /* BVH Spatial Storage
300  *
301  * The idea of this storage is have thread-specific storage for the spatial
302  * splitters. We can pre-allocate this storage in advance and avoid heavy memory
303  * operations during split process.
304  */
305
306 struct BVHSpatialStorage {
307   /* Accumulated bounds when sweeping from right to left.  */
308   vector<BoundBox> right_bounds;
309
310   /* Bins used for histogram when selecting best split plane. */
311   BVHSpatialBin bins[3][BVHParams::NUM_SPATIAL_BINS];
312
313   /* Temporary storage for the new references. Used by spatial split to store
314    * new references in before they're getting inserted into actual array,
315    */
316   vector<BVHReference> new_references;
317 };
318
319 CCL_NAMESPACE_END
320
321 #endif /* __BVH_PARAMS_H__ */