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

The Renderer class is responsible for managing the graphics pipeline, descriptor sets, and rendering frames. It interacts with the device context and swapchain context to draw the scene on the screen. More...

#include <headers/evan/Renderer.hpp>

Inheritance diagram for evan::Renderer:
Collaboration diagram for evan::Renderer:

Classes

struct  PipelineVariant
 Identifies one graphics pipeline variant. More...
 

Public Member Functions

 Renderer (std::shared_ptr< DeviceContext > deviceContext, VkRenderPass renderPass, VkSampleCountFlagBits msaaSamples, std::size_t perFrameSlotCount, std::shared_ptr< RessourceManager > ressourceManager)
 Constructs a Renderer object.
 
void destroy (VkDevice device)
 Destroys the Renderer and releases associated resources.
 
size_t addObject (std::shared_ptr< RenderObject > object)
 Registers a render object in the renderer's object registry.
 
bool updateObject (std::shared_ptr< RenderObject > object, size_t objectID)
 Updates a render object in the renderer's object registry.
 
bool removeObject (size_t objectID)
 Removes a render object from the renderer's registry.
 
std::shared_ptr< RenderObject > getObject (size_t objectID) const
 Retrieves a render object from the renderer's registry.
 
Error drawFrame (const DeviceContext &deviceContext, ASwapchainContext &swapchainContext)
 Draws a frame by recording command buffers and submitting them to the graphics queue.
 
void setScissor (const utility::graphic::ScissorRect &rect)
 Set the scissor (clip) rectangle applied when recording.
 
void clearScissor (void)
 Clear the active scissor rectangle (restore the full extent).
 
const FrameStats & getStats () const noexcept
 Retrieves the frame statistics of this renderer.
 
void resetStats () noexcept
 Starts a new statistics window.
 
VkDescriptorPool getDescriptorPool () const
 Retrieves the Vulkan descriptor pool associated with the Renderer.
 
const std::vector< VkBuffer > getUniformBuffers () const
 Retrieves the Vulkan descriptor set layout associated with the Renderer.
 
VkDescriptorSetLayout getDescriptorSetLayout () const
 Retrieves the Vulkan descriptor set layout associated with the Renderer.
 
void setCullingEnabled (bool enabled)
 Enables or disables frustum and distance culling.
 
bool isCullingEnabled () const
 Checks whether culling is currently enabled.
 
void setMaxDrawDistance (float maxDistance)
 Sets the maximum draw distance for distance culling.
 
float getMaxDrawDistance () const
 Retrieves the maximum draw distance.
 
void setInstancingEnabled (bool enabled)
 Enables or disables merging of identical meshes.
 
bool isInstancingEnabled () const
 Checks whether identical meshes are merged into one draw.
 
void setIndirectDrawingEnabled (bool enabled)
 Enables or disables indirect drawing.
 
bool isIndirectDrawingEnabled () const
 Checks whether indirect drawing is enabled.
 
void setShaderBlendMode (uint32_t shaderID, BlendMode blendMode)
 Overrides the blend mode used for a shader.
 
BlendMode getShaderBlendMode (uint32_t shaderID) const
 Retrieves the blend mode used for a shader.
 
void setOpaqueSortMode (OpaqueSortMode mode)
 Sets the ordering strategy used for opaque draws.
 
OpaqueSortMode getOpaqueSortMode () const
 Retrieves the ordering strategy used for opaque draws.
 

Static Public Member Functions

static VkRect2D clampScissor (const utility::graphic::ScissorRect &rect, VkExtent2D extent)
 Clamp a scissor rectangle to a render target extent.
 
static bool viewOwnsInFlightFence (std::size_t viewIndex, std::size_t viewCount) noexcept
 Whether the view at viewIndex carries the in-flight fence for a submission group of viewCount views.
 

Protected Attributes

std::map< PipelineVariant, VkPipeline > _pipelines
 
std::map< uint32_t, VkPipelineLayout > _pipelineLayouts
 
std::vector< std::shared_ptr< Frame > > _frames
 A collection of frames used for rendering.
 
