Mini Blit refactor (#20118)

# Objective

- Clean up usage of BlitPipeline

## Solution

- add `create_bind_group` method
- adjust some field and variable names for clarity

## Testing

- ran 3d_scene
This commit is contained in:
Emerson Coskey 2025-07-14 14:50:56 -07:00 committed by GitHub
parent 6671575eb0
commit 7447b0ab97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 23 deletions

View File

@ -36,7 +36,7 @@ impl Plugin for BlitPlugin {
#[derive(Resource)]
pub struct BlitPipeline {
pub texture_bind_group: BindGroupLayout,
pub layout: BindGroupLayout,
pub sampler: Sampler,
pub fullscreen_shader: FullscreenShader,
pub fragment_shader: Handle<Shader>,
@ -46,7 +46,7 @@ impl FromWorld for BlitPipeline {
fn from_world(render_world: &mut World) -> Self {
let render_device = render_world.resource::<RenderDevice>();
let texture_bind_group = render_device.create_bind_group_layout(
let layout = render_device.create_bind_group_layout(
"blit_bind_group_layout",
&BindGroupLayoutEntries::sequential(
ShaderStages::FRAGMENT,
@ -60,7 +60,7 @@ impl FromWorld for BlitPipeline {
let sampler = render_device.create_sampler(&SamplerDescriptor::default());
BlitPipeline {
texture_bind_group,
layout,
sampler,
fullscreen_shader: render_world.resource::<FullscreenShader>().clone(),
fragment_shader: load_embedded_asset!(render_world, "blit.wgsl"),
@ -68,6 +68,20 @@ impl FromWorld for BlitPipeline {
}
}
impl BlitPipeline {
pub fn create_bind_group(
&self,
render_device: &RenderDevice,
src_texture: &TextureView,
) -> BindGroup {
render_device.create_bind_group(
None,
&self.layout,
&BindGroupEntries::sequential((src_texture, &self.sampler)),
)
}
}
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
pub struct BlitPipelineKey {
pub texture_format: TextureFormat,
@ -81,7 +95,7 @@ impl SpecializedRenderPipeline for BlitPipeline {
fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor {
RenderPipelineDescriptor {
label: Some("blit pipeline".into()),
layout: vec![self.texture_bind_group.clone()],
layout: vec![self.layout.clone()],
vertex: self.fullscreen_shader.to_vertex_state(),
fragment: Some(FragmentState {
shader: self.fragment_shader.clone(),

View File

@ -98,11 +98,8 @@ impl ViewNode for MsaaWritebackNode {
occlusion_query_set: None,
};
let bind_group = render_context.render_device().create_bind_group(
None,
&blit_pipeline.texture_bind_group,
&BindGroupEntries::sequential((post_process.source, &blit_pipeline.sampler)),
);
let bind_group =
blit_pipeline.create_bind_group(render_context.render_device(), post_process.source);
let mut render_pass = render_context
.command_encoder()

View File

@ -3,9 +3,7 @@ use bevy_ecs::{prelude::*, query::QueryItem};
use bevy_render::{
camera::{CameraOutputMode, ClearColor, ClearColorConfig, ExtractedCamera},
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
render_resource::{
BindGroup, BindGroupEntries, PipelineCache, RenderPassDescriptor, TextureViewId,
},
render_resource::{BindGroup, PipelineCache, RenderPassDescriptor, TextureViewId},
renderer::RenderContext,
view::ViewTarget,
};
@ -30,9 +28,9 @@ impl ViewNode for UpscalingNode {
(target, upscaling_target, camera): QueryItem<Self::ViewQuery>,
world: &World,
) -> Result<(), NodeRunError> {
let pipeline_cache = world.get_resource::<PipelineCache>().unwrap();
let blit_pipeline = world.get_resource::<BlitPipeline>().unwrap();
let clear_color_global = world.get_resource::<ClearColor>().unwrap();
let pipeline_cache = world.resource::<PipelineCache>();
let blit_pipeline = world.resource::<BlitPipeline>();
let clear_color_global = world.resource::<ClearColor>();
let clear_color = if let Some(camera) = camera {
match camera.output_mode {
@ -48,19 +46,18 @@ impl ViewNode for UpscalingNode {
ClearColorConfig::None => None,
};
let converted_clear_color = clear_color.map(Into::into);
let upscaled_texture = target.main_texture_view();
// texture to be upscaled to the output texture
let main_texture_view = target.main_texture_view();
let mut cached_bind_group = self.cached_texture_bind_group.lock().unwrap();
let bind_group = match &mut *cached_bind_group {
Some((id, bind_group)) if upscaled_texture.id() == *id => bind_group,
Some((id, bind_group)) if main_texture_view.id() == *id => bind_group,
cached_bind_group => {
let bind_group = render_context.render_device().create_bind_group(
None,
&blit_pipeline.texture_bind_group,
&BindGroupEntries::sequential((upscaled_texture, &blit_pipeline.sampler)),
);
let bind_group = blit_pipeline
.create_bind_group(render_context.render_device(), main_texture_view);
let (_, bind_group) = cached_bind_group.insert((upscaled_texture.id(), bind_group));
let (_, bind_group) =
cached_bind_group.insert((main_texture_view.id(), bind_group));
bind_group
}
};