diff options
Diffstat (limited to 'intern/cycles/bvh/bvh_params.h')
-rw-r--r-- | intern/cycles/bvh/bvh_params.h | 448 |
1 files changed, 240 insertions, 208 deletions
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h index 6408d56da80..2731662a39d 100644 --- a/intern/cycles/bvh/bvh_params.h +++ b/intern/cycles/bvh/bvh_params.h @@ -43,120 +43,121 @@ 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; - - /* Mask of primitives to be included into the BVH. */ - int primitive_mask; - - /* 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_flags; - 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; - - primitive_mask = PRIMITIVE_ALL; - - num_motion_curve_steps = 0; - num_motion_triangle_steps = 0; - - bvh_type = 0; - - curve_flags = 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); +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; + + /* Mask of primitives to be included into the BVH. */ + int primitive_mask; + + /* 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_flags; + 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; + + primitive_mask = PRIMITIVE_ALL; + + num_motion_curve_steps = 0; + num_motion_triangle_steps = 0; + + bvh_type = 0; + + curve_flags = 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 @@ -164,49 +165,65 @@ public: * 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_; +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 @@ -215,53 +232,68 @@ protected: * 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; +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 ¢_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; +struct BVHSpatialBin { + BoundBox bounds; + int enter; + int exit; - __forceinline BVHSpatialBin() - { - } + __forceinline BVHSpatialBin() + { + } }; /* BVH Spatial Storage @@ -272,18 +304,18 @@ struct BVHSpatialBin */ struct BVHSpatialStorage { - /* Accumulated bounds when sweeping from right to left. */ - vector<BoundBox> right_bounds; + /* 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]; + /* 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; + /* 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__ */ +#endif /* __BVH_PARAMS_H__ */ |