evan 2026.1.4
Evan
Loading...
Searching...
No Matches
evan::Frame Class Reference

Frame class representing a single frame of rendering in the Vulkan application. More...

#include <headers/evan/Frame.hpp>

Inheritance diagram for evan::Frame:
Collaboration diagram for evan::Frame:

Classes

struct  UniformBufferObject
 Uniform buffer object structure. More...
 
struct  ViewUniform
 Per-view matrices consumed by the vertex shader. More...
 

Public Member Functions

 Frame (std::shared_ptr< DeviceContext > deviceContext, std::size_t perFrameSlotCount)
 Constructs a Frame object.
 
void destroy (VkDevice device)
 Destroys the Vulkan resources associated with this frame.
 
void resetCommandBuffer (std::size_t viewSlot)
 Resets the command buffer of the given view slot.
 
VkCommandBuffer getCommandBuffer (std::size_t viewSlot) const
 Gets the command buffer of the given view slot.
 
std::size_t getPerFrameSlotCount () const
 Gets the number of view/swapchain slots this frame was allocated for.
 
VkBuffer getUniformBuffer () const
 Gets the Vulkan uniform buffer associated with this frame.
 
VkDeviceSize getUniformBufferAlignedSize () const
 Gets the aligned byte size of one uniform buffer slot.
 
void * getUniformBufferMapped (std::size_t viewSlot) const
 Gets the mapped CPU pointer of a view's uniform slot.
 
VkBuffer getInstanceBuffer () const
 Gets the Vulkan instance buffer associated with this frame.
 
void * getInstanceBufferMapped (std::size_t viewSlot) const
 Gets the mapped CPU pointer of a view's instance slot.
 
VkDeviceSize getInstanceBufferAlignedSize () const
 Gets the aligned byte size of one instance buffer slot.
 
std::size_t getInstanceCapacity () const
 Gets the number of model matrices one instance slot holds.
 
bool ensureInstanceCapacity (std::size_t transforms)
 Makes sure one instance slot can hold transforms matrices.
 
VkBuffer getIndirectBuffer () const
 Gets the Vulkan indirect draw buffer associated with this frame.
 
void * getIndirectBufferMapped (std::size_t viewSlot) const
 Gets the mapped CPU pointer of a view's indirect slot.
 
VkDeviceSize getIndirectBufferAlignedSize () const
 Gets the aligned byte size of one indirect buffer slot.
 
bool hasTimestampQueries () const noexcept
 Indicates whether this frame owns GPU timestamp queries.
 
VkQueryPool getTimestampQueryPool () const noexcept
 Gets the timestamp query pool of this frame.
 

Public Attributes

VkFence _inFlight = VK_NULL_HANDLE
 
VkQueryPool _timestampQueryPool = VK_NULL_HANDLE
 
std::vector< VkSemaphore > _imageAvailable
 
std::vector< VkCommandBuffer > _commandBuffers
 
std::vector< VkSemaphore > _renderFinished
 
std::size_t _perFrameSlotCount = 1
 
void * _uniformBufferMapped = nullptr
 Pointer to the mapped memory of the uniform buffer.
 

Protected Member Functions

void cleanup ()
 Releases the synchronization objects, command buffer and uniform buffer owned by this frame.
 
void createCommandBuffer (VkDevice device, VkCommandPool commandPool)
 Creates the Vulkan command buffer for this frame.
 
void createSyncObjects (VkDevice device)
 Creates the synchronization objects for this frame.
 
void createUniformBuffer (const ADeviceBackend &deviceBackend)
 Creates the uniform buffer for this frame.
 
void createInstanceBuffer (const ADeviceBackend &deviceBackend)
 Creates the instance buffer for this frame.
 
void createIndirectBuffer (const ADeviceBackend &deviceBackend)
 Creates the indirect draw buffer for this frame.
 
void createTimestampQueryPool (VkDevice device)
 Creates the timestamp query pool for this frame.
 

Protected Attributes

VkBuffer _uniformBuffer = VK_NULL_HANDLE
 Vulkan buffer for the uniform buffer object (UBO) used in this frame.
 
VkDeviceMemory _uniformBufferMemory = VK_NULL_HANDLE
 Vulkan device memory associated with the uniform buffer.
 
