refactor rendering interface, working edit overlay
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use std::f32::consts::PI;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use ash::vk::SubmitInfo;
|
||||
use glam::{Affine3A, Vec3, Vec3A, Vec4};
|
||||
@@ -8,7 +8,6 @@ use idmap::IdMap;
|
||||
use ovr_overlay::overlay::OverlayManager;
|
||||
use ovr_overlay::sys::ETrackingUniverseOrigin;
|
||||
use vulkano::{
|
||||
VulkanObject,
|
||||
command_buffer::{
|
||||
CommandBufferBeginInfo, CommandBufferLevel, CommandBufferUsage, RecordingCommandBuffer,
|
||||
},
|
||||
@@ -16,19 +15,19 @@ use vulkano::{
|
||||
image::view::ImageView,
|
||||
image::{Image, ImageLayout},
|
||||
sync::{
|
||||
AccessFlags, DependencyInfo, ImageMemoryBarrier, PipelineStages,
|
||||
fence::{Fence, FenceCreateInfo},
|
||||
AccessFlags, DependencyInfo, ImageMemoryBarrier, PipelineStages,
|
||||
},
|
||||
VulkanObject,
|
||||
};
|
||||
use wgui::gfx::WGfx;
|
||||
|
||||
use crate::backend::input::{HoverResult, PointerHit};
|
||||
use crate::graphics::CommandBuffers;
|
||||
use crate::state::AppState;
|
||||
use crate::subsystem::hid::WheelDelta;
|
||||
use crate::windowing::Z_ORDER_LINES;
|
||||
use crate::windowing::backend::{FrameMeta, OverlayBackend, ShouldRender};
|
||||
use crate::windowing::backend::{FrameMeta, OverlayBackend, RenderResources, ShouldRender};
|
||||
use crate::windowing::window::{OverlayWindowConfig, OverlayWindowData};
|
||||
use crate::windowing::Z_ORDER_LINES;
|
||||
|
||||
use super::overlay::OpenVrOverlayData;
|
||||
|
||||
@@ -189,14 +188,8 @@ impl OverlayBackend for LineBackend {
|
||||
fn should_render(&mut self, _: &mut AppState) -> anyhow::Result<ShouldRender> {
|
||||
Ok(ShouldRender::Unable)
|
||||
}
|
||||
fn render(
|
||||
&mut self,
|
||||
_: &mut AppState,
|
||||
_: Arc<ImageView>,
|
||||
_: &mut CommandBuffers,
|
||||
_: f32,
|
||||
) -> anyhow::Result<bool> {
|
||||
Ok(false)
|
||||
fn render(&mut self, _: &mut AppState, _: &mut RenderResources) -> anyhow::Result<()> {
|
||||
unreachable!()
|
||||
}
|
||||
fn frame_meta(&mut self) -> Option<FrameMeta> {
|
||||
Some(FrameMeta {
|
||||
|
||||
@@ -29,14 +29,18 @@ use crate::{
|
||||
BackendError,
|
||||
},
|
||||
config::save_state,
|
||||
graphics::{init_openvr_graphics, CommandBuffers},
|
||||
graphics::{init_openvr_graphics, GpuFutures},
|
||||
overlays::{
|
||||
toast::{Toast, ToastTopic},
|
||||
watch::{watch_fade, WATCH_NAME},
|
||||
},
|
||||
state::AppState,
|
||||
subsystem::notifications::NotificationManager,
|
||||
windowing::{backend::ShouldRender, manager::OverlayWindowManager, window::OverlayWindowData},
|
||||
windowing::{
|
||||
backend::{RenderResources, ShouldRender},
|
||||
manager::OverlayWindowManager,
|
||||
window::OverlayWindowData,
|
||||
},
|
||||
};
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
@@ -311,7 +315,7 @@ pub fn openvr_run(
|
||||
}
|
||||
|
||||
app.hid_provider.inner.commit();
|
||||
let mut buffers = CommandBuffers::default();
|
||||
let mut futures = GpuFutures::default();
|
||||
|
||||
lines.update(universe.clone(), &mut overlay_mgr, &mut app)?;
|
||||
|
||||
@@ -338,26 +342,17 @@ pub fn openvr_run(
|
||||
let ShouldRender::Should = o.should_render(&mut app)? else {
|
||||
continue;
|
||||
};
|
||||
if !o.ensure_image_allocated(&mut app)? {
|
||||
continue;
|
||||
}
|
||||
o.data.image_dirty = o.render(
|
||||
&mut app,
|
||||
o.data.image_view.as_ref().unwrap().clone(),
|
||||
&mut buffers,
|
||||
1.0, // alpha is instead set using OVR API
|
||||
)?;
|
||||
let meta = o.config.backend.frame_meta().unwrap();
|
||||
let tgt = o.ensure_staging_image(&mut app, meta.extent)?;
|
||||
let mut rdr = RenderResources::new(app.gfx.clone(), tgt, &meta, 1.0)?;
|
||||
o.render(&mut app, &mut rdr)?;
|
||||
o.data.image_dirty = true;
|
||||
futures.execute(rdr.end()?)?;
|
||||
}
|
||||
}
|
||||
|
||||
log::trace!("Rendering overlays");
|
||||
|
||||
if let Some(mut future) = buffers.execute_now(app.gfx.queue_gfx.clone())? {
|
||||
if let Err(e) = future.flush() {
|
||||
return Err(BackendError::Fatal(e.into()));
|
||||
}
|
||||
future.cleanup_finished();
|
||||
}
|
||||
futures.wait()?;
|
||||
|
||||
overlays
|
||||
.values_mut()
|
||||
|
||||
@@ -62,21 +62,33 @@ impl OverlayWindowData<OpenVrOverlayData> {
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
pub(super) fn ensure_image_allocated(&mut self, app: &mut AppState) -> anyhow::Result<bool> {
|
||||
if self.data.image_view.is_some() {
|
||||
return Ok(true);
|
||||
pub(super) fn ensure_staging_image(
|
||||
&mut self,
|
||||
app: &mut AppState,
|
||||
extent: [u32; 3],
|
||||
) -> anyhow::Result<Arc<ImageView>> {
|
||||
if let Some(image_view) = self.data.image_view.as_ref()
|
||||
&& image_view.image().extent() == extent
|
||||
{
|
||||
return Ok(image_view.clone());
|
||||
}
|
||||
let Some(meta) = self.config.backend.frame_meta() else {
|
||||
return Ok(false);
|
||||
};
|
||||
|
||||
log::debug!(
|
||||
"{}: recreating staging image at {}x{}",
|
||||
self.config.name,
|
||||
extent[0],
|
||||
extent[1],
|
||||
);
|
||||
|
||||
let image = app.gfx.new_image(
|
||||
meta.extent[0],
|
||||
meta.extent[1],
|
||||
extent[0],
|
||||
extent[1],
|
||||
app.gfx.surface_format,
|
||||
ImageUsage::TRANSFER_SRC | ImageUsage::COLOR_ATTACHMENT | ImageUsage::SAMPLED,
|
||||
)?;
|
||||
self.data.image_view = Some(ImageView::new_default(image)?);
|
||||
Ok(true)
|
||||
let image_view = ImageView::new_default(image)?;
|
||||
self.data.image_view = Some(image_view.clone());
|
||||
Ok(image_view)
|
||||
}
|
||||
|
||||
pub(super) fn after_input(
|
||||
|
||||
@@ -18,7 +18,7 @@ use wgui::gfx::{
|
||||
|
||||
use crate::{
|
||||
backend::openxr::helpers,
|
||||
graphics::{CommandBuffers, Vert2Uv},
|
||||
graphics::{GpuFutures, Vert2Uv},
|
||||
state::AppState,
|
||||
};
|
||||
use vulkano::{
|
||||
@@ -152,7 +152,7 @@ impl LinePool {
|
||||
pub(super) fn render(
|
||||
&mut self,
|
||||
app: &AppState,
|
||||
buf: &mut CommandBuffers,
|
||||
futures: &mut GpuFutures,
|
||||
) -> anyhow::Result<()> {
|
||||
for line in self.lines.values_mut() {
|
||||
if let Some(inner) = line.maybe_line.as_mut() {
|
||||
@@ -167,7 +167,7 @@ impl LinePool {
|
||||
cmd_buffer.run_ref(&self.pass)?;
|
||||
cmd_buffer.end_rendering()?;
|
||||
|
||||
buf.push(cmd_buffer.build()?);
|
||||
futures.execute((cmd_buffer.queue.clone(), cmd_buffer.build()?))?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,14 +23,18 @@ use crate::{
|
||||
BackendError,
|
||||
},
|
||||
config::save_state,
|
||||
graphics::{init_openxr_graphics, CommandBuffers},
|
||||
graphics::{init_openxr_graphics, GpuFutures},
|
||||
overlays::{
|
||||
toast::{Toast, ToastTopic},
|
||||
watch::{watch_fade, WATCH_NAME},
|
||||
},
|
||||
state::AppState,
|
||||
subsystem::notifications::NotificationManager,
|
||||
windowing::{backend::ShouldRender, manager::OverlayWindowManager, window::OverlayWindowData},
|
||||
windowing::{
|
||||
backend::{RenderResources, ShouldRender},
|
||||
manager::OverlayWindowManager,
|
||||
window::OverlayWindowData,
|
||||
},
|
||||
};
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
@@ -378,10 +382,10 @@ pub fn openxr_run(
|
||||
}
|
||||
|
||||
// Begin rendering
|
||||
let mut buffers = CommandBuffers::default();
|
||||
let mut futures = GpuFutures::default();
|
||||
|
||||
if !main_session_visible && let Some(skybox) = skybox.as_mut() {
|
||||
skybox.render(&xr_state, &app, &mut buffers)?;
|
||||
skybox.render(&xr_state, &app, &mut futures)?;
|
||||
}
|
||||
|
||||
for o in overlays.values_mut() {
|
||||
@@ -402,30 +406,20 @@ pub fn openxr_run(
|
||||
};
|
||||
|
||||
if should_render {
|
||||
if !o.ensure_swapchain(&app, &xr_state)? {
|
||||
continue;
|
||||
}
|
||||
let tgt = o.data.swapchain.as_mut().unwrap().acquire_wait_image()?; // want
|
||||
if !o.render(&mut app, tgt, &mut buffers, alpha)? {
|
||||
o.data.swapchain.as_mut().unwrap().ensure_image_released()?; // want
|
||||
continue;
|
||||
}
|
||||
let meta = o.config.backend.frame_meta().unwrap(); // want panic
|
||||
let tgt = o.ensure_swapchain_acquire(&app, &xr_state, meta.extent)?;
|
||||
let mut rdr = RenderResources::new(app.gfx.clone(), tgt, &meta, alpha)?;
|
||||
o.render(&mut app, &mut rdr)?;
|
||||
o.data.last_alpha = alpha;
|
||||
futures.execute(rdr.end()?)?;
|
||||
} else if o.data.swapchain.is_none() {
|
||||
continue;
|
||||
}
|
||||
o.data.cur_visible = true;
|
||||
}
|
||||
|
||||
lines.render(&app, &mut buffers)?;
|
||||
|
||||
let future = buffers.execute_now(app.gfx.queue_gfx.clone())?;
|
||||
if let Some(mut future) = future {
|
||||
if let Err(e) = future.flush() {
|
||||
return Err(BackendError::Fatal(e.into()));
|
||||
}
|
||||
future.cleanup_finished();
|
||||
}
|
||||
lines.render(&app, &mut futures)?;
|
||||
futures.wait()?;
|
||||
// End rendering
|
||||
|
||||
// Layer composition
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use glam::Vec3A;
|
||||
use openxr::{self as xr, CompositionLayerFlags};
|
||||
use std::f32::consts::PI;
|
||||
use std::{f32::consts::PI, sync::Arc};
|
||||
use vulkano::image::view::ImageView;
|
||||
use xr::EyeVisibility;
|
||||
|
||||
use super::{CompositionLayer, XrState, helpers, swapchain::WlxSwapchain};
|
||||
use super::{helpers, swapchain::WlxSwapchain, CompositionLayer, XrState};
|
||||
use crate::{
|
||||
backend::openxr::swapchain::{SwapchainOpts, create_swapchain},
|
||||
backend::openxr::swapchain::{create_swapchain, SwapchainOpts},
|
||||
state::AppState,
|
||||
windowing::window::OverlayWindowData,
|
||||
};
|
||||
@@ -20,41 +21,28 @@ pub struct OpenXrOverlayData {
|
||||
}
|
||||
|
||||
impl OverlayWindowData<OpenXrOverlayData> {
|
||||
pub(super) fn ensure_swapchain<'a>(
|
||||
pub(super) fn ensure_swapchain_acquire<'a>(
|
||||
&'a mut self,
|
||||
app: &AppState,
|
||||
xr: &'a XrState,
|
||||
) -> anyhow::Result<bool> {
|
||||
let Some(meta) = self.frame_meta() else {
|
||||
log::warn!(
|
||||
"{}: swapchain cannot be created due to missing metadata",
|
||||
self.config.name
|
||||
);
|
||||
return Ok(false);
|
||||
};
|
||||
|
||||
if self
|
||||
.data
|
||||
.swapchain
|
||||
.as_ref()
|
||||
.is_some_and(|s| s.extent == meta.extent)
|
||||
extent: [u32; 3],
|
||||
) -> anyhow::Result<Arc<ImageView>> {
|
||||
if let Some(swapchain) = self.data.swapchain.as_mut()
|
||||
&& swapchain.extent == extent
|
||||
{
|
||||
return Ok(true);
|
||||
return Ok(swapchain.acquire_wait_image()?);
|
||||
}
|
||||
|
||||
log::debug!(
|
||||
"{}: recreating swapchain at {}x{}",
|
||||
self.config.name,
|
||||
meta.extent[0],
|
||||
meta.extent[1],
|
||||
extent[0],
|
||||
extent[1],
|
||||
);
|
||||
self.data.swapchain = Some(create_swapchain(
|
||||
xr,
|
||||
app.gfx.clone(),
|
||||
meta.extent,
|
||||
SwapchainOpts::new(),
|
||||
)?);
|
||||
Ok(true)
|
||||
let mut swapchain = create_swapchain(xr, app.gfx.clone(), extent, SwapchainOpts::new())?;
|
||||
let tgt = swapchain.acquire_wait_image()?;
|
||||
self.data.swapchain = Some(swapchain);
|
||||
Ok(tgt)
|
||||
}
|
||||
|
||||
pub(super) fn present<'a>(
|
||||
|
||||
@@ -15,7 +15,7 @@ use wgui::gfx::{cmd::WGfxClearMode, pipeline::WPipelineCreateInfo};
|
||||
use crate::{
|
||||
backend::openxr::{helpers::translation_rotation_to_posef, swapchain::SwapchainOpts},
|
||||
config_io,
|
||||
graphics::{dds::WlxCommandBufferDds, CommandBuffers, ExtentExt},
|
||||
graphics::{dds::WlxCommandBufferDds, ExtentExt, GpuFutures},
|
||||
state::AppState,
|
||||
};
|
||||
|
||||
@@ -85,7 +85,7 @@ impl Skybox {
|
||||
&'a mut self,
|
||||
xr: &'a XrState,
|
||||
app: &AppState,
|
||||
buf: &mut CommandBuffers,
|
||||
futures: &mut GpuFutures,
|
||||
) -> anyhow::Result<()> {
|
||||
if self.sky.is_some() {
|
||||
return Ok(());
|
||||
@@ -119,7 +119,7 @@ impl Skybox {
|
||||
cmd_buffer.run_ref(&pass)?;
|
||||
cmd_buffer.end_rendering()?;
|
||||
|
||||
buf.push(cmd_buffer.build()?);
|
||||
futures.execute((cmd_buffer.queue.clone(), cmd_buffer.build()?))?;
|
||||
|
||||
self.sky = Some(swapchain);
|
||||
Ok(())
|
||||
@@ -129,7 +129,7 @@ impl Skybox {
|
||||
&'a mut self,
|
||||
xr: &'a XrState,
|
||||
app: &AppState,
|
||||
buf: &mut CommandBuffers,
|
||||
futures: &mut GpuFutures,
|
||||
) -> anyhow::Result<()> {
|
||||
if self.grid.is_some() {
|
||||
return Ok(());
|
||||
@@ -165,7 +165,7 @@ impl Skybox {
|
||||
cmd_buffer.run_ref(&pass)?;
|
||||
cmd_buffer.end_rendering()?;
|
||||
|
||||
buf.push(cmd_buffer.build()?);
|
||||
futures.execute((cmd_buffer.queue.clone(), cmd_buffer.build()?))?;
|
||||
|
||||
self.grid = Some(swapchain);
|
||||
Ok(())
|
||||
@@ -175,7 +175,7 @@ impl Skybox {
|
||||
&mut self,
|
||||
xr: &XrState,
|
||||
app: &AppState,
|
||||
buf: &mut CommandBuffers,
|
||||
buf: &mut GpuFutures,
|
||||
) -> anyhow::Result<()> {
|
||||
self.prepare_sky(xr, app, buf)?;
|
||||
self.prepare_grid(xr, app, buf)?;
|
||||
|
||||
Reference in New Issue
Block a user