Fix #106431: Resolve Metal workload dependency

Splitting workload dependency chains such that they
only exist within the context of a single frame.
Dependencies are required to ensure sequential
command buffer submissions execute in order,
but the additional dependencies between frames
could incur GPU timeouts, if a signal was delayed.

This could be triggered by both CPU/GPU cycles
texture updates and Viewport Compositor operations.

Should also resolve #106401

Authored by Apple: Michael Parkin-White

Pull Request: https://projects.blender.org/blender/blender/pulls/106443
This commit is contained in:
Jason Fielder
2023-04-03 08:53:42 +02:00
committed by Jeroen Bakker
parent 682cb6ecd3
commit 8954df63ef

View File

@@ -2138,9 +2138,13 @@ void present(MTLRenderPassDescriptor *blit_descriptor,
MTLCommandBufferManager::num_active_cmd_bufs++;
if (MTLCommandBufferManager::sync_event != nil) {
/* Ensure command buffer ordering. */
[cmdbuf encodeWaitForEvent:MTLCommandBufferManager::sync_event
value:MTLCommandBufferManager::event_signal_val];
/* Release synchronization primitive for current frame to avoid cross-frame dependencies.
* We require MTLEvents to ensure correct ordering of workload submissions within a frame,
* however, we should not create long chains of dependencies spanning several drawables as any
* temporary stalls can then trigger erroneous GPU timeouts in non-dependent submsisions. */
[MTLCommandBufferManager::sync_event release];
MTLCommandBufferManager::sync_event = nil;
MTLCommandBufferManager::event_signal_val = 0;
}
/* Do Present Call and final Blit to MTLDrawable. */
@@ -2192,17 +2196,6 @@ void present(MTLRenderPassDescriptor *blit_descriptor,
perf_max_drawables);
}];
if (MTLCommandBufferManager::sync_event == nil) {
MTLCommandBufferManager::sync_event = [ctx->device newEvent];
BLI_assert(MTLCommandBufferManager::sync_event);
[MTLCommandBufferManager::sync_event retain];
}
BLI_assert(MTLCommandBufferManager::sync_event != nil);
MTLCommandBufferManager::event_signal_val++;
[cmdbuf encodeSignalEvent:MTLCommandBufferManager::sync_event
value:MTLCommandBufferManager::event_signal_val];
[cmdbuf commit];
/* When debugging, fetch advanced command buffer errors. */