rt(wgpu): sketch out skeleton for filter chain logic
This commit is contained in:
parent
cc26be486b
commit
d5aa6b2e4a
|
@ -3,8 +3,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
pub struct WgpuMappedBuffer {
|
pub struct WgpuMappedBuffer {
|
||||||
buffer: wgpu::Buffer,
|
buffer: wgpu::Buffer,
|
||||||
backing: Box<[u8]>,
|
shadow: Box<[u8]>,
|
||||||
device: Arc<wgpu::Device>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuMappedBuffer {
|
impl WgpuMappedBuffer {
|
||||||
|
@ -23,8 +22,7 @@ impl WgpuMappedBuffer {
|
||||||
|
|
||||||
WgpuMappedBuffer {
|
WgpuMappedBuffer {
|
||||||
buffer,
|
buffer,
|
||||||
backing: vec![0u8; size as usize].into_boxed_slice(),
|
shadow: vec![0u8; size as usize].into_boxed_slice(),
|
||||||
device: Arc::clone(&device)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +33,7 @@ impl WgpuMappedBuffer {
|
||||||
/// Write the contents of the backing buffer to the device buffer.
|
/// Write the contents of the backing buffer to the device buffer.
|
||||||
pub fn flush(&self) {
|
pub fn flush(&self) {
|
||||||
self.buffer.slice(..)
|
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];
|
type Target = [u8];
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
self.backing.deref()
|
self.shadow.deref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DerefMut for WgpuMappedBuffer {
|
impl DerefMut for WgpuMappedBuffer {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
self.backing.deref_mut()
|
self.shadow.deref_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,6 +29,7 @@ use crate::draw_quad::DrawQuad;
|
||||||
use crate::error;
|
use crate::error;
|
||||||
use crate::error::FilterChainError;
|
use crate::error::FilterChainError;
|
||||||
use crate::filter_pass::FilterPass;
|
use crate::filter_pass::FilterPass;
|
||||||
|
use crate::framebuffer::OutputImage;
|
||||||
use crate::graphics_pipeline::WgpuGraphicsPipeline;
|
use crate::graphics_pipeline::WgpuGraphicsPipeline;
|
||||||
use crate::luts::LutTexture;
|
use crate::luts::LutTexture;
|
||||||
use crate::options::FrameOptionsWGPU;
|
use crate::options::FrameOptionsWGPU;
|
||||||
|
@ -234,10 +235,10 @@ impl FilterChainWGPU {
|
||||||
Ok(filters.into_boxed_slice())
|
Ok(filters.into_boxed_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn frame(&mut self,
|
pub fn frame<'a>(&mut self,
|
||||||
input: wgpu::Texture,
|
input: wgpu::Texture,
|
||||||
viewport: &Viewport<OwnedImage>,
|
viewport: &Viewport<OutputImage<'a>>,
|
||||||
cmd: wgpu::CommandEncoder,
|
cmd: &mut wgpu::CommandEncoder,
|
||||||
frame_count: usize,
|
frame_count: usize,
|
||||||
options: Option<&FrameOptionsWGPU>,
|
options: Option<&FrameOptionsWGPU>,
|
||||||
|
|
||||||
|
@ -322,8 +323,67 @@ impl FilterChainWGPU {
|
||||||
let passes_len = passes.len();
|
let passes_len = passes.len();
|
||||||
let (pass, last) = passes.split_at_mut(passes_len - 1);
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ impl FilterPass {
|
||||||
parent: &FilterCommon,
|
parent: &FilterCommon,
|
||||||
frame_count: u32,
|
frame_count: u32,
|
||||||
frame_direction: i32,
|
frame_direction: i32,
|
||||||
viewport: &Viewport<OwnedImage>,
|
viewport: &Viewport<OutputImage>,
|
||||||
original: &InputImage,
|
original: &InputImage,
|
||||||
source: &InputImage,
|
source: &InputImage,
|
||||||
output: &RenderTarget<OutputImage>,
|
output: &RenderTarget<OutputImage>,
|
||||||
|
@ -201,7 +201,7 @@ impl FilterPass {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_semantics<'a, 'b>(
|
fn build_semantics<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
pass_index: usize,
|
pass_index: usize,
|
||||||
parent: &FilterCommon,
|
parent: &FilterCommon,
|
||||||
|
@ -214,7 +214,7 @@ impl FilterPass {
|
||||||
source: &InputImage,
|
source: &InputImage,
|
||||||
main_heap: &'a mut FxHashMap<u32, WgpuArcBinding<wgpu::TextureView>>,
|
main_heap: &'a mut FxHashMap<u32, WgpuArcBinding<wgpu::TextureView>>,
|
||||||
sampler_heap: &'a mut FxHashMap<u32, WgpuArcBinding<wgpu::Sampler>>
|
sampler_heap: &'a mut FxHashMap<u32, WgpuArcBinding<wgpu::Sampler>>
|
||||||
) where 'a: 'b {
|
) {
|
||||||
Self::bind_semantics(
|
Self::bind_semantics(
|
||||||
&self.device,
|
&self.device,
|
||||||
&parent.samplers,
|
&parent.samplers,
|
||||||
|
|
|
@ -1,7 +1,19 @@
|
||||||
use wgpu::TextureView;
|
use wgpu::TextureView;
|
||||||
use librashader_common::Size;
|
use librashader_common::Size;
|
||||||
|
use crate::texture::OwnedImage;
|
||||||
|
|
||||||
pub(crate) struct OutputImage {
|
pub struct OutputImage<'a> {
|
||||||
pub size: Size<u32>,
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@ use crate::framebuffer::OutputImage;
|
||||||
pub struct WgpuGraphicsPipeline {
|
pub struct WgpuGraphicsPipeline {
|
||||||
pub layout: PipelineLayoutObjects,
|
pub layout: PipelineLayoutObjects,
|
||||||
render_pipeline: wgpu::RenderPipeline,
|
render_pipeline: wgpu::RenderPipeline,
|
||||||
|
pub format: wgpu::TextureFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PipelineLayoutObjects {
|
pub struct PipelineLayoutObjects {
|
||||||
|
@ -201,6 +202,7 @@ impl WgpuGraphicsPipeline {
|
||||||
Self {
|
Self {
|
||||||
layout,
|
layout,
|
||||||
render_pipeline,
|
render_pipeline,
|
||||||
|
format: render_pass_format
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ pub struct OwnedImage {
|
||||||
pub max_miplevels: u32,
|
pub max_miplevels: u32,
|
||||||
pub levels: u32,
|
pub levels: u32,
|
||||||
pub size: Size<u32>,
|
pub size: Size<u32>,
|
||||||
pub format: wgpu::TextureFormat,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Handle<'a, T> {
|
pub enum Handle<'a, T> {
|
||||||
|
@ -98,7 +97,6 @@ impl OwnedImage {
|
||||||
max_miplevels,
|
max_miplevels,
|
||||||
levels: std::cmp::min(max_miplevels, size.calculate_miplevels()),
|
levels: std::cmp::min(max_miplevels, size.calculate_miplevels()),
|
||||||
size,
|
size,
|
||||||
format,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +115,7 @@ impl OwnedImage {
|
||||||
if self.size != size
|
if self.size != size
|
||||||
|| (mipmap && self.max_miplevels == 1)
|
|| (mipmap && self.max_miplevels == 1)
|
||||||
|| (!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());
|
let mut new = OwnedImage::new(Arc::clone(&self.device), size, self.max_miplevels, format.into());
|
||||||
std::mem::swap(self, &mut new);
|
std::mem::swap(self, &mut new);
|
||||||
|
|
Loading…
Reference in a new issue