From cb039de4091fbc576964ebaa8995cc582b8a144a Mon Sep 17 00:00:00 2001 From: galister <22305755+galister@users.noreply.github.com> Date: Tue, 5 Dec 2023 02:06:51 +0100 Subject: [PATCH] on the right path --- src/backend/openvr/mod.rs | 15 ++++--- src/backend/openvr/overlay.rs | 74 ++++++++++++++++++++--------------- src/graphics.rs | 20 ++++++---- src/gui/mod.rs | 35 +++++++++++++++-- src/overlays/screen.rs | 17 ++++---- 5 files changed, 107 insertions(+), 54 deletions(-) diff --git a/src/backend/openvr/mod.rs b/src/backend/openvr/mod.rs index 609b349..73baddd 100644 --- a/src/backend/openvr/mod.rs +++ b/src/backend/openvr/mod.rs @@ -30,9 +30,9 @@ pub mod overlay; pub fn openvr_run() { let app_type = EVRApplicationType::VRApplication_Overlay; let Ok(context) = ovr_overlay::Context::init(app_type) else { - error!("Failed to initialize OpenVR"); - return; - }; + error!("Failed to initialize OpenVR"); + return; + }; let mut overlay_mngr = context.overlay_mngr(); //let mut settings_mngr = context.settings_mngr(); @@ -65,11 +65,16 @@ pub fn openvr_run() { return; }; - let Ok(refresh_rate) = system_mngr.get_tracked_device_property::(TrackedDeviceIndex::HMD, ETrackedDeviceProperty::Prop_DisplayFrequency_Float) else { + let Ok(refresh_rate) = system_mngr.get_tracked_device_property::( + TrackedDeviceIndex::HMD, + ETrackedDeviceProperty::Prop_DisplayFrequency_Float, + ) else { error!("Failed to get display refresh rate"); return; }; + info!("HMD running @ {} Hz", refresh_rate); + let frame_time = (1000.0 / refresh_rate).floor() * 0.001; let mut next_device_update = Instant::now(); let mut due_tasks = VecDeque::with_capacity(4); @@ -141,7 +146,7 @@ pub fn openvr_run() { let mut seconds_since_vsync = 0f32; std::thread::sleep(Duration::from_secs_f32( if system_mngr.get_time_since_last_vsync(&mut seconds_since_vsync, &mut 0u64) { - frame_time - seconds_since_vsync + (frame_time - seconds_since_vsync).max(0.0) } else { 0.011 }, diff --git a/src/backend/openvr/overlay.rs b/src/backend/openvr/overlay.rs index 47ae59c..b5cf42c 100644 --- a/src/backend/openvr/overlay.rs +++ b/src/backend/openvr/overlay.rs @@ -1,19 +1,10 @@ use glam::Vec4; use ovr_overlay::{ overlay::{OverlayHandle, OverlayManager}, - sys::VRVulkanTextureData_t, -}; -use vulkano::{ - command_buffer::{ - synced::{ - SyncCommandBuffer, SyncCommandBufferBuilder, SyncCommandBufferBuilderExecuteCommands, - }, - AutoCommandBufferBuilder, CommandBufferExecFuture, - }, - image::{ImageAccess, ImageLayout}, - sync::{future::NowFuture, ImageMemoryBarrier}, - Handle, VulkanObject, + pose::Matrix3x4, + sys::{ETrackingUniverseOrigin, VRVulkanTextureData_t}, }; +use vulkano::{image::ImageAccess, Handle, VulkanObject}; use crate::{backend::overlay::OverlayData, graphics::WlxGraphics, state::AppState}; @@ -43,6 +34,7 @@ impl OverlayData { log::debug!("{}: initialize", self.state.name); self.data.handle = Some(handle); + self.data.color = Vec4::ONE; self.init(app); @@ -63,6 +55,7 @@ impl OverlayData { pub fn after_render(&mut self, overlay: &mut OverlayManager, graphics: &WlxGraphics) { if self.data.visible { + self.upload_transform(overlay); self.upload_texture(overlay, graphics); } } @@ -104,7 +97,7 @@ impl OverlayData { r: self.data.color.x, g: self.data.color.y, b: self.data.color.z, - a: 1.0, + a: self.data.color.w, }, ) { panic!("Failed to set overlay tint: {}", e); @@ -141,6 +134,42 @@ impl OverlayData { } } + fn upload_transform(&self, overlay: &mut OverlayManager) { + let Some(handle) = self.data.handle else { + log::debug!("{}: No overlay handle", self.state.name); + return; + }; + + let transform = Matrix3x4([ + [ + self.state.transform.matrix3.x_axis.x, + self.state.transform.matrix3.y_axis.x, + self.state.transform.matrix3.z_axis.x, + self.state.transform.translation.x, + ], + [ + self.state.transform.matrix3.x_axis.y, + self.state.transform.matrix3.y_axis.y, + self.state.transform.matrix3.z_axis.y, + self.state.transform.translation.y, + ], + [ + self.state.transform.matrix3.x_axis.z, + self.state.transform.matrix3.y_axis.z, + self.state.transform.matrix3.z_axis.z, + self.state.transform.translation.z, + ], + ]); + + if let Err(e) = overlay.set_transform_absolute( + handle, + ETrackingUniverseOrigin::TrackingUniverseStanding, + &transform, + ) { + panic!("Failed to set overlay transform: {}", e); + } + } + fn upload_texture(&mut self, overlay: &mut OverlayManager, graphics: &WlxGraphics) { let Some(handle) = self.data.handle else { log::debug!("{}: No overlay handle", self.state.name); @@ -181,27 +210,10 @@ impl OverlayData { m_nQueueFamilyIndex: graphics.queue.queue_family_index(), }; - graphics - .transition_layout( - image.clone(), - ImageLayout::ColorAttachmentOptimal, - ImageLayout::TransferSrcOptimal, - ) - .wait(None) - .unwrap(); - + log::info!("Usages: {:?}", image.usage()); log::info!("nImage: {}, nFormat: {:?}, nWidth: {}, nHeight: {}, nSampleCount: {}, nQueueFamilyIndex: {}", texture.m_nImage, format, texture.m_nWidth, texture.m_nHeight, texture.m_nSampleCount, texture.m_nQueueFamilyIndex); if let Err(e) = overlay.set_image_vulkan(handle, &mut texture) { panic!("Failed to set overlay texture: {}", e); } - - graphics - .transition_layout( - image, - ImageLayout::TransferSrcOptimal, - ImageLayout::ColorAttachmentOptimal, - ) - .wait(None) - .unwrap(); } } diff --git a/src/graphics.rs b/src/graphics.rs index 5ce061a..adb1495 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -134,23 +134,27 @@ impl WlxGraphics { .build_vk_surface(&event_loop, instance.clone()) .unwrap(); - let (physical_device, queue_family_index) = instance + let (physical_device, my_extensions, queue_family_index) = instance .enumerate_physical_devices() .unwrap() .filter(|p| { p.api_version() >= Version::V1_3 || p.supported_extensions().khr_dynamic_rendering }) - .filter(|p| { - let runtime_extensions = vk_device_extensions_fn(p); + .filter_map(|p| { + let runtime_extensions = vk_device_extensions_fn(&p); debug!( "Device exts for {}: {:?}", p.properties().device_name, &runtime_extensions ); let my_extensions = runtime_extensions.union(&device_extensions); - p.supported_extensions().contains(&my_extensions) + if p.supported_extensions().contains(&my_extensions) { + Some((p, my_extensions)) + } else { + None + } }) - .filter_map(|p| { + .filter_map(|(p, my_extensions)| { p.queue_family_properties() .iter() .enumerate() @@ -158,9 +162,9 @@ impl WlxGraphics { q.queue_flags.intersects(QueueFlags::GRAPHICS) && p.surface_support(i as u32, &surface).unwrap_or(false) }) - .map(|i| (p, i as u32)) + .map(|i| (p, my_extensions, i as u32)) }) - .min_by_key(|(p, _)| match p.properties().device_type { + .min_by_key(|(p, _, _)| match p.properties().device_type { PhysicalDeviceType::DiscreteGpu => 0, PhysicalDeviceType::IntegratedGpu => 1, PhysicalDeviceType::VirtualGpu => 2, @@ -182,7 +186,7 @@ impl WlxGraphics { let (device, mut queues) = Device::new( physical_device, DeviceCreateInfo { - enabled_extensions: device_extensions, + enabled_extensions: my_extensions, enabled_features: Features { dynamic_rendering: true, ..Features::empty() diff --git a/src/gui/mod.rs b/src/gui/mod.rs index 111ca1f..6e5212e 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -4,7 +4,7 @@ use glam::{Vec2, Vec3}; use vulkano::{ command_buffer::{CommandBufferUsage, PrimaryAutoCommandBuffer}, format::Format, - image::{view::ImageView, AttachmentImage, ImageLayout, ImageViewAbstract}, + image::{view::ImageView, AttachmentImage, ImageAccess, ImageLayout, ImageViewAbstract}, sampler::Filter, }; @@ -209,6 +209,8 @@ pub struct Canvas { pass_fg: WlxPass, pass_bg: WlxPass, + + first_render: bool, } impl Canvas { @@ -286,6 +288,7 @@ impl Canvas { view_final, pass_fg, pass_bg, + first_render: true, } } @@ -400,6 +403,22 @@ impl OverlayRenderer for Canvas { } } + let image = self.view_final.image().inner().image.clone(); + + if self.first_render { + self.first_render = false; + } else { + self.canvas + .graphics + .transition_layout( + image.clone(), + ImageLayout::TransferSrcOptimal, + ImageLayout::ColorAttachmentOptimal, + ) + .wait(None) + .unwrap(); + } + let mut cmd_buffer = self .canvas .graphics @@ -431,8 +450,18 @@ impl OverlayRenderer for Canvas { // mostly static text cmd_buffer.run_ref(&self.pass_fg); - - let _ = cmd_buffer.end_render_and_execute(); + { + let _ = cmd_buffer.end_render_and_execute(); + } + self.canvas + .graphics + .transition_layout( + image, + ImageLayout::ColorAttachmentOptimal, + ImageLayout::TransferSrcOptimal, + ) + .wait(None) + .unwrap(); } fn view(&mut self) -> Option> { Some(self.view_final.clone()) diff --git a/src/overlays/screen.rs b/src/overlays/screen.rs index 9de27c6..0ab2e54 100644 --- a/src/overlays/screen.rs +++ b/src/overlays/screen.rs @@ -8,7 +8,7 @@ use std::{ use vulkano::{ command_buffer::CommandBufferUsage, format::Format, - image::{view::ImageView, ImageAccess, ImageViewAbstract, ImmutableImage}, + image::{view::ImageView, ImageAccess, ImageLayout, ImageViewAbstract, ImmutableImage}, Handle, VulkanObject, }; use wlx_capture::{ @@ -144,13 +144,8 @@ impl ScreenRenderer { } impl OverlayRenderer for ScreenRenderer { - fn init(&mut self, app: &mut AppState) { + fn init(&mut self, _app: &mut AppState) { self.receiver = Some(self.capture.init()); - let mut cmd = app - .graphics - .create_command_buffer(CommandBufferUsage::OneTimeSubmit); - let default_image = cmd.texture2d(1, 1, Format::R8G8B8A8_UNORM, vec![255, 0, 255, 255]); - let _ = cmd.end_and_execute(); } fn render(&mut self, app: &mut AppState) { let Some(receiver) = self.receiver.as_mut() else { @@ -169,6 +164,14 @@ impl OverlayRenderer for ScreenRenderer { return; } } + app.graphics + .transition_layout( + new.inner().image.clone(), + ImageLayout::Undefined, + ImageLayout::TransferSrcOptimal, + ) + .wait(None) + .unwrap(); self.view = Some(ImageView::new_default(new).unwrap()); } }