MVGAL Architecture

Version: 0.7.3 | Last Updated: August 2026


Overview

MVGAL (Multi-Vendor GPU Aggregation Layer for Linux) is an eight-layer system that presents two or more heterogeneous GPUs from different vendors as a single logical device to all applications without requiring application changes.

┌──────────────────────────────────────────────────────────────────┐
│                        Applications                              │
│          (Games, Blender, PyTorch, OpenCL programs)              │
├──────────────────────────────────────────────────────────────────┤
│                Layer 8: Tooling & Bindings                        │
│  CLI (mvgal-info/status/bench) · Qt Dashboard · REST API ·      │
│  Steam Frame Pacer · Language Bindings (Java, C#, D, Nim, V,    │
│  Crystal, Haxe)                                                  │
├──────────────────────────────────────────────────────────────────┤
│                Layer 7: API Interception                          │
│  VK_LAYER_MVGAL · libmvgal_opencl.so · libmvgal_cuda.so ·       │
│  libmvgal_gl.so (OpenGL LD_PRELOAD) · D3D9/11/12 shims ·        │
│  Metal shim · WebGPU shim · SPIR-V Routing                       │
├──────────────────────────────────────────────────────────────────┤
│                Layer 6: Safety Subsystems (Rust)                  │
│  fence_manager · memory_safety · capability_model                │
│  Memory-safe FFI boundary between C/C++ and Rust                 │
├──────────────────────────────────────────────────────────────────┤
│          Layer 5: Work Distribution Engine (WDE)                  │
│  7+3 Scheduling Strategies · Memory Heap Hierarchy               │
│  (Heaps 0-4) · Workload Analysis → Strategy Selection            │
│  RLD (Render Layer Dist.) · REP (Replication) · PPL (Pipeline)   │
├──────────────────────────────────────────────────────────────────┤
│          Layer 4: Intermediate Framing Layer (IMFL)               │
│  Frame Sessions · Cross-GPU Migration Plans · Steam Profiles   │
│  Execution Context Lifecycle · Migration Path Selection           │
├──────────────────────────────────────────────────────────────────┤
│                Layer 3: Runtime Daemon (mvgald)                   │
│  Scheduler · MemoryManager · PowerManager · MetricsCollector ·   │
│  IpcServer · DeviceRegistry · D-Bus API · Daemon State Machine   │
├──────────────────────────────────────────────────────────────────┤
│          Layer 2: Vendor GPU Driver Dispatch (VGDD)               │
│  struct mvgal_vendor_ops · amdgpu / nvidia / intel / mtt        │
│  Per-vendor command submission · VRAM alloc · power mgmt         │
│  DMA-BUF export/import · PCIe P2P · Utilization query            │
├──────────────────────────────────────────────────────────────────┤
│          Layer 1: Hardware Abstraction Layer (HAL)                │
│  mvgal.ko (char dev → DRM migration path) · PCI enumeration ·   │
│  GPU topology · IOCTL interface · NTSYNC · Cross-GPU DMA-BUF    │
│  /dev/mvgal0 · sysfs interface                                   │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│   ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐       │
│   │ amdgpu.ko│  │nvidia.ko │  │i915/xe.ko│  │mtgpu-drv │       │
│   │  (AMD)   │  │ (NVIDIA) │  │ (Intel)  │  │  (MTT)   │       │
│   └──────────┘  └──────────┘  └──────────┘  └──────────┘       │
│                    Vendor Kernel Drivers                          │
└──────────────────────────────────────────────────────────────────┘

Layer Summary

Layer Name Abbr. Source Language
1 Hardware Abstraction Layer HAL kernel/ C (GPL-2.0)
2 Vendor GPU Driver Dispatch VGDD kernel/vendors/ C (GPL-2.0)
3 Runtime Daemon Runtime runtime/daemon/ C++20
4 Intermediate Framing Layer IMFL src/userspace/execution/ C17
5 Work Distribution Engine WDE src/userspace/scheduler/ C17
6 Safety Subsystems Safety safe/ Rust
7 API Interception Intercept src/userspace/intercept/ + opengl/ C17
8 Tooling & Bindings Tooling tools/ + steam/ + ui/ + bindings/ C17, Go, Qt

