rt(wgpu): draw final pass to output targets

This commit is contained in:
chyyran 2024-09-12 00:50:29 -04:00 committed by Ronny Chan
parent e68da7b984
commit 477d0ae67c
3 changed files with 50 additions and 15 deletions

View file

@ -438,11 +438,11 @@ impl FilterChainWgpu {
let options = options.unwrap_or(&self.default_frame_options); let options = options.unwrap_or(&self.default_frame_options);
for (index, pass) in pass.iter_mut().enumerate() { for (index, pass) in pass.iter_mut().enumerate() {
let target = &self.output_framebuffers[index];
source.filter_mode = pass.config.filter; source.filter_mode = pass.config.filter;
source.wrap_mode = pass.config.wrap_mode; source.wrap_mode = pass.config.wrap_mode;
source.mip_filter = pass.config.filter; source.mip_filter = pass.config.filter;
let target = &self.output_framebuffers[index];
let output_image = WgpuOutputView::from(target); let output_image = WgpuOutputView::from(target);
let out = RenderTarget::identity(&output_image); let out = RenderTarget::identity(&output_image);
@ -476,18 +476,38 @@ impl FilterChainWgpu {
assert_eq!(last.len(), 1); assert_eq!(last.len(), 1);
if let Some(pass) = last.iter_mut().next() { 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 // need to recompile
pass.graphics_pipeline.recompile(viewport.output.format); pass.graphics_pipeline.recompile(viewport.output.format);
} }
source.filter_mode = pass.config.filter; source.filter_mode = pass.config.filter;
source.wrap_mode = pass.config.wrap_mode; source.wrap_mode = pass.config.wrap_mode;
source.mip_filter = pass.config.filter; 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 output_image = &viewport.output;
let out = RenderTarget::viewport_with_output(output_image, viewport); let out = RenderTarget::viewport_with_output(output_image, viewport);
pass.draw( pass.draw(
cmd, cmd,
passes_len - 1, index,
&self.common, &self.common,
pass.config.get_frame_count(frame_count), pass.config.get_frame_count(frame_count),
options, options,

View file

@ -1,6 +1,7 @@
use crate::framebuffer::WgpuOutputView; use crate::framebuffer::WgpuOutputView;
use crate::util; use crate::util;
use librashader_cache::cache_pipeline; use librashader_cache::cache_pipeline;
use librashader_common::map::FastHashMap;
use librashader_reflect::back::wgsl::NagaWgslContext; use librashader_reflect::back::wgsl::NagaWgslContext;
use librashader_reflect::back::ShaderCompilerOutput; use librashader_reflect::back::ShaderCompilerOutput;
use librashader_reflect::reflect::ShaderReflection; use librashader_reflect::reflect::ShaderReflection;
@ -19,9 +20,8 @@ use wgpu::{
pub struct WgpuGraphicsPipeline { pub struct WgpuGraphicsPipeline {
pub layout: PipelineLayoutObjects, pub layout: PipelineLayoutObjects,
render_pipeline: wgpu::RenderPipeline,
cache: Option<wgpu::PipelineCache>, cache: Option<wgpu::PipelineCache>,
pub format: wgpu::TextureFormat, render_pipelines: FastHashMap<wgpu::TextureFormat, wgpu::RenderPipeline>,
} }
pub struct PipelineLayoutObjects { pub struct PipelineLayoutObjects {
@ -249,18 +249,25 @@ impl WgpuGraphicsPipeline {
}; };
let layout = PipelineLayoutObjects::new(reflection, shader_assembly, device); 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 { Self {
layout, layout,
render_pipeline, render_pipelines,
format: render_pass_format,
cache, cache,
} }
} }
pub fn has_format(&self, format: TextureFormat) -> bool {
self.render_pipelines.contains_key(&format)
}
pub fn recompile(&mut self, format: TextureFormat) { pub fn recompile(&mut self, format: TextureFormat) {
let render_pipeline = self.layout.create_pipeline(format, self.cache.as_ref()); 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>( pub(crate) fn begin_rendering<'pass>(
@ -268,6 +275,14 @@ impl WgpuGraphicsPipeline {
output: &RenderTarget<'pass, WgpuOutputView>, output: &RenderTarget<'pass, WgpuOutputView>,
cmd: &'pass mut CommandEncoder, cmd: &'pass mut CommandEncoder,
) -> RenderPass<'pass> { ) -> 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 { let mut render_pass = cmd.begin_render_pass(&RenderPassDescriptor {
label: Some("librashader"), label: Some("librashader"),
color_attachments: &[Some(RenderPassColorAttachment { color_attachments: &[Some(RenderPassColorAttachment {
@ -304,7 +319,7 @@ impl WgpuGraphicsPipeline {
1.0, 1.0,
); );
render_pass.set_pipeline(&self.render_pipeline); render_pass.set_pipeline(pipeline);
render_pass render_pass
} }
} }

View file

@ -124,12 +124,12 @@ impl<'a> State<'a> {
// //
// let preset = ShaderPreset::try_parse("../test/basic.slangp").unwrap(); // 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( // let preset = ShaderPreset::try_parse(
"../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", // "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
) // )
.unwrap(); // .unwrap();
let chain = FilterChainWgpu::load_from_preset( let chain = FilterChainWgpu::load_from_preset(
preset, preset,