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. /// shader source, returns such format.
pub fn get_format_override(&self) -> Option<ImageFormat> { pub fn get_format_override(&self) -> Option<ImageFormat> {
if self.srgb_framebuffer { if self.srgb_framebuffer {
return Some(ImageFormat::R8G8B8A8Srgb) return Some(ImageFormat::R8G8B8A8Srgb);
} else if self.float_framebuffer { } 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 WIDTH: i32 = 800;
const HEIGHT: i32 = 1080; const HEIGHT: i32 = 600;
const TITLE: &str = "librashader DirectX 11"; const TITLE: &str = "librashader DirectX 11";
use windows::{ use windows::{

View file

@ -23,13 +23,13 @@ pub use viewport::Viewport;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::options::FilterChainOptionsD3D11;
use super::*; use super::*;
use crate::options::FilterChainOptionsD3D11;
#[test] #[test]
fn triangle_d3d11() { fn triangle_d3d11() {
let sample = hello_triangle::d3d11_hello_triangle::Sample::new( 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 { Some(&FilterChainOptionsD3D11 {
use_deferred_context: false, use_deferred_context: false,
force_no_mipmaps: false, force_no_mipmaps: false,

View file

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

View file

@ -44,7 +44,7 @@ impl Framebuffer {
viewport: &Viewport, viewport: &Viewport,
original: &Texture, original: &Texture,
source: &Texture, source: &Texture,
mipmap: bool mipmap: bool,
) -> Result<Size<u32>> { ) -> Result<Size<u32>> {
T::scale(self, scaling, format, viewport, original, source, mipmap) 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) { pub fn bind_vbo(&self, cmd: vk::CommandBuffer, vbo: VboType) {
unsafe { unsafe {
self.device.cmd_bind_vertex_buffers( self.device
cmd, .cmd_bind_vertex_buffers(cmd, 0, &[self.buffer.handle], &[0])
0,
&[self.buffer.handle],
&[0],
)
} }
} }
} }

View file

@ -1,12 +1,19 @@
use std::collections::VecDeque; use crate::draw_quad::DrawQuad;
use crate::{error, util};
use crate::filter_pass::FilterPass; use crate::filter_pass::FilterPass;
use crate::framebuffer::OutputImage;
use crate::luts::LutTexture; use crate::luts::LutTexture;
use crate::render_target::{RenderTarget, DEFAULT_MVP};
use crate::samplers::SamplerSet; 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::ubo_ring::VkUboRing;
use crate::viewport::Viewport;
use crate::vulkan_state::VulkanGraphicsPipeline; 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 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;
@ -21,14 +28,10 @@ use librashader_reflect::reflect::ReflectShader;
use librashader_runtime::image::{Image, UVDirection}; 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::collections::VecDeque;
use std::error::Error; use std::error::Error;
use std::ffi::CStr; use std::ffi::CStr;
use std::path::Path; 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 { pub struct Vulkan {
// physical_device: vk::PhysicalDevice, // physical_device: vk::PhysicalDevice,
@ -38,7 +41,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 debug: DebugUtils,
} }
type ShaderPassMeta = ( type ShaderPassMeta = (
@ -85,9 +88,12 @@ impl TryFrom<VulkanInfo<'_>> for Vulkan {
)? )?
}; };
let debug = DebugUtils::new(&Entry::from_static_fn(StaticFn { let debug = DebugUtils::new(
get_instance_proc_addr: vulkan.get_instance_proc_addr, &Entry::from_static_fn(StaticFn {
}), &instance); get_instance_proc_addr: vulkan.get_instance_proc_addr,
}),
&instance,
);
Ok(Vulkan { Ok(Vulkan {
device, device,
@ -96,16 +102,30 @@ 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 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>; 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 { unsafe {
let device = value.0; let device = value.0;
@ -128,7 +148,7 @@ impl TryFrom<(ash::Device, vk::Queue, vk::PhysicalDeviceMemoryProperties, DebugU
command_pool, command_pool,
pipeline_cache, pipeline_cache,
memory_properties: value.2, memory_properties: value.2,
debug: value.3 debug: value.3,
}) })
} }
} }
@ -164,7 +184,7 @@ pub(crate) struct FilterCommon {
pub struct FilterChainFrameIntermediates { pub struct FilterChainFrameIntermediates {
device: ash::Device, device: ash::Device,
image_views: Vec<vk::ImageView>, image_views: Vec<vk::ImageView>,
owned: Vec<OwnedImage> owned: Vec<OwnedImage>,
} }
impl FilterChainFrameIntermediates { impl FilterChainFrameIntermediates {
@ -235,29 +255,21 @@ impl FilterChainVulkan {
let mut output_framebuffers = Vec::new(); let mut output_framebuffers = Vec::new();
output_framebuffers.resize_with(filters.len(), || { output_framebuffers.resize_with(filters.len(), || {
OwnedImage::new( OwnedImage::new(&device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, 1)
&device,
Size::new(1, 1),
ImageFormat::R8G8B8A8Unorm,
1
)
}); });
let mut feedback_framebuffers = Vec::new(); let mut feedback_framebuffers = Vec::new();
feedback_framebuffers.resize_with(filters.len(), || { feedback_framebuffers.resize_with(filters.len(), || {
OwnedImage::new( OwnedImage::new(&device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, 1)
&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(); let mut output_textures = Vec::new();
output_textures.resize_with(filters.len(), || None); 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(); let mut feedback_textures = Vec::new();
feedback_textures.resize_with(filters.len(), || None); feedback_textures.resize_with(filters.len(), || None);
@ -499,12 +511,9 @@ impl FilterChainVulkan {
eprintln!("[history] using frame history with {required_images} images"); eprintln!("[history] using frame history with {required_images} images");
let mut images = Vec::with_capacity(required_images); let mut images = Vec::with_capacity(required_images);
images.resize_with(required_images, || OwnedImage::new( images.resize_with(required_images, || {
&vulkan, OwnedImage::new(&vulkan, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, 1)
Size::new(1, 1), });
ImageFormat::R8G8B8A8Unorm,
1
));
let images: error::Result<Vec<OwnedImage>> = images.into_iter().collect(); let images: error::Result<Vec<OwnedImage>> = images.into_iter().collect();
let images = VecDeque::from(images?); let images = VecDeque::from(images?);
@ -516,19 +525,29 @@ impl FilterChainVulkan {
} }
// image must be in SHADER_READ_OPTIMAL // image must be in SHADER_READ_OPTIMAL
pub fn push_history(&mut self, input: &VulkanImage, intermediates: &mut FilterChainFrameIntermediates, pub fn push_history(
cmd: vk::CommandBuffer) -> error::Result<()> { &mut self,
input: &VulkanImage,
intermediates: &mut FilterChainFrameIntermediates,
cmd: vk::CommandBuffer,
) -> 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 || (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"); eprintln!("[history] resizing");
// old back will get dropped.. do we need to defer? // old back will get dropped.. do we need to defer?
let old_back = let old_back = std::mem::replace(
std::mem::replace(&mut back, OwnedImage::new(&self.vulkan, input.size, input.format.into(), 1)?); &mut back,
OwnedImage::new(&self.vulkan, input.size, input.format.into(), 1)?,
);
intermediates.dispose_owned(old_back); intermediates.dispose_owned(old_back);
} }
unsafe { unsafe {
util::vulkan_image_layout_transition_levels(&self.vulkan.device, cmd, util::vulkan_image_layout_transition_levels(
&self.vulkan.device,
cmd,
input.image, input.image,
1, 1,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL, vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
@ -538,24 +557,25 @@ impl FilterChainVulkan {
vk::PipelineStageFlags::FRAGMENT_SHADER, vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::PipelineStageFlags::TRANSFER, vk::PipelineStageFlags::TRANSFER,
vk::QUEUE_FAMILY_IGNORED, vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED vk::QUEUE_FAMILY_IGNORED,
); );
back.copy_from(cmd, &input, vk::ImageLayout::TRANSFER_SRC_OPTIMAL); back.copy_from(cmd, &input, vk::ImageLayout::TRANSFER_SRC_OPTIMAL);
util::vulkan_image_layout_transition_levels(&self.vulkan.device, cmd, util::vulkan_image_layout_transition_levels(
input.image, &self.vulkan.device,
1, cmd,
vk::ImageLayout::TRANSFER_SRC_OPTIMAL, input.image,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL, 1,
vk::AccessFlags::TRANSFER_READ, vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
vk::AccessFlags::SHADER_READ, vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
vk::PipelineStageFlags::TRANSFER, vk::AccessFlags::TRANSFER_READ,
vk::PipelineStageFlags::FRAGMENT_SHADER, vk::AccessFlags::SHADER_READ,
vk::QUEUE_FAMILY_IGNORED, vk::PipelineStageFlags::TRANSFER,
vk::QUEUE_FAMILY_IGNORED vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED,
); );
} }
self.history_framebuffers.push_front(back) self.history_framebuffers.push_front(back)
@ -592,17 +612,21 @@ impl FilterChainVulkan {
.image(input.image) .image(input.image)
.format(input.format) .format(input.format)
.view_type(vk::ImageViewType::TYPE_2D) .view_type(vk::ImageViewType::TYPE_2D)
.subresource_range(vk::ImageSubresourceRange::builder() .subresource_range(
.aspect_mask(vk::ImageAspectFlags::COLOR) vk::ImageSubresourceRange::builder()
.level_count(1) .aspect_mask(vk::ImageAspectFlags::COLOR)
.layer_count(1) .level_count(1)
.build()) .layer_count(1)
.components(vk::ComponentMapping::builder() .build(),
.r(vk::ComponentSwizzle::R) )
.g(vk::ComponentSwizzle::G) .components(
.b(vk::ComponentSwizzle::B) vk::ComponentMapping::builder()
.a(vk::ComponentSwizzle::A) .r(vk::ComponentSwizzle::R)
.build()) .g(vk::ComponentSwizzle::G)
.b(vk::ComponentSwizzle::B)
.a(vk::ComponentSwizzle::A)
.build(),
)
.build(); .build();
self.vulkan.device.create_image_view(&create_info, None)? self.vulkan.device.create_image_view(&create_info, None)?
@ -632,7 +656,10 @@ impl FilterChainVulkan {
let mut source = &original; let mut source = &original;
// swap output and feedback **before** recording command buffers // 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. // 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() {
@ -655,15 +682,17 @@ impl FilterChainVulkan {
source, source,
// todo: need to check **next** // todo: need to check **next**
pass.config.mipmap_input, pass.config.mipmap_input,
None None,
)?; )?;
// self.feedback_framebuffers[index].image.image
// refresh inputs // refresh inputs
self.common.feedback_inputs[index] = self.common.feedback_inputs[index] = Some(
Some(self.feedback_framebuffers[index].as_input(pass.config.filter, pass.config.wrap_mode)); self.feedback_framebuffers[index]
self.common.output_inputs[index] = .as_input(pass.config.filter, pass.config.wrap_mode),
Some(self.output_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();
@ -679,17 +708,27 @@ impl FilterChainVulkan {
x: 0.0, x: 0.0,
y: 0.0, y: 0.0,
mvp: DEFAULT_MVP, mvp: DEFAULT_MVP,
output: OutputImage::new(&self.vulkan, /*&pass.graphics_pipeline.render_pass,*/ output: OutputImage::new(
target.image.clone())?, &self.vulkan, /*&pass.graphics_pipeline.render_pass,*/
target.image.clone(),
)?,
}; };
pass.draw(cmd, index, &self.common, if pass.config.frame_count_mod > 0 { pass.draw(
count % pass.config.frame_count_mod as usize cmd,
} else { index,
count &self.common,
} as u32 if pass.config.frame_count_mod > 0 {
, 0, count % pass.config.frame_count_mod as usize
viewport, &original, &source, &out)?; } else {
count
} as u32,
0,
viewport,
&original,
&source,
&out,
)?;
if target.max_miplevels > 1 { if target.max_miplevels > 1 {
target.generate_mipmaps_and_end_pass(cmd); target.generate_mipmaps_and_end_pass(cmd);
@ -711,14 +750,20 @@ impl FilterChainVulkan {
x: viewport.x, x: viewport.x,
y: viewport.y, y: viewport.y,
mvp: viewport.mvp.unwrap_or(DEFAULT_MVP), mvp: viewport.mvp.unwrap_or(DEFAULT_MVP),
output: OutputImage::new(&self.vulkan, output: OutputImage::new(&self.vulkan, viewport.output.clone())?,
viewport.output.clone())?,
}; };
pass.draw(cmd, passes_len - 1, pass.draw(
&self.common, cmd,
count as u32, passes_len - 1,
0, viewport, &original, source, &out)?; &self.common,
count as u32,
0,
viewport,
&original,
source,
&out,
)?;
intermediates.dispose_outputs(out.output); 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::filter_chain::FilterCommon;
use crate::render_target::RenderTarget; use crate::render_target::RenderTarget;
use crate::samplers::{SamplerSet, VulkanSampler}; use crate::samplers::{SamplerSet, VulkanSampler};
use crate::texture::InputImage; use crate::texture::InputImage;
use crate::ubo_ring::VkUboRing; use crate::ubo_ring::VkUboRing;
use crate::viewport::Viewport;
use crate::vulkan_state::VulkanGraphicsPipeline; use crate::vulkan_state::VulkanGraphicsPipeline;
use crate::{error, util};
use ash::vk; use ash::vk;
use librashader_common::{ImageFormat, Size}; use librashader_common::{ImageFormat, Size};
use librashader_preprocess::ShaderSource; use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPassConfig; use librashader_presets::ShaderPassConfig;
use librashader_reflect::back::ShaderCompilerOutput; 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_reflect::reflect::ShaderReflection;
use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess}; use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use crate::draw_quad::VboType;
use crate::viewport::Viewport;
pub struct FilterPass { pub struct FilterPass {
pub device: ash::Device, pub device: ash::Device,
@ -114,21 +116,28 @@ impl FilterPass {
let rendering_info = vk::RenderingInfo::builder() let rendering_info = vk::RenderingInfo::builder()
.layer_count(1) .layer_count(1)
.render_area(vk::Rect2D { .render_area(vk::Rect2D {
offset: vk::Offset2D { offset: vk::Offset2D { x: 0, y: 0 },
x: 0,
y: 0,
},
extent: output.output.size.into(), extent: output.output.size.into(),
}) })
.color_attachments(&attachments); .color_attachments(&attachments);
unsafe { unsafe {
parent.device.cmd_begin_rendering(cmd, &rendering_info); 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. // todo: allow frames in flight.
parent.device.cmd_bind_descriptor_sets(cmd, vk::PipelineBindPoint::GRAPHICS, self.graphics_pipeline.layout.layout, 0, parent.device.cmd_bind_descriptor_sets(
&[self.graphics_pipeline.layout.descriptor_sets[0]], &[]); 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 { if let Some(push) = &self.reflection.push_constant {
let mut stage_mask = vk::ShaderStageFlags::empty(); let mut stage_mask = vk::ShaderStageFlags::empty();
@ -139,21 +148,32 @@ impl FilterPass {
stage_mask |= vk::ShaderStageFlags::VERTEX; 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.draw_quad.bind_vbo(cmd, VboType::Final);
parent.device.cmd_set_scissor(cmd, 0, &[ parent.device.cmd_set_scissor(
vk::Rect2D { cmd,
0,
&[vk::Rect2D {
offset: vk::Offset2D { offset: vk::Offset2D {
x: output.x as i32, x: output.x as i32,
y: output.y 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_draw(cmd, 4, 1, 0, 0);
parent.device.cmd_end_rendering(cmd); parent.device.cmd_end_rendering(cmd);
} }

View file

@ -1,6 +1,6 @@
use crate::{error, util};
use crate::filter_chain::Vulkan; use crate::filter_chain::Vulkan;
use crate::texture::{VulkanImage}; use crate::texture::VulkanImage;
use crate::{error, util};
use ash::vk; use ash::vk;
use librashader_common::Size; use librashader_common::Size;
@ -13,8 +13,7 @@ pub(crate) struct OutputImage {
} }
impl OutputImage { impl OutputImage {
pub fn new(vulkan: &Vulkan, pub fn new(vulkan: &Vulkan, image: VulkanImage) -> error::Result<OutputImage> {
image: VulkanImage) -> error::Result<OutputImage> {
let image_subresource = vk::ImageSubresourceRange::builder() let image_subresource = vk::ImageSubresourceRange::builder()
.base_mip_level(0) .base_mip_level(0)
.base_array_layer(0) .base_array_layer(0)
@ -38,8 +37,7 @@ impl OutputImage {
.components(swizzle_components) .components(swizzle_components)
.build(); .build();
let image_view = unsafe { vulkan.device.create_image_view( let image_view = unsafe { vulkan.device.create_image_view(&view_info, None)? };
&view_info, None)? };
Ok(OutputImage { Ok(OutputImage {
device: vulkan.device.clone(), device: vulkan.device.clone(),
@ -51,32 +49,40 @@ impl OutputImage {
pub fn begin_pass(&self, cmd: vk::CommandBuffer) { pub fn begin_pass(&self, cmd: vk::CommandBuffer) {
unsafe { unsafe {
util::vulkan_image_layout_transition_levels(&self.device, cmd, self.image, util::vulkan_image_layout_transition_levels(
1, &self.device,
vk::ImageLayout::UNDEFINED, cmd,
vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, self.image,
vk::AccessFlags::empty(), 1,
vk::AccessFlags::COLOR_ATTACHMENT_READ | vk::AccessFlags::COLOR_ATTACHMENT_WRITE, vk::ImageLayout::UNDEFINED,
vk::PipelineStageFlags::ALL_GRAPHICS, vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT, vk::AccessFlags::empty(),
vk::QUEUE_FAMILY_IGNORED, vk::AccessFlags::COLOR_ATTACHMENT_READ | vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
vk::QUEUE_FAMILY_IGNORED) 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) { pub fn end_pass(&self, cmd: vk::CommandBuffer) {
// todo: generate mips // todo: generate mips
unsafe { unsafe {
util::vulkan_image_layout_transition_levels(&self.device, cmd, self.image, util::vulkan_image_layout_transition_levels(
vk::REMAINING_MIP_LEVELS, &self.device,
vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, cmd,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL, self.image,
vk::AccessFlags::COLOR_ATTACHMENT_WRITE, vk::REMAINING_MIP_LEVELS,
vk::AccessFlags::SHADER_READ, vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
vk::PipelineStageFlags::ALL_GRAPHICS, vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
vk::PipelineStageFlags::FRAGMENT_SHADER, vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
vk::QUEUE_FAMILY_IGNORED, vk::AccessFlags::SHADER_READ,
vk::QUEUE_FAMILY_IGNORED) 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; mod syncobjects;
pub mod vulkan_base; pub mod vulkan_base;
use std::ffi::CString;
use crate::filter_chain::{FilterChainVulkan, Vulkan}; use crate::filter_chain::{FilterChainVulkan, Vulkan};
use crate::hello_triangle::command::VulkanCommandPool; use crate::hello_triangle::command::VulkanCommandPool;
use crate::hello_triangle::framebuffer::VulkanFramebuffer; 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::swapchain::VulkanSwapchain;
use crate::hello_triangle::syncobjects::SyncObjects; 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::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 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 crate::texture::VulkanImage;
use crate::viewport::Viewport;
// Constants // Constants
const WINDOW_TITLE: &'static str = "librashader Vulkan"; const WINDOW_TITLE: &'static str = "librashader Vulkan";
@ -50,8 +50,7 @@ impl VulkanWindow {
mut filter_chain: FilterChainVulkan, mut filter_chain: FilterChainVulkan,
) { ) {
let mut counter = 0; let mut counter = 0;
event_loop.run(move |event, _, control_flow| { event_loop.run(move |event, _, control_flow| match event {
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 {
@ -76,9 +75,7 @@ impl VulkanWindow {
counter += 1; counter += 1;
} }
_ => (), _ => (),
}
}) })
} }
unsafe fn record_command_buffer( unsafe fn record_command_buffer(
@ -179,7 +176,6 @@ impl VulkanWindow {
.begin_command_buffer(cmd, &vk::CommandBufferBeginInfo::default()) .begin_command_buffer(cmd, &vk::CommandBufferBeginInfo::default())
.expect("failed to begin command buffer"); .expect("failed to begin command buffer");
// util::vulkan_image_layout_transition_levels( // util::vulkan_image_layout_transition_levels(
// &vulkan.base.device, // &vulkan.base.device,
// cmd, // cmd,
@ -212,20 +208,27 @@ impl VulkanWindow {
// vk::QUEUE_FAMILY_IGNORED // vk::QUEUE_FAMILY_IGNORED
// ); // );
let intermediates = filter.frame(frame, &Viewport { let intermediates = filter
x: 0.0, .frame(
y: 0.0, frame,
output: VulkanImage { &Viewport {
size: vulkan.swapchain.extent.into(), x: 0.0,
image: swapchain_image, y: 0.0,
format: vulkan.swapchain.format.format, output: VulkanImage {
}, size: vulkan.swapchain.extent.into(),
mvp: None, image: swapchain_image,
}, &VulkanImage { format: vulkan.swapchain.format.format,
size: vulkan.swapchain.extent.into(), },
image: framebuffer_image, mvp: None,
format: vulkan.swapchain.format.format, },
}, cmd, None) &VulkanImage {
size: vulkan.swapchain.extent.into(),
image: framebuffer_image,
format: vulkan.swapchain.format.format,
},
cmd,
None,
)
.unwrap(); .unwrap();
// eprintln!("{:x}", framebuffer_image.as_raw()); // 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::surface::VulkanSurface;
use crate::hello_triangle::vulkan_base::VulkanBase; use crate::hello_triangle::vulkan_base::VulkanBase;
use crate::util::find_vulkan_memory_type; use crate::util::find_vulkan_memory_type;
@ -6,6 +5,7 @@ use crate::vulkan_primitives::VulkanImageMemory;
use ash::prelude::VkResult; use ash::prelude::VkResult;
use ash::vk; use ash::vk;
use ash::vk::{Extent3D, Handle}; use ash::vk::{Extent3D, Handle};
use std::ffi::CStr;
pub struct VulkanSwapchain { pub struct VulkanSwapchain {
pub swapchain: vk::SwapchainKHR, pub swapchain: vk::SwapchainKHR,
@ -83,19 +83,27 @@ impl VulkanSwapchain {
.tiling(vk::ImageTiling::OPTIMAL) .tiling(vk::ImageTiling::OPTIMAL)
.array_layers(1) .array_layers(1)
.mip_levels(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); .initial_layout(vk::ImageLayout::UNDEFINED);
unsafe { unsafe {
let image = base.device.create_image(&create_info, None)?; let image = base.device.create_image(&create_info, None)?;
let mem_reqs = unsafe { base.device.get_image_memory_requirements(image.clone()) }; let mem_reqs = unsafe { base.device.get_image_memory_requirements(image.clone()) };
base.debug.loader.set_debug_utils_object_name(base.device.handle(), base.debug
&vk::DebugUtilsObjectNameInfoEXT::builder() .loader
.object_handle(image.as_raw()) .set_debug_utils_object_name(
.object_name(CStr::from_bytes_with_nul_unchecked(b"RenderImage\0")) base.device.handle(),
.object_type(vk::ObjectType::IMAGE) &vk::DebugUtilsObjectNameInfoEXT::builder()
.build()) .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"); .expect("could not set object name");
let alloc_info = vk::MemoryAllocateInfo::builder() let alloc_info = vk::MemoryAllocateInfo::builder()
@ -139,19 +147,31 @@ impl VulkanSwapchain {
let view = unsafe { base.device.create_image_view(&create_info, None)? }; let view = unsafe { base.device.create_image_view(&create_info, None)? };
unsafe { unsafe {
base.debug.loader.set_debug_utils_object_name(base.device.handle(), base.debug
&vk::DebugUtilsObjectNameInfoEXT::builder() .loader
.object_handle(image.as_raw()) .set_debug_utils_object_name(
.object_name(CStr::from_bytes_with_nul_unchecked(b"SwapchainImage\0")) base.device.handle(),
.object_type(vk::ObjectType::IMAGE) &vk::DebugUtilsObjectNameInfoEXT::builder()
.build()) .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"); .expect("could not set object name");
base.debug.loader.set_debug_utils_object_name(base.device.handle(), base.debug
&vk::DebugUtilsObjectNameInfoEXT::builder() .loader
.object_handle(view.as_raw()) .set_debug_utils_object_name(
.object_name(CStr::from_bytes_with_nul_unchecked(b"SwapchainImageView\0")) base.device.handle(),
.object_type(vk::ObjectType::IMAGE_VIEW) &vk::DebugUtilsObjectNameInfoEXT::builder()
.build()) .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"); .expect("could not set object name");
} }
Ok(view) Ok(view)
@ -182,12 +202,18 @@ impl VulkanSwapchain {
let view = unsafe { base.device.create_image_view(&create_info, None)? }; let view = unsafe { base.device.create_image_view(&create_info, None)? };
unsafe { unsafe {
base.debug.loader.set_debug_utils_object_name(base.device.handle(), base.debug
&vk::DebugUtilsObjectNameInfoEXT::builder() .loader
.object_handle(view.as_raw()) .set_debug_utils_object_name(
.object_name(CStr::from_bytes_with_nul_unchecked(b"RenderImageView\0")) base.device.handle(),
.object_type(vk::ObjectType::IMAGE_VIEW) &vk::DebugUtilsObjectNameInfoEXT::builder()
.build()) .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"); .expect("could not set object name");
} }
Ok(view) Ok(view)

View file

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

View file

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

View file

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

View file

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