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 20 additions and 5 deletions
Showing only changes of commit 215f1267ca - Show all commits

View File

@ -12,6 +12,8 @@
#include "util/vector.h"
#include "util/thread.h"
#include <atomic>
CCL_NAMESPACE_BEGIN
#define BVH_NODE_SIZE 4
@ -37,6 +39,7 @@ class BVH2 : public BVH {
are used to ensure that it the case. */
thread_mutex build_mutex;
thread_condition_variable build_cv;
std::atomic<int> building{0};
void build(Progress &progress, Stats *stats);
void refit(Progress &progress);

View File

@ -51,22 +51,25 @@ void Device::build_bvh(BVH *bvh, DeviceScene *dscene, Progress &progress, bool r
{
assert(bvh->params.bvh_layout == BVH_LAYOUT_BVH2);
BVH2 *const bvh2 = static_cast<BVH2 *>(bvh);
static std::atomic<int> building{0};
/* Top level BVH2 build must wait on all other BVH2 builds to finish
otherwise the top level BVH2 will not have all the correct data
*/
if(bvh2->params.top_level) {
/*
This is used to make sure all workers have reached this point.
device_init_update_bvh increments the counter.
*/
bvh2->building--;
thread_scoped_lock build_wait_lock(bvh2->build_mutex);
/* Wait for other BVH2 builds to complete before proceeding */
VLOG_INFO << std::this_thread::get_id() << ":" << bvh2 << " Waiting on other BVH2 builds.";
bvh2->build_cv.wait(build_wait_lock, [=]() { return (building == 0); });
bvh2->build_cv.wait(build_wait_lock, [=]() { return (bvh2->building == 0); });
VLOG_INFO << std::this_thread::get_id() << ":" << bvh2 << " Done waiting on other BVH2 builds";
}
thread_scoped_lock build_lock(bvh2->build_mutex, std::try_to_lock);
if (build_lock) {
/* Has the BVH already been built? */
if (!bvh->built) {
building++;
/* Build the BVH */
VLOG_INFO << std::this_thread::get_id() << ":" << bvh2 << " Performing BVH2 build.";
if (refit) {
@ -77,7 +80,6 @@ void Device::build_bvh(BVH *bvh, DeviceScene *dscene, Progress &progress, bool r
}
bvh->built = true;
VLOG_INFO << std::this_thread::get_id() << ":" << bvh2 << " Done building BVH2";
building--;
}
else {
VLOG_INFO << std::this_thread::get_id() << ":" << bvh2 << " BVH2 Already built";

View File

@ -798,7 +798,7 @@ void GeometryManager::device_data_xfer_and_bvh_update(int idx,
}
sub_dscene->device_scene_clear_modified();
device_init_update_bvh(scene);
{
scoped_callback_timer timer([scene, idx](double time) {
if (scene->update_stats) {

View File

@ -331,6 +331,7 @@ class GeometryManager {
DeviceScene *dscene,
Scene *scene,
Progress &progress);
void device_init_update_bvh(Scene *scene);
void device_update_bvh(Device *device,
DeviceScene *dscene,
Scene *scene,

View File

@ -32,6 +32,15 @@
CCL_NAMESPACE_BEGIN
void GeometryManager::device_init_update_bvh(Scene *scene)
{
if (scene->bvh->params.bvh_layout == BVH_LAYOUT_BVH2) {
/* To ensure that only 1 BVH2 scene is built a count of workers is used */
BVH2 *const bvh2 = static_cast<BVH2 *>(scene->bvh);
bvh2->building++;
}
}
void GeometryManager::device_update_bvh(Device *device,
DeviceScene *dscene,
Scene *scene,