mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Evaluate gfx_select's #[cfg] conditions at the right time. (#3253)
See the comments in the code for details.
This commit is contained in:
@@ -120,6 +120,7 @@ Additionally `Surface::get_default_config` now returns an Option and returns Non
|
||||
- Fix an integer overflow in `queue_write_texture` by @nical in (#3146)[https://github.com/gfx-rs/wgpu/pull/3146]
|
||||
- Make `RenderPassCompatibilityError` and `CreateShaderModuleError` not so huge. By @jimblandy in (#3226)[https://github.com/gfx-rs/wgpu/pull/3226]
|
||||
- Check for invalid bitflag bits in wgpu-core and allow them to be captured/replayed by @nical in (#3229)[https://github.com/gfx-rs/wgpu/pull/3229]
|
||||
- Evaluate `gfx_select!`'s `#[cfg]` conditions at the right time. By @jimblandy in [#3253](https://github.com/gfx-rs/wgpu/pull/3253)
|
||||
|
||||
#### WebGPU
|
||||
|
||||
|
||||
@@ -243,6 +243,101 @@ If you are running this program on native and not in a browser and wish to work
|
||||
Adapter::downlevel_properties or Device::downlevel_properties to get a listing of the features the current \
|
||||
platform supports.";
|
||||
|
||||
// #[cfg] attributes in exported macros are interesting!
|
||||
//
|
||||
// The #[cfg] conditions in a macro's expansion are evaluated using the
|
||||
// configuration options (features, target architecture and os, etc.) in force
|
||||
// where the macro is *used*, not where it is *defined*. That is, if crate A
|
||||
// defines a macro like this:
|
||||
//
|
||||
// #[macro_export]
|
||||
// macro_rules! if_bleep {
|
||||
// { } => {
|
||||
// #[cfg(feature = "bleep")]
|
||||
// bleep();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// and then crate B uses it like this:
|
||||
//
|
||||
// fn f() {
|
||||
// if_bleep! { }
|
||||
// }
|
||||
//
|
||||
// then it is crate B's `"bleep"` feature, not crate A's, that determines
|
||||
// whether the macro expands to a function call or an empty statement. The
|
||||
// entire configuration predicate is evaluated in the use's context, not the
|
||||
// definition's.
|
||||
//
|
||||
// Since `wgpu-core` selects back ends using features, we need to make sure the
|
||||
// arms of the `gfx_select!` macro are pruned according to `wgpu-core`'s
|
||||
// features, not those of whatever crate happens to be using `gfx_select!`. This
|
||||
// means we can't use `#[cfg]` attributes in `gfx_select!`s definition itself.
|
||||
// Instead, for each backend, `gfx_select!` must use a macro whose definition is
|
||||
// selected by `#[cfg]` in `wgpu-core`. The configuration predicate is still
|
||||
// evaluated when the macro is used; we've just moved the `#[cfg]` into a macro
|
||||
// used by `wgpu-core` itself.
|
||||
|
||||
/// Define an exported macro named `$public` that expands to a call if the
|
||||
/// configuration predicate `$condition` is true, or to a panic otherwise.
|
||||
///
|
||||
/// Because of odd technical limitations on exporting macros expanded by other
|
||||
/// macros, you must supply both a public-facing name for the macro and a
|
||||
/// private name, which is never used outside this macro. For details:
|
||||
/// <https://github.com/rust-lang/rust/pull/52234#issuecomment-976702997>
|
||||
macro_rules! define_backend_caller {
|
||||
{ $public:ident, $private:ident if $condition:meta } => {
|
||||
#[cfg( $condition )]
|
||||
#[macro_export]
|
||||
macro_rules! $private {
|
||||
( $backend:literal, $call:expr ) => ( $call )
|
||||
}
|
||||
|
||||
#[cfg(not( $condition ))]
|
||||
#[macro_export]
|
||||
macro_rules! $private {
|
||||
( $backend:literal, $call:expr ) => (
|
||||
panic!("Unexpected backend {:?}", $backend)
|
||||
)
|
||||
}
|
||||
|
||||
// See note about rust-lang#52234 above.
|
||||
#[doc(hidden)] pub use $private as $public;
|
||||
}
|
||||
}
|
||||
|
||||
define_backend_caller! {
|
||||
gfx_if_vulkan, gfx_if_vulkan_hidden
|
||||
if any(
|
||||
all(not(target_arch = "wasm32"), not(target_os = "ios"), not(target_os = "macos")),
|
||||
feature = "vulkan-portability"
|
||||
)
|
||||
}
|
||||
|
||||
define_backend_caller! {
|
||||
gfx_if_metal, gfx_if_metal_hidden
|
||||
if all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos"))
|
||||
}
|
||||
|
||||
define_backend_caller! {
|
||||
gfx_if_dx12, gfx_if_dx12_hidden
|
||||
if all(not(target_arch = "wasm32"), windows)
|
||||
}
|
||||
|
||||
define_backend_caller! {
|
||||
gfx_if_dx11, gfx_if_dx11_hidden
|
||||
if all(not(target_arch = "wasm32"), windows)
|
||||
}
|
||||
|
||||
define_backend_caller! {
|
||||
gfx_if_gles, gfx_if_gles_hidden
|
||||
if any(
|
||||
all(unix, not(target_os = "macos"), not(target_os = "ios")),
|
||||
feature = "angle",
|
||||
target_arch = "wasm32"
|
||||
)
|
||||
}
|
||||
|
||||
/// Dispatch on an [`Id`]'s backend to a backend-generic method.
|
||||
///
|
||||
/// Uses of this macro have the form:
|
||||
@@ -291,29 +386,13 @@ platform supports.";
|
||||
#[macro_export]
|
||||
macro_rules! gfx_select {
|
||||
($id:expr => $global:ident.$method:ident( $($param:expr),* )) => {
|
||||
// Note: For some reason the cfg aliases defined in build.rs
|
||||
// don't succesfully apply in this macro so we must specify
|
||||
// their equivalents manually.
|
||||
match $id.backend() {
|
||||
#[cfg(any(
|
||||
all(not(target_arch = "wasm32"), not(target_os = "ios"), not(target_os = "macos")),
|
||||
feature = "vulkan-portability"
|
||||
))]
|
||||
wgt::Backend::Vulkan => $global.$method::<$crate::api::Vulkan>( $($param),* ),
|
||||
#[cfg(all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")))]
|
||||
wgt::Backend::Metal => $global.$method::<$crate::api::Metal>( $($param),* ),
|
||||
#[cfg(all(not(target_arch = "wasm32"), windows))]
|
||||
wgt::Backend::Dx12 => $global.$method::<$crate::api::Dx12>( $($param),* ),
|
||||
#[cfg(all(not(target_arch = "wasm32"), windows))]
|
||||
wgt::Backend::Dx11 => $global.$method::<$crate::api::Dx11>( $($param),* ),
|
||||
#[cfg(any(
|
||||
all(unix, not(target_os = "macos"), not(target_os = "ios")),
|
||||
feature = "angle",
|
||||
target_arch = "wasm32"
|
||||
))]
|
||||
wgt::Backend::Gl => $global.$method::<$crate::api::Gles>( $($param),+ ),
|
||||
wgt::Backend::Vulkan => $crate::gfx_if_vulkan!("Vulkan", $global.$method::<$crate::api::Vulkan>( $($param),* )),
|
||||
wgt::Backend::Metal => $crate::gfx_if_metal!("Metal", $global.$method::<$crate::api::Metal>( $($param),* )),
|
||||
wgt::Backend::Dx12 => $crate::gfx_if_dx12!("Dx12", $global.$method::<$crate::api::Dx12>( $($param),* )),
|
||||
wgt::Backend::Dx11 => $crate::gfx_if_dx11!("Dx11", $global.$method::<$crate::api::Dx11>( $($param),* )),
|
||||
wgt::Backend::Gl => $crate::gfx_if_gles!("Gles", $global.$method::<$crate::api::Gles>( $($param),+ )),
|
||||
other => panic!("Unexpected backend {:?}", other),
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user