vk: fix frame_count logic
This commit is contained in:
parent
8474dcd6dc
commit
d55b057e44
|
@ -6,8 +6,8 @@ use crate::samplers::SamplerSet;
|
||||||
use crate::texture::{OwnedImage, InputImage, VulkanImage, OwnedImageLayout};
|
use crate::texture::{OwnedImage, InputImage, VulkanImage, OwnedImageLayout};
|
||||||
use crate::ubo_ring::VkUboRing;
|
use crate::ubo_ring::VkUboRing;
|
||||||
use crate::vulkan_state::VulkanGraphicsPipeline;
|
use crate::vulkan_state::VulkanGraphicsPipeline;
|
||||||
use ash::vk::{CommandPoolCreateFlags, PFN_vkGetInstanceProcAddr, Queue, StaticFn};
|
use ash::vk::{CommandPoolCreateFlags, DebugUtilsObjectNameInfoEXT, Handle, PFN_vkGetInstanceProcAddr, Queue, StaticFn};
|
||||||
use ash::{vk, Device};
|
use ash::{vk, Device, Entry};
|
||||||
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||||
|
@ -22,7 +22,9 @@ use librashader_runtime::image::{Image, UVDirection};
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::ffi::CStr;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use ash::extensions::ext::DebugUtils;
|
||||||
use crate::draw_quad::DrawQuad;
|
use crate::draw_quad::DrawQuad;
|
||||||
use crate::framebuffer::OutputImage;
|
use crate::framebuffer::OutputImage;
|
||||||
use crate::render_target::{DEFAULT_MVP, RenderTarget};
|
use crate::render_target::{DEFAULT_MVP, RenderTarget};
|
||||||
|
@ -36,6 +38,7 @@ pub struct Vulkan {
|
||||||
command_pool: vk::CommandPool,
|
command_pool: vk::CommandPool,
|
||||||
pipeline_cache: vk::PipelineCache,
|
pipeline_cache: vk::PipelineCache,
|
||||||
pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties,
|
pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties,
|
||||||
|
debug: DebugUtils
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShaderPassMeta = (
|
type ShaderPassMeta = (
|
||||||
|
@ -82,6 +85,10 @@ impl TryFrom<VulkanInfo<'_>> for Vulkan {
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let debug = DebugUtils::new(&Entry::from_static_fn(StaticFn {
|
||||||
|
get_instance_proc_addr: vulkan.get_instance_proc_addr,
|
||||||
|
}), &instance);
|
||||||
|
|
||||||
Ok(Vulkan {
|
Ok(Vulkan {
|
||||||
device,
|
device,
|
||||||
// instance,
|
// instance,
|
||||||
|
@ -89,15 +96,16 @@ impl TryFrom<VulkanInfo<'_>> for Vulkan {
|
||||||
command_pool,
|
command_pool,
|
||||||
pipeline_cache,
|
pipeline_cache,
|
||||||
memory_properties: vulkan.memory_properties.clone(),
|
memory_properties: vulkan.memory_properties.clone(),
|
||||||
|
debug
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<(ash::Device, vk::Queue, vk::PhysicalDeviceMemoryProperties)> for Vulkan {
|
impl TryFrom<(ash::Device, vk::Queue, vk::PhysicalDeviceMemoryProperties, DebugUtils)> for Vulkan {
|
||||||
type Error = Box<dyn Error>;
|
type Error = Box<dyn Error>;
|
||||||
|
|
||||||
fn try_from(value: (Device, Queue, vk::PhysicalDeviceMemoryProperties)) -> error::Result<Self> {
|
fn try_from(value: (Device, Queue, vk::PhysicalDeviceMemoryProperties, DebugUtils)) -> error::Result<Self> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let device = value.0;
|
let device = value.0;
|
||||||
|
|
||||||
|
@ -120,6 +128,7 @@ impl TryFrom<(ash::Device, vk::Queue, vk::PhysicalDeviceMemoryProperties)> for V
|
||||||
command_pool,
|
command_pool,
|
||||||
pipeline_cache,
|
pipeline_cache,
|
||||||
memory_properties: value.2,
|
memory_properties: value.2,
|
||||||
|
debug: value.3
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,8 +153,8 @@ pub(crate) struct FilterCommon {
|
||||||
pub samplers: SamplerSet,
|
pub samplers: SamplerSet,
|
||||||
pub(crate) draw_quad: DrawQuad,
|
pub(crate) draw_quad: DrawQuad,
|
||||||
|
|
||||||
pub output_textures: Box<[Option<InputImage>]>,
|
pub output_inputs: Box<[Option<InputImage>]>,
|
||||||
pub feedback_textures: Box<[Option<InputImage>]>,
|
pub feedback_inputs: Box<[Option<InputImage>]>,
|
||||||
pub history_textures: Box<[Option<InputImage>]>,
|
pub history_textures: Box<[Option<InputImage>]>,
|
||||||
pub config: FilterMutable,
|
pub config: FilterMutable,
|
||||||
pub device: ash::Device,
|
pub device: ash::Device,
|
||||||
|
@ -267,8 +276,8 @@ impl FilterChainVulkan {
|
||||||
},
|
},
|
||||||
draw_quad: DrawQuad::new(&device.device, &device.memory_properties)?,
|
draw_quad: DrawQuad::new(&device.device, &device.memory_properties)?,
|
||||||
device: device.device.clone(),
|
device: device.device.clone(),
|
||||||
output_textures: output_textures.into_boxed_slice(),
|
output_inputs: output_textures.into_boxed_slice(),
|
||||||
feedback_textures: feedback_textures.into_boxed_slice(),
|
feedback_inputs: feedback_textures.into_boxed_slice(),
|
||||||
history_textures,
|
history_textures,
|
||||||
},
|
},
|
||||||
passes: filters,
|
passes: filters,
|
||||||
|
@ -609,7 +618,7 @@ impl FilterChainVulkan {
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.zip(self.history_framebuffers.iter())
|
.zip(self.history_framebuffers.iter())
|
||||||
{
|
{
|
||||||
*texture = Some(image.as_input(filter, wrap_mode)?);
|
*texture = Some(image.as_input(filter, wrap_mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
let original = InputImage {
|
let original = InputImage {
|
||||||
|
@ -620,7 +629,10 @@ impl FilterChainVulkan {
|
||||||
mip_filter: filter,
|
mip_filter: filter,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut source = original.clone();
|
let mut source = &original;
|
||||||
|
|
||||||
|
// swap output and feedback **before** recording command buffers
|
||||||
|
std::mem::swap(&mut self.output_framebuffers, &mut self.feedback_framebuffers);
|
||||||
|
|
||||||
// rescale render buffers to ensure all bindings are valid.
|
// rescale render buffers to ensure all bindings are valid.
|
||||||
for (index, pass) in passes.iter_mut().enumerate() {
|
for (index, pass) in passes.iter_mut().enumerate() {
|
||||||
|
@ -629,7 +641,7 @@ impl FilterChainVulkan {
|
||||||
pass.get_format(),
|
pass.get_format(),
|
||||||
&viewport.output.size,
|
&viewport.output.size,
|
||||||
&original,
|
&original,
|
||||||
&source,
|
source,
|
||||||
// todo: need to check **next**
|
// todo: need to check **next**
|
||||||
pass.config.mipmap_input,
|
pass.config.mipmap_input,
|
||||||
None,
|
None,
|
||||||
|
@ -640,16 +652,18 @@ impl FilterChainVulkan {
|
||||||
pass.get_format(),
|
pass.get_format(),
|
||||||
&viewport.output.size,
|
&viewport.output.size,
|
||||||
&original,
|
&original,
|
||||||
&source,
|
source,
|
||||||
// todo: need to check **next**
|
// todo: need to check **next**
|
||||||
pass.config.mipmap_input,
|
pass.config.mipmap_input,
|
||||||
None
|
None
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if self.common.feedback_textures[index].is_none() {
|
// self.feedback_framebuffers[index].image.image
|
||||||
self.common.feedback_textures[index] =
|
// refresh inputs
|
||||||
Some(source.clone());
|
self.common.feedback_inputs[index] =
|
||||||
}
|
Some(self.feedback_framebuffers[index].as_input(pass.config.filter, pass.config.wrap_mode));
|
||||||
|
self.common.output_inputs[index] =
|
||||||
|
Some(self.output_framebuffers[index].as_input(pass.config.filter, pass.config.wrap_mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
let passes_len = passes.len();
|
let passes_len = passes.len();
|
||||||
|
@ -657,6 +671,7 @@ impl FilterChainVulkan {
|
||||||
|
|
||||||
for (index, pass) in pass.iter_mut().enumerate() {
|
for (index, pass) in pass.iter_mut().enumerate() {
|
||||||
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.
|
// todo: the output framebuffers can only be dropped after command queue submission.
|
||||||
|
|
||||||
|
@ -668,7 +683,12 @@ impl FilterChainVulkan {
|
||||||
target.image.clone())?,
|
target.image.clone())?,
|
||||||
};
|
};
|
||||||
|
|
||||||
pass.draw(cmd, index, &self.common, count as u32, 0,
|
pass.draw(cmd, index, &self.common, if pass.config.frame_count_mod > 0 {
|
||||||
|
count % pass.config.frame_count_mod as usize
|
||||||
|
} else {
|
||||||
|
count
|
||||||
|
} as u32
|
||||||
|
, 0,
|
||||||
viewport, &original, &source, &out)?;
|
viewport, &original, &source, &out)?;
|
||||||
|
|
||||||
if target.max_miplevels > 1 {
|
if target.max_miplevels > 1 {
|
||||||
|
@ -677,17 +697,15 @@ impl FilterChainVulkan {
|
||||||
out.output.end_pass(cmd);
|
out.output.end_pass(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
source = target.as_input(pass.config.filter, pass.config.wrap_mode)?;
|
source = &self.common.output_inputs[index].as_ref().unwrap();
|
||||||
|
|
||||||
let feedback = self.common.output_textures[index].replace(source.clone());
|
|
||||||
intermediates.dispose_outputs(out.output);
|
intermediates.dispose_outputs(out.output);
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to hint the optimizer
|
// try to hint the optimizer
|
||||||
assert_eq!(last.len(), 1);
|
assert_eq!(last.len(), 1);
|
||||||
if let Some(pass) = last.iter_mut().next() {
|
if let Some(pass) = last.iter_mut().next() {
|
||||||
source.filter_mode = pass.config.filter;
|
// source.filter_mode = pass.config.filter;
|
||||||
source.mip_filter = pass.config.filter;
|
// source.mip_filter = pass.config.filter;
|
||||||
|
|
||||||
let out = RenderTarget {
|
let out = RenderTarget {
|
||||||
x: viewport.x,
|
x: viewport.x,
|
||||||
|
@ -700,7 +718,7 @@ impl FilterChainVulkan {
|
||||||
pass.draw(cmd, passes_len - 1,
|
pass.draw(cmd, passes_len - 1,
|
||||||
&self.common,
|
&self.common,
|
||||||
count as u32,
|
count as u32,
|
||||||
0, viewport, &original, &source, &out)?;
|
0, viewport, &original, source, &out)?;
|
||||||
|
|
||||||
intermediates.dispose_outputs(out.output);
|
intermediates.dispose_outputs(out.output);
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,7 +312,7 @@ impl FilterPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PassOutput
|
// PassOutput
|
||||||
for (index, output) in parent.output_textures.iter().enumerate() {
|
for (index, output) in parent.output_inputs.iter().enumerate() {
|
||||||
let Some(output) = output else {
|
let Some(output) = output else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
@ -341,7 +341,7 @@ impl FilterPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PassFeedback
|
// PassFeedback
|
||||||
for (index, feedback) in parent.feedback_textures.iter().enumerate() {
|
for (index, feedback) in parent.feedback_inputs.iter().enumerate() {
|
||||||
let Some(feedback) = feedback else {
|
let Some(feedback) = feedback else {
|
||||||
eprintln!("no passfeedback {index}");
|
eprintln!("no passfeedback {index}");
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -49,7 +49,9 @@ impl VulkanWindow {
|
||||||
vulkan: VulkanDraw,
|
vulkan: VulkanDraw,
|
||||||
mut filter_chain: FilterChainVulkan,
|
mut filter_chain: FilterChainVulkan,
|
||||||
) {
|
) {
|
||||||
event_loop.run(move |event, _, control_flow| match event {
|
let mut counter = 0;
|
||||||
|
event_loop.run(move |event, _, control_flow| {
|
||||||
|
match event {
|
||||||
Event::WindowEvent { event, .. } => match event {
|
Event::WindowEvent { event, .. } => match event {
|
||||||
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
||||||
WindowEvent::KeyboardInput { input, .. } => match input {
|
WindowEvent::KeyboardInput { input, .. } => match input {
|
||||||
|
@ -70,10 +72,13 @@ impl VulkanWindow {
|
||||||
window.request_redraw();
|
window.request_redraw();
|
||||||
}
|
}
|
||||||
Event::RedrawRequested(_window_id) => {
|
Event::RedrawRequested(_window_id) => {
|
||||||
VulkanWindow::draw_frame(&vulkan, &mut filter_chain);
|
VulkanWindow::draw_frame(counter, &vulkan, &mut filter_chain);
|
||||||
|
counter += 1;
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn record_command_buffer(
|
unsafe fn record_command_buffer(
|
||||||
|
@ -133,7 +138,7 @@ impl VulkanWindow {
|
||||||
vulkan.base.device.cmd_end_render_pass(cmd);
|
vulkan.base.device.cmd_end_render_pass(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_frame(vulkan: &VulkanDraw, filter: &mut FilterChainVulkan) {
|
fn draw_frame(frame: usize, vulkan: &VulkanDraw, filter: &mut FilterChainVulkan) {
|
||||||
unsafe {
|
unsafe {
|
||||||
vulkan
|
vulkan
|
||||||
.base
|
.base
|
||||||
|
@ -207,7 +212,7 @@ impl VulkanWindow {
|
||||||
// vk::QUEUE_FAMILY_IGNORED
|
// vk::QUEUE_FAMILY_IGNORED
|
||||||
// );
|
// );
|
||||||
|
|
||||||
let intermediates = filter.frame(0, &Viewport {
|
let intermediates = filter.frame(frame, &Viewport {
|
||||||
x: 0.0,
|
x: 0.0,
|
||||||
y: 0.0,
|
y: 0.0,
|
||||||
output: VulkanImage {
|
output: VulkanImage {
|
||||||
|
|
|
@ -166,6 +166,7 @@ impl TryFrom<&VulkanBase> for Vulkan {
|
||||||
value.device.clone(),
|
value.device.clone(),
|
||||||
value.graphics_queue.clone(),
|
value.graphics_queue.clone(),
|
||||||
value.mem_props,
|
value.mem_props,
|
||||||
|
value.debug.loader.clone()
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,14 +165,14 @@ impl OwnedImage {
|
||||||
Ok(size)
|
Ok(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_input(&self, filter: FilterMode, wrap_mode: WrapMode) -> error::Result<InputImage> {
|
pub fn as_input(&self, filter: FilterMode, wrap_mode: WrapMode) -> InputImage {
|
||||||
Ok(InputImage {
|
InputImage {
|
||||||
image: self.image.clone(),
|
image: self.image.clone(),
|
||||||
image_view: self.image_view.clone(),
|
image_view: self.image_view.clone(),
|
||||||
wrap_mode,
|
wrap_mode,
|
||||||
filter_mode: filter,
|
filter_mode: filter,
|
||||||
mip_filter: filter,
|
mip_filter: filter,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_mipmaps_and_end_pass(&self, cmd: vk::CommandBuffer) {
|
pub fn generate_mipmaps_and_end_pass(&self, cmd: vk::CommandBuffer) {
|
||||||
|
|
Loading…
Reference in a new issue