VisuTwin Canvas
C++ 3D Engine — Metal Backend
Loading...
Searching...
No Matches
visutwin::canvas::MetalUniformRingBuffer Class Reference

#include <platform/graphics/metal/metalUniformRingBuffer.h>

Public Member Functions

size_t alignedSlotSize () const
size_t allocate (const void *data, size_t dataSize)
void beginFrame ()
MTL::Buffer * buffer () const
size_t currentDrawCount () const
void endFrame (MTL::CommandBuffer *commandBuffer)
size_t maxDrawsPerFrame () const
 MetalUniformRingBuffer (const MetalUniformRingBuffer &)=delete
 MetalUniformRingBuffer (MetalUniformRingBuffer &&)=delete
 MetalUniformRingBuffer (MTL::Device *device, size_t maxDrawsPerFrame, size_t uniformStructSize, const char *label="UniformRing")
MetalUniformRingBufferoperator= (const MetalUniformRingBuffer &)=delete
MetalUniformRingBufferoperator= (MetalUniformRingBuffer &&)=delete
size_t totalSize () const
 ~MetalUniformRingBuffer ()

Static Public Attributes

static constexpr size_t kAlignment = 256
static constexpr int kMaxInflightFrames = 3

Detailed Description

Triple-buffered ring buffer for per-draw uniform data.

Replaces setVertexBytes()/setFragmentBytes() with a pre-allocated MTLBuffer where each draw call's uniforms are sub-allocated from a linearly-advancing write cursor. Three frame regions prevent CPU/GPU contention without explicit fencing per draw.

Apple Metal Best Practices Guide recommends:

  • setVertexBytes() for data < 4 KB (acceptable for small draw counts)
  • Persistent MTLBuffer + setVertexBufferOffset() for high draw counts
  • Triple buffering with dispatch_semaphore_t for CPU/GPU sync
  • 256-byte alignment for constant buffer offsets

Usage:

  1. beginFrame() – wait for GPU, advance to next region
  2. allocate(data, size) – write per-draw data, get buffer offset
  3. encoder->setVertexBufferOffset(offset, index) – cheap offset-only bind
  4. endFrame(commandBuffer) – register GPU completion signal

Definition at line 35 of file metalUniformRingBuffer.h.

Constructor & Destructor Documentation

◆ MetalUniformRingBuffer() [1/3]

visutwin::canvas::MetalUniformRingBuffer::MetalUniformRingBuffer ( MTL::Device * device,
size_t maxDrawsPerFrame,
size_t uniformStructSize,
const char * label = "UniformRing" )
inline
Parameters
deviceMetal device for buffer allocation
maxDrawsPerFrameMaximum draw calls expected per frame (grows if exceeded)
uniformStructSizeSize of the largest uniform struct this ring will hold
labelDebug label for Metal GPU capture

Definition at line 47 of file metalUniformRingBuffer.h.

References kAlignment, kMaxInflightFrames, and maxDrawsPerFrame().

Referenced by MetalUniformRingBuffer(), MetalUniformRingBuffer(), operator=(), and operator=().

◆ ~MetalUniformRingBuffer()

visutwin::canvas::MetalUniformRingBuffer::~MetalUniformRingBuffer ( )
inline

Definition at line 64 of file metalUniformRingBuffer.h.

◆ MetalUniformRingBuffer() [2/3]

visutwin::canvas::MetalUniformRingBuffer::MetalUniformRingBuffer ( const MetalUniformRingBuffer & )
delete

◆ MetalUniformRingBuffer() [3/3]

visutwin::canvas::MetalUniformRingBuffer::MetalUniformRingBuffer ( MetalUniformRingBuffer && )
delete

Member Function Documentation

◆ alignedSlotSize()

size_t visutwin::canvas::MetalUniformRingBuffer::alignedSlotSize ( ) const
inlinenodiscard

Definition at line 123 of file metalUniformRingBuffer.h.

◆ allocate()

size_t visutwin::canvas::MetalUniformRingBuffer::allocate ( const void * data,
size_t dataSize )
inlinenodiscard

Write uniform data for one draw call into the ring buffer.

Parameters
dataPointer to uniform struct data
dataSizeSize in bytes of the data to copy (must be <= alignedSlotSize)
Returns
Byte offset into the MTLBuffer — pass to setVertexBufferOffset/setFragmentBufferOffset

Definition at line 96 of file metalUniformRingBuffer.h.

Referenced by visutwin::canvas::MetalUniformBinder::setTransformUniforms(), and visutwin::canvas::MetalUniformBinder::submitPerDrawUniforms().

◆ beginFrame()

void visutwin::canvas::MetalUniformRingBuffer::beginFrame ( )
inline

Call at frame start. Blocks if GPU hasn't finished with this region. Must be called before any allocate() calls for the new frame.

Definition at line 82 of file metalUniformRingBuffer.h.

References kMaxInflightFrames.

◆ buffer()

MTL::Buffer * visutwin::canvas::MetalUniformRingBuffer::buffer ( ) const
inlinenodiscard

Definition at line 122 of file metalUniformRingBuffer.h.

◆ currentDrawCount()

size_t visutwin::canvas::MetalUniformRingBuffer::currentDrawCount ( ) const
inlinenodiscard

Definition at line 124 of file metalUniformRingBuffer.h.

◆ endFrame()

void visutwin::canvas::MetalUniformRingBuffer::endFrame ( MTL::CommandBuffer * commandBuffer)
inline

Register GPU completion signal on the frame's command buffer. Must be called on the LAST command buffer committed per frame (typically the present buffer in onFrameEnd).

Definition at line 113 of file metalUniformRingBuffer.h.

◆ maxDrawsPerFrame()

size_t visutwin::canvas::MetalUniformRingBuffer::maxDrawsPerFrame ( ) const
inlinenodiscard

Definition at line 125 of file metalUniformRingBuffer.h.

Referenced by MetalUniformRingBuffer().

◆ operator=() [1/2]

MetalUniformRingBuffer & visutwin::canvas::MetalUniformRingBuffer::operator= ( const MetalUniformRingBuffer & )
delete

◆ operator=() [2/2]

MetalUniformRingBuffer & visutwin::canvas::MetalUniformRingBuffer::operator= ( MetalUniformRingBuffer && )
delete

◆ totalSize()

size_t visutwin::canvas::MetalUniformRingBuffer::totalSize ( ) const
inlinenodiscard

Definition at line 126 of file metalUniformRingBuffer.h.

Member Data Documentation

◆ kAlignment

size_t visutwin::canvas::MetalUniformRingBuffer::kAlignment = 256
staticconstexpr

Definition at line 39 of file metalUniformRingBuffer.h.

Referenced by MetalUniformRingBuffer().

◆ kMaxInflightFrames

int visutwin::canvas::MetalUniformRingBuffer::kMaxInflightFrames = 3
staticconstexpr

Definition at line 38 of file metalUniformRingBuffer.h.

Referenced by beginFrame(), and MetalUniformRingBuffer().


The documentation for this class was generated from the following file: