[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 &params_,
@@ -99,24 +85,27 @@ BVH::BVH(const BVHParams &params_,
 BVH *BVH::create(const BVHParams &params,
                  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 &params,
   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