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:
Sergey Sharybin 2018-01-19 10:59:58 +01:00
parent 0f69026b1c
commit 2f79d1c058
23 changed files with 267 additions and 136 deletions

View File

@ -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)

View File

@ -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()

View File

@ -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");

View File

@ -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;
}

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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++;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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); }
};

View File

@ -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";

View File

@ -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;