std::shared_ptr< DeviceContext > _deviceContext
 The device context used to create this renderer's resources.
 
uint32_t _currentFrameIndex
 The index of the current frame being rendered.
 
FrameStats _stats
 Frame statistics window (CPU phases, counters, GPU passes).
 
float _timestampPeriod = 0.0f
 Nanoseconds per GPU timestamp tick, cached at construction.
 
uint32_t _timestampValidBits = 0
 Number of valid bits in a GPU timestamp, cached at construction.
 
VkDescriptorSetLayout _descriptorSetLayout
 Vulkan descriptor set layout used for rendering operations.
 
VkDescriptorPool _descriptorPool
 Vulkan descriptor pool used for allocating descriptor sets.
 
std::map< size_t, std::shared_ptr< RenderObject > > _objects
 The registry of render objects owned by the renderer.
 
size_t _nextObjectID = 1
 A counter to generate unique object IDs for the registered render objects. Incremented each time a new object is added.
 
std::optional< utility::graphic::ScissorRect > _scissor
 The active scissor rectangle, in framebuffer pixels.
 

Detailed Description

The Renderer class is responsible for managing the graphics pipeline, descriptor sets, and rendering frames. It interacts with the device context and swapchain context to draw the scene on the screen.

The Renderer class provides methods to create the graphics pipeline, descriptor set layout, and descriptor pool. It also handles the drawing of frames by recording command buffers and updating uniform buffers with scene data. The class maintains a collection of frames for rendering and manages the current frame index for synchronization.

Note
The Renderer class is designed to work with Vulkan and requires a valid DeviceContext and ASwapchainContext to function properly. It encapsulates the rendering logic and resource management for a Vulkan-based rendering system.

Definition at line 61 of file Renderer.hpp.

Constructor & Destructor Documentation

◆ Renderer()

evan::Renderer::Renderer ( std::shared_ptr< DeviceContext >  deviceContext,
VkRenderPass  renderPass,
VkSampleCountFlagBits  msaaSamples,
std::size_t  perFrameSlotCount,
std::shared_ptr< RessourceManager >  ressourceManager 
)

Constructs a Renderer object.

This constructor initializes the Renderer by creating the graphics pipeline, descriptor set layout, and descriptor pool. It takes a reference to the DeviceContext, the Vulkan render pass, and the MSAA sample count as parameters. The constructor sets up the necessary resources for rendering frames and prepares the Renderer for drawing operations.

Parameters
deviceContextA reference to the DeviceContext, which provides access to the Vulkan device and related resources.
renderPassThe Vulkan render pass that defines the structure of the rendering operations.
msaaSamplesThe MSAA sample count to be used for multisample anti aliasing operations in the graphics pipeline.
perFrameSlotCountNumber of view/swapchain slots each frame allocates per-frame resources for, normally frameSlotCount(viewCount, swapchainCount). Clamped to [1, MAX_SWAPCHAINS].
ressourceManagerA shared pointer to the RessourceManager, which is responsible for managing materials, textures, and other resources used in rendering. The Renderer interacts with the RessourceManager to access the necessary resources for rendering scenes, such as materials and textures associated with render objects.
Note
The constructor may throw exceptions if resource creation fails, such as if the graphics pipeline or descriptor pool cannot be created successfully. Ensure that the provided DeviceContext and render pass are valid and properly initialized before constructing the Renderer.

Member Function Documentation

◆ addObject()

size_t evan::Renderer::addObject ( std::shared_ptr< RenderObject >  object)

Registers a render object in the renderer's object registry.

The renderer owns the registry of render objects drawn each frame. The object is assigned a unique object ID, which can later be used to remove it or to access it (e.g. for in-place mesh updates).

Parameters
objectA shared pointer to the RenderObject to register.
Returns
The unique object ID assigned to the render object.

◆ clampScissor()

static VkRect2D evan::Renderer::clampScissor ( const utility::graphic::ScissorRect &  rect,
VkExtent2D  extent 
)
static

Clamp a scissor rectangle to a render target extent.

Exposed so the clamping can be covered by a unit test without a device.

