diff --git a/librashader-runtime-vk/src/filter_chain.rs b/librashader-runtime-vk/src/filter_chain.rs index 8e3a90d..b66c5c5 100644 --- a/librashader-runtime-vk/src/filter_chain.rs +++ b/librashader-runtime-vk/src/filter_chain.rs @@ -122,6 +122,7 @@ impl TryFrom<(ash::Device, vk::Queue, vk::PhysicalDeviceMemoryProperties)> for V pub struct FilterChainVulkan { pub(crate) common: FilterCommon, pub(crate) passes: Box<[FilterPass]>, + pub(crate) vulkan: Vulkan, // pub(crate) output_framebuffers: Box<[OwnedFramebuffer]>, // pub(crate) feedback_framebuffers: Box<[OwnedFramebuffer]>, // pub(crate) history_framebuffers: VecDeque, @@ -186,6 +187,7 @@ impl FilterChainVulkan { }, }, passes: filters, + vulkan: device }) } @@ -371,10 +373,27 @@ impl FilterChainVulkan { viewport: &vk::Viewport, input: &VulkanImage, options: Option<()>, + wait: vk::Semaphore, + signal: vk::Semaphore, ) -> error::Result<()> { // limit number of passes to those enabled. let passes = &mut self.passes[0..self.common.config.passes_enabled]; + // + // for (index, pass) in passes.iter_mut().enumerate() { + // pass.draw(index, &self.common, count as u32, 0, viewport, &Default::default(), &Texture {}, &Texture {}) + // } + + unsafe { + self.vulkan.device.queue_submit(self.vulkan.queue, &[vk::SubmitInfo::builder() + .wait_semaphores(&[wait]) + .wait_dst_stage_mask(&[vk::PipelineStageFlags::ALL_COMMANDS],) + .signal_semaphores(&[signal]) + .command_buffers(&[]) + .build()], vk::Fence::null())? + } + + Ok(()) } } diff --git a/librashader-runtime-vk/src/filter_pass.rs b/librashader-runtime-vk/src/filter_pass.rs index 018eb32..dce18d7 100644 --- a/librashader-runtime-vk/src/filter_pass.rs +++ b/librashader-runtime-vk/src/filter_pass.rs @@ -8,6 +8,7 @@ use librashader_runtime::uniforms::UniformStorage; use rustc_hash::FxHashMap; use librashader_common::Size; use librashader_reflect::reflect::ShaderReflection; +use crate::error; use crate::filter_chain::FilterCommon; use crate::rendertarget::RenderTarget; use crate::texture::Texture; @@ -61,24 +62,30 @@ impl FilterPass { parent: &FilterCommon, frame_count: u32, frame_direction: i32, - descriptor: &vk::DescriptorSet, viewport: &vk::Viewport, original: &Texture, source: &Texture, output: &RenderTarget, - ) { + ) -> error::Result<()> { + let descriptor = *&self.graphics_pipeline.layout.descriptor_sets[0]; + self.build_semantics(pass_index, parent, &output.mvp, frame_count, frame_direction, Size::new(100, 100), - Size::new(100,100),descriptor, original, source); + Size::new(100,100),&descriptor, original, source); if let Some(ubo) = &self.reflection.ubo { + // shader_vulkan: 2554 (ra uses uses one big buffer) // itll be simpler for us if we just use a RingBuffer tbh. + self.ubo_ring.bind_for_frame(descriptor, ubo.binding, &self.uniform_storage)?; } + + Ok(()) } - fn bind_ubo(device: &vk::Device, descriptor: &vk::DescriptorSet, binding: u32, buffer: &vk::Buffer, offset: vk::DeviceSize, range: vk::DeviceSize) { - - } + // + // fn bind_ubo(device: &vk::Device, descriptor: &vk::DescriptorSet, binding: u32, buffer: &vk::Buffer, offset: vk::DeviceSize, range: vk::DeviceSize) { + // + // } fn build_semantics( &mut self, @@ -137,7 +144,7 @@ impl FilterPass { FilterPass::bind_texture( &self.device, &parent.samplers, - descriptor_set, + *descriptor_set, binding, original, ); @@ -149,7 +156,7 @@ impl FilterPass { .get(&TextureSemantics::Original.semantics(0).into()) { self.uniform_storage - .bind_vec4(*offset, original.size, None); + .bind_vec4(*offset, original.image.size, None); } // bind Source sampler @@ -163,7 +170,7 @@ impl FilterPass { FilterPass::bind_texture( &self.device, &parent.samplers, - descriptor_set, + *descriptor_set, binding, source ); @@ -175,7 +182,7 @@ impl FilterPass { .get(&TextureSemantics::Source.semantics(0).into()) { self.uniform_storage - .bind_vec4(*offset, source.size, None); + .bind_vec4(*offset, source.image.size, None); } if let Some(binding) = self @@ -187,7 +194,7 @@ impl FilterPass { FilterPass::bind_texture( &self.device, &parent.samplers, - descriptor_set, + *descriptor_set, binding, original, ); @@ -198,7 +205,7 @@ impl FilterPass { .get(&TextureSemantics::OriginalHistory.semantics(0).into()) { self.uniform_storage - .bind_vec4(*offset, original.size, None); + .bind_vec4(*offset, original.image.size, None); } // for (index, output) in parent.history_textures.iter().enumerate() { @@ -327,7 +334,7 @@ impl FilterPass { FilterPass::bind_texture( &self.device, &parent.samplers, - descriptor_set, + *descriptor_set, binding, &lut.image, ); @@ -338,7 +345,7 @@ impl FilterPass { .get(&TextureSemantics::User.semantics(*index).into()) { self.uniform_storage - .bind_vec4(*offset, lut.image.size, None); + .bind_vec4(*offset, lut.image.image.size, None); } } diff --git a/librashader-runtime-vk/src/framebuffer.rs b/librashader-runtime-vk/src/framebuffer.rs index 4ef5f8d..9011554 100644 --- a/librashader-runtime-vk/src/framebuffer.rs +++ b/librashader-runtime-vk/src/framebuffer.rs @@ -46,8 +46,8 @@ impl OwnedFramebuffer { &vk::FramebufferCreateInfo::builder() .render_pass(render_pass.handle) .attachments(&[image.image_view]) - .width(image.size.width) - .height(image.size.height) + .width(image.image.size.width) + .height(image.image.size.height) .layers(1) .build(), None, diff --git a/librashader-runtime-vk/src/hello_triangle.rs b/librashader-runtime-vk/src/hello_triangle.rs index 74c9d22..ce16f9d 100644 --- a/librashader-runtime-vk/src/hello_triangle.rs +++ b/librashader-runtime-vk/src/hello_triangle.rs @@ -9,6 +9,8 @@ use std::mem::align_of; mod base; pub use base::*; +use crate::filter_chain::FilterChainVulkan; +use crate::texture::VulkanImage; #[derive(Clone, Debug, Copy)] struct Vertex { @@ -16,7 +18,7 @@ struct Vertex { color: [f32; 4], } -pub(crate) fn main(base: ExampleBase) { +pub(crate) fn main(base: ExampleBase, mut filter_chain: FilterChainVulkan) { unsafe { let renderpass_attachments = [ vk::AttachmentDescription { @@ -429,8 +431,18 @@ pub(crate) fn main(base: ExampleBase) { device.cmd_end_render_pass(draw_command_buffer); }, ); + + + filter_chain.frame(0, &viewports[0], &VulkanImage { + size: Default::default(), + image: Default::default(), + format: Default::default(), + }, None, base.rendering_complete_semaphore, base.postprocess_complete_semaphore) + .unwrap(); + //let mut present_info_err = mem::zeroed(); - let wait_semaphors = [base.rendering_complete_semaphore]; + let wait_semaphors = [base.postprocess_complete_semaphore]; + let swapchains = [base.swapchain]; let image_indices = [present_index]; let present_info = vk::PresentInfoKHR::builder() diff --git a/librashader-runtime-vk/src/hello_triangle/base.rs b/librashader-runtime-vk/src/hello_triangle/base.rs index 6450890..958065d 100644 --- a/librashader-runtime-vk/src/hello_triangle/base.rs +++ b/librashader-runtime-vk/src/hello_triangle/base.rs @@ -181,13 +181,14 @@ pub struct ExampleBase { pub present_complete_semaphore: vk::Semaphore, pub rendering_complete_semaphore: vk::Semaphore, + pub postprocess_complete_semaphore: vk::Semaphore, pub draw_commands_reuse_fence: vk::Fence, pub setup_commands_reuse_fence: vk::Fence, } impl ExampleBase { - pub fn render_loop(&self, f: F) { + pub fn render_loop(&self, mut f: F) { self.event_loop .borrow_mut() .run_return(|event, _, control_flow| { @@ -554,7 +555,9 @@ impl ExampleBase { let rendering_complete_semaphore = device .create_semaphore(&semaphore_create_info, None) .unwrap(); - + let postprocess_complete_semaphore = device + .create_semaphore(&semaphore_create_info, None) + .unwrap(); ExampleBase { event_loop: RefCell::new(event_loop), entry, @@ -585,6 +588,7 @@ impl ExampleBase { debug_call_back, debug_utils_loader, depth_image_memory, + postprocess_complete_semaphore } } } @@ -598,6 +602,8 @@ impl Drop for ExampleBase { .destroy_semaphore(self.present_complete_semaphore, None); self.device .destroy_semaphore(self.rendering_complete_semaphore, None); + self.device + .destroy_semaphore(self.postprocess_complete_semaphore, None); self.device .destroy_fence(self.draw_commands_reuse_fence, None); self.device diff --git a/librashader-runtime-vk/src/lib.rs b/librashader-runtime-vk/src/lib.rs index cd52b87..d03325f 100644 --- a/librashader-runtime-vk/src/lib.rs +++ b/librashader-runtime-vk/src/lib.rs @@ -42,6 +42,6 @@ mod tests { ) // FilterChain::load_from_path("../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", None) .unwrap(); - hello_triangle::main(base); + hello_triangle::main(base, filter); } } diff --git a/librashader-runtime-vk/src/luts.rs b/librashader-runtime-vk/src/luts.rs index 1a593d8..2467cb4 100644 --- a/librashader-runtime-vk/src/luts.rs +++ b/librashader-runtime-vk/src/luts.rs @@ -8,7 +8,7 @@ use librashader_common::{FilterMode, WrapMode}; use librashader_presets::TextureConfig; use librashader_runtime::image::{Image, BGRA8}; use librashader_runtime::scaling::MipmapSize; -use crate::texture::Texture; +use crate::texture::{Texture, VulkanImage}; pub struct LutTexture { pub memory: VulkanImageMemory, @@ -237,13 +237,15 @@ impl LutTexture { memory, staging, image: Texture { - size: image.size, image_view: texture_view, - image: texture, + image: VulkanImage { + size: image.size, + image: texture, + format: vk::Format::B8G8R8A8_UNORM + }, filter_mode: config.filter_mode, wrap_mode: config.wrap_mode, mip_filter: config.filter_mode, - format: vk::Format::B8G8R8A8_UNORM } }) } diff --git a/librashader-runtime-vk/src/texture.rs b/librashader-runtime-vk/src/texture.rs index a0a47fa..92d3ecc 100644 --- a/librashader-runtime-vk/src/texture.rs +++ b/librashader-runtime-vk/src/texture.rs @@ -112,8 +112,8 @@ impl OwnedTexture { let mut view_info = vk::ImageViewCreateInfo::builder() .view_type(ImageViewType::TYPE_2D) - .format(self.format) - .image(self.image.clone()) + .format(self.image.format) + .image(self.image.image.clone()) .subresource_range(image_subresource) .components(swizzle_components) .build(); @@ -129,7 +129,7 @@ impl Drop for OwnedTexture { if self.image_view != vk::ImageView::null() { self.device.destroy_image_view(self.image_view, None); } - if self.image != vk::Image::null() { + if self.image.image != vk::Image::null() { self.device.destroy_image(self.image.image, None); } } diff --git a/librashader-runtime-vk/src/ubo_ring.rs b/librashader-runtime-vk/src/ubo_ring.rs index e4a65f9..b94bb3e 100644 --- a/librashader-runtime-vk/src/ubo_ring.rs +++ b/librashader-runtime-vk/src/ubo_ring.rs @@ -1,10 +1,12 @@ use ash::vk; -use librashader_runtime::ringbuffer::{BoxRingBuffer, InlineRingBuffer}; +use librashader_runtime::ringbuffer::{BoxRingBuffer, InlineRingBuffer, RingBuffer}; +use librashader_runtime::uniforms::UniformStorageAccess; use crate::error; use crate::vulkan_primitives::VulkanBuffer; pub struct VkUboRing { ring: BoxRingBuffer, + device: ash::Device, } impl VkUboRing { @@ -15,7 +17,37 @@ impl VkUboRing { } Ok(VkUboRing { - ring: BoxRingBuffer::from_vec(ring) + ring: BoxRingBuffer::from_vec(ring), + device: device.clone() }) } + + pub fn bind_for_frame(&mut self, descriptor_set: vk::DescriptorSet, binding: u32, storage: &impl UniformStorageAccess) -> error::Result<()>{ + let mut buffer = self.ring.current_mut(); + // todo: write directly to allocated buffer. + unsafe { + let mut map = buffer.map()?; + map.copy_from(0, storage.ubo_slice()) + } + + unsafe { + let buffer_info = vk::DescriptorBufferInfo::builder() + .buffer(buffer.handle) + .offset(0) + .range(storage.ubo_slice().len() as vk::DeviceSize) + .build(); + + let write_info = vk::WriteDescriptorSet::builder() + .descriptor_type(vk::DescriptorType::UNIFORM_BUFFER) + .dst_set(descriptor_set) + .dst_binding(binding) + .dst_array_element(0) + .buffer_info(&[buffer_info]) + .build(); + + self.device.update_descriptor_sets(&[write_info], &[]) + } + self.ring.next(); + Ok(()) + } } diff --git a/librashader-runtime-vk/src/vulkan_state.rs b/librashader-runtime-vk/src/vulkan_state.rs index f591565..512a319 100644 --- a/librashader-runtime-vk/src/vulkan_state.rs +++ b/librashader-runtime-vk/src/vulkan_state.rs @@ -176,8 +176,8 @@ impl Drop for VulkanShaderModule { } pub struct VulkanGraphicsPipeline { - layout: PipelineLayoutObjects, - render_pass: VulkanRenderPass, + pub layout: PipelineLayoutObjects, + pub render_pass: VulkanRenderPass, pipeline: vk::Pipeline, } diff --git a/librashader-runtime/src/uniforms.rs b/librashader-runtime/src/uniforms.rs index 51bc80e..741ce3e 100644 --- a/librashader-runtime/src/uniforms.rs +++ b/librashader-runtime/src/uniforms.rs @@ -23,19 +23,37 @@ pub trait UniformStorageAccess { /// of the implementing struct. fn ubo_pointer(&self) -> *const u8; + /// Get a pointer to the backing UBO storage. This pointer must be valid for the lifetime + /// of the implementing struct. + fn ubo_slice(&self) -> &[u8]; + /// Get a pointer to the backing Push Constant buffer storage. /// This pointer must be valid for the lifetime of the implementing struct. fn push_pointer(&self) -> *const u8; + + + /// Get a slice to the backing Push Constant buffer storage. + /// This pointer must be valid for the lifetime of the implementing struct. + fn push_slice(&self) -> &[u8]; } impl UniformStorageAccess for UniformStorage { + fn ubo_pointer(&self) -> *const u8 { self.ubo.as_ptr() } + fn ubo_slice(&self) -> &[u8] { + &self.ubo + } + fn push_pointer(&self) -> *const u8 { self.push.as_ptr() } + + fn push_slice(&self) -> &[u8] { + &self.push + } } /// A uniform binder that always returns `None`, and does not do any binding of uniforms.