From acab02e4017dd0117d231df05f19848eb22e9789 Mon Sep 17 00:00:00 2001 From: chyyran Date: Wed, 30 Nov 2022 22:50:57 -0500 Subject: [PATCH] doc: general add docs and clean up --- Cargo.lock | 1 + librashader-common/src/gl.rs | 1 + librashader-common/src/image.rs | 16 ++- librashader-common/src/lib.rs | 27 +++- librashader-common/src/runtime.rs | 1 - librashader-preprocess/src/error.rs | 11 +- librashader-preprocess/src/lib.rs | 19 +++ librashader-preprocess/src/pragma.rs | 2 +- librashader-presets/src/error.rs | 16 ++- librashader-presets/src/preset.rs | 10 ++ librashader-reflect/src/lib.rs | 4 + librashader-reflect/src/reflect/semantics.rs | 1 - librashader-runtime-d3d11/src/filter_chain.rs | 21 ++- librashader-runtime-d3d11/src/filter_pass.rs | 6 +- librashader-runtime-d3d11/src/framebuffer.rs | 14 +- .../src/hello_triangle.rs | 1 + librashader-runtime-d3d11/src/lib.rs | 3 +- librashader-runtime-d3d11/src/parameters.rs | 31 +++++ .../filter_impl.rs} | 119 ++++------------- .../src/filter_chain/inner.rs | 6 + .../src/filter_chain/mod.rs | 82 ++++++++++++ .../src/filter_chain/parameters.rs | 74 +++++++++++ librashader-runtime-gl/src/filter_pass.rs | 2 +- .../src/gl/gl3/draw_quad.rs | 14 ++ librashader-runtime-gl/src/gl/gl3/lut_load.rs | 4 +- .../src/gl/gl46/draw_quad.rs | 14 ++ .../src/gl/gl46/lut_load.rs | 4 +- librashader-runtime-gl/src/lib.rs | 2 +- librashader-runtime-gl/src/render_target.rs | 2 +- librashader-runtime/src/filter_chain.rs | 30 +++++ librashader-runtime/src/lib.rs | 13 ++ librashader-runtime/src/parameters.rs | 19 +++ librashader-runtime/src/scaling.rs | 21 ++- librashader-runtime/src/semantics.rs | 5 + librashader-runtime/src/uniforms.rs | 41 ++++-- librashader/Cargo.toml | 1 + librashader/src/lib.rs | 123 +++++++++--------- 37 files changed, 561 insertions(+), 200 deletions(-) delete mode 100644 librashader-common/src/runtime.rs create mode 100644 librashader-runtime-d3d11/src/parameters.rs rename librashader-runtime-gl/src/{filter_chain.rs => filter_chain/filter_impl.rs} (87%) create mode 100644 librashader-runtime-gl/src/filter_chain/inner.rs create mode 100644 librashader-runtime-gl/src/filter_chain/mod.rs create mode 100644 librashader-runtime-gl/src/filter_chain/parameters.rs create mode 100644 librashader-runtime/src/filter_chain.rs create mode 100644 librashader-runtime/src/parameters.rs diff --git a/Cargo.lock b/Cargo.lock index 8a91bd0..ae1249b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -416,6 +416,7 @@ dependencies = [ "librashader-preprocess", "librashader-presets", "librashader-reflect", + "librashader-runtime", "librashader-runtime-d3d11", "librashader-runtime-gl", ] diff --git a/librashader-common/src/gl.rs b/librashader-common/src/gl.rs index 366c703..0389eb9 100644 --- a/librashader-common/src/gl.rs +++ b/librashader-common/src/gl.rs @@ -59,6 +59,7 @@ impl From for gl::types::GLenum { } impl FilterMode { + /// Get the mipmap filtering mode for the given combination. pub fn gl_mip(&self, mip: FilterMode) -> gl::types::GLenum { match (self, mip) { (FilterMode::Linear, FilterMode::Linear) => gl::LINEAR_MIPMAP_LINEAR, diff --git a/librashader-common/src/image.rs b/librashader-common/src/image.rs index 0719ae4..a01dfec 100644 --- a/librashader-common/src/image.rs +++ b/librashader-common/src/image.rs @@ -6,9 +6,20 @@ pub struct Image { pub pitch: usize, } +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum UVDirection { + TopLeft, + BottomLeft, +} impl Image { - pub fn load(path: impl AsRef) -> Result { - let image = image::open(path.as_ref())?.flipv().to_rgba8(); + pub fn load(path: impl AsRef, direction: UVDirection) -> Result { + let mut image = image::open(path.as_ref())?; + + if direction == BottomLeft { + image = image.flipv(); + } + + let image = image.to_rgba8(); let height = image.height(); let width = image.width(); @@ -27,3 +38,4 @@ impl Image { use crate::Size; pub use image::ImageError; +use crate::image::UVDirection::BottomLeft; diff --git a/librashader-common/src/lib.rs b/librashader-common/src/lib.rs index b99386d..6222029 100644 --- a/librashader-common/src/lib.rs +++ b/librashader-common/src/lib.rs @@ -1,20 +1,25 @@ -#[cfg(feature = "d3d11")] -pub mod d3d11; +/// OpenGL common conversions. #[cfg(feature = "opengl")] pub mod gl; -pub mod image; -pub mod runtime; - +/// DXGI common conversions. #[cfg(feature = "dxgi")] pub mod dxgi; +/// Direct3D 11 common conversions. +#[cfg(feature = "d3d11")] +pub mod d3d11; + +/// Image handing helpers. +pub mod image; + use num_traits::AsPrimitive; use std::convert::Infallible; use std::str::FromStr; #[repr(u32)] #[derive(Default, Copy, Clone, Debug, Eq, PartialEq, Hash)] +/// Supported image formats for textures. pub enum ImageFormat { #[default] Unknown = 0, @@ -60,9 +65,13 @@ pub enum ImageFormat { #[repr(i32)] #[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Hash)] +/// The filtering mode for a texture sampler. pub enum FilterMode { #[default] + /// Linear filtering. Linear = 0, + + /// Nearest-neighbour (point) filtering. Nearest, } @@ -82,11 +91,16 @@ impl FromStr for WrapMode { #[repr(i32)] #[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Hash)] +/// The wrapping (address) mode for a texture sampler. pub enum WrapMode { #[default] + /// Clamp txture to border. ClampToBorder = 0, + /// Clamp texture to edge. ClampToEdge, + /// Repeat addressing mode. Repeat, + /// Mirrored repeat addressing mode. MirroredRepeat, } @@ -135,6 +149,7 @@ impl FromStr for ImageFormat { } } +/// A size with a width and height. #[derive(Default, Debug, Copy, Clone, PartialEq, Eq)] pub struct Size { pub width: T, @@ -142,6 +157,7 @@ pub struct Size { } impl Size { + /// Create a new `Size` with the given width and height. pub fn new(width: T, height: T) -> Self { Size { width, height } } @@ -151,6 +167,7 @@ impl From> for [f32; 4] where T: Copy + AsPrimitive, { + /// Convert a `Size` to a `vec4` uniform. fn from(value: Size) -> Self { [ value.width.as_(), diff --git a/librashader-common/src/runtime.rs b/librashader-common/src/runtime.rs deleted file mode 100644 index 8b13789..0000000 --- a/librashader-common/src/runtime.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/librashader-preprocess/src/error.rs b/librashader-preprocess/src/error.rs index 6ab20c1..bdaebe8 100644 --- a/librashader-preprocess/src/error.rs +++ b/librashader-preprocess/src/error.rs @@ -2,22 +2,31 @@ use std::convert::Infallible; use std::path::PathBuf; use thiserror::Error; +/// Error type for source preprocessing. #[derive(Error, Debug)] pub enum PreprocessError { + /// The version header was not found in the source file. #[error("the version header was missing")] MissingVersionHeader, + /// An IO error occurred when reading the source file. #[error("the file was not found during resolution")] IOError(PathBuf, std::io::Error), + /// Unexpected EOF when reading the source file. #[error("unexpected end of file")] UnexpectedEof, + /// Unexpected end of line when reading the source file. #[error("unexpected end of line")] UnexpectedEol(usize), + /// An error occurred when parsing a pragma statement. #[error("error parsing pragma")] PragmaParseError(String), + /// The given pragma was declared multiple times with differing values. #[error("duplicate pragma found")] DuplicatePragmaError(String), + /// The imaged format requested by the shader was unknown or not supported. #[error("shader format is unknown or not found")] - UnknownShaderFormat, + UnknownImageFormat, + /// The stage declared by the shader source was not `vertex` or `fragment`. #[error("stage must be either vertex or fragment")] InvalidStage, } diff --git a/librashader-preprocess/src/lib.rs b/librashader-preprocess/src/lib.rs index a58f725..b1ffa5d 100644 --- a/librashader-preprocess/src/lib.rs +++ b/librashader-preprocess/src/lib.rs @@ -8,26 +8,45 @@ pub use error::*; use librashader_common::ImageFormat; use std::path::Path; +/// The source file for a single shader pass. #[derive(Debug, Clone, PartialEq)] pub struct ShaderSource { + /// The source contents for the vertex shader. pub vertex: String, + + /// The source contents for the fragment shader. pub fragment: String, + + /// The alias of the shader if available. pub name: Option, + + /// The list of shader parameters found in the shader source. pub parameters: Vec, + + /// The image format the shader expects. pub format: ImageFormat, } +/// A user tweakable parameter for the shader as declared in source. #[derive(Debug, Clone, PartialEq)] pub struct ShaderParameter { + /// The name of the parameter. pub id: String, + /// The description of the parameter. pub description: String, + /// The initial value the parameter is set to. pub initial: f32, + /// The minimum value that the parameter can be set to. pub minimum: f32, + /// The maximum value that the parameter can be set to. pub maximum: f32, + /// The step by which this parameter can be incremented or decremented. pub step: f32, } impl ShaderSource { + /// Load the source file at the given path, resolving includes relative to the location of the + /// source file. pub fn load(path: impl AsRef) -> Result { load_shader_source(path) } diff --git a/librashader-preprocess/src/pragma.rs b/librashader-preprocess/src/pragma.rs index 6a5cd0e..322a4c5 100644 --- a/librashader-preprocess/src/pragma.rs +++ b/librashader-preprocess/src/pragma.rs @@ -96,7 +96,7 @@ pub(crate) fn parse_pragma_meta(source: impl AsRef) -> Result), } +/// The kind of error that may occur in parsing. #[derive(Debug)] pub enum ParseErrorKind { + /// Expected an indexed key (i.e. `shader0`, `shader1`, ...) Index(&'static str), + /// Expected a signed integer. Int, + /// Expected an unsigned integer. UnsignedInt, + /// Expected a float. Float, + /// Expected a boolean. Bool, } diff --git a/librashader-presets/src/preset.rs b/librashader-presets/src/preset.rs index b3d2261..a2209ee 100644 --- a/librashader-presets/src/preset.rs +++ b/librashader-presets/src/preset.rs @@ -4,16 +4,26 @@ use std::ops::Mul; use std::path::PathBuf; use std::str::FromStr; +/// The configuration for a single shader pass. #[derive(Debug, Clone)] pub struct ShaderPassConfig { + /// The index of the shader pass relative to its parent preset. pub id: i32, + /// The path to the shader pass source file. pub name: PathBuf, + /// The alias of the shader pass if available. pub alias: Option, + /// The filtering mode that this shader pass should expect. pub filter: FilterMode, + /// The texture addressing (wrap) mode that this shader pass expects. pub wrap_mode: WrapMode, + /// The number to which to wrap the frame count before passing it to the uniforms. pub frame_count_mod: u32, + /// Whether or not this shader pass expects an SRGB framebuffer output. pub srgb_framebuffer: bool, + /// Whether or not this shader pass expects an float framebuffer output. pub float_framebuffer: bool, + /// Whether or not to generate mipm pub mipmap_input: bool, pub scaling: Scale2D, } diff --git a/librashader-reflect/src/lib.rs b/librashader-reflect/src/lib.rs index ae951fb..6defb3b 100644 --- a/librashader-reflect/src/lib.rs +++ b/librashader-reflect/src/lib.rs @@ -1,6 +1,10 @@ #![feature(type_alias_impl_trait)] +/// Shader codegen backends. pub mod back; +/// Error types. pub mod error; +/// Shader frontend parsers. pub mod front; +/// Shader reflection. pub mod reflect; diff --git a/librashader-reflect/src/reflect/semantics.rs b/librashader-reflect/src/reflect/semantics.rs index dd11d8a..920538c 100644 --- a/librashader-reflect/src/reflect/semantics.rs +++ b/librashader-reflect/src/reflect/semantics.rs @@ -3,7 +3,6 @@ use bitflags::bitflags; use rustc_hash::FxHashMap; use std::str::FromStr; -pub const BASE_SEMANTICS_COUNT: usize = 5; pub const MAX_BINDINGS_COUNT: u32 = 16; pub const MAX_PUSH_BUFFER_SIZE: u32 = 128; diff --git a/librashader-runtime-d3d11/src/filter_chain.rs b/librashader-runtime-d3d11/src/filter_chain.rs index 4a1b239..efbb4e9 100644 --- a/librashader-runtime-d3d11/src/filter_chain.rs +++ b/librashader-runtime-d3d11/src/filter_chain.rs @@ -1,5 +1,5 @@ use crate::texture::{DxImageView, LutTexture, Texture}; -use librashader_common::image::Image; +use librashader_common::image::{Image, UVDirection}; use librashader_common::{ImageFormat, Size}; use librashader_preprocess::ShaderSource; use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig}; @@ -123,6 +123,7 @@ impl FilterChain { OwnedFramebuffer::new( device, Size::new(1, 1), + 0, ImageFormat::R8G8B8A8Unorm, ) }); @@ -141,6 +142,7 @@ impl FilterChain { OwnedFramebuffer::new( device, Size::new(1, 1), + 1, ImageFormat::R8G8B8A8Unorm, ) }); @@ -349,7 +351,7 @@ impl FilterChain { eprintln!("[history] using frame history with {required_images} images"); let mut framebuffers = VecDeque::with_capacity(required_images); framebuffers.resize_with(required_images, || { - OwnedFramebuffer::new(device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm) + OwnedFramebuffer::new(device, Size::new(1, 1), 1, ImageFormat::R8G8B8A8Unorm) }); let framebuffers = framebuffers @@ -379,7 +381,7 @@ impl FilterChain { let mut luts = FxHashMap::default(); for (index, texture) in textures.iter().enumerate() { - let image = Image::load(&texture.path)?; + let image = Image::load(&texture.path, UVDirection::TopLeft)?; let desc = D3D11_TEXTURE2D_DESC { Width: image.size.width, Height: image.size.height, @@ -459,6 +461,7 @@ impl FilterChain { Ok((passes, semantics)) } + /// Process a frame with the input image. pub fn frame( &mut self, input: DxImageView, @@ -544,6 +547,7 @@ impl FilterChain { self.common.output_textures[index] = Some(source.clone()); } + // try to hint the optimizer assert_eq!(last.len(), 1); for pass in last { source.filter = pass.config.filter; @@ -590,3 +594,14 @@ impl FilterChain { Ok(()) } } + +impl librashader_runtime::filter_chain::FilterChain for FilterChain { + type Error = FilterChainError; + type Input<'a> = DxImageView; + type Viewport<'a> = Viewport<'a>; + type FrameOptions = FrameOptions; + + fn frame<'a>(&mut self, input: Self::Input<'a>, viewport: &Self::Viewport<'a>, frame_count: usize, options: Option<&Self::FrameOptions>) -> Result<(), Self::Error> { + self.frame(input, viewport, frame_count, options) + } +} \ No newline at end of file diff --git a/librashader-runtime-d3d11/src/filter_pass.rs b/librashader-runtime-d3d11/src/filter_pass.rs index 6c9bfcf..fb1cb6c 100644 --- a/librashader-runtime-d3d11/src/filter_pass.rs +++ b/librashader-runtime-d3d11/src/filter_pass.rs @@ -20,7 +20,7 @@ use crate::error; use crate::render_target::RenderTarget; use crate::samplers::SamplerSet; use crate::viewport::Viewport; -use librashader_runtime::uniforms::UniformStorage; +use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess}; pub struct ConstantBufferBinding { pub binding: u32, @@ -379,7 +379,7 @@ impl FilterPass { unsafe { let map = context.Map(&ubo.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0)?; std::ptr::copy_nonoverlapping( - self.uniform_storage.ubo.as_ptr(), + self.uniform_storage.ubo_pointer(), map.pData.cast(), ubo.size as usize, ); @@ -403,7 +403,7 @@ impl FilterPass { unsafe { let map = context.Map(&push.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0)?; std::ptr::copy_nonoverlapping( - self.uniform_storage.push.as_ptr(), + self.uniform_storage.push_pointer(), map.pData.cast(), push.size as usize, ); diff --git a/librashader-runtime-d3d11/src/framebuffer.rs b/librashader-runtime-d3d11/src/framebuffer.rs index bccab22..1a139cf 100644 --- a/librashader-runtime-d3d11/src/framebuffer.rs +++ b/librashader-runtime-d3d11/src/framebuffer.rs @@ -21,6 +21,7 @@ pub(crate) struct OwnedFramebuffer { pub texture: ID3D11Texture2D, pub size: Size, pub format: DXGI_FORMAT, + pub max_levels: u32, device: ID3D11Device, is_raw: bool, } @@ -29,6 +30,7 @@ impl OwnedFramebuffer { pub fn new( device: &ID3D11Device, size: Size, + mip_levels: u32, format: ImageFormat, ) -> error::Result { unsafe { @@ -39,7 +41,7 @@ impl OwnedFramebuffer { | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0 | D3D11_FORMAT_SUPPORT_RENDER_TARGET.0, ); - let desc = default_desc(size, format); + let desc = default_desc(size, format, mip_levels); let texture = device.CreateTexture2D(&desc, None)?; Ok(OwnedFramebuffer { @@ -47,18 +49,20 @@ impl OwnedFramebuffer { size, format, device: device.clone(), + max_levels: mip_levels, is_raw: false, }) } } + pub(crate) fn scale( &mut self, scaling: Scale2D, format: ImageFormat, viewport_size: &Size, _original: &Texture, - source: &Texture, + source: &Texture ) -> error::Result> { if self.is_raw { return Ok(self.size); @@ -94,7 +98,7 @@ impl OwnedFramebuffer { | D3D11_FORMAT_SUPPORT_RENDER_TARGET.0, ); - let desc = default_desc(size, format); + let desc = default_desc(size, format, self.max_levels); unsafe { let mut texture = self.device.CreateTexture2D(&desc, None)?; std::mem::swap(&mut self.texture, &mut texture); @@ -179,11 +183,11 @@ pub(crate) struct OutputFramebuffer { pub viewport: D3D11_VIEWPORT, } -fn default_desc(size: Size, format: DXGI_FORMAT) -> D3D11_TEXTURE2D_DESC { +fn default_desc(size: Size, format: DXGI_FORMAT, mip_levels: u32) -> D3D11_TEXTURE2D_DESC { D3D11_TEXTURE2D_DESC { Width: size.width, Height: size.height, - MipLevels: 1, + MipLevels: mip_levels, ArraySize: 1, Format: format, SampleDesc: DXGI_SAMPLE_DESC { diff --git a/librashader-runtime-d3d11/src/hello_triangle.rs b/librashader-runtime-d3d11/src/hello_triangle.rs index 129883f..cce7c1c 100644 --- a/librashader-runtime-d3d11/src/hello_triangle.rs +++ b/librashader-runtime-d3d11/src/hello_triangle.rs @@ -221,6 +221,7 @@ struct TriangleUniforms { } pub mod d3d11_hello_triangle { + use super::*; use std::path::Path; diff --git a/librashader-runtime-d3d11/src/lib.rs b/librashader-runtime-d3d11/src/lib.rs index 0b2e92a..a27ff33 100644 --- a/librashader-runtime-d3d11/src/lib.rs +++ b/librashader-runtime-d3d11/src/lib.rs @@ -15,6 +15,7 @@ mod samplers; mod texture; mod util; mod viewport; +mod parameters; pub use filter_chain::FilterChain; pub use viewport::Viewport; @@ -28,7 +29,7 @@ mod tests { #[test] fn triangle_d3d11() { let sample = hello_triangle::d3d11_hello_triangle::Sample::new( - "../test/slang-shaders/crt/crt-royale.slangp", + "../test/slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp", None, ) .unwrap(); diff --git a/librashader-runtime-d3d11/src/parameters.rs b/librashader-runtime-d3d11/src/parameters.rs new file mode 100644 index 0000000..2d5edf7 --- /dev/null +++ b/librashader-runtime-d3d11/src/parameters.rs @@ -0,0 +1,31 @@ +use std::collections::hash_map::Iter; +use librashader_runtime::parameters::FilterChainParameters; +use crate::FilterChain; + +impl FilterChainParameters for FilterChain { + fn get_enabled_pass_count(&self) -> usize { + self.common.config.passes_enabled + } + + fn set_enabled_pass_count(&mut self, count: usize) { + self.common.config.passes_enabled = count + } + + fn enumerate_parameters(&self) -> Iter { + self.common.config.parameters.iter() + } + + fn get_parameter(&self, parameter: &str) -> Option { + self.common.config.parameters.get::(parameter.as_ref()).map(|f| *f) + } + + fn set_parameter(&mut self, parameter: &str, new_value: f32) -> Option { + if let Some(value) = self.common.config.parameters.get_mut::(parameter.as_ref()) { + let old = *value; + *value = new_value; + Some(old) + } else { + None + } + } +} \ No newline at end of file diff --git a/librashader-runtime-gl/src/filter_chain.rs b/librashader-runtime-gl/src/filter_chain/filter_impl.rs similarity index 87% rename from librashader-runtime-gl/src/filter_chain.rs rename to librashader-runtime-gl/src/filter_chain/filter_impl.rs index 1eb60bd..a55f7e3 100644 --- a/librashader-runtime-gl/src/filter_chain.rs +++ b/librashader-runtime-gl/src/filter_chain/filter_impl.rs @@ -1,95 +1,31 @@ -use crate::binding::{UniformLocation, VariableLocation}; -use crate::error::{FilterChainError, Result}; -use crate::filter_pass::FilterPass; -use crate::framebuffer::GLImage; -use crate::render_target::RenderTarget; -use crate::util; -use crate::util::{gl_get_version, gl_u16_to_version}; - +use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig}; +use librashader_reflect::reflect::semantics::{MemberOffset, ReflectSemantics, SemanticMap, TextureSemantics, UniformBinding, UniformMeta, UniformSemantic, VariableSemantics}; +use rustc_hash::FxHashMap; +use librashader_preprocess::ShaderSource; +use librashader_reflect::back::{CompilerBackend, CompileShader, FromCompilation}; +use librashader_reflect::back::cross::{GlslangGlslContext, GlVersion}; +use librashader_reflect::back::targets::GLSL; +use librashader_reflect::front::shaderc::GlslangCompilation; +use spirv_cross::spirv::Decoration; use gl::types::{GLint, GLuint}; - -use crate::binding::BufferStorage; +use librashader_common::{FilterMode, WrapMode}; +use std::collections::VecDeque; +use librashader_reflect::reflect::ReflectShader; +use crate::{error, GLImage, util, Viewport}; +use crate::binding::{BufferStorage, UniformLocation, VariableLocation}; +use crate::error::FilterChainError; +use crate::filter_pass::FilterPass; use crate::gl::{DrawQuad, Framebuffer, FramebufferInterface, GLInterface, LoadLut, UboRing}; use crate::options::{FilterChainOptions, FrameOptions}; +use crate::render_target::RenderTarget; use crate::samplers::SamplerSet; use crate::texture::Texture; -use crate::viewport::Viewport; -use librashader_common::{FilterMode, WrapMode}; -use librashader_preprocess::ShaderSource; -use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig}; -use librashader_reflect::back::cross::{GlVersion, GlslangGlslContext}; -use librashader_reflect::back::targets::GLSL; -use librashader_reflect::back::{CompileShader, CompilerBackend, FromCompilation}; -use librashader_reflect::front::shaderc::GlslangCompilation; -use librashader_reflect::reflect::semantics::{ - MemberOffset, ReflectSemantics, SemanticMap, TextureSemantics, UniformBinding, UniformMeta, - UniformSemantic, VariableSemantics, -}; -use librashader_reflect::reflect::ReflectShader; -use rustc_hash::FxHashMap; -use spirv_cross::spirv::Decoration; -use std::collections::VecDeque; -use std::path::Path; +use crate::util::{gl_get_version, gl_u16_to_version}; -pub struct FilterChain { - filter: FilterChainInner, -} - -impl FilterChain { - pub fn load_from_preset( - preset: ShaderPreset, - options: Option<&FilterChainOptions>, - ) -> Result { - if let Some(options) = options && options.use_dsa { - return Ok(Self { - filter: FilterChainInner::DirectStateAccess(FilterChainImpl::load_from_preset(preset, Some(options))?) - }) - } - Ok(Self { - filter: FilterChainInner::Compatibility(FilterChainImpl::load_from_preset( - preset, options, - )?), - }) - } - - /// Load the shader preset at the given path into a filter chain. - pub fn load_from_path( - path: impl AsRef, - options: Option<&FilterChainOptions>, - ) -> Result { - // load passes from preset - let preset = ShaderPreset::try_parse(path)?; - Self::load_from_preset(preset, options) - } - - /// Process a frame with the input image. - /// - /// When this frame returns, GL_FRAMEBUFFER is bound to 0. - pub fn frame( - &mut self, - input: &GLImage, - viewport: &Viewport, - frame_count: usize, - options: Option<&FrameOptions>, - ) -> Result<()> { - match &mut self.filter { - FilterChainInner::DirectStateAccess(p) => { - p.frame(frame_count, viewport, input, options) - } - FilterChainInner::Compatibility(p) => p.frame(frame_count, viewport, input, options), - } - } -} - -enum FilterChainInner { - DirectStateAccess(FilterChainImpl), - Compatibility(FilterChainImpl), -} - -struct FilterChainImpl { +pub(crate) struct FilterChainImpl { + pub(crate) common: FilterCommon, passes: Box<[FilterPass]>, - common: FilterCommon, - pub(crate) draw_quad: T::DrawQuad, + draw_quad: T::DrawQuad, output_framebuffers: Box<[Framebuffer]>, feedback_framebuffers: Box<[Framebuffer]>, history_framebuffers: VecDeque, @@ -152,7 +88,7 @@ impl FilterChainImpl { pub(crate) fn load_from_preset( preset: ShaderPreset, options: Option<&FilterChainOptions>, - ) -> Result { + ) -> error::Result { let (passes, semantics) = Self::load_preset(preset.shaders, &preset.textures)?; let version = options @@ -218,7 +154,7 @@ impl FilterChainImpl { fn load_preset( passes: Vec, textures: &[TextureConfig], - ) -> Result<(Vec, ReflectSemantics)> { + ) -> error::Result<(Vec, ReflectSemantics)> { let mut uniform_semantics: FxHashMap = Default::default(); let mut texture_semantics: FxHashMap> = Default::default(); @@ -244,7 +180,7 @@ impl FilterChainImpl { Ok::<_, FilterChainError>((shader, source, reflect)) }) .into_iter() - .collect::)>>>()?; + .collect::)>>>()?; for details in &passes { librashader_runtime::semantics::insert_pass_semantics( @@ -272,7 +208,7 @@ impl FilterChainImpl { version: GlVersion, passes: Vec, semantics: &ReflectSemantics, - ) -> Result]>> { + ) -> error::Result]>> { let mut filters = Vec::new(); // initialize passes @@ -456,7 +392,7 @@ impl FilterChainImpl { (framebuffers, history_textures.into_boxed_slice()) } - fn push_history(&mut self, input: &GLImage) -> Result<()> { + fn push_history(&mut self, input: &GLImage) -> error::Result<()> { if let Some(mut back) = self.history_framebuffers.pop_back() { if back.size != input.size || (input.format != 0 && input.format != back.format) { eprintln!("[history] resizing"); @@ -480,7 +416,7 @@ impl FilterChainImpl { viewport: &Viewport, input: &GLImage, options: Option<&FrameOptions>, - ) -> Result<()> { + ) -> error::Result<()> { // limit number of passes to those enabled. let passes = &mut self.passes[0..self.common.config.passes_enabled]; if let Some(options) = options { @@ -579,6 +515,7 @@ impl FilterChainImpl { source = target; } + // try to hint the optimizer assert_eq!(last.len(), 1); for pass in last { source.filter = pass.config.filter; diff --git a/librashader-runtime-gl/src/filter_chain/inner.rs b/librashader-runtime-gl/src/filter_chain/inner.rs new file mode 100644 index 0000000..84394ca --- /dev/null +++ b/librashader-runtime-gl/src/filter_chain/inner.rs @@ -0,0 +1,6 @@ +use crate::filter_chain::filter_impl::FilterChainImpl; + +pub(in crate::filter_chain) enum FilterChainDispatch { + DirectStateAccess(FilterChainImpl), + Compatibility(FilterChainImpl), +} diff --git a/librashader-runtime-gl/src/filter_chain/mod.rs b/librashader-runtime-gl/src/filter_chain/mod.rs new file mode 100644 index 0000000..ed00c87 --- /dev/null +++ b/librashader-runtime-gl/src/filter_chain/mod.rs @@ -0,0 +1,82 @@ +use std::path::Path; + +use librashader_presets::ShaderPreset; +use crate::filter_chain::filter_impl::FilterChainImpl; +use crate::filter_chain::inner::FilterChainDispatch; +use crate::{GLImage, Viewport}; +use crate::error::{Result, FilterChainError}; +use crate::options::{FilterChainOptions, FrameOptions}; + +mod filter_impl; +mod inner; +mod parameters; + +pub(crate) use filter_impl::FilterCommon; + +pub struct FilterChain { + pub(in crate::filter_chain) filter: FilterChainDispatch, +} + +impl FilterChain { + pub fn load_from_preset( + preset: ShaderPreset, + options: Option<&FilterChainOptions>, + ) -> Result { + if let Some(options) = options && options.use_dsa { + return Ok(Self { + filter: FilterChainDispatch::DirectStateAccess(FilterChainImpl::load_from_preset(preset, Some(options))?) + }) + } + Ok(Self { + filter: FilterChainDispatch::Compatibility(FilterChainImpl::load_from_preset( + preset, options, + )?), + }) + } + + /// Load the shader preset at the given path into a filter chain. + pub fn load_from_path( + path: impl AsRef, + options: Option<&FilterChainOptions>, + ) -> Result { + // load passes from preset + let preset = ShaderPreset::try_parse(path)?; + Self::load_from_preset(preset, options) + } + + /// Process a frame with the input image. + /// + /// When this frame returns, GL_FRAMEBUFFER is bound to 0 if not using Direct State Access. + pub(crate) fn frame( + &mut self, + input: &GLImage, + viewport: &Viewport, + frame_count: usize, + options: Option<&FrameOptions>, + ) -> Result<()> { + match &mut self.filter { + FilterChainDispatch::DirectStateAccess(p) => { + p.frame(frame_count, viewport, input, options) + } + FilterChainDispatch::Compatibility(p) => p.frame(frame_count, viewport, input, options), + } + } +} + +impl librashader_runtime::filter_chain::FilterChain for FilterChain { + type Error = FilterChainError; + type Input<'a> = &'a GLImage; + type Viewport<'a> = Viewport<'a>; + type FrameOptions = FrameOptions; + + fn frame<'a>( + &mut self, + input: Self::Input<'a>, + viewport: &Self::Viewport<'a>, + frame_count: usize, + options: Option<&Self::FrameOptions>, + ) -> std::result::Result<(), Self::Error> { + self.frame(input, viewport, frame_count, options) + } +} + diff --git a/librashader-runtime-gl/src/filter_chain/parameters.rs b/librashader-runtime-gl/src/filter_chain/parameters.rs new file mode 100644 index 0000000..738feb7 --- /dev/null +++ b/librashader-runtime-gl/src/filter_chain/parameters.rs @@ -0,0 +1,74 @@ +use std::collections::hash_map::Iter; +use librashader_runtime::parameters::FilterChainParameters; +use crate::filter_chain::filter_impl::FilterChainImpl; +use crate::filter_chain::inner::FilterChainDispatch; +use crate::FilterChain; +use crate::gl::GLInterface; + +impl AsRef for FilterChainDispatch { + fn as_ref<'a>(&'a self) -> &'a (dyn FilterChainParameters + 'static) { + match self { + FilterChainDispatch::DirectStateAccess(p) => p, + FilterChainDispatch::Compatibility(p) => p, + } + } +} + +impl AsMut for FilterChainDispatch { + fn as_mut<'a>(&'a mut self) -> &'a mut (dyn FilterChainParameters + 'static) { + match self { + FilterChainDispatch::DirectStateAccess(p) => p, + FilterChainDispatch::Compatibility(p) => p, + } + } +} + +impl FilterChainParameters for FilterChain { + fn get_enabled_pass_count(&self) -> usize { + self.filter.as_ref().get_enabled_pass_count() + } + + fn set_enabled_pass_count(&mut self, count: usize) { + self.filter.as_mut().set_enabled_pass_count(count) + } + + fn enumerate_parameters(&self) -> Iter { + self.filter.as_ref().enumerate_parameters() + } + + fn get_parameter(&self, parameter: &str) -> Option { + self.filter.as_ref().get_parameter(parameter) + } + + fn set_parameter(&mut self, parameter: &str, new_value: f32) -> Option { + self.filter.as_mut().set_parameter(parameter, new_value) + } +} + +impl FilterChainParameters for FilterChainImpl { + fn get_enabled_pass_count(&self) -> usize { + self.common.config.passes_enabled + } + + fn set_enabled_pass_count(&mut self, count: usize) { + self.common.config.passes_enabled = count + } + + fn enumerate_parameters(&self) -> Iter { + self.common.config.parameters.iter() + } + + fn get_parameter(&self, parameter: &str) -> Option { + self.common.config.parameters.get::(parameter.as_ref()).map(|f| *f) + } + + fn set_parameter(&mut self, parameter: &str, new_value: f32) -> Option { + if let Some(value) = self.common.config.parameters.get_mut::(parameter.as_ref()) { + let old = *value; + *value = new_value; + Some(old) + } else { + None + } + } +} \ No newline at end of file diff --git a/librashader-runtime-gl/src/filter_pass.rs b/librashader-runtime-gl/src/filter_pass.rs index a981b90..4477d53 100644 --- a/librashader-runtime-gl/src/filter_pass.rs +++ b/librashader-runtime-gl/src/filter_pass.rs @@ -13,7 +13,7 @@ use rustc_hash::FxHashMap; use crate::binding::{BufferStorage, UniformLocation, VariableLocation}; use crate::filter_chain::FilterCommon; -use crate::gl::{BindTexture, FramebufferInterface, GLInterface, UboRing}; +use crate::gl::{BindTexture, GLInterface, UboRing}; use crate::render_target::RenderTarget; use crate::viewport::Viewport; diff --git a/librashader-runtime-gl/src/gl/gl3/draw_quad.rs b/librashader-runtime-gl/src/gl/gl3/draw_quad.rs index 28db030..61ae562 100644 --- a/librashader-runtime-gl/src/gl/gl3/draw_quad.rs +++ b/librashader-runtime-gl/src/gl/gl3/draw_quad.rs @@ -74,3 +74,17 @@ impl DrawQuad for Gl3DrawQuad { } } } + +impl Drop for Gl3DrawQuad { + fn drop(&mut self) { + unsafe { + if self.vbo != 0 { + gl::DeleteBuffers(1, &self.vbo); + } + + if self.vao != 0 { + gl::DeleteVertexArrays(1, &self.vao) + } + } + } +} diff --git a/librashader-runtime-gl/src/gl/gl3/lut_load.rs b/librashader-runtime-gl/src/gl/gl3/lut_load.rs index 226dbba..f18bd41 100644 --- a/librashader-runtime-gl/src/gl/gl3/lut_load.rs +++ b/librashader-runtime-gl/src/gl/gl3/lut_load.rs @@ -3,7 +3,7 @@ use crate::framebuffer::GLImage; use crate::gl::LoadLut; use crate::texture::Texture; use gl::types::{GLsizei, GLuint}; -use librashader_common::image::Image; +use librashader_common::image::{Image, UVDirection}; use librashader_common::Size; use librashader_presets::TextureConfig; use rustc_hash::FxHashMap; @@ -19,7 +19,7 @@ impl LoadLut for Gl3LutLoad { }; for (index, texture) in textures.iter().enumerate() { - let image = Image::load(&texture.path)?; + let image = Image::load(&texture.path, UVDirection::BottomLeft)?; let levels = if texture.mipmap { librashader_runtime::scaling::calc_miplevel(image.size) } else { diff --git a/librashader-runtime-gl/src/gl/gl46/draw_quad.rs b/librashader-runtime-gl/src/gl/gl46/draw_quad.rs index a35eb4a..8f6f1b2 100644 --- a/librashader-runtime-gl/src/gl/gl46/draw_quad.rs +++ b/librashader-runtime-gl/src/gl/gl46/draw_quad.rs @@ -63,3 +63,17 @@ impl DrawQuad for Gl46DrawQuad { } } } + +impl Drop for Gl46DrawQuad { + fn drop(&mut self) { + unsafe { + if self.vbo != 0 { + gl::DeleteBuffers(1, &self.vbo); + } + + if self.vao != 0 { + gl::DeleteVertexArrays(1, &self.vao) + } + } + } +} \ No newline at end of file diff --git a/librashader-runtime-gl/src/gl/gl46/lut_load.rs b/librashader-runtime-gl/src/gl/gl46/lut_load.rs index 10b3677..2f65076 100644 --- a/librashader-runtime-gl/src/gl/gl46/lut_load.rs +++ b/librashader-runtime-gl/src/gl/gl46/lut_load.rs @@ -3,7 +3,7 @@ use crate::framebuffer::GLImage; use crate::gl::LoadLut; use crate::texture::Texture; use gl::types::{GLsizei, GLuint}; -use librashader_common::image::Image; +use librashader_common::image::{Image, UVDirection}; use librashader_common::Size; use librashader_presets::TextureConfig; use rustc_hash::FxHashMap; @@ -23,7 +23,7 @@ impl LoadLut for Gl46LutLoad { } for (index, texture) in textures.iter().enumerate() { - let image = Image::load(&texture.path)?; + let image = Image::load(&texture.path, UVDirection::BottomLeft)?; let levels = if texture.mipmap { librashader_runtime::scaling::calc_miplevel(image.size) } else { diff --git a/librashader-runtime-gl/src/lib.rs b/librashader-runtime-gl/src/lib.rs index 8d16698..99745ef 100644 --- a/librashader-runtime-gl/src/lib.rs +++ b/librashader-runtime-gl/src/lib.rs @@ -31,7 +31,7 @@ mod tests { fn triangle_gl() { let (glfw, window, events, shader, vao) = gl::gl3::hello_triangle::setup(); let mut filter = FilterChain::load_from_path( - "../test/slang-shaders/vhs/VHSPro.slangp", + "../test/slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp", Some(&FilterChainOptions { gl_version: 0, use_dsa: false, diff --git a/librashader-runtime-gl/src/render_target.rs b/librashader-runtime-gl/src/render_target.rs index 6bcba2f..727b812 100644 --- a/librashader-runtime-gl/src/render_target.rs +++ b/librashader-runtime-gl/src/render_target.rs @@ -1,4 +1,4 @@ -use crate::gl::{Framebuffer, FramebufferInterface}; +use crate::gl::Framebuffer; use crate::viewport::Viewport; #[rustfmt::skip] diff --git a/librashader-runtime/src/filter_chain.rs b/librashader-runtime/src/filter_chain.rs new file mode 100644 index 0000000..b9dd2fe --- /dev/null +++ b/librashader-runtime/src/filter_chain.rs @@ -0,0 +1,30 @@ +use std::error::Error; + +/// Common trait for filter chains. +pub trait FilterChain { + /// The error type for a filter chain. + type Error: Error; + + /// The type for the input surface to apply a filter chain to. + type Input<'a>; + + /// The type for the output surface, including viewport information, to output the result of a + /// filter chain to. + type Viewport<'a>; + + /// The per-frame options to pass to the filter chain. + type FrameOptions; + + /// Process a frame with the input image. + /// + /// The output image should be written to the viewport. It is expected that the viewport + /// contains some sort of handle with interior mutability to a GPU buffer, e.g. a + /// `RenderTargetView`, `vkImage`, or a texture `GLuint`. + fn frame<'a>( + &mut self, + input: Self::Input<'a>, + viewport: &Self::Viewport<'a>, + frame_count: usize, + options: Option<&Self::FrameOptions>, + ) -> Result<(), Self::Error>; +} \ No newline at end of file diff --git a/librashader-runtime/src/lib.rs b/librashader-runtime/src/lib.rs index 83e5273..8bd48ff 100644 --- a/librashader-runtime/src/lib.rs +++ b/librashader-runtime/src/lib.rs @@ -1,3 +1,16 @@ +//! Helpers and shared logic for librashader runtime implementations. + +/// Scaling helpers. pub mod scaling; + +/// Semantics helpers. pub mod semantics; + +/// Uniform binding helpers. pub mod uniforms; + +/// Parameter reflection helpers and traits. +pub mod parameters; + +/// Filter chain helpers and traits. +pub mod filter_chain; diff --git a/librashader-runtime/src/parameters.rs b/librashader-runtime/src/parameters.rs new file mode 100644 index 0000000..661c699 --- /dev/null +++ b/librashader-runtime/src/parameters.rs @@ -0,0 +1,19 @@ +/// Trait for filter chains that allow runtime reflection of shader parameters. +pub trait FilterChainParameters { + /// Gets the number of shader passes enabled at runtime. + fn get_enabled_pass_count(&self) -> usize; + + /// Sets the number of shader passes enabled at runtime. + fn set_enabled_pass_count(&mut self, count: usize); + + /// Enumerates the active parameters as well as their values in the current filter chain. + fn enumerate_parameters(&self) -> std::collections::hash_map::Iter; + + /// Get the value of the given parameter if present. + fn get_parameter(&self, parameter: &str) -> Option; + + /// Set the value of the given parameter if present. + /// + /// Returns `None` if the parameter did not exist, or the old value if successful. + fn set_parameter(&mut self, parameter: &str, new_value: f32) -> Option; +} \ No newline at end of file diff --git a/librashader-runtime/src/scaling.rs b/librashader-runtime/src/scaling.rs index 9e6cc02..5ed6a91 100644 --- a/librashader-runtime/src/scaling.rs +++ b/librashader-runtime/src/scaling.rs @@ -3,42 +3,40 @@ use librashader_presets::{Scale2D, ScaleFactor, ScaleType, Scaling}; use num_traits::AsPrimitive; use std::ops::Mul; +/// Produce a `Size` scaled with the input scaling options. pub fn scale(scaling: Scale2D, source: Size, viewport: Size) -> Size where T: Mul + Copy + 'static, f32: AsPrimitive, { - let width: f32; - let height: f32; - - match scaling.x { + let width = match scaling.x { Scaling { scale_type: ScaleType::Input, factor, - } => width = source.width * factor, + } => source.width * factor, Scaling { scale_type: ScaleType::Absolute, factor, - } => width = factor.into(), + } => factor.into(), Scaling { scale_type: ScaleType::Viewport, factor, - } => width = viewport.width * factor, + } => viewport.width * factor, }; - match scaling.y { + let height = match scaling.y { Scaling { scale_type: ScaleType::Input, factor, - } => height = source.height * factor, + } => source.height * factor, Scaling { scale_type: ScaleType::Absolute, factor, - } => height = factor.into(), + } => factor.into(), Scaling { scale_type: ScaleType::Viewport, factor, - } => height = viewport.height * factor, + } => viewport.height * factor, }; Size { @@ -47,6 +45,7 @@ where } } +/// Calculate the number of mipmap levels for a given size. pub fn calc_miplevel(size: Size) -> u32 { let mut size = std::cmp::max(size.width, size.height); let mut levels = 0; diff --git a/librashader-runtime/src/semantics.rs b/librashader-runtime/src/semantics.rs index ecae41f..e126bd3 100644 --- a/librashader-runtime/src/semantics.rs +++ b/librashader-runtime/src/semantics.rs @@ -2,9 +2,13 @@ use librashader_presets::{ShaderPassConfig, TextureConfig}; use librashader_reflect::reflect::semantics::{SemanticMap, TextureSemantics, UniformSemantic}; use rustc_hash::FxHashMap; +/// A map for variable names and uniform semantics pub type UniformSemanticsMap = FxHashMap; + +/// A map for sampler names and texture semantics. pub type TextureSemanticsMap = FxHashMap>; +/// Insert the available semantics for the input pass config into the provided semantic maps. pub fn insert_pass_semantics( uniform_semantics: &mut UniformSemanticsMap, texture_semantics: &mut TextureSemanticsMap, @@ -54,6 +58,7 @@ pub fn insert_pass_semantics( ); } +/// /// Insert the available semantics for the input texture config into the provided semantic maps. pub fn insert_lut_semantics( textures: &[TextureConfig], uniform_semantics: &mut UniformSemanticsMap, diff --git a/librashader-runtime/src/uniforms.rs b/librashader-runtime/src/uniforms.rs index e6db3d6..e6fe458 100644 --- a/librashader-runtime/src/uniforms.rs +++ b/librashader-runtime/src/uniforms.rs @@ -1,24 +1,30 @@ use librashader_reflect::reflect::semantics::MemberOffset; use std::marker::PhantomData; +/// A scalar value that is valid as a uniform member pub trait UniformScalar: Copy + bytemuck::Pod {} impl UniformScalar for f32 {} impl UniformScalar for i32 {} impl UniformScalar for u32 {} -pub struct NoUniformBinder; -impl BindUniform, T> for NoUniformBinder { - fn bind_uniform(_: T, _: Option<()>) -> Option<()> { - None - } -} - +/// A trait for a binder that binds the given value and context into the uniform for a shader pass. pub trait BindUniform { + /// Bind the given value to the shader uniforms given the input context. + /// + /// A `BindUniform` implementation should not write to a backing buffer from a [`UniformStorage`](crate::uniforms::UniformStorage). + /// If the binding is successful and no writes to a backing buffer is necessary, this function should return `Some(())`. + /// If this function returns `None`, then the value will instead be written to the backing buffer. fn bind_uniform(value: T, ctx: C) -> Option<()>; } +/// A trait to access the raw pointer to a backing uniform storage. pub trait UniformStorageAccess { + /// Get a pointer to the backing UBO storage. This pointer must be valid for the lifetime + /// of the implementing struct. fn ubo_pointer(&self) -> *const u8; + + /// Get a pointer to the backing Push Constant buffer storage. + /// This pointer must be valid for the lifetime of the implementing struct. fn push_pointer(&self) -> *const u8; } @@ -32,9 +38,19 @@ impl UniformStorageAccess for UniformStorage { } } +/// A uniform binder that always returns `None`, and does not do any binding of uniforms. +/// All uniform data is thus written into the backing buffer storage. +pub struct NoUniformBinder; +impl BindUniform, T> for NoUniformBinder { + fn bind_uniform(_: T, _: Option<()>) -> Option<()> { + None + } +} + +/// A helper to bind uniform variables to UBO or Push Constant Buffers. pub struct UniformStorage> { - pub ubo: Box<[u8]>, - pub push: Box<[u8]>, + ubo: Box<[u8]>, + push: Box<[u8]>, _h: PhantomData, _c: PhantomData, } @@ -47,6 +63,8 @@ where H: for<'a> BindUniform, H: for<'a> BindUniform, { + + /// Create a new `UniformStorage` with the given size for UBO and Push Constant Buffer sizes. pub fn new(ubo_size: usize, push_size: usize) -> Self { UniformStorage { ubo: vec![0u8; ubo_size].into_boxed_slice(), @@ -67,6 +85,7 @@ where }; } + #[inline(always)] fn write_mat4_inner(buffer: &mut [u8], mat4: &[f32; 16], ctx: C) { if H::bind_uniform(mat4, ctx).is_none() { let mat4 = bytemuck::cast_slice(mat4); @@ -74,6 +93,7 @@ where } } + #[inline(always)] fn write_vec4_inner(buffer: &mut [u8], vec4: impl Into<[f32; 4]>, ctx: C) { let vec4 = vec4.into(); if H::bind_uniform(&vec4, ctx).is_none() { @@ -82,6 +102,7 @@ where } } + /// Bind a `mat4` to the given offset. pub fn bind_mat4(&mut self, offset: MemberOffset, value: &[f32; 16], ctx: C) { let (buffer, offset) = match offset { MemberOffset::Ubo(offset) => (&mut self.ubo, offset), @@ -94,6 +115,7 @@ where ); } + /// Bind a `vec4` to the given offset. pub fn bind_vec4(&mut self, offset: MemberOffset, value: impl Into<[f32; 4]>, ctx: C) { let (buffer, offset) = match offset { MemberOffset::Ubo(offset) => (&mut self.ubo, offset), @@ -107,6 +129,7 @@ where ); } + /// Bind a scalar to the given offset. pub fn bind_scalar(&mut self, offset: MemberOffset, value: T, ctx: C) where H: BindUniform, diff --git a/librashader/Cargo.toml b/librashader/Cargo.toml index 35b5afc..cdc8b01 100644 --- a/librashader/Cargo.toml +++ b/librashader/Cargo.toml @@ -9,6 +9,7 @@ librashader-common = { path = "../librashader-common" } librashader-presets = { path = "../librashader-presets" } librashader-preprocess = { path = "../librashader-preprocess" } librashader-reflect = { path = "../librashader-reflect" } +librashader-runtime = { path = "../librashader-runtime" } librashader-runtime-d3d11 = { path = "../librashader-runtime-d3d11" } librashader-runtime-gl = { path = "../librashader-runtime-gl" } diff --git a/librashader/src/lib.rs b/librashader/src/lib.rs index 136e0e5..7986546 100644 --- a/librashader/src/lib.rs +++ b/librashader/src/lib.rs @@ -1,68 +1,17 @@ //! Re-exports for usage of librashader in consuming libraries. //! //! Runtime implementations should depend directly on constituent crates. + + +/// Parsing and usage of shader presets. +/// +/// Shader presets contain shader and texture parameters, and the order in which to apply a set of shaders +/// in a filter chain. pub mod presets { pub use librashader_presets::*; -} - -pub mod preprocess { - pub use librashader_preprocess::*; -} - -pub mod reflect { - pub use librashader_reflect::error::*; - - pub use librashader_reflect::reflect::{ - semantics, ReflectMeta, ReflectShader, ShaderReflection, - }; - - pub use librashader_reflect::back::{ - targets::OutputTarget, CompileShader, CompilerBackend, FromCompilation, - ShaderCompilerOutput, - }; - pub use librashader_reflect::front::shaderc::GlslangCompilation; -} - -pub mod targets { - /// Shader compiler targets and runtime for OpenGL 3.3+. - pub mod gl { - /// Shader compiler target for GLSL. - pub use librashader_reflect::back::targets::GLSL; - - /// Shader runtime for OpenGL. - pub mod runtime { - pub use librashader_runtime_gl::*; - } - } - - /// Shader compiler targets and runtime for DirectX. - pub mod d3d { - /// Shader compiler target for HLSL. - pub use librashader_reflect::back::targets::HLSL; - - /// Shader runtime for DirectX. - pub mod runtime { - - /// Shader runtime for DirectX 11. - pub mod d3d11 { - pub use librashader_runtime_d3d11::*; - } - } - } - - /// Shader compiler targets and runtime for Vulkan. - pub mod vk { - /// Shader compiler target for SPIR-V. - pub use librashader_reflect::back::targets::SPIRV; - } -} - -pub use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; - -pub mod util { use librashader_preprocess::{PreprocessError, ShaderParameter, ShaderSource}; use librashader_presets::ShaderPreset; - + /// Get full parameter metadata from a shader preset. pub fn get_parameter_meta( preset: &ShaderPreset, ) -> Result, PreprocessError> { @@ -76,3 +25,61 @@ pub mod util { Ok(iters.into_iter().flatten()) } } + +/// Loading and preprocessing of 'slang' shader source files. +/// +/// Shader sources files must be loaded with imports resolved before being able to be compiled. +/// Shader parameters are also defined in `#pragma`s within shader source files which must be parsed. +pub mod preprocess { + pub use librashader_preprocess::*; +} + +/// Shader compilation and reflection. +pub mod reflect { + /// Supported shader compiler targets. + pub mod targets { + /// Shader compiler target for GLSL. + pub use librashader_reflect::back::targets::GLSL; + + /// Shader compiler target for HLSL. + pub use librashader_reflect::back::targets::HLSL; + + /// Shader compiler target for SPIR-V. + pub use librashader_reflect::back::targets::SPIRV; + } + + pub use librashader_reflect::error::*; + + pub use librashader_reflect::reflect::{ + semantics, ReflectMeta, ReflectShader, ShaderReflection, + }; + + pub use librashader_reflect::back::{ + targets::OutputTarget, CompileShader, CompilerBackend, FromCompilation, + ShaderCompilerOutput, + }; + pub use librashader_reflect::front::shaderc::GlslangCompilation; +} + +/// Shader runtimes to execute a filter chain on a GPU surface. +pub mod runtime { + pub use librashader_runtime::parameters::FilterChainParameters; + pub use librashader_runtime::filter_chain::FilterChain; + + /// Shader runtime for OpenGL 3.3+. + pub mod gl { + pub use librashader_runtime_gl::*; + } + + /// Shader runtime for Direct3D11 + pub mod d3d11 { + pub use librashader_runtime_d3d11::*; + } + + /// Shader compiler targets and runtime for Vulkan. + pub mod vk { + + } +} + +pub use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};