Parameters
rectThe requested scissor rectangle, in pixels.
extentThe render target extent, in pixels.
Returns
The clamped Vulkan scissor rectangle.

◆ destroy()

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

Destroys the Renderer and releases associated resources.

This method is responsible for cleaning up all Vulkan resources associated with the Renderer, including the graphics pipeline, pipeline layout, descriptor set layout, descriptor pool, and any frames that were created. It takes a Vulkan device as a parameter to perform the necessary cleanup operations. Implement this method to ensure that all resources related to the Renderer are properly released when the Renderer is no longer needed.

Parameters
deviceThe Vulkan device used to perform cleanup operations for the Renderer.
Note
This method should be called when the Renderer is being destroyed to ensure that all Vulkan resources are properly released and to prevent memory leaks. Make sure to handle any exceptions that may arise during resource cleanup to maintain stability in the application.

◆ drawFrame()

Error evan::Renderer::drawFrame ( const DeviceContext &  deviceContext,
ASwapchainContext &  swapchainContext 
)

Draws a frame by recording command buffers and submitting them to the graphics queue.

This method handles the rendering of a frame by updating the uniform buffer, recording the command buffer with the appropriate render pass and framebuffer, and submitting the command buffer to the graphics queue for execution. It takes references to the DeviceContext and ASwapchainContext as parameters to access the necessary resources and data for rendering. Implement this method to ensure that frames are rendered correctly based on the registered render objects and the swapchain context.

Parameters
deviceContextA reference to the DeviceContext, which provides access to the Vulkan device and related resources.
swapchainContextA reference to the ASwapchainContext, which provides access to the swapchain and render pass for rendering operations.
Returns
evan::Error::Ok on success. evan::Error::Suboptimal or evan::Error::SwapchainOutOfDate when the swapchain was recreated and the caller should retry on the next frame. Any other value is fatal (e.g. evan::Error::DeviceLost) and the caller should stop cleanly.
Note
This method should be called for each frame that needs to be rendered. Ensure that the DeviceContext and ASwapchainContext are properly initialized and contain valid data before calling this method to avoid rendering issues or exceptions during command buffer recording and submission.

◆ getDescriptorPool()

VkDescriptorPool evan::Renderer::getDescriptorPool ( ) const

Retrieves the Vulkan descriptor pool associated with the Renderer.

This method returns the Vulkan descriptor pool that is used by the Renderer to allocate descriptor sets for rendering operations. The descriptor pool is a crucial resource for managing descriptor sets, which are used to bind resources such as uniform buffers and textures to the graphics pipeline. Implement this method to provide access to the descriptor pool for other components of the rendering system that may need to allocate descriptor sets.

Returns
The Vulkan descriptor pool associated with the Renderer.

◆ getDescriptorSetLayout()

VkDescriptorSetLayout evan::Renderer::getDescriptorSetLayout ( ) const

Retrieves the Vulkan descriptor set layout associated with the Renderer.

This method returns the Vulkan descriptor set layout that defines the structure of the descriptor sets used by the Renderer. The descriptor set layout specifies the types and counts of resources that can be bound to the graphics pipeline, such as uniform buffers and textures. Implement this method to provide access to the descriptor set layout for other components of the rendering system that may need to create or manage descriptor sets based on this layout.

Returns
The Vulkan descriptor set layout associated with the Renderer.

◆ getMaxDrawDistance()

float evan::Renderer::getMaxDrawDistance ( ) const
inline

Retrieves the maximum draw distance.

Returns
The maximum draw distance (0 means disabled).

Definition at line 379 of file Renderer.hpp.

◆ getObject()

std::shared_ptr< RenderObject > evan::Renderer::getObject ( size_t  objectID) const

Retrieves a render object from the renderer's registry.

Parameters
objectIDThe object ID of the render object to retrieve.
Returns
A shared pointer to the RenderObject if found, or nullptr if no object with the given ID exists.

◆ getOpaqueSortMode()

OpaqueSortMode evan::Renderer::getOpaqueSortMode ( ) const
inline

Retrieves the ordering strategy used for opaque draws.

Returns
The current ordering strategy.

