Vulkan

From Open-IOV
Jump to navigation Jump to search

An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.

This CC-BY-4.0 licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.

Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.

Vulkan

Scope. How a stock guest Vulkan application runs on the emulated vGPU: the guest-side stack, the submit/completion path, and the honest state of the work — including the one thing every Vulkan run on the emulated vGPU currently has in common: the pipeline completes, and the frames are black. The shared host machinery is on Graphics-Execution.md; the CUDA compute chain (further along) is on Execution-Frontier.md. Canonical sources: ../docs/04-implementation/04-real-render-walls.md and ../docs/04-implementation/05-graphics-execution-plan.md; the docs tree wins on disagreement.

Status: 2026-10-30, tree master @ b4930168. Tags: [live] observed with the stock guest driver; [wip] partial; [wall] current blocker; [target] defined success state.

1. The guest Vulkan stack

A Vulkan application loads the loader (libvulkan.so), which dispatches to an installable client driver (ICD) — for NVIDIA GPUs, the NVIDIA Vulkan driver. On Linux, Vulkan compute does not require an X server; the display path does (through nvidia-modeset/DRM for presentation). The kernel-side requirements are the same as CUDA's: nvidia.ko, the GSP client, channels, memory objects and fences.

At device creation the driver also walks the display/modeset device allocation path (the ALLOC_DEVICE class family) — on a vGPU-style device the driver expects the host to provide those display classes, which the emulation must answer for vkCreateDevice to succeed. Past that gate, the driver behaves much like the compute stack: memory types through its VidHeap classes, queues as channels, and work as method streams.

2. The submit and completion path (observed)

One Vulkan queue submit end to end on the emulated vGPU.
app: vkQueueSubmit(fence)
  -> NVIDIA driver: push buffer + GPFIFO entry + doorbell
  -> vgsp.ko: capture section, translate to a vendor launch,
     relocate operands into shadow pages, submit on a real channel
  -> physical GPU: front-end fetch, engine executes, authors release
  -> vgsp.ko: completion relay (MSI-X + poller) back to the guest
  -> app: fence releases; frame readback proceeds
ASCII fallback above; the sequence shows one queue submit end to end.

Two mechanics make this work today: the emulation decodes the driver's compute-dispatch shape — a direct method stream (object bind, window runs, code runs, a subchannel data-port stream) with no inline launch descriptor — and translates it into a launch the real engine accepts, and it derives the submit's release groups from the driver's own push words so the fence value is released when the engine completes (the "fence fold": the pre-built GPFIFO continuation beyond the put pointer is swept and the submit's release groups are applied forward-only).

3. Status on the emulated vGPU

Item State
vkCreateDevice on the emulated vGPU (display/modeset allocation path answered) [live]
Full pipeline: instance, device, allocation, image/view/buffer/shader/descriptor, pipeline, command buffer, fence [live]
Queue submit, engine-side execution of the translated launch, fence release, frame readback [live]
The client saves frames end to end (VKFRAME evidence) [live]
Non-black frames [wall]
The driver's program (SASS) upload materialised by the emulation [wall]
The engine's page tables mapping the program VA [wall]

4. Where the wall is, precisely

The client believes it uploaded its shader and dispatches with a valid program address, but the bytes never appear in any source the emulation can see: the driver delivers programmed SASS and descriptors through an MME program + inline-to-memory stream on its copy/utility channel, and the inline-data writes are not yet materialised for the graphics clients. Two coupled facts define the remaining work:

  1. Delivery — decode and execute the driver's inline upload so the program page becomes non-zero (the same machinery already works for CUDA's uploads; the graphics clients' shapes are the extension).
  2. Mapping — the engine's page tables must map the program VA. With the data-set gate bypassed, the engine fetches the launch and raises a real MMU fault (FAULT_PDE) at the program VA — proof the channel, context and fetch path are alive, and that mapping plus content is the missing pair.

When both land, the emulated vGPU should carry its first non-black Vulkan frame — the milestone the whole graphics effort is converging on (Graphics-Execution.md §6).

5. What this page is not claiming

  • No rendered pixels yet — every frame saved so far is black.
  • No performance numbers.
  • vkCreateDevice success does not imply rendering; it means the device model answers the driver's device-view correctly.

6. Related pages