diff --git a/librashader-presets/src/preset.rs b/librashader-presets/src/preset.rs index a4a5be6..b1dfc02 100644 --- a/librashader-presets/src/preset.rs +++ b/librashader-presets/src/preset.rs @@ -34,11 +34,11 @@ impl ShaderPassConfig { /// shader source, returns such format. pub fn get_format_override(&self) -> Option { 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; } } diff --git a/librashader-runtime-d3d11/src/hello_triangle.rs b/librashader-runtime-d3d11/src/hello_triangle.rs index 984dc83..c2d943f 100644 --- a/librashader-runtime-d3d11/src/hello_triangle.rs +++ b/librashader-runtime-d3d11/src/hello_triangle.rs @@ -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::{ diff --git a/librashader-runtime-d3d11/src/lib.rs b/librashader-runtime-d3d11/src/lib.rs index 0a8e669..3cd4d51 100644 --- a/librashader-runtime-d3d11/src/lib.rs +++ b/librashader-runtime-d3d11/src/lib.rs @@ -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, diff --git a/librashader-runtime-gl/src/filter_chain/filter_impl.rs b/librashader-runtime-gl/src/filter_chain/filter_impl.rs index eb98387..bd531e5 100644 --- a/librashader-runtime-gl/src/filter_chain/filter_impl.rs +++ b/librashader-runtime-gl/src/filter_chain/filter_impl.rs @@ -261,7 +261,7 @@ impl FilterChainImpl { 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 FilterChainImpl { viewport, &original, &source, - pass.config.mipmap_input + pass.config.mipmap_input, )?; self.feedback_framebuffers[index].scale::( @@ -505,7 +505,7 @@ impl FilterChainImpl { viewport, &original, &source, - pass.config.mipmap_input + pass.config.mipmap_input, )?; } diff --git a/librashader-runtime-gl/src/gl/framebuffer.rs b/librashader-runtime-gl/src/gl/framebuffer.rs index 9bd0637..f38a41e 100644 --- a/librashader-runtime-gl/src/gl/framebuffer.rs +++ b/librashader-runtime-gl/src/gl/framebuffer.rs @@ -44,7 +44,7 @@ impl Framebuffer { viewport: &Viewport, original: &Texture, source: &Texture, - mipmap: bool + mipmap: bool, ) -> Result> { T::scale(self, scaling, format, viewport, original, source, mipmap) } diff --git a/librashader-runtime-vk/src/draw_quad.rs b/librashader-runtime-vk/src/draw_quad.rs index 7b78d20..e3b51d6 100644 --- a/librashader-runtime-vk/src/draw_quad.rs +++ b/librashader-runtime-vk/src/draw_quad.rs @@ -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]) } } } diff --git a/librashader-runtime-vk/src/filter_chain.rs b/librashader-runtime-vk/src/filter_chain.rs index 1c81a5d..2a7d755 100644 --- a/librashader-runtime-vk/src/filter_chain.rs +++ b/librashader-runtime-vk/src/filter_chain.rs @@ -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> 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> 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; - fn try_from(value: (Device, Queue, vk::PhysicalDeviceMemoryProperties, DebugUtils)) -> error::Result { + fn try_from( + value: ( + Device, + Queue, + vk::PhysicalDeviceMemoryProperties, + DebugUtils, + ), + ) -> error::Result { 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, - owned: Vec + owned: Vec, } 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> = output_framebuffers.into_iter().collect(); + let output_framebuffers: error::Result> = + output_framebuffers.into_iter().collect(); let mut output_textures = Vec::new(); output_textures.resize_with(filters.len(), || None); - let feedback_framebuffers: error::Result> = feedback_framebuffers.into_iter().collect(); + let feedback_framebuffers: error::Result> = + 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> = 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); } diff --git a/librashader-runtime-vk/src/filter_pass.rs b/librashader-runtime-vk/src/filter_pass.rs index 051b08d..330a510 100644 --- a/librashader-runtime-vk/src/filter_pass.rs +++ b/librashader-runtime-vk/src/filter_pass.rs @@ -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); } diff --git a/librashader-runtime-vk/src/framebuffer.rs b/librashader-runtime-vk/src/framebuffer.rs index eda0dae..b33a86f 100644 --- a/librashader-runtime-vk/src/framebuffer.rs +++ b/librashader-runtime-vk/src/framebuffer.rs @@ -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 { + pub fn new(vulkan: &Vulkan, image: VulkanImage) -> error::Result { 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, + ) } } } diff --git a/librashader-runtime-vk/src/hello_triangle/mod.rs b/librashader-runtime-vk/src/hello_triangle/mod.rs index f6b4c1f..d054634 100644 --- a/librashader-runtime-vk/src/hello_triangle/mod.rs +++ b/librashader-runtime-vk/src/hello_triangle/mod.rs @@ -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()); diff --git a/librashader-runtime-vk/src/hello_triangle/swapchain.rs b/librashader-runtime-vk/src/hello_triangle/swapchain.rs index bff1fc3..f1f1ee3 100644 --- a/librashader-runtime-vk/src/hello_triangle/swapchain.rs +++ b/librashader-runtime-vk/src/hello_triangle/swapchain.rs @@ -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) diff --git a/librashader-runtime-vk/src/hello_triangle/vulkan_base.rs b/librashader-runtime-vk/src/hello_triangle/vulkan_base.rs index e708293..1057cee 100644 --- a/librashader-runtime-vk/src/hello_triangle/vulkan_base.rs +++ b/librashader-runtime-vk/src/hello_triangle/vulkan_base.rs @@ -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(), )) } } diff --git a/librashader-runtime-vk/src/lib.rs b/librashader-runtime-vk/src/lib.rs index ee86bdc..e8a3386 100644 --- a/librashader-runtime-vk/src/lib.rs +++ b/librashader-runtime-vk/src/lib.rs @@ -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 { diff --git a/librashader-runtime-vk/src/texture.rs b/librashader-runtime-vk/src/texture.rs index 807326b..0587fe4 100644 --- a/librashader-runtime-vk/src/texture.rs +++ b/librashader-runtime-vk/src/texture.rs @@ -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 { - 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 + layout: Option, ) -> error::Result> { 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, diff --git a/librashader-runtime-vk/src/viewport.rs b/librashader-runtime-vk/src/viewport.rs index e20669c..a2d0cc9 100644 --- a/librashader-runtime-vk/src/viewport.rs +++ b/librashader-runtime-vk/src/viewport.rs @@ -1,4 +1,3 @@ - use crate::texture::VulkanImage; #[derive(Clone)]