rt(wgpu): sketch out skeleton for filter chain logic

This commit is contained in:
chyyran 2024-02-02 00:51:17 -05:00 committed by Ronny Chan
parent cc26be486b
commit d5aa6b2e4a
6 changed files with 89 additions and 19 deletions

View file

@ -3,8 +3,7 @@ use std::sync::Arc;
pub struct WgpuMappedBuffer {
buffer: wgpu::Buffer,
backing: Box<[u8]>,
device: Arc<wgpu::Device>
shadow: Box<[u8]>,
}
impl WgpuMappedBuffer {
@ -23,8 +22,7 @@ impl WgpuMappedBuffer {
WgpuMappedBuffer {
buffer,
backing: vec![0u8; size as usize].into_boxed_slice(),
device: Arc::clone(&device)
shadow: vec![0u8; size as usize].into_boxed_slice(),
}
}
@ -35,7 +33,7 @@ impl WgpuMappedBuffer {
/// Write the contents of the backing buffer to the device buffer.
pub fn flush(&self) {
self.buffer.slice(..)
.get_mapped_range_mut().copy_from_slice(&self.backing)
.get_mapped_range_mut().copy_from_slice(&self.shadow)
}
}
@ -43,12 +41,12 @@ impl Deref for WgpuMappedBuffer {
type Target = [u8];
fn deref(&self) -> &Self::Target {
self.backing.deref()
self.shadow.deref()
}
}
impl DerefMut for WgpuMappedBuffer {
fn deref_mut(&mut self) -> &mut Self::Target {
self.backing.deref_mut()
self.shadow.deref_mut()
}
}

View file

@ -29,6 +29,7 @@ use crate::draw_quad::DrawQuad;
use crate::error;
use crate::error::FilterChainError;
use crate::filter_pass::FilterPass;
use crate::framebuffer::OutputImage;
use crate::graphics_pipeline::WgpuGraphicsPipeline;
use crate::luts::LutTexture;
use crate::options::FrameOptionsWGPU;
@ -234,10 +235,10 @@ impl FilterChainWGPU {
Ok(filters.into_boxed_slice())
}
pub fn frame(&mut self,
pub fn frame<'a>(&mut self,
input: wgpu::Texture,
viewport: &Viewport<OwnedImage>,
cmd: wgpu::CommandEncoder,
viewport: &Viewport<OutputImage<'a>>,
cmd: &mut wgpu::CommandEncoder,
frame_count: usize,
options: Option<&FrameOptionsWGPU>,
@ -322,8 +323,67 @@ impl FilterChainWGPU {
let passes_len = passes.len();
let (pass, last) = passes.split_at_mut(passes_len - 1);
// let frame_direction = options.map_or(1, |f| f.frame_direction);
let frame_direction = options.map_or(1, |f| f.frame_direction);
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 output_image = OutputImage::new(target);
let out = RenderTarget::identity(&output_image);
pass.draw(
cmd,
index,
&self.common,
pass.config.get_frame_count(frame_count),
frame_direction,
viewport,
&original,
&source,
&out,
QuadType::Offscreen
)?;
if target.max_miplevels > 1 && !self.disable_mipmaps {
// todo: mipmaps
}
source = self.common.output_textures[index].clone().unwrap();
}
// try to hint the optimizer
assert_eq!(last.len(), 1);
if let Some(pass) = last.iter_mut().next() {
if pass.graphics_pipeline.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 output_image = &viewport.output;
let out = RenderTarget::viewport_with_output(output_image, viewport);
pass.draw(
cmd,
passes_len - 1,
&self.common,
pass.config.get_frame_count(frame_count),
frame_direction,
viewport,
&original,
&source,
&out,
QuadType::Final
)?;
}
// self.push_history(input, cmd)?;
self.common.internal_frame_count = self.common.internal_frame_count.wrapping_add(1);
Ok(())
}

View file

@ -86,7 +86,7 @@ impl FilterPass {
parent: &FilterCommon,
frame_count: u32,
frame_direction: i32,
viewport: &Viewport<OwnedImage>,
viewport: &Viewport<OutputImage>,
original: &InputImage,
source: &InputImage,
output: &RenderTarget<OutputImage>,
@ -201,7 +201,7 @@ impl FilterPass {
Ok(())
}
fn build_semantics<'a, 'b>(
fn build_semantics<'a>(
&mut self,
pass_index: usize,
parent: &FilterCommon,
@ -214,7 +214,7 @@ impl FilterPass {
source: &InputImage,
main_heap: &'a mut FxHashMap<u32, WgpuArcBinding<wgpu::TextureView>>,
sampler_heap: &'a mut FxHashMap<u32, WgpuArcBinding<wgpu::Sampler>>
) where 'a: 'b {
) {
Self::bind_semantics(
&self.device,
&parent.samplers,

View file

@ -1,7 +1,19 @@
use wgpu::TextureView;
use librashader_common::Size;
use crate::texture::OwnedImage;
pub(crate) struct OutputImage {
pub struct OutputImage<'a> {
pub size: Size<u32>,
pub view: TextureView
pub view: &'a wgpu::TextureView,
pub format: wgpu::TextureFormat,
}
impl<'a> OutputImage<'a> {
pub fn new(image: &'a OwnedImage) -> Self {
Self {
size: image.size,
view: &image.view,
format: image.image.format()
}
}
}

View file

@ -11,6 +11,7 @@ use crate::framebuffer::OutputImage;
pub struct WgpuGraphicsPipeline {
pub layout: PipelineLayoutObjects,
render_pipeline: wgpu::RenderPipeline,
pub format: wgpu::TextureFormat
}
pub struct PipelineLayoutObjects {
@ -201,6 +202,7 @@ impl WgpuGraphicsPipeline {
Self {
layout,
render_pipeline,
format: render_pass_format
}
}

View file

@ -13,7 +13,6 @@ pub struct OwnedImage {
pub max_miplevels: u32,
pub levels: u32,
pub size: Size<u32>,
pub format: wgpu::TextureFormat,
}
pub enum Handle<'a, T> {
@ -98,7 +97,6 @@ impl OwnedImage {
max_miplevels,
levels: std::cmp::min(max_miplevels, size.calculate_miplevels()),
size,
format,
}
}
@ -117,7 +115,7 @@ impl OwnedImage {
if self.size != size
|| (mipmap && self.max_miplevels == 1)
|| (!mipmap && self.max_miplevels != 1)
|| format != self.format
|| format != self.image.format()
{
let mut new = OwnedImage::new(Arc::clone(&self.device), size, self.max_miplevels, format.into());
std::mem::swap(self, &mut new);