Skip to content

Commit d4d3ee8

Browse files
committed
Fix for BVH construction hang
1 parent 3191e8e commit d4d3ee8

File tree

1 file changed

+35
-11
lines changed

1 file changed

+35
-11
lines changed

RadeonRays/src/accelerator/bvh2.cpp

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,12 @@ namespace RadeonRays
225225
// Mutex to guard cv
226226
std::mutex mutex;
227227
// Indicates if we need to shutdown all the threads
228-
std::atomic<bool> shutdown;
228+
bool shutdown = false;
229229
// Number of primitives processed so far
230230
std::atomic<std::uint32_t> num_refs_processed;
231+
num_refs_processed.store(0);
231232

232-
num_refs_processed.store(0);
233-
shutdown.store(false);
234-
233+
// Push root request
235234
requests.push(SplitRequest{
236235
scene_min,
237236
scene_max,
@@ -243,33 +242,42 @@ namespace RadeonRays
243242
0u
244243
});
245244

245+
// Worker build function
246246
auto worker_thread = [&]()
247247
{
248+
// Local stack for requests
248249
thread_local std::stack<SplitRequest> local_requests;
249250

251+
// Thread loop
250252
for (;;)
251253
{
252254
// Wait for signal
253255
{
256+
// Wait on the global stack to receive a request
254257
std::unique_lock<std::mutex> lock(mutex);
255258
cv.wait(lock, [&]() { return !requests.empty() || shutdown; });
256259

260+
// If we have been awaken by shutdown, we need to leave asap
257261
if (shutdown) return;
258-
262+
// Otherwise take a request from global stack and put it
263+
// into our local stack
259264
local_requests.push(requests.top());
260265
requests.pop();
261266
}
262267

268+
// Allocated space for requests
263269
_MM_ALIGN16 SplitRequest request;
264270
_MM_ALIGN16 SplitRequest request_left;
265271
_MM_ALIGN16 SplitRequest request_right;
266272

267-
// Process local requests
273+
// Start handling local stack of requests
268274
while (!local_requests.empty())
269275
{
276+
// Pop next request
270277
request = local_requests.top();
271278
local_requests.pop();
272279

280+
// Handle it
273281
auto node_type = HandleRequest(
274282
request,
275283
aabb_min,
@@ -281,28 +289,40 @@ namespace RadeonRays
281289
request_left,
282290
request_right);
283291

292+
// If it is a leaf, update number of processed primitives
293+
// and continue
284294
if (node_type == kLeaf)
285295
{
286296
num_refs_processed += static_cast<std::uint32_t>(request.num_refs);
287297
continue;
288298
}
289299

290-
if (request_right.num_refs > 4096u)
300+
// Here we know we have just built and internal node,
301+
// so we are going to handle its left child on this thread and
302+
// its right child on:
303+
// - this thread if it is small
304+
// - another thread if it is huge (since this one is going to handle left child)
305+
if (request_right.num_refs > 2048u)
291306
{
307+
// Put request into the global queue
292308
std::unique_lock<std::mutex> lock(mutex);
293309
requests.push(request_right);
310+
// Wake up one of the workers
294311
cv.notify_one();
295312
}
296313
else
297314
{
315+
// Put small request into the local queue
298316
local_requests.push(request_right);
299317
}
300318

319+
// Put left request to local stack (always handled on this thread)
301320
local_requests.push(request_left);
302321
}
303322
}
304323
};
305324

325+
// Launch several threads
306326
auto num_threads = std::thread::hardware_concurrency();
307327
std::vector<std::thread> threads(num_threads);
308328

@@ -311,15 +331,19 @@ namespace RadeonRays
311331
threads[i] = std::thread(worker_thread);
312332
}
313333

334+
// Wait until all primitives are handled
314335
while (num_refs_processed != num_aabbs)
315336
{
316337
std::this_thread::sleep_for(std::chrono::milliseconds(20));
317338
}
318339

319-
// Signal shutdown and wake up all the threads
320-
shutdown.store(true);
321-
cv.notify_all();
322-
340+
// Signal shutdown and wake up all the threads
341+
{
342+
std::unique_lock<std::mutex> lock(mutex);
343+
shutdown = true;
344+
cv.notify_all();
345+
}
346+
323347
// Wait for all the threads to finish
324348
for (auto i = 0u; i < num_threads; ++i)
325349
{

0 commit comments

Comments
 (0)