Use a slotmap for render assets storage#13013
Use a slotmap for render assets storage#13013superdump wants to merge 8 commits intobevyengine:mainfrom
Conversation
Smaller keys!
| diffuse: item.diffuse_map.id(), | ||
| specular: item.specular_map.id(), | ||
| }) | ||
| pub fn update_pending_environment_maps( |
There was a problem hiding this comment.
I did want this to use the plugin, but I feel like it's an exception, and I don't want to make the trait for the helper plugin much more complicated just to cover this case. Not certain it's the right choice though.
| } | ||
| } | ||
|
|
||
| pub fn extract_visible_material_instances<M: Material>( |
There was a problem hiding this comment.
Maybe this simple extraction case can be pluginified.
JMS55
left a comment
There was a problem hiding this comment.
Not the cleanest solution, but it's not awful either. I don't love that the extract time goes up so much, nor the extra complexity involved. I won't block on it, but we could use more docs around the logic in the various systems. There's several nested conditions which makes understanding the code at a glance difficult.
I think there's a couple of questions worth asking:
- Can we remove AssetId::Uuid outright?
- If we want to move RenderAsset preparation into the asset loader directly, mostly for images in the context of this PR, will it be possible now that there's an extra layer of indirection for render assets?
We definitely should run the screenshot diff tool on all the examples before merging this.
|
|
||
| for material_id in render_material_instances.values() { | ||
| let Some(material) = render_materials.get(*material_id) else { | ||
| for &material_key in render_material_instances.values() { |
There was a problem hiding this comment.
I have this fixed in a future PR by changing it to .values().collect::<HashSet<_>>(), but this code is currently bugged and adds too many materials, as it does not deduplicate between multiple entities with the same material (AssetId).
What this code really wants to do is iterate over every instance of material M that exists. I don't think we have a good way of doing this, even with these changes, right?
| ) { | ||
| material_instances.clear(); | ||
| for (entity, view_visibility, material) in &query { | ||
| if view_visibility.get() { |
There was a problem hiding this comment.
This isn't a change from how it is now, but meshlets uses RenderMaterialInstances. But, ViewVisibility should never get computed for MeshletMeshes?? It only gets updated for WithMesh entities, and it defaults to false afaiu. What am I missing here?
There was a problem hiding this comment.
Hmm, the meshlet example works, so there doesn't seem to be any problem. I'm not sure how it works, but this also didn't really change anything versus main, other than to allow use of RenderAssetKey.
|
@cart Weren't you planning on removing |
|
I'm moving this PR to a draft. After the push back about the regression in extraction time, I went down a rabbit hole of changing Handle and AssetId to not be enums, instead to be structs and require always having an AssetIndex member, and optionally a Uuid. See Discord for details, but the short version is it performs even better than this PR, and it feels like a better solution if we can stomach not having support for compile-time const Handle. |
|
Closing. After discussion with @cart we decided not to do this, but rather wait for the long-term solution. |
Objective
Vec<u32>Solution
RenderAssetsAssetId<A: RenderAsset>to slotmap key insideRenderAssetsand use it to look up keys for known render assets at extraction timeUpdatePendingRenderAssetKeyPluginto help with updating asset keys on instance data for assets that were loaded during the current frame, to avoid a 1-frame lag.Benchmarks
On an M1 Max, running
cargo run --release --example bevymark -- --benchmark --waves 160 --per-wave 1000 --mode mesh2d. Yellow is main, red is this PR:A 6.3% reduction in median frame time.
Main:

PR:

Noteworthy spans:
Changelog
RenderAssetKeyslotmap key type to be used withRenderAssetsget_key,get_with_key, andget_with_key_mutmethods toRenderAssetsto use slotmap keys.UpdatePendingRenderAssetKeyPluginto help with updating asset keys on instance data for assets that were loaded during the current frame, to avoid a 1-frame lag.RenderAssetsfor improved performance due to the smaller asset reference data size of slotmap keys compared toAssetId