diff --git a/CLI.md b/CLI.md index ccc3c4d..92ba626 100644 --- a/CLI.md +++ b/CLI.md @@ -233,7 +233,7 @@ will output the following JSON "shaders": [ { "id": 0, - "name": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-first-pass-linearize-crt-gamma-bob-fields.slang", + "path": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-first-pass-linearize-crt-gamma-bob-fields.slang", "alias": "ORIG_LINEARIZED", "filter": "Nearest", "wrap_mode": "ClampToBorder", @@ -259,7 +259,7 @@ will output the following JSON }, { "id": 1, - "name": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-vertical-interlacing.slang", + "path": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-vertical-interlacing.slang", "alias": "VERTICAL_SCANLINES", "filter": "Linear", "wrap_mode": "ClampToBorder", @@ -285,7 +285,7 @@ will output the following JSON }, { "id": 2, - "name": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-bloom-approx.slang", + "path": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-bloom-approx.slang", "alias": "BLOOM_APPROX", "filter": "Linear", "wrap_mode": "ClampToBorder", @@ -311,7 +311,7 @@ will output the following JSON }, { "id": 3, - "name": "/tmp/shaders_slang/blurs/shaders/royale/blur9fast-vertical.slang", + "path": "/tmp/shaders_slang/blurs/shaders/royale/blur9fast-vertical.slang", "alias": null, "filter": "Linear", "wrap_mode": "ClampToBorder", @@ -337,7 +337,7 @@ will output the following JSON }, { "id": 4, - "name": "/tmp/shaders_slang/blurs/shaders/royale/blur9fast-horizontal.slang", + "path": "/tmp/shaders_slang/blurs/shaders/royale/blur9fast-horizontal.slang", "alias": "HALATION_BLUR", "filter": "Linear", "wrap_mode": "ClampToBorder", @@ -363,7 +363,7 @@ will output the following JSON }, { "id": 5, - "name": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-mask-resize-vertical.slang", + "path": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-mask-resize-vertical.slang", "alias": null, "filter": "Linear", "wrap_mode": "ClampToBorder", @@ -389,7 +389,7 @@ will output the following JSON }, { "id": 6, - "name": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-mask-resize-horizontal.slang", + "path": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-mask-resize-horizontal.slang", "alias": "MASK_RESIZE", "filter": "Nearest", "wrap_mode": "ClampToBorder", @@ -415,7 +415,7 @@ will output the following JSON }, { "id": 7, - "name": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang", + "path": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang", "alias": "MASKED_SCANLINES", "filter": "Linear", "wrap_mode": "ClampToBorder", @@ -441,7 +441,7 @@ will output the following JSON }, { "id": 8, - "name": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-brightpass.slang", + "path": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-brightpass.slang", "alias": "BRIGHTPASS", "filter": "Linear", "wrap_mode": "ClampToBorder", @@ -467,7 +467,7 @@ will output the following JSON }, { "id": 9, - "name": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-bloom-vertical.slang", + "path": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-bloom-vertical.slang", "alias": null, "filter": "Linear", "wrap_mode": "ClampToBorder", @@ -493,7 +493,7 @@ will output the following JSON }, { "id": 10, - "name": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-bloom-horizontal-reconstitute.slang", + "path": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-bloom-horizontal-reconstitute.slang", "alias": null, "filter": "Linear", "wrap_mode": "ClampToBorder", @@ -519,7 +519,7 @@ will output the following JSON }, { "id": 11, - "name": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-geometry-aa-last-pass.slang", + "path": "/tmp/shaders_slang/crt/shaders/crt-royale/src/crt-royale-geometry-aa-last-pass.slang", "alias": null, "filter": "Linear", "wrap_mode": "ClampToEdge", @@ -955,3 +955,42 @@ The above command will output the following JSON } ``` + +## Serializing a preset pack to a single file + +``` +Create a serialized preset pack from a shader preset + +Usage: librashader-cli pack [OPTIONS] --preset --out --format + +Options: + -p, --preset + The path to the shader preset to load + + -w, --wildcards ... + 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 + + -o, --out + The path to write the output + + If `-`, writes the output to stdout + + -f, --format + The file format to output + + [possible values: json, msgpack] + + -h, --help + Print help (see a summary with '-h') + +``` + +The `pack` command can be used to create a "preset pack", a format to store an entire shader preset, including files and preprocessed source code, +into a JSON or MessagePack representation where it can be loaded into memory without filesystem access. + +This file format is experimental, and may be used in the future as a way to cache shader presets, or for usages in environments without a filesystem, +such as on the web. Note that packs are only supported by the librashader Rust API, and are not portable across other implementations of "slang" shaders. + +It is unlikely that the librashader C API will ever support loading shader packs. \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 87d219b..d4e33cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1606,6 +1606,7 @@ dependencies = [ "objc2-metal", "parking_lot", "pollster", + "rmp-serde", "serde", "serde_json", "spq-spvasm", diff --git a/librashader-cli/Cargo.toml b/librashader-cli/Cargo.toml index f27e197..f6e33f8 100644 --- a/librashader-cli/Cargo.toml +++ b/librashader-cli/Cargo.toml @@ -35,6 +35,8 @@ serde = "1.0" serde_json = "1.0" spq-spvasm = "0.1.4" +rmp-serde = "1.3.0" + [features] default = ["full"] diff --git a/librashader-cli/src/cli/main.rs b/librashader-cli/src/cli/main.rs index 5c779ce..9ed2e6d 100644 --- a/librashader-cli/src/cli/main.rs +++ b/librashader-cli/src/cli/main.rs @@ -2,7 +2,7 @@ use anyhow::anyhow; use clap::{Parser, Subcommand}; use image::codecs::png::PngEncoder; use librashader::presets::context::ContextItem; -use librashader::presets::{ShaderPreset, WildcardContext}; +use librashader::presets::{ShaderPreset, ShaderPresetPack, WildcardContext}; use librashader::reflect::cross::{GlslVersion, HlslShaderModel, MslVersion, SpirvCross}; use librashader::reflect::naga::{Naga, NagaLoweringOptions}; use librashader::reflect::semantics::ShaderSemantics; @@ -10,6 +10,8 @@ use librashader::reflect::{CompileShader, FromCompilation, ReflectShader, SpirvC use librashader::{FastHashMap, ShortString}; use librashader_runtime::parameters::RuntimeParameters; use librashader_test::render::{CommonFrameOptions, RenderTest}; +use std::fs::File; +use std::io::Write; use std::path::{Path, PathBuf}; /// Helpers and utilities to reflect and debug 'slang' shaders and presets. @@ -126,6 +128,19 @@ enum Commands { #[clap(flatten)] preset: PresetArgs, }, + /// Create a serialized preset pack from a shader preset. + Pack { + #[clap(flatten)] + preset: PresetArgs, + /// The path to write the output + /// + /// If `-`, writes the output to stdout + #[arg(short, long)] + out: PathBuf, + /// The file format to output. + #[arg(value_enum, short, long)] + format: PackFormat, + }, /// Get the raw GLSL output of a preprocessed shader. Preprocess { /// The path to the slang shader. @@ -213,6 +228,14 @@ enum TranspileFormat { SPIRV, } +#[derive(clap::ValueEnum, Clone, Debug)] +enum PackFormat { + #[clap(name = "json")] + JSON, + #[clap(name = "msgpack")] + MsgPack, +} + #[derive(clap::ValueEnum, Clone, Debug)] enum Runtime { #[cfg(feature = "opengl")] @@ -517,6 +540,27 @@ pub fn main() -> Result<(), anyhow::Error> { print!("{}", serde_json::to_string_pretty(&reflection)?); } + Commands::Pack { + preset, + out, + format, + } => { + let PresetArgs { preset, wildcards } = preset; + let preset = get_shader_preset(preset, wildcards)?; + let preset = ShaderPresetPack::load_from_preset::(preset)?; + let output_bytes = match format { + PackFormat::JSON => serde_json::to_vec_pretty(&preset)?, + PackFormat::MsgPack => rmp_serde::to_vec(&preset)?, + }; + + if out.as_path() == Path::new("-") { + let mut out = std::io::stdout(); + out.write_all(output_bytes.as_slice())?; + } else { + let mut file = File::create(out.as_path())?; + file.write_all(output_bytes.as_slice())?; + } + } } Ok(())