Interface Contracts

Boundary Mechanism Protocol/Format
HAL → VGDD Function pointer table struct mvgal_vendor_ops
HAL → Runtime IOCTL mvgal_uapi.h (10 ioctls)
VGDD → Vendor kdbs Linux kernel API DRM, DMA-BUF, PCI subsystem
Runtime → IMFL/WDE Unix socket IPC MVGAL IPC binary protocol
IMFL → WDE Internal function calls execution_plan.h / scheduler.h
Runtime → Safety C FFI (extern "C") mvgal_fence_, mvgal_mem_, mvgal_cap_*
Intercept → IMFL C function calls mvgal_execution_* API
Tooling → Runtime IPC (socket) or REST MVGAL IPC or HTTP :7474

Layer 1 — Hardware Abstraction Layer (HAL)

Source: kernel/ (9 source files) License: GPL-2.0-only Device node: /dev/mvgal0 (char dev, Phase 1) → future DRM driver (Phase 2)

Responsibilities

Module Parameters

Parameter Type Default Description
enable_debug bool false Enable verbose kernel log output
max_devices uint 8 Maximum number of GPUs supported

IOCTL Interface

Defined in include/mvgal/mvgal_uapi.h:

IOCTL Direction Description
MVGAL_IOCTL_QUERY_DEVICES Read Number and descriptors of detected GPUs
MVGAL_IOCTL_QUERY_CAPABILITIES Read Aggregate capability profile
MVGAL_IOCTL_SUBMIT_WORKLOAD Write Submit a workload to the scheduler
MVGAL_IOCTL_ALLOC_MEMORY Read/Write Allocate unified virtual memory
MVGAL_IOCTL_FREE_MEMORY Write Free a unified memory allocation
MVGAL_IOCTL_IMPORT_DMABUF Write Import a DMA-BUF file descriptor
MVGAL_IOCTL_EXPORT_DMABUF Read Export a buffer as DMA-BUF
MVGAL_IOCTL_WAIT_FENCE Write Wait for a fence to be signaled
MVGAL_IOCTL_SIGNAL_FENCE Write Signal a fence
MVGAL_IOCTL_SET_GPU_AFFINITY Write Pin a context to specific GPUs

Kernel Source Files

File Purpose
mvgal_main.c Module init/exit, PCI scan, char dev registration
mvgal_ioctl.c IOCTL dispatch table (10 handlers)
mvgal_dma_buf.c Cross-GPU DMA-BUF export/import implementation
mvgal_fence.c Fence and timeline sync primitives
mvgal_memory.c Kernel-side memory management (GEM/buffer objects)
mvgal_sched.c Kernel-side workload queue (16 priority levels)
mvgal_sysfs.c Sysfs interface for GPU metrics
mvgal_ntsync.c NTSYNC Windows-compatible sync primitives
mvgal_p2p.c PCIe P2P DMA setup and teardown

Char Dev → DRM Driver Migration Path

The current HAL uses a character device (/dev/mvgal0) for Phase 1. A full DRM driver is planned:

Phase Approach Status
Phase 1 (current) alloc_chrdev_region + cdev_add ✅ Implemented
Phase 2 drm_driver registration as minor DRM subsystem 🔄 Planned
Phase 2 goals DRM sync object support, DRM scheduler integration, GEM object lifecycle, drm_gem_prime_export/import 🔄 Planned
Rationale Char dev avoids claiming PCI devices from vendor drivers; DRM path enables native compositor integration

Migration does not replace vendor DRM drivers (amdgpu.ko, nvidia.ko, etc.). MVGAL remains an above-driver coordinator.


Layer 2 — Vendor GPU Driver Dispatch (VGDD)

Source: kernel/vendors/ License: GPL-2.0-only

Responsibilities

Each vendor implements the same struct mvgal_vendor_ops interface to abstract away vendor-specific GPU driver interactions.

Vendor Operations

