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.
This commit is contained in:
Kanabenki 2024-01-26 14:34:29 +01:00 committed by GitHub
parent bfb8e9978a
commit 86e91f4368
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 37 additions and 41 deletions

View file

@ -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,16 +123,16 @@ 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::<RenderDevice>()
.create_bind_group_layout(
let render_device = render_world.resource::<RenderDevice>();
let texture_bind_group = render_device.create_bind_group_layout(
"fxaa_texture_bind_group_layout",
&BindGroupLayoutEntries::sequential(
ShaderStages::FRAGMENT,
@ -143,7 +143,17 @@ impl FromWorld for FxaaPipeline {
),
);
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,
}
}
}

View file

@ -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));

View file

@ -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::<RenderDevice>()
let render_device = render_world.resource::<RenderDevice>();
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,
}
}
}

View file

@ -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::<TonemappingLuts>();
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,
)),

View file

@ -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));