Merge pull request #125 from Schmarni-Dev/next_chain_sessions

Implement next pointer chain for xrCreateSession
This commit is contained in:
Schmarni
2024-06-25 19:42:47 +02:00
committed by GitHub
6 changed files with 134 additions and 5 deletions

View File

@@ -6,8 +6,9 @@ pub mod vulkan;
use std::any::TypeId; use std::any::TypeId;
use bevy::math::UVec2; use bevy::math::UVec2;
use openxr::{FrameStream, FrameWaiter, Session};
use crate::types::{AppInfo, OxrExtensions, Result, WgpuGraphics}; use crate::{session::OxrSessionCreateNextChain, types::{AppInfo, OxrExtensions, Result, WgpuGraphics}};
/// This is an extension trait to the [`Graphics`](openxr::Graphics) trait and is how the graphics API should be interacted with. /// This is an extension trait to the [`Graphics`](openxr::Graphics) trait and is how the graphics API should be interacted with.
pub unsafe trait GraphicsExt: openxr::Graphics { pub unsafe trait GraphicsExt: openxr::Graphics {
@@ -36,6 +37,12 @@ pub unsafe trait GraphicsExt: openxr::Graphics {
instance: &openxr::Instance, instance: &openxr::Instance,
system_id: openxr::SystemId, system_id: openxr::SystemId,
) -> Result<(WgpuGraphics, Self::SessionCreateInfo)>; ) -> Result<(WgpuGraphics, Self::SessionCreateInfo)>;
unsafe fn create_session(
instance: &openxr::Instance,
system_id: openxr::SystemId,
info: &Self::SessionCreateInfo,
session_create_info_chain: &mut OxrSessionCreateNextChain,
) -> openxr::Result<(Session<Self>, FrameWaiter, FrameStream<Self>)>;
} }
/// A type that can be used in [`GraphicsWrap`]. /// A type that can be used in [`GraphicsWrap`].

View File

@@ -1,10 +1,12 @@
use bevy::log::error; use bevy::log::error;
use openxr::sys;
use wgpu_hal::{Adapter, Instance}; use wgpu_hal::{Adapter, Instance};
use winapi::shared::dxgiformat::DXGI_FORMAT; use winapi::shared::dxgiformat::DXGI_FORMAT;
use winapi::um::d3d12 as winapi_d3d12; use winapi::um::d3d12 as winapi_d3d12;
use super::{GraphicsExt, GraphicsType, GraphicsWrap}; use super::{GraphicsExt, GraphicsType, GraphicsWrap};
use crate::error::OxrError; use crate::error::OxrError;
use crate::session::OxrSessionCreateNextChain;
use crate::types::{AppInfo, OxrExtensions, Result, WgpuGraphics}; use crate::types::{AppInfo, OxrExtensions, Result, WgpuGraphics};
unsafe impl GraphicsExt for openxr::D3D12 { unsafe impl GraphicsExt for openxr::D3D12 {
@@ -155,6 +157,49 @@ unsafe impl GraphicsExt for openxr::D3D12 {
}, },
)) ))
} }
unsafe fn create_session(
instance: &openxr::Instance,
system_id: openxr::SystemId,
info: &Self::SessionCreateInfo,
session_create_info_chain: &mut OxrSessionCreateNextChain,
) -> openxr::Result<(
openxr::Session<Self>,
openxr::FrameWaiter,
openxr::FrameStream<Self>,
)> {
let binding = sys::GraphicsBindingD3D12KHR {
ty: sys::GraphicsBindingD3D12KHR::TYPE,
next: session_create_info_chain.chain_pointer(),
device: info.device,
queue: info.queue,
};
let info = sys::SessionCreateInfo {
ty: sys::SessionCreateInfo::TYPE,
next: &binding as *const _ as *const _,
create_flags: Default::default(),
system_id: system_id,
};
let mut out = sys::Session::NULL;
cvt((instance.fp().create_session)(
instance.as_raw(),
&info,
&mut out,
))?;
Ok(openxr::Session::from_raw(
instance.clone(),
out,
Box::new(()),
))
}
}
fn cvt(x: sys::Result) -> openxr::Result<sys::Result> {
if x.into_raw() >= 0 {
Ok(x)
} else {
Err(x)
}
} }
// Extracted from https://github.com/gfx-rs/wgpu/blob/1161a22f4fbb4fc204eb06f2ac4243f83e0e980d/wgpu-hal/src/dx12/adapter.rs#L73-L94 // Extracted from https://github.com/gfx-rs/wgpu/blob/1161a22f4fbb4fc204eb06f2ac4243f83e0e980d/wgpu-hal/src/dx12/adapter.rs#L73-L94
@@ -345,3 +390,4 @@ fn wgpu_to_d3d12(format: wgpu::TextureFormat) -> Option<DXGI_FORMAT> {
} => return None, } => return None,
}) })
} }

