Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swapchain performance/correctness #92

Merged
merged 6 commits into from
Feb 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading