bevy_render/render_resource/
texture.rs1use 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
11pub struct TextureId(core::num::NonZero<u32>);
#[automatically_derived]
impl ::core::marker::Copy for TextureId { }
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for TextureId { }
#[automatically_derived]
impl ::core::clone::Clone for TextureId {
#[inline]
fn clone(&self) -> TextureId {
let _: ::core::clone::AssertParamIsClone<core::num::NonZero<u32>>;
*self
}
}
#[automatically_derived]
impl ::core::hash::Hash for TextureId {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}
#[automatically_derived]
impl ::core::cmp::Eq for TextureId {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<core::num::NonZero<u32>>;
}
}
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for TextureId { }
#[automatically_derived]
impl ::core::cmp::PartialEq for TextureId {
#[inline]
fn eq(&self, other: &TextureId) -> bool { self.0 == other.0 }
}
#[automatically_derived]
impl ::core::cmp::PartialOrd for TextureId {
#[inline]
fn partial_cmp(&self, other: &TextureId)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}
#[automatically_derived]
impl ::core::cmp::Ord for TextureId {
#[inline]
fn cmp(&self, other: &TextureId) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}
#[automatically_derived]
impl ::core::fmt::Debug for TextureId {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "TextureId",
&&self.0)
}
}
impl TextureId {
#[expect(clippy :: new_without_default, reason =
"Implementing the `Default` trait on atomic IDs would imply that two `<AtomicIdType>::default()` equal each other. By only implementing `new()`, we indicate that each atomic ID created will be unique.")]
pub fn new() -> Self {
use core::sync::atomic::{AtomicU32, Ordering};
static COUNTER: AtomicU32 = AtomicU32::new(1);
let counter = COUNTER.fetch_add(1, Ordering::Relaxed);
Self(core::num::NonZero::<u32>::new(counter).unwrap_or_else(||
{
{
::core::panicking::panic_fmt(format_args!("The system ran out of unique `{0}`s.",
"TextureId"));
};
}))
}
}
impl From<TextureId> for core::num::NonZero<u32> {
fn from(value: TextureId) -> Self { value.0 }
}
impl From<core::num::NonZero<u32>> for TextureId {
fn from(value: core::num::NonZero<u32>) -> Self { Self(value) }
}define_atomic_id!(TextureId);
12
13#[derive(#[automatically_derived]
impl ::core::clone::Clone for Texture {
#[inline]
fn clone(&self) -> Texture {
Texture {
id: ::core::clone::Clone::clone(&self.id),
value: ::core::clone::Clone::clone(&self.value),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Texture {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Texture", "id",
&self.id, "value", &&self.value)
}
}Debug)]
27pub struct Texture {
28 id: TextureId,
29 value: WgpuWrapper<wgpu::Texture>,
30}
31
32impl Texture {
33 #[inline]
35 pub fn id(&self) -> TextureId {
36 self.id
37 }
38
39 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
63pub struct TextureViewId(core::num::NonZero<u32>);
#[automatically_derived]
impl ::core::marker::Copy for TextureViewId { }
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for TextureViewId { }
#[automatically_derived]
impl ::core::clone::Clone for TextureViewId {
#[inline]
fn clone(&self) -> TextureViewId {
let _: ::core::clone::AssertParamIsClone<core::num::NonZero<u32>>;
*self
}
}
#[automatically_derived]
impl ::core::hash::Hash for TextureViewId {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}
#[automatically_derived]
impl ::core::cmp::Eq for TextureViewId {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<core::num::NonZero<u32>>;
}
}
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for TextureViewId { }
#[automatically_derived]
impl ::core::cmp::PartialEq for TextureViewId {
#[inline]
fn eq(&self, other: &TextureViewId) -> bool { self.0 == other.0 }
}
#[automatically_derived]
impl ::core::cmp::PartialOrd for TextureViewId {
#[inline]
fn partial_cmp(&self, other: &TextureViewId)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}
#[automatically_derived]
impl ::core::cmp::Ord for TextureViewId {
#[inline]
fn cmp(&self, other: &TextureViewId) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}
#[automatically_derived]
impl ::core::fmt::Debug for TextureViewId {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "TextureViewId",
&&self.0)
}
}
impl TextureViewId {
#[expect(clippy :: new_without_default, reason =
"Implementing the `Default` trait on atomic IDs would imply that two `<AtomicIdType>::default()` equal each other. By only implementing `new()`, we indicate that each atomic ID created will be unique.")]
pub fn new() -> Self {
use core::sync::atomic::{AtomicU32, Ordering};
static COUNTER: AtomicU32 = AtomicU32::new(1);
let counter = COUNTER.fetch_add(1, Ordering::Relaxed);
Self(core::num::NonZero::<u32>::new(counter).unwrap_or_else(||
{
{
::core::panicking::panic_fmt(format_args!("The system ran out of unique `{0}`s.",
"TextureViewId"));
};
}))
}
}
impl From<TextureViewId> for core::num::NonZero<u32> {
fn from(value: TextureViewId) -> Self { value.0 }
}
impl From<core::num::NonZero<u32>> for TextureViewId {
fn from(value: core::num::NonZero<u32>) -> Self { Self(value) }
}define_atomic_id!(TextureViewId);
64
65#[derive(#[automatically_derived]
impl ::core::clone::Clone for TextureView {
#[inline]
fn clone(&self) -> TextureView {
TextureView {
id: ::core::clone::Clone::clone(&self.id),
value: ::core::clone::Clone::clone(&self.value),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for TextureView {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "TextureView",
"id", &self.id, "value", &&self.value)
}
}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 #[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
125pub struct SamplerId(core::num::NonZero<u32>);
#[automatically_derived]
impl ::core::marker::Copy for SamplerId { }
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for SamplerId { }
#[automatically_derived]
impl ::core::clone::Clone for SamplerId {
#[inline]
fn clone(&self) -> SamplerId {
let _: ::core::clone::AssertParamIsClone<core::num::NonZero<u32>>;
*self
}
}
#[automatically_derived]
impl ::core::hash::Hash for SamplerId {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}
#[automatically_derived]
impl ::core::cmp::Eq for SamplerId {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<core::num::NonZero<u32>>;
}
}
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for SamplerId { }
#[automatically_derived]
impl ::core::cmp::PartialEq for SamplerId {
#[inline]
fn eq(&self, other: &SamplerId) -> bool { self.0 == other.0 }
}
#[automatically_derived]
impl ::core::cmp::PartialOrd for SamplerId {
#[inline]
fn partial_cmp(&self, other: &SamplerId)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}
#[automatically_derived]
impl ::core::cmp::Ord for SamplerId {
#[inline]
fn cmp(&self, other: &SamplerId) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}
#[automatically_derived]
impl ::core::fmt::Debug for SamplerId {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "SamplerId",
&&self.0)
}
}
impl SamplerId {
#[expect(clippy :: new_without_default, reason =
"Implementing the `Default` trait on atomic IDs would imply that two `<AtomicIdType>::default()` equal each other. By only implementing `new()`, we indicate that each atomic ID created will be unique.")]
pub fn new() -> Self {
use core::sync::atomic::{AtomicU32, Ordering};
static COUNTER: AtomicU32 = AtomicU32::new(1);
let counter = COUNTER.fetch_add(1, Ordering::Relaxed);
Self(core::num::NonZero::<u32>::new(counter).unwrap_or_else(||
{
{
::core::panicking::panic_fmt(format_args!("The system ran out of unique `{0}`s.",
"SamplerId"));
};
}))
}
}
impl From<SamplerId> for core::num::NonZero<u32> {
fn from(value: SamplerId) -> Self { value.0 }
}
impl From<core::num::NonZero<u32>> for SamplerId {
fn from(value: core::num::NonZero<u32>) -> Self { Self(value) }
}define_atomic_id!(SamplerId);
126
127#[derive(#[automatically_derived]
impl ::core::clone::Clone for Sampler {
#[inline]
fn clone(&self) -> Sampler {
Sampler {
id: ::core::clone::Clone::clone(&self.id),
value: ::core::clone::Clone::clone(&self.value),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Sampler {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Sampler", "id",
&self.id, "value", &&self.value)
}
}Debug)]
133pub struct Sampler {
134 id: SamplerId,
135 value: WgpuWrapper<wgpu::Sampler>,
136}
137
138impl Sampler {
139 #[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#[derive(impl bevy_ecs::resource::Resource for DefaultImageSamplerDescriptor where
Self: ::core::marker::Send + ::core::marker::Sync + 'static {}Resource, #[automatically_derived]
impl ::core::fmt::Debug for DefaultImageSamplerDescriptor {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"DefaultImageSamplerDescriptor", &&self.0)
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for DefaultImageSamplerDescriptor {
#[inline]
fn clone(&self) -> DefaultImageSamplerDescriptor {
DefaultImageSamplerDescriptor(::core::clone::Clone::clone(&self.0))
}
}Clone, impl ::core::ops::Deref for DefaultImageSamplerDescriptor {
type Target = ImageSamplerDescriptor;
fn deref(&self) -> &Self::Target { &self.0 }
}Deref)]
168pub struct DefaultImageSamplerDescriptor(pub ImageSamplerDescriptor);
169
170#[derive(impl bevy_ecs::resource::Resource for DefaultImageSampler where
Self: ::core::marker::Send + ::core::marker::Sync + 'static {}Resource, #[automatically_derived]
impl ::core::fmt::Debug for DefaultImageSampler {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"DefaultImageSampler", &&self.0)
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for DefaultImageSampler {
#[inline]
fn clone(&self) -> DefaultImageSampler {
DefaultImageSampler(::core::clone::Clone::clone(&self.0))
}
}Clone, impl ::core::ops::Deref for DefaultImageSampler {
type Target = Sampler;
fn deref(&self) -> &Self::Target { &self.0 }
}Deref, impl ::core::ops::DerefMut for DefaultImageSampler {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}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}