summaryrefslogtreecommitdiffstats
path: root/wiki/OpenGL.md
blob: c4999678399d74cf03f442fc2ca373f4d3435f83 (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
142
143
# 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 @ bb802909`. 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]` |
| X green on attempt 1 in three consecutive cycles (`ebf3130f`) | `[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=5-7`) | `[live]` |
| GR backend timeouts fixed (`backend_timeout=0`; draws retire in 3-2400 ms) | `[live]` |
| CB-DIAG decodes the draw's fixed-CB stream (1492 `0x3800` offsets, 1092 words) | `[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 submits and retires its per-frame draws (GR `0xbeef0100`, CE `0xbeef0101`/`0xbeef0102`); DDX kick channel decoded | `[live]` |
| X server survives the run on a 12 GB guest (the DDX's 4 GB sysmem allocation forces the size) | `[live]` |
| Beef GR ring resolves deterministically; fixed-CB scan runs every cycle | `[wall]` |
| Fixed-CB image's `0x80` MVP block becomes non-zero | `[wall]` |
| Render-target bind matches the copy-out page | `[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]` |

## 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 guest's GL draws forward and execute on the physical GPU and X is
reliable. The remaining gates are the beef GR ring resolution, the fixed-CB
image's zero MVP block, and the render-target bind 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. glxgears completes swaps and its GL
  draws execute on the physical GPU, but the replayed draw still writes 0
  pages: the beef ring, the fixed-CB image's zero MVP block and the
  render-target bind are unresolved.
* 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.