Fix: Metal: GPU_finish() not syncing when there's no (current) command buffer to sync on #128987
@ -20,7 +20,7 @@ using namespace blender::gpu;
|
||||
namespace blender::gpu {
|
||||
|
||||
/* Counter for active command buffers. */
|
||||
int MTLCommandBufferManager::num_active_cmd_bufs = 0;
|
||||
volatile std::atomic<int> MTLCommandBufferManager::num_active_cmd_bufs_in_system = 0;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name MTLCommandBuffer initialization and render coordination.
|
||||
@ -50,7 +50,7 @@ id<MTLCommandBuffer> MTLCommandBufferManager::ensure_begin()
|
||||
*
|
||||
* NOTE: We currently stall until completion of GPU work upon ::submit if we have reached the
|
||||
* in-flight command buffer limit. */
|
||||
BLI_assert(MTLCommandBufferManager::num_active_cmd_bufs <
|
||||
BLI_assert(MTLCommandBufferManager::num_active_cmd_bufs_in_system <
|
||||
GHOST_ContextCGL::max_command_buffer_count);
|
||||
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
@ -68,7 +68,7 @@ id<MTLCommandBuffer> MTLCommandBufferManager::ensure_begin()
|
||||
}
|
||||
|
||||
[active_command_buffer_ retain];
|
||||
MTLCommandBufferManager::num_active_cmd_bufs++;
|
||||
context_.main_command_buffer.inc_active_command_buffer_count();
|
||||
|
||||
/* Ensure we begin new Scratch Buffer if we are on a new frame. */
|
||||
MTLScratchBufferManager &mem = context_.memory_manager;
|
||||
@ -90,6 +90,12 @@ bool MTLCommandBufferManager::submit(bool wait)
|
||||
{
|
||||
/* Skip submission if command buffer is empty. */
|
||||
if (empty_ || active_command_buffer_ == nil) {
|
||||
if (wait) {
|
||||
/* Wait for any previously submitted work on this context to complete. */
|
||||
while (context_.main_command_buffer.get_active_command_buffer_count()) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -123,7 +129,7 @@ bool MTLCommandBufferManager::submit(bool wait)
|
||||
[cmd_buffer_ref release];
|
||||
|
||||
/* Decrement count. */
|
||||
MTLCommandBufferManager::num_active_cmd_bufs--;
|
||||
context_.main_command_buffer.dec_active_command_buffer_count();
|
||||
}];
|
||||
|
||||
/* Submit command buffer to GPU. */
|
||||
@ -131,7 +137,7 @@ bool MTLCommandBufferManager::submit(bool wait)
|
||||
|
||||
/* If we have too many active command buffers in flight, wait until completed to avoid running
|
||||
* out. We can increase */
|
||||
if (MTLCommandBufferManager::num_active_cmd_bufs >=
|
||||
if (MTLCommandBufferManager::num_active_cmd_bufs_in_system >=
|
||||
(GHOST_ContextCGL::max_command_buffer_count - 1))
|
||||
{
|
||||
wait = true;
|
||||
|
@ -548,8 +548,8 @@ class MTLCommandBufferManager {
|
||||
friend class MTLContext;
|
||||
|
||||
public:
|
||||
/* Counter for active command buffers. */
|
||||
static int num_active_cmd_bufs;
|
||||
/* Counter for all active command buffers. */
|
||||
static volatile std::atomic<int> num_active_cmd_bufs_in_system;
|
||||
|
||||
private:
|
||||
/* Associated Context and properties. */
|
||||
@ -559,6 +559,7 @@ class MTLCommandBufferManager {
|
||||
/* CommandBuffer tracking. */
|
||||
id<MTLCommandBuffer> active_command_buffer_ = nil;
|
||||
id<MTLCommandBuffer> last_submitted_command_buffer_ = nil;
|
||||
volatile std::atomic<int> num_active_cmd_bufs = 0;
|
||||
|
||||
/* Active MTLCommandEncoders. */
|
||||
enum {
|
||||
@ -653,6 +654,24 @@ class MTLCommandBufferManager {
|
||||
void push_debug_group(const char *name, int index);
|
||||
void pop_debug_group();
|
||||
|
||||
void inc_active_command_buffer_count()
|
||||
{
|
||||
num_active_cmd_bufs_in_system++;
|
||||
num_active_cmd_bufs++;
|
||||
}
|
||||
|
||||
void dec_active_command_buffer_count()
|
||||
{
|
||||
BLI_assert(num_active_cmd_bufs_in_system > 0 && num_active_cmd_bufs > 0);
|
||||
num_active_cmd_bufs_in_system--;
|
||||
num_active_cmd_bufs--;
|
||||
}
|
||||
|
||||
int get_active_command_buffer_count()
|
||||
{
|
||||
return num_active_cmd_bufs;
|
||||
}
|
||||
|
||||
private:
|
||||
/* Begin new command buffer. */
|
||||
id<MTLCommandBuffer> ensure_begin();
|
||||
|
@ -2706,7 +2706,7 @@ void present(MTLRenderPassDescriptor *blit_descriptor,
|
||||
* possible. This command buffer is separate as it does not utilize the global state
|
||||
* for rendering as the main context does. */
|
||||
id<MTLCommandBuffer> cmdbuf = [ctx->queue commandBuffer];
|
||||
MTLCommandBufferManager::num_active_cmd_bufs++;
|
||||
ctx->main_command_buffer.inc_active_command_buffer_count();
|
||||
|
||||
/* Do Present Call and final Blit to MTLDrawable. */
|
||||
id<MTLRenderCommandEncoder> enc = [cmdbuf renderCommandEncoderWithDescriptor:blit_descriptor];
|
||||
@ -2739,8 +2739,10 @@ void present(MTLRenderPassDescriptor *blit_descriptor,
|
||||
[cmd_buffer_ref release];
|
||||
|
||||
/* Decrement count */
|
||||
MTLCommandBufferManager::num_active_cmd_bufs--;
|
||||
MTL_LOG_INFO("Active command buffers: %d", MTLCommandBufferManager::num_active_cmd_bufs);
|
||||
ctx->main_command_buffer.dec_active_command_buffer_count();
|
||||
|
||||
MTL_LOG_INFO("Active command buffers: %d",
|
||||
int(MTLCommandBufferManager::num_active_cmd_bufs_in_system));
|
||||
|
||||
/* Drawable count and latency management. */
|
||||
MTLContext::max_drawables_in_flight--;
|
||||
|
Loading…
Reference in New Issue
Block a user