Skip to main content

bevy_render/render_resource/
texture.rs

1use crate::renderer::{wgpu_wrapper, RenderDevice, RenderQueue};
2use bevy_derive::{Deref, DerefMut};
3use bevy_ecs::{
4    resource::Resource,
5    world::{FromWorld, World},
6};
7use bevy_image::ImageSamplerDescriptor;
8use bevy_utils::define_atomic_id;
9use core::ops::Deref;
10
11define_atomic_id!(TextureId);
12
13wgpu_wrapper! {
14    #[derive(Clone, Debug)]
15    struct WgpuTexture(wgpu::Texture);
16}
17
18/// A GPU-accessible texture.
19///
20/// May be converted from and dereferences to a wgpu [`Texture`](wgpu::Texture).
21/// Can be created via [`RenderDevice::create_texture`](crate::renderer::RenderDevice::create_texture).
22///
23/// Other options for storing GPU-accessible data are:
24/// * [`BufferVec`](crate::render_resource::BufferVec)
25/// * [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer)
26/// * [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer)
27/// * [`GpuArrayBuffer`](crate::render_resource::GpuArrayBuffer)
28/// * [`RawBufferVec`](crate::render_resource::RawBufferVec)
29/// * [`StorageBuffer`](crate::render_resource::StorageBuffer)
30/// * [`UniformBuffer`](crate::render_resource::UniformBuffer)
31#[derive(Clone, Debug)]
32pub struct Texture {
33    id: TextureId,
34    value: WgpuTexture,
35}
36
37impl Texture {
38    /// Returns the [`TextureId`].
39    #[inline]
40    pub fn id(&self) -> TextureId {
41        self.id
42    }
43
44    /// Creates a view of this texture.
45    pub fn create_view(&self, desc: &wgpu::TextureViewDescriptor) -> TextureView {
46        TextureView::from(self.value.create_view(desc))
47    }
48}
49
50impl From<wgpu::Texture> for Texture {
51    fn from(value: wgpu::Texture) -> Self {
52        Texture {
53            id: TextureId::new(),
54            value: WgpuTexture::new(value),
55        }
56    }
57}
58
59impl Deref for Texture {
60    type Target = wgpu::Texture;
61
62    #[inline]
63    fn deref(&self) -> &Self::Target {
64        &self.value
65    }
66}
67
68define_atomic_id!(TextureViewId);
69
70wgpu_wrapper! {
71    #[derive(Clone, Debug)]
72    struct WgpuTextureView(wgpu::TextureView);
73
74    struct WgpuSurfaceTexture(wgpu::SurfaceTexture);
75}
76
77/// Describes a [`Texture`] with its associated metadata required by a pipeline or [`BindGroup`](super::BindGroup).
78#[derive(Clone, Debug)]
79pub struct TextureView {
80    id: TextureViewId,
81    value: WgpuTextureView,
82}
83
84pub struct SurfaceTexture {
85    value: WgpuSurfaceTexture,
86}
87
88impl SurfaceTexture {
89    pub fn present(self, render_queue: &RenderQueue) {
90        render_queue.present(self.value.into_inner());
91    }
92}
93
94impl TextureView {
95    /// Returns the [`TextureViewId`].
96    #[inline]
97    pub fn id(&self) -> TextureViewId {
98        self.id
99    }
100}
101
102impl From<wgpu::TextureView> for TextureView {
103    fn from(value: wgpu::TextureView) -> Self {
104        TextureView {
105            id: TextureViewId::new(),
106            value: WgpuTextureView::new(value),
107        }
108    }
109}
110
111impl From<wgpu::SurfaceTexture> for SurfaceTexture {
112    fn from(value: wgpu::SurfaceTexture) -> Self {
113        SurfaceTexture {
114            value: WgpuSurfaceTexture::new(value),
115        }
116    }
117}
118
119impl Deref for TextureView {
120    type Target = wgpu::TextureView;
121
122    #[inline]
123    fn deref(&self) -> &Self::Target {
124        &self.value
125    }
126}
127
128impl Deref for SurfaceTexture {
129    type Target = wgpu::SurfaceTexture;
130
131    #[inline]
132    fn deref(&self) -> &Self::Target {
133        &self.value
134    }
135}
136
137define_atomic_id!(SamplerId);
138
139wgpu_wrapper! {
140    #[derive(Clone, Debug)]
141    struct WgpuSampler(wgpu::Sampler);
142}
143
144/// A Sampler defines how a pipeline will sample from a [`TextureView`].
145/// They define image filters (including anisotropy) and address (wrapping) modes, among other things.
146///
147/// May be converted from and dereferences to a wgpu [`Sampler`](wgpu::Sampler).
148/// Can be created via [`RenderDevice::create_sampler`](crate::renderer::RenderDevice::create_sampler).
149#[derive(Clone, Debug)]
150pub struct Sampler {
151    id: SamplerId,
152    value: WgpuSampler,
153}
154
155impl Sampler {
156    /// Returns the [`SamplerId`].
157    #[inline]
158    pub fn id(&self) -> SamplerId {
159        self.id
160    }
161}
162
163impl From<wgpu::Sampler> for Sampler {
164    fn from(value: wgpu::Sampler) -> Self {
165        Sampler {
166            id: SamplerId::new(),
167            value: WgpuSampler::new(value),
168        }
169    }
170}
171
172impl Deref for Sampler {
173    type Target = wgpu::Sampler;
174
175    #[inline]
176    fn deref(&self) -> &Self::Target {
177        &self.value
178    }
179}
180
181/// Stores the [`ImageSamplerDescriptor`] used to create the [`DefaultImageSampler`].
182///
183/// This is kept as a resource so that [`DefaultImageSampler`] can be recreated on GPU device recovery.
184#[derive(Resource, Debug, Clone, Deref)]
185pub struct DefaultImageSamplerDescriptor(pub ImageSamplerDescriptor);
186
187/// A rendering resource for the default image sampler which is set during renderer
188/// initialization.
189///
190/// The [`ImagePlugin`](bevy_image::ImagePlugin) can be set during app initialization to change the default
191/// image sampler.
192#[derive(Resource, Debug, Clone, Deref, DerefMut)]
193pub struct DefaultImageSampler(pub(crate) Sampler);
194
195impl FromWorld for DefaultImageSampler {
196    fn from_world(world: &mut World) -> Self {
197        let descriptor = world.resource::<DefaultImageSamplerDescriptor>();
198        let wgpu_descriptor = descriptor.as_wgpu();
199        let device = world.resource::<RenderDevice>();
200        let sampler = device.create_sampler(&wgpu_descriptor);
201        Self(sampler)
202    }
203}