From f8ba964b017a24cb2fa63cecfefbbe424a02ff61 Mon Sep 17 00:00:00 2001 From: chyyran Date: Tue, 10 Jan 2023 00:45:48 -0500 Subject: [PATCH] vk: log commands to renderpass --- librashader-common/src/vk.rs | 22 +++++++++ librashader-runtime-vk/src/draw_quad.rs | 4 +- librashader-runtime-vk/src/filter_chain.rs | 12 +++-- librashader-runtime-vk/src/filter_pass.rs | 53 ++++++++++++++++++++-- librashader-runtime-vk/src/framebuffer.rs | 35 +++++++++++++- librashader-runtime-vk/src/rendertarget.rs | 8 ++++ librashader-runtime-vk/src/vulkan_state.rs | 2 +- 7 files changed, 123 insertions(+), 13 deletions(-) diff --git a/librashader-common/src/vk.rs b/librashader-common/src/vk.rs index 63a8d82..f6984b8 100644 --- a/librashader-common/src/vk.rs +++ b/librashader-common/src/vk.rs @@ -87,6 +87,16 @@ impl From> for vk::Extent3D { } } } + +impl From> for vk::Extent2D { + fn from(value: Size) -> Self { + vk::Extent2D { + width: value.width, + height: value.height, + } + } +} + impl From for Size { fn from(value: vk::Extent3D) -> Self { Size { @@ -123,6 +133,18 @@ impl From<&vk::Viewport> for Size { } } +impl From> for vk::Viewport { + fn from(value: Size) -> Self { + vk::Viewport { + x: 0.0, + y: 0.0, + width: value.width as f32, + height: value.height as f32, + min_depth: 0.0, + max_depth: 1.0, + } + } +} impl From for vk::Filter { fn from(value: FilterMode) -> Self { match value { diff --git a/librashader-runtime-vk/src/draw_quad.rs b/librashader-runtime-vk/src/draw_quad.rs index eaea5d7..1a51730 100644 --- a/librashader-runtime-vk/src/draw_quad.rs +++ b/librashader-runtime-vk/src/draw_quad.rs @@ -58,7 +58,7 @@ impl DrawQuad { }) } - pub fn bind_vbo(&self, cmd: &vk::CommandBuffer, vbo: VboType) { + pub fn bind_vbo(&self, cmd: vk::CommandBuffer, vbo: VboType) { let offset = match vbo { VboType::Offscreen => 0, VboType::Final => std::mem::size_of::<[f32; 16]>(), @@ -66,7 +66,7 @@ impl DrawQuad { unsafe { self.device.cmd_bind_vertex_buffers( - *cmd, + cmd, 0, &[self.buffer.handle], &[offset as vk::DeviceSize], diff --git a/librashader-runtime-vk/src/filter_chain.rs b/librashader-runtime-vk/src/filter_chain.rs index 8613a2b..8191ed3 100644 --- a/librashader-runtime-vk/src/filter_chain.rs +++ b/librashader-runtime-vk/src/filter_chain.rs @@ -22,9 +22,9 @@ use librashader_runtime::uniforms::UniformStorage; use rustc_hash::FxHashMap; use std::error::Error; use std::path::Path; -use crate::draw_quad::{VBO_DEFAULT_FINAL, VBO_OFFSCREEN}; +use crate::draw_quad::{DrawQuad, VBO_DEFAULT_FINAL, VBO_OFFSCREEN}; use crate::framebuffer::OutputFramebuffer; -use crate::rendertarget::RenderTarget; +use crate::rendertarget::{DEFAULT_MVP, RenderTarget}; pub struct Vulkan { // physical_device: vk::PhysicalDevice, @@ -130,7 +130,6 @@ pub struct FilterChainVulkan { pub(crate) output_framebuffers: Box<[OwnedTexture]>, // pub(crate) feedback_framebuffers: Box<[OwnedFramebuffer]>, // pub(crate) history_framebuffers: VecDeque, - // pub(crate) draw_quad: DrawQuad, } pub struct FilterMutable { @@ -141,10 +140,13 @@ pub struct FilterMutable { pub(crate) struct FilterCommon { pub(crate) luts: FxHashMap, pub samplers: SamplerSet, + pub(crate) draw_quad: DrawQuad, + // pub output_textures: Box<[Option]>, // pub feedback_textures: Box<[Option]>, // pub history_textures: Box<[Option]>, pub config: FilterMutable, + pub device: ash::Device, } pub type FilterChainOptionsVulkan = (); @@ -200,6 +202,8 @@ impl FilterChainVulkan { .map(|param| (param.name, param.value)) .collect(), }, + draw_quad: DrawQuad::new(&device.device, &device.memory_properties)?, + device: device.device.clone() }, passes: filters, vulkan: device, @@ -470,7 +474,7 @@ impl FilterChainVulkan { let target = &self.output_framebuffers[index]; // todo: use proper mode let out = RenderTarget { - mvp: VBO_DEFAULT_FINAL, + 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 9e65922..a416c47 100644 --- a/librashader-runtime-vk/src/filter_pass.rs +++ b/librashader-runtime-vk/src/filter_pass.rs @@ -1,4 +1,4 @@ -use crate::error; +use crate::{error, util}; use crate::filter_chain::FilterCommon; use crate::rendertarget::RenderTarget; use crate::samplers::{SamplerSet, VulkanSampler}; @@ -10,12 +10,11 @@ use librashader_common::{ImageFormat, Size}; use librashader_preprocess::ShaderSource; use librashader_presets::ShaderPassConfig; use librashader_reflect::back::ShaderCompilerOutput; -use librashader_reflect::reflect::semantics::{ - 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; +use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess}; use rustc_hash::FxHashMap; +use crate::draw_quad::VboType; pub struct FilterPass { pub device: ash::Device, @@ -101,6 +100,50 @@ impl FilterPass { .bind_to_descriptor_set(descriptor, ubo.binding, &self.uniform_storage)?; } + output.output.begin_pass(cmd); + + let render_pass_info = vk::RenderPassBeginInfo::builder() + .framebuffer(output.output.framebuffer) + .render_pass(self.graphics_pipeline.render_pass.handle) + .render_area(vk::Rect2D { + offset: Default::default(), + extent: output.output.size.into(), + }).build(); + + unsafe { + parent.device.cmd_begin_render_pass(cmd, &render_pass_info, vk::SubpassContents::INLINE); + 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]], &[]); + + if let Some(push) = &self.reflection.push_constant { + let mut stage_mask = vk::ShaderStageFlags::empty(); + if push.stage_mask.contains(BindingStage::FRAGMENT) { + stage_mask |= vk::ShaderStageFlags::FRAGMENT; + } + if push.stage_mask.contains(BindingStage::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.draw_quad.bind_vbo(cmd, VboType::Offscreen); + + parent.device.cmd_set_scissor(cmd, 0, &[ + vk::Rect2D { + offset: Default::default(), + extent: 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_render_pass(cmd); + + output.output.end_pass(cmd); + } Ok(()) } diff --git a/librashader-runtime-vk/src/framebuffer.rs b/librashader-runtime-vk/src/framebuffer.rs index d020223..2917ee3 100644 --- a/librashader-runtime-vk/src/framebuffer.rs +++ b/librashader-runtime-vk/src/framebuffer.rs @@ -1,4 +1,4 @@ -use crate::error; +use crate::{error, util}; use crate::filter_chain::Vulkan; use crate::renderpass::VulkanRenderPass; use crate::texture::OwnedTexture; @@ -70,6 +70,7 @@ pub(crate) struct OutputFramebuffer { pub size: Size, device: ash::Device, image_view: vk::ImageView, + image: vk::Image, } // @@ -125,11 +126,43 @@ impl OutputFramebuffer { Ok(OutputFramebuffer { device: vulkan.device.clone(), size, + image, framebuffer, image_view, }) } + 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) + } + } + + 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) + } + } + // pub fn get_renderpass_begin_info(&self, area: vk::Rect2D, clear: Option<&[vk::ClearValue]>) -> vk::RenderPassBeginInfo { // let mut builder = vk::RenderPassBeginInfo::builder() // .render_pass(self.render_pass.handle) diff --git a/librashader-runtime-vk/src/rendertarget.rs b/librashader-runtime-vk/src/rendertarget.rs index d0f7c98..6e19809 100644 --- a/librashader-runtime-vk/src/rendertarget.rs +++ b/librashader-runtime-vk/src/rendertarget.rs @@ -1,6 +1,14 @@ use crate::framebuffer::OutputFramebuffer; use ash::vk; +#[rustfmt::skip] +pub static DEFAULT_MVP: &[f32; 16] = &[ + 2f32, 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 2.0, 0.0, + -1.0, -1.0, 0.0, 1.0, +]; + #[derive(Clone)] pub(crate) struct RenderTarget<'a> { pub mvp: &'a [f32; 16], diff --git a/librashader-runtime-vk/src/vulkan_state.rs b/librashader-runtime-vk/src/vulkan_state.rs index 512a319..8c96a4f 100644 --- a/librashader-runtime-vk/src/vulkan_state.rs +++ b/librashader-runtime-vk/src/vulkan_state.rs @@ -178,7 +178,7 @@ impl Drop for VulkanShaderModule { pub struct VulkanGraphicsPipeline { pub layout: PipelineLayoutObjects, pub render_pass: VulkanRenderPass, - pipeline: vk::Pipeline, + pub pipeline: vk::Pipeline, } impl VulkanGraphicsPipeline {