Merge branch 'main' into color-space-variants-renamings
This commit is contained in:
commit
134184ce5d
@ -18,9 +18,7 @@ bevy_input_focus = { path = "../bevy_input_focus", version = "0.17.0-dev" }
|
||||
bevy_log = { path = "../bevy_log", version = "0.17.0-dev" }
|
||||
bevy_math = { path = "../bevy_math", version = "0.17.0-dev" }
|
||||
bevy_picking = { path = "../bevy_picking", version = "0.17.0-dev" }
|
||||
bevy_ui = { path = "../bevy_ui", version = "0.17.0-dev", features = [
|
||||
"bevy_ui_picking_backend",
|
||||
] }
|
||||
bevy_ui = { path = "../bevy_ui", version = "0.17.0-dev" }
|
||||
|
||||
# other
|
||||
accesskit = "0.19"
|
||||
|
@ -472,58 +472,58 @@ impl<'w> ComponentsQueuedRegistrator<'w> {
|
||||
Self { components, ids }
|
||||
}
|
||||
|
||||
/// Queues this function to run as a component registrator.
|
||||
/// Queues this function to run as a component registrator if the given
|
||||
/// type is not already queued as a component.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The [`TypeId`] must not already be registered or queued as a component.
|
||||
unsafe fn force_register_arbitrary_component(
|
||||
/// The [`TypeId`] must not already be registered as a component.
|
||||
unsafe fn register_arbitrary_component(
|
||||
&self,
|
||||
type_id: TypeId,
|
||||
descriptor: ComponentDescriptor,
|
||||
func: impl FnOnce(&mut ComponentsRegistrator, ComponentId, ComponentDescriptor) + 'static,
|
||||
) -> ComponentId {
|
||||
let id = self.ids.next();
|
||||
self.components
|
||||
.queued
|
||||
.write()
|
||||
.unwrap_or_else(PoisonError::into_inner)
|
||||
.components
|
||||
.insert(
|
||||
type_id,
|
||||
.entry(type_id)
|
||||
.or_insert_with(|| {
|
||||
// SAFETY: The id was just generated.
|
||||
unsafe { QueuedRegistration::new(id, descriptor, func) },
|
||||
);
|
||||
id
|
||||
unsafe { QueuedRegistration::new(self.ids.next(), descriptor, func) }
|
||||
})
|
||||
.id
|
||||
}
|
||||
|
||||
/// Queues this function to run as a resource registrator.
|
||||
/// Queues this function to run as a resource registrator if the given
|
||||
/// type is not already queued as a resource.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The [`TypeId`] must not already be registered or queued as a resource.
|
||||
unsafe fn force_register_arbitrary_resource(
|
||||
/// The [`TypeId`] must not already be registered as a resource.
|
||||
unsafe fn register_arbitrary_resource(
|
||||
&self,
|
||||
type_id: TypeId,
|
||||
descriptor: ComponentDescriptor,
|
||||
func: impl FnOnce(&mut ComponentsRegistrator, ComponentId, ComponentDescriptor) + 'static,
|
||||
) -> ComponentId {
|
||||
let id = self.ids.next();
|
||||
self.components
|
||||
.queued
|
||||
.write()
|
||||
.unwrap_or_else(PoisonError::into_inner)
|
||||
.resources
|
||||
.insert(
|
||||
type_id,
|
||||
.entry(type_id)
|
||||
.or_insert_with(|| {
|
||||
// SAFETY: The id was just generated.
|
||||
unsafe { QueuedRegistration::new(id, descriptor, func) },
|
||||
);
|
||||
id
|
||||
unsafe { QueuedRegistration::new(self.ids.next(), descriptor, func) }
|
||||
})
|
||||
.id
|
||||
}
|
||||
|
||||
/// Queues this function to run as a dynamic registrator.
|
||||
fn force_register_arbitrary_dynamic(
|
||||
fn register_arbitrary_dynamic(
|
||||
&self,
|
||||
descriptor: ComponentDescriptor,
|
||||
func: impl FnOnce(&mut ComponentsRegistrator, ComponentId, ComponentDescriptor) + 'static,
|
||||
@ -554,9 +554,9 @@ impl<'w> ComponentsQueuedRegistrator<'w> {
|
||||
#[inline]
|
||||
pub fn queue_register_component<T: Component>(&self) -> ComponentId {
|
||||
self.component_id::<T>().unwrap_or_else(|| {
|
||||
// SAFETY: We just checked that this type was not in the queue.
|
||||
// SAFETY: We just checked that this type was not already registered.
|
||||
unsafe {
|
||||
self.force_register_arbitrary_component(
|
||||
self.register_arbitrary_component(
|
||||
TypeId::of::<T>(),
|
||||
ComponentDescriptor::new::<T>(),
|
||||
|registrator, id, _descriptor| {
|
||||
@ -584,7 +584,7 @@ impl<'w> ComponentsQueuedRegistrator<'w> {
|
||||
&self,
|
||||
descriptor: ComponentDescriptor,
|
||||
) -> ComponentId {
|
||||
self.force_register_arbitrary_dynamic(descriptor, |registrator, id, descriptor| {
|
||||
self.register_arbitrary_dynamic(descriptor, |registrator, id, descriptor| {
|
||||
// SAFETY: Id uniqueness handled by caller.
|
||||
unsafe {
|
||||
registrator.register_component_inner(id, descriptor);
|
||||
@ -606,9 +606,9 @@ impl<'w> ComponentsQueuedRegistrator<'w> {
|
||||
pub fn queue_register_resource<T: Resource>(&self) -> ComponentId {
|
||||
let type_id = TypeId::of::<T>();
|
||||
self.get_resource_id(type_id).unwrap_or_else(|| {
|
||||
// SAFETY: We just checked that this type was not in the queue.
|
||||
// SAFETY: We just checked that this type was not already registered.
|
||||
unsafe {
|
||||
self.force_register_arbitrary_resource(
|
||||
self.register_arbitrary_resource(
|
||||
type_id,
|
||||
ComponentDescriptor::new_resource::<T>(),
|
||||
move |registrator, id, descriptor| {
|
||||
@ -638,9 +638,9 @@ impl<'w> ComponentsQueuedRegistrator<'w> {
|
||||
pub fn queue_register_non_send<T: Any>(&self) -> ComponentId {
|
||||
let type_id = TypeId::of::<T>();
|
||||
self.get_resource_id(type_id).unwrap_or_else(|| {
|
||||
// SAFETY: We just checked that this type was not in the queue.
|
||||
// SAFETY: We just checked that this type was not already registered.
|
||||
unsafe {
|
||||
self.force_register_arbitrary_resource(
|
||||
self.register_arbitrary_resource(
|
||||
type_id,
|
||||
ComponentDescriptor::new_non_send::<T>(StorageType::default()),
|
||||
move |registrator, id, descriptor| {
|
||||
@ -669,7 +669,7 @@ impl<'w> ComponentsQueuedRegistrator<'w> {
|
||||
&self,
|
||||
descriptor: ComponentDescriptor,
|
||||
) -> ComponentId {
|
||||
self.force_register_arbitrary_dynamic(descriptor, |registrator, id, descriptor| {
|
||||
self.register_arbitrary_dynamic(descriptor, |registrator, id, descriptor| {
|
||||
// SAFETY: Id uniqueness handled by caller.
|
||||
unsafe {
|
||||
registrator.register_component_inner(id, descriptor);
|
||||
|
@ -2776,4 +2776,17 @@ mod tests {
|
||||
|
||||
fn custom_clone(_source: &SourceComponent, _ctx: &mut ComponentCloneCtx) {}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn queue_register_component_toctou() {
|
||||
for _ in 0..1000 {
|
||||
let w = World::new();
|
||||
|
||||
std::thread::scope(|s| {
|
||||
let c1 = s.spawn(|| w.components_queue().queue_register_component::<A>());
|
||||
let c2 = s.spawn(|| w.components_queue().queue_register_component::<A>());
|
||||
assert_eq!(c1.join().unwrap(), c2.join().unwrap());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ pub fn ktx2_buffer_to_image(
|
||||
})?;
|
||||
levels.push(decompressed);
|
||||
}
|
||||
#[cfg(feature = "zstd_rust")]
|
||||
#[cfg(all(feature = "zstd_rust", not(feature = "zstd_c")))]
|
||||
SupercompressionScheme::Zstandard => {
|
||||
let mut cursor = std::io::Cursor::new(level.data);
|
||||
let mut decoder = ruzstd::decoding::StreamingDecoder::new(&mut cursor)
|
||||
@ -71,7 +71,7 @@ pub fn ktx2_buffer_to_image(
|
||||
})?;
|
||||
levels.push(decompressed);
|
||||
}
|
||||
#[cfg(all(feature = "zstd_c", not(feature = "zstd_rust")))]
|
||||
#[cfg(feature = "zstd_c")]
|
||||
SupercompressionScheme::Zstandard => {
|
||||
levels.push(zstd::decode_all(level.data).map_err(|err| {
|
||||
TextureError::SuperDecompressionError(format!(
|
||||
|
@ -67,9 +67,14 @@ The [Tracy profiling tool](https://github.com/wolfpld/tracy) is:
|
||||
|
||||
There are binaries available for Windows, and installation / build instructions for other operating systems can be found in the [Tracy documentation PDF](https://github.com/wolfpld/tracy/releases/latest/download/tracy.pdf).
|
||||
|
||||
To determine which Tracy version to install
|
||||
|
||||
1. Run `cargo tree --features bevy/trace_tracy | grep tracy` in your Bevy workspace root to see which tracy dep versions are used
|
||||
2. Cross reference the tracy dep versions with the [Version Support Table](https://github.com/nagisa/rust_tracy_client?tab=readme-ov-file#version-support-table)
|
||||
|
||||
It has a command line capture tool that can record the execution of graphical applications, saving it as a profile file. Tracy has a GUI to inspect these profile files. The GUI app also supports live capture, showing you in real time the trace of your app. The version of tracy must be matched to the version of tracing-tracy used in bevy. A compatibility table can be found on [crates.io](https://crates.io/crates/tracing-tracy) and the version used can be found [here](https://github.com/bevyengine/bevy/blob/latest/crates/bevy_log/Cargo.toml).
|
||||
|
||||
On macOS, Tracy can be installed through Homebrew by running `brew install tracy`, and the GUI client can be launched by running `tracy`.
|
||||
On macOS, Tracy can be installed through Homebrew by running `brew install tracy`, and the GUI client can be launched by running `tracy`. Note that `brew` does not always have the latest version of Tracy available, in which cases you may be required to build from source.
|
||||
|
||||
In one terminal, run:
|
||||
`./capture-release -o my_capture.tracy`
|
||||
@ -154,20 +159,20 @@ Follow the steps below to start GPU debugging on macOS. There is no need to crea
|
||||
|
||||
1. In the menu bar click on Debug > Debug Executable…
|
||||
|
||||

|
||||

|
||||
|
||||
2. Select your executable from your project’s target folder.
|
||||
3. The Scheme Editor will open. If your assets are not located next to your executable, you can go to the Arguments tab and set `BEVY_ASSET_ROOT` to the absolute path for your project (the parent of your assets folder). The rest of the defaults should be fine.
|
||||
|
||||

|
||||

|
||||
|
||||
4. Click the play button in the top left and this should start your bevy app.
|
||||
|
||||

|
||||

|
||||
|
||||
5. Go back to Xcode and click on the Metal icon in the bottom drawer and then Capture in the following the popup menu.
|
||||
|
||||

|
||||

|
||||
|
||||
6. Start debugging and profiling!
|
||||
|
||||
@ -183,6 +188,7 @@ When you compile with Bevy's `trace_tracy` feature, GPU spans will show up in a
|
||||
|
||||
> [!NOTE]
|
||||
> Due to dynamic clock speeds, GPU timings will have large frame-to-frame variance, unless you use an external tool to lock your GPU clocks to base speeds. When measuring GPU performance via Tracy, only look at the MTPC column of Tracy's statistics panel, or the span distribution/median, and not at any individual frame data.
|
||||
|
||||
<!-- markdownlint-disable MD028 -->
|
||||
|
||||
> [!NOTE]
|
||||
|
27
release-content/release-notes/faster-zstd-option.md
Normal file
27
release-content/release-notes/faster-zstd-option.md
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
title: Faster Zstd decompression option
|
||||
authors: ["@atlv24", "@brianreavis"]
|
||||
pull_requests: [19793]
|
||||
---
|
||||
|
||||
There is now an option to use the [zstd](https://crates.io/crates/zstd) c-bindings instead of [ruzstd](https://crates.io/crates/ruzstd).
|
||||
This is less safe and portable, but can be around 44% faster.
|
||||
|
||||
The two features that control which one is used are `zstd_rust` and `zstd_c`.
|
||||
`zstd_rust` is enabled by default, but `zstd_c` takes precedence if both are enabled.
|
||||
|
||||
To enable it, add the feature to the `bevy` entry of your Cargo.toml:
|
||||
|
||||
```toml
|
||||
bevy = { version = "0.17.0", features = ["zstd_c"] }
|
||||
```
|
||||
|
||||
Note: this will still include a dependency on `ruzstd`, because mutually exclusive features are not supported by Cargo.
|
||||
To remove this dependency, disable default-features, and manually enable any default features you need:
|
||||
|
||||
```toml
|
||||
bevy = { version = "0.17.0", default-features = false, features = [
|
||||
"zstd_c",
|
||||
"bevy_render", # etc..
|
||||
] }
|
||||
```
|
10
release-content/release-notes/light-textures.md
Normal file
10
release-content/release-notes/light-textures.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Light Textures
|
||||
authors: ["@robtfm"]
|
||||
pull_requests: [18031]
|
||||
---
|
||||
|
||||
New components `PointLightTexture`, `SpotLightTexture`, and `DirectionalLightTexture` allow specifying light textures for lights, also commonly known as light cookies.
|
||||
These modulate the intensity of light cast upon surfaces for various artistic effects. See the light_textures example for usage.
|
||||
|
||||
(TODO: Embed light_textures example screenshot here)
|
Loading…
Reference in New Issue
Block a user