Skip to content

Commit

Permalink
Reuse sampler when creating cached bind groups (#10610)
Browse files Browse the repository at this point in the history
# 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.
  • Loading branch information
Kanabenki authored Jan 26, 2024
1 parent bfb8e99 commit 86e91f4
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 41 deletions.
38 changes: 24 additions & 14 deletions crates/bevy_core_pipeline/src/fxaa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand All @@ -22,6 +21,7 @@ use bevy_render::{
view::{ExtractedView, ViewTarget},
Render, RenderApp, RenderSet,
};
use bevy_utils::default;

mod node;

Expand Down Expand Up @@ -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::<RenderDevice>()
.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::<RenderDevice>();
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,
}
}
}

Expand Down
16 changes: 3 additions & 13 deletions crates/bevy_core_pipeline/src/fxaa/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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));
Expand Down
8 changes: 6 additions & 2 deletions crates/bevy_core_pipeline/src/tonemapping/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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,
}
}
}
Expand Down
8 changes: 2 additions & 6 deletions crates/bevy_core_pipeline/src/tonemapping/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand All @@ -94,7 +90,7 @@ impl ViewNode for TonemappingNode {
&BindGroupEntries::sequential((
view_uniforms,
source,
&sampler,
&tonemapping_pipeline.sampler,
lut_bindings.0,
lut_bindings.1,
)),
Expand Down
8 changes: 2 additions & 6 deletions crates/bevy_core_pipeline/src/upscaling/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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));
Expand Down

0 comments on commit 86e91f4

Please sign in to comment.