Skip to main content

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}