reflect: abstract away output compiler into its own trait

This commit is contained in:
chyyran 2024-02-10 18:54:57 -05:00 committed by Ronny Chan
parent a7ca391ef6
commit 252f685967
32 changed files with 210 additions and 161 deletions

66
Cargo.lock generated
View file

@ -327,17 +327,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68"
dependencies = [ dependencies = [
"block-sys", "block-sys",
"objc2 0.4.1", "objc2",
]
[[package]]
name = "block2"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e58aa60e59d8dbfcc36138f5f18be5f24394d33b38b24f7fd0b1caa33095f22f"
dependencies = [
"block-sys",
"objc2 0.5.0",
] ]
[[package]] [[package]]
@ -1295,19 +1285,9 @@ version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319"
dependencies = [ dependencies = [
"block2 0.3.0", "block2",
"dispatch", "dispatch",
"objc2 0.4.1", "objc2",
]
[[package]]
name = "icrate"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e286f4b975ac6c054971a0600a9b76438b332edace54bff79c71c9d3adfc9772"
dependencies = [
"block2 0.4.0",
"objc2 0.5.0",
] ]
[[package]] [[package]]
@ -1554,7 +1534,6 @@ version = "0.2.0-beta.9"
dependencies = [ dependencies = [
"ash", "ash",
"gl", "gl",
"icrate 0.1.0",
"num-traits", "num-traits",
"wgpu-types", "wgpu-types",
"windows 0.48.0", "windows 0.48.0",
@ -1704,23 +1683,6 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "librashader-runtime-metal"
version = "0.2.0-beta.7"
dependencies = [
"array-concat",
"bytemuck",
"icrate 0.1.0",
"librashader-common 0.2.0-beta.9",
"librashader-preprocess",
"librashader-presets 0.2.0-beta.9",
"librashader-reflect",
"librashader-runtime",
"objc2 0.5.0",
"rustc-hash",
"thiserror",
]
[[package]] [[package]]
name = "librashader-runtime-vk" name = "librashader-runtime-vk"
version = "0.2.0-beta.9" version = "0.2.0-beta.9"
@ -2095,17 +2057,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d"
dependencies = [ dependencies = [
"objc-sys", "objc-sys",
"objc2-encode 3.0.0", "objc2-encode",
]
[[package]]
name = "objc2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a9c7f0d511a4ce26b078183179dca908171cfc69f88986fe36c5138e1834476"
dependencies = [
"objc-sys",
"objc2-encode 4.0.0",
] ]
[[package]] [[package]]
@ -2114,12 +2066,6 @@ version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666"
[[package]]
name = "objc2-encode"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ff06a6505cde0766484f38d8479ac8e6d31c66fbc2d5492f65ca8c091456379"
[[package]] [[package]]
name = "objc_exception" name = "objc_exception"
version = "0.1.2" version = "0.1.2"
@ -3642,14 +3588,14 @@ dependencies = [
"core-foundation", "core-foundation",
"core-graphics", "core-graphics",
"cursor-icon", "cursor-icon",
"icrate 0.0.4", "icrate",
"js-sys", "js-sys",
"libc", "libc",
"log", "log",
"memmap2", "memmap2",
"ndk", "ndk",
"ndk-sys", "ndk-sys",
"objc2 0.4.1", "objc2",
"once_cell", "once_cell",
"orbclient", "orbclient",
"percent-encoding", "percent-encoding",

View file

@ -6,18 +6,20 @@ use librashader_reflect::back::targets::{GLSL, HLSL, SPIRV};
use librashader_reflect::back::{CompilerBackend, FromCompilation}; use librashader_reflect::back::{CompilerBackend, FromCompilation};
use librashader_reflect::error::{ShaderCompileError, ShaderReflectError}; use librashader_reflect::error::{ShaderCompileError, ShaderReflectError};
use librashader_reflect::front::{Glslang, ShaderInputCompiler, ShaderReflectObject, SpirvCompilation}; use librashader_reflect::front::{
Glslang, ShaderInputCompiler, ShaderReflectObject, SpirvCompilation,
};
pub struct CachedCompilation<T> { pub struct CachedCompilation<T> {
compilation: T, compilation: T,
} }
impl <T: ShaderReflectObject> ShaderReflectObject for CachedCompilation<T> { impl<T: ShaderReflectObject> ShaderReflectObject for CachedCompilation<T> {}
}
impl<T: ShaderReflectObject + for<'de> serde::Deserialize<'de> + serde::Serialize + Clone> impl<T: ShaderReflectObject + for<'de> serde::Deserialize<'de> + serde::Serialize + Clone>
ShaderInputCompiler<CachedCompilation<T>> for Glslang where Glslang: ShaderInputCompiler<T> ShaderInputCompiler<CachedCompilation<T>> for Glslang
where
Glslang: ShaderInputCompiler<T>,
{ {
fn compile(source: &ShaderSource) -> Result<CachedCompilation<T>, ShaderCompileError> { fn compile(source: &ShaderSource) -> Result<CachedCompilation<T>, ShaderCompileError> {
let cache = crate::cache::internal::get_cache(); let cache = crate::cache::internal::get_cache();

View file

@ -70,24 +70,21 @@ use librashader::runtime::d3d11::FilterChain as FilterChainD3D11;
/// A handle to a Direct3D 11 filter chain. /// A handle to a Direct3D 11 filter chain.
#[cfg(all(target_os = "windows", feature = "runtime-d3d11"))] #[cfg(all(target_os = "windows", feature = "runtime-d3d11"))]
#[doc(cfg(all(target_os = "windows", feature = "runtime-d3d11")))] #[doc(cfg(all(target_os = "windows", feature = "runtime-d3d11")))]
pub type libra_d3d11_filter_chain_t = pub type libra_d3d11_filter_chain_t = Option<NonNull<FilterChainD3D11>>;
Option<NonNull<FilterChainD3D11>>;
#[cfg(all(target_os = "windows", feature = "runtime-d3d12"))] #[cfg(all(target_os = "windows", feature = "runtime-d3d12"))]
use librashader::runtime::d3d12::FilterChain as FilterChainD3D12; use librashader::runtime::d3d12::FilterChain as FilterChainD3D12;
/// A handle to a Direct3D 12 filter chain. /// A handle to a Direct3D 12 filter chain.
#[cfg(all(target_os = "windows", feature = "runtime-d3d12"))] #[cfg(all(target_os = "windows", feature = "runtime-d3d12"))]
#[doc(cfg(all(target_os = "windows", feature = "runtime-d3d12")))] #[doc(cfg(all(target_os = "windows", feature = "runtime-d3d12")))]
pub type libra_d3d12_filter_chain_t = pub type libra_d3d12_filter_chain_t = Option<NonNull<FilterChainD3D12>>;
Option<NonNull<FilterChainD3D12>>;
#[cfg(feature = "runtime-vulkan")] #[cfg(feature = "runtime-vulkan")]
use librashader::runtime::vk::FilterChain as FilterChainVulkan; use librashader::runtime::vk::FilterChain as FilterChainVulkan;
/// A handle to a Vulkan filter chain. /// A handle to a Vulkan filter chain.
#[cfg(feature = "runtime-vulkan")] #[cfg(feature = "runtime-vulkan")]
#[doc(cfg(feature = "runtime-vulkan"))] #[doc(cfg(feature = "runtime-vulkan"))]
pub type libra_vk_filter_chain_t = pub type libra_vk_filter_chain_t = Option<NonNull<FilterChainVulkan>>;
Option<NonNull<FilterChainVulkan>>;
/// Defines the output viewport for a rendered frame. /// Defines the output viewport for a rendered frame.
#[repr(C)] #[repr(C)]

View file

@ -3,7 +3,9 @@ use crate::ctypes::{
}; };
use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError}; use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError};
use crate::ffi::extern_fn; use crate::ffi::extern_fn;
use librashader::runtime::d3d11::{FilterChain, FilterChainOptions, FrameOptions, D3D11InputView, D3D11OutputView}; use librashader::runtime::d3d11::{
D3D11InputView, D3D11OutputView, FilterChain, FilterChainOptions, FrameOptions,
};
use std::ffi::c_char; use std::ffi::c_char;
use std::ffi::CStr; use std::ffi::CStr;
use std::mem::{ManuallyDrop, MaybeUninit}; use std::mem::{ManuallyDrop, MaybeUninit};

View file

@ -14,7 +14,9 @@ use windows::Win32::Graphics::Direct3D12::{
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT; use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
use crate::LIBRASHADER_API_VERSION; use crate::LIBRASHADER_API_VERSION;
use librashader::runtime::d3d12::{FilterChain, FilterChainOptions, FrameOptions, D3D12InputImage, D3D12OutputView}; use librashader::runtime::d3d12::{
D3D12InputImage, D3D12OutputView, FilterChain, FilterChainOptions, FrameOptions,
};
use librashader::runtime::{FilterChainParameters, Size, Viewport}; use librashader::runtime::{FilterChainParameters, Size, Viewport};
/// Direct3D 12 parameters for the source image. /// Direct3D 12 parameters for the source image.

View file

@ -3,7 +3,9 @@ use crate::ctypes::{
}; };
use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError}; use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError};
use crate::ffi::extern_fn; use crate::ffi::extern_fn;
use librashader::runtime::gl::{FilterChain, FilterChainOptions, FrameOptions, GLFramebuffer, GLImage}; use librashader::runtime::gl::{
FilterChain, FilterChainOptions, FrameOptions, GLFramebuffer, GLImage,
};
use std::ffi::CStr; use std::ffi::CStr;
use std::ffi::{c_char, c_void, CString}; use std::ffi::{c_char, c_void, CString};
use std::mem::MaybeUninit; use std::mem::MaybeUninit;

View file

@ -3,7 +3,9 @@ use crate::ctypes::{
}; };
use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError}; use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError};
use crate::ffi::extern_fn; use crate::ffi::extern_fn;
use librashader::runtime::vk::{FrameOptions, FilterChainOptions, FilterChain, VulkanImage, VulkanInstance}; use librashader::runtime::vk::{
FilterChain, FilterChainOptions, FrameOptions, VulkanImage, VulkanInstance,
};
use std::ffi::CStr; use std::ffi::CStr;
use std::ffi::{c_char, c_void}; use std::ffi::{c_char, c_void};
use std::mem::MaybeUninit; use std::mem::MaybeUninit;

