diff options
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; |