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

View file

@ -29,6 +29,7 @@ pub struct FilterPass {
pub config: ShaderPassConfig,
pub graphics_pipeline: VulkanGraphicsPipeline,
pub ubo_ring: VkUboRing,
pub frames_in_flight: u32,
}
impl FilterPass {
@ -82,7 +83,7 @@ impl FilterPass {
source: &InputImage,
output: &RenderTarget,
) -> 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(
pass_index,
@ -135,7 +136,7 @@ impl FilterPass {
vk::PipelineBindPoint::GRAPHICS,
self.graphics_pipeline.layout.layout,
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_WIDTH: u32 = 800;
const WINDOW_HEIGHT: u32 = 600;
const MAX_FRAMES_IN_FLIGHT: usize = 3;
struct VulkanWindow;
@ -136,16 +137,22 @@ impl VulkanWindow {
}
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 {
vulkan
.base
.device
.wait_for_fences(&[vulkan.sync.in_flight], true, u64::MAX)
.wait_for_fences(&[in_flight], true, u64::MAX)
.unwrap();
vulkan
.base
.device
.reset_fences(&[vulkan.sync.in_flight])
.reset_fences(&[in_flight])
.unwrap();
let (swapchain_index, _) = vulkan
@ -154,12 +161,12 @@ impl VulkanWindow {
.acquire_next_image(
vulkan.swapchain.swapchain,
u64::MAX,
vulkan.sync.image_available,
image_available,
vk::Fence::null(),
)
.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_image = vulkan.swapchain.render_images[swapchain_index as usize].0;
let swapchain_image = vulkan.swapchain.swapchain_images[swapchain_index as usize];
@ -309,8 +316,8 @@ impl VulkanWindow {
let submit_info = vk::SubmitInfo::builder()
.wait_dst_stage_mask(&[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT])
.wait_semaphores(&[vulkan.sync.image_available])
.signal_semaphores(&[vulkan.sync.render_finished])
.wait_semaphores(&[image_available])
.signal_semaphores(&[render_finished])
.command_buffers(&[cmd])
.build();
@ -320,12 +327,12 @@ impl VulkanWindow {
.queue_submit(
vulkan.base.graphics_queue,
&[submit_info],
vulkan.sync.in_flight,
in_flight,
)
.expect("failed to submit queue");
let present_info = vk::PresentInfoKHR::builder()
.wait_semaphores(&[vulkan.sync.render_finished])
.wait_semaphores(&[render_finished])
.swapchains(&[vulkan.swapchain.swapchain])
.image_indices(&[swapchain_index])
.build();
@ -336,8 +343,10 @@ impl VulkanWindow {
.queue_present(vulkan.base.graphics_queue, &present_info)
.unwrap();
vulkan.base.device.device_wait_idle().unwrap();
drop(intermediates)
//oops i pooped my pants
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 render_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, 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 {
surface,

View file

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