struct mvgal_vendor_ops {
    int  (*init)(struct mvgal_gpu_device *dev);
    void (*fini)(struct mvgal_gpu_device *dev);
    int  (*submit_cs)(struct mvgal_gpu_device *dev, struct mvgal_workload *wl);
    int  (*alloc_vram)(struct mvgal_gpu_device *dev, size_t size, uint64_t *addr);
    void (*free_vram)(struct mvgal_gpu_device *dev, uint64_t addr);
    int  (*wait_idle)(struct mvgal_gpu_device *dev, uint32_t timeout_ms);
    int  (*set_power_state)(struct mvgal_gpu_device *dev, enum mvgal_power_state);
    struct dma_buf *(*export_dmabuf)(struct mvgal_gpu_device *dev, uint64_t addr, size_t size);
    int  (*import_dmabuf)(struct mvgal_gpu_device *dev, struct dma_buf *buf, uint64_t *addr);
    int  (*query_utilization)(struct mvgal_gpu_device *dev, uint32_t *util_percent);
};

Vendor Implementations

File Vendor Driver Interfaces
mvgal_amd.c AMD amdgpu.ko via DRM prime + sysfs
mvgal_nvidia.c NVIDIA nvidia.ko / nvidia-open.ko via procfs + DMA-BUF
mvgal_intel.c Intel i915.ko / xe.ko via DRM prime
mvgal_mtt.c Moore Threads mtgpu-drv.ko via vendor API (experimental)

Design Decisions

No pci_register_driver: MVGAL must not claim PCI devices away from vendor drivers. Using pci_get_device in a scan loop allows MVGAL to observe all GPUs without interfering with their existing drivers.

Vendor ops as function pointers: Allows compile-time selection of supported vendors and clean degradation when a vendor module is absent.


Layer 3 — Runtime Daemon (mvgald)

Source: runtime/daemon/ (C++20) Socket: /run/mvgal/mvgal.sock PID file: /run/mvgal/mvgald.pid D-Bus: org.mvgal.daemon

Responsibilities

Central coordination point for all MVGAL operations. Runs as a systemd service, manages GPU state, handles client IPC, and exposes telemetry.

Subsystems

DeviceRegistry (device_registry.cpp)

Enumerates GPUs via /sys/class/drm/cardN/device/ and PCI bus scan. Normalizes vendor-specific metadata into GpuDevice objects with:

Scheduler (scheduler.cpp)

Three scheduling modes:

Priority queue with 16 levels. Work-stealing when one GPU's queue depth exceeds threshold.

MemoryManager (memory_manager.cpp)

Coordinates cross-GPU memory allocation. Tracks allocations per GPU, implements DMA-BUF transfer path, PCIe P2P fallback, and host-RAM staging.

PowerManager (power_manager.cpp)

Power state machine:

ACTIVE → SUSTAINED → IDLE → PARK

Configurable timeouts:

DVFS: adjusts GPU clock based on utilization. Thermal throttling at configurable threshold (default: 85°C).

MetricsCollector (metrics_collector.cpp)

Polls sysfs at configurable interval (default: 1000 ms). Collects:

Exposes telemetry subscription API for clients.

IpcServer (ipc_server.cpp)

Unix domain socket server. Binary message format:

┌──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐
│  magic   │ version  │  type    │ reqId    │ payloadSz│  flags   │ reserved │
│ 'MVGL'   │    1     │ uint32   │ uint32   │ uint32   │ uint32   │ uint32   │
│ 4 bytes  │ 4 bytes  │ 4 bytes  │ 4 bytes  │ 4 bytes  │ 4 bytes  │ 4 bytes  │
└──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘

Message types: HELLO, GOODBYE, QUERY_DEVICES, QUERY_DEVICE_CAPABILITIES, QUERY_UNIFIED_CAPABILITIES, ALLOC_MEMORY, FREE_MEMORY, IMPORT_DMABUF, EXPORT_DMABUF, SUBMIT_WORKLOAD, WAIT_WORKLOAD, SET_SCHEDULING_MODE, SET_GPU_PRIORITY, SET_GPU_ENABLED, GET_STATISTICS, SUBSCRIBE_TELEMETRY, UNSUBSCRIBE_TELEMETRY, GET_CONFIG, SET_CONFIG, LOAD_CONFIG, SAVE_CONFIG, ERROR.

