22#include <Metal/Metal.hpp>
23#include <dispatch/dispatch.h>
27#include "spdlog/spdlog.h"
43 _buffer = device->newBuffer(_totalSize, MTL::ResourceStorageModeShared);
45 _buffer->setLabel(NS::String::string(label, NS::UTF8StringEncoding));
46 _basePtr =
static_cast<uint8_t*
>(_buffer->contents());
71 dispatch_semaphore_wait(_frameSemaphore, DISPATCH_TIME_FOREVER);
85 [[nodiscard]]
size_t allocate(
const void* data,
size_t size)
87 assert(data !=
nullptr);
90 const size_t alignedSize = alignUp(size,
kAlignment);
92 spdlog::warn(
"PaletteRingBuffer: frame allocation exceeded {}KB budget "
93 "(requested {}B at offset {})",
kRegionSize / 1024, size, _writeOffset);
97 const size_t absoluteOffset =
static_cast<size_t>(_frameIndex) *
kRegionSize + _writeOffset;
98 std::memcpy(_basePtr + absoluteOffset, data, size);
99 _writeOffset += alignedSize;
100 return absoluteOffset;
109 assert(commandBuffer !=
nullptr);
110 dispatch_semaphore_t sem = _frameSemaphore;
111 commandBuffer->addCompletedHandler(^(MTL::CommandBuffer*) {
112 dispatch_semaphore_signal(sem);
116 [[nodiscard]] MTL::Buffer*
buffer()
const {
return _buffer; }
118 [[nodiscard]]
size_t totalSize()
const {
return _totalSize; }
121 static size_t alignUp(
size_t value,
size_t alignment)
123 return (value + alignment - 1) & ~(alignment - 1);
126 MTL::Buffer* _buffer =
nullptr;
127 uint8_t* _basePtr =
nullptr;
128 dispatch_semaphore_t _frameSemaphore =
nullptr;
130 size_t _totalSize = 0;
131 int _frameIndex = -1;
132 size_t _writeOffset = 0;