fmt: run cargo fmt

This commit is contained in:
chyyran 2023-01-12 21:29:42 -05:00
parent d55b057e44
commit 5545f89f28
15 changed files with 451 additions and 322 deletions

View file

@ -34,11 +34,11 @@ impl ShaderPassConfig {
/// shader source, returns such format.
pub fn get_format_override(&self) -> Option<ImageFormat> {
if self.srgb_framebuffer {
return Some(ImageFormat::R8G8B8A8Srgb)
return Some(ImageFormat::R8G8B8A8Srgb);
} else if self.float_framebuffer {
return Some(ImageFormat::R16G16B16A16Sfloat)
return Some(ImageFormat::R16G16B16A16Sfloat);
}
return None
return None;
}
}

View file

@ -1,5 +1,5 @@
const WIDTH: i32 = 1920;
const HEIGHT: i32 = 1080;
const WIDTH: i32 = 800;
const HEIGHT: i32 = 600;
const TITLE: &str = "librashader DirectX 11";
use windows::{

View file

@ -23,13 +23,13 @@ pub use viewport::Viewport;
#[cfg(test)]
mod tests {
use crate::options::FilterChainOptionsD3D11;
use super::*;
use crate::options::FilterChainOptionsD3D11;
#[test]
fn triangle_d3d11() {
let sample = hello_triangle::d3d11_hello_triangle::Sample::new(
"../test/slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp",
"../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
Some(&FilterChainOptionsD3D11 {
use_deferred_context: false,
force_no_mipmaps: false,

View file

@ -261,7 +261,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
let mut status = 0;
gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);
if status != 1 {
return Err(FilterChainError::GLLinkError)
return Err(FilterChainError::GLLinkError);
}
gl::UseProgram(program);
@ -496,7 +496,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
viewport,
&original,
&source,
pass.config.mipmap_input
pass.config.mipmap_input,
)?;
self.feedback_framebuffers[index].scale::<T::FramebufferInterface>(
@ -505,7 +505,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
viewport,
&original,
&source,
pass.config.mipmap_input
pass.config.mipmap_input,
)?;
}

View file

@ -44,7 +44,7 @@ impl Framebuffer {
viewport: &Viewport,
original: &Texture,
source: &Texture,
mipmap: bool
mipmap: bool,
) -> Result<Size<u32>> {
T::scale(self, scaling, format, viewport, original, source, mipmap)
}

View file

@ -47,12 +47,8 @@ impl DrawQuad {
pub fn bind_vbo(&self, cmd: vk::CommandBuffer, vbo: VboType) {
unsafe {
self.device.cmd_bind_vertex_buffers(
cmd,
0,
&[self.buffer.handle],
&[0],
)
self.device
.cmd_bind_vertex_buffers(cmd, 0, &[self.buffer.handle], &[0])
}
}
}

View file

@ -1,12 +1,19 @@
use std::collections::VecDeque;
use crate::{error, util};
use crate::draw_quad::DrawQuad;
use crate::filter_pass::FilterPass;
use crate::framebuffer::OutputImage;
use crate::luts::LutTexture;
use crate::render_target::{RenderTarget, DEFAULT_MVP};
use crate::samplers::SamplerSet;
use crate::texture::{OwnedImage, InputImage, VulkanImage, OwnedImageLayout};
use crate::texture::{InputImage, OwnedImage, OwnedImageLayout, VulkanImage};
use crate::ubo_ring::VkUboRing;
use crate::viewport::Viewport;
use crate::vulkan_state::VulkanGraphicsPipeline;
use ash::vk::{CommandPoolCreateFlags, DebugUtilsObjectNameInfoEXT, Handle, PFN_vkGetInstanceProcAddr, Queue, StaticFn};
use crate::{error, util};
use ash::extensions::ext::DebugUtils;
use ash::vk::{
CommandPoolCreateFlags, DebugUtilsObjectNameInfoEXT, Handle, PFN_vkGetInstanceProcAddr, Queue,
StaticFn,
};
use ash::{vk, Device, Entry};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_preprocess::ShaderSource;
@ -21,14 +28,10 @@ use librashader_reflect::reflect::ReflectShader;
use librashader_runtime::image::{Image, UVDirection};
use librashader_runtime::uniforms::UniformStorage;
use rustc_hash::FxHashMap;
use std::collections::VecDeque;
use std::error::Error;
use std::ffi::CStr;
use std::path::Path;
use ash::extensions::ext::DebugUtils;
use crate::draw_quad::DrawQuad;
use crate::framebuffer::OutputImage;
use crate::render_target::{DEFAULT_MVP, RenderTarget};
use crate::viewport::Viewport;
pub struct Vulkan {
// physical_device: vk::PhysicalDevice,
@ -38,7 +41,7 @@ pub struct Vulkan {
command_pool: vk::CommandPool,
pipeline_cache: vk::PipelineCache,
pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties,
debug: DebugUtils
debug: DebugUtils,
}
type ShaderPassMeta = (
@ -85,9 +88,12 @@ impl TryFrom<VulkanInfo<'_>> for Vulkan {
)?
};
let debug = DebugUtils::new(&Entry::from_static_fn(StaticFn {
get_instance_proc_addr: vulkan.get_instance_proc_addr,
}), &instance);
let debug = DebugUtils::new(
&Entry::from_static_fn(StaticFn {
get_instance_proc_addr: vulkan.get_instance_proc_addr,
}),
&instance,
);
Ok(Vulkan {
device,
@ -96,16 +102,30 @@ impl TryFrom<VulkanInfo<'_>> for Vulkan {
command_pool,
pipeline_cache,
memory_properties: vulkan.memory_properties.clone(),
debug
debug,
})
}
}
}
impl TryFrom<(ash::Device, vk::Queue, vk::PhysicalDeviceMemoryProperties, DebugUtils)> for Vulkan {
impl
TryFrom<(
ash::Device,
vk::Queue,
vk::PhysicalDeviceMemoryProperties,
DebugUtils,
)> for Vulkan
{
type Error = Box<dyn Error>;
fn try_from(value: (Device, Queue, vk::PhysicalDeviceMemoryProperties, DebugUtils)) -> error::Result<Self> {
fn try_from(
value: (
Device,
Queue,
vk::PhysicalDeviceMemoryProperties,
DebugUtils,
),
) -> error::Result<Self> {
unsafe {
let device = value.0;
@ -128,7 +148,7 @@ impl TryFrom<(ash::Device, vk::Queue, vk::PhysicalDeviceMemoryProperties, DebugU
command_pool,
pipeline_cache,
memory_properties: value.2,
debug: value.3
debug: value.3,
})
}
}
@ -164,7 +184,7 @@ pub(crate) struct FilterCommon {
pub struct FilterChainFrameIntermediates {
device: ash::Device,
image_views: Vec<vk::ImageView>,
owned: Vec<OwnedImage>
owned: Vec<OwnedImage>,
}
impl FilterChainFrameIntermediates {
@ -235,29 +255,21 @@ impl FilterChainVulkan {
let mut output_framebuffers = Vec::new();
output_framebuffers.resize_with(filters.len(), || {
OwnedImage::new(
&device,
Size::new(1, 1),
ImageFormat::R8G8B8A8Unorm,
1
)
OwnedImage::new(&device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, 1)
});
let mut feedback_framebuffers = Vec::new();
feedback_framebuffers.resize_with(filters.len(), || {
OwnedImage::new(
&device,
Size::new(1, 1),
ImageFormat::R8G8B8A8Unorm,
1
)
OwnedImage::new(&device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, 1)
});
let output_framebuffers: error::Result<Vec<OwnedImage>> = output_framebuffers.into_iter().collect();
let output_framebuffers: error::Result<Vec<OwnedImage>> =
output_framebuffers.into_iter().collect();
let mut output_textures = Vec::new();
output_textures.resize_with(filters.len(), || None);
let feedback_framebuffers: error::Result<Vec<OwnedImage>> = feedback_framebuffers.into_iter().collect();
let feedback_framebuffers: error::Result<Vec<OwnedImage>> =
feedback_framebuffers.into_iter().collect();
let mut feedback_textures = Vec::new();
feedback_textures.resize_with(filters.len(), || None);
@ -499,12 +511,9 @@ impl FilterChainVulkan {
eprintln!("[history] using frame history with {required_images} images");
let mut images = Vec::with_capacity(required_images);
images.resize_with(required_images, || OwnedImage::new(
&vulkan,
Size::new(1, 1),
ImageFormat::R8G8B8A8Unorm,
1
));
images.resize_with(required_images, || {
OwnedImage::new(&vulkan, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, 1)
});
let images: error::Result<Vec<OwnedImage>> = images.into_iter().collect();
let images = VecDeque::from(images?);
@ -516,19 +525,29 @@ impl FilterChainVulkan {
}
// image must be in SHADER_READ_OPTIMAL
pub fn push_history(&mut self, input: &VulkanImage, intermediates: &mut FilterChainFrameIntermediates,
cmd: vk::CommandBuffer) -> error::Result<()> {
pub fn push_history(
&mut self,
input: &VulkanImage,
intermediates: &mut FilterChainFrameIntermediates,
cmd: vk::CommandBuffer,
) -> error::Result<()> {
if let Some(mut back) = self.history_framebuffers.pop_back() {
if back.image.size != input.size || (input.format != vk::Format::UNDEFINED && input.format != back.image.format) {
if back.image.size != input.size
|| (input.format != vk::Format::UNDEFINED && input.format != back.image.format)
{
eprintln!("[history] resizing");
// old back will get dropped.. do we need to defer?
let old_back =
std::mem::replace(&mut back, OwnedImage::new(&self.vulkan, input.size, input.format.into(), 1)?);
let old_back = std::mem::replace(
&mut back,
OwnedImage::new(&self.vulkan, input.size, input.format.into(), 1)?,
);
intermediates.dispose_owned(old_back);
}
unsafe {
util::vulkan_image_layout_transition_levels(&self.vulkan.device, cmd,
util::vulkan_image_layout_transition_levels(
&self.vulkan.device,
cmd,
input.image,
1,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
@ -538,24 +557,25 @@ impl FilterChainVulkan {
vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::PipelineStageFlags::TRANSFER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED
vk::QUEUE_FAMILY_IGNORED,
);
back.copy_from(cmd, &input, vk::ImageLayout::TRANSFER_SRC_OPTIMAL);
util::vulkan_image_layout_transition_levels(&self.vulkan.device, cmd,
input.image,
1,
vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
vk::AccessFlags::TRANSFER_READ,
vk::AccessFlags::SHADER_READ,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED
util::vulkan_image_layout_transition_levels(
&self.vulkan.device,
cmd,
input.image,
1,
vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
vk::AccessFlags::TRANSFER_READ,
vk::AccessFlags::SHADER_READ,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED,
);
}
self.history_framebuffers.push_front(back)
@ -592,17 +612,21 @@ impl FilterChainVulkan {
.image(input.image)
.format(input.format)
.view_type(vk::ImageViewType::TYPE_2D)
.subresource_range(vk::ImageSubresourceRange::builder()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.level_count(1)
.layer_count(1)
.build())
.components(vk::ComponentMapping::builder()
.r(vk::ComponentSwizzle::R)
.g(vk::ComponentSwizzle::G)
.b(vk::ComponentSwizzle::B)
.a(vk::ComponentSwizzle::A)
.build())
.subresource_range(
vk::ImageSubresourceRange::builder()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.level_count(1)
.layer_count(1)
.build(),
)
.components(
vk::ComponentMapping::builder()
.r(vk::ComponentSwizzle::R)
.g(vk::ComponentSwizzle::G)
.b(vk::ComponentSwizzle::B)
.a(vk::ComponentSwizzle::A)
.build(),
)
.build();
self.vulkan.device.create_image_view(&create_info, None)?
@ -632,7 +656,10 @@ impl FilterChainVulkan {
let mut source = &original;
// swap output and feedback **before** recording command buffers
std::mem::swap(&mut self.output_framebuffers, &mut self.feedback_framebuffers);
std::mem::swap(
&mut self.output_framebuffers,
&mut self.feedback_framebuffers,
);
// rescale render buffers to ensure all bindings are valid.
for (index, pass) in passes.iter_mut().enumerate() {
@ -655,15 +682,17 @@ impl FilterChainVulkan {
source,
// todo: need to check **next**
pass.config.mipmap_input,
None
None,
)?;
// self.feedback_framebuffers[index].image.image
// refresh inputs
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));
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();
@ -679,17 +708,27 @@ impl FilterChainVulkan {
x: 0.0,
y: 0.0,
mvp: DEFAULT_MVP,
output: OutputImage::new(&self.vulkan, /*&pass.graphics_pipeline.render_pass,*/
target.image.clone())?,
output: OutputImage::new(
&self.vulkan, /*&pass.graphics_pipeline.render_pass,*/
target.image.clone(),
)?,
};
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)?;
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,
)?;
if target.max_miplevels > 1 {
target.generate_mipmaps_and_end_pass(cmd);
@ -711,14 +750,20 @@ impl FilterChainVulkan {
x: viewport.x,
y: viewport.y,
mvp: viewport.mvp.unwrap_or(DEFAULT_MVP),
output: OutputImage::new(&self.vulkan,
viewport.output.clone())?,
output: OutputImage::new(&self.vulkan, viewport.output.clone())?,
};
pass.draw(cmd, passes_len - 1,
&self.common,
count as u32,
0, viewport, &original, source, &out)?;
pass.draw(
cmd,
passes_len - 1,
&self.common,
count as u32,
0,
viewport,
&original,
source,
&out,
)?;
intermediates.dispose_outputs(out.output);
}

View file

@ -1,21 +1,23 @@
use crate::{error, util};
use crate::draw_quad::VboType;
use crate::filter_chain::FilterCommon;
use crate::render_target::RenderTarget;
use crate::samplers::{SamplerSet, VulkanSampler};
use crate::texture::InputImage;
use crate::ubo_ring::VkUboRing;
use crate::viewport::Viewport;
use crate::vulkan_state::VulkanGraphicsPipeline;
use crate::{error, util};
use ash::vk;
use librashader_common::{ImageFormat, Size};
use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPassConfig;
use librashader_reflect::back::ShaderCompilerOutput;
use librashader_reflect::reflect::semantics::{BindingStage, MemberOffset, TextureBinding, TextureSemantics, UniformBinding, UniqueSemantics};
use librashader_reflect::reflect::semantics::{
BindingStage, MemberOffset, TextureBinding, TextureSemantics, UniformBinding, UniqueSemantics,
};
use librashader_reflect::reflect::ShaderReflection;
use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess};
use rustc_hash::FxHashMap;
use crate::draw_quad::VboType;
use crate::viewport::Viewport;
pub struct FilterPass {
pub device: ash::Device,
@ -114,21 +116,28 @@ impl FilterPass {
let rendering_info = vk::RenderingInfo::builder()
.layer_count(1)
.render_area(vk::Rect2D {
offset: vk::Offset2D {
x: 0,
y: 0,
},
offset: vk::Offset2D { x: 0, y: 0 },
extent: output.output.size.into(),
})
.color_attachments(&attachments);
unsafe {
parent.device.cmd_begin_rendering(cmd, &rendering_info);
parent.device.cmd_bind_pipeline(cmd, vk::PipelineBindPoint::GRAPHICS, self.graphics_pipeline.pipeline);
parent.device.cmd_bind_pipeline(
cmd,
vk::PipelineBindPoint::GRAPHICS,
self.graphics_pipeline.pipeline,
);
// todo: allow frames in flight.
parent.device.cmd_bind_descriptor_sets(cmd, vk::PipelineBindPoint::GRAPHICS, self.graphics_pipeline.layout.layout, 0,
&[self.graphics_pipeline.layout.descriptor_sets[0]], &[]);
parent.device.cmd_bind_descriptor_sets(
cmd,
vk::PipelineBindPoint::GRAPHICS,
self.graphics_pipeline.layout.layout,
0,
&[self.graphics_pipeline.layout.descriptor_sets[0]],
&[],
);
if let Some(push) = &self.reflection.push_constant {
let mut stage_mask = vk::ShaderStageFlags::empty();
@ -139,21 +148,32 @@ impl FilterPass {
stage_mask |= vk::ShaderStageFlags::VERTEX;
}
parent.device.cmd_push_constants(cmd, self.graphics_pipeline.layout.layout, stage_mask, 0, self.uniform_storage.push_slice());
parent.device.cmd_push_constants(
cmd,
self.graphics_pipeline.layout.layout,
stage_mask,
0,
self.uniform_storage.push_slice(),
);
}
parent.draw_quad.bind_vbo(cmd, VboType::Final);
parent.device.cmd_set_scissor(cmd, 0, &[
vk::Rect2D {
parent.device.cmd_set_scissor(
cmd,
0,
&[vk::Rect2D {
offset: vk::Offset2D {
x: output.x as i32,
y: output.y as i32,
},
extent: output.output.size.into()
}]);
extent: output.output.size.into(),
}],
);
parent.device.cmd_set_viewport(cmd, 0, &[output.output.size.into()]);
parent
.device
.cmd_set_viewport(cmd, 0, &[output.output.size.into()]);
parent.device.cmd_draw(cmd, 4, 1, 0, 0);
parent.device.cmd_end_rendering(cmd);
}

View file

@ -1,6 +1,6 @@
use crate::{error, util};
use crate::filter_chain::Vulkan;
use crate::texture::{VulkanImage};
use crate::texture::VulkanImage;
use crate::{error, util};
use ash::vk;
use librashader_common::Size;
@ -13,8 +13,7 @@ pub(crate) struct OutputImage {
}
impl OutputImage {
pub fn new(vulkan: &Vulkan,
image: VulkanImage) -> error::Result<OutputImage> {
pub fn new(vulkan: &Vulkan, image: VulkanImage) -> error::Result<OutputImage> {
let image_subresource = vk::ImageSubresourceRange::builder()
.base_mip_level(0)
.base_array_layer(0)
@ -38,8 +37,7 @@ impl OutputImage {
.components(swizzle_components)
.build();
let image_view = unsafe { vulkan.device.create_image_view(
&view_info, None)? };
let image_view = unsafe { vulkan.device.create_image_view(&view_info, None)? };
Ok(OutputImage {
device: vulkan.device.clone(),
@ -51,32 +49,40 @@ impl OutputImage {
pub fn begin_pass(&self, cmd: vk::CommandBuffer) {
unsafe {
util::vulkan_image_layout_transition_levels(&self.device, cmd, self.image,
1,
vk::ImageLayout::UNDEFINED,
vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
vk::AccessFlags::empty(),
vk::AccessFlags::COLOR_ATTACHMENT_READ | vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
vk::PipelineStageFlags::ALL_GRAPHICS,
vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED)
util::vulkan_image_layout_transition_levels(
&self.device,
cmd,
self.image,
1,
vk::ImageLayout::UNDEFINED,
vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
vk::AccessFlags::empty(),
vk::AccessFlags::COLOR_ATTACHMENT_READ | vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
vk::PipelineStageFlags::ALL_GRAPHICS,
vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED,
)
}
}
pub fn end_pass(&self, cmd: vk::CommandBuffer) {
// todo: generate mips
unsafe {
util::vulkan_image_layout_transition_levels(&self.device, cmd, self.image,
vk::REMAINING_MIP_LEVELS,
vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
vk::AccessFlags::SHADER_READ,
vk::PipelineStageFlags::ALL_GRAPHICS,
vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED)
util::vulkan_image_layout_transition_levels(
&self.device,
cmd,
self.image,
vk::REMAINING_MIP_LEVELS,
vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
vk::AccessFlags::SHADER_READ,
vk::PipelineStageFlags::ALL_GRAPHICS,
vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED,
)
}
}
}

View file

@ -8,7 +8,6 @@ mod swapchain;
mod syncobjects;
pub mod vulkan_base;
use std::ffi::CString;
use crate::filter_chain::{FilterChainVulkan, Vulkan};
use crate::hello_triangle::command::VulkanCommandPool;
use crate::hello_triangle::framebuffer::VulkanFramebuffer;
@ -17,14 +16,15 @@ use crate::hello_triangle::surface::VulkanSurface;
use crate::hello_triangle::swapchain::VulkanSwapchain;
use crate::hello_triangle::syncobjects::SyncObjects;
use crate::hello_triangle::vulkan_base::VulkanBase;
use crate::texture::VulkanImage;
use crate::util;
use crate::viewport::Viewport;
use ash::vk;
use ash::vk::{Handle, RenderingInfo};
use std::ffi::CString;
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder};
use winit::platform::windows::EventLoopBuilderExtWindows;
use crate::texture::VulkanImage;
use crate::viewport::Viewport;
// Constants
const WINDOW_TITLE: &'static str = "librashader Vulkan";
@ -50,8 +50,7 @@ impl VulkanWindow {
mut filter_chain: FilterChainVulkan,
) {
let mut counter = 0;
event_loop.run(move |event, _, control_flow| {
match event {
event_loop.run(move |event, _, control_flow| match event {
Event::WindowEvent { event, .. } => match event {
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
WindowEvent::KeyboardInput { input, .. } => match input {
@ -76,9 +75,7 @@ impl VulkanWindow {
counter += 1;
}
_ => (),
}
})
}
unsafe fn record_command_buffer(
@ -179,7 +176,6 @@ impl VulkanWindow {
.begin_command_buffer(cmd, &vk::CommandBufferBeginInfo::default())
.expect("failed to begin command buffer");
// util::vulkan_image_layout_transition_levels(
// &vulkan.base.device,
// cmd,
@ -212,20 +208,27 @@ impl VulkanWindow {
// vk::QUEUE_FAMILY_IGNORED
// );
let intermediates = filter.frame(frame, &Viewport {
x: 0.0,
y: 0.0,
output: VulkanImage {
size: vulkan.swapchain.extent.into(),
image: swapchain_image,
format: vulkan.swapchain.format.format,
},
mvp: None,
}, &VulkanImage {
size: vulkan.swapchain.extent.into(),
image: framebuffer_image,
format: vulkan.swapchain.format.format,
}, cmd, None)
let intermediates = filter
.frame(
frame,
&Viewport {
x: 0.0,
y: 0.0,
output: VulkanImage {
size: vulkan.swapchain.extent.into(),
image: swapchain_image,
format: vulkan.swapchain.format.format,
},
mvp: None,
},
&VulkanImage {
size: vulkan.swapchain.extent.into(),
image: framebuffer_image,
format: vulkan.swapchain.format.format,
},
cmd,
None,
)
.unwrap();
// eprintln!("{:x}", framebuffer_image.as_raw());

View file

@ -1,4 +1,3 @@
use std::ffi::CStr;
use crate::hello_triangle::surface::VulkanSurface;
use crate::hello_triangle::vulkan_base::VulkanBase;
use crate::util::find_vulkan_memory_type;
@ -6,6 +5,7 @@ use crate::vulkan_primitives::VulkanImageMemory;
use ash::prelude::VkResult;
use ash::vk;
use ash::vk::{Extent3D, Handle};
use std::ffi::CStr;
pub struct VulkanSwapchain {
pub swapchain: vk::SwapchainKHR,
@ -83,19 +83,27 @@ impl VulkanSwapchain {
.tiling(vk::ImageTiling::OPTIMAL)
.array_layers(1)
.mip_levels(1)
.usage(vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::TRANSFER_SRC)
.usage(
vk::ImageUsageFlags::SAMPLED
| vk::ImageUsageFlags::COLOR_ATTACHMENT
| vk::ImageUsageFlags::TRANSFER_SRC,
)
.initial_layout(vk::ImageLayout::UNDEFINED);
unsafe {
let image = base.device.create_image(&create_info, None)?;
let mem_reqs = unsafe { base.device.get_image_memory_requirements(image.clone()) };
base.debug.loader.set_debug_utils_object_name(base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(image.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked(b"RenderImage\0"))
.object_type(vk::ObjectType::IMAGE)
.build())
base.debug
.loader
.set_debug_utils_object_name(
base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(image.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked(b"RenderImage\0"))
.object_type(vk::ObjectType::IMAGE)
.build(),
)
.expect("could not set object name");
let alloc_info = vk::MemoryAllocateInfo::builder()
@ -139,19 +147,31 @@ impl VulkanSwapchain {
let view = unsafe { base.device.create_image_view(&create_info, None)? };
unsafe {
base.debug.loader.set_debug_utils_object_name(base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(image.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked(b"SwapchainImage\0"))
.object_type(vk::ObjectType::IMAGE)
.build())
base.debug
.loader
.set_debug_utils_object_name(
base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(image.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked(
b"SwapchainImage\0",
))
.object_type(vk::ObjectType::IMAGE)
.build(),
)
.expect("could not set object name");
base.debug.loader.set_debug_utils_object_name(base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(view.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked(b"SwapchainImageView\0"))
.object_type(vk::ObjectType::IMAGE_VIEW)
.build())
base.debug
.loader
.set_debug_utils_object_name(
base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(view.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked(
b"SwapchainImageView\0",
))
.object_type(vk::ObjectType::IMAGE_VIEW)
.build(),
)
.expect("could not set object name");
}
Ok(view)
@ -182,12 +202,18 @@ impl VulkanSwapchain {
let view = unsafe { base.device.create_image_view(&create_info, None)? };
unsafe {
base.debug.loader.set_debug_utils_object_name(base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(view.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked(b"RenderImageView\0"))
.object_type(vk::ObjectType::IMAGE_VIEW)
.build())
base.debug
.loader
.set_debug_utils_object_name(
base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(view.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked(
b"RenderImageView\0",
))
.object_type(vk::ObjectType::IMAGE_VIEW)
.build(),
)
.expect("could not set object name");
}
Ok(view)

View file

@ -96,7 +96,6 @@ impl VulkanBase {
// vk::PhysicalDeviceFeatures2::builder().push_next(&mut physical_device_features)
// .build();
let device_create_info = vk::DeviceCreateInfo::builder()
.queue_create_infos(&[queue_info])
.enabled_layer_names(&[debug])
@ -166,7 +165,7 @@ impl TryFrom<&VulkanBase> for Vulkan {
value.device.clone(),
value.graphics_queue.clone(),
value.mem_props,
value.debug.loader.clone()
value.debug.loader.clone(),
))
}
}

View file

@ -14,9 +14,9 @@ mod samplers;
mod texture;
mod ubo_ring;
mod util;
mod viewport;
mod vulkan_primitives;
mod vulkan_state;
mod viewport;
#[cfg(test)]
mod tests {

View file

@ -1,7 +1,7 @@
use crate::{error, util};
use crate::filter_chain::Vulkan;
use crate::util::find_vulkan_memory_type;
use crate::vulkan_primitives::VulkanImageMemory;
use crate::{error, util};
use ash::vk;
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
@ -23,7 +23,7 @@ pub struct OwnedImageLayout {
pub(crate) dst_access: vk::AccessFlags,
pub(crate) src_stage: vk::PipelineStageFlags,
pub(crate) dst_stage: vk::PipelineStageFlags,
pub(crate) cmd: vk::CommandBuffer
pub(crate) cmd: vk::CommandBuffer,
}
impl OwnedImage {
@ -109,7 +109,7 @@ impl OwnedImage {
},
memory,
max_miplevels,
levels: std::cmp::min(max_miplevels, size.calculate_miplevels())
levels: std::cmp::min(max_miplevels, size.calculate_miplevels()),
})
}
@ -119,7 +119,13 @@ impl OwnedImage {
format: ImageFormat,
max_miplevels: u32,
) -> error::Result<OwnedImage> {
Self::new_internal(vulkan.device.clone(), vulkan.memory_properties, size, format, max_miplevels)
Self::new_internal(
vulkan.device.clone(),
vulkan.memory_properties,
size,
format,
max_miplevels,
)
}
pub(crate) fn scale(
@ -130,35 +136,46 @@ impl OwnedImage {
_original: &InputImage,
source: &InputImage,
mipmap: bool,
layout: Option<OwnedImageLayout>
layout: Option<OwnedImageLayout>,
) -> error::Result<Size<u32>> {
let size = source.image.size.scale_viewport(scaling, *viewport_size);
if self.image.size != size || (mipmap && self.max_miplevels == 1) || (!mipmap && self.max_miplevels != 1) {
let max_levels = if mipmap {
u32::MAX
} else {
1
};
if self.image.size != size
|| (mipmap && self.max_miplevels == 1)
|| (!mipmap && self.max_miplevels != 1)
{
let max_levels = if mipmap { u32::MAX } else { 1 };
let mut new = OwnedImage::new_internal(self.device.clone(), self.mem_props, size, if format == ImageFormat::Unknown {
ImageFormat::R8G8B8A8Unorm
} else {
format
}, max_levels)?;
let mut new = OwnedImage::new_internal(
self.device.clone(),
self.mem_props,
size,
if format == ImageFormat::Unknown {
ImageFormat::R8G8B8A8Unorm
} else {
format
},
max_levels,
)?;
let old = std::mem::replace(self, new);
drop(old);
if let Some(layout) = layout {
unsafe {
util::vulkan_image_layout_transition_levels(&self.device, layout.cmd,
self.image.image,
self.levels,
vk::ImageLayout::UNDEFINED,
layout.dst_layout, vk::AccessFlags::empty(),
layout.dst_access, layout.src_stage, layout.dst_stage, vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED)
util::vulkan_image_layout_transition_levels(
&self.device,
layout.cmd,
self.image.image,
self.levels,
vk::ImageLayout::UNDEFINED,
layout.dst_layout,
vk::AccessFlags::empty(),
layout.dst_access,
layout.src_stage,
layout.dst_stage,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED,
)
}
}
}
@ -189,11 +206,10 @@ impl OwnedImage {
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
layer_count: vk::REMAINING_ARRAY_LAYERS
layer_count: vk::REMAINING_ARRAY_LAYERS,
})
.build();
let mipchain_barrier = vk::ImageMemoryBarrier::builder()
.src_access_mask(vk::AccessFlags::empty())
.dst_access_mask(vk::AccessFlags::TRANSFER_WRITE)
@ -207,24 +223,24 @@ impl OwnedImage {
base_mip_level: 1,
base_array_layer: 0,
level_count: vk::REMAINING_MIP_LEVELS,
layer_count: vk::REMAINING_ARRAY_LAYERS
layer_count: vk::REMAINING_ARRAY_LAYERS,
})
.build();
unsafe {
self.device.cmd_pipeline_barrier(cmd,
vk::PipelineStageFlags::ALL_GRAPHICS,
vk::PipelineStageFlags::TRANSFER,
vk::DependencyFlags::empty(),
&[],
&[],
&[input_barrier, mipchain_barrier]
self.device.cmd_pipeline_barrier(
cmd,
vk::PipelineStageFlags::ALL_GRAPHICS,
vk::PipelineStageFlags::TRANSFER,
vk::DependencyFlags::empty(),
&[],
&[],
&[input_barrier, mipchain_barrier],
);
for level in 1..self.levels {
// need to transition from DST to SRC, one level at a time.
if level > 1 {
let next_barrier = vk::ImageMemoryBarrier::builder()
.src_access_mask(vk::AccessFlags::TRANSFER_WRITE)
.dst_access_mask(vk::AccessFlags::TRANSFER_READ)
@ -238,17 +254,18 @@ impl OwnedImage {
base_mip_level: level - 1,
base_array_layer: 0,
level_count: 1,
layer_count: vk::REMAINING_ARRAY_LAYERS
layer_count: vk::REMAINING_ARRAY_LAYERS,
})
.build();
self.device.cmd_pipeline_barrier(cmd,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::TRANSFER,
vk::DependencyFlags::empty(),
&[],
&[],
&[next_barrier]
self.device.cmd_pipeline_barrier(
cmd,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::TRANSFER,
vk::DependencyFlags::empty(),
&[],
&[],
&[next_barrier],
);
}
@ -320,11 +337,10 @@ impl OwnedImage {
base_mip_level: 0,
level_count: self.levels - 1,
base_array_layer: 0,
layer_count: vk::REMAINING_ARRAY_LAYERS
layer_count: vk::REMAINING_ARRAY_LAYERS,
})
.build();
let mipchain_barrier = vk::ImageMemoryBarrier::builder()
.src_access_mask(vk::AccessFlags::TRANSFER_WRITE)
.dst_access_mask(vk::AccessFlags::SHADER_READ)
@ -338,39 +354,47 @@ impl OwnedImage {
base_mip_level: self.levels - 1,
base_array_layer: 0,
level_count: 1,
layer_count: vk::REMAINING_ARRAY_LAYERS
layer_count: vk::REMAINING_ARRAY_LAYERS,
})
.build();
// next past waits for ALL_GRAPHICS, use dependency chain and FRAGMENT_SHADER dst stage
// to ensure that next pass doesn't start until mipchain is complete.
self.device.cmd_pipeline_barrier(cmd,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::DependencyFlags::empty(),
&[],
&[],
&[input_barrier, mipchain_barrier]
self.device.cmd_pipeline_barrier(
cmd,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::DependencyFlags::empty(),
&[],
&[],
&[input_barrier, mipchain_barrier],
);
}
}
/// SAFETY: self must fit the source image
pub unsafe fn copy_from(&self, cmd: vk::CommandBuffer, source: &VulkanImage, source_layout: vk::ImageLayout) {
pub unsafe fn copy_from(
&self,
cmd: vk::CommandBuffer,
source: &VulkanImage,
source_layout: vk::ImageLayout,
) {
let region = vk::ImageCopy::builder()
.src_subresource(vk::ImageSubresourceLayers::builder()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.mip_level(0)
.base_array_layer(0)
.layer_count(1)
.build()
.src_subresource(
vk::ImageSubresourceLayers::builder()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.mip_level(0)
.base_array_layer(0)
.layer_count(1)
.build(),
)
.dst_subresource(vk::ImageSubresourceLayers::builder()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.mip_level(0)
.base_array_layer(0)
.layer_count(1)
.build()
.dst_subresource(
vk::ImageSubresourceLayers::builder()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.mip_level(0)
.base_array_layer(0)
.layer_count(1)
.build(),
)
.src_offset(Default::default())
.dst_offset(Default::default())
@ -378,7 +402,8 @@ impl OwnedImage {
.build();
unsafe {
util::vulkan_image_layout_transition_levels(&self.device,
util::vulkan_image_layout_transition_levels(
&self.device,
cmd,
self.image.image,
vk::REMAINING_MIP_LEVELS,
@ -388,69 +413,80 @@ impl OwnedImage {
vk::AccessFlags::TRANSFER_WRITE,
vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::PipelineStageFlags::TRANSFER,
vk::QUEUE_FAMILY_IGNORED, vk::QUEUE_FAMILY_IGNORED
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED,
);
self.device.cmd_copy_image(cmd, source.image, source_layout, self.image.image, vk::ImageLayout::TRANSFER_DST_OPTIMAL, &[region]);
util::vulkan_image_layout_transition_levels(&self.device,
cmd,
self.image.image,
vk::REMAINING_MIP_LEVELS,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
vk::AccessFlags::TRANSFER_WRITE,
vk::AccessFlags::SHADER_READ,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED
self.device.cmd_copy_image(
cmd,
source.image,
source_layout,
self.image.image,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
&[region],
);
util::vulkan_image_layout_transition_levels(
&self.device,
cmd,
self.image.image,
vk::REMAINING_MIP_LEVELS,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
vk::AccessFlags::TRANSFER_WRITE,
vk::AccessFlags::SHADER_READ,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED,
);
}
}
pub fn clear(&self, cmd: vk::CommandBuffer) {
unsafe {
util::vulkan_image_layout_transition_levels(&self.device,
cmd,
self.image.image,
vk::REMAINING_MIP_LEVELS,
vk::ImageLayout::UNDEFINED,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
vk::AccessFlags::empty(),
vk::AccessFlags::TRANSFER_WRITE,
vk::PipelineStageFlags::TOP_OF_PIPE,
vk::PipelineStageFlags::TRANSFER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED
util::vulkan_image_layout_transition_levels(
&self.device,
cmd,
self.image.image,
vk::REMAINING_MIP_LEVELS,
vk::ImageLayout::UNDEFINED,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
vk::AccessFlags::empty(),
vk::AccessFlags::TRANSFER_WRITE,
vk::PipelineStageFlags::TOP_OF_PIPE,
vk::PipelineStageFlags::TRANSFER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED,
);
self.device.cmd_clear_color_image(cmd,
self.image.image,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
&vk::ClearColorValue {
float32: [0.0, 0.0, 0.0, 0.0]
},
&[vk::ImageSubresourceRange::builder()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.base_mip_level(0)
.level_count(1)
.base_array_layer(0)
.layer_count(1)
.build()]
self.device.cmd_clear_color_image(
cmd,
self.image.image,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
&vk::ClearColorValue {
float32: [0.0, 0.0, 0.0, 0.0],
},
&[vk::ImageSubresourceRange::builder()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.base_mip_level(0)
.level_count(1)
.base_array_layer(0)
.layer_count(1)
.build()],
);
util::vulkan_image_layout_transition_levels(&self.device,
cmd,
self.image.image,
vk::REMAINING_MIP_LEVELS,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
vk::AccessFlags::TRANSFER_WRITE,
vk::AccessFlags::SHADER_READ,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED
util::vulkan_image_layout_transition_levels(
&self.device,
cmd,
self.image.image,
vk::REMAINING_MIP_LEVELS,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
vk::AccessFlags::TRANSFER_WRITE,
vk::AccessFlags::SHADER_READ,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED,
);
}
}
@ -476,7 +512,6 @@ pub struct VulkanImage {
pub format: vk::Format,
}
#[derive(Clone)]
pub struct InputImage {
pub image: VulkanImage,

View file

@ -1,4 +1,3 @@
use crate::texture::VulkanImage;
#[derive(Clone)]