Skip to main content

bevy_render/render_resource/
texture.rs

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