1use super::binding::BindGroup;
2use super::binding::CreateBindGroupLayout;
3use super::buffer::*;
4use super::binding;
5use std::ops::{Deref, DerefMut};
6
7pub struct UniformRef<'ur, C: bytemuck::Pod>{
12 queue: &'ur wgpu::Queue,
13 uniform: &'ur mut Uniform<C>,
14}
15
16
17impl<C: bytemuck::Pod> Deref for UniformRef<'_, C>{
18 type Target = C;
19
20 fn deref(&self) -> &Self::Target {
21 &self.uniform.uniform_vec.content[0]
22 }
23}
24
25impl<C: bytemuck::Pod> DerefMut for UniformRef<'_, C>{
26 fn deref_mut(&mut self) -> &mut Self::Target {
27 &mut self.uniform.uniform_vec.content[0]
28 }
29}
30
31impl<C: bytemuck::Pod> Drop for UniformRef<'_, C>{
32 fn drop(&mut self) {
33 self.uniform.uniform_vec.update_int(self.queue);
34 }
35}
36
37pub struct UniformVecRef<'ur, C: bytemuck::Pod>{
42 queue: &'ur mut wgpu::Queue,
43 uniform_vec: &'ur mut UniformVec<C>,
44}
45
46impl<C: bytemuck::Pod> Deref for UniformVecRef<'_, C>{
47 type Target = [C];
48
49 fn deref(&self) -> &Self::Target{
50 &self.uniform_vec.content
51 }
52}
53
54impl<C: bytemuck::Pod> DerefMut for UniformVecRef<'_, C>{
55 fn deref_mut(&mut self) -> &mut Self::Target {
56 &mut self.uniform_vec.content
57 }
58}
59
60impl<C: bytemuck::Pod> Drop for UniformVecRef<'_, C>{
61 fn drop(&mut self){
62 self.uniform_vec.update_int(self.queue);
63 }
64}
65
66pub struct UniformVec<C: bytemuck::Pod>{
72 buffer: Buffer<C>,
73
74 content: Vec<C>,
75}
76
77impl<C: bytemuck::Pod> UniformVec<C>{
78 fn name() -> &'static str{
79 let type_name = std::any::type_name::<C>();
80 let pos = type_name.rfind(':').unwrap_or_else(||{0});
81 &type_name[(pos + 1)..]
82 }
83
84 pub fn new(src: &[C], device: &wgpu::Device) -> Self{
85 let buffer = Buffer::new_dst_uniform(
86 device,
87 Some(&format!("UniformBuffer: {}", Self::name())),
88 src,
89 );
90 Self{
100 buffer,
101 content: Vec::from(src),
102 }
103 }
104
105 pub fn update_int(&mut self, queue: &wgpu::Queue){
106 queue.write_buffer(&self.buffer, 0, bytemuck::cast_slice(&self.content));
107 }
108
109 pub fn borrow_ref<'ur>(&'ur mut self, queue: &'ur mut wgpu::Queue) -> UniformVecRef<'ur, C>{
110 UniformVecRef{
111 queue,
112 uniform_vec: self,
113 }
114 }
115}
116
117impl<C: bytemuck::Pod> binding::BindGroupContent for UniformVec<C>{
118 fn entries(visibility: wgpu::ShaderStages) -> Vec<binding::BindGroupLayoutEntry>{
119 vec!{
120 binding::BindGroupLayoutEntry::new(visibility, binding::wgsl::uniform()),
121 }
122 }
123
124 fn resources<'br>(&'br self) -> Vec<wgpu::BindingResource<'br>> {
125 vec!{
126 self.buffer.as_entire_binding(),
127 }
128 }
129}
130
131pub struct Uniform<C: bytemuck::Pod>{
135 uniform_vec: UniformVec<C>,
136}
137
138impl<C: bytemuck::Pod> Uniform<C>{
139 pub fn new(src: C, device: &wgpu::Device) -> Self{
140 Self{
141 uniform_vec: UniformVec::new(&[src], device)
142 }
143 }
144
145 pub fn borrow_ref<'ur>(&'ur mut self, queue: &'ur wgpu::Queue) -> UniformRef<'ur, C>{
146 UniformRef{
147 queue,
148 uniform: self,
149 }
150 }
151}
152
153impl<C: bytemuck::Pod> binding::BindGroupContent for Uniform<C>{
154 fn entries(visibility: wgpu::ShaderStages) -> Vec<binding::BindGroupLayoutEntry>{
155 vec!{
156 binding::BindGroupLayoutEntry::new(visibility, binding::wgsl::uniform())
157 }
158 }
159
160 fn resources<'br>(&'br self) -> Vec<wgpu::BindingResource<'br>> {
161 vec!{
162 self.uniform_vec.buffer.as_entire_binding(),
163 }
164 }
165}
166
167pub struct UniformBindGroup<C: bytemuck::Pod>{
171 bind_group: binding::BindGroup<Uniform<C>>,
172}
173
174impl <C: bytemuck::Pod> UniformBindGroup<C>{
175 pub fn new(device: &wgpu::Device, src: C) -> Self{
176 Self{
177 bind_group: binding::BindGroup::new(Uniform::new(src, device), device)
178 }
179 }
180}
181
182impl<C: bytemuck::Pod> binding::GetBindGroup for UniformBindGroup<C>{
183 fn get_bind_group<'l>(&'l self) -> &'l wgpu::BindGroup {
184 self.bind_group.get_bind_group()
185 }
186}
187
188impl<C: bytemuck::Pod> Deref for UniformBindGroup<C>{
189 type Target = binding::BindGroup<Uniform<C>>;
190
191 fn deref(&self) -> &Self::Target {
192 &self.bind_group
193 }
194}
195
196impl<C: bytemuck::Pod> DerefMut for UniformBindGroup<C>{
197 fn deref_mut(&mut self) -> &mut Self::Target {
198 &mut self.bind_group
199 }
200}
201
202impl<C: bytemuck::Pod> CreateBindGroupLayout for UniformBindGroup<C>{
203 fn create_bind_group_layout(device: &wgpu::Device, label: Option<&str>) -> binding::BindGroupLayoutWithDesc {
204 BindGroup::<Uniform<C>>::create_bind_group_layout(device, label)
205 }
206 fn create_bind_group_layout_vis(device: &wgpu::Device, label: Option<&str>, visibility: wgpu::ShaderStages) -> crate::BindGroupLayoutWithDesc {
207 BindGroup::<Uniform<C>>::create_bind_group_layout_vis(device, label, visibility)
208 }
209}