From 90ab9baa309ae3c54d371546872c918c4c801920 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Tue, 10 Nov 2026 05:25:15 -0500 Subject: wiki: 2026-11-10 status refresh - guest GL draws execute on the physical GPU Refresh STATE-CURRENT, the Main Page and the status/frontier pages: the GSP event-IRQ fix completes swaps; the 2D path is green end-to-end; the guest's real GL draws now forward and execute on the physical GPU (work_gr backend_ok=9); the draw writes 0 pages because its constant-buffer (MVP) page is unresolved and forced to the seed page; the MME front-end defer, GR stale-wedge and the X DDX get-word/notifier completion remain. Published to open-iov.org. --- STATE-CURRENT.md | 50 +++++++++++++++++ tools/site/pages/Main-Page.wiki | 2 +- wiki/.publish-manifest.json | 120 ++++++++++++++++++++-------------------- wiki/Execution-Frontier.md | 29 +++++----- wiki/Execution-Plane.md | 15 +++-- wiki/FAQ.md | 24 ++++---- wiki/Graphics-Execution.md | 96 +++++++++++++++++--------------- wiki/Host-Module.md | 18 +++--- wiki/OpenGL.md | 35 ++++++------ wiki/Physical-GPU-Backend.md | 10 ++-- wiki/Project-Goals.md | 4 +- wiki/Project-Plan.md | 24 ++++---- wiki/Project-Status.md | 13 ++--- wiki/System-Overview.md | 15 ++--- 14 files changed, 254 insertions(+), 201 deletions(-) diff --git a/STATE-CURRENT.md b/STATE-CURRENT.md index b0b382c..608c238 100644 --- a/STATE-CURRENT.md +++ b/STATE-CURRENT.md @@ -1,5 +1,55 @@ # Open-IOV Current State +> **Snapshot: 2026-11-10 ~05:30 (SESSION 156 continued; HEAD `cb8e822b`, +> tree clean, `vgpu/master` in sync; supersedes the 19:15 entry below).** +> The execution chain came alive overnight. The guest's **real GL draws now +> forward and execute on the physical GPU** (`work_gr backend_ok=9` on r1683, +> `backend_ok=5` on r1685), the 2D path is green end-to-end (accelerated X +> fills read back correctly via `xwd`), and the earlier glxgears poll hang is +> gone: the GSP event-IRQ fix (`a478f0b4`) now sets the RISC-V SWGEN0 +> IRQSTAT/IRQMASK/IRQDEST and latches the CPU-tree leaf so the guest services +> the event. The working recipe is a 12 GB file-backed guest +> (`-object memory-backend-file ... /dev/shm/vgpu-guest-ram`), the +> `gsp-phys-guest-ram` debugfs translation, the RM-call ladder stages 5/3/4, +> the full r1624 module-argument set, and `sema_vas_cand_ms=1` (which made X +> green on attempt 1 in r1685). The beef GR channel `0xbeef0100` now captures +> real GL draw sections (`len=4808`, `win=1201 words`, `prog=0x4390900`). +> +> The new frontier is the **constant buffer**: the draw executes but the +> engine writes 0 pages, and `bounce copy-out` reports 0 changed. The GL +> draw's constant-buffer source is forced to the seed page because +> `sema-gl: cb-copy src=0x0cd70000 ... first8=00000000 ... src=synthetic-id` +> reads all zeros; a guest-RAM scan found no MVP matrix, and the +> `0x3f800000` hits in vidmem are shader microcode immediates, not matrices. +> With a zero MVP every vertex collapses to the origin, so there are no +> fragments regardless of viewport/render-target. The next step is to decode +> the CB-bind method on the beef channel, resolve that VA through the channel +> VAS, and copy the real page into the seed page. Secondary walls: the MME +> front-end busy/deferred class, the GR stale-wedge recovery, the X DDX +> push-buffer get-word/notifier recycle (X can still die after a few forward +> frames into the RM-degraded state), and the DDX's 4 GB sysmem allocation +> that forces the 12 GB guest. +> +> Honest state: still no rendered pixel through the emulated vGPU and no +> video. The execution chain (submit -> forward -> physical GR -> stores) is +> now live for the guest's own GL work; the first pixel is gated on the MVP +> constant-buffer content and the present/copy-out. Milestone position: +> between M-GL1 and M-GL2. Estimate (subjective): a first non-black frame +> hours-to-days if the constant-buffer decode behaves like its predecessors; +> the two-VM GPU-accelerated video after that. +> +> CUDA front unchanged (backgrounded while graphics holds the device; its +> 10-30 status stands): `41343c63` green (`victory_mail` `VADD bad=0` + +> `STATUS OK`; `vecadd_loop` 100 launches PASS); the fresh-boot battery's +> red class is D2H-stage with release-discipline fixes staged; the SESSION +> 143 Vulkan fence regression is not re-measured. +> +> Live at check (read-only): r1685 VM up (QEMU 72960, mdev +> `0dcda61f-a8ef-4111-8993-35942d2d5392`), X green, glxgears 300x300 +> rendering black, `work_gr backend_ok=5`; `vgsp` loaded (HEAD `cb8e822b` +> plus the runtime parameters above), `guest_ram active=1`, ladder stage 4; +> pstore empty; no reboot during the check. +> > **Snapshot: 2026-11-09 ~19:15 (SESSION 156 continued; HEAD `21e0d611`, > tree clean; supersedes the 19:05 entry below).** > The forced-GLX path moved the renderer wall: with diff --git a/tools/site/pages/Main-Page.wiki b/tools/site/pages/Main-Page.wiki index a5089a0..7b22763 100644 --- a/tools/site/pages/Main-Page.wiki +++ b/tools/site/pages/Main-Page.wiki @@ -36,7 +36,7 @@ The only new component is one host kernel module (vgsp.ko), which i |- | Display and KMS (nvidia-modeset/NvKms, /dev/dri, X) || Working — the emulated display engine serves the modeset push buffers and notifier completion; NvKms registers, X settles and glxinfo reports OpenGL 4.6.0 with direct rendering |- -| 3D graphics: Xorg + OpenGL, Vulkan || In progress — the display/KMS and GL stacks run, the direct GL client's GR/CE channels submit and retire, and forcing GLX selects libnvidia-glcore; the minimal windowed glxgears hangs in the glcore kick wait. Kernel-visible present completion, the X DDX push-buffer get-word/notifier completion and physical dispatch of the GL draws are the current frontier — see [[Graphics Execution]], [[OpenGL]], [[Vulkan]] +| 3D graphics: Xorg + OpenGL, Vulkan || In progress — the display/KMS and GL stacks run, the direct GL client's GR/CE channels submit and retire, the GSP event-IRQ fix completes swaps, and the guest's real GL draws now forward and execute on the physical GPU; the 2D path is green. The draw writes 0 pixels because its constant-buffer (MVP) page does not resolve, so constant-buffer content, MME/wedge stability and the X DDX push-buffer get-word/notifier completion are the current frontier — see [[Graphics Execution]], [[OpenGL]], [[Vulkan]] |- | Windows guests, multi-tenancy, migration, performance || Not yet — multiple mediated devices (different emulated VRAM sizes) and multiple guests already coexist; per-guest execution isolation is in progress |} diff --git a/wiki/.publish-manifest.json b/wiki/.publish-manifest.json index 27c52de..239ab66 100644 --- a/wiki/.publish-manifest.json +++ b/wiki/.publish-manifest.json @@ -64,11 +64,11 @@ }, "FAQ": { "file": "FAQ.wiki", - "new_revid": 24061, - "old_revid": 24049, - "source_sha": "17fa28555cd7eb71", - "summary": "2026-11-09 evening refresh 2: forced GLX selects libnvidia-glcore; windowed glxgears hangs in the glcore kick wait; kernel-visible present completion is the wall", - "timestamp": "2026-11-10T00:06:45Z", + "new_revid": 24073, + "old_revid": 24061, + "source_sha": "993f4e23553d2842", + "summary": "2026-11-10 status refresh: guest GL draws forward and execute on the physical GPU; the 0-pixel wall is the constant-buffer (MVP) content", + "timestamp": "2026-11-10T10:23:37Z", "title": "FAQ" }, "GMMU Multi-Tenant Protection": { @@ -127,11 +127,11 @@ }, "Graphics Execution": { "file": "Graphics-Execution.wiki", - "new_revid": 24062, - "old_revid": 24050, - "source_sha": "11e8fa4f83fed247", - "summary": "2026-11-09 evening refresh 2: forced GLX selects libnvidia-glcore; windowed glxgears hangs in the glcore kick wait; kernel-visible present completion is the wall", - "timestamp": "2026-11-10T00:06:46Z", + "new_revid": 24074, + "old_revid": 24062, + "source_sha": "bbc2783864468dab", + "summary": "2026-11-10 status refresh: guest GL draws forward and execute on the physical GPU; the 0-pixel wall is the constant-buffer (MVP) content", + "timestamp": "2026-11-10T10:23:37Z", "title": "Graphics Execution" }, "Guest Driver Lifecycle: A Field Guide": { @@ -190,11 +190,11 @@ }, "Main Page": { "file": "Main-Page.wiki", - "new_revid": 24070, - "old_revid": 24058, - "source_sha": "d79ac879f1798d05", - "summary": "2026-11-09 evening refresh 2: forced GLX selects libnvidia-glcore; windowed glxgears hangs in the glcore kick wait", - "timestamp": "2026-11-10T00:06:53Z", + "new_revid": 24082, + "old_revid": 24070, + "source_sha": "fb770eaffa1533f3", + "summary": "2026-11-10 status refresh: guest GL draws execute on the physical GPU; constant-buffer (MVP) content is the 0-pixel wall", + "timestamp": "2026-11-10T10:23:50Z", "title": "Main Page" }, "MediaWiki:Sidebar": { @@ -226,11 +226,11 @@ }, "OpenGL": { "file": "OpenGL.wiki", - "new_revid": 24064, - "old_revid": 24052, - "source_sha": "cd8779694a581bf5", - "summary": "2026-11-09 evening refresh 2: forced GLX selects libnvidia-glcore; windowed glxgears hangs in the glcore kick wait; kernel-visible present completion is the wall", - "timestamp": "2026-11-10T00:06:47Z", + "new_revid": 24076, + "old_revid": 24064, + "source_sha": "144f1627a14c54a3", + "summary": "2026-11-10 status refresh: guest GL draws forward and execute on the physical GPU; the 0-pixel wall is the constant-buffer (MVP) content", + "timestamp": "2026-11-10T10:23:38Z", "title": "OpenGL" }, "Performance": { @@ -244,38 +244,38 @@ }, "Physical GPU Backend and Guest Wiring": { "file": "Physical-GPU-Backend.wiki", - "new_revid": 24065, - "old_revid": 24053, - "source_sha": "cce4eba81a924f9f", - "summary": "2026-11-09 evening refresh 2: forced GLX selects libnvidia-glcore; windowed glxgears hangs in the glcore kick wait; kernel-visible present completion is the wall", - "timestamp": "2026-11-10T00:06:48Z", + "new_revid": 24077, + "old_revid": 24065, + "source_sha": "5a0b0fab129d042c", + "summary": "2026-11-10 status refresh: guest GL draws forward and execute on the physical GPU; the 0-pixel wall is the constant-buffer (MVP) content", + "timestamp": "2026-11-10T10:23:39Z", "title": "Physical GPU Backend and Guest Wiring" }, "Project Goals": { "file": "Project-Goals.wiki", - "new_revid": 24066, - "old_revid": 24054, - "source_sha": "f717cd829cb16ff3", - "summary": "2026-11-09 evening refresh 2: forced GLX selects libnvidia-glcore; windowed glxgears hangs in the glcore kick wait; kernel-visible present completion is the wall", - "timestamp": "2026-11-10T00:06:49Z", + "new_revid": 24078, + "old_revid": 24066, + "source_sha": "1a1a231fa6da0d5a", + "summary": "2026-11-10 status refresh: guest GL draws forward and execute on the physical GPU; the 0-pixel wall is the constant-buffer (MVP) content", + "timestamp": "2026-11-10T10:23:39Z", "title": "Project Goals" }, "Project Plan": { "file": "Project-Plan.wiki", - "new_revid": 24067, - "old_revid": 24055, - "source_sha": "57c421e0af6c3d69", - "summary": "2026-11-09 evening refresh 2: forced GLX selects libnvidia-glcore; windowed glxgears hangs in the glcore kick wait; kernel-visible present completion is the wall", - "timestamp": "2026-11-10T00:06:49Z", + "new_revid": 24079, + "old_revid": 24067, + "source_sha": "dba7840c299c0751", + "summary": "2026-11-10 status refresh: guest GL draws forward and execute on the physical GPU; the 0-pixel wall is the constant-buffer (MVP) content", + "timestamp": "2026-11-10T10:23:40Z", "title": "Project Plan" }, "Project Status": { "file": "Project-Status.wiki", - "new_revid": 24068, - "old_revid": 24056, - "source_sha": "91905880addcf2e7", - "summary": "2026-11-09 evening refresh 2: forced GLX selects libnvidia-glcore; windowed glxgears hangs in the glcore kick wait; kernel-visible present completion is the wall", - "timestamp": "2026-11-10T00:06:50Z", + "new_revid": 24080, + "old_revid": 24068, + "source_sha": "1fe9bb91cd4cef31", + "summary": "2026-11-10 status refresh: guest GL draws forward and execute on the physical GPU; the 0-pixel wall is the constant-buffer (MVP) content", + "timestamp": "2026-11-10T10:23:40Z", "title": "Project Status" }, "RPC Message Format": { @@ -289,11 +289,11 @@ }, "System Overview": { "file": "System-Overview.wiki", - "new_revid": 24069, - "old_revid": 24057, - "source_sha": "49cc4d259bf1e8d5", - "summary": "2026-11-09 evening refresh 2: forced GLX selects libnvidia-glcore; windowed glxgears hangs in the glcore kick wait; kernel-visible present completion is the wall", - "timestamp": "2026-11-10T00:06:50Z", + "new_revid": 24081, + "old_revid": 24069, + "source_sha": "5d3502ef3e24189d", + "summary": "2026-11-10 status refresh: guest GL draws forward and execute on the physical GPU; the 0-pixel wall is the constant-buffer (MVP) content", + "timestamp": "2026-11-10T10:23:41Z", "title": "System Overview" }, "Template:About message": { @@ -325,11 +325,11 @@ }, "The Execution Frontier": { "file": "Execution-Frontier.wiki", - "new_revid": 24059, - "old_revid": 24047, - "source_sha": "8bdff873c9b0f66b", - "summary": "2026-11-09 evening refresh 2: forced GLX selects libnvidia-glcore; windowed glxgears hangs in the glcore kick wait; kernel-visible present completion is the wall", - "timestamp": "2026-11-10T00:06:44Z", + "new_revid": 24071, + "old_revid": 24059, + "source_sha": "e6debfdea2d1a520", + "summary": "2026-11-10 status refresh: guest GL draws forward and execute on the physical GPU; the 0-pixel wall is the constant-buffer (MVP) content", + "timestamp": "2026-11-10T10:23:36Z", "title": "The Execution Frontier" }, "The Guest Stack and CUDASW": { @@ -343,20 +343,20 @@ }, "The Host Module (vgsp.ko)": { "file": "Host-Module.wiki", - "new_revid": 24063, - "old_revid": 24051, - "source_sha": "4631ad02e69f5e8f", - "summary": "2026-11-09 evening refresh 2: forced GLX selects libnvidia-glcore; windowed glxgears hangs in the glcore kick wait; kernel-visible present completion is the wall", - "timestamp": "2026-11-10T00:06:47Z", + "new_revid": 24075, + "old_revid": 24063, + "source_sha": "278deddb70a2098d", + "summary": "2026-11-10 status refresh: guest GL draws forward and execute on the physical GPU; the 0-pixel wall is the constant-buffer (MVP) content", + "timestamp": "2026-11-10T10:23:38Z", "title": "The Host Module (vgsp.ko)" }, "The vGSP Execution Plane (vEP)": { "file": "Execution-Plane.wiki", - "new_revid": 24060, - "old_revid": 24048, - "source_sha": "578bf257456d5b8b", - "summary": "2026-11-09 evening refresh 2: forced GLX selects libnvidia-glcore; windowed glxgears hangs in the glcore kick wait; kernel-visible present completion is the wall", - "timestamp": "2026-11-10T00:06:45Z", + "new_revid": 24072, + "old_revid": 24060, + "source_sha": "4124b0721387025d", + "summary": "2026-11-10 status refresh: guest GL draws forward and execute on the physical GPU; the 0-pixel wall is the constant-buffer (MVP) content", + "timestamp": "2026-11-10T10:23:36Z", "title": "The vGSP Execution Plane (vEP)" }, "UVM in the Guest": { diff --git a/wiki/Execution-Frontier.md b/wiki/Execution-Frontier.md index 658f222..18f150c 100644 --- a/wiki/Execution-Frontier.md +++ b/wiki/Execution-Frontier.md @@ -14,7 +14,7 @@ > [`../docs/04-implementation/03-execution-frontier.md`](../docs/04-implementation/03-execution-frontier.md); > the docs tree wins on disagreement. -Status: 2026-11-09, tree `master @ 21e0d611`. +Status: 2026-11-09, tree `master @ cb8e822b`. Tags: `[live]` observed; `[wip]` partial; `[wall]` current blocker; theories are labelled as such. @@ -103,13 +103,13 @@ OpenGL 4.6.0 with direct rendering, and the X DDX waits are fixed release applied); the direct GL client's GR and CE channels submit and retire, and the X DDX kick channel is decoded. GZDoom reached `MAP01` once the DDX push-buffer loop was unblocked, but on Mesa llvmpipe — not the emulated vGPU. -What is missing is **rendered pixels through the NVIDIA path**: forcing GLX -now selects `libnvidia-glcore`, but the minimal windowed `glxgears` hangs in -the glcore kick wait (the client polls its per-slot `/dev/nvidia-modeset` fd -and the guest kernel never signals the event), the DDX push-buffer -get-word/notifier completion is not implemented, and the direct-GL draws still -report no physical dispatch; the guest Vulkan pipeline's inline-to-memory -upload arm remains its gap. The full +What is missing is **rendered pixels through the NVIDIA path**: the GSP +event-IRQ fix completes swaps, the 2D path is green end-to-end, and the +guest's real GL draws now forward and execute on the physical GPU, but the +draw writes 0 pages because its constant-buffer (MVP) page is unresolved and +forced to the seed page; the MME front-end defer, the GR stale-wedge and the +DDX push-buffer get-word/notifier completion remain. The guest Vulkan +pipeline's inline-to-memory upload arm is its gap. The full picture lives on [`Graphics-Execution.md`](Graphics-Execution.md). No breadth beyond these is claimed: Windows guests, migration and performance @@ -168,13 +168,12 @@ CUDA guests is in progress. **Issue D — the graphics pixel frontier.** The display/KMS stack and the GL client now run end to end (NvKms registers, X settles, GL 4.6, direct-GL -channels submit and retire, the X DDX waits are fixed), and forcing GLX -selects `libnvidia-glcore`; but the minimal windowed `glxgears` hangs in the -glcore kick wait (the client polls its per-slot `/dev/nvidia-modeset` fd and -the guest kernel never signals the event), and no rendered (non-black) frame -has been produced yet. The kernel-visible present completion, the DDX -get-word/notifier completion and physical dispatch of the GL draws -(`forwarded=0`) are the named blockers +channels submit and retire, the X DDX waits are fixed), and the guest's real +GL draws forward and execute on the physical GPU; but the draw writes 0 pages +because its constant-buffer (MVP) page is unresolved and forced to the seed +page, and no rendered (non-black) frame has been produced yet. The constant +buffer, the MME front-end/stale-wedge stability and the DDX get-word/notifier +completion are the named blockers ([`Graphics-Execution.md`](Graphics-Execution.md)). ## 6. Lines of investigation (live) diff --git a/wiki/Execution-Plane.md b/wiki/Execution-Plane.md index 0cb7e7c..ef285a3 100644 --- a/wiki/Execution-Plane.md +++ b/wiki/Execution-Plane.md @@ -8,7 +8,7 @@ > when the two disagree, the docs tree wins. Front door: > [`../docs/README.md`](../docs/README.md). -Status: 2026-11-09, tree `master @ 21e0d611`. Tags: `[live]` proven with the +Status: 2026-11-09, tree `master @ cb8e822b`. Tags: `[live]` proven with the stock guest driver; `[gated]` implemented, default-off or parameter-gated; `[wip]` partial; `[wall]` current blocker; `[target]` named success latch; `[planned]` designed, not built. @@ -148,13 +148,12 @@ guest: push + QMD + GPFIFO entry + doorbell (BAR0 0x88704) display/KMS path is served by the emulated display engine (modeset push buffers plus the notifier/`UPDATE` completion, class-aware arm), so NvKms registers, X settles and GL 4.6 is live, the X DDX waits are fixed, and - forcing GLX selects `libnvidia-glcore`. No rendered (non-black) frame has - been produced through the NVIDIA path yet: the kernel-visible GL present/kick - completion (the minimal `glxgears` hangs there), the DDX push-buffer - get-word/notifier completion and physical dispatch of the GL draws - (`forwarded=0`) are the named blockers; GZDoom's `MAP01` is a Mesa llvmpipe - datapoint. The lanes and the ladder are on - [`Graphics-Execution.md`](Graphics-Execution.md). + the guest's real GL draws now forward and execute on the physical GPU + (`backend_ok=9`); the 2D path is green. No rendered (non-black) frame has + been produced through the NVIDIA path yet: the constant-buffer (MVP) content + (the draw writes 0 pages), the MME front-end/stale-wedge stability and the + DDX push-buffer get-word/notifier completion are the named blockers. The + lanes and the ladder are on [`Graphics-Execution.md`](Graphics-Execution.md). ## 6. Portability diff --git a/wiki/FAQ.md b/wiki/FAQ.md index 5025175..f9d5251 100644 --- a/wiki/FAQ.md +++ b/wiki/FAQ.md @@ -5,7 +5,7 @@ > [`../docs/09-reference/glossary-and-faq.md`](../docs/09-reference/glossary-and-faq.md); > the docs tree wins on disagreement. -Status: 2026-11-09, tree `master @ 21e0d611`. +Status: 2026-11-09, tree `master @ cb8e822b`. ## Project and positioning @@ -40,17 +40,17 @@ progress). This is the project's known status, not a misconfiguration — see Partially, and it is an active frontier. The display/KMS stack and the X server now run on the emulated vGPU with the stock driver: nvidia-modeset/NvKms registers (`/dev/dri`), `glxinfo` reports OpenGL 4.6.0 with direct rendering, -the direct GL client's GR and CE channels submit and retire, and forcing GLX -(`SDL_VIDEO_X11_FORCE_EGL=0`) selects `libnvidia-glcore`. The minimal -windowed `glxgears` then hangs in the glcore kick wait: the client polls its -per-slot `/dev/nvidia-modeset` fd and the guest kernel never signals the -event, even though the host completes the beef notifier memory. The guest -Vulkan pipeline runs end to end (device → command buffer → fence → readback, -frames black). Rendered (non-black) frames through the NVIDIA path are the -remaining wall: kernel-visible present completion, the X DDX -get-word/notifier completion, the DDX's 4 GB sysmem allocation (12 GB guest -workaround) and physical dispatch of the GL draws are the current gates — -see [`OpenGL.md`](OpenGL.md), [`Vulkan.md`](Vulkan.md) and +the direct GL client's GR and CE channels submit and retire, and the GSP +event-IRQ fix completes swaps. The guest's **real GL draws now forward and +execute on the physical GPU** (`work_gr backend_ok=9`) and the 2D path is +green end-to-end, but the frames are black: the draw's constant-buffer (MVP) +page does not resolve and is forced to the seed page, so the engine writes 0 +pages. The guest Vulkan pipeline runs end to end (device → command buffer → +fence → readback, frames black). Rendered (non-black) frames through the +NVIDIA path are the remaining wall: constant-buffer content, the MME +front-end/stale-wedge stability, the X DDX get-word/notifier completion and +the DDX's 4 GB sysmem allocation (12 GB guest workaround) are the current +gates — see [`OpenGL.md`](OpenGL.md), [`Vulkan.md`](Vulkan.md) and [`Graphics-Execution.md`](Graphics-Execution.md). **How fast is it?** diff --git a/wiki/Graphics-Execution.md b/wiki/Graphics-Execution.md index ffbcfaf..7771d6a 100644 --- a/wiki/Graphics-Execution.md +++ b/wiki/Graphics-Execution.md @@ -12,7 +12,7 @@ > [`../docs/04-implementation/04-real-render-walls.md`](../docs/04-implementation/04-real-render-walls.md) > (the measured walls); the docs tree wins on disagreement. -Status: 2026-11-09, tree `master @ 21e0d611`. Tags: `[live]` observed end to +Status: 2026-11-09, tree `master @ cb8e822b`. Tags: `[live]` observed end to end; `[wip]` partially built; `[wall]` current blocker; `[target]` defined success state; `[planned]` designed, not built. @@ -89,10 +89,12 @@ fidelity: kick channel (`0xbfef0002`) is decoded from its ring head with its class-2D notification authored. The X DDX waits are fixed (class-aware display arm, `0x8000 -> 0` notification completion, decoded GL release - applied), and with GLX forced (`SDL_VIDEO_X11_FORCE_EGL=0`) the windowed - GL path selects `libnvidia-glcore`. What remains is the kernel-visible GL - present/kick completion, the DDX get-word/notifier recycle, and physical - dispatch of the client's draws (§6). + applied), forcing GLX selects `libnvidia-glcore`, and the event-IRQ fix + (`a478f0b4`) lets the guest service the completion, so glxgears completes + swaps and the guest's real GL draws now forward and execute on the + physical GPU (`work_gr backend_ok=9`). What remains is the constant-buffer + (MVP) content, the MME front-end defer and GR stale-wedge, and the DDX + get-word/notifier completion (§6). ## 4. The channel and object picture @@ -139,10 +141,12 @@ until it posts, so the X server's mode set finishes. For the X DDX's own 2D push buffers, completion also requires the GPU-written engine get word to advance and the notifier to be recycled to `0xffff` after a kick; both are host-side levers now, and a diagnostic write of the get word released the -DDX's reserve loop. For a windowed GL client the present is a kick whose -completion the guest kernel observes by polling its per-slot -`/dev/nvidia-modeset` fd; the host must complete the exact notifier page the -kernel watches and signal that event, not only write the notifier memory. +DDX's reserve loop. For a windowed GL client the present is a kick; the GSP +event-IRQ fix now sets the RISC-V SWGEN0 IRQSTAT/IRQMASK/IRQDEST and latches +the CPU-tree leaf, so the guest services the event and glxgears completes +swaps. The next completion step is the constant buffer: the draw's CB page +must be resolved and copied into the seed page so the engine produces +fragments. During bring-up the module also carries a **diagnostics-only mirror** for apps that spin on a shared progress word; it exists so a run can proceed while the @@ -151,32 +155,35 @@ requires it switched off, along with any external poke. ## 6. Where the frontier is (ranked walls) -1. **Kernel-visible GL present completion** `[wall]`. With GLX forced the - windowed client uses `libnvidia-glcore`; the minimal `glxgears` then hangs - in the glcore kick wait: the client polls its per-slot - `/dev/nvidia-modeset` fd (`poll(POLLIN, 1 s)`). The host's sweep completes - the beef notifier memory, but the guest kernel never signals the event the - poll waits on. The exact notifier page the kernel watches must be - completed and the guest event signalled (the kick-notify executor), not - just the memory written. -2. **The X DDX push-buffer completion** `[wall]`. The DDX's 2D reserve loop +1. **The constant buffer (MVP) content** `[wall]`. The guest's GL draws now + execute on the physical GPU, but the engine writes 0 pages. The draw's + constant-buffer source is forced to the seed page because + `cb-copy src=0x0cd70000 ... first8=00000000 ... src=synthetic-id` reads all + zeros; a guest-RAM scan found no MVP matrix and the `0x3f800000` vidmem + hits are shader microcode immediates. With a zero MVP every vertex + collapses to the origin, so there are no fragments. Decode the CB-bind + method on the beef channel, resolve that VA through the channel VAS, and + copy the real page into the seed page. +2. **Execution stability** `[wall]`. The MME front-end is busy/deferred + (`MME-FE-DEFER` then forced loads) and the GR channel stale-wedges + (`GR-STALL-stale-wedge`, recovered), so the pipeline restarts mid-frame. + Fixing the CB page may unstick the MME; the wedge recovery needs a durable + fix. +3. **The X DDX push-buffer completion** `[wall]`. The DDX's 2D reserve loop exits only when the GPU-written engine get word advances (`get <= put`) and - the kick requires the notifier to be recycled to `0xffff` after - completion. A diagnostic host write released the loop; the kernel levers - to publish/advance the get word and recycle the notifier are next. -3. **The X DDX footprint** `[wall]`. The DDX allocates 4 GB of system pages at + the kick requires the notifier to be recycled to `0xffff` after completion. + `sema_vas_cand_ms=1` makes X green on attempt 1, but X can still die after a + few forward frames into the RM-degraded state. +4. **The X DDX footprint** `[wall]`. The DDX allocates 4 GB of system pages at startup; an 8 GB guest has no headroom once GZDoom's own footprint lands and both are OOM-killed. Current runs use a 12 GB guest; the allocation is a suspected emulation gap (a 512 MiB emulated VRAM falling back to a 4 GB sysmem allocation) to fix. -4. **Physical dispatch of the GL draws** `[wall]`. The direct-GL channels - submit and get host-completed releases, but the forwarding path reports no - dispatch to the physical GR engine (`forwarded=0`); the draws are decoded - and host-completed, not executed on hardware. 5. **Non-black frames and sustained rate** `[wall]`/`[target]`. Once the - kernel-visible present completion and the DDX get-word/notifier completion - land, the capture must show motion, then 60 fps in one VM with no forcing, - then two VMs on two mediated devices with non-black frames in both. + constant buffer, the MME/wedge stability and the DDX get-word/notifier + completion land, the capture must show motion, then 60 fps in one VM with + no forcing, then two VMs on two mediated devices with non-black frames in + both. ## 7. What is proven today @@ -186,21 +193,19 @@ requires it switched off, along with any external poke. | Display engine serves the modeset push buffers; notifier plus `UPDATE -> FINISHED` | `[live]` (campaign configuration) | | nvidia-modeset/NvKms registers (`/dev/dri/card0`, `renderD128`, `fb0`); `nvidia-smi -L` enumerates | `[live]` | | `glxinfo` reports the emulated GPU with the NVIDIA renderer (OpenGL 4.6.0, direct rendering) | `[live]` | -| GZDoom obtains a real GL context; windowed reaches renderer startup | `[live]` (pixels frontier) | -| GZDoom reaches `MAP01` on Mesa llvmpipe (not the emulated vGPU path) | `[wip]` | -| Forced GLX (`SDL_VIDEO_X11_FORCE_EGL=0`) selects `libnvidia-glcore` | `[live]` | -| Windowed GL present/kick completion (minimal `glxgears`) | `[wall]` | -| X server survives the GZDoom run on a 12 GB guest (the DDX's 4 GB sysmem allocation forces the size) | `[live]` | -| GL section capture: the X server's `0xC597` stream decoded | `[live]` | +| X server green with `sema_vas_cand_ms=1`; glxinfo 4.6.0 direct | `[live]` | +| GSP event-IRQ fix wakes the guest poll; glxgears completes swaps | `[live]` | +| 2D path end-to-end: accelerated X fills read back via `xwd` | `[live]` | +| Guest's real GL draws forward and execute on the physical GPU (`work_gr backend_ok=9`) | `[live]` | +| Beef GR channel `0xbeef0100` captures real GL draw sections | `[live]` | +| GL section capture: the X channel's `0xC597` stream decoded | `[live]` | | Verbatim 3D method-stream replay retired by the engine (no MMU fault) | `[live]` | | Synthesized launch executes real `sm_75` SASS; Turing `V3` program header accepted | `[live]` | -| 2D screen fills and copy-engine present ops execute | `[live]` | -| Direct GL client: device-init gate handled, channels allocate, readback path returns clean | `[live]` | -| Direct GL client channels submit and retire (GR `0xbeef0100`, CE `0xbeef0101`/`0xbeef0102`); DDX kick channel decoded | `[live]` | -| Guest kernel observes the kick completion and signals the modeset event | `[wall]` | -| NVIDIA Vulkan ICD creates a device | `[wall]` | +| X server survives the run on a 12 GB guest (the DDX's 4 GB sysmem allocation forces the size) | `[live]` | +| Constant-buffer (MVP) page resolves and the draw writes render-target pixels | `[wall]` | +| MME front-end defer / GR stale-wedge stability | `[wall]` | | DDX push-buffer get-word publish and notifier recycle | `[wall]` | -| Physical dispatch of the direct-GL draws (`forwarded=0`) | `[wall]` | +| NVIDIA Vulkan ICD creates a device | `[wall]` | | Non-black pixels from the emulated vGPU's 3D pipeline | `[wall]` | | Windows/DirectX guests | `[planned]` | @@ -208,11 +213,10 @@ requires it switched off, along with any external poke. * No non-black pixel has been produced by the emulated vGPU's 3D pipeline yet. * Display/KMS bring-up (NvKms, `/dev/dri`, X, a real GL context) is not a - rendered-frame claim; GZDoom reaching `MAP01` on Mesa llvmpipe is not the - emulated-vGPU path, and the later forced-GLX run selects `libnvidia-glcore` - but hangs in the present/kick wait. The kernel-visible present completion, - the DDX get-word/notifier completion and the physical dispatch of the GL - draws are the current walls. + rendered-frame claim; the guest's GL draws now execute on the physical GPU + and glxgears completes swaps, but the frames are black. The constant-buffer + (MVP) content, the MME/wedge stability and the DDX get-word/notifier + completion are the current walls. * No frame-rate or latency numbers: the scheduled measurement is defined (60 fps over 60 s, no forcing) but not yet met. * The `virgl`-based demo videos are a different, labelled path — not this one. diff --git a/wiki/Host-Module.md b/wiki/Host-Module.md index 35bf3c8..6405874 100644 --- a/wiki/Host-Module.md +++ b/wiki/Host-Module.md @@ -6,7 +6,7 @@ > source: [`../docs/03-architecture/06-host-module-and-hybrid-model.md`](../docs/03-architecture/06-host-module-and-hybrid-model.md); > the docs tree wins on disagreement with this page. > -> Status: 2026-11-09, tree `master @ 21e0d611`. Tags: `[live]` observed with +> Status: 2026-11-09, tree `master @ cb8e822b`. Tags: `[live]` observed with > the stock guest driver; `[wip]` demonstrated live, being productized; > `[gated]` implemented default-off behind supervised gates; `[wall]` known > blocking limit; `[target]` designed, not built; `[planned]` roadmap. @@ -107,9 +107,11 @@ from kernel context**, so the module **owns the device and runs its real GSP firmware as the resource-manager server**, with emulation as the control plane. CE copies, release and fault relay are implemented default-off and verified live [gated]; forwarded guest CUDA launches execute on the engine -with engine-authored completions relayed to the guest, and graphics method -streams execute in three shapes, including the direct GL client's own GR/CE -channels ([`Execution-Frontier.md`](Execution-Frontier.md), +with engine-authored completions relayed to the guest; the guest's real GL +draws now forward and execute on the physical GR engine (`work_gr +backend_ok=9`), and graphics method streams execute in three shapes, +including the direct GL client's own GR/CE channels +([`Execution-Frontier.md`](Execution-Frontier.md), [`Graphics-Execution.md`](Graphics-Execution.md)). The same plane carries the display/modeset path [live in the campaign @@ -122,10 +124,10 @@ nvidia-modeset/NvKms register (`/dev/dri`), X settle and GLX clients obtain a real GL context. The display-capability seam is parameterised. For the DDX's own 2D push buffers the remaining host levers are publishing/advancing the GPU-written engine get word and recycling the notifier to `0xffff` after -completion. For a windowed GL client the host must also make the kick -completion visible to the guest kernel and signal its modeset event: writing -the beef notifier memory alone leaves `poll()` on the per-slot -`/dev/nvidia-modeset` fd waiting. +completion. For a windowed GL client the GSP event-IRQ path raises the +RISC-V SWGEN0 interrupt and latches the CPU-tree leaf so the guest services +the event and completes swaps; the remaining GL gap is the constant-buffer +(MVP) page (the draw writes 0 pages) and the MME/wedge stability. ## 6. Debug parameters diff --git a/wiki/OpenGL.md b/wiki/OpenGL.md index 45af4c8..1219b84 100644 --- a/wiki/OpenGL.md +++ b/wiki/OpenGL.md @@ -12,7 +12,7 @@ > [`../docs/03-architecture/02-guest-stack-and-cudasw.md`](../docs/03-architecture/02-guest-stack-and-cudasw.md) > (the guest stack). The docs tree wins on disagreement. -Status: 2026-11-09, tree `master @ 21e0d611`. Tags: `[live]` observed with the +Status: 2026-11-09, tree `master @ cb8e822b`. Tags: `[live]` observed with the stock guest driver; `[wip]` partial; `[wall]` current blocker; `[target]` defined success state. @@ -75,20 +75,19 @@ Rated honestly, against the milestone ladder in the plan: | nvidia-modeset/NvKms registers (`/dev/dri/card0`, `renderD128`, `fb0`); `nvidia-smi -L` enumerates | `[live]` (campaign configuration) | | `glxinfo -B` reports the NVIDIA renderer (OpenGL 4.6.0, driver 570.144, direct rendering) | `[live]` | | The X driver's RC-watchdog channel registers and its notifier is authored | `[live]` | -| GZDoom obtains a real GL context; windowed GZDoom reaches renderer startup | `[live]` (menu/frames black) | -| GZDoom reaches `MAP01` on Mesa llvmpipe (not the emulated vGPU path) | `[wip]` | -| Forced GLX (`SDL_VIDEO_X11_FORCE_EGL=0`) selects `libnvidia-glcore` | `[live]` | -| Windowed GL present/kick completion (minimal `glxgears`) | `[wall]` | -| X server survives the GZDoom run on a 12 GB guest (the DDX's 4 GB sysmem allocation forces the size) | `[live]` | -| X server's `0xC597` graphics section captured and decoded | `[live]` | +| X server green with `sema_vas_cand_ms=1`; `glxinfo -B` NVIDIA 4.6.0 direct | `[live]` | +| GSP event-IRQ fix wakes the guest poll; glxgears completes swaps | `[live]` | +| 2D path end-to-end: accelerated X fills read back via `xwd` | `[live]` | +| Guest's real GL draws forward and execute on the physical GPU (`work_gr backend_ok=9`) | `[live]` | +| Beef GR channel `0xbeef0100` captures real GL draw sections | `[live]` | | Engine executes a launch built from the captured section (real `sm_75` SASS retired) | `[live]` | | Verbatim 3D method-stream replay retired by the engine, no MMU fault | `[live]` | -| Direct GL client: device-init gate handled; client channels allocate; readback path returns with no GL error | `[live]` | | Direct GL client submits and retires its per-frame draws (GR `0xbeef0100`, CE `0xbeef0101`/`0xbeef0102`); DDX kick channel decoded | `[live]` | -| Guest kernel observes the kick completion and signals the modeset event | `[wall]` | -| NVIDIA Vulkan ICD creates a device | `[wall]` | +| X server survives the run on a 12 GB guest (the DDX's 4 GB sysmem allocation forces the size) | `[live]` | +| Constant-buffer (MVP) page resolves and the draw writes render-target pixels | `[wall]` | +| MME front-end defer / GR stale-wedge stability | `[wall]` | | DDX push-buffer get-word publish and notifier recycle | `[wall]` | -| Physical dispatch of the direct-GL draws (`forwarded=0`) | `[wall]` | +| NVIDIA Vulkan ICD creates a device | `[wall]` | | Non-black rendered frames through the emulated vGPU | `[wall]` | | 60 fps sustained, no forcing (M-GL4) | `[target]` | @@ -111,17 +110,17 @@ non-black through the mdev), M-GL4 (60 fps, no forcing), M-GL5 (two VMs, two mdevs), M-GL6 (split-screen video). The project sits **between M-GL1 and M-GL2**: the interface and execution work is done — the display/KMS stack registers, X settles, the client submits and retires its GR/CE channels, and -the engine authors stores — and the remaining gates are the kernel-visible GL -present/kick completion, the X DDX get-word/notifier completion, and physical -dispatch of the client's draws before the first rendered frame. +the guest's GL draws forward and execute on the physical GPU. The remaining +gates are the constant-buffer (MVP) page, the MME front-end/stale-wedge +stability, and the X DDX get-word/notifier completion before the first +rendered frame. ## 6. What is not claimed * No OpenGL frame from the emulated vGPU has produced real rendered pixels - yet; every capture so far is black. GZDoom reaching `MAP01` on Mesa - llvmpipe is not a rendered frame from the emulated vGPU, and the forced-GLX - run selects `libnvidia-glcore` but hangs in the present/kick wait - (`glxgears` reproduces it). + yet; every capture so far is black. glxgears completes swaps and its GL + draws execute on the physical GPU, but the constant-buffer (MVP) page does + not resolve, so the engine writes 0 pages. * No frame-rate or latency numbers. * The published two-VM GZDoom demo videos used the labelled `virtio-gpu`/ `virgl` path, not the emulated vGPU. diff --git a/wiki/Physical-GPU-Backend.md b/wiki/Physical-GPU-Backend.md index 21ad279..6b64d46 100644 --- a/wiki/Physical-GPU-Backend.md +++ b/wiki/Physical-GPU-Backend.md @@ -5,7 +5,7 @@ > guest-facing emulation. Canonical sources: [`../docs/03-architecture/08-physical-gpu-integration.md`](../docs/03-architecture/08-physical-gpu-integration.md) > and [`../docs/03-architecture/11-physical-backend-guest-wiring.md`](../docs/03-architecture/11-physical-backend-guest-wiring.md); the docs tree wins on disagreement. -Status: 2026-11-09, tree `master @ 21e0d611`. Tags: `[live]` proven with the +Status: 2026-11-09, tree `master @ cb8e822b`. Tags: `[live]` proven with the stock guest driver; `[gated]` implemented default-off; `[wip]` partially built; `[wall]` current blocker; `[target]` planned end state. @@ -123,10 +123,10 @@ same machinery in three shapes (a verbatim 3D method-stream replay, synthesized launches, and the direct GL client's own GR/CE channels); the captured and synthesized streams execute on the engine, and the direct GL client's channels submit. The display/KMS stack registers, the X DDX waits are -fixed, X settles and forcing GLX selects `libnvidia-glcore`, so the remaining -graphics gates are the kernel-visible GL present completion, the DDX -push-buffer get-word/notifier completion, and physical dispatch of the -client's draws (`forwarded=0`) before rendered pixels. The remaining compute work is the staged-transfer +fixed, X settles and the guest's real GL draws forward and execute on the +physical GPU, so the remaining graphics gates are the constant-buffer (MVP) +content, the MME front-end/stale-wedge stability, and the DDX push-buffer +get-word/notifier completion before rendered pixels. The remaining compute work is the staged-transfer class (under repair), the every-boot acceptance campaign, and per-guest execution isolation — see [`Execution-Frontier.md`](Execution-Frontier.md) and diff --git a/wiki/Project-Goals.md b/wiki/Project-Goals.md index ff35ff7..942c0d3 100644 --- a/wiki/Project-Goals.md +++ b/wiki/Project-Goals.md @@ -10,7 +10,7 @@ > [`Execution-Frontier.md`](Execution-Frontier.md) and > [`Graphics-Execution.md`](Graphics-Execution.md). -Status: 2026-11-09, tree `master @ 21e0d611`. Tags: `[live]` working with the +Status: 2026-11-09, tree `master @ cb8e822b`. Tags: `[live]` working with the stock guest driver; `[wip]` in progress; `[planned]` designed, not built; `[target]` bring-up ahead; `[non-goal]` explicitly out of scope. @@ -51,7 +51,7 @@ drivers, no license.** | Stock guest driver initialisation | The unmodified driver probes, initialises and enumerates as on bare metal (`nvidia-smi`) | `[live]` — TU104 reference platform | | Full CUDA driver-API surface | Context creation, allocation, copies, free, destroy complete with correct results | `[live]` — the driver-API smoke prints `ALL OK`; the 64-byte payload round-trips | | CUDA kernel execution on real hardware | Verified guest kernels execute on the physical GPU, with engine-authored completions waking the guest | `[live]` — vector-add, matrix-multiply and transformer clients green on fresh boots; the staged-transfer class, the every-boot acceptance campaign and per-guest isolation are in progress ([`Execution-Frontier.md`](Execution-Frontier.md)) | -| OpenGL (3D graphics) | Stock guest GL applications render real pixels through the emulated vGPU | `[wip]` — the display/KMS stack and X run (NvKms registers, `glxinfo` OpenGL 4.6.0 direct), the direct GL client's GR/CE channels submit and retire, and forcing GLX selects `libnvidia-glcore`; the minimal windowed `glxgears` hangs in the glcore kick wait. Kernel-visible present completion, the DDX get-word/notifier completion and physical dispatch of the GL draws are the frontier ([`OpenGL.md`](OpenGL.md)) | +| OpenGL (3D graphics) | Stock guest GL applications render real pixels through the emulated vGPU | `[wip]` — the display/KMS stack and X run (NvKms registers, `glxinfo` OpenGL 4.6.0 direct), the direct GL client's GR/CE channels submit and retire, and the guest's real GL draws now forward and execute on the physical GPU (`backend_ok=9`); the 2D path is green, but the draw writes 0 pixels because its constant-buffer (MVP) page does not resolve. Constant-buffer content, MME/wedge stability and the DDX get-word/notifier completion are the frontier ([`OpenGL.md`](OpenGL.md)) | | Vulkan | Stock guest Vulkan applications render real pixels | `[wip]` — the pipeline runs end to end (device → command buffer → fence → readback); frames are black — program delivery and program-VA mapping are the frontier ([`Vulkan.md`](Vulkan.md)) | | Windows guests (DirectX, CUDA) | A stock WDDM driver and stock D3D/CUDA applications run in Windows guests | `[target]` — not started; same emulation target ([`DirectX.md`](DirectX.md)) | | Video (NVENC/NVDEC) | Encode/decode through the emulated device | `[planned]` | diff --git a/wiki/Project-Plan.md b/wiki/Project-Plan.md index 459dc59..8280697 100644 --- a/wiki/Project-Plan.md +++ b/wiki/Project-Plan.md @@ -15,7 +15,7 @@ > [`../docs/06-portability/03-device-validation-and-porting-sequence.md`](../docs/06-portability/03-device-validation-and-porting-sequence.md); > the docs tree wins on disagreement. -Status: 2026-11-09, tree `master @ 21e0d611`. Tags: `[done]`, `[active]`, +Status: 2026-11-09, tree `master @ cb8e822b`. Tags: `[done]`, `[active]`, `[ahead]` — the plan's own state vocabulary, distinct from the goal tags. ## 1. How the plan works @@ -44,7 +44,7 @@ itself: |---|---|---|---| | **P0 — Platform** | Emulated vGPU device, GSP boot and GSP-RM emulation, stock guest driver initialisation | Driver-API smoke green (`ALL OK`) = evaluation rung 2 | `[done]` | | **P1 — First execution (compute)** | Guest CUDA kernels executing on the physical GPU, with engine-authored completions; then hardening | Verified clients + engine-authored completion = rung 3 core; hardening: staged-transfer class, every-boot acceptance, per-guest isolation | `[active]` — execution green; hardening in progress | -| **P2 — Graphics execution** | OpenGL/Vulkan draw commands executed by the physical 3D pipeline and delivered as readable pixels | The graphics ladder: M-GL1 client context-init executes; M-GL2 `glxgears` non-black; M-GL3 GZDoom GL non-black through the mdev | `[active]` — between M-GL1 and M-GL2; the display/KMS and direct-GL channel work is live; kernel-visible GL present completion, the DDX get-word/notifier completion and physical dispatch of the GL draws are the walls | +| **P2 — Graphics execution** | OpenGL/Vulkan draw commands executed by the physical 3D pipeline and delivered as readable pixels | The graphics ladder: M-GL1 client context-init executes; M-GL2 `glxgears` non-black; M-GL3 GZDoom GL non-black through the mdev | `[active]` — between M-GL1 and M-GL2; the display/KMS and direct-GL channel work is live and the guest's GL draws execute on the physical GPU; the constant-buffer (MVP) content, the MME/wedge stability and the DDX get-word/notifier completion are the walls | | **P3 — Sustained and multi-tenant** | Frame rates without assistance; multiple VMs sharing the GPU with measured fairness; soak-stable operation | Graphics M-GL4 (60 fps, no forcing) and M-GL5 (two VMs, two mdevs); CUDA battery + soak; per-guest execution isolation = rungs 4/5 | `[ahead]` | | **P4 — Breadth** | Video (NVENC/NVDEC), Windows/DirectX guests, live migration, non-KVM hypervisor transports | Per-case bring-up gates plus the matrix's evidence expectations | `[ahead]` | | **P5 — Scale and portability** | New GPU generations and driver families carried forward; published performance programme | A profile + measured delta per version, validated on hardware; A/B numbers published per the measurement contract | `[ahead]` | @@ -57,12 +57,12 @@ available (P5 runs across the whole plan). Ranked, in dependency order: -1. **Graphics pixels (P2).** The client and display stacks execute, and - forcing GLX selects `libnvidia-glcore`; the named walls are the - kernel-visible GL present/kick completion (minimal `glxgears` hangs in it), - the X DDX push-buffer get-word/notifier completion, the DDX's 4 GB sysmem - allocation (12 GB guest workaround), physical dispatch of the GL draws - (`forwarded=0`), then non-black frames. Full detail: +1. **Graphics pixels (P2).** The client and display stacks execute, the + guest's GL draws forward and execute on the physical GPU, and the 2D path + is green; the named walls are the constant-buffer (MVP) content (the draw + writes 0 pages), the MME front-end/stale-wedge stability, the X DDX + push-buffer get-word/notifier completion, and the DDX's 4 GB sysmem + allocation (12 GB guest workaround), then non-black frames. Full detail: [`Graphics-Execution.md`](Graphics-Execution.md) §6. 2. **Compute hardening (P1).** The staged-transfer class (failure modes proven, fixes in flight); the every-boot acceptance campaign; per-guest execution @@ -79,10 +79,10 @@ post-reboot client-stall defect (compute reproducibility); the display/KMS bring-up (NvKms registers, X settles, GL 4.6); the UVM channel-pool tracker; the direct-GL GR release and CE ring discovery; the X DDX kick-channel decode and its three wait fixes (class-aware display arm, `0x8000 -> 0` notification -completion, decoded GL release applied); forced GLX selecting `libnvidia-glcore` -(the EGL/Mesa fallback is gone); GZDoom reaching renderer startup and `MAP01` -once the DDX push-buffer loop was unblocked (a Mesa llvmpipe datapoint); and -the guest Vulkan pipeline running end to end. +completion, decoded GL release applied); the GSP event-IRQ fix that completes +swaps; the 2D path end-to-end; the guest's real GL draws forwarding and +executing on the physical GPU (`backend_ok=9`); and the guest Vulkan pipeline +running end to end. ## 4. The gates diff --git a/wiki/Project-Status.md b/wiki/Project-Status.md index e61d307..4ebf765 100644 --- a/wiki/Project-Status.md +++ b/wiki/Project-Status.md @@ -10,7 +10,7 @@ > (the execution frontier). When this page and the docs disagree, the docs tree > wins. -Status: 2026-11-09, tree `master @ 21e0d611`. Tags: `[live]` proven with the +Status: 2026-11-09, tree `master @ cb8e822b`. Tags: `[live]` proven with the stock guest driver; `[gated]` implemented, default-off or behind supervised gates; `[wip]` partially implemented; `[wall]` current blocker; `[target]` named success state; `[planned]` designed, not built. @@ -28,7 +28,7 @@ named success state; `[planned]` designed, not built. | Physical backend on real hardware (module-owned GPU running its real GSP-RM) | `[live]` boot, RPC session, object creation, copy-engine work and GR execution proven — the verified guest CUDA kernel clients execute through this backend, and graphics method streams execute on the engine ([`Graphics-Execution.md`](Graphics-Execution.md)) | | Display and KMS on the emulated vGPU (nvidia-modeset/NvKms, `/dev/dri`, X) | `[live]` in the campaign configuration — the emulated display engine serves the guest's display push-buffer channels (notifier plus `UPDATE -> FINISHED`), nvidia-modeset/NvKms registers (`/dev/dri/card0`, `renderD128`, `fb0`), `nvidia-smi -L` enumerates and X settles; the display-capability seam is parameterised ([`Graphics-Execution.md`](Graphics-Execution.md)) | | Multi-tenant isolation (mdev per VM, per-context page directories) | `[wip]` device-level coexistence works — multiple mediated devices with different emulated VRAM sizes and multiple guests coexist (two guests demonstrated); per-guest execution isolation for simultaneous CUDA guests is in progress | -| OpenGL (3D graphics) | `[wip]` — the display/KMS stack registers and X settles; `glxinfo` reports OpenGL 4.6.0 with direct rendering; with GLX forced (`SDL_VIDEO_X11_FORCE_EGL=0`) the windowed GL path uses `libnvidia-glcore`, and the direct GL client's GR and CE channels submit. **No rendered pixels through the emulated vGPU yet:** the minimal `glxgears` hangs in the glcore kick wait (the client polls the per-slot `/dev/nvidia-modeset` fd; the host completes the beef notifier memory but the guest kernel never signals the event), the X DDX get-word/notifier recycle is not implemented, the DDX's 4 GB sysmem allocation forces a 12 GB guest, and the direct-GL draws still report `forwarded=0` ([`OpenGL.md`](OpenGL.md)) | +| OpenGL (3D graphics) | `[wip]` — the display/KMS stack registers, X settles and `glxinfo` reports OpenGL 4.6.0 with direct rendering; the GSP event-IRQ fix completes swaps, the 2D path is green end-to-end, and the guest's **real GL draws now forward and execute on the physical GPU** (`work_gr backend_ok=9`; glxgears swaps, black). **No rendered pixels through the emulated vGPU yet:** the draw writes 0 pages because its constant-buffer (MVP) page is unresolved/zero and is forced to the seed page; the MME front-end defer, GR stale-wedge, X DDX get-word/notifier completion and the DDX's 4 GB sysmem allocation (12 GB guest) are the remaining walls ([`OpenGL.md`](OpenGL.md)) | | Vulkan (3D/compute) | `[wip]` — the guest Vulkan pipeline runs end to end on the emulated vGPU (device, allocation, pipeline, command buffer, fence, queue submit, readback) and the engine executes translated launches; frames are still black — program delivery and program-VA mapping are the frontier ([`Vulkan.md`](Vulkan.md)) | | DirectX / Windows guests | `[planned]` (target) — no Windows guest booted yet; the architecture is the same emulation target ([`DirectX.md`](DirectX.md)) | | Video (NVENC/NVDEC) | `[planned]` | @@ -66,7 +66,7 @@ The project's definition of done for CUDA requires all of the following Until every gate holds, the honest formulation is: **initialization, the driver-API path and kernel execution on the physical GPU work and verify; the staged-transfer class, per-guest isolation and the graphics -present-completion/DDX/first-frame frontier remain.** +MVP-content/present/first-frame frontier remain.** ## 3. How to see it yourself @@ -76,10 +76,9 @@ outcome is exactly the ladder above — driver probe, `nvidia-smi`, the full driver-API smoke, and guest CUDA kernels executing and verifying on the physical GPU. On the graphics side the same setup brings up the display/KMS stack and the X server on the emulated vGPU (`glxinfo` reports OpenGL 4.6.0 -with direct rendering); forcing GLX (`SDL_VIDEO_X11_FORCE_EGL=0`) selects -`libnvidia-glcore`, but the minimal windowed `glxgears` hangs in the glcore -kick wait and the DDX completion is not yet authored, so kernel-visible -completion is the frontier ([`OpenGL.md`](OpenGL.md)). The +with direct rendering); the guest's GL draws execute on the physical GPU and +glxgears completes swaps, but the constant-buffer (MVP) page does not resolve, +so the frames are black ([`OpenGL.md`](OpenGL.md)). The risc-v-gsp-rm-debugger workbench ([`Riscv-GSP-RM-Debugger.md`](Riscv-GSP-RM-Debugger.md)) is the host-side tooling used to study the firmware side of that frontier. diff --git a/wiki/System-Overview.md b/wiki/System-Overview.md index de6f632..3531eeb 100644 --- a/wiki/System-Overview.md +++ b/wiki/System-Overview.md @@ -7,7 +7,7 @@ > and [`../docs/03-architecture/10-interaction-and-scheduling.md`](../docs/03-architecture/10-interaction-and-scheduling.md) > for the full picture); the docs tree wins on disagreement. -Status: 2026-11-09, tree `master @ 21e0d611`. Tags: `[live]` proven with the +Status: 2026-11-09, tree `master @ cb8e822b`. Tags: `[live]` proven with the stock guest driver; `[gated]` implemented default-off; `[wip]` partial; `[wall]` current blocker; `[target]` designed end state. @@ -142,12 +142,13 @@ RPC from the guest to "firmware": buffers and the display notifier/completion (class-aware arm), so nvidia-modeset/NvKms registers (`/dev/dri`), X settles and `glxinfo` reports OpenGL 4.6.0 with direct rendering; the direct GL client's - channels submit, the X DDX waits are fixed, forcing GLX selects - `libnvidia-glcore`, and the guest Vulkan pipeline runs end to end. The - minimal windowed `glxgears` hangs in the glcore kick wait, so the remaining - gate is kernel-visible present completion, the DDX get-word/notifier - completion and physical dispatch of the GL draws before the first rendered - (non-black) frame ([`OpenGL.md`](OpenGL.md), [`Vulkan.md`](Vulkan.md)). + channels submit, the X DDX waits are fixed, the guest's real GL draws + forward and execute on the physical GPU, the 2D path is green, and the + guest Vulkan pipeline runs end to end. The draw writes 0 pixels because its + constant-buffer (MVP) page does not resolve, so the remaining gate is the + constant-buffer content, MME/wedge stability and the DDX get-word/notifier + completion before the first rendered (non-black) frame + ([`OpenGL.md`](OpenGL.md), [`Vulkan.md`](Vulkan.md)). ## 6. Where the detail lives -- cgit v1.2.3