High-performance single-app fullscreen Wayland compositor for gaming and robotics.
- Direct scanout — Zero-copy, zero-GPU presentation when possible (DRM backend)
- Zero-copy DMA-BUF forwarding — Forward client buffers to host compositor without GPU work (Wayland backend)
- Vulkan compute compositor — Fast shader-based composition when overlays or scaling are needed
- Aspect-preserving letterboxing — Subsurface architecture with automatic pillarbox/letterbox
- XWayland — Full X11 application support with per-server XWM threads
- VRR support — Variable refresh rate for compatible displays
- Wayland backend — Run inside another Wayland compositor for development/testing
- Hardware cursor — DRM cursor plane with dumb buffer, position updates independent of primary plane flip
- Pointer lock & constraints —
zwp_pointer_constraints_v1/zwp_relative_pointer_v1for FPS games and pointer-locked UIs - libinput — DPI-normalized unaccelerated pointer deltas with configurable sensitivity, automatic device hotplug
- Multi-XWayland — Multiple XWayland servers with independent focus tracking and lifecycle management
- Focus gating — 4-phase cross-server focus arbitration (baselayer → stealer → retention → fallback). Only the focused server's clients receive frame callbacks — zero GPU waste on unfocused servers.
- Baselayer control —
GAMESCOPECTRL_BASELAYER_APPIDX11 atom for cross-server focus pinning - Frame pacing — Adaptive VBlank scheduling with rolling peak draw-time tracking, compositing floor, and FPS limiting
- Headless mode — Offscreen rendering for CI and robotics pipelines
High-level feature goals for Gamecomp. No hard dates — contributions welcome.
- DRM/KMS backend with atomic modesetting
- Headless backend for CI and robotics
- Wayland backend (run inside another Wayland compositor)
- Direct scanout (zero-copy presentation)
- Zero-copy DMA-BUF forwarding in wayland backend
- Host format/modifier passthrough for optimal buffer allocation
- Aspect-preserving letterboxing via subsurface architecture
- Vulkan blit fallback for unsupported modifiers
- DMA-BUF import and format negotiation
- Configuration via CLI args + TOML file
- SPIR-V shader compilation at build time
- Vulkan compute shader composition (blit.comp + VulkanBlitter pipeline)
- Session switching — VT switch handling via libseat (Ctrl+Alt+Fn, pause/resume, fd revocation)
- Keyboard monitor — raw evdev with udev hotplug, modifier tracking, connect/disconnect support
- Pointer monitor — libinput with udev hotplug, DPI-normalized unaccelerated deltas, configurable sensitivity
- GBM-backed output buffer allocation (native GEM handles, no PRIME corruption)
- Async DMA-BUF implicit sync (non-blocking poll before blit)
- Input routing — keyboard, pointer, scroll forwarding to focused client (DRM evdev + nested host passthrough)
- Cursor passthrough — client cursor images forwarded to host compositor via SHM
- XKB keymap and modifier forwarding from host to clients (nested mode)
- Multi-XWayland server lifecycle — spawn, monitor, respawn with per-server XWM threads
- Focus gating — 4-phase cross-server focus arbitration with per-surface commit gating
- Baselayer focus control —
GAMESCOPECTRL_BASELAYER_APPIDatom for cross-server focus pinning - Adaptive frame pacing — rolling peak draw-time, compositing floor, VRR mode, FPS limiting
- XWayland window management — XWM with property monitoring, window classification, per-server window tracking
- Runtime resolution control —
GAMESCOPE_XWAYLAND_MODE_CONTROLatom for per-server resolution switching - PID-based AppID resolution —
steam_modewalks parent process chain for Steam reaper (SteamLaunch AppId=N) - Commit-based presentation gating — old content stays visible until new focus target commits a frame
- Gamescope atom compatibility — full
GAMESCOPE_*/GAMESCOPECTRL_*atom set for ecosystem tool compatibility - Hardware cursor — DRM cursor plane via dumb buffer, independent atomic commits for position updates
- Pointer lock / constraints —
zwp_pointer_constraints_v1(lock + confine) andzwp_relative_pointer_v1 - Window fill-on-map — XWayland windows configured to fill output on map and resize (no blurry upscale)
- VRR (variable refresh rate) — frame pacer support exists, needs per-connector toggle
- Multi-plane assignment — overlay plane offload to reduce GPU work (cursor plane done)
- Multi-display — span or mirror across multiple connected outputs (multi-XWayland spawning done, display routing in progress)
- Overlay composition — Steam Overlay and external overlay rendering (window classification exists, composition layer not wired up)
- Fullscreen handling —
_NET_WM_STATE_FULLSCREENatom support (atom interned, handler not implemented) - HDR — HDR10 metadata passthrough, PQ tone mapping (feature-gated:
hdr) - FSR upscaling — AMD FidelityFX Super Resolution via compute shader (
fsr) - NIS upscaling — NVIDIA Image Scaling via compute shader (
nis) - CAS sharpening — Contrast Adaptive Sharpening post-process
- PipeWire screen capture — zero-copy DMA-BUF stream for recording/streaming (
pipewire) - Tracy profiling — per-frame instrumentation (
profile-with-tracy) - Gamepad input — evdev gamepad passthrough to client
- Color management — ICC/LUT loading, color-blind filters
- Touch input — touchscreen support for handheld devices
cargo build --releaseRequires Rust stable (edition 2024) and the following system dependencies:
libdrm,libgbm— DRM/KMS supportlibinput,libudev— Input handling and device managementlibseat— Session managementlibwayland— Wayland protocolvulkan-loader— Vulkan runtime
# Run a game fullscreen on DRM
gamecomp -- my-game
# Run nested inside your desktop
gamecomp --nested -- my-game
# Headless mode for CI
gamecomp --backend headless -- my-app
# 2 XWayland servers (focus gating + baselayer control)
gamecomp --xwayland-count 2 -- steam
# Baselayer pinning (pin focus to a specific server's app)
# Set GAMESCOPECTRL_BASELAYER_APPID on a server's root window to pin focus
# Multiple XWayland servers (server 0 = platform, 1+ = game)
gamecomp --xwayland-count 2 -- my-game| Flag | Description |
|---|---|
-n, --nested |
Run inside another Wayland compositor (alias: --wayland) |
--backend headless |
Offscreen rendering for CI |
-W, --output-width |
Output width in pixels |
-H, --output-height |
Output height in pixels |
-w, --nested-width |
Game render width (client-side resolution) |
-h, --nested-height |
Game render height (client-side resolution) |
-r, --refresh-rate |
Refresh rate in Hz |
-o, --output |
Preferred output connector (e.g., eDP-1) |
--xwayland-count N |
Number of XWayland servers to spawn (default: 1). Sets STEAM_GAME_DISPLAY_N env vars for child processes. |
--vrr / --no-vrr |
Enable/disable variable refresh rate |
--hdr / --no-hdr |
Enable/disable HDR |
--upscale MODE |
Upscaling algorithm: fsr, nis, cas, or none |
--fps-limit N |
FPS cap (0 = match display refresh rate) |
--stats-pipe PATH |
Write per-frame stats to a named pipe |
--sensitivity N |
Pointer sensitivity multiplier (default: 1.0, libinput-normalized) |
-e, --steam |
Enable Steam mode (PID-based AppID resolution) |
--log LEVEL |
Log level (trace, debug, info, warn, error) |
Create ~/.config/gamecomp/config.toml:
vrr = true
hdr = false
upscale = "none" # or "fsr", "nis", "cas"
pointer_sensitivity = 1.0 # 1.0 = 1:1 libinput-normalized, higher = faster- Architecture — Module map, thread model, design decisions
- Wayland Backend — Zero-copy DMA-BUF forwarding, subsurface letterboxing, host format passthrough
Portions of this codebase were generated with the assistance of large language models (LLMs). All AI-generated code has been reviewed and tested by the project maintainers.
GPL-3.0. See LICENSE for details.