Skip to content

Use RenderStartup for all basic cases in bevy_core_pipeline. #20002

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 17 additions & 24 deletions crates/bevy_core_pipeline/src/auto_exposure/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use bevy_render::{
Buffer, BufferDescriptor, BufferUsages, PipelineCache, SpecializedComputePipelines,
},
renderer::RenderDevice,
ExtractSchedule, Render, RenderApp, RenderSystems,
ExtractSchedule, Render, RenderApp, RenderStartup, RenderSystems,
};

mod buffers;
Expand All @@ -25,7 +25,9 @@ use pipeline::{AutoExposurePass, AutoExposurePipeline, ViewAutoExposurePipeline}
pub use settings::AutoExposure;

use crate::{
auto_exposure::compensation_curve::GpuAutoExposureCompensationCurve,
auto_exposure::{
compensation_curve::GpuAutoExposureCompensationCurve, pipeline::init_auto_exposure_pipeline,
},
core_3d::graph::{Core3d, Node3d},
};

Expand Down Expand Up @@ -61,6 +63,10 @@ impl Plugin for AutoExposurePlugin {
render_app
.init_resource::<SpecializedComputePipelines<AutoExposurePipeline>>()
.init_resource::<AutoExposureBuffers>()
.add_systems(
RenderStartup,
(init_auto_exposure_pipeline, init_auto_exposure_resources),
)
.add_systems(ExtractSchedule, extract_buffers)
.add_systems(
Render,
Expand All @@ -75,30 +81,17 @@ impl Plugin for AutoExposurePlugin {
(Node3d::EndMainPass, node::AutoExposure, Node3d::Tonemapping),
);
}

fn finish(&self, app: &mut App) {
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
};

render_app.init_resource::<AutoExposurePipeline>();
render_app.init_resource::<AutoExposureResources>();
}
}

