rt(wgpu): add blocking submission API
This commit is contained in:
parent
54e86e7b06
commit
acc9bfeb53
|
@ -11,6 +11,8 @@ use librashader_runtime::quad::QuadType;
|
|||
use librashader_runtime::uniforms::UniformStorage;
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::collections::VecDeque;
|
||||
use std::convert::Infallible;
|
||||
use std::path::Path;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -31,7 +33,7 @@ use crate::framebuffer::OutputView;
|
|||
use crate::graphics_pipeline::WgpuGraphicsPipeline;
|
||||
use crate::luts::LutTexture;
|
||||
use crate::mipmap::MipmapGen;
|
||||
use crate::options::FrameOptionsWGPU;
|
||||
use crate::options::{FilterChainOptionsWGPU, FrameOptionsWGPU};
|
||||
use crate::samplers::SamplerSet;
|
||||
use crate::texture::{InputImage, OwnedImage};
|
||||
|
||||
|
@ -76,6 +78,46 @@ pub(crate) struct FilterCommon {
|
|||
}
|
||||
|
||||
impl FilterChainWGPU {
|
||||
/// Load the shader preset at the given path into a filter chain.
|
||||
pub fn load_from_path(
|
||||
path: impl AsRef<Path>,
|
||||
device: Arc<Device>,
|
||||
queue: Arc<wgpu::Queue>,
|
||||
options: Option<&FilterChainOptionsWGPU>,
|
||||
) -> error::Result<FilterChainWGPU> {
|
||||
// load passes from preset
|
||||
let preset = ShaderPreset::try_parse(path)?;
|
||||
|
||||
Self::load_from_preset(preset, device, queue, options)
|
||||
}
|
||||
|
||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||
pub fn load_from_preset(
|
||||
preset: ShaderPreset,
|
||||
device: Arc<Device>,
|
||||
queue: Arc<wgpu::Queue>,
|
||||
options: Option<&FilterChainOptionsWGPU>,
|
||||
) -> error::Result<FilterChainWGPU> {
|
||||
let mut cmd = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: Some("librashader load cmd"),
|
||||
});
|
||||
let filter_chain = Self::load_from_preset_deferred(
|
||||
preset,
|
||||
Arc::clone(&device),
|
||||
Arc::clone(&queue),
|
||||
&mut cmd,
|
||||
options,
|
||||
)?;
|
||||
|
||||
let cmd = cmd.finish();
|
||||
|
||||
// Wait for device
|
||||
let index = queue.submit([cmd]);
|
||||
device.poll(wgpu::Maintain::WaitForSubmissionIndex(index));
|
||||
|
||||
Ok(filter_chain)
|
||||
}
|
||||
|
||||
/// Load a filter chain from a pre-parsed `ShaderPreset`, deferring and GPU-side initialization
|
||||
/// to the caller. This function therefore requires no external synchronization of the device queue.
|
||||
///
|
||||
|
@ -84,10 +126,11 @@ impl FilterChainWGPU {
|
|||
/// The caller is responsible for ending the command buffer and immediately submitting it to a
|
||||
/// graphics queue. The command buffer must be completely executed before calling [`frame`](Self::frame).
|
||||
pub fn load_from_preset_deferred(
|
||||
preset: ShaderPreset,
|
||||
device: Arc<Device>,
|
||||
queue: Arc<wgpu::Queue>,
|
||||
cmd: &mut wgpu::CommandEncoder,
|
||||
preset: ShaderPreset,
|
||||
options: Option<&FilterChainOptionsWGPU>,
|
||||
) -> error::Result<FilterChainWGPU> {
|
||||
let (passes, semantics) = compile_passes(preset.shaders, &preset.textures)?;
|
||||
|
||||
|
@ -157,7 +200,7 @@ impl FilterChainWGPU {
|
|||
output_framebuffers,
|
||||
feedback_framebuffers,
|
||||
history_framebuffers,
|
||||
disable_mipmaps: false, // todo: force no mipmaps,
|
||||
disable_mipmaps: options.map(|f| f.force_no_mipmaps).unwrap_or(false),
|
||||
mipmapper,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -8,3 +8,11 @@ pub struct FrameOptionsWGPU {
|
|||
/// -1 indicates that the frames are played in reverse order.
|
||||
pub frame_direction: i32,
|
||||
}
|
||||
|
||||
/// Options for filter chain creation.
|
||||
#[repr(C)]
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct FilterChainOptionsWGPU {
|
||||
/// Whether or not to explicitly disable mipmap generation regardless of shader preset settings.
|
||||
pub force_no_mipmaps: bool,
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ impl<'a> State<'a> {
|
|||
let size = window.inner_size();
|
||||
|
||||
let instance = wgpu::Instance::default();
|
||||
let surface = unsafe { instance.create_surface(window).unwrap() };
|
||||
let surface = instance.create_surface(window).unwrap();
|
||||
// NOTE: could be none, see: https://sotrh.github.io/learn-wgpu/beginner/tutorial2-surface/#state-new
|
||||
let adapter = instance
|
||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
|
@ -121,26 +121,17 @@ impl<'a> State<'a> {
|
|||
let device = Arc::new(device);
|
||||
let queue = Arc::new(queue);
|
||||
|
||||
let mut cmd = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: Some("start encoder"),
|
||||
});
|
||||
|
||||
let preset =
|
||||
ShaderPreset::try_parse("../test/shaders_slang/crt/crt-royale.slangp").unwrap();
|
||||
|
||||
let chain = FilterChainWGPU::load_from_preset_deferred(
|
||||
let chain = FilterChainWGPU::load_from_preset(
|
||||
preset,
|
||||
Arc::clone(&device),
|
||||
Arc::clone(&queue),
|
||||
&mut cmd,
|
||||
preset,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let cmd = cmd.finish();
|
||||
|
||||
let index = queue.submit([cmd]);
|
||||
device.poll(Maintain::WaitForSubmissionIndex(index));
|
||||
|
||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||
label: Some("Shader"),
|
||||
source: wgpu::ShaderSource::Wgsl(include_str!("../shader/triangle.wgsl").into()),
|
||||
|
|
Loading…
Reference in a new issue