summaryrefslogtreecommitdiffstats
path: root/wgpu/src/triangle/msaa.rs
diff options
context:
space:
mode:
Diffstat (limited to 'wgpu/src/triangle/msaa.rs')
-rw-r--r--wgpu/src/triangle/msaa.rs130
1 files changed, 91 insertions, 39 deletions
diff --git a/wgpu/src/triangle/msaa.rs b/wgpu/src/triangle/msaa.rs
index 14abd20b..71c16925 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 =
@@ -112,43 +142,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 +239,7 @@ struct Targets {
attachment: wgpu::TextureView,
resolve: wgpu::TextureView,
bind_group: wgpu::BindGroup,
- width: u32,
- height: u32,
+ size: Size<u32>,
}
impl Targets {
@@ -201,12 +248,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 +298,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,
+}