Alternative Upload geometry data in parallel to multiple GPUs using the "Multi-Device" #107552

Open
William Leeson wants to merge 137 commits from leesonw/blender-cluster:upload_changed into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
5 changed files with 43 additions and 7 deletions
Showing only changes of commit 4e1469b8bb - Show all commits

View File

@ -65,7 +65,7 @@ class BVH {
BVHParams params;
vector<Geometry *> geometry;
vector<Object *> objects;
bool built;
static BVH *create(const BVHParams &params,
const vector<Geometry *> &geometry,
const vector<Object *> &objects,

View File

@ -10,6 +10,7 @@
#include "util/types.h"
#include "util/vector.h"
#include "util/thread.h"
CCL_NAMESPACE_BEGIN
@ -32,6 +33,11 @@ struct BVHStackEntry {
*/
class BVH2 : public BVH {
public:
/* The BVH2 needs to be build only once these
are used to ensure that it the case. */
thread_mutex build_mutex;
thread_condition_variable build_cv;
void build(Progress &progress, Stats *stats);
void refit(Progress &progress);

View File

@ -52,13 +52,39 @@ Device::~Device() noexcept(false)
void Device::build_bvh(BVH *bvh, DeviceScene *dscene, Progress &progress, bool refit)
{
assert(bvh->params.bvh_layout == BVH_LAYOUT_BVH2);
BVH2 *const bvh2 = static_cast<BVH2 *>(bvh);
if (refit) {
bvh2->refit(progress);
thread_scoped_lock build_lock(bvh2->build_mutex, std::try_to_lock);
if (build_lock) {
/* Has the BVH already been built */
if (!bvh->built) {
/* Build the BVH */
VLOG_INFO << "Performing BVH2 build.";
if (refit) {
bvh2->refit(progress);
}
else {
bvh2->build(progress, &stats);
}
bvh->built = true;
VLOG_INFO << "done building BVH2";
}
else {
VLOG_INFO << "BVH2 Already built";
}
bvh2->build_cv.notify_all();
}
else {
bvh2->build(progress, &stats);
/* Only need to wait for the top level BVH otherwise
this thread can skip on the the next object */
if (bvh2->params.top_level) {
/* wait for BVH build to complete before proceeding */
VLOG_INFO << "Waiting on BVH2 build.";
bvh2->build_cv.wait(build_lock);
VLOG_INFO << "done waiting on BVH2 build";
} else {
VLOG_INFO << "Skipping BVH2 build.";
}
}
}

View File

@ -1222,7 +1222,7 @@ void GeometryManager::deviceDataXferAndBVHUpdate(int idx,
// the correct data
device_update_host_pointers(sub_device, dscene, sub_dscene, &sizes);
// Upload geometry and attribute buffers to the device
/* Upload geometry and attribute buffers to the device */
{
scoped_callback_timer timer([scene, idx](double time) {
if (scene->update_stats) {
@ -1250,6 +1250,7 @@ void GeometryManager::deviceDataXferAndBVHUpdate(int idx,
}
});
size_t i = 0;
/* Build the Object BVHs */
foreach (Geometry *geom, scene->geometry) {
if (geom->is_modified() || geom->need_update_bvh_for_offset) {
geom->compute_bvh(sub_device, sub_dscene, &scene->params, &progress, i, num_bvh);
@ -1266,6 +1267,7 @@ void GeometryManager::deviceDataXferAndBVHUpdate(int idx,
scene->scene_bvh_times[idx] = time;
}
});
/* Build the scene BVH */
device_update_bvh(sub_device, sub_dscene, scene, can_refit, 1, 1, progress);
device_update_bvh2(sub_device, sub_dscene, scene, progress);
}
@ -1485,6 +1487,7 @@ void GeometryManager::device_update(Device *device,
}
{
size_t num_scenes = scene->dscenes.size();
VLOG_INFO << "Rendering using " << num_scenes << " devices";
// Parallel upload the geometry data to the devices and
// calculate or refit the BVHs
parallel_for(

View File

@ -933,7 +933,8 @@ bool GeometryManager::device_update_bvh_preprocess(Device *device,
if (!scene->bvh) {
bvh = scene->bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
}
/* Mark BVH as having not been built yet */
bvh->built = false;
return can_refit;
}