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