Definition at line 513 of file Renderer.hpp.

◆ getShaderBlendMode()

BlendMode evan::Renderer::getShaderBlendMode ( uint32_t  shaderID) const

Retrieves the blend mode used for a shader.

Parameters
shaderIDThe shader to look up.
Returns
The blend mode resulting from setShaderBlendMode(), or BlendMode::Opaque when no override was registered.

◆ getStats()

const FrameStats & evan::Renderer::getStats ( ) const
inlinenoexcept

Retrieves the frame statistics of this renderer.

Returns the live report window: CPU phase timings, per-view GPU pass times (when timestamp queries are available) and per-frame counters. The data accumulates in memory and is never logged per frame; the renderer itself emits one aggregated log record every EVAN_STATS_INTERVAL frames when EVAN_STATS is set. An application may read this accessor to draw its own debug overlay.

The window is reset after each aggregated log record and by resetStats().

Returns
The current frame statistics.

Definition at line 270 of file Renderer.hpp.

◆ getUniformBuffers()

const std::vector< VkBuffer > evan::Renderer::getUniformBuffers ( ) const

Retrieves the Vulkan descriptor set layout associated with the Renderer.

This method returns the Vulkan descriptor set layout that defines the structure of the descriptor sets used by the Renderer. The descriptor set layout specifies the types and counts of resources that can be bound to the graphics pipeline, such as uniform buffers and textures. Implement this method to provide access to the descriptor set layout for other components of the rendering system that may need to create or manage descriptor sets based on this layout.

Returns
The Vulkan descriptor set layout associated with the Renderer.

◆ isCullingEnabled()

bool evan::Renderer::isCullingEnabled ( ) const
inline

Checks whether culling is currently enabled.

Returns
True when culling is enabled.

Definition at line 356 of file Renderer.hpp.

◆ isIndirectDrawingEnabled()

bool evan::Renderer::isIndirectDrawingEnabled ( ) const
inline

Checks whether indirect drawing is enabled.

Returns
True when indirect drawing is enabled.

Definition at line 437 of file Renderer.hpp.

◆ isInstancingEnabled()

bool evan::Renderer::isInstancingEnabled ( ) const
inline

Checks whether identical meshes are merged into one draw.

Returns
True when consecutive identical meshes are merged.

Definition at line 412 of file Renderer.hpp.

◆ removeObject()

bool evan::Renderer::removeObject ( size_t  objectID)

Removes a render object from the renderer's registry.

Parameters
objectIDThe object ID of the render object to remove.
Returns
True if the object was found and removed, false otherwise.

◆ resetStats()

void evan::Renderer::resetStats ( )
inlinenoexcept

Starts a new statistics window.

Clears the accumulated phase samples, counters and frame count; keeps the enabled/available flags.

Definition at line 281 of file Renderer.hpp.

Here is the call graph for this function:

◆ setCullingEnabled()

void evan::Renderer::setCullingEnabled ( bool  enabled)
inline

Enables or disables frustum and distance culling.

When enabled, meshes whose bounds are fully outside the current view frustum (or beyond the maximum draw distance) are skipped before recording their draw commands. Disable for debugging: a wrong bound then never hides geometry.

Parameters
enabledTrue to cull, false to draw every mesh.

Definition at line 346 of file Renderer.hpp.

◆ setIndirectDrawingEnabled()

void evan::Renderer::setIndirectDrawingEnabled ( bool  enabled)
inline

Enables or disables indirect drawing.

When enabled, the sorted draws are written into the per-frame indirect buffer and submitted with vkCmdDrawIndexedIndirect, one call per consecutive group sharing the same pipeline/descriptor/ vertex state. Disabled by default.

Parameters
enabledTrue to batch draws through the indirect buffer.

Definition at line 427 of file Renderer.hpp.

◆ setInstancingEnabled()

void evan::Renderer::setInstancingEnabled ( bool  enabled)
inline

Enables or disables merging of identical meshes.

The per-object transform always reaches the GPU: every mesh is drawn with the model matrix of its own slot in the per-view instance buffer, whether or not this flag is set. This flag only controls batching: when enabled, consecutive meshes sharing the same geometry (pipeline, material, vertex and index buffers) are merged into a single vkCmdDrawIndexed with instanceCount > 1.