Authentication: SCM_CREDENTIALS — only video group members or root may submit workloads.

D-Bus API (org.mvgal.daemon)

Interface Method Description
org.mvgal.GPUManager ListGPUs Returns array of GPU device paths
org.mvgal.GPUManager GetGPUStats(path) Returns utilization, temp, power
org.mvgal.Scheduler GetStrategy Returns current scheduling strategy
org.mvgal.Scheduler SetStrategy(string) Sets scheduling strategy
org.mvgal.Scheduler GetGPUPriorities Returns per-GPU priority levels
org.mvgal.Power GetPowerState(path) Returns current power state of a GPU
org.mvgal.Power SetPowerState(path, string) Manually set power state
org.mvgal.Config GetConfig Returns full daemon configuration
org.mvgal.Config SetConfig(string, variant) Set a configuration value

Layer 4 — Intermediate Framing Layer (IMFL)

Source: src/userspace/execution/ (C17) Header: include/mvgal/execution.h

Responsibilities

Translates intercepted API calls into scheduler workloads. Manages frame sessions (begin → submit → present lifecycle), generates cross-GPU migration plans, and produces Steam/Proton scheduling profiles.

Execution Context Lifecycle

mvgal_execution_begin_frame()   → allocates frame_id, records API/strategy/app
mvgal_execution_submit()        → creates execution plan, selects GPUs, chooses migration path
mvgal_execution_present()       → finalizes frame, triggers frame pacer if needed
mvgal_execution_get_frame_stats() → returns timing, GPU list, bytes migrated

Migration Path Selection

1. DMA-BUF zero-copy   (MVGAL_EXECUTION_MIGRATION_STREAM)
2. PCIe P2P            (MVGAL_EXECUTION_MIGRATION_STREAM with P2P)
3. Host-RAM staging    (MVGAL_EXECUTION_MIGRATION_EVICT)
4. Mirror/replicate    (MVGAL_EXECUTION_MIGRATION_MIRROR)

Frame Session Data

Field Type Description
frame_id uint64_t Monotonically increasing frame identifier
api enum mvgal_api Originating API (Vulkan, OpenCL, CUDA, etc.)
strategy enum mvgal_strategy Scheduling strategy assigned to this frame
gpu_mask uint32_t Bitmask of GPUs selected for this frame
migration_path enum mvgal_migration Selected migration path (stream/P2P/evict/mirror)
bytes_migrated uint64_t Total bytes transferred for this frame
start_ns uint64_t Frame start timestamp (CLOCK_MONOTONIC)
end_ns uint64_t Frame end timestamp

Layer 5 — Work Distribution Engine (WDE)

Source: src/userspace/scheduler/ + src/userspace/memory/ (C17) Headers: include/mvgal/scheduler.h, include/mvgal/memory.h

Responsibilities

Selects the optimal work distribution strategy per workload, manages memory allocation across the GPU memory hierarchy, and implements 10 scheduling strategies (7 existing + 3 new).

Scheduling Strategies

Existing Strategies (7)

Strategy Enum Description
Round-robin MVGAL_STRATEGY_ROUND_ROBIN Even distribution across all GPUs
AFR MVGAL_STRATEGY_AFR Even frames → GPU 0, odd frames → GPU 1
SFR MVGAL_STRATEGY_SFR Screen split horizontally or vertically
Task-based MVGAL_STRATEGY_TASK Route by workload type (graphics vs compute)
Compute offload MVGAL_STRATEGY_COMPUTE_OFFLOAD Route compute to highest-FLOPS GPU
Hybrid MVGAL_STRATEGY_HYBRID Adaptive — selects best strategy per workload
Single GPU MVGAL_STRATEGY_SINGLE_GPU Use only the primary GPU

New Strategies (3)

