reflect: abstract away preset compilation
This commit is contained in:
parent
422253b42b
commit
4e51704e35
|
@ -136,7 +136,7 @@ extern_fn! {
|
||||||
/// - `preset` must be null or a valid and aligned pointer to a shader preset.
|
/// - `preset` must be null or a valid and aligned pointer to a shader preset.
|
||||||
fn libra_preset_print(preset: *mut libra_shader_preset_t) |preset| {
|
fn libra_preset_print(preset: *mut libra_shader_preset_t) |preset| {
|
||||||
assert_some_ptr!(preset);
|
assert_some_ptr!(preset);
|
||||||
println!("{:#?}", preset);
|
println!("{preset:#?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
use crate::error;
|
use crate::error;
|
||||||
use librashader::preprocess::ShaderSource;
|
|
||||||
use librashader::presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader::presets::{ShaderPassConfig, ShaderPreset};
|
||||||
use librashader::reflect::image::{Image, UVDirection, RGBA8};
|
use librashader::reflect::semantics::ShaderSemantics;
|
||||||
use librashader::reflect::semantics::{
|
|
||||||
Semantic, ShaderSemantics, TextureSemantics, UniformSemantic, UniqueSemantics,
|
|
||||||
};
|
|
||||||
use librashader::reflect::targets::SPIRV;
|
use librashader::reflect::targets::SPIRV;
|
||||||
use librashader::reflect::{
|
use librashader::reflect::{CompileShader, ReflectShader, ShaderCompilerOutput, ShaderReflection};
|
||||||
CompileShader, CompilerBackend, FromCompilation, GlslangCompilation, ReflectShader,
|
|
||||||
ShaderCompilerOutput, ShaderReflection,
|
|
||||||
};
|
|
||||||
use librashader::{FilterMode, WrapMode};
|
use librashader::{FilterMode, WrapMode};
|
||||||
use rustc_hash::FxHashMap;
|
|
||||||
|
use librashader::reflect::cross::GlslangCompilation;
|
||||||
|
use librashader::reflect::helper::image::{Image, UVDirection, RGBA8};
|
||||||
|
|
||||||
pub(crate) struct LookupTexture {
|
pub(crate) struct LookupTexture {
|
||||||
wrap_mode: WrapMode,
|
wrap_mode: WrapMode,
|
||||||
|
@ -40,55 +36,12 @@ impl FilterReflection {
|
||||||
direction: UVDirection,
|
direction: UVDirection,
|
||||||
) -> Result<FilterReflection, error::LibrashaderError> {
|
) -> Result<FilterReflection, error::LibrashaderError> {
|
||||||
let (passes, textures) = (preset.shaders, preset.textures);
|
let (passes, textures) = (preset.shaders, preset.textures);
|
||||||
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
|
||||||
let mut texture_semantics: FxHashMap<String, Semantic<TextureSemantics>> =
|
|
||||||
Default::default();
|
|
||||||
|
|
||||||
let passes = passes
|
let (passes, semantics) = librashader::reflect::helper::compile_preset_passes::<
|
||||||
.into_iter()
|
SPIRV,
|
||||||
.enumerate()
|
GlslangCompilation,
|
||||||
.map(|(index, shader)| {
|
error::LibrashaderError,
|
||||||
let source: ShaderSource = ShaderSource::load(&shader.name)?;
|
>(passes, &textures)?;
|
||||||
|
|
||||||
let spirv = GlslangCompilation::compile(&source)?;
|
|
||||||
let mut reflect = SPIRV::from_compilation(spirv)?;
|
|
||||||
|
|
||||||
for parameter in source.parameters.iter() {
|
|
||||||
uniform_semantics.insert(
|
|
||||||
parameter.id.clone(),
|
|
||||||
UniformSemantic::Unique(Semantic {
|
|
||||||
semantics: UniqueSemantics::FloatParameter,
|
|
||||||
index: (),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok::<_, error::LibrashaderError>((shader, source, reflect))
|
|
||||||
})
|
|
||||||
.into_iter()
|
|
||||||
.collect::<Result<
|
|
||||||
Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>,
|
|
||||||
error::LibrashaderError,
|
|
||||||
>>()?;
|
|
||||||
|
|
||||||
for details in &passes {
|
|
||||||
librashader::runtime::helper::insert_pass_semantics(
|
|
||||||
&mut uniform_semantics,
|
|
||||||
&mut texture_semantics,
|
|
||||||
&details.0,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
librashader::runtime::helper::insert_lut_semantics(
|
|
||||||
&textures,
|
|
||||||
&mut uniform_semantics,
|
|
||||||
&mut texture_semantics,
|
|
||||||
);
|
|
||||||
|
|
||||||
let semantics = ShaderSemantics {
|
|
||||||
uniform_semantics,
|
|
||||||
texture_semantics,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut reflects = Vec::new();
|
let mut reflects = Vec::new();
|
||||||
|
|
||||||
|
@ -114,7 +67,6 @@ impl FilterReflection {
|
||||||
image: lut,
|
image: lut,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.into_iter()
|
|
||||||
.collect::<Result<Vec<LookupTexture>, error::LibrashaderError>>()?;
|
.collect::<Result<Vec<LookupTexture>, error::LibrashaderError>>()?;
|
||||||
|
|
||||||
Ok(FilterReflection {
|
Ok(FilterReflection {
|
||||||
|
|
|
@ -67,7 +67,7 @@ pub(crate) trait SourceOutput {
|
||||||
fn push_line(&mut self, str: &str);
|
fn push_line(&mut self, str: &str);
|
||||||
fn mark_line(&mut self, line_no: usize, comment: &str) {
|
fn mark_line(&mut self, line_no: usize, comment: &str) {
|
||||||
#[cfg(feature = "line_directives")]
|
#[cfg(feature = "line_directives")]
|
||||||
self.push_line(&format!("#line {} \"{}\"", line_no, comment))
|
self.push_line(&format!("#line {line_no} \"{comment}\""))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ mod test {
|
||||||
pub fn parse_preset() {
|
pub fn parse_preset() {
|
||||||
let root = PathBuf::from("../test/slang-shaders/ntsc/ntsc-256px-svideo.slangp");
|
let root = PathBuf::from("../test/slang-shaders/ntsc/ntsc-256px-svideo.slangp");
|
||||||
let basic = ShaderPreset::try_parse(root);
|
let basic = ShaderPreset::try_parse(root);
|
||||||
eprintln!("{:#?}", basic);
|
eprintln!("{basic:#?}");
|
||||||
assert!(basic.is_ok());
|
assert!(basic.is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,13 +157,13 @@ mod test {
|
||||||
fn parses_single_line_comment() {
|
fn parses_single_line_comment() {
|
||||||
let parsed =
|
let parsed =
|
||||||
single_comment("// Define textures to be used by the different passes\ntetx=n".into());
|
single_comment("// Define textures to be used by the different passes\ntetx=n".into());
|
||||||
eprintln!("{:?}", parsed)
|
eprintln!("{parsed:?}")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parses_key_value_line() {
|
fn parses_key_value_line() {
|
||||||
let parsed = do_lex(TEST);
|
let parsed = do_lex(TEST);
|
||||||
eprintln!("{:#?}", parsed)
|
eprintln!("{parsed:#?}")
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: fix
|
// todo: fix
|
||||||
|
|
|
@ -99,7 +99,7 @@ fn from_ul(input: Span) -> Result<u32, ParsePresetError> {
|
||||||
|
|
||||||
fn from_float(input: Span) -> Result<f32, ParsePresetError> {
|
fn from_float(input: Span) -> Result<f32, ParsePresetError> {
|
||||||
f32::from_str(input.trim()).map_err(|_| {
|
f32::from_str(input.trim()).map_err(|_| {
|
||||||
eprintln!("{:?}", input);
|
eprintln!("{input:?}");
|
||||||
ParsePresetError::ParserError {
|
ParsePresetError::ParserError {
|
||||||
offset: input.location_offset(),
|
offset: input.location_offset(),
|
||||||
row: input.location_line(),
|
row: input.location_line(),
|
||||||
|
@ -491,7 +491,7 @@ mod test {
|
||||||
let root =
|
let root =
|
||||||
PathBuf::from("../test/slang-shaders/bezel/Mega_Bezel/Presets/Base_CRT_Presets/MBZ__3__STD__MEGATRON-NTSC.slangp");
|
PathBuf::from("../test/slang-shaders/bezel/Mega_Bezel/Presets/Base_CRT_Presets/MBZ__3__STD__MEGATRON-NTSC.slangp");
|
||||||
let basic = parse_preset(root);
|
let basic = parse_preset(root);
|
||||||
eprintln!("{:?}", basic);
|
eprintln!("{basic:?}");
|
||||||
assert!(basic.is_ok());
|
assert!(basic.is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
|
use crate::error::ShaderCompileError;
|
||||||
|
use librashader_preprocess::ShaderSource;
|
||||||
|
|
||||||
#[cfg(feature = "unstable-naga")]
|
#[cfg(feature = "unstable-naga")]
|
||||||
pub mod naga;
|
pub mod naga;
|
||||||
|
|
||||||
pub mod shaderc;
|
pub mod shaderc;
|
||||||
|
|
||||||
|
pub trait ShaderCompilation: Sized {
|
||||||
|
/// Compile the input shader source file into a compilation unit.
|
||||||
|
fn compile(source: &ShaderSource) -> Result<Self, ShaderCompileError>;
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::error::ShaderCompileError;
|
use crate::error::ShaderCompileError;
|
||||||
|
use crate::front::ShaderCompilation;
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
use shaderc::{CompilationArtifact, CompileOptions, Limit, ShaderKind};
|
use shaderc::{CompilationArtifact, CompileOptions, Limit, ShaderKind};
|
||||||
|
|
||||||
|
@ -15,6 +16,12 @@ impl GlslangCompilation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ShaderCompilation for GlslangCompilation {
|
||||||
|
fn compile(source: &ShaderSource) -> Result<Self, ShaderCompileError> {
|
||||||
|
GlslangCompilation::compile(source)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TryFrom<&ShaderSource> for GlslangCompilation {
|
impl TryFrom<&ShaderSource> for GlslangCompilation {
|
||||||
type Error = ShaderCompileError;
|
type Error = ShaderCompileError;
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
use crate::texture::{D3D11InputView, InputTexture, LutTexture};
|
use crate::texture::{D3D11InputView, InputTexture, LutTexture};
|
||||||
use librashader_common::{ImageFormat, Size, Viewport};
|
use librashader_common::{ImageFormat, Size, Viewport};
|
||||||
use librashader_preprocess::ShaderSource;
|
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::cross::CrossHlslContext;
|
use librashader_reflect::back::cross::CrossHlslContext;
|
||||||
use librashader_reflect::back::targets::HLSL;
|
use librashader_reflect::back::targets::HLSL;
|
||||||
use librashader_reflect::back::{CompileShader, CompilerBackend, FromCompilation};
|
use librashader_reflect::back::CompileShader;
|
||||||
use librashader_reflect::front::shaderc::GlslangCompilation;
|
use librashader_reflect::front::shaderc::GlslangCompilation;
|
||||||
use librashader_reflect::reflect::semantics::{
|
use librashader_reflect::reflect::semantics::{ShaderSemantics, TextureSemantics, UniformBinding};
|
||||||
Semantic, ShaderSemantics, TextureSemantics, UniformBinding, UniformSemantic, UniqueSemantics,
|
|
||||||
};
|
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use librashader_runtime::image::{Image, UVDirection};
|
use librashader_runtime::image::{Image, UVDirection};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
@ -25,6 +23,7 @@ use crate::render_target::RenderTarget;
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
use crate::util::d3d11_compile_bound_shader;
|
use crate::util::d3d11_compile_bound_shader;
|
||||||
use crate::{error, util, D3D11OutputView};
|
use crate::{error, util, D3D11OutputView};
|
||||||
|
use librashader_runtime::reflect;
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
use windows::Win32::Graphics::Direct3D11::{
|
use windows::Win32::Graphics::Direct3D11::{
|
||||||
ID3D11Buffer, ID3D11Device, ID3D11DeviceContext, D3D11_BIND_CONSTANT_BUFFER, D3D11_BUFFER_DESC,
|
ID3D11Buffer, ID3D11Device, ID3D11DeviceContext, D3D11_BIND_CONSTANT_BUFFER, D3D11_BUFFER_DESC,
|
||||||
|
@ -38,13 +37,9 @@ pub struct FilterMutable {
|
||||||
pub(crate) parameters: FxHashMap<String, f32>,
|
pub(crate) parameters: FxHashMap<String, f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShaderPassMeta = (
|
type ShaderPassMeta = reflect::ShaderPassMeta<
|
||||||
ShaderPassConfig,
|
impl CompileShader<HLSL, Options = Option<()>, Context = CrossHlslContext> + ReflectShader,
|
||||||
ShaderSource,
|
>;
|
||||||
CompilerBackend<
|
|
||||||
impl CompileShader<HLSL, Options = Option<()>, Context = CrossHlslContext> + ReflectShader,
|
|
||||||
>,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// A Direct3D 11 filter chain.
|
/// A Direct3D 11 filter chain.
|
||||||
pub struct FilterChainD3D11 {
|
pub struct FilterChainD3D11 {
|
||||||
|
@ -92,7 +87,11 @@ impl FilterChainD3D11 {
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
options: Option<&FilterChainOptionsD3D11>,
|
options: Option<&FilterChainOptionsD3D11>,
|
||||||
) -> error::Result<FilterChainD3D11> {
|
) -> error::Result<FilterChainD3D11> {
|
||||||
let (passes, semantics) = FilterChainD3D11::load_preset(preset.shaders, &preset.textures)?;
|
let (passes, semantics) = reflect::compile_preset_passes::<
|
||||||
|
HLSL,
|
||||||
|
GlslangCompilation,
|
||||||
|
FilterChainError,
|
||||||
|
>(preset.shaders, &preset.textures)?;
|
||||||
|
|
||||||
let use_deferred_context = options.map(|f| f.use_deferred_context).unwrap_or(false);
|
let use_deferred_context = options.map(|f| f.use_deferred_context).unwrap_or(false);
|
||||||
|
|
||||||
|
@ -412,59 +411,6 @@ impl FilterChainD3D11 {
|
||||||
Ok(luts)
|
Ok(luts)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_preset(
|
|
||||||
passes: Vec<ShaderPassConfig>,
|
|
||||||
textures: &[TextureConfig],
|
|
||||||
) -> error::Result<(Vec<ShaderPassMeta>, ShaderSemantics)> {
|
|
||||||
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
|
||||||
let mut texture_semantics: FxHashMap<String, Semantic<TextureSemantics>> =
|
|
||||||
Default::default();
|
|
||||||
|
|
||||||
let passes = passes
|
|
||||||
.into_iter()
|
|
||||||
.map(|shader| {
|
|
||||||
// eprintln!("[dx11] loading {}", &shader.name.display());
|
|
||||||
let source: ShaderSource = ShaderSource::load(&shader.name)?;
|
|
||||||
|
|
||||||
let spirv = GlslangCompilation::compile(&source)?;
|
|
||||||
let reflect = HLSL::from_compilation(spirv)?;
|
|
||||||
|
|
||||||
for parameter in source.parameters.values() {
|
|
||||||
uniform_semantics.insert(
|
|
||||||
parameter.id.clone(),
|
|
||||||
UniformSemantic::Unique(Semantic {
|
|
||||||
semantics: UniqueSemantics::FloatParameter,
|
|
||||||
index: (),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Ok::<_, FilterChainError>((shader, source, reflect))
|
|
||||||
})
|
|
||||||
.into_iter()
|
|
||||||
.collect::<error::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
|
|
||||||
)?;
|
|
||||||
|
|
||||||
for details in &passes {
|
|
||||||
librashader_runtime::semantics::insert_pass_semantics(
|
|
||||||
&mut uniform_semantics,
|
|
||||||
&mut texture_semantics,
|
|
||||||
&details.0,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
librashader_runtime::semantics::insert_lut_semantics(
|
|
||||||
textures,
|
|
||||||
&mut uniform_semantics,
|
|
||||||
&mut texture_semantics,
|
|
||||||
);
|
|
||||||
|
|
||||||
let semantics = ShaderSemantics {
|
|
||||||
uniform_semantics,
|
|
||||||
texture_semantics,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((passes, semantics))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Process a frame with the input image.
|
/// Process a frame with the input image.
|
||||||
pub fn frame(
|
pub fn frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -10,17 +10,17 @@ use crate::util::{gl_get_version, gl_u16_to_version};
|
||||||
use crate::{error, util, GLImage};
|
use crate::{error, util, GLImage};
|
||||||
use gl::types::{GLint, GLuint};
|
use gl::types::{GLint, GLuint};
|
||||||
use librashader_common::{FilterMode, Viewport, WrapMode};
|
use librashader_common::{FilterMode, Viewport, WrapMode};
|
||||||
use librashader_preprocess::ShaderSource;
|
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::ShaderPreset;
|
||||||
use librashader_reflect::back::cross::{CrossGlslContext, GlslVersion};
|
use librashader_reflect::back::cross::{CrossGlslContext, GlslVersion};
|
||||||
use librashader_reflect::back::targets::GLSL;
|
use librashader_reflect::back::targets::GLSL;
|
||||||
use librashader_reflect::back::{CompileShader, CompilerBackend, FromCompilation};
|
use librashader_reflect::back::CompileShader;
|
||||||
use librashader_reflect::front::shaderc::GlslangCompilation;
|
use librashader_reflect::front::shaderc::GlslangCompilation;
|
||||||
use librashader_reflect::reflect::semantics::{
|
use librashader_reflect::reflect::semantics::{
|
||||||
MemberOffset, Semantic, ShaderSemantics, TextureSemantics, UniformBinding, UniformMeta,
|
MemberOffset, ShaderSemantics, TextureSemantics, UniformBinding, UniformMeta,
|
||||||
UniformSemantic, UniqueSemantics,
|
|
||||||
};
|
};
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
|
use librashader_runtime::reflect;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use spirv_cross::spirv::Decoration;
|
use spirv_cross::spirv::Decoration;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
@ -79,13 +79,9 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShaderPassMeta = (
|
type ShaderPassMeta = reflect::ShaderPassMeta<
|
||||||
ShaderPassConfig,
|
impl CompileShader<GLSL, Options = GlslVersion, Context = CrossGlslContext> + ReflectShader,
|
||||||
ShaderSource,
|
>;
|
||||||
CompilerBackend<
|
|
||||||
impl CompileShader<GLSL, Options = GlslVersion, Context = CrossGlslContext> + ReflectShader,
|
|
||||||
>,
|
|
||||||
);
|
|
||||||
|
|
||||||
impl<T: GLInterface> FilterChainImpl<T> {
|
impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
|
@ -93,7 +89,11 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
options: Option<&FilterChainOptionsGL>,
|
options: Option<&FilterChainOptionsGL>,
|
||||||
) -> error::Result<Self> {
|
) -> error::Result<Self> {
|
||||||
let (passes, semantics) = Self::load_preset(preset.shaders, &preset.textures)?;
|
let (passes, semantics) = reflect::compile_preset_passes::<
|
||||||
|
GLSL,
|
||||||
|
GlslangCompilation,
|
||||||
|
FilterChainError,
|
||||||
|
>(preset.shaders, &preset.textures)?;
|
||||||
|
|
||||||
let version = options
|
let version = options
|
||||||
.map(|o| gl_u16_to_version(o.gl_version))
|
.map(|o| gl_u16_to_version(o.gl_version))
|
||||||
|
@ -156,60 +156,6 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_preset(
|
|
||||||
passes: Vec<ShaderPassConfig>,
|
|
||||||
textures: &[TextureConfig],
|
|
||||||
) -> error::Result<(Vec<ShaderPassMeta>, ShaderSemantics)> {
|
|
||||||
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
|
||||||
let mut texture_semantics: FxHashMap<String, Semantic<TextureSemantics>> =
|
|
||||||
Default::default();
|
|
||||||
|
|
||||||
let passes = passes
|
|
||||||
.into_iter()
|
|
||||||
.map(|shader| {
|
|
||||||
// eprintln!("[gl] loading {}", &shader.name.display());
|
|
||||||
let source: ShaderSource = ShaderSource::load(&shader.name)?;
|
|
||||||
|
|
||||||
let spirv = GlslangCompilation::compile(&source)?;
|
|
||||||
let reflect = GLSL::from_compilation(spirv)?;
|
|
||||||
|
|
||||||
for parameter in source.parameters.values() {
|
|
||||||
uniform_semantics.insert(
|
|
||||||
parameter.id.clone(),
|
|
||||||
UniformSemantic::Unique(Semantic {
|
|
||||||
semantics: UniqueSemantics::FloatParameter,
|
|
||||||
index: (),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Ok::<_, FilterChainError>((shader, source, reflect))
|
|
||||||
})
|
|
||||||
.into_iter()
|
|
||||||
.collect::<error::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
|
|
||||||
)?;
|
|
||||||
|
|
||||||
for details in &passes {
|
|
||||||
librashader_runtime::semantics::insert_pass_semantics(
|
|
||||||
&mut uniform_semantics,
|
|
||||||
&mut texture_semantics,
|
|
||||||
&details.0,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
librashader_runtime::semantics::insert_lut_semantics(
|
|
||||||
textures,
|
|
||||||
&mut uniform_semantics,
|
|
||||||
&mut texture_semantics,
|
|
||||||
);
|
|
||||||
|
|
||||||
let semantics = ShaderSemantics {
|
|
||||||
uniform_semantics,
|
|
||||||
texture_semantics,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((passes, semantics))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init_passes(
|
fn init_passes(
|
||||||
version: GlslVersion,
|
version: GlslVersion,
|
||||||
passes: Vec<ShaderPassMeta>,
|
passes: Vec<ShaderPassMeta>,
|
||||||
|
|
|
@ -14,16 +14,15 @@ use crate::vulkan_state::VulkanGraphicsPipeline;
|
||||||
use crate::{error, util};
|
use crate::{error, util};
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
use librashader_common::{ImageFormat, Size, Viewport};
|
use librashader_common::{ImageFormat, Size, Viewport};
|
||||||
use librashader_preprocess::ShaderSource;
|
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::targets::SPIRV;
|
use librashader_reflect::back::targets::SPIRV;
|
||||||
use librashader_reflect::back::{CompileShader, CompilerBackend, FromCompilation};
|
use librashader_reflect::back::CompileShader;
|
||||||
use librashader_reflect::front::shaderc::GlslangCompilation;
|
use librashader_reflect::front::shaderc::GlslangCompilation;
|
||||||
use librashader_reflect::reflect::semantics::{
|
use librashader_reflect::reflect::semantics::{ShaderSemantics, TextureSemantics, UniformBinding};
|
||||||
Semantic, ShaderSemantics, TextureSemantics, UniformBinding, UniformSemantic, UniqueSemantics,
|
|
||||||
};
|
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use librashader_runtime::image::{Image, UVDirection};
|
use librashader_runtime::image::{Image, UVDirection};
|
||||||
|
use librashader_runtime::reflect;
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
@ -38,11 +37,9 @@ pub struct VulkanObjects {
|
||||||
pipeline_cache: vk::PipelineCache,
|
pipeline_cache: vk::PipelineCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShaderPassMeta = (
|
type ShaderPassMeta = reflect::ShaderPassMeta<
|
||||||
ShaderPassConfig,
|
impl CompileShader<SPIRV, Options = Option<()>, Context = ()> + ReflectShader,
|
||||||
ShaderSource,
|
>;
|
||||||
CompilerBackend<impl CompileShader<SPIRV, Options = Option<()>, Context = ()> + ReflectShader>,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// A collection of handles needed to access the Vulkan instance.
|
/// A collection of handles needed to access the Vulkan instance.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -211,7 +208,11 @@ impl FilterChainVulkan {
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
options: Option<&FilterChainOptionsVulkan>,
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
) -> error::Result<FilterChainVulkan> {
|
) -> error::Result<FilterChainVulkan> {
|
||||||
let (passes, semantics) = FilterChainVulkan::load_preset(preset.shaders, &preset.textures)?;
|
let (passes, semantics) = reflect::compile_preset_passes::<
|
||||||
|
SPIRV,
|
||||||
|
GlslangCompilation,
|
||||||
|
FilterChainError,
|
||||||
|
>(preset.shaders, &preset.textures)?;
|
||||||
let device = vulkan.try_into()?;
|
let device = vulkan.try_into()?;
|
||||||
|
|
||||||
let mut frames_in_flight = options.map(|o| o.frames_in_flight).unwrap_or(0);
|
let mut frames_in_flight = options.map(|o| o.frames_in_flight).unwrap_or(0);
|
||||||
|
@ -281,59 +282,6 @@ impl FilterChainVulkan {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_preset(
|
|
||||||
passes: Vec<ShaderPassConfig>,
|
|
||||||
textures: &[TextureConfig],
|
|
||||||
) -> error::Result<(Vec<ShaderPassMeta>, ShaderSemantics)> {
|
|
||||||
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
|
||||||
let mut texture_semantics: FxHashMap<String, Semantic<TextureSemantics>> =
|
|
||||||
Default::default();
|
|
||||||
|
|
||||||
let passes = passes
|
|
||||||
.into_iter()
|
|
||||||
.map(|shader| {
|
|
||||||
// eprintln!("[vk] loading {}", &shader.name.display());
|
|
||||||
let source: ShaderSource = ShaderSource::load(&shader.name)?;
|
|
||||||
|
|
||||||
let spirv = GlslangCompilation::compile(&source)?;
|
|
||||||
let reflect = SPIRV::from_compilation(spirv)?;
|
|
||||||
|
|
||||||
for parameter in source.parameters.values() {
|
|
||||||
uniform_semantics.insert(
|
|
||||||
parameter.id.clone(),
|
|
||||||
UniformSemantic::Unique(Semantic {
|
|
||||||
semantics: UniqueSemantics::FloatParameter,
|
|
||||||
index: (),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Ok::<_, FilterChainError>((shader, source, reflect))
|
|
||||||
})
|
|
||||||
.into_iter()
|
|
||||||
.collect::<error::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
|
|
||||||
)?;
|
|
||||||
|
|
||||||
for details in &passes {
|
|
||||||
librashader_runtime::semantics::insert_pass_semantics(
|
|
||||||
&mut uniform_semantics,
|
|
||||||
&mut texture_semantics,
|
|
||||||
&details.0,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
librashader_runtime::semantics::insert_lut_semantics(
|
|
||||||
textures,
|
|
||||||
&mut uniform_semantics,
|
|
||||||
&mut texture_semantics,
|
|
||||||
);
|
|
||||||
|
|
||||||
let semantics = ShaderSemantics {
|
|
||||||
uniform_semantics,
|
|
||||||
texture_semantics,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((passes, semantics))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init_passes(
|
fn init_passes(
|
||||||
vulkan: &VulkanObjects,
|
vulkan: &VulkanObjects,
|
||||||
passes: Vec<ShaderPassMeta>,
|
passes: Vec<ShaderPassMeta>,
|
||||||
|
|
|
@ -26,3 +26,6 @@ pub mod ringbuffer;
|
||||||
|
|
||||||
/// Generic implementation of semantics binding.
|
/// Generic implementation of semantics binding.
|
||||||
pub mod binding;
|
pub mod binding;
|
||||||
|
|
||||||
|
/// Generic helpers for loading shader passes into compiled shader targets and semantics.
|
||||||
|
pub mod reflect;
|
||||||
|
|
79
librashader-runtime/src/reflect.rs
Normal file
79
librashader-runtime/src/reflect.rs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
use librashader_preprocess::{PreprocessError, ShaderSource};
|
||||||
|
use librashader_presets::{ShaderPassConfig, TextureConfig};
|
||||||
|
use librashader_reflect::back::targets::OutputTarget;
|
||||||
|
use librashader_reflect::back::{CompilerBackend, FromCompilation};
|
||||||
|
use librashader_reflect::error::{ShaderCompileError, ShaderReflectError};
|
||||||
|
use librashader_reflect::front::ShaderCompilation;
|
||||||
|
use librashader_reflect::reflect::semantics::{
|
||||||
|
Semantic, ShaderSemantics, TextureSemantics, UniformSemantic, UniqueSemantics,
|
||||||
|
};
|
||||||
|
use rustc_hash::FxHashMap;
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
pub type ShaderPassMeta<T> = (ShaderPassConfig, ShaderSource, CompilerBackend<T>);
|
||||||
|
|
||||||
|
/// Compile passes of a shader preset given the applicable
|
||||||
|
/// shader output target, compilation type, and resulting error.
|
||||||
|
pub fn compile_preset_passes<T, C, E>(
|
||||||
|
passes: Vec<ShaderPassConfig>,
|
||||||
|
textures: &[TextureConfig],
|
||||||
|
) -> Result<
|
||||||
|
(
|
||||||
|
Vec<ShaderPassMeta<<T as FromCompilation<C>>::Output>>,
|
||||||
|
ShaderSemantics,
|
||||||
|
),
|
||||||
|
E,
|
||||||
|
>
|
||||||
|
where
|
||||||
|
T: OutputTarget,
|
||||||
|
T: FromCompilation<C>,
|
||||||
|
C: ShaderCompilation,
|
||||||
|
E: Error,
|
||||||
|
E: From<PreprocessError>,
|
||||||
|
E: From<ShaderReflectError>,
|
||||||
|
E: From<ShaderCompileError>,
|
||||||
|
{
|
||||||
|
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
||||||
|
let mut texture_semantics: FxHashMap<String, Semantic<TextureSemantics>> = Default::default();
|
||||||
|
|
||||||
|
let passes = passes
|
||||||
|
.into_iter()
|
||||||
|
.map(|shader| {
|
||||||
|
let source: ShaderSource = ShaderSource::load(&shader.name)?;
|
||||||
|
|
||||||
|
let compiled = C::compile(&source)?;
|
||||||
|
let reflect = T::from_compilation(compiled)?;
|
||||||
|
|
||||||
|
for parameter in source.parameters.values() {
|
||||||
|
uniform_semantics.insert(
|
||||||
|
parameter.id.clone(),
|
||||||
|
UniformSemantic::Unique(Semantic {
|
||||||
|
semantics: UniqueSemantics::FloatParameter,
|
||||||
|
index: (),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Ok::<_, E>((shader, source, reflect))
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>, E>>()?;
|
||||||
|
|
||||||
|
for details in &passes {
|
||||||
|
crate::semantics::insert_pass_semantics(
|
||||||
|
&mut uniform_semantics,
|
||||||
|
&mut texture_semantics,
|
||||||
|
&details.0,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
crate::semantics::insert_lut_semantics(
|
||||||
|
textures,
|
||||||
|
&mut uniform_semantics,
|
||||||
|
&mut texture_semantics,
|
||||||
|
);
|
||||||
|
|
||||||
|
let semantics = ShaderSemantics {
|
||||||
|
uniform_semantics,
|
||||||
|
texture_semantics,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((passes, semantics))
|
||||||
|
}
|
|
@ -58,7 +58,7 @@ pub fn insert_pass_semantics(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// /// Insert the available semantics for the input texture config into the provided semantic maps.
|
/// Insert the available semantics for the input texture config into the provided semantic maps.
|
||||||
pub fn insert_lut_semantics(
|
pub fn insert_lut_semantics(
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureConfig],
|
||||||
uniform_semantics: &mut UniformSemanticsMap,
|
uniform_semantics: &mut UniformSemanticsMap,
|
||||||
|
|
|
@ -53,7 +53,6 @@ pub mod presets {
|
||||||
.shaders
|
.shaders
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| ShaderSource::load(&s.name).map(|s| s.parameters.into_values().collect()))
|
.map(|s| ShaderSource::load(&s.name).map(|s| s.parameters.into_values().collect()))
|
||||||
.into_iter()
|
|
||||||
.collect();
|
.collect();
|
||||||
let iters = iters?;
|
let iters = iters?;
|
||||||
Ok(iters.into_iter().flatten())
|
Ok(iters.into_iter().flatten())
|
||||||
|
@ -113,6 +112,16 @@ pub mod reflect {
|
||||||
pub use librashader_reflect::reflect::cross::CompiledProgram;
|
pub use librashader_reflect::reflect::cross::CompiledProgram;
|
||||||
}
|
}
|
||||||
pub use librashader_reflect::reflect::semantics::BindingMeta;
|
pub use librashader_reflect::reflect::semantics::BindingMeta;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[cfg(feature = "internal")]
|
||||||
|
/// Helper methods for runtimes.
|
||||||
|
///
|
||||||
|
/// This is internal to librashader runtimes and is exempt from semantic versioning.
|
||||||
|
pub mod helper {
|
||||||
|
pub use librashader_runtime::image;
|
||||||
|
pub use librashader_runtime::reflect::compile_preset_passes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shader runtimes to execute a filter chain on a GPU surface.
|
/// Shader runtimes to execute a filter chain on a GPU surface.
|
||||||
|
@ -190,16 +199,6 @@ pub mod runtime {
|
||||||
pub use librashader_runtime_vk::*;
|
pub use librashader_runtime_vk::*;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[cfg(feature = "internal")]
|
|
||||||
/// Helper methods for runtimes.
|
|
||||||
///
|
|
||||||
/// This is internal to librashader runtimes and is exempt from semantic versioning.
|
|
||||||
pub mod helper {
|
|
||||||
pub use librashader_runtime::semantics::insert_lut_semantics;
|
|
||||||
pub use librashader_runtime::semantics::insert_pass_semantics;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use librashader_common::{FilterMode, ImageFormat, WrapMode};
|
pub use librashader_common::{FilterMode, ImageFormat, WrapMode};
|
||||||
|
|
Loading…
Reference in a new issue