[Bf-blender-cvs] [590aae2] soc-2014-cycles: Cycles: Commiting some WIP code for a Quad BVH (CPU only)

Thomas Dinges noreply at git.blender.org
Fri Jun 6 19:59:42 CEST 2014


Commit: 590aae22a6cb9109f15611bb3ffd87362f03c5dd
Author: Thomas Dinges
Date:   Fri Jun 6 19:51:06 2014 +0200
https://developer.blender.org/rB590aae22a6cb9109f15611bb3ffd87362f03c5dd

Cycles: Commiting some WIP code for a Quad BVH (CPU only)

* This is highly experimental, but commiting it makes is a bit easier to work on.
* Traversal code in geom_qbvh_traversal.h and geom_triangle.h based on code by Brecht, from the early Cycles days. I updated it, added some AVX2 code and integrated it into the current code base.
* Simple scenes such as cornell box etc. from our test files render ~7% faster, but bigger scenes are quite slower.
* The idea is to use traversal and improved builder code from Embree later.

Differential Revision: https://developer.blender.org/D579

===================================================================

M	intern/cycles/blender/addon/properties.py
M	intern/cycles/blender/addon/ui.py
M	intern/cycles/blender/blender_sync.cpp
M	intern/cycles/kernel/CMakeLists.txt
M	intern/cycles/kernel/geom/geom.h
M	intern/cycles/kernel/geom/geom_bvh.h
A	intern/cycles/kernel/geom/geom_qbvh_traversal.h
M	intern/cycles/kernel/geom/geom_triangle.h
M	intern/cycles/kernel/kernel_compat_cpu.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/render/object.cpp
M	intern/cycles/render/scene.h

===================================================================

diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 7205a27..f39b9be 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -450,6 +450,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
                 description="Use BVH spatial splits: longer builder time, faster render",
                 default=False,
                 )
+        cls.use_qbvh = BoolProperty(
+                name="Use QBVH",
+                description="Use Quad BVH (CPU only)",
+                default=False,
+                )
         cls.use_cache = BoolProperty(
                 name="Cache BVH",
                 description="Cache last built BVH to disk for faster re-render if no geometry changed",
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 5c8115b..dfc66a7 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -324,6 +324,8 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
 
         col.label(text="Acceleration structure:")
         col.prop(cscene, "debug_use_spatial_splits")
+        if use_cpu(context):
+            col.prop(cscene, "use_qbvh")
 
 
 class CyclesRender_PT_layer_options(CyclesButtonsPanel, Panel):
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index bdb3e20..3d71eb7 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -371,6 +371,7 @@ SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background)
 	else
 		params.bvh_type = (SceneParams::BVHType)RNA_enum_get(&cscene, "debug_bvh_type");
 
