[Bf-blender-cvs] [f826686] cycles_bvh: Cycles: Move forward with heterogeneous BVH nodes
Sergey Sharybin
noreply at git.blender.org
Tue Jun 14 17:37:48 CEST 2016
Commit: f82668691d2d0c35f764041a87adbfae21f21958
Author: Sergey Sharybin
Date: Tue Jun 14 17:35:39 2016 +0200
Branches: cycles_bvh
https://developer.blender.org/rBf82668691d2d0c35f764041a87adbfae21f21958
Cycles: Move forward with heterogeneous BVH nodes
- Made it so unaligned flag gets incoded into visibility flag,
so no need to bump size of regular BVH nodes.
- Made sure visibility flags are always in front of bounding
box, so it can be read first and then decision made about
what intersection code to use.
- Simplified node packing a bit, avoid duplicated code.
- Fixed some bugs in nodes refit.
===================================================================
M intern/cycles/bvh/bvh.cpp
M intern/cycles/bvh/bvh.h
M intern/cycles/kernel/geom/geom_bvh_shadow.h
M intern/cycles/kernel/geom/geom_bvh_subsurface.h
M intern/cycles/kernel/geom/geom_bvh_traversal.h
M intern/cycles/kernel/geom/geom_bvh_volume.h
M intern/cycles/kernel/geom/geom_bvh_volume_all.h
M intern/cycles/kernel/kernel_types.h
===================================================================
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 44b1f25..ffc6025 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -367,10 +367,10 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
*/
size_t nsize_bbox;
if(params.use_unaligned_nodes) {
- nsize_bbox = (use_qbvh)? 13: 8;
+ nsize_bbox = (use_qbvh)? 13: 0;
}
else {
- nsize_bbox = (use_qbvh)? 7: 3;
+ nsize_bbox = (use_qbvh)? 7: 0;
}
int4 *bvh_nodes = &bvh->pack.nodes[0];
size_t bvh_nodes_size = bvh->pack.nodes.size();
@@ -444,59 +444,45 @@ void RegularBVH::pack_inner(const BVHStackEntry& e,
const BVHStackEntry& e0,
const BVHStackEntry& e1)
{
- pack_node(e.idx,
- e0.node->m_bounds, e1.node->m_bounds,
- e0.encodeIdx(), e1.encodeIdx(),
- e0.node->m_visibility, e1.node->m_visibility);
+ if (e0.node->is_unaligned() || e1.node->is_unaligned()) {
+ pack_unaligned_inner(e, e0, e1);
+ } else {
+ pack_aligned_inner(e, e0, e1);
+ }
+}
+
+void RegularBVH::pack_aligned_inner(const BVHStackEntry& e,
+ const BVHStackEntry& e0,
+ const BVHStackEntry& e1)
+{
+ pack_aligned_node(e.idx,
+ e0.node->m_bounds, e1.node->m_bounds,
+ e0.encodeIdx(), e1.encodeIdx(),
+ e0.node->m_visibility, e1.node->m_visibility);
}
-void RegularBVH::pack_node(int idx,
- const BoundBox& b0,
- const BoundBox& b1,
- int c0, int c1,
- uint visibility0, uint visibility1)
+void RegularBVH::pack_aligned_node(int idx,
+ const BoundBox& b0,
+ const BoundBox& b1,
+ int c0, int c1,
+ uint visibility0, uint visibility1)
{
int4 data[BVH_NODE_SIZE] =
{
+ make_int4(c0, c1, visibility0, visibility1),
make_int4(__float_as_int(b0.min.x), __float_as_int(b1.min.x), __float_as_int(b0.max.x), __float_as_int(b1.max.x)),
make_int4(__float_as_int(b0.min.y), __float_as_int(b1.min.y), __float_as_int(b0.max.y), __float_as_int(b1.max.y)),
make_int4(__float_as_int(b0.min.z), __float_as_int(b1.min.z), __float_as_int(b0.max.z), __float_as_int(b1.max.z)),
- make_int4(c0, c1, visibility0, visibility1)
};
memcpy(&pack.nodes[idx], data, sizeof(int4)*BVH_NODE_SIZE);
}
-void RegularBVH::pack_unaligned_leaf(const BVHStackEntry& e,
- const LeafNode *leaf)
-{
- float4 data[BVH_NODE_LEAF_SIZE];
-
- if(leaf->num_triangles() == 1 && pack.prim_index[leaf->m_lo] == -1) {
- /* Object. */
- data[0].x = __int_as_float(~(leaf->m_lo));
- data[0].y = __int_as_float(0);
- }
- else {
- /* Curve. */
- data[0].x = __int_as_float(leaf->m_lo);
- data[0].y = __int_as_float(leaf->m_hi);
- }
- data[0].z = __uint_as_float(leaf->m_visibility);
- if(leaf->num_triangles() != 0) {
- data[0].w = __uint_as_float(pack.prim_type[leaf->m_lo]);
- }
-
- memcpy(&pack.leaf_nodes[e.idx], data, sizeof(int4)*BVH_NODE_LEAF_SIZE);
-}
-
void RegularBVH::pack_unaligned_inner(const BVHStackEntry& e,
const BVHStackEntry& e0,
const BVHStackEntry& e1)
{
pack_unaligned_node(e.idx,
- e0.node->is_unaligned(),
- e1.node->is_unaligned(),
e0.node->m_aligned_space,
e1.node->m_aligned_space,
e0.node->m_bounds,
@@ -506,8 +492,6 @@ void RegularBVH::pack_unaligned_inner(const BVHStackEntry& e,
}
void RegularBVH::pack_unaligned_node(int idx,
- const bool is_unaligned0,
- const bool is_unaligned1,
const Transform& aligned_space0,
const Transform& aligned_space1,
const BoundBox& bounds0,
@@ -516,38 +500,23 @@ void RegularBVH::pack_unaligned_node(int idx,
uint visibility0, uint visibility1)
{
float4 data[BVH_UNALIGNED_NODE_SIZE];
- if (is_unaligned0 || is_unaligned1) {
- Transform space0 = BVHUnaligned::compute_node_transform(bounds0,
- aligned_space0);
- Transform space1 = BVHUnaligned::compute_node_transform(bounds1,
- aligned_space1);
- data[0] = space0.x;
- data[1] = space0.y;
- data[2] = space0.z;
- data[3] = space0.w;
- data[4] = space1.x;
- data[5] = space1.y;
- data[6] = space1.z;
- data[7] = space1.w;
- }
- else {
- data[0] = make_float4(bounds0.min.x, bounds1.min.x,
- bounds0.max.x, bounds1.max.x);
- data[1] = make_float4(bounds0.min.y, bounds1.min.y,
- bounds0.max.y, bounds1.max.y);
- data[2] = make_float4(bounds0.min.z, bounds1.min.z,
- bounds0.max.z, bounds1.max.z);
- data[3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- data[4] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- data[5] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- data[6] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- data[7] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
-
- data[8] = make_float4(__int_as_float(c0),
+ Transform space0 = BVHUnaligned::compute_node_transform(bounds0,
+ aligned_space0);
+ Transform space1 = BVHUnaligned::compute_node_transform(bounds1,
+ aligned_space1);
+ data[0] = make_float4(__int_as_float(c0),
__int_as_float(c1),
- __int_as_float(visibility0),
- __int_as_float(visibility1));
+ __int_as_float(visibility0 | PATH_RAY_NODE_UNALIGNED),
+ __int_as_float(visibility1 | PATH_RAY_NODE_UNALIGNED));
+
+ data[1] = space0.x;
+ data[2] = space0.y;
+ data[3] = space0.z;
+ data[4] = space0.w;
+ data[5] = space1.x;
+ data[6] = space1.y;
+ data[7] = space1.z;
+ data[8] = space1.w;
memcpy(&pack.nodes[idx], data, sizeof(float4)*BVH_UNALIGNED_NODE_SIZE);
}
@@ -591,12 +560,7 @@ void RegularBVH::pack_nodes(const BVHNode *root)
if(e.node->is_leaf()) {
/* leaf node */
const LeafNode *leaf = reinterpret_cast<const LeafNode*>(e.node);
- if(params.use_unaligned_nodes) {
- pack_unaligned_leaf(e, leaf);
- }
- else {
- pack_leaf(e, leaf);
- }
+ pack_leaf(e, leaf);
}
else {
/* innner node */
@@ -613,12 +577,8 @@ void RegularBVH::pack_nodes(const BVHNode *root)
stack.push_back(BVHStackEntry(e.node->get_child(0), idx[0]));
stack.push_back(BVHStackEntry(e.node->get_child(1), idx[1]));
- if(params.use_unaligned_nodes) {
- pack_unaligned_inner(e, stack[stack.size()-2], stack[stack.size()-1]);
- }
- else {
- pack_inner(e, stack[stack.size()-2], stack[stack.size()-1]);
- }
+
+ pack_inner(e, stack[stack.size()-2], stack[stack.size()-1]);
}
}
@@ -637,15 +597,8 @@ void RegularBVH::refit_nodes()
void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
{
- size_t nsize;
- if(params.use_unaligned_nodes) {
- nsize = BVH_UNALIGNED_NODE_SIZE;
- }
- else {
- nsize = BVH_NODE_SIZE;
- }
if(leaf) {
- int4 *data = &pack.leaf_nodes[idx*BVH_NODE_LEAF_SIZE];
+ int4 *data = &pack.leaf_nodes[idx];
int c0 = data[0].x;
int c1 = data[0].y;
/* refit leaf node */
@@ -724,10 +677,9 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
sizeof(float4)*BVH_NODE_LEAF_SIZE);
}
else {
- const int cnode_offset = params.use_unaligned_nodes? 8: 3;
- int4 *data = &pack.nodes[idx*nsize];
- int c0 = data[cnode_offset].x;
- int c1 = data[cnode_offset].y;
+ int4 *data = &pack.nodes[idx];
+ int c0 = data[0].x;
+ int c1 = data[0].y;
/* refit inner node, set bbox from children */
BoundBox bbox0 = BoundBox::empty, bbox1 = BoundBox::empty;
uint visibility0 = 0, visibility1 = 0;
@@ -735,19 +687,7 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
refit_node((c0 < 0)? -c0-1: c0, (c0 < 0), bbox0, visibility0);
refit_node((c1 < 0)? -c1-1: c1, (c1 < 0), bbox1, visibility1);
- if(params.use_unaligned_nodes) {
- Transform dummy_transform = transform_identity();
- pack_unaligned_node(idx,
- false, false,
- dummy_transform, dummy_transform,
- bbox0, bbox1,
- c0, c1,
- visibility0,
- visibility1);
- }
- else {
- pack_node(idx, bbox0, bbox1, c0, c1, visibility0, visibility1);
- }
+ pack_aligned_node(idx, bbox0, bbox1, c0, c1, visibility0, visibility1);
bbox.grow(bbox0);
bbox.grow(bbox1);
@@ -785,7 +725,37 @@ void QBVH::pack_leaf(const BVHStackEntry& e, const LeafNode *leaf)
memcpy(&pack.leaf_nodes[e.idx], data, sizeof(float4)*BVH_QNODE_LEAF_SIZE);
}
-void QBVH::pack_inner(const BVHStackEntry& e, const BVHStackEntry *en, int num)
+void QBVH::pack_inner(const BVHStackEntry& e,
+ const BVHStackEntry *en,
+ int num)
+{
+ bool has_unaligned = false;
+ /* Check whether we have to create unaligned node or all nodes are aligned
+ * and we can cut some corner here.
+ */
+ if(params.use_unaligned_nodes) {
+ for(int i = 0; i < num; i++) {
+ if(en[i].node->is_unaligned()) {
+ has_unaligned = true;
+ break;
+ }
+ }
+ }
+ if(has_unaligned) {
+ /* There's no unaligned children, pack into AABB node. */
+ pack_aligned_inner(e, en, num);
+ }
+ else {
+ /* Create unaligned node with orientation transform for each of the
+ * children.
+ */
+ pack_aligned_inner(e, en, num);
+ }
+}
+
+void QBVH::pack_aligned_inner(const BVHStackEntry& e,
+ const BVHStackEntry *en,
+ int num)
{
float4 data[BVH_QNODE_SIZE];
@@ -823,27 +7
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list