Strategy Abbr. Enum Description
Render Layer Distribution RLD MVGAL_STRATEGY_RLD Distribute render layers (e.g., UI, world, post-fx) across different GPUs based on layer affinity. Best for complex scenes with separable rendering passes.
Replication Mode REP MVGAL_STRATEGY_REPLICATION Replicate identical work across GPUs for comparison/redundancy. Useful for scientific computing validation and fault-tolerant rendering.
Pipeline Parallelism PPL MVGAL_STRATEGY_PIPELINE_PARALLELISM Split a pipeline across GPUs (GPU 0 → pre-process, GPU N → post-process). Best for streaming workloads and media encoding pipelines.

Strategy Selection Criteria

Workload Type Recommended Strategy Rationale
Gaming (fast-paced) AFR, SFR Minimizes frame latency, even GPU utilization
Gaming (complex scenes) RLD Separates rendering layers across GPUs
AI Training Compute offload, PPL Maximizes throughput via batch sharding
AI Inference Round-robin, Task-based Even load distribution
Media encoding PPL Pipeline stages across GPUs
Scientific computing REP Cross-verification of results
Mixed workloads Hybrid Adaptive strategy selection

Memory Heap Hierarchy (Heaps 0–4)

The WDE manages memory across a 5-tier heap hierarchy, each with distinct performance/latency characteristics:

Heap Name Location Access Latency Capacity Best For
Heap 0 GPU VRAM (local) On each GPU die ~1–10 µs GB–tens of GB Active rendering, compute working set
Heap 1 GPU VRAM (peer) On other GPUs via PCIe ~5–50 µs GB–tens of GB Shared data, read-only textures
Heap 2 Host RAM (NIC-attached) System RAM, NUMA-local ~100–500 ns GB–hundreds of GB Staging, fallback allocations
Heap 3 Host RAM (remote) System RAM, non-local NUMA ~200–1000 ns GB–hundreds of GB Cold data, persistent storage
Heap 4 SSD/Storage NVMe / block device swap ~10–100 µs TB Memory oversubscription, checkpoint

Allocation Policy:

Request size < 64 MB  →  Heap 0 (GPU with most free VRAM)
Render target         →  Heap 0 (GPU that will write first, from workload history)
Large buffer (>1 GB)  →  Heap 2 (host RAM staging) + stream to Heap 0 as needed
Read-only textures    →  Heap 1 (replicate to peer GPU VRAM)
Cold data             →  Heap 3 (remote NUMA) or Heap 4 (SSD swap)

Layer 6 — Safety Subsystems (Rust)

Source: safe/ (3 Rust crates, edition 2021, MSRV 1.75) License: MIT OR Apache-2.0

Responsibilities

Memory-safe implementations of critical subsystems that require rigorous lifetime tracking. Each crate exposes a C FFI interface with #[no_mangle] extern "C" functions.

fence_manager (~248 LOC)

Cross-device fence lifecycle management.

State machine: Pending → Submitted → Signalled → Reset

uint64_t mvgal_fence_create(uint32_t gpu_index);
void     mvgal_fence_submit(uint64_t handle);
void     mvgal_fence_signal(uint64_t handle);
uint32_t mvgal_fence_state(uint64_t handle);   // 0=Pending 1=Submitted 2=Signalled 3=Reset
void     mvgal_fence_reset(uint64_t handle);
void     mvgal_fence_destroy(uint64_t handle);

C FFI:

memory_safety (~230 LOC)

Safe wrappers for cross-GPU memory allocation tracking with reference counting.

Placements: SystemRam, GpuVram, Mirrored

uint64_t mvgal_mem_track(uint64_t size, uint32_t placement);
void     mvgal_mem_retain(uint64_t handle);
void     mvgal_mem_release(uint64_t handle);
void     mvgal_mem_set_dmabuf(uint64_t handle, int32_t fd);
uint64_t mvgal_mem_size(uint64_t handle);
uint32_t mvgal_mem_placement(uint64_t handle);
uint64_t mvgal_mem_total_system_bytes(void);
uint64_t mvgal_mem_total_gpu_bytes(void);

C FFI:

capability_model (~260 LOC)

