test: add CLI with multiple functions
This commit is contained in:
parent
bac09ad2a3
commit
5573f13227
5 changed files with 555 additions and 4 deletions
107
Cargo.lock
generated
107
Cargo.lock
generated
|
@ -251,6 +251,12 @@ version = "0.13.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "2.0.0-rc.3"
|
||||
|
@ -296,6 +302,9 @@ name = "bitflags"
|
|||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
|
@ -678,7 +687,7 @@ dependencies = [
|
|||
"lazy_static",
|
||||
"nom",
|
||||
"pathdiff",
|
||||
"ron",
|
||||
"ron 0.7.1",
|
||||
"rust-ini",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -790,6 +799,12 @@ version = "0.8.20"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
|
@ -977,6 +992,12 @@ dependencies = [
|
|||
"miniz_oxide 0.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.5.0"
|
||||
|
@ -1230,6 +1251,17 @@ dependencies = [
|
|||
"bitflags 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crunchy",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "halfbrown"
|
||||
version = "0.2.5"
|
||||
|
@ -1481,6 +1513,12 @@ dependencies = [
|
|||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
||||
|
||||
[[package]]
|
||||
name = "librashader"
|
||||
version = "0.4.5"
|
||||
|
@ -1577,6 +1615,7 @@ dependencies = [
|
|||
"librashader-common",
|
||||
"nom",
|
||||
"rayon",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
|
@ -1800,8 +1839,10 @@ dependencies = [
|
|||
"objc2-metal",
|
||||
"parking_lot",
|
||||
"pollster",
|
||||
"ron 0.8.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"spq-spvasm",
|
||||
"wgpu",
|
||||
"wgpu-types",
|
||||
"windows 0.58.0",
|
||||
|
@ -2091,6 +2132,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2267,6 +2309,15 @@ dependencies = [
|
|||
"libredox 0.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "4.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d501f1a72f71d3c063a6bbc8f7271fa73aa09fe5d6283b6571e2ed176a2537"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-multimap"
|
||||
version = "0.4.3"
|
||||
|
@ -2684,11 +2735,23 @@ version = "0.7.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"base64 0.13.1",
|
||||
"bitflags 1.3.2",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bitflags 2.6.0",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rspirv"
|
||||
version = "0.12.0+sdk-1.3.268.0"
|
||||
|
@ -2908,6 +2971,19 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spirq"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5ab05ab7b72dbb729fe1831a7e4b717b0d18f552c8b2dc9fb06b85878a017a6"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
"ordered-float",
|
||||
"spq-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spirv"
|
||||
version = "0.3.0+sdk-1.3.268.0"
|
||||
|
@ -2978,6 +3054,33 @@ dependencies = [
|
|||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spq-core"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "605fb8ae60065f7a9d21d1ae1e89f7a5ff93ca7755df88ada937ac06ba0a0a43"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytemuck",
|
||||
"fnv",
|
||||
"half",
|
||||
"num-traits",
|
||||
"ordered-float",
|
||||
"spirv",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spq-spvasm"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e703e41f4ae2b3081129430559e5a0a0420a4de624c050a6d58b76e9b632b742"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"half",
|
||||
"num-traits",
|
||||
"spirq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sptr"
|
||||
version = "0.3.2"
|
||||
|
|
|
@ -11,7 +11,7 @@ name = "librashader-cli"
|
|||
path = "src/cli/main.rs"
|
||||
|
||||
[dependencies]
|
||||
librashader = { version = "0.4.5", path = "../librashader", features = ["presets", "serde"], default-features = false }
|
||||
librashader = { version = "0.4.5", path = "../librashader", features = ["presets", "preprocess", "serde"], default-features = false }
|
||||
librashader-runtime = { version = "0.4.5", path = "../librashader-runtime"}
|
||||
wgpu = { version = "22", default-features = false, optional = true }
|
||||
wgpu-types = { version = "22", optional = true }
|
||||
|
@ -32,6 +32,8 @@ ash = { workspace = true, optional = true }
|
|||
clap = { workspace = true }
|
||||
serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
spq-spvasm = "0.1.4"
|
||||
ron = "0.8.1"
|
||||
|
||||
[features]
|
||||
default = ["full"]
|
||||
|
|
445
librashader-test/src/cli/main.rs
Normal file
445
librashader-test/src/cli/main.rs
Normal file
|
@ -0,0 +1,445 @@
|
|||
use anyhow::anyhow;
|
||||
use clap::{Parser, Subcommand};
|
||||
use image::codecs::png::PngEncoder;
|
||||
use librashader::presets::context::ContextItem;
|
||||
use librashader::presets::{ShaderPreset, WildcardContext};
|
||||
use librashader::reflect::cross::{GlslVersion, HlslShaderModel, MslVersion, SpirvCross};
|
||||
use librashader::reflect::naga::{Naga, NagaLoweringOptions};
|
||||
use librashader::reflect::semantics::{ ShaderSemantics};
|
||||
use librashader::reflect::{CompileShader, FromCompilation, ReflectShader, SpirvCompilation};
|
||||
use librashader_test::render::RenderTest;
|
||||
use std::path::{Path, PathBuf};
|
||||
use ron::ser::PrettyConfig;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(version, about)]
|
||||
struct Args {
|
||||
#[command(subcommand)]
|
||||
command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum Commands {
|
||||
/// Render a shader preset against an image
|
||||
Render {
|
||||
/// The frame to render.
|
||||
#[arg(short, long, default_value_t = 60)]
|
||||
frame: usize,
|
||||
/// The path to the shader preset to load.
|
||||
#[arg(short, long)]
|
||||
preset: PathBuf,
|
||||
/// The path to the input image.
|
||||
#[arg(short, long)]
|
||||
image: PathBuf,
|
||||
/// The path to the output image.
|
||||
///
|
||||
/// If `-`, writes the image in PNG format to stdout.
|
||||
#[arg(short, long)]
|
||||
out: PathBuf,
|
||||
/// The runtime to use to render the shader preset.
|
||||
#[arg(value_enum, short, long)]
|
||||
runtime: Runtime,
|
||||
},
|
||||
/// Compare two runtimes and get a similarity score between the two
|
||||
/// runtimes rendering the same frame
|
||||
Compare {
|
||||
/// The frame to render.
|
||||
#[arg(short, long, default_value_t = 60)]
|
||||
frame: usize,
|
||||
/// The path to the shader preset to load.
|
||||
#[arg(short, long)]
|
||||
preset: PathBuf,
|
||||
/// The path to the input image.
|
||||
#[arg(short, long)]
|
||||
image: PathBuf,
|
||||
/// The runtime to compare against
|
||||
#[arg(value_enum, short, long)]
|
||||
left: Runtime,
|
||||
/// The runtime to compare to
|
||||
#[arg(value_enum, short, long)]
|
||||
right: Runtime,
|
||||
/// The path to write the similarity image.
|
||||
///
|
||||
/// If `-`, writes the image to stdout.
|
||||
#[arg(short, long)]
|
||||
out: Option<PathBuf>,
|
||||
},
|
||||
/// Parse a preset and get a JSON representation of the data.
|
||||
Parse {
|
||||
/// The path to the shader preset to load.
|
||||
#[arg(short, long)]
|
||||
preset: PathBuf,
|
||||
/// Additional wildcard options, comma separated with equals signs. The PRESET and PRESET_DIR
|
||||
/// wildcards are always added to the preset parsing context.
|
||||
///
|
||||
/// For example, CONTENT-DIR=MyVerticalGames,GAME=mspacman
|
||||
#[arg(short, long, value_delimiter = ',', num_args = 1..)]
|
||||
wildcards: Option<Vec<String>>,
|
||||
},
|
||||
/// Get the raw GLSL output of a preprocessed shader.
|
||||
Preprocess {
|
||||
/// The path to the slang shader.
|
||||
#[arg(short, long)]
|
||||
shader: PathBuf,
|
||||
/// The item to output.
|
||||
///
|
||||
/// `json` will print a JSON representation of the preprocessed shader.
|
||||
#[arg(value_enum, short, long)]
|
||||
output: PreprocessOutput,
|
||||
},
|
||||
/// Transpile a shader in a given preset to the given format.
|
||||
Transpile {
|
||||
/// The path to the slang shader.
|
||||
#[arg(short, long)]
|
||||
shader: PathBuf,
|
||||
|
||||
/// The shader stage to output.
|
||||
#[arg(value_enum, short = 'o', long)]
|
||||
stage: TranspileStage,
|
||||
|
||||
/// The output format.
|
||||
#[arg(value_enum, short, long)]
|
||||
format: TranspileFormat,
|
||||
|
||||
/// The version of the output format to parse as.
|
||||
/// This could be a GLSL version, a shader model, or an MSL version.
|
||||
#[arg(short, long)]
|
||||
version: Option<String>,
|
||||
},
|
||||
/// Reflect the shader relative to a preset, giving information about semantics used in a slang shader.
|
||||
///
|
||||
/// Due to limitations
|
||||
Reflect {
|
||||
/// The path to the shader preset to load.
|
||||
#[arg(short, long)]
|
||||
preset: PathBuf,
|
||||
/// Additional wildcard options, comma separated with equals signs. The PRESET and PRESET_DIR
|
||||
/// wildcards are always added to the preset parsing context.
|
||||
///
|
||||
/// For example, CONTENT-DIR=MyVerticalGames,GAME=mspacman
|
||||
#[arg(short, long, value_delimiter = ',', num_args = 1..)]
|
||||
wildcards: Option<Vec<String>>,
|
||||
|
||||
/// The pass index to use.
|
||||
#[arg(short, long)]
|
||||
index: usize,
|
||||
|
||||
#[arg(value_enum, short, long, default_value = "cross")]
|
||||
backend: ReflectionBackend,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(clap::ValueEnum, Clone, Debug)]
|
||||
enum PreprocessOutput {
|
||||
#[clap(name = "fragment")]
|
||||
Fragment,
|
||||
#[clap(name = "vertex")]
|
||||
Vertex,
|
||||
#[clap(name = "params")]
|
||||
Params,
|
||||
#[clap(name = "passformat")]
|
||||
Format,
|
||||
#[clap(name = "json")]
|
||||
Json,
|
||||
}
|
||||
|
||||
#[derive(clap::ValueEnum, Clone, Debug)]
|
||||
enum TranspileStage {
|
||||
#[clap(name = "fragment")]
|
||||
Fragment,
|
||||
#[clap(name = "vertex")]
|
||||
Vertex,
|
||||
}
|
||||
|
||||
#[derive(clap::ValueEnum, Clone, Debug)]
|
||||
enum TranspileFormat {
|
||||
#[clap(name = "glsl")]
|
||||
GLSL,
|
||||
#[clap(name = "hlsl")]
|
||||
HLSL,
|
||||
#[clap(name = "wgsl")]
|
||||
WGSL,
|
||||
#[clap(name = "msl")]
|
||||
MSL,
|
||||
#[clap(name = "spirv")]
|
||||
SPIRV,
|
||||
}
|
||||
|
||||
#[derive(clap::ValueEnum, Clone, Debug)]
|
||||
enum Runtime {
|
||||
#[cfg(feature = "opengl")]
|
||||
#[clap(name = "opengl3")]
|
||||
OpenGL3,
|
||||
#[cfg(feature = "opengl")]
|
||||
#[clap(name = "opengl4")]
|
||||
OpenGL4,
|
||||
#[cfg(feature = "vulkan")]
|
||||
#[clap(name = "vulkan")]
|
||||
Vulkan,
|
||||
#[cfg(feature = "wgpu")]
|
||||
#[clap(name = "wgpu")]
|
||||
Wgpu,
|
||||
#[cfg(all(windows, feature = "d3d9"))]
|
||||
#[clap(name = "d3d9")]
|
||||
Direct3D9,
|
||||
#[cfg(all(windows, feature = "d3d11"))]
|
||||
#[clap(name = "d3d11")]
|
||||
Direct3D11,
|
||||
#[cfg(all(windows, feature = "d3d12"))]
|
||||
#[clap(name = "d3d12")]
|
||||
Direct3D12,
|
||||
#[cfg(all(target_vendor = "apple", feature = "metal"))]
|
||||
#[clap(name = "metal")]
|
||||
Metal,
|
||||
}
|
||||
|
||||
#[derive(clap::ValueEnum, Clone, Debug)]
|
||||
enum ReflectionBackend {
|
||||
#[clap(name = "cross")]
|
||||
SpirvCross,
|
||||
#[clap(name = "naga")]
|
||||
Naga,
|
||||
}
|
||||
|
||||
macro_rules! get_runtime {
|
||||
($rt:ident, $image:ident) => {
|
||||
match $rt {
|
||||
#[cfg(feature = "opengl")]
|
||||
Runtime::OpenGL3 => &mut librashader_test::render::gl::OpenGl3::new($image.as_path())?,
|
||||
#[cfg(feature = "opengl")]
|
||||
Runtime::OpenGL4 => &mut librashader_test::render::gl::OpenGl4::new($image.as_path())?,
|
||||
#[cfg(feature = "vulkan")]
|
||||
Runtime::Vulkan => &mut librashader_test::render::vk::Vulkan::new($image.as_path())?,
|
||||
#[cfg(feature = "wgpu")]
|
||||
Runtime::Wgpu => &mut librashader_test::render::wgpu::Wgpu::new($image.as_path())?,
|
||||
#[cfg(all(windows, feature = "d3d9"))]
|
||||
Runtime::Direct3D9 => {
|
||||
&mut librashader_test::render::d3d9::Direct3D9::new($image.as_path())?
|
||||
}
|
||||
#[cfg(all(windows, feature = "d3d11"))]
|
||||
Runtime::Direct3D11 => {
|
||||
&mut librashader_test::render::d3d11::Direct3D11::new($image.as_path())?
|
||||
}
|
||||
#[cfg(all(windows, feature = "d3d12"))]
|
||||
Runtime::Direct3D12 => {
|
||||
&mut librashader_test::render::d3d12::Direct3D12::new($image.as_path())?
|
||||
}
|
||||
#[cfg(all(target_vendor = "apple", feature = "metal"))]
|
||||
Runtime::Metal => &mut librashader_test::render::mtl::Metal::new($image.as_path())?,
|
||||
}
|
||||
};
|
||||
}
|
||||
pub fn main() -> Result<(), anyhow::Error> {
|
||||
let args = Args::parse();
|
||||
|
||||
match args.command {
|
||||
Commands::Render {
|
||||
frame,
|
||||
preset,
|
||||
image,
|
||||
out,
|
||||
runtime,
|
||||
} => {
|
||||
let test: &mut dyn RenderTest = get_runtime!(runtime, image);
|
||||
let image = test.render(preset.as_path(), frame)?;
|
||||
|
||||
if out.as_path() == Path::new("-") {
|
||||
let out = std::io::stdout();
|
||||
image.write_with_encoder(PngEncoder::new(out))?;
|
||||
} else {
|
||||
image.save(out)?;
|
||||
}
|
||||
}
|
||||
Commands::Compare {
|
||||
frame,
|
||||
preset,
|
||||
image,
|
||||
left,
|
||||
right,
|
||||
out,
|
||||
} => {
|
||||
let left: &mut dyn RenderTest = get_runtime!(left, image);
|
||||
let right: &mut dyn RenderTest = get_runtime!(right, image);
|
||||
|
||||
let left_image = left.render(preset.as_path(), frame)?;
|
||||
let right_image = right.render(preset.as_path(), frame)?;
|
||||
let similarity = image_compare::rgba_hybrid_compare(&left_image, &right_image)?;
|
||||
print!("{}", similarity.score);
|
||||
|
||||
if let Some(out) = out {
|
||||
let image = similarity.image.to_color_map();
|
||||
if out.as_path() == Path::new("-") {
|
||||
let out = std::io::stdout();
|
||||
image.write_with_encoder(PngEncoder::new(out))?;
|
||||
} else {
|
||||
image.save(out)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Commands::Parse { preset, wildcards } => {
|
||||
let preset = get_shader_preset(preset, wildcards)?;
|
||||
let out = serde_json::to_string_pretty(&preset)?;
|
||||
print!("{out:}");
|
||||
}
|
||||
Commands::Preprocess { shader, output } => {
|
||||
let source = librashader::preprocess::ShaderSource::load(shader.as_path())?;
|
||||
match output {
|
||||
PreprocessOutput::Fragment => print!("{}", source.fragment),
|
||||
PreprocessOutput::Vertex => print!("{}", source.vertex),
|
||||
PreprocessOutput::Params => {
|
||||
print!("{}", serde_json::to_string_pretty(&source.parameters)?)
|
||||
}
|
||||
PreprocessOutput::Format => print!("{:?}", source.format),
|
||||
PreprocessOutput::Json => print!("{}", serde_json::to_string_pretty(&source)?),
|
||||
}
|
||||
}
|
||||
Commands::Transpile {
|
||||
shader,
|
||||
stage,
|
||||
format,
|
||||
version,
|
||||
} => {
|
||||
let source = librashader::preprocess::ShaderSource::load(shader.as_path())?;
|
||||
let compilation = SpirvCompilation::try_from(&source)?;
|
||||
let output = match format {
|
||||
TranspileFormat::GLSL => {
|
||||
let compilation =
|
||||
librashader::reflect::targets::GLSL::from_compilation(compilation)?;
|
||||
let output = compilation.compile(GlslVersion::Glsl330)?;
|
||||
TranspileOutput {
|
||||
vertex: output.vertex,
|
||||
fragment: output.fragment,
|
||||
}
|
||||
}
|
||||
TranspileFormat::HLSL => {
|
||||
let compilation =
|
||||
librashader::reflect::targets::HLSL::from_compilation(compilation)?;
|
||||
let output = compilation.compile(Some(HlslShaderModel::ShaderModel5_0))?;
|
||||
TranspileOutput {
|
||||
vertex: output.vertex,
|
||||
fragment: output.fragment,
|
||||
}
|
||||
}
|
||||
TranspileFormat::WGSL => {
|
||||
let compilation =
|
||||
librashader::reflect::targets::WGSL::from_compilation(compilation)?;
|
||||
let output = compilation.compile(NagaLoweringOptions {
|
||||
write_pcb_as_ubo: true,
|
||||
sampler_bind_group: 1,
|
||||
})?;
|
||||
TranspileOutput {
|
||||
vertex: output.vertex,
|
||||
fragment: output.fragment,
|
||||
}
|
||||
}
|
||||
TranspileFormat::MSL => {
|
||||
let compilation = <librashader::reflect::targets::MSL as FromCompilation<
|
||||
SpirvCompilation,
|
||||
SpirvCross,
|
||||
>>::from_compilation(compilation)?;
|
||||
let output = compilation.compile(Some(MslVersion::new(1, 2, 0)))?;
|
||||
TranspileOutput {
|
||||
vertex: output.vertex,
|
||||
fragment: output.fragment,
|
||||
}
|
||||
}
|
||||
TranspileFormat::SPIRV => {
|
||||
let compilation = <librashader::reflect::targets::SPIRV as FromCompilation<
|
||||
SpirvCompilation,
|
||||
SpirvCross,
|
||||
>>::from_compilation(compilation)?;
|
||||
let output = compilation.compile(None)?;
|
||||
|
||||
TranspileOutput {
|
||||
vertex: spirv_to_dis(output.vertex)?,
|
||||
fragment: spirv_to_dis(output.fragment)?,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let print = match stage {
|
||||
TranspileStage::Fragment => output.fragment,
|
||||
TranspileStage::Vertex => output.vertex,
|
||||
};
|
||||
|
||||
print!("{print}")
|
||||
}
|
||||
Commands::Reflect {
|
||||
preset,
|
||||
wildcards,
|
||||
index,
|
||||
backend,
|
||||
} => {
|
||||
let preset = get_shader_preset(preset, wildcards)?;
|
||||
let Some(shader) = preset.shaders.get(index) else {
|
||||
return Err(anyhow!("Invalid pass index for the preset"));
|
||||
};
|
||||
|
||||
let source = librashader::preprocess::ShaderSource::load(shader.name.as_path())?;
|
||||
let compilation = SpirvCompilation::try_from(&source)?;
|
||||
|
||||
let semantics = ShaderSemantics::create_pass_semantics::<anyhow::Error>(&preset, index)?;
|
||||
|
||||
let reflection = match backend {
|
||||
ReflectionBackend::SpirvCross => {
|
||||
let mut compilation =
|
||||
<librashader::reflect::targets::SPIRV as FromCompilation<
|
||||
SpirvCompilation,
|
||||
SpirvCross,
|
||||
>>::from_compilation(compilation)?;
|
||||
compilation.reflect(index, &semantics)?
|
||||
}
|
||||
ReflectionBackend::Naga => {
|
||||
let mut compilation =
|
||||
<librashader::reflect::targets::SPIRV as FromCompilation<
|
||||
SpirvCompilation,
|
||||
Naga,
|
||||
>>::from_compilation(compilation)?;
|
||||
compilation.reflect(index, &semantics)?
|
||||
}
|
||||
};
|
||||
|
||||
print!("{}", ron::ser::to_string_pretty(&reflection, PrettyConfig::new())?);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct TranspileOutput {
|
||||
vertex: String,
|
||||
fragment: String,
|
||||
}
|
||||
|
||||
fn get_shader_preset(
|
||||
preset: PathBuf,
|
||||
wildcards: Option<Vec<String>>,
|
||||
) -> anyhow::Result<ShaderPreset> {
|
||||
let mut context = WildcardContext::new();
|
||||
context.add_path_defaults(preset.as_path());
|
||||
if let Some(wildcards) = wildcards {
|
||||
for string in wildcards {
|
||||
let Some((left, right)) = string.split_once("=") else {
|
||||
return Err(anyhow!("Encountered invalid context string {string}"));
|
||||
};
|
||||
|
||||
context.append_item(ContextItem::ExternContext(
|
||||
left.to_string(),
|
||||
right.to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
let preset = ShaderPreset::try_parse_with_context(preset, context)?;
|
||||
Ok(preset)
|
||||
}
|
||||
|
||||
fn spirv_to_dis(spirv: Vec<u32>) -> anyhow::Result<String> {
|
||||
let binary = spq_spvasm::SpirvBinary::from(spirv);
|
||||
spq_spvasm::Disassembler::new()
|
||||
.print_header(true)
|
||||
.name_ids(true)
|
||||
.name_type_ids(true)
|
||||
.name_const_ids(true)
|
||||
.indent(true)
|
||||
.disassemble(&binary)
|
||||
}
|
|
@ -84,7 +84,7 @@ full = ["runtime-all", "reflect-all", "preprocess", "presets"]
|
|||
# cache hack
|
||||
docsrs = ["librashader-cache/docsrs"]
|
||||
|
||||
serde = ["librashader-presets/serde"]
|
||||
serde = ["librashader-presets/serde", "librashader-preprocess/serde", "librashader-reflect/serde"]
|
||||
|
||||
# emits warning messages in tests
|
||||
github-ci = []
|
||||
|
|
|
@ -236,6 +236,7 @@ pub mod reflect {
|
|||
pub use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
|
||||
|
||||
pub use librashader_reflect::front::ShaderInputCompiler;
|
||||
|
||||
#[doc(hidden)]
|
||||
#[cfg(feature = "internal")]
|
||||
/// Helper methods for runtimes.
|
||||
|
|
Loading…
Add table
Reference in a new issue