lib: add wgpu to librashader library

This commit is contained in:
chyyran 2024-02-06 18:42:32 -05:00 committed by Ronny Chan
parent 754e8da620
commit 37397ff216
16 changed files with 102 additions and 62 deletions

View file

@ -13,16 +13,22 @@
</component>
<component name="ChangeListManager">
<list default="true" id="02471831-07cd-4975-a00c-e042450023a1" name="Changes" comment="rt(wgpu): wip filter chain logic">
<change afterPath="$PROJECT_DIR$/librashader-runtime-wgpu/src/options.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Cargo.lock" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-common/src/wgpu.rs" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-common/src/wgpu.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-reflect/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-reflect/Cargo.toml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-reflect/src/reflect/naga.rs" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-reflect/src/reflect/naga.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-runtime-gl/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-runtime-gl/Cargo.toml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-runtime-vk/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-runtime-vk/Cargo.toml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-runtime-wgpu/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-runtime-wgpu/Cargo.toml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-runtime-wgpu/src/error.rs" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-runtime-wgpu/src/error.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-runtime-wgpu/src/filter_chain.rs" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-runtime-wgpu/src/filter_chain.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-runtime-wgpu/src/filter_pass.rs" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-runtime-wgpu/src/filter_pass.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-runtime-wgpu/src/graphics_pipeline.rs" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-runtime-wgpu/src/graphics_pipeline.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-runtime-wgpu/src/framebuffer.rs" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-runtime-wgpu/src/framebuffer.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-runtime-wgpu/src/lib.rs" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-runtime-wgpu/src/lib.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-runtime-wgpu/src/luts.rs" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-runtime-wgpu/src/luts.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-runtime-wgpu/src/texture.rs" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-runtime-wgpu/src/texture.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-runtime-wgpu/src/options.rs" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-runtime-wgpu/src/options.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader-runtime-wgpu/tests/hello_triangle.rs" beforeDir="false" afterPath="$PROJECT_DIR$/librashader-runtime-wgpu/tests/hello_triangle.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/librashader/Cargo.toml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/librashader/src/lib.rs" beforeDir="false" afterPath="$PROJECT_DIR$/librashader/src/lib.rs" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -278,6 +284,7 @@
<workItem from="1706229877283" duration="1844000" />
<workItem from="1706680503632" duration="3415000" />
<workItem from="1706766058493" duration="620000" />
<workItem from="1707260879653" duration="1928000" />
</task>
<task id="LOCAL-00001" summary="rt(wgpu): basic triangle example">
<option name="closed" value="true" />
@ -381,6 +388,17 @@
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
<component name="VcsManagerConfiguration">
<ignored-roots>
<path value="$PROJECT_DIR$/.." />

3
Cargo.lock generated
View file

