forked from blender/blender
main sync #3
@ -287,17 +287,17 @@ class MTLSafeFreeList {
|
|||||||
std::atomic<bool> in_free_queue_;
|
std::atomic<bool> in_free_queue_;
|
||||||
std::atomic<bool> referenced_by_workload_;
|
std::atomic<bool> referenced_by_workload_;
|
||||||
std::recursive_mutex lock_;
|
std::recursive_mutex lock_;
|
||||||
|
|
||||||
/* Linked list of next MTLSafeFreeList chunk if current chunk is full. */
|
/* Linked list of next MTLSafeFreeList chunk if current chunk is full. */
|
||||||
std::atomic<int> has_next_pool_;
|
|
||||||
std::atomic<MTLSafeFreeList *> next_;
|
std::atomic<MTLSafeFreeList *> next_;
|
||||||
|
|
||||||
/* Lockless list. MAX_NUM_BUFFERS_ within a chunk based on considerations
|
/* Lockless list. MAX_NUM_BUFFERS_ within a chunk based on considerations
|
||||||
* for performance and memory.
|
* for performance and memory. Higher chunk counts are preferable for efficiently
|
||||||
|
* performing block operations such as copying several objects simultaneously.
|
||||||
|
*
|
||||||
* MIN_BUFFER_FLUSH_COUNT refers to the minimum count of buffers in the MTLSafeFreeList
|
* MIN_BUFFER_FLUSH_COUNT refers to the minimum count of buffers in the MTLSafeFreeList
|
||||||
* before buffers are returned to global memory pool. This is set at a point to reduce
|
* before buffers are returned to global memory pool. This is set at a point to reduce
|
||||||
* overhead of small pool flushes, while ensuring floating memory overhead is not excessive. */
|
* overhead of small pool flushes, while ensuring floating memory overhead is not excessive. */
|
||||||
static const int MAX_NUM_BUFFERS_ = 1024;
|
static const int MAX_NUM_BUFFERS_ = 8192;
|
||||||
static const int MIN_BUFFER_FLUSH_COUNT = 120;
|
static const int MIN_BUFFER_FLUSH_COUNT = 120;
|
||||||
std::atomic<int> current_list_index_;
|
std::atomic<int> current_list_index_;
|
||||||
gpu::MTLBuffer *safe_free_pool_[MAX_NUM_BUFFERS_];
|
gpu::MTLBuffer *safe_free_pool_[MAX_NUM_BUFFERS_];
|
||||||
@ -305,8 +305,8 @@ class MTLSafeFreeList {
|
|||||||
public:
|
public:
|
||||||
MTLSafeFreeList();
|
MTLSafeFreeList();
|
||||||
|
|
||||||
/* Add buffer to Safe Free List, can be called from secondary threads.
|
/* Can be used from multiple threads. Performs insertion into Safe Free List with the least
|
||||||
* Performs a lockless list insert. */
|
* amount of threading synchronization. */
|
||||||
void insert_buffer(gpu::MTLBuffer *buffer);
|
void insert_buffer(gpu::MTLBuffer *buffer);
|
||||||
|
|
||||||
/* Whether we need to start a new safe free list, or can carry on using the existing one. */
|
/* Whether we need to start a new safe free list, or can carry on using the existing one. */
|
||||||
@ -321,10 +321,11 @@ class MTLSafeFreeList {
|
|||||||
void flag_in_queue()
|
void flag_in_queue()
|
||||||
{
|
{
|
||||||
in_free_queue_ = true;
|
in_free_queue_ = true;
|
||||||
if (has_next_pool_) {
|
if (current_list_index_ >= MTLSafeFreeList::MAX_NUM_BUFFERS_) {
|
||||||
MTLSafeFreeList *next_pool = next_.load();
|
MTLSafeFreeList *next_pool = next_.load();
|
||||||
BLI_assert(next_pool != nullptr);
|
if (next_pool) {
|
||||||
next_pool->flag_in_queue();
|
next_pool->flag_in_queue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -257,10 +257,7 @@ void MTLBufferPool::update_memory_pools()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch next MTLSafeFreeList chunk, if any. */
|
/* Fetch next MTLSafeFreeList chunk, if any. */
|
||||||
MTLSafeFreeList *next_list = nullptr;
|
MTLSafeFreeList *next_list = current_pool->next_.load();
|
||||||
if (current_pool->has_next_pool_ > 0) {
|
|
||||||
next_list = current_pool->next_.load();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete current MTLSafeFreeList */
|
/* Delete current MTLSafeFreeList */
|
||||||
current_pool->lock_.unlock();
|
current_pool->lock_.unlock();
|
||||||
@ -396,7 +393,6 @@ MTLSafeFreeList::MTLSafeFreeList()
|
|||||||
in_free_queue_ = false;
|
in_free_queue_ = false;
|
||||||
current_list_index_ = 0;
|
current_list_index_ = 0;
|
||||||
next_ = nullptr;
|
next_ = nullptr;
|
||||||
has_next_pool_ = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MTLSafeFreeList::insert_buffer(gpu::MTLBuffer *buffer)
|
void MTLSafeFreeList::insert_buffer(gpu::MTLBuffer *buffer)
|
||||||
@ -410,12 +406,19 @@ void MTLSafeFreeList::insert_buffer(gpu::MTLBuffer *buffer)
|
|||||||
* insert the buffer into the next available chunk. */
|
* insert the buffer into the next available chunk. */
|
||||||
if (insert_index >= MTLSafeFreeList::MAX_NUM_BUFFERS_) {
|
if (insert_index >= MTLSafeFreeList::MAX_NUM_BUFFERS_) {
|
||||||
|
|
||||||
/* Check if first caller to generate next pool. */
|
/* Check if first caller to generate next pool in chain.
|
||||||
int has_next = has_next_pool_++;
|
* Otherwise, ensure pool exists or wait for first caller to create next pool. */
|
||||||
if (has_next == 0) {
|
|
||||||
next_ = new MTLSafeFreeList();
|
|
||||||
}
|
|
||||||
MTLSafeFreeList *next_list = next_.load();
|
MTLSafeFreeList *next_list = next_.load();
|
||||||
|
|
||||||
|
if (!next_list) {
|
||||||
|
std::unique_lock lock(lock_);
|
||||||
|
|
||||||
|
next_list = next_.load();
|
||||||
|
if (!next_list) {
|
||||||
|
next_list = new MTLSafeFreeList();
|
||||||
|
next_.store(next_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
BLI_assert(next_list);
|
BLI_assert(next_list);
|
||||||
next_list->insert_buffer(buffer);
|
next_list->insert_buffer(buffer);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user