Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions quest/m1/gpu-ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,19 @@ skipping inside the Nix shell.
- `just rs nvidia`, a one-line recipe over `sh/rs/nvidia.sh`: symlink only those three libraries (by
soname) from `/usr/lib/x86_64-linux-gnu` into a private directory, put that
on `LD_LIBRARY_PATH`, and run that selection. Fail when a library is missing
instead of skipping. `just rs vulkan-cuda` (`sh/rs/vulkan-cuda.sh`) puts the
whole host driver directory on the path, which lets host libraries shadow
the Nix ones; fold it into this script and recipe, since its `vulkan_cuda_`
tests are the same kind. Those also need
instead of skipping. `sh/rs/vulkan-cuda.sh`, the NVIDIA branch of
`just rs gpu`, already symlinks those three libraries for its `vulkan_cuda_`
tests; widen it into this script rather than adding a second one. They also need
the Vulkan loader to find the host NVIDIA ICD: point it at the ICD manifest
and expose the driver libraries it names, or keep them in their own recipe.
- [One external GPU image](/quest/m2/gpu-surface.md) adds `just rs gpu`,
which detects the host's GPU vendors and runs each one's ignored tests.
`just rs nvidia` is its NVIDIA branch, not a second detector.
- `just rs gpu` (added by #4975) detects the host's GPU vendors and runs
each one's ignored tests. `just rs nvidia` is its NVIDIA branch, not a
second detector.
- The selection includes the `vulkan_cuda_` external-image tests in
`rs/moq-video/src/frame/cuda_test.rs`, which have never run on hardware.
`vulkan_cuda_auto_external_encode` must pass its per-plane pixel checks
against the CPU reference for both renditions, RGBA and BGRA, through
NVENC and CUDA external-image import (the verification #4975 deferred here).
- Nightly: a job in `.github/workflows/nightly.yml` runs `nix develop
--command just rs nvidia` on the self-hosted runner, a recipe and not a
script path, like every other workflow step. A self-hosted runner on a public repository must
Expand All @@ -56,4 +60,3 @@ Public API: none. Wire: none.
## Related

- [Video hardware validation](/quest/m3/video-hardware.md) - hardware paths nothing runs yet
- [One external GPU image](/quest/m2/gpu-surface.md) - the vendor-detecting `just rs gpu` recipe
1 change: 0 additions & 1 deletion quest/m2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ waiting on an upstream release waits in [m4](/quest/m4/README.md).
- [moq-transport cluster peers](/quest/m2/ietf-cluster-peers.md) - an extended cluster draft lets moq-transport relays peer again, carrying the cluster route layer
- [MSFTS convergence](/quest/m2/msfts-convergence.md) - the demultiplexed TS lane converges on MSFTS where the two still differ: program tables and the ES payload unit
- [VAAPI encode and decode](/quest/m2/video-vaapi.md) - H.265 encode and decode, pre-generated bindings, and pooled resize surfaces, including the moq-dev/vaapi release that carries them
- [One external GPU image for every encoder](/quest/m2/gpu-surface.md) - a vendor-neutral `Surface::Vulkan` that `Kind::Auto` routes to whichever backend imports it on its device; NVENC imports internally
- [Vulkan Video encode on AMD](/quest/m2/vulkan-encode.md) - H.264 and H.265 from an external Vulkan image on RADV, hand-rolled on ash, proven on an RX 9070
- [VA-API encodes an external Vulkan image](/quest/m2/vaapi-vulkan-import.md) - an explicit-sync DMA-BUF reaches Intel's encoder, proven on Arrow Lake
- [A release carries multi-vendor GPU input](/quest/m2/gpu-release.md) - `release` ships all three so a pinned consumer drops its vendor code
Expand Down
12 changes: 4 additions & 8 deletions quest/m2/gpu-health.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ utilization. It also reports device health (whether the device is usable,
lost, or reset) and the GPU model, which moq.pro's admission keys its
per-model limits on. The same API works on NVIDIA, AMD, and Intel, keyed by
the device's render node `dev_t`, the identity
[`Surface::Vulkan`](/quest/m2/gpu-surface.md) carries, so a caller writes no
`Surface::Vulkan` carries, so a caller writes no
vendor code. A value a driver cannot provide is absent, never guessed.

Not here: admission policy, thresholds, frame-lateness tracking, or draining.
Expand All @@ -18,7 +18,7 @@ Those are the caller's.
## Plan

Decided 2026-10-05 in moq.pro's quest audit: vendor-neutral now, not
NVIDIA-scoped. Reason: [GPU surface](/quest/m2/gpu-surface.md),
NVIDIA-scoped. Reason: the external GPU surface (#4975),
[Vulkan encode](/quest/m2/vulkan-encode.md), and
[VA-API import](/quest/m2/vaapi-vulkan-import.md) make AMD and Intel encode
first-class, so an NVML-shaped API would be rewritten once they land.
Expand All @@ -28,7 +28,7 @@ adopt this instead.
Decided 2026-10-05: one device identity everywhere, the render node's
`dev_t`, shared with [VA-API import](/quest/m2/vaapi-vulkan-import.md).
NVIDIA's device UUID maps to its node through `VK_EXT_physical_device_drm`.
That is why this Requires [GPU surface](/quest/m2/gpu-surface.md).
The external GPU surface (#4975) carries that identity.

Guidance, to be settled while building:

Expand Down Expand Up @@ -59,15 +59,11 @@ Guidance, to be settled while building:

Test: a unit test of each source's parsing against recorded fixtures, and
ignored hardware tests in `just rs gpu`'s per-vendor branches (the recipe
[GPU surface](/quest/m2/gpu-surface.md) adds) that open an encoder and see
#4975 added) that open an encoder and see
the session and memory counts move.

Public API: a device capacity and health snapshot in moq-video. Wire: none.

## Required

- [One external GPU image for every encoder](/quest/m2/gpu-surface.md) - the render node identity this keys by, and the `just rs gpu` recipe its tests run in

## Related

- [VA-API encodes an external Vulkan image](/quest/m2/vaapi-vulkan-import.md) - picks a render node by the same `dev_t`
Expand Down
1 change: 0 additions & 1 deletion quest/m2/gpu-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ maintainer at release time:

## Required

- [One external GPU image for every encoder](/quest/m2/gpu-surface.md) - the neutral surface and auto-selection
- [Vulkan Video encode on AMD](/quest/m2/vulkan-encode.md) - the AMD encoder
- [VA-API encodes an external Vulkan image](/quest/m2/vaapi-vulkan-import.md) - the Intel proof
- [GPU capacity and health](/quest/m2/gpu-health.md) - keyed by the same device identity; moq.pro's admission still needs vendor code without it
113 changes: 0 additions & 113 deletions quest/m2/gpu-surface.md

This file was deleted.

8 changes: 2 additions & 6 deletions quest/m2/vaapi-vulkan-import.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Goal

An external [`Surface::Vulkan`](/quest/m2/gpu-surface.md) exported as a
An external `Surface::Vulkan` exported as a
DMA-BUF with a DRM format modifier, from a producer that synchronizes
explicitly through a timeline, encodes through VA-API on Intel (iHD) without a
CPU round trip. An ignored hardware test proves it on an Arrow Lake iGPU, and
Expand Down Expand Up @@ -41,7 +41,7 @@ sync_file import, so an explicit-sync producer races it.
resize share it so a DMA-BUF moves between them without a copy. Choosing a
node per surface makes `device()` per-node, so keep decode, resize, and
encode on one node per DMA-BUF. Decided 2026-10-05: the producer puts the
render node's `dev_t` in the [surface](/quest/m2/gpu-surface.md), read from
render node's `dev_t` in the surface, read from
its own `VK_EXT_physical_device_drm`, and VA-API opens that node. It is
the one device identity [GPU health](/quest/m2/gpu-health.md) keys by too.
Rejected: mapping the surface's UUID to a node on the VA-API side, which
Expand All @@ -61,10 +61,6 @@ first render node: the second-node check moved here from

Public API: none beyond the surface quest's. Wire: none.

## Required

- [One external GPU image for every encoder](/quest/m2/gpu-surface.md) - the surface VA-API imports

## Related

- [Vulkan Video encode on AMD](/quest/m2/vulkan-encode.md) - the AMD half of the same proof
Expand Down
6 changes: 1 addition & 5 deletions quest/m2/vulkan-encode.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Goal

moq-video encodes an external [`Surface::Vulkan`](/quest/m2/gpu-surface.md)
moq-video encodes an external `Surface::Vulkan`
with Vulkan Video on AMD (RADV), in H.264 and H.265, scaled per rendition on
the GPU, with no CPU round trip. An ignored hardware test proves it on an
RX 9070, and `Kind::Auto` picks this backend for a surface on an AMD device
Expand Down Expand Up @@ -73,10 +73,6 @@ only if it costs nothing beyond cargo, per the rule in

Public API: a new encoder backend and feature. Wire: none.

## Required

- [One external GPU image for every encoder](/quest/m2/gpu-surface.md) - the surface this backend imports

## Related

- [VA-API encodes an external Vulkan image](/quest/m2/vaapi-vulkan-import.md) - the Intel half of the same proof
Expand Down
2 changes: 1 addition & 1 deletion quest/m3/obs-linux-gpu.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ the bottleneck.
## Related

- [Video hardware validation](/quest/m3/video-hardware.md) - native input and encoder acceptance need hardware evidence
- [VA-API encodes an external Vulkan image](/quest/m2/vaapi-vulkan-import.md) - explicit sync for an external DMA-BUF, and the public `DmaBuf` constructor from [One external GPU image](/quest/m2/gpu-surface.md)
- [VA-API encodes an external Vulkan image](/quest/m2/vaapi-vulkan-import.md) - explicit sync for an external DMA-BUF, and the public `DmaBuf` constructor from #4975
- [VAAPI encode and decode](/quest/m2/video-vaapi.md) - H.265 and checked-in bindings. The DMA-BUF encoder import this quest needs is already on main (moq-vaapi 0.1.0).
6 changes: 3 additions & 3 deletions rs/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ media-features:
test *args:
RUSTC_WORKSPACE_WRAPPER="$(command -v clippy-driver || true)" cargo nextest run --locked --all-targets "$@"

# Exercise Vulkan -> CUDA -> NVENC on Linux/NVIDIA hardware.
vulkan-cuda:
sh/rs/vulkan-cuda.sh
# Exercise the ignored hardware tests for every GPU vendor on this Linux host.
gpu:
sh/rs/gpu.sh

# The media tasks run against a recorder rather than a device (see
# `rs/moq-cli/src/play/fake.rs`), so this needs no speaker or display.
Expand Down
3 changes: 2 additions & 1 deletion rs/moq-video/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ mediacodec = ["dep:ndk"]
# zero-copy transcode path. Everything is dlopen'd at runtime, so a build with
# this on still links GPU-less and starts driverless, falling back to the next
# encoder or decoder.
nvidia = ["dep:cudarc", "dep:moq-nvenc", "dep:libloading"]
nvidia = ["dep:ash", "dep:cudarc", "dep:moq-nvenc", "dep:libloading"]
# Vendored, statically linked software H.264 encode/decode. Enabled by default,
# but separable from native codecs for hardware-only and minimal builds.
openh264 = ["dep:openh264", "dep:openh264-sys2"]
Expand Down Expand Up @@ -164,6 +164,7 @@ objc2-video-toolbox = "0.3.2"
ndk = { version = "0.9", optional = true, default-features = false, features = ["media", "api-level-26"] }

[target.'cfg(target_os="linux")'.dependencies]
ash = { workspace = true, optional = true }
# xdg-desktop-portal ScreenCast and Camera negotiation for the `pipewire` feature
# (pure Rust, zbus over DBus). The ScreenCast portal owns source selection: the
# user picks a monitor in a compositor dialog, and we get back a PipeWire fd +
Expand Down
Loading
Loading