# MVGAL Steam and Proton Compatibility Layer

This directory contains the Steam and Proton integration components for MVGAL.

## Overview

MVGAL integrates with Steam via three mechanisms:

1. **Vulkan implicit layer** (`VK_LAYER_MVGAL`) — automatically active for all
   Vulkan applications, including those launched through Proton.
2. **Steam compatibility tool** — MVGAL can be selected as a compatibility tool in Steam.
3. **Steam launch options** — `ENABLE_MVGAL=1 %command%` enables MVGAL for
   a specific game with optimized settings.

## Files

| File | Purpose |
|------|---------|
| `mvgal_steam_compat.sh` | Steam compatibility tool entry point |
| `mvgal_proton_hook.sh` | Proton pre-launch hook that sets MVGAL env vars |
| `mvgal_frame_pacer.c/h` | Frame pacing queue implementation |
| `mvgal_afr.c` | Alternate Frame Rendering coordinator |
| `toolmanifest.vdf` | Steam compatibility tool manifest |
| `compatibilitytool.vdf` | Steam tool registration |
| `steam_profiles/` | Per-game optimization profiles |

## Usage

### Per-game launch option
Add to Steam game properties → Launch Options:
```
ENABLE_MVGAL=1 MVGAL_STRATEGY=gaming MVGAL_POWER_PROFILE=gaming %command%
```

### Environment variables

| Variable | Values | Description |
|----------|--------|-------------|
| `ENABLE_MVGAL` | `0` / `1` | Enable/disable MVGAL for this launch |
| `MVGAL_STRATEGY` | `gaming`, `afr`, `sfr`, `hybrid`, `single` | Scheduling strategy |
| `MVGAL_POWER_PROFILE` | `gaming`, `rendering`, `performance` | Power management profile |
| `MVGAL_FRAME_PACING` | `0` / `1` | Enable frame pacing correction |
| `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 |
| `MVGAL_VULKAN_LOG_PATH` | path | Write Vulkan layer log to file |
| `MVGAL_STEAM_PROFILE` | app_id | Override Steam App ID for profile |

### Steam compatibility tool setup

1. Copy `steam/` to `~/.steam/root/compatibilitytools.d/mvgal/`
2. Restart Steam
3. Select "MVGAL Multi-GPU" in game properties → Compatibility

## Gaming-Optimized Strategies

### Gaming Profile (Recommended for most games)

- Uses AFR for maximum FPS scaling
- Implements frame pacing to prevent microstutter
- Enables power boost during active gameplay
- Disables for known incompatible anti-cheat games

### SFR for VR

- Split Frame Rendering for VR workloads
- Each GPU renders half the frame to reduce latency
- Recommended for VR titles like SteamVR Home, Half-Life: Alyx

### Hybrid Auto-Detect

- Automatically selects best strategy per-frame
- Gaming: AFR
- Ray tracing: Task-based compute
- UI-heavy: Single GPU (reduce overhead)

## Frame Pacing

Multi-GPU AFR can cause microstutter if frames are delivered to the display at
uneven intervals. MVGAL's frame pacing queue holds completed frames and releases
them at the correct display refresh interval (vsync-aligned).

### How It Works

```
GPU 0 completes frame N ──┐
                          ├──► Frame Pacer Queue (ring buffer, 8 deep)
GPU 1 completes frame N+1 ──┘
                          │
                          ▼
                Sleep until vsync time
                          │
                          ▼
                Presents to display in order
```

### Frame Pacer Configuration

```bash
# Frame pacing enabled
MVGAL_FRAME_PACING=1

# Disable for uncapped framerates
MVGAL_FRAME_PACING=0
```

## Alternate Frame Rendering (AFR)

- Even frames (0, 2, 4, …) → GPU 0
- Odd frames (1, 3, 5, …) → GPU 1  
- Frame N+1 is not presented until frame N is complete (dependency enforced via
  Vulkan timeline semaphore)
- If GPU 1 finishes before GPU 0, it waits in the frame pacing queue
- Automatic GPU switch on failure

## Steam Game Profiles

MVGAL includes pre-configured profiles for popular games:

| Game | App ID | Recommended Strategy | Notes |
|------|--------|---------------------|-------|
| Cyberpunk 2077 | 1091500 | AFR + Frame Pacing | Disable RT for multi-GPU scaling |
| Baldur's Gate 3 | 1086940 | AFR + Frame Pacing | Large textures benefit from MVGAL |
| Apex Legends | 1172470 | AFR | Known working |
| Counter-Strike 2 | 730 | Single GPU | Competitive FPS (disable Multi-GPU) |
| Portal 2 (Proton) | 620 | AFR | Classic Source engine |
| Half-Life: Alyx | 546560 | SFR | VR optimized |

To add a custom profile, create `~/.mvgal/profiles/steam_<appid>.conf`:
```ini
[strategy]
primary = afr
fallback = single

[frame_pacing]
enabled = true
max_latency_ms = 8
```

## DXVK Compatibility

DXVK 2.x translates Direct3D 9/10/11 to Vulkan. MVGAL's Vulkan layer sits
above DXVK in the layer stack and intercepts `vkQueueSubmit` calls. No special
configuration is needed — DXVK games work automatically.

Tested DXVK versions: 2.3, 2.4

## VKD3D-Proton Compatibility

VKD3D-Proton translates Direct3D 12 to Vulkan. Same as DXVK — MVGAL intercepts
at the Vulkan queue submission level. Frame pacing is more important for DX12
titles due to their use of explicit synchronisation.

Recommended: `MVGAL_FRAME_PACING=1`

## Wine/Proton Integration

MVGAL provides a WoW64 thunk layer (`libmvgal_wow64.so`) for 32-bit Windows games:

```bash
# For 32-bit games under Wine/Proton
export MVGAL_WOW64=1
wine game32.exe
```

The WoW64 layer provides:
- Structure repacking (32-bit pointers to 64-bit)
- Handle mapping between address spaces
- Frame pacing for multi-GPU gaming
- Gaming-aware AFR scheduling

## Known Limitations

- Kernel-level anti-cheat (EasyAntiCheat, BattlEye) blocks Vulkan layers.
  Disable MVGAL for affected games.
- Ray tracing workloads are not split across GPUs in the current implementation.
- Some competitive games may experience input lag with multi-GPU enabled.
- Windows 7 era anti-cheat may have false positives with NTSYNC.