ranim_render/pipelines/
oit_resolve.rs1use std::ops::Deref;
2
3use bevy_ecs::prelude::*;
4
5use crate::{
6 ResolutionInfo, WgpuContext,
7 resource::{GpuResource, OUTPUT_TEXTURE_FORMAT, PipelinesPool},
8 schedule::{FrameTarget, RenderContext},
9};
10
11pub(crate) fn resolve(
12 mut render: RenderContext,
13 ctx: Res<WgpuContext>,
14 pipelines: Res<PipelinesPool>,
15 resolution: Res<ResolutionInfo>,
16 target: Res<FrameTarget>,
17) {
18 let mut pass = render
19 .encoder()
20 .begin_render_pass(&wgpu::RenderPassDescriptor {
21 label: Some("OIT Resolve Pass"),
22 color_attachments: &[Some(wgpu::RenderPassColorAttachment {
23 view: &target.render_view,
24 resolve_target: None,
25 depth_slice: None,
26 ops: wgpu::Operations {
27 load: wgpu::LoadOp::Load,
28 store: wgpu::StoreOp::Store,
29 },
30 })],
31 depth_stencil_attachment: None,
32 timestamp_writes: None,
33 occlusion_query_set: None,
34 multiview_mask: None,
35 });
36 pass.set_pipeline(&pipelines.get_or_init::<OITResolvePipeline>(&ctx));
37 pass.set_bind_group(0, &resolution.bind_group, &[]);
38 pass.set_bind_group(1, &target.depth_bind_group, &[]);
39 pass.draw(0..3, 0..1);
40 drop(pass);
41 render
42 .encoder()
43 .clear_buffer(&resolution.pixel_count_buffer.buffer, 0, None);
44}
45
46pub struct OITResolvePipeline {
47 pipeline: wgpu::RenderPipeline,
48}
49
50impl Deref for OITResolvePipeline {
51 type Target = wgpu::RenderPipeline;
52 fn deref(&self) -> &Self::Target {
53 &self.pipeline
54 }
55}
56
57impl OITResolvePipeline {
58 pub fn depth_bind_group_layout(ctx: &WgpuContext) -> wgpu::BindGroupLayout {
59 ctx.device
60 .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
61 label: Some("OIT Resolve Depth BGL"),
62 entries: &[wgpu::BindGroupLayoutEntry {
63 binding: 0,
64 visibility: wgpu::ShaderStages::FRAGMENT,
65 ty: wgpu::BindingType::Texture {
66 sample_type: wgpu::TextureSampleType::Depth,
67 view_dimension: wgpu::TextureViewDimension::D2,
68 multisampled: false,
69 },
70 count: None,
71 }],
72 })
73 }
74}
75
76impl GpuResource for OITResolvePipeline {
77 fn new(wgpu_ctx: &WgpuContext) -> Self {
78 let WgpuContext { device, .. } = wgpu_ctx;
79
80 let module =
81 &device.create_shader_module(wgpu::include_wgsl!("./shaders/oit_resolve.wgsl"));
82
83 let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
84 label: Some("OIT Resolve Pipeline Layout"),
85 bind_group_layouts: &[
86 Some(&ResolutionInfo::create_bind_group_layout(wgpu_ctx)),
87 Some(&Self::depth_bind_group_layout(wgpu_ctx)),
88 ],
89 immediate_size: 0,
90 });
91
92 let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
93 label: Some("OIT Resolve Pipeline"),
94 layout: Some(&pipeline_layout),
95 vertex: wgpu::VertexState {
96 module,
97 entry_point: Some("vs_main"),
98 buffers: &[],
99 compilation_options: wgpu::PipelineCompilationOptions::default(),
100 },
101 fragment: Some(wgpu::FragmentState {
102 module,
103 entry_point: Some("fs_main"),
104 compilation_options: wgpu::PipelineCompilationOptions::default(),
105 targets: &[Some(wgpu::ColorTargetState {
106 format: OUTPUT_TEXTURE_FORMAT,
107 blend: Some(wgpu::BlendState::ALPHA_BLENDING),
108 write_mask: wgpu::ColorWrites::ALL,
109 })],
110 }),
111 primitive: wgpu::PrimitiveState {
112 topology: wgpu::PrimitiveTopology::TriangleList,
113 ..Default::default()
114 },
115 depth_stencil: None, multisample: wgpu::MultisampleState {
117 count: 1,
118 mask: !0,
119 alpha_to_coverage_enabled: false,
120 },
121 multiview_mask: None,
122 cache: None,
123 });
124
125 Self { pipeline }
126 }
127}