wgpu/api/
texture.rs

1use std::{sync::Arc, thread};
2
3use crate::context::DynContext;
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)]
12pub struct Texture {
13    pub(crate) context: Arc<C>,
14    pub(crate) data: Box<Data>,
15    pub(crate) descriptor: TextureDescriptor<'static>,
16}
17#[cfg(send_sync)]
18static_assertions::assert_impl_all!(Texture: Send, Sync);
19
20super::impl_partialeq_eq_hash!(Texture);
21
22impl Texture {
23    /// Returns the inner hal Texture using a callback. The hal texture will be `None` if the
24    /// backend type argument does not match with this wgpu Texture
25    ///
26    /// # Safety
27    ///
28    /// - The raw handle obtained from the hal Texture must not be manually destroyed
29    #[cfg(wgpu_core)]
30    pub unsafe fn as_hal<A: wgc::hal_api::HalApi, F: FnOnce(Option<&A::Texture>) -> R, R>(
31        &self,
32        hal_texture_callback: F,
33    ) -> R {
34        if let Some(ctx) = self
35            .context
36            .as_any()
37            .downcast_ref::<crate::backend::ContextWgpuCore>()
38        {
39            unsafe {
40                ctx.texture_as_hal::<A, F, R>(
41                    crate::context::downcast_ref(self.data.as_ref()),
42                    hal_texture_callback,
43                )
44            }
45        } else {
46            hal_texture_callback(None)
47        }
48    }
49
50    /// Creates a view of this texture.
51    pub fn create_view(&self, desc: &TextureViewDescriptor<'_>) -> TextureView {
52        let data = DynContext::texture_create_view(&*self.context, self.data.as_ref(), desc);
53        TextureView {
54            context: Arc::clone(&self.context),
55            data,
56        }
57    }
58
59    /// Destroy the associated native resources as soon as possible.
60    pub fn destroy(&self) {
61        DynContext::texture_destroy(&*self.context, self.data.as_ref());
62    }
63
64    /// Make an `ImageCopyTexture` representing the whole texture.
65    pub fn as_image_copy(&self) -> ImageCopyTexture<'_> {
66        ImageCopyTexture {
67            texture: self,
68            mip_level: 0,
69            origin: Origin3d::ZERO,
70            aspect: TextureAspect::All,
71        }
72    }
73
74    /// Returns the size of this `Texture`.
75    ///
76    /// This is always equal to the `size` that was specified when creating the texture.
77    pub fn size(&self) -> Extent3d {
78        self.descriptor.size
79    }
80
81    /// Returns the width of this `Texture`.
82    ///
83    /// This is always equal to the `size.width` that was specified when creating the texture.
84    pub fn width(&self) -> u32 {
85        self.descriptor.size.width
86    }
87
88    /// Returns the height of this `Texture`.
89    ///
90    /// This is always equal to the `size.height` that was specified when creating the texture.
91    pub fn height(&self) -> u32 {
92        self.descriptor.size.height
93    }
94
95    /// Returns the depth or layer count of this `Texture`.
96    ///
97    /// This is always equal to the `size.depth_or_array_layers` that was specified when creating the texture.
98    pub fn depth_or_array_layers(&self) -> u32 {
99        self.descriptor.size.depth_or_array_layers
100    }
101
102    /// Returns the mip_level_count of this `Texture`.
103    ///
104    /// This is always equal to the `mip_level_count` that was specified when creating the texture.
105    pub fn mip_level_count(&self) -> u32 {
106        self.descriptor.mip_level_count
107    }
108
109    /// Returns the sample_count of this `Texture`.
110    ///
111    /// This is always equal to the `sample_count` that was specified when creating the texture.
112    pub fn sample_count(&self) -> u32 {
113        self.descriptor.sample_count
114    }
115
116    /// Returns the dimension of this `Texture`.
117    ///
118    /// This is always equal to the `dimension` that was specified when creating the texture.
119    pub fn dimension(&self) -> TextureDimension {
120        self.descriptor.dimension
121    }
122
123    /// Returns the format of this `Texture`.
124    ///
125    /// This is always equal to the `format` that was specified when creating the texture.
126    pub fn format(&self) -> TextureFormat {
127        self.descriptor.format
128    }
129
130    /// Returns the allowed usages of this `Texture`.
131    ///
132    /// This is always equal to the `usage` that was specified when creating the texture.
133    pub fn usage(&self) -> TextureUsages {
134        self.descriptor.usage
135    }
136}
137
138impl Drop for Texture {
139    fn drop(&mut self) {
140        if !thread::panicking() {
141            self.context.texture_drop(self.data.as_ref());
142        }
143    }
144}
145
146/// Describes a [`Texture`].
147///
148/// For use with [`Device::create_texture`].
149///
150/// Corresponds to [WebGPU `GPUTextureDescriptor`](
151/// https://gpuweb.github.io/gpuweb/#dictdef-gputexturedescriptor).
152pub type TextureDescriptor<'a> = wgt::TextureDescriptor<Label<'a>, &'a [TextureFormat]>;
153static_assertions::assert_impl_all!(TextureDescriptor<'_>: Send, Sync);