View file

@ -379,7 +379,6 @@ pub(crate) fn apply_context(path: &mut PathBuf, context: &FxHashMap<String, Stri
Component::Normal(path) => { Component::Normal(path) => {
let haystack = path.as_encoded_bytes(); let haystack = path.as_encoded_bytes();
let replaced = let replaced =
WILDCARD_REGEX.replace_all(haystack, |caps: &regex::bytes::Captures| { WILDCARD_REGEX.replace_all(haystack, |caps: &regex::bytes::Captures| {
let Some(name) = caps.get(1) else { let Some(name) = caps.get(1) else {

View file

@ -11,11 +11,11 @@
#![allow(stable_features)] #![allow(stable_features)]
#![allow(unstable_name_collisions)] #![allow(unstable_name_collisions)]
pub mod context;
mod error; mod error;
mod extract_if; mod extract_if;
mod parse; mod parse;
mod preset; mod preset;
pub mod context;
pub use context::WildcardContext; pub use context::WildcardContext;
pub use error::*; pub use error::*;

View file

@ -10,8 +10,8 @@ mod value;
pub(crate) type Span<'a> = LocatedSpan<&'a str>; pub(crate) type Span<'a> = LocatedSpan<&'a str>;
pub(crate) use token::Token; pub(crate) use token::Token;
use crate::error::ParsePresetError;
use crate::context::{VideoDriver, WildcardContext}; use crate::context::{VideoDriver, WildcardContext};
use crate::error::ParsePresetError;
use crate::parse::preset::resolve_values; use crate::parse::preset::resolve_values;
use crate::parse::value::parse_preset; use crate::parse::value::parse_preset;
use crate::ShaderPreset; use crate::ShaderPreset;

View file

@ -171,7 +171,7 @@ pub fn do_lex(input: &str) -> Result<Vec<Token>, ParsePresetError> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::parse::token::{single_comment}; use crate::parse::token::single_comment;
#[test] #[test]
fn parses_single_line_comment() { fn parses_single_line_comment() {

View file

@ -17,8 +17,8 @@ use std::io::Read;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
use crate::extract_if::MakeExtractIf;
use crate::context::{apply_context, WildcardContext}; use crate::context::{apply_context, WildcardContext};
use crate::extract_if::MakeExtractIf;
#[derive(Debug)] #[derive(Debug)]
pub enum Value { pub enum Value {
@ -615,8 +615,8 @@ pub fn parse_values(
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::parse::value::parse_preset; use crate::parse::value::parse_preset;
use std::path::PathBuf;
use crate::WildcardContext; use crate::WildcardContext;
use std::path::PathBuf;
#[test] #[test]
pub fn parse_basic() { pub fn parse_basic() {

View file

@ -44,3 +44,4 @@ dxil = ["cross", "spirv-to-dxil"]
wgsl = ["cross", "naga", "spirv", "rspirv"] wgsl = ["cross", "naga", "spirv", "rspirv"]
cross = [ "spirv_cross", "spirv_cross/glsl", "spirv_cross/hlsl" ] cross = [ "spirv_cross", "spirv_cross/glsl", "spirv_cross/hlsl" ]
serialize = [ "serde" ] serialize = [ "serde" ]
msl = [ "cross", "naga" ]

View file

@ -2,8 +2,8 @@ use crate::back::targets::{GLSL, HLSL};
use crate::back::{CompileShader, CompilerBackend, FromCompilation}; use crate::back::{CompileShader, CompilerBackend, FromCompilation};
use crate::error::ShaderReflectError; use crate::error::ShaderReflectError;
use crate::front::SpirvCompilation; use crate::front::SpirvCompilation;
use crate::reflect::cross::{CompiledProgram, GlslReflect, HlslReflect}; use crate::reflect::cross::{CompiledProgram, GlslReflect, HlslReflect, SpirvCross};
use crate::reflect::ReflectShader; use crate::reflect::{ReflectShader, ShaderOutputCompiler};
/// The GLSL version to target. /// The GLSL version to target.
pub use spirv_cross::glsl::Version as GlslVersion; pub use spirv_cross::glsl::Version as GlslVersion;
@ -29,8 +29,9 @@ impl FromCompilation<SpirvCompilation> for GLSL {
fn from_compilation( fn from_compilation(
compile: SpirvCompilation, compile: SpirvCompilation,
) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> { ) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> {
let backend = SpirvCross::<GLSL>::create_reflection(compile)?;
Ok(CompilerBackend { Ok(CompilerBackend {
backend: GlslReflect::try_from(&compile)?, backend,
}) })
} }
} }
@ -52,7 +53,7 @@ impl FromCompilation<SpirvCompilation> for HLSL {
compile: SpirvCompilation, compile: SpirvCompilation,
) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> { ) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> {
Ok(CompilerBackend { Ok(CompilerBackend {
backend: HlslReflect::try_from(&compile)?, backend: SpirvCross::<HLSL>::create_reflection(compile)?,
}) })
} }
} }

View file

@ -10,7 +10,7 @@ use crate::back::targets::{OutputTarget, DXIL};
use crate::error::{ShaderCompileError, ShaderReflectError}; use crate::error::{ShaderCompileError, ShaderReflectError};
use crate::front::SpirvCompilation; use crate::front::SpirvCompilation;
use crate::reflect::cross::GlslReflect; use crate::reflect::cross::GlslReflect;
use crate::reflect::ReflectShader; use crate::reflect::{ReflectShader, ShaderOutputCompiler};
impl OutputTarget for DXIL { impl OutputTarget for DXIL {
type Output = DxilObject; type Output = DxilObject;
@ -26,7 +26,7 @@ impl FromCompilation<SpirvCompilation> for DXIL {
fn from_compilation( fn from_compilation(
compile: SpirvCompilation, compile: SpirvCompilation,
) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> { ) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> {
let reflect = GlslReflect::try_from(&compile)?; let reflect = GlslReflect::new().create_reflection(compile)?;
let vertex = compile.vertex; let vertex = compile.vertex;
let fragment = compile.fragment; let fragment = compile.fragment;
Ok(CompilerBackend { Ok(CompilerBackend {

View file

@ -1,17 +1,16 @@
pub mod cross; pub mod cross;
#[cfg(all(target_os = "windows", feature = "dxil"))] #[cfg(all(target_os = "windows", feature = "dxil"))]
pub mod dxil; pub mod dxil;
mod msl;
mod spirv; mod spirv;
pub mod targets; pub mod targets;
pub mod wgsl; pub mod wgsl;
mod msl;
use crate::back::targets::OutputTarget; use crate::back::targets::OutputTarget;
use crate::error::{ShaderCompileError, ShaderReflectError}; use crate::error::{ShaderCompileError, ShaderReflectError};
use crate::reflect::semantics::ShaderSemantics; use crate::reflect::semantics::ShaderSemantics;
use crate::reflect::{ReflectShader, ShaderReflection}; use crate::reflect::{ReflectShader, ShaderReflection};
use std::fmt::Debug; use std::fmt::Debug;
use crate::front::ShaderReflectObject;
/// The output of the shader compiler. /// The output of the shader compiler.
#[derive(Debug)] #[derive(Debug)]

View file

@ -0,0 +1 @@

View file

@ -1,17 +1,13 @@
mod lower_samplers;
use crate::back::targets::WGSL; use crate::back::targets::WGSL;
use crate::back::wgsl::lower_samplers::LowerCombinedImageSamplerPass;
use crate::back::{CompileShader, CompilerBackend, FromCompilation, ShaderCompilerOutput}; use crate::back::{CompileShader, CompilerBackend, FromCompilation, ShaderCompilerOutput};
use crate::error::{ShaderCompileError, ShaderReflectError}; use crate::error::{ShaderCompileError, ShaderReflectError};
use crate::front::SpirvCompilation; use crate::front::SpirvCompilation;
use crate::reflect::naga::NagaReflect; use crate::reflect::naga::{Naga, NagaReflect};
use crate::reflect::ReflectShader; use crate::reflect::{ReflectShader, ShaderOutputCompiler};
use naga::back::wgsl::WriterFlags; use naga::back::wgsl::WriterFlags;
use naga::valid::{Capabilities, ValidationFlags}; use naga::valid::{Capabilities, ValidationFlags};
use naga::{AddressSpace, Module}; use naga::{AddressSpace, Module};
use rspirv::binary::Assemble; use rspirv::binary::Assemble;
use rspirv::dr::Builder;
/// The context for a WGSL compilation via Naga /// The context for a WGSL compilation via Naga
pub struct NagaWgslContext { pub struct NagaWgslContext {
@ -36,36 +32,8 @@ impl FromCompilation<SpirvCompilation> for WGSL {
fn from_compilation( fn from_compilation(
compile: SpirvCompilation, compile: SpirvCompilation,
) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> { ) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> {
fn lower_fragment_shader(words: &[u32]) -> Vec<u32> {
let mut loader = rspirv::dr::Loader::new();
rspirv::binary::parse_words(words, &mut loader).unwrap();
let module = loader.module();
let mut builder = Builder::new_from_module(module);
let mut pass = LowerCombinedImageSamplerPass::new(&mut builder);
pass.ensure_op_type_sampler();
pass.do_pass();
let module = builder.module();
module.assemble()
}
let options = naga::front::spv::Options {
adjust_coordinate_space: true,
strict_capabilities: false,
block_ctx_dump_prefix: None,
};
let vertex =
naga::front::spv::parse_u8_slice(bytemuck::cast_slice(&compile.vertex), &options)?;
let fragment = lower_fragment_shader(&compile.fragment);
let fragment = naga::front::spv::parse_u8_slice(bytemuck::cast_slice(&fragment), &options)?;
Ok(CompilerBackend { Ok(CompilerBackend {
backend: NagaReflect { vertex, fragment }, backend: Naga::create_reflection(compile)?,
}) })
} }
} }

View file

@ -2,9 +2,9 @@ use crate::error::ShaderCompileError;
use glslang::{CompilerOptions, ShaderInput}; use glslang::{CompilerOptions, ShaderInput};
use librashader_preprocess::ShaderSource; use librashader_preprocess::ShaderSource;
use crate::front::{ShaderInputCompiler, SpirvCompilation};
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::front::{ShaderInputCompiler, SpirvCompilation};
/// glslang compiler /// glslang compiler
pub struct Glslang; pub struct Glslang;
@ -15,9 +15,7 @@ impl ShaderInputCompiler<SpirvCompilation> for Glslang {
} }
} }
pub(crate) fn compile_spirv( pub(crate) fn compile_spirv(source: &ShaderSource) -> Result<SpirvCompilation, ShaderCompileError> {
source: &ShaderSource,
) -> Result<SpirvCompilation, ShaderCompileError> {
let compiler = glslang::Compiler::acquire().ok_or(ShaderCompileError::CompilerInitError)?; let compiler = glslang::Compiler::acquire().ok_or(ShaderCompileError::CompilerInitError)?;
let options = CompilerOptions { let options = CompilerOptions {
source_language: glslang::SourceLanguage::GLSL, source_language: glslang::SourceLanguage::GLSL,

View file

@ -4,10 +4,7 @@ use serde::{Deserialize, Serialize};
mod glslang; mod glslang;
pub trait ShaderReflectObject: Sized {}
pub trait ShaderReflectObject : Sized {
}
pub use glslang::Glslang; pub use glslang::Glslang;
@ -17,7 +14,7 @@ pub trait ShaderInputCompiler<O: ShaderReflectObject>: Sized {
fn compile(source: &ShaderSource) -> Result<O, ShaderCompileError>; fn compile(source: &ShaderSource) -> Result<O, ShaderCompileError>;
} }
impl ShaderReflectObject for SpirvCompilation { } impl ShaderReflectObject for SpirvCompilation {}
/// A reflectable shader compilation via glslang. /// A reflectable shader compilation via glslang.
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -41,4 +38,3 @@ impl TryFrom<&ShaderSource> for SpirvCompilation {
Glslang::compile(source) Glslang::compile(source)
} }
} }

View file

@ -1,3 +1,5 @@
use std::borrow::Borrow;
use std::marker::PhantomData;
use crate::error::{SemanticsErrorKind, ShaderCompileError, ShaderReflectError}; use crate::error::{SemanticsErrorKind, ShaderCompileError, ShaderReflectError};
use crate::front::SpirvCompilation; use crate::front::SpirvCompilation;
use crate::reflect::semantics::{ use crate::reflect::semantics::{
@ -6,23 +8,72 @@ use crate::reflect::semantics::{
UniformMemberBlock, UniqueSemanticMap, UniqueSemantics, ValidateTypeSemantics, VariableMeta, UniformMemberBlock, UniqueSemanticMap, UniqueSemantics, ValidateTypeSemantics, VariableMeta,
MAX_BINDINGS_COUNT, MAX_PUSH_BUFFER_SIZE, MAX_BINDINGS_COUNT, MAX_PUSH_BUFFER_SIZE,
}; };
use crate::reflect::{align_uniform_size, ReflectShader}; use crate::reflect::{align_uniform_size, ReflectShader, ShaderOutputCompiler};
use std::ops::Deref; use std::ops::Deref;
use spirv_cross::spirv::{Ast, Decoration, Module, Resource, ShaderResources, Type}; use spirv_cross::spirv::{Ast, Decoration, Module, Resource, ShaderResources, Type};
use spirv_cross::{glsl, hlsl, ErrorCode}; use spirv_cross::{glsl, hlsl, ErrorCode};
use crate::back::cross::{CrossGlslContext, CrossHlslContext, HlslShaderModel}; use crate::back::cross::{CrossGlslContext, CrossHlslContext, HlslShaderModel};
use crate::back::targets::{GLSL, HLSL}; use crate::back::targets::{GLSL, HLSL, OutputTarget};
use crate::back::{CompileShader, ShaderCompilerOutput}; use crate::back::{CompileShader, ShaderCompilerOutput};
use crate::reflect::helper::{SemanticErrorBlame, TextureData, UboData}; use crate::reflect::helper::{SemanticErrorBlame, TextureData, UboData};
pub trait SpirvCrossTarget {
type CrossTarget: spirv_cross::spirv::Target;
}
impl SpirvCrossTarget for HLSL {
type CrossTarget = spirv_cross::hlsl::Target;
}
impl SpirvCrossTarget for GLSL {
type CrossTarget = spirv_cross::glsl::Target;
}
pub struct SpirvCross<T: OutputTarget + SpirvCrossTarget>(PhantomData<T>);
pub(crate) type HlslReflect = CrossReflect<hlsl::Target>;
pub(crate) type GlslReflect = CrossReflect<glsl::Target>;
impl<T: OutputTarget + SpirvCrossTarget, Opt, Ctx>
ShaderOutputCompiler<SpirvCompilation, T, Opt, Ctx> for SpirvCross<T>
// where Spv: spirv_cross::spirv::Target,
// Ast<Spv>: spirv_cross::spirv::Compile<Spv>,
// Ast<Spv>: spirv_cross::spirv::Parse<Spv>,
where CrossReflect<<T as SpirvCrossTarget>::CrossTarget>
: CompileShader<T, Options = Opt, Context=Ctx>,
<T as SpirvCrossTarget>::CrossTarget: spirv_cross::spirv::Target,
Ast<<T as SpirvCrossTarget>::CrossTarget>: spirv_cross::spirv::Compile<<T as SpirvCrossTarget>::CrossTarget>,
Ast<<T as SpirvCrossTarget>::CrossTarget>: spirv_cross::spirv::Parse<<T as SpirvCrossTarget>::CrossTarget>,
{
fn create_reflection(compiled: SpirvCompilation)
-> Result<impl ReflectShader + CompileShader<T, Options = Opt, Context = Ctx>,
ShaderReflectError> {
let compiled = compiled.borrow();
let vertex_module = Module::from_words(&compiled.vertex);
let fragment_module = Module::from_words(&compiled.fragment);
let vertex = Ast::<T::CrossTarget>::parse(&vertex_module)?;
let fragment = Ast::<T::CrossTarget>::parse(&fragment_module)?;
Ok(CrossReflect { vertex, fragment })
}
}
// This is "probably" OK. // This is "probably" OK.
unsafe impl<T: Send + spirv_cross::spirv::Target> Send for CrossReflect<T> {} unsafe impl<T: Send + spirv_cross::spirv::Target> Send for CrossReflect<T>
where Ast<T>: spirv_cross::spirv::Compile<T>,
Ast<T>: spirv_cross::spirv::Parse<T>,
{}
pub(crate) struct CrossReflect<T> pub(crate) struct CrossReflect<T>
where where
T: spirv_cross::spirv::Target, T: spirv_cross::spirv::Target,
Ast<T>: spirv_cross::spirv::Compile<T>,
Ast<T>: spirv_cross::spirv::Parse<T>,
{ {
vertex: Ast<T>, vertex: Ast<T>,
fragment: Ast<T>, fragment: Ast<T>,
@ -49,8 +100,7 @@ where
pub fragment: CompiledAst<T>, pub fragment: CompiledAst<T>,
} }
pub(crate) type HlslReflect = CrossReflect<hlsl::Target>;
pub(crate) type GlslReflect = CrossReflect<glsl::Target>;
impl ValidateTypeSemantics<Type> for UniqueSemantics { impl ValidateTypeSemantics<Type> for UniqueSemantics {
fn validate_type(&self, ty: &Type) -> Option<TypeInfo> { fn validate_type(&self, ty: &Type) -> Option<TypeInfo> {

View file

@ -1,3 +1,4 @@
use std::borrow::Borrow;
use crate::error::ShaderReflectError; use crate::error::ShaderReflectError;
use semantics::ShaderSemantics; use semantics::ShaderSemantics;
@ -12,9 +13,19 @@ pub mod presets;
mod helper; mod helper;
#[cfg(feature = "wgsl")] #[cfg(feature = "naga")]
pub mod naga; pub mod naga;
pub trait ShaderOutputCompiler<O: ShaderReflectObject, T: OutputTarget, Opt, Ctx> {
/// Create the reflection object
fn create_reflection(
compiled: O,
) -> Result<
impl ReflectShader + CompileShader<T, Options = Opt, Context = Ctx>,
ShaderReflectError,
>;
}
/// A trait for compilation outputs that can provide reflection information. /// A trait for compilation outputs that can provide reflection information.
pub trait ReflectShader { pub trait ReflectShader {
/// Reflect the shader as the given pass within the shader preset, against the provided /// Reflect the shader as the given pass within the shader preset, against the provided
@ -26,6 +37,9 @@ pub trait ReflectShader {
) -> Result<ShaderReflection, ShaderReflectError>; ) -> Result<ShaderReflection, ShaderReflectError>;
} }
use crate::back::targets::OutputTarget;
use crate::back::CompileShader;
use crate::front::ShaderReflectObject;
pub use semantics::ShaderReflection; pub use semantics::ShaderReflection;
#[inline(always)] #[inline(always)]

View file

@ -1,9 +1,17 @@
mod lower_samplers;
use std::borrow::Borrow;
use crate::error::{SemanticsErrorKind, ShaderReflectError}; use crate::error::{SemanticsErrorKind, ShaderReflectError};
use crate::back::targets::OutputTarget;
use crate::back::CompileShader;
use crate::front::SpirvCompilation;
use naga::{ use naga::{
AddressSpace, Binding, GlobalVariable, Handle, ImageClass, Module, ResourceBinding, Scalar, AddressSpace, Binding, GlobalVariable, Handle, ImageClass, Module, ResourceBinding, Scalar,
ScalarKind, TypeInner, VectorSize, ScalarKind, TypeInner, VectorSize,
}; };
use rspirv::binary::Assemble;
use rspirv::dr::Builder;
use crate::reflect::helper::{SemanticErrorBlame, TextureData, UboData}; use crate::reflect::helper::{SemanticErrorBlame, TextureData, UboData};
use crate::reflect::semantics::{ use crate::reflect::semantics::{
@ -12,7 +20,57 @@ use crate::reflect::semantics::{
UniqueSemanticMap, UniqueSemantics, ValidateTypeSemantics, VariableMeta, MAX_BINDINGS_COUNT, UniqueSemanticMap, UniqueSemantics, ValidateTypeSemantics, VariableMeta, MAX_BINDINGS_COUNT,
MAX_PUSH_BUFFER_SIZE, MAX_PUSH_BUFFER_SIZE,
}; };
use crate::reflect::{align_uniform_size, ReflectShader, ShaderReflection}; use crate::reflect::{align_uniform_size, ReflectShader, ShaderOutputCompiler, ShaderReflection};
/// Represents the naga output compiler.
///
/// The Naga reflector will lower combined image samplers to split,
/// with the same bind point on descriptor group 1.
pub struct Naga;
impl<T: OutputTarget, Opt, Ctx> ShaderOutputCompiler<SpirvCompilation, T, Opt, Ctx> for Naga
where
NagaReflect: CompileShader<T, Options = Opt, Context = Ctx>,
{
fn create_reflection(
compile: SpirvCompilation,
) -> Result<
impl ReflectShader + CompileShader<T, Options = Opt, Context = Ctx>,
ShaderReflectError
> {
fn lower_fragment_shader(words: &[u32]) -> Vec<u32> {
let mut loader = rspirv::dr::Loader::new();
rspirv::binary::parse_words(words, &mut loader).unwrap();
let module = loader.module();
let mut builder = Builder::new_from_module(module);
let mut pass = lower_samplers::LowerCombinedImageSamplerPass::new(&mut builder);
pass.ensure_op_type_sampler();
pass.do_pass();
let module = builder.module();
module.assemble()
}
let compile = compile.borrow();
let options = naga::front::spv::Options {
adjust_coordinate_space: true,
strict_capabilities: false,
block_ctx_dump_prefix: None,
};
let vertex =
naga::front::spv::parse_u8_slice(bytemuck::cast_slice(&compile.vertex), &options)?;
let fragment = lower_fragment_shader(&compile.fragment);
let fragment = naga::front::spv::parse_u8_slice(bytemuck::cast_slice(&fragment), &options)?;
Ok(NagaReflect { vertex, fragment })
}
}
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct NagaReflect { pub(crate) struct NagaReflect {

View file

@ -1,7 +1,7 @@
use crate::back::targets::OutputTarget; use crate::back::targets::OutputTarget;
use crate::back::{CompilerBackend, FromCompilation}; use crate::back::{CompilerBackend, FromCompilation};
use crate::error::{ShaderCompileError, ShaderReflectError}; use crate::error::{ShaderCompileError, ShaderReflectError};
use crate::front::{ShaderInputCompiler, ShaderReflectObject, SpirvCompilation}; use crate::front::{ShaderInputCompiler, ShaderReflectObject};
use crate::reflect::semantics::{ use crate::reflect::semantics::{
Semantic, ShaderSemantics, TextureSemantics, UniformSemantic, UniqueSemantics, Semantic, ShaderSemantics, TextureSemantics, UniformSemantic, UniqueSemantics,
}; };

View file

@ -73,8 +73,7 @@ pub(crate) struct FilterCommon {
pub(crate) draw_quad: DrawQuad, pub(crate) draw_quad: DrawQuad,
} }
type ShaderPassMeta = type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<HLSL, SpirvCompilation> + Send>;
ShaderPassArtifact<impl CompileReflectShader<HLSL, SpirvCompilation> + Send>;
fn compile_passes( fn compile_passes(
shaders: Vec<ShaderPassConfig>, shaders: Vec<ShaderPassConfig>,
textures: &[TextureConfig], textures: &[TextureConfig],
@ -85,7 +84,9 @@ fn compile_passes(
shaders, &textures, shaders, &textures,
)? )?
} else { } else {
HLSL::compile_preset_passes::<Glslang, SpirvCompilation, FilterChainError>(shaders, &textures)? HLSL::compile_preset_passes::<Glslang, SpirvCompilation, FilterChainError>(
shaders, &textures,
)?
}; };
Ok((passes, semantics)) Ok((passes, semantics))

View file

@ -3,6 +3,7 @@ use crate::descriptor_heap::{
CpuStagingHeap, D3D12DescriptorHeap, D3D12DescriptorHeapSlot, RenderTargetHeap, CpuStagingHeap, D3D12DescriptorHeap, D3D12DescriptorHeapSlot, RenderTargetHeap,
ResourceWorkHeap, ResourceWorkHeap,
}; };
use crate::draw_quad::DrawQuad;
use crate::error::FilterChainError; use crate::error::FilterChainError;
use crate::filter_pass::FilterPass; use crate::filter_pass::FilterPass;
use crate::framebuffer::OwnedImage; use crate::framebuffer::OwnedImage;
@ -10,7 +11,6 @@ use crate::graphics_pipeline::{D3D12GraphicsPipeline, D3D12RootSignature};
use crate::luts::LutTexture; use crate::luts::LutTexture;
use crate::mipmap::D3D12MipmapGen; use crate::mipmap::D3D12MipmapGen;
use crate::options::{FilterChainOptionsD3D12, FrameOptionsD3D12}; use crate::options::{FilterChainOptionsD3D12, FrameOptionsD3D12};
use crate::draw_quad::DrawQuad;
use crate::samplers::SamplerSet; use crate::samplers::SamplerSet;
use crate::texture::{D3D12InputImage, D3D12OutputView, InputTexture, OutputDescriptor}; use crate::texture::{D3D12InputImage, D3D12OutputView, InputTexture, OutputDescriptor};
use crate::{error, util}; use crate::{error, util};
@ -156,7 +156,9 @@ fn compile_passes_dxil(
shaders, &textures, shaders, &textures,
)? )?
} else { } else {
DXIL::compile_preset_passes::<Glslang, SpirvCompilation, FilterChainError>(shaders, &textures)? DXIL::compile_preset_passes::<Glslang, SpirvCompilation, FilterChainError>(
shaders, &textures,
)?
}; };
Ok((passes, semantics)) Ok((passes, semantics))
@ -173,7 +175,9 @@ fn compile_passes_hlsl(
shaders, &textures, shaders, &textures,
)? )?
} else { } else {
HLSL::compile_preset_passes::<Glslang, SpirvCompilation, FilterChainError>(shaders, &textures)? HLSL::compile_preset_passes::<Glslang, SpirvCompilation, FilterChainError>(
shaders, &textures,
)?
}; };
Ok((passes, semantics)) Ok((passes, semantics))

View file

@ -1,6 +1,6 @@
use crate::draw_quad::DrawQuad;
use crate::error::assume_d3d12_init; use crate::error::assume_d3d12_init;
use crate::error::FilterChainError::Direct3DOperationError; use crate::error::FilterChainError::Direct3DOperationError;
use crate::draw_quad::DrawQuad;
use crate::{error, util}; use crate::{error, util};
use librashader_cache::{cache_pipeline, cache_shader_object}; use librashader_cache::{cache_pipeline, cache_shader_object};
use librashader_reflect::back::cross::CrossHlslContext; use librashader_reflect::back::cross::CrossHlslContext;

View file

@ -5,6 +5,7 @@
mod buffer; mod buffer;
mod descriptor_heap; mod descriptor_heap;
mod draw_quad;
mod filter_chain; mod filter_chain;
mod filter_pass; mod filter_pass;
mod framebuffer; mod framebuffer;
@ -12,7 +13,6 @@ mod graphics_pipeline;
mod luts; mod luts;
mod mipmap; mod mipmap;
mod parameters; mod parameters;
mod draw_quad;
mod samplers; mod samplers;
mod texture; mod texture;
mod util; mod util;

View file

@ -108,7 +108,9 @@ fn compile_passes(
shaders, &textures, shaders, &textures,
)? )?
} else { } else {
GLSL::compile_preset_passes::<Glslang, SpirvCompilation, FilterChainError>(shaders, &textures)? GLSL::compile_preset_passes::<Glslang, SpirvCompilation, FilterChainError>(
shaders, &textures,
)?
}; };
Ok((passes, semantics)) Ok((passes, semantics))

View file

@ -207,19 +207,22 @@ impl Drop for FrameResiduals {
} }
} }
type ShaderPassMeta = type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<SPIRV, SpirvCompilation> + Send>;
ShaderPassArtifact<impl CompileReflectShader<SPIRV, SpirvCompilation> + Send>;
fn compile_passes( fn compile_passes(
shaders: Vec<ShaderPassConfig>, shaders: Vec<ShaderPassConfig>,
textures: &[TextureConfig], textures: &[TextureConfig],
disable_cache: bool, disable_cache: bool,
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> { ) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
let (passes, semantics) = if !disable_cache { let (passes, semantics) = if !disable_cache {
SPIRV::compile_preset_passes::<Glslang, CachedCompilation<SpirvCompilation>, FilterChainError>( SPIRV::compile_preset_passes::<
Glslang,
CachedCompilation<SpirvCompilation>,
FilterChainError,
>(shaders, &textures)?
} else {
SPIRV::compile_preset_passes::<Glslang, SpirvCompilation, FilterChainError>(
shaders, &textures, shaders, &textures,
)? )?
} else {
SPIRV::compile_preset_passes::<Glslang, SpirvCompilation, FilterChainError>(shaders, &textures)?
}; };
Ok((passes, semantics)) Ok((passes, semantics))

View file

@ -37,14 +37,15 @@ use crate::options::{FilterChainOptionsWgpu, FrameOptionsWgpu};
use crate::samplers::SamplerSet; use crate::samplers::SamplerSet;
use crate::texture::{InputImage, OwnedImage}; use crate::texture::{InputImage, OwnedImage};
type ShaderPassMeta = type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<WGSL, SpirvCompilation> + Send>;
ShaderPassArtifact<impl CompileReflectShader<WGSL, SpirvCompilation> + Send>;
fn compile_passes( fn compile_passes(
shaders: Vec<ShaderPassConfig>, shaders: Vec<ShaderPassConfig>,
textures: &[TextureConfig], textures: &[TextureConfig],
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> { ) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
let (passes, semantics) = let (passes, semantics) =
WGSL::compile_preset_passes::<Glslang, SpirvCompilation, FilterChainError>(shaders, &textures)?; WGSL::compile_preset_passes::<Glslang, SpirvCompilation, FilterChainError>(
shaders, &textures,
)?;
Ok((passes, semantics)) Ok((passes, semantics))
} }