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::hal_type_vulkan!("Texture")]
35 #[doc = crate::hal_type_metal!("Texture")]
36 #[doc = crate::hal_type_dx12!("Texture")]
37 #[doc = crate::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 the `webgpu` or `custom` backend.
50 /// - The texture has had [`Self::destroy()`] called on it.
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.context.texture_as_hal::<A>(texture) }
64 }
65
66 #[cfg(custom)]
67 /// Returns custom implementation of Texture (if custom backend and is internally T)
68 pub fn as_custom<T: custom::TextureInterface>(&self) -> Option<&T> {
69 self.inner.as_custom()
70 }
71
72 #[cfg(custom)]
73 /// Creates a texture from already created custom implementation with the given description
74 pub fn from_custom<T: custom::TextureInterface>(
75 texture: T,
76 desc: &TextureDescriptor<'_>,
77 ) -> Self {
78 Self {
79 inner: dispatch::DispatchTexture::custom(texture),
80 descriptor: TextureDescriptor {
81 label: None,
82 view_formats: &[],
83 ..desc.clone()
84 },
85 }
86 }
87
88 /// Creates a view of this texture, specifying an interpretation of its texels and
89 /// possibly a subset of its layers and mip levels.
90 ///
91 /// Texture views are needed to use a texture as a binding in a [`BindGroup`]
92 /// or as an attachment in a [`RenderPass`].
93 pub fn create_view(&self, desc: &TextureViewDescriptor<'_>) -> TextureView {
94 let view = self.inner.create_view(desc);
95
96 TextureView {
97 inner: view,
98 texture: self.clone(),
99 }
100 }
101
102 /// Destroy the associated native resources as soon as possible.
103 pub fn destroy(&self) {
104 self.inner.destroy();
105 }
106
107 /// Make an `TexelCopyTextureInfo` representing the whole texture.
108 pub fn as_image_copy(&self) -> TexelCopyTextureInfo<'_> {
109 TexelCopyTextureInfo {
110 texture: self,
111 mip_level: 0,
112 origin: Origin3d::ZERO,
113 aspect: TextureAspect::All,
114 }
115 }
116
117 /// Returns the size of this `Texture`.
118 ///
119 /// This is always equal to the `size` that was specified when creating the texture.
120 pub fn size(&self) -> Extent3d {
121 self.descriptor.size
122 }
123
124 /// Returns the width of this `Texture`.
125 ///
126 /// This is always equal to the `size.width` that was specified when creating the texture.
127 pub fn width(&self) -> u32 {
128 self.descriptor.size.width
129 }
130
131 /// Returns the height of this `Texture`.
132 ///
133 /// This is always equal to the `size.height` that was specified when creating the texture.
134 pub fn height(&self) -> u32 {
135 self.descriptor.size.height
136 }
137
138 /// Returns the depth or layer count of this `Texture`.
139 ///
140 /// This is always equal to the `size.depth_or_array_layers` that was specified when creating the texture.
141 pub fn depth_or_array_layers(&self) -> u32 {
142 self.descriptor.size.depth_or_array_layers
143 }
144
145 /// Returns the mip_level_count of this `Texture`.
146 ///
147 /// This is always equal to the `mip_level_count` that was specified when creating the texture.
148 pub fn mip_level_count(&self) -> u32 {
149 self.descriptor.mip_level_count
150 }
151
152 /// Returns the sample_count of this `Texture`.
153 ///
154 /// This is always equal to the `sample_count` that was specified when creating the texture.
155 pub fn sample_count(&self) -> u32 {
156 self.descriptor.sample_count
157 }
158
159 /// Returns the dimension of this `Texture`.
160 ///
161 /// This is always equal to the `dimension` that was specified when creating the texture.
162 pub fn dimension(&self) -> TextureDimension {
163 self.descriptor.dimension
164 }
165
166 /// Returns the format of this `Texture`.
167 ///
168 /// This is always equal to the `format` that was specified when creating the texture.
169 pub fn format(&self) -> TextureFormat {
170 self.descriptor.format
171 }
172
173 /// Returns the allowed usages of this `Texture`.
174 ///
175 /// This is always equal to the `usage` that was specified when creating the texture.
176 pub fn usage(&self) -> TextureUsages {
177 self.descriptor.usage
178 }
179}
180
181/// Describes a [`Texture`].
182///
183/// For use with [`Device::create_texture`].
184///
185/// Corresponds to [WebGPU `GPUTextureDescriptor`](
186/// https://gpuweb.github.io/gpuweb/#dictdef-gputexturedescriptor).
187pub type TextureDescriptor<'a> = wgt::TextureDescriptor<Label<'a>, &'a [TextureFormat]>;
188static_assertions::assert_impl_all!(TextureDescriptor<'_>: Send, Sync);