View File

@@ -3,12 +3,13 @@ use std::ffi::{c_void, CString};
use ash::vk::Handle; use ash::vk::Handle;
use bevy::log::error; use bevy::log::error;
use bevy::math::UVec2; use bevy::math::UVec2;
use openxr::Version; use openxr::{sys, Version};
use wgpu_hal::api::Vulkan; use wgpu_hal::api::Vulkan;
use wgpu_hal::Api; use wgpu_hal::Api;
use super::{GraphicsExt, GraphicsType, GraphicsWrap}; use super::{GraphicsExt, GraphicsType, GraphicsWrap};
use crate::error::OxrError; use crate::error::OxrError;
use crate::session::OxrSessionCreateNextChain;
use crate::types::{AppInfo, OxrExtensions, Result, WgpuGraphics}; use crate::types::{AppInfo, OxrExtensions, Result, WgpuGraphics};
#[cfg(not(target_os = "android"))] #[cfg(not(target_os = "android"))]
@@ -294,6 +295,53 @@ unsafe impl GraphicsExt for openxr::Vulkan {
}, },
)) ))
} }
unsafe fn create_session(
instance: &openxr::Instance,
system_id: openxr::SystemId,
info: &Self::SessionCreateInfo,
session_create_info_chain: &mut OxrSessionCreateNextChain,
) -> openxr::Result<(
openxr::Session<Self>,
openxr::FrameWaiter,
openxr::FrameStream<Self>,
)> {
let next_ptr = session_create_info_chain.chain_pointer();
let binding = sys::GraphicsBindingVulkanKHR {
ty: sys::GraphicsBindingVulkanKHR::TYPE,
next: next_ptr,
instance: info.instance,
physical_device: info.physical_device,
device: info.device,
queue_family_index: info.queue_family_index,
queue_index: info.queue_index,
};
let info = sys::SessionCreateInfo {
ty: sys::SessionCreateInfo::TYPE,
next: &binding as *const _ as *const _,
create_flags: Default::default(),
system_id: system_id,
};
let mut out = sys::Session::NULL;
cvt((instance.fp().create_session)(
instance.as_raw(),
&info,
&mut out,
))?;
Ok(openxr::Session::from_raw(
instance.clone(),
out,
Box::new(()),
))
}
}
fn cvt(x: sys::Result) -> openxr::Result<sys::Result> {
if x.into_raw() >= 0 {
Ok(x)
} else {
Err(x)
}
} }
fn vulkan_to_wgpu(format: ash::vk::Format) -> Option<wgpu::TextureFormat> { fn vulkan_to_wgpu(format: ash::vk::Format) -> Option<wgpu::TextureFormat> {
@@ -676,3 +724,4 @@ fn wgpu_to_vulkan(format: wgpu::TextureFormat) -> Option<ash::vk::Format> {
}, },
}) })
} }

View File

