Ralith / openxrs

OpenXR bindings for Rust
Apache License 2.0
282 stars 59 forks source link

Uninitialized booleans w/ Qualcomm Space SDK #176

Closed xujunjie12345 closed 1 month ago

xujunjie12345 commented 1 month ago

I have made the following attempts based on ALVR 20.6.0 + OpenXR 0.17.1:

(1)Modify the debug implementation of Bool32 openxrs\sys\src\lib.rs

 impl fmt::Debug for Bool32 {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        (*self != FALSE).fmt(fmt)
+        write!(fmt, "{}", self.0)
     }
 }

(2)Add logs openxrs\openxr\src\action.rs

 pub struct Action<T: ActionTy> {
     inner: Arc<ActionInner>,
@@ -204,6 +205,8 @@ impl ActionInput for bool {
                 out.as_mut_ptr(),
             ))?;
             let out = out.assume_init();
+            info!("jie12 1   current_state :{:?} , is_active : {:?} ",out.current_state , out.is_active);
+
             Ok(ActionState {
                 current_state: out.current_state.into(),
                 changed_since_last_sync: out.changed_since_last_sync.into(),

alvr\client_openxr\src\lib.rs

@@ -405,7 +405,7 @@ pub fn update_buttons(
                 let Ok(state) = action.state(xr_session, xr::Path::NULL) else {
                     continue;
                 };
-
+                info!("jie12  path : {:?}   current_state :{:?} , is_active : {:?}",BUTTON_INFO.get(id).unwrap().path,state.current_state, state.is_active);
                 if state.changed_since_last_sync {
                     button_entries.push(ButtonEntry {
                         path_id: *id,

When I press the system button on the right controller, you can see that many buttons show random values:

         28471: 10-15 17:43:35.744  9459  9956 I [ALVR NATIVE-RUST]: jie12  path : "/user/hand/right/input/trigger/touch"   current_state :true , is_active : true
     28473: 10-15 17:43:35.744  9459  9956 I [ALVR NATIVE-RUST]: jie12 1   current_state :4284943296 , is_active : 355258728 
     28474: 10-15 17:43:35.744  9459  9956 I [ALVR NATIVE-RUST]: jie12  path : "/user/hand/left/input/menu/click"   current_state :true , is_active : true
     28476: 10-15 17:43:35.744  9459  9956 I [ALVR NATIVE-RUST]: jie12 1   current_state :4284943296 , is_active : 355258728 
     28477: 10-15 17:43:35.744  9459  9956 I [ALVR NATIVE-RUST]: jie12  path : "/user/hand/right/input/a/touch"   current_state :true , is_active : true
     28479: 10-15 17:43:35.744  9459  9956 I [ALVR NATIVE-RUST]: jie12 1   current_state :4284943296 , is_active : 355258728 
     28480: 10-15 17:43:35.744  9459  9956 I [ALVR NATIVE-RUST]: jie12  path : "/user/hand/left/input/trigger/touch"   current_state :true , is_active : true
     28482: 10-15 17:43:35.744  9459  9956 I [ALVR NATIVE-RUST]: jie12 1   current_state :4284943296 , is_active : 355258728 
     28483: 10-15 17:43:35.744  9459  9956 I [ALVR NATIVE-RUST]: jie12  path : "/user/hand/left/input/x/touch"   current_state :true , is_active : true
     28485: 10-15 17:43:35.744  9459  9956 I [ALVR NATIVE-RUST]: jie12 1   current_state :4284943296 , is_active : 355258728 
     28486: 10-15 17:43:35.744  9459  9956 I [ALVR NATIVE-RUST]: jie12  path : "/user/hand/right/input/a/click"   current_state :true , is_active : true
      。。。

When I implement the same logic using C++, this issue does not occur. Therefore, I suspect there might be compatibility issues between the Rust version of the OpenXR SDK and the Qualcomm Space SDK.

Do you have any ideas?

Ralith commented 1 month ago

Looks like the fields are uninitialized. Does this happen if you update the OpenXR loader version? Does this happen with other OpenXR runtimes? What is the C++ code you're comparing against?

xujunjie12345 commented 1 month ago

Looks like the fields are uninitialized. Does this happen if you update the OpenXR loader version? Does this happen with other OpenXR runtimes? What is the C++ code you're comparing against?

I have tried upgrading or downgrading the version of openxr_loader, as well as upgrading or downgrading the version of the OpenXR SDK, but this issue always occurs.

I do not encounter this issue with PICO. Currently, this problem only occurs with the Qualcomm Space SDK.

In other projects, I have implemented OpenXR interfaces using C++, also based on the Qualcomm Space SDK, and I do not encounter such anomalies. I have repeatedly compared the calls with those in ALVR and found no differences

Ralith commented 1 month ago

Please share the exact C++ code you're comparing against.

xujunjie12345 commented 1 month ago

Please share the exact C++ code you're comparing against.

Here is a demo where I implemented a streaming solution based on the CloudXR scheme using C++. The overall process is similar to ALVR, but the XrBool32 type does not exhibit the issue of random values

Note that this demo can only run on the Qualcomm Space platform CloudVR_Demo.zip

Ralith commented 1 month ago

Your C++ code is zero-initializing the XrActionStateBoolean structure's fields (other than type). What happens if you initialize them to some other value?

xujunjie12345 commented 1 month ago

Your C++ code is zero-initializing the XrActionStateBoolean structure's fields (other than type). What happens if you initialize them to some other value?

Following your advice, I fixed the issue with random values by modifying the initialization methods of structures like ActionStatePose and ActionStateBoolean in action.rs.

It seems that the Qualcomm Space SDK does not initialize these structures under certain conditions.

The modifications are as follows:

--- a/openxr/src/action.rs
+++ b/openxr/src/action.rs
@@ -1,6 +1,7 @@
 use std::{marker::PhantomData, ptr, sync::Arc};

 use crate::*;
+use log::info;

 pub struct Action<T: ActionTy> {
     inner: Arc<ActionInner>,
@@ -109,15 +110,21 @@ impl Action<Posef> {
             subaction_path,
         };
         let out = unsafe {
-            let mut out = sys::ActionStatePose::out(ptr::null_mut());
+            //let mut out = sys::ActionStatePose::out(ptr::null_mut());
+            let mut out = sys::ActionStatePose{
+                is_active: sys::FALSE,
+                ty: sys::ActionStatePose::TYPE,
+                next: ptr::null_mut(),
+            };
             cvt((self.fp().get_action_state_pose)(
                 session.as_raw(),
                 &info,
-                out.as_mut_ptr(),
+                &mut out as *mut _,
             ))?;
-            out.assume_init()
+            //out.assume_init()
+            out.is_active.into()
         };
-        Ok(out.is_active.into())
+        Ok(out)
     }
 }

@@ -197,13 +204,26 @@ impl ActionInput for bool {
             subaction_path,
         };
         unsafe {
-            let mut out = sys::ActionStateBoolean::out(ptr::null_mut());
+           // let mut out = sys::ActionStateBoolean::out(ptr::null_mut());
+
+           let mut out = sys::ActionStateBoolean {
+                 current_state: sys::FALSE,
+                 changed_since_last_sync:sys::FALSE,
+                 last_change_time: sys::Time::from_nanos(0),
+                 is_active: sys::FALSE,
+                 ty: sys::ActionStateBoolean::TYPE,
+                 next: ptr::null_mut(),
+           };
+            info!("jie12 ---------------   current_state :{:?} , is_active : {:?} ",out.current_state , out.is_active);
+
             cvt((action.fp().get_action_state_boolean)(
                 session.as_raw(),
                 &info,
-                out.as_mut_ptr(),
+                &mut out as *mut _,
             ))?;
-            let out = out.assume_init();
+            //let out = out.assume_init();
+            info!("jie12 1   current_state :{:?} , is_active : {:?} ",out.current_state , out.is_active);
+
             Ok(ActionState {
                 current_state: out.current_state.into(),
                 changed_since_last_sync: out.changed_since_last_sync.into(),
@@ -231,13 +251,21 @@ impl ActionInput for f32 {
             subaction_path,
         };
         unsafe {
-            let mut out = sys::ActionStateFloat::out(ptr::null_mut());
+           // let mut out = sys::ActionStateFloat::out(ptr::null_mut());
+           let mut out = sys::ActionStateFloat{
+                current_state: 0.0,
+                changed_since_last_sync:sys::FALSE,
+                last_change_time: sys::Time::from_nanos(0),
+                is_active: sys::FALSE,
+                ty: sys::ActionStateFloat::TYPE,
+                next: ptr::null_mut(),
+           };
             cvt((action.fp().get_action_state_float)(
                 session.as_raw(),
                 &info,
-                out.as_mut_ptr(),
+                &mut out as *mut _,
             ))?;
-            let out = out.assume_init();
+           // let out = out.assume_init();
             Ok(ActionState {
                 current_state: out.current_state,
                 changed_since_last_sync: out.changed_since_last_sync.into(),
@@ -265,13 +293,21 @@ impl ActionInput for Vector2f {
             subaction_path,
         };
         unsafe {
-            let mut out = sys::ActionStateVector2f::out(ptr::null_mut());
+            //let mut out = sys::ActionStateVector2f::out(ptr::null_mut());
+            let mut out = sys::ActionStateVector2f{
+                current_state:Vector2f{x:0.0,y:0.0},
+                changed_since_last_sync:sys::FALSE,
+                last_change_time: sys::Time::from_nanos(0),
+                is_active: sys::FALSE,
+                ty: sys::ActionStateVector2f::TYPE,
+                next: ptr::null_mut(),
+            };
             cvt((action.fp().get_action_state_vector2f)(
                 session.as_raw(),
                 &info,
-                out.as_mut_ptr(),
+                &mut out as *mut _,
             ))?;
-            let out = out.assume_init();
+            //let out = out.assume_init();
             Ok(ActionState {
                 current_state: out.current_state,
                 changed_since_last_sync: out.changed_since_last_sync.into(),
xujunjie12345 commented 1 month ago

However, unfortunately, this modification did not completely resolve the compatibility issues with the Qualcomm Space SDK. When enabling XR_EXT_hand_tracking, it still results in errors.

Do you have any other suggestions regarding this issue?

XR_ERROR_PATH_UNSUPPORTED: xrGetActionStateFloat(getInfo->subactionPath == '/user/hand/left') the subaction path was not specified at action creation

Ralith commented 1 month ago

It seems that the Qualcomm Space SDK does not initialize these structures under certain conditions.

This sounds like a conformance bug in the vendor's OpenXR implementation, then. Please report it to them.

Do you have any other suggestions regarding this issue?

Did you specify that subaction path when creating the action?