13#include <unordered_map>
17#include <Cocoa/Cocoa.h>
18#include <Metal/Metal.h>
19#include <QuartzCore/QuartzCore.h>
22@class MTLCommandQueue;
23@class MTLRenderPipelineState;
92#define MTL_DEBUG_MEMORY_STATISTICS 0
96#define MTL_SCRATCH_BUFFER_ALLOW_TEMPORARY_EXPANSION 1
102class MTLCommandBufferManager;
119 id<MTLBuffer> metal_buffer_;
131 bool is_external_ =
false;
134 MTLResourceOptions options_;
135 id<MTLDevice> device_;
146 std::atomic<bool> in_use_;
150 MTLBuffer(id<MTLBuffer> external_buffer);
249 this->buffer_size = this->buffer->
get_size();
250 this->insert_time = std::time(
nullptr);
255 this->buffer =
nullptr;
257 this->insert_time = 0;
300 std::atomic<int> reference_count_;
301 std::atomic<bool> in_free_queue_;
302 std::atomic<bool> referenced_by_workload_;
303 std::recursive_mutex lock_;
305 std::atomic<MTLSafeFreeList *> next_;
314 static const int MAX_NUM_BUFFERS_ = 8192;
315 static const int MIN_BUFFER_FLUSH_COUNT = 120;
316 std::atomic<int> current_list_index_;
337 in_free_queue_ =
true;
338 if (current_list_index_ >= MTLSafeFreeList::MAX_NUM_BUFFERS_) {
366#if MTL_DEBUG_MEMORY_STATISTICS == 1
368 std::atomic<int64_t> total_allocation_bytes_;
371 std::atomic<int> per_frame_allocation_count_;
372 std::atomic<int64_t> buffers_in_pool_;
376 bool initialized_ =
false;
377 id<MTLDevice> device_ = nil;
387 static constexpr float mtl_buffer_size_threshold_factor_ = 1.26;
398 using MTLBufferPoolOrderedList = std::multiset<MTLBufferHandle, CompareMTLBuffer>;
399 using MTLBufferResourceOptions =
uint64_t;
401 std::mutex buffer_pool_lock_;
406 uint allocations_list_size_;
412 std::mutex safelist_lock_;
418 std::atomic<MTLSafeFreeList *> current_free_list_;
419 std::atomic<int64_t> allocations_in_pool_;
425 void init(id<MTLDevice> device);
434 const void *data =
nullptr);
449 void ensure_buffer_pool(MTLResourceOptions
options);
456 void allocations_list_delete_all();
488 bool initialised_ =
false;
491 uint current_scratch_buffer_ = 0;
void push_completed_safe_list(MTLSafeFreeList *list)
gpu::MTLBuffer * allocate_with_data(uint64_t size, bool cpu_visible, const void *data=nullptr)
MTLSafeFreeList * get_current_safe_list()
void update_memory_pools()
void begin_new_safe_list()
gpu::MTLBuffer * allocate(uint64_t size, bool cpu_visible)
gpu::MTLBuffer * allocate_aligned(uint64_t size, uint alignment, bool cpu_visible)
gpu::MTLBuffer * allocate_aligned_with_data(uint64_t size, uint alignment, bool cpu_visible, const void *data=nullptr)
bool free_buffer(gpu::MTLBuffer *buffer)
void flag_in_use(bool used)
uint64_t get_size() const
void set_usage_size(uint64_t size_used)
uint64_t get_size_used() const
void * get_host_ptr() const
void flush_range(uint64_t offset, uint64_t length)
MTLBuffer(id< MTLDevice > device, uint64_t size, MTLResourceOptions options, uint alignment=1)
void set_label(NSString *str)
MTLResourceOptions get_resource_options()
id< MTLBuffer > get_metal_buffer() const
MEM_CXX_CLASS_ALLOC_FUNCS("MTLBuffer")
MTLCircularBuffer(MTLContext &ctx, uint64_t initial_size, bool allow_grow)
MTLTemporaryBuffer allocate_range_aligned(uint64_t alloc_size, uint alignment)
MTLTemporaryBuffer allocate_range(uint64_t alloc_size)
void increment_reference()
void decrement_reference()
MEM_CXX_CLASS_ALLOC_FUNCS("MTLSafeFreeList")
void insert_buffer(gpu::MTLBuffer *buffer)
static constexpr uint mtl_scratch_buffer_max_size_
static constexpr uint mtl_scratch_buffer_initial_size_
MEM_CXX_CLASS_ALLOC_FUNCS("MTLBufferPool")
MTLScratchBufferManager(MTLContext &context)
MTLTemporaryBuffer scratch_buffer_allocate_range_aligned(uint64_t alloc_size, uint alignment)
void flush_active_scratch_buffer()
void ensure_increment_scratch_buffer()
~MTLScratchBufferManager()
MTLTemporaryBuffer scratch_buffer_allocate_range(uint64_t alloc_size)
local_group_size(16, 16) .push_constant(Type rhs
CCL_NAMESPACE_BEGIN struct Options options
static int compare_size(void *user_data, const void *a1, const void *a2)
#define MTL_NUM_SAFE_FRAMES
unsigned __int64 uint64_t
bool operator()(const MTLBufferHandle &lhs, const MTLBufferHandle &rhs) const
MTLBufferHandle(gpu::MTLBuffer *buf)
MTLBufferHandle(uint64_t compare_size)
MTLResourceOptions options
id< MTLBuffer > metal_buffer