add session creation next chain infrastructure
Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
@@ -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`].
|
||||||
|
|||||||
@@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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> {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)) => {
|
||||||
|
|||||||
@@ -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))))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user