Metal: Resolve premature memory release
After previous changes to allow command buffers to not require execution and completion in submission order, guarantees for releasing freed buffers back to the memory pool within the frame life time had changed. This could mean a released buffer could be returned to the memory pool prematurely, if a subsequent command buffer completes before a previously submitted one, flagging a resource as no longer in use by the GPU, while it still may be in use by the orignal command buffer. This PR defers final reference count release for buffers being actively used until the following call to GPU_render_step, to ensure that buffers freed will be available for the lifetime of the frame, covering all command submissions, rather than just within the lifetime of the command buffer submission within which a buffer was freed. Authored by Apple: Michael Parkin-White Pull Request: https://projects.blender.org/blender/blender/pulls/114329
This commit is contained in:
committed by
Clément Foucault
parent
5974a4482a
commit
a96aabc6f6
@@ -156,7 +156,6 @@ void MTLBackend::render_step()
|
||||
MTLContext::get_global_memory_manager()->get_current_safe_list();
|
||||
if (cmd_free_buffer_list->should_flush()) {
|
||||
MTLContext::get_global_memory_manager()->begin_new_safe_list();
|
||||
cmd_free_buffer_list->decrement_reference();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -418,6 +418,9 @@ class MTLBufferPool {
|
||||
std::atomic<MTLSafeFreeList *> current_free_list_;
|
||||
std::atomic<int64_t> allocations_in_pool_;
|
||||
|
||||
/* Previous list, to be released after one full frame. */
|
||||
MTLSafeFreeList *prev_free_buffer_list_ = nullptr;
|
||||
|
||||
public:
|
||||
void init(id<MTLDevice> device);
|
||||
~MTLBufferPool();
|
||||
|
||||
@@ -425,8 +425,17 @@ MTLSafeFreeList *MTLBufferPool::get_current_safe_list()
|
||||
void MTLBufferPool::begin_new_safe_list()
|
||||
{
|
||||
safelist_lock_.lock();
|
||||
MTLSafeFreeList *previous_list = prev_free_buffer_list_;
|
||||
MTLSafeFreeList *active_list = get_current_safe_list();
|
||||
current_free_list_ = new MTLSafeFreeList();
|
||||
prev_free_buffer_list_ = active_list;
|
||||
safelist_lock_.unlock();
|
||||
|
||||
/* Release final reference for previous list.
|
||||
* Note: Outside of lock as this function itself locks. */
|
||||
if (previous_list) {
|
||||
previous_list->decrement_reference();
|
||||
}
|
||||
}
|
||||
|
||||
void MTLBufferPool::ensure_buffer_pool(MTLResourceOptions options)
|
||||
|
||||
Reference in New Issue
Block a user