Skip to main content

molgfx_gpu/
host.rs

1//! Host-supplied GPU contexts and render targets.
2//!
3//! The one place the abstraction admits that a process may already own a GPU
4//! context: an embedding application (a desktop shell, a compositor, another
5//! engine) hands the renderer its device and queue, and its textures, instead
6//! of letting the renderer open its own. Everything here is an interface; the
7//! backend decides what its native handles are.
8
9use crate::{Device, GpuError, Opened, TextureFormat};
10
11/// How a host-supplied device is adopted.
12#[derive(Clone, Copy, Debug, Default)]
13pub struct HostDeviceDesc {
14    /// Optional hard ceiling for live buffer and texture bytes the renderer
15    /// allocates on the host's device. The host's own resources are not
16    /// counted.
17    pub resource_memory_limit_bytes: Option<u64>,
18    /// Whether the renderer installs its own asynchronous error and device-loss
19    /// handlers on the device. Handlers are per device, so installing them
20    /// replaces the host's. The default leaves them alone.
21    pub observe_device_errors: bool,
22}
23
24/// What importing a host texture established about it.
25#[derive(Clone, Copy, PartialEq, Eq, Debug)]
26pub struct ImportedTarget {
27    /// Width in texels.
28    pub width: u32,
29    /// Height in texels.
30    pub height: u32,
31    /// The host texture's own format.
32    pub texture_format: TextureFormat,
33    /// The format the renderer writes through: the linear member of the
34    /// texture's format family.
35    pub render_format: TextureFormat,
36}
37
38impl TextureFormat {
39    /// The linear member of an sRGB format family; every other format is its
40    /// own. The renderer writes display-encoded values through this view, so
41    /// an sRGB texture holds the same bytes a linear one does and samples
42    /// back correctly.
43    #[must_use]
44    pub const fn without_srgb(self) -> Self {
45        match self {
46            Self::Rgba8UnormSrgb => Self::Rgba8Unorm,
47            Self::Bgra8UnormSrgb => Self::Bgra8Unorm,
48            other => other,
49        }
50    }
51
52    /// Whether this format may be the renderer's output format on a host
53    /// target.
54    #[must_use]
55    pub const fn is_host_output(self) -> bool {
56        matches!(self, Self::Rgba8Unorm | Self::Bgra8Unorm)
57    }
58}
59
60/// A device that can adopt a host's GPU context and render into its textures.
61pub trait HostDevice: Device {
62    /// The backend-native handles the host owns and lends: the adapter,
63    /// device and queue it already opened.
64    type Context;
65    /// A backend-native texture handle. Cloning shares the underlying
66    /// texture; the host's clone keeps it alive for as long as it likes.
67    type ExternalTexture: Clone + std::fmt::Debug;
68
69    /// Adopts the host's context instead of opening a device.
70    ///
71    /// # Errors
72    ///
73    /// [`GpuError::HostRequirements`] names every feature, limit or format
74    /// capability the context lacks.
75    fn adopt(context: Self::Context, desc: &HostDeviceDesc) -> Result<Opened<Self>, GpuError>;
76
77    /// Checks a host texture against what rendering needs and creates the
78    /// view the renderer will attach.
79    ///
80    /// # Errors
81    ///
82    /// [`GpuError::HostTarget`] names every way the texture is unusable.
83    fn import_target(
84        &self,
85        texture: &Self::ExternalTexture,
86        render_format: TextureFormat,
87    ) -> Result<(Self::TextureView, ImportedTarget), GpuError>;
88
89    /// A shareable native handle to a texture this device created, so the host
90    /// can sample or copy a renderer-owned target.
91    fn export_texture(&self, texture: &Self::Texture) -> Self::ExternalTexture;
92}