Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/bvh/params.h')
-rw-r--r--intern/cycles/bvh/params.h335
1 files changed, 335 insertions, 0 deletions
diff --git a/intern/cycles/bvh/params.h b/intern/cycles/bvh/params.h
new file mode 100644
index 00000000000..8f185a2640f
--- /dev/null
+++ b/intern/cycles/bvh/params.h
@@ -0,0 +1,335 @@
+/*
+ * Adapted from code copyright 2009-2010 NVIDIA Corporation
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BVH_PARAMS_H__
+#define __BVH_PARAMS_H__
+
+#include "util/boundbox.h"
+
+#include "kernel/types.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* Layout of BVH tree.
+ *
+ * For example, how wide BVH tree is, in terms of number of children
+ * per node.
+ */
+typedef KernelBVHLayout BVHLayout;
+
+/* Type of BVH, in terms whether it is supported dynamic updates of meshes
+ * or whether modifying geometry requires full BVH rebuild.
+ */
+enum BVHType {
+ /* BVH supports dynamic updates of geometry.
+ *
+ * Faster for updating BVH tree when doing modifications in viewport,
+ * but slower for rendering.
+ */
+ BVH_TYPE_DYNAMIC = 0,
+ /* BVH tree is calculated for specific scene, updates in geometry
+ * requires full tree rebuild.
+ *
+ * Slower to update BVH tree when modifying objects in viewport, also
+ * slower to build final BVH tree but gives best possible render speed.
+ */
+ BVH_TYPE_STATIC = 1,
+
+ BVH_NUM_TYPES,
+};
+
+/* Names bitflag type to denote which BVH layouts are supported by
+ * particular area.
+ *
+ * Bitflags are the BVH_LAYOUT_* values.
+ */
+typedef int BVHLayoutMask;
+
+/* Get human readable name of BVH layout. */
+const char *bvh_layout_name(BVHLayout layout);
+
+/* BVH Parameters */
+
+class BVHParams {
+ public:
+ /* spatial split area threshold */
+ bool use_spatial_split;
+ float spatial_split_alpha;
+
+ /* Unaligned nodes creation threshold */
+ float unaligned_split_threshold;
+
+ /* SAH costs */
+ float sah_node_cost;
+ float sah_primitive_cost;
+
+ /* number of primitives in leaf */
+ int min_leaf_size;
+ int max_triangle_leaf_size;
+ int max_motion_triangle_leaf_size;
+ int max_curve_leaf_size;
+ int max_motion_curve_leaf_size;
+
+ /* object or mesh level bvh */
+ bool top_level;
+
+ /* BVH layout to be built. */
+ BVHLayout bvh_layout;
+
+ /* Use unaligned bounding boxes.
+ * Only used for curves BVH.
+ */
+ bool use_unaligned_nodes;
+
+ /* Split time range to this number of steps and create leaf node for each
+ * of this time steps.
+ *
+ * Speeds up rendering of motion curve primitives in the cost of higher
+ * memory usage.
+ */
+ int num_motion_curve_steps;
+
+ /* Same as above, but for triangle primitives. */
+ int num_motion_triangle_steps;
+
+ /* Same as in SceneParams. */
+ int bvh_type;
+
+ /* These are needed for Embree. */
+ int curve_subdivisions;
+
+ /* fixed parameters */
+ enum { MAX_DEPTH = 64, MAX_SPATIAL_DEPTH = 48, NUM_SPATIAL_BINS = 32 };
+
+ BVHParams()
+ {
+ use_spatial_split = true;
+ spatial_split_alpha = 1e-5f;
+
+ unaligned_split_threshold = 0.7f;
+
+ /* todo: see if splitting up primitive cost to be separate for triangles
+ * and curves can help. so far in tests it doesn't help, but why? */
+ sah_node_cost = 1.0f;
+ sah_primitive_cost = 1.0f;
+
+ min_leaf_size = 1;
+ max_triangle_leaf_size = 8;
+ max_motion_triangle_leaf_size = 8;
+ max_curve_leaf_size = 1;
+ max_motion_curve_leaf_size = 4;
+
+ top_level = false;
+ bvh_layout = BVH_LAYOUT_BVH2;
+ use_unaligned_nodes = false;
+
+ num_motion_curve_steps = 0;
+ num_motion_triangle_steps = 0;
+
+ bvh_type = 0;
+
+ curve_subdivisions = 4;
+ }
+
+ /* SAH costs */
+ __forceinline float cost(int num_nodes, int num_primitives) const
+ {
+ return node_cost(num_nodes) + primitive_cost(num_primitives);
+ }
+
+ __forceinline float primitive_cost(int n) const
+ {
+ return n * sah_primitive_cost;
+ }
+
+ __forceinline float node_cost(int n) const
+ {
+ return n * sah_node_cost;
+ }
+
+ __forceinline bool small_enough_for_leaf(int size, int level)
+ {
+ return (size <= min_leaf_size || level >= MAX_DEPTH);
+ }
+
+ /* Gets best matching BVH.
+ *
+ * If the requested layout is supported by the device, it will be used.
+ * Otherwise, widest supported layout below that will be used.
+ */
+ static BVHLayout best_bvh_layout(BVHLayout requested_layout, BVHLayoutMask supported_layouts);
+};
+
+/* BVH Reference
+ *
+ * Reference to a primitive. Primitive index and object are sneakily packed
+ * into BoundBox to reduce memory usage and align nicely */
+
+class BVHReference {
+ public:
+ __forceinline BVHReference()
+ {
+ }
+
+ __forceinline BVHReference(const BoundBox &bounds_,
+ int prim_index_,
+ int prim_object_,
+ int prim_type,
+ float time_from = 0.0f,
+ float time_to = 1.0f)
+ : rbounds(bounds_), time_from_(time_from), time_to_(time_to)
+ {
+ rbounds.min.w = __int_as_float(prim_index_);
+ rbounds.max.w = __int_as_float(prim_object_);
+ type = prim_type;
+ }
+
+ __forceinline const BoundBox &bounds() const
+ {
+ return rbounds;
+ }
+ __forceinline int prim_index() const
+ {
+ return __float_as_int(rbounds.min.w);
+ }
+ __forceinline int prim_object() const
+ {
+ return __float_as_int(rbounds.max.w);
+ }
+ __forceinline int prim_type() const
+ {
+ return type;
+ }
+ __forceinline float time_from() const
+ {
+ return time_from_;
+ }
+ __forceinline float time_to() const
+ {
+ return time_to_;
+ }
+
+ BVHReference &operator=(const BVHReference &arg)
+ {
+ if (&arg != this) {
+ /* TODO(sergey): Check if it is still faster to memcpy() with
+ * modern compilers.
+ */
+ memcpy((void *)this, &arg, sizeof(BVHReference));
+ }
+ return *this;
+ }
+
+ protected:
+ BoundBox rbounds;
+ uint type;
+ float time_from_, time_to_;
+};
+
+/* BVH Range
+ *
+ * Build range used during construction, to indicate the bounds and place in
+ * the reference array of a subset of primitives Again uses trickery to pack
+ * integers into BoundBox for alignment purposes. */
+
+class BVHRange {
+ public:
+ __forceinline BVHRange()
+ {
+ rbounds.min.w = __int_as_float(0);
+ rbounds.max.w = __int_as_float(0);
+ }
+
+ __forceinline BVHRange(const BoundBox &bounds_, int start_, int size_) : rbounds(bounds_)
+ {
+ rbounds.min.w = __int_as_float(start_);
+ rbounds.max.w = __int_as_float(size_);
+ }
+
+ __forceinline BVHRange(const BoundBox &bounds_, const BoundBox &cbounds_, int start_, int size_)
+ : rbounds(bounds_), cbounds(cbounds_)
+ {
+ rbounds.min.w = __int_as_float(start_);
+ rbounds.max.w = __int_as_float(size_);
+ }
+
+ __forceinline void set_start(int start_)
+ {
+ rbounds.min.w = __int_as_float(start_);
+ }
+
+ __forceinline const BoundBox &bounds() const
+ {
+ return rbounds;
+ }
+ __forceinline const BoundBox &cent_bounds() const
+ {
+ return cbounds;
+ }
+ __forceinline int start() const
+ {
+ return __float_as_int(rbounds.min.w);
+ }
+ __forceinline int size() const
+ {
+ return __float_as_int(rbounds.max.w);
+ }
+ __forceinline int end() const
+ {
+ return start() + size();
+ }
+
+ protected:
+ BoundBox rbounds;
+ BoundBox cbounds;
+};
+
+/* BVH Spatial Bin */
+
+struct BVHSpatialBin {
+ BoundBox bounds;
+ int enter;
+ int exit;
+
+ __forceinline BVHSpatialBin()
+ {
+ }
+};
+
+/* BVH Spatial Storage
+ *
+ * The idea of this storage is have thread-specific storage for the spatial
+ * splitters. We can pre-allocate this storage in advance and avoid heavy memory
+ * operations during split process.
+ */
+
+struct BVHSpatialStorage {
+ /* Accumulated bounds when sweeping from right to left. */
+ vector<BoundBox> right_bounds;
+
+ /* Bins used for histogram when selecting best split plane. */
+ BVHSpatialBin bins[3][BVHParams::NUM_SPATIAL_BINS];
+
+ /* Temporary storage for the new references. Used by spatial split to store
+ * new references in before they're getting inserted into actual array,
+ */
+ vector<BVHReference> new_references;
+};
+
+CCL_NAMESPACE_END
+
+#endif /* __BVH_PARAMS_H__ */