diff --git a/src/backend/openxr/overlay.rs b/src/backend/openxr/overlay.rs index ac7cad38..1cf55fd3 100644 --- a/src/backend/openxr/overlay.rs +++ b/src/backend/openxr/overlay.rs @@ -4,7 +4,6 @@ use super::XrState; use crate::{ backend::overlay::OverlayData, graphics::{WlxPass, WlxPipeline}, - shaders::{frag_srgb, vert_common}, state::AppState, }; use ash::vk::{self}; @@ -31,6 +30,12 @@ impl OverlayData { self.data.inner = { let extent = my_view.image().extent(); + log::info!( + "{}: Create swapchain {}x{}", + self.state.name, + extent[0], + extent[1] + ); let swapchain = xr .session @@ -73,10 +78,13 @@ impl OverlayData { let view = ImageView::new_default(image).unwrap(); // HACK: maybe not create one pipeline per image? + + let shaders = state.graphics.shared_shaders.read().unwrap(); + let pipeline = state.graphics.create_pipeline( view.clone(), - vert_common::load(state.graphics.device.clone()).unwrap(), - frag_srgb::load(state.graphics.device.clone()).unwrap(), + shaders.get("vert_common").unwrap().clone(), + shaders.get("frag_srgb").unwrap().clone(), state.graphics.native_format, ); let set = pipeline.uniform_sampler(0, my_view.clone(), Filter::Linear); diff --git a/src/graphics.rs b/src/graphics.rs index 56a27830..687b0473 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -1,9 +1,10 @@ use std::{ + collections::HashMap, error::Error, io::Cursor, os::fd::{FromRawFd, IntoRawFd}, slice::Iter, - sync::Arc, + sync::{Arc, RwLock}, }; use ash::vk::{self, SubmitInfo}; @@ -100,6 +101,9 @@ pub struct WlxGraphics { pub quad_verts: Subbuffer<[Vert2Uv]>, pub quad_indices: Subbuffer<[u16]>, + + pub shared_shaders: RwLock>>, + pub shared_images: RwLock>>, } impl WlxGraphics { @@ -258,6 +262,8 @@ impl WlxGraphics { descriptor_set_allocator, quad_indices, quad_verts, + shared_images: RwLock::new(HashMap::new()), + shared_shaders: RwLock::new(HashMap::new()), }; Arc::new(me) @@ -380,6 +386,8 @@ impl WlxGraphics { descriptor_set_allocator, quad_indices, quad_verts, + shared_images: RwLock::new(HashMap::new()), + shared_shaders: RwLock::new(HashMap::new()), }; Arc::new(me) diff --git a/src/gui/mod.rs b/src/gui/mod.rs index bf710bd6..fb3fbc36 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -13,7 +13,6 @@ use crate::{ overlay::{OverlayBackend, OverlayRenderer}, }, graphics::{WlxCommandBuffer, WlxGraphics, WlxPass, WlxPipeline}, - shaders::{frag_color, frag_glyph, frag_sprite, vert_common}, state::AppState, }; @@ -226,17 +225,19 @@ impl Canvas { let view_bg = ImageView::new_default(tex_bg.clone()).unwrap(); let view_final = ImageView::new_default(tex_final.clone()).unwrap(); + let shaders = graphics.shared_shaders.read().unwrap(); + let pipeline_bg_color = graphics.create_pipeline( view_bg.clone(), - vert_common::load(graphics.device.clone()).unwrap(), - frag_color::load(graphics.device.clone()).unwrap(), + shaders.get("vert_common").unwrap().clone(), + shaders.get("frag_color").unwrap().clone(), format, ); let pipeline_fg_glyph = graphics.create_pipeline( view_fg.clone(), - vert_common::load(graphics.device.clone()).unwrap(), - frag_glyph::load(graphics.device.clone()).unwrap(), + shaders.get("vert_common").unwrap().clone(), + shaders.get("frag_glyph").unwrap().clone(), format, ); @@ -245,8 +246,8 @@ impl Canvas { let pipeline_final = graphics.create_pipeline_with_layouts( view_final.clone(), - vert_common::load(graphics.device.clone()).unwrap(), - frag_sprite::load(graphics.device.clone()).unwrap(), + shaders.get("vert_common").unwrap().clone(), + shaders.get("frag_sprite").unwrap().clone(), format, ImageLayout::TransferSrcOptimal, ImageLayout::TransferSrcOptimal, @@ -275,7 +276,7 @@ impl Canvas { data, width, height, - graphics, + graphics: graphics.clone(), pipeline_bg_color, pipeline_fg_glyph, pipeline_final, diff --git a/src/overlays/screen.rs b/src/overlays/screen.rs index 451be471..42cb0081 100644 --- a/src/overlays/screen.rs +++ b/src/overlays/screen.rs @@ -32,7 +32,6 @@ use crate::{ }, graphics::{fourcc_to_vk, Vert2Uv, WlxGraphics, WlxPipeline}, hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT}, - shaders::{frag_screen, vert_common}, state::{AppSession, AppState}, }; @@ -127,14 +126,18 @@ impl ScreenPipeline { let view = ImageView::new_default(render_texture).unwrap(); - let pipeline = graphics.create_pipeline( - view, - vert_common::load(graphics.device.clone()).unwrap(), - frag_screen::load(graphics.device.clone()).unwrap(), - Format::R8G8B8A8_UNORM, - // ImageLayout::TransferSrcOptimal, - // ImageLayout::TransferSrcOptimal, - ); + let pipeline = { + let shaders = graphics.shared_shaders.read().unwrap(); + + graphics.create_pipeline( + view, + shaders.get("vert_common").unwrap().clone(), + shaders.get("frag_screen").unwrap().clone(), + Format::R8G8B8A8_UNORM, + // ImageLayout::TransferSrcOptimal, + // ImageLayout::TransferSrcOptimal, + ) + }; Self { graphics, diff --git a/src/state.rs b/src/state.rs index 00d926c3..824b7120 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,13 +1,17 @@ use std::{env::VarError, path::Path, sync::Arc}; use glam::{Quat, Vec3}; -use vulkano::format::Format; +use vulkano::{ + command_buffer::CommandBufferUsage, format::Format, image::view::ImageView, + shader::ShaderModule, +}; use crate::{ backend::{common::TaskContainer, input::InputState}, graphics::WlxGraphics, gui::font::FontCache, hid::HidProvider, + shaders::{frag_color, frag_glyph, frag_screen, frag_sprite, frag_srgb, vert_common}, }; pub const WATCH_DEFAULT_POS: Vec3 = Vec3::new(0., 0., 0.15); @@ -25,6 +29,41 @@ pub struct AppState { impl AppState { pub fn from_graphics(graphics: Arc) -> Self { + // insert shared resources + { + let mut uploads = graphics.create_command_buffer(CommandBufferUsage::OneTimeSubmit); + let texture = uploads.texture2d(1, 1, Format::R8G8B8A8_UNORM, &[255, 0, 255, 255]); + uploads.build_and_execute_now(); + + let Ok(mut images) = graphics.shared_images.write() else { + panic!("Shared Images RwLock poisoned"); + }; + + images.insert("fallback", ImageView::new_default(texture).unwrap()); + + let Ok(mut shaders) = graphics.shared_shaders.write() else { + panic!("Shared Shaders RwLock poisoned"); + }; + + let shader = vert_common::load(graphics.device.clone()).unwrap(); + shaders.insert("vert_common", shader); + + let shader = frag_color::load(graphics.device.clone()).unwrap(); + shaders.insert("frag_color", shader); + + let shader = frag_glyph::load(graphics.device.clone()).unwrap(); + shaders.insert("frag_glyph", shader); + + let shader = frag_screen::load(graphics.device.clone()).unwrap(); + shaders.insert("frag_screen", shader); + + let shader = frag_sprite::load(graphics.device.clone()).unwrap(); + shaders.insert("frag_sprite", shader); + + let shader = frag_srgb::load(graphics.device.clone()).unwrap(); + shaders.insert("frag_srgb", shader); + } + AppState { fc: FontCache::new(), session: AppSession::load(),