chore: bump openxr crate version

Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
Schmarni
2026-02-12 06:51:20 +01:00
parent 728581d8d7
commit 18879e9f06
10 changed files with 409 additions and 458 deletions

490
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -32,7 +32,7 @@ bevy_platform = { version = "0.18", default-features = false }
bevy_mod_xr = { path = "crates/bevy_xr", version = "0.4.0" } bevy_mod_xr = { path = "crates/bevy_xr", version = "0.4.0" }
bevy_mod_openxr = { path = "crates/bevy_openxr", version = "0.4.0" } bevy_mod_openxr = { path = "crates/bevy_openxr", version = "0.4.0" }
bevy_xr_utils = { path = "crates/bevy_xr_utils", version = "0.4.0" } bevy_xr_utils = { path = "crates/bevy_xr_utils", version = "0.4.0" }
openxr = "0.19.0" openxr = "0.21.1"
thiserror = "2.0.3" thiserror = "2.0.3"
wgpu = "27" wgpu = "27"
wgpu-hal = "27" wgpu-hal = "27"

View File

@@ -1,5 +1,11 @@
use std::{
ffi::CStr,
ops::{BitAnd, BitOr},
};
use bevy_derive::{Deref, DerefMut}; use bevy_derive::{Deref, DerefMut};
use bevy_ecs::resource::Resource; use bevy_ecs::resource::Resource;
use bevy_log::error;
use openxr::ExtensionSet; use openxr::ExtensionSet;
#[derive(Clone, Debug, Eq, PartialEq, Deref, DerefMut, Resource)] #[derive(Clone, Debug, Eq, PartialEq, Deref, DerefMut, Resource)]
@@ -36,7 +42,47 @@ impl OxrExtensions {
} }
/// returns true if all of the extensions enabled are also available in `available_exts` /// returns true if all of the extensions enabled are also available in `available_exts`
pub fn is_available(&self, available_exts: &OxrExtensions) -> bool { pub fn is_available(&self, available_exts: &OxrExtensions) -> bool {
self.clone() & available_exts.clone() == *self self.0.intersection(&available_exts) == self.0
}
/// Returns any extensions needed by `required_exts` that aren't available in `self`
pub fn unavailable_exts(&self, required_exts: &Self) -> Vec<String> {
required_exts
.difference(&self)
.names()
.into_iter()
.filter_map(|v| {
CStr::from_bytes_with_nul(v)
.inspect_err(|err| error!("failed to convert openxr ext name to CStr: {err}"))
.ok()
})
.filter_map(|v| {
v.to_str()
.inspect_err(|err| error!("openxr ext name is not valid utf8: {err}"))
.ok()
})
.map(|v| v.to_string())
.collect()
}
}
impl BitOr for OxrExtensions {
type Output = Self;
// this is horribly slow, but doesn't require a bunch of code duplication
fn bitor(self, rhs: Self) -> Self::Output {
Self(
self.0
.names()
.into_iter()
.chain(rhs.names().into_iter())
.collect(),
)
}
}
impl BitAnd for OxrExtensions {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
Self(self.intersection(&rhs))
} }
} }
impl From<ExtensionSet> for OxrExtensions { impl From<ExtensionSet> for OxrExtensions {
@@ -56,293 +102,3 @@ impl Default for OxrExtensions {
Self(exts) Self(exts)
} }
} }
macro_rules! unavailable_exts {
(
$exts:ty;
$(
$(
#[$meta:meta]
)*
$ident:ident
),*
$(,)?
) => {
impl $exts {
/// Returns any extensions needed by `required_exts` that aren't available in `self`
pub fn unavailable_exts(&self, required_exts: &Self) -> Vec<std::borrow::Cow<'static, str>> {
let mut exts = vec![];
$(
$(
#[$meta]
)*
if required_exts.0.$ident && !self.0.$ident {
exts.push(std::borrow::Cow::Borrowed(stringify!($ident)))
}
)*
for ext in required_exts.0.other.iter() {
if !self.0.other.contains(ext) {
exts.push(std::borrow::Cow::Owned(ext.clone()))
}
}
exts
}
}
};
}
macro_rules! bitor {
(
$exts:ty;
$(
$(
#[$meta:meta]
)*
$ident:ident
),*
$(,)?
) => {
impl std::ops::BitOr for $exts {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
let mut out = ExtensionSet::default();
$(
$(
#[$meta]
)*
{
out.$ident = self.0.$ident || rhs.0.$ident;
}
)*
out.other = self.0.other;
for ext in rhs.0.other {
if !out.other.contains(&ext) {
out.other.push(ext);
}
}
Self(out)
}
}
};
}
macro_rules! bitand {
(
$exts:ty;
$(
$(
#[$meta:meta]
)*
$ident:ident
),*
$(,)?
) => {
impl std::ops::BitAnd for $exts {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
let mut out = ExtensionSet::default();
$(
$(
#[$meta]
)*
{
out.$ident = self.0.$ident && rhs.0.$ident;
}
)*
for ext in self.0.other {
if rhs.0.other.contains(&ext) {
out.other.push(ext);
}
}
Self(out)
}
}
};
}
macro_rules! impl_ext {
(
$(
$macro:ident
),*
) => {
$(
$macro! {
OxrExtensions;
almalence_digital_lens_control,
bd_controller_interaction,
epic_view_configuration_fov,
ext_performance_settings,
ext_thermal_query,
ext_debug_utils,
ext_eye_gaze_interaction,
ext_view_configuration_depth_range,
ext_conformance_automation,
ext_hand_tracking,
#[cfg(windows)]
ext_win32_appcontainer_compatible,
ext_dpad_binding,
ext_hand_joints_motion_range,
ext_samsung_odyssey_controller,
ext_hp_mixed_reality_controller,
ext_palm_pose,
ext_uuid,
ext_hand_interaction,
ext_active_action_set_priority,
ext_local_floor,
ext_hand_tracking_data_source,
ext_plane_detection,
ext_future,
ext_user_presence,
fb_composition_layer_image_layout,
fb_composition_layer_alpha_blend,
#[cfg(target_os = "android")]
fb_android_surface_swapchain_create,
fb_swapchain_update_state,
fb_composition_layer_secure_content,
fb_body_tracking,
fb_display_refresh_rate,
fb_color_space,
fb_hand_tracking_mesh,
fb_hand_tracking_aim,
fb_hand_tracking_capsules,
fb_spatial_entity,
fb_foveation,
fb_foveation_configuration,
fb_keyboard_tracking,
fb_triangle_mesh,
fb_passthrough,
fb_render_model,
fb_spatial_entity_query,
fb_spatial_entity_storage,
fb_foveation_vulkan,
#[cfg(target_os = "android")]
fb_swapchain_update_state_android_surface,
fb_swapchain_update_state_opengl_es,
fb_swapchain_update_state_vulkan,
fb_touch_controller_pro,
fb_spatial_entity_sharing,
fb_space_warp,
fb_haptic_amplitude_envelope,
fb_scene,
fb_scene_capture,
fb_spatial_entity_container,
fb_face_tracking,
fb_eye_tracking_social,
fb_passthrough_keyboard_hands,
fb_composition_layer_settings,
fb_touch_controller_proximity,
fb_haptic_pcm,
fb_composition_layer_depth_test,
fb_spatial_entity_storage_batch,
fb_spatial_entity_user,
fb_face_tracking2,
htc_vive_cosmos_controller_interaction,
htc_facial_tracking,
htc_vive_focus3_controller_interaction,
htc_hand_interaction,
htc_vive_wrist_tracker_interaction,
htc_passthrough,
htc_foveation,
htc_anchor,
huawei_controller_interaction,
#[cfg(target_os = "android")]
khr_android_thread_settings,
#[cfg(target_os = "android")]
khr_android_surface_swapchain,
khr_composition_layer_cube,
#[cfg(target_os = "android")]
khr_android_create_instance,
khr_composition_layer_depth,
khr_vulkan_swapchain_format_list,
khr_composition_layer_cylinder,
khr_composition_layer_equirect,
khr_opengl_enable,
khr_opengl_es_enable,
khr_vulkan_enable,
#[cfg(windows)]
khr_d3d11_enable,
#[cfg(windows)]
khr_d3d12_enable,
khr_visibility_mask,
khr_composition_layer_color_scale_bias,
#[cfg(windows)]
khr_win32_convert_performance_counter_time,
khr_convert_timespec_time,
khr_loader_init,
#[cfg(target_os = "android")]
khr_loader_init_android,
khr_vulkan_enable2,
khr_composition_layer_equirect2,
khr_binding_modification,
khr_swapchain_usage_input_attachment_bit,
khr_locate_spaces,
khr_maintenance1,
meta_foveation_eye_tracked,
meta_local_dimming,
meta_passthrough_preferences,
meta_virtual_keyboard,
meta_vulkan_swapchain_create_info,
meta_performance_metrics,
meta_headset_id,
meta_recommended_layer_resolution,
meta_passthrough_color_lut,
meta_spatial_entity_mesh,
meta_automatic_layer_filter,
meta_touch_controller_plus,
meta_environment_depth,
ml_ml2_controller_interaction,
ml_frame_end_info,
ml_global_dimmer,
ml_compat,
ml_marker_understanding,
ml_localization_map,
ml_user_calibration,
mnd_headless,
mnd_swapchain_usage_input_attachment_bit,
msft_unbounded_reference_space,
msft_spatial_anchor,
msft_spatial_graph_bridge,
msft_hand_interaction,
msft_hand_tracking_mesh,
msft_secondary_view_configuration,
msft_first_person_observer,
msft_controller_model,
#[cfg(windows)]
msft_perception_anchor_interop,
#[cfg(windows)]
msft_holographic_window_attachment,
msft_composition_layer_reprojection,
msft_spatial_anchor_persistence,
#[cfg(target_os = "android")]
oculus_android_session_state_enable,
oculus_audio_device_guid,
oculus_external_camera,
oppo_controller_interaction,
qcom_tracking_optimization_settings,
ultraleap_hand_tracking_forearm,
valve_analog_threshold,
varjo_quad_views,
varjo_foveated_rendering,
varjo_composition_layer_depth_test,
varjo_environment_depth_estimation,
varjo_marker_tracking,
varjo_view_offset,
varjo_xr4_controller_interaction,
yvr_controller_interaction,
extx_overlay,
mndx_egl_enable,
mndx_force_feedback_curl,
htcx_vive_tracker_interaction,
}
)*
};
}
impl_ext!(bitor, bitand, unavailable_exts);

