removed winit dependency from renderer and included raw window handle
This commit is contained in:
parent
28c6cc35f3
commit
7b7badd4d4
|
@ -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"
|
|
@ -7,4 +7,7 @@ edition = "2021"
|
||||||
winit = { workspace = true }
|
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 }
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 }
|
|
@ -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),
|
||||||
|
|
27
crates/renderer/src/render_graph.rs
Normal file
27
crates/renderer/src/render_graph.rs
Normal 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 {
|
||||||
|
}
|
Loading…
Reference in a new issue