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:
authorSergey Sharybin <sergey.vfx@gmail.com>2018-01-19 12:59:58 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2018-01-22 19:19:20 +0300
commit2f79d1c0584f4d72984e56db1f5878be3360e044 (patch)
treef2385b9834d7a9e0c15be92ca5356f4bc91aa247
parent0f69026b1c3c07b203aeba658048f1129e41b116 (diff)
Cycles: Replace use_qbvh boolean flag with an enum-based property
This was we can introduce other types of BVH, for example, wider ones, without causing too much mess around boolean flags. Thoughs: - Ideally device info should probably return bitflag of what BVH types it supports. It is possible to implement based on simple logic in device/ and mesh.cpp, rest of the changes will stay the same. - Not happy with workarounds in util_debug and duplicated enum in kernel. Maybe enbum should be stores in kernel, but then it's kind of weird to include kernel types from utils. Soudns some cyclkic dependency. Reviewers: brecht, maxim_d33 Reviewed By: brecht Differential Revision: https://developer.blender.org/D3011
-rw-r--r--intern/cycles/blender/addon/properties.py11
-rw-r--r--intern/cycles/blender/addon/ui.py2
-rw-r--r--intern/cycles/blender/blender_python.cpp2
-rw-r--r--intern/cycles/blender/blender_sync.cpp2
-rw-r--r--intern/cycles/bvh/bvh.cpp54
-rw-r--r--intern/cycles/bvh/bvh4.cpp2
-rw-r--r--intern/cycles/bvh/bvh_params.h32
-rw-r--r--intern/cycles/device/device.cpp4
-rw-r--r--intern/cycles/device/device.h20
-rw-r--r--intern/cycles/device/device_cpu.cpp5
-rw-r--r--intern/cycles/device/device_cuda.cpp2
-rw-r--r--intern/cycles/device/device_network.cpp2
-rw-r--r--intern/cycles/device/device_opencl.cpp2
-rw-r--r--intern/cycles/kernel/bvh/bvh_local.h33
-rw-r--r--intern/cycles/kernel/bvh/bvh_shadow_all.h34
-rw-r--r--intern/cycles/kernel/bvh/bvh_traversal.h48
-rw-r--r--intern/cycles/kernel/bvh/bvh_volume.h26
-rw-r--r--intern/cycles/kernel/bvh/bvh_volume_all.h30
-rw-r--r--intern/cycles/kernel/kernel_types.h12
-rw-r--r--intern/cycles/render/mesh.cpp14
-rw-r--r--intern/cycles/render/scene.h36
-rw-r--r--intern/cycles/util/util_debug.cpp20
-rw-r--r--intern/cycles/util/util_debug.h10
23 files changed, 267 insertions, 136 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 7410cc32342..a63d84f2da6 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -47,6 +47,11 @@ enum_displacement_methods = (
('BOTH', "Both", "Combination of displacement and bump mapping"),
)
+enum_bvh_layouts = (
+ ('BVH2', "BVH2", "", 1),
+ ('BVH4', "BVH4", "", 2),
+ )
+
enum_bvh_types = (
('DYNAMIC_BVH', "Dynamic BVH", "Objects can be individually updated, at the cost of slower render time"),
('STATIC_BVH', "Static BVH", "Any object modification requires a complete BVH rebuild, but renders faster"),
@@ -670,7 +675,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
cls.debug_use_cpu_sse41 = BoolProperty(name="SSE41", default=True)
cls.debug_use_cpu_sse3 = BoolProperty(name="SSE3", default=True)
cls.debug_use_cpu_sse2 = BoolProperty(name="SSE2", default=True)
- cls.debug_use_qbvh = BoolProperty(name="QBVH", default=True)
+ cls.debug_bvh_layout = EnumProperty(
+ name="BVH Layout",
+ items=enum_bvh_layouts,
+ default='BVH4',
+ )
cls.debug_use_cpu_split_kernel = BoolProperty(name="Split Kernel", default=False)
cls.debug_use_cuda_adaptive_compile = BoolProperty(name="Adaptive Compile", default=False)
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 5d58ecc99eb..543ba7c6d4d 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1609,7 +1609,7 @@ class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
row.prop(cscene, "debug_use_cpu_sse41", toggle=True)
row.prop(cscene, "debug_use_cpu_avx", toggle=True)
row.prop(cscene, "debug_use_cpu_avx2", toggle=True)
- col.prop(cscene, "debug_use_qbvh")
+ col.prop(cscene, "debug_bvh_layout")
col.prop(cscene, "debug_use_cpu_split_kernel")
col.separator()
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 687ddd9e7c3..792597cbad5 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -69,7 +69,7 @@ bool debug_flags_sync_from_scene(BL::Scene b_scene)
flags.cpu.sse41 = get_boolean(cscene, "debug_use_cpu_sse41");
flags.cpu.sse3 = get_boolean(cscene, "debug_use_cpu_sse3");
flags.cpu.sse2 = get_boolean(cscene, "debug_use_cpu_sse2");
- flags.cpu.qbvh = get_boolean(cscene, "debug_use_qbvh");
+ flags.cpu.bvh_layout = (BVHLayout)get_enum(cscene, "debug_bvh_layout");
flags.cpu.split_kernel = get_boolean(cscene, "debug_use_cpu_split_kernel");
/* Synchronize CUDA flags. */
flags.cuda.adaptive_compile = get_boolean(cscene, "debug_use_cuda_adaptive_compile");
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index b7c6fbc9d29..283aa5600fd 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -662,7 +662,7 @@ SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene,
params.texture_limit = 0;
}
- params.use_qbvh = DebugFlags().cpu.qbvh;
+ params.bvh_layout = DebugFlags().cpu.bvh_layout;
return params;
}
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 6531ca50d9a..5bfe9d4ed1a 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -26,10 +26,46 @@
#include "bvh/bvh_node.h"
#include "util/util_foreach.h"
+#include "util/util_logging.h"
#include "util/util_progress.h"
CCL_NAMESPACE_BEGIN
+/* BVH Parameters. */
+
+const char *bvh_layout_name(BVHLayout layout)
+{
+ switch(layout) {
+ case BVH_LAYOUT_BVH2: return "BVH2";
+ case BVH_LAYOUT_BVH4: return "BVH4";
+ case BVH_LAYOUT_NONE: return "NONE";
+ case BVH_LAYOUT_ALL: return "ALL";
+ }
+ LOG(DFATAL) << "Unsupported BVH layout was passed.";
+ return "";
+}
+
+BVHLayout BVHParams::best_bvh_layout(BVHLayout requested_layout,
+ BVHLayoutMask supported_layouts)
+{
+ const BVHLayoutMask requested_layout_mask = (BVHLayoutMask)requested_layout;
+ /* Check whether requested layout is supported, if so -- no need to do
+ * any extra computation.
+ */
+ if(supported_layouts & requested_layout_mask) {
+ return requested_layout;
+ }
+ /* Some bit magic to get widest supported BVH layout. */
+ /* This is a mask of supported BVH layouts which are narrower than the
+ * requested one.
+ */
+ const BVHLayoutMask allowed_layouts_mask =
+ (supported_layouts & (requested_layout_mask - 1));
+ /* We get widest from allowed ones and convert mask to actual layout. */
+ const BVHLayoutMask widest_allowed_layout_mask = __bsr(allowed_layouts_mask);
+ return (BVHLayout)widest_allowed_layout_mask;
+}
+
/* Pack Utility */
BVHStackEntry::BVHStackEntry(const BVHNode *n, int i)
@@ -51,10 +87,17 @@ BVH::BVH(const BVHParams& params_, const vector<Object*>& objects_)
BVH *BVH::create(const BVHParams& params, const vector<Object*>& objects)
{
- if(params.use_qbvh)
- return new BVH4(params, objects);
- else
- return new BVH2(params, objects);
+ switch(params.bvh_layout) {
+ case BVH_LAYOUT_BVH2:
+ return new BVH2(params, objects);
+ case BVH_LAYOUT_BVH4:
+ return new BVH4(params, objects);
+ case BVH_LAYOUT_NONE:
+ case BVH_LAYOUT_ALL:
+ break;
+ }
+ LOG(DFATAL) << "Requested unsupported BVH layout.";
+ return NULL;
}
/* Building */
@@ -248,7 +291,8 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
* BVH's are stored in global arrays. This function merges them into the
* top level BVH, adjusting indexes and offsets where appropriate.
*/
- const bool use_qbvh = params.use_qbvh;
+ /* TODO(sergey): This code needs adjustment for wider BVH than 4. */
+ const bool use_qbvh = (params.bvh_layout == BVH_LAYOUT_BVH4);
/* Adjust primitive index to point to the triangle in the global array, for
* meshes with transform applied and already in the top level BVH.
diff --git a/intern/cycles/bvh/bvh4.cpp b/intern/cycles/bvh/bvh4.cpp
index b910feccec8..4faf47af7bb 100644
--- a/intern/cycles/bvh/bvh4.cpp
+++ b/intern/cycles/bvh/bvh4.cpp
@@ -55,7 +55,7 @@ static bool node_qbvh_is_unaligned(const BVHNode *node)
BVH4::BVH4(const BVHParams& params_, const vector<Object*>& objects_)
: BVH(params_, objects_)
{
- params.use_qbvh = true;
+ params.bvh_layout = BVH_LAYOUT_BVH4;
}
void BVH4::pack_leaf(const BVHStackEntry& e, const LeafNode *leaf)
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index 7dd699b33a4..89a379cf356 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -24,11 +24,29 @@
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;
+
+/* 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;
@@ -50,8 +68,8 @@ public:
/* object or mesh level bvh */
bool top_level;
- /* QBVH */
- bool use_qbvh;
+ /* BVH layout to be built. */
+ BVHLayout bvh_layout;
/* Mask of primitives to be included into the BVH. */
int primitive_mask;
@@ -98,7 +116,7 @@ public:
max_motion_curve_leaf_size = 4;
top_level = false;
- use_qbvh = false;
+ bvh_layout = BVH_LAYOUT_BVH2;
use_unaligned_nodes = false;
primitive_mask = PRIMITIVE_ALL;
@@ -119,6 +137,14 @@ public:
__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
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index d55a999c454..1ec0bc3e1c6 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -362,7 +362,7 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo>& subdevices, int th
info.has_fermi_limits = false;
info.has_half_images = true;
info.has_volume_decoupled = true;
- info.has_qbvh = true;
+ info.bvh_layout_mask = BVH_LAYOUT_ALL;
info.has_osl = true;
foreach(const DeviceInfo &device, subdevices) {
@@ -399,7 +399,7 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo>& subdevices, int th
device.has_fermi_limits;
info.has_half_images &= device.has_half_images;
info.has_volume_decoupled &= device.has_volume_decoupled;
- info.has_qbvh &= device.has_qbvh;
+ info.bvh_layout_mask = device.bvh_layout_mask & info.bvh_layout_mask;
info.has_osl &= device.has_osl;
}
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 528a6dc10f6..99e80d10424 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -19,6 +19,8 @@
#include <stdlib.h>
+#include "bvh/bvh_params.h"
+
#include "device/device_memory.h"
#include "device/device_task.h"
@@ -52,14 +54,14 @@ public:
string description;
string id; /* used for user preferences, should stay fixed with changing hardware config */
int num;
- bool display_device; /* GPU is used as a display device. */
- bool advanced_shading; /* Supports full shading system. */
- bool has_fermi_limits; /* Fixed number of textures limit. */
- bool has_half_images; /* Support half-float textures. */
- bool has_volume_decoupled; /* Decoupled volume shading. */
- bool has_qbvh; /* Supports both BVH2 and BVH4 raytracing. */
- bool has_osl; /* Support Open Shading Language. */
- bool use_split_kernel; /* Use split or mega kernel. */
+ bool display_device; /* GPU is used as a display device. */
+ bool advanced_shading; /* Supports full shading system. */
+ bool has_fermi_limits; /* Fixed number of textures limit. */
+ bool has_half_images; /* Support half-float textures. */
+ bool has_volume_decoupled; /* Decoupled volume shading. */
+ BVHLayoutMask bvh_layout_mask; /* Bitmask of supported BVH layouts. */
+ bool has_osl; /* Support Open Shading Language. */
+ bool use_split_kernel; /* Use split or mega kernel. */
int cpu_threads;
vector<DeviceInfo> multi_devices;
@@ -74,7 +76,7 @@ public:
has_fermi_limits = false;
has_half_images = false;
has_volume_decoupled = false;
- has_qbvh = false;
+ bvh_layout_mask = BVH_LAYOUT_NONE;
has_osl = false;
use_split_kernel = false;
}
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 6b6b3432446..fd55ec3687a 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -1046,7 +1046,10 @@ void device_cpu_info(vector<DeviceInfo>& devices)
info.id = "CPU";
info.num = 0;
info.advanced_shading = true;
- info.has_qbvh = system_cpu_support_sse2();
+ info.bvh_layout_mask = BVH_LAYOUT_BVH2;
+ if (system_cpu_support_sse2()) {
+ info.bvh_layout_mask |= BVH_LAYOUT_BVH4;
+ }
info.has_volume_decoupled = true;
info.has_osl = true;
info.has_half_images = true;
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 116f4e2a452..f3548640679 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -2551,7 +2551,7 @@ void device_cuda_info(vector<DeviceInfo>& devices)
info.has_fermi_limits = !(major >= 3);
info.has_half_images = (major >= 3);
info.has_volume_decoupled = false;
- info.has_qbvh = false;
+ info.bvh_layout_mask = BVH_LAYOUT_BVH2;
int pci_location[3] = {0, 0, 0};
cuDeviceGetAttribute(&pci_location[0], CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, num);
diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp
index 536d5ee08c0..5ad4405366e 100644
--- a/intern/cycles/device/device_network.cpp
+++ b/intern/cycles/device/device_network.cpp
@@ -306,7 +306,7 @@ void device_network_info(vector<DeviceInfo>& devices)
/* todo: get this info from device */
info.advanced_shading = true;
info.has_volume_decoupled = false;
- info.has_qbvh = false;
+ info.bvh_layout_mask = BVH_LAYOUT_BVH2;
info.has_osl = false;
devices.push_back(info);
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index d3eebb10028..9d61bbdae5d 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -135,7 +135,7 @@ void device_opencl_info(vector<DeviceInfo>& devices)
info.use_split_kernel = OpenCLInfo::kernel_use_split(platform_name,
device_type);
info.has_volume_decoupled = false;
- info.has_qbvh = false;
+ info.bvh_layout_mask = BVH_LAYOUT_BVH2;
info.id = id;
devices.push_back(info);
num_devices++;
diff --git a/intern/cycles/kernel/bvh/bvh_local.h b/intern/cycles/kernel/bvh/bvh_local.h
index 12d14428d6d..9292cc76a5c 100644
--- a/intern/cycles/kernel/bvh/bvh_local.h
+++ b/intern/cycles/kernel/bvh/bvh_local.h
@@ -243,26 +243,25 @@ ccl_device_inline void BVH_FUNCTION_NAME(KernelGlobals *kg,
uint *lcg_state,
int max_hits)
{
+ switch(kernel_data.bvh.bvh_layout) {
#ifdef __QBVH__
- if(kernel_data.bvh.use_qbvh) {
- return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
- ray,
- local_isect,
- local_object,
- lcg_state,
- max_hits);
- }
- else
+ case BVH_LAYOUT_BVH4:
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
+ ray,
+ local_isect,
+ local_object,
+ lcg_state,
+ max_hits);
#endif
- {
- kernel_assert(kernel_data.bvh.use_qbvh == false);
- return BVH_FUNCTION_FULL_NAME(BVH)(kg,
- ray,
- local_isect,
- local_object,
- lcg_state,
- max_hits);
+ case BVH_LAYOUT_BVH2:
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg,
+ ray,
+ local_isect,
+ local_object,
+ lcg_state,
+ max_hits);
}
+ kernel_assert(!"Should not happen");
}
#undef BVH_FUNCTION_NAME
diff --git a/intern/cycles/kernel/bvh/bvh_shadow_all.h b/intern/cycles/kernel/bvh/bvh_shadow_all.h
index a6a4353562c..efd6798ca51 100644
--- a/intern/cycles/kernel/bvh/bvh_shadow_all.h
+++ b/intern/cycles/kernel/bvh/bvh_shadow_all.h
@@ -395,26 +395,26 @@ ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
const uint max_hits,
uint *num_hits)
{
+ switch(kernel_data.bvh.bvh_layout) {
#ifdef __QBVH__
- if(kernel_data.bvh.use_qbvh) {
- return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
- ray,
- isect_array,
- visibility,
- max_hits,
- num_hits);
- }
- else
+ case BVH_LAYOUT_BVH4:
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
+ ray,
+ isect_array,
+ visibility,
+ max_hits,
+ num_hits);
#endif
- {
- kernel_assert(kernel_data.bvh.use_qbvh == false);
- return BVH_FUNCTION_FULL_NAME(BVH)(kg,
- ray,
- isect_array,
- visibility,
- max_hits,
- num_hits);
+ case BVH_LAYOUT_BVH2:
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg,
+ ray,
+ isect_array,
+ visibility,
+ max_hits,
+ num_hits);
}
+ kernel_assert(!"Should not happen");
+ return false;
}
#undef BVH_FUNCTION_NAME
diff --git a/intern/cycles/kernel/bvh/bvh_traversal.h b/intern/cycles/kernel/bvh/bvh_traversal.h
index ae8f54821f2..551625eae78 100644
--- a/intern/cycles/kernel/bvh/bvh_traversal.h
+++ b/intern/cycles/kernel/bvh/bvh_traversal.h
@@ -426,34 +426,34 @@ ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
#endif
)
{
+ switch(kernel_data.bvh.bvh_layout) {
#ifdef __QBVH__
- if(kernel_data.bvh.use_qbvh) {
- return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
- ray,
- isect,
- visibility
-#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- , lcg_state,
- difl,
- extmax
-#endif
- );
- }
- else
-#endif
- {
- kernel_assert(kernel_data.bvh.use_qbvh == false);
- return BVH_FUNCTION_FULL_NAME(BVH)(kg,
- ray,
- isect,
- visibility
+ case BVH_LAYOUT_BVH4:
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
+ ray,
+ isect,
+ visibility
+# if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+ , lcg_state,
+ difl,
+ extmax
+# endif
+ );
+#endif /* __QBVH__ */
+ case BVH_LAYOUT_BVH2:
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg,
+ ray,
+ isect,
+ visibility
#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- , lcg_state,
- difl,
- extmax
+ , lcg_state,
+ difl,
+ extmax
#endif
- );
+ );
}
+ kernel_assert(!"Should not happen");
+ return false;
}
#undef BVH_FUNCTION_NAME
diff --git a/intern/cycles/kernel/bvh/bvh_volume.h b/intern/cycles/kernel/bvh/bvh_volume.h
index 764aaee44a1..ce5fc7be33d 100644
--- a/intern/cycles/kernel/bvh/bvh_volume.h
+++ b/intern/cycles/kernel/bvh/bvh_volume.h
@@ -309,22 +309,22 @@ ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
Intersection *isect,
const uint visibility)
{
+ switch(kernel_data.bvh.bvh_layout) {
#ifdef __QBVH__
- if(kernel_data.bvh.use_qbvh) {
- return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
- ray,
- isect,
- visibility);
- }
- else
+ case BVH_LAYOUT_BVH4:
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
+ ray,
+ isect,
+ visibility);
#endif
- {
- kernel_assert(kernel_data.bvh.use_qbvh == false);
- return BVH_FUNCTION_FULL_NAME(BVH)(kg,
- ray,
- isect,
- visibility);
+ case BVH_LAYOUT_BVH2:
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg,
+ ray,
+ isect,
+ visibility);
}
+ kernel_assert(!"Should not happen");
+ return false;
}
#undef BVH_FUNCTION_NAME
diff --git a/intern/cycles/kernel/bvh/bvh_volume_all.h b/intern/cycles/kernel/bvh/bvh_volume_all.h
index 04ec334e54d..f2379efc656 100644
--- a/intern/cycles/kernel/bvh/bvh_volume_all.h
+++ b/intern/cycles/kernel/bvh/bvh_volume_all.h
@@ -381,24 +381,24 @@ ccl_device_inline uint BVH_FUNCTION_NAME(KernelGlobals *kg,
const uint max_hits,
const uint visibility)
{
+ switch(kernel_data.bvh.bvh_layout) {
#ifdef __QBVH__
- if(kernel_data.bvh.use_qbvh) {
- return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
- ray,
- isect_array,
- max_hits,
- visibility);
- }
- else
+ case BVH_LAYOUT_BVH4:
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
+ ray,
+ isect_array,
+ max_hits,
+ visibility);
#endif
- {
- kernel_assert(kernel_data.bvh.use_qbvh == false);
- return BVH_FUNCTION_FULL_NAME(BVH)(kg,
- ray,
- isect_array,
- max_hits,
- visibility);
+ case BVH_LAYOUT_BVH2:
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg,
+ ray,
+ isect_array,
+ max_hits,
+ visibility);
}
+ kernel_assert(!"Should not happen");
+ return 0;
}
#undef BVH_FUNCTION_NAME
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 4f655784044..1e1a4f34650 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -1344,13 +1344,23 @@ typedef struct KernelIntegrator {
} KernelIntegrator;
static_assert_align(KernelIntegrator, 16);
+typedef enum KernelBVHLayout {
+ BVH_LAYOUT_NONE = 0,
+
+ BVH_LAYOUT_BVH2 = (1 << 0),
+ BVH_LAYOUT_BVH4 = (1 << 1),
+
+ BVH_LAYOUT_DEFAULT = BVH_LAYOUT_BVH4,
+ BVH_LAYOUT_ALL = (unsigned int)(-1),
+} KernelBVHLayout;
+
typedef struct KernelBVH {
/* root node */
int root;
int have_motion;
int have_curves;
int have_instancing;
- int use_qbvh;
+ int bvh_layout;
int use_bvh_steps;
int pad1, pad2;
} KernelBVH;
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 5d5a416e293..4bf5b60a737 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -1058,7 +1058,9 @@ void Mesh::compute_bvh(Device *device,
BVHParams bparams;
bparams.use_spatial_split = params->use_bvh_spatial_split;
- bparams.use_qbvh = params->use_qbvh && device->info.has_qbvh;
+ bparams.bvh_layout = BVHParams::best_bvh_layout(
+ params->bvh_layout,
+ device->info.bvh_layout_mask);
bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
params->use_bvh_unaligned_nodes;
bparams.num_motion_triangle_steps = params->num_bvh_time_steps;
@@ -1817,15 +1819,17 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
BVHParams bparams;
bparams.top_level = true;
- bparams.use_qbvh = scene->params.use_qbvh && device->info.has_qbvh;
+ bparams.bvh_layout = BVHParams::best_bvh_layout(
+ scene->params.bvh_layout,
+ device->info.bvh_layout_mask);
bparams.use_spatial_split = scene->params.use_bvh_spatial_split;
bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
scene->params.use_bvh_unaligned_nodes;
bparams.num_motion_triangle_steps = scene->params.num_bvh_time_steps;
bparams.num_motion_curve_steps = scene->params.num_bvh_time_steps;
- VLOG(1) << (bparams.use_qbvh ? "Using QBVH optimization structure"
- : "Using regular BVH optimization structure");
+ VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout)
+ << " layout.";
BVH *bvh = BVH::create(bparams, scene->objects);
bvh->build(progress);
@@ -1882,7 +1886,7 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
}
dscene->data.bvh.root = pack.root_index;
- dscene->data.bvh.use_qbvh = bparams.use_qbvh;
+ dscene->data.bvh.bvh_layout = bparams.bvh_layout;
dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0);
delete bvh;
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 5f717e93b43..ea9485ff230 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -17,6 +17,8 @@
#ifndef __SCENE_H__
#define __SCENE_H__
+#include "bvh/bvh_params.h"
+
#include "render/image.h"
#include "render/shader.h"
@@ -122,39 +124,63 @@ public:
class SceneParams {
public:
- ShadingSystem shadingsystem;
+ /* 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_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_STATIC = 1,
BVH_NUM_TYPES,
- } bvh_type;
+ };
+
+ ShadingSystem shadingsystem;
+
+ /* Requested BVH layout.
+ *
+ * If it's not supported by the device, the widest one from supported ones
+ * will be used, but BVH wider than this one will never be used.
+ */
+ BVHLayout bvh_layout;
+
+ BVHType bvh_type;
bool use_bvh_spatial_split;
bool use_bvh_unaligned_nodes;
int num_bvh_time_steps;
- bool use_qbvh;
+
bool persistent_data;
int texture_limit;
SceneParams()
{
shadingsystem = SHADINGSYSTEM_SVM;
+ bvh_layout = BVH_LAYOUT_BVH2;
bvh_type = BVH_DYNAMIC;
use_bvh_spatial_split = false;
use_bvh_unaligned_nodes = true;
num_bvh_time_steps = 0;
- use_qbvh = true;
persistent_data = false;
texture_limit = 0;
}
bool modified(const SceneParams& params)
{ return !(shadingsystem == params.shadingsystem
+ && bvh_layout == params.bvh_layout
&& bvh_type == params.bvh_type
&& use_bvh_spatial_split == params.use_bvh_spatial_split
&& use_bvh_unaligned_nodes == params.use_bvh_unaligned_nodes
&& num_bvh_time_steps == params.num_bvh_time_steps
- && use_qbvh == params.use_qbvh
&& persistent_data == params.persistent_data
&& texture_limit == params.texture_limit); }
};
diff --git a/intern/cycles/util/util_debug.cpp b/intern/cycles/util/util_debug.cpp
index eb078d69252..9a66a372822 100644
--- a/intern/cycles/util/util_debug.cpp
+++ b/intern/cycles/util/util_debug.cpp
@@ -18,6 +18,8 @@
#include <stdlib.h>
+#include "bvh/bvh_params.h"
+
#include "util/util_logging.h"
#include "util/util_string.h"
@@ -29,7 +31,7 @@ DebugFlags::CPU::CPU()
sse41(true),
sse3(true),
sse2(true),
- qbvh(true),
+ bvh_layout(BVH_LAYOUT_DEFAULT),
split_kernel(false)
{
reset();
@@ -55,7 +57,7 @@ void DebugFlags::CPU::reset()
#undef STRINGIFY
#undef CHECK_CPU_FLAGS
- qbvh = true;
+ bvh_layout = BVH_LAYOUT_DEFAULT;
split_kernel = false;
}
@@ -139,13 +141,13 @@ std::ostream& operator <<(std::ostream &os,
DebugFlagsConstRef debug_flags)
{
os << "CPU flags:\n"
- << " AVX2 : " << string_from_bool(debug_flags.cpu.avx2) << "\n"
- << " AVX : " << string_from_bool(debug_flags.cpu.avx) << "\n"
- << " SSE4.1 : " << string_from_bool(debug_flags.cpu.sse41) << "\n"
- << " SSE3 : " << string_from_bool(debug_flags.cpu.sse3) << "\n"
- << " SSE2 : " << string_from_bool(debug_flags.cpu.sse2) << "\n"
- << " QBVH : " << string_from_bool(debug_flags.cpu.qbvh) << "\n"
- << " Split : " << string_from_bool(debug_flags.cpu.split_kernel) << "\n";
+ << " AVX2 : " << string_from_bool(debug_flags.cpu.avx2) << "\n"
+ << " AVX : " << string_from_bool(debug_flags.cpu.avx) << "\n"
+ << " SSE4.1 : " << string_from_bool(debug_flags.cpu.sse41) << "\n"
+ << " SSE3 : " << string_from_bool(debug_flags.cpu.sse3) << "\n"
+ << " SSE2 : " << string_from_bool(debug_flags.cpu.sse2) << "\n"
+ << " BVH layout : " << bvh_layout_name(debug_flags.cpu.bvh_layout) << "\n"
+ << " Split : " << string_from_bool(debug_flags.cpu.split_kernel) << "\n";
os << "CUDA flags:\n"
<< " Adaptive Compile: " << string_from_bool(debug_flags.cuda.adaptive_compile) << "\n";
diff --git a/intern/cycles/util/util_debug.h b/intern/cycles/util/util_debug.h
index ec38cd373ba..f17f8a560ee 100644
--- a/intern/cycles/util/util_debug.h
+++ b/intern/cycles/util/util_debug.h
@@ -20,6 +20,8 @@
#include <cassert>
#include <iostream>
+#include "bvh/bvh_params.h"
+
CCL_NAMESPACE_BEGIN
/* Global storage for all sort of flags used to fine-tune behavior of particular
@@ -54,8 +56,12 @@ public:
bool has_sse3() { return has_sse2() && sse3; }
bool has_sse2() { return sse2; }
- /* Whether QBVH usage is allowed or not. */
- bool qbvh;
+ /* Requested BVH size.
+ *
+ * Rendering will use widest possible BVH which is below or equal
+ * this one.
+ */
+ BVHLayout bvh_layout;
/* Whether split kernel is used */
bool split_kernel;