vk: accept output viewport
This commit is contained in:
parent
9dd656d49f
commit
ace6774a15
|
@ -25,6 +25,7 @@ use std::path::Path;
|
||||||
use crate::draw_quad::{DrawQuad, VBO_DEFAULT_FINAL, VBO_OFFSCREEN};
|
use crate::draw_quad::{DrawQuad, VBO_DEFAULT_FINAL, VBO_OFFSCREEN};
|
||||||
use crate::framebuffer::OutputFramebuffer;
|
use crate::framebuffer::OutputFramebuffer;
|
||||||
use crate::render_target::{DEFAULT_MVP, RenderTarget};
|
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,
|
||||||
|
@ -453,7 +454,7 @@ impl FilterChainVulkan {
|
||||||
pub fn frame(
|
pub fn frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
count: usize,
|
count: usize,
|
||||||
viewport: &vk::Viewport,
|
viewport: &Viewport,
|
||||||
input: &VulkanImage,
|
input: &VulkanImage,
|
||||||
cmd: vk::CommandBuffer,
|
cmd: vk::CommandBuffer,
|
||||||
options: Option<()>,
|
options: Option<()>,
|
||||||
|
@ -502,7 +503,7 @@ impl FilterChainVulkan {
|
||||||
self.output_framebuffers[index].scale(
|
self.output_framebuffers[index].scale(
|
||||||
pass.config.scaling.clone(),
|
pass.config.scaling.clone(),
|
||||||
pass.get_format(),
|
pass.get_format(),
|
||||||
&viewport.into(),
|
&viewport.output.size,
|
||||||
&original,
|
&original,
|
||||||
&source,
|
&source,
|
||||||
)?;
|
)?;
|
||||||
|
@ -515,6 +516,8 @@ impl FilterChainVulkan {
|
||||||
// todo: the output framebuffers can only be dropped after command queue submission.
|
// todo: the output framebuffers can only be dropped after command queue submission.
|
||||||
|
|
||||||
let out = RenderTarget {
|
let out = RenderTarget {
|
||||||
|
x: 0.0,
|
||||||
|
y: 0.0,
|
||||||
mvp: DEFAULT_MVP,
|
mvp: DEFAULT_MVP,
|
||||||
output: OutputFramebuffer::new(&self.vulkan, &pass.graphics_pipeline.render_pass, target.image.image, target.image.size)?,
|
output: OutputFramebuffer::new(&self.vulkan, &pass.graphics_pipeline.render_pass, target.image.image, target.image.size)?,
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,6 +15,7 @@ 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::draw_quad::VboType;
|
||||||
|
use crate::viewport::Viewport;
|
||||||
|
|
||||||
pub struct FilterPass {
|
pub struct FilterPass {
|
||||||
pub device: ash::Device,
|
pub device: ash::Device,
|
||||||
|
@ -73,7 +74,7 @@ impl FilterPass {
|
||||||
parent: &FilterCommon,
|
parent: &FilterCommon,
|
||||||
frame_count: u32,
|
frame_count: u32,
|
||||||
frame_direction: i32,
|
frame_direction: i32,
|
||||||
viewport: &vk::Viewport,
|
viewport: &Viewport,
|
||||||
original: &InputTexture,
|
original: &InputTexture,
|
||||||
source: &InputTexture,
|
source: &InputTexture,
|
||||||
output: &RenderTarget,
|
output: &RenderTarget,
|
||||||
|
@ -87,7 +88,7 @@ impl FilterPass {
|
||||||
frame_count,
|
frame_count,
|
||||||
frame_direction,
|
frame_direction,
|
||||||
output.output.size,
|
output.output.size,
|
||||||
viewport.into(),
|
viewport.output.size,
|
||||||
&descriptor,
|
&descriptor,
|
||||||
original,
|
original,
|
||||||
source,
|
source,
|
||||||
|
@ -110,8 +111,12 @@ impl FilterPass {
|
||||||
float32: [0.0, 0.0, 0.0, 0.0]
|
float32: [0.0, 0.0, 0.0, 0.0]
|
||||||
}
|
}
|
||||||
}])
|
}])
|
||||||
|
// always render into the full output, regardless of viewport settings.
|
||||||
.render_area(vk::Rect2D {
|
.render_area(vk::Rect2D {
|
||||||
offset: Default::default(),
|
offset: vk::Offset2D {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
},
|
||||||
extent: output.output.size.into(),
|
extent: output.output.size.into(),
|
||||||
}).build();
|
}).build();
|
||||||
|
|
||||||
|
@ -139,7 +144,10 @@ impl FilterPass {
|
||||||
|
|
||||||
parent.device.cmd_set_scissor(cmd, 0, &[
|
parent.device.cmd_set_scissor(cmd, 0, &[
|
||||||
vk::Rect2D {
|
vk::Rect2D {
|
||||||
offset: Default::default(),
|
offset: vk::Offset2D {
|
||||||
|
x: output.x as i32,
|
||||||
|
y: output.y as i32,
|
||||||
|
},
|
||||||
extent: output.output.size.into()
|
extent: output.output.size.into()
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEve
|
||||||
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::texture::VulkanImage;
|
||||||
|
use crate::viewport::Viewport;
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const WINDOW_TITLE: &'static str = "librashader Vulkan";
|
const WINDOW_TITLE: &'static str = "librashader Vulkan";
|
||||||
|
@ -206,13 +207,15 @@ impl VulkanWindow {
|
||||||
// vk::QUEUE_FAMILY_IGNORED
|
// vk::QUEUE_FAMILY_IGNORED
|
||||||
// );
|
// );
|
||||||
|
|
||||||
let intermediates = filter.frame(0, &vk::Viewport {
|
let intermediates = filter.frame(0, &Viewport {
|
||||||
x: 0.0,
|
x: 0.0,
|
||||||
y: 0.0,
|
y: 0.0,
|
||||||
width: vulkan.swapchain.extent.width as f32,
|
output: VulkanImage {
|
||||||
height: vulkan.swapchain.extent.height as f32,
|
size: vulkan.swapchain.extent.into(),
|
||||||
min_depth: 0.0,
|
image: swapchain_image,
|
||||||
max_depth: 1.0,
|
format: vulkan.swapchain.format.format,
|
||||||
|
},
|
||||||
|
mvp: None,
|
||||||
}, &VulkanImage {
|
}, &VulkanImage {
|
||||||
size: vulkan.swapchain.extent.into(),
|
size: vulkan.swapchain.extent.into(),
|
||||||
image: framebuffer_image,
|
image: framebuffer_image,
|
||||||
|
@ -222,6 +225,7 @@ impl VulkanWindow {
|
||||||
|
|
||||||
eprintln!("{:x}", framebuffer_image.as_raw());
|
eprintln!("{:x}", framebuffer_image.as_raw());
|
||||||
// todo: output image will remove need for ImageLayout::GENERAL
|
// 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(
|
util::vulkan_image_layout_transition_levels(
|
||||||
&vulkan.base.device,
|
&vulkan.base.device,
|
||||||
cmd,
|
cmd,
|
||||||
|
|
|
@ -14,8 +14,9 @@ pub struct VulkanSwapchain {
|
||||||
pub extent: vk::Extent2D,
|
pub extent: vk::Extent2D,
|
||||||
mode: vk::PresentModeKHR,
|
mode: vk::PresentModeKHR,
|
||||||
pub swapchain_images: Vec<vk::Image>,
|
pub swapchain_images: Vec<vk::Image>,
|
||||||
pub render_images: Vec<(vk::Image, VulkanImageMemory)>,
|
pub swapchain_image_views: Vec<vk::ImageView>,
|
||||||
|
|
||||||
|
pub render_images: Vec<(vk::Image, VulkanImageMemory)>,
|
||||||
pub render_image_views: Vec<vk::ImageView>,
|
pub render_image_views: Vec<vk::ImageView>,
|
||||||
device: ash::Device,
|
device: ash::Device,
|
||||||
}
|
}
|
||||||
|
@ -56,7 +57,7 @@ impl VulkanSwapchain {
|
||||||
.clipped(true)
|
.clipped(true)
|
||||||
.image_array_layers(1)
|
.image_array_layers(1)
|
||||||
// todo: switch to IMAGE_USAGE_TRANSFER_DST
|
// todo: switch to IMAGE_USAGE_TRANSFER_DST
|
||||||
.image_usage(vk::ImageUsageFlags::TRANSFER_DST)
|
.image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let loader = ash::extensions::khr::Swapchain::new(&base.instance, &base.device);
|
let loader = ash::extensions::khr::Swapchain::new(&base.instance, &base.device);
|
||||||
|
@ -114,48 +115,48 @@ impl VulkanSwapchain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// let image_views: VkResult<Vec<vk::ImageView>> = swapchain_images
|
let swapchain_image_views: VkResult<Vec<vk::ImageView>> = swapchain_images
|
||||||
// .iter()
|
.iter()
|
||||||
// .map(|image| {
|
.map(|image| {
|
||||||
// let create_info = vk::ImageViewCreateInfo::builder()
|
let create_info = vk::ImageViewCreateInfo::builder()
|
||||||
// .view_type(vk::ImageViewType::TYPE_2D)
|
.view_type(vk::ImageViewType::TYPE_2D)
|
||||||
// .format(format.format)
|
.format(format.format)
|
||||||
// .components(vk::ComponentMapping {
|
.components(vk::ComponentMapping {
|
||||||
// r: vk::ComponentSwizzle::IDENTITY,
|
r: vk::ComponentSwizzle::IDENTITY,
|
||||||
// g: vk::ComponentSwizzle::IDENTITY,
|
g: vk::ComponentSwizzle::IDENTITY,
|
||||||
// b: vk::ComponentSwizzle::IDENTITY,
|
b: vk::ComponentSwizzle::IDENTITY,
|
||||||
// a: vk::ComponentSwizzle::IDENTITY,
|
a: vk::ComponentSwizzle::IDENTITY,
|
||||||
// })
|
})
|
||||||
// .subresource_range(vk::ImageSubresourceRange {
|
.subresource_range(vk::ImageSubresourceRange {
|
||||||
// aspect_mask: vk::ImageAspectFlags::COLOR,
|
aspect_mask: vk::ImageAspectFlags::COLOR,
|
||||||
// base_mip_level: 0,
|
base_mip_level: 0,
|
||||||
// level_count: 1,
|
level_count: 1,
|
||||||
// base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
// layer_count: 1,
|
layer_count: 1,
|
||||||
// })
|
})
|
||||||
// .image(*image)
|
.image(*image)
|
||||||
// .build();
|
.build();
|
||||||
//
|
|
||||||
// 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.loader.set_debug_utils_object_name(base.device.handle(),
|
||||||
// &vk::DebugUtilsObjectNameInfoEXT::builder()
|
&vk::DebugUtilsObjectNameInfoEXT::builder()
|
||||||
// .object_handle(image.as_raw())
|
.object_handle(image.as_raw())
|
||||||
// .object_name(CStr::from_bytes_with_nul_unchecked(b"SwapchainImage\0"))
|
.object_name(CStr::from_bytes_with_nul_unchecked(b"SwapchainImage\0"))
|
||||||
// .object_type(vk::ObjectType::IMAGE)
|
.object_type(vk::ObjectType::IMAGE)
|
||||||
// .build())
|
.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.loader.set_debug_utils_object_name(base.device.handle(),
|
||||||
// &vk::DebugUtilsObjectNameInfoEXT::builder()
|
&vk::DebugUtilsObjectNameInfoEXT::builder()
|
||||||
// .object_handle(view.as_raw())
|
.object_handle(view.as_raw())
|
||||||
// .object_name(CStr::from_bytes_with_nul_unchecked(b"SwapchainImageView\0"))
|
.object_name(CStr::from_bytes_with_nul_unchecked(b"SwapchainImageView\0"))
|
||||||
// .object_type(vk::ObjectType::IMAGE_VIEW)
|
.object_type(vk::ObjectType::IMAGE_VIEW)
|
||||||
// .build())
|
.build())
|
||||||
// .expect("could not set object name");
|
.expect("could not set object name");
|
||||||
// }
|
}
|
||||||
// Ok(view)
|
Ok(view)
|
||||||
// })
|
})
|
||||||
// .collect();
|
.collect();
|
||||||
|
|
||||||
let render_image_views: VkResult<Vec<vk::ImageView>> = render_images
|
let render_image_views: VkResult<Vec<vk::ImageView>> = render_images
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -200,7 +201,7 @@ impl VulkanSwapchain {
|
||||||
mode,
|
mode,
|
||||||
swapchain_images,
|
swapchain_images,
|
||||||
render_images,
|
render_images,
|
||||||
// swapchain_image_views: image_views?,
|
swapchain_image_views: swapchain_image_views?,
|
||||||
render_image_views: render_image_views?,
|
render_image_views: render_image_views?,
|
||||||
device: base.device.clone(),
|
device: base.device.clone(),
|
||||||
})
|
})
|
||||||
|
@ -213,7 +214,7 @@ impl Drop for VulkanSwapchain {
|
||||||
for view in &self.render_image_views {
|
for view in &self.render_image_views {
|
||||||
self.device.destroy_image_view(*view, None)
|
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.device.destroy_image(*view, None);
|
||||||
}
|
}
|
||||||
self.loader.destroy_swapchain(self.swapchain, None)
|
self.loader.destroy_swapchain(self.swapchain, None)
|
||||||
|
|
|
@ -17,6 +17,7 @@ mod ubo_ring;
|
||||||
mod util;
|
mod util;
|
||||||
mod vulkan_primitives;
|
mod vulkan_primitives;
|
||||||
mod vulkan_state;
|
mod vulkan_state;
|
||||||
|
mod viewport;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -11,6 +11,8 @@ pub(crate) static DEFAULT_MVP: &[f32; 16] = &[
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct RenderTarget<'a> {
|
pub(crate) struct RenderTarget<'a> {
|
||||||
|
pub x: f32,
|
||||||
|
pub y: f32,
|
||||||
pub mvp: &'a [f32; 16],
|
pub mvp: &'a [f32; 16],
|
||||||
pub output: OutputFramebuffer,
|
pub output: OutputFramebuffer,
|
||||||
}
|
}
|
||||||
|
|
10
librashader-runtime-vk/src/viewport.rs
Normal file
10
librashader-runtime-vk/src/viewport.rs
Normal file
|
@ -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]>,
|
||||||
|
}
|
Loading…
Reference in a new issue