View File

@@ -69,7 +69,7 @@ pub fn insert_passthrough(world: &mut World) {
pub fn resume_passthrough( pub fn resume_passthrough(
passthrough: Res<OxrPassthrough>, passthrough: Res<OxrPassthrough>,
passthrough_layer: Res<OxrPassthroughLayer>, passthrough_layer: Res<OxrPassthroughLayerFB>,
) { ) {
passthrough.start().unwrap(); passthrough.start().unwrap();
passthrough_layer.resume().unwrap(); passthrough_layer.resume().unwrap();
@@ -77,7 +77,7 @@ pub fn resume_passthrough(
pub fn pause_passthrough( pub fn pause_passthrough(
passthrough: Res<OxrPassthrough>, passthrough: Res<OxrPassthrough>,
passthrough_layer: Res<OxrPassthroughLayer>, passthrough_layer: Res<OxrPassthroughLayerFB>,
) { ) {
passthrough_layer.pause().unwrap(); passthrough_layer.pause().unwrap();
passthrough.pause().unwrap(); passthrough.pause().unwrap();
@@ -87,7 +87,7 @@ pub fn create_passthrough(
session: &OxrSession, session: &OxrSession,
flags: openxr::PassthroughFlagsFB, flags: openxr::PassthroughFlagsFB,
purpose: openxr::PassthroughLayerPurposeFB, purpose: openxr::PassthroughLayerPurposeFB,
) -> OxrResult<(OxrPassthrough, OxrPassthroughLayer)> { ) -> OxrResult<(OxrPassthrough, OxrPassthroughLayerFB)> {
let passthrough = session.create_passthrough(flags)?; let passthrough = session.create_passthrough(flags)?;
let passthrough_layer = session.create_passthrough_layer(&passthrough, purpose)?; let passthrough_layer = session.create_passthrough_layer(&passthrough, purpose)?;

View File

@@ -4,6 +4,7 @@ use std::str::FromStr;
use ash::vk::{self, Handle}; use ash::vk::{self, Handle};
use bevy_log::{debug, error}; use bevy_log::{debug, error};
use bevy_math::UVec2; use bevy_math::UVec2;
use openxr::sys::Handle as _;
use openxr::{Version, sys}; use openxr::{Version, sys};
use wgpu::TextureUses; use wgpu::TextureUses;
use wgpu::{ExperimentalFeatures, InstanceFlags, MemoryBudgetThresholds}; use wgpu::{ExperimentalFeatures, InstanceFlags, MemoryBudgetThresholds};

View File

@@ -65,8 +65,8 @@ impl LayerProvider for ProjectionLayer {
impl LayerProvider for PassthroughLayer { impl LayerProvider for PassthroughLayer {
fn get(&self, world: &World) -> Option<Box<dyn CompositionLayer<'_>>> { fn get(&self, world: &World) -> Option<Box<dyn CompositionLayer<'_>>> {
Some(Box::new( Some(Box::new(
CompositionLayerPassthrough::new() CompositionLayerPassthroughFB::new()
.layer_handle(world.get_resource::<OxrPassthroughLayer>()?) .layer_handle(world.get_resource::<OxrPassthroughLayerFB>()?)
.layer_flags(CompositionLayerFlags::BLEND_TEXTURE_SOURCE_ALPHA), .layer_flags(CompositionLayerFlags::BLEND_TEXTURE_SOURCE_ALPHA),
)) ))
} }
@@ -236,16 +236,16 @@ impl Default for CompositionLayerProjection<'_> {
Self::new() Self::new()
} }
} }
pub struct CompositionLayerPassthrough { pub struct CompositionLayerPassthroughFB {
inner: sys::CompositionLayerPassthroughFB, inner: sys::CompositionLayerPassthroughFB,
} }
impl Default for CompositionLayerPassthrough { impl Default for CompositionLayerPassthroughFB {
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()
} }
} }
impl CompositionLayerPassthrough { impl CompositionLayerPassthroughFB {
#[inline] #[inline]
pub const fn new() -> Self { pub const fn new() -> Self {
Self { Self {
@@ -256,7 +256,7 @@ impl CompositionLayerPassthrough {
} }
} }
#[inline] #[inline]
pub fn layer_handle(mut self, layer_handle: &OxrPassthroughLayer) -> Self { pub fn layer_handle(mut self, layer_handle: &OxrPassthroughLayerFB) -> Self {
self.inner.layer_handle = *layer_handle.inner(); self.inner.layer_handle = *layer_handle.inner();
self self
} }
@@ -266,7 +266,7 @@ impl CompositionLayerPassthrough {
self self
} }
} }
unsafe impl<'a> CompositionLayer<'a> for CompositionLayerPassthrough { unsafe impl<'a> CompositionLayer<'a> for CompositionLayerPassthroughFB {
fn swapchain(&self) -> Option<&'a OxrSwapchain> { fn swapchain(&self) -> Option<&'a OxrSwapchain> {
None None
} }

View File

@@ -322,11 +322,11 @@ impl OxrPassthrough {
/// Wrapper around [`openxr::Passthrough`]. /// Wrapper around [`openxr::Passthrough`].
/// ///
/// Used to create a [`CompositionLayerPassthrough`](crate::layer_builder::CompositionLayerPassthrough), and to [`pause`](openxr::PassthroughLayer::pause) or [`resume`](openxr::PassthroughLayer::resume) rendering of the passthrough layer. /// Used to create a [`CompositionLayerPassthrough`](crate::layer_builder::CompositionLayerPassthrough), and to [`pause`](openxr::PassthroughLayerFB::pause) or [`resume`](openxr::PassthroughLayerFB::resume) rendering of the passthrough layer.
/// ///
/// See [`openxr::PassthroughLayer`] for available methods. /// See [`openxr::PassthroughLayerFB`] for available methods.
#[derive(Resource, Deref, DerefMut)] #[derive(Resource, Deref, DerefMut)]
pub struct OxrPassthroughLayer(pub openxr::PassthroughLayer); pub struct OxrPassthroughLayerFB(pub openxr::PassthroughLayerFB);
#[derive(Resource, Deref, DerefMut, Default)] #[derive(Resource, Deref, DerefMut, Default)]
pub struct OxrRenderLayers(pub Vec<Box<dyn LayerProvider + Send + Sync>>); pub struct OxrRenderLayers(pub Vec<Box<dyn LayerProvider + Send + Sync>>);

View File

@@ -1,7 +1,7 @@
use std::ffi::c_void; use std::ffi::c_void;
use crate::next_chain::{OxrNextChain, OxrNextChainStructBase, OxrNextChainStructProvider}; use crate::next_chain::{OxrNextChain, OxrNextChainStructBase, OxrNextChainStructProvider};
use crate::resources::{OxrPassthrough, OxrPassthroughLayer, OxrSwapchain}; use crate::resources::{OxrPassthrough, OxrPassthroughLayerFB, OxrSwapchain};
use crate::types::{Result, SwapchainCreateInfo}; use crate::types::{Result, SwapchainCreateInfo};
use bevy_derive::Deref; use bevy_derive::Deref;
use bevy_ecs::resource::Resource; use bevy_ecs::resource::Resource;
@@ -91,8 +91,8 @@ impl OxrSession {
&self, &self,
passthrough: &OxrPassthrough, passthrough: &OxrPassthrough,
purpose: openxr::PassthroughLayerPurposeFB, purpose: openxr::PassthroughLayerPurposeFB,
) -> Result<OxrPassthroughLayer> { ) -> Result<OxrPassthroughLayerFB> {
Ok(OxrPassthroughLayer(graphics_match! { Ok(OxrPassthroughLayerFB(graphics_match! {
&self.1; &self.1;
session => session.create_passthrough_layer(&passthrough.0, passthrough.1, purpose)? session => session.create_passthrough_layer(&passthrough.0, passthrough.1, purpose)?
})) }))

View File

@@ -19,7 +19,7 @@ use bevy_platform::collections::hash_set::HashSet;
use bevy_transform::components::Transform; use bevy_transform::components::Transform;
use openxr::{ use openxr::{
HAND_JOINT_COUNT, HandJointLocation, HandJointLocations, HandJointVelocities, HAND_JOINT_COUNT, HandJointLocation, HandJointLocations, HandJointVelocities,
HandJointVelocity, ReferenceSpaceType, SpaceLocationFlags, SpaceVelocityFlags, sys, HandJointVelocity, ReferenceSpaceType, SpaceLocationFlags, SpaceVelocityFlags, sys::{self, Handle as _},
}; };
use std::{mem::MaybeUninit, ptr, sync::Mutex}; use std::{mem::MaybeUninit, ptr, sync::Mutex};

View File

@@ -26,7 +26,7 @@ bevy.workspace = true
[target.'cfg(not(target_family = "wasm"))'.dependencies] [target.'cfg(not(target_family = "wasm"))'.dependencies]
openxr.workspace = true openxr.workspace = true
openxr_mndx_xdev_space = "0.1.0" openxr_mndx_xdev_space = "0.2.0"
[lints.clippy] [lints.clippy]
too_many_arguments = "allow" too_many_arguments = "allow"