GPU capability normalization, aggregate profile computation, and JSON serialization.

Tiers: Full (all GPUs same API set), ComputeOnly, Mixed

uint64_t    mvgal_cap_compute(const GpuCapability *caps, uint32_t count);
void        mvgal_cap_free(uint64_t handle);
uint64_t    mvgal_cap_total_vram(uint64_t handle);
uint32_t    mvgal_cap_tier(uint64_t handle);
const char *mvgal_cap_to_json(uint64_t handle);

C FFI:

Rust/C++ FFI Boundary

The FFI boundary between Rust safety crates (Layer 6) and the C++ daemon (Layer 3) is defined as follows:

┌──────────────────────────────────────────────────────────┐
│                   C++ Daemon (mvgald)                    │
│  #include "fence_manager.h"  // C FFI declarations       │
│  #include "memory_safety.h"  // C FFI declarations       │
│  #include "capability_model.h"  // C FFI declarations    │
├──────────────────────────────────────────────────────────┤
│                    extern "C" {                           │
│  mvgal_fence_create()  →  fence_manager::Fence::new()    │
│  mvgal_mem_track()     →  memory_safety::TrackedAlloc    │
│  mvgal_cap_compute()   →  capability_model::compute()    │
│                    }                                      │
├──────────────────────────────────────────────────────────┤
│                Rust Crates (safe/)                        │
│  fence_manager   →  #[no_mangle] extern "C" fn ...       │
│  memory_safety   →  #[no_mangle] extern "C" fn ...       │
│  capability_model  →  #[no_mangle] extern "C" fn ...     │
└──────────────────────────────────────────────────────────┘

Rules:


Layer 7 — API Interception

Source: src/userspace/intercept/ + opengl/ (C17)

Responsibilities

Intercepts application API calls transparently and routes them through the MVGAL pipeline without application modification.

Vulkan Layer (src/userspace/intercept/vulkan/)

VK_LAYER_MVGAL is a Vulkan explicit layer registered via /usr/share/vulkan/implicit_layer.d/VK_LAYER_MVGAL.json.

Uses the Vulkan loader dispatch-chain pattern. Each intercepted function looks up the next function pointer via vkGetInstanceProcAddr / vkGetDeviceProcAddr.

Intercepted functions:

Global state (g_mvgal_layer_state): linked lists of instance, device, queue, and physical device dispatch tables. Protected by pthread_mutex_t. Atomic submit counter.

MVGAL VkPhysicalDevice extensions:

Debug: MVGAL_VULKAN_DEBUG=1 enables logging. MVGAL_VULKAN_LOG_PATH=<path> redirects to file.

OpenCL Layer (src/userspace/intercept/opencl/)

LD_PRELOAD-based interception. Presents all GPUs as a single MVGAL OpenCL platform. NDRange kernels are partitioned across GPUs by splitting the global work size.

Registered via /etc/OpenCL/vendors/mvgal.icd.

CUDA Shim (src/userspace/intercept/cuda/)

LD_PRELOAD-based interception of 40+ CUDA Driver and Runtime API functions. Intercepts:

Direct3D Shims (src/userspace/intercept/d3d/)

Shim Targets Approach
D3D9 Direct3D 9 games DXVK bridge → Vulkan layer
D3D11 Direct3D 11 applications DXVK bridge → Vulkan layer
D3D12 Direct3D 12 applications VKD3D-Proton bridge → Vulkan layer

All D3D shims intercept CreateDXGIFactory, CreateDirect3D11Device, CreateDirect3D12Device* and inject MVGAL into the DXVK/VKD3D-Proton pipeline.

Metal Shim (src/userspace/intercept/metal/)

Interposes MTLCreateSystemDefaultDevice and MTLCopyAllDevices via DYLD_INSERT_LIBRARIES. Routes Metal command buffers through MVGAL scheduling. Note: Metal interception is macOS-only (future).

WebGPU Shim (src/userspace/intercept/webgpu/)

Intercepts wgpuCreateInstance, WGPUAdapter enumeration. Proxies WebGPU workloads to MVGAL for browser-based compute and ML workloads.

