-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Use RenderStartup
for SSAO systems.
#20206
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?
Conversation
ebd1078
to
80ad27c
Compare
80ad27c
to
c8ebfa8
Compare
c8ebfa8
to
3a91f1a
Compare
I just noticed that there's quite a bad limitation to the |
I added a little hack for this. If you want to order the condition, you can configure |
f552ac1
to
849bb1a
Compare
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.
makes sense to me, i think the conditional is still nice
849bb1a
to
7c5e973
Compare
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.
Hmm. This uses run conditions (not 100% ideal, conditionally adding systems / removing them would be slightly lower overhead), and there's gnarly "configure this system set across multiple schedules" nonsense, which is something that shouldn't be necessary.
That said, there's a lot to be said for having a consistent way to do this, and the exact details are clear and well documented.
Let me think about better patterns, to see if we can get something better now without waiting on further improvements to 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.
I've thought harder about this, and I really don't like the complexity and ad-hoc nature of conditional_render_set
. If we had commands.add_systems
, would that work fine for you? That's one straightforward PR away. It's already possible by mutating Schedules
, but a command would make it a bit clearer and less boilerplate.
The core request here is "conditionally add systems" and with the RenderStartup
changes, we need to move this from plugin-init time to normal systems.
@alice-i-cecile I have a couple concerns with that. First, it means we can't conditionally have systems in RenderStartup, because of course we can't add systems to the schedule we are currently in. That can be worked around by either making a mega system to build all the resources in one system (though some of these systems get pretty big already with a single resource), or you can check whether the feature is supported in the system. Second, these systems won't show up on tools like bevy_mod_debugdump. It's a little concerning to me to have first-party "sneaky systems". Perhaps in the future, we'll have tools to debug schedules after launch, but that's probably not gonna be the first iteration anyway even for the bevy editor. These are problems we could live with, but I wasn't excited about these caveats |
Okay, hmm. I see your point there with the drawbacks of conditionally adding systems. If we're not going to conditionally add systems, a run condition is about as good as it can get. This is well-encapsulated, so I can swallow it for now. Let me get feedback from the Rendering SMEs before taking on this tech debt though. |
/// | ||
/// This allows the condition to be ordered after its dependencies for example. | ||
#[derive(SystemSet)] | ||
pub struct ConditionalRenderSetCondition<S: SystemSet>(pub PhantomData<fn() -> S>); |
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.
Why not just ConditionalRenderSet? It’s a set of systems, not a condition?
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.
The trouble is theres two system sets at play here. There are the systems that you want to run conditionally, and there's the system that runs the condition to determine whether to run that first set of systems. In this case we referring to that second system and not the first group. We can't use the name of a system because we use closures for it (to capture local variables), so we can't add any after dependencies on the condition.
If you have a better name for it, please let me know. I despise the current name, but I couldn't think of anything that wouldn't also be confusing (ConditionalRenderSet sounds like the systems that are running conditionally).
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.
Correction: we use system piping* so we can't name the system to put after dependencies on it. The capture is no longer relevant thanks to your other comment.
crates/bevy_render/src/lib.rs
Outdated
|
||
let mut resource = Some(EnabledRenderSet::<S>(PhantomData)); | ||
let condition = condition.pipe(move |In(condition): In<bool>, mut commands: Commands| { | ||
let resource = resource |
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 suppose this prevents reconfiguration, but that isn’t a regression from the plugin build/finish model anyway.
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.
Good spot! This was a leftover from a previous iteration where users were passing in the "enabled" resource. Now since we construct it here, avoiding the capture is much better!
|
||
render_app | ||
.init_resource::<SsaoPipelines>() | ||
.init_resource::<SpecializedComputePipelines<SsaoPipelines>>() |
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.
Is there a reason to still insert this resource if the condition fails?
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.
No, there isn't. The advantage is simplicity. Resources that impl Default are safe to init all the time. In contrast if we didn't want to init the resource if the condition is false, we'd need to add a system whose only job is to insert that resource. That's kinda cumbersome here, and I'd only like to use that pattern when things actually depend on the world.
This also makes the diff smaller :)
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.
The pattern looks sensible enough to me, so from my perspective, the idea is no longer controversial to me.
That said, it may be that access to more things is or could be needed. I’m not certain that RenderDevice alone is enough. I feel like some information is available from the adapter as well, and perhaps other custom resources may be needed.
As for the rest of the discussion - I can see value in commands.add_systems() but also see that it could be too flexible for initialisation if we need various plugins to have dependencies on each other. Namely if you don’t constrain when a system can be added, it can be difficult to schedule your system to run after that system. |
I misremembered where I’d seen the use of RenderDevice in the PR. The above can be ignored. |
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.
After a bit more thought, I’m fine with this. We can always iterate and make further changes, and people don’t have to use this if something about it turns out to be problematic. Low risk change imo.
Can we use #20298 instead? Add the systems unconditionally, then conditionally remove them? |
@alice-i-cecile I tried to mock up what this would look like with #20298. Here is it andriyDev@29a5e24. I've done my best to give it a fair shake - please let me know if there's another way that would look nicer. The main system to look at is I personally do not like how it looks. We now need to do 2+ things in one system in RenderStartup. If the feature is unsupported, remove systems from the schedules. If the feature is supported, add some render graph nodes, and init the pipeline resource. I also tried using run conditions for the systems in RenderStartup and keeping that separate. That looked like this andriyDev@4cc4d1c (see where the systems are added to Let me know which one you prefer. My personal preference is still the run conditions one just because how little setup there is on the user - it's all tucked away in the one (admittedly gross) |
Objective
RenderStartup
.Solution
RenderStartup
.conditional_render_set
to generalize the pattern of creating system sets + resources to conditionally run systems!Thanks to @JMS55 for suggesting this generalization in #19918!
Testing