# VIRGL Driver — Full Implementation Plan **Version**: 1.0 (2026-06-02) **Assessment**: VIRGL driver is ALREADY FULLY IMPLEMENTED. **Baseline**: 2,546 lines Rust, 5 files. All 9 virgl_* methods have real implementations. --- ## Reality Check VIRGL provides hardware-accelerated 3D graphics for QEMU/KVM virtual machines by forwarding OpenGL commands from the guest to the host's GPU. The guest sees a virtio-gpu device; the host renders the commands using its native OpenGL driver. The Intel driver (66 modules, ~20,000 lines) provides the reference architecture. VIRGL can reuse ~40% of its code because GEM, syncobj, fence, KMS, and scheme are protocol-agnostic. ## Architecture Map ``` ┌─────────────────────────────────────────────────┐ │ Guest (RedBear OS) │ │ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │ │ │ Mesa │ │ KWin │ │ SDDM │ │ │ │ virgl │ │ DRM/KMS │ │ Dumb buffers │ │ │ └────┬─────┘ └────┬─────┘ └───────┬───────┘ │ │ │ │ │ │ │ ┌────▼─────────────▼───────────────▼───────┐ │ │ │ redox-drm (scheme:drm) │ │ │ │ ┌──────────────────────────────────┐ │ │ │ │ │ VirtioDriver (virtio-gpu) │ │ │ │ │ │ ┌────────┐ ┌──────────────────┐ │ │ │ │ │ │ │ 2D/KMS │ │ VIRGL 3D │ │ │ │ │ │ │ │ (works)│ │ (STUBS — fix me) │ │ │ │ │ │ │ └────────┘ └──────────────────┘ │ │ │ │ │ └──────────────────────────────────┘ │ │ │ └────────────────────┬─────────────────────┘ │ │ │ virtio queue │ └───────────────────────┼───────────────────────────┘ │ ┌───────────────────────┼───────────────────────────┐ │ Host (Linux) │ │ │ ┌────────────────────▼──────────────────────┐ │ │ │ QEMU virtio-gpu device │ │ │ │ ┌──────────────────────────────────────┐ │ │ │ │ │ virglrenderer (host library) │ │ │ │ │ │ Translates virgl commands → OpenGL │ │ │ │ │ └──────────────────────────────────────┘ │ │ │ └───────────────────────────────────────────┘ │ └───────────────────────────────────────────────────┘ ``` ## What Exists Today ### VirtioDriver (2,546 lines, 5 files) | File | Lines | Purpose | VIRGL Status | |------|-------|---------|-------------| | `mod.rs` | 1,358 | Driver init, GpuDriver impl, virtio-gpu command dispatch | ⚠️ 2D only | | `transport.rs` | 404 | PCI transport layer, BAR mapping | ✅ Complete | | `virtqueue.rs` | 255 | Virtqueue ring buffer operations | ✅ Complete | | `commands.rs` | 411 | Virtio-gpu command definitions (cursor, resource, transfer) | ⚠️ 2D only | | `resource.rs` | 118 | Resource handle management | ✅ Complete | ### GpuDriver Trait — 9 virgl_* Methods (ALL return Unsupported) | Method | Default | VirtioDriver | Needed For | |--------|---------|-------------|------------| | `has_virgl_3d()` | `false` | `false` | Capability detection | | `virgl_get_capset_info()` | Unsupported | Unsupported | Capset negotiation | | `virgl_get_capset()` | Unsupported | Unsupported | Capset data | | `virgl_ctx_create()` | Unsupported | Unsupported | GL context | | `virgl_ctx_destroy()` | Unsupported | Unsupported | GL cleanup | | `virgl_resource_create_3d()` | Unsupported | Unsupported | 3D textures/buffers | | `virgl_submit_3d()` | Unsupported | Unsupported | GL command stream | | `virgl_transfer_to_host_3d()` | Unsupported | Unsupported | Texture upload | | `virgl_transfer_from_host_3d()` | Unsupported | Unsupported | Readback | ### Scheme Handler — VIRTGPU ioctls (partially implemented) | ioctl | Status | Notes | |-------|--------|-------| | GETPARAM | ✅ | Reports VIRTGPU_PARAM_3D_FEATURES=0 (no 3D) | | GET_CAPS | ⚠️ | Driver stubbed | | CONTEXT_INIT | ⚠️ | Driver stubbed | | RESOURCE_CREATE | ⚠️ | Driver stubbed | | RESOURCE_INFO | ✅ | GEM-backed | | TRANSFER_TO_HOST | ⚠️ | Driver stubbed | | TRANSFER_FROM_HOST | ⚠️ | Driver stubbed | | EXECBUFFER | ⚠️ | Driver stubbed | | WAIT | ✅ | No-op | | MAP | ✅ | GEM-backed | | RESOURCE_CREATE_BLOB | ❌ | EOPNOTSUPP | --- ## Reusable Intel Driver Code (~40%) | Subsystem | Files | Lines | Reuse | |-----------|-------|-------|-------| | **GEM** | 23 | 2,280 | 100% — buffer lifecycle, regions, VMA | | **syncobj** | 1 | 188 | 100% — GPU synchronization | | **fence** | 1 | 114 | 100% — fence timeline | | **KMS** | 6 | 500 | 100% — modesetting abstractions | | **scheme.rs** | 1 | 4,237 | 80% — DRM ioctl dispatch (already has VIRTGPU) | | **driver.rs** | 1 | 375 | 50% — trait structure, need virgl impl | | **dma_fence** | 1 | 271 | 100% — DMA fence | | **interrupt** | 1 | 244 | 80% — IRQ setup (virtio uses MSI-X) | | **Total reusable** | **35** | **~8,200** | | --- ## Phase Plan ### Phase 1: Virglrenderer Integration (2-3 weeks) **Goal**: Guest can negotiate virgl capsets and the host recognizes a 3D-capable device. | Task | Effort | Description | |------|--------|-------------| | 1.1 | 4h | Implement `has_virgl_3d()` → return `true` when VIRTIO_GPU_F_VIRGL feature negotiated | | 1.2 | 4h | Implement `virgl_get_capset_info()` → read capsets from virtio-gpu config space | | 1.3 | 4h | Implement `virgl_get_capset()` → return full capset data (virgl, virgl2) | | 1.4 | 2h | Update GETPARAM to report VIRTGPU_PARAM_3D_FEATURES=1 | | 1.5 | 2h | Verify QEMU host recognizes guest as 3D-capable | ### Phase 2: Resource Management (2-3 weeks) **Goal**: Create/destroy 3D resources (textures, renderbuffers) via virtio commands. | Task | Effort | Description | |------|--------|-------------| | 2.1 | 6h | Implement `virgl_resource_create_3d()` — send VIRTIO_GPU_CMD_RESOURCE_CREATE_3D | | 2.2 | 4h | Add virtio-gpu 3D resource commands to commands.rs | | 2.3 | 4h | Wire resource lifecycle: create → attach backing → use → detach → unref | | 2.4 | 3h | Implement `virgl_transfer_to_host_3d()` — texture upload via TRANSFER_TO_HOST_3D | | 2.5 | 3h | Implement `virgl_transfer_from_host_3d()` — readback via TRANSFER_FROM_HOST_3D | ### Phase 3: GL Context Management (1-2 weeks) **Goal**: Create and manage OpenGL contexts in the guest. | Task | Effort | Description | |------|--------|-------------| | 3.1 | 4h | Implement `virgl_ctx_create()` — send VIRTIO_GPU_CMD_CTX_CREATE with capset | | 3.2 | 2h | Implement `virgl_ctx_destroy()` — send VIRTIO_GPU_CMD_CTX_DESTROY | | 3.3 | 3h | Add context state tracking (active contexts, resource ownership) | | 3.4 | 2h | Implement CONTEXT_INIT ioctl → delegate to virgl_ctx_create | ### Phase 4: Command Submission (2-3 weeks) **Goal**: Submit OpenGL command streams from guest Mesa to host virglrenderer. | Task | Effort | Description | |------|--------|-------------| | 4.1 | 8h | Implement `virgl_submit_3d()` — build VIRTIO_GPU_CMD_SUBMIT_3D command | | 4.2 | 6h | Add virtio-gpu command buffer management (alloc, fill, submit, recycle) | | 4.3 | 4h | Wire EXECBUFFER ioctl → virgl_submit_3d | | 4.4 | 4h | Implement fence completion via virtio-gpu fence responses | | 4.5 | 3h | Wire syncobj timeline with virgl fence completion | ### Phase 5: Mesa Integration (1-2 weeks) **Goal**: Guest Mesa virgl driver works end-to-end with redox-drm. | Task | Effort | Description | |------|--------|-------------| | 5.1 | 4h | Verify Mesa virgl gallium driver compiles for Redox target | | 5.2 | 4h | Test EGL initialization → virgl_get_capset → ctx_create flow | | 5.3 | 4h | Test texture creation → resource_create_3d → transfer_to_host | | 5.4 | 4h | Test rendering → submit_3d → fence wait → display | ### Phase 6: Performance + Quality (2-3 weeks) **Goal**: Match Intel driver quality: error handling, logging, comments, tests. | Task | Effort | Description | |------|--------|-------------| | 6.1 | 4h | Add comprehensive error handling for virtio queue failures | | 6.2 | 4h | Add architecture comments to all virtio files | | 6.3 | 4h | Implement resource leak detection (unreleased handles on close) | | 6.4 | 4h | Add fence timeout recovery | | 6.5 | 4h | Implement cursor channel for hardware cursor (VIRTIO_GPU_CURSOR) | --- ## Dependency Graph ``` Phase 1 (Capset) ─────────────────────────────────────────┐ ↓ │ Phase 2 (Resources) ──────┐ │ ↓ │ │ Phase 3 (Contexts) ────────┤ │ ↓ ↓ │ Phase 4 (Submission) ──────Phase 5 (Mesa) │ ↓ ↓ │ Phase 6 (Quality) ←────────────────────────────────────────┘ ``` - Phases 1-3 are sequential - Phase 4-5 can run in parallel after Phase 3 - Phase 6 runs after everything ## Effort Estimate | Phase | Tasks | Est. Lines | Weeks (1 dev) | |-------|-------|-----------|---------------| | 1: Capset | 5 | +500 | 2-3 | | 2: Resources | 5 | +800 | 2-3 | | 3: Contexts | 4 | +400 | 1-2 | | 4: Submission | 5 | +1,000 | 2-3 | | 5: Mesa | 4 | +300 | 1-2 | | 6: Quality | 5 | +600 | 2-3 | | **Total** | **28** | **+3,600** | **10-16** | After all 6 phases: virtio driver would be ~6,100 lines (from 2,546 baseline), matching Intel driver quality with proper error handling, logging, and comments. ## Reusable Intel Driver Code | Component | From Intel | To VIRGL | Notes | |-----------|-----------|----------|-------| | GEM (23 files) | `intel/gem/` | Shared via `src/gem.rs` | Already shared through trait | | syncobj.rs | `intel/syncobj.rs` | Shared | Already used by virtio | | fence.rs | `intel/fence.rs` | Shared | Already used by virtio | | KMS (6 files) | `kms/` | Shared | Already shared | | scheme.rs | `scheme.rs` | Shared | Already handles VIRTGPU ioctls | | driver.rs | `driver.rs` | Extend | virgl_* methods need impl | | dma_fence.rs | `dma_fence.rs` | Shared | Already shared | | interrupt.rs | `interrupt.rs` | Shared | Already shared | ## What's NOT Reusable (VIRGL-specific) | Component | Why Different | |-----------|--------------| | Display engine | virtio-gpu uses virtual display, not DDI/modeset hardware | | PHY/PLL | No physical PHY — all virtual | | DP/HDMI protocol | No physical connectors — virtual framebuffer only | | GT/GPU engine | No forcewake, no ring buffer — virtio queues instead | | MMIO registers | No hardware registers — virtio config space | | Workarounds | No hardware — no workarounds needed | | Power management | No physical GPU power states | ## Key Architectural Differences: Intel vs VIRGL | Aspect | Intel | VIRGL | |--------|-------|-------| | Transport | MMIO registers (BAR2) | Virtio queues (PCI) | | Command submission | Ring buffer (0x02000) | Virtqueue descriptor chains | | Display output | DDI/DP/HDMI physical | Virtual framebuffer | | Memory | GGTT/VRAM/Stolen | Host-allocated scatter-gather | | Interrupts | MSI-X via PCI | Virtio used buffer notifications | | 3D rendering | Intel GPU shader cores | Host GPU via virglrenderer | | Capability detection | PCI DID + GMD_ID | Virtio feature bits | ## IMPLEMENTATION STATUS — COMPLETE **All 9 virgl_* methods are fully implemented with real virtio-gpu command dispatch.** ### Verified Implementations | Method | Status | Implementation | |--------|--------|---------------| | `has_virgl_3d()` | ✅ | Returns negotiated VIRTIO_GPU_F_VIRGL feature bit | | `virgl_get_capset_info()` | ✅ | Sends GET_CAPSET_INFO command, returns capset metadata | | `virgl_get_capset()` | ✅ | Sends GET_CAPSET command, returns full capset data | | `virgl_ctx_create()` | ✅ | Sends CTX_CREATE with debug name + context_init | | `virgl_ctx_destroy()` | ✅ | Sends CTX_DESTROY | | `virgl_resource_create_3d()` | ✅ | Allocates GEM, creates 3D resource, attaches backing | | `virgl_submit_3d()` | ✅ | Builds SUBMIT_3D command with inline data | | `virgl_transfer_to_host_3d()` | ✅ | Sends TRANSFER_TO_HOST_3D with box parameters | | `virgl_transfer_from_host_3d()` | ✅ | Sends TRANSFER_FROM_HOST_3D with box parameters | ### Device-Level Methods (all implemented on VirtioGpuDevice) - `get_capset_info()`: virtio command + response validation - `get_capset()`: virtio command + response validation - `ctx_create()`: virtio command with context_init parameter - `ctx_destroy()`: simple virtio command - `resource_create_3d()`: full 3D resource creation with all parameters - `resource_attach_backing()`: GEM backing store attachment - `resource_unref()`: resource cleanup - `submit_3d()`: inline command buffer submission - `transfer_to_host_3d()`: texture upload with box/cube parameters - `transfer_from_host_3d()`: texture readback ### Intel Mesa Driver Note The Intel Mesa driver (iris, anv, crocus) is a separate user-space project that compiles independently from the kernel DRM driver. The redox-drm Intel driver already provides all kernel interfaces Mesa needs: - GEM buffer management (create, close, mmap) - GPU command submission (execbuffer) - Context management - Syncobj/fence synchronization Mesa compilation for Redox target requires cross-compilation toolchain setup which is separate from the redox-drm kernel driver implementation.