-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Cold Specialization #17567
base: main
Are you sure you want to change the base?
Cold Specialization #17567
Conversation
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.
A couple of comments to start with. I'll have more later when I take a closer look.
.render_lightmaps | ||
.get(&entity) | ||
.map(|lightmap| lightmap.slab_index); | ||
self.shared.lightmap_slab_index = lightmap_slab_index; |
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.
Check pass ordering here. Are we sure that render_lightmaps
is populated before this runs?
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.
Okay, will check. I also think that Lightmap
needs to be added to the invalidation logic.
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 like we're good, as RenderLightmaps
is populated during the extraction phase, and RenderMeshInstanceGpuBuilder::update
is called during the collection subphase of the render phase.
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.
This is a more thorough review. I mostly just had some simplification suggestions that you can do if you want. This is great stuff.
.render_lightmaps | ||
.get(&entity) | ||
.map(|lightmap| lightmap.slab_index); | ||
self.shared.lightmap_slab_index = lightmap_slab_index; |
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 like we're good, as RenderLightmaps
is populated during the extraction phase, and RenderMeshInstanceGpuBuilder::update
is called during the collection subphase of the render phase.
Co-authored-by: Patrick Walton <[email protected]>
Co-authored-by: Patrick Walton <[email protected]>
Co-authored-by: Patrick Walton <[email protected]>
Cold Specialization
Objective
An ongoing part of our quest to retain everything in the render world, cold-specialization aims to cache pipeline specialization so that pipeline IDs can be recomputed only when necessary, rather than every frame. This approach reduces redundant work in stable scenes, while still accommodating scenarios in which materials, views, or visibility might change, as well as unlocking future optimization work like retaining render bins.
Solution
Queue systems are split into a specialization system and queue system, the former of which only runs when necessary to compute a new pipeline id. Pipelines are invalidated using a combination of change detection and ECS ticks.
The difficulty with change detection
Detecting “what changed” can be tricky because pipeline specialization depends not only on the entity’s components (e.g., mesh, material, etc.) but also on which view (camera) it is rendering in. In other words, the cache key for a given pipeline id is a view entity/render entity pair. As such, it's not sufficient simply to react to change detection in order to specialize -- an entity could currently be out of view or could be rendered in the future in camera that is currently disabled or hasn't spawned yet.
Why ticks?
Ticks allow us to ensure correctness by allowing us to compare the last time a view or entity was updated compared to the cached pipeline id. This ensures that even if an entity was out of view or has never been seen in a given camera before we can still correctly determine whether it needs to be re-specialized or not.
Testing
TODO: Tested a bunch of different examples, need to test more.
Migration Guide
TODO
AssetEvents
has been moved into thePostUpdate
schedule.