Pin the mandatory-driver matrix, portable platform services, Linux packaging and connected gates, and the evidence threshold for any GPU migration. Co-authored-by: OpenAI Codex <codex@openai.com>
297 lines
12 KiB
Markdown
297 lines
12 KiB
Markdown
# Modern runtime Slice L — Linux graphical host and evidence-gated GPU work
|
||
|
||
**Status:** PREPARED — BEGINS AFTER SLICE K CLOSEOUT
|
||
**Parent:** `2026-07-24-modern-runtime-architecture.md`, Slice L
|
||
**Authorization:** the user approved Slices F–L on 2026-07-24
|
||
**Purpose:** ship the existing modern OpenGL client on supported Linux drivers
|
||
with identical Runtime behavior and accepted visual presentation, then make
|
||
only GPU changes whose measured bottleneck and visual equivalence are proven.
|
||
|
||
## 1. Entry contract
|
||
|
||
Slice L begins only after Slice K proves Linux Runtime/Core.Net/Content,
|
||
portable paths/config/credentials, one production headless host, deterministic
|
||
wire timing, shared immutable content, and a clean 30-session stress gate.
|
||
|
||
L does not fork the game client into a second Linux implementation. The same
|
||
`AcDream.App`, `GameRuntime`, retained UI, rendering pipeline, shaders, and
|
||
resource owners run on both platforms. Platform-specific behavior is confined
|
||
to typed host services selected once at startup.
|
||
|
||
## 2. Mandatory renderer boundary
|
||
|
||
The modern path remains mandatory:
|
||
|
||
- OpenGL 4.3 core;
|
||
- `GL_ARB_bindless_texture`;
|
||
- `GL_ARB_shader_draw_parameters`;
|
||
- the current bindless texture/SSBO/MDI layouts and shaders.
|
||
|
||
There is no legacy renderer, texture-unit fallback, reduced-distance mode, or
|
||
platform-specific gameplay/render path. An unsupported driver fails startup
|
||
with a precise capability report.
|
||
|
||
Driver acceptance begins with a committed matrix:
|
||
|
||
- AMD Mesa/RadeonSI on X11;
|
||
- AMD Mesa/RadeonSI on Wayland;
|
||
- NVIDIA proprietary driver on X11;
|
||
- NVIDIA proprietary driver on Wayland where Silk's backend is supported;
|
||
- Intel only if the hardware/driver exposes every mandatory extension.
|
||
|
||
Each row records distribution/kernel, display protocol, compositor, GPU,
|
||
driver, OpenGL vendor/renderer/version, extension presence, swap interval,
|
||
monitor refresh, and audio backend. A row may be “unsupported” only because a
|
||
mandatory capability is absent or the native window backend cannot create the
|
||
required context—not because a visual mismatch was waived.
|
||
|
||
## 3. Initial platform inventory
|
||
|
||
Portable foundations already exist:
|
||
|
||
- Silk.NET owns window/input/OpenGL APIs;
|
||
- OpenAL Soft is designed for PulseAudio/PipeWire/CoreAudio as well as Windows;
|
||
- shader and UI asset paths use `AppContext.BaseDirectory`/`Path.Combine`;
|
||
- `BitmapFont.TryLoadSystemMonospaceFont` already includes common Linux font
|
||
paths;
|
||
- Runtime/Core.Net/Content are presentation-independent after J/K.
|
||
|
||
Known Linux blockers and audit targets:
|
||
|
||
- `FramePacingController` unconditionally constructs
|
||
`WindowsHighResolutionFramePacingWaiter`, which throws off Windows.
|
||
- The OpenAL Soft native package/runtime assets must be verified for each
|
||
Linux RID rather than assumed.
|
||
- Silk window backend/native dependency publication is not packaged or tested.
|
||
- the smoke-plugin MSBuild copy target uses Windows path separators;
|
||
- key bindings, cursor creation, clipboard, relative mouse, monitor refresh,
|
||
window-state callbacks, and high-DPI scaling need live X11/Wayland evidence;
|
||
- settings, layouts, keymaps, logs, screenshots, and diagnostics must use the
|
||
portable path owner established in K rather than `%LOCALAPPDATA%` wording or
|
||
ad hoc paths;
|
||
- no Linux graphical CI/smoke environment exists;
|
||
- no Linux driver timer-query validation or screenshot baseline exists;
|
||
- no package/install/uninstall contract exists.
|
||
|
||
## 4. Platform-service contracts
|
||
|
||
### Frame pacing
|
||
|
||
Keep the existing display-aware policy:
|
||
|
||
- VSync uses the driver's swap wait.
|
||
- VSync-off normal play uses a refresh-matched low-CPU software deadline.
|
||
- explicit uncapped diagnostics perform no wait.
|
||
|
||
Replace direct Windows construction with `IFramePacingWaiterFactory`.
|
||
Windows retains the high-resolution waitable timer. Linux uses an
|
||
absolute-monotonic deadline wait (`clock_nanosleep` or a proven equivalent)
|
||
with cancellation-safe disposal. Neither path busy-spins for the normal wait.
|
||
The same missed-deadline rebase rule prevents catch-up bursts.
|
||
|
||
Gate both waiters for deadline error, CPU usage, cancellation, disposal, missed
|
||
deadlines, monitor changes, and long stalls.
|
||
|
||
### Paths and persistence
|
||
|
||
Reuse K's portable path owner for:
|
||
|
||
- settings and key bindings;
|
||
- retained UI layouts;
|
||
- logs and diagnostic captures;
|
||
- screenshots and automation artifacts;
|
||
- plugins;
|
||
- prepared assets and DAT location overrides.
|
||
|
||
No feature reads a Windows-only environment variable/path at its call site.
|
||
|
||
### Input/window
|
||
|
||
Test the exact retained-input pipeline on X11 and Wayland:
|
||
|
||
- keyboard keys, modifiers, text input, repeat, and configurable bindings;
|
||
- mouse buttons, wheel, press-time selection, dragging, resizing, and cursors;
|
||
- relative mouse capture, recenter/release, and focus loss;
|
||
- clipboard;
|
||
- window move/resize/minimize/restore/close and monitor transition;
|
||
- DPI/framebuffer size versus logical size.
|
||
|
||
Retail input behavior remains the acceptance oracle; Linux key/scancode
|
||
adaptation cannot alter action semantics.
|
||
|
||
### Audio
|
||
|
||
OpenAL initialization remains fail-open only for the existing explicit
|
||
no-audio mode or unavailable device. Package the correct OpenAL Soft native
|
||
asset, identify PulseAudio/PipeWire device/context selection, and prove
|
||
source/buffer/context teardown. Audio absence must not stall the frame or
|
||
change Runtime/VFX timing.
|
||
|
||
## 5. Packaging contract
|
||
|
||
Produce repeatable `linux-x64` artifacts first; add `linux-arm64` only after
|
||
the complete native dependency and GL extension matrix passes.
|
||
|
||
Artifacts contain:
|
||
|
||
- the App and managed dependency closure;
|
||
- Silk window/input/OpenGL native dependencies;
|
||
- OpenAL Soft;
|
||
- shaders and retained-UI XML;
|
||
- plugin directory/manifest support;
|
||
- a launch entry point and version/provenance record.
|
||
|
||
DATs, account credentials, and the machine-local `acdream.pak` are not bundled.
|
||
Startup diagnostics identify their configured paths without exposing secrets.
|
||
|
||
Provide:
|
||
|
||
- framework-dependent development publish;
|
||
- self-contained release publish if native/runtime size and licenses are
|
||
acceptable;
|
||
- desktop entry/icon/install documentation;
|
||
- package validation on a clean Linux user account.
|
||
|
||
## 6. Execution
|
||
|
||
### L0 — platform services and Linux build
|
||
|
||
- Add Linux App build/publish jobs to CI after K's non-graphical Linux jobs.
|
||
- Add typed platform capability, path, pacing, and native-dependency owners.
|
||
- Implement the Linux monotonic frame waiter and factory selection.
|
||
- Correct cross-platform MSBuild paths and packaging assumptions.
|
||
- Add source/dependency guards against platform checks outside platform-owner
|
||
classes.
|
||
|
||
Gate: App restores/builds/publishes for `linux-x64`; unit tests prove both
|
||
frame waiters and portable paths; no Windows P/Invoke executes on Linux.
|
||
|
||
### L1 — context, extensions, and native backends
|
||
|
||
- Create a Linux window and OpenGL 4.3 core context under X11 and Wayland.
|
||
- Capture the full capability record before renderer construction.
|
||
- Verify mandatory bindless and shader-draw-parameter calls, MDI, SSBOs,
|
||
persistent resource ownership, timer queries, framebuffer sRGB/depth/stencil,
|
||
and swap behavior.
|
||
- Initialize input and OpenAL Soft.
|
||
- Fail unsupported rows with one actionable diagnostic.
|
||
|
||
Gate: a packaged smoke scene opens, renders, accepts input, plays optional
|
||
audio, captures a screenshot, and shuts down with zero GL/OpenAL/window debt on
|
||
each supported matrix row.
|
||
|
||
### L2 — complete graphical connected route
|
||
|
||
- Run the same exact-binary lifecycle/reconnect route used on Windows.
|
||
- Run the canonical nine-stop route with movement, jump, combat, portal,
|
||
revisit, and graceful shutdown.
|
||
- Verify radar, retained UI, inventory paperdoll, Use/approach, combat facing,
|
||
spell effects, portal tunnel/materialization/exit, cursors, chat, and audio.
|
||
- Compare pinned-camera images against accepted Windows references using the
|
||
existing per-channel tolerance and differing-pixel-fraction rule.
|
||
- Record CPU/GPU frame history, allocation, managed/native/GPU residency,
|
||
handles, threads, and driver facts.
|
||
|
||
Gate: lifecycle/resource invariants and retail behavior match; screenshot
|
||
differences are within the committed driver-aware threshold and individually
|
||
inspected; no resource growth survives repeated portals.
|
||
|
||
### L3 — packaging and clean-machine gate
|
||
|
||
- Publish versioned Linux artifacts.
|
||
- Test install, first launch, configuration discovery, plugin discovery,
|
||
upgrade, and uninstall on a clean user account.
|
||
- Prove no implicit write occurs beside a read-only installed binary.
|
||
- Prove missing DAT/pak/driver/audio conditions produce actionable,
|
||
credential-safe errors.
|
||
|
||
Gate: a clean machine reaches world, completes the route, exits gracefully,
|
||
and preserves settings/layout/key bindings under XDG paths.
|
||
|
||
### L4 — accurate Linux profiling
|
||
|
||
- Validate GL timer-query attribution on each accepted driver.
|
||
- Capture capped and uncapped canonical route, dense-town, portal-window, and
|
||
long-duration profiles on a physical local display.
|
||
- Attribute CPU update, render submission, GPU passes, allocations, upload,
|
||
particle, light, culling, and command-compaction costs.
|
||
- Compare Windows and Linux without mixing RDP/display protocol populations.
|
||
|
||
Gate: the dominant remaining CPU/GPU stages are named with reliable samples.
|
||
If no GPU stage is material, do not migrate work merely because the roadmap
|
||
lists candidates.
|
||
|
||
### L5 — evidence-gated GPU changes
|
||
|
||
For each candidate independently:
|
||
|
||
1. show it is a dominant stage in L4 evidence;
|
||
2. write a focused plan with ownership, synchronization, fallback/error, and
|
||
teardown contracts;
|
||
3. implement one bisectable change;
|
||
4. run deterministic/Release/connected/resource gates;
|
||
5. publish CPU and GPU before/after plus visual equivalence;
|
||
6. keep the change only if the intended metric materially improves without
|
||
regressions.
|
||
|
||
Candidate order, only when evidence supports it:
|
||
|
||
- GPU visibility culling;
|
||
- indirect command compaction;
|
||
- particle simulation;
|
||
- bounded light selection.
|
||
|
||
No candidate changes server authority, physics, animation ordering, DAT effect
|
||
semantics, retained UI, or visible draw range.
|
||
|
||
### L6 — closeout
|
||
|
||
- Repeat the accepted Linux driver, packaging, connected, screenshot,
|
||
resource, and performance matrices.
|
||
- Run Windows regression gates.
|
||
- Audit every GPU migration and exact rollback.
|
||
- Update architecture, milestones, roadmap, issues/divergences,
|
||
AGENTS/CLAUDE, and durable memory.
|
||
|
||
Gate: supported Linux graphical artifacts ship the same intended client
|
||
behavior; every retained GPU change has measured evidence and visual parity;
|
||
all teardown ledgers converge.
|
||
|
||
## 7. Adversarial matrix
|
||
|
||
- X11 versus Wayland, compositor on/off where practical;
|
||
- AMD versus NVIDIA extension/function-pointer behavior;
|
||
- mandatory extension advertised but call returns invalid handle/error;
|
||
- no display, no audio device, missing font, missing clipboard service;
|
||
- monitor hotplug, refresh change, DPI change, minimize, suspend/resume, focus
|
||
loss, and close during portal;
|
||
- VSync ignored, adaptive sync, software pacing stall, timer interruption, and
|
||
clock discontinuity;
|
||
- read-only install directory and XDG paths with spaces/non-ASCII;
|
||
- missing/corrupt pak, DAT mismatch, plugin failure, shader compile failure;
|
||
- GL context loss/failure during construction and teardown;
|
||
- audio context/buffer/source partial construction failure;
|
||
- screenshot differences from gamma, texture filtering, precision, clip
|
||
origin, or driver shader compilation;
|
||
- GPU migration overflow, indirect count mismatch, fence delay, stale
|
||
generation, device reset, and visibility false-negative;
|
||
- Windows regression after each platform abstraction.
|
||
|
||
## 8. Non-goals
|
||
|
||
- No legacy renderer or extension fallback.
|
||
- No reduced visual distance or Linux-specific quality default.
|
||
- No renderer rewrite solely for portability.
|
||
- No GPU migration without measured dominance.
|
||
- No macOS graphical support in Slice L; the portable Runtime/headless work and
|
||
typed platform services should make a later macOS plan smaller, but Apple
|
||
OpenGL capability constraints require a separate decision.
|
||
- No bundled DAT files, credentials, or local server.
|
||
|
||
## 9. Commit and rollback discipline
|
||
|
||
Land L0–L6 as separate buildable commits. Record the full production SHA and
|
||
exact `git revert <sha>` after each focused/Linux/Windows/connected/visual
|
||
gate. GPU candidates each receive their own plan, commit, measurement, visual
|
||
gate, and rollback; rejected experiments are reverted rather than hidden
|
||
behind dormant alternate paths.
|