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
This commit is contained in:
parent
0f69026b1c
commit
2f79d1c058
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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++;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
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
|
||||
);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
kernel_assert(kernel_data.bvh.use_qbvh == false);
|
||||
return BVH_FUNCTION_FULL_NAME(BVH)(kg,
|
||||
ray,
|
||||
isect,
|
||||
visibility
|
||||
#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
|
||||
, lcg_state,
|
||||
difl,
|
||||
extmax
|
||||
#endif
|
||||
);
|
||||
);
|
||||
}
|
||||
kernel_assert(!"Should not happen");
|
||||
return false;
|
||||
}
|
||||
|
||||
#undef BVH_FUNCTION_NAME
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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); }
|
||||
};
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user