Skip to main content
Prisma::Graphic::RenderSystem is the engine subsystem that owns the GPU device, swap chain, resource manager, and active render pipeline. The engine constructs and registers it automatically during Engine::Initialize() — you access it through Engine::GetRenderSystem() rather than constructing it yourself. The system implements ISubSystem, so the engine drives its lifecycle and per-frame updates alongside all other subsystems.

RenderSystemDesc

RenderSystem is constructed from a RenderSystemDesc that specifies the graphics API, window target, and initial resolution.
RenderAPIType
The graphics API to use. See RenderAPIType below. Defaults to RenderAPIType::Vulkan.
void*
Platform window handle — HWND on Windows, ANativeWindow* on Android.
void*
Vulkan surface handle or nullptr when using DirectX 12.
uint32_t
Initial render target width in pixels. Defaults to 1600.
uint32_t
Initial render target height in pixels. Defaults to 900.
bool
Enables API-level debug layers (D3D12 debug layer / Vulkan validation layers). Defaults to true. Disable in release builds for performance.
bool
Enables extended validation reporting. Defaults to true.
PresentMode
Swap-chain presentation mode. Defaults to PresentMode::VSync.
uint32_t
Number of frames the CPU can run ahead of the GPU. Defaults to 3.
std::string
Identifies this render system in debug tools and log output. Defaults to "PrismaApp".

RenderAPIType

DirectX 12 is the primary backend on Windows. Vulkan is the cross-platform backend used on Windows (editor), Linux, and Android. OpenGL is a fallback path on Linux.

Class overview

Lifecycle (ISubSystem)

Initialize

Called by the engine during startup. Runs the following internal stages in order:
  1. InitializeDevice() — selects and initialises the backend (DX12 or Vulkan), creates the swap chain.
  2. InitializeRenderResourceManager() — creates the resource factory and allocators.
  3. InitializeRenderPipelines() — constructs the default forward render pipeline.
Returns 0 on success or a non-zero error code on failure. A failure here aborts engine startup.

Shutdown

Flushes all in-flight GPU work, destroys pipelines, releases the swap chain, and destroys the device. Called automatically by the engine on exit.

Update

Per-frame housekeeping — updates resource streaming, hot-reload checks for shaders, and any async upload completion. Called by the engine before BeginFrame().

Frame control

A typical frame calls these four methods in order:

BeginFrame

Acquires the next swap-chain image, resets command allocators for the current frame-in-flight index, and opens command lists. Call once at the start of each rendered frame.

EndFrame

Closes and submits all open command lists to the GPU queue, signals the frame fence, and advances the frame-in-flight counter. Call after all draw calls are submitted for the frame.

Present

Presents the finished frame to the display according to the configured PresentMode. Blocks until a swap-chain slot is available when PresentMode::VSync is active.

Resize

Recreates the swap chain and all resolution-dependent render targets at the new dimensions. Call from your OnEvent() handler when a window resize event is received.
uint32_t
required
New render target width in pixels.
uint32_t
required
New render target height in pixels.

Device access

GetDevice

Returns the underlying render device interface. Use this to create low-level GPU resources (buffers, textures, pipelines) directly. Returns nullptr and logs an error if called before Initialize().

GetRenderResourceManager

Returns the resource manager that wraps the backend-specific resource factories (DX12ResourceFactory or VulkanResourceFactory). Use this for managed resource creation with automatic lifetime tracking.

Pipeline management

SetMainPipeline

Replaces the active render pipeline. The engine defaults to a ForwardPipeline at startup. Pass a DeferredPipeline or a custom IPipeline implementation to switch rendering strategies at runtime.
std::shared_ptr<IPipeline>
required
The new pipeline to use. Ownership is shared — the previous pipeline is destroyed when no other references to it exist.

GetMainPipeline

Returns a raw pointer to the current active pipeline. Valid as long as the RenderSystem is alive and SetMainPipeline() has not replaced it.

Scene rendering

RenderScene

Drives the full scene-rendering path through the current main pipeline: geometry collection → depth pre-pass → opaque pass → transparent pass (forward) or geometry pass → composition pass (deferred). Pass targetTexture to render to an off-screen texture instead of the swap chain back buffer.
Prisma::Scene*
required
The scene graph to render. All visible mesh renderers in the scene are submitted to the pipeline.
Prisma::Graphic::ICamera*
required
The camera providing the view and projection matrices for this frame.
ITexture*
Optional off-screen render target. When nullptr (default), output goes to the swap-chain back buffer.

Render pipeline architecture

The following diagram shows how RenderSystem sits in the broader rendering stack:

Renderer (high-level command API)

For code that wants to submit draw calls without touching the pipeline directly, use the static Renderer API in src/engine/graphic/Renderer.h:
Renderer::BeginScene() sets the active camera, Submit() enqueues a RenderCommand, and EndScene() signals that no more commands will arrive this frame. The pipeline retrieves the queue via GetCommandQueue() and dispatches the GPU work.
Mesh*
required
The mesh geometry to draw.
Material*
required
The material (shader + textures + constants) to apply.
const PrismaMath::mat4&
required
World-space transform matrix for this draw call.
const Prisma::Color&
Per-instance tint color. Defaults to opaque white (1, 1, 1, 1).