wgpu/api/
texture.rs

1#[cfg(wgpu_core)]
2use core::ops::Deref;
3
4use crate::*;
5
6/// Handle to a texture on the GPU.
7///
8/// It can be created with [`Device::create_texture`].
9///
10/// Corresponds to [WebGPU `GPUTexture`](https://gpuweb.github.io/gpuweb/#texture-interface).
11#[derive(Debug, Clone)]
12pub struct Texture {
13    pub(crate) inner: dispatch::DispatchTexture,
14    pub(crate) descriptor: TextureDescriptor<'static>,
15}
16#[cfg(send_sync)]
17static_assertions::assert_impl_all!(Texture: Send, Sync);
18
19crate::cmp::impl_eq_ord_hash_proxy!(Texture => .inner);
20
21impl Texture {
22    /// Get the [`wgpu_hal`] texture from this `Texture`.
23    ///
24    /// Find the Api struct corresponding to the active backend in [`wgpu_hal::api`],
25    /// and pass that struct to the to the `A` type parameter.
26    ///
27    /// Returns a guard that dereferences to the type of the hal backend
28    /// which implements [`A::Texture`].
29    ///
30    /// # Deadlocks
31    ///
32    /// - The returned guard holds a read-lock on a device-local "destruction"
33    ///   lock, which will cause all calls to `destroy` to block until the
34    ///   guard is released.
35    ///
36    /// # Errors
37    ///
38    /// This method will return None if:
39    /// - The texture is not from the backend specified by `A`.
40    /// - The texture is from the `webgpu` or `custom` backend.
41    /// - The texture has had [`Self::destroy()`] called on it.
42    ///
43    /// # Safety
44    ///
45    /// - The returned resource must not be destroyed unless the guard
46    ///   is the last reference to it and it is not in use by the GPU.
47    ///   The guard and handle may be dropped at any time however.
48    /// - All the safety requirements of wgpu-hal must be upheld.
49    ///
50    /// [`A::Texture`]: hal::Api::Texture
51    #[cfg(wgpu_core)]
52    pub unsafe fn as_hal<A: wgc::hal_api::HalApi>(
53        &self,
54    ) -> Option<impl Deref<Target = A::Texture>> {
55        let texture = self.inner.as_core_opt()?;
56        unsafe { texture.context.texture_as_hal::<A>(texture) }
57    }
58
59    #[cfg(custom)]
60    /// Returns custom implementation of Texture (if custom backend and is internally T)
61    pub fn as_custom<T: custom::TextureInterface>(&self) -> Option<&T> {
62        self.inner.as_custom()
63    }
64
65    /// Creates a view of this texture, specifying an interpretation of its texels and
66    /// possibly a subset of its layers and mip levels.
67    ///
68    /// Texture views are needed to use a texture as a binding in a [`BindGroup`]
69    /// or as an attachment in a [`RenderPass`].
70    pub fn create_view(&self, desc: &TextureViewDescriptor<'_>) -> TextureView {
71        let view = self.inner.create_view(desc);
72
73        TextureView {
74            inner: view,
75            texture: self.clone(),
76        }
77    }
78
79    /// Destroy the associated native resources as soon as possible.
80    pub fn destroy(&self) {
81        self.inner.destroy();
82    }
83
84    /// Make an `TexelCopyTextureInfo` representing the whole texture.
85    pub fn as_image_copy(&self) -> TexelCopyTextureInfo<'_> {
86        TexelCopyTextureInfo {
87            texture: self,
88            mip_level: 0,
89            origin: Origin3d::ZERO,
90            aspect: TextureAspect::All,
91        }
92    }
93
94    /// Returns the size of this `Texture`.
95    ///
96    /// This is always equal to the `size` that was specified when creating the texture.
97    pub fn size(&self) -> Extent3d {
98        self.descriptor.size
99    }
100
101    /// Returns the width of this `Texture`.
102    ///
103    /// This is always equal to the `size.width` that was specified when creating the texture.
104    pub fn width(&self) -> u32 {
105        self.descriptor.size.width
106    }
107
108    /// Returns the height of this `Texture`.
109    ///
110    /// This is always equal to the `size.height` that was specified when creating the texture.
111    pub fn height(&self) -> u32 {
112        self.descriptor.size.height
113    }
114
115    /// Returns the depth or layer count of this `Texture`.
116    ///
117    /// This is always equal to the `size.depth_or_array_layers` that was specified when creating the texture.
118    pub fn depth_or_array_layers(&self) -> u32 {
119        self.descriptor.size.depth_or_array_layers
120    }
121
122    /// Returns the mip_level_count of this `Texture`.
123    ///
124    /// This is always equal to the `mip_level_count` that was specified when creating the texture.
125    pub fn mip_level_count(&self) -> u32 {
126        self.descriptor.mip_level_count
127    }
128
129    /// Returns the sample_count of this `Texture`.
130    ///
131    /// This is always equal to the `sample_count` that was specified when creating the texture.
132    pub fn sample_count(&self) -> u32 {
133        self.descriptor.sample_count
134    }
135
136    /// Returns the dimension of this `Texture`.
137    ///
138    /// This is always equal to the `dimension` that was specified when creating the texture.
139    pub fn dimension(&self) -> TextureDimension {
140        self.descriptor.dimension
141    }
142
143    /// Returns the format of this `Texture`.
144    ///
145    /// This is always equal to the `format` that was specified when creating the texture.
146    pub fn format(&self) -> TextureFormat {
147        self.descriptor.format
148    }
149
150    /// Returns the allowed usages of this `Texture`.
151    ///
152    /// This is always equal to the `usage` that was specified when creating the texture.
153    pub fn usage(&self) -> TextureUsages {
154        self.descriptor.usage
155    }
156}
157
158/// Describes a [`Texture`].
159///
160/// For use with [`Device::create_texture`].
161///
162/// Corresponds to [WebGPU `GPUTextureDescriptor`](
163/// https://gpuweb.github.io/gpuweb/#dictdef-gputexturedescriptor).
164pub type TextureDescriptor<'a> = wgt::TextureDescriptor<Label<'a>, &'a [TextureFormat]>;
165static_assertions::assert_impl_all!(TextureDescriptor<'_>: Send, Sync);