VkDeviceSize _uniformBufferAlignedSize = 0
 Aligned byte size of one view's uniform buffer slot.
 
VkBuffer _instanceBuffer = VK_NULL_HANDLE
 Vulkan buffer storing per-instance model matrices.
 
VkDeviceMemory _instanceBufferMemory = VK_NULL_HANDLE
 Vulkan device memory associated with the instance buffer.
 
void * _instanceBufferMapped = nullptr
 Pointer to the mapped memory of the instance buffer.
 
VkDeviceSize _instanceBufferAlignedSize = 0
 Aligned byte size of one view's instance buffer slot.
 
std::size_t _instanceCapacity = 0
 Number of model matrices one instance buffer slot currently holds. Grown on demand by ensureInstanceCapacity().
 
VkBuffer _indirectBuffer = VK_NULL_HANDLE
 Vulkan buffer storing indirect draw commands.
 
VkDeviceMemory _indirectBufferMemory = VK_NULL_HANDLE
 Vulkan device memory associated with the indirect buffer.
 
void * _indirectBufferMapped = nullptr
 Pointer to the mapped memory of the indirect buffer.
 
VkDeviceSize _indirectBufferAlignedSize = 0
 Aligned byte size of one view's indirect buffer slot.
 
std::shared_ptr< DeviceContext > _deviceContext
 The device context used to create this frame, kept alive for the lifetime of the frame so that cleanup can safely destroy its Vulkan resources.
 

Detailed Description

Frame class representing a single frame of rendering in the Vulkan application.

This class encapsulates the Vulkan resources and synchronization objects needed for rendering a single frame, such as command buffers, fences, semaphores, and uniform buffers. It provides functions to create and manage these resources, as well as to reset the command buffer for recording new commands each frame. The Frame class is designed to be used in a multi-frame rendering loop, where each frame has its own set of resources to ensure proper synchronization and efficient rendering.

Note
The Frame class is closely tied to the ADeviceBackend class, which provides access to Vulkan resources and functions needed for creating buffers and synchronization objects. It is important to ensure that the Frame class is properly integrated with the device backend to manage Vulkan resources effectively.

Definition at line 40 of file Frame.hpp.

Constructor & Destructor Documentation

◆ Frame()

evan::Frame::Frame ( std::shared_ptr< DeviceContext >  deviceContext,
std::size_t  perFrameSlotCount 
)

Constructs a Frame object.

This constructor initializes the synchronization objects and command buffer for the frame. It takes a command pool and a reference to the device backend to set up the necessary Vulkan resources for rendering.

Parameters
commandPoolThe Vulkan command pool used to allocate command buffers for this frame.
deviceBackendA reference to the device backend that provides access to Vulkan resources and functions needed to create synchronization objects and uniform buffers.
perFrameSlotCountNumber of view/swapchain slots to allocate per-frame resources for, normally frameSlotCount(viewCount, swapchainCount). Clamped to [1, MAX_SWAPCHAINS].

Member Function Documentation

◆ cleanup()

void evan::Frame::cleanup ( )
protected

Releases the synchronization objects, command buffer and uniform buffer owned by this frame.

Idempotent: every handle is null-checked and reset after being destroyed, making it safe to call from both the destructor and the public destroy() method.

◆ createCommandBuffer()

void evan::Frame::createCommandBuffer ( VkDevice  device,
VkCommandPool  commandPool 
)
protected

Creates the Vulkan command buffer for this frame.

This function allocates a command buffer from the specified command pool and initializes it for recording rendering commands.

Parameters
deviceThe Vulkan logical device used to create the command buffer.
commandPoolThe Vulkan command pool from which to allocate the

◆ createIndirectBuffer()

void evan::Frame::createIndirectBuffer ( const ADeviceBackend &  deviceBackend)
protected

Creates the indirect draw buffer for this frame.

This buffer stores VkDrawIndexedIndirectCommand entries used to batch the sorted draws, with one aligned slot per view.

Parameters
deviceBackendA reference to the device backend used to create the buffer and allocate memory.

◆ createInstanceBuffer()

void evan::Frame::createInstanceBuffer ( const ADeviceBackend &  deviceBackend)
protected

Creates the instance buffer for this frame.

This buffer stores per-instance model matrices for instanced rendering, with one aligned slot per view. Each slot holds _instanceCapacity matrices; ensureInstanceCapacity() is the only caller and sets that capacity before allocating.

