vk: enable frames in flight
This commit is contained in:
parent
5545f89f28
commit
a4a7dca208
|
@ -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(),
|
||||
)?,
|
||||
};
|
||||
|
|
|
@ -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],
|
||||
&[],
|
||||
);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
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,
|
||||
|
|
Loading…
Reference in a new issue