@ -1714,6 +1714,7 @@ dependencies = [
"librashader-runtime-d3d12",
"librashader-runtime-gl",
"librashader-runtime-vk",
"librashader-runtime-wgpu",
"windows 0.48.0",
]
@ -1941,7 +1942,7 @@ dependencies = [
[[package]]
name = "librashader-runtime-wgpu"
version = "0.1.0"
version = "0.2.0-beta.2"
dependencies = [
"array-concat",
"bytemuck",

View file

@ -33,6 +33,7 @@ serde = { version = "1.0", features = ["derive"], optional = true }
indexmap = { version = "2.1.0", features = [] }
matches = { version = "0.1.10", features = [] }
[target.'cfg(windows)'.dependencies.spirv-to-dxil]
version = "0.4"
optional = true

View file

@ -15,7 +15,7 @@ use crate::reflect::semantics::{
use crate::reflect::{align_uniform_size, ReflectShader, ShaderReflection};
#[derive(Debug)]
pub struct NagaReflect {
pub(crate) struct NagaReflect {
pub(crate) vertex: Module,
pub(crate) fragment: Module,
}

View file

@ -31,8 +31,5 @@ sptr = "0.3"
[dev-dependencies]
glfw = "0.47.0"
[[test]]
name = "triangle"
[package.metadata.docs.rs]
features = ["librashader-cache/docsrs"]

View file

@ -37,9 +37,5 @@ winit = "0.27.5"
raw-window-handle = "0.5"
ash-window = "0.12.0"
[[test]]
name = "triangle"
[package.metadata.docs.rs]
features = ["librashader-cache/docsrs"]

View file

@ -1,8 +1,16 @@
[package]
name = "librashader-runtime-wgpu"
version = "0.1.0"
edition = "2021"
version = "0.2.0-beta.2"
license = "MPL-2.0 OR GPL-3.0-only"
authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md"
categories = ["emulators", "compilers", "graphics"]
keywords = ["shader", "retroarch", "SPIR-V"]
description = "RetroArch shaders for all."
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
@ -28,6 +36,3 @@ winit = "0.29.10"
pollster = "0.3"
log = "0.4.20"
[[test]]
name = "triangle"

View file

@ -1,12 +1,11 @@
//! Vulkan shader runtime errors.
//! wgpu shader runtime errors.
use librashader_preprocess::PreprocessError;
use librashader_presets::ParsePresetError;
use librashader_reflect::error::{ShaderCompileError, ShaderReflectError};
use librashader_runtime::image::ImageError;
use std::convert::Infallible;
use thiserror::Error;
/// Cumulative error type for WGPU filter chains.
/// Cumulative error type for wgpu filter chains.
#[derive(Error, Debug)]
pub enum FilterChainError {
#[error("shader preset parse error")]
@ -21,11 +20,5 @@ pub enum FilterChainError {
LutLoadError(#[from] ImageError),
}
impl From<Infallible> for FilterChainError {
fn from(_value: Infallible) -> Self {
panic!("uninhabited error")
}
}
/// Result type for Vulkan filter chains.
/// Result type for wgpu filter chains.
pub type Result<T> = std::result::Result<T, FilterChainError>;

View file

@ -11,7 +11,6 @@ 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;
@ -33,7 +32,7 @@ use crate::framebuffer::OutputView;
use crate::graphics_pipeline::WgpuGraphicsPipeline;
use crate::luts::LutTexture;
use crate::mipmap::MipmapGen;
use crate::options::{FilterChainOptionsWGPU, FrameOptionsWGPU};
use crate::options::{FilterChainOptionsWgpu, FrameOptionsWgpu};
use crate::samplers::SamplerSet;
use crate::texture::{InputImage, OwnedImage};
@ -48,8 +47,8 @@ fn compile_passes(
Ok((passes, semantics))
}
/// A WGPU filter chain.
pub struct FilterChainWGPU {
/// A wgpu filter chain.
pub struct FilterChainWgpu {
pub(crate) common: FilterCommon,
passes: Box<[FilterPass]>,
output_framebuffers: Box<[OwnedImage]>,
@ -77,14 +76,14 @@ pub(crate) struct FilterCommon {
pub(crate) queue: Arc<wgpu::Queue>,
}
impl FilterChainWGPU {
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> {
options: Option<&FilterChainOptionsWgpu>,
) -> error::Result<FilterChainWgpu> {
// load passes from preset
let preset = ShaderPreset::try_parse(path)?;
@ -96,8 +95,8 @@ impl FilterChainWGPU {
preset: ShaderPreset,
device: Arc<Device>,
queue: Arc<wgpu::Queue>,
options: Option<&FilterChainOptionsWGPU>,
) -> error::Result<FilterChainWGPU> {
options: Option<&FilterChainOptionsWgpu>,
) -> error::Result<FilterChainWgpu> {
let mut cmd = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("librashader load cmd"),
});
@ -130,8 +129,8 @@ impl FilterChainWGPU {
device: Arc<Device>,
queue: Arc<wgpu::Queue>,
cmd: &mut wgpu::CommandEncoder,
options: Option<&FilterChainOptionsWGPU>,
) -> error::Result<FilterChainWGPU> {
options: Option<&FilterChainOptionsWgpu>,
) -> error::Result<FilterChainWgpu> {
let (passes, semantics) = compile_passes(preset.shaders, &preset.textures)?;
// // initialize passes
@ -139,7 +138,7 @@ impl FilterChainWGPU {
let samplers = SamplerSet::new(&device);
let mut mipmapper = MipmapGen::new(Arc::clone(&device));
let luts = FilterChainWGPU::load_luts(
let luts = FilterChainWgpu::load_luts(
&device,
&queue,
cmd,
@ -176,7 +175,7 @@ impl FilterChainWGPU {
let draw_quad = DrawQuad::new(&device);
Ok(FilterChainWGPU {
Ok(FilterChainWgpu {
common: FilterCommon {
luts,
samplers,
@ -302,7 +301,6 @@ impl FilterChainWGPU {
Ok(FilterPass {
device: Arc::clone(&device),
reflection,
compiled: wgsl,
uniform_storage,
uniform_bindings,
source,
@ -317,13 +315,14 @@ impl FilterChainWGPU {
Ok(filters.into_boxed_slice())
}
/// Records shader rendering commands to the provided command encoder.
pub fn frame<'a>(
&mut self,
input: Arc<wgpu::Texture>,
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];

View file

@ -8,8 +8,6 @@ use crate::texture::InputImage;
use librashader_common::{ImageFormat, Size, Viewport};
use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPassConfig;
use librashader_reflect::back::wgsl::NagaWgslContext;
use librashader_reflect::back::ShaderCompilerOutput;
use librashader_reflect::reflect::semantics::{
BindingStage, MemberOffset, TextureBinding, UniformBinding,
};
@ -26,7 +24,6 @@ use wgpu::{BindGroupDescriptor, BindGroupEntry, BindingResource, BufferBinding,
pub struct FilterPass {
pub device: Arc<wgpu::Device>,
pub reflection: ShaderReflection,
pub(crate) compiled: ShaderCompilerOutput<String, NagaWgslContext>,
pub(crate) uniform_storage:
UniformStorage<NoUniformBinder, Option<()>, WgpuStagedBuffer, WgpuStagedBuffer>,
pub uniform_bindings: FxHashMap<UniformBinding, MemberOffset>,

View file

@ -3,6 +3,7 @@ use crate::texture::OwnedImage;
use librashader_common::Size;
use wgpu::TextureViewDescriptor;
/// A wgpu `TextureView` with size and texture information to output.
pub struct OutputView<'a> {
pub(crate) size: Size<u32>,
pub(crate) view: Handle<'a, wgpu::TextureView>,

View file

@ -9,7 +9,6 @@
mod buffer;
mod draw_quad;
mod error;
mod filter_chain;
mod filter_pass;
mod framebuffer;
@ -17,11 +16,13 @@ mod graphics_pipeline;
mod handle;
mod luts;
mod mipmap;
mod options;
mod samplers;
mod texture;
mod util;
pub use filter_chain::FilterChainWGPU;
pub use filter_pass::FilterPass;
pub use filter_chain::FilterChainWgpu;
pub use framebuffer::OutputView;
pub mod error;
pub mod options;

View file

@ -1,7 +1,9 @@
/// Options for each WGPU shader frame.
//! wgpu shader runtime options.
/// Options for each wgpu shader frame.
#[repr(C)]
#[derive(Default, Debug, Clone)]
pub struct FrameOptionsWGPU {
pub struct FrameOptionsWgpu {
/// Whether or not to clear the history buffers.
pub clear_history: bool,
/// The direction of rendering.
@ -12,7 +14,7 @@ pub struct FrameOptionsWGPU {
/// Options for filter chain creation.
#[repr(C)]
#[derive(Default, Debug, Clone)]
pub struct FilterChainOptionsWGPU {
pub struct FilterChainOptionsWgpu {
/// Whether or not to explicitly disable mipmap generation regardless of shader preset settings.
pub force_no_mipmaps: bool,
}

View file

@ -8,7 +8,7 @@ use winit::{
use librashader_common::Viewport;
use librashader_presets::ShaderPreset;
use librashader_runtime_wgpu::FilterChainWGPU;
use librashader_runtime_wgpu::FilterChainWgpu;
use wgpu::util::DeviceExt;
use winit::event_loop::EventLoopBuilder;
use winit::keyboard::{Key, KeyCode, PhysicalKey};
@ -74,7 +74,7 @@ struct State<'a> {
vertex_buffer: wgpu::Buffer,
num_vertices: u32,
chain: FilterChainWGPU,
chain: FilterChainWgpu,
frame_count: usize,
}
impl<'a> State<'a> {
@ -124,7 +124,7 @@ impl<'a> State<'a> {
let preset =
ShaderPreset::try_parse("../test/shaders_slang/crt/crt-royale.slangp").unwrap();
let chain = FilterChainWGPU::load_from_preset(
let chain = FilterChainWgpu::load_from_preset(
preset,
Arc::clone(&device),
Arc::clone(&queue),

View file

@ -22,6 +22,7 @@ librashader-runtime-d3d11 = { path = "../librashader-runtime-d3d11", version =
librashader-runtime-d3d12 = { path = "../librashader-runtime-d3d12", version = "0.2.0-beta.2", optional = true }
librashader-runtime-gl = { path = "../librashader-runtime-gl", version = "0.2.0-beta.2", optional = true }
librashader-runtime-vk = { path = "../librashader-runtime-vk", version = "0.2.0-beta.2", optional = true }
librashader-runtime-wgpu = { path = "../librashader-runtime-wgpu", version = "0.2.0-beta.2", optional = true }
librashader-cache = { path = "../librashader-cache", version = "0.2.0-beta.2" }
@ -39,17 +40,20 @@ preprocess = []
presets = []
# runtimes
runtime-gl = [ "runtime", "reflect-cross", "librashader-common/opengl", "librashader-runtime-gl" ]
runtime-d3d11 = [ "runtime", "reflect-cross","librashader-common/d3d11", "librashader-runtime-d3d11", "windows/Win32_Graphics_Direct3D11" ]
runtime-d3d12 = [ "runtime", "reflect-cross", "reflect-dxil", "librashader-common/d3d12", "librashader-runtime-d3d12", "windows/Win32_Graphics_Direct3D12" ]
runtime-vk = ["runtime", "reflect-cross", "librashader-common/vulkan", "librashader-runtime-vk", "ash" ]
runtime-wgpu = [ "runtime", "reflect-naga", "librashader-common/wgpu", "librashader-runtime-wgpu" ]
# reflection
reflect-cross = ["reflect", "librashader-reflect/cross"]
reflect-dxil = ["reflect", "librashader-reflect/dxil"]
reflect-naga = ["reflect", "librashader-reflect/naga"]
runtime-all = ["runtime-gl", "runtime-d3d11", "runtime-d3d12", "runtime-vk"]
reflect-all = ["reflect-cross", "reflect-dxil"]
runtime-all = ["runtime-gl", "runtime-d3d11", "runtime-d3d12", "runtime-vk", "runtime-wgpu"]
reflect-all = ["reflect-cross", "reflect-dxil", "reflect-naga"]
# enable all features by default
default = [ "full" ]

View file

@ -15,7 +15,7 @@
//! called with appropriate input and output parameters to draw a frame with the shader effect applied.
//!
//! ## Runtimes
//! Currently available runtimes are Vulkan, OpenGL 3.3+ and 4.6 (with DSA), Direct3D 11, and Direct3D 12.
//! Currently available runtimes are wgpu, Vulkan, OpenGL 3.3+ and 4.6 (with DSA), Direct3D 11, and Direct3D 12.
//!
//! The Vulkan runtime requires [`VK_KHR_dynamic_rendering`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_dynamic_rendering.html)
//! by default, unless [`FilterChainOptions::use_render_pass`](crate::runtime::vk::FilterChainOptions) is explicitly set. Note that dynamic rendering
@ -24,6 +24,8 @@
//! The Direct3D 12 runtime requires support for [render passes](https://learn.microsoft.com/en-us/windows/win32/direct3d12/direct3d-12-render-passes), which
//! have been available since Windows 10, version 1809.
//!
//! wgpu support is not available in the librashader C API.
//!
//! | **API** | **Status** | **`librashader` feature** |
//! |-------------|------------|---------------------------|
//! | OpenGL 3.3+ | ✔ | `gl` |
@ -31,8 +33,9 @@
//! | Vulkan | ✔ | `vk` |
//! | Direct3D 11 | ✔ | `d3d11` |
//! | Direct3D 12 | ✔ | `d3d12` |
//! | wgpu | ✔ | `wgpu` |
//! | Metal | ❌ | |
//! | WebGPU | ❌ | |
//!
//! ## C API
//! For documentation on the librashader C API, see [librashader-capi](https://docs.rs/librashader-capi/latest/librashader_capi/),
//! or [`librashader.h`](https://github.com/SnowflakePowered/librashader/blob/master/include/librashader.h).
@ -135,6 +138,7 @@ pub mod reflect {
pub use librashader_reflect::back::targets::GLSL;
pub use librashader_reflect::back::targets::HLSL;
pub use librashader_reflect::back::targets::SPIRV;
pub use librashader_reflect::back::targets::WGSL;
}
pub use librashader_reflect::error::*;
@ -146,12 +150,12 @@ pub mod reflect {
FromCompilation, ShaderCompilerOutput,
};
pub use librashader_reflect::front::GlslangCompilation;
/// Reflection via SPIRV-Cross.
#[cfg(feature = "reflect-cross")]
#[doc(cfg(feature = "reflect-cross"))]
pub mod cross {
pub use librashader_reflect::front::GlslangCompilation;
/// The version of GLSL to target.
///
pub use librashader_reflect::back::cross::GlslVersion;
@ -180,6 +184,14 @@ pub mod reflect {
pub use librashader_reflect::back::dxil::DxilObject;
}
/// Reflection via Naga
#[cfg(feature = "reflect-naga")]
#[doc(cfg(feature = "reflect-naga"))]
pub mod naga {
pub use librashader_reflect::back::wgsl::NagaWgslContext;
pub use librashader_reflect::back::wgsl::WgslCompileOptions;
}
pub use librashader_reflect::reflect::semantics::BindingMeta;
pub use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
@ -292,6 +304,19 @@ pub mod runtime {
pub use librashader_runtime_vk::*;
}
}
#[cfg(feature = "runtime-wgpu")]
#[doc(cfg(feature = "runtime-wgpu"))]
/// Shader runtime for wgpu
pub mod wgpu {
pub use librashader_runtime_wgpu::{
error,
options::{
FilterChainOptionsWgpu as FilterChainOptions, FrameOptionsWgpu as FrameOptions,
},
FilterChainWgpu as FilterChain, OutputView,
};
}
}
pub use librashader_common::{FilterMode, ImageFormat, WrapMode};