[Bf-blender-cvs] [c0edbf86bd6] cycles_procedural_api: reuse the packed vertices array to build object BVHs from

Kévin Dietrich noreply at git.blender.org
Thu Nov 5 18:57:54 CET 2020


Commit: c0edbf86bd6e84a06ca40012918822e7063e6e92
Author: Kévin Dietrich
Date:   Thu Nov 5 18:35:20 2020 +0100
Branches: cycles_procedural_api
https://developer.blender.org/rBc0edbf86bd6e84a06ca40012918822e7063e6e92

reuse the packed vertices array to build object BVHs from

===================================================================

M	intern/cycles/bvh/bvh.h
M	intern/cycles/bvh/bvh_optix.cpp
M	intern/cycles/device/device_optix.cpp
M	intern/cycles/render/geometry.cpp

===================================================================

diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index 033b1fd8e04..705151e4e02 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -87,6 +87,9 @@ class BVH {
   vector<Geometry *> geometry;
   vector<Object *> objects;
 
+  device_ptr prim_vert_pointer;
+  size_t pack_verts_offset;
+
   static BVH *create(const BVHParams &params,
                      const vector<Geometry *> &geometry,
                      const vector<Object *> &objects,
diff --git a/intern/cycles/bvh/bvh_optix.cpp b/intern/cycles/bvh/bvh_optix.cpp
index cc4ebac13b0..ffa69cb72bc 100644
--- a/intern/cycles/bvh/bvh_optix.cpp
+++ b/intern/cycles/bvh/bvh_optix.cpp
@@ -162,6 +162,8 @@ void BVHOptiX::pack_tlas()
   foreach (Geometry *geom, geometry) {
     PackedBVH &bvh_pack = geom->bvh->pack;
 
+    geom->bvh->pack_verts_offset = pack_verts_offset;
+
     // Merge visibility flags of all objects and fix object indices for non-instanced geometry
     int object_index = 0;  // Unused for instanced geometry
     int object_visibility = 0;
diff --git a/intern/cycles/device/device_optix.cpp b/intern/cycles/device/device_optix.cpp
index a5a8c8b54b9..6d5bb4e55f5 100644
--- a/intern/cycles/device/device_optix.cpp
+++ b/intern/cycles/device/device_optix.cpp
@@ -1426,14 +1426,15 @@ class OptiXDevice : public CUDADevice {
           continue;
         }
 
-        const size_t num_verts = mesh->get_verts().size();
-
         size_t num_motion_steps = 1;
         Attribute *motion_keys = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
         if (motion_blur && mesh->get_use_motion_blur() && motion_keys) {
           num_motion_steps = mesh->get_motion_steps();
         }
 
+#if 0
+        const size_t num_verts = mesh->get_verts().size();
+
         device_vector<int> index_data(this, "temp_index_data", MEM_READ_ONLY);
         index_data.alloc(mesh->get_triangles().size());
         memcpy(index_data.data(),
@@ -1483,6 +1484,30 @@ class OptiXDevice : public CUDADevice {
         // one and rely on that having the same meaning in this case.
         build_input.triangleArray.numSbtRecords = 1;
         build_input.triangleArray.primitiveIndexOffset = mesh->optix_prim_offset;
+#else
+        vector<device_ptr> vertex_ptrs;
+        vertex_ptrs.reserve(num_motion_steps);
+        vertex_ptrs.push_back(bvh->prim_vert_pointer + geom->bvh->pack_verts_offset * sizeof(float3));
+
+        // Force a single any-hit call, so shadow record-all behavior works correctly
+        unsigned int build_flags = OPTIX_GEOMETRY_FLAG_REQUIRE_SINGLE_ANYHIT_CALL;
+        OptixBuildInput build_input = {};
+        build_input.type = OPTIX_BUILD_INPUT_TYPE_TRIANGLES;
+        build_input.triangleArray.vertexBuffers = (CUdeviceptr *)vertex_ptrs.data();
+        build_input.triangleArray.numVertices = mesh->num_triangles() * 3;
+        build_input.triangleArray.vertexFormat = OPTIX_VERTEX_FORMAT_FLOAT3;
+        build_input.triangleArray.vertexStrideInBytes = sizeof(float3);
+        build_input.triangleArray.indexBuffer = 0;
+        build_input.triangleArray.numIndexTriplets = 0;
+        //build_input.triangleArray.indexFormat = OPTIX_INDICES_FORMAT_UNSIGNED_INT3;
+        build_input.triangleArray.indexStrideInBytes = 0;
+        build_input.triangleArray.flags = &build_flags;
+        // The SBT does not store per primitive data since Cycles already allocates separate
+        // buffers for that purpose. OptiX does not allow this to be zero though, so just pass in
+        // one and rely on that having the same meaning in this case.
+        build_input.triangleArray.numSbtRecords = 1;
+        build_input.triangleArray.primitiveIndexOffset = mesh->optix_prim_offset;
+#endif
 
         // Allocate memory for new BLAS and build it
         if (build_optix_bvh(build_input, num_motion_steps, handle, out_data, operation)) {
diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp
index e62d5ce348f..88ab31b86ac 100644
--- a/intern/cycles/render/geometry.cpp
+++ b/intern/cycles/render/geometry.cpp
@@ -1230,96 +1230,111 @@ void GeometryManager::device_update_bvh(Device *device,
 {
   /* bvh build */
   progress.set_status("Updating Scene BVH", "Building");
+  {
+    scoped_callback_timer timer([scene](double time) {
+      if (scene->update_stats) {
+        scene->update_stats->geometry.times.add_entry({"device_update (build scene BVH)", time});
+      }
+    });
+    BVHParams bparams;
+    bparams.top_level = true;
+    bparams.bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
+                                                    device->get_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;
+    bparams.bvh_type = scene->params.bvh_type;
+    bparams.curve_subdivisions = scene->params.curve_subdivisions();
 
-  BVHParams bparams;
-  bparams.top_level = true;
-  bparams.bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
-                                                  device->get_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;
-  bparams.bvh_type = scene->params.bvh_type;
-  bparams.curve_subdivisions = scene->params.curve_subdivisions();
-
-  VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
+    VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
 
-  if (bvh && !(device_update_flags & DEVICE_DATA_NEEDS_REALLOC)) {
-    bvh->pack = {};
-    bvh->refit(progress);
-  }
+    if (bvh && !(device_update_flags & DEVICE_DATA_NEEDS_REALLOC)) {
+      bvh->pack = {};
+      bvh->refit(progress);
+    }
 
-  if (!bvh || (device_update_flags & DEVICE_DATA_NEEDS_REALLOC)) {
-    bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
-  }
+    if (!bvh || (device_update_flags & DEVICE_DATA_NEEDS_REALLOC)) {
+      bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
+    }
 
-  bvh->build(progress, &device->stats);
+    bvh->build(progress, &device->stats);
 
-  if (progress.get_cancel()) {
+    if (progress.get_cancel()) {
 #ifdef WITH_EMBREE
-    if (dscene->data.bvh.scene) {
-      BVHEmbree::destroy(dscene->data.bvh.scene);
-      dscene->data.bvh.scene = NULL;
-    }
+      if (dscene->data.bvh.scene) {
+        BVHEmbree::destroy(dscene->data.bvh.scene);
+        dscene->data.bvh.scene = NULL;
+      }
 #endif
-    delete bvh;
-    bvh = nullptr;
-    return;
-  }
+      delete bvh;
+      bvh = nullptr;
+      return;
+    }
 
-  /* copy to device */
-  progress.set_status("Updating Scene BVH", "Copying BVH to device");
+    /* copy to device */
+    progress.set_status("Updating Scene BVH", "Copying BVH to device");
 
-  PackedBVH &pack = bvh->pack;
+    PackedBVH &pack = bvh->pack;
 
-  if (pack.nodes.size()) {
-    dscene->bvh_nodes.steal_data(pack.nodes);
-    dscene->bvh_nodes.copy_to_device();
-  }
-  if (pack.leaf_nodes.size()) {
-    dscene->bvh_leaf_nodes.steal_data(pack.leaf_nodes);
-    dscene->bvh_leaf_nodes.copy_to_device();
-  }
-  if (pack.object_node.size()) {
-    dscene->object_node.steal_data(pack.object_node);
-    dscene->object_node.copy_to_device();
-  }
-  if (pack.prim_tri_index.size() && (device_update_flags & DEVICE_DATA_NEEDS_REALLOC)) {
-    dscene->prim_tri_index.steal_data(pack.prim_tri_index);
-    dscene->prim_tri_index.copy_to_device();
-  }
-  if (pack.prim_tri_verts.size()) {
-    dscene->prim_tri_verts.steal_data(pack.prim_tri_verts);
-    dscene->prim_tri_verts.copy_to_device();
-  }
-  if (pack.prim_type.size() && (device_update_flags & DEVICE_DATA_NEEDS_REALLOC)) {
-    dscene->prim_type.steal_data(pack.prim_type);
-    dscene->prim_type.copy_to_device();
-  }
-  if (pack.prim_visibility.size() && (device_update_flags & DEVICE_DATA_NEEDS_REALLOC)) {
-    dscene->prim_visibility.steal_data(pack.prim_visibility);
-    dscene->prim_visibility.copy_to_device();
-  }
-  if (pack.prim_index.size() && (device_update_flags & DEVICE_DATA_NEEDS_REALLOC)) {
-    dscene->prim_index.steal_data(pack.prim_index);
-    dscene->prim_index.copy_to_device();
-  }
-  if (pack.prim_object.size() && (device_update_flags & DEVICE_DATA_NEEDS_REALLOC)) {
-    dscene->prim_object.steal_data(pack.prim_object);
-    dscene->prim_object.copy_to_device();
-  }
-  if (pack.prim_time.size() && (device_update_flags & DEVICE_DATA_NEEDS_REALLOC)) {
-    dscene->prim_time.steal_data(pack.prim_time);
-    dscene->prim_time.copy_to_device();
-  }
+    if (pack.nodes.size()) {
+      dscene->bvh_nodes.steal_data(pack.nodes);
+      dscene->bvh_nodes.copy_to_device();
+    }
+    if (pack.leaf_nodes.size()) {
+      dscene->bvh_leaf_nodes.steal_data(pack.leaf_nodes);
+      dscene->bvh_leaf_nodes.copy_to_device();
+    }
+    if (pack.object_node.size()) {
+      dscene->object_node.steal_data(pack.object_node);
+      dscene->object_node.copy_to_device();
+    }
+    if (pack.prim_tri_index.size() && (device_update_flags & DEVICE_DATA_NEEDS_REALLOC)) {
+      dscene->prim_tri_index.steal_data(pack.prim_tri_index);
+      dscene->prim_tri_index.copy_to_device();
+    }
+    if (pack.prim_tri_verts.size()) {
+      dscene->prim_tri_verts.steal_data(pack.prim_tri_verts);
+      dscene->prim_tri_verts.copy_to_device();
 
-  dscene->data.bvh.root = pack.root_index;
-  dscene->data.bvh.bvh_layout = bparams.bvh_layout;
-  dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0);
-  dscene->data.bvh.curve_subdivisions = scene->params.curve_subdivisions();
+      bvh->prim_vert_pointer = dscene->prim_tri_verts.device_pointer;
+    }
+    if (pack.prim_type.size() && (device_update_flags & DEVICE_DATA_NEEDS_REALLOC)) {
+      

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list