1pub mod core;
2pub mod gfx_pipeline;
3pub mod renderer;
4pub mod resources;
5pub mod timestamps;
6
7pub use core::debug::DebugMessenger;
8pub use core::device::Device;
9pub use core::instance::Instance;
10pub use core::swapchain::Swapchain;
11pub use gfx_pipeline::Pipeline;
12pub use renderer::{build_dyn_renderer, DynRenderer, Renderer};
13pub use resources::bindless::BindlessSet;
14pub use resources::mapped_buffer::MappedGpuBuffer;
15pub use resources::texture::GpuTexture;
16
17use crate::EngineFlags;
18use ash::ext::debug_utils;
19use ash::vk;
20use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
21use std::sync::Arc;
22
23pub struct VulkanContext {
24 pub swapchain: Option<Swapchain>,
25 pub device: Arc<Device>,
26 pub surface: vk::SurfaceKHR,
27 _debug: Option<DebugMessenger>,
28 pub debug_utils: Option<Arc<debug_utils::Device>>,
29 pub instance: Arc<Instance>,
30}
31
32impl VulkanContext {
33 pub fn from_handles(
34 display: RawDisplayHandle,
35 window: RawWindowHandle,
36 flags: EngineFlags,
37 ) -> anyhow::Result<Self> {
38 let instance = Arc::new(Instance::new(display, flags.validation, flags.debug_labels)?);
39
40 let validation_active = instance.validation_active;
41 let debug_utils_active = instance.debug_utils_active;
42
43 let debug = if validation_active {
44 Some(DebugMessenger::new(&instance)?)
45 } else {
46 None
47 };
48
49 let surface = unsafe { ash_window::create_surface(&instance.entry, &instance.handle, display, window, None)? };
50
51 let device = Arc::new(Device::new(&instance, surface)?);
52
53 let swapchain = Swapchain::new(&instance, &device, surface, 1280, 720, false)?;
54
55 let debug_utils = if debug_utils_active {
56 Some(Arc::new(debug_utils::Device::new(&instance.handle, &device.handle)))
57 } else {
58 None
59 };
60
61 Ok(Self { swapchain: Some(swapchain), debug_utils, device, surface, _debug: debug, instance })
62 }
63
64 pub fn new(window: &winit::window::Window, flags: EngineFlags) -> anyhow::Result<Self> {
65 use winit::raw_window_handle::{HasDisplayHandle, HasWindowHandle};
66 let display = window.display_handle()?.as_raw();
67 let whandle = window.window_handle()?.as_raw();
68 let size = window.inner_size();
69
70 let mut ctx = Self::from_handles(display, whandle, flags)?;
71 ctx.recreate_swapchain(size.width, size.height, false)?;
72 Ok(ctx)
73 }
74
75 pub fn recreate_swapchain(&mut self, width: u32, height: u32, vsync: bool) -> anyhow::Result<()> {
76 unsafe { self.device.handle.device_wait_idle()? };
77 drop(self.swapchain.take());
78 self.swapchain = Some(Swapchain::new(&self.instance, &self.device, self.surface, width, height, vsync)?);
79 Ok(())
80 }
81}
82
83impl Drop for VulkanContext {
84 fn drop(&mut self) {
85 unsafe {
86 self.device.handle.device_wait_idle().ok();
87 drop(self.swapchain.take());
88 let surface_loader = ash::khr::surface::Instance::new(&self.instance.entry, &self.instance.handle);
89 surface_loader.destroy_surface(self.surface, None);
90 }
91 }
92}