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}