on the right path

This commit is contained in:
galister
2023-12-05 02:06:51 +01:00
parent e5ab46be91
commit cb039de409
5 changed files with 107 additions and 54 deletions

View File

@@ -65,11 +65,16 @@ pub fn openvr_run() {
return; return;
}; };
let Ok(refresh_rate) = system_mngr.get_tracked_device_property::<f32>(TrackedDeviceIndex::HMD, ETrackedDeviceProperty::Prop_DisplayFrequency_Float) else { let Ok(refresh_rate) = system_mngr.get_tracked_device_property::<f32>(
TrackedDeviceIndex::HMD,
ETrackedDeviceProperty::Prop_DisplayFrequency_Float,
) else {
error!("Failed to get display refresh rate"); error!("Failed to get display refresh rate");
return; return;
}; };
info!("HMD running @ {} Hz", refresh_rate);
let frame_time = (1000.0 / refresh_rate).floor() * 0.001; let frame_time = (1000.0 / refresh_rate).floor() * 0.001;
let mut next_device_update = Instant::now(); let mut next_device_update = Instant::now();
let mut due_tasks = VecDeque::with_capacity(4); let mut due_tasks = VecDeque::with_capacity(4);
@@ -141,7 +146,7 @@ pub fn openvr_run() {
let mut seconds_since_vsync = 0f32; let mut seconds_since_vsync = 0f32;
std::thread::sleep(Duration::from_secs_f32( std::thread::sleep(Duration::from_secs_f32(
if system_mngr.get_time_since_last_vsync(&mut seconds_since_vsync, &mut 0u64) { 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 { } else {
0.011 0.011
}, },

View File

@@ -1,19 +1,10 @@
use glam::Vec4; use glam::Vec4;
use ovr_overlay::{ use ovr_overlay::{
overlay::{OverlayHandle, OverlayManager}, overlay::{OverlayHandle, OverlayManager},
sys::VRVulkanTextureData_t, pose::Matrix3x4,
}; sys::{ETrackingUniverseOrigin, VRVulkanTextureData_t},
use vulkano::{
command_buffer::{
synced::{
SyncCommandBuffer, SyncCommandBufferBuilder, SyncCommandBufferBuilderExecuteCommands,
},
AutoCommandBufferBuilder, CommandBufferExecFuture,
},
image::{ImageAccess, ImageLayout},
sync::{future::NowFuture, ImageMemoryBarrier},
Handle, VulkanObject,
}; };
use vulkano::{image::ImageAccess, Handle, VulkanObject};
use crate::{backend::overlay::OverlayData, graphics::WlxGraphics, state::AppState}; use crate::{backend::overlay::OverlayData, graphics::WlxGraphics, state::AppState};
@@ -43,6 +34,7 @@ impl OverlayData<OpenVrOverlayData> {
log::debug!("{}: initialize", self.state.name); log::debug!("{}: initialize", self.state.name);
self.data.handle = Some(handle); self.data.handle = Some(handle);
self.data.color = Vec4::ONE;
self.init(app); self.init(app);
@@ -63,6 +55,7 @@ impl OverlayData<OpenVrOverlayData> {
pub fn after_render(&mut self, overlay: &mut OverlayManager, graphics: &WlxGraphics) { pub fn after_render(&mut self, overlay: &mut OverlayManager, graphics: &WlxGraphics) {
if self.data.visible { if self.data.visible {
self.upload_transform(overlay);
self.upload_texture(overlay, graphics); self.upload_texture(overlay, graphics);
} }
} }
@@ -104,7 +97,7 @@ impl OverlayData<OpenVrOverlayData> {
r: self.data.color.x, r: self.data.color.x,
g: self.data.color.y, g: self.data.color.y,
b: self.data.color.z, b: self.data.color.z,
a: 1.0, a: self.data.color.w,
}, },
) { ) {
panic!("Failed to set overlay tint: {}", e); panic!("Failed to set overlay tint: {}", e);
@@ -141,6 +134,42 @@ impl OverlayData<OpenVrOverlayData> {
} }
} }
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) { fn upload_texture(&mut self, overlay: &mut OverlayManager, graphics: &WlxGraphics) {
let Some(handle) = self.data.handle else { let Some(handle) = self.data.handle else {
log::debug!("{}: No overlay handle", self.state.name); log::debug!("{}: No overlay handle", self.state.name);
@@ -181,27 +210,10 @@ impl OverlayData<OpenVrOverlayData> {
m_nQueueFamilyIndex: graphics.queue.queue_family_index(), m_nQueueFamilyIndex: graphics.queue.queue_family_index(),
}; };
graphics log::info!("Usages: {:?}", image.usage());
.transition_layout(
image.clone(),
ImageLayout::ColorAttachmentOptimal,
ImageLayout::TransferSrcOptimal,
)
.wait(None)
.unwrap();
log::info!("nImage: {}, nFormat: {:?}, nWidth: {}, nHeight: {}, nSampleCount: {}, nQueueFamilyIndex: {}", texture.m_nImage, format, texture.m_nWidth, texture.m_nHeight, texture.m_nSampleCount, texture.m_nQueueFamilyIndex); 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) { if let Err(e) = overlay.set_image_vulkan(handle, &mut texture) {
panic!("Failed to set overlay texture: {}", e); panic!("Failed to set overlay texture: {}", e);
} }
graphics
.transition_layout(
image,
ImageLayout::TransferSrcOptimal,
ImageLayout::ColorAttachmentOptimal,
)
.wait(None)
.unwrap();
} }
} }

