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