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:
parent
bfb8e9978a
commit
86e91f4368
@ -5,7 +5,6 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use bevy_app::prelude::*;
|
use bevy_app::prelude::*;
|
||||||
use bevy_asset::{load_internal_asset, Handle};
|
use bevy_asset::{load_internal_asset, Handle};
|
||||||
use bevy_derive::Deref;
|
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
@ -22,6 +21,7 @@ use bevy_render::{
|
|||||||
view::{ExtractedView, ViewTarget},
|
view::{ExtractedView, ViewTarget},
|
||||||
Render, RenderApp, RenderSet,
|
Render, RenderApp, RenderSet,
|
||||||
};
|
};
|
||||||
|
use bevy_utils::default;
|
||||||
|
|
||||||
mod node;
|
mod node;
|
||||||
|
|
||||||
@ -123,27 +123,37 @@ impl Plugin for FxaaPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Resource, Deref)]
|
#[derive(Resource)]
|
||||||
pub struct FxaaPipeline {
|
pub struct FxaaPipeline {
|
||||||
texture_bind_group: BindGroupLayout,
|
texture_bind_group: BindGroupLayout,
|
||||||
|
sampler: Sampler,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromWorld for FxaaPipeline {
|
impl FromWorld for FxaaPipeline {
|
||||||
fn from_world(render_world: &mut World) -> Self {
|
fn from_world(render_world: &mut World) -> Self {
|
||||||
let texture_bind_group = render_world
|
let render_device = render_world.resource::<RenderDevice>();
|
||||||
.resource::<RenderDevice>()
|
let texture_bind_group = render_device.create_bind_group_layout(
|
||||||
.create_bind_group_layout(
|
"fxaa_texture_bind_group_layout",
|
||||||
"fxaa_texture_bind_group_layout",
|
&BindGroupLayoutEntries::sequential(
|
||||||
&BindGroupLayoutEntries::sequential(
|
ShaderStages::FRAGMENT,
|
||||||
ShaderStages::FRAGMENT,
|
(
|
||||||
(
|
texture_2d(TextureSampleType::Float { filterable: true }),
|
||||||
texture_2d(TextureSampleType::Float { filterable: true }),
|
sampler(SamplerBindingType::Filtering),
|
||||||
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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,13 +6,12 @@ use bevy_ecs::query::QueryItem;
|
|||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupEntries, FilterMode, Operations, PipelineCache,
|
BindGroup, BindGroupEntries, Operations, PipelineCache, RenderPassColorAttachment,
|
||||||
RenderPassColorAttachment, RenderPassDescriptor, SamplerDescriptor, TextureViewId,
|
RenderPassDescriptor, TextureViewId,
|
||||||
},
|
},
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
view::ViewTarget,
|
view::ViewTarget,
|
||||||
};
|
};
|
||||||
use bevy_utils::default;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct FxaaNode {
|
pub struct FxaaNode {
|
||||||
@ -51,19 +50,10 @@ impl ViewNode for FxaaNode {
|
|||||||
let bind_group = match &mut *cached_bind_group {
|
let bind_group = match &mut *cached_bind_group {
|
||||||
Some((id, bind_group)) if source.id() == *id => bind_group,
|
Some((id, bind_group)) if source.id() == *id => bind_group,
|
||||||
cached_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(
|
let bind_group = render_context.render_device().create_bind_group(
|
||||||
None,
|
None,
|
||||||
&fxaa_pipeline.texture_bind_group,
|
&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));
|
let (_, bind_group) = cached_bind_group.insert((source.id(), bind_group));
|
||||||
|
|||||||
@ -114,6 +114,7 @@ impl Plugin for TonemappingPlugin {
|
|||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct TonemappingPipeline {
|
pub struct TonemappingPipeline {
|
||||||
texture_bind_group: BindGroupLayout,
|
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.
|
/// 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 =
|
||||||
entries.extend_with_indices(((3, lut_layout_entries[0]), (4, lut_layout_entries[1])));
|
entries.extend_with_indices(((3, lut_layout_entries[0]), (4, lut_layout_entries[1])));
|
||||||
|
|
||||||
let tonemap_texture_bind_group = render_world
|
let render_device = render_world.resource::<RenderDevice>();
|
||||||
.resource::<RenderDevice>()
|
let tonemap_texture_bind_group = render_device
|
||||||
.create_bind_group_layout("tonemapping_hdr_texture_bind_group_layout", &entries);
|
.create_bind_group_layout("tonemapping_hdr_texture_bind_group_layout", &entries);
|
||||||
|
|
||||||
|
let sampler = render_device.create_sampler(&SamplerDescriptor::default());
|
||||||
|
|
||||||
TonemappingPipeline {
|
TonemappingPipeline {
|
||||||
texture_bind_group: tonemap_texture_bind_group,
|
texture_bind_group: tonemap_texture_bind_group,
|
||||||
|
sampler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use bevy_render::{
|
|||||||
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupEntries, BufferId, LoadOp, Operations, PipelineCache,
|
BindGroup, BindGroupEntries, BufferId, LoadOp, Operations, PipelineCache,
|
||||||
RenderPassColorAttachment, RenderPassDescriptor, SamplerDescriptor, StoreOp, TextureViewId,
|
RenderPassColorAttachment, RenderPassDescriptor, StoreOp, TextureViewId,
|
||||||
},
|
},
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
texture::Image,
|
texture::Image,
|
||||||
@ -80,10 +80,6 @@ impl ViewNode for TonemappingNode {
|
|||||||
bind_group
|
bind_group
|
||||||
}
|
}
|
||||||
cached_bind_group => {
|
cached_bind_group => {
|
||||||
let sampler = render_context
|
|
||||||
.render_device()
|
|
||||||
.create_sampler(&SamplerDescriptor::default());
|
|
||||||
|
|
||||||
let tonemapping_luts = world.resource::<TonemappingLuts>();
|
let tonemapping_luts = world.resource::<TonemappingLuts>();
|
||||||
|
|
||||||
let lut_bindings = get_lut_bindings(gpu_images, tonemapping_luts, tonemapping);
|
let lut_bindings = get_lut_bindings(gpu_images, tonemapping_luts, tonemapping);
|
||||||
@ -94,7 +90,7 @@ impl ViewNode for TonemappingNode {
|
|||||||
&BindGroupEntries::sequential((
|
&BindGroupEntries::sequential((
|
||||||
view_uniforms,
|
view_uniforms,
|
||||||
source,
|
source,
|
||||||
&sampler,
|
&tonemapping_pipeline.sampler,
|
||||||
lut_bindings.0,
|
lut_bindings.0,
|
||||||
lut_bindings.1,
|
lut_bindings.1,
|
||||||
)),
|
)),
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use bevy_render::{
|
|||||||
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupEntries, LoadOp, Operations, PipelineCache, RenderPassColorAttachment,
|
BindGroup, BindGroupEntries, LoadOp, Operations, PipelineCache, RenderPassColorAttachment,
|
||||||
RenderPassDescriptor, SamplerDescriptor, StoreOp, TextureViewId,
|
RenderPassDescriptor, StoreOp, TextureViewId,
|
||||||
},
|
},
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
view::ViewTarget,
|
view::ViewTarget,
|
||||||
@ -52,14 +52,10 @@ impl ViewNode for UpscalingNode {
|
|||||||
let bind_group = match &mut *cached_bind_group {
|
let bind_group = match &mut *cached_bind_group {
|
||||||
Some((id, bind_group)) if upscaled_texture.id() == *id => bind_group,
|
Some((id, bind_group)) if upscaled_texture.id() == *id => bind_group,
|
||||||
cached_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(
|
let bind_group = render_context.render_device().create_bind_group(
|
||||||
None,
|
None,
|
||||||
&blit_pipeline.texture_bind_group,
|
&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));
|
let (_, bind_group) = cached_bind_group.insert((upscaled_texture.id(), bind_group));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user