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}
15#[cfg(send_sync)]
16static_assertions::assert_impl_all!(Texture: Send, Sync);
17
18crate::cmp::impl_eq_ord_hash_proxy!(Texture => .inner);
19
20impl Texture {
21    /// Get the [`wgpu_hal`] texture from this `Texture`.
22    ///
23    /// Find the Api struct corresponding to the active backend in [`wgpu_hal::api`],
24    /// and pass that struct to the to the `A` type parameter.
25    ///
26    /// Returns a guard that dereferences to the type of the hal backend
27    /// which implements [`A::Texture`].
28    ///
29    /// # Types
30    ///
31    /// The returned type depends on the backend:
32    ///
33    #[doc = crate::macros::hal_type_vulkan!("Texture")]
34    #[doc = crate::macros::hal_type_metal!("Texture")]
35    #[doc = crate::macros::hal_type_dx12!("Texture")]
36    #[doc = crate::macros::hal_type_gles!("Texture")]
37    ///
38    /// # Deadlocks
39    ///
40    /// - The returned guard holds a read-lock on a device-local "destruction"
41    ///   lock, which will cause all calls to `destroy` to block until the
42    ///   guard is released.
43    ///
44    /// # Errors
45    ///
46    /// This method will return None if:
47    /// - The texture is not from the backend specified by `A`.
48    /// - The texture is from [`Backend::BrowserWebGpu`].
49    ///   (Use `Texture::as_webgpu()` instead.)
50    /// - The texture is from a custom backend.
51    ///
52    /// # Safety
53    ///
54    /// - The returned resource must not be destroyed unless the guard
55    ///   is the last reference to it and it is not in use by the GPU.
56    ///   The guard and handle may be dropped at any time however.
57    /// - All the safety requirements of wgpu-hal must be upheld.
58    ///
59    /// [`A::Texture`]: hal::Api::Texture
60    #[cfg(wgpu_core)]
61    pub unsafe fn as_hal<A: hal::Api>(&self) -> Option<impl Deref<Target = A::Texture>> {
62        let texture = self.inner.as_core_opt()?;
63        unsafe { texture.as_hal::<A>() }
64    }
65
66    /// Returns the underlying [`webgpu::GpuTexture`] handle if this `Texture`
67    /// is on the WebGPU backend.
68    ///
69    /// Use this on the WebGPU backend instead of [`Self::as_hal`].
70    ///
71    /// The returned handle is the same JS object wgpu uses internally; it can
72    /// be passed to other WebGPU-aware JS APIs, used for identity comparison,
73    /// or fed back into [`Device::create_texture_from_webgpu_handle`].
74    #[cfg(webgpu)]
75    pub fn as_webgpu(&self) -> Option<&webgpu::GpuTexture> {
76        self.inner.as_webgpu_opt().map(|wt| &wt.inner)
77    }
78
79    #[cfg(custom)]
80    /// Returns custom implementation of Texture (if custom backend and is internally T)
81    pub fn as_custom<T: custom::TextureInterface>(&self) -> Option<&T> {
82        self.inner.as_custom()
83    }
84
85    #[cfg(custom)]
86    /// Creates a texture from already created custom implementation with the given description
87    pub fn from_custom<T: custom::TextureInterface>(texture: T) -> Self {
88        Self {
89            inner: dispatch::DispatchTexture::custom(texture),
90        }
91    }
92
93    /// Creates a view of this texture, specifying an interpretation of its texels and
94    /// possibly a subset of its layers and mip levels.
95    ///
96    /// Texture views are needed to use a texture as a binding in a [`BindGroup`]
97    /// or as an attachment in a [`RenderPass`].
98    pub fn create_view(&self, desc: &TextureViewDescriptor<'_>) -> TextureView {
99        let view = self.inner.create_view(desc);
100
101        TextureView {
102            inner: view,
103            texture: self.clone(),
104        }
105    }
106
107    /// Destroy the associated native resources as soon as possible.
108    pub fn destroy(&self) {
109        self.inner.destroy();
110    }
111
112    /// Make an `TexelCopyTextureInfo` representing the whole texture.
113    pub fn as_image_copy(&self) -> TexelCopyTextureInfo<'_> {
114        TexelCopyTextureInfo {
115            texture: self,
116            mip_level: 0,
117            origin: Origin3d::ZERO,
118            aspect: TextureAspect::All,
119        }
120    }
121
122    /// Returns the size of this `Texture`.
123    ///
124    /// This is always equal to the `size` that was specified when creating the texture.
125    pub fn size(&self) -> Extent3d {
126        self.inner.size()
127    }
128
129    /// Returns the width of this `Texture`.
130    ///
131    /// This is always equal to the `size.width` that was specified when creating the texture.
132    pub fn width(&self) -> u32 {
133        self.inner.size().width
134    }
135
136    /// Returns the height of this `Texture`.
137    ///
138    /// This is always equal to the `size.height` that was specified when creating the texture.
139    pub fn height(&self) -> u32 {
140        self.inner.size().height
141    }
142
143    /// Returns the depth or layer count of this `Texture`.
144    ///
145    /// This is always equal to the `size.depth_or_array_layers` that was specified when creating the texture.
146    pub fn depth_or_array_layers(&self) -> u32 {
147        self.inner.size().depth_or_array_layers
148    }
149
150    /// Returns the mip_level_count of this `Texture`.
151    ///
152    /// This is always equal to the `mip_level_count` that was specified when creating the texture.
153    pub fn mip_level_count(&self) -> u32 {
154        self.inner.mip_level_count()
155    }
156
157    /// Returns the sample_count of this `Texture`.
158    ///
159    /// This is always equal to the `sample_count` that was specified when creating the texture.
160    pub fn sample_count(&self) -> u32 {
161        self.inner.sample_count()
162    }
163
164    /// Returns the dimension of this `Texture`.
165    ///
166    /// This is always equal to the `dimension` that was specified when creating the texture.
167    pub fn dimension(&self) -> TextureDimension {
168        self.inner.dimension()
169    }
170
171    /// Returns the format of this `Texture`.
172    ///
173    /// This is always equal to the `format` that was specified when creating the texture.
174    pub fn format(&self) -> TextureFormat {
175        self.inner.format()
176    }
177
178    /// Returns the allowed usages of this `Texture`.
179    ///
180    /// This is always equal to the `usage` that was specified when creating the texture.
181    pub fn usage(&self) -> TextureUsages {
182        self.inner.usage()
183    }
184
185    /// Marks this texture's contents as already initialized, skipping wgpu's
186    /// lazy zero-initialization of it.
187    ///
188    /// This is a no-op on backends without a concept of lazy
189    /// zero-initialization, such as WebGPU.
190    ///
191    /// # Safety
192    ///
193    /// The entire contents of the texture must already be initialized, e.g. by
194    /// writing to it through the handle returned by [`Texture::as_hal`].
195    pub unsafe fn mark_externally_initialized(&self) {
196        unsafe { self.inner.mark_externally_initialized() }
197    }
198}
199
200/// Describes a [`Texture`].
201///
202/// For use with [`Device::create_texture`].
203///
204/// Corresponds to [WebGPU `GPUTextureDescriptor`](
205/// https://gpuweb.github.io/gpuweb/#dictdef-gputexturedescriptor).
206pub type TextureDescriptor<'a> = wgt::TextureDescriptor<Label<'a>, &'a [TextureFormat]>;
207static_assertions::assert_impl_all!(TextureDescriptor<'_>: Send, Sync);