(&mut self)
| 8864 | } |
| 8865 | |
| 8866 | pub fn end_frame(&mut self) { |
| 8867 | // Flush pending joint matrices to GPU right before rendering |
| 8868 | self.flush_joint_matrices(); |
| 8869 | |
| 8870 | // Q1: If rendering to a texture, use the RT view. Otherwise use the surface. |
| 8871 | // We take ownership of the RT views (via Option::take) to avoid holding a |
| 8872 | // borrow on `self` while the rest of end_frame mutates it. |
| 8873 | let rt_color = self.rt_color_view.take(); |
| 8874 | let rt_depth = self.rt_depth_view.take(); |
| 8875 | let using_rt = rt_color.is_some(); |
| 8876 | |
| 8877 | let surface_output = if using_rt { |
| 8878 | None |
| 8879 | } else { |
| 8880 | match self.surface.get_current_texture() { |
| 8881 | wgpu::CurrentSurfaceTexture::Success(t) | wgpu::CurrentSurfaceTexture::Suboptimal(t) => Some(t), |
| 8882 | _ => { |
| 8883 | self.surface.configure(&self.device, &self.surface_config); |
| 8884 | // Restore RT views if they were set. |
| 8885 | self.rt_color_view = rt_color; |
| 8886 | self.rt_depth_view = rt_depth; |
| 8887 | return; |
| 8888 | } |
| 8889 | } |
| 8890 | }; |
| 8891 | |
| 8892 | let view: wgpu::TextureView; |
| 8893 | let owned_depth_view: wgpu::TextureView; |
| 8894 | |
| 8895 | if let Some(ref rt_view) = rt_color { |
| 8896 | view = rt_view.clone(); |
| 8897 | owned_depth_view = rt_depth.as_ref().unwrap().clone(); |
| 8898 | } else { |
| 8899 | view = surface_output.as_ref().unwrap().texture.create_view(&wgpu::TextureViewDescriptor::default()); |
| 8900 | owned_depth_view = self.depth_texture.create_view(&wgpu::TextureViewDescriptor::default()); |
| 8901 | } |
| 8902 | |
| 8903 | // Restore RT views so they persist across frames. |
| 8904 | self.rt_color_view = rt_color; |
| 8905 | self.rt_depth_view = rt_depth; |
| 8906 | |
| 8907 | let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { |
| 8908 | label: Some("bloom_encoder"), |
| 8909 | }); |
| 8910 | |
| 8911 | // Upload 2D data to persistent GPU buffers |
| 8912 | let has_2d = !self.vertices_2d.is_empty(); |
| 8913 | if has_2d { |
| 8914 | let vb_size = std::mem::size_of_val(self.vertices_2d.as_slice()); |
| 8915 | let ib_size = std::mem::size_of_val(self.indices_2d.as_slice()); |
| 8916 | self.ensure_buffer_capacity_2d(vb_size, ib_size); |
| 8917 | self.queue.write_buffer(&self.persistent_vb_2d, 0, bytemuck::cast_slice(&self.vertices_2d)); |
| 8918 | self.queue.write_buffer(&self.persistent_ib_2d, 0, bytemuck::cast_slice(&self.indices_2d)); |
| 8919 | } |
| 8920 | |
| 8921 | // Upload 3D data to persistent GPU buffers |
| 8922 | let has_3d = !self.vertices_3d.is_empty(); |
| 8923 | if has_3d { |
nothing calls this directly
no test coverage detected