impl FromWorld for AutoExposureResources {
fn from_world(world: &mut World) -> Self {
Self {
histogram: world
.resource::<RenderDevice>()
.create_buffer(&BufferDescriptor {
label: Some("histogram buffer"),
size: pipeline::HISTOGRAM_BIN_COUNT * 4,
usage: BufferUsages::STORAGE,
mapped_at_creation: false,
}),
}
}
pub fn init_auto_exposure_resources(mut commands: Commands, render_device: Res<RenderDevice>) {
commands.insert_resource(AutoExposureResources {
histogram: render_device.create_buffer(&BufferDescriptor {
label: Some("histogram buffer"),
size: pipeline::HISTOGRAM_BIN_COUNT * 4,
usage: BufferUsages::STORAGE,
mapped_at_creation: false,
}),
});
}

fn queue_view_auto_exposure_pipelines(
Expand Down
46 changes: 23 additions & 23 deletions crates/bevy_core_pipeline/src/auto_exposure/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,31 +47,31 @@ pub enum AutoExposurePass {

pub const HISTOGRAM_BIN_COUNT: u64 = 64;

impl FromWorld for AutoExposurePipeline {
fn from_world(world: &mut World) -> Self {
let render_device = world.resource::<RenderDevice>();

Self {
histogram_layout: render_device.create_bind_group_layout(
"compute histogram bind group",
&BindGroupLayoutEntries::sequential(
ShaderStages::COMPUTE,
(
uniform_buffer::<GlobalsUniform>(false),
uniform_buffer::<AutoExposureUniform>(false),
texture_2d(TextureSampleType::Float { filterable: false }),
texture_2d(TextureSampleType::Float { filterable: false }),
texture_1d(TextureSampleType::Float { filterable: false }),
uniform_buffer::<AutoExposureCompensationCurveUniform>(false),
storage_buffer_sized(false, NonZero::<u64>::new(HISTOGRAM_BIN_COUNT * 4)),
storage_buffer_sized(false, NonZero::<u64>::new(4)),
storage_buffer::<ViewUniform>(true),
),
pub fn init_auto_exposure_pipeline(
mut commands: Commands,
render_device: Res<RenderDevice>,
asset_server: Res<AssetServer>,
) {
commands.insert_resource(AutoExposurePipeline {
histogram_layout: render_device.create_bind_group_layout(
"compute histogram bind group",
&BindGroupLayoutEntries::sequential(
ShaderStages::COMPUTE,
(
uniform_buffer::<GlobalsUniform>(false),
uniform_buffer::<AutoExposureUniform>(false),
texture_2d(TextureSampleType::Float { filterable: false }),
texture_2d(TextureSampleType::Float { filterable: false }),
texture_1d(TextureSampleType::Float { filterable: false }),
uniform_buffer::<AutoExposureCompensationCurveUniform>(false),
storage_buffer_sized(false, NonZero::<u64>::new(HISTOGRAM_BIN_COUNT * 4)),
storage_buffer_sized(false, NonZero::<u64>::new(4)),
storage_buffer::<ViewUniform>(true),
),
),
histogram_shader: load_embedded_asset!(world, "auto_exposure.wgsl"),
}
}
),
histogram_shader: load_embedded_asset!(asset_server.as_ref(), "auto_exposure.wgsl"),
});
}

impl SpecializedComputePipeline for AutoExposurePipeline {
Expand Down
59 changes: 28 additions & 31 deletions crates/bevy_core_pipeline/src/blit/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use crate::FullscreenShader;
use bevy_app::{App, Plugin};
use bevy_asset::{embedded_asset, load_embedded_asset, Handle};
use bevy_asset::{embedded_asset, load_embedded_asset, AssetServer, Handle};
use bevy_ecs::prelude::*;
use bevy_render::{
render_resource::{
binding_types::{sampler, texture_2d},
*,
},
renderer::RenderDevice,
RenderApp,
RenderApp, RenderStartup,
};
use bevy_utils::default;

Expand All @@ -19,18 +19,14 @@ impl Plugin for BlitPlugin {
fn build(&self, app: &mut App) {
embedded_asset!(app, "blit.wgsl");

if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
render_app.allow_ambiguous_resource::<SpecializedRenderPipelines<BlitPipeline>>();
}
}

fn finish(&self, app: &mut App) {
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
};

render_app
.init_resource::<BlitPipeline>()
.init_resource::<SpecializedRenderPipelines<BlitPipeline>>();
.allow_ambiguous_resource::<SpecializedRenderPipelines<BlitPipeline>>()
.init_resource::<SpecializedRenderPipelines<BlitPipeline>>()
.add_systems(RenderStartup, init_blit_pipeline);
}
}

Expand All @@ -42,30 +38,31 @@ pub struct BlitPipeline {
pub fragment_shader: Handle<Shader>,
}

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(
"blit_bind_group_layout",
&BindGroupLayoutEntries::sequential(
ShaderStages::FRAGMENT,
(
texture_2d(TextureSampleType::Float { filterable: false }),
sampler(SamplerBindingType::NonFiltering),
),
pub fn init_blit_pipeline(
mut commands: Commands,
render_device: Res<RenderDevice>,
fullscreen_shader: Res<FullscreenShader>,
asset_server: Res<AssetServer>,
) {
let texture_bind_group = render_device.create_bind_group_layout(
"blit_bind_group_layout",
&BindGroupLayoutEntries::sequential(
ShaderStages::FRAGMENT,
(
texture_2d(TextureSampleType::Float { filterable: false }),
sampler(SamplerBindingType::NonFiltering),
),
);
),
);

let sampler = render_device.create_sampler(&SamplerDescriptor::default());
let sampler = render_device.create_sampler(&SamplerDescriptor::default());

BlitPipeline {
texture_bind_group,
sampler,
fullscreen_shader: render_world.resource::<FullscreenShader>().clone(),
fragment_shader: load_embedded_asset!(render_world, "blit.wgsl"),
}
}
commands.insert_resource(BlitPipeline {
texture_bind_group,
sampler,
fullscreen_shader: fullscreen_shader.clone(),
fragment_shader: load_embedded_asset!(asset_server.as_ref(), "blit.wgsl"),
});
}

#[derive(PartialEq, Eq, Hash, Clone, Copy)]
Expand Down
74 changes: 37 additions & 37 deletions crates/bevy_core_pipeline/src/bloom/downsampling_pipeline.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use crate::FullscreenShader;

use super::{Bloom, BLOOM_TEXTURE_FORMAT};
use bevy_asset::{load_embedded_asset, Handle};
use bevy_asset::{load_embedded_asset, AssetServer, Handle};
use bevy_ecs::{
prelude::{Component, Entity},
resource::Resource,
system::{Commands, Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_math::{Vec2, Vec4};
use bevy_render::{
Expand Down Expand Up @@ -53,42 +52,43 @@ pub struct BloomUniforms {
pub aspect: f32,
}

impl FromWorld for BloomDownsamplingPipeline {
fn from_world(world: &mut World) -> Self {
let render_device = world.resource::<RenderDevice>();

// Bind group layout
let bind_group_layout = render_device.create_bind_group_layout(
"bloom_downsampling_bind_group_layout_with_settings",
&BindGroupLayoutEntries::sequential(
ShaderStages::FRAGMENT,
(
// Input texture binding
texture_2d(TextureSampleType::Float { filterable: true }),
// Sampler binding
sampler(SamplerBindingType::Filtering),
// Downsampling settings binding
uniform_buffer::<BloomUniforms>(true),
),
pub fn init_bloom_downsampling_pipeline(
mut commands: Commands,
render_device: Res<RenderDevice>,
fullscreen_shader: Res<FullscreenShader>,
asset_server: Res<AssetServer>,
) {
// Bind group layout
let bind_group_layout = render_device.create_bind_group_layout(
"bloom_downsampling_bind_group_layout_with_settings",
&BindGroupLayoutEntries::sequential(
ShaderStages::FRAGMENT,
(
// Input texture binding
texture_2d(TextureSampleType::Float { filterable: true }),
// Sampler binding
sampler(SamplerBindingType::Filtering),
// Downsampling settings binding
uniform_buffer::<BloomUniforms>(true),
),
);

// Sampler
let sampler = render_device.create_sampler(&SamplerDescriptor {
min_filter: FilterMode::Linear,
mag_filter: FilterMode::Linear,
address_mode_u: AddressMode::ClampToEdge,
address_mode_v: AddressMode::ClampToEdge,
..Default::default()
});

BloomDownsamplingPipeline {
bind_group_layout,
sampler,
fullscreen_shader: world.resource::<FullscreenShader>().clone(),
fragment_shader: load_embedded_asset!(world, "bloom.wgsl"),
}
}
),
);

// Sampler
let sampler = render_device.create_sampler(&SamplerDescriptor {
min_filter: FilterMode::Linear,
mag_filter: FilterMode::Linear,
address_mode_u: AddressMode::ClampToEdge,
address_mode_v: AddressMode::ClampToEdge,
..Default::default()
});

commands.insert_resource(BloomDownsamplingPipeline {
bind_group_layout,
sampler,
fullscreen_shader: fullscreen_shader.clone(),
fragment_shader: load_embedded_asset!(asset_server.as_ref(), "bloom.wgsl"),
});
}

impl SpecializedRenderPipeline for BloomDownsamplingPipeline {
Expand Down
22 changes: 12 additions & 10 deletions crates/bevy_core_pipeline/src/bloom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ use bevy_image::ToExtents;
pub use settings::{Bloom, BloomCompositeMode, BloomPrefilter};

use crate::{
bloom::{
downsampling_pipeline::init_bloom_downsampling_pipeline,
upsampling_pipeline::init_bloom_upscaling_pipeline,
},
core_2d::graph::{Core2d, Node2d},
core_3d::graph::{Core3d, Node3d},
};
Expand All @@ -25,7 +29,7 @@ use bevy_render::{
renderer::{RenderContext, RenderDevice},
texture::{CachedTexture, TextureCache},
view::ViewTarget,
Render, RenderApp, RenderSystems,
Render, RenderApp, RenderStartup, RenderSystems,
};
use downsampling_pipeline::{
prepare_downsampling_pipeline, BloomDownsamplingPipeline, BloomDownsamplingPipelineIds,
Expand Down Expand Up @@ -59,6 +63,13 @@ impl Plugin for BloomPlugin {
render_app
.init_resource::<SpecializedRenderPipelines<BloomDownsamplingPipeline>>()
.init_resource::<SpecializedRenderPipelines<BloomUpsamplingPipeline>>()
.add_systems(
RenderStartup,
(
init_bloom_downsampling_pipeline,
init_bloom_upscaling_pipeline,
),
)
.add_systems(
Render,
(
Expand All @@ -81,15 +92,6 @@ impl Plugin for BloomPlugin {
(Node2d::EndMainPass, Node2d::Bloom, Node2d::Tonemapping),
);
}

fn finish(&self, app: &mut App) {
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
};
render_app
.init_resource::<BloomDownsamplingPipeline>()
.init_resource::<BloomUpsamplingPipeline>();
}
}

#[derive(Default)]
Expand Down
Loading