vk: experiment with internally handling frame residuals
This commit is contained in:
parent
98e5070d81
commit
e9a1518c5d
|
@ -119,7 +119,8 @@ pub struct FilterChain {
|
||||||
output_framebuffers: Box<[OwnedImage]>,
|
output_framebuffers: Box<[OwnedImage]>,
|
||||||
feedback_framebuffers: Box<[OwnedImage]>,
|
feedback_framebuffers: Box<[OwnedImage]>,
|
||||||
history_framebuffers: VecDeque<OwnedImage>,
|
history_framebuffers: VecDeque<OwnedImage>,
|
||||||
disable_mipmaps: bool
|
disable_mipmaps: bool,
|
||||||
|
intermediates: Box<[FrameIntermediates]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FilterMutable {
|
pub struct FilterMutable {
|
||||||
|
@ -168,7 +169,7 @@ impl FrameIntermediates {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dispose of the intermediate objects created during a frame.
|
/// Dispose of the intermediate objects created during a frame.
|
||||||
pub fn dispose(self) {
|
pub fn dispose(&mut self) {
|
||||||
for image_view in &self.image_views {
|
for image_view in &self.image_views {
|
||||||
if *image_view != vk::ImageView::null() {
|
if *image_view != vk::ImageView::null() {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -176,7 +177,7 @@ impl FrameIntermediates {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drop(self)
|
self.owned.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +236,9 @@ impl FilterChain {
|
||||||
let mut feedback_textures = Vec::new();
|
let mut feedback_textures = Vec::new();
|
||||||
feedback_textures.resize_with(filters.len(), || None);
|
feedback_textures.resize_with(filters.len(), || None);
|
||||||
|
|
||||||
|
let mut intermediates = Vec::new();
|
||||||
|
intermediates.resize_with(frames_in_flight as usize, || FrameIntermediates::new(&device.device));
|
||||||
|
|
||||||
Ok(FilterChain {
|
Ok(FilterChain {
|
||||||
common: FilterCommon {
|
common: FilterCommon {
|
||||||
luts,
|
luts,
|
||||||
|
@ -258,6 +262,7 @@ impl FilterChain {
|
||||||
output_framebuffers: output_framebuffers?.into_boxed_slice(),
|
output_framebuffers: output_framebuffers?.into_boxed_slice(),
|
||||||
feedback_framebuffers: feedback_framebuffers?.into_boxed_slice(),
|
feedback_framebuffers: feedback_framebuffers?.into_boxed_slice(),
|
||||||
history_framebuffers,
|
history_framebuffers,
|
||||||
|
intermediates: intermediates.into_boxed_slice(),
|
||||||
disable_mipmaps: options.map_or(false, |o| o.force_no_mipmaps),
|
disable_mipmaps: options.map_or(false, |o| o.force_no_mipmaps),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -503,8 +508,8 @@ impl FilterChain {
|
||||||
pub fn push_history(
|
pub fn push_history(
|
||||||
&mut self,
|
&mut self,
|
||||||
input: &VulkanImage,
|
input: &VulkanImage,
|
||||||
intermediates: &mut FrameIntermediates,
|
|
||||||
cmd: vk::CommandBuffer,
|
cmd: vk::CommandBuffer,
|
||||||
|
count: usize,
|
||||||
) -> error::Result<()> {
|
) -> error::Result<()> {
|
||||||
if let Some(mut back) = self.history_framebuffers.pop_back() {
|
if let Some(mut back) = self.history_framebuffers.pop_back() {
|
||||||
if back.image.size != input.size
|
if back.image.size != input.size
|
||||||
|
@ -516,7 +521,7 @@ impl FilterChain {
|
||||||
&mut back,
|
&mut back,
|
||||||
OwnedImage::new(&self.vulkan, input.size, input.format.into(), 1)?,
|
OwnedImage::new(&self.vulkan, input.size, input.format.into(), 1)?,
|
||||||
);
|
);
|
||||||
intermediates.dispose_owned(old_back);
|
self.intermediates[count % self.intermediates.len()].dispose_owned(old_back);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -566,11 +571,6 @@ impl FilterChain {
|
||||||
/// librashader **will not** create a pipeline barrier for the final pass. The output image will
|
/// librashader **will not** create a pipeline barrier for the final pass. The output image will
|
||||||
/// remain in `VK_COLOR_ATTACHMENT_OPTIMAL` after all shader passes. The caller must transition
|
/// remain in `VK_COLOR_ATTACHMENT_OPTIMAL` after all shader passes. The caller must transition
|
||||||
/// the output image to the final layout.
|
/// the output image to the final layout.
|
||||||
///
|
|
||||||
/// This function returns an [`FrameIntermediates`](crate::filter_chain::FrameIntermediates) struct,
|
|
||||||
/// which contains intermediate ImageViews. These may be disposed by calling
|
|
||||||
/// [`FrameIntermediates::dispose`](crate::filter_chain::FrameIntermediates::dispose),
|
|
||||||
/// only after they are no longer in use by the GPU, after queue submission.
|
|
||||||
pub fn frame(
|
pub fn frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
count: usize,
|
count: usize,
|
||||||
|
@ -578,7 +578,10 @@ impl FilterChain {
|
||||||
input: &VulkanImage,
|
input: &VulkanImage,
|
||||||
cmd: vk::CommandBuffer,
|
cmd: vk::CommandBuffer,
|
||||||
options: Option<FrameOptions>,
|
options: Option<FrameOptions>,
|
||||||
) -> error::Result<FrameIntermediates> {
|
) -> error::Result<()> {
|
||||||
|
let mut intermediates = &mut self.intermediates[count % self.intermediates.len()];
|
||||||
|
intermediates.dispose();
|
||||||
|
|
||||||
// limit number of passes to those enabled.
|
// limit number of passes to those enabled.
|
||||||
let passes = &mut self.passes[0..self.common.config.passes_enabled];
|
let passes = &mut self.passes[0..self.common.config.passes_enabled];
|
||||||
|
|
||||||
|
@ -590,9 +593,8 @@ impl FilterChain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut intermediates = FrameIntermediates::new(&self.vulkan.device);
|
|
||||||
if passes.is_empty() {
|
if passes.is_empty() {
|
||||||
return Ok(intermediates);
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let original_image_view = unsafe {
|
let original_image_view = unsafe {
|
||||||
|
@ -751,8 +753,7 @@ impl FilterChain {
|
||||||
intermediates.dispose_outputs(out.output);
|
intermediates.dispose_outputs(out.output);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.push_history(input, &mut intermediates, cmd)?;
|
self.push_history(input, cmd, count)?;
|
||||||
|
Ok(())
|
||||||
Ok(intermediates)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,13 @@ use crate::hello_triangle::syncobjects::SyncObjects;
|
||||||
use crate::hello_triangle::vulkan_base::VulkanBase;
|
use crate::hello_triangle::vulkan_base::VulkanBase;
|
||||||
use crate::texture::VulkanImage;
|
use crate::texture::VulkanImage;
|
||||||
use crate::util;
|
use crate::util;
|
||||||
use crate::viewport::Viewport;
|
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
use ash::vk::{Handle, RenderingInfo};
|
use ash::vk::{Handle, RenderingInfo};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent};
|
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent};
|
||||||
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder};
|
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder};
|
||||||
use winit::platform::windows::EventLoopBuilderExtWindows;
|
use winit::platform::windows::EventLoopBuilderExtWindows;
|
||||||
|
use librashader_common::Viewport;
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const WINDOW_TITLE: &'static str = "librashader Vulkan";
|
const WINDOW_TITLE: &'static str = "librashader Vulkan";
|
||||||
|
@ -210,7 +210,7 @@ impl VulkanWindow {
|
||||||
// vk::QUEUE_FAMILY_IGNORED
|
// vk::QUEUE_FAMILY_IGNORED
|
||||||
// );
|
// );
|
||||||
|
|
||||||
let intermediates = filter
|
filter
|
||||||
.frame(
|
.frame(
|
||||||
frame,
|
frame,
|
||||||
&Viewport {
|
&Viewport {
|
||||||
|
@ -339,7 +339,7 @@ impl VulkanWindow {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
vulkan.base.device.device_wait_idle().unwrap();
|
vulkan.base.device.device_wait_idle().unwrap();
|
||||||
intermediates.dispose();
|
// intermediates.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue