diff options
author | 2024-04-07 18:45:30 +0200 | |
---|---|---|
committer | 2024-04-07 18:45:48 +0200 | |
commit | 288f62bfb691a91e01b9ddbce9dbdc560ee9036a (patch) | |
tree | 6744614d18c7b53046c37d4c045b9df1ffe947f0 /wgpu/src/triangle | |
parent | 13289dbd1933e7d7a0b21cffd197813f8f6f7fc0 (diff) | |
download | iced-288f62bfb691a91e01b9ddbce9dbdc560ee9036a.tar.gz iced-288f62bfb691a91e01b9ddbce9dbdc560ee9036a.tar.bz2 iced-288f62bfb691a91e01b9ddbce9dbdc560ee9036a.zip |
Share `msaa::Blit` texture between multiple windows
Diffstat (limited to 'wgpu/src/triangle')
-rw-r--r-- | wgpu/src/triangle/msaa.rs | 134 |
1 files changed, 92 insertions, 42 deletions
diff --git a/wgpu/src/triangle/msaa.rs b/wgpu/src/triangle/msaa.rs index 14abd20b..fcee6b3e 100644 --- a/wgpu/src/triangle/msaa.rs +++ b/wgpu/src/triangle/msaa.rs @@ -1,13 +1,18 @@ +use crate::core::{Size, Transformation}; use crate::graphics; +use std::num::NonZeroU64; + #[derive(Debug)] pub struct Blit { format: wgpu::TextureFormat, pipeline: wgpu::RenderPipeline, constants: wgpu::BindGroup, + ratio: wgpu::Buffer, texture_layout: wgpu::BindGroupLayout, sample_count: u32, targets: Option<Targets>, + last_region: Option<Size<u32>>, } impl Blit { @@ -19,27 +24,52 @@ impl Blit { let sampler = device.create_sampler(&wgpu::SamplerDescriptor::default()); + let ratio = device.create_buffer(&wgpu::BufferDescriptor { + label: Some("iced-wgpu::triangle::msaa ratio"), + size: std::mem::size_of::<Ratio>() as u64, + usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::UNIFORM, + mapped_at_creation: false, + }); + let constant_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { label: Some("iced_wgpu::triangle:msaa uniforms layout"), - entries: &[wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStages::FRAGMENT, - ty: wgpu::BindingType::Sampler( - wgpu::SamplerBindingType::NonFiltering, - ), - count: None, - }], + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Sampler( + wgpu::SamplerBindingType::NonFiltering, + ), + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStages::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None, + }, + count: None, + }, + ], }); let constant_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { label: Some("iced_wgpu::triangle::msaa uniforms bind group"), layout: &constant_layout, - entries: &[wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::Sampler(&sampler), - }], + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::Sampler(&sampler), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: ratio.as_entire_binding(), + }, + ], }); let texture_layout = @@ -88,9 +118,7 @@ impl Blit { entry_point: "fs_main", targets: &[Some(wgpu::ColorTargetState { format, - blend: Some( - wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING, - ), + blend: Some(wgpu::BlendState::ALPHA_BLENDING), write_mask: wgpu::ColorWrites::ALL, })], }), @@ -112,43 +140,61 @@ impl Blit { format, pipeline, constants: constant_bind_group, + ratio, texture_layout, sample_count: antialiasing.sample_count(), targets: None, + last_region: None, } } - pub fn targets( + pub fn prepare( &mut self, device: &wgpu::Device, - width: u32, - height: u32, - ) -> (&wgpu::TextureView, &wgpu::TextureView) { + encoder: &mut wgpu::CommandEncoder, + belt: &mut wgpu::util::StagingBelt, + region_size: Size<u32>, + ) -> Transformation { match &mut self.targets { - None => { + Some(targets) + if region_size.width <= targets.size.width + && region_size.height <= targets.size.height => {} + _ => { self.targets = Some(Targets::new( device, self.format, &self.texture_layout, self.sample_count, - width, - height, + region_size, )); } - Some(targets) => { - if targets.width != width || targets.height != height { - self.targets = Some(Targets::new( - device, - self.format, - &self.texture_layout, - self.sample_count, - width, - height, - )); - } - } } + let targets = self.targets.as_mut().unwrap(); + + if Some(region_size) != self.last_region { + let ratio = Ratio { + u: region_size.width as f32 / targets.size.width as f32, + v: region_size.height as f32 / targets.size.height as f32, + }; + + belt.write_buffer( + encoder, + &self.ratio, + 0, + NonZeroU64::new(std::mem::size_of::<Ratio>() as u64) + .expect("non-empty ratio"), + device, + ) + .copy_from_slice(bytemuck::bytes_of(&ratio)); + + self.last_region = Some(region_size); + } + + Transformation::orthographic(targets.size.width, targets.size.height) + } + + pub fn targets(&self) -> (&wgpu::TextureView, &wgpu::TextureView) { let targets = self.targets.as_ref().unwrap(); (&targets.attachment, &targets.resolve) @@ -191,8 +237,7 @@ struct Targets { attachment: wgpu::TextureView, resolve: wgpu::TextureView, bind_group: wgpu::BindGroup, - width: u32, - height: u32, + size: Size<u32>, } impl Targets { @@ -201,12 +246,11 @@ impl Targets { format: wgpu::TextureFormat, texture_layout: &wgpu::BindGroupLayout, sample_count: u32, - width: u32, - height: u32, + size: Size<u32>, ) -> Targets { let extent = wgpu::Extent3d { - width, - height, + width: size.width, + height: size.height, depth_or_array_layers: 1, }; @@ -252,8 +296,14 @@ impl Targets { attachment, resolve, bind_group, - width, - height, + size, } } } + +#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)] +#[repr(C)] +struct Ratio { + u: f32, + v: f32, +} |