From 86e91f4368adb8d6beb355b4d53348a624fb51c3 Mon Sep 17 00:00:00 2001 From: Kanabenki Date: Fri, 26 Jan 2024 14:34:29 +0100 Subject: [PATCH] Reuse sampler when creating cached bind groups (#10610) # Objective - Some passes recreate a sampler when creating a bind group to be cached, even if the sampler is always the same. ## Solution - Store the sampler in the corresponding pipeline resource. --- crates/bevy_core_pipeline/src/fxaa/mod.rs | 38 ++++++++++++------- crates/bevy_core_pipeline/src/fxaa/node.rs | 16 ++------ .../bevy_core_pipeline/src/tonemapping/mod.rs | 8 +++- .../src/tonemapping/node.rs | 8 +--- .../bevy_core_pipeline/src/upscaling/node.rs | 8 +--- 5 files changed, 37 insertions(+), 41 deletions(-) diff --git a/crates/bevy_core_pipeline/src/fxaa/mod.rs b/crates/bevy_core_pipeline/src/fxaa/mod.rs index 26fd1bd13a..c7777cd33c 100644 --- a/crates/bevy_core_pipeline/src/fxaa/mod.rs +++ b/crates/bevy_core_pipeline/src/fxaa/mod.rs @@ -5,7 +5,6 @@ use crate::{ }; use bevy_app::prelude::*; use bevy_asset::{load_internal_asset, Handle}; -use bevy_derive::Deref; use bevy_ecs::prelude::*; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ @@ -22,6 +21,7 @@ use bevy_render::{ view::{ExtractedView, ViewTarget}, Render, RenderApp, RenderSet, }; +use bevy_utils::default; mod node; @@ -123,27 +123,37 @@ impl Plugin for FxaaPlugin { } } -#[derive(Resource, Deref)] +#[derive(Resource)] pub struct FxaaPipeline { texture_bind_group: BindGroupLayout, + sampler: Sampler, } impl FromWorld for FxaaPipeline { fn from_world(render_world: &mut World) -> Self { - let texture_bind_group = render_world - .resource::() - .create_bind_group_layout( - "fxaa_texture_bind_group_layout", - &BindGroupLayoutEntries::sequential( - ShaderStages::FRAGMENT, - ( - texture_2d(TextureSampleType::Float { filterable: true }), - sampler(SamplerBindingType::Filtering), - ), + let render_device = render_world.resource::(); + let texture_bind_group = render_device.create_bind_group_layout( + "fxaa_texture_bind_group_layout", + &BindGroupLayoutEntries::sequential( + ShaderStages::FRAGMENT, + ( + texture_2d(TextureSampleType::Float { filterable: true }), + sampler(SamplerBindingType::Filtering), ), - ); + ), + ); - FxaaPipeline { texture_bind_group } + let sampler = render_device.create_sampler(&SamplerDescriptor { + mipmap_filter: FilterMode::Linear, + mag_filter: FilterMode::Linear, + min_filter: FilterMode::Linear, + ..default() + }); + + FxaaPipeline { + texture_bind_group, + sampler, + } } } diff --git a/crates/bevy_core_pipeline/src/fxaa/node.rs b/crates/bevy_core_pipeline/src/fxaa/node.rs index 9c920d5d59..1a575b8338 100644 --- a/crates/bevy_core_pipeline/src/fxaa/node.rs +++ b/crates/bevy_core_pipeline/src/fxaa/node.rs @@ -6,13 +6,12 @@ use bevy_ecs::query::QueryItem; use bevy_render::{ render_graph::{NodeRunError, RenderGraphContext, ViewNode}, render_resource::{ - BindGroup, BindGroupEntries, FilterMode, Operations, PipelineCache, - RenderPassColorAttachment, RenderPassDescriptor, SamplerDescriptor, TextureViewId, + BindGroup, BindGroupEntries, Operations, PipelineCache, RenderPassColorAttachment, + RenderPassDescriptor, TextureViewId, }, renderer::RenderContext, view::ViewTarget, }; -use bevy_utils::default; #[derive(Default)] pub struct FxaaNode { @@ -51,19 +50,10 @@ impl ViewNode for FxaaNode { let bind_group = match &mut *cached_bind_group { Some((id, bind_group)) if source.id() == *id => bind_group, cached_bind_group => { - let sampler = render_context - .render_device() - .create_sampler(&SamplerDescriptor { - mipmap_filter: FilterMode::Linear, - mag_filter: FilterMode::Linear, - min_filter: FilterMode::Linear, - ..default() - }); - let bind_group = render_context.render_device().create_bind_group( None, &fxaa_pipeline.texture_bind_group, - &BindGroupEntries::sequential((source, &sampler)), + &BindGroupEntries::sequential((source, &fxaa_pipeline.sampler)), ); let (_, bind_group) = cached_bind_group.insert((source.id(), bind_group)); diff --git a/crates/bevy_core_pipeline/src/tonemapping/mod.rs b/crates/bevy_core_pipeline/src/tonemapping/mod.rs index 8e277a2e50..71eec7a18d 100644 --- a/crates/bevy_core_pipeline/src/tonemapping/mod.rs +++ b/crates/bevy_core_pipeline/src/tonemapping/mod.rs @@ -114,6 +114,7 @@ impl Plugin for TonemappingPlugin { #[derive(Resource)] pub struct TonemappingPipeline { texture_bind_group: BindGroupLayout, + sampler: Sampler, } /// Optionally enables a tonemapping shader that attempts to map linear input stimulus into a perceptually uniform image for a given [`Camera`] entity. @@ -266,12 +267,15 @@ impl FromWorld for TonemappingPipeline { entries = entries.extend_with_indices(((3, lut_layout_entries[0]), (4, lut_layout_entries[1]))); - let tonemap_texture_bind_group = render_world - .resource::() + let render_device = render_world.resource::(); + let tonemap_texture_bind_group = render_device .create_bind_group_layout("tonemapping_hdr_texture_bind_group_layout", &entries); + let sampler = render_device.create_sampler(&SamplerDescriptor::default()); + TonemappingPipeline { texture_bind_group: tonemap_texture_bind_group, + sampler, } } } diff --git a/crates/bevy_core_pipeline/src/tonemapping/node.rs b/crates/bevy_core_pipeline/src/tonemapping/node.rs index 08084592c0..df57976654 100644 --- a/crates/bevy_core_pipeline/src/tonemapping/node.rs +++ b/crates/bevy_core_pipeline/src/tonemapping/node.rs @@ -8,7 +8,7 @@ use bevy_render::{ render_graph::{NodeRunError, RenderGraphContext, ViewNode}, render_resource::{ BindGroup, BindGroupEntries, BufferId, LoadOp, Operations, PipelineCache, - RenderPassColorAttachment, RenderPassDescriptor, SamplerDescriptor, StoreOp, TextureViewId, + RenderPassColorAttachment, RenderPassDescriptor, StoreOp, TextureViewId, }, renderer::RenderContext, texture::Image, @@ -80,10 +80,6 @@ impl ViewNode for TonemappingNode { bind_group } cached_bind_group => { - let sampler = render_context - .render_device() - .create_sampler(&SamplerDescriptor::default()); - let tonemapping_luts = world.resource::(); let lut_bindings = get_lut_bindings(gpu_images, tonemapping_luts, tonemapping); @@ -94,7 +90,7 @@ impl ViewNode for TonemappingNode { &BindGroupEntries::sequential(( view_uniforms, source, - &sampler, + &tonemapping_pipeline.sampler, lut_bindings.0, lut_bindings.1, )), diff --git a/crates/bevy_core_pipeline/src/upscaling/node.rs b/crates/bevy_core_pipeline/src/upscaling/node.rs index 16e277aeb0..59232f51c0 100644 --- a/crates/bevy_core_pipeline/src/upscaling/node.rs +++ b/crates/bevy_core_pipeline/src/upscaling/node.rs @@ -5,7 +5,7 @@ use bevy_render::{ render_graph::{NodeRunError, RenderGraphContext, ViewNode}, render_resource::{ BindGroup, BindGroupEntries, LoadOp, Operations, PipelineCache, RenderPassColorAttachment, - RenderPassDescriptor, SamplerDescriptor, StoreOp, TextureViewId, + RenderPassDescriptor, StoreOp, TextureViewId, }, renderer::RenderContext, view::ViewTarget, @@ -52,14 +52,10 @@ impl ViewNode for UpscalingNode { let bind_group = match &mut *cached_bind_group { Some((id, bind_group)) if upscaled_texture.id() == *id => bind_group, cached_bind_group => { - let sampler = render_context - .render_device() - .create_sampler(&SamplerDescriptor::default()); - let bind_group = render_context.render_device().create_bind_group( None, &blit_pipeline.texture_bind_group, - &BindGroupEntries::sequential((upscaled_texture, &sampler)), + &BindGroupEntries::sequential((upscaled_texture, &blit_pipeline.sampler)), ); let (_, bind_group) = cached_bind_group.insert((upscaled_texture.id(), bind_group));