A fork of bevy to implement some features for forestia
Go to file
Patrick Walton 28441337bb
Use global binding arrays for bindless resources. (#17898)
Currently, Bevy's implementation of bindless resources is rather
unusual: every binding in an object that implements `AsBindGroup` (most
commonly, a material) becomes its own separate binding array in the
shader. This is inefficient for two reasons:

1. If multiple materials reference the same texture or other resource,
the reference to that resource will be duplicated many times. This
increases `wgpu` validation overhead.

2. It creates many unused binding array slots. This increases `wgpu` and
driver overhead and makes it easier to hit limits on APIs that `wgpu`
currently imposes tight resource limits on, like Metal.

This PR fixes these issues by switching Bevy to use the standard
approach in GPU-driven renderers, in which resources are de-duplicated
and passed as global arrays, one for each type of resource.

Along the way, this patch introduces per-platform resource limits and
bumps them from 16 resources per binding array to 64 resources per bind
group on Metal and 2048 resources per bind group on other platforms.
(Note that the number of resources per *binding array* isn't the same as
the number of resources per *bind group*; as it currently stands, if all
the PBR features are turned on, Bevy could pack as many as 496 resources
into a single slab.) The limits have been increased because `wgpu` now
has universal support for partially-bound binding arrays, which mean
that we no longer need to fill the binding arrays with fallback
resources on Direct3D 12. The `#[bindless(LIMIT)]` declaration when
deriving `AsBindGroup` can now simply be written `#[bindless]` in order
to have Bevy choose a default limit size for the current platform.
Custom limits are still available with the new
`#[bindless(limit(LIMIT))]` syntax: e.g. `#[bindless(limit(8))]`.

The material bind group allocator has been completely rewritten. Now
there are two allocators: one for bindless materials and one for
non-bindless materials. The new non-bindless material allocator simply
maintains a 1:1 mapping from material to bind group. The new bindless
material allocator maintains a list of slabs and allocates materials
into slabs on a first-fit basis. This unfortunately makes its
performance O(number of resources per object * number of slabs), but the
number of slabs is likely to be low, and it's planned to become even
lower in the future with `wgpu` improvements. Resources are
de-duplicated with in a slab and reference counted. So, for instance, if
multiple materials refer to the same texture, that texture will exist
only once in the appropriate binding array.

To support these new features, this patch adds the concept of a
*bindless descriptor* to the `AsBindGroup` trait. The bindless
descriptor allows the material bind group allocator to probe the layout
of the material, now that an array of `BindGroupLayoutEntry` records is
insufficient to describe the group. The `#[derive(AsBindGroup)]` has
been heavily modified to support the new features. The most important
user-facing change to that macro is that the struct-level `uniform`
attribute, `#[uniform(BINDING_NUMBER, StandardMaterial)]`, now reads
`#[uniform(BINDLESS_INDEX, MATERIAL_UNIFORM_TYPE,
binding_array(BINDING_NUMBER)]`, allowing the material to specify the
binding number for the binding array that holds the uniform data.

To make this patch simpler, I removed support for bindless
`ExtendedMaterial`s, as well as field-level bindless uniform and storage
buffers. I intend to add back support for these as a follow-up. Because
they aren't in any released Bevy version yet, I figured this was OK.

Finally, this patch updates `StandardMaterial` for the new bindless
changes. Generally, code throughout the PBR shaders that looked like
`base_color_texture[slot]` now looks like
`bindless_2d_textures[material_indices[slot].base_color_texture]`.

This patch fixes a system hang that I experienced on the [Caldera test]
when running with `caldera --random-materials --texture-count 100`. The
time per frame is around 19.75 ms, down from 154.2 ms in Bevy 0.14: a
7.8× speedup.

[Caldera test]: https://github.com/DGriffin91/bevy_caldera_scene
2025-02-21 05:55:36 +00:00
.cargo Fix typos in config_fast_builds.toml (#16025) 2024-10-20 16:50:40 +00:00
.github Bump typos to 1.29.7 (#17902) 2025-02-17 20:41:25 +00:00
assets Use global binding arrays for bindless resources. (#17898) 2025-02-21 05:55:36 +00:00
benches Improved Spawn APIs and Bundle Effects (#17521) 2025-02-09 23:32:56 +00:00
crates Use global binding arrays for bindless resources. (#17898) 2025-02-21 05:55:36 +00:00
docs Use target_abi = "sim" instead of ios_simulator feature (#17702) 2025-02-11 23:01:26 +00:00
docs-rs Trait tags on docs.rs (#17758) 2025-02-11 22:13:38 +00:00
docs-template Fix a few typos (#17292) 2025-01-10 22:48:30 +00:00
errors Fix Visibility link on b0004 error page (#17562) 2025-01-27 18:06:22 +00:00
examples Use global binding arrays for bindless resources. (#17898) 2025-02-21 05:55:36 +00:00
src Move #![warn(clippy::allow_attributes, clippy::allow_attributes_without_reason)] to the workspace Cargo.toml (#17374) 2025-01-15 01:14:58 +00:00
tests Move hashbrown and foldhash out of bevy_utils (#17460) 2025-01-23 16:46:08 +00:00
tests-integration Fix failing proc macros when depending on bevy through dev and normal dependencies. (#17795) 2025-02-11 18:28:15 +00:00
tools Add ways to configure EasingFunction::Steps via new StepConfig (#17752) 2025-02-11 22:19:01 +00:00
.gitattributes
.gitignore Harden proc macro path resolution and add integration tests. (#17330) 2025-02-09 19:45:45 +00:00
Cargo.toml Deterministic fallible_systems example (#17813) 2025-02-11 23:54:20 +00:00
clippy.toml Migrate to core::hint::black_box() (#16980) 2024-12-29 19:33:42 +00:00
CODE_OF_CONDUCT.md
CONTRIBUTING.md Reworded the CONTRIBUTING.md doc (#16849) 2024-12-17 19:18:34 +00:00
CREDITS.md Fix typos CREDITS.md (#17899) 2025-02-17 09:30:04 +00:00
deny.toml make bevy math publishable (#17727) 2025-02-10 22:15:53 +00:00
LICENSE-APACHE
LICENSE-MIT
README.md Update Contributor's Guide link in README.md (#16592) 2024-12-02 15:18:19 +00:00
rustfmt.toml Simpler lint fixes: makes ci lints work but disables a lint for now (#15376) 2024-09-24 11:42:59 +00:00
typos.toml Bump typos to 1.29.7 (#17902) 2025-02-17 20:41:25 +00:00

Bevy

License Crates.io Downloads Docs CI Discord

What is Bevy?

Bevy is a refreshingly simple data-driven game engine built in Rust. It is free and open-source forever!

WARNING

Bevy is still in the early stages of development. Important features are missing. Documentation is sparse. A new version of Bevy containing breaking changes to the API is released approximately once every 3 months. We provide migration guides, but we can't guarantee migrations will always be easy. Use only if you are willing to work in this environment.

MSRV: Bevy relies heavily on improvements in the Rust language and compiler. As a result, the Minimum Supported Rust Version (MSRV) is generally close to "the latest stable release" of Rust.

Design Goals

  • Capable: Offer a complete 2D and 3D feature set
  • Simple: Easy for newbies to pick up, but infinitely flexible for power users
  • Data Focused: Data-oriented architecture using the Entity Component System paradigm
  • Modular: Use only what you need. Replace what you don't like
  • Fast: App logic should run quickly, and when possible, in parallel
  • Productive: Changes should compile quickly ... waiting isn't fun

About

  • Features: A quick overview of Bevy's features.
  • News: A development blog that covers our progress, plans and shiny new features.

Docs

Community

Before contributing or participating in discussions with the community, you should familiarize yourself with our Code of Conduct.

  • Discord: Bevy's official discord server.
  • Reddit: Bevy's official subreddit.
  • GitHub Discussions: The best place for questions about Bevy, answered right here!
  • Bevy Assets: A collection of awesome Bevy projects, tools, plugins and learning materials.

Contributing

If you'd like to help build Bevy, check out the Contributor's Guide. For simple problems, feel free to open an issue or PR and tackle it yourself!

For more complex architecture decisions and experimental mad science, please open an RFC (Request For Comments) so we can brainstorm together effectively!

Getting Started

We recommend checking out the Quick Start Guide for a brief introduction.

Follow the Setup guide to ensure your development environment is set up correctly. Once set up, you can quickly try out the examples by cloning this repo and running the following commands:

# Switch to the correct version (latest release, default is main development branch)
git checkout latest
# Runs the "breakout" example
cargo run --example breakout

To draw a window with standard functionality enabled, use:

use bevy::prelude::*;

fn main(){
  App::new()
    .add_plugins(DefaultPlugins)
    .run();
}

Fast Compiles

Bevy can be built just fine using default configuration on stable Rust. However for really fast iterative compiles, you should enable the "fast compiles" setup by following the instructions here.

Bevy Cargo Features

This list outlines the different cargo features supported by Bevy. These allow you to customize the Bevy feature set for your use-case.

Thanks

Bevy is the result of the hard work of many people. A huge thanks to all Bevy contributors, the many open source projects that have come before us, the Rust gamedev ecosystem, and the many libraries we build on.

A huge thanks to Bevy's generous sponsors. Bevy will always be free and open source, but it isn't free to make. Please consider sponsoring our work if you like what we're building.

This project is tested with BrowserStack.

License

Bevy is free, open source and permissively licensed! Except where noted (below and/or in individual files), all code in this repository is dual-licensed under either:

at your option. This means you can select the license you prefer! This dual-licensing approach is the de-facto standard in the Rust ecosystem and there are very good reasons to include both.

Some of the engine's code carries additional copyright notices and license terms due to their external origins. These are generally BSD-like, but exact details vary by crate: If the README of a crate contains a 'License' header (or similar), the additional copyright notices and license terms applicable to that crate will be listed. The above licensing requirement still applies to contributions to those crates, and sections of those crates will carry those license terms. The license field of each crate will also reflect this. For example, bevy_mikktspace has code under the Zlib license (as well as a copyright notice when choosing the MIT license).

The assets included in this repository (for our examples) typically fall under different open licenses. These will not be included in your game (unless copied in by you), and they are not distributed in the published bevy crates. See CREDITS.md for the details of the licenses of those files.

Your contributions

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.