summaryrefslogtreecommitdiffstats
path: root/wgpu/src/triangle
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-02-15 10:08:27 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-02-15 10:08:27 +0100
commitdadae122533ae0916bebd04d6efab3de145263d4 (patch)
treed0fda3d65fe0e842e97547ba4b18c398ce45ab25 /wgpu/src/triangle
parent4969bfdb66cf2b33033cb642423bc326e288e15b (diff)
downloadiced-dadae122533ae0916bebd04d6efab3de145263d4.tar.gz
iced-dadae122533ae0916bebd04d6efab3de145263d4.tar.bz2
iced-dadae122533ae0916bebd04d6efab3de145263d4.zip
Implement MSAA for `triangle` pipeline in `iced_wgpu`
Diffstat (limited to 'wgpu/src/triangle')
-rw-r--r--wgpu/src/triangle/msaa.rs255
1 files changed, 255 insertions, 0 deletions
diff --git a/wgpu/src/triangle/msaa.rs b/wgpu/src/triangle/msaa.rs
new file mode 100644
index 00000000..93fbe49b
--- /dev/null
+++ b/wgpu/src/triangle/msaa.rs
@@ -0,0 +1,255 @@
+use crate::settings;
+
+#[derive(Debug)]
+pub struct Blit {
+ pipeline: wgpu::RenderPipeline,
+ constants: wgpu::BindGroup,
+ texture_layout: wgpu::BindGroupLayout,
+ sample_count: u32,
+ targets: Option<Targets>,
+}
+
+impl Blit {
+ pub fn new(device: &wgpu::Device, antialiasing: settings::MSAA) -> Blit {
+ let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
+ address_mode_u: wgpu::AddressMode::ClampToEdge,
+ address_mode_v: wgpu::AddressMode::ClampToEdge,
+ address_mode_w: wgpu::AddressMode::ClampToEdge,
+ mag_filter: wgpu::FilterMode::Linear,
+ min_filter: wgpu::FilterMode::Linear,
+ mipmap_filter: wgpu::FilterMode::Linear,
+ lod_min_clamp: -100.0,
+ lod_max_clamp: 100.0,
+ compare_function: wgpu::CompareFunction::Always,
+ });
+
+ let constant_layout =
+ device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
+ bindings: &[wgpu::BindGroupLayoutBinding {
+ binding: 0,
+ visibility: wgpu::ShaderStage::FRAGMENT,
+ ty: wgpu::BindingType::Sampler,
+ }],
+ });
+
+ let constant_bind_group =
+ device.create_bind_group(&wgpu::BindGroupDescriptor {
+ layout: &constant_layout,
+ bindings: &[wgpu::Binding {
+ binding: 0,
+ resource: wgpu::BindingResource::Sampler(&sampler),
+ }],
+ });
+
+ let texture_layout =
+ device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
+ bindings: &[wgpu::BindGroupLayoutBinding {
+ binding: 0,
+ visibility: wgpu::ShaderStage::FRAGMENT,
+ ty: wgpu::BindingType::SampledTexture {
+ multisampled: false,
+ dimension: wgpu::TextureViewDimension::D2,
+ },
+ }],
+ });
+
+ let layout =
+ device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
+ bind_group_layouts: &[&constant_layout, &texture_layout],
+ });
+
+ let vs = include_bytes!("../shader/blit.vert.spv");
+ let vs_module = device.create_shader_module(
+ &wgpu::read_spirv(std::io::Cursor::new(&vs[..]))
+ .expect("Read blit vertex shader as SPIR-V"),
+ );
+
+ let fs = include_bytes!("../shader/blit.frag.spv");
+ let fs_module = device.create_shader_module(
+ &wgpu::read_spirv(std::io::Cursor::new(&fs[..]))
+ .expect("Read blit fragment shader as SPIR-V"),
+ );
+
+ let pipeline =
+ device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
+ layout: &layout,
+ vertex_stage: wgpu::ProgrammableStageDescriptor {
+ module: &vs_module,
+ entry_point: "main",
+ },
+ fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
+ module: &fs_module,
+ entry_point: "main",
+ }),
+ rasterization_state: Some(wgpu::RasterizationStateDescriptor {
+ front_face: wgpu::FrontFace::Cw,
+ cull_mode: wgpu::CullMode::None,
+ depth_bias: 0,
+ depth_bias_slope_scale: 0.0,
+ depth_bias_clamp: 0.0,
+ }),
+ primitive_topology: wgpu::PrimitiveTopology::TriangleList,
+ color_states: &[wgpu::ColorStateDescriptor {
+ format: wgpu::TextureFormat::Bgra8UnormSrgb,
+ color_blend: wgpu::BlendDescriptor {
+ src_factor: wgpu::BlendFactor::SrcAlpha,
+ dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
+ operation: wgpu::BlendOperation::Add,
+ },
+ alpha_blend: wgpu::BlendDescriptor {
+ src_factor: wgpu::BlendFactor::One,
+ dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
+ operation: wgpu::BlendOperation::Add,
+ },
+ write_mask: wgpu::ColorWrite::ALL,
+ }],
+ depth_stencil_state: None,
+ index_format: wgpu::IndexFormat::Uint16,
+ vertex_buffers: &[],
+ sample_count: 1,
+ sample_mask: !0,
+ alpha_to_coverage_enabled: false,
+ });
+
+ Blit {
+ pipeline,
+ constants: constant_bind_group,
+ texture_layout: texture_layout,
+ sample_count: antialiasing.sample_count(),
+ targets: None,
+ }
+ }
+
+ pub fn targets(
+ &mut self,
+ device: &wgpu::Device,
+ width: u32,
+ height: u32,
+ ) -> (&wgpu::TextureView, &wgpu::TextureView) {
+ match &mut self.targets {
+ None => {
+ self.targets = Some(Targets::new(
+ &device,
+ &self.texture_layout,
+ self.sample_count,
+ width,
+ height,
+ ));
+ }
+ Some(targets) => {
+ if targets.width != width || targets.height != height {
+ self.targets = Some(Targets::new(
+ &device,
+ &self.texture_layout,
+ self.sample_count,
+ width,
+ height,
+ ));
+ }
+ }
+ }
+
+ let targets = self.targets.as_ref().unwrap();
+
+ (&targets.attachment, &targets.resolve)
+ }
+
+ pub fn draw(
+ &self,
+ encoder: &mut wgpu::CommandEncoder,
+ target: &wgpu::TextureView,
+ ) {
+ let mut render_pass =
+ encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
+ color_attachments: &[
+ wgpu::RenderPassColorAttachmentDescriptor {
+ attachment: target,
+ resolve_target: None,
+ load_op: wgpu::LoadOp::Load,
+ store_op: wgpu::StoreOp::Store,
+ clear_color: wgpu::Color {
+ r: 0.0,
+ g: 0.0,
+ b: 0.0,
+ a: 0.0,
+ },
+ },
+ ],
+ depth_stencil_attachment: None,
+ });
+
+ render_pass.set_pipeline(&self.pipeline);
+ render_pass.set_bind_group(0, &self.constants, &[]);
+ render_pass.set_bind_group(
+ 1,
+ &self.targets.as_ref().unwrap().bind_group,
+ &[],
+ );
+ render_pass.draw(0..6, 0..1);
+ }
+}
+
+#[derive(Debug)]
+struct Targets {
+ attachment: wgpu::TextureView,
+ resolve: wgpu::TextureView,
+ bind_group: wgpu::BindGroup,
+ width: u32,
+ height: u32,
+}
+
+impl Targets {
+ pub fn new(
+ device: &wgpu::Device,
+ texture_layout: &wgpu::BindGroupLayout,
+ sample_count: u32,
+ width: u32,
+ height: u32,
+ ) -> Targets {
+ let extent = wgpu::Extent3d {
+ width,
+ height,
+ depth: 1,
+ };
+
+ let attachment = device.create_texture(&wgpu::TextureDescriptor {
+ size: extent,
+ array_layer_count: 1,
+ mip_level_count: 1,
+ sample_count,
+ dimension: wgpu::TextureDimension::D2,
+ format: wgpu::TextureFormat::Bgra8UnormSrgb,
+ usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
+ });
+
+ let resolve = device.create_texture(&wgpu::TextureDescriptor {
+ size: extent,
+ array_layer_count: 1,
+ mip_level_count: 1,
+ sample_count: 1,
+ dimension: wgpu::TextureDimension::D2,
+ format: wgpu::TextureFormat::Bgra8UnormSrgb,
+ usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT
+ | wgpu::TextureUsage::SAMPLED,
+ });
+
+ let attachment = attachment.create_default_view();
+ let resolve = resolve.create_default_view();
+
+ let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
+ layout: texture_layout,
+ bindings: &[wgpu::Binding {
+ binding: 0,
+ resource: wgpu::BindingResource::TextureView(&resolve),
+ }],
+ });
+
+ Targets {
+ attachment,
+ resolve,
+ bind_group,
+ width,
+ height,
+ }
+ }
+}