wgpu_types/texture/
external_texture.rs

1#[cfg(any(feature = "serde", test))]
2use serde::{Deserialize, Serialize};
3
4#[cfg(doc)]
5use crate::TextureFormat;
6
7/// Format of an `ExternalTexture`. This indicates the number of underlying
8/// planes used by the `ExternalTexture` as well as each plane's format.
9#[repr(C)]
10#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12pub enum ExternalTextureFormat {
13    /// Single [`TextureFormat::Rgba8Unorm`] or [`TextureFormat::Bgra8Unorm`] format plane.
14    Rgba,
15    /// [`TextureFormat::R8Unorm`] Y plane, and [`TextureFormat::Rg8Unorm`]
16    /// interleaved CbCr plane.
17    Nv12,
18    /// Separate [`TextureFormat::R8Unorm`] Y, Cb, and Cr planes.
19    Yu12,
20}
21
22/// Parameters describing a gamma encoding transfer function in the form
23/// tf = { k * linear                   | linear < b
24///      { a * pow(linear, 1/g) - (a-1) | linear >= b
25#[repr(C)]
26#[derive(Clone, Copy, Debug, PartialEq, bytemuck::Zeroable, bytemuck::Pod)]
27#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
28#[allow(missing_docs)]
29pub struct ExternalTextureTransferFunction {
30    pub a: f32,
31    pub b: f32,
32    pub g: f32,
33    pub k: f32,
34}
35
36impl Default for ExternalTextureTransferFunction {
37    fn default() -> Self {
38        Self {
39            a: 1.0,
40            b: 1.0,
41            g: 1.0,
42            k: 1.0,
43        }
44    }
45}
46
47/// Describes an [`ExternalTexture`](../wgpu/struct.ExternalTexture.html).
48///
49/// Note that [`width`] and [`height`] are the values that should be returned by
50/// size queries in shader code; they do not necessarily match the dimensions of
51/// the underlying plane texture(s). As a special case, if `(width, height)` is
52/// `(0, 0)`, the actual size of the first underlying plane should be used instead.
53///
54/// The size given by [`width`] and [`height`] must be consistent with
55/// [`sample_transform`]: they should be the size in texels of the rectangle
56/// covered by the square (0,0)..(1,1) after [`sample_transform`] has been applied
57/// to it.
58///
59/// [`width`]: Self::width
60/// [`height`]: Self::height
61/// [`sample_transform`]: Self::sample_transform
62///
63/// Corresponds to [WebGPU `GPUExternalTextureDescriptor`](
64/// https://gpuweb.github.io/gpuweb/#dictdef-gpuexternaltexturedescriptor).
65#[repr(C)]
66#[derive(Clone, Debug, PartialEq)]
67#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
68pub struct ExternalTextureDescriptor<L> {
69    /// Debug label of the external texture. This will show up in graphics
70    /// debuggers for easy identification.
71    pub label: L,
72
73    /// Width of the external texture.
74    pub width: u32,
75
76    /// Height of the external texture.
77    pub height: u32,
78
79    /// Format of the external texture.
80    pub format: ExternalTextureFormat,
81
82    /// 4x4 column-major matrix with which to convert sampled YCbCr values
83    /// to RGBA.
84    /// This is ignored when `format` is [`ExternalTextureFormat::Rgba`].
85    pub yuv_conversion_matrix: [f32; 16],
86
87    /// 3x3 column-major matrix to transform linear RGB values in the source
88    /// color space to linear RGB values in the destination color space. In
89    /// combination with [`Self::src_transfer_function`] and
90    /// [`Self::dst_transfer_function`] this can be used to ensure that
91    /// [`ImageSample`] and [`ImageLoad`] operations return values in the
92    /// desired destination color space rather than the source color space of
93    /// the underlying planes.
94    ///
95    /// [`ImageSample`]: https://docs.rs/naga/latest/naga/ir/enum.Expression.html#variant.ImageSample
96    /// [`ImageLoad`]: https://docs.rs/naga/latest/naga/ir/enum.Expression.html#variant.ImageLoad
97    pub gamut_conversion_matrix: [f32; 9],
98
99    /// Transfer function for the source color space. The *inverse* of this
100    /// will be applied to decode non-linear RGB to linear RGB in the source
101    /// color space.
102    pub src_transfer_function: ExternalTextureTransferFunction,
103
104    /// Transfer function for the destination color space. This will be applied
105    /// to encode linear RGB to non-linear RGB in the destination color space.
106    pub dst_transfer_function: ExternalTextureTransferFunction,
107
108    /// Transform to apply to [`ImageSample`] coordinates.
109    ///
110    /// This is a 3x2 column-major matrix representing an affine transform from
111    /// normalized texture coordinates to the normalized coordinates that should
112    /// be sampled from the external texture's underlying plane(s).
113    ///
114    /// This transform may scale, translate, flip, and rotate in 90-degree
115    /// increments, but the result of transforming the rectangle (0,0)..(1,1)
116    /// must be an axis-aligned rectangle that falls within the bounds of
117    /// (0,0)..(1,1).
118    ///
119    /// [`ImageSample`]: https://docs.rs/naga/latest/naga/ir/enum.Expression.html#variant.ImageSample
120    pub sample_transform: [f32; 6],
121
122    /// Transform to apply to [`ImageLoad`] coordinates.
123    ///
124    /// This is a 3x2 column-major matrix representing an affine transform from
125    /// non-normalized texel coordinates to the non-normalized coordinates of
126    /// the texel that should be loaded from the external texture's underlying
127    /// plane 0. For planes 1 and 2, if present, plane 0's coordinates are
128    /// scaled according to the textures' relative sizes.
129    ///
130    /// This transform may scale, translate, flip, and rotate in 90-degree
131    /// increments, but the result of transforming the rectangle (0,0)..([`width`],
132    /// [`height`]) must be an axis-aligned rectangle that falls within the bounds
133    /// of (0,0)..([`width`], [`height`]).
134    ///
135    /// [`ImageLoad`]: https://docs.rs/naga/latest/naga/ir/enum.Expression.html#variant.ImageLoad
136    /// [`width`]: Self::width
137    /// [`height`]: Self::height
138    pub load_transform: [f32; 6],
139}
140
141impl<L> ExternalTextureDescriptor<L> {
142    /// Takes a closure and maps the label of the external texture descriptor into another.
143    #[must_use]
144    pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> ExternalTextureDescriptor<K> {
145        ExternalTextureDescriptor {
146            label: fun(&self.label),
147            width: self.width,
148            height: self.height,
149            format: self.format,
150            yuv_conversion_matrix: self.yuv_conversion_matrix,
151            sample_transform: self.sample_transform,
152            load_transform: self.load_transform,
153            gamut_conversion_matrix: self.gamut_conversion_matrix,
154            src_transfer_function: self.src_transfer_function,
155            dst_transfer_function: self.dst_transfer_function,
156        }
157    }
158
159    /// The number of underlying planes used by the external texture.
160    pub fn num_planes(&self) -> usize {
161        match self.format {
162            ExternalTextureFormat::Rgba => 1,
163            ExternalTextureFormat::Nv12 => 2,
164            ExternalTextureFormat::Yu12 => 3,
165        }
166    }
167}