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

Fix depth_bias and build errors on less capable platforms #17079

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

nandee95
Copy link

@nandee95 nandee95 commented Jan 1, 2025

Objective

  • I'm compiling (parts of) bevy for an embedded platform with no 64bit atomic and ctrlc handler support. Some compilation errors came up. This PR contains the fixes for those.
  • Fix depth_bias casting in PBR material (Fixes depth_bias is ignored on StandardMaterial #14169)
    • Negative depth_bias values were casted to 0 before this PR
    • f32::INFINITY depth_bias value was casted to -1 before this PR

Solutions

  • Restrict 64bit atomic reflection to supported platforms
  • Restrict ctrlc handler to supported platforms (linux, windows or macos instead of "not wasm")
  • The depth bias value (f32) is first casted to i32 then u64 in order to preserve negative values

Testing

  • This version compiles on a platform with no 64bit atomic support, and no ctrlc support
  • CtrlC handler still works on Linux and Windows (I can't test on Macos)
  • depth_bias:
println!("{}",f32::INFINITY as u64 as i32); // Prints: -1 (old implementation)
println!("{}",f32::INFINITY as i32 as u64 as i32); // Prints: 2147483647 (expected, new implementation)

Also ran a modified version of 3d_scene example with the following results:

RED cube depth_bias: -1000.0
BLUE cube depth_bias: 0.0
image

RED cube depth_bias: -INF
BLUE cube depth_bias: 0.0
image

RED cube depth_bias: INF (case reported in #14169)
BLUE cube depth_bias: 0.0
(Im not completely sure whats going on with the shadows here, it seems like depth_bias has some affect to those aswell, if this is unintentional this issue was not introduced by this PR)
image

Copy link
Contributor

github-actions bot commented Jan 1, 2025

Welcome, new contributor!

Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨

@alice-i-cecile alice-i-cecile added C-Bug An unexpected or incorrect behavior A-Rendering Drawing game state to the screen S-Needs-Review Needs reviewer attention (from anyone!) to move forward O-Embedded Weird hardware and no_std platforms labels Jan 1, 2025
@BD103
Copy link
Member

BD103 commented Jan 2, 2025

Out of curiosity, which platform + OS were you compiling for?

@nandee95
Copy link
Author

nandee95 commented Jan 2, 2025

ESP32 microcontroller. It runs FreeRTOS and have a compatibility layer for std.
https://docs.esp-rs.org/book/overview/using-the-standard-library.html

The compiler target_os config is the following:

#[cfg(target_os = "espidf")]

I don't think bevy should have any traces of this platform thats why I thought its a better idea to just specify the OSes that actually have support for ctrlc.

@@ -1238,7 +1238,7 @@ impl From<&StandardMaterial> for StandardMaterialKey {
}

key.insert(StandardMaterialKey::from_bits_retain(
(material.depth_bias as u64) << STANDARD_MATERIAL_KEY_DEPTH_BIAS_SHIFT,
(material.depth_bias as i32 as u64) << STANDARD_MATERIAL_KEY_DEPTH_BIAS_SHIFT,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this correct?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The depth_bias is actually stored as an i32 past this step, the i32 value will go to wgpu. Casting from f32 to an unsigned will cause it to lose its value when its negative and will not work well with i32 out of range values(e.g. f32::INFINITY). If we cast to i32 first, it will then cast to u64 it will retain the full range of i32 and will be passed to wgpu correctly.

I also made you a small demo here to better understand the casting (left os old behaviour, right is new):
https://godbolt.org/z/d94h7nfYT

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment describing this? I'm fine if it's even just copy pasted from what you just wrote. It's not immediately obvious otherwise.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave it some thought. I wouldn't copy my previous comment as is since it was made in the context of the current issue which may cause more confusion to a future contributor.
Instead I explained why the double casting is necessary to make sure its not removed accidentally by someone else:

           // Casting to i32 first to ensure the full i32 range is preserved.
           // (wgpu expects the depth_bias as an i32 when this is extracted in a later step)

Copy link
Member

@BD103 BD103 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ctrlc and reflection feature gate look fine, given all the platforms supported by ctrlc are supported by us. I'm not sure I completely understand the as i32 as u64 casting, so @pcwalton I would appreciate your eyes on it!

@@ -93,7 +93,7 @@ portable-atomic-util = { version = "0.2.4", features = [
"alloc",
], optional = true }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
[target.'cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))'.dependencies]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this work for all platforms supported by ctrlc? Looks like they use #[cfg(unix)] and #[cfg(windows)]:

#[cfg(unix)]
mod unix;

#[cfg(windows)]
mod windows;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically, are there platforms that are #[cfg(unix)] that are not Linux or MacOS that we should worry about?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We support FreeBSD and there are others like TvOS we could support.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed all occurrences from

cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))

to

cfg(any(unix, windows))

Re-tested on Windows and Linux and CtrlC handler still works.

@BenjaminBrienen BenjaminBrienen added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it D-Straightforward Simple bug fixes and API improvements, docs, test and examples and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jan 4, 2025
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-Bug An unexpected or incorrect behavior D-Straightforward Simple bug fixes and API improvements, docs, test and examples O-Embedded Weird hardware and no_std platforms S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

depth_bias is ignored on StandardMaterial
5 participants