bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
36.24k stars 3.57k forks source link

RenderAssetUsages::RENDER_WORLD assets are not cleaned when their handles are dropped #13500

Closed mockersf closed 5 months ago

mockersf commented 5 months ago

Bevy version

0.13 and main

What you did

load many images, set them as RenderAssetUsages::RENDER_WORLD, display them then drop them

What went wrong

GPU memory is not freed

Additional information

first video images are loaded as RenderAssetUsages::all(), all displayed, then all the entities are despawned, there are no strong handles left CPU and GPU memory are freed, as can be seen in the metal HUD

https://github.com/bevyengine/bevy/assets/8672791/9dd0aec0-7b2c-4024-bece-75484ddc9bf5

second video images are loaded as RenderAssetUsages:: RENDER_WORLD, all displayed, then all the entities are despawned, there are no strong handles left CPU memory is freed as soon as the images are sent to the GPU, GPU memory is never freed

https://github.com/bevyengine/bevy/assets/8672791/5acbe238-fd29-42dc-bd27-754f664a1d2f

Example code this example loads all the images in the Bevy repo ```rust use bevy::{ prelude::*, render::{render_asset::RenderAssetUsages, texture::ImageLoaderSettings}, }; fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .add_systems(Update, (drop_handles, update_asset_count)) .run(); } fn setup(mut commands: Commands, asset_server: Res) { commands.spawn(Camera2dBundle { ..default() }); commands .spawn(NodeBundle { style: Style { width: Val::Percent(100.0), height: Val::Percent(100.0), align_items: AlignItems::End, justify_content: JustifyContent::Center, ..default() }, ..default() }) .with_children(|parent| { parent.spawn(TextBundle::from_section( "image assets", TextStyle { font_size: 100.0, ..default() }, )); }); ALL_IMAGES.into_iter().enumerate().for_each(|(i, p)| { let handle = asset_server.load_with_settings(p, |s: &mut _| { *s = ImageLoaderSettings { asset_usage: RenderAssetUsages::all(), // asset_usage: RenderAssetUsages::RENDER_WORLD, ..default() }; }); commands.spawn(SpriteBundle { texture: handle, transform: Transform::from_xyz( (i % 20) as f32 * 10.0 - 5.0, (i / 20) as f32 * 10.0, 0.0, ) .with_scale(Vec3::splat(0.1)), ..default() }); }); } fn drop_handles( keyboard_input: Res>, mut commands: Commands, images: Query>>, ) { if keyboard_input.just_pressed(KeyCode::Space) { for entity in &images { commands.entity(entity).despawn(); } } } fn update_asset_count(mut text: Query<&mut Text>, images: Res>) { text.single_mut().sections[0].value = format!("CPU side: {} assets", images.len()); } const ALL_IMAGES: [&str; 221] = [ "textures/simplespace/ship_C.png", "textures/simplespace/enemy_B.png", "textures/simplespace/enemy_A.png", "textures/rpg/ui/generic-rpg-ui-inventario.png", "textures/rpg/ui/generic-rpg-ui-text-box.png", "textures/rpg/ui/generic-rpg-ui-inventario01.png", "textures/rpg/ui/generic-rpg-ui-inventario03.png", "textures/rpg/ui/generic-rpg-ui-inventario02.png", "textures/rpg/ui/generic-rpg-ui-inventario04.png", "textures/rpg/mobs/worm-run-idle.png", "textures/rpg/mobs/slime-blue.png", "textures/rpg/mobs/boss_bee.png", "textures/rpg/mobs/fox-run.png", "textures/rpg/mobs/slime-green.png", "textures/rpg/mobs/slime-orange.png", "textures/rpg/mobs/kobold-idle.png", "textures/rpg/props/generic-rpg-board02.png", "textures/rpg/props/generic-rpg-barrel02.png", "textures/rpg/props/generic-rpg-grass02.png", "textures/rpg/props/generic-rpg-barrel03.png", "textures/rpg/props/generic-rpg-board03.png", "textures/rpg/props/generic-rpg-treasure-closed.png", "textures/rpg/props/generic-rpg-board01.png", "textures/rpg/props/generic-rpg-barrel01.png", "textures/rpg/props/generic-rpg-grass01.png", "textures/rpg/props/generic-rpg-board04.png", "textures/rpg/props/generic-rpg-flowers.png", "textures/rpg/props/generic-rpg-fence-raw03.png", "textures/rpg/props/generic-rpg-fence-raw17.png", "textures/rpg/props/generic-rpg-rock01.png", "textures/rpg/props/generic-rpg-loot01.png", "textures/rpg/props/generic-rpg-fence-raw16.png", "textures/rpg/props/generic-rpg-fence-raw02.png", "textures/rpg/props/generic-rpg-fence-raw14.png", "textures/rpg/props/generic-rpg-loot03.png", "textures/rpg/props/generic-rpg-rock03.png", "textures/rpg/props/generic-rpg-rock02.png", "textures/rpg/props/generic-rpg-loot02.png", "textures/rpg/props/generic-rpg-fence-raw01.png", "textures/rpg/props/generic-rpg-fence-raw15.png", "textures/rpg/props/generic-rpg-fence-raw11.png", "textures/rpg/props/generic-rpg-fence-raw05.png", "textures/rpg/props/generic-rpg-rock06.png", "textures/rpg/props/generic-rpg-rod.png", "textures/rpg/props/generic-rpg-fence-raw04.png", "textures/rpg/props/generic-rpg-fence-raw10.png", "textures/rpg/props/generic-rpg-bridge.png", "textures/rpg/props/generic-rpg-fence-raw06.png", "textures/rpg/props/generic-rpg-fence-raw12.png", "textures/rpg/props/generic-rpg-loot05.png", "textures/rpg/props/generic-rpg-rock05.png", "textures/rpg/props/generic-rpg-fence08.png", "textures/rpg/props/generic-rpg-fence09.png", "textures/rpg/props/generic-rpg-rock04.png", "textures/rpg/props/generic-rpg-loot04.png", "textures/rpg/props/generic-rpg-fence-raw13.png", "textures/rpg/props/generic-rpg-fence-raw07.png", "textures/rpg/props/generic-rpg-fence-raw22.png", "textures/rpg/props/generic-rpg-fence04.png", "textures/rpg/props/generic-rpg-fence10.png", "textures/rpg/props/generic-rpg-fence11.png", "textures/rpg/props/generic-rpg-fence05.png", "textures/rpg/props/generic-rpg-flower01.png", "textures/rpg/props/generic-rpg-fence-raw23.png", "textures/rpg/props/generic-rpg-fence-raw21.png", "textures/rpg/props/generic-rpg-fence-raw09.png", "textures/rpg/props/generic-rpg-flower03.png", "textures/rpg/props/generic-rpg-fence-complete.png", "textures/rpg/props/generic-rpg-fence13.png", "textures/rpg/props/generic-rpg-fence07.png", "textures/rpg/props/generic-rpg-fence06.png", "textures/rpg/props/generic-rpg-fence12.png", "textures/rpg/props/generic-rpg-flower02.png", "textures/rpg/props/generic-rpg-fence-raw08.png", "textures/rpg/props/generic-rpg-fence-raw20.png", "textures/rpg/props/generic-rpg-tree02.png", "textures/rpg/props/generic-rpg-fence-raw18.png", "textures/rpg/props/generic-rpg-fence-raw24.png", "textures/rpg/props/generic-rpg-fence02.png", "textures/rpg/props/generic-rpg-fence03.png", "textures/rpg/props/generic-rpg-fence-raw25.png", "textures/rpg/props/generic-rpg-fence-raw19.png", "textures/rpg/props/generic-rpg-tree01.png", "textures/rpg/props/generic-rpg-house-inn.png", "textures/rpg/props/generic-rpg-fence01.png", "textures/rpg/props/generic-rpg-fence14.png", "textures/rpg/props/generic-rpg-crate02.png", "textures/rpg/props/generic-rpg-crate03.png", "textures/rpg/props/generic-rpg-crate01.png", "textures/rpg/props/generic-rpg-fish04.png", "textures/rpg/props/generic-rpg-mini-lake.png", "textures/rpg/props/generic-rpg-fish01.png", "textures/rpg/props/generic-rpg-fish02.png", "textures/rpg/props/generic-rpg-fish03.png", "textures/rpg/props/generic-rpg-trasure-open.png", "textures/rpg/chars/sensei/sensei.png", "textures/rpg/chars/mani/mani-idle-run.png", "textures/rpg/chars/hat-guy/hat-guy.png", "textures/rpg/chars/vendor/generic-rpg-vendor.png", "textures/rpg/chars/gabe/gabe-idle-run.png", "textures/rpg/tiles/generic-rpg-tile35.png", "textures/rpg/tiles/generic-rpg-tile21.png", "textures/rpg/tiles/generic-rpg-tile09.png", "textures/rpg/tiles/generic-rpg-tile08.png", "textures/rpg/tiles/generic-rpg-tile20.png", "textures/rpg/tiles/generic-rpg-tile34.png", "textures/rpg/tiles/generic-rpg-tile22.png", "textures/rpg/tiles/generic-rpg-tile37.png", "textures/rpg/tiles/generic-rpg-tile23.png", "textures/rpg/tiles/generic-rpg-tile27.png", "textures/rpg/tiles/generic-rpg-tile33.png", "textures/rpg/tiles/generic-rpg-tile32.png", "textures/rpg/tiles/generic-rpg-tile26.png", "textures/rpg/tiles/generic-rpg-tile18.png", "textures/rpg/tiles/generic-rpg-tile30.png", "textures/rpg/tiles/generic-rpg-tile24.png", "textures/rpg/tiles/generic-rpg-tile25.png", "textures/rpg/tiles/generic-rpg-tile31.png", "textures/rpg/tiles/generic-rpg-tile19.png", "textures/rpg/tiles/generic-rpg-tile56.png", "textures/rpg/tiles/generic-rpg-tile42.png", "textures/rpg/tiles/generic-rpg-tile43.png", "textures/rpg/tiles/generic-rpg-tile57.png", "textures/rpg/tiles/generic-rpg-tile41.png", "textures/rpg/tiles/generic-rpg-tile55.png", "textures/rpg/tiles/generic-rpg-tile69.png", "textures/rpg/tiles/generic-rpg-tile68.png", "textures/rpg/tiles/generic-rpg-tile54.png", "textures/rpg/tiles/generic-rpg-tile40.png", "textures/rpg/tiles/generic-rpg-tile44.png", "textures/rpg/tiles/generic-rpg-tile50.png", "textures/rpg/tiles/generic-rpg-tile51.png", "textures/rpg/tiles/generic-rpg-tile45.png", "textures/rpg/tiles/generic-rpg-tile53.png", "textures/rpg/tiles/generic-rpg-tile47.png", "textures/rpg/tiles/generic-rpg-tile46.png", "textures/rpg/tiles/generic-rpg-tile52.png", "textures/rpg/tiles/generic-rpg-tile63.png", "textures/rpg/tiles/generic-rpg-tile-waterfall01.png", "textures/rpg/tiles/generic-rpg-tile62.png", "textures/rpg/tiles/generic-rpg-tile60.png", "textures/rpg/tiles/generic-rpg-tile48.png", "textures/rpg/tiles/generic-rpg-tile-waterfall02.png", "textures/rpg/tiles/generic-rpg-tile-waterfall03.png", "textures/rpg/tiles/generic-rpg-tile49.png", "textures/rpg/tiles/generic-rpg-tile61.png", "textures/rpg/tiles/generic-rpg-tile59.png", "textures/rpg/tiles/generic-rpg-tile65.png", "textures/rpg/tiles/generic-rpg-tile71.png", "textures/rpg/tiles/generic-rpg-tile-waterfall07.png", "textures/rpg/tiles/generic-rpg-tile-waterfall06.png", "textures/rpg/tiles/generic-rpg-tile70.png", "textures/rpg/tiles/generic-rpg-tile64.png", "textures/rpg/tiles/generic-rpg-tile58.png", "textures/rpg/tiles/generic-rpg-tile66.png", "textures/rpg/tiles/generic-rpg-tile-waterfall04.png", "textures/rpg/tiles/generic-rpg-tile-waterfall05.png", "textures/rpg/tiles/generic-rpg-tile67.png", "textures/rpg/tiles/generic-rpg-tile14.png", "textures/rpg/tiles/generic-rpg-tile28.png", "textures/rpg/tiles/generic-rpg-tile29.png", "textures/rpg/tiles/generic-rpg-tile01.png", "textures/rpg/tiles/generic-rpg-tile15.png", "textures/rpg/tiles/generic-rpg-tile03.png", "textures/rpg/tiles/generic-rpg-tile17.png", "textures/rpg/tiles/generic-rpg-tile16.png", "textures/rpg/tiles/generic-rpg-tile02.png", "textures/rpg/tiles/generic-rpg-tile06.png", "textures/rpg/tiles/generic-rpg-tile12.png", "textures/rpg/tiles/generic-rpg-tile13.png", "textures/rpg/tiles/generic-rpg-tile07.png", "textures/rpg/tiles/generic-rpg-tile39.png", "textures/rpg/tiles/generic-rpg-tile11.png", "textures/rpg/tiles/generic-rpg-tile05.png", "textures/rpg/tiles/generic-rpg-tile04.png", "textures/rpg/tiles/generic-rpg-tile10.png", "textures/rpg/tiles/generic-rpg-tile38.png", "textures/rpg/tiles/generic-rpg-Slice.png", "textures/fantasy_ui_borders/panel-border-015.png", "textures/fantasy_ui_borders/panel-border-010.png", "textures/fantasy_ui_borders/border_sheet.png", "textures/fantasy_ui_borders/panel-border-010-repeated.png", "textures/slice_square.png", "textures/BlueNoise-Normal.png", "textures/parallax_example/cube_color.png", "textures/parallax_example/cube_normal.png", "textures/parallax_example/cube_depth.png", "textures/Ryfjallet_cubemap.png", "textures/slice_square_2.png", "textures/ScratchedGold-Normal.png", "textures/array_texture.png", "textures/basic_metering_mask.png", "textures/Game Icons/exitRight.png", "textures/Game Icons/wrench.png", "textures/Game Icons/right.png", "branding/icon.png", "branding/banner.png", "branding/bevy_logo_dark_big.png", "branding/bevy_logo_light.png", "branding/bevy_bird_dark.png", "branding/bevy_logo_dark.png", "models/TonemappingTest/TestPattern.png", "models/FlightHelmet/FlightHelmet_Materials_GlassPlasticMat_BaseColor.png", "models/FlightHelmet/FlightHelmet_Materials_LeatherPartsMat_OcclusionRoughMetal.png", "models/FlightHelmet/FlightHelmet_Materials_RubberWoodMat_Normal.png", "models/FlightHelmet/FlightHelmet_Materials_LensesMat_OcclusionRoughMetal.png", "models/FlightHelmet/FlightHelmet_Materials_GlassPlasticMat_OcclusionRoughMetal.png", "models/FlightHelmet/FlightHelmet_Materials_LensesMat_BaseColor.png", "models/FlightHelmet/FlightHelmet_Materials_LeatherPartsMat_Normal.png", "models/FlightHelmet/FlightHelmet_Materials_RubberWoodMat_BaseColor.png", "models/FlightHelmet/FlightHelmet_Materials_GlassPlasticMat_Normal.png", "models/FlightHelmet/FlightHelmet_Materials_RubberWoodMat_OcclusionRoughMetal.png", "models/FlightHelmet/FlightHelmet_Materials_LeatherPartsMat_BaseColor.png", "models/FlightHelmet/FlightHelmet_Materials_MetalPartsMat_OcclusionRoughMetal.png", "models/FlightHelmet/FlightHelmet_Materials_MetalPartsMat_Normal.png", "models/FlightHelmet/FlightHelmet_Materials_MetalPartsMat_BaseColor.png", "models/FlightHelmet/FlightHelmet_Materials_LensesMat_Normal.png", "docs/Mesh.png", "pixel/bevy_pixel_dark.png", "pixel/bevy_pixel_light.png", "android-res/mipmap-mdpi/ic_launcher.png", ]; ```
JMS55 commented 5 months ago

Assuming it's not a wgpu issue (e.g. https://github.com/gfx-rs/wgpu/issues/5707, which I'm not sure if it applies to 0.19 or not), this PR https://github.com/bevyengine/bevy/pull/12459 probably broke it.

Can you run a git bisect and see if it worked before #12459?

EDIT: Also try adding a print statement here and seeing if assets are properly dropped.

EDIT2: Could also have been https://github.com/bevyengine/bevy/pull/12827 breaking something.

JMS55 commented 5 months ago

I added a Drop impl to GpuImage and ran the example. I see all the images being dropped. If there's memory leaks, I think it's on wgpu's side.

mockersf commented 5 months ago

@JMS55 the GpuUimage is dropped, but the bind group was kept, keeping the memory used. #13609 fixes that