Skip to main content

Overview

The Vulkan backend is Ryujinx’s primary graphics API implementation, providing high-performance rendering through direct control of GPU resources and minimal driver overhead. It implements the Graphics Abstraction Layer (GAL) using modern Vulkan 1.2+ features.
Ryujinx requires Vulkan 1.2 with extensions including VK_KHR_dynamic_rendering, VK_EXT_extended_dynamic_state, and VK_EXT_transform_feedback for optimal compatibility.

Architecture Overview

VulkanRenderer

The main renderer class initializes the Vulkan instance, selects a physical device, and manages global resources.

Initialization

1

Instance Creation

Create a Vulkan instance with required extensions:
2

Physical Device Selection

Select the most suitable GPU:
3

Device and Queue Creation

Create logical device and command queue:
4

Resource Initialization

Initialize memory allocators and resource managers:

Hardware Capabilities

Pipeline Management

The PipelineFull class extends PipelineBase and manages all pipeline state and rendering operations.

Pipeline State

Dynamic State Management

Drawing Operations

Descriptor Set Management

Vulkan’s descriptor system binds resources (buffers, textures, samplers) to shaders.

Descriptor Set Layout

Ryujinx organizes descriptors into 4 sets:

Set 0: Uniform Buffers

Constant buffers for shader uniforms

Set 1: Storage Buffers

Read/write storage buffers (SSBOs)

Set 2: Textures

Sampled textures with samplers

Set 3: Images

Storage images for compute/fragment shader writes

Descriptor Set Updater

Push Descriptors

For frequently updated resources, Ryujinx uses push descriptors (VK_KHR_push_descriptor) to avoid allocation overhead:

Command Buffer Management

Vulkan command buffers record GPU commands for later execution.

Command Buffer Pool

Render Pass Management

With VK_KHR_dynamic_rendering, render passes are begun dynamically:

Memory Management

Memory Allocator

The MemoryAllocator manages device memory using a buddy allocator:

Buffer Creation

Synchronization

Vulkan synchronization uses fences, semaphores, and pipeline barriers.

Fence-Based Sync

Pipeline Barriers

Shader Management

SPIR-V Compilation

Shaders are compiled to SPIR-V:

Shader Collection

Performance Optimizations

Push Descriptors

Uses VK_KHR_push_descriptor to avoid descriptor set allocation overhead for frequently updated resources

Dynamic Rendering

VK_KHR_dynamic_rendering eliminates render pass pre-creation and enables more flexible rendering

Extended Dynamic State

VK_EXT_extended_dynamic_state reduces pipeline state object (PSO) permutations

Command Buffer Pooling

Reuses command buffers across frames to minimize allocation overhead

Memory Suballocation

Buddy allocator reduces memory fragmentation and minimizes allocation calls

Descriptor Templates

Uses VK_KHR_descriptor_update_template for faster bulk descriptor updates

Debugging

Validation Layers

References

Source Files

  • src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
  • src/Ryujinx.Graphics.Vulkan/PipelineBase.cs
  • src/Ryujinx.Graphics.Vulkan/PipelineFull.cs
  • src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs
  • src/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs