1#![deny(missing_docs)]
71
72mod shader;
73use shader::{ShaderQuality, ShaderSource, ShaderStage};
74
75#[path = "../third_party/smaa/Textures/AreaTex.rs"]
76mod area_tex;
77use area_tex::*;
78
79#[path = "../third_party/smaa/Textures/SearchTex.rs"]
80mod search_tex;
81use search_tex::*;
82
83use wgpu::util::DeviceExt;
84
85#[non_exhaustive]
87#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
88pub enum SmaaMode {
89 Disabled,
91 Smaa1X,
93}
94
95struct BindGroupLayouts {
96 edge_detect_bind_group_layout: wgpu::BindGroupLayout,
97 blend_weight_bind_group_layout: wgpu::BindGroupLayout,
98 neighborhood_blending_bind_group_layout: wgpu::BindGroupLayout,
99}
100struct Pipelines {
101 edge_detect: wgpu::RenderPipeline,
102 blend_weight: wgpu::RenderPipeline,
103 neighborhood_blending: wgpu::RenderPipeline,
104}
105struct Resources {
106 area_texture: wgpu::Texture,
107 search_texture: wgpu::Texture,
108 linear_sampler: wgpu::Sampler,
109}
110struct Targets {
111 rt_uniforms: wgpu::Buffer,
112 color_target: wgpu::TextureView,
113 edges_target: wgpu::TextureView,
114 blend_target: wgpu::TextureView,
115}
116struct BindGroups {
117 edge_detect_bind_group: wgpu::BindGroup,
118 blend_weight_bind_group: wgpu::BindGroup,
119 neighborhood_blending_bind_group: wgpu::BindGroup,
120}
121
122impl BindGroupLayouts {
123 pub fn new(device: &wgpu::Device) -> Self {
124 Self {
125 edge_detect_bind_group_layout: device.create_bind_group_layout(
126 &wgpu::BindGroupLayoutDescriptor {
127 label: Some("smaa.bind_group_layout.edge_detect"),
128 entries: &[
129 wgpu::BindGroupLayoutEntry {
130 binding: 0,
131 visibility: wgpu::ShaderStages::FRAGMENT,
132 ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
133 count: None,
134 },
135 wgpu::BindGroupLayoutEntry {
136 binding: 1,
137 visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
138 ty: wgpu::BindingType::Buffer {
139 ty: wgpu::BufferBindingType::Uniform,
140 has_dynamic_offset: false,
141 min_binding_size: None,
142 },
143 count: None,
144 },
145 wgpu::BindGroupLayoutEntry {
146 binding: 2,
147 visibility: wgpu::ShaderStages::FRAGMENT,
148 ty: wgpu::BindingType::Texture {
149 sample_type: wgpu::TextureSampleType::Float { filterable: true },
150 view_dimension: wgpu::TextureViewDimension::D2,
151 multisampled: false,
152 },
153 count: None,
154 },
155 ],
156 },
157 ),
158 blend_weight_bind_group_layout: device.create_bind_group_layout(
159 &wgpu::BindGroupLayoutDescriptor {
160 label: Some("smaa.bind_group_layout.blend_weight"),
161 entries: &[
162 wgpu::BindGroupLayoutEntry {
163 binding: 0,
164 visibility: wgpu::ShaderStages::FRAGMENT,
165 ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
166 count: None,
167 },
168 wgpu::BindGroupLayoutEntry {
169 binding: 1,
170 visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
171 ty: wgpu::BindingType::Buffer {
172 ty: wgpu::BufferBindingType::Uniform,
173 has_dynamic_offset: false,
174 min_binding_size: None,
175 },
176 count: None,
177 },
178 wgpu::BindGroupLayoutEntry {
179 binding: 2,
180 visibility: wgpu::ShaderStages::FRAGMENT,
181 ty: wgpu::BindingType::Texture {
182 sample_type: wgpu::TextureSampleType::Float { filterable: true },
183 view_dimension: wgpu::TextureViewDimension::D2,
184 multisampled: false,
185 },
186 count: None,
187 },
188 wgpu::BindGroupLayoutEntry {
189 binding: 3,
190 visibility: wgpu::ShaderStages::FRAGMENT,
191 ty: wgpu::BindingType::Texture {
192 sample_type: wgpu::TextureSampleType::Float { filterable: true },
193 view_dimension: wgpu::TextureViewDimension::D2,
194 multisampled: false,
195 },
196 count: None,
197 },
198 wgpu::BindGroupLayoutEntry {
199 binding: 4,
200 visibility: wgpu::ShaderStages::FRAGMENT,
201 ty: wgpu::BindingType::Texture {
202 sample_type: wgpu::TextureSampleType::Float { filterable: true },
203 view_dimension: wgpu::TextureViewDimension::D2,
204 multisampled: false,
205 },
206 count: None,
207 },
208 ],
209 },
210 ),
211 neighborhood_blending_bind_group_layout: device.create_bind_group_layout(
212 &wgpu::BindGroupLayoutDescriptor {
213 label: Some("smaa.bind_group_layout.neighborhood_blending"),
214 entries: &[
215 wgpu::BindGroupLayoutEntry {
216 binding: 0,
217 visibility: wgpu::ShaderStages::FRAGMENT,
218 ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
219 count: None,
220 },
221 wgpu::BindGroupLayoutEntry {
222 binding: 1,
223 visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
224 ty: wgpu::BindingType::Buffer {
225 ty: wgpu::BufferBindingType::Uniform,
226 has_dynamic_offset: false,
227 min_binding_size: None,
228 },
229 count: None,
230 },
231 wgpu::BindGroupLayoutEntry {
232 binding: 2,
233 visibility: wgpu::ShaderStages::FRAGMENT,
234 ty: wgpu::BindingType::Texture {
235 sample_type: wgpu::TextureSampleType::Float { filterable: true },
236 view_dimension: wgpu::TextureViewDimension::D2,
237 multisampled: false,
238 },
239 count: None,
240 },
241 wgpu::BindGroupLayoutEntry {
242 binding: 3,
243 visibility: wgpu::ShaderStages::FRAGMENT,
244 ty: wgpu::BindingType::Texture {
245 sample_type: wgpu::TextureSampleType::Float { filterable: true },
246 view_dimension: wgpu::TextureViewDimension::D2,
247 multisampled: false,
248 },
249 count: None,
250 },
251 ],
252 },
253 ),
254 }
255 }
256}
257
258impl Pipelines {
259 pub fn new(
260 device: &wgpu::Device,
261 format: wgpu::TextureFormat,
262 layouts: &BindGroupLayouts,
263 ) -> Self {
264 let source = ShaderSource {
265 quality: ShaderQuality::High,
266 };
267
268 let edge_detect_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
269 label: Some("smaa.pipeline_layout.edge_detect"),
270 bind_group_layouts: &[&layouts.edge_detect_bind_group_layout],
271 immediate_size: 0,
272 });
273 let edge_detect_shader_vert = wgpu::VertexState {
274 module: &source.get_shader(
275 device,
276 ShaderStage::EdgeDetectionVS,
277 "smaa.shader.edge_detect.vert",
278 ),
279 entry_point: Some("main"),
280 buffers: &[],
281 compilation_options: wgpu::PipelineCompilationOptions::default(),
282 };
283 let edge_detect_shader_frag = wgpu::FragmentState {
284 module: &source.get_shader(
285 device,
286 ShaderStage::LumaEdgeDetectionPS,
287 "smaa.shader.edge_detect.frag",
288 ),
289 entry_point: Some("main"),
290 targets: &[Some(wgpu::ColorTargetState {
291 format: wgpu::TextureFormat::Rg8Unorm,
292 blend: Some(wgpu::BlendState {
293 color: wgpu::BlendComponent::REPLACE,
294 alpha: wgpu::BlendComponent::REPLACE,
295 }),
296 write_mask: wgpu::ColorWrites::ALL,
297 })],
298 compilation_options: wgpu::PipelineCompilationOptions::default(),
299 };
300 let edge_detect = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
301 label: Some("smaa.pipeline.edge_detect"),
302 layout: Some(&edge_detect_layout),
303 vertex: edge_detect_shader_vert,
304 fragment: Some(edge_detect_shader_frag),
305 primitive: Default::default(),
306 multisample: Default::default(),
307 depth_stencil: None,
308 multiview_mask: None,
309 cache: None
310 });
311
312 let blend_weight_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
313 label: Some("smaa.pipeline_layout.blend_weight"),
314 bind_group_layouts: &[&layouts.blend_weight_bind_group_layout],
315 immediate_size: 0,
316 });
317 let blend_weight_shader_vert = wgpu::VertexState {
318 module: &source.get_shader(
319 device,
320 ShaderStage::BlendingWeightVS,
321 "smaa.shader.blending_weight.vert",
322 ),
323 entry_point: Some("main"),
324 buffers: &[],
325 compilation_options: wgpu::PipelineCompilationOptions::default(),
326 };
327 let blend_weight_shader_frag = wgpu::FragmentState {
328 module: &source.get_shader(
329 device,
330 ShaderStage::BlendingWeightPS,
331 "smaa.shader.blending_weight.frag",
332 ),
333 entry_point: Some("main"),
334 targets: &[Some(wgpu::ColorTargetState {
335 format: wgpu::TextureFormat::Rgba8Unorm,
336 blend: Some(wgpu::BlendState {
337 color: wgpu::BlendComponent::REPLACE,
338 alpha: wgpu::BlendComponent::REPLACE,
339 }),
340 write_mask: wgpu::ColorWrites::ALL,
341 })],
342 compilation_options: wgpu::PipelineCompilationOptions::default(),
343 };
344 let blend_weight = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
345 label: Some("smaa.pipeline.blend_weight"),
346 layout: Some(&blend_weight_layout),
347 vertex: blend_weight_shader_vert,
348 fragment: Some(blend_weight_shader_frag),
349 primitive: Default::default(),
350 multisample: Default::default(),
351 depth_stencil: None,
352 multiview_mask: None,
353 cache: None
354 });
355
356 let neighborhood_blending_layout =
357 device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
358 label: Some("smaa.pipeline_layout.neighborhood_blending"),
359 bind_group_layouts: &[&layouts.neighborhood_blending_bind_group_layout],
360 immediate_size: 0,
361 });
362 let neighborhood_blending_vert = wgpu::VertexState {
363 module: &source.get_shader(
364 device,
365 ShaderStage::NeighborhoodBlendingVS,
366 "smaa.shader.neighborhood_blending.vert",
367 ),
368 entry_point: Some("main"),
369 buffers: &[],
370 compilation_options: wgpu::PipelineCompilationOptions::default(),
371 };
372 let neighborhood_blending_frag = wgpu::FragmentState {
373 module: &source.get_shader(
374 device,
375 ShaderStage::NeighborhoodBlendingPS,
376 "smaa.shader.neighborhood_blending.frag",
377 ),
378 entry_point: Some("main"),
379 targets: &[Some(wgpu::ColorTargetState {
380 format,
381 blend: Some(wgpu::BlendState {
382 color: wgpu::BlendComponent::REPLACE,
383 alpha: wgpu::BlendComponent::REPLACE,
384 }),
385 write_mask: wgpu::ColorWrites::ALL,
386 })],
387 compilation_options: wgpu::PipelineCompilationOptions::default(),
388 };
389 let neighborhood_blending =
390 device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
391 label: Some("smaa.pipeline.neighborhood_blending"),
392 layout: Some(&neighborhood_blending_layout),
393 vertex: neighborhood_blending_vert,
394 fragment: Some(neighborhood_blending_frag),
395 primitive: Default::default(),
396 multisample: Default::default(),
397 depth_stencil: None,
398 multiview_mask: None,
399 cache: None
400 });
401
402 Self {
403 edge_detect,
404 blend_weight,
405 neighborhood_blending,
406 }
407 }
408}
409impl Targets {
410 pub fn new(
411 device: &wgpu::Device,
412 width: u32,
413 height: u32,
414 format: wgpu::TextureFormat,
415 ) -> Self {
416 let size = wgpu::Extent3d {
417 width,
418 height,
419 depth_or_array_layers: 1,
420 };
421 let texture_desc = wgpu::TextureDescriptor {
422 size,
423 mip_level_count: 1,
424 sample_count: 1,
425 dimension: wgpu::TextureDimension::D2,
426 format: wgpu::TextureFormat::Rgba8Unorm,
427 usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING,
428 label: None,
429 view_formats: &[],
430 };
431
432 let mut uniform_data = Vec::new();
433 for f in &[
434 1.0 / width as f32,
435 1.0 / height as f32,
436 width as f32,
437 height as f32,
438 ] {
439 uniform_data.extend_from_slice(&f.to_ne_bytes());
440 }
441 let rt_uniforms = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
442 label: Some("smaa.uniforms"),
443 usage: wgpu::BufferUsages::UNIFORM,
444 contents: &uniform_data,
445 });
446
447 Self {
448 rt_uniforms,
449 color_target: device
450 .create_texture(&wgpu::TextureDescriptor {
451 format,
452 ..texture_desc
453 })
454 .create_view(&wgpu::TextureViewDescriptor {
455 label: Some("smaa.color_target.view"),
456 ..Default::default()
457 }),
458 edges_target: device
459 .create_texture(&wgpu::TextureDescriptor {
460 format: wgpu::TextureFormat::Rg8Unorm,
461 label: Some("smaa.texture.edge_target"),
462 ..texture_desc
463 })
464 .create_view(&wgpu::TextureViewDescriptor {
465 label: Some("smaa.texture_view.edge_target"),
466 ..Default::default()
467 }),
468
469 blend_target: device
470 .create_texture(&wgpu::TextureDescriptor {
471 format: wgpu::TextureFormat::Rgba8Unorm,
472 label: Some("smaa.texture.blend_target"),
473 ..texture_desc
474 })
475 .create_view(&wgpu::TextureViewDescriptor {
476 label: Some("smaa.texture_view.blend_target"),
477 ..Default::default()
478 }),
479 }
480 }
481}
482impl Resources {
483 fn new(device: &wgpu::Device, queue: &wgpu::Queue) -> Self {
484 let area_texture = device.create_texture_with_data(
485 queue,
486 &wgpu::TextureDescriptor {
487 label: Some("smaa.texture.area"),
488 size: wgpu::Extent3d {
489 width: AREATEX_WIDTH,
490 height: AREATEX_HEIGHT,
491 depth_or_array_layers: 1,
492 },
493 mip_level_count: 1,
494 sample_count: 1,
495 dimension: wgpu::TextureDimension::D2,
496 format: wgpu::TextureFormat::Rg8Unorm,
497 usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
498 view_formats: &[],
499 },
500 wgpu::util::TextureDataOrder::LayerMajor,
501 &AREATEX_BYTES,
502 );
503
504 let search_texture = device.create_texture_with_data(
505 queue,
506 &wgpu::TextureDescriptor {
507 label: Some("smaa.texture.search"),
508 size: wgpu::Extent3d {
509 width: SEARCHTEX_WIDTH,
510 height: SEARCHTEX_HEIGHT,
511 depth_or_array_layers: 1,
512 },
513 mip_level_count: 1,
514 sample_count: 1,
515 dimension: wgpu::TextureDimension::D2,
516 format: wgpu::TextureFormat::R8Unorm,
517 usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
518 view_formats: &[],
519 },
520 wgpu::util::TextureDataOrder::LayerMajor,
521 &SEARCHTEX_BYTES,
522 );
523
524 let linear_sampler = device.create_sampler(&wgpu::SamplerDescriptor {
525 label: Some("smaa.sampler"),
526 mag_filter: wgpu::FilterMode::Linear,
527 min_filter: wgpu::FilterMode::Linear,
528 mipmap_filter: wgpu::MipmapFilterMode::Nearest,
529 address_mode_u: wgpu::AddressMode::ClampToEdge,
530 address_mode_v: wgpu::AddressMode::ClampToEdge,
531 ..Default::default()
532 });
533
534 Self {
535 area_texture,
536 search_texture,
537 linear_sampler,
538 }
539 }
540}
541
542impl BindGroups {
543 fn new(
544 device: &wgpu::Device,
545 layouts: &BindGroupLayouts,
546 resources: &Resources,
547 targets: &Targets,
548 ) -> Self {
549 Self {
550 edge_detect_bind_group: device.create_bind_group(&wgpu::BindGroupDescriptor {
551 label: Some("smaa.bind_group.edge_detect"),
552 layout: &layouts.edge_detect_bind_group_layout,
553 entries: &[
554 wgpu::BindGroupEntry {
555 binding: 0,
556 resource: wgpu::BindingResource::Sampler(&resources.linear_sampler),
557 },
558 wgpu::BindGroupEntry {
559 binding: 1,
560 resource: wgpu::BindingResource::Buffer(wgpu::BufferBinding {
561 buffer: &targets.rt_uniforms,
562 offset: 0,
563 size: None,
564 }),
565 },
566 wgpu::BindGroupEntry {
567 binding: 2,
568 resource: wgpu::BindingResource::TextureView(&targets.color_target),
569 },
570 ],
571 }),
572
573 blend_weight_bind_group: device.create_bind_group(&wgpu::BindGroupDescriptor {
574 label: Some("smaa.bind_group.blend_weight"),
575 layout: &layouts.blend_weight_bind_group_layout,
576 entries: &[
577 wgpu::BindGroupEntry {
578 binding: 0,
579 resource: wgpu::BindingResource::Sampler(&resources.linear_sampler),
580 },
581 wgpu::BindGroupEntry {
582 binding: 1,
583 resource: wgpu::BindingResource::Buffer(wgpu::BufferBinding {
584 buffer: &targets.rt_uniforms,
585 offset: 0,
586 size: None,
587 }),
588 },
589 wgpu::BindGroupEntry {
590 binding: 2,
591 resource: wgpu::BindingResource::TextureView(&targets.edges_target),
592 },
593 wgpu::BindGroupEntry {
594 binding: 3,
595 resource: wgpu::BindingResource::TextureView(
596 &resources.area_texture.create_view(&Default::default()),
597 ),
598 },
599 wgpu::BindGroupEntry {
600 binding: 4,
601 resource: wgpu::BindingResource::TextureView(
602 &resources.search_texture.create_view(&Default::default()),
603 ),
604 },
605 ],
606 }),
607 neighborhood_blending_bind_group: device.create_bind_group(
608 &wgpu::BindGroupDescriptor {
609 label: Some("smaa.bind_group.neighborhood_blending"),
610 layout: &layouts.neighborhood_blending_bind_group_layout,
611 entries: &[
612 wgpu::BindGroupEntry {
613 binding: 0,
614 resource: wgpu::BindingResource::Sampler(&resources.linear_sampler),
615 },
616 wgpu::BindGroupEntry {
617 binding: 1,
618 resource: wgpu::BindingResource::Buffer(wgpu::BufferBinding {
619 buffer: &targets.rt_uniforms,
620 offset: 0,
621 size: None,
622 }),
623 },
624 wgpu::BindGroupEntry {
625 binding: 2,
626 resource: wgpu::BindingResource::TextureView(&targets.color_target),
627 },
628 wgpu::BindGroupEntry {
629 binding: 3,
630 resource: wgpu::BindingResource::TextureView(&targets.blend_target),
631 },
632 ],
633 },
634 ),
635 }
636 }
637}
638
639struct SmaaTargetInner {
640 pipelines: Pipelines,
641 layouts: BindGroupLayouts,
642 resources: Resources,
643 targets: Targets,
644 bind_groups: BindGroups,
645 format: wgpu::TextureFormat,
646}
647
648pub struct SmaaTarget {
651 inner: Option<SmaaTargetInner>,
652}
653
654impl SmaaTarget {
655 pub fn new(
657 device: &wgpu::Device,
658 queue: &wgpu::Queue,
659 width: u32,
660 height: u32,
661 format: wgpu::TextureFormat,
662 mode: SmaaMode,
663 ) -> Self {
664 if let SmaaMode::Disabled = mode {
665 return SmaaTarget { inner: None };
666 }
667
668 let layouts = BindGroupLayouts::new(device);
669 let pipelines = Pipelines::new(device, format, &layouts);
670 let resources = Resources::new(device, queue);
671 let targets = Targets::new(device, width, height, format);
672 let bind_groups = BindGroups::new(device, &layouts, &resources, &targets);
673
674 SmaaTarget {
675 inner: Some(SmaaTargetInner {
676 layouts,
677 pipelines,
678 resources,
679 targets,
680 bind_groups,
681 format,
682 }),
683 }
684 }
685
686 pub fn resize(&mut self, device: &wgpu::Device, width: u32, height: u32) {
688 if let Some(ref mut inner) = self.inner {
689 inner.targets = Targets::new(device, width, height, inner.format);
690 inner.bind_groups =
691 BindGroups::new(device, &inner.layouts, &inner.resources, &inner.targets);
692 }
693 }
694
695 pub fn start_frame<'a>(
697 &'a mut self,
698 device: &'a wgpu::Device,
699 queue: &'a wgpu::Queue,
700 output_view: &'a wgpu::TextureView,
701 ) -> SmaaFrame<'a> {
702 SmaaFrame {
703 target: self,
704 device,
705 queue,
706 output_view,
707 }
708 }
709}
710
711pub struct SmaaFrame<'a> {
713 target: &'a mut SmaaTarget,
714 device: &'a wgpu::Device,
715 queue: &'a wgpu::Queue,
716 output_view: &'a wgpu::TextureView,
717}
718impl<'a> SmaaFrame<'a> {
719 pub fn resolve(self) {
721 std::mem::drop(self);
722 }
723}
724impl<'a> std::ops::Deref for SmaaFrame<'a> {
725 type Target = wgpu::TextureView;
726 fn deref(&self) -> &Self::Target {
727 match self.target.inner {
728 None => self.output_view,
729 Some(ref inner) => &inner.targets.color_target,
730 }
731 }
732}
733impl<'a> Drop for SmaaFrame<'a> {
734 fn drop(&mut self) {
735 if let Some(ref mut inner) = self.target.inner {
736 let mut encoder = self
737 .device
738 .create_command_encoder(&wgpu::CommandEncoderDescriptor {
739 label: Some("smaa.command_encoder"),
740 });
741 {
742 let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
743 color_attachments: &[Some(wgpu::RenderPassColorAttachment {
744 view: &inner.targets.edges_target,
745 resolve_target: None,
746 ops: wgpu::Operations {
747 load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
748 store: wgpu::StoreOp::Store,
749 },
750 depth_slice: None,
751 })],
752 depth_stencil_attachment: None,
753 label: Some("smaa.render_pass.edge_detect"),
754 occlusion_query_set: None,
755 timestamp_writes: None,
756 multiview_mask: None,
757 });
758 rpass.set_pipeline(&inner.pipelines.edge_detect);
759 rpass.set_bind_group(0, &inner.bind_groups.edge_detect_bind_group, &[]);
760 rpass.draw(0..3, 0..1);
761 }
762 {
763 let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
764 color_attachments: &[Some(wgpu::RenderPassColorAttachment {
765 view: &inner.targets.blend_target,
766 resolve_target: None,
767 ops: wgpu::Operations {
768 load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
769 store: wgpu::StoreOp::Store,
770 },
771 depth_slice: None,
772 })],
773 depth_stencil_attachment: None,
774 label: Some("smaa.render_pass.blend_weight"),
775 occlusion_query_set: None,
776 timestamp_writes: None,
777 multiview_mask: None,
778 });
779 rpass.set_pipeline(&inner.pipelines.blend_weight);
780 rpass.set_bind_group(0, &inner.bind_groups.blend_weight_bind_group, &[]);
781 rpass.draw(0..3, 0..1);
782 }
783 {
784 let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
785 color_attachments: &[Some(wgpu::RenderPassColorAttachment {
786 view: self.output_view,
787 resolve_target: None,
788 ops: wgpu::Operations {
789 load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
790 store: wgpu::StoreOp::Store,
791 },
792 depth_slice: None,
793 })],
794 depth_stencil_attachment: None,
795 label: Some("smaa.render_pass.neighborhood_blending"),
796 occlusion_query_set: None,
797 timestamp_writes: None,
798 multiview_mask: None,
799 });
800 rpass.set_pipeline(&inner.pipelines.neighborhood_blending);
801 rpass.set_bind_group(0, &inner.bind_groups.neighborhood_blending_bind_group, &[]);
802 rpass.draw(0..3, 0..1);
803 }
804 self.queue.submit(Some(encoder.finish()));
805 }
806 }
807}