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