Skip to content

Commit bc858da

Browse files
committed
migrate blit
1 parent 498b109 commit bc858da

File tree

4 files changed

+71
-52
lines changed

4 files changed

+71
-52
lines changed
Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
use core::result::Result;
2+
13
use crate::FullscreenShader;
24
use bevy_app::{App, Plugin};
3-
use bevy_asset::{embedded_asset, load_embedded_asset, Handle};
5+
use bevy_asset::{embedded_asset, load_embedded_asset};
46
use bevy_ecs::prelude::*;
57
use bevy_render::{
68
render_resource::{
@@ -20,26 +22,23 @@ impl Plugin for BlitPlugin {
2022
embedded_asset!(app, "blit.wgsl");
2123

2224
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
23-
render_app.allow_ambiguous_resource::<SpecializedRenderPipelines<BlitPipeline>>();
25+
render_app.allow_ambiguous_resource::<BlitPipeline>();
2426
}
2527
}
2628

2729
fn finish(&self, app: &mut App) {
2830
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
2931
return;
3032
};
31-
render_app
32-
.init_resource::<BlitPipeline>()
33-
.init_resource::<SpecializedRenderPipelines<BlitPipeline>>();
33+
render_app.init_resource::<BlitPipeline>();
3434
}
3535
}
3636

3737
#[derive(Resource)]
3838
pub struct BlitPipeline {
39-
pub texture_bind_group: BindGroupLayout,
39+
pub layout: BindGroupLayout,
4040
pub sampler: Sampler,
41-
pub fullscreen_shader: FullscreenShader,
42-
pub fragment_shader: Handle<Shader>,
41+
pub specialized_cache: SpecializedCache<RenderPipeline, BlitSpecializer>,
4342
}
4443

4544
impl FromWorld for BlitPipeline {
@@ -59,44 +58,59 @@ impl FromWorld for BlitPipeline {
5958

6059
let sampler = render_device.create_sampler(&SamplerDescriptor::default());
6160

61+
let fullscreen_shader = render_world.resource::<FullscreenShader>().clone();
62+
let fragment_shader = load_embedded_asset!(render_world, "blit.wgsl");
63+
64+
let base_descriptor = RenderPipelineDescriptor {
65+
label: Some("blit pipeline".into()),
66+
layout: vec![texture_bind_group.clone()],
67+
vertex: fullscreen_shader.to_vertex_state(),
68+
fragment: Some(FragmentState {
69+
shader: fragment_shader,
70+
targets: vec![],
71+
..default()
72+
}),
73+
..default()
74+
};
75+
76+
let specialized_cache = SpecializedCache::new(BlitSpecializer, None, base_descriptor);
77+
6278
BlitPipeline {
63-
texture_bind_group,
79+
layout: texture_bind_group,
6480
sampler,
65-
fullscreen_shader: render_world.resource::<FullscreenShader>().clone(),
66-
fragment_shader: load_embedded_asset!(render_world, "blit.wgsl"),
81+
specialized_cache,
6782
}
6883
}
6984
}
7085

71-
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
72-
pub struct BlitPipelineKey {
73-
pub texture_format: TextureFormat,
74-
pub blend_state: Option<BlendState>,
75-
pub samples: u32,
76-
}
86+
pub struct BlitSpecializer;
7787

78-
impl SpecializedRenderPipeline for BlitPipeline {
79-
type Key = BlitPipelineKey;
88+
impl Specializer<RenderPipeline> for BlitSpecializer {
89+
type Key = BlitKey;
8090

81-
fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor {
82-
RenderPipelineDescriptor {
83-
label: Some("blit pipeline".into()),
84-
layout: vec![self.texture_bind_group.clone()],
85-
vertex: self.fullscreen_shader.to_vertex_state(),
86-
fragment: Some(FragmentState {
87-
shader: self.fragment_shader.clone(),
88-
targets: vec![Some(ColorTargetState {
89-
format: key.texture_format,
90-
blend: key.blend_state,
91-
write_mask: ColorWrites::ALL,
92-
})],
93-
..default()
94-
}),
95-
multisample: MultisampleState {
96-
count: key.samples,
97-
..default()
91+
fn specialize(
92+
&self,
93+
key: Self::Key,
94+
descriptor: &mut <RenderPipeline as Specializable>::Descriptor,
95+
) -> Result<Canonical<Self::Key>, BevyError> {
96+
descriptor.multisample.count = key.samples;
97+
98+
descriptor.fragment_mut()?.set_target(
99+
0,
100+
ColorTargetState {
101+
format: key.texture_format,
102+
blend: key.blend_state,
103+
write_mask: ColorWrites::ALL,
98104
},
99-
..default()
100-
}
105+
);
106+
107+
Ok(key)
101108
}
102109
}
110+
111+
#[derive(PartialEq, Eq, Hash, Clone, Copy, SpecializerKey)]
112+
pub struct BlitKey {
113+
pub texture_format: TextureFormat,
114+
pub blend_state: Option<BlendState>,
115+
pub samples: u32,
116+
}

crates/bevy_core_pipeline/src/msaa_writeback.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
blit::{BlitPipeline, BlitPipelineKey},
2+
blit::{BlitKey, BlitPipeline},
33
core_2d::graph::{Core2d, Node2d},
44
core_3d::graph::{Core3d, Node3d},
55
};
@@ -100,7 +100,7 @@ impl ViewNode for MsaaWritebackNode {
100100

101101
let bind_group = render_context.render_device().create_bind_group(
102102
None,
103-
&blit_pipeline.texture_bind_group,
103+
&blit_pipeline.layout,
104104
&BindGroupEntries::sequential((post_process.source, &blit_pipeline.sampler)),
105105
);
106106

@@ -122,22 +122,23 @@ pub struct MsaaWritebackBlitPipeline(CachedRenderPipelineId);
122122
fn prepare_msaa_writeback_pipelines(
123123
mut commands: Commands,
124124
pipeline_cache: Res<PipelineCache>,
125-
mut pipelines: ResMut<SpecializedRenderPipelines<BlitPipeline>>,
126-
blit_pipeline: Res<BlitPipeline>,
125+
mut blit_pipeline: ResMut<BlitPipeline>,
127126
view_targets: Query<(Entity, &ViewTarget, &ExtractedCamera, &Msaa)>,
128-
) {
127+
) -> Result<(), BevyError> {
129128
for (entity, view_target, camera, msaa) in view_targets.iter() {
130129
// only do writeback if writeback is enabled for the camera and this isn't the first camera in the target,
131130
// as there is nothing to write back for the first camera.
132131
if msaa.samples() > 1 && camera.msaa_writeback && camera.sorted_camera_index_for_target > 0
133132
{
134-
let key = BlitPipelineKey {
133+
let key = BlitKey {
135134
texture_format: view_target.main_texture_format(),
136135
samples: msaa.samples(),
137136
blend_state: None,
138137
};
139138

140-
let pipeline = pipelines.specialize(&pipeline_cache, &blit_pipeline, key);
139+
let pipeline = blit_pipeline
140+
.specialized_cache
141+
.specialize(&pipeline_cache, key)?;
141142
commands
142143
.entity(entity)
143144
.insert(MsaaWritebackBlitPipeline(pipeline));
@@ -149,4 +150,5 @@ fn prepare_msaa_writeback_pipelines(
149150
.remove::<MsaaWritebackBlitPipeline>();
150151
}
151152
}
153+
Ok(())
152154
}

crates/bevy_core_pipeline/src/upscaling/mod.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::blit::{BlitPipeline, BlitPipelineKey};
1+
use crate::blit::{BlitKey, BlitPipeline};
22
use bevy_app::prelude::*;
33
use bevy_ecs::prelude::*;
44
use bevy_platform::collections::HashSet;
@@ -39,10 +39,9 @@ pub struct ViewUpscalingPipeline(CachedRenderPipelineId);
3939
fn prepare_view_upscaling_pipelines(
4040
mut commands: Commands,
4141
mut pipeline_cache: ResMut<PipelineCache>,
42-
mut pipelines: ResMut<SpecializedRenderPipelines<BlitPipeline>>,
43-
blit_pipeline: Res<BlitPipeline>,
42+
mut blit_pipeline: ResMut<BlitPipeline>,
4443
view_targets: Query<(Entity, &ViewTarget, Option<&ExtractedCamera>)>,
45-
) {
44+
) -> Result<(), BevyError> {
4645
let mut output_textures = <HashSet<_>>::default();
4746
for (entity, view_target, camera) in view_targets.iter() {
4847
let out_texture_id = view_target.out_texture().id();
@@ -73,12 +72,14 @@ fn prepare_view_upscaling_pipelines(
7372
None
7473
};
7574

76-
let key = BlitPipelineKey {
75+
let key = BlitKey {
7776
texture_format: view_target.out_texture_format(),
7877
blend_state,
7978
samples: 1,
8079
};
81-
let pipeline = pipelines.specialize(&pipeline_cache, &blit_pipeline, key);
80+
let pipeline = blit_pipeline
81+
.specialized_cache
82+
.specialize(&pipeline_cache, key)?;
8283

8384
// Ensure the pipeline is loaded before continuing the frame to prevent frames without any GPU work submitted
8485
pipeline_cache.block_on_render_pipeline(pipeline);
@@ -87,4 +88,6 @@ fn prepare_view_upscaling_pipelines(
8788
.entity(entity)
8889
.insert(ViewUpscalingPipeline(pipeline));
8990
}
91+
92+
Ok(())
9093
}

crates/bevy_core_pipeline/src/upscaling/node.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl ViewNode for UpscalingNode {
5656
cached_bind_group => {
5757
let bind_group = render_context.render_device().create_bind_group(
5858
None,
59-
&blit_pipeline.texture_bind_group,
59+
&blit_pipeline.layout,
6060
&BindGroupEntries::sequential((upscaled_texture, &blit_pipeline.sampler)),
6161
);
6262

0 commit comments

Comments
 (0)