migrate blit
This commit is contained in:
parent
88b3b5e71e
commit
9d41372966
@ -1,6 +1,8 @@
|
||||
use core::{ops::Deref, result::Result};
|
||||
|
||||
use crate::FullscreenShader;
|
||||
use bevy_app::{App, Plugin};
|
||||
use bevy_asset::{embedded_asset, load_embedded_asset, AssetServer, Handle};
|
||||
use bevy_asset::{embedded_asset, load_embedded_asset, AssetServer};
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_render::{
|
||||
render_resource::{
|
||||
@ -24,8 +26,7 @@ impl Plugin for BlitPlugin {
|
||||
};
|
||||
|
||||
render_app
|
||||
.allow_ambiguous_resource::<SpecializedRenderPipelines<BlitPipeline>>()
|
||||
.init_resource::<SpecializedRenderPipelines<BlitPipeline>>()
|
||||
.allow_ambiguous_resource::<BlitPipeline>()
|
||||
.add_systems(RenderStartup, init_blit_pipeline);
|
||||
}
|
||||
}
|
||||
@ -34,8 +35,7 @@ impl Plugin for BlitPlugin {
|
||||
pub struct BlitPipeline {
|
||||
pub layout: BindGroupLayout,
|
||||
pub sampler: Sampler,
|
||||
pub fullscreen_shader: FullscreenShader,
|
||||
pub fragment_shader: Handle<Shader>,
|
||||
pub specialized_cache: SpecializedCache<RenderPipeline, BlitSpecializer>,
|
||||
}
|
||||
|
||||
pub fn init_blit_pipeline(
|
||||
@ -57,11 +57,23 @@ pub fn init_blit_pipeline(
|
||||
|
||||
let sampler = render_device.create_sampler(&SamplerDescriptor::default());
|
||||
|
||||
let base_descriptor = RenderPipelineDescriptor {
|
||||
label: Some("blit pipeline".into()),
|
||||
layout: vec![layout.clone()],
|
||||
vertex: fullscreen_shader.to_vertex_state(),
|
||||
fragment: Some(FragmentState {
|
||||
shader: load_embedded_asset!(asset_server.deref(), "blit.wgsl"),
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
};
|
||||
|
||||
let specialized_cache = SpecializedCache::new(BlitSpecializer, base_descriptor);
|
||||
|
||||
commands.insert_resource(BlitPipeline {
|
||||
layout,
|
||||
sampler,
|
||||
fullscreen_shader: fullscreen_shader.clone(),
|
||||
fragment_shader: load_embedded_asset!(asset_server.as_ref(), "blit.wgsl"),
|
||||
specialized_cache,
|
||||
});
|
||||
}
|
||||
|
||||
@ -79,35 +91,34 @@ impl BlitPipeline {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
|
||||
pub struct BlitPipelineKey {
|
||||
pub struct BlitSpecializer;
|
||||
|
||||
impl Specializer<RenderPipeline> for BlitSpecializer {
|
||||
type Key = BlitKey;
|
||||
|
||||
fn specialize(
|
||||
&self,
|
||||
key: Self::Key,
|
||||
descriptor: &mut <RenderPipeline as Specializable>::Descriptor,
|
||||
) -> Result<Canonical<Self::Key>, BevyError> {
|
||||
descriptor.multisample.count = key.samples;
|
||||
|
||||
descriptor.fragment_mut()?.set_target(
|
||||
0,
|
||||
ColorTargetState {
|
||||
format: key.texture_format,
|
||||
blend: key.blend_state,
|
||||
write_mask: ColorWrites::ALL,
|
||||
},
|
||||
);
|
||||
|
||||
Ok(key)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Clone, Copy, SpecializerKey)]
|
||||
pub struct BlitKey {
|
||||
pub texture_format: TextureFormat,
|
||||
pub blend_state: Option<BlendState>,
|
||||
pub samples: u32,
|
||||
}
|
||||
|
||||
impl SpecializedRenderPipeline for BlitPipeline {
|
||||
type Key = BlitPipelineKey;
|
||||
|
||||
fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor {
|
||||
RenderPipelineDescriptor {
|
||||
label: Some("blit pipeline".into()),
|
||||
layout: vec![self.layout.clone()],
|
||||
vertex: self.fullscreen_shader.to_vertex_state(),
|
||||
fragment: Some(FragmentState {
|
||||
shader: self.fragment_shader.clone(),
|
||||
targets: vec![Some(ColorTargetState {
|
||||
format: key.texture_format,
|
||||
blend: key.blend_state,
|
||||
write_mask: ColorWrites::ALL,
|
||||
})],
|
||||
..default()
|
||||
}),
|
||||
multisample: MultisampleState {
|
||||
count: key.samples,
|
||||
..default()
|
||||
},
|
||||
..default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
blit::{BlitPipeline, BlitPipelineKey},
|
||||
blit::{BlitKey, BlitPipeline},
|
||||
core_2d::graph::{Core2d, Node2d},
|
||||
core_3d::graph::{Core3d, Node3d},
|
||||
};
|
||||
@ -119,22 +119,23 @@ pub struct MsaaWritebackBlitPipeline(CachedRenderPipelineId);
|
||||
fn prepare_msaa_writeback_pipelines(
|
||||
mut commands: Commands,
|
||||
pipeline_cache: Res<PipelineCache>,
|
||||
mut pipelines: ResMut<SpecializedRenderPipelines<BlitPipeline>>,
|
||||
blit_pipeline: Res<BlitPipeline>,
|
||||
mut blit_pipeline: ResMut<BlitPipeline>,
|
||||
view_targets: Query<(Entity, &ViewTarget, &ExtractedCamera, &Msaa)>,
|
||||
) {
|
||||
) -> Result<(), BevyError> {
|
||||
for (entity, view_target, camera, msaa) in view_targets.iter() {
|
||||
// only do writeback if writeback is enabled for the camera and this isn't the first camera in the target,
|
||||
// as there is nothing to write back for the first camera.
|
||||
if msaa.samples() > 1 && camera.msaa_writeback && camera.sorted_camera_index_for_target > 0
|
||||
{
|
||||
let key = BlitPipelineKey {
|
||||
let key = BlitKey {
|
||||
texture_format: view_target.main_texture_format(),
|
||||
samples: msaa.samples(),
|
||||
blend_state: None,
|
||||
};
|
||||
|
||||
let pipeline = pipelines.specialize(&pipeline_cache, &blit_pipeline, key);
|
||||
let pipeline = blit_pipeline
|
||||
.specialized_cache
|
||||
.specialize(&pipeline_cache, key)?;
|
||||
commands
|
||||
.entity(entity)
|
||||
.insert(MsaaWritebackBlitPipeline(pipeline));
|
||||
@ -146,4 +147,5 @@ fn prepare_msaa_writeback_pipelines(
|
||||
.remove::<MsaaWritebackBlitPipeline>();
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::blit::{BlitPipeline, BlitPipelineKey};
|
||||
use crate::blit::{BlitKey, BlitPipeline};
|
||||
use bevy_app::prelude::*;
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_platform::collections::HashSet;
|
||||
@ -39,10 +39,9 @@ pub struct ViewUpscalingPipeline(CachedRenderPipelineId);
|
||||
fn prepare_view_upscaling_pipelines(
|
||||
mut commands: Commands,
|
||||
mut pipeline_cache: ResMut<PipelineCache>,
|
||||
mut pipelines: ResMut<SpecializedRenderPipelines<BlitPipeline>>,
|
||||
blit_pipeline: Res<BlitPipeline>,
|
||||
mut blit_pipeline: ResMut<BlitPipeline>,
|
||||
view_targets: Query<(Entity, &ViewTarget, Option<&ExtractedCamera>)>,
|
||||
) {
|
||||
) -> Result<(), BevyError> {
|
||||
let mut output_textures = <HashSet<_>>::default();
|
||||
for (entity, view_target, camera) in view_targets.iter() {
|
||||
let out_texture_id = view_target.out_texture().id();
|
||||
@ -73,12 +72,14 @@ fn prepare_view_upscaling_pipelines(
|
||||
None
|
||||
};
|
||||
|
||||
let key = BlitPipelineKey {
|
||||
let key = BlitKey {
|
||||
texture_format: view_target.out_texture_format(),
|
||||
blend_state,
|
||||
samples: 1,
|
||||
};
|
||||
let pipeline = pipelines.specialize(&pipeline_cache, &blit_pipeline, key);
|
||||
let pipeline = blit_pipeline
|
||||
.specialized_cache
|
||||
.specialize(&pipeline_cache, key)?;
|
||||
|
||||
// Ensure the pipeline is loaded before continuing the frame to prevent frames without any GPU work submitted
|
||||
pipeline_cache.block_on_render_pipeline(pipeline);
|
||||
@ -87,4 +88,6 @@ fn prepare_view_upscaling_pipelines(
|
||||
.entity(entity)
|
||||
.insert(ViewUpscalingPipeline(pipeline));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user