Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Mours <pmours@nvidia.com>2020-12-10 16:18:25 +0300
committerPatrick Mours <pmours@nvidia.com>2020-12-11 15:24:29 +0300
commitbfb6fce6594e9cf133bd18aee311c1e5e32dc799 (patch)
tree7c813e17ea87e9aae64221b3ac7a8d42ab894c85 /intern/cycles/bvh/bvh_optix.cpp
parentd72ec16e70721408c875040325c984941687b4a2 (diff)
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
Diffstat (limited to 'intern/cycles/bvh/bvh_optix.cpp')
-rw-r--r--intern/cycles/bvh/bvh_optix.cpp204
1 files changed, 7 insertions, 197 deletions
diff --git a/intern/cycles/bvh/bvh_optix.cpp b/intern/cycles/bvh/bvh_optix.cpp
index 52fc9c0a50d..e094f339ede 100644
--- a/intern/cycles/bvh/bvh_optix.cpp
+++ b/intern/cycles/bvh/bvh_optix.cpp
@@ -19,212 +19,22 @@
# include "bvh/bvh_optix.h"
-# include "device/device.h"
-
-# include "render/geometry.h"
-# include "render/hair.h"
-# include "render/mesh.h"
-# include "render/object.h"
-
-# include "util/util_foreach.h"
-# include "util/util_logging.h"
-# include "util/util_progress.h"
-
CCL_NAMESPACE_BEGIN
BVHOptiX::BVHOptiX(const BVHParams &params_,
const vector<Geometry *> &geometry_,
- const vector<Object *> &objects_)
- : BVH(params_, geometry_, objects_)
+ const vector<Object *> &objects_,
+ Device *device)
+ : BVH(params_, geometry_, objects_),
+ traversable_handle(0),
+ as_data(device, params_.top_level ? "optix tlas" : "optix blas"),
+ motion_transform_data(device, "optix motion transform")
{
- optix_handle = 0;
- optix_data_handle = 0;
- do_refit = false;
}
BVHOptiX::~BVHOptiX()
{
-}
-
-void BVHOptiX::build(Progress &, Stats *)
-{
- if (params.top_level)
- pack_tlas();
- else
- pack_blas();
-}
-
-void BVHOptiX::copy_to_device(Progress &progress, DeviceScene *dscene)
-{
- progress.set_status("Updating Scene BVH", "Building OptiX acceleration structure");
-
- Device *const device = dscene->bvh_nodes.device;
- if (!device->build_optix_bvh(this))
- progress.set_error("Failed to build OptiX acceleration structure");
-}
-
-void BVHOptiX::pack_blas()
-{
- // Bottom-level BVH can contain multiple primitive types, so merge them:
- assert(geometry.size() == 1 && objects.size() == 1); // These are built per-mesh
- Geometry *const geom = geometry[0];
-
- if (geom->geometry_type == Geometry::HAIR) {
- Hair *const hair = static_cast<Hair *const>(geom);
- if (hair->num_curves() > 0) {
- const size_t num_curves = hair->num_curves();
- const size_t num_segments = hair->num_segments();
- pack.prim_type.reserve(pack.prim_type.size() + num_segments);
- pack.prim_index.reserve(pack.prim_index.size() + num_segments);
- pack.prim_object.reserve(pack.prim_object.size() + num_segments);
- // 'pack.prim_time' is only used in geom_curve_intersect.h
- // It is not needed because of OPTIX_MOTION_FLAG_[START|END]_VANISH
-
- uint type = (hair->get_use_motion_blur() &&
- hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) ?
- ((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON :
- PRIMITIVE_MOTION_CURVE_THICK) :
- ((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_CURVE_RIBBON :
- PRIMITIVE_CURVE_THICK);
-
- for (size_t j = 0; j < num_curves; ++j) {
- const Hair::Curve curve = hair->get_curve(j);
- for (size_t k = 0; k < curve.num_segments(); ++k) {
- pack.prim_type.push_back_reserved(PRIMITIVE_PACK_SEGMENT(type, k));
- // Each curve segment points back to its curve index
- pack.prim_index.push_back_reserved(j);
- pack.prim_object.push_back_reserved(0);
- }
- }
- }
- }
- else if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
- Mesh *const mesh = static_cast<Mesh *const>(geom);
- if (mesh->num_triangles() > 0) {
- const size_t num_triangles = mesh->num_triangles();
- pack.prim_type.reserve(pack.prim_type.size() + num_triangles);
- pack.prim_index.reserve(pack.prim_index.size() + num_triangles);
- pack.prim_object.reserve(pack.prim_object.size() + num_triangles);
-
- uint type = PRIMITIVE_TRIANGLE;
- if (mesh->get_use_motion_blur() && mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION))
- type = PRIMITIVE_MOTION_TRIANGLE;
-
- for (size_t k = 0; k < num_triangles; ++k) {
- pack.prim_type.push_back_reserved(type);
- pack.prim_index.push_back_reserved(k);
- pack.prim_object.push_back_reserved(0);
- }
- }
- }
-
- // Initialize visibility to zero and later update it during top-level build
- uint prev_visibility = objects[0]->get_visibility();
- objects[0]->set_visibility(0);
-
- // Update 'pack.prim_tri_index', 'pack.prim_tri_verts' and 'pack.prim_visibility'
- pack_primitives();
-
- // Reset visibility after packing
- objects[0]->set_visibility(prev_visibility);
-}
-
-void BVHOptiX::pack_tlas()
-{
- // Calculate total packed size
- size_t prim_index_size = 0;
- size_t prim_tri_verts_size = 0;
- foreach (Geometry *geom, geometry) {
- BVH *const bvh = geom->bvh;
- prim_index_size += bvh->pack.prim_index.size();
- prim_tri_verts_size += bvh->pack.prim_tri_verts.size();
- }
-
- if (prim_index_size == 0)
- return; // Abort right away if this is an empty BVH
-
- size_t pack_offset = 0;
- size_t pack_verts_offset = 0;
-
- pack.prim_type.resize(prim_index_size);
- int *pack_prim_type = pack.prim_type.data();
- pack.prim_index.resize(prim_index_size);
- int *pack_prim_index = pack.prim_index.data();
- pack.prim_object.resize(prim_index_size);
- int *pack_prim_object = pack.prim_object.data();
- pack.prim_visibility.resize(prim_index_size);
- uint *pack_prim_visibility = pack.prim_visibility.data();
- pack.prim_tri_index.resize(prim_index_size);
- uint *pack_prim_tri_index = pack.prim_tri_index.data();
- pack.prim_tri_verts.resize(prim_tri_verts_size);
- float4 *pack_prim_tri_verts = pack.prim_tri_verts.data();
-
- // Top-level BVH should only contain instances, see 'Geometry::need_build_bvh'
- // Iterate over scene mesh list instead of objects, since the 'prim_offset' is calculated based
- // on that list, which may be ordered differently from the object list.
- foreach (Geometry *geom, geometry) {
- PackedBVH &bvh_pack = geom->bvh->pack;
- int geom_prim_offset = geom->prim_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;
- foreach (Object *ob, objects) {
- if (ob->get_geometry() == geom) {
- object_visibility |= ob->visibility_for_tracing();
- if (!geom->is_instanced()) {
- object_index = ob->get_device_index();
- break;
- }
- }
- }
-
- // Merge primitive, object and triangle indexes
- if (!bvh_pack.prim_index.empty()) {
- int *bvh_prim_type = &bvh_pack.prim_type[0];
- int *bvh_prim_index = &bvh_pack.prim_index[0];
- uint *bvh_prim_tri_index = &bvh_pack.prim_tri_index[0];
- uint *bvh_prim_visibility = &bvh_pack.prim_visibility[0];
-
- for (size_t i = 0; i < bvh_pack.prim_index.size(); i++, pack_offset++) {
- if (bvh_pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
- pack_prim_index[pack_offset] = bvh_prim_index[i] + geom_prim_offset;
- pack_prim_tri_index[pack_offset] = -1;
- }
- else {
- pack_prim_index[pack_offset] = bvh_prim_index[i] + geom_prim_offset;
- pack_prim_tri_index[pack_offset] = bvh_prim_tri_index[i] + pack_verts_offset;
- }
-
- pack_prim_type[pack_offset] = bvh_prim_type[i];
- pack_prim_object[pack_offset] = object_index;
- pack_prim_visibility[pack_offset] = bvh_prim_visibility[i] | object_visibility;
- }
- }
-
- // Merge triangle vertex data
- if (!bvh_pack.prim_tri_verts.empty()) {
- const size_t prim_tri_size = bvh_pack.prim_tri_verts.size();
- memcpy(pack_prim_tri_verts + pack_verts_offset,
- bvh_pack.prim_tri_verts.data(),
- prim_tri_size * sizeof(float4));
- pack_verts_offset += prim_tri_size;
- }
- }
-}
-
-void BVHOptiX::pack_nodes(const BVHNode *)
-{
-}
-
-void BVHOptiX::refit_nodes()
-{
- do_refit = true;
-}
-
-BVHNode *BVHOptiX::widen_children_nodes(const BVHNode *)
-{
- return NULL;
+ // Acceleration structure memory is freed via the 'as_data' destructor
}
CCL_NAMESPACE_END