2020-11-18 03:04:25 +11:00
|
|
|
use piet_gpu_hal::hub;
|
2020-05-05 01:05:54 +10:00
|
|
|
use piet_gpu_hal::vulkan::VkInstance;
|
2020-11-18 03:04:25 +11:00
|
|
|
use piet_gpu_hal::{CmdBuf, Error, ImageLayout};
|
2020-05-05 01:05:54 +10:00
|
|
|
|
2020-05-12 13:01:06 +10:00
|
|
|
use piet_gpu::{render_scene, PietGpuRenderContext, Renderer, HEIGHT, WIDTH};
|
2020-05-05 01:05:54 +10:00
|
|
|
|
|
|
|
use winit::{
|
|
|
|
event::{Event, WindowEvent},
|
|
|
|
event_loop::{ControlFlow, EventLoop},
|
|
|
|
window::WindowBuilder,
|
|
|
|
};
|
|
|
|
|
|
|
|
const NUM_FRAMES: usize = 2;
|
|
|
|
|
|
|
|
fn main() -> Result<(), Error> {
|
|
|
|
let event_loop = EventLoop::new();
|
|
|
|
let window = WindowBuilder::new()
|
|
|
|
.with_inner_size(winit::dpi::LogicalSize {
|
|
|
|
width: (WIDTH / 2) as f64,
|
|
|
|
height: (HEIGHT / 2) as f64,
|
|
|
|
})
|
|
|
|
.with_resizable(false) // currently not supported
|
|
|
|
.build(&event_loop)?;
|
|
|
|
|
|
|
|
let (instance, surface) = VkInstance::new(Some(&window))?;
|
|
|
|
unsafe {
|
|
|
|
let device = instance.device(surface.as_ref())?;
|
2021-03-19 22:18:57 +11:00
|
|
|
let mut swapchain = instance.swapchain(WIDTH / 2, HEIGHT / 2, &device, surface.as_ref().unwrap())?;
|
2020-11-18 03:04:25 +11:00
|
|
|
let session = hub::Session::new(device);
|
2020-05-05 01:05:54 +10:00
|
|
|
|
|
|
|
let mut current_frame = 0;
|
|
|
|
let present_semaphores = (0..NUM_FRAMES)
|
2020-11-18 03:04:25 +11:00
|
|
|
.map(|_| session.create_semaphore())
|
2020-05-05 01:05:54 +10:00
|
|
|
.collect::<Result<Vec<_>, Error>>()?;
|
|
|
|
let query_pools = (0..NUM_FRAMES)
|
2020-11-18 03:04:25 +11:00
|
|
|
.map(|_| session.create_query_pool(8))
|
2020-05-05 01:05:54 +10:00
|
|
|
.collect::<Result<Vec<_>, Error>>()?;
|
|
|
|
|
|
|
|
let mut ctx = PietGpuRenderContext::new();
|
|
|
|
render_scene(&mut ctx);
|
2020-06-03 10:10:20 +10:00
|
|
|
let n_paths = ctx.path_count();
|
|
|
|
let n_pathseg = ctx.pathseg_count();
|
2021-04-11 02:12:21 +10:00
|
|
|
let n_trans = ctx.trans_count();
|
2020-05-05 01:05:54 +10:00
|
|
|
let scene = ctx.get_scene_buf();
|
|
|
|
|
2021-03-15 22:28:04 +11:00
|
|
|
let renderer = Renderer::new(&session, scene, n_paths, n_pathseg, n_trans)?;
|
2020-11-18 03:04:25 +11:00
|
|
|
|
|
|
|
let mut submitted: Option<hub::SubmittedCmdBuf> = None;
|
2020-12-10 03:34:01 +11:00
|
|
|
let mut last_frame_idx = 0;
|
2020-05-05 01:05:54 +10:00
|
|
|
|
|
|
|
event_loop.run(move |event, _, control_flow| {
|
|
|
|
*control_flow = ControlFlow::Poll; // `ControlFlow::Wait` if only re-render on event
|
|
|
|
|
|
|
|
match event {
|
|
|
|
Event::WindowEvent { event, window_id } if window_id == window.id() => {
|
|
|
|
match event {
|
|
|
|
WindowEvent::CloseRequested => {
|
|
|
|
*control_flow = ControlFlow::Exit;
|
|
|
|
}
|
|
|
|
_ => (),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Event::MainEventsCleared => {
|
|
|
|
window.request_redraw();
|
|
|
|
}
|
|
|
|
Event::RedrawRequested(window_id) if window_id == window.id() => {
|
|
|
|
let frame_idx = current_frame % NUM_FRAMES;
|
|
|
|
|
2020-12-10 03:34:01 +11:00
|
|
|
// Note: this logic is a little strange. We have two sets of renderer
|
|
|
|
// resources, so we could have two frames in flight (submit two, wait on
|
|
|
|
// the first), but we actually just wait on the last submitted.
|
|
|
|
//
|
|
|
|
// Getting this right will take some thought.
|
2020-11-18 03:04:25 +11:00
|
|
|
if let Some(submitted) = submitted.take() {
|
|
|
|
submitted.wait().unwrap();
|
2020-05-05 01:05:54 +10:00
|
|
|
|
2020-12-10 03:34:01 +11:00
|
|
|
let ts = session.fetch_query_pool(&query_pools[last_frame_idx]).unwrap();
|
2020-05-12 13:01:06 +10:00
|
|
|
window.set_title(&format!(
|
2020-06-15 07:32:59 +10:00
|
|
|
"{:.3}ms :: e:{:.3}ms|alloc:{:.3}ms|cp:{:.3}ms|bd:{:.3}ms|bin:{:.3}ms|cr:{:.3}ms|r:{:.3}ms",
|
|
|
|
ts[6] * 1e3,
|
|
|
|
ts[0] * 1e3,
|
|
|
|
(ts[1] - ts[0]) * 1e3,
|
|
|
|
(ts[2] - ts[1]) * 1e3,
|
|
|
|
(ts[3] - ts[2]) * 1e3,
|
|
|
|
(ts[4] - ts[3]) * 1e3,
|
|
|
|
(ts[5] - ts[4]) * 1e3,
|
|
|
|
(ts[6] - ts[5]) * 1e3,
|
2020-05-05 01:05:54 +10:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2020-12-10 03:34:01 +11:00
|
|
|
|
2020-05-05 01:05:54 +10:00
|
|
|
let (image_idx, acquisition_semaphore) = swapchain.next().unwrap();
|
|
|
|
let swap_image = swapchain.image(image_idx);
|
2020-12-10 03:34:01 +11:00
|
|
|
let query_pool = &query_pools[frame_idx];
|
2020-11-18 03:04:25 +11:00
|
|
|
let mut cmd_buf = session.cmd_buf().unwrap();
|
2020-05-05 01:05:54 +10:00
|
|
|
cmd_buf.begin();
|
2020-11-18 03:04:25 +11:00
|
|
|
renderer.record(&mut cmd_buf, &query_pool);
|
2020-05-05 01:05:54 +10:00
|
|
|
|
|
|
|
// Image -> Swapchain
|
|
|
|
cmd_buf.image_barrier(
|
|
|
|
&swap_image,
|
|
|
|
ImageLayout::Undefined,
|
|
|
|
ImageLayout::BlitDst,
|
|
|
|
);
|
2020-11-18 03:04:25 +11:00
|
|
|
cmd_buf.blit_image(renderer.image_dev.vk_image(), &swap_image);
|
2020-05-12 13:01:06 +10:00
|
|
|
cmd_buf.image_barrier(&swap_image, ImageLayout::BlitDst, ImageLayout::Present);
|
2020-05-05 01:05:54 +10:00
|
|
|
cmd_buf.finish();
|
|
|
|
|
2020-11-18 03:04:25 +11:00
|
|
|
submitted = Some(session
|
2020-05-05 01:05:54 +10:00
|
|
|
.run_cmd_buf(
|
2020-11-18 03:04:25 +11:00
|
|
|
cmd_buf,
|
2020-05-05 01:05:54 +10:00
|
|
|
&[acquisition_semaphore],
|
|
|
|
&[present_semaphores[frame_idx]],
|
|
|
|
)
|
2020-11-18 03:04:25 +11:00
|
|
|
.unwrap());
|
2020-12-10 03:34:01 +11:00
|
|
|
last_frame_idx = frame_idx;
|
2020-05-05 01:05:54 +10:00
|
|
|
|
|
|
|
swapchain
|
|
|
|
.present(image_idx, &[present_semaphores[frame_idx]])
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
current_frame += 1;
|
|
|
|
}
|
|
|
|
_ => (),
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|