Merging is only correct with a vertex shader that consumes the per-instance matrix (locations 3 to 6): such a shader places each instance at its own transform, while a shader ignoring the instance data would draw every instance of the run at the same place. Disabled by default.

Parameters
enabledTrue to merge identical meshes into instanced draws.

Definition at line 402 of file Renderer.hpp.

◆ setMaxDrawDistance()

void evan::Renderer::setMaxDrawDistance ( float  maxDistance)
inline

Sets the maximum draw distance for distance culling.

Meshes whose bounding sphere is entirely beyond this distance from the view are culled. A value of 0 disables distance culling.

Parameters
maxDistanceMaximum draw distance in world units (0 disables).

Definition at line 369 of file Renderer.hpp.

◆ setOpaqueSortMode()

void evan::Renderer::setOpaqueSortMode ( OpaqueSortMode  mode)
inline

Sets the ordering strategy used for opaque draws.

Parameters
modeThe ordering strategy to use.

Definition at line 503 of file Renderer.hpp.

◆ setScissor()

void evan::Renderer::setScissor ( const utility::graphic::ScissorRect &  rect)

Set the scissor (clip) rectangle applied when recording.

The rectangle is expressed in framebuffer pixels and clamped to the swapchain extent when a frame is recorded. It applies to every view recorded in a frame.

Parameters
rectThe scissor rectangle to apply.

◆ setShaderBlendMode()

void evan::Renderer::setShaderBlendMode ( uint32_t  shaderID,
BlendMode  blendMode 
)

Overrides the blend mode used for a shader.

Materials decide their own blend mode (see utility::graphic::Material::getAlphaMode and GPUMaterial::getBlendMode), which covers assets that declare their transparency. This setter is the escape hatch for shaders whose alpha behaviour is not described by the material, for instance a shader that derives its transparency from something other than the albedo texture.

The override applies to the next recorded frame; the pipelines of both variants already exist.

Parameters
shaderIDThe shader whose draws are switched.
blendModeThe blend mode used for every draw of that shader.

◆ updateObject()

bool evan::Renderer::updateObject ( std::shared_ptr< RenderObject >  object,
size_t  objectID 
)

Updates a render object in the renderer's object registry.

The renderer owns the registry of render objects drawn each frame. The object is updated in-place using the provided object ID, which must correspond to an existing registered render object.

Parameters
objectA shared pointer to the RenderObject to update.
objectIDThe unique object ID of the render object to update.
Returns
True if the update was successful, false otherwise.

◆ viewOwnsInFlightFence()

static bool evan::Renderer::viewOwnsInFlightFence ( std::size_t  viewIndex,
std::size_t  viewCount 
)
staticnoexcept

Whether the view at viewIndex carries the in-flight fence for a submission group of viewCount views.

drawFrame records and submits every view of a frame back-to-back and attaches the in-flight fence only to the last submission. The graphics queue executes submissions in order, so the last submission's completion implies every earlier view has completed; attaching the fence to every view would make the CPU wait for each eye in turn and reintroduce the P0-03 inter-eye stall.

Exposed so the invariant can be covered by a unit test.

Parameters
viewIndexIndex of the view within the submission group.
viewCountNumber of views in the submission group.
Returns
True when the view is the last one of the group.

Member Data Documentation

◆ _currentFrameIndex

uint32_t evan::Renderer::_currentFrameIndex
protected

The index of the current frame being rendered.

This member variable keeps track of the index of the current frame being rendered in the _frames vector. It is used to manage synchronization and to ensure that the correct frame resources are accessed during rendering operations. The Renderer updates this index as it cycles through the frames for rendering.

Definition at line 569 of file Renderer.hpp.

◆ _descriptorPool

VkDescriptorPool evan::Renderer::_descriptorPool
protected

Vulkan descriptor pool used for allocating descriptor sets.

