-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Fix panic when specializing materials for entities spawned in PostUpdate
#19064
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,9 +2,9 @@ use crate::{ | |||||||||||||||
| DrawMesh2d, Mesh2d, Mesh2dPipeline, Mesh2dPipelineKey, RenderMesh2dInstances, | ||||||||||||||||
| SetMesh2dBindGroup, SetMesh2dViewBindGroup, ViewKeyCache, ViewSpecializationTicks, | ||||||||||||||||
| }; | ||||||||||||||||
| use bevy_app::{App, Plugin, PostUpdate}; | ||||||||||||||||
| use bevy_app::{App, Last, Plugin}; | ||||||||||||||||
| use bevy_asset::prelude::AssetChanged; | ||||||||||||||||
| use bevy_asset::{AsAssetId, Asset, AssetApp, AssetEvents, AssetId, AssetServer, Handle}; | ||||||||||||||||
| use bevy_asset::{AsAssetId, Asset, AssetApp, AssetId, AssetServer, Handle}; | ||||||||||||||||
| use bevy_core_pipeline::{ | ||||||||||||||||
| core_2d::{ | ||||||||||||||||
| AlphaMask2d, AlphaMask2dBinKey, BatchSetKey2d, Opaque2d, Opaque2dBinKey, Transparent2d, | ||||||||||||||||
|
|
@@ -271,10 +271,7 @@ where | |||||||||||||||
| .init_resource::<EntitiesNeedingSpecialization<M>>() | ||||||||||||||||
| .register_type::<MeshMaterial2d<M>>() | ||||||||||||||||
| .add_plugins(RenderAssetPlugin::<PreparedMaterial2d<M>>::default()) | ||||||||||||||||
| .add_systems( | ||||||||||||||||
| PostUpdate, | ||||||||||||||||
| check_entities_needing_specialization::<M>.after(AssetEvents), | ||||||||||||||||
| ); | ||||||||||||||||
| .add_systems(Last, check_entities_needing_specialization::<M>); | ||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Going with option 2 as described above
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was actually my initial choice for a fix, but @tychedelia mentioned on discord that moving the system to
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Then we should at least move |
||||||||||||||||
|
|
||||||||||||||||
| if let Some(render_app) = app.get_sub_app_mut(RenderApp) { | ||||||||||||||||
| render_app | ||||||||||||||||
|
|
||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With option 2. described above, this would look like:
The chaining is not strictly necessary, we could just add the new
aftercondition tocheck_entities_needing_specialization.But that's also a point I'd like to discuss. Currently
check_entities_needing_specializationneedlessly? checks forBut that is literally what
mark_3d_meshes_as_changed_if_their_assets_changedandmark_meshes_as_changed_if_their_materials_changedseem to be there for (markingMesh3das changed) ? So chaining, and just checking forChanged<Mesh3d>incheck_entities_needing_specializationwould probably be simpler and achieve the expected goal.Also:
mark_meshes_as_changed_if_their_materials_changedandmark_3d_meshes_as_changed_if_their_assets_changedare not properly scheduled afterAssetEventsmain,mark_meshes_as_changed_if_their_materials_changedis not either, which could expain why all theOrparameters were introduced incheck_entities_needing_specializationThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you may have misread something here.
mark_3d_meshes_as_changed_if_their_assets_changedis frombevy_render, and isn't added here. The only ordering constraint related to it in either main or this PR should bemark_meshes_as_changed_if_their_materials_changed.after(mark_3d_meshes_as_changed_if_their_assets_changed)unless there's some other interaction happening.The minimal change from main to ensure ordering relative to
CheckVisibilitywould just be:mark_3d_meshes_as_changed_if_their_assets_changedis also already explicitly ordered before asset events here:bevy/crates/bevy_render/src/mesh/mod.rs
Lines 74 to 76 in 4051465
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right about
mark_3d_meshes_as_changed_if_their_assets_changed, it's only used for ordering inbevy_pbr, my bad.I'm still surprised though that
mark_3d_meshes_as_changed_if_their_assets_changedis ordered beforeAssetEventsall the while reading the asset events. If anyone knows why I'd gladly take an explanation.And, even a bit worse,
mark_meshes_as_changed_if_their_materials_changedis also reading asset events. Its execution order is not deterministic as its only ordered aftermark_3d_meshes_as_changed_if_their_assets_changedwhich itself is beforeAssetEvents. Somark_meshes_as_changed_if_their_materials_changedcan end up running before or afterAssetEventsdepending on scheduling (and as such, marking meshes as modifed or not depending on scheduling).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks to me like you just uncovered another bug
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for thinking about this deeply. These indeed seem to be sketchy to me. I think that both these systems were implemented before the
AssetChangedfilter was added and so they are ad-hoc implementations of the same thing. We should be able to simply add that filter inextract_meshes_for_gpu_buildingformark_3d_meshes_as_changed_if_their_assets_changed.mark_meshes_as_changed_if_their_materials_changedis a bit more complicated because it requires the material type, so needs to stay in place with the potential for fixing post #18075 potentially.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's a chance that this scheduling ambiguity I just ran into is also caused by this.