[Bf-blender-cvs] [bfb6fce6594] master: Cycles: Add CPU+GPU rendering support with OptiX
Patrick Mours
noreply at git.blender.org
Fri Dec 11 14:03:48 CET 2020
Commit: bfb6fce6594e9cf133bd18aee311c1e5e32dc799
Author: Patrick Mours
Date: Thu Dec 10 14:18:25 2020 +0100
Branches: master
https://developer.blender.org/rBbfb6fce6594e9cf133bd18aee311c1e5e32dc799
Cycles: Add CPU+GPU rendering support with OptiX
Adds support for building multiple BVH types in order to support using both CPU and OptiX
devices for rendering simultaneously. Primitive packing for Embree and OptiX is now
standalone, so it only needs to be run once and can be shared between the two. Additionally,
BVH building was made a device call, so that each device backend can decide how to
perform the building. The multi-device for instance creates a special multi-BVH that holds
references to several sub-BVHs, one for each sub-device.
Reviewed By: brecht, kevindietrich
Differential Revision: https://developer.blender.org/D9718
===================================================================
M intern/cycles/blender/addon/properties.py
M intern/cycles/blender/blender_device.cpp
M intern/cycles/bvh/CMakeLists.txt
M intern/cycles/bvh/bvh.cpp
M intern/cycles/bvh/bvh.h
M intern/cycles/bvh/bvh2.cpp
M intern/cycles/bvh/bvh2.h
M intern/cycles/bvh/bvh_embree.cpp
M intern/cycles/bvh/bvh_embree.h
A intern/cycles/bvh/bvh_multi.cpp
A intern/cycles/bvh/bvh_multi.h
M intern/cycles/bvh/bvh_optix.cpp
M intern/cycles/bvh/bvh_optix.h
M intern/cycles/device/cuda/device_cuda.h
M intern/cycles/device/cuda/device_cuda_impl.cpp
M intern/cycles/device/device.cpp
M intern/cycles/device/device.h
M intern/cycles/device/device_cpu.cpp
M intern/cycles/device/device_multi.cpp
M intern/cycles/device/device_optix.cpp
M intern/cycles/kernel/bvh/bvh_embree.h
M intern/cycles/kernel/kernel_types.h
M intern/cycles/render/geometry.cpp
M intern/cycles/render/geometry.h
M intern/cycles/render/hair.cpp
M intern/cycles/render/hair.h
M intern/cycles/render/mesh.cpp
M intern/cycles/render/mesh.h
M intern/cycles/render/scene.cpp
M intern/cycles/render/scene.h
===================================================================
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 1cb29fc6cb0..2f204b2c658 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -1570,7 +1570,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
elif entry.type == 'CPU':
cpu_devices.append(entry)
# Extend all GPU devices with CPU.
- if compute_device_type in {'CUDA', 'OPENCL'}:
+ if compute_device_type in {'CUDA', 'OPTIX', 'OPENCL'}:
devices.extend(cpu_devices)
return devices
diff --git a/intern/cycles/blender/blender_device.cpp b/intern/cycles/blender/blender_device.cpp
index ffcaef0b2a9..977f8297de1 100644
--- a/intern/cycles/blender/blender_device.cpp
+++ b/intern/cycles/blender/blender_device.cpp
@@ -90,8 +90,7 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
mask |= DEVICE_MASK_CUDA;
}
else if (compute_device == COMPUTE_DEVICE_OPTIX) {
- /* Cannot use CPU and OptiX device at the same time right now, so replace mask. */
- mask = DEVICE_MASK_OPTIX;
+ mask |= DEVICE_MASK_OPTIX;
}
else if (compute_device == COMPUTE_DEVICE_OPENCL) {
mask |= DEVICE_MASK_OPENCL;
diff --git a/intern/cycles/bvh/CMakeLists.txt b/intern/cycles/bvh/CMakeLists.txt
index 703c69b1797..8cc72359757 100644
--- a/intern/cycles/bvh/CMakeLists.txt
+++ b/intern/cycles/bvh/CMakeLists.txt
@@ -25,6 +25,7 @@ set(SRC
bvh_binning.cpp
bvh_build.cpp
bvh_embree.cpp
+ bvh_multi.cpp
bvh_node.cpp
bvh_optix.cpp
bvh_sort.cpp
@@ -38,6 +39,7 @@ set(SRC_HEADERS
bvh_binning.h
bvh_build.h
bvh_embree.h
+ bvh_multi.h
bvh_node.h
bvh_optix.h
bvh_params.h
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index a51ac4cf4a9..256382e63ba 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -17,17 +17,11 @@
#include "bvh/bvh.h"
-#include "render/hair.h"
-#include "render/mesh.h"
-#include "render/object.h"
-
#include "bvh/bvh2.h"
-#include "bvh/bvh_build.h"
#include "bvh/bvh_embree.h"
-#include "bvh/bvh_node.h"
+#include "bvh/bvh_multi.h"
#include "bvh/bvh_optix.h"
-#include "util/util_foreach.h"
#include "util/util_logging.h"
#include "util/util_progress.h"
@@ -38,14 +32,17 @@ CCL_NAMESPACE_BEGIN
const char *bvh_layout_name(BVHLayout layout)
{
switch (layout) {
- case BVH_LAYOUT_BVH2:
- return "BVH2";
case BVH_LAYOUT_NONE:
return "NONE";
+ case BVH_LAYOUT_BVH2:
+ return "BVH2";
case BVH_LAYOUT_EMBREE:
return "EMBREE";
case BVH_LAYOUT_OPTIX:
return "OPTIX";
+ case BVH_LAYOUT_MULTI_OPTIX:
+ case BVH_LAYOUT_MULTI_OPTIX_EMBREE:
+ return "MULTI";
case BVH_LAYOUT_ALL:
return "ALL";
}
@@ -76,17 +73,6 @@ BVHLayout BVHParams::best_bvh_layout(BVHLayout requested_layout, BVHLayoutMask s
return (BVHLayout)(1 << widest_allowed_layout_mask);
}
-/* Pack Utility */
-
-BVHStackEntry::BVHStackEntry(const BVHNode *n, int i) : node(n), idx(i)
-{
-}
-
-int BVHStackEntry::encodeIdx() const
-{
- return (node->is_leaf()) ? ~idx : idx;
-}
-
/* BVH */
BVH::BVH(const BVHParams ¶ms_,
@@ -99,24 +85,27 @@ BVH::BVH(const BVHParams ¶ms_,
BVH *BVH::create(const BVHParams ¶ms,
const vector<Geometry *> &geometry,
const vector<Object *> &objects,
- const Device *device)
+ Device *device)
{
switch (params.bvh_layout) {
case BVH_LAYOUT_BVH2:
return new BVH2(params, geometry, objects);
case BVH_LAYOUT_EMBREE:
#ifdef WITH_EMBREE
- return new BVHEmbree(params, geometry, objects, device);
+ return new BVHEmbree(params, geometry, objects);
#else
- (void)device;
break;
#endif
case BVH_LAYOUT_OPTIX:
#ifdef WITH_OPTIX
- return new BVHOptiX(params, geometry, objects);
+ return new BVHOptiX(params, geometry, objects, device);
#else
+ (void)device;
break;
#endif
+ case BVH_LAYOUT_MULTI_OPTIX:
+ case BVH_LAYOUT_MULTI_OPTIX_EMBREE:
+ return new BVHMulti(params, geometry, objects);
case BVH_LAYOUT_NONE:
case BVH_LAYOUT_ALL:
break;
@@ -125,399 +114,4 @@ BVH *BVH::create(const BVHParams ¶ms,
return NULL;
}
-/* Building */
-
-void BVH::build(Progress &progress, Stats *)
-{
- progress.set_substatus("Building BVH");
-
- /* build nodes */
- BVHBuild bvh_build(objects,
- pack.prim_type,
- pack.prim_index,
- pack.prim_object,
- pack.prim_time,
- params,
- progress);
- BVHNode *bvh2_root = bvh_build.run();
-
- if (progress.get_cancel()) {
- if (bvh2_root != NULL) {
- bvh2_root->deleteSubtree();
- }
- return;
- }
-
- /* BVH builder returns tree in a binary mode (with two children per inner
- * node. Need to adopt that for a wider BVH implementations. */
- BVHNode *root = widen_children_nodes(bvh2_root);
- if (root != bvh2_root) {
- bvh2_root->deleteSubtree();
- }
-
- if (progress.get_cancel()) {
- if (root != NULL) {
- root->deleteSubtree();
- }
- return;
- }
-
- /* pack triangles */
- progress.set_substatus("Packing BVH triangles and strands");
- pack_primitives();
-
- if (progress.get_cancel()) {
- root->deleteSubtree();
- return;
- }
-
- /* pack nodes */
- progress.set_substatus("Packing BVH nodes");
- pack_nodes(root);
-
- /* free build nodes */
- root->deleteSubtree();
-}
-
-/* Refitting */
-
-void BVH::refit(Progress &progress)
-{
- progress.set_substatus("Packing BVH primitives");
- pack_primitives();
-
- if (progress.get_cancel())
- return;
-
- progress.set_substatus("Refitting BVH nodes");
- refit_nodes();
-}
-
-void BVH::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility)
-{
- /* Refit range of primitives. */
- for (int prim = start; prim < end; prim++) {
- int pidx = pack.prim_index[prim];
- int tob = pack.prim_object[prim];
- Object *ob = objects[tob];
-
- if (pidx == -1) {
- /* Object instance. */
- bbox.grow(ob->bounds);
- }
- else {
- /* Primitives. */
- if (pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
- /* Curves. */
- const Hair *hair = static_cast<const Hair *>(ob->get_geometry());
- int prim_offset = (params.top_level) ? hair->prim_offset : 0;
- Hair::Curve curve = hair->get_curve(pidx - prim_offset);
- int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
-
- curve.bounds_grow(k, &hair->get_curve_keys()[0], &hair->get_curve_radius()[0], bbox);
-
- /* Motion curves. */
- if (hair->get_use_motion_blur()) {
- Attribute *attr = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if (attr) {
- size_t hair_size = hair->get_curve_keys().size();
- size_t steps = hair->get_motion_steps() - 1;
- float3 *key_steps = attr->data_float3();
-
- for (size_t i = 0; i < steps; i++)
- curve.bounds_grow(k, key_steps + i * hair_size, &hair->get_curve_radius()[0], bbox);
- }
- }
- }
- else {
- /* Triangles. */
- const Mesh *mesh = static_cast<const Mesh *>(ob->get_geometry());
- int prim_offset = (params.top_level) ? mesh->prim_offset : 0;
- Mesh::Triangle triangle = mesh->get_triangle(pidx - prim_offset);
- const float3 *vpos = &mesh->verts[0];
-
- triangle.bounds_grow(vpos, bbox);
-
- /* Motion triangles. */
- if (mesh->use_motion_blur) {
- Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if (attr) {
- size_t mesh_size = mesh->verts.size();
- size_t steps = mesh->motion_steps - 1;
- float3 *vert_steps = attr->data_float3();
-
- for (size_t i = 0; i < steps; i++)
- triangle.bounds_grow(vert_steps + i * mesh_size, bbox);
- }
- }
- }
- }
- visibility |= ob->visibility_for_tracing();
- }
-}
-
-/* Triangles */
-
-void BVH::pack_triangle(int idx, float4 tri_verts[3])
-{
- int tob = pack.prim_object[idx];
- assert(tob >= 0 && tob < objects.size());
- const Mesh *mesh = static_cast<const Mesh *>(objects[tob]->get_geometry());
-
- int tidx = pack.prim_index[idx];
- Mesh::Triangle t = mesh->get_triangle(tidx);
- const float3 *vpos = &mesh->verts[0];
- float3 v0 = vpos[t.v[0]];
- float3 v1 = vpos[t.v[1]];
- float3 v2 = vpos[t.v[2]];
-
- tri_verts[0] = float3_to_float4(v0);
- tri_verts[1] = float3_to_float4(v1);
- tri_verts[2] = float3_to_float4(v2);
-}
-
-void BVH::pack_primitives()
-{
- const size_t tidx_size = pack.prim_index.size();
- size_t num_prim_triangles = 0;
- /* Count number of triangles primitives in BVH. */
- for (unsigned int i = 0; i < tidx_size; i++) {
- if ((pack.prim_index[i] != -1)) {
- if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
- ++num_prim_triangles;
- }
- }
- }
- /* Reserve size for arrays. */
- pack.prim_tri_index.clear();
- pack.prim_tri_index.resize(tidx_size);
- pack.prim_tri_verts.clear();
- pack.prim_tri_verts.resize(num_prim_triangles * 3);
- pack.prim_visibility.clear();
- pack.prim_visibility.resize(tidx_size);
- /* Fill in all the arrays. */
- size_t prim_triangle_index = 0;
- for (unsigned int i = 0; i < tidx_size; i++) {
- if (pack.prim_index[i] != -1) {
- int tob = pack.prim_object[i];
- Object *ob = objects[tob];
- if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
- pack_triangle(i, (float4 *)&pack.prim_tri_verts[3 * prim_triangle_index]);
- pack.prim_tri_index[i] = 3 * prim_triangle_index;
- ++prim_triangle_index;
- }
- else {
- pack.prim_tri_index[i] = -1;
- }
- pack.prim_visibility[i] = ob->visibility_for_tracing();
- }
- else {
- pack.prim_tri_index[i] = -1;
- pack.prim_visibility[i] = 0;
- }
- }
-}
-
-/* Pack Instances */
-
-void BVH::pack_instances(size_t nodes_size, size_t leaf_n
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list