Parameters
deviceBackendA reference to the device backend used to create the buffer and allocate memory.

◆ createSyncObjects()

void evan::Frame::createSyncObjects ( VkDevice  device)
protected

Creates the synchronization objects for this frame.

This function creates the Vulkan synchronization objects (fences and semaphores) needed for rendering this frame, such as the in-flight fence, image available semaphore, and render finished semaphore.

Parameters
deviceThe Vulkan logical device used to create the synchronization objects.

◆ createTimestampQueryPool()

void evan::Frame::createTimestampQueryPool ( VkDevice  device)
protected

Creates the timestamp query pool for this frame.

Only called when frame statistics ask for GPU timings and the device supports timestamp queries; the pool holds two queries per view slot and is destroyed in cleanup().

Parameters
deviceThe Vulkan logical device used to create the pool.

◆ createUniformBuffer()

void evan::Frame::createUniformBuffer ( const ADeviceBackend &  deviceBackend)
protected

Creates the uniform buffer for this frame.

This function allocates a Vulkan buffer and its associated memory for the uniform buffer object (UBO) used in this frame. It sets up the buffer to be used for passing data to the vertex shader during rendering.

Parameters
deviceBackendA reference to the device backend that provides access to Vulkan resources and functions needed to create the buffer and allocate memory for the uniform buffer.

◆ destroy()

void evan::Frame::destroy ( VkDevice  device)

Destroys the Vulkan resources associated with this frame.

This function cleans up the synchronization objects, command buffer, and uniform buffer associated with this frame. It should be called when the frame is no longer needed to free up Vulkan resources.

Parameters
deviceThe Vulkan logical device used to destroy the resources.

◆ ensureInstanceCapacity()

bool evan::Frame::ensureInstanceCapacity ( std::size_t  transforms)

Makes sure one instance slot can hold transforms matrices.

Grows the instance buffer on demand instead of dropping meshes past a fixed bound. If the current capacity already covers the request this is a no-op. Otherwise the buffer and its memory are released and reallocated at the capacity returned by nextInstanceCapacity(), which grows geometrically so reallocation happens rarely.

The caller must not hold a mapped pointer across this call, and must not call it while a recorded command buffer of this frame still references the previous buffer: the handle changes. The renderer therefore calls it once per frame, before recording any view.

Parameters
transformsNumber of model matrices the frame needs per view.
Returns
True when the buffer was reallocated.

◆ getCommandBuffer()

VkCommandBuffer evan::Frame::getCommandBuffer ( std::size_t  viewSlot) const

Gets the command buffer of the given view slot.

Parameters
viewSlotIndex of the view whose command buffer is returned.
Returns
The Vulkan command buffer for this view.

◆ getIndirectBuffer()

VkBuffer evan::Frame::getIndirectBuffer ( ) const

Gets the Vulkan indirect draw buffer associated with this frame.

This buffer holds one slot per view, each slot storing up to MAX_INDIRECT_COMMANDS_PER_VIEW indirect draw commands used to batch the sorted draws when indirect drawing is enabled.

Returns
The Vulkan buffer for this frame.

◆ getIndirectBufferAlignedSize()

VkDeviceSize evan::Frame::getIndirectBufferAlignedSize ( ) const

Gets the aligned byte size of one indirect buffer slot.

Returns
The aligned size, a multiple of minUniformBufferOffsetAlignment.

◆ getIndirectBufferMapped()

void * evan::Frame::getIndirectBufferMapped ( std::size_t  viewSlot) const

Gets the mapped CPU pointer of a view's indirect slot.

Parameters
viewSlotIndex of the view slot.
Returns
Mapped pointer to the slot, ready for a memcpy of VkDrawIndexedIndirectCommand entries.

◆ getInstanceBuffer()

VkBuffer evan::Frame::getInstanceBuffer ( ) const

Gets the Vulkan instance buffer associated with this frame.

This buffer holds one slot per view, each slot storing the model matrices consumed by the vertex shader as per-instance attributes. One matrix is stored per drawn mesh, so every draw addresses its transform with firstInstance and the engine never bakes a transform into vertex data. The slot capacity grows on demand; see ensureInstanceCapacity().

Returns
The Vulkan buffer for this frame.