SPIR-V Routing (src/userspace/intercept/spirv/)

Inspects SPIR-V shader modules at pipeline creation time. Routes compute shaders identified as AI/ML kernels to the Compute Offload scheduler. Enables cross-vendor SPIR-V capability probing.

OpenGL Preload (opengl/mvgal_gl_preload.c)

LD_PRELOAD shim intercepting glXSwapBuffers and eglSwapBuffers. Injects frame pacing telemetry. Actual OpenGL→Vulkan translation is handled by Zink (Mesa).


Layer 8 — Tooling & Bindings

CLI Tools (tools/)

Tool Key Functions Language
mvgal-info enumerate_drm_gpus(), reads /sys/class/drm/cardN/device/, JSON output C
mvgal-status discover_gpus(), refresh_gpu_status(), ANSI progress bars, daemon socket check C
mvgal-bench bench_memory_bandwidth(), bench_compute(), bench_scheduling_latency(), bench_sync_overhead() C
mvgal-compat check_system(), check_app(), 15+ app database, system readiness scoring C
mvgal-config list_gpus(), set_strategy(), set_gpu_enabled(), show_stats() C
mvgal-powercurve Per-GPU power curve tuning, DVFS override, thermal threshold config C

Qt Dashboard (ui/)

REST API

Endpoint Method Description
GET /api/v1/gpus Read All GPU metrics
GET /api/v1/gpus/{id} Read Single GPU
GET /api/v1/scheduler Read Current mode and GPU count
PUT /api/v1/scheduler Write Set scheduling strategy
GET /api/v1/stats Read Aggregate stats (total VRAM, avg utilization, daemon status)
GET /api/v1/logs Read Last 100 lines of daemon log

Steam Integration (steam/)

Environment Variable Values Description
ENABLE_MVGAL 0 / 1 Enable MVGAL for this launch
MVGAL_STRATEGY afr, sfr, hybrid, single, rld, ppl Scheduling strategy
MVGAL_FRAME_PACING 0 / 1 Enable vsync-aligned frame pacing
MVGAL_GPU_MASK hex bitmask Which GPUs to use (e.g. 0x3 = GPU 0+1)
MVGAL_VULKAN_DEBUG 0 / 1 Enable Vulkan layer debug logging

Language Bindings (bindings/)

Language Directory Status
Java bindings/java/ JNI wrappers around C API
C# bindings/csharp/ P/Invoke bindings
D bindings/d/ D import bindings
Nim bindings/nim/ Nim wrapper
V bindings/v/ V bindings
Crystal bindings/crystal/ Crystal FFI wrappers
Haxe bindings/haxe/ Haxe extern bindings

Data Flow: Gaming Workload (AFR)

Game (via Proton/DXVK)
  │
  │ vkQueueSubmit (frame N)
  ▼
VK_LAYER_MVGAL (Layer 7 — Intercept)
  │ intercepts submit, increments atomic counter, logs telemetry
  │ forwards to next layer in dispatch chain
  ▼
Physical ICD (AMD / NVIDIA / Intel)
  │
  │ (parallel) mvgald AFR scheduler
  │   ├─ Frame N   → GPU 0  (even)
  │   └─ Frame N+1 → GPU 1  (odd)
  ▼
Frame pacer (steam/mvgal_frame_pacer.c) [Layer 8 — Tooling]
  │ ring buffer depth 8, background thread
  │ sleep_until_ns(next_vsync_boundary)
  ▼
vkQueuePresentKHR on display-connected GPU

Data Flow: AI Compute Workload

PyTorch / TensorFlow
  │
  │ CUDA kernel launch (cudaLaunchKernel)
  ▼
MVGAL CUDA shim (Layer 7 — Intercept, LD_PRELOAD)
  │ intercepts, translates to MVGAL workload submission
  ▼
mvgald Compute Offload scheduler (Layer 3 — Runtime)
  │ shards batch dimension across N GPUs
  │ allocates input tensors via unified memory manager
  │ issues DMA-BUF transfers for cross-GPU data
  ▼