This member variable holds the Vulkan descriptor pool that is used by the Renderer to allocate descriptor sets for rendering operations. The descriptor pool is a crucial resource for managing descriptor sets, which are used to bind resources such as uniform buffers and textures to the graphics pipeline. It is essential for ensuring that the Renderer can efficiently manage and allocate descriptor sets as needed during rendering operations.

Definition at line 615 of file Renderer.hpp.

◆ _descriptorSetLayout

VkDescriptorSetLayout evan::Renderer::_descriptorSetLayout
protected

Vulkan descriptor set layout used for rendering operations.

This member variable holds the Vulkan descriptor set layout that defines the structure of the descriptor sets used by the Renderer. The descriptor set layout specifies the types and counts of resources that can be bound to the graphics pipeline, such as uniform buffers and textures. It is essential for configuring how resources are accessed by shaders and how they are organized in the graphics pipeline during rendering operations.

Definition at line 602 of file Renderer.hpp.

◆ _deviceContext

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

The device context used to create this renderer's resources.

Kept alive for the lifetime of the Renderer so that frames created from it can safely destroy their Vulkan resources on destruction.

Definition at line 558 of file Renderer.hpp.

◆ _frames

std::vector<std::shared_ptr<Frame> > evan::Renderer::_frames
protected

A collection of frames used for rendering.

This member variable holds a vector of Frame objects that are used by the Renderer to manage the rendering of frames. Each Frame contains the necessary Vulkan resources, such as command buffers and synchronization objects, for rendering operations. The Renderer uses this collection of frames to handle multiple frames in flight and to ensure proper synchronization between rendering operations.

Definition at line 550 of file Renderer.hpp.

◆ _nextObjectID

size_t evan::Renderer::_nextObjectID = 1
protected

A counter to generate unique object IDs for the registered render objects. Incremented each time a new object is added.

Definition at line 631 of file Renderer.hpp.

◆ _objects

std::map<size_t, std::shared_ptr<RenderObject> > evan::Renderer::_objects
protected

The registry of render objects owned by the renderer.

The key is the unique object ID returned by addObject(), and the value is the RenderObject whose GPU meshes are drawn each frame. This is the single owner of the renderable content registered by the application.

Definition at line 625 of file Renderer.hpp.

◆ _pipelineLayouts

std::map<uint32_t, VkPipelineLayout> evan::Renderer::_pipelineLayouts
protected

A map of pipeline layer identifiers to Vulkan pipeline layout objects. This map is used to manage different pipeline layouts for rendering operations based on the pipeline layer associated with render objects. Each entry in the map corresponds to a specific pipeline layer and its associated Vulkan pipeline layout, which defines the interface between shader stages and the resources bound to the graphics pipeline for rendering objects that belong to that layer.

Definition at line 527 of file Renderer.hpp.

◆ _pipelines

std::map<PipelineVariant, VkPipeline> evan::Renderer::_pipelines
protected

Graphics pipeline per (shader, blend mode) variant. Each shader has an opaque and an alpha-blended pipeline so that blending and depth writes are only enabled for the draws that need them.

Definition at line 520 of file Renderer.hpp.

◆ _scissor

std::optional<utility::graphic::ScissorRect> evan::Renderer::_scissor
protected

The active scissor rectangle, in framebuffer pixels.

When set, it is clamped to the swapchain extent and applied to every view recorded in a frame instead of the full-extent default.

Definition at line 639 of file Renderer.hpp.

◆ _stats

FrameStats evan::Renderer::_stats
protected

Frame statistics window (CPU phases, counters, GPU passes).

Disabled by default through EVAN_STATS; see FrameStats. The renderer fills the phases while drawing and emits one aggregated record every EVAN_STATS_INTERVAL frames.

Definition at line 578 of file Renderer.hpp.

◆ _timestampPeriod

float evan::Renderer::_timestampPeriod = 0.0f
protected

Nanoseconds per GPU timestamp tick, cached at construction.

Definition at line 583 of file Renderer.hpp.

◆ _timestampValidBits

uint32_t evan::Renderer::_timestampValidBits = 0
protected

Number of valid bits in a GPU timestamp, cached at construction.

Definition at line 589 of file Renderer.hpp.


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