Merge pull request #125 from Schmarni-Dev/next_chain_sessions
Implement next pointer chain for xrCreateSession
This commit is contained in:
@@ -6,8 +6,9 @@ pub mod vulkan;
|
||||
use std::any::TypeId;
|
||||
|
||||
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.
|
||||
pub unsafe trait GraphicsExt: openxr::Graphics {
|
||||
@@ -36,6 +37,12 @@ pub unsafe trait GraphicsExt: openxr::Graphics {
|
||||
instance: &openxr::Instance,
|
||||
system_id: openxr::SystemId,
|
||||
) -> 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`].
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
use bevy::log::error;
|
||||
use openxr::sys;
|
||||
use wgpu_hal::{Adapter, Instance};
|
||||
use winapi::shared::dxgiformat::DXGI_FORMAT;
|
||||
use winapi::um::d3d12 as winapi_d3d12;
|
||||
|
||||
use super::{GraphicsExt, GraphicsType, GraphicsWrap};
|
||||
use crate::error::OxrError;
|
||||
use crate::session::OxrSessionCreateNextChain;
|
||||
use crate::types::{AppInfo, OxrExtensions, Result, WgpuGraphics};
|
||||
|
||||
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
|
||||
@@ -345,3 +390,4 @@ fn wgpu_to_d3d12(format: wgpu::TextureFormat) -> Option<DXGI_FORMAT> {
|
||||
} => return None,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,13 @@ use std::ffi::{c_void, CString};
|
||||
use ash::vk::Handle;
|
||||
use bevy::log::error;
|
||||
use bevy::math::UVec2;
|
||||
use openxr::Version;
|
||||
use openxr::{sys, Version};
|
||||
use wgpu_hal::api::Vulkan;
|
||||
use wgpu_hal::Api;
|
||||
|
||||
use super::{GraphicsExt, GraphicsType, GraphicsWrap};
|
||||
use crate::error::OxrError;
|
||||
use crate::session::OxrSessionCreateNextChain;
|
||||
use crate::types::{AppInfo, OxrExtensions, Result, WgpuGraphics};
|
||||
|
||||
#[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> {
|
||||
@@ -676,3 +724,4 @@ fn wgpu_to_vulkan(format: wgpu::TextureFormat) -> Option<ash::vk::Format> {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ use crate::error::OxrError;
|
||||
use crate::graphics::*;
|
||||
use crate::resources::*;
|
||||
use crate::session::OxrSession;
|
||||
use crate::session::OxrSessionCreateNextChain;
|
||||
use crate::session::OxrSessionStatusEvent;
|
||||
use crate::types::*;
|
||||
|
||||
@@ -281,6 +282,7 @@ fn init_xr_session(
|
||||
device: &wgpu::Device,
|
||||
instance: &OxrInstance,
|
||||
system_id: openxr::SystemId,
|
||||
chain: &mut OxrSessionCreateNextChain,
|
||||
SessionConfigInfo {
|
||||
blend_modes,
|
||||
formats,
|
||||
@@ -296,7 +298,7 @@ fn init_xr_session(
|
||||
OxrGraphicsInfo,
|
||||
)> {
|
||||
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
|
||||
let available_view_configurations = instance.enumerate_view_configurations(system_id)?;
|
||||
@@ -440,12 +442,14 @@ pub fn create_xr_session(
|
||||
instance: Res<OxrInstance>,
|
||||
create_info: NonSend<SessionConfigInfo>,
|
||||
system_id: Res<OxrSystemId>,
|
||||
mut chain: NonSendMut<OxrSessionCreateNextChain>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
match init_xr_session(
|
||||
device.wgpu_device(),
|
||||
&instance,
|
||||
**system_id,
|
||||
&mut chain,
|
||||
create_info.clone(),
|
||||
) {
|
||||
Ok((session, frame_waiter, frame_stream, swapchain, images, graphics_info)) => {
|
||||
|
||||
@@ -6,7 +6,7 @@ use bevy::render::extract_resource::ExtractResource;
|
||||
use crate::error::OxrError;
|
||||
use crate::graphics::*;
|
||||
use crate::layer_builder::{CompositionLayer, LayerProvider};
|
||||
use crate::session::OxrSession;
|
||||
use crate::session::{OxrSession, OxrSessionCreateNextChain};
|
||||
use crate::types::*;
|
||||
|
||||
/// Wrapper around an [`Entry`](openxr::Entry) with some methods overridden to use bevy types.
|
||||
@@ -128,6 +128,7 @@ impl OxrInstance {
|
||||
&self,
|
||||
system_id: openxr::SystemId,
|
||||
info: SessionCreateInfo,
|
||||
chain: &mut OxrSessionCreateNextChain,
|
||||
) -> Result<(OxrSession, OxrFrameWaiter, OxrFrameStream)> {
|
||||
if !info.0.using_graphics_of_val(&self.1) {
|
||||
return Err(OxrError::GraphicsBackendMismatch {
|
||||
@@ -139,7 +140,7 @@ impl OxrInstance {
|
||||
graphics_match!(
|
||||
info.0;
|
||||
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))))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use std::ffi::c_void;
|
||||
|
||||
use crate::init::{OxrHandleEvents, OxrLast};
|
||||
use crate::next_chain::{OxrNextChain, OxrNextChainStructBase, OxrNextChainStructProvider};
|
||||
use crate::resources::{
|
||||
OxrCleanupSession, OxrPassthrough, OxrPassthroughLayer, OxrSessionStarted, OxrSwapchain,
|
||||
};
|
||||
@@ -22,6 +25,7 @@ pub struct OxrSessionPlugin;
|
||||
|
||||
impl Plugin for OxrSessionPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_non_send_resource::<OxrSessionCreateNextChain>();
|
||||
app.add_event::<OxrSessionStatusEvent>();
|
||||
app.add_systems(OxrLast, run_session_status_schedules.after(OxrHandleEvents));
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user