Skip to content
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

extensible view bindgroups / reusable binding definitions #6738

Closed
wants to merge 33 commits into from

Conversation

robtfm
Copy link
Contributor

@robtfm robtfm commented Nov 23, 2022

Objective

  • allow users/plugins to extend core pipeline @group(0)/view bind groups
  • allow user-defined pipelines with custom bind groups to easily use bindings defined in the core plugins (e.g. view, globals, point lights, shadow maps, etc)
  • consolidate some of the shared pbr/sprite/mesh2d/ui bind group operations (this was necessary to share the autobinding structs but is good to do anyway)

Solution

builds on #5703.

  • beefed up OwnedBindingResource from bind_group.rs, currently used for AsBindGroup impls

    • moved it into it's own file in bevy_render
    • added DynamicBuffer variant, including the dynamic offset
    • added support functions to get OwnedBindingResources for UniformBuffer/DynamicUniformBuffer (todo: add helpers to more resource types, storage buffer etc)
  • created AutoBindGroupPlugin to manage automatic bindgroups

    • used like render_app.add_plugin(AutoBindGroupPlugin::<MeshViewBindGroup, With<RenderPhase<Opaque3d>>>::default()) (for pbr)
    • takes 2 generics, G is a bind group marker struct, and F is a filter that defines which entities the bind group is generated for
    • used it for bevy_pbr's MeshViewBindGroup and ShadowViewBindGroup, bevy_sprite's SpriteViewBindGroup and Mesh2dViewBindGroup, bevy_ui's UiViewBindGroup
  • created AutoBinding trait which encapsulates info about a binding; the shader variable name, binding layout, and data source

    • a globally unique binding slot is allocated for each AutoBinding on first use (so that any combo of AutoBindings can be added to any AutoBindGroup - webgpu allows binding slots up to 65536 so there is lots of room)
    • impl'd AutoBinding for all the current main pipeline @group(0) bind group entries (excl post-processing)
    • moved view and globals bindings into bevy_render
    • made all the main pipeline view bind groups use bevy_render's definitions/imports for view and global
  • used automatically managed binding slots for auto bindings in .wgsl shaders by specifying @binding(auto)

    • added the binding slot allocation to pipeline_cache.rs
    • added a little bit of support to naga_oil for @binding(auto) syntax
    • note using @binding(auto) isn't strictly necessary and code using @binding(0), @binding(1) etc will still generally work (though the binding slots will not necessarily be 0, 1 any more). and if multiple plugins add to the same bind group and both use the same binding slot, they will be mapped to separate binding slots anyway. but if the naga_oil validation is switched on (as it is in debug builds by default) then duplicate binding slot definitions cause validation errors. anyway, i think it is clearer to say @binding(auto) to indicate that you can't actually tell what the slot value will be.
  • allowed users/plugins to add new AutoBinding items to the builtin auto bindgroups via render_app.add_auto_binding<G: AutoBindGroup, B: AutoBinding>()

    • makes the user binding available to all pipelines using the bindgroup G
    • added example as part of pbr_global_override.rs (which also uses a function override to modify pbr's point light function using the user binding)
  • allowed users/plugins to use core bindings in their own bindgroups via e.g. render_app.add_auto_binding<MyBindGroup, bevy_pbr::mesh_view_bindings::PointLightsBinding>()

    • note that this will also mean using auto bindings for other items in the user bindgroup - mixing auto and non-auto bindings can't be guaranteed to work
  • removed view_layout member for several Pipelines, these are now accessed statically via auto_layout::<G>() since they can be changed by user plugins

perf notes

this requires a lot of systems (one per binding per containing bindgroup), and bumps/drops Arcs on each resource every frame.
for view bindgroups i think the capabilities are very much worth this small cost, and i notice no impact on benchmarks.
this auto strategy should maybe not be used for more high-frequency bindgroups like material / mesh (although allowing plugin extensions to StandardMaterial would be interesting ...)

issues

can make it even harder to tell whats going wrong when wgpu throws binding mismatch errors, since you don't even know what slot refers to what data any more. there is logging for the binding slot allocation ("bevy_render::auto_binding=debug"), but we could consider adding a custom wgpu error handler as well.

migration guide

  • change the import location for the view and global bindings in user shaders:

    • bevy_pbr::mesh_view_bindings::view -> bevy_render::core_bindings::view
    • bevy_pbr::mesh_view_bindings::globals -> bevy_render::core_bindings::globals
    • bevy_sprite::sprite.wgsl view -> bevy_render::core_bindings::view
    • bevy_sprite::sprite.wgsl globals -> bevy_render::core_bindings::globals
    • bevy_sprite::mesh_2d_view_bindings::view -> bevy_render::core_bindings::view
    • bevy_sprite::mesh_2d_view_bindings::globals -> bevy_render::core_bindings::globals
    • bevy_ui::ui.wgsl view -> bevy_render::core_bindings::view
    • bevy_ui::ui.wgsl globals -> bevy_render::core_bindings::globals
  • change source for pipeline view_layouts to use auto_layout::<G>()

@IceSentry IceSentry added the A-Rendering Drawing game state to the screen label Nov 23, 2022
@alice-i-cecile alice-i-cecile added the C-Usability A targeted quality-of-life change that makes Bevy easier to use label Jan 12, 2023
@robtfm robtfm marked this pull request as draft January 15, 2023 17:14
@bas-ie
Copy link
Contributor

bas-ie commented Oct 20, 2024

Backlog cleanup: @robtfm hard keeping 76 files up to date with main! Should this be closed, at least for now, or do you still intend to try to get it merged?

@bas-ie
Copy link
Contributor

bas-ie commented Oct 28, 2024

Backlog cleanup: closing due to inactivity, would be considerable bitrot to combat at this point.

@bas-ie bas-ie closed this Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants