Skip to content

Commit

Permalink
rt(wgpu): fix enough stuff to get it to draw a frame
Browse files Browse the repository at this point in the history
  • Loading branch information
chyyran committed Feb 6, 2024
1 parent 5cbda63 commit 283fff2
Show file tree
Hide file tree
Showing 12 changed files with 402 additions and 285 deletions.
26 changes: 13 additions & 13 deletions librashader-runtime-wgpu/src/buffer.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
use std::ops::{Deref, DerefMut};
use std::sync::Arc;
use parking_lot::RwLock;

pub struct WgpuMappedBuffer {
pub struct WgpuStagedBuffer {
buffer: wgpu::Buffer,
shadow: Box<[u8]>,
}

impl WgpuMappedBuffer {
impl WgpuStagedBuffer {
pub fn new(
device: &Arc<wgpu::Device>,
usage: wgpu::BufferUsages,
size: wgpu::BufferAddress,
label: wgpu::Label<'static>
) -> WgpuMappedBuffer {
label: wgpu::Label<'static>,
) -> WgpuStagedBuffer {
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
label,
size,
usage,
mapped_at_creation: true,
usage: usage | wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false,
});

WgpuMappedBuffer {
WgpuStagedBuffer {
buffer,
shadow: vec![0u8; size as usize].into_boxed_slice(),
}
Expand All @@ -31,22 +32,21 @@ 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.shadow)
pub fn flush(&self, queue: &wgpu::Queue) {
queue.write_buffer(&self.buffer, 0, &self.shadow);
}
}

impl Deref for WgpuMappedBuffer {
impl Deref for WgpuStagedBuffer {
type Target = [u8];

fn deref(&self) -> &Self::Target {
self.shadow.deref()
}
}

impl DerefMut for WgpuMappedBuffer {
impl DerefMut for WgpuStagedBuffer {
fn deref_mut(&mut self) -> &mut Self::Target {
self.shadow.deref_mut()
}
}
}
10 changes: 4 additions & 6 deletions librashader-runtime-wgpu/src/draw_quad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub struct DrawQuad {
}

impl DrawQuad {
pub fn new(device: &Device, queue: &mut Queue) -> DrawQuad {
pub fn new(device: &Device) -> DrawQuad {
let buffer = device.create_buffer_init(&BufferInitDescriptor {
label: Some("librashader vbo"),
contents: bytemuck::cast_slice(&VBO_DATA),
Expand All @@ -38,14 +38,12 @@ impl DrawQuad {
DrawQuad { buffer }
}

pub fn bind_vbo_for_frame<'a, 'b: 'a>(&'b self, cmd: &mut RenderPass<'a>) {
pub fn draw_quad<'a, 'b: 'a>(&'b self, cmd: &mut RenderPass<'a>, vbo: QuadType) {
cmd.set_vertex_buffer(0, self.buffer.slice(0..));
}

pub fn draw_quad<'a, 'b: 'a>(&'b self, cmd: &mut RenderPass<'a>, vbo: QuadType) {
let offset = match vbo {
QuadType::Offscreen => 0..3,
QuadType::Final => 1..4,
QuadType::Offscreen => 0..4,
QuadType::Final => 4..8,
};

cmd.draw(offset, 0..1)
Expand Down
143 changes: 85 additions & 58 deletions librashader-runtime-wgpu/src/filter_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,22 @@ use std::convert::Infallible;
use std::path::Path;
use std::sync::Arc;

use crate::buffer::WgpuStagedBuffer;
use crate::draw_quad::DrawQuad;
use librashader_common::{ImageFormat, Size, Viewport};
use librashader_reflect::back::wgsl::WgslCompileOptions;
use librashader_runtime::framebuffer::FramebufferInit;
use librashader_runtime::render_target::RenderTarget;
use librashader_runtime::scaling::ScaleFramebuffer;
use rayon::prelude::*;
use wgpu::{BindGroupEntry, CommandBuffer, CommandEncoder, Device, Queue, TextureAspect, TextureFormat};
use crate::buffer::WgpuMappedBuffer;
use crate::draw_quad::DrawQuad;
use wgpu::{
BindGroupEntry, CommandBuffer, CommandEncoder, Device, Queue, TextureAspect, TextureFormat,
};

use crate::error;
use crate::error::FilterChainError;
use crate::filter_pass::FilterPass;
use crate::framebuffer::OutputImage;
use crate::framebuffer::OutputView;
use crate::graphics_pipeline::WgpuGraphicsPipeline;
use crate::luts::LutTexture;
use crate::options::FrameOptionsWGPU;
Expand Down Expand Up @@ -73,6 +75,7 @@ pub(crate) struct FilterCommon {
pub internal_frame_count: i32,
pub(crate) draw_quad: DrawQuad,
device: Arc<Device>,
pub(crate) queue: Arc<wgpu::Queue>
}

impl FilterChainWGPU {
Expand All @@ -85,7 +88,7 @@ impl FilterChainWGPU {
/// graphics queue. The command buffer must be completely executed before calling [`frame`](Self::frame).
pub fn load_from_preset_deferred(
device: Arc<Device>,
queue: &mut wgpu::Queue,
queue: Arc<wgpu::Queue>,
cmd: &mut wgpu::CommandEncoder,
preset: ShaderPreset,
) -> error::Result<FilterChainWGPU> {
Expand All @@ -94,11 +97,17 @@ impl FilterChainWGPU {
// // initialize passes
let filters = Self::init_passes(Arc::clone(&device), passes, &semantics)?;
//
let luts = FilterChainWGPU::load_luts(&device, queue, cmd, &preset.textures)?;
let luts = FilterChainWGPU::load_luts(&device, &queue, cmd, &preset.textures)?;
let samplers = SamplerSet::new(&device);
//
let framebuffer_gen =
|| Ok::<_, error::FilterChainError>(OwnedImage::new(Arc::clone(&device), Size::new(1, 1), 1, ImageFormat::R8G8B8A8Unorm));
let framebuffer_gen = || {
Ok::<_, error::FilterChainError>(OwnedImage::new(
Arc::clone(&device),
Size::new(1, 1),
1,
ImageFormat::R8G8B8A8Unorm,
))
};
let input_gen = || None;
let framebuffer_init = FramebufferInit::new(
filters.iter().map(|f| &f.reflection.meta),
Expand All @@ -122,39 +131,39 @@ impl FilterChainWGPU {
// FrameResiduals::new(&device.device)
// });

let draw_quad = DrawQuad::new(&device, queue);
let draw_quad = DrawQuad::new(&device);

Ok(FilterChainWGPU {
common: FilterCommon {
luts,
samplers,
config: FilterMutable {
passes_enabled: preset.shader_count as usize,
parameters: preset
.parameters
.into_iter()
.map(|param| (param.name, param.value))
.collect(),
},
draw_quad,
device,
output_textures,
feedback_textures,
history_textures,
internal_frame_count: 0,

config: FilterMutable {
passes_enabled: preset.shader_count as usize,
parameters: preset
.parameters
.into_iter()
.map(|param| (param.name, param.value))
.collect(),
},
draw_quad,
device,
queue,
output_textures,
feedback_textures,
history_textures,
internal_frame_count: 0,
},
passes: filters,
output_framebuffers,
feedback_framebuffers,
history_framebuffers,
disable_mipmaps: false // todo: force no mipmaps,
output_framebuffers,
feedback_framebuffers,
history_framebuffers,
disable_mipmaps: false, // todo: force no mipmaps,
})
}

fn load_luts(
device: &wgpu::Device,
queue: &mut wgpu::Queue,
queue: &wgpu::Queue,
cmd: &mut wgpu::CommandEncoder,
textures: &[TextureConfig],
) -> error::Result<FxHashMap<usize, LutTexture>> {
Expand All @@ -170,6 +179,29 @@ impl FilterChainWGPU {
Ok(luts)
}

fn push_history(&mut self, input: &wgpu::Texture, cmd: &mut wgpu::CommandEncoder) {
if let Some(mut back) = self.history_framebuffers.pop_back() {
if back.image.size() != input.size() || input.format() != back.image.format() {
// old back will get dropped.. do we need to defer?
let _old_back = std::mem::replace(
&mut back,
OwnedImage::new(
Arc::clone(&self.common.device),
input.size().into(),
1,
input.format().into(),
),
);
}

unsafe {
back.copy_from(cmd, input);
}

self.history_framebuffers.push_front(back)
}
}

fn init_passes(
device: Arc<Device>,
passes: Vec<ShaderPassMeta>,
Expand All @@ -193,10 +225,19 @@ impl FilterChainWGPU {
.as_ref()
.map_or(0, |push| push.size as wgpu::BufferAddress);


let uniform_storage = UniformStorage::new_with_storage(
WgpuMappedBuffer::new(&device, wgpu::BufferUsages::UNIFORM, ubo_size as wgpu::BufferAddress, Some("ubo")),
WgpuMappedBuffer::new(&device, wgpu::BufferUsages::UNIFORM, push_size as wgpu::BufferAddress, Some("push"))
WgpuStagedBuffer::new(
&device,
wgpu::BufferUsages::UNIFORM,
ubo_size as wgpu::BufferAddress,
Some("ubo"),
),
WgpuStagedBuffer::new(
&device,
wgpu::BufferUsages::UNIFORM,
push_size as wgpu::BufferAddress,
Some("push"),
),
);

let uniform_bindings = reflection.meta.create_binding_map(|param| param.offset());
Expand All @@ -212,11 +253,9 @@ impl FilterChainWGPU {
Arc::clone(&device),
&wgsl,
&reflection,
render_pass_format.unwrap_or(TextureFormat::R8Unorm),
render_pass_format.unwrap_or(TextureFormat::Rgba8Unorm),
);



Ok(FilterPass {
device: Arc::clone(&device),
reflection,
Expand All @@ -235,21 +274,21 @@ impl FilterChainWGPU {
Ok(filters.into_boxed_slice())
}

pub fn frame<'a>(&mut self,
pub fn frame<'a>(
&mut self,
input: Arc<wgpu::Texture>,
viewport: &Viewport<OutputImage<'a>>,
viewport: &Viewport<OutputView<'a>>,
cmd: &mut wgpu::CommandEncoder,
frame_count: usize,
options: Option<&FrameOptionsWGPU>,

options: Option<&FrameOptionsWGPU>,
) -> error::Result<()> {
let max = std::cmp::min(self.passes.len(), self.common.config.passes_enabled);
let passes = &mut self.passes[0..max];

if let Some(options) = &options {
if options.clear_history {
for history in &mut self.history_framebuffers {
// history.clear(cmd);
history.clear(cmd);
}
}
}
Expand All @@ -258,21 +297,11 @@ impl FilterChainWGPU {
return Ok(());
}

let original_image_view = input.create_view(&wgpu::TextureViewDescriptor {
label: Some("original_image_view"),
format: Some(input.format()),
dimension: Some(wgpu::TextureViewDimension::D2),
aspect: TextureAspect::All,
base_mip_level: 1,
mip_level_count: None,
base_array_layer: 1,
array_layer_count: None,
});
let original_image_view = input.create_view(&wgpu::TextureViewDescriptor::default());

let filter = passes[0].config.filter;
let wrap_mode = passes[0].config.wrap_mode;


// update history
for (texture, image) in self
.common
Expand Down Expand Up @@ -325,14 +354,13 @@ impl FilterChainWGPU {

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 output_image = OutputView::new(target);
let out = RenderTarget::identity(&output_image);

pass.draw(
Expand All @@ -345,11 +373,11 @@ impl FilterChainWGPU {
&original,
&source,
&out,
QuadType::Offscreen
QuadType::Offscreen,
)?;

if target.max_miplevels > 1 && !self.disable_mipmaps {
// todo: mipmaps
target.generate_mipmaps(cmd);
}

source = self.common.output_textures[index].clone().unwrap();
Expand Down Expand Up @@ -378,13 +406,12 @@ impl FilterChainWGPU {
&original,
&source,
&out,
QuadType::Final
QuadType::Final,
)?;
}

// self.push_history(input, cmd)?;
self.push_history(&input, cmd);
self.common.internal_frame_count = self.common.internal_frame_count.wrapping_add(1);
Ok(())
}

}
Loading

0 comments on commit 283fff2

Please sign in to comment.