-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Turn on GPU culling automatically if the target platform supports it. #16670
Conversation
This commit removes the undocumented `GpuCulling` component in favor of automatically turning GPU culling on when the platform supports it. The main reason to make GPU culling automatic is that GPU culling enables indirect mode. Indirect mode is needed for multidraw (bevyengine#16427), because non-indirect multidraw doesn't exist in `wgpu`. Since multidraw is such a win for performance, when that feature is supported the small performance tax that indirect mode incurs is virtually always worth paying. CPU culling is always used in addition to GPU culling unless the `NoCpuCulling` component is placed on the camera. This results in some amount of redundant computation on the GPU, but the overhead is negligible. I figured that the GPU time savings gained from skipping this computation when not needed didn't outweigh the costs of the added complexity that would be necessarily to implement that optimization, especially with GPU two-phase occlusion culling on the horizon.
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, I think this is a better design.
This patch makes shadows use multidraw when the camera they'll be drawn to has the `GpuCulling` component. This results in a significant reduction in drawcalls; Bistro Exterior drops to 3 drawcalls for each shadow cascade. Note that PR bevyengine#16670 will remove the `GpuCulling` component, making shadows automatically use multidraw. Beware of that when testing this patch; before bevyengine#16670 lands, you'll need to manually add `GpuCulling` to your camera in order to see any performance benefits.
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.
Approved once docs are fixed (see CI).
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.
Tested many_cubes
in Windows 10 on a i5 1240P Framework 13 and everything appears to be working as expected. Code definitely looks cleaner too!
Testing via example run. |
I believe the failure is #15981. |
These seem to be the finished runs: mac: Looks like |
This patch makes shadows use multidraw when the camera they'll be drawn to has the `GpuCulling` component. This results in a significant reduction in drawcalls; Bistro Exterior drops to 3 drawcalls for each shadow cascade. Note that PR #16670 will remove the `GpuCulling` component, making shadows automatically use multidraw. Beware of that when testing this patch; before #16670 lands, you'll need to manually add `GpuCulling` to your camera in order to see any performance benefits.
…tomatic-gpu-culling
This patch makes shadows use multidraw when the camera they'll be drawn to has the `GpuCulling` component. This results in a significant reduction in drawcalls; Bistro Exterior drops to 3 drawcalls for each shadow cascade. Note that PR bevyengine#16670 will remove the `GpuCulling` component, making shadows automatically use multidraw. Beware of that when testing this patch; before bevyengine#16670 lands, you'll need to manually add `GpuCulling` to your camera in order to see any performance benefits.
multidraw. This commit resolves most of the failures seen in bevyengine#16670. It contains two major fixes: 1. The prepass shaders weren't updated for bindless mode, so they were accessing `material` as a single element instead of as an array. I added the needed `BINDLESS` check. 2. If the mesh didn't support batch set keys (i.e. `get_batch_set_key()` returns `None`), and multidraw was enabled, the batching logic would try to multidraw all the meshes in a bin together instead of disabling multidraw. This is because we checked whether the `Option<BatchSetKey>` for the previous batch was equal to the `Option<BatchSetKey>` for the next batch to determine whether objects could be multidrawn together, which would return true if batch set keys were absent, causing an entire bin to be multidrawn together. This patch fixes the logic so that multidraw is only enabled if the batch set keys match *and are `Some`*. Additionally, this commit adds batch key support for bins that use `Opaque3dNoLightmapBinKey`, which in practice means prepasses. Consequently, this patch enables multidraw for the prepass when GPU culling is enabled. When testing this patch, try adding `GpuCulling` to the camera in the `deferred_rendering` and `ssr` examples. You can see that these examples break without this patch and work properly with it.
default. This patch replaces the undocumented `NoGpuCulling` component with a new component, `NoIndirectDrawing`, effectively turning indirect drawing on by default. Indirect mode is needed for the recently-landed multidraw feature (bevyengine#16427). Since multidraw is such a win for performance, when that feature is supported the small performance tax that indirect mode incurs is virtually always worth paying. To ensure that custom drawing code such as that in the `custom_shader_instancing` example continues to function, this commit additionally makes GPU culling take the `NoFrustumCulling` component into account. This PR is an alternative to bevyengine#16670 that doesn't break the `custom_shader_instancing` example. **PR bevyengine#16755 should land first in order to avoid breaking deferred rendering, as multidraw currently breaks it**.
…d multidraw. (#16755) This commit resolves most of the failures seen in #16670. It contains two major fixes: 1. The prepass shaders weren't updated for bindless mode, so they were accessing `material` as a single element instead of as an array. I added the needed `BINDLESS` check. 2. If the mesh didn't support batch set keys (i.e. `get_batch_set_key()` returns `None`), and multidraw was enabled, the batching logic would try to multidraw all the meshes in a bin together instead of disabling multidraw. This is because we checked whether the `Option<BatchSetKey>` for the previous batch was equal to the `Option<BatchSetKey>` for the next batch to determine whether objects could be multidrawn together, which would return true if batch set keys were absent, causing an entire bin to be multidrawn together. This patch fixes the logic so that multidraw is only enabled if the batch set keys match *and are `Some`*. Additionally, this commit adds batch key support for bins that use `Opaque3dNoLightmapBinKey`, which in practice means prepasses. Consequently, this patch enables multidraw for the prepass when GPU culling is enabled. When testing this patch, try adding `GpuCulling` to the camera in the `deferred_rendering` and `ssr` examples. You can see that these examples break without this patch and work properly with it. --------- Co-authored-by: Alice Cecile <[email protected]>
…y default. (#16757) This patch replaces the undocumented `NoGpuCulling` component with a new component, `NoIndirectDrawing`, effectively turning indirect drawing on by default. Indirect mode is needed for the recently-landed multidraw feature (#16427). Since multidraw is such a win for performance, when that feature is supported the small performance tax that indirect mode incurs is virtually always worth paying. To ensure that custom drawing code such as that in the `custom_shader_instancing` example continues to function, this commit additionally makes GPU culling take the `NoFrustumCulling` component into account. This PR is an alternative to #16670 that doesn't break the `custom_shader_instancing` example. **PR #16755 should land first in order to avoid breaking deferred rendering, as multidraw currently breaks it**. ## Migration Guide * Indirect drawing (GPU culling) is now enabled by default, so the `GpuCulling` component is no longer available. To disable indirect mode, which may be useful with custom render nodes, add the new `NoIndirectDrawing` component to your camera.
This commit removes the undocumented
GpuCulling
component in favor of automatically turning GPU culling on when the platform supports it. The main reason to make GPU culling automatic is that GPU culling enables indirect mode. Indirect mode is needed for multidraw (#16427), because non-indirect multidraw doesn't exist inwgpu
. Since multidraw is such a win for performance, when that feature is supported the small performance tax that indirect mode incurs is virtually always worth paying.CPU culling is always used in addition to GPU culling unless the
NoCpuCulling
component is placed on the camera. This results in some amount of redundant computation on the GPU, but the overhead is negligible. I figured that the GPU time savings gained from skipping this computation when not needed didn't outweigh the costs of the added complexity that would be necessarily to implement that optimization, especially with GPU two-phase occlusion culling on the horizon.Migration Guide
GpuCulling
component has been removed. GPU culling is now automatically enabled for all cameras if the hardware and platform support it.