GPU 0 … GPU N-1 (parallel execution)
  │
  │ results collected via write-combined system
  ▼
Application receives aggregated result

Data Flow: Render Layer Distribution (RLD)

Game with separable UI / world / post-fx layers
  │
  │ vkQueueSubmit (multiple command buffers per frame)
  ▼
VK_LAYER_MVGAL (Layer 7 — Intercept)
  │ identifies layer boundaries from render passes
  ▼
WDE RLD strategy (Layer 5)
  │   ├─ UI layer       → GPU 0 (simple, latency-sensitive)
  │   ├─ World layer    → GPU 1 (complex geometry, high FLOPS)
  │   └─ Post-FX layer  → GPU 2 (compute-heavy, low VRAM need)
  ▼
IMFL (Layer 4) produces composite plan
  │ DMA-BUF transfer for final composite
  ▼
Display-connected GPU presents final frame

Memory Architecture

Allocation Policy

Request size < 64 MB          → Heap 0 (GPU local VRAM)
Render target                 → Heap 0 (write GPU)
Read-only texture             → Heap 1 (replicate to peers)
Large buffer >1 GB            → Heap 2 (host staging → stream to Heap 0)
Persistent/cold data          → Heap 3 (remote NUMA)
Memory oversubscription       → Heap 4 (SSD swap)

Transfer Path

Source GPU export
  │
  ├─ DMA-BUF viable?  →  dma_buf_map_attachment (zero-copy, kernel-supported)
  │
  └─ DMA-BUF not viable
       │
       ├─ PCIe P2P viable?  →  pci_p2pdma (requires same root complex, kernel 5.10+)
       │
       └─ Fallback  →  mmap source + DMA to host staging buffer + upload to dest GPU

Memory Flags

Flag Value Description
HOST_VALID 1<<0 CPU can access (mapped)
GPU_VALID 1<<1 GPUs can access
CPU_CACHED 1<<2 CPU cached
CPU_UNCACHED 1<<3 CPU uncached (write-combined)
SHARED 1<<4 Shared across GPUs
DMA_BUF 1<<5 Use DMA-BUF
P2P 1<<6 Enable P2P transfers
REPLICATED 1<<7 Mirror across all GPUs
PERSISTENT 1<<8 Persistent CPU mapping
LAZY_ALLOCATE 1<<9 Defer physical allocation
ZERO_INITIALIZED 1<<10 Zero on allocation

Key Design Decisions

Decision Rationale
Character device instead of DRM driver (Phase 1) Avoids claiming PCI devices from vendor drivers; simpler to maintain across kernel versions
DRM driver (Phase 2) Planned migration for native compositor integration, DRM sync objects, and GEM lifecycle
Vulkan layer instead of full ICD (Phase 1) Allows transparent interception without application changes; full ICD planned for Phase 5
8-layer architecture Separates HAL (kernel) from VGDD (vendor dispatch), distinguishes IMFL (framing) from WDE (strategy), elevates Rust safety to its own layer
Rust for safety-critical paths Eliminates memory safety bugs in fence/memory tracking; C FFI boundary provides clean interop
C17 for userspace, C++20 for daemon C17 maximizes compatibility with GPU driver headers; C++20 provides modern abstractions for daemon
Unix socket IPC with SCM_CREDENTIALS Zero-dependency authentication; no D-Bus or systemd dependency required for core IPC
D-Bus as optional management interface Standard Linux desktop integration for monitoring tools and session services
DMA-BUF for cross-GPU transfers Kernel-supported zero-copy path; works across all vendor drivers that support it
Sysfs polling for GPU metrics No vendor-specific SDK required; works on all supported vendors
pkexec for all privileged operations Policy-compliant privilege escalation; no sudo dependency
5-tier memory heap hierarchy Matches real hardware topology (local VRAM, peer VRAM, NUMA host RAM, remote RAM, SSD)
10 scheduling strategies (7+3) Covers all known workload patterns; RLD/REP/PPL address gaps from original 7 strategies
Language bindings for 7 languages Maximizes accessibility for developers in different ecosystems with zero additional runtime cost