From ace6774a158e7f56e90ae2d20100f7bd098377ee Mon Sep 17 00:00:00 2001 From: chyyran Date: Wed, 11 Jan 2023 02:36:37 -0500 Subject: [PATCH] vk: accept output viewport --- librashader-runtime-vk/src/filter_chain.rs | 7 +- librashader-runtime-vk/src/filter_pass.rs | 16 +++- .../src/hello_triangle/mod.rs | 14 ++- .../src/hello_triangle/swapchain.rs | 93 ++++++++++--------- librashader-runtime-vk/src/lib.rs | 1 + librashader-runtime-vk/src/render_target.rs | 2 + librashader-runtime-vk/src/viewport.rs | 10 ++ 7 files changed, 86 insertions(+), 57 deletions(-) create mode 100644 librashader-runtime-vk/src/viewport.rs diff --git a/librashader-runtime-vk/src/filter_chain.rs b/librashader-runtime-vk/src/filter_chain.rs index 62f1262..fb4bd19 100644 --- a/librashader-runtime-vk/src/filter_chain.rs +++ b/librashader-runtime-vk/src/filter_chain.rs @@ -25,6 +25,7 @@ use std::path::Path; use crate::draw_quad::{DrawQuad, VBO_DEFAULT_FINAL, VBO_OFFSCREEN}; use crate::framebuffer::OutputFramebuffer; use crate::render_target::{DEFAULT_MVP, RenderTarget}; +use crate::viewport::Viewport; pub struct Vulkan { // physical_device: vk::PhysicalDevice, @@ -453,7 +454,7 @@ impl FilterChainVulkan { pub fn frame( &mut self, count: usize, - viewport: &vk::Viewport, + viewport: &Viewport, input: &VulkanImage, cmd: vk::CommandBuffer, options: Option<()>, @@ -502,7 +503,7 @@ impl FilterChainVulkan { self.output_framebuffers[index].scale( pass.config.scaling.clone(), pass.get_format(), - &viewport.into(), + &viewport.output.size, &original, &source, )?; @@ -515,6 +516,8 @@ impl FilterChainVulkan { // todo: the output framebuffers can only be dropped after command queue submission. let out = RenderTarget { + x: 0.0, + y: 0.0, mvp: DEFAULT_MVP, output: OutputFramebuffer::new(&self.vulkan, &pass.graphics_pipeline.render_pass, target.image.image, target.image.size)?, }; diff --git a/librashader-runtime-vk/src/filter_pass.rs b/librashader-runtime-vk/src/filter_pass.rs index 7017a56..64ddb84 100644 --- a/librashader-runtime-vk/src/filter_pass.rs +++ b/librashader-runtime-vk/src/filter_pass.rs @@ -15,6 +15,7 @@ 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, @@ -73,7 +74,7 @@ impl FilterPass { parent: &FilterCommon, frame_count: u32, frame_direction: i32, - viewport: &vk::Viewport, + viewport: &Viewport, original: &InputTexture, source: &InputTexture, output: &RenderTarget, @@ -87,7 +88,7 @@ impl FilterPass { frame_count, frame_direction, output.output.size, - viewport.into(), + viewport.output.size, &descriptor, original, source, @@ -110,8 +111,12 @@ impl FilterPass { float32: [0.0, 0.0, 0.0, 0.0] } }]) + // always render into the full output, regardless of viewport settings. .render_area(vk::Rect2D { - offset: Default::default(), + offset: vk::Offset2D { + x: 0, + y: 0, + }, extent: output.output.size.into(), }).build(); @@ -139,7 +144,10 @@ impl FilterPass { parent.device.cmd_set_scissor(cmd, 0, &[ vk::Rect2D { - offset: Default::default(), + offset: vk::Offset2D { + x: output.x as i32, + y: output.y as i32, + }, extent: output.output.size.into() }]); diff --git a/librashader-runtime-vk/src/hello_triangle/mod.rs b/librashader-runtime-vk/src/hello_triangle/mod.rs index d261654..9124f5b 100644 --- a/librashader-runtime-vk/src/hello_triangle/mod.rs +++ b/librashader-runtime-vk/src/hello_triangle/mod.rs @@ -24,6 +24,7 @@ use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEve 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"; @@ -206,13 +207,15 @@ impl VulkanWindow { // vk::QUEUE_FAMILY_IGNORED // ); - let intermediates = filter.frame(0, &vk::Viewport { + let intermediates = filter.frame(0, &Viewport { x: 0.0, y: 0.0, - width: vulkan.swapchain.extent.width as f32, - height: vulkan.swapchain.extent.height as f32, - min_depth: 0.0, - max_depth: 1.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, @@ -222,6 +225,7 @@ impl VulkanWindow { eprintln!("{:x}", framebuffer_image.as_raw()); // todo: output image will remove need for ImageLayout::GENERAL + // todo: make `frame` render into swapchain image rather than blit. util::vulkan_image_layout_transition_levels( &vulkan.base.device, cmd, diff --git a/librashader-runtime-vk/src/hello_triangle/swapchain.rs b/librashader-runtime-vk/src/hello_triangle/swapchain.rs index c2518c3..bff1fc3 100644 --- a/librashader-runtime-vk/src/hello_triangle/swapchain.rs +++ b/librashader-runtime-vk/src/hello_triangle/swapchain.rs @@ -14,8 +14,9 @@ pub struct VulkanSwapchain { pub extent: vk::Extent2D, mode: vk::PresentModeKHR, pub swapchain_images: Vec, - pub render_images: Vec<(vk::Image, VulkanImageMemory)>, + pub swapchain_image_views: Vec, + pub render_images: Vec<(vk::Image, VulkanImageMemory)>, pub render_image_views: Vec, device: ash::Device, } @@ -56,7 +57,7 @@ impl VulkanSwapchain { .clipped(true) .image_array_layers(1) // todo: switch to IMAGE_USAGE_TRANSFER_DST - .image_usage(vk::ImageUsageFlags::TRANSFER_DST) + .image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT) .build(); let loader = ash::extensions::khr::Swapchain::new(&base.instance, &base.device); @@ -114,48 +115,48 @@ impl VulkanSwapchain { } } - // let image_views: VkResult> = swapchain_images - // .iter() - // .map(|image| { - // let create_info = vk::ImageViewCreateInfo::builder() - // .view_type(vk::ImageViewType::TYPE_2D) - // .format(format.format) - // .components(vk::ComponentMapping { - // r: vk::ComponentSwizzle::IDENTITY, - // g: vk::ComponentSwizzle::IDENTITY, - // b: vk::ComponentSwizzle::IDENTITY, - // a: vk::ComponentSwizzle::IDENTITY, - // }) - // .subresource_range(vk::ImageSubresourceRange { - // aspect_mask: vk::ImageAspectFlags::COLOR, - // base_mip_level: 0, - // level_count: 1, - // base_array_layer: 0, - // layer_count: 1, - // }) - // .image(*image) - // .build(); - // - // 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()) - // .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()) - // .expect("could not set object name"); - // } - // Ok(view) - // }) - // .collect(); + let swapchain_image_views: VkResult> = swapchain_images + .iter() + .map(|image| { + let create_info = vk::ImageViewCreateInfo::builder() + .view_type(vk::ImageViewType::TYPE_2D) + .format(format.format) + .components(vk::ComponentMapping { + r: vk::ComponentSwizzle::IDENTITY, + g: vk::ComponentSwizzle::IDENTITY, + b: vk::ComponentSwizzle::IDENTITY, + a: vk::ComponentSwizzle::IDENTITY, + }) + .subresource_range(vk::ImageSubresourceRange { + aspect_mask: vk::ImageAspectFlags::COLOR, + base_mip_level: 0, + level_count: 1, + base_array_layer: 0, + layer_count: 1, + }) + .image(*image) + .build(); + + 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()) + .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()) + .expect("could not set object name"); + } + Ok(view) + }) + .collect(); let render_image_views: VkResult> = render_images .iter() @@ -200,7 +201,7 @@ impl VulkanSwapchain { mode, swapchain_images, render_images, - // swapchain_image_views: image_views?, + swapchain_image_views: swapchain_image_views?, render_image_views: render_image_views?, device: base.device.clone(), }) @@ -213,7 +214,7 @@ impl Drop for VulkanSwapchain { for view in &self.render_image_views { self.device.destroy_image_view(*view, None) } - for (view, memory) in &self.render_images { + for (view, _memory) in &self.render_images { self.device.destroy_image(*view, None); } self.loader.destroy_swapchain(self.swapchain, None) diff --git a/librashader-runtime-vk/src/lib.rs b/librashader-runtime-vk/src/lib.rs index 4080f3b..69dddff 100644 --- a/librashader-runtime-vk/src/lib.rs +++ b/librashader-runtime-vk/src/lib.rs @@ -17,6 +17,7 @@ mod ubo_ring; mod util; mod vulkan_primitives; mod vulkan_state; +mod viewport; #[cfg(test)] mod tests { diff --git a/librashader-runtime-vk/src/render_target.rs b/librashader-runtime-vk/src/render_target.rs index 81a5704..661c81e 100644 --- a/librashader-runtime-vk/src/render_target.rs +++ b/librashader-runtime-vk/src/render_target.rs @@ -11,6 +11,8 @@ pub(crate) static DEFAULT_MVP: &[f32; 16] = &[ #[derive(Clone)] pub(crate) struct RenderTarget<'a> { + pub x: f32, + pub y: f32, pub mvp: &'a [f32; 16], pub output: OutputFramebuffer, } diff --git a/librashader-runtime-vk/src/viewport.rs b/librashader-runtime-vk/src/viewport.rs new file mode 100644 index 0000000..e20669c --- /dev/null +++ b/librashader-runtime-vk/src/viewport.rs @@ -0,0 +1,10 @@ + +use crate::texture::VulkanImage; + +#[derive(Clone)] +pub struct Viewport<'a> { + pub x: f32, + pub y: f32, + pub output: VulkanImage, + pub mvp: Option<&'a [f32; 16]>, +}