Merge pull request #190 from Schmarni-Dev/vk_exts
allow manually defining additional vulkan extensions
This commit is contained in:
57
crates/bevy_openxr/examples/custom_vulkan_extensions.rs
Normal file
57
crates/bevy_openxr/examples/custom_vulkan_extensions.rs
Normal file
@@ -0,0 +1,57 @@
|
||||
//! A simple 3D scene with light shining over a cube sitting on a plane.
|
||||
|
||||
use bevy::{prelude::*, render::pipelined_rendering::PipelinedRenderingPlugin};
|
||||
use bevy_mod_openxr::{
|
||||
add_xr_plugins,
|
||||
graphics::{GraphicsBackend, OxrManualGraphicsConfig},
|
||||
};
|
||||
|
||||
fn main() -> AppExit {
|
||||
App::new()
|
||||
.insert_resource(OxrManualGraphicsConfig {
|
||||
fallback_backend: GraphicsBackend::Vulkan(()),
|
||||
vk_instance_exts: vec![],
|
||||
vk_device_exts: vec![ash::khr::external_memory::NAME],
|
||||
})
|
||||
.add_plugins(add_xr_plugins(
|
||||
// Disabling Pipelined Rendering should reduce latency a little bit for button inputs
|
||||
// and increase accuracy for hand tracking, controller positions and similar,
|
||||
// the views are updated right before rendering so they are as accurate as possible
|
||||
DefaultPlugins.build().disable::<PipelinedRenderingPlugin>(),
|
||||
))
|
||||
.add_plugins(bevy_mod_xr::hand_debug_gizmos::HandGizmosPlugin)
|
||||
.add_systems(Startup, setup)
|
||||
.run()
|
||||
}
|
||||
|
||||
/// set up a simple 3D scene
|
||||
fn setup(
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
// circular base
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Circle::new(4.0))),
|
||||
MeshMaterial3d(materials.add(Color::WHITE)),
|
||||
Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
|
||||
));
|
||||
// cube
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb_u8(124, 144, 255))),
|
||||
Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
));
|
||||
// light
|
||||
commands.spawn((
|
||||
PointLight {
|
||||
shadows_enabled: true,
|
||||
..default()
|
||||
},
|
||||
Transform::from_xyz(4.0, 8.0, 4.0),
|
||||
));
|
||||
commands.spawn((
|
||||
Camera3d::default(),
|
||||
Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||
));
|
||||
}
|
||||
@@ -3,9 +3,9 @@
|
||||
#[cfg(feature = "vulkan")]
|
||||
pub mod vulkan;
|
||||
|
||||
use std::any::TypeId;
|
||||
use std::{any::TypeId, ffi::CStr};
|
||||
|
||||
use bevy::math::UVec2;
|
||||
use bevy::{ecs::resource::Resource, math::UVec2};
|
||||
use openxr::{FrameStream, FrameWaiter, Session};
|
||||
|
||||
use crate::{
|
||||
@@ -39,6 +39,7 @@ pub unsafe trait GraphicsExt: openxr::Graphics {
|
||||
app_info: &AppInfo,
|
||||
instance: &openxr::Instance,
|
||||
system_id: openxr::SystemId,
|
||||
cfg: Option<&OxrManualGraphicsConfig>,
|
||||
) -> Result<(WgpuGraphics, Self::SessionCreateInfo)>;
|
||||
unsafe fn create_session(
|
||||
instance: &openxr::Instance,
|
||||
@@ -46,6 +47,17 @@ pub unsafe trait GraphicsExt: openxr::Graphics {
|
||||
info: &Self::SessionCreateInfo,
|
||||
session_create_info_chain: &mut OxrSessionCreateNextChain,
|
||||
) -> openxr::Result<(Session<Self>, FrameWaiter, FrameStream<Self>)>;
|
||||
fn init_fallback_graphics(
|
||||
app_info: &AppInfo,
|
||||
cfg: &OxrManualGraphicsConfig,
|
||||
) -> Result<WgpuGraphics>;
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
pub struct OxrManualGraphicsConfig {
|
||||
pub fallback_backend: GraphicsBackend,
|
||||
pub vk_instance_exts: Vec<&'static CStr>,
|
||||
pub vk_device_exts: Vec<&'static CStr>,
|
||||
}
|
||||
|
||||
/// A type that can be used in [`GraphicsWrap`].
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
use std::ffi::{c_void, CString};
|
||||
use std::ffi::{c_void, CStr, CString};
|
||||
use std::str::FromStr;
|
||||
|
||||
use ash::vk::Handle;
|
||||
use ash::vk::{self, Handle};
|
||||
use bevy::log::{debug, error};
|
||||
use bevy::math::UVec2;
|
||||
use openxr::{sys, Version};
|
||||
use wgpu::InstanceFlags;
|
||||
use wgpu_hal::api::Vulkan;
|
||||
use wgpu_hal::Api;
|
||||
|
||||
use super::{GraphicsExt, GraphicsType, GraphicsWrap};
|
||||
use super::{GraphicsExt, GraphicsType, GraphicsWrap, OxrManualGraphicsConfig};
|
||||
use crate::error::OxrError;
|
||||
use crate::session::OxrSessionCreateNextChain;
|
||||
use crate::types::{AppInfo, OxrExtensions, Result, WgpuGraphics};
|
||||
@@ -17,7 +19,7 @@ const VK_TARGET_VERSION: Version = Version::new(1, 2, 0);
|
||||
#[cfg(target_os = "android")]
|
||||
const VK_TARGET_VERSION: Version = Version::new(1, 1, 0);
|
||||
|
||||
const VK_TARGET_VERSION_ASH: u32 = ash::vk::make_api_version(
|
||||
const VK_TARGET_VERSION_ASH: u32 = vk::make_api_version(
|
||||
0,
|
||||
VK_TARGET_VERSION.major() as u32,
|
||||
VK_TARGET_VERSION.minor() as u32,
|
||||
@@ -40,7 +42,7 @@ unsafe impl GraphicsExt for openxr::Vulkan {
|
||||
}
|
||||
|
||||
fn into_wgpu_format(format: Self::Format) -> Option<wgpu::TextureFormat> {
|
||||
vulkan_to_wgpu(ash::vk::Format::from_raw(format as _))
|
||||
vulkan_to_wgpu(vk::Format::from_raw(format as _))
|
||||
}
|
||||
|
||||
unsafe fn to_wgpu_img(
|
||||
@@ -49,7 +51,7 @@ unsafe impl GraphicsExt for openxr::Vulkan {
|
||||
format: wgpu::TextureFormat,
|
||||
resolution: UVec2,
|
||||
) -> Result<wgpu::Texture> {
|
||||
let color_image = ash::vk::Image::from_raw(color_image);
|
||||
let color_image = vk::Image::from_raw(color_image);
|
||||
let wgpu_hal_texture = unsafe {
|
||||
<wgpu_hal::vulkan::Api as wgpu_hal::Api>::Device::texture_from_raw(
|
||||
color_image,
|
||||
@@ -97,6 +99,7 @@ unsafe impl GraphicsExt for openxr::Vulkan {
|
||||
app_info: &AppInfo,
|
||||
instance: &openxr::Instance,
|
||||
system_id: openxr::SystemId,
|
||||
cfg: Option<&OxrManualGraphicsConfig>,
|
||||
) -> Result<(WgpuGraphics, Self::SessionCreateInfo)> {
|
||||
let reqs = instance.graphics_requirements::<openxr::Vulkan>(system_id)?;
|
||||
if VK_TARGET_VERSION < reqs.min_api_version_supported
|
||||
@@ -110,26 +113,12 @@ unsafe impl GraphicsExt for openxr::Vulkan {
|
||||
return Err(OxrError::FailedGraphicsRequirements);
|
||||
};
|
||||
let vk_entry = unsafe { ash::Entry::load() }?;
|
||||
let flags = wgpu::InstanceFlags::default().with_env();
|
||||
let extensions =
|
||||
<Vulkan as Api>::Instance::desired_extensions(&vk_entry, VK_TARGET_VERSION_ASH, flags)?;
|
||||
let device_extensions = [
|
||||
ash::khr::swapchain::NAME,
|
||||
ash::khr::draw_indirect_count::NAME,
|
||||
ash::khr::timeline_semaphore::NAME,
|
||||
ash::khr::imageless_framebuffer::NAME,
|
||||
ash::khr::image_format_list::NAME,
|
||||
#[cfg(target_os = "macos")]
|
||||
ash::khr::portability_subset::NAME,
|
||||
#[cfg(target_os = "macos")]
|
||||
ash::ext::metal_objects::NAME,
|
||||
];
|
||||
|
||||
let (flags, instance_exts, device_exts) = get_extensions(cfg, &vk_entry)?;
|
||||
let vk_instance = unsafe {
|
||||
let extensions_cchar: Vec<_> = extensions.iter().map(|s| s.as_ptr()).collect();
|
||||
let extensions_cchar: Vec<_> = instance_exts.iter().map(|s| s.as_ptr()).collect();
|
||||
|
||||
let app_name = CString::new(app_info.name.clone().into_owned())?;
|
||||
let vk_app_info = ash::vk::ApplicationInfo::default()
|
||||
let vk_app_info = vk::ApplicationInfo::default()
|
||||
.application_name(&app_name)
|
||||
.application_version(1)
|
||||
.engine_name(&app_name)
|
||||
@@ -141,18 +130,182 @@ unsafe impl GraphicsExt for openxr::Vulkan {
|
||||
system_id,
|
||||
#[allow(clippy::missing_transmute_annotations)]
|
||||
std::mem::transmute(vk_entry.static_fn().get_instance_proc_addr),
|
||||
&ash::vk::InstanceCreateInfo::default()
|
||||
&vk::InstanceCreateInfo::default()
|
||||
.application_info(&vk_app_info)
|
||||
.enabled_extension_names(&extensions_cchar) as *const _
|
||||
as *const _,
|
||||
)?
|
||||
.map_err(ash::vk::Result::from_raw)?;
|
||||
.map_err(vk::Result::from_raw)?;
|
||||
|
||||
ash::Instance::load(
|
||||
vk_entry.static_fn(),
|
||||
ash::vk::Instance::from_raw(vk_instance as _),
|
||||
vk::Instance::from_raw(vk_instance as _),
|
||||
)
|
||||
};
|
||||
let vk_physical_device = vk::PhysicalDevice::from_raw(unsafe {
|
||||
instance.vulkan_graphics_device(system_id, vk_instance.handle().as_raw() as _)? as _
|
||||
});
|
||||
init_from_instance_and_dev(
|
||||
vk_entry.clone(),
|
||||
vk_instance.clone(),
|
||||
vk_physical_device,
|
||||
instance_exts,
|
||||
flags,
|
||||
device_exts.into(),
|
||||
|info| unsafe {
|
||||
let vk_device = instance
|
||||
.create_vulkan_device(
|
||||
system_id,
|
||||
#[allow(clippy::missing_transmute_annotations)]
|
||||
std::mem::transmute(vk_entry.static_fn().get_instance_proc_addr),
|
||||
vk_physical_device.as_raw() as _,
|
||||
info as *const _ as *const _,
|
||||
)?
|
||||
.map_err(vk::Result::from_raw)?;
|
||||
|
||||
Ok(ash::Device::load(
|
||||
vk_instance.fp_v1_0(),
|
||||
vk::Device::from_raw(vk_device as _),
|
||||
))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
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 init_fallback_graphics(
|
||||
app_info: &AppInfo,
|
||||
cfg: &OxrManualGraphicsConfig,
|
||||
) -> Result<WgpuGraphics> {
|
||||
let vk_entry = unsafe { ash::Entry::load() }?;
|
||||
let (instance_flags, instance_exts, device_exts) = get_extensions(Some(cfg), &vk_entry)?;
|
||||
|
||||
let vk_instance = unsafe {
|
||||
let extensions_cchar: Vec<_> = instance_exts.iter().map(|s| s.as_ptr()).collect();
|
||||
|
||||
let app_name = CString::from_str(&app_info.name)?;
|
||||
let vk_app_info = ash::vk::ApplicationInfo::default()
|
||||
.application_name(&app_name)
|
||||
.application_version(1)
|
||||
.engine_name(c"bevy")
|
||||
.engine_version(16)
|
||||
.api_version(VK_TARGET_VERSION_ASH);
|
||||
|
||||
vk_entry.create_instance(
|
||||
&ash::vk::InstanceCreateInfo::default()
|
||||
.application_info(&vk_app_info)
|
||||
.enabled_extension_names(&extensions_cchar),
|
||||
None,
|
||||
)?
|
||||
};
|
||||
let vk_physical_device = {
|
||||
let mut devices = unsafe { vk_instance.enumerate_physical_devices()? };
|
||||
devices.sort_by_key(|physical_device| {
|
||||
match unsafe {
|
||||
vk_instance
|
||||
.get_physical_device_properties(*physical_device)
|
||||
.device_type
|
||||
} {
|
||||
vk::PhysicalDeviceType::DISCRETE_GPU => 1,
|
||||
vk::PhysicalDeviceType::INTEGRATED_GPU => 2,
|
||||
vk::PhysicalDeviceType::OTHER => 3,
|
||||
vk::PhysicalDeviceType::VIRTUAL_GPU => 4,
|
||||
vk::PhysicalDeviceType::CPU => 5,
|
||||
_ => 6,
|
||||
}
|
||||
});
|
||||
let Some(phys_dev) = devices.into_iter().next() else {
|
||||
return Err(OxrError::NoAvailableBackend);
|
||||
};
|
||||
phys_dev
|
||||
};
|
||||
init_from_instance_and_dev(
|
||||
vk_entry.clone(),
|
||||
vk_instance.clone(),
|
||||
vk_physical_device,
|
||||
instance_exts,
|
||||
instance_flags,
|
||||
device_exts.into(),
|
||||
|info| unsafe { Ok(vk_instance.create_device(vk_physical_device, &info, None)?) },
|
||||
)
|
||||
.map(|v| v.0)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_extensions(
|
||||
cfg: Option<&OxrManualGraphicsConfig>,
|
||||
vk_entry: &ash::Entry,
|
||||
) -> Result<(wgpu::InstanceFlags, Vec<&'static CStr>, Vec<&'static CStr>)> {
|
||||
let flags = wgpu::InstanceFlags::default().with_env();
|
||||
let mut instance_exts =
|
||||
<Vulkan as Api>::Instance::desired_extensions(&vk_entry, VK_TARGET_VERSION_ASH, flags)?;
|
||||
let mut device_exts = vec![
|
||||
ash::khr::swapchain::NAME,
|
||||
ash::khr::draw_indirect_count::NAME,
|
||||
ash::khr::timeline_semaphore::NAME,
|
||||
ash::khr::imageless_framebuffer::NAME,
|
||||
ash::khr::image_format_list::NAME,
|
||||
#[cfg(target_os = "macos")]
|
||||
ash::khr::portability_subset::NAME,
|
||||
#[cfg(target_os = "macos")]
|
||||
ash::ext::metal_objects::NAME,
|
||||
];
|
||||
if let Some(cfg) = cfg {
|
||||
instance_exts.extend(&cfg.vk_instance_exts);
|
||||
device_exts.extend(&cfg.vk_device_exts);
|
||||
}
|
||||
instance_exts.dedup();
|
||||
device_exts.dedup();
|
||||
|
||||
Ok((flags, instance_exts, device_exts))
|
||||
}
|
||||
|
||||
fn init_from_instance_and_dev(
|
||||
vk_entry: ash::Entry,
|
||||
vk_instance: ash::Instance,
|
||||
vk_physical_device: vk::PhysicalDevice,
|
||||
instance_exts: Vec<&'static CStr>,
|
||||
instance_flags: InstanceFlags,
|
||||
device_exts: Vec<&'static CStr>,
|
||||
create_dev: impl for<'a> FnOnce(&'a vk::DeviceCreateInfo) -> Result<ash::Device>,
|
||||
) -> Result<(WgpuGraphics, openxr::vulkan::SessionCreateInfo)> {
|
||||
let api_layers = unsafe { vk_entry.enumerate_instance_layer_properties()? };
|
||||
let has_nv_optimus = api_layers.iter().any(|v| {
|
||||
v.layer_name_as_c_str()
|
||||
@@ -161,11 +314,10 @@ unsafe impl GraphicsExt for openxr::Vulkan {
|
||||
|
||||
drop(api_layers);
|
||||
|
||||
// these to my knowledge aren't pointers, idk why openxr_sys says that they are,
|
||||
// they're just ids
|
||||
let vk_instance_ptr = vk_instance.handle().as_raw() as *const c_void;
|
||||
|
||||
let vk_physical_device = ash::vk::PhysicalDevice::from_raw(unsafe {
|
||||
instance.vulkan_graphics_device(system_id, vk_instance.handle().as_raw() as _)? as _
|
||||
});
|
||||
let vk_physical_device_ptr = vk_physical_device.as_raw() as *const c_void;
|
||||
|
||||
let vk_device_properties =
|
||||
@@ -216,8 +368,8 @@ unsafe impl GraphicsExt for openxr::Vulkan {
|
||||
vk_device_properties.api_version,
|
||||
android_sdk_version,
|
||||
None,
|
||||
extensions,
|
||||
flags,
|
||||
instance_exts,
|
||||
instance_flags,
|
||||
has_nv_optimus,
|
||||
None,
|
||||
)?
|
||||
@@ -235,42 +387,27 @@ unsafe impl GraphicsExt for openxr::Vulkan {
|
||||
.required_device_extensions(wgpu_features);
|
||||
|
||||
let (wgpu_open_device, vk_device_ptr, queue_family_index) = {
|
||||
let extensions_cchar: Vec<_> = device_extensions.iter().map(|s| s.as_ptr()).collect();
|
||||
let extensions_cchar: Vec<_> = device_exts.iter().map(|s| s.as_ptr()).collect();
|
||||
let mut enabled_phd_features = wgpu_exposed_adapter
|
||||
.adapter
|
||||
.physical_device_features(&enabled_extensions, wgpu_features);
|
||||
let family_index = 0;
|
||||
let family_info = ash::vk::DeviceQueueCreateInfo::default()
|
||||
let family_info = vk::DeviceQueueCreateInfo::default()
|
||||
.queue_family_index(family_index)
|
||||
.queue_priorities(&[1.0]);
|
||||
let family_infos = [family_info];
|
||||
let mut physical_device_multiview_features = ash::vk::PhysicalDeviceMultiviewFeatures {
|
||||
multiview: ash::vk::TRUE,
|
||||
let mut physical_device_multiview_features = vk::PhysicalDeviceMultiviewFeatures {
|
||||
multiview: vk::TRUE,
|
||||
..Default::default()
|
||||
};
|
||||
let info = enabled_phd_features
|
||||
.add_to_device_create(
|
||||
ash::vk::DeviceCreateInfo::default()
|
||||
vk::DeviceCreateInfo::default()
|
||||
.queue_create_infos(&family_infos)
|
||||
.push_next(&mut physical_device_multiview_features),
|
||||
)
|
||||
.enabled_extension_names(&extensions_cchar);
|
||||
let vk_device = unsafe {
|
||||
let vk_device = instance
|
||||
.create_vulkan_device(
|
||||
system_id,
|
||||
#[allow(clippy::missing_transmute_annotations)]
|
||||
std::mem::transmute(vk_entry.static_fn().get_instance_proc_addr),
|
||||
vk_physical_device.as_raw() as _,
|
||||
&info as *const _ as *const _,
|
||||
)?
|
||||
.map_err(ash::vk::Result::from_raw)?;
|
||||
|
||||
ash::Device::load(
|
||||
vk_instance.fp_v1_0(),
|
||||
ash::vk::Device::from_raw(vk_device as _),
|
||||
)
|
||||
};
|
||||
let vk_device = create_dev(&info)?;
|
||||
let vk_device_ptr = vk_device.handle().as_raw() as *const c_void;
|
||||
|
||||
let wgpu_open_device = unsafe {
|
||||
@@ -309,7 +446,6 @@ unsafe impl GraphicsExt for openxr::Vulkan {
|
||||
None,
|
||||
)
|
||||
}?;
|
||||
|
||||
Ok((
|
||||
WgpuGraphics(
|
||||
wgpu_device,
|
||||
@@ -328,46 +464,6 @@ 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,
|
||||
};
|
||||
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)
|
||||
@@ -376,7 +472,7 @@ fn cvt(x: sys::Result) -> openxr::Result<sys::Result> {
|
||||
}
|
||||
}
|
||||
|
||||
fn vulkan_to_wgpu(format: ash::vk::Format) -> Option<wgpu::TextureFormat> {
|
||||
fn vulkan_to_wgpu(format: vk::Format) -> Option<wgpu::TextureFormat> {
|
||||
use ash::vk::Format as F;
|
||||
use wgpu::TextureFormat as Tf;
|
||||
use wgpu::{AstcBlock, AstcChannel};
|
||||
@@ -624,7 +720,7 @@ fn vulkan_to_wgpu(format: ash::vk::Format) -> Option<wgpu::TextureFormat> {
|
||||
})
|
||||
}
|
||||
|
||||
fn wgpu_to_vulkan(format: wgpu::TextureFormat) -> Option<ash::vk::Format> {
|
||||
fn wgpu_to_vulkan(format: wgpu::TextureFormat) -> Option<vk::Format> {
|
||||
// Copied with minor modification from:
|
||||
// https://github.com/gfx-rs/wgpu/blob/a7defb723f856d946d6d220e9897d20dbb7b8f61/wgpu-hal/src/vulkan/conv.rs#L5-L151
|
||||
// license: MIT OR Apache-2.0
|
||||
|
||||
@@ -81,7 +81,8 @@ impl Plugin for OxrInitPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_event::<OxrInteractionProfileChanged>();
|
||||
app.init_resource::<OxrSessionConfig>();
|
||||
match self.init_xr() {
|
||||
let cfg = app.world_mut().remove_resource::<OxrManualGraphicsConfig>();
|
||||
match self.init_xr(cfg.as_ref()) {
|
||||
Ok((
|
||||
instance,
|
||||
system_id,
|
||||
@@ -160,6 +161,31 @@ impl Plugin for OxrInitPlugin {
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to initialize openxr: {e}");
|
||||
if let Some(cfg) = cfg {
|
||||
if let Ok(WgpuGraphics(device, queue, adapter_info, adapter, wgpu_instance)) =
|
||||
graphics_match!(
|
||||
cfg.fallback_backend;
|
||||
_ => Api::init_fallback_graphics(&self.app_info ,&cfg)
|
||||
)
|
||||
.inspect_err(|err| {
|
||||
error!("Failed to initialize custom fallback graphics: {err}")
|
||||
})
|
||||
{
|
||||
app.add_plugins(RenderPlugin {
|
||||
render_creation: RenderCreation::manual(
|
||||
device.into(),
|
||||
RenderQueue(Arc::new(WgpuWrapper::new(queue))),
|
||||
RenderAdapterInfo(WgpuWrapper::new(adapter_info)),
|
||||
RenderAdapter(Arc::new(WgpuWrapper::new(adapter))),
|
||||
RenderInstance(Arc::new(WgpuWrapper::new(wgpu_instance))),
|
||||
),
|
||||
synchronous_pipeline_compilation: self.synchronous_pipeline_compilation,
|
||||
debug_flags: self.render_debug_flags,
|
||||
})
|
||||
.insert_resource(XrState::Unavailable);
|
||||
return;
|
||||
}
|
||||
}
|
||||
app.add_plugins(RenderPlugin::default())
|
||||
.insert_resource(XrState::Unavailable);
|
||||
}
|
||||
@@ -203,6 +229,7 @@ fn detect_session_destroyed(
|
||||
impl OxrInitPlugin {
|
||||
fn init_xr(
|
||||
&self,
|
||||
cfg: Option<&OxrManualGraphicsConfig>,
|
||||
) -> OxrResult<(
|
||||
OxrInstance,
|
||||
OxrSystemId,
|
||||
@@ -272,7 +299,7 @@ impl OxrInitPlugin {
|
||||
}
|
||||
);
|
||||
|
||||
let (graphics, graphics_info) = instance.init_graphics(system_id)?;
|
||||
let (graphics, graphics_info) = instance.init_graphics(system_id, cfg)?;
|
||||
|
||||
Ok((
|
||||
instance,
|
||||
|
||||
@@ -106,11 +106,12 @@ impl OxrInstance {
|
||||
pub fn init_graphics(
|
||||
&self,
|
||||
system_id: openxr::SystemId,
|
||||
manual_config: Option<&OxrManualGraphicsConfig>,
|
||||
) -> OxrResult<(WgpuGraphics, SessionGraphicsCreateInfo)> {
|
||||
graphics_match!(
|
||||
self.1;
|
||||
_ => {
|
||||
let (graphics, session_info) = Api::init_graphics(&self.2, self, system_id)?;
|
||||
let (graphics, session_info) = Api::init_graphics(&self.2, self, system_id, manual_config)?;
|
||||
|
||||
Ok((graphics, SessionGraphicsCreateInfo(Api::wrap(session_info))))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user