Skip to content

Commit 09ccedd

Browse files
authored
Clean up several miscellaneous uses of weak_handle. (#19408)
# Objective - Related to #19024. ## Solution - This is a mix of several ways to get rid of weak handles. The primary strategy is putting strong asset handles in resources that the rendering code clones into its pipelines (or whatever). - This does not handle every remaining case, but we are slowly clearing them out. ## Testing - `anti_aliasing` example still works. - `fog_volumes` example still works.
1 parent 5e3927b commit 09ccedd

File tree

9 files changed

+145
-141
lines changed

9 files changed

+145
-141
lines changed

crates/bevy_anti_aliasing/src/smaa/mod.rs

Lines changed: 31 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@
3030
//!
3131
//! [SMAA]: https://www.iryoku.com/smaa/
3232
use bevy_app::{App, Plugin};
33-
#[cfg(feature = "smaa_luts")]
34-
use bevy_asset::load_internal_binary_asset;
35-
use bevy_asset::{embedded_asset, load_embedded_asset, uuid_handle, AssetServer, Handle};
33+
use bevy_asset::{embedded_asset, load_embedded_asset, AssetServer, Handle};
3634
#[cfg(not(feature = "smaa_luts"))]
3735
use bevy_core_pipeline::tonemapping::lut_placeholder;
3836
use bevy_core_pipeline::{
@@ -79,13 +77,6 @@ use bevy_render::{
7977
};
8078
use bevy_utils::prelude::default;
8179

82-
/// The handle of the area LUT, a KTX2 format texture that SMAA uses internally.
83-
const SMAA_AREA_LUT_TEXTURE_HANDLE: Handle<Image> =
84-
uuid_handle!("569c4d67-c7fa-4958-b1af-0836023603c0");
85-
/// The handle of the search LUT, a KTX2 format texture that SMAA uses internally.
86-
const SMAA_SEARCH_LUT_TEXTURE_HANDLE: Handle<Image> =
87-
uuid_handle!("43b97515-252e-4c8a-b9af-f2fc528a1c27");
88-
8980
/// Adds support for subpixel morphological antialiasing, or SMAA.
9081
pub struct SmaaPlugin;
9182

@@ -125,6 +116,14 @@ pub enum SmaaPreset {
125116
Ultra,
126117
}
127118

119+
#[derive(Resource)]
120+
struct SmaaLuts {
121+
/// The handle of the area LUT, a KTX2 format texture that SMAA uses internally.
122+
area_lut: Handle<Image>,
123+
/// The handle of the search LUT, a KTX2 format texture that SMAA uses internally.
124+
search_lut: Handle<Image>,
125+
}
126+
128127
/// A render world resource that holds all render pipeline data needed for SMAA.
129128
///
130129
/// There are three separate passes, so we need three separate pipelines.
@@ -292,49 +291,26 @@ impl Plugin for SmaaPlugin {
292291
// Load the shader.
293292
embedded_asset!(app, "smaa.wgsl");
294293

295-
// Load the two lookup textures. These are compressed textures in KTX2
296-
// format.
297-
#[cfg(feature = "smaa_luts")]
298-
load_internal_binary_asset!(
299-
app,
300-
SMAA_AREA_LUT_TEXTURE_HANDLE,
301-
"SMAAAreaLUT.ktx2",
302-
|bytes, _: String| Image::from_buffer(
303-
bytes,
304-
bevy_image::ImageType::Format(bevy_image::ImageFormat::Ktx2),
305-
bevy_image::CompressedImageFormats::NONE,
306-
false,
307-
bevy_image::ImageSampler::Default,
308-
bevy_asset::RenderAssetUsages::RENDER_WORLD,
309-
)
310-
.expect("Failed to load SMAA area LUT")
311-
);
312-
313294
#[cfg(feature = "smaa_luts")]
314-
load_internal_binary_asset!(
315-
app,
316-
SMAA_SEARCH_LUT_TEXTURE_HANDLE,
317-
"SMAASearchLUT.ktx2",
318-
|bytes, _: String| Image::from_buffer(
319-
bytes,
320-
bevy_image::ImageType::Format(bevy_image::ImageFormat::Ktx2),
321-
bevy_image::CompressedImageFormats::NONE,
322-
false,
323-
bevy_image::ImageSampler::Default,
324-
bevy_asset::RenderAssetUsages::RENDER_WORLD,
325-
)
326-
.expect("Failed to load SMAA search LUT")
327-
);
328-
329-
#[cfg(not(feature = "smaa_luts"))]
330-
app.world_mut()
331-
.resource_mut::<bevy_asset::Assets<Image>>()
332-
.insert(SMAA_AREA_LUT_TEXTURE_HANDLE.id(), lut_placeholder());
333-
295+
let smaa_luts = {
296+
// Load the two lookup textures. These are compressed textures in KTX2 format.
297+
embedded_asset!(app, "SMAAAreaLUT.ktx2");
298+
embedded_asset!(app, "SMAASearchLUT.ktx2");
299+
300+
SmaaLuts {
301+
area_lut: load_embedded_asset!(app, "SMAAAreaLUT.ktx2"),
302+
search_lut: load_embedded_asset!(app, "SMAASearchLUT.ktx2"),
303+
}
304+
};
334305
#[cfg(not(feature = "smaa_luts"))]
335-
app.world_mut()
336-
.resource_mut::<bevy_asset::Assets<Image>>()
337-
.insert(SMAA_SEARCH_LUT_TEXTURE_HANDLE.id(), lut_placeholder());
306+
let smaa_luts = {
307+
let mut images = app.world_mut().resource_mut::<bevy_asset::Assets<Image>>();
308+
let handle = images.add(lut_placeholder());
309+
SmaaLuts {
310+
area_lut: handle.clone(),
311+
search_lut: handle.clone(),
312+
}
313+
};
338314

339315
app.add_plugins(ExtractComponentPlugin::<Smaa>::default())
340316
.register_type::<Smaa>();
@@ -344,6 +320,7 @@ impl Plugin for SmaaPlugin {
344320
};
345321

346322
render_app
323+
.insert_resource(smaa_luts)
347324
.init_resource::<SmaaSpecializedRenderPipelines>()
348325
.init_resource::<SmaaInfoUniformBuffer>()
349326
.add_systems(RenderStartup, init_smaa_pipelines)
@@ -747,13 +724,14 @@ fn prepare_smaa_bind_groups(
747724
mut commands: Commands,
748725
render_device: Res<RenderDevice>,
749726
smaa_pipelines: Res<SmaaPipelines>,
727+
smaa_luts: Res<SmaaLuts>,
750728
images: Res<RenderAssets<GpuImage>>,
751729
view_targets: Query<(Entity, &SmaaTextures), (With<ExtractedView>, With<Smaa>)>,
752730
) {
753731
// Fetch the two lookup textures. These are bundled in this library.
754732
let (Some(search_texture), Some(area_texture)) = (
755-
images.get(&SMAA_SEARCH_LUT_TEXTURE_HANDLE),
756-
images.get(&SMAA_AREA_LUT_TEXTURE_HANDLE),
733+
images.get(&smaa_luts.search_lut),
734+
images.get(&smaa_luts.area_lut),
757735
) else {
758736
return;
759737
};

crates/bevy_asset/src/handle.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -492,8 +492,8 @@ impl<A: Asset> TryFrom<UntypedHandle> for Handle<A> {
492492
///
493493
/// ```
494494
/// # use bevy_asset::{Handle, uuid_handle};
495-
/// # type Shader = ();
496-
/// const SHADER: Handle<Shader> = uuid_handle!("1347c9b7-c46a-48e7-b7b8-023a354b7cac");
495+
/// # type Image = ();
496+
/// const IMAGE: Handle<Image> = uuid_handle!("1347c9b7-c46a-48e7-b7b8-023a354b7cac");
497497
/// ```
498498
#[macro_export]
499499
macro_rules! uuid_handle {

crates/bevy_core_pipeline/src/experimental/mip_generation/mod.rs

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::core_3d::{
1212
prepare_core_3d_depth_textures,
1313
};
1414
use bevy_app::{App, Plugin};
15-
use bevy_asset::{load_internal_asset, uuid_handle, Handle};
15+
use bevy_asset::{embedded_asset, load_embedded_asset, Handle};
1616
use bevy_derive::{Deref, DerefMut};
1717
use bevy_ecs::{
1818
component::Component,
@@ -51,8 +51,8 @@ use bitflags::bitflags;
5151
use tracing::debug;
5252

5353
/// Identifies the `downsample_depth.wgsl` shader.
54-
pub const DOWNSAMPLE_DEPTH_SHADER_HANDLE: Handle<Shader> =
55-
uuid_handle!("a09a149e-5922-4fa4-9170-3c1a13065364");
54+
#[derive(Resource, Deref)]
55+
pub struct DownsampleDepthShader(Handle<Shader>);
5656

5757
/// The maximum number of mip levels that we can produce.
5858
///
@@ -69,18 +69,16 @@ pub struct MipGenerationPlugin;
6969

7070
impl Plugin for MipGenerationPlugin {
7171
fn build(&self, app: &mut App) {
72-
load_internal_asset!(
73-
app,
74-
DOWNSAMPLE_DEPTH_SHADER_HANDLE,
75-
"downsample_depth.wgsl",
76-
Shader::from_wgsl
77-
);
72+
embedded_asset!(app, "downsample_depth.wgsl");
73+
74+
let downsample_depth_shader = load_embedded_asset!(app, "downsample_depth.wgsl");
7875

7976
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
8077
return;
8178
};
8279

8380
render_app
81+
.insert_resource(DownsampleDepthShader(downsample_depth_shader))
8482
.init_resource::<SpecializedComputePipelines<DownsampleDepthPipeline>>()
8583
.add_render_graph_node::<DownsampleDepthNode>(Core3d, Node3d::EarlyDownsampleDepth)
8684
.add_render_graph_node::<DownsampleDepthNode>(Core3d, Node3d::LateDownsampleDepth)
@@ -294,17 +292,21 @@ pub struct DownsampleDepthPipeline {
294292
bind_group_layout: BindGroupLayout,
295293
/// A handle that identifies the compiled shader.
296294
pipeline_id: Option<CachedComputePipelineId>,
295+
/// The shader asset handle.
296+
shader: Handle<Shader>,
297297
}
298298

299299
impl DownsampleDepthPipeline {
300-
/// Creates a new [`DownsampleDepthPipeline`] from a bind group layout.
300+
/// Creates a new [`DownsampleDepthPipeline`] from a bind group layout and the downsample
301+
/// shader.
301302
///
302303
/// This doesn't actually specialize the pipeline; that must be done
303304
/// afterward.
304-
fn new(bind_group_layout: BindGroupLayout) -> DownsampleDepthPipeline {
305+
fn new(bind_group_layout: BindGroupLayout, shader: Handle<Shader>) -> DownsampleDepthPipeline {
305306
DownsampleDepthPipeline {
306307
bind_group_layout,
307308
pipeline_id: None,
309+
shader,
308310
}
309311
}
310312
}
@@ -335,6 +337,7 @@ fn create_downsample_depth_pipelines(
335337
pipeline_cache: Res<PipelineCache>,
336338
mut specialized_compute_pipelines: ResMut<SpecializedComputePipelines<DownsampleDepthPipeline>>,
337339
gpu_preprocessing_support: Res<GpuPreprocessingSupport>,
340+
downsample_depth_shader: Res<DownsampleDepthShader>,
338341
mut has_run: Local<bool>,
339342
) {
340343
// Only run once.
@@ -368,10 +371,22 @@ fn create_downsample_depth_pipelines(
368371

369372
// Initialize the pipelines.
370373
let mut downsample_depth_pipelines = DownsampleDepthPipelines {
371-
first: DownsampleDepthPipeline::new(standard_bind_group_layout.clone()),
372-
second: DownsampleDepthPipeline::new(standard_bind_group_layout.clone()),
373-
first_multisample: DownsampleDepthPipeline::new(multisampled_bind_group_layout.clone()),
374-
second_multisample: DownsampleDepthPipeline::new(multisampled_bind_group_layout.clone()),
374+
first: DownsampleDepthPipeline::new(
375+
standard_bind_group_layout.clone(),
376+
downsample_depth_shader.0.clone(),
377+
),
378+
second: DownsampleDepthPipeline::new(
379+
standard_bind_group_layout.clone(),
380+
downsample_depth_shader.0.clone(),
381+
),
382+
first_multisample: DownsampleDepthPipeline::new(
383+
multisampled_bind_group_layout.clone(),
384+
downsample_depth_shader.0.clone(),
385+
),
386+
second_multisample: DownsampleDepthPipeline::new(
387+
multisampled_bind_group_layout.clone(),
388+
downsample_depth_shader.0.clone(),
389+
),
375390
sampler,
376391
};
377392

@@ -491,7 +506,7 @@ impl SpecializedComputePipeline for DownsampleDepthPipeline {
491506
stages: ShaderStages::COMPUTE,
492507
range: 0..4,
493508
}],
494-
shader: DOWNSAMPLE_DEPTH_SHADER_HANDLE,
509+
shader: self.shader.clone(),
495510
shader_defs,
496511
entry_point: Some(if key.contains(DownsampleDepthPipelineKey::SECOND_PHASE) {
497512
"downsample_depth_second".into()

crates/bevy_core_pipeline/src/post_process/mod.rs

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! Currently, this consists only of chromatic aberration.
44
55
use bevy_app::{App, Plugin};
6-
use bevy_asset::{embedded_asset, load_embedded_asset, uuid_handle, Assets, Handle};
6+
use bevy_asset::{embedded_asset, load_embedded_asset, Assets, Handle};
77
use bevy_derive::{Deref, DerefMut};
88
use bevy_ecs::{
99
component::Component,
@@ -47,13 +47,6 @@ use crate::{
4747
FullscreenShader,
4848
};
4949

50-
/// The handle to the default chromatic aberration lookup texture.
51-
///
52-
/// This is just a 3x1 image consisting of one red pixel, one green pixel, and
53-
/// one blue pixel, in that order.
54-
const DEFAULT_CHROMATIC_ABERRATION_LUT_HANDLE: Handle<Image> =
55-
uuid_handle!("dc3e3307-40a1-49bb-be6d-e0634e8836b2");
56-
5750
/// The default chromatic aberration intensity amount, in a fraction of the
5851
/// window size.
5952
const DEFAULT_CHROMATIC_ABERRATION_INTENSITY: f32 = 0.02;
@@ -68,6 +61,9 @@ const DEFAULT_CHROMATIC_ABERRATION_MAX_SAMPLES: u32 = 8;
6861
static DEFAULT_CHROMATIC_ABERRATION_LUT_DATA: [u8; 12] =
6962
[255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255];
7063

64+
#[derive(Resource)]
65+
struct DefaultChromaticAberrationLut(Handle<Image>);
66+
7167
/// A plugin that implements a built-in postprocessing stack with some common
7268
/// effects.
7369
///
@@ -96,14 +92,14 @@ pub struct PostProcessingPlugin;
9692
pub struct ChromaticAberration {
9793
/// The lookup texture that determines the color gradient.
9894
///
99-
/// By default, this is a 3×1 texel texture consisting of one red pixel, one
100-
/// green pixel, and one blue texel, in that order. This recreates the most
101-
/// typical chromatic aberration pattern. However, you can change it to
102-
/// achieve different artistic effects.
95+
/// By default (if None), this is a 3×1 texel texture consisting of one red
96+
/// pixel, one green pixel, and one blue texel, in that order. This
97+
/// recreates the most typical chromatic aberration pattern. However, you
98+
/// can change it to achieve different artistic effects.
10399
///
104100
/// The texture is always sampled in its vertical center, so it should
105101
/// ordinarily have a height of 1 texel.
106-
pub color_lut: Handle<Image>,
102+
pub color_lut: Option<Handle<Image>>,
107103

108104
/// The size of the streaks around the edges of objects, as a fraction of
109105
/// the window size.
@@ -192,20 +188,17 @@ impl Plugin for PostProcessingPlugin {
192188

193189
// Load the default chromatic aberration LUT.
194190
let mut assets = app.world_mut().resource_mut::<Assets<_>>();
195-
assets.insert(
196-
DEFAULT_CHROMATIC_ABERRATION_LUT_HANDLE.id(),
197-
Image::new(
198-
Extent3d {
199-
width: 3,
200-
height: 1,
201-
depth_or_array_layers: 1,
202-
},
203-
TextureDimension::D2,
204-
DEFAULT_CHROMATIC_ABERRATION_LUT_DATA.to_vec(),
205-
TextureFormat::Rgba8UnormSrgb,
206-
RenderAssetUsages::RENDER_WORLD,
207-
),
208-
);
191+
let default_lut = assets.add(Image::new(
192+
Extent3d {
193+
width: 3,
194+
height: 1,
195+
depth_or_array_layers: 1,
196+
},
197+
TextureDimension::D2,
198+
DEFAULT_CHROMATIC_ABERRATION_LUT_DATA.to_vec(),
199+
TextureFormat::Rgba8UnormSrgb,
200+
RenderAssetUsages::RENDER_WORLD,
201+
));
209202

210203
app.register_type::<ChromaticAberration>();
211204
app.add_plugins(ExtractComponentPlugin::<ChromaticAberration>::default());
@@ -215,6 +208,7 @@ impl Plugin for PostProcessingPlugin {
215208
};
216209

217210
render_app
211+
.insert_resource(DefaultChromaticAberrationLut(default_lut))
218212
.init_resource::<SpecializedRenderPipelines<PostProcessingPipeline>>()
219213
.init_resource::<PostProcessingUniformBuffers>()
220214
.add_systems(
@@ -258,7 +252,7 @@ impl Plugin for PostProcessingPlugin {
258252
impl Default for ChromaticAberration {
259253
fn default() -> Self {
260254
Self {
261-
color_lut: DEFAULT_CHROMATIC_ABERRATION_LUT_HANDLE,
255+
color_lut: None,
262256
intensity: DEFAULT_CHROMATIC_ABERRATION_INTENSITY,
263257
max_samples: DEFAULT_CHROMATIC_ABERRATION_MAX_SAMPLES,
264258
}
@@ -357,15 +351,20 @@ impl ViewNode for PostProcessingNode {
357351
let post_processing_pipeline = world.resource::<PostProcessingPipeline>();
358352
let post_processing_uniform_buffers = world.resource::<PostProcessingUniformBuffers>();
359353
let gpu_image_assets = world.resource::<RenderAssets<GpuImage>>();
354+
let default_lut = world.resource::<DefaultChromaticAberrationLut>();
360355

361356
// We need a render pipeline to be prepared.
362357
let Some(pipeline) = pipeline_cache.get_render_pipeline(**pipeline_id) else {
363358
return Ok(());
364359
};
365360

366361
// We need the chromatic aberration LUT to be present.
367-
let Some(chromatic_aberration_lut) = gpu_image_assets.get(&chromatic_aberration.color_lut)
368-
else {
362+
let Some(chromatic_aberration_lut) = gpu_image_assets.get(
363+
chromatic_aberration
364+
.color_lut
365+
.as_ref()
366+
.unwrap_or(&default_lut.0),
367+
) else {
369368
return Ok(());
370369
};
371370

0 commit comments

Comments
 (0)