+	params.use_qbvh = RNA_boolean_get(&cscene, "use_qbvh");
 	params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
 	params.use_bvh_cache = (background)? RNA_boolean_get(&cscene, "use_cache"): false;
 
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 9896a55..43297c3 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -114,6 +114,7 @@ set(SRC_GEOM_HEADERS
 	geom/geom_bvh.h
 	geom/geom_bvh_subsurface.h
 	geom/geom_bvh_traversal.h
+	geom/geom_qbvh_traversal.h
 	geom/geom_curve.h
 	geom/geom_motion_curve.h
 	geom/geom_motion_triangle.h
diff --git a/intern/cycles/kernel/geom/geom.h b/intern/cycles/kernel/geom/geom.h
index 9495a25..28d4272 100644
--- a/intern/cycles/kernel/geom/geom.h
+++ b/intern/cycles/kernel/geom/geom.h
@@ -23,6 +23,9 @@
 #define BVH_NODE_SIZE 4
 #define TRI_NODE_SIZE 3
 
+/* QBVH */
+#define QBVH_NODE_SIZE 8
+
 /* silly workaround for float extended precision that happens when compiling
  * without sse support on x86, it results in different results for float ops
  * that you would otherwise expect to compare correctly */
diff --git a/intern/cycles/kernel/geom/geom_bvh.h b/intern/cycles/kernel/geom/geom_bvh.h
index dd7c25d..af96441 100644
--- a/intern/cycles/kernel/geom/geom_bvh.h
+++ b/intern/cycles/kernel/geom/geom_bvh.h
@@ -35,6 +35,8 @@ CCL_NAMESPACE_BEGIN
 #define BVH_HAIR				4
 #define BVH_HAIR_MINIMUM_WIDTH	8
 
+/* Regular BVH */
+
 #define BVH_FUNCTION_NAME bvh_intersect
 #define BVH_FUNCTION_FEATURES 0
 #include "geom_bvh_traversal.h"
@@ -123,6 +125,35 @@ CCL_NAMESPACE_BEGIN
 #include "geom_bvh_shadow.h"
 #endif
 
+/* QBVH */
+#define BVH_FUNCTION_NAME qbvh_intersect
+#define BVH_FUNCTION_FEATURES 0
+#include "geom_qbvh_traversal.h"
+
+#if defined(__INSTANCING__)
+#define BVH_FUNCTION_NAME qbvh_intersect_instancing
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING
+#include "geom_qbvh_traversal.h"
+#endif
+
+#if defined(__HAIR__)
+#define BVH_FUNCTION_NAME qbvh_intersect_hair
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH
+#include "geom_qbvh_traversal.h"
+#endif
+
+#if defined(__OBJECT_MOTION__)
+#define BVH_FUNCTION_NAME qbvh_intersect_motion
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION
+#include "geom_qbvh_traversal.h"
+#endif
+
+#if defined(__HAIR__) && defined(__OBJECT_MOTION__)
+#define BVH_FUNCTION_NAME qbvh_intersect_hair_motion
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH|BVH_MOTION
+#include "geom_qbvh_traversal.h"
+#endif
+
 /* to work around titan bug when using arrays instead of textures */
 #if !defined(__KERNEL_CUDA__) || defined(__KERNEL_CUDA_TEX_STORAGE__)
 ccl_device_inline
@@ -135,6 +166,33 @@ bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, I
 bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
 #endif
 {
+#ifdef __QBVH__
+	if(kernel_data.bvh.use_qbvh) {
+#ifdef __OBJECT_MOTION__
+		if(kernel_data.bvh.have_motion) {
+#ifdef __HAIR__
+			if(kernel_data.bvh.have_curves)
+				return qbvh_intersect_hair_motion(kg, ray, isect, visibility, lcg_state, difl, extmax);
+#endif /* __HAIR__ */
+
+			return qbvh_intersect_motion(kg, ray, isect, visibility);
+		}
+#endif /* __OBJECT_MOTION__ */
+
+#ifdef __HAIR__
+		if(kernel_data.bvh.have_curves)
+			return qbvh_intersect_hair(kg, ray, isect, visibility, lcg_state, difl, extmax);
+#endif /* __HAIR__ */
+
+#ifdef __INSTANCING__
+		if(kernel_data.bvh.have_instancing)
+			return qbvh_intersect_instancing(kg, ray, isect, visibility);
+#endif /* __INSTANCING__ */
+
+		return qbvh_intersect(kg, ray, isect, visibility);
+	}
+#endif
+
 #ifdef __OBJECT_MOTION__
 	if(kernel_data.bvh.have_motion) {
 #ifdef __HAIR__
diff --git a/intern/cycles/kernel/geom/geom_qbvh_traversal.h b/intern/cycles/kernel/geom/geom_qbvh_traversal.h
new file mode 100644
index 0000000..25d04bf
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_qbvh_traversal.h
@@ -0,0 +1,197 @@
+/*
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation,
+ * and code copyright 2009-2012 Intel Corporation
+ *
+ * Modifications Copyright 2011-2014, 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.
+ */
+
+/* This is a template QBVH traversal function, where various features can be
+ * enabled/disabled. This way we can compile optimized versions for each case
+ * without new features slowing things down.
+ *
+ * BVH_INSTANCING: object instancing
+ * BVH_HAIR: hair curve rendering
+ * BVH_HAIR_MINIMUM_WIDTH: hair curve rendering with minimum width
+ * BVH_MOTION: motion blur rendering
+ *
+ */
+
+#define FEATURE(f) (((BVH_FUNCTION_FEATURES) & (f)) != 0)
+
+ccl_device bool BVH_FUNCTION_NAME
+(KernelGlobals *kg, const Ray *ray, Intersection *isect, const uint visibility
+#if FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+,uint *lcg_state, float difl, float extmax
+#endif
+)
+{
+	/* todo:
+	 * - Visibility test
+	 * - Subsurface Scattering and Hair Min Width
+	 * - Check on Embree traversal code for further improvements
+	 */
+
+	/* traversal stack in CUDA thread-local memory */
+	int traversalStack[BVH_STACK_SIZE];
+	traversalStack[0] = ENTRYPOINT_SENTINEL;
+
+	/* traversal variables in registers */
+	int stackPtr = 0;
+	int nodeAddr = kernel_data.bvh.root;
+
+	/* ray parameters in registers */
+	float3 P = ray->P;
+	float3 dir = bvh_clamp_direction(ray->D);
+	float3 idir = bvh_inverse_direction(dir);
+	int object = OBJECT_NONE;
+
+#if FEATURE(BVH_MOTION)
+	Transform ob_tfm;
+#endif
+
+	isect->t = ray->t;
+	isect->object = OBJECT_NONE;
+	isect->prim = PRIM_NONE;
+	isect->u = 0.0f;
+	isect->v = 0.0f;
+
+	/* traversal loop */
+	do {
+		do
+		{
+			/* traverse internal nodes */
+			while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL)
+			{
+				int traverseChild, nodeAddrChild[4];
+
+				qbvh_node_intersect(kg, &traverseChild, nodeAddrChild, P, idir, isect->t, nodeAddr);
+
+				if(traverseChild & 1) {
+					++stackPtr;
+					traversalStack[stackPtr] = nodeAddrChild[0];
+				}
+				if(traverseChild & 2) {
+					++stackPtr;
+					traversalStack[stackPtr] = nodeAddrChild[1];
+				}
+				if(traverseChild & 4) {
+					++stackPtr;
+					traversalStack[stackPtr] = nodeAddrChild[2];
+				}
+				if(traverseChild & 8) {
+					++stackPtr;
+					traversalStack[stackPtr] = nodeAddrChild[3];
+				}
+
+				nodeAddr = traversalStack[stackPtr];
+				--stackPtr;
+			}
+
+			/* if node is leaf, fetch triangle list */
+			if(nodeAddr < 0) {
+				float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*QBVH_NODE_SIZE+(QBVH_NODE_SIZE-2));
+				int primAddr = __float_as_int(leaf.x);
+
+#if FEATURE(BVH_INSTANCING)
+				if(primAddr >= 0) {
+#endif
+					int primAddr2 = __float_as_int(leaf.y);
+
+					/* pop */
+					nodeAddr = traversalStack[stackPtr];
+					--stackPtr;
+
+					/* triangle intersection */
+					while(primAddr < primAddr2) {
+						bool hit;
+						uint type = kernel_tex_fetch(__prim_type, primAddr);
+
+						switch(type & PRIMITIVE_ALL) {
+							case PRIMITIVE_TRIANGLE: {
+								hit = triangle_intersect(kg, isect, P, dir, visibility, object, primAddr);
+								break;
+							}
+#if FEATURE(BVH_MOTION)
+							case PRIMITIVE_MOTION_TRIANGLE: {
+								hit = motion_triangle_intersect(kg, isect, P, dir, ray->time, visibility, object, primAddr);
+								break;
+							}
+#endif
+#if FEATURE(BVH_HAIR)
+							case PRIMITIVE_CURVE:
+							case PRIMITIVE_MOTION_CURVE: {
+								if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
+									hit = bvh_cardinal_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax);
+								else
+									hit = bvh_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax);
+								break;
+							}
+#endif
+							default:
+								hit = false;
+								break;
+						}
+
+						/* shadow ray early termination */
+						if(hit

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list