removed winit dependency from renderer and included raw window handle

This commit is contained in:
Janis 2024-12-21 17:29:08 +01:00
parent 28c6cc35f3
commit 7b7badd4d4
6 changed files with 155 additions and 72 deletions

View file

@ -17,7 +17,6 @@ tracing = "0.1.40"
tracing-subscriber = "0.3.18" tracing-subscriber = "0.3.18"
vk-mem = "0.4.0" vk-mem = "0.4.0"
vk-sync = "0.1.6" vk-sync = "0.1.6"
winit = "0.30.5"
tinyvec = "1.8" tinyvec = "1.8"
rand = "0.8.5" rand = "0.8.5"
tokio = "1.42.0" tokio = "1.42.0"
@ -25,3 +24,9 @@ tokio = "1.42.0"
futures = "0.3" futures = "0.3"
smol = "2.0" smol = "2.0"
rayon = "1.10" rayon = "1.10"
winit = {version = "0.30.5", features = ["rwh_06"]}
raw-window-handle = "0.6"
egui = "0.30.0"
egui_winit_platform = "0.24.0"

View file

@ -8,3 +8,6 @@ winit = { workspace = true }
tracing = { workspace = true } tracing = { workspace = true }
tracing-subscriber = { workspace = true } tracing-subscriber = { workspace = true }
renderer = { path = "../renderer" } renderer = { path = "../renderer" }
egui = { workspace = true }
egui_winit_platform = { workspace = true }

View file

