From 477d0ae67c65a2714becfb824cdcaef6ec4d95d9 Mon Sep 17 00:00:00 2001 From: chyyran Date: Thu, 12 Sep 2024 00:50:29 -0400 Subject: [PATCH] rt(wgpu): draw final pass to output targets --- librashader-runtime-wgpu/src/filter_chain.rs | 26 +++++++++++++++-- .../src/graphics_pipeline.rs | 29 ++++++++++++++----- .../tests/hello_triangle.rs | 10 +++---- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/librashader-runtime-wgpu/src/filter_chain.rs b/librashader-runtime-wgpu/src/filter_chain.rs index adaadb0..01d998e 100644 --- a/librashader-runtime-wgpu/src/filter_chain.rs +++ b/librashader-runtime-wgpu/src/filter_chain.rs @@ -438,11 +438,11 @@ impl FilterChainWgpu { let options = options.unwrap_or(&self.default_frame_options); for (index, pass) in pass.iter_mut().enumerate() { - let target = &self.output_framebuffers[index]; source.filter_mode = pass.config.filter; source.wrap_mode = pass.config.wrap_mode; source.mip_filter = pass.config.filter; + let target = &self.output_framebuffers[index]; let output_image = WgpuOutputView::from(target); let out = RenderTarget::identity(&output_image); @@ -476,18 +476,38 @@ impl FilterChainWgpu { assert_eq!(last.len(), 1); if let Some(pass) = last.iter_mut().next() { - if pass.graphics_pipeline.format != viewport.output.format { + let index = passes_len - 1; + if !pass.graphics_pipeline.has_format(viewport.output.format) { // need to recompile pass.graphics_pipeline.recompile(viewport.output.format); } + source.filter_mode = pass.config.filter; source.wrap_mode = pass.config.wrap_mode; source.mip_filter = pass.config.filter; + + let target = &self.output_framebuffers[index]; + let output_image = WgpuOutputView::from(target); + let out = RenderTarget::viewport_with_output(&output_image, viewport); + + pass.draw( + cmd, + index, + &self.common, + pass.config.get_frame_count(frame_count), + options, + viewport, + &original, + &source, + &out, + QuadType::Final, + )?; + let output_image = &viewport.output; let out = RenderTarget::viewport_with_output(output_image, viewport); pass.draw( cmd, - passes_len - 1, + index, &self.common, pass.config.get_frame_count(frame_count), options, diff --git a/librashader-runtime-wgpu/src/graphics_pipeline.rs b/librashader-runtime-wgpu/src/graphics_pipeline.rs index cd3ecd9..c0d338a 100644 --- a/librashader-runtime-wgpu/src/graphics_pipeline.rs +++ b/librashader-runtime-wgpu/src/graphics_pipeline.rs @@ -1,6 +1,7 @@ use crate::framebuffer::WgpuOutputView; use crate::util; use librashader_cache::cache_pipeline; +use librashader_common::map::FastHashMap; use librashader_reflect::back::wgsl::NagaWgslContext; use librashader_reflect::back::ShaderCompilerOutput; use librashader_reflect::reflect::ShaderReflection; @@ -19,9 +20,8 @@ use wgpu::{ pub struct WgpuGraphicsPipeline { pub layout: PipelineLayoutObjects, - render_pipeline: wgpu::RenderPipeline, cache: Option, - pub format: wgpu::TextureFormat, + render_pipelines: FastHashMap, } pub struct PipelineLayoutObjects { @@ -249,18 +249,25 @@ impl WgpuGraphicsPipeline { }; let layout = PipelineLayoutObjects::new(reflection, shader_assembly, device); - let render_pipeline = layout.create_pipeline(render_pass_format, cache.as_ref()); + let mut render_pipelines = FastHashMap::default(); + render_pipelines.insert( + render_pass_format, + layout.create_pipeline(render_pass_format, cache.as_ref()), + ); Self { layout, - render_pipeline, - format: render_pass_format, + render_pipelines, cache, } } + pub fn has_format(&self, format: TextureFormat) -> bool { + self.render_pipelines.contains_key(&format) + } + pub fn recompile(&mut self, format: TextureFormat) { let render_pipeline = self.layout.create_pipeline(format, self.cache.as_ref()); - self.render_pipeline = render_pipeline; + self.render_pipelines.insert(format, render_pipeline); } pub(crate) fn begin_rendering<'pass>( @@ -268,6 +275,14 @@ impl WgpuGraphicsPipeline { output: &RenderTarget<'pass, WgpuOutputView>, cmd: &'pass mut CommandEncoder, ) -> RenderPass<'pass> { + let Some(pipeline) = self + .render_pipelines + .get(&output.output.format) + .or_else(|| self.render_pipelines.values().next()) + else { + panic!("No available render pipelines found") + }; + let mut render_pass = cmd.begin_render_pass(&RenderPassDescriptor { label: Some("librashader"), color_attachments: &[Some(RenderPassColorAttachment { @@ -304,7 +319,7 @@ impl WgpuGraphicsPipeline { 1.0, ); - render_pass.set_pipeline(&self.render_pipeline); + render_pass.set_pipeline(pipeline); render_pass } } diff --git a/librashader-runtime-wgpu/tests/hello_triangle.rs b/librashader-runtime-wgpu/tests/hello_triangle.rs index 8b4a067..d487a35 100644 --- a/librashader-runtime-wgpu/tests/hello_triangle.rs +++ b/librashader-runtime-wgpu/tests/hello_triangle.rs @@ -124,12 +124,12 @@ impl<'a> State<'a> { // // let preset = ShaderPreset::try_parse("../test/basic.slangp").unwrap(); // - // let preset = ShaderPreset::try_parse("../test/shaders_slang/test/history.slangp").unwrap(); + let preset = ShaderPreset::try_parse("../test/shaders_slang/test/feedback.slangp").unwrap(); - let preset = ShaderPreset::try_parse( - "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", - ) - .unwrap(); + // let preset = ShaderPreset::try_parse( + // "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", + // ) + // .unwrap(); let chain = FilterChainWgpu::load_from_preset( preset,