◆ getInstanceBufferAlignedSize()

VkDeviceSize evan::Frame::getInstanceBufferAlignedSize ( ) const

Gets the aligned byte size of one instance buffer slot.

Returns
The aligned size, a multiple of minUniformBufferOffsetAlignment.

◆ getInstanceBufferMapped()

void * evan::Frame::getInstanceBufferMapped ( std::size_t  viewSlot) const

Gets the mapped CPU pointer of a view's instance slot.

Parameters
viewSlotIndex of the view slot.
Returns
Mapped pointer to the slot, ready for a memcpy of instance transforms.

◆ getInstanceCapacity()

std::size_t evan::Frame::getInstanceCapacity ( ) const

Gets the number of model matrices one instance slot holds.

Returns
The per-view transform capacity.

◆ getPerFrameSlotCount()

std::size_t evan::Frame::getPerFrameSlotCount ( ) const

Gets the number of view/swapchain slots this frame was allocated for.

Returns
The per-frame slot count.

◆ getTimestampQueryPool()

VkQueryPool evan::Frame::getTimestampQueryPool ( ) const
inlinenoexcept

Gets the timestamp query pool of this frame.

The pool holds two queries per view slot (begin and end of the render pass). vkCmdResetQueryPool is recorded at the start of every command buffer, so a query is only read after the in-flight fence of the frame slot has signalled.

Returns
The query pool, or VK_NULL_HANDLE when timestamps are off.

Definition at line 291 of file Frame.hpp.

◆ getUniformBuffer()

VkBuffer evan::Frame::getUniformBuffer ( ) const

Gets the Vulkan uniform buffer associated with this frame.

This buffer holds one aligned slot per view. Descriptor sets bind it as a dynamic uniform buffer and select the view slot through a dynamic offset at bind time.

Returns
The Vulkan buffer for this frame.

◆ getUniformBufferAlignedSize()

VkDeviceSize evan::Frame::getUniformBufferAlignedSize ( ) const

Gets the aligned byte size of one uniform buffer slot.

Returns
The aligned size, a multiple of minUniformBufferOffsetAlignment.

◆ getUniformBufferMapped()

void * evan::Frame::getUniformBufferMapped ( std::size_t  viewSlot) const

Gets the mapped CPU pointer of a view's uniform slot.

Parameters
viewSlotIndex of the view slot.
Returns
Mapped pointer to the slot, ready for a memcpy of one UniformBufferObject.

◆ hasTimestampQueries()

bool evan::Frame::hasTimestampQueries ( ) const
inlinenoexcept

Indicates whether this frame owns GPU timestamp queries.

True when EVAN_STATS and EVAN_STATS_GPU are enabled and the device supports timestamp queries; the renderer only writes and reads timestamps when it is true.

Returns
True when timestamp queries are available on this frame.

Definition at line 276 of file Frame.hpp.

◆ resetCommandBuffer()

void evan::Frame::resetCommandBuffer ( std::size_t  viewSlot)

Resets the command buffer of the given view slot.

Each view owns its own command buffer so that stereo views can be recorded back-to-back without waiting for the GPU between them.

Parameters
viewSlotIndex of the view whose command buffer is reset.

Member Data Documentation

◆ _commandBuffers

std::vector<VkCommandBuffer> evan::Frame::_commandBuffers

Vulkan command buffers recorded for this frame, one per view.

Definition at line 323 of file Frame.hpp.

◆ _deviceContext

std::shared_ptr<DeviceContext> evan::Frame::_deviceContext
protected

The device context used to create this frame, kept alive for the lifetime of the frame so that cleanup can safely destroy its Vulkan resources.

Definition at line 504 of file Frame.hpp.

◆ _imageAvailable

std::vector<VkSemaphore> evan::Frame::_imageAvailable

Per-swapchain semaphores signaled when a swapchain image is available for rendering (only used by backends that signal them, e.g. desktop).

Definition at line 318 of file Frame.hpp.

◆ _indirectBuffer

VkBuffer evan::Frame::_indirectBuffer = VK_NULL_HANDLE
protected

Vulkan buffer storing indirect draw commands.

Definition at line 482 of file Frame.hpp.

◆ _indirectBufferAlignedSize

VkDeviceSize evan::Frame::_indirectBufferAlignedSize = 0
protected

