summaryrefslogtreecommitdiffstats
path: root/wiki/OpenGL.md
blob: 45af4c8abb6a5659da6b2ded518bc3dcc3d015ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# OpenGL

> **Scope.** How a stock guest OpenGL application's commands travel through the
> unmodified NVIDIA stack on the emulated vGPU, and the honest state of running
> OpenGL on it. The host-side execution machinery shared by all graphics APIs
> is on [`Graphics-Execution.md`](Graphics-Execution.md); CUDA compute is on
> [`Execution-Frontier.md`](Execution-Frontier.md). Canonical sources:
> [`../docs/04-implementation/05-graphics-execution-plan.md`](../docs/04-implementation/05-graphics-execution-plan.md)
> (the plan and milestones),
> [`../docs/04-implementation/04-real-render-walls.md`](../docs/04-implementation/04-real-render-walls.md)
> (the measured walls) and
> [`../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
stock guest driver; `[wip]` partial; `[wall]` current blocker; `[target]`
defined success state.

## 1. The guest OpenGL stack

On Linux, an OpenGL application does not talk to the kernel driver directly:
it talks to the GL implementation, and — when a display is involved — through
the X server's GLX extension:

```text
application (toolkit / SDL / GLFW / raw GLX)
  -> libGL (dispatch)                    -> libGLX_nvidia (NVIDIA GLX client)
  -> libnvidia-glcore (the vendor GL engine: state, programs, shaders, draws)
  -> ioctls + mappings to nvidia.ko      -> channels, buffers, synchronization
X server (Xorg)
  -> GLX extension module (glxserver_nvidia) and the NVIDIA DDX (X driver)
  -> owns the screen, drawables and the present path
```

Two forms of operation exist, and both are visible in the guest:

* **Direct rendering** — the normal desktop case. The GL client builds GPU
  commands in its own process and the X server coordinates buffers and
  presents. The client's channel is the source of truth for per-draw state.
* **Indirect GLX** — the client's GL protocol is serialised to the X server,
  which executes it against its own GL context. Here the X server's channel
  carries the graphics stream.

On the emulated vGPU the readable command sources today are the **direct GL
client's own channels** — the GR channel `0xbeef0100` and its CE siblings
`0xbeef0101`/`0xbeef0102` — and the **X server's channels**, whose
graphics-class (`0xC597`, `TURING_A`) sections the emulation captures and
whose DDX kick channel (`0xbfef0002`) is decoded from its ring head
([`Graphics-Execution.md`](Graphics-Execution.md) §3).

## 2. What an NVIDIA GL frame involves (observed shapes)

* **Context and state setup** — shader programs (SASS) uploaded to device
  memory, constant/descriptor banks, render targets and depth surfaces
  allocated and mapped.
* **Per-draw work** — a graphics-class method stream: state binds (viewport,
  render target, ZS, blend/ROP), program and constant binds, vertex/index
  data, and draw-issuing methods that drive the fixed-function pipeline
  (vertex fetch, primitive assembly, rasterisation, fragment work, ROP).
* **Program/descriptor delivery** — the driver uploads shader code and
  descriptors through its copy/utility-channel inline-data path. The GL draw
  path decodes these uploads and the engine executes the draw; Vulkan's
  inline-to-memory arm is the remaining mirror-image gap
  ([`Vulkan.md`](Vulkan.md)).
* **Present** — the X server's present/readback path runs as light 2D-class
  and copy-engine operations; the emulator decodes and executes those shapes.

## 3. Status on the emulated vGPU

Rated honestly, against the milestone ladder in the plan:

| Item | State |
|---|---|
| X server initialises on the emulated vGPU (driver push-DMA sanity test, ScreenInit) | `[live]` |
| 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]` |
| 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]` |
| DDX push-buffer get-word publish and notifier recycle | `[wall]` |
| Physical dispatch of the direct-GL draws (`forwarded=0`) | `[wall]` |
| Non-black rendered frames through the emulated vGPU | `[wall]` |
| 60 fps sustained, no forcing (M-GL4) | `[target]` |

## 4. How OpenGL runs are verified

Instruments that matter, in order of usefulness: the X server log and
`xdpyinfo` (did the server initialise?), `glxinfo -B` (which renderer is
real), the application's own progress output, and frame capture at the GL
source (a swap-hook capture is the ground truth for pixels — the X screen
itself is not, on some stacks). Captures are decoded offline and scored:
fraction of pixels above a luminance threshold, colour count, and
frame-to-frame motion. A run counts only when the capture shows motion with
the NVIDIA renderer in use.

## 5. Milestones on this path

The graphics plan defines M-GL1 (client context-init decodes and executes; the
client leaves its retry loop), M-GL2 (`glxgears` non-black), M-GL3 (GZDoom GL
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.

## 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).
* No frame-rate or latency numbers.
* The published two-VM GZDoom demo videos used the labelled `virtio-gpu`/
  `virgl` path, not the emulated vGPU.

## 7. Related pages

* [`Graphics-Execution.md`](Graphics-Execution.md) — the shared execution
  machinery and the ranked walls.
* [`Vulkan.md`](Vulkan.md) — the sibling API path, further along in the
  pipeline lifecycle.
* [`DirectX.md`](DirectX.md) — the Windows/DirectX target.
* [`CUDA-Userspace-Driver.md`](CUDA-Userspace-Driver.md) — how the NVIDIA
  userspace stack is analysed.
* [`Install-and-First-Run.md`](Install-and-First-Run.md) — bringing the stack
  up.
* [`../docs/04-implementation/05-graphics-execution-plan.md`](../docs/04-implementation/05-graphics-execution-plan.md) —
  the canonical plan, gap list and gates.