View File

@@ -134,23 +134,27 @@ impl WlxGraphics {
.build_vk_surface(&event_loop, instance.clone()) .build_vk_surface(&event_loop, instance.clone())
.unwrap(); .unwrap();
let (physical_device, queue_family_index) = instance let (physical_device, my_extensions, queue_family_index) = instance
.enumerate_physical_devices() .enumerate_physical_devices()
.unwrap() .unwrap()
.filter(|p| { .filter(|p| {
p.api_version() >= Version::V1_3 || p.supported_extensions().khr_dynamic_rendering p.api_version() >= Version::V1_3 || p.supported_extensions().khr_dynamic_rendering
}) })
.filter(|p| { .filter_map(|p| {
let runtime_extensions = vk_device_extensions_fn(p); let runtime_extensions = vk_device_extensions_fn(&p);
debug!( debug!(
"Device exts for {}: {:?}", "Device exts for {}: {:?}",
p.properties().device_name, p.properties().device_name,
&runtime_extensions &runtime_extensions
); );
let my_extensions = runtime_extensions.union(&device_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() p.queue_family_properties()
.iter() .iter()
.enumerate() .enumerate()
@@ -158,9 +162,9 @@ impl WlxGraphics {
q.queue_flags.intersects(QueueFlags::GRAPHICS) q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false) && 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::DiscreteGpu => 0,
PhysicalDeviceType::IntegratedGpu => 1, PhysicalDeviceType::IntegratedGpu => 1,
PhysicalDeviceType::VirtualGpu => 2, PhysicalDeviceType::VirtualGpu => 2,
@@ -182,7 +186,7 @@ impl WlxGraphics {
let (device, mut queues) = Device::new( let (device, mut queues) = Device::new(
physical_device, physical_device,
DeviceCreateInfo { DeviceCreateInfo {
enabled_extensions: device_extensions, enabled_extensions: my_extensions,
enabled_features: Features { enabled_features: Features {
dynamic_rendering: true, dynamic_rendering: true,
..Features::empty() ..Features::empty()

View File

@@ -4,7 +4,7 @@ use glam::{Vec2, Vec3};
use vulkano::{ use vulkano::{
command_buffer::{CommandBufferUsage, PrimaryAutoCommandBuffer}, command_buffer::{CommandBufferUsage, PrimaryAutoCommandBuffer},
format::Format, format::Format,
image::{view::ImageView, AttachmentImage, ImageLayout, ImageViewAbstract}, image::{view::ImageView, AttachmentImage, ImageAccess, ImageLayout, ImageViewAbstract},
sampler::Filter, sampler::Filter,
}; };
@@ -209,6 +209,8 @@ pub struct Canvas<D, S> {
pass_fg: WlxPass, pass_fg: WlxPass,
pass_bg: WlxPass, pass_bg: WlxPass,
first_render: bool,
} }
impl<D, S> Canvas<D, S> { impl<D, S> Canvas<D, S> {
@@ -286,6 +288,7 @@ impl<D, S> Canvas<D, S> {
view_final, view_final,
pass_fg, pass_fg,
pass_bg, pass_bg,
first_render: true,
} }
} }
@@ -400,6 +403,22 @@ impl<D, S> OverlayRenderer for Canvas<D, S> {
} }
} }
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 let mut cmd_buffer = self
.canvas .canvas
.graphics .graphics
@@ -431,9 +450,19 @@ impl<D, S> OverlayRenderer for Canvas<D, S> {
// mostly static text // mostly static text
cmd_buffer.run_ref(&self.pass_fg); 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<Arc<dyn ImageViewAbstract>> { fn view(&mut self) -> Option<Arc<dyn ImageViewAbstract>> {
Some(self.view_final.clone()) Some(self.view_final.clone())
} }

View File

@@ -8,7 +8,7 @@ use std::{
use vulkano::{ use vulkano::{
command_buffer::CommandBufferUsage, command_buffer::CommandBufferUsage,
format::Format, format::Format,
image::{view::ImageView, ImageAccess, ImageViewAbstract, ImmutableImage}, image::{view::ImageView, ImageAccess, ImageLayout, ImageViewAbstract, ImmutableImage},
Handle, VulkanObject, Handle, VulkanObject,
}; };
use wlx_capture::{ use wlx_capture::{
@@ -144,13 +144,8 @@ impl ScreenRenderer {
} }
impl OverlayRenderer for 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()); 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) { fn render(&mut self, app: &mut AppState) {
let Some(receiver) = self.receiver.as_mut() else { let Some(receiver) = self.receiver.as_mut() else {
@@ -169,6 +164,14 @@ impl OverlayRenderer for ScreenRenderer {
return; return;
} }
} }
app.graphics
.transition_layout(
new.inner().image.clone(),
ImageLayout::Undefined,
ImageLayout::TransferSrcOptimal,
)
.wait(None)
.unwrap();
self.view = Some(ImageView::new_default(new).unwrap()); self.view = Some(ImageView::new_default(new).unwrap());
} }
} }