Aligned byte size of one view's indirect buffer slot.

Definition at line 497 of file Frame.hpp.

◆ _indirectBufferMapped

void* evan::Frame::_indirectBufferMapped = nullptr
protected

Pointer to the mapped memory of the indirect buffer.

Definition at line 492 of file Frame.hpp.

◆ _indirectBufferMemory

VkDeviceMemory evan::Frame::_indirectBufferMemory = VK_NULL_HANDLE
protected

Vulkan device memory associated with the indirect buffer.

Definition at line 487 of file Frame.hpp.

◆ _inFlight

VkFence evan::Frame::_inFlight = VK_NULL_HANDLE

In-flight fence ensuring that a frame's resources (command buffer, uniform buffer and semaphores) are not reused until the previous frame using them has finished on the GPU. One fence is kept per in-flight frame, signaled by the frame's queue submission and waited on before the frame is reused.

Definition at line 303 of file Frame.hpp.

◆ _instanceBuffer

VkBuffer evan::Frame::_instanceBuffer = VK_NULL_HANDLE
protected

Vulkan buffer storing per-instance model matrices.

Definition at line 456 of file Frame.hpp.

◆ _instanceBufferAlignedSize

VkDeviceSize evan::Frame::_instanceBufferAlignedSize = 0
protected

Aligned byte size of one view's instance buffer slot.

Definition at line 471 of file Frame.hpp.

◆ _instanceBufferMapped

void* evan::Frame::_instanceBufferMapped = nullptr
protected

Pointer to the mapped memory of the instance buffer.

Definition at line 466 of file Frame.hpp.

◆ _instanceBufferMemory

VkDeviceMemory evan::Frame::_instanceBufferMemory = VK_NULL_HANDLE
protected

Vulkan device memory associated with the instance buffer.

Definition at line 461 of file Frame.hpp.

◆ _instanceCapacity

std::size_t evan::Frame::_instanceCapacity = 0
protected

Number of model matrices one instance buffer slot currently holds. Grown on demand by ensureInstanceCapacity().

Definition at line 477 of file Frame.hpp.

◆ _perFrameSlotCount

std::size_t evan::Frame::_perFrameSlotCount = 1

Number of view/swapchain slots this frame allocated its per-frame resources for (command buffers, semaphores and buffer slots). Always in [1, MAX_SWAPCHAINS].

Definition at line 336 of file Frame.hpp.

◆ _renderFinished

std::vector<VkSemaphore> evan::Frame::_renderFinished

Per-swapchain semaphores signaled when rendering to a swapchain image is finished and the image can be presented.

Definition at line 329 of file Frame.hpp.

◆ _timestampQueryPool

VkQueryPool evan::Frame::_timestampQueryPool = VK_NULL_HANDLE

Timestamp query pool used by the frame statistics, two queries per view slot (begin/end of the render pass). VK_NULL_HANDLE when EVAN_STATS or EVAN_STATS_GPU is off, or when the device does not support timestamp queries.

Definition at line 311 of file Frame.hpp.

◆ _uniformBuffer

VkBuffer evan::Frame::_uniformBuffer = VK_NULL_HANDLE
protected

Vulkan buffer for the uniform buffer object (UBO) used in this frame.

This buffer is allocated to store the model, view, and projection matrices that will be passed to the vertex shader as a uniform buffer during rendering.

Definition at line 434 of file Frame.hpp.

◆ _uniformBufferAlignedSize

VkDeviceSize evan::Frame::_uniformBufferAlignedSize = 0
protected

Aligned byte size of one view's uniform buffer slot.

Computed from minUniformBufferOffsetAlignment so each view slot starts on an offset the dynamic uniform buffer binding accepts.

Definition at line 451 of file Frame.hpp.

◆ _uniformBufferMapped

void* evan::Frame::_uniformBufferMapped = nullptr

Pointer to the mapped memory of the uniform buffer.

Definition at line 341 of file Frame.hpp.

◆ _uniformBufferMemory

VkDeviceMemory evan::Frame::_uniformBufferMemory = VK_NULL_HANDLE
protected

Vulkan device memory associated with the uniform buffer.

This memory is allocated to back the uniform buffer and is used to store the data for the UBO. It is mapped to allow CPU access for updating the UBO data before rendering.

Definition at line 443 of file Frame.hpp.


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