mediaway_common/gpu.rs
1//! Opaque GPU resource handles for Zero-Copy encode/decode paths.
2//!
3//! Platform backends cast [`NativeHandle`] bits to native pointers. This crate stays
4//! `forbid(unsafe_code)`; all casting lives in `mediaway-*-<platform>` crates.
5//! Ownership and fence contracts are documented in those backends’ ADRs.
6//!
7//! Framework bridges (wgpu, WebGPU, Dawn): [`docs/spec/gpu-interop.md`].
8
9#![forbid(unsafe_code)]
10
11use core::num::NonZeroUsize;
12
13/// Opaque non-null native pointer / `HANDLE` bits.
14///
15/// Backs every "raw platform handle" field in [`GpuBufferHandle`] and
16/// [`GpuDeviceHandle`] (and the `gpu_device` config field in
17/// `mediaway-encoder`/`mediaway-decoder`/`mediaway-device`). Never dereferenced
18/// in this crate — platform backends cast [`NativeHandle::get`] to/from the
19/// real pointer type. Backed by [`NonZeroUsize`] so "unset" is
20/// `Option<NativeHandle>::None` instead of a `0` sentinel repeated in doc
21/// comments; the niche keeps `Option<NativeHandle>` the same size as `usize`.
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
23pub struct NativeHandle(NonZeroUsize);
24
25impl NativeHandle {
26 /// Wrap native pointer bits. `None` when `bits == 0`.
27 #[must_use]
28 pub const fn new(bits: usize) -> Option<Self> {
29 match NonZeroUsize::new(bits) {
30 Some(n) => Some(Self(n)),
31 None => None,
32 }
33 }
34
35 /// Recover the native pointer bits for an FFI cast.
36 #[must_use]
37 pub const fn get(self) -> usize {
38 self.0.get()
39 }
40}
41
42/// Native GPU buffer / texture handle without CPU readback.
43///
44/// Variants are declared early so facades can name Zero-Copy inputs. Backends
45/// that do not support a variant return an explicit unsupported error — never
46/// silently read back.
47#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
48#[non_exhaustive]
49pub enum GpuBufferHandle {
50 /// `ID3D11Texture2D*` (+ subresource index).
51 DirectX11 {
52 /// Opaque texture pointer.
53 texture: NativeHandle,
54 /// Subresource / array slice.
55 subresource: u32,
56 },
57 /// `ID3D12Resource*` (or agreed shared representation in the Windows ADR).
58 DirectX12 {
59 /// Opaque resource pointer.
60 resource: NativeHandle,
61 },
62 /// Windows shared `HANDLE` for cross-device / wgpu HAL export.
63 DirectXShared {
64 /// Opaque `HANDLE`.
65 handle: NativeHandle,
66 },
67 /// Metal / `CVPixelBuffer` / `IOSurface` token (Apple backends).
68 Metal {
69 /// Opaque native pointer.
70 buffer: NativeHandle,
71 },
72 /// `AHardwareBuffer*` (Android).
73 AndroidSurface {
74 /// Opaque buffer pointer.
75 buffer: NativeHandle,
76 },
77 /// Vulkan image + binding token (layout decided in Linux ADR).
78 Vulkan {
79 /// Opaque `VkImage` (or wrapper).
80 image: NativeHandle,
81 /// Opaque device/memory cookie for the backend.
82 memory: NativeHandle,
83 },
84 /// Browser / WASM `GPUTexture` host token.
85 WebGpu {
86 /// Host-defined texture id (not a raw WASM pointer).
87 texture_id: u64,
88 },
89}
90
91/// Native GPU **device** handle — owns the buffers submitted via [`GpuBufferHandle`].
92///
93/// Mirrors `GpuBufferHandle`'s platform variants but names the device, not a
94/// buffer (e.g. the `ID3D11Device*` that must own submitted `DirectX11`
95/// textures). Facade configs (`VideoEncoderConfig::gpu_device`, …) use
96/// `Option<GpuDeviceHandle>` — `None` means no Zero-Copy device was supplied.
97/// `#[non_exhaustive]`: declared ahead of backend support, like
98/// [`GpuBufferHandle`].
99#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
100#[non_exhaustive]
101pub enum GpuDeviceHandle {
102 /// `ID3D11Device*`.
103 DirectX11(NativeHandle),
104 /// `ID3D12Device*`.
105 DirectX12(NativeHandle),
106 /// `VkDevice` (or wrapper token; layout decided in Linux ADR).
107 Vulkan(NativeHandle),
108 /// `MTLDevice` (Apple backends).
109 Metal(NativeHandle),
110 /// Browser / WASM `GPUDevice` host token (not a raw WASM pointer).
111 WebGpu {
112 /// Host-defined device id.
113 device_id: u64,
114 },
115}