@@ -31,6 +31,7 @@ use crate::error::OxrError;
use crate::graphics::*; use crate::graphics::*;
use crate::resources::*; use crate::resources::*;
use crate::session::OxrSession; use crate::session::OxrSession;
use crate::session::OxrSessionCreateNextChain;
use crate::session::OxrSessionStatusEvent; use crate::session::OxrSessionStatusEvent;
use crate::types::*; use crate::types::*;
@@ -281,6 +282,7 @@ fn init_xr_session(
device: &wgpu::Device, device: &wgpu::Device,
instance: &OxrInstance, instance: &OxrInstance,
system_id: openxr::SystemId, system_id: openxr::SystemId,
chain: &mut OxrSessionCreateNextChain,
SessionConfigInfo { SessionConfigInfo {
blend_modes, blend_modes,
formats, formats,
@@ -296,7 +298,7 @@ fn init_xr_session(
OxrGraphicsInfo, OxrGraphicsInfo,
)> { )> {
let (session, frame_waiter, frame_stream) = let (session, frame_waiter, frame_stream) =
unsafe { instance.create_session(system_id, graphics_info)? }; unsafe { instance.create_session(system_id, graphics_info, chain)? };
// TODO!() support other view configurations // TODO!() support other view configurations
let available_view_configurations = instance.enumerate_view_configurations(system_id)?; let available_view_configurations = instance.enumerate_view_configurations(system_id)?;
@@ -440,12 +442,14 @@ pub fn create_xr_session(
instance: Res<OxrInstance>, instance: Res<OxrInstance>,
create_info: NonSend<SessionConfigInfo>, create_info: NonSend<SessionConfigInfo>,
system_id: Res<OxrSystemId>, system_id: Res<OxrSystemId>,
mut chain: NonSendMut<OxrSessionCreateNextChain>,
mut commands: Commands, mut commands: Commands,
) { ) {
match init_xr_session( match init_xr_session(
device.wgpu_device(), device.wgpu_device(),
&instance, &instance,
**system_id, **system_id,
&mut chain,
create_info.clone(), create_info.clone(),
) { ) {
Ok((session, frame_waiter, frame_stream, swapchain, images, graphics_info)) => { Ok((session, frame_waiter, frame_stream, swapchain, images, graphics_info)) => {

View File

@@ -6,7 +6,7 @@ use bevy::render::extract_resource::ExtractResource;
use crate::error::OxrError; use crate::error::OxrError;
use crate::graphics::*; use crate::graphics::*;
use crate::layer_builder::{CompositionLayer, LayerProvider}; use crate::layer_builder::{CompositionLayer, LayerProvider};
use crate::session::OxrSession; use crate::session::{OxrSession, OxrSessionCreateNextChain};
use crate::types::*; use crate::types::*;
/// Wrapper around an [`Entry`](openxr::Entry) with some methods overridden to use bevy types. /// Wrapper around an [`Entry`](openxr::Entry) with some methods overridden to use bevy types.
@@ -128,6 +128,7 @@ impl OxrInstance {
&self, &self,
system_id: openxr::SystemId, system_id: openxr::SystemId,
info: SessionCreateInfo, info: SessionCreateInfo,
chain: &mut OxrSessionCreateNextChain,
) -> Result<(OxrSession, OxrFrameWaiter, OxrFrameStream)> { ) -> Result<(OxrSession, OxrFrameWaiter, OxrFrameStream)> {
if !info.0.using_graphics_of_val(&self.1) { if !info.0.using_graphics_of_val(&self.1) {
return Err(OxrError::GraphicsBackendMismatch { return Err(OxrError::GraphicsBackendMismatch {
@@ -139,7 +140,7 @@ impl OxrInstance {
graphics_match!( graphics_match!(
info.0; info.0;
info => { info => {
let (session, frame_waiter, frame_stream) = self.0.create_session::<Api>(system_id, &info)?; let (session, frame_waiter, frame_stream) = Api::create_session(self,system_id, &info,chain)?;
Ok((session.into(), OxrFrameWaiter(frame_waiter), OxrFrameStream(Api::wrap(frame_stream)))) Ok((session.into(), OxrFrameWaiter(frame_waiter), OxrFrameStream(Api::wrap(frame_stream))))
} }
) )

View File

@@ -1,4 +1,7 @@
use std::ffi::c_void;
use crate::init::{OxrHandleEvents, OxrLast}; use crate::init::{OxrHandleEvents, OxrLast};
use crate::next_chain::{OxrNextChain, OxrNextChainStructBase, OxrNextChainStructProvider};
use crate::resources::{ use crate::resources::{
OxrCleanupSession, OxrPassthrough, OxrPassthroughLayer, OxrSessionStarted, OxrSwapchain, OxrCleanupSession, OxrPassthrough, OxrPassthroughLayer, OxrSessionStarted, OxrSwapchain,
}; };
@@ -22,6 +25,7 @@ pub struct OxrSessionPlugin;
impl Plugin for OxrSessionPlugin { impl Plugin for OxrSessionPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.init_non_send_resource::<OxrSessionCreateNextChain>();
app.add_event::<OxrSessionStatusEvent>(); app.add_event::<OxrSessionStatusEvent>();
app.add_systems(OxrLast, run_session_status_schedules.after(OxrHandleEvents)); app.add_systems(OxrLast, run_session_status_schedules.after(OxrHandleEvents));
app.add_systems(XrSessionExiting, clean_session); app.add_systems(XrSessionExiting, clean_session);
@@ -169,3 +173,21 @@ impl OxrSession {
})) }))
} }
} }
pub trait OxrSessionCreateNextProvider: OxrNextChainStructProvider {}
/// NonSend Resource
#[derive(Default)]
pub struct OxrSessionCreateNextChain(OxrNextChain);
impl OxrSessionCreateNextChain {
pub fn push<T: OxrSessionCreateNextProvider>(&mut self, info_struct: T) {
self.0.push(info_struct)
}
pub fn chain(&self) -> Option<&OxrNextChainStructBase> {
self.0.chain()
}
pub fn chain_pointer(&self) -> *const c_void {
self.0.chain_pointer()
}
}