@ -12,21 +12,31 @@ use winit::{
}; };
struct WindowState { struct WindowState {
last_resize_events: BTreeMap<WindowId, PhysicalSize<u32>>, window: Window,
window_attrs: WindowAttributes, egui_platform: egui_winit_platform::Platform,
windows: BTreeMap<WindowId, Window>,
renderer: Renderer,
} }
impl WindowState { struct WinitState {
fn new(window_title: String, display: DisplayHandle) -> WindowState { last_resize_events: BTreeMap<WindowId, PhysicalSize<u32>>,
window_attrs: WindowAttributes,
windows2: BTreeMap<WindowId, WindowState>,
renderer: Renderer<WindowId>,
}
impl WinitState {
const BASE_WIDTH: u32 = 800;
const BASE_HEIGHT: u32 = 600;
fn new(window_title: String, display: DisplayHandle) -> WinitState {
Self { Self {
windows: BTreeMap::new(), windows2: BTreeMap::new(),
last_resize_events: BTreeMap::new(), last_resize_events: BTreeMap::new(),
window_attrs: WindowAttributes::default() window_attrs: WindowAttributes::default()
.with_title(window_title) .with_title(window_title)
.with_resizable(true) .with_resizable(true)
.with_inner_size(LogicalSize::new(800, 600)), .with_inner_size(LogicalSize::new(
Self::BASE_WIDTH,
Self::BASE_HEIGHT,
)),
// TODO: pass down this error and add some kind of error handling UI or dump // TODO: pass down this error and add some kind of error handling UI or dump
renderer: Renderer::new(display.as_raw()).expect("renderer"), renderer: Renderer::new(display.as_raw()).expect("renderer"),
} }
@ -54,7 +64,30 @@ impl WindowState {
window_id = u64::from(window_id), window_id = u64::from(window_id),
"TODO: implement draw request" "TODO: implement draw request"
); );
self.renderer.debug_draw().expect("drawing"); if let Some(window) = self.windows2.get_mut(&window_id) {
// egui
window.egui_platform.begin_frame();
let output = window.egui_platform.end_frame(Some(&window.window));
let _draw_data = window
.egui_platform
.context()
.tessellate(output.shapes, output.pixels_per_point);
// rendering
self.renderer
.debug_draw(&window_id, || window.window.pre_present_notify())
.expect("drawing");
window.window.request_redraw();
}
}
fn remove_window(&mut self, window_id: WindowId) {
tracing::info!(window = u64::from(window_id), "window close requested");
self.windows2.remove(&window_id);
self.renderer.window_contexts.remove(&window_id);
} }
fn create_window( fn create_window(
@ -87,11 +120,24 @@ impl WindowState {
window.window_handle().expect("window handle"), window.window_handle().expect("window handle"),
); );
self.windows.insert(window.id(), window); self.windows2.insert(
window_id,
WindowState {
window,
egui_platform: egui_winit_platform::Platform::new(
egui_winit_platform::PlatformDescriptor {
physical_width: size.width,
physical_height: size.height,
scale_factor: 1.0,
..Default::default()
},
),
},
);
} }
} }
impl ApplicationHandler for WindowState { impl ApplicationHandler for WinitState {
fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) { fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
tracing::info!("winit::resumed"); tracing::info!("winit::resumed");
@ -100,13 +146,17 @@ impl ApplicationHandler for WindowState {
fn about_to_wait( fn about_to_wait(
&mut self, &mut self,
_event_loop: &winit::event_loop::ActiveEventLoop, event_loop: &winit::event_loop::ActiveEventLoop,
) { ) {
tracing::info!("winit::about_to_wait"); tracing::info!("winit::about_to_wait");
for (&window, &resize) in self.last_resize_events.clone().iter() { for (&window, &resize) in self.last_resize_events.clone().iter() {
self.handle_final_resize(window, resize); self.handle_final_resize(window, resize);
} }
self.last_resize_events.clear(); self.last_resize_events.clear();
if self.windows2.is_empty() {
event_loop.exit();
}
} }
fn window_event( fn window_event(
@ -115,28 +165,35 @@ impl ApplicationHandler for WindowState {
window_id: winit::window::WindowId, window_id: winit::window::WindowId,
event: winit::event::WindowEvent, event: winit::event::WindowEvent,
) { ) {
if !matches!(event, winit::event::WindowEvent::Resized(_)) { // if !matches!(event, winit::event::WindowEvent::Resized(_)) {
if let Some(resize) = self.last_resize_events.remove(&window_id) { // if let Some(resize) = self.last_resize_events.remove(&window_id) {
self.handle_final_resize(window_id, resize); // self.handle_final_resize(window_id, resize);
} // }
// }
if let Some(window) = self.windows2.get_mut(&window_id) {
window.egui_platform.handle_event(&event);
} }
match event { match event {
winit::event::WindowEvent::Resized(physical_size) => { winit::event::WindowEvent::Resized(physical_size) => {
_ = self.last_resize_events.insert(window_id, physical_size); _ = self.last_resize_events.insert(window_id, physical_size);
} }
winit::event::WindowEvent::CloseRequested => { winit::event::WindowEvent::CloseRequested
tracing::info!( | winit::event::WindowEvent::KeyboardInput {
window = u64::from(window_id), event:
"window close requested" winit::event::KeyEvent {
); physical_key:
winit::keyboard::PhysicalKey::Code(
self.windows.remove(&window_id); winit::keyboard::KeyCode::KeyQ,
self.renderer.window_contexts.remove(&window_id); ),
state: ElementState::Pressed,
if self.windows.is_empty() { repeat: false,
event_loop.exit(); ..
} },
..
} => {
self.remove_window(window_id);
} }
winit::event::WindowEvent::KeyboardInput { winit::event::WindowEvent::KeyboardInput {
event: event:
@ -153,30 +210,6 @@ impl ApplicationHandler for WindowState {
} => { } => {
self.create_window(event_loop); self.create_window(event_loop);
} }
winit::event::WindowEvent::KeyboardInput {
event:
winit::event::KeyEvent {
physical_key:
winit::keyboard::PhysicalKey::Code(
winit::keyboard::KeyCode::KeyQ,
),
state: ElementState::Pressed,
repeat: false,
..
},
..
} => {
tracing::info!(
window = u64::from(window_id),
"window close requested"
);
self.windows.remove(&window_id);
self.renderer.window_contexts.remove(&window_id);
if self.windows.is_empty() {
event_loop.exit();
}
}
winit::event::WindowEvent::KeyboardInput { winit::event::WindowEvent::KeyboardInput {
device_id, device_id,
event, event,
@ -199,9 +232,6 @@ impl ApplicationHandler for WindowState {
} }
winit::event::WindowEvent::RedrawRequested => { winit::event::WindowEvent::RedrawRequested => {
self.handle_draw_request(window_id); self.handle_draw_request(window_id);
if let Some(window) = self.windows.get(&window_id) {
window.request_redraw();
}
} }
_ => {} // unhandled event _ => {} // unhandled event
} }
@ -214,6 +244,6 @@ fn main() {
ev.set_control_flow(winit::event_loop::ControlFlow::Poll); ev.set_control_flow(winit::event_loop::ControlFlow::Poll);
let display = ev.display_handle().expect("display handle"); let display = ev.display_handle().expect("display handle");
let mut game = WindowState::new("Vidya".to_owned(), display); let mut game = WinitState::new("Vidya".to_owned(), display);
ev.run_app(&mut game).unwrap(); ev.run_app(&mut game).unwrap();
} }

View file

@ -17,8 +17,11 @@ tracing = "0.1.40"
tracing-subscriber = "0.3.18" tracing-subscriber = "0.3.18"
vk-mem = "0.4.0" vk-mem = "0.4.0"
vk-sync = "0.1.6" vk-sync = "0.1.6"
winit = "0.30.5"
crossbeam = "0.8.4" crossbeam = "0.8.4"
parking_lot = "0.12.3" parking_lot = "0.12.3"
smol.workspace = true smol.workspace = true
tracing-test = "0.2.5" tracing-test = "0.2.5"
raw-window-handle = { workspace = true }
egui = { workspace = true }
egui_winit_platform = { workspace = true }

View file

@ -29,12 +29,13 @@ use ash::{
}; };
use dyn_clone::DynClone; use dyn_clone::DynClone;
use rand::{Rng, SeedableRng}; use rand::{Rng, SeedableRng};
use raw_window_handle::{DisplayHandle, RawDisplayHandle};
use tinyvec::{array_vec, ArrayVec}; use tinyvec::{array_vec, ArrayVec};
use tracing::info; use tracing::info;
use winit::raw_window_handle::{DisplayHandle, RawDisplayHandle};
mod commands; mod commands;
mod images; mod images;
mod render_graph;
mod sync; mod sync;
type VkAllocator = Arc<vk_mem::Allocator>; type VkAllocator = Arc<vk_mem::Allocator>;
@ -1166,7 +1167,7 @@ impl Surface {
fn create( fn create(
instance: Arc<Instance>, instance: Arc<Instance>,
display_handle: RawDisplayHandle, display_handle: RawDisplayHandle,
window_handle: winit::raw_window_handle::RawWindowHandle, window_handle: raw_window_handle::RawWindowHandle,
) -> Result<Self> { ) -> Result<Self> {
let surface = unsafe { let surface = unsafe {
ash_window::create_surface( ash_window::create_surface(
@ -1887,7 +1888,7 @@ impl Vulkan {
} }
} }
use winit::raw_window_handle::RawWindowHandle; use raw_window_handle::RawWindowHandle;
pub struct WindowContext { pub struct WindowContext {
window_handle: RawWindowHandle, window_handle: RawWindowHandle,
@ -1935,7 +1936,7 @@ impl WindowContext {
instance: Arc<Instance>, instance: Arc<Instance>,
device: Device, device: Device,
extent: vk::Extent2D, extent: vk::Extent2D,
window_handle: winit::raw_window_handle::RawWindowHandle, window_handle: raw_window_handle::RawWindowHandle,
display: RawDisplayHandle, display: RawDisplayHandle,
) -> Result<Self> { ) -> Result<Self> {
let surface = Arc::new(Surface::create( let surface = Arc::new(Surface::create(
@ -2005,15 +2006,15 @@ impl WindowContext {
} }
} }
pub struct Renderer { pub struct Renderer<W> {
vulkan: Vulkan, vulkan: Vulkan,
display: RawDisplayHandle, display: RawDisplayHandle,
pub window_contexts: HashMap<winit::window::WindowId, WindowContext>, pub window_contexts: HashMap<W, WindowContext>,
} }
pub use vk::Extent2D; pub use vk::Extent2D;
impl Renderer { impl<W> Renderer<W> {
pub fn new(display: RawDisplayHandle) -> Result<Self> { pub fn new(display: RawDisplayHandle) -> Result<Self> {
let vulkan = Vulkan::new("Vidya", &[], &[], Some(display))?; let vulkan = Vulkan::new("Vidya", &[], &[], Some(display))?;
Ok(Self { Ok(Self {
@ -2023,7 +2024,15 @@ impl Renderer {
}) })
} }
pub fn debug_draw(&mut self) -> Result<()> { pub fn debug_draw<K, F: FnOnce()>(
&mut self,
window: &K,
pre_present_cb: F,
) -> Result<()>
where
K: core::hash::Hash + Eq,
W: core::hash::Hash + Eq + Borrow<K>,
{
let dev = self.vulkan.device.clone(); let dev = self.vulkan.device.clone();
unsafe { dev.dev().device_wait_idle()? }; unsafe { dev.dev().device_wait_idle()? };
@ -2033,7 +2042,7 @@ impl Renderer {
dev.graphics_queue().clone(), dev.graphics_queue().clone(),
)?; )?;
for ctx in self.window_contexts.values() { if let Some(ctx) = self.window_contexts.get(window) {
let cmd = pool.alloc()?; let cmd = pool.alloc()?;
let buffer = cmd.buffer(); let buffer = cmd.buffer();
@ -2125,6 +2134,9 @@ impl Renderer {
Arc::new(sync::Fence::create(dev.clone())?), Arc::new(sync::Fence::create(dev.clone())?),
)?; )?;
// call pre_present_notify
pre_present_cb();
frame.present(); frame.present();
future.block()?; future.block()?;
@ -2139,9 +2151,12 @@ impl Renderer {
pub fn new_window_context( pub fn new_window_context(
&mut self, &mut self,
extent: vk::Extent2D, extent: vk::Extent2D,
window_id: winit::window::WindowId, window_id: W,
window: winit::raw_window_handle::WindowHandle, window: raw_window_handle::WindowHandle,
) -> Result<()> { ) -> Result<()>
where
W: core::hash::Hash + Eq,
{
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
match self.window_contexts.entry(window_id) { match self.window_contexts.entry(window_id) {
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
@ -2827,7 +2842,7 @@ mod test_swapchain {
let window_ctx = WindowContext { let window_ctx = WindowContext {
window_handle: RawWindowHandle::Web( window_handle: RawWindowHandle::Web(
winit::raw_window_handle::WebWindowHandle::new(0), raw_window_handle::WebWindowHandle::new(0),
), ),
surface, surface,
current_swapchain: RwLock::new(swapchain), current_swapchain: RwLock::new(swapchain),

View file

@ -0,0 +1,27 @@
use ash::vk;
struct Rgba([f32;4]);
enum LoadOp {
Clear(Rgba),
Load,
DontCare,
}
enum StoreOp {
DontCare,Store,
}
struct AttachmentInfo {
size: glam::UVec2,
format: vk::Format,
load: LoadOp,
store: StoreOp,
}
struct Texture {
texture: vk::Image,
}
pub struct RenderGraph {
}