vk: enable frames in flight

This commit is contained in:
chyyran 2023-01-12 22:10:25 -05:00
parent 5545f89f28
commit a4a7dca208
4 changed files with 49 additions and 35 deletions

View file

@ -357,9 +357,10 @@ impl FilterChainVulkan {
vulkan: &Vulkan, vulkan: &Vulkan,
passes: Vec<ShaderPassMeta>, passes: Vec<ShaderPassMeta>,
semantics: &ShaderSemantics, semantics: &ShaderSemantics,
images: u32, frames_in_flight: u32,
) -> error::Result<Box<[FilterPass]>> { ) -> error::Result<Box<[FilterPass]>> {
let mut filters = Vec::new(); let mut filters = Vec::new();
let frames_in_flight = std::cmp::max(1, frames_in_flight);
// initialize passes // initialize passes
for (index, (config, mut source, mut reflect)) in passes.into_iter().enumerate() { for (index, (config, mut source, mut reflect)) in passes.into_iter().enumerate() {
@ -399,13 +400,13 @@ impl FilterChainVulkan {
&vulkan.pipeline_cache, &vulkan.pipeline_cache,
&spirv_words, &spirv_words,
&reflection, &reflection,
images, frames_in_flight,
)?; )?;
let ubo_ring = VkUboRing::new( let ubo_ring = VkUboRing::new(
&vulkan.device, &vulkan.device,
&vulkan.memory_properties, &vulkan.memory_properties,
images as usize, frames_in_flight as usize,
ubo_size, ubo_size,
)?; )?;
// shader_vulkan: 2026 // shader_vulkan: 2026
@ -419,6 +420,7 @@ impl FilterChainVulkan {
config, config,
graphics_pipeline, graphics_pipeline,
ubo_ring, ubo_ring,
frames_in_flight
}); });
} }
@ -702,14 +704,12 @@ impl FilterChainVulkan {
let target = &self.output_framebuffers[index]; let target = &self.output_framebuffers[index];
// todo: use proper mode // todo: use proper mode
// todo: the output framebuffers can only be dropped after command queue submission.
let out = RenderTarget { let out = RenderTarget {
x: 0.0, x: 0.0,
y: 0.0, y: 0.0,
mvp: DEFAULT_MVP, mvp: DEFAULT_MVP,
output: OutputImage::new( output: OutputImage::new(
&self.vulkan, /*&pass.graphics_pipeline.render_pass,*/ &self.vulkan,
target.image.clone(), target.image.clone(),
)?, )?,
}; };

View file

@ -29,6 +29,7 @@ pub struct FilterPass {
pub config: ShaderPassConfig, pub config: ShaderPassConfig,
pub graphics_pipeline: VulkanGraphicsPipeline, pub graphics_pipeline: VulkanGraphicsPipeline,
pub ubo_ring: VkUboRing, pub ubo_ring: VkUboRing,
pub frames_in_flight: u32,
} }
impl FilterPass { impl FilterPass {
@ -82,7 +83,7 @@ impl FilterPass {
source: &InputImage, source: &InputImage,
output: &RenderTarget, output: &RenderTarget,
) -> error::Result<()> { ) -> error::Result<()> {
let descriptor = *&self.graphics_pipeline.layout.descriptor_sets[0]; let descriptor = *&self.graphics_pipeline.layout.descriptor_sets[(frame_count % self.frames_in_flight) as usize];
self.build_semantics( self.build_semantics(
pass_index, pass_index,
@ -135,7 +136,7 @@ impl FilterPass {
vk::PipelineBindPoint::GRAPHICS, vk::PipelineBindPoint::GRAPHICS,
self.graphics_pipeline.layout.layout, self.graphics_pipeline.layout.layout,
0, 0,
&[self.graphics_pipeline.layout.descriptor_sets[0]], &[descriptor],
&[], &[],
); );

View file

@ -30,6 +30,7 @@ use winit::platform::windows::EventLoopBuilderExtWindows;
const WINDOW_TITLE: &'static str = "librashader Vulkan"; const WINDOW_TITLE: &'static str = "librashader Vulkan";
const WINDOW_WIDTH: u32 = 800; const WINDOW_WIDTH: u32 = 800;
const WINDOW_HEIGHT: u32 = 600; const WINDOW_HEIGHT: u32 = 600;
const MAX_FRAMES_IN_FLIGHT: usize = 3;
struct VulkanWindow; struct VulkanWindow;
@ -136,16 +137,22 @@ impl VulkanWindow {
} }
fn draw_frame(frame: usize, vulkan: &VulkanDraw, filter: &mut FilterChainVulkan) { fn draw_frame(frame: usize, vulkan: &VulkanDraw, filter: &mut FilterChainVulkan) {
let index = frame % MAX_FRAMES_IN_FLIGHT;
let in_flight = vulkan.sync.in_flight[index];
let image_available = vulkan.sync.image_available[index];
let render_finished = vulkan.sync.render_finished[index];
unsafe { unsafe {
vulkan vulkan
.base .base
.device .device
.wait_for_fences(&[vulkan.sync.in_flight], true, u64::MAX) .wait_for_fences(&[in_flight], true, u64::MAX)
.unwrap(); .unwrap();
vulkan vulkan
.base .base
.device .device
.reset_fences(&[vulkan.sync.in_flight]) .reset_fences(&[in_flight])
.unwrap(); .unwrap();
let (swapchain_index, _) = vulkan let (swapchain_index, _) = vulkan
@ -154,12 +161,12 @@ impl VulkanWindow {
.acquire_next_image( .acquire_next_image(
vulkan.swapchain.swapchain, vulkan.swapchain.swapchain,
u64::MAX, u64::MAX,
vulkan.sync.image_available, image_available,
vk::Fence::null(), vk::Fence::null(),
) )
.unwrap(); .unwrap();
let cmd = vulkan.render_command_pool.buffers[swapchain_index as usize]; let cmd = vulkan.render_command_pool.buffers[index];
let framebuffer = vulkan.render_framebuffers[swapchain_index as usize].framebuffer; let framebuffer = vulkan.render_framebuffers[swapchain_index as usize].framebuffer;
let framebuffer_image = vulkan.swapchain.render_images[swapchain_index as usize].0; let framebuffer_image = vulkan.swapchain.render_images[swapchain_index as usize].0;
let swapchain_image = vulkan.swapchain.swapchain_images[swapchain_index as usize]; let swapchain_image = vulkan.swapchain.swapchain_images[swapchain_index as usize];
@ -309,8 +316,8 @@ impl VulkanWindow {
let submit_info = vk::SubmitInfo::builder() let submit_info = vk::SubmitInfo::builder()
.wait_dst_stage_mask(&[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT]) .wait_dst_stage_mask(&[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT])
.wait_semaphores(&[vulkan.sync.image_available]) .wait_semaphores(&[image_available])
.signal_semaphores(&[vulkan.sync.render_finished]) .signal_semaphores(&[render_finished])
.command_buffers(&[cmd]) .command_buffers(&[cmd])
.build(); .build();
@ -320,12 +327,12 @@ impl VulkanWindow {
.queue_submit( .queue_submit(
vulkan.base.graphics_queue, vulkan.base.graphics_queue,
&[submit_info], &[submit_info],
vulkan.sync.in_flight, in_flight,
) )
.expect("failed to submit queue"); .expect("failed to submit queue");
let present_info = vk::PresentInfoKHR::builder() let present_info = vk::PresentInfoKHR::builder()
.wait_semaphores(&[vulkan.sync.render_finished]) .wait_semaphores(&[render_finished])
.swapchains(&[vulkan.swapchain.swapchain]) .swapchains(&[vulkan.swapchain.swapchain])
.image_indices(&[swapchain_index]) .image_indices(&[swapchain_index])
.build(); .build();
@ -336,8 +343,10 @@ impl VulkanWindow {
.queue_present(vulkan.base.graphics_queue, &present_info) .queue_present(vulkan.base.graphics_queue, &present_info)
.unwrap(); .unwrap();
vulkan.base.device.device_wait_idle().unwrap(); //oops i pooped my pants
drop(intermediates) std::mem::forget(intermediates);
// vulkan.base.device.device_wait_idle().unwrap();
// drop(intermediates)
} }
} }
} }
@ -395,10 +404,10 @@ pub fn main(vulkan: VulkanBase, filter_chain: FilterChainVulkan) {
) )
} }
let swapchain_command_pool = VulkanCommandPool::new(&vulkan, 3).unwrap(); let swapchain_command_pool = VulkanCommandPool::new(&vulkan, MAX_FRAMES_IN_FLIGHT as u32).unwrap();
let render_command_pool = VulkanCommandPool::new(&vulkan, 3).unwrap(); let render_command_pool = VulkanCommandPool::new(&vulkan, MAX_FRAMES_IN_FLIGHT as u32).unwrap();
let sync = SyncObjects::new(&vulkan.device).unwrap(); let sync = SyncObjects::new(&vulkan.device, MAX_FRAMES_IN_FLIGHT).unwrap();
let vulkan = VulkanDraw { let vulkan = VulkanDraw {
surface, surface,

View file

@ -2,24 +2,28 @@ use ash::prelude::VkResult;
use ash::vk; use ash::vk;
pub struct SyncObjects { pub struct SyncObjects {
pub image_available: vk::Semaphore, pub image_available: Vec<vk::Semaphore>,
pub render_finished: vk::Semaphore, pub render_finished: Vec<vk::Semaphore>,
pub in_flight: vk::Fence, pub in_flight: Vec<vk::Fence>,
} }
impl SyncObjects { impl SyncObjects {
pub fn new(device: &ash::Device) -> VkResult<SyncObjects> { pub fn new(device: &ash::Device, frames_in_flight: usize) -> VkResult<SyncObjects> {
unsafe { unsafe {
let image_available = let mut image_available = Vec::new();
device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?; let mut render_finished = Vec::new();
let render_finished = let mut in_flight = Vec::new();
device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?;
let in_flight = device.create_fence( for _ in 0..frames_in_flight {
image_available.push(device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?);
render_finished.push(device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?);
in_flight.push(device.create_fence(
&vk::FenceCreateInfo::builder() &vk::FenceCreateInfo::builder()
.flags(vk::FenceCreateFlags::SIGNALED) .flags(vk::FenceCreateFlags::SIGNALED)
.build(), .build(),
None, None,
)?; )?)
}
Ok(SyncObjects { Ok(SyncObjects {
image_available, image_available,