Skip to content

Commit

Permalink
Swapchain performance/correctness (#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
attackgoat authored Feb 17, 2025
1 parent 197306b commit 7cde64b
Show file tree
Hide file tree
Showing 19 changed files with 720 additions and 553 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ spirq = "1.2"
vk-sync = { path = "contrib/vk-sync" } #git = "https://github.com/attackgoat/vk-sync-rs.git", rev = "19fc3f811cc1d38b2231cdb8840fddf271879ac1", package = "vk-sync-fork" } #version = "0.4.0", package = "vk-sync-fork" } # // SEE: https://github.com/gwihlidal/vk-sync-rs/pull/4 -> https://github.com/expenses/vk-sync-rs

[target.'cfg(target_os = "macos")'.dependencies]
ash-molten = "0.19"
ash-molten = "0.20"

[dev-dependencies]
anyhow = "1.0"
Expand Down
103 changes: 58 additions & 45 deletions contrib/screen-13-window/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mod frame;
pub use self::frame::FrameContext;

use {
log::{info, warn},
log::{info,trace, warn},
screen_13::{
driver::{
ash::vk,
Expand All @@ -14,7 +14,7 @@ use {
},
graph::RenderGraph,
pool::hash::HashPool,
Display,
Display, DisplayError, DisplayInfoBuilder,
},
std::{error, fmt, sync::Arc},
winit::{
Expand Down Expand Up @@ -67,12 +67,10 @@ impl Window {
}

impl<F> Application<F> {
fn create_display_swapchain(
fn create_display(
&mut self,
window: &winit::window::Window,
) -> Result<(Display, Swapchain), DriverError> {
let display_pool = Box::new(HashPool::new(&self.device));
let display = Display::new(&self.device, display_pool, self.data.cmd_buf_count, 0)?;
) -> Result<Display, DriverError> {
let surface = Surface::create(&self.device, &window)?;
let surface_formats = Surface::formats(&surface)?;
let surface_format = self
Expand All @@ -96,10 +94,15 @@ impl Window {
}

let swapchain = Swapchain::new(&self.device, surface, swapchain_info)?;
let display = Display::new(
&self.device,
swapchain,
DisplayInfoBuilder::default().command_buffer_count(self.data.cmd_buf_count),
)?;

info!("Created swapchain");
trace!("created display");

Ok((display, swapchain))
Ok(display)
}

fn window_mode_attributes(
Expand Down Expand Up @@ -210,7 +213,7 @@ impl Window {
}
Ok(res) => res,
};
let (display, swapchain) = match self.create_display_swapchain(&window) {
let display = match self.create_display(&window) {
Err(err) => {
warn!("Unable to create swapchain: {err}");

Expand All @@ -221,20 +224,15 @@ impl Window {
}
Ok(res) => res,
};
let display_pool = HashPool::new(&self.device);

let mut active_window = ActiveWindow {
self.active_window = Some(ActiveWindow {
display,
display_pool,
display_resize: None,
events: vec![],
swapchain,
window,
};

if !active_window.draw(&self.device, &mut self.draw_fn) {
event_loop.exit();
return;
}

self.active_window = Some(active_window);
});
}

fn user_event(&mut self, _event_loop: &ActiveEventLoop, event: ()) {
Expand All @@ -252,20 +250,21 @@ impl Window {
if let Some(active_window) = self.active_window.as_mut() {
match &event {
WindowEvent::CloseRequested => {
info!("Close requested");
info!("close requested");

event_loop.exit();
}
WindowEvent::RedrawRequested => {
if !active_window.draw(&self.device, &mut self.draw_fn) {
let draw = active_window.draw(&self.device, &mut self.draw_fn);

profiling::finish_frame!();

if !draw.unwrap() {
event_loop.exit();
}
}
WindowEvent::Resized(size) => {
let mut swapchain_info = active_window.swapchain.info();
swapchain_info.width = size.width;
swapchain_info.height = size.height;
active_window.swapchain.set_info(swapchain_info);
active_window.display_resize = Some((size.width, size.height));
}
_ => (),
}
Expand All @@ -279,23 +278,33 @@ impl Window {

struct ActiveWindow {
display: Display,
display_pool: HashPool,
display_resize: Option<(u32, u32)>,
events: Vec<Event<()>>,
swapchain: Swapchain,
window: winit::window::Window,
}

impl ActiveWindow {
fn draw(&mut self, device: &Arc<Device>, mut f: impl FnMut(FrameContext)) -> bool {
if let Ok(swapchain_image) = self.swapchain.acquire_next_image() {
self.window.pre_present_notify();
fn draw(
&mut self,
device: &Arc<Device>,
mut f: impl FnMut(FrameContext),
) -> Result<bool, DisplayError> {
if let Some((width, height)) = self.display_resize.take() {
let mut swapchain_info = self.display.swapchain_info();
swapchain_info.width = width;
swapchain_info.height = height;
self.display.set_swapchain_info(swapchain_info);
}

if let Some(swapchain_image) = self.display.acquire_next_image()? {
let mut render_graph = RenderGraph::new();
let swapchain_image = render_graph.bind_node(swapchain_image);
let swapchain_info = self.swapchain.info();
let swapchain_info = self.display.swapchain_info();

let mut will_exit = false;

info!("Drawing");
trace!("drawing");

f(FrameContext {
device,
Expand All @@ -311,28 +320,24 @@ impl Window {
self.events.clear();

if will_exit {
info!("Exit requested");
info!("exit requested");

return false;
return Ok(false);
}

match self.display.resolve_image(render_graph, swapchain_image) {
Err(err) => {
warn!("Unable to resolve swapchain image: {err}");

return false;
}
Ok(swapchain_image) => self.swapchain.present_image(swapchain_image, 0, 0),
}
self.window.pre_present_notify();
self.display
.present_image(&mut self.display_pool, render_graph, swapchain_image, 0)
.inspect_err(|err| {
warn!("unable to present swapchain image: {err}");
})?;
} else {
warn!("Failed to acquire swapchain image");
warn!("unable to acquire swapchain image");
}

profiling::finish_frame!();

self.window.request_redraw();

true
Ok(true)
}
}

Expand All @@ -347,6 +352,14 @@ impl Window {

self.event_loop.run_app(&mut app)?;

if let Some(ActiveWindow {
display, window, ..
}) = app.active_window.take()
{
drop(display);
drop(window);
}

info!("Window closed");

if let Some(err) = app.error {
Expand Down
51 changes: 31 additions & 20 deletions examples/app.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
mod profile_with_puffin;

use {
clap::Parser,
log::error,
screen_13::{
driver::{
device::{Device, DeviceInfoBuilder},
Expand All @@ -8,7 +11,7 @@ use {
},
graph::RenderGraph,
pool::hash::HashPool,
Display,
Display, DisplayError, DisplayInfo,
},
std::sync::Arc,
winit::{
Expand All @@ -21,6 +24,9 @@ use {
};

fn main() -> Result<(), EventLoopError> {
pretty_env_logger::init();
profile_with_puffin::init();

EventLoop::new()?.run_app(&mut Application::default())
}

Expand All @@ -35,11 +41,11 @@ impl ApplicationHandler for Application {
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
let window_attributes = Window::default_attributes().with_title("Screen 13");
let window = event_loop.create_window(window_attributes).unwrap();

let args = Args::parse();
let device_info = DeviceInfoBuilder::default().debug(args.debug);
let device = Arc::new(Device::create_display(device_info, &window).unwrap());
let display_pool = Box::new(HashPool::new(&device));
let display = Display::new(&device, display_pool, 3, 0).unwrap();

let surface = Surface::create(&device, &window).unwrap();
let surface_formats = Surface::formats(&surface).unwrap();
let surface_format = Surface::linear_or_default(&surface_formats);
Expand All @@ -51,10 +57,12 @@ impl ApplicationHandler for Application {
)
.unwrap();

let display_pool = HashPool::new(&device);
let display = Display::new(&device, swapchain, DisplayInfo::default()).unwrap();

self.0 = Some(Context {
device,
display,
swapchain,
display_pool,
window,
});
}
Expand All @@ -70,13 +78,20 @@ impl ApplicationHandler for Application {
match event {
WindowEvent::CloseRequested => event_loop.exit(),
WindowEvent::Resized(size) => {
let mut swapchain_info = context.swapchain.info();
let mut swapchain_info = context.display.swapchain_info();
swapchain_info.width = size.width;
swapchain_info.height = size.height;
context.swapchain.set_info(swapchain_info);
context.display.set_swapchain_info(swapchain_info);
}
WindowEvent::RedrawRequested => {
context.draw();
if let Err(err) = context.draw() {
// This would be a good time to recreate the device or surface
error!("unable to draw window: {err}");

event_loop.exit();
};

profiling::finish_frame!();
}
_ => (),
}
Expand All @@ -91,29 +106,25 @@ struct Args {
}

struct Context {
device: Arc<Device>,
display: Display,
swapchain: Swapchain,
display_pool: HashPool,
window: Window,
}

impl Context {
fn draw(&mut self) {
if let Ok(swapchain_image) = self.swapchain.acquire_next_image() {
self.window.pre_present_notify();

fn draw(&mut self) -> Result<(), DisplayError> {
if let Some(swapchain_image) = self.display.acquire_next_image()? {
let mut render_graph = RenderGraph::new();
let swapchain_image = render_graph.bind_node(swapchain_image);

// Rendering goes here!
render_graph.clear_color_image_value(swapchain_image, [1.0, 0.0, 1.0]);
let _ = self.device;

let swapchain_image = self
.display
.resolve_image(render_graph, swapchain_image)
.unwrap();
self.swapchain.present_image(swapchain_image, 0, 0);
self.window.pre_present_notify();
self.display
.present_image(&mut self.display_pool, render_graph, swapchain_image, 0)?;
}

Ok(())
}
}
2 changes: 1 addition & 1 deletion examples/cpu_readback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn main() -> Result<(), DriverError> {

// Resolve and wait (or you can check has_executed without blocking) - alternatively you might
// use device.queue_wait_idle(0) or device.device_wait_idle() - but those block on larger scopes
let cmd_buf = render_graph
let mut cmd_buf = render_graph
.resolve()
.submit(&mut HashPool::new(&device), 0, 0)?;

Expand Down
2 changes: 1 addition & 1 deletion examples/msaa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ fn best_depth_format(device: &Device) -> vk::Format {
vk::ImageCreateFlags::empty(),
);

if format_props.is_ok() {
if matches!(format_props, Ok(Some(_))) {
return format;
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/multipass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ fn best_depth_stencil_format(device: &Device) -> vk::Format {
vk::ImageCreateFlags::empty(),
);

if format_props.is_ok() {
if matches!(format_props, Ok(Some(_))) {
return format;
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/ray_omni.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ fn best_2d_optimal_format(
flags,
);

if format_props.is_ok() {
if matches!(format_props, Ok(Some(_))) {
return *format;
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/subgroup_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ fn exclusive_sum(
});

let output_buf = render_graph.unbind_node(output_buf);
let cmd_buf = render_graph
let mut cmd_buf = render_graph
.resolve()
.submit(&mut HashPool::new(device), 0, 0)?;

Expand Down
2 changes: 1 addition & 1 deletion examples/vsm_omni.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ fn best_2d_optimal_format(
flags,
);

if format_props.is_ok() {
if matches!(format_props, Ok(Some(_))) {
return *format;
}
}
Expand Down
Loading

0 comments on commit 7cde64b

Please sign in to comment.