Merge pull request #37 from SnowflakePowered/preset-context

Preset context
This commit is contained in:
Ronny Chan 2024-02-09 18:29:11 -05:00 committed by GitHub
commit b9a6b869e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 2769 additions and 916 deletions

223
Cargo.lock generated
View file

@ -108,54 +108,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "anstream"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
[[package]]
name = "anstyle-parse"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "array-concat" name = "array-concat"
version = "0.5.2" version = "0.5.2"
@ -404,9 +356,9 @@ checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205"
[[package]] [[package]]
name = "bytemuck" name = "bytemuck"
version = "1.14.2" version = "1.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea31d69bda4949c1c1562c1e6f042a1caefac98cdc8a298260a2ff41c1e2d42b" checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f"
dependencies = [ dependencies = [
"bytemuck_derive", "bytemuck_derive",
] ]
@ -538,36 +490,30 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.4.18" version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" checksum = "aa91278560fc226a5d9d736cc21e485ff9aad47d26b8ffe1f54cba868b684b9f"
dependencies = [ dependencies = [
"clap_builder", "bitflags 1.3.2",
"clap_derive", "clap_derive",
] "clap_lex 0.3.3",
"is-terminal",
[[package]] "once_cell",
name = "clap_builder"
version = "4.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
dependencies = [
"anstream",
"anstyle",
"clap_lex 0.6.0",
"strsim", "strsim",
"termcolor",
] ]
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.4.7" version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.48", "syn 1.0.109",
] ]
[[package]] [[package]]
@ -581,9 +527,12 @@ dependencies = [
[[package]] [[package]]
name = "clap_lex" name = "clap_lex"
version = "0.6.0" version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" checksum = "033f6b7a4acb1f358c742aaca805c939ee73b4c6209ae4318ec7aca81c42e646"
dependencies = [
"os_str_bytes",
]
[[package]] [[package]]
name = "cmake" name = "cmake"
@ -656,12 +605,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colorchoice"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]] [[package]]
name = "com" name = "com"
version = "0.6.0" version = "0.6.0"
@ -1355,9 +1298,9 @@ dependencies = [
[[package]] [[package]]
name = "glslang-sys" name = "glslang-sys"
version = "0.3.1" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d76f2d75ad6e8a12c26e77ed6443a9369ef7957daf361e751c3489a97f8b816" checksum = "6a47e052f086ec9b43df0bca02c1675c2a89bceb5386dd64382dc36143930985"
dependencies = [ dependencies = [
"cc", "cc",
"glob", "glob",
@ -1591,12 +1534,12 @@ dependencies = [
[[package]] [[package]]
name = "is-terminal" name = "is-terminal"
version = "0.4.10" version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" checksum = "fe8f25ce1159c7740ff0b9b2f5cdf4a8428742ba7c112b9f20f22cd5219c7dab"
dependencies = [ dependencies = [
"hermit-abi 0.3.5", "hermit-abi 0.3.5",
"rustix", "libc",
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
@ -1630,9 +1573,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]] [[package]]
name = "jobserver" name = "jobserver"
version = "0.1.27" version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -1723,13 +1666,13 @@ dependencies = [
[[package]] [[package]]
name = "librashader" name = "librashader"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
dependencies = [ dependencies = [
"ash", "ash",
"librashader-cache", "librashader-cache",
"librashader-common 0.2.0-beta.7", "librashader-common 0.2.0-beta.8",
"librashader-preprocess", "librashader-preprocess",
"librashader-presets 0.2.0-beta.7", "librashader-presets 0.2.0-beta.8",
"librashader-reflect", "librashader-reflect",
"librashader-runtime", "librashader-runtime",
"librashader-runtime-d3d11", "librashader-runtime-d3d11",
@ -1747,12 +1690,12 @@ name = "librashader-build-script"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"cbindgen", "cbindgen",
"clap 4.4.18", "clap 4.1.0",
] ]
[[package]] [[package]]
name = "librashader-cache" name = "librashader-cache"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
dependencies = [ dependencies = [
"bincode", "bincode",
"blake3", "blake3",
@ -1768,7 +1711,7 @@ dependencies = [
[[package]] [[package]]
name = "librashader-capi" name = "librashader-capi"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
dependencies = [ dependencies = [
"ash", "ash",
"gl", "gl",
@ -1791,7 +1734,7 @@ dependencies = [
[[package]] [[package]]
name = "librashader-common" name = "librashader-common"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
dependencies = [ dependencies = [
"ash", "ash",
"gl", "gl",
@ -1802,11 +1745,11 @@ dependencies = [
[[package]] [[package]]
name = "librashader-preprocess" name = "librashader-preprocess"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
dependencies = [ dependencies = [
"encoding_rs", "encoding_rs",
"glob", "glob",
"librashader-common 0.2.0-beta.7", "librashader-common 0.2.0-beta.8",
"librashader-presets 0.1.4", "librashader-presets 0.1.4",
"nom", "nom",
"rayon", "rayon",
@ -1829,27 +1772,32 @@ dependencies = [
[[package]] [[package]]
name = "librashader-presets" name = "librashader-presets"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
dependencies = [ dependencies = [
"glob", "glob",
"librashader-common 0.2.0-beta.7", "librashader-common 0.2.0-beta.8",
"nom", "nom",
"nom_locate", "nom_locate",
"num-traits", "num-traits",
"once_cell",
"os_str_bytes",
"regex",
"rustc-hash",
"rustversion",
"thiserror", "thiserror",
] ]
[[package]] [[package]]
name = "librashader-reflect" name = "librashader-reflect"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
dependencies = [ dependencies = [
"bitflags 2.4.2", "bitflags 2.4.2",
"bytemuck", "bytemuck",
"glslang", "glslang",
"indexmap 2.2.2", "indexmap 2.2.2",
"librashader-common 0.2.0-beta.7", "librashader-common 0.2.0-beta.8",
"librashader-preprocess", "librashader-preprocess",
"librashader-presets 0.2.0-beta.7", "librashader-presets 0.2.0-beta.8",
"librashader-spirv-cross", "librashader-spirv-cross",
"matches", "matches",
"naga", "naga",
@ -1863,13 +1811,13 @@ dependencies = [
[[package]] [[package]]
name = "librashader-runtime" name = "librashader-runtime"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"image", "image",
"librashader-common 0.2.0-beta.7", "librashader-common 0.2.0-beta.8",
"librashader-preprocess", "librashader-preprocess",
"librashader-presets 0.2.0-beta.7", "librashader-presets 0.2.0-beta.8",
"librashader-reflect", "librashader-reflect",
"num-traits", "num-traits",
"rustc-hash", "rustc-hash",
@ -1877,15 +1825,15 @@ dependencies = [
[[package]] [[package]]
name = "librashader-runtime-d3d11" name = "librashader-runtime-d3d11"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
dependencies = [ dependencies = [
"array-concat", "array-concat",
"bytemuck", "bytemuck",
"gfx-maths", "gfx-maths",
"librashader-cache", "librashader-cache",
"librashader-common 0.2.0-beta.7", "librashader-common 0.2.0-beta.8",
"librashader-preprocess", "librashader-preprocess",
"librashader-presets 0.2.0-beta.7", "librashader-presets 0.2.0-beta.8",
"librashader-reflect", "librashader-reflect",
"librashader-runtime", "librashader-runtime",
"librashader-spirv-cross", "librashader-spirv-cross",
@ -1897,7 +1845,7 @@ dependencies = [
[[package]] [[package]]
name = "librashader-runtime-d3d12" name = "librashader-runtime-d3d12"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
dependencies = [ dependencies = [
"array-concat", "array-concat",
"array-init", "array-init",
@ -1905,9 +1853,9 @@ dependencies = [
"bytemuck", "bytemuck",
"gfx-maths", "gfx-maths",
"librashader-cache", "librashader-cache",
"librashader-common 0.2.0-beta.7", "librashader-common 0.2.0-beta.8",
"librashader-preprocess", "librashader-preprocess",
"librashader-presets 0.2.0-beta.7", "librashader-presets 0.2.0-beta.8",
"librashader-reflect", "librashader-reflect",
"librashader-runtime", "librashader-runtime",
"librashader-spirv-cross", "librashader-spirv-cross",
@ -1921,15 +1869,15 @@ dependencies = [
[[package]] [[package]]
name = "librashader-runtime-gl" name = "librashader-runtime-gl"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"gl", "gl",
"glfw 0.47.0", "glfw 0.47.0",
"librashader-cache", "librashader-cache",
"librashader-common 0.2.0-beta.7", "librashader-common 0.2.0-beta.8",
"librashader-preprocess", "librashader-preprocess",
"librashader-presets 0.2.0-beta.7", "librashader-presets 0.2.0-beta.8",
"librashader-reflect", "librashader-reflect",
"librashader-runtime", "librashader-runtime",
"librashader-spirv-cross", "librashader-spirv-cross",
@ -1941,7 +1889,7 @@ dependencies = [
[[package]] [[package]]
name = "librashader-runtime-vk" name = "librashader-runtime-vk"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
dependencies = [ dependencies = [
"ash", "ash",
"ash-window", "ash-window",
@ -1949,9 +1897,9 @@ dependencies = [
"glfw 0.49.1", "glfw 0.49.1",
"gpu-allocator 0.22.0", "gpu-allocator 0.22.0",
"librashader-cache", "librashader-cache",
"librashader-common 0.2.0-beta.7", "librashader-common 0.2.0-beta.8",
"librashader-preprocess", "librashader-preprocess",
"librashader-presets 0.2.0-beta.7", "librashader-presets 0.2.0-beta.8",
"librashader-reflect", "librashader-reflect",
"librashader-runtime", "librashader-runtime",
"librashader-spirv-cross", "librashader-spirv-cross",
@ -1966,16 +1914,16 @@ dependencies = [
[[package]] [[package]]
name = "librashader-runtime-wgpu" name = "librashader-runtime-wgpu"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
dependencies = [ dependencies = [
"array-concat", "array-concat",
"bytemuck", "bytemuck",
"config", "config",
"env_logger", "env_logger",
"image", "image",
"librashader-common 0.2.0-beta.7", "librashader-common 0.2.0-beta.8",
"librashader-preprocess", "librashader-preprocess",
"librashader-presets 0.2.0-beta.7", "librashader-presets 0.2.0-beta.8",
"librashader-reflect", "librashader-reflect",
"librashader-runtime", "librashader-runtime",
"log", "log",
@ -2497,6 +2445,9 @@ name = "os_str_bytes"
version = "6.6.1" version = "6.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "owned_ttf_parser" name = "owned_ttf_parser"
@ -2682,6 +2633,30 @@ dependencies = [
"toml_edit 0.21.1", "toml_edit 0.21.1",
] ]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn 1.0.109",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.78" version = "1.0.78"
@ -2923,6 +2898,12 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.16" version = "1.0.16"
@ -2980,7 +2961,7 @@ dependencies = [
"ab_glyph", "ab_glyph",
"log", "log",
"memmap2 0.9.4", "memmap2 0.9.4",
"smithay-client-toolkit 0.18.0", "smithay-client-toolkit 0.18.1",
"tiny-skia 0.11.4", "tiny-skia 0.11.4",
] ]
@ -3098,9 +3079,9 @@ dependencies = [
[[package]] [[package]]
name = "smithay-client-toolkit" name = "smithay-client-toolkit"
version = "0.18.0" version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60e3d9941fa3bacf7c2bf4b065304faa14164151254cd16ce1b1bc8fc381600f" checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a"
dependencies = [ dependencies = [
"bitflags 2.4.2", "bitflags 2.4.2",
"calloop 0.12.4", "calloop 0.12.4",
@ -3425,12 +3406,6 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]] [[package]]
name = "vcpkg" name = "vcpkg"
version = "0.2.15" version = "0.2.15"
@ -4221,7 +4196,7 @@ dependencies = [
"redox_syscall 0.3.5", "redox_syscall 0.3.5",
"rustix", "rustix",
"sctk-adwaita 0.8.1", "sctk-adwaita 0.8.1",
"smithay-client-toolkit 0.18.0", "smithay-client-toolkit 0.18.1",
"smol_str", "smol_str",
"unicode-segmentation", "unicode-segmentation",
"wasm-bindgen", "wasm-bindgen",

File diff suppressed because it is too large Load diff

View file

@ -92,6 +92,72 @@ int32_t __librashader__noop_error_write(libra_error_t error, char **out) {
int32_t __librashader__noop_error_free_string(char **out) { return 1; } int32_t __librashader__noop_error_free_string(char **out) { return 1; }
libra_error_t __librashader__noop_preset_ctx_create(libra_preset_ctx_t *out) {
*out = NULL;
return NULL;
}
libra_error_t __librashader__noop_preset_ctx_free(libra_preset_ctx_t *context) {
return NULL;
}
libra_error_t __librashader__noop_preset_ctx_set_core_name(
libra_preset_ctx_t *context, const char *name) {
return NULL;
}
libra_error_t __librashader__noop_preset_ctx_set_content_dir(
libra_preset_ctx_t *context, const char *name) {
return NULL;
}
libra_error_t __librashader__noop_preset_ctx_set_param(
libra_preset_ctx_t *context, const char *name, const char *value) {
return NULL;
}
libra_error_t __librashader__noop_preset_ctx_set_runtime(
libra_preset_ctx_t *context, LIBRA_PRESET_CTX_RUNTIME value) {
return NULL;
}
libra_error_t __librashader__noop_preset_ctx_set_core_rotation(
libra_preset_ctx_t *context, uint32_t value) {
return NULL;
}
libra_error_t __librashader__noop_preset_ctx_set_user_rotation(
libra_preset_ctx_t *context, uint32_t value) {
return NULL;
}
libra_error_t __librashader__noop_preset_ctx_set_screen_orientation(
libra_preset_ctx_t *context, uint32_t value) {
return NULL;
}
libra_error_t __librashader__noop_preset_ctx_set_allow_rotation(
libra_preset_ctx_t *context, bool value) {
return NULL;
}
libra_error_t __librashader__noop_preset_ctx_set_view_aspect_orientation(
libra_preset_ctx_t *context, LIBRA_PRESET_CTX_ORIENTATION value) {
return NULL;
}
libra_error_t __librashader__noop_preset_ctx_set_core_aspect_orientation(
libra_preset_ctx_t *context, LIBRA_PRESET_CTX_ORIENTATION value) {
return NULL;
}
libra_error_t __librashader__noop_preset_create_with_context(
const char *filename, libra_preset_ctx_t *context,
libra_shader_preset_t *out) {
*out = NULL;
return NULL;
}
libra_error_t __librashader__noop_preset_create(const char *filename, libra_error_t __librashader__noop_preset_create(const char *filename,
libra_shader_preset_t *out) { libra_shader_preset_t *out) {
*out = NULL; *out = NULL;
@ -119,7 +185,8 @@ libra_error_t __librashader__noop_preset_get_runtime_params(
libra_shader_preset_t *preset, struct libra_preset_param_list_t *out) { libra_shader_preset_t *preset, struct libra_preset_param_list_t *out) {
return NULL; return NULL;
} }
libra_error_t __librashader__noop_preset_free_runtime_params(struct libra_preset_param_list_t out) { libra_error_t __librashader__noop_preset_free_runtime_params(
struct libra_preset_param_list_t out) {
return NULL; return NULL;
} }
#if defined(LIBRA_RUNTIME_OPENGL) #if defined(LIBRA_RUNTIME_OPENGL)
@ -228,7 +295,8 @@ libra_error_t __librashader__noop_d3d11_filter_chain_create(
} }
libra_error_t __librashader__noop_d3d11_filter_chain_create_deferred( libra_error_t __librashader__noop_d3d11_filter_chain_create_deferred(
libra_shader_preset_t *preset, ID3D11Device *device, ID3D11DeviceContext *device_context, libra_shader_preset_t *preset, ID3D11Device *device,
ID3D11DeviceContext *device_context,
const struct filter_chain_d3d11_opt_t *options, const struct filter_chain_d3d11_opt_t *options,
libra_d3d11_filter_chain_t *out) { libra_d3d11_filter_chain_t *out) {
*out = NULL; *out = NULL;
@ -236,11 +304,10 @@ libra_error_t __librashader__noop_d3d11_filter_chain_create_deferred(
} }
libra_error_t __librashader__noop_d3d11_filter_chain_frame( libra_error_t __librashader__noop_d3d11_filter_chain_frame(
libra_d3d11_filter_chain_t *chain, libra_d3d11_filter_chain_t *chain, ID3D11DeviceContext *device_context,
ID3D11DeviceContext *device_context, size_t frame_count, size_t frame_count, struct libra_source_image_d3d11_t image,
struct libra_source_image_d3d11_t image, struct libra_viewport_t viewport, struct libra_viewport_t viewport, ID3D11RenderTargetView *out,
ID3D11RenderTargetView *out, const float *mvp, const float *mvp, const struct frame_d3d11_opt_t *opt) {
const struct frame_d3d11_opt_t *opt) {
return NULL; return NULL;
} }
@ -270,7 +337,6 @@ libra_error_t __librashader__noop_d3d11_filter_chain_get_active_pass_count(
} }
#endif #endif
#if defined(LIBRA_RUNTIME_D3D12) #if defined(LIBRA_RUNTIME_D3D12)
libra_error_t __librashader__noop_d3d12_filter_chain_create( libra_error_t __librashader__noop_d3d12_filter_chain_create(
libra_shader_preset_t *preset, ID3D12Device *device, libra_shader_preset_t *preset, ID3D12Device *device,
@ -290,11 +356,10 @@ libra_error_t __librashader__noop_d3d12_filter_chain_create_deferred(
} }
libra_error_t __librashader__noop_d3d12_filter_chain_frame( libra_error_t __librashader__noop_d3d12_filter_chain_frame(
libra_d3d12_filter_chain_t *chain, libra_d3d12_filter_chain_t *chain, ID3D12GraphicsCommandList *command_list,
ID3D12GraphicsCommandList *command_list, size_t frame_count, size_t frame_count, struct libra_source_image_d3d12_t image,
struct libra_source_image_d3d12_t image, struct libra_viewport_t viewport, struct libra_viewport_t viewport, struct libra_output_image_d3d12_t out,
struct libra_output_image_d3d12_t out, const float *mvp, const float *mvp, const struct frame_d3d12_opt_t *opt) {
const struct frame_d3d12_opt_t *opt) {
return NULL; return NULL;
} }
@ -335,6 +400,151 @@ typedef struct libra_instance_t {
/// The null instance has API version 0. /// The null instance has API version 0.
PFN_libra_instance_api_version instance_api_version; PFN_libra_instance_api_version instance_api_version;
/// Create a wildcard context
///
/// The C API does not allow directly setting certain variables
///
/// - `PRESET_DIR` and `PRESET` are inferred on preset creation.
/// - `VID-DRV-SHADER-EXT` and `VID-DRV-PRESET-EXT` are always set to
/// `slang` and `slangp` for librashader.
/// - `VID-FINAL-ROT` is automatically calculated as the sum of
/// `VID-USER-ROT` and `CORE-REQ-ROT` if either are present.
///
/// These automatically inferred variables, as well as all other variables
/// can be overridden with `libra_preset_ctx_set_param`, but the expected
/// string values must be provided. See
/// https://github.com/libretro/RetroArch/pull/15023 for a list of expected
/// string values.
///
/// No variables can be removed once added to the context, however
/// subsequent calls to set the same variable will overwrite the expected
/// variable.
/// ## Safety
/// - `out` must be either null, or an aligned pointer to an uninitialized
/// or invalid `libra_preset_ctx_t`.
/// ## Returns
/// - If any parameters are null, `out` is unchanged, and this function
/// returns `LIBRA_ERR_INVALID_PARAMETER`.
PFN_libra_preset_ctx_create preset_ctx_create;
/// Free the wildcard context.
///
/// If `context` is null, this function does nothing. The resulting value in
/// `context` then becomes null.
///
/// ## Safety
/// - `context` must be a valid and aligned pointer to a
/// `libra_preset_ctx_t`
PFN_libra_preset_ctx_free preset_ctx_free;
/// Set the core name (`CORE`) variable in the context
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a
/// `libra_preset_ctx_t`.
/// - `name` must be null or a valid and aligned pointer to a string.
PFN_libra_preset_ctx_set_core_name preset_ctx_set_core_name;
/// Set the content directory (`CONTENT-DIR`) variable in the context.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a
/// `libra_preset_ctx_t`.
/// - `name` must be null or a valid and aligned pointer to a string.
PFN_libra_preset_ctx_set_content_dir preset_ctx_set_content_dir;
/// Set a custom string variable in context.
///
/// If the path contains this variable when loading a preset, it will be
/// replaced with the provided contents.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a
/// `libra_preset_ctx_t`.
/// - `name` must be null or a valid and aligned pointer to a string.
/// - `value` must be null or a valid and aligned pointer to a string.
PFN_libra_preset_ctx_set_param preset_ctx_set_param;
/// Set the graphics runtime (`VID-DRV`) variable in the context.
///
/// Note that librashader only supports the following runtimes.
///
/// - Vulkan
/// - GLCore
/// - Direct3D11
/// - Direct3D12
///
/// This will also set the appropriate video driver extensions.
///
/// For librashader, `VID-DRV-SHADER-EXT` and `VID-DRV-PRESET-EXT` are
/// always `slang` and `slangp`. To override this, use
/// `libra_preset_ctx_set_param`.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a
/// `libra_preset_ctx_t`.
/// - `name` must be null or a valid and aligned pointer to a string.
PFN_libra_preset_ctx_set_runtime preset_ctx_set_runtime;
/// Set the core requested rotation (`CORE-REQ-ROT`) variable in the
/// context.
///
/// Rotation is represented by quarter rotations around the unit circle.
/// For example. `0` = 0deg, `1` = 90deg, `2` = 180deg, `3` = 270deg, `4` =
/// 0deg.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a
/// `libra_preset_ctx_t`.
PFN_libra_preset_ctx_set_core_rotation preset_ctx_set_core_rotation;
/// Set the user rotation (`VID-USER-ROT`) variable in the context.
///
/// Rotation is represented by quarter rotations around the unit circle.
/// For example. `0` = 0deg, `1` = 90deg, `2` = 180deg, `3` = 270deg, `4` =
/// 0deg.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a
/// `libra_preset_ctx_t`.
PFN_libra_preset_ctx_set_user_rotation preset_ctx_set_user_rotation;
/// Set the screen orientation (`SCREEN-ORIENT`) variable in the context.
///
/// Orientation is represented by quarter rotations around the unit circle.
/// For example. `0` = 0deg, `1` = 90deg, `2` = 180deg, `3` = 270deg, `4` =
/// 0deg.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a
/// `libra_preset_ctx_t`.
PFN_libra_preset_ctx_set_screen_orientation
preset_ctx_set_screen_orientation;
/// Set whether or not to allow rotation (`VID-ALLOW-CORE-ROT`) variable in
/// the context.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a
/// `libra_preset_ctx_t`.
PFN_libra_preset_ctx_set_allow_rotation preset_ctx_set_allow_rotation;
/// Set the view aspect orientation (`VIEW-ASPECT-ORIENT`) variable in the
/// context.
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a
/// `libra_preset_ctx_t`.
PFN_libra_preset_ctx_set_view_aspect_orientation
preset_ctx_set_view_aspect_orientation;
/// Set the core aspect orientation (`CORE-ASPECT-ORIENT`) variable in the
/// context.
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a
/// `libra_preset_ctx_t`.
PFN_libra_preset_ctx_set_core_aspect_orientation
preset_ctx_set_core_aspect_orientation;
/// Load a preset. /// Load a preset.
/// ///
/// If this function is not loaded, `out` will unconditionally be set to /// If this function is not loaded, `out` will unconditionally be set to
@ -351,6 +561,26 @@ typedef struct libra_instance_t {
/// returns `LIBRA_ERR_INVALID_PARAMETER`. /// returns `LIBRA_ERR_INVALID_PARAMETER`.
PFN_libra_preset_create preset_create; PFN_libra_preset_create preset_create;
/// Load a preset with the given wildcard context.
///
/// The wildcard context is immediately invalidated and must be recreated
/// after the preset is created.
///
/// Path information variables `PRESET_DIR` and `PRESET` will automatically
/// be filled in.
/// ## Safety
/// - `filename` must be either null or a valid, aligned pointer to a
/// string path to the shader preset.
/// - `context` must be either null or a valid, aligned pointer to a
/// initialized `libra_preset_ctx_t`.
/// - `context` is invalidated after this function returns.
/// - `out` must be either null, or an aligned pointer to an uninitialized
/// or invalid `libra_shader_preset_t`.
/// ## Returns
/// - If any parameters are null, `out` is unchanged, and this function
/// returns `LIBRA_ERR_INVALID_PARAMETER`.
PFN_libra_preset_create_with_context preset_create_with_context;
/// Free the preset. /// Free the preset.
/// ///
/// If `preset` is null, this function does nothing. The resulting value in /// If `preset` is null, this function does nothing. The resulting value in
@ -425,7 +655,6 @@ typedef struct libra_instance_t {
/// result in undefined behaviour. /// result in undefined behaviour.
PFN_libra_preset_free_runtime_params preset_free_runtime_params; PFN_libra_preset_free_runtime_params preset_free_runtime_params;
/// Get the error code corresponding to this error object. /// Get the error code corresponding to this error object.
/// ///
/// ## Safety /// ## Safety
@ -473,7 +702,8 @@ typedef struct libra_instance_t {
/// Initialize the OpenGL Context for librashader. /// Initialize the OpenGL Context for librashader.
/// ///
/// ## Safety /// ## Safety
/// Attempting to create a filter chain will fail if the context is not initialized. /// Attempting to create a filter chain will fail if the context is not
/// initialized.
/// ///
/// Reinitializing the OpenGL context with a different loader immediately /// Reinitializing the OpenGL context with a different loader immediately
/// invalidates previous filter chain objects, and drawing with them causes /// invalidates previous filter chain objects, and drawing with them causes
@ -717,7 +947,8 @@ typedef struct libra_instance_t {
/// ///
/// If the context is immediate, then access to the immediate context /// If the context is immediate, then access to the immediate context
/// requires external synchronization. /// requires external synchronization.
PFN_libra_d3d11_filter_chain_create_deferred d3d11_filter_chain_create_deferred; PFN_libra_d3d11_filter_chain_create_deferred
d3d11_filter_chain_create_deferred;
/// Draw a frame with the given parameters for the given filter chain. /// Draw a frame with the given parameters for the given filter chain.
/// ///
@ -776,7 +1007,6 @@ typedef struct libra_instance_t {
PFN_libra_d3d11_filter_chain_set_param d3d11_filter_chain_set_param; PFN_libra_d3d11_filter_chain_set_param d3d11_filter_chain_set_param;
#endif #endif
#if defined(LIBRA_RUNTIME_D3D12) #if defined(LIBRA_RUNTIME_D3D12)
/// Create the filter chain given the shader preset. /// Create the filter chain given the shader preset.
/// ///
@ -801,8 +1031,9 @@ typedef struct libra_instance_t {
/// The shader preset is immediately invalidated and must be recreated after /// The shader preset is immediately invalidated and must be recreated after
/// the filter chain is created. /// the filter chain is created.
/// ///
/// If this function is not loaded, `out` will unconditionally be set to null. /// If this function is not loaded, `out` will unconditionally be set to
/// If this function returns an error, the state of `out` is unspecified. /// null. If this function returns an error, the state of `out` is
/// unspecified.
/// ///
/// ## Safety: /// ## Safety:
/// - `preset` must be either null, or valid and aligned. /// - `preset` must be either null, or valid and aligned.
@ -815,7 +1046,8 @@ typedef struct libra_instance_t {
/// prior commands. The caller is responsible for ending the command list /// prior commands. The caller is responsible for ending the command list
/// and immediately submitting it to a graphics queue. The command list must /// and immediately submitting it to a graphics queue. The command list must
/// be completely executed before calling `libra_d3d12_filter_chain_frame` /// be completely executed before calling `libra_d3d12_filter_chain_frame`
PFN_libra_d3d12_filter_chain_create_deferred d3d12_filter_chain_create_deferred; PFN_libra_d3d12_filter_chain_create_deferred
d3d12_filter_chain_create_deferred;
/// Draw a frame with the given parameters for the given filter chain. /// Draw a frame with the given parameters for the given filter chain.
/// ///
@ -881,7 +1113,8 @@ typedef struct libra_instance_t {
/// was created with librashader_load_instance if and only if: /// was created with librashader_load_instance if and only if:
/// ///
/// 1. A librashader library was found in the search path. /// 1. A librashader library was found in the search path.
/// 2. The ABI version of the librashader library in the search path is compatible. /// 2. The ABI version of the librashader library in the search path is
/// compatible.
/// ///
/// This flag can only be relied upon when checked immediately after /// This flag can only be relied upon when checked immediately after
/// librashader_load_instance as there is no protection against mutating /// librashader_load_instance as there is no protection against mutating
@ -894,14 +1127,35 @@ typedef struct libra_instance_t {
bool instance_loaded; bool instance_loaded;
} libra_instance_t; } libra_instance_t;
libra_instance_t __librashader_make_null_instance() { libra_instance_t __librashader_make_null_instance() {
return libra_instance_t { return libra_instance_t {
.instance_abi_version = __librashader__noop_instance_abi_version, .instance_abi_version = __librashader__noop_instance_abi_version,
.instance_api_version = __librashader__noop_instance_api_version, .instance_api_version = __librashader__noop_instance_api_version,
.preset_ctx_create = __librashader__noop_preset_ctx_create,
.preset_ctx_free = __librashader__noop_preset_ctx_free,
.preset_ctx_set_core_name =
__librashader__noop_preset_ctx_set_core_name,
.preset_ctx_set_content_dir =
__librashader__noop_preset_ctx_set_content_dir,
.preset_ctx_set_param = __librashader__noop_preset_ctx_set_param,
.preset_ctx_set_runtime = __librashader__noop_preset_ctx_set_runtime,
.preset_ctx_set_core_rotation =
__librashader__noop_preset_ctx_set_core_rotation,
.preset_ctx_set_user_rotation =
__librashader__noop_preset_ctx_set_user_rotation,
.preset_ctx_set_screen_orientation =
__librashader__noop_preset_ctx_set_screen_orientation,
.preset_ctx_set_allow_rotation =
__librashader__noop_preset_ctx_set_allow_rotation,
.preset_ctx_set_view_aspect_orientation =
__librashader__noop_preset_ctx_set_view_aspect_orientation,
.preset_ctx_set_core_aspect_orientation =
__librashader__noop_preset_ctx_set_core_aspect_orientation,
.preset_create = __librashader__noop_preset_create, .preset_create = __librashader__noop_preset_create,
.preset_create_with_context =
__librashader__noop_preset_create_with_context,
.preset_free = __librashader__noop_preset_free, .preset_free = __librashader__noop_preset_free,
.preset_set_param = __librashader__noop_preset_set_param, .preset_set_param = __librashader__noop_preset_set_param,
.preset_get_param = __librashader__noop_preset_get_param, .preset_get_param = __librashader__noop_preset_get_param,
@ -934,7 +1188,8 @@ libra_instance_t __librashader_make_null_instance() {
#if defined(LIBRA_RUNTIME_VULKAN) #if defined(LIBRA_RUNTIME_VULKAN)
.vk_filter_chain_create = __librashader__noop_vk_filter_chain_create, .vk_filter_chain_create = __librashader__noop_vk_filter_chain_create,
.vk_filter_chain_create_deferred = __librashader__noop_vk_filter_chain_create_deferred, .vk_filter_chain_create_deferred =
__librashader__noop_vk_filter_chain_create_deferred,
.vk_filter_chain_frame = __librashader__noop_vk_filter_chain_frame, .vk_filter_chain_frame = __librashader__noop_vk_filter_chain_frame,
.vk_filter_chain_free = __librashader__noop_vk_filter_chain_free, .vk_filter_chain_free = __librashader__noop_vk_filter_chain_free,
.vk_filter_chain_get_active_pass_count = .vk_filter_chain_get_active_pass_count =
@ -1000,7 +1255,8 @@ libra_instance_t __librashader_make_null_instance() {
/// \return An `libra_instance_t` struct with loaded function pointers. /// \return An `libra_instance_t` struct with loaded function pointers.
libra_instance_t librashader_load_instance(); libra_instance_t librashader_load_instance();
#if defined(_WIN32) || defined(__linux__) || defined(__unix__) || defined(__APPLE__) #if defined(_WIN32) || defined(__linux__) || defined(__unix__) || \
defined(__APPLE__)
libra_instance_t librashader_load_instance() { libra_instance_t librashader_load_instance() {
_LIBRASHADER_IMPL_HANDLE librashader = _LIBRASHADER_LOAD; _LIBRASHADER_IMPL_HANDLE librashader = _LIBRASHADER_LOAD;
libra_instance_t instance = __librashader_make_null_instance(); libra_instance_t instance = __librashader_make_null_instance();
@ -1016,15 +1272,31 @@ libra_instance_t librashader_load_instance() {
return instance; return instance;
} }
_LIBRASHADER_ASSIGN(librashader, instance, preset_ctx_create);
_LIBRASHADER_ASSIGN(librashader, instance, preset_ctx_free);
_LIBRASHADER_ASSIGN(librashader, instance, preset_ctx_set_core_name);
_LIBRASHADER_ASSIGN(librashader, instance, preset_ctx_set_content_dir);
_LIBRASHADER_ASSIGN(librashader, instance, preset_ctx_set_param);
_LIBRASHADER_ASSIGN(librashader, instance, preset_ctx_set_runtime);
_LIBRASHADER_ASSIGN(librashader, instance, preset_ctx_set_core_rotation);
_LIBRASHADER_ASSIGN(librashader, instance, preset_ctx_set_user_rotation);
_LIBRASHADER_ASSIGN(librashader, instance,
preset_ctx_set_screen_orientation);
_LIBRASHADER_ASSIGN(librashader, instance, preset_ctx_set_allow_rotation);
_LIBRASHADER_ASSIGN(librashader, instance,
preset_ctx_set_view_aspect_orientation);
_LIBRASHADER_ASSIGN(librashader, instance,
preset_ctx_set_core_aspect_orientation);
_LIBRASHADER_ASSIGN(librashader, instance, preset_create); _LIBRASHADER_ASSIGN(librashader, instance, preset_create);
_LIBRASHADER_ASSIGN(librashader, instance, preset_create_with_context);
_LIBRASHADER_ASSIGN(librashader, instance, preset_free); _LIBRASHADER_ASSIGN(librashader, instance, preset_free);
_LIBRASHADER_ASSIGN(librashader, instance, preset_set_param); _LIBRASHADER_ASSIGN(librashader, instance, preset_set_param);
_LIBRASHADER_ASSIGN(librashader, instance, preset_get_param); _LIBRASHADER_ASSIGN(librashader, instance, preset_get_param);
_LIBRASHADER_ASSIGN(librashader, instance, preset_print); _LIBRASHADER_ASSIGN(librashader, instance, preset_print);
_LIBRASHADER_ASSIGN(librashader, instance, _LIBRASHADER_ASSIGN(librashader, instance, preset_get_runtime_params);
preset_get_runtime_params); _LIBRASHADER_ASSIGN(librashader, instance, preset_free_runtime_params);
_LIBRASHADER_ASSIGN(librashader, instance,
preset_free_runtime_params);
_LIBRASHADER_ASSIGN(librashader, instance, error_errno); _LIBRASHADER_ASSIGN(librashader, instance, error_errno);
_LIBRASHADER_ASSIGN(librashader, instance, error_print); _LIBRASHADER_ASSIGN(librashader, instance, error_print);
@ -1037,10 +1309,8 @@ libra_instance_t librashader_load_instance() {
_LIBRASHADER_ASSIGN(librashader, instance, gl_filter_chain_create); _LIBRASHADER_ASSIGN(librashader, instance, gl_filter_chain_create);
_LIBRASHADER_ASSIGN(librashader, instance, gl_filter_chain_frame); _LIBRASHADER_ASSIGN(librashader, instance, gl_filter_chain_frame);
_LIBRASHADER_ASSIGN(librashader, instance, gl_filter_chain_free); _LIBRASHADER_ASSIGN(librashader, instance, gl_filter_chain_free);
_LIBRASHADER_ASSIGN(librashader, instance, _LIBRASHADER_ASSIGN(librashader, instance, gl_filter_chain_get_param);
gl_filter_chain_get_param); _LIBRASHADER_ASSIGN(librashader, instance, gl_filter_chain_set_param);
_LIBRASHADER_ASSIGN(librashader, instance,
gl_filter_chain_set_param);
_LIBRASHADER_ASSIGN(librashader, instance, _LIBRASHADER_ASSIGN(librashader, instance,
gl_filter_chain_get_active_pass_count); gl_filter_chain_get_active_pass_count);
_LIBRASHADER_ASSIGN(librashader, instance, _LIBRASHADER_ASSIGN(librashader, instance,
@ -1053,10 +1323,8 @@ libra_instance_t librashader_load_instance() {
_LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_create_deferred); _LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_create_deferred);
_LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_frame); _LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_frame);
_LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_free); _LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_free);
_LIBRASHADER_ASSIGN(librashader, instance, _LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_get_param);
vk_filter_chain_get_param); _LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_set_param);
_LIBRASHADER_ASSIGN(librashader, instance,
vk_filter_chain_set_param);
_LIBRASHADER_ASSIGN(librashader, instance, _LIBRASHADER_ASSIGN(librashader, instance,
vk_filter_chain_get_active_pass_count); vk_filter_chain_get_active_pass_count);
_LIBRASHADER_ASSIGN(librashader, instance, _LIBRASHADER_ASSIGN(librashader, instance,
@ -1065,7 +1333,8 @@ libra_instance_t librashader_load_instance() {
#if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D11) #if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D11)
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_create); _LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_create);
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_create_deferred); _LIBRASHADER_ASSIGN(librashader, instance,
d3d11_filter_chain_create_deferred);
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_frame); _LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_frame);
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_free); _LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_free);
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_get_param); _LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_get_param);
@ -1078,7 +1347,8 @@ libra_instance_t librashader_load_instance() {
#if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D12) #if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D12)
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_create); _LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_create);
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_create_deferred); _LIBRASHADER_ASSIGN(librashader, instance,
d3d12_filter_chain_create_deferred);
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_frame); _LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_frame);
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_free); _LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_free);
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_get_param); _LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_get_param);

View file

@ -7,7 +7,7 @@ publish = false
[dependencies] [dependencies]
cbindgen = "0.26.0" cbindgen = "0.26.0"
clap = { version = "4.1.0", features = ["derive"] } clap = { version = "=4.1.0", features = ["derive"] }
[package.metadata.release] [package.metadata.release]

View file

@ -73,8 +73,7 @@ pub fn main() {
let ext = ext.replace("_capi", ""); let ext = ext.replace("_capi", "");
fs::rename(output_dir.join(artifact), output_dir.join(ext)).unwrap(); fs::rename(output_dir.join(artifact), output_dir.join(ext)).unwrap();
} }
} } else if cfg!(target_family = "unix") {
else if cfg!(target_family = "unix") {
let artifacts = &["liblibrashader_capi.so", "liblibrashader_capi.a"]; let artifacts = &["liblibrashader_capi.so", "liblibrashader_capi.a"];
for artifact in artifacts { for artifact in artifacts {
let ext = artifact.strip_prefix("lib").unwrap(); let ext = artifact.strip_prefix("lib").unwrap();

View file

@ -2,7 +2,7 @@
name = "librashader-cache" name = "librashader-cache"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -12,8 +12,8 @@ description = "RetroArch shaders for all."
[dependencies] [dependencies]
serde = { version = "1.0" } serde = { version = "1.0" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.7", features = ["serialize"] } librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.8", features = ["serialize"] }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.8" }
platform-dirs = "0.3.0" platform-dirs = "0.3.0"
blake3 = { version = "1.3.3" } blake3 = { version = "1.3.3" }
thiserror = "1.0.38" thiserror = "1.0.38"

View file

@ -3,7 +3,7 @@ name = "librashader-capi"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -23,7 +23,7 @@ runtime-d3d12 = ["windows", "librashader/runtime-d3d12", "windows/Win32_Graphics
runtime-vulkan = ["ash", "librashader/runtime-vk"] runtime-vulkan = ["ash", "librashader/runtime-vk"]
[dependencies] [dependencies]
librashader = { path = "../librashader", version = "0.2.0-beta.7", features = ["internal"] } librashader = { path = "../librashader", version = "0.2.0-beta.8" }
thiserror = "1.0.37" thiserror = "1.0.37"
paste = "1.0.9" paste = "1.0.9"
gl = { version = "0.14.0", optional = true } gl = { version = "0.14.0", optional = true }

View file

@ -68,15 +68,7 @@ typedef void D3D12_CPU_DESCRIPTOR_HANDLE;
[parse] [parse]
parse_deps = true parse_deps = true
include = ["librashader", include = ["librashader"]
"librashader-presets",
"librashader-preprocess",
"librashader-reflect",
"librashader-runtime-gl",
"librashader-runtime-vk",
"librashader-runtime-d3d11",
"librashader-runtime-d3d12",
]
expand = ["librashader-capi"] expand = ["librashader-capi"]
[struct] [struct]
@ -99,6 +91,20 @@ include = [
"PFN_libra_preset_print", "PFN_libra_preset_print",
"PFN_libra_preset_get_runtime_params", "PFN_libra_preset_get_runtime_params",
"PFN_libra_preset_free_runtime_params", "PFN_libra_preset_free_runtime_params",
"PFN_libra_preset_create_with_context",
"PFN_libra_preset_ctx_create",
"PFN_libra_preset_ctx_free",
"PFN_libra_preset_ctx_set_core_name",
"PFN_libra_preset_ctx_set_content_dir",
"PFN_libra_preset_ctx_set_param",
"PFN_libra_preset_ctx_set_core_rotation",
"PFN_libra_preset_ctx_set_user_rotation",
"PFN_libra_preset_ctx_set_screen_orientation",
"PFN_libra_preset_ctx_set_allow_rotation",
"PFN_libra_preset_ctx_set_view_aspect_orientation",
"PFN_libra_preset_ctx_set_core_aspect_orientation",
"PFN_libra_preset_ctx_set_runtime",
# error # error
"PFN_libra_error_errno", "PFN_libra_error_errno",
@ -154,6 +160,9 @@ exclude = ["Option_ID3D11DeviceContext"]
[export.rename] [export.rename]
"LibrashaderError" = "_libra_error" "LibrashaderError" = "_libra_error"
"ShaderPreset" = "_shader_preset" "ShaderPreset" = "_shader_preset"
"WildcardContext" = "_preset_ctx"
"FilterChainGL" = "_filter_chain_gl" "FilterChainGL" = "_filter_chain_gl"
"FilterChainVulkan" = "_filter_chain_vk" "FilterChainVulkan" = "_filter_chain_vk"
"FilterChainD3D11" = "_filter_chain_d3d11" "FilterChainD3D11" = "_filter_chain_d3d11"

View file

@ -1,5 +1,6 @@
//! Binding types for the librashader C API. //! Binding types for the librashader C API.
use crate::error::LibrashaderError; use crate::error::LibrashaderError;
use librashader::presets::context::{Orientation, VideoDriver, WildcardContext};
use librashader::presets::ShaderPreset; use librashader::presets::ShaderPreset;
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use std::ptr::NonNull; use std::ptr::NonNull;
@ -7,31 +8,86 @@ use std::ptr::NonNull;
/// A handle to a shader preset object. /// A handle to a shader preset object.
pub type libra_shader_preset_t = Option<NonNull<ShaderPreset>>; pub type libra_shader_preset_t = Option<NonNull<ShaderPreset>>;
/// A handle to a preset wildcard context object.
pub type libra_preset_ctx_t = Option<NonNull<WildcardContext>>;
/// A handle to a librashader error object. /// A handle to a librashader error object.
pub type libra_error_t = Option<NonNull<LibrashaderError>>; pub type libra_error_t = Option<NonNull<LibrashaderError>>;
/// An enum representing orientation for use in preset contexts.
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
pub enum LIBRA_PRESET_CTX_ORIENTATION {
Vertical = 0,
Horizontal,
}
impl From<LIBRA_PRESET_CTX_ORIENTATION> for Orientation {
fn from(value: LIBRA_PRESET_CTX_ORIENTATION) -> Self {
match value {
LIBRA_PRESET_CTX_ORIENTATION::Vertical => Orientation::Vertical,
LIBRA_PRESET_CTX_ORIENTATION::Horizontal => Orientation::Horizontal,
}
}
}
// An enum representing graphics runtimes (video drivers) for use in preset contexts.
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
pub enum LIBRA_PRESET_CTX_RUNTIME {
None = 0,
GlCore,
Vulkan,
D3D11,
D3D12,
Metal,
}
impl From<LIBRA_PRESET_CTX_RUNTIME> for VideoDriver {
fn from(value: LIBRA_PRESET_CTX_RUNTIME) -> Self {
match value {
LIBRA_PRESET_CTX_RUNTIME::None => VideoDriver::None,
LIBRA_PRESET_CTX_RUNTIME::GlCore => VideoDriver::GlCore,
LIBRA_PRESET_CTX_RUNTIME::Vulkan => VideoDriver::Vulkan,
LIBRA_PRESET_CTX_RUNTIME::D3D11 => VideoDriver::Direct3D11,
LIBRA_PRESET_CTX_RUNTIME::D3D12 => VideoDriver::Direct3D12,
LIBRA_PRESET_CTX_RUNTIME::Metal => VideoDriver::Metal,
}
}
}
#[cfg(feature = "runtime-opengl")]
use librashader::runtime::gl::FilterChain as FilterChainGL;
/// A handle to a OpenGL filter chain. /// A handle to a OpenGL filter chain.
#[cfg(feature = "runtime-opengl")] #[cfg(feature = "runtime-opengl")]
#[doc(cfg(feature = "runtime-opengl"))] #[doc(cfg(feature = "runtime-opengl"))]
pub type libra_gl_filter_chain_t = Option<NonNull<librashader::runtime::gl::capi::FilterChainGL>>; pub type libra_gl_filter_chain_t = Option<NonNull<FilterChainGL>>;
/// A handle to a Direct3D 11 filter chain.
#[cfg(all(target_os = "windows", feature = "runtime-d3d11"))]
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<librashader::runtime::d3d11::capi::FilterChainD3D11>>; Option<NonNull<FilterChainD3D11>>;
#[cfg(all(target_os = "windows", feature = "runtime-d3d12"))]
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<librashader::runtime::d3d12::capi::FilterChainD3D12>>; Option<NonNull<FilterChainD3D12>>;
#[cfg(feature = "runtime-vulkan")]
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<librashader::runtime::vk::capi::FilterChainVulkan>>; Option<NonNull<FilterChainVulkan>>;
/// Defines the output viewport for a rendered frame. /// Defines the output viewport for a rendered frame.
#[repr(C)] #[repr(C)]
@ -87,3 +143,35 @@ macro_rules! config_struct {
pub(crate) use config_set_field; pub(crate) use config_set_field;
pub(crate) use config_struct; pub(crate) use config_struct;
pub(crate) use config_version_set; pub(crate) use config_version_set;
#[doc(hidden)]
#[deny(deprecated)]
#[deprecated = "Forward declarations for cbindgen, do not use."]
mod __cbindgen_opaque_forward_declarations {
macro_rules! typedef_struct {
($($(#[$($attrss:tt)*])* $name:ident;)*) => {
$($(#[$($attrss)*])*
#[allow(unused)]
#[doc(hidden)]
#[deny(deprecated)]
#[deprecated]
pub struct $name;
)*
};
}
typedef_struct! {
/// Opaque struct for a preset context.
WildcardContext;
/// Opaque struct for a shader preset.
ShaderPreset;
/// Opaque struct for an OpenGL filter chain.
FilterChainGL;
/// Opaque struct for a Direct3D 11 filter chain.
FilterChainD3D11;
/// Opaque struct for a Direct3D 12 filter chain.
FilterChainD3D12;
/// Opaque struct for a Vulkan filter chain.
FilterChainVulkan;
}
}

View file

@ -5,7 +5,7 @@ use std::mem::MaybeUninit;
use std::ptr::NonNull; use std::ptr::NonNull;
use thiserror::Error; use thiserror::Error;
/// The error type for librashader. /// The error type for librashader C API.
#[non_exhaustive] #[non_exhaustive]
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum LibrashaderError { pub enum LibrashaderError {

View file

@ -68,6 +68,7 @@
#![feature(pointer_is_aligned)] #![feature(pointer_is_aligned)]
#![feature(vec_into_raw_parts)] #![feature(vec_into_raw_parts)]
#![deny(unsafe_op_in_unsafe_fn)] #![deny(unsafe_op_in_unsafe_fn)]
#![deny(deprecated)]
pub mod ctypes; pub mod ctypes;
pub mod error; pub mod error;
@ -80,6 +81,7 @@ pub mod reflect;
pub mod runtime; pub mod runtime;
pub mod version; pub mod version;
pub mod wildcard;
pub use version::LIBRASHADER_ABI_VERSION; pub use version::LIBRASHADER_ABI_VERSION;
pub use version::LIBRASHADER_API_VERSION; pub use version::LIBRASHADER_API_VERSION;

View file

@ -1,5 +1,5 @@
//! librashader preset C API (`libra_preset_*`). //! librashader preset C API (`libra_preset_*`).
use crate::ctypes::libra_shader_preset_t; use crate::ctypes::{libra_preset_ctx_t, libra_shader_preset_t};
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::presets::ShaderPreset; use librashader::presets::ShaderPreset;
@ -55,7 +55,6 @@ extern_fn! {
let filename = unsafe { CStr::from_ptr(filename) }; let filename = unsafe { CStr::from_ptr(filename) };
let filename = filename.to_str()?; let filename = filename.to_str()?;
println!("loading {filename}");
let preset = ShaderPreset::try_parse(filename)?; let preset = ShaderPreset::try_parse(filename)?;
unsafe { unsafe {
@ -66,6 +65,49 @@ extern_fn! {
} }
} }
extern_fn! {
/// Load a preset with the given wildcard context.
///
/// The wildcard context is immediately invalidated and must be recreated after
/// the preset is created.
///
/// Path information variables `PRESET_DIR` and `PRESET` will automatically be filled in.
/// ## Safety
/// - `filename` must be either null or a valid, aligned pointer to a string path to the shader preset.
/// - `context` must be either null or a valid, aligned pointer to a initialized `libra_preset_ctx_t`.
/// - `context` is invalidated after this function returns.
/// - `out` must be either null, or an aligned pointer to an uninitialized or invalid `libra_shader_preset_t`.
/// ## Returns
/// - If any parameters are null, `out` is unchanged, and this function returns `LIBRA_ERR_INVALID_PARAMETER`.
fn libra_preset_create_with_context(
filename: *const c_char,
context: *mut libra_preset_ctx_t,
out: *mut MaybeUninit<libra_shader_preset_t>
) {
assert_non_null!(filename);
assert_non_null!(context);
assert_non_null!(out);
let filename = unsafe { CStr::from_ptr(filename) };
let filename = filename.to_str()?;
let mut context = unsafe {
let context_ptr = &mut *context;
let context = context_ptr.take();
Box::from_raw(context.unwrap().as_ptr())
};
context.add_path_defaults(filename);
let preset = ShaderPreset::try_parse_with_context(filename, *context)?;
unsafe {
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
preset,
)))))
}
}
}
extern_fn! { extern_fn! {
/// Free the preset. /// Free the preset.
/// ///
@ -73,7 +115,7 @@ extern_fn! {
/// null. /// null.
/// ///
/// ## Safety /// ## Safety
/// - `preset` must be a valid and aligned pointer to a shader preset. /// - `preset` must be a valid and aligned pointer to a `libra_shader_preset_t`.
fn libra_preset_free(preset: *mut libra_shader_preset_t) { fn libra_preset_free(preset: *mut libra_shader_preset_t) {
assert_non_null!(preset); assert_non_null!(preset);
unsafe { unsafe {
@ -88,7 +130,7 @@ extern_fn! {
/// Set the value of the parameter in the preset. /// Set the value of the parameter in the preset.
/// ///
/// ## Safety /// ## Safety
/// - `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 `libra_shader_preset_t`.
/// - `name` must be null or a valid and aligned pointer to a string. /// - `name` must be null or a valid and aligned pointer to a string.
fn libra_preset_set_param( fn libra_preset_set_param(
preset: *mut libra_shader_preset_t, preset: *mut libra_shader_preset_t,
@ -135,7 +177,7 @@ extern_fn! {
/// Pretty print the shader preset. /// Pretty print the shader preset.
/// ///
/// ## Safety /// ## Safety
/// - `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 `libra_shader_preset_t`.
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:#?}");
@ -146,7 +188,7 @@ extern_fn! {
/// Get a list of runtime parameters. /// Get a list of runtime parameters.
/// ///
/// ## Safety /// ## Safety
/// - `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 `libra_shader_preset_t`.
/// - `out` must be an aligned pointer to a `libra_preset_parameter_list_t`. /// - `out` must be an aligned pointer to a `libra_preset_parameter_list_t`.
/// - The output struct should be treated as immutable. Mutating any struct fields /// - The output struct should be treated as immutable. Mutating any struct fields
/// in the returned struct may at best cause memory leaks, and at worse /// in the returned struct may at best cause memory leaks, and at worse

View file

@ -3,7 +3,7 @@ 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::{D3D11InputView, D3D11OutputView}; use librashader::runtime::d3d11::{FilterChain, FilterChainOptions, FrameOptions, D3D11InputView, D3D11OutputView};
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};
@ -13,9 +13,6 @@ use windows::Win32::Graphics::Direct3D11::{
ID3D11Device, ID3D11DeviceContext, ID3D11RenderTargetView, ID3D11ShaderResourceView, ID3D11Device, ID3D11DeviceContext, ID3D11RenderTargetView, ID3D11ShaderResourceView,
}; };
use librashader::runtime::d3d11::capi::options::FilterChainOptionsD3D11;
use librashader::runtime::d3d11::capi::options::FrameOptionsD3D11;
use crate::LIBRASHADER_API_VERSION; use crate::LIBRASHADER_API_VERSION;
use librashader::runtime::{FilterChainParameters, Size, Viewport}; use librashader::runtime::{FilterChainParameters, Size, Viewport};
@ -58,7 +55,7 @@ pub struct filter_chain_d3d11_opt_t {
} }
config_struct! { config_struct! {
impl FilterChainOptionsD3D11 => filter_chain_d3d11_opt_t { impl FilterChainOptions => filter_chain_d3d11_opt_t {
0 => [force_no_mipmaps, disable_cache]; 0 => [force_no_mipmaps, disable_cache];
} }
} }
@ -77,7 +74,7 @@ pub struct frame_d3d11_opt_t {
} }
config_struct! { config_struct! {
impl FrameOptionsD3D11 => frame_d3d11_opt_t { impl FrameOptions => frame_d3d11_opt_t {
0 => [clear_history, frame_direction]; 0 => [clear_history, frame_direction];
} }
} }
@ -114,7 +111,7 @@ extern_fn! {
let options = options.map(FromUninit::from_uninit); let options = options.map(FromUninit::from_uninit);
unsafe { unsafe {
let chain = librashader::runtime::d3d11::capi::FilterChainD3D11::load_from_preset( let chain = FilterChain::load_from_preset(
*preset, *preset,
&device, &device,
options.as_ref(), options.as_ref(),
@ -174,7 +171,7 @@ extern_fn! {
let options = options.map(FromUninit::from_uninit); let options = options.map(FromUninit::from_uninit);
unsafe { unsafe {
let chain = librashader::runtime::d3d11::capi::FilterChainD3D11::load_from_preset_deferred( let chain = FilterChain::load_from_preset_deferred(
*preset, *preset,
&device, &device,
&device_context, &device_context,

View file

@ -13,11 +13,8 @@ use windows::Win32::Graphics::Direct3D12::{
}; };
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT; use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
use librashader::runtime::d3d12::capi::options::FilterChainOptionsD3D12;
use librashader::runtime::d3d12::capi::options::FrameOptionsD3D12;
use crate::LIBRASHADER_API_VERSION; use crate::LIBRASHADER_API_VERSION;
use librashader::runtime::d3d12::{D3D12InputImage, D3D12OutputView}; use librashader::runtime::d3d12::{FilterChain, FilterChainOptions, FrameOptions, D3D12InputImage, D3D12OutputView};
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.
@ -58,7 +55,7 @@ pub struct frame_d3d12_opt_t {
} }
config_struct! { config_struct! {
impl FrameOptionsD3D12 => frame_d3d12_opt_t { impl FrameOptions => frame_d3d12_opt_t {
0 => [clear_history, frame_direction]; 0 => [clear_history, frame_direction];
} }
} }
@ -84,7 +81,7 @@ pub struct filter_chain_d3d12_opt_t {
} }
config_struct! { config_struct! {
impl FilterChainOptionsD3D12 => filter_chain_d3d12_opt_t { impl FilterChainOptions => filter_chain_d3d12_opt_t {
0 => [force_hlsl_pipeline, force_no_mipmaps, disable_cache]; 0 => [force_hlsl_pipeline, force_no_mipmaps, disable_cache];
} }
} }
@ -136,7 +133,7 @@ extern_fn! {
let options = options.map(FromUninit::from_uninit); let options = options.map(FromUninit::from_uninit);
unsafe { unsafe {
let chain = librashader::runtime::d3d12::capi::FilterChainD3D12::load_from_preset( let chain = FilterChain::load_from_preset(
*preset, *preset,
&device, &device,
options.as_ref(), options.as_ref(),
@ -188,7 +185,7 @@ extern_fn! {
let options = options.map(FromUninit::from_uninit); let options = options.map(FromUninit::from_uninit);
unsafe { unsafe {
let chain = librashader::runtime::d3d12::capi::FilterChainD3D12::load_from_preset_deferred( let chain = FilterChain::load_from_preset_deferred(
*preset, *preset,
&device, &device,
&command_list, &command_list,

View file

@ -3,7 +3,7 @@ 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::{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;
@ -11,8 +11,6 @@ use std::ptr::NonNull;
use std::slice; use std::slice;
use crate::LIBRASHADER_API_VERSION; use crate::LIBRASHADER_API_VERSION;
use librashader::runtime::gl::capi::options::FilterChainOptionsGL;
use librashader::runtime::gl::capi::options::FrameOptionsGL;
use librashader::runtime::FilterChainParameters; use librashader::runtime::FilterChainParameters;
use librashader::runtime::{Size, Viewport}; use librashader::runtime::{Size, Viewport};
@ -67,7 +65,7 @@ pub struct frame_gl_opt_t {
} }
config_struct! { config_struct! {
impl FrameOptionsGL => frame_gl_opt_t { impl FrameOptions => frame_gl_opt_t {
0 => [clear_history, frame_direction]; 0 => [clear_history, frame_direction];
} }
} }
@ -92,7 +90,7 @@ pub struct filter_chain_gl_opt_t {
} }
config_struct! { config_struct! {
impl FilterChainOptionsGL => filter_chain_gl_opt_t { impl FilterChainOptions => filter_chain_gl_opt_t {
0 => [glsl_version, use_dsa, force_no_mipmaps, disable_cache]; 0 => [glsl_version, use_dsa, force_no_mipmaps, disable_cache];
} }
} }
@ -149,7 +147,7 @@ extern_fn! {
let options = options.map(FromUninit::from_uninit); let options = options.map(FromUninit::from_uninit);
unsafe { unsafe {
let chain = librashader::runtime::gl::capi::FilterChainGL::load_from_preset(*preset, options.as_ref())?; let chain = FilterChain::load_from_preset(*preset, options.as_ref())?;
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new( out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
chain, chain,

View file

@ -3,15 +3,13 @@ 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::{VulkanImage, VulkanInstance}; use librashader::runtime::vk::{FrameOptions, FilterChainOptions, FilterChain, 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;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::slice; use std::slice;
use librashader::runtime::vk::capi::options::FilterChainOptionsVulkan;
use librashader::runtime::vk::capi::options::FrameOptionsVulkan;
use librashader::runtime::FilterChainParameters; use librashader::runtime::FilterChainParameters;
use librashader::runtime::{Size, Viewport}; use librashader::runtime::{Size, Viewport};
@ -96,7 +94,7 @@ pub struct frame_vk_opt_t {
} }
config_struct! { config_struct! {
impl FrameOptionsVulkan => frame_vk_opt_t { impl FrameOptions => frame_vk_opt_t {
0 => [clear_history, frame_direction]; 0 => [clear_history, frame_direction];
} }
} }
@ -120,7 +118,7 @@ pub struct filter_chain_vk_opt_t {
} }
config_struct! { config_struct! {
impl FilterChainOptionsVulkan => filter_chain_vk_opt_t { impl FilterChainOptions => filter_chain_vk_opt_t {
0 => [frames_in_flight, force_no_mipmaps, use_render_pass, disable_cache]; 0 => [frames_in_flight, force_no_mipmaps, use_render_pass, disable_cache];
} }
} }
@ -161,7 +159,7 @@ extern_fn! {
let options = options.map(FromUninit::from_uninit); let options = options.map(FromUninit::from_uninit);
unsafe { unsafe {
let chain = librashader::runtime::vk::capi::FilterChainVulkan::load_from_preset(*preset, vulkan, options.as_ref())?; let chain = FilterChain::load_from_preset(*preset, vulkan, options.as_ref())?;
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new( out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
chain, chain,
@ -212,7 +210,7 @@ extern_fn! {
let options = options.map(FromUninit::from_uninit); let options = options.map(FromUninit::from_uninit);
unsafe { unsafe {
let chain = librashader::runtime::vk::capi::FilterChainVulkan::load_from_preset_deferred(*preset, let chain = FilterChain::load_from_preset_deferred(*preset,
vulkan, vulkan,
command_buffer, command_buffer,
options.as_ref())?; options.as_ref())?;

View file

@ -0,0 +1,263 @@
//! librashader preset wildcard context C API (`libra_preset_ctx_*`).
use crate::ctypes::{libra_preset_ctx_t, LIBRA_PRESET_CTX_ORIENTATION, LIBRA_PRESET_CTX_RUNTIME};
use crate::error::{assert_non_null, assert_some_ptr};
use librashader::presets::context::{
ContextItem, PresetExtension, Rotation, ShaderExtension, WildcardContext,
};
use std::ffi::{c_char, CStr};
use std::mem::MaybeUninit;
use std::ptr::NonNull;
use crate::ffi::extern_fn;
const _: () = crate::assert_thread_safe::<WildcardContext>();
extern_fn! {
/// Create a wildcard context
///
/// The C API does not allow directly setting certain variables
///
/// - `PRESET_DIR` and `PRESET` are inferred on preset creation.
/// - `VID-DRV-SHADER-EXT` and `VID-DRV-PRESET-EXT` are always set to `slang` and `slangp` for librashader.
/// - `VID-FINAL-ROT` is automatically calculated as the sum of `VID-USER-ROT` and `CORE-REQ-ROT` if either are present.
///
/// These automatically inferred variables, as well as all other variables can be overridden with
/// `libra_preset_ctx_set_param`, but the expected string values must be provided.
/// See https://github.com/libretro/RetroArch/pull/15023 for a list of expected string values.
///
/// No variables can be removed once added to the context, however subsequent calls to set the same
/// variable will overwrite the expected variable.
/// ## Safety
/// - `out` must be either null, or an aligned pointer to an uninitialized or invalid `libra_preset_ctx_t`.
/// ## Returns
/// - If any parameters are null, `out` is unchanged, and this function returns `LIBRA_ERR_INVALID_PARAMETER`.
fn libra_preset_ctx_create(
out: *mut MaybeUninit<libra_preset_ctx_t>
) {
assert_non_null!(out);
unsafe {
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
WildcardContext::new(),
)))));
}
}
}
extern_fn! {
/// Free the wildcard context.
///
/// If `context` is null, this function does nothing. The resulting value in `context` then becomes
/// null.
///
/// ## Safety
/// - `context` must be a valid and aligned pointer to a `libra_preset_ctx_t`
fn libra_preset_ctx_free(context: *mut libra_preset_ctx_t) {
assert_non_null!(context);
unsafe {
let context_ptr = &mut *context;
let context = context_ptr.take();
drop(Box::from_raw(context.unwrap().as_ptr()));
}
}
}
extern_fn! {
/// Set the core name (`CORE`) variable in the context
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a `libra_preset_ctx_t`.
/// - `name` must be null or a valid and aligned pointer to a string.
fn libra_preset_ctx_set_core_name(
context: *mut libra_preset_ctx_t,
name: *const c_char,
) |name|; mut |context| {
let name = unsafe {
CStr::from_ptr(name)
};
let name = name.to_str()?;
assert_some_ptr!(mut context);
context.append_item(ContextItem::CoreName(String::from(name)));
}
}
extern_fn! {
/// Set the content directory (`CONTENT-DIR`) variable in the context.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a `libra_preset_ctx_t`.
/// - `name` must be null or a valid and aligned pointer to a string.
fn libra_preset_ctx_set_content_dir(
context: *mut libra_preset_ctx_t,
name: *const c_char,
) |name|; mut |context| {
let name = unsafe {
CStr::from_ptr(name)
};
let name = name.to_str()?;
assert_some_ptr!(mut context);
context.append_item(ContextItem::ContentDirectory(String::from(name)));
}
}
extern_fn! {
/// Set a custom string variable in context.
///
/// If the path contains this variable when loading a preset, it will be replaced with the
/// provided contents.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a `libra_preset_ctx_t`.
/// - `name` must be null or a valid and aligned pointer to a string.
/// - `value` must be null or a valid and aligned pointer to a string.
fn libra_preset_ctx_set_param(
context: *mut libra_preset_ctx_t,
name: *const c_char,
value: *const c_char,
) |name, value|; mut |context| {
let name = unsafe {
CStr::from_ptr(name)
};
let name = name.to_str()?;
let value = unsafe {
CStr::from_ptr(value)
};
let value = value.to_str()?;
assert_some_ptr!(mut context);
context.append_item(ContextItem::ExternContext(String::from(name), String::from(value)));
}
}
extern_fn! {
/// Set the graphics runtime (`VID-DRV`) variable in the context.
///
/// Note that librashader only supports the following runtimes.
///
/// - Vulkan
/// - GLCore
/// - Direct3D11
/// - Direct3D12
///
/// This will also set the appropriate video driver extensions.
///
/// For librashader, `VID-DRV-SHADER-EXT` and `VID-DRV-PRESET-EXT` are always `slang` and `slangp`.
/// To override this, use `libra_preset_ctx_set_param`.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a `libra_preset_ctx_t`.
/// - `name` must be null or a valid and aligned pointer to a string.
fn libra_preset_ctx_set_runtime(
context: *mut libra_preset_ctx_t,
value: LIBRA_PRESET_CTX_RUNTIME,
) mut |context| {
assert_some_ptr!(mut context);
context.append_item(ContextItem::VideoDriverPresetExtension(
PresetExtension::Slangp,
));
context.append_item(ContextItem::VideoDriverShaderExtension(
ShaderExtension::Slang,
));
context.append_item(ContextItem::VideoDriver(value.into()));
}
}
extern_fn! {
/// Set the core requested rotation (`CORE-REQ-ROT`) variable in the context.
///
/// Rotation is represented by quarter rotations around the unit circle.
/// For example. `0` = 0deg, `1` = 90deg, `2` = 180deg, `3` = 270deg, `4` = 0deg.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a `libra_preset_ctx_t`.
fn libra_preset_ctx_set_core_rotation(
context: *mut libra_preset_ctx_t,
value: u32,
) mut |context| {
assert_some_ptr!(mut context);
context.append_item(ContextItem::CoreRequestedRotation(Rotation::from(value)))
}
}
extern_fn! {
/// Set the user rotation (`VID-USER-ROT`) variable in the context.
///
/// Rotation is represented by quarter rotations around the unit circle.
/// For example. `0` = 0deg, `1` = 90deg, `2` = 180deg, `3` = 270deg, `4` = 0deg.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a `libra_preset_ctx_t`.
fn libra_preset_ctx_set_user_rotation(
context: *mut libra_preset_ctx_t,
value: u32,
) mut |context| {
assert_some_ptr!(mut context);
context.append_item(ContextItem::UserRotation(Rotation::from(value)))
}
}
extern_fn! {
/// Set the screen orientation (`SCREEN-ORIENT`) variable in the context.
///
/// Orientation is represented by quarter rotations around the unit circle.
/// For example. `0` = 0deg, `1` = 90deg, `2` = 180deg, `3` = 270deg, `4` = 0deg.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a `libra_preset_ctx_t`.
fn libra_preset_ctx_set_screen_orientation(
context: *mut libra_preset_ctx_t,
value: u32,
) mut |context| {
assert_some_ptr!(mut context);
context.append_item(ContextItem::ScreenOrientation(Rotation::from(value)))
}
}
extern_fn! {
/// Set whether or not to allow rotation (`VID-ALLOW-CORE-ROT`) variable in the context.
///
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a `libra_preset_ctx_t`.
fn libra_preset_ctx_set_allow_rotation(
context: *mut libra_preset_ctx_t,
value: bool,
) mut |context| {
assert_some_ptr!(mut context);
context.append_item(ContextItem::AllowCoreRotation(value.into()))
}
}
extern_fn! {
/// Set the view aspect orientation (`VIEW-ASPECT-ORIENT`) variable in the context.
//////
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a `libra_preset_ctx_t`.
fn libra_preset_ctx_set_view_aspect_orientation(
context: *mut libra_preset_ctx_t,
value: LIBRA_PRESET_CTX_ORIENTATION,
) mut |context| {
assert_some_ptr!(mut context);
context.append_item(ContextItem::ViewAspectOrientation(value.into()))
}
}
extern_fn! {
/// Set the core aspect orientation (`CORE-ASPECT-ORIENT`) variable in the context.
//////
/// ## Safety
/// - `context` must be null or a valid and aligned pointer to a `libra_preset_ctx_t`.
fn libra_preset_ctx_set_core_aspect_orientation(
context: *mut libra_preset_ctx_t,
value: LIBRA_PRESET_CTX_ORIENTATION,
) mut |context| {
assert_some_ptr!(mut context);
context.append_item(ContextItem::CoreAspectOrientation(value.into()))
}
}

View file

@ -3,7 +3,7 @@ name = "librashader-common"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"

View file

@ -3,7 +3,7 @@ name = "librashader-preprocess"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -14,7 +14,7 @@ description = "RetroArch shaders for all."
[dependencies] [dependencies]
thiserror = "1.0.37" thiserror = "1.0.37"
nom = "7.1.1" nom = "7.1.1"
librashader-common = { path = "../librashader-common", version = "0.2.0-beta.7" } librashader-common = { path = "../librashader-common", version = "0.2.0-beta.8" }
rustc-hash = "1.1.0" rustc-hash = "1.1.0"
encoding_rs = "0.8.31" encoding_rs = "0.8.31"

View file

@ -3,7 +3,7 @@ name = "librashader-presets"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -15,8 +15,15 @@ description = "RetroArch shaders for all."
thiserror = "1.0.37" thiserror = "1.0.37"
nom = "7.1.1" nom = "7.1.1"
nom_locate = "4.0.0" nom_locate = "4.0.0"
librashader-common = { path = "../librashader-common", version = "0.2.0-beta.7" } librashader-common = { path = "../librashader-common", version = "0.2.0-beta.8" }
num-traits = "0.2" num-traits = "0.2"
once_cell = "1"
# we don't need unicode
regex = { version = "1", default-features = false, features = ["perf"] }
rustc-hash = "1.1.0"
rustversion = "1.0"
os_str_bytes = { version = "6", features = ["conversions"] }
[features] [features]
parse_legacy_glsl = [] parse_legacy_glsl = []

View file

@ -0,0 +1,460 @@
// pub use librashader_presets_context::*;
//! Shader preset wildcard replacement context handling.
//!
//! Implements wildcard replacement of shader paths specified in
//! [RetroArch#15023](https://github.com/libretro/RetroArch/pull/15023).
use once_cell::sync::Lazy;
use regex::bytes::Regex;
use rustc_hash::FxHashMap;
use std::collections::VecDeque;
use std::fmt::{Debug, Display, Formatter};
use std::ops::Add;
use std::path::{Component, Path, PathBuf};
/// Valid video driver or runtime. This list is non-exhaustive.
#[repr(u32)]
#[non_exhaustive]
#[derive(Debug, Copy, Clone)]
pub enum VideoDriver {
/// None (`null`)
None = 0,
/// OpenGL Core (`glcore`)
GlCore,
/// Legacy OpenGL (`gl`)
Gl,
/// Vulkan (`vulkan`)
Vulkan,
/// Direct3D 9 (`d3d9_hlsl`)
Direct3D9Hlsl,
/// Direct3D 11 (`d3d11`)
Direct3D11,
/// Direct3D12 (`d3d12`)
Direct3D12,
/// Metal (`metal`)
Metal,
}
impl Display for VideoDriver {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
VideoDriver::None => f.write_str("null"),
VideoDriver::GlCore => f.write_str("glcore"),
VideoDriver::Gl => f.write_str("gl"),
VideoDriver::Vulkan => f.write_str("vulkan"),
VideoDriver::Direct3D11 => f.write_str("d3d11"),
VideoDriver::Direct3D9Hlsl => f.write_str("d3d9_hlsl"),
VideoDriver::Direct3D12 => f.write_str("d3d12"),
VideoDriver::Metal => f.write_str("metal"),
}
}
}
/// Valid extensions for shader extensions.
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
pub enum ShaderExtension {
/// `.slang`
Slang = 0,
/// `.glsl`
Glsl,
/// `.cg`
Cg,
}
impl Display for ShaderExtension {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
ShaderExtension::Slang => f.write_str("slang"),
ShaderExtension::Glsl => f.write_str("glsl"),
ShaderExtension::Cg => f.write_str("cg"),
}
}
}
/// Valid extensions for shader presets
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
pub enum PresetExtension {
/// `.slangp`
Slangp = 0,
/// `.glslp`
Glslp,
/// `.cgp`
Cgp,
}
impl Display for PresetExtension {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
PresetExtension::Slangp => f.write_str("slangp"),
PresetExtension::Glslp => f.write_str("glslp"),
PresetExtension::Cgp => f.write_str("cgp"),
}
}
}
/// Rotation of the viewport.
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
pub enum Rotation {
/// Zero
Zero = 0,
/// 90 degrees
Right = 1,
/// 180 degrees
Straight = 2,
/// 270 degrees
Reflex = 3,
}
impl From<u32> for Rotation {
fn from(value: u32) -> Self {
let value = value % 4;
match value {
0 => Rotation::Zero,
1 => Rotation::Right,
2 => Rotation::Straight,
3 => Rotation::Reflex,
_ => unreachable!(),
}
}
}
impl Add for Rotation {
type Output = Rotation;
fn add(self, rhs: Self) -> Self::Output {
let lhs = self as u32;
let out = lhs + rhs as u32;
Rotation::from(out)
}
}
impl Display for Rotation {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Rotation::Zero => f.write_str("0"),
Rotation::Right => f.write_str("90"),
Rotation::Straight => f.write_str("180"),
Rotation::Reflex => f.write_str("270"),
}
}
}
/// Orientation of aspect ratios
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
pub enum Orientation {
/// Vertical orientation.
Vertical = 0,
/// Horizontal orientation.
Horizontal,
}
impl Display for Orientation {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Orientation::Vertical => f.write_str("VERT"),
Orientation::Horizontal => f.write_str("HORZ"),
}
}
}
/// An item representing a variable that can be replaced in a path preset.
#[derive(Debug, Clone)]
pub enum ContextItem {
/// The content directory of the game (`CONTENT-DIR`)
ContentDirectory(String),
/// The name of the libretro core (`CORE`)
CoreName(String),
/// The filename of the game (`GAME`)
GameName(String),
/// The name of the preset (`PRESET`)
Preset(String),
/// The name of the preset directory (`PRESET_DIR`)
PresetDirectory(String),
/// The video driver (runtime) (`VID-DRV`)
VideoDriver(VideoDriver),
/// The extension of shader types supported by the driver (`VID-DRV-SHADER-EXT`)
VideoDriverShaderExtension(ShaderExtension),
/// The extension of shader presets supported by the driver (`VID-DRV-PRESET-EXT`)
VideoDriverPresetExtension(PresetExtension),
/// The rotation that the core is requesting (`CORE-REQ-ROT`)
CoreRequestedRotation(Rotation),
/// Whether or not to allow core-requested rotation (`VID-ALLOW-CORE-ROT`)
AllowCoreRotation(bool),
/// The rotation the user is requesting (`VID-USER-ROT`)
UserRotation(Rotation),
/// The final rotation (`VID-FINAL-ROT`) calculated by the sum of `VID-USER-ROT` and `CORE-REQ-ROT`
FinalRotation(Rotation),
/// The user-adjusted screen orientation (`SCREEN-ORIENT`)
ScreenOrientation(Rotation),
/// The orientation of the viewport aspect ratio (`VIEW-ASPECT-ORIENT`)
ViewAspectOrientation(Orientation),
/// The orientation of the aspect ratio requested by the core (`CORE-ASPECT-ORIENT`)
CoreAspectOrientation(Orientation),
/// An external, arbitrary context variable.
ExternContext(String, String),
}
impl ContextItem {
fn toggle_str(v: bool) -> &'static str {
if v {
"ON"
} else {
"OFF"
}
}
pub fn key(&self) -> &str {
match self {
ContextItem::ContentDirectory(_) => "CONTENT-DIR",
ContextItem::CoreName(_) => "CORE",
ContextItem::GameName(_) => "GAME",
ContextItem::Preset(_) => "PRESET",
ContextItem::PresetDirectory(_) => "PRESET_DIR",
ContextItem::VideoDriver(_) => "VID-DRV",
ContextItem::CoreRequestedRotation(_) => "CORE-REQ-ROT",
ContextItem::AllowCoreRotation(_) => "VID-ALLOW-CORE-ROT",
ContextItem::UserRotation(_) => "VID-USER-ROT",
ContextItem::FinalRotation(_) => "VID-FINAL-ROT",
ContextItem::ScreenOrientation(_) => "SCREEN-ORIENT",
ContextItem::ViewAspectOrientation(_) => "VIEW-ASPECT-ORIENT",
ContextItem::CoreAspectOrientation(_) => "CORE-ASPECT-ORIENT",
ContextItem::VideoDriverShaderExtension(_) => "VID-DRV-SHADER-EXT",
ContextItem::VideoDriverPresetExtension(_) => "VID-DRV-PRESET-EXT",
ContextItem::ExternContext(key, _) => key,
}
}
}
impl Display for ContextItem {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
ContextItem::ContentDirectory(v) => f.write_str(v),
ContextItem::CoreName(v) => f.write_str(v),
ContextItem::GameName(v) => f.write_str(v),
ContextItem::Preset(v) => f.write_str(v),
ContextItem::PresetDirectory(v) => f.write_str(v),
ContextItem::VideoDriver(v) => f.write_fmt(format_args!("{}", v)),
ContextItem::CoreRequestedRotation(v) => {
f.write_fmt(format_args!("{}-{}", self.key(), v))
}
ContextItem::AllowCoreRotation(v) => f.write_fmt(format_args!(
"{}-{}",
self.key(),
ContextItem::toggle_str(*v)
)),
ContextItem::UserRotation(v) => f.write_fmt(format_args!("{}-{}", self.key(), v)),
ContextItem::FinalRotation(v) => f.write_fmt(format_args!("{}-{}", self.key(), v)),
ContextItem::ScreenOrientation(v) => f.write_fmt(format_args!("{}-{}", self.key(), v)),
ContextItem::ViewAspectOrientation(v) => {
f.write_fmt(format_args!("{}-{}", self.key(), v))
}
ContextItem::CoreAspectOrientation(v) => {
f.write_fmt(format_args!("{}-{}", self.key(), v))
}
ContextItem::VideoDriverShaderExtension(v) => f.write_fmt(format_args!("{}", v)),
ContextItem::VideoDriverPresetExtension(v) => f.write_fmt(format_args!("{}", v)),
ContextItem::ExternContext(_, v) => f.write_fmt(format_args!("{}", v)),
}
}
}
/// A preset wildcard context.
///
/// Any items added after will have higher priority
/// when passed to the shader preset parser.
///
/// When passed to the preset parser, the preset parser
/// will automatically add inferred items at lowest priority.
///
/// Any items added by the user will override the automatically
/// inferred items.
#[derive(Debug, Clone)]
pub struct WildcardContext(VecDeque<ContextItem>);
impl WildcardContext {
/// Create a new wildcard context.
pub fn new() -> Self {
Self(VecDeque::new())
}
/// Prepend an item to the context builder.
pub fn prepend_item(&mut self, item: ContextItem) {
self.0.push_front(item);
}
/// Append an item to the context builder.
/// The new item will take precedence over all items added before it.
pub fn append_item(&mut self, item: ContextItem) {
self.0.push_back(item);
}
/// Prepend sensible defaults for the given video driver.
///
/// Any values added, either previously or afterwards will not be overridden.
pub fn add_video_driver_defaults(&mut self, video_driver: VideoDriver) {
self.prepend_item(ContextItem::VideoDriverPresetExtension(
PresetExtension::Slangp,
));
self.prepend_item(ContextItem::VideoDriverShaderExtension(
ShaderExtension::Slang,
));
self.prepend_item(ContextItem::VideoDriver(video_driver));
}
/// Prepend default entries from the path of the preset.
///
/// Any values added, either previously or afterwards will not be overridden.
pub fn add_path_defaults(&mut self, path: impl AsRef<Path>) {
let path = path.as_ref();
if let Some(preset_name) = path.file_stem() {
let preset_name = preset_name.to_string_lossy();
self.prepend_item(ContextItem::Preset(preset_name.into()))
}
if let Some(preset_dir_name) = path.parent().and_then(|p| {
if !p.is_dir() {
return None;
};
p.file_name()
}) {
let preset_dir_name = preset_dir_name.to_string_lossy();
self.prepend_item(ContextItem::PresetDirectory(preset_dir_name.into()))
}
}
pub fn to_hashmap(mut self) -> FxHashMap<String, String> {
let mut map = FxHashMap::default();
let last_user_rot = self
.0
.iter()
.rfind(|i| matches!(i, ContextItem::UserRotation(_)));
let last_core_rot = self
.0
.iter()
.rfind(|i| matches!(i, ContextItem::CoreRequestedRotation(_)));
let final_rot = match (last_core_rot, last_user_rot) {
(Some(ContextItem::UserRotation(u)), None) => Some(ContextItem::FinalRotation(*u)),
(None, Some(ContextItem::CoreRequestedRotation(c))) => {
Some(ContextItem::FinalRotation(*c))
}
(Some(ContextItem::UserRotation(u)), Some(ContextItem::CoreRequestedRotation(c))) => {
Some(ContextItem::FinalRotation(*u + *c))
}
_ => None,
};
if let Some(final_rot) = final_rot {
self.prepend_item(final_rot);
}
for item in self.0 {
map.insert(String::from(item.key()), item.to_string());
}
map
}
}
#[rustversion::since(1.74)]
pub(crate) fn apply_context(path: &mut PathBuf, context: &FxHashMap<String, String>) {
use std::ffi::{OsStr, OsString};
static WILDCARD_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new("\\$([A-Z-_]+)\\$").unwrap());
if context.is_empty() {
return;
}
// Don't want to do any extra work if there's no match.
if !WILDCARD_REGEX.is_match(path.as_os_str().as_encoded_bytes()) {
return;
}
let mut new_path = PathBuf::with_capacity(path.capacity());
for component in path.components() {
match component {
Component::Normal(path) => {
let haystack = path.as_encoded_bytes();
let replaced =
WILDCARD_REGEX.replace_all(haystack, |caps: &regex::bytes::Captures| {
let Some(name) = caps.get(1) else {
return caps[0].to_vec();
};
let Ok(key) = std::str::from_utf8(name.as_bytes()) else {
return caps[0].to_vec();
};
if let Some(replacement) = context.get(key) {
return OsString::from(replacement.to_string()).into_encoded_bytes();
}
return caps[0].to_vec();
});
// SAFETY: The original source is valid encoded bytes, and our replacement is
// valid encoded bytes. This upholds the safety requirements of `from_encoded_bytes_unchecked`.
new_path.push(unsafe { OsStr::from_encoded_bytes_unchecked(&replaced.as_ref()) })
}
_ => new_path.push(component),
}
}
// If no wildcards are found within the path, or the path after replacing the wildcards does not exist on disk, the path returned will be unaffected.
if let Ok(true) = new_path.try_exists() {
*path = new_path;
}
}
#[rustversion::before(1.74)]
pub(crate) fn apply_context(path: &mut PathBuf, context: &FxHashMap<String, String>) {
use os_str_bytes::RawOsStr;
static WILDCARD_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new("\\$([A-Z-_]+)\\$").unwrap());
if context.is_empty() {
return;
}
let path_str = RawOsStr::new(path.as_os_str());
let path_bytes = path_str.to_raw_bytes();
// Don't want to do any extra work if there's no match.
if !WILDCARD_REGEX.is_match(&path_bytes) {
return;
}
let mut new_path = PathBuf::with_capacity(path.capacity());
for component in path.components() {
match component {
Component::Normal(path) => {
let haystack = RawOsStr::new(path);
let haystack = haystack.to_raw_bytes();
let replaced =
WILDCARD_REGEX.replace_all(&haystack, |caps: &regex::bytes::Captures| {
let Some(name) = caps.get(1) else {
return caps[0].to_vec();
};
let Ok(key) = std::str::from_utf8(name.as_bytes()) else {
return caps[0].to_vec();
};
if let Some(replacement) = context.get(key) {
return RawOsStr::from_str(replacement).to_raw_bytes().to_vec();
}
return caps[0].to_vec();
});
// SAFETY: The original source is valid encoded bytes, and our replacement is
// valid encoded bytes. This upholds the safety requirements of `from_encoded_bytes_unchecked`.
new_path.push(RawOsStr::assert_cow_from_raw_bytes(&replaced.as_ref()).to_os_str())
}
_ => new_path.push(component),
}
}
// If no wildcards are found within the path, or the path after replacing the wildcards does not exist on disk, the path returned will be unaffected.
if let Ok(true) = new_path.try_exists() {
*path = new_path;
}
}

View file

@ -148,7 +148,7 @@ where
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::MakeExtractIf; use crate::extract_if::MakeExtractIf;
#[test] #[test]
fn drain_filter_empty() { fn drain_filter_empty() {
let mut vec: Vec<i32> = vec![]; let mut vec: Vec<i32> = vec![];

View file

@ -8,12 +8,15 @@
//! //!
//! Re-exported as [`librashader::presets`](https://docs.rs/librashader/latest/librashader/presets/index.html). //! Re-exported as [`librashader::presets`](https://docs.rs/librashader/latest/librashader/presets/index.html).
#![allow(stable_features)]
#![allow(unstable_name_collisions)] #![allow(unstable_name_collisions)]
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 error::*; pub use error::*;
pub use preset::*; pub use preset::*;

View file

@ -0,0 +1,404 @@
//! Shader preset wildcard replacement context handling.
//!
//! Implements wildcard replacement of shader paths specified in
//! [RetroArch#15023](https://github.com/libretro/RetroArch/pull/15023).
use once_cell::sync::Lazy;
use regex::bytes::Regex;
use rustc_hash::FxHashMap;
use std::collections::VecDeque;
use std::ffi::{OsStr, OsString};
use std::fmt::{Debug, Display, Formatter};
use std::ops::Add;
use std::path::{Component, Path, PathBuf};
/// Valid video driver or runtime. This list is non-exhaustive.
#[repr(u32)]
#[non_exhaustive]
#[derive(Debug, Copy, Clone)]
pub enum VideoDriver {
/// None (`null`)
None = 0,
/// OpenGL Core (`glcore`)
GlCore,
/// Legacy OpenGL (`gl`)
Gl,
/// Vulkan (`vulkan`)
Vulkan,
/// Direct3D 9 (`d3d9_hlsl`)
Direct3D9Hlsl,
/// Direct3D 11 (`d3d11`)
Direct3D11,
/// Direct3D12 (`d3d12`)
Direct3D12,
/// Metal (`metal`)
Metal,
}
impl Display for VideoDriver {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
VideoDriver::None => f.write_str("null"),
VideoDriver::GlCore => f.write_str("glcore"),
VideoDriver::Gl => f.write_str("gl"),
VideoDriver::Vulkan => f.write_str("vulkan"),
VideoDriver::Direct3D11 => f.write_str("d3d11"),
VideoDriver::Direct3D9Hlsl => f.write_str("d3d9_hlsl"),
VideoDriver::Direct3D12 => f.write_str("d3d12"),
VideoDriver::Metal => f.write_str("metal"),
}
}
}
/// Valid extensions for shader extensions.
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
pub enum ShaderExtension {
/// `.slang`
Slang = 0,
/// `.glsl`
Glsl,
/// `.cg`
Cg,
}
impl Display for ShaderExtension {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
ShaderExtension::Slang => f.write_str("slang"),
ShaderExtension::Glsl => f.write_str("glsl"),
ShaderExtension::Cg => f.write_str("cg"),
}
}
}
/// Valid extensions for shader presets
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
pub enum PresetExtension {
/// `.slangp`
Slangp = 0,
/// `.glslp`
Glslp,
/// `.cgp`
Cgp,
}
impl Display for PresetExtension {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
PresetExtension::Slangp => f.write_str("slangp"),
PresetExtension::Glslp => f.write_str("glslp"),
PresetExtension::Cgp => f.write_str("cgp"),
}
}
}
/// Rotation of the viewport.
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
pub enum Rotation {
/// Zero
Zero = 0,
/// 90 degrees
Right = 1,
/// 180 degrees
Straight = 2,
/// 270 degrees
Reflex = 3,
}
impl From<u32> for Rotation {
fn from(value: u32) -> Self {
let value = value % 4;
match value {
0 => Rotation::Zero,
1 => Rotation::Right,
2 => Rotation::Straight,
3 => Rotation::Reflex,
_ => unreachable!(),
}
}
}
impl Add for Rotation {
type Output = Rotation;
fn add(self, rhs: Self) -> Self::Output {
let lhs = self as u32;
let out = lhs + rhs as u32;
Rotation::from(out)
}
}
impl Display for Rotation {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Rotation::Zero => f.write_str("0"),
Rotation::Right => f.write_str("90"),
Rotation::Straight => f.write_str("180"),
Rotation::Reflex => f.write_str("270"),
}
}
}
/// Orientation of aspect ratios
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
pub enum Orientation {
/// Vertical orientation.
Vertical = 0,
/// Horizontal orientation.
Horizontal,
}
impl Display for Orientation {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Orientation::Vertical => f.write_str("VERT"),
Orientation::Horizontal => f.write_str("HORZ"),
}
}
}
/// An item representing a variable that can be replaced in a path preset.
#[derive(Debug, Clone)]
pub enum ContextItem {
/// The content directory of the game (`CONTENT-DIR`)
ContentDirectory(String),
/// The name of the libretro core (`CORE`)
CoreName(String),
/// The filename of the game (`GAME`)
GameName(String),
/// The name of the preset (`PRESET`)
Preset(String),
/// The name of the preset directory (`PRESET_DIR`)
PresetDirectory(String),
/// The video driver (runtime) (`VID-DRV`)
VideoDriver(VideoDriver),
/// The extension of shader types supported by the driver (`VID-DRV-SHADER-EXT`)
VideoDriverShaderExtension(ShaderExtension),
/// The extension of shader presets supported by the driver (`VID-DRV-PRESET-EXT`)
VideoDriverPresetExtension(PresetExtension),
/// The rotation that the core is requesting (`CORE-REQ-ROT`)
CoreRequestedRotation(Rotation),
/// Whether or not to allow core-requested rotation (`VID-ALLOW-CORE-ROT`)
AllowCoreRotation(bool),
/// The rotation the user is requesting (`VID-USER-ROT`)
UserRotation(Rotation),
/// The final rotation (`VID-FINAL-ROT`) calculated by the sum of `VID-USER-ROT` and `CORE-REQ-ROT`
FinalRotation(Rotation),
/// The user-adjusted screen orientation (`SCREEN-ORIENT`)
ScreenOrientation(Rotation),
/// The orientation of the viewport aspect ratio (`VIEW-ASPECT-ORIENT`)
ViewAspectOrientation(Orientation),
/// The orientation of the aspect ratio requested by the core (`CORE-ASPECT-ORIENT`)
CoreAspectOrientation(Orientation),
/// An external, arbitrary context variable.
ExternContext(String, String),
}
impl ContextItem {
fn toggle_str(v: bool) -> &'static str {
if v {
"ON"
} else {
"OFF"
}
}
pub fn key(&self) -> &str {
match self {
ContextItem::ContentDirectory(_) => "CONTENT-DIR",
ContextItem::CoreName(_) => "CORE",
ContextItem::GameName(_) => "GAME",
ContextItem::Preset(_) => "PRESET",
ContextItem::PresetDirectory(_) => "PRESET_DIR",
ContextItem::VideoDriver(_) => "VID-DRV",
ContextItem::CoreRequestedRotation(_) => "CORE-REQ-ROT",
ContextItem::AllowCoreRotation(_) => "VID-ALLOW-CORE-ROT",
ContextItem::UserRotation(_) => "VID-USER-ROT",
ContextItem::FinalRotation(_) => "VID-FINAL-ROT",
ContextItem::ScreenOrientation(_) => "SCREEN-ORIENT",
ContextItem::ViewAspectOrientation(_) => "VIEW-ASPECT-ORIENT",
ContextItem::CoreAspectOrientation(_) => "CORE-ASPECT-ORIENT",
ContextItem::VideoDriverShaderExtension(_) => "VID-DRV-SHADER-EXT",
ContextItem::VideoDriverPresetExtension(_) => "VID-DRV-PRESET-EXT",
ContextItem::ExternContext(key, _) => key,
}
}
}
impl Display for ContextItem {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
ContextItem::ContentDirectory(v) => f.write_str(v),
ContextItem::CoreName(v) => f.write_str(v),
ContextItem::GameName(v) => f.write_str(v),
ContextItem::Preset(v) => f.write_str(v),
ContextItem::PresetDirectory(v) => f.write_str(v),
ContextItem::VideoDriver(v) => f.write_fmt(format_args!("{}", v)),
ContextItem::CoreRequestedRotation(v) => {
f.write_fmt(format_args!("{}-{}", self.key(), v))
}
ContextItem::AllowCoreRotation(v) => f.write_fmt(format_args!(
"{}-{}",
self.key(),
ContextItem::toggle_str(*v)
)),
ContextItem::UserRotation(v) => f.write_fmt(format_args!("{}-{}", self.key(), v)),
ContextItem::FinalRotation(v) => f.write_fmt(format_args!("{}-{}", self.key(), v)),
ContextItem::ScreenOrientation(v) => f.write_fmt(format_args!("{}-{}", self.key(), v)),
ContextItem::ViewAspectOrientation(v) => {
f.write_fmt(format_args!("{}-{}", self.key(), v))
}
ContextItem::CoreAspectOrientation(v) => {
f.write_fmt(format_args!("{}-{}", self.key(), v))
}
ContextItem::VideoDriverShaderExtension(v) => f.write_fmt(format_args!("{}", v)),
ContextItem::VideoDriverPresetExtension(v) => f.write_fmt(format_args!("{}", v)),
ContextItem::ExternContext(_, v) => f.write_fmt(format_args!("{}", v)),
}
}
}
/// A preset wildcard context.
///
/// Any items added after will have higher priority
/// when passed to the shader preset parser.
///
/// When passed to the preset parser, the preset parser
/// will automatically add inferred items at lowest priority.
///
/// Any items added by the user will override the automatically
/// inferred items.
#[derive(Debug, Clone)]
pub struct WildcardContext(VecDeque<ContextItem>);
impl WildcardContext {
/// Create a new wildcard context.
pub fn new() -> Self {
Self(VecDeque::new())
}
/// Prepend an item to the context builder.
pub fn prepend_item(&mut self, item: ContextItem) {
self.0.push_front(item);
}
/// Append an item to the context builder.
/// The new item will take precedence over all items added before it.
pub fn append_item(&mut self, item: ContextItem) {
self.0.push_back(item);
}
/// Prepend sensible defaults for the given video driver.
///
/// Any values added, either previously or afterwards will not be overridden.
pub fn add_video_driver_defaults(&mut self, video_driver: VideoDriver) {
self.prepend_item(ContextItem::VideoDriverPresetExtension(
PresetExtension::Slangp,
));
self.prepend_item(ContextItem::VideoDriverShaderExtension(
ShaderExtension::Slang,
));
self.prepend_item(ContextItem::VideoDriver(video_driver));
}
/// Prepend default entries from the path of the preset.
///
/// Any values added, either previously or afterwards will not be overridden.
pub fn add_path_defaults(&mut self, path: impl AsRef<Path>) {
let path = path.as_ref();
if let Some(preset_name) = path.file_stem() {
let preset_name = preset_name.to_string_lossy();
self.prepend_item(ContextItem::Preset(preset_name.into()))
}
if let Some(preset_dir_name) = path.parent().and_then(|p| {
if !p.is_dir() {
return None;
};
p.file_name()
}) {
let preset_dir_name = preset_dir_name.to_string_lossy();
self.prepend_item(ContextItem::PresetDirectory(preset_dir_name.into()))
}
}
pub(crate) fn to_hashmap(mut self) -> FxHashMap<String, String> {
let mut map = FxHashMap::default();
let last_user_rot = self
.0
.iter()
.rfind(|i| matches!(i, ContextItem::UserRotation(_)));
let last_core_rot = self
.0
.iter()
.rfind(|i| matches!(i, ContextItem::CoreRequestedRotation(_)));
let final_rot = match (last_core_rot, last_user_rot) {
(Some(ContextItem::UserRotation(u)), None) => Some(ContextItem::FinalRotation(*u)),
(None, Some(ContextItem::CoreRequestedRotation(c))) => {
Some(ContextItem::FinalRotation(*c))
}
(Some(ContextItem::UserRotation(u)), Some(ContextItem::CoreRequestedRotation(c))) => {
Some(ContextItem::FinalRotation(*u + *c))
}
_ => None,
};
if let Some(final_rot) = final_rot {
self.prepend_item(final_rot);
}
for item in self.0 {
map.insert(String::from(item.key()), item.to_string());
}
map
}
}
pub(crate) fn apply_context(path: &mut PathBuf, context: &FxHashMap<String, String>) {
static WILDCARD_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new("\\$([A-Z-_]+)\\$").unwrap());
if context.is_empty() {
return;
}
// Don't want to do any extra work if there's no match.
if !WILDCARD_REGEX.is_match(path.as_os_str().as_encoded_bytes()) {
return;
}
let mut new_path = PathBuf::with_capacity(path.capacity());
for component in path.components() {
match component {
Component::Normal(path) => {
let haystack = path.as_encoded_bytes();
let replaced =
WILDCARD_REGEX.replace_all(haystack, |caps: &regex::bytes::Captures| {
let Some(name) = caps.get(1) else {
return caps[0].to_vec();
};
let Ok(key) = std::str::from_utf8(name.as_bytes()) else {
return caps[0].to_vec();
};
if let Some(replacement) = context.get(key) {
return OsString::from(replacement.to_string()).into_encoded_bytes();
}
return caps[0].to_vec();
});
// SAFETY: The original source is valid encoded bytes, and our replacement is
// valid encoded bytes. This upholds the safety requirements of `from_encoded_bytes_unchecked`.
new_path.push(unsafe { OsStr::from_encoded_bytes_unchecked(&replaced.as_ref()) })
}
_ => new_path.push(component),
}
}
// If no wildcards are found within the path, or the path after replacing the wildcards does not exist on disk, the path returned will be unaffected.
if let Ok(true) = new_path.try_exists() {
*path = new_path;
}
}

View file

@ -11,6 +11,7 @@ pub(crate) type Span<'a> = LocatedSpan<&'a str>;
pub(crate) use token::Token; pub(crate) use token::Token;
use crate::error::ParsePresetError; use crate::error::ParsePresetError;
use crate::context::{VideoDriver, WildcardContext};
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;
@ -21,8 +22,38 @@ pub(crate) fn remove_if<T>(values: &mut Vec<T>, f: impl FnMut(&T) -> bool) -> Op
impl ShaderPreset { impl ShaderPreset {
/// Try to parse the shader preset at the given path. /// Try to parse the shader preset at the given path.
///
/// This will add path defaults to the wildcard resolution context.
pub fn try_parse(path: impl AsRef<Path>) -> Result<ShaderPreset, ParsePresetError> { pub fn try_parse(path: impl AsRef<Path>) -> Result<ShaderPreset, ParsePresetError> {
let values = parse_preset(path)?; let mut context = WildcardContext::new();
context.add_path_defaults(path.as_ref());
let values = parse_preset(path, WildcardContext::new())?;
Ok(resolve_values(values))
}
/// Try to parse the shader preset at the given path.
///
/// This will add path and driver defaults to the wildcard resolution context.
pub fn try_parse_with_driver_context(
path: impl AsRef<Path>,
driver: VideoDriver,
) -> Result<ShaderPreset, ParsePresetError> {
let mut context = WildcardContext::new();
context.add_path_defaults(path.as_ref());
context.add_video_driver_defaults(driver);
let values = parse_preset(path, context)?;
Ok(resolve_values(values))
}
/// Try to parse the shader preset at the given path, with the exact provided context.
///
/// This function does not change any of the values in the provided context, except calculating `VID-FINAL-ROT`
/// if `CORE-REQ-ROT` and `VID-USER-ROT` is present.
pub fn try_parse_with_context(
path: impl AsRef<Path>,
context: WildcardContext,
) -> Result<ShaderPreset, ParsePresetError> {
let values = parse_preset(path, context)?;
Ok(resolve_values(values)) Ok(resolve_values(values))
} }
} }

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::{do_lex, single_comment}; use crate::parse::token::{single_comment};
#[test] #[test]
fn parses_single_line_comment() { fn parses_single_line_comment() {

View file

@ -11,12 +11,14 @@ use num_traits::cast::ToPrimitive;
use crate::parse::token::do_lex; use crate::parse::token::do_lex;
use librashader_common::{FilterMode, WrapMode}; use librashader_common::{FilterMode, WrapMode};
use rustc_hash::FxHashMap;
use std::fs::File; use std::fs::File;
use std::io::Read; 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::extract_if::MakeExtractIf;
use crate::context::{apply_context, WildcardContext};
#[derive(Debug)] #[derive(Debug)]
pub enum Value { pub enum Value {
@ -150,9 +152,11 @@ fn parse_indexed_key<'a>(key: &'static str, input: Span<'a>) -> IResult<Span<'a>
pub const SHADER_MAX_REFERENCE_DEPTH: usize = 16; pub const SHADER_MAX_REFERENCE_DEPTH: usize = 16;
// prereq: root_path must be contextualized
fn load_child_reference_strings( fn load_child_reference_strings(
root_references: Vec<PathBuf>, root_references: Vec<PathBuf>,
root_path: impl AsRef<Path>, root_path: impl AsRef<Path>,
context: &FxHashMap<String, String>,
) -> Result<Vec<(PathBuf, String)>, ParsePresetError> { ) -> Result<Vec<(PathBuf, String)>, ParsePresetError> {
let root_path = root_path.as_ref(); let root_path = root_path.as_ref();
@ -161,13 +165,14 @@ fn load_child_reference_strings(
let root_references = vec![(root_path.to_path_buf(), root_references)]; let root_references = vec![(root_path.to_path_buf(), root_references)];
let mut root_references = VecDeque::from(root_references); let mut root_references = VecDeque::from(root_references);
// search needs to be depth first to allow for overrides. // search needs to be depth first to allow for overrides.
while let Some((reference_root, referenced_paths)) = root_references.pop_front() { while let Some((mut reference_root, referenced_paths)) = root_references.pop_front() {
if reference_depth > SHADER_MAX_REFERENCE_DEPTH { if reference_depth > SHADER_MAX_REFERENCE_DEPTH {
return Err(ParsePresetError::ExceededReferenceDepth); return Err(ParsePresetError::ExceededReferenceDepth);
} }
// enter the current root // enter the current root
reference_depth += 1; reference_depth += 1;
// canonicalize current root // canonicalize current root
apply_context(&mut reference_root, context);
let reference_root = reference_root let reference_root = reference_root
.canonicalize() .canonicalize()
.map_err(|e| ParsePresetError::IOError(reference_root.to_path_buf(), e))?; .map_err(|e| ParsePresetError::IOError(reference_root.to_path_buf(), e))?;
@ -176,8 +181,10 @@ fn load_child_reference_strings(
// println!("Resolving {referenced_paths:?} against {reference_root:?}."); // println!("Resolving {referenced_paths:?} against {reference_root:?}.");
for path in referenced_paths { for path in referenced_paths {
let mut path = reference_root let mut path = reference_root.join(path.clone());
.join(path.clone()) apply_context(&mut path, context);
let mut path = path
.canonicalize() .canonicalize()
.map_err(|e| ParsePresetError::IOError(path.clone(), e))?; .map_err(|e| ParsePresetError::IOError(path.clone(), e))?;
// println!("Opening {:?}", path); // println!("Opening {:?}", path);
@ -204,8 +211,16 @@ fn load_child_reference_strings(
Ok(reference_strings.into()) Ok(reference_strings.into())
} }
pub fn parse_preset(path: impl AsRef<Path>) -> Result<Vec<Value>, ParsePresetError> { pub(crate) fn parse_preset(
path: impl AsRef<Path>,
context: WildcardContext,
) -> Result<Vec<Value>, ParsePresetError> {
let path = path.as_ref(); let path = path.as_ref();
let mut path = path.to_path_buf();
let context = context.to_hashmap();
apply_context(&mut path, &context);
let path = path let path = path
.canonicalize() .canonicalize()
.map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?; .map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?;
@ -216,12 +231,14 @@ pub fn parse_preset(path: impl AsRef<Path>) -> Result<Vec<Value>, ParsePresetErr
.map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?; .map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?;
let tokens = super::token::do_lex(&contents)?; let tokens = super::token::do_lex(&contents)?;
parse_values(tokens, path) parse_values(tokens, path, context)
} }
// prereq: root_path must be contextualized
pub fn parse_values( pub fn parse_values(
mut tokens: Vec<Token>, mut tokens: Vec<Token>,
root_path: impl AsRef<Path>, root_path: impl AsRef<Path>,
context: FxHashMap<String, String>,
) -> Result<Vec<Value>, ParsePresetError> { ) -> Result<Vec<Value>, ParsePresetError> {
let mut root_path = root_path.as_ref().to_path_buf(); let mut root_path = root_path.as_ref().to_path_buf();
if root_path.is_relative() { if root_path.is_relative() {
@ -239,7 +256,9 @@ pub fn parse_values(
.collect(); .collect();
// unfortunately we need to lex twice because there's no way to know the references ahead of time. // unfortunately we need to lex twice because there's no way to know the references ahead of time.
let child_strings = load_child_reference_strings(references, &root_path)?; // the returned references should have context applied
let child_strings = load_child_reference_strings(references, &root_path, &context)?;
let mut all_tokens: Vec<(&Path, Vec<Token>)> = Vec::new(); let mut all_tokens: Vec<(&Path, Vec<Token>)> = Vec::new();
for (path, string) in child_strings.iter() { for (path, string) in child_strings.iter() {
@ -597,12 +616,13 @@ pub fn parse_values(
mod test { mod test {
use crate::parse::value::parse_preset; use crate::parse::value::parse_preset;
use std::path::PathBuf; use std::path::PathBuf;
use crate::WildcardContext;
#[test] #[test]
pub fn parse_basic() { pub fn parse_basic() {
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, WildcardContext::new());
eprintln!("{basic:?}"); eprintln!("{basic:?}");
assert!(basic.is_ok()); assert!(basic.is_ok());
} }

View file

@ -1,4 +1,5 @@
use glob::glob; use glob::glob;
use librashader_presets::context::{ContextItem, VideoDriver, WildcardContext};
use librashader_presets::ShaderPreset; use librashader_presets::ShaderPreset;
#[test] #[test]
@ -17,3 +18,17 @@ fn parses_problematic() {
let path = "../test/Mega_Bezel_Packs/Duimon-Mega-Bezel/Presets/Advanced/Nintendo_NDS_DREZ/NDS-[DREZ]-[Native]-[ADV]-[Guest]-[Night].slangp"; let path = "../test/Mega_Bezel_Packs/Duimon-Mega-Bezel/Presets/Advanced/Nintendo_NDS_DREZ/NDS-[DREZ]-[Native]-[ADV]-[Guest]-[Night].slangp";
ShaderPreset::try_parse(path).expect(&format!("Failed to parse {}", path)); ShaderPreset::try_parse(path).expect(&format!("Failed to parse {}", path));
} }
#[test]
fn parses_wildcard() {
let path =
"../test/shaders_slang/bezel/Mega_Bezel/resource/wildcard-examples/Preset-01-Core.slangp";
let mut context = WildcardContext::new();
context.add_video_driver_defaults(VideoDriver::Vulkan);
context.append_item(ContextItem::CoreName(String::from("image display")));
ShaderPreset::try_parse_with_context(path, context)
.expect(&format!("Failed to parse {}", path));
}

View file

@ -3,7 +3,7 @@ name = "librashader-reflect"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -19,15 +19,15 @@ thiserror = "1.0.37"
bitflags = "2.4.2" bitflags = "2.4.2"
rustc-hash = "1.1.0" rustc-hash = "1.1.0"
librashader-common = { path = "../librashader-common", version = "0.2.0-beta.7" } librashader-common = { path = "../librashader-common", version = "0.2.0-beta.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.8" }
spirv_cross = { package = "librashader-spirv-cross", version = "0.23", optional = true } spirv_cross = { package = "librashader-spirv-cross", version = "0.23", optional = true }
naga = { version = "0.19.0", features = ["spv-in", "wgsl-out"], optional = true } naga = { version = "0.19.0", features = ["spv-in", "wgsl-out"], optional = true }
rspirv = { version = "0.12.0+sdk-1.3.268.0", optional = true } rspirv = { version = "0.12.0", optional = true }
spirv = { version = "0.3.0+sdk-1.3.268.0", optional = true} spirv = { version = "0.3.0", optional = true}
serde = { version = "1.0", features = ["derive"], optional = true } serde = { version = "1.0", features = ["derive"], optional = true }

View file

@ -1,5 +1,5 @@
use glslang::{CompilerOptions, ShaderInput};
use crate::error::ShaderCompileError; use crate::error::ShaderCompileError;
use glslang::{CompilerOptions, ShaderInput};
use librashader_preprocess::ShaderSource; use librashader_preprocess::ShaderSource;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
@ -37,27 +37,17 @@ pub(crate) fn compile_spirv(
source_language: glslang::SourceLanguage::GLSL, source_language: glslang::SourceLanguage::GLSL,
target: glslang::Target::Vulkan { target: glslang::Target::Vulkan {
version: glslang::VulkanVersion::Vulkan1_0, version: glslang::VulkanVersion::Vulkan1_0,
spirv_version: glslang::SpirvVersion::SPIRV1_0 spirv_version: glslang::SpirvVersion::SPIRV1_0,
}, },
version_profile: None, version_profile: None,
}; };
let vertex = glslang::ShaderSource::from(source.vertex.as_str()); let vertex = glslang::ShaderSource::from(source.vertex.as_str());
let vertex = ShaderInput::new( let vertex = ShaderInput::new(&vertex, glslang::ShaderStage::Vertex, &options, None)?;
&vertex,
glslang::ShaderStage::Vertex,
&options,
None,
)?;
let vertex = compiler.create_shader(vertex)?; let vertex = compiler.create_shader(vertex)?;
let fragment = glslang::ShaderSource::from(source.fragment.as_str()); let fragment = glslang::ShaderSource::from(source.fragment.as_str());
let fragment = ShaderInput::new( let fragment = ShaderInput::new(&fragment, glslang::ShaderStage::Fragment, &options, None)?;
&fragment,
glslang::ShaderStage::Fragment,
&options,
None,
)?;
let fragment = compiler.create_shader(fragment)?; let fragment = compiler.create_shader(fragment)?;
let vertex = Vec::from(vertex.compile()?); let vertex = Vec::from(vertex.compile()?);

View file

@ -3,7 +3,7 @@ name = "librashader-runtime-d3d11"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -12,13 +12,13 @@ keywords = ["shader", "retroarch", "SPIR-V"]
description = "RetroArch shaders for all." description = "RetroArch shaders for all."
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", features = ["d3d11"], version = "0.2.0-beta.7" } librashader-common = { path = "../librashader-common", features = ["d3d11"], version = "0.2.0-beta.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.7" } librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.8" }
librashader-runtime = { path = "../librashader-runtime", version = "0.2.0-beta.7" } librashader-runtime = { path = "../librashader-runtime", version = "0.2.0-beta.8" }
spirv_cross = { package = "librashader-spirv-cross", version = "0.23" } spirv_cross = { package = "librashader-spirv-cross", version = "0.23" }
librashader-cache = { path = "../librashader-cache", version = "0.2.0-beta.7", features = ["d3d"] } librashader-cache = { path = "../librashader-cache", version = "0.2.0-beta.8", features = ["d3d"] }
thiserror = "1.0.37" thiserror = "1.0.37"
rustc-hash = "1.1.0" rustc-hash = "1.1.0"

View file

@ -24,6 +24,7 @@ use crate::util::d3d11_compile_bound_shader;
use crate::{error, util, D3D11OutputView}; use crate::{error, util, D3D11OutputView};
use librashader_cache::cache_shader_object; use librashader_cache::cache_shader_object;
use librashader_cache::CachedCompilation; use librashader_cache::CachedCompilation;
use librashader_presets::context::VideoDriver;
use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact}; use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
use librashader_runtime::binding::{BindingUtil, TextureInput}; use librashader_runtime::binding::{BindingUtil, TextureInput};
use librashader_runtime::framebuffer::FramebufferInit; use librashader_runtime::framebuffer::FramebufferInit;
@ -98,7 +99,7 @@ impl FilterChainD3D11 {
options: Option<&FilterChainOptionsD3D11>, options: Option<&FilterChainOptionsD3D11>,
) -> error::Result<FilterChainD3D11> { ) -> error::Result<FilterChainD3D11> {
// load passes from preset // load passes from preset
let preset = ShaderPreset::try_parse(path)?; let preset = ShaderPreset::try_parse_with_driver_context(path, VideoDriver::Direct3D11)?;
unsafe { Self::load_from_preset(preset, device, options) } unsafe { Self::load_from_preset(preset, device, options) }
} }

View file

@ -3,7 +3,7 @@ name = "librashader-runtime-d3d12"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -12,12 +12,12 @@ keywords = ["shader", "retroarch", "SPIR-V"]
description = "RetroArch shaders for all." description = "RetroArch shaders for all."
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", features = ["d3d12"], version = "0.2.0-beta.7" } librashader-common = { path = "../librashader-common", features = ["d3d12"], version = "0.2.0-beta.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.7", features = ["dxil"] } librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.8", features = ["dxil"] }
librashader-runtime = { path = "../librashader-runtime", version = "0.2.0-beta.7" } librashader-runtime = { path = "../librashader-runtime", version = "0.2.0-beta.8" }
librashader-cache = { path = "../librashader-cache", version = "0.2.0-beta.7", features = ["d3d"] } librashader-cache = { path = "../librashader-cache", version = "0.2.0-beta.8", features = ["d3d"] }
thiserror = "1.0.37" thiserror = "1.0.37"
spirv_cross = { package = "librashader-spirv-cross", version = "0.23" } spirv_cross = { package = "librashader-spirv-cross", version = "0.23" }

View file

@ -47,6 +47,7 @@ use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_UNKNOWN;
use windows::Win32::System::Threading::{CreateEventA, WaitForSingleObject, INFINITE}; use windows::Win32::System::Threading::{CreateEventA, WaitForSingleObject, INFINITE};
use librashader_cache::CachedCompilation; use librashader_cache::CachedCompilation;
use librashader_presets::context::VideoDriver;
use librashader_runtime::framebuffer::FramebufferInit; use librashader_runtime::framebuffer::FramebufferInit;
use librashader_runtime::render_target::RenderTarget; use librashader_runtime::render_target::RenderTarget;
use librashader_runtime::scaling::ScaleFramebuffer; use librashader_runtime::scaling::ScaleFramebuffer;
@ -186,7 +187,7 @@ impl FilterChainD3D12 {
options: Option<&FilterChainOptionsD3D12>, options: Option<&FilterChainOptionsD3D12>,
) -> error::Result<FilterChainD3D12> { ) -> error::Result<FilterChainD3D12> {
// load passes from preset // load passes from preset
let preset = ShaderPreset::try_parse(path)?; let preset = ShaderPreset::try_parse_with_driver_context(path, VideoDriver::Direct3D12)?;
unsafe { Self::load_from_preset(preset, device, options) } unsafe { Self::load_from_preset(preset, device, options) }
} }

View file

@ -3,7 +3,7 @@ name = "librashader-runtime-gl"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -12,12 +12,12 @@ keywords = ["shader", "retroarch", "SPIR-V"]
description = "RetroArch shaders for all." description = "RetroArch shaders for all."
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", features = ["opengl"], version = "0.2.0-beta.7" } librashader-common = { path = "../librashader-common", features = ["opengl"], version = "0.2.0-beta.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.7" } librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.8" }
librashader-runtime = { path = "../librashader-runtime" , version = "0.2.0-beta.7" } librashader-runtime = { path = "../librashader-runtime" , version = "0.2.0-beta.8" }
librashader-cache = { path = "../librashader-cache", version = "0.2.0-beta.7" } librashader-cache = { path = "../librashader-cache", version = "0.2.0-beta.8" }
spirv_cross = { package = "librashader-spirv-cross", version = "0.23" } spirv_cross = { package = "librashader-spirv-cross", version = "0.23" }
rustc-hash = "1.1.0" rustc-hash = "1.1.0"

View file

@ -14,6 +14,7 @@ mod parameters;
pub(crate) use filter_impl::FilterCommon; pub(crate) use filter_impl::FilterCommon;
use librashader_common::Viewport; use librashader_common::Viewport;
use librashader_presets::context::VideoDriver;
/// An OpenGL filter chain. /// An OpenGL filter chain.
pub struct FilterChainGL { pub struct FilterChainGL {
@ -42,10 +43,7 @@ impl FilterChainGL {
}), }),
}) })
}); });
match result { result.unwrap_or_else(|_| Err(FilterChainError::GLLoadError))
Err(_) => Err(FilterChainError::GLLoadError),
Ok(res) => res,
}
} }
/// Load the shader preset at the given path into a filter chain. /// Load the shader preset at the given path into a filter chain.
@ -54,7 +52,7 @@ impl FilterChainGL {
options: Option<&FilterChainOptionsGL>, options: Option<&FilterChainOptionsGL>,
) -> Result<Self> { ) -> Result<Self> {
// load passes from preset // load passes from preset
let preset = ShaderPreset::try_parse(path)?; let preset = ShaderPreset::try_parse_with_driver_context(path, VideoDriver::GlCore)?;
unsafe { Self::load_from_preset(preset, options) } unsafe { Self::load_from_preset(preset, options) }
} }

View file

@ -3,7 +3,7 @@ name = "librashader-runtime-vk"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -14,18 +14,18 @@ description = "RetroArch shaders for all."
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", features = ["vulkan"], version = "0.2.0-beta.7" } librashader-common = { path = "../librashader-common", features = ["vulkan"], version = "0.2.0-beta.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.7" } librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.8" }
librashader-runtime = { path = "../librashader-runtime" , version = "0.2.0-beta.7" } librashader-runtime = { path = "../librashader-runtime" , version = "0.2.0-beta.8" }
librashader-cache = { path = "../librashader-cache", version = "0.2.0-beta.7" } librashader-cache = { path = "../librashader-cache", version = "0.2.0-beta.8" }
spirv_cross = { package = "librashader-spirv-cross", version = "0.23" } spirv_cross = { package = "librashader-spirv-cross", version = "0.23" }
rustc-hash = "1.1.0" rustc-hash = "1.1.0"
bytemuck = "1.12.3" bytemuck = "1.12.3"
thiserror = "1.0.37" thiserror = "1.0.37"
ash = { version = "0.37.1+1.3.235", features = ["debug"] } ash = { version = "0.37", features = ["debug"] }
gpu-allocator = { version = "0.22.0", default-features = false, features = ["vulkan"] } gpu-allocator = { version = "0.22.0", default-features = false, features = ["vulkan"] }
parking_lot = "0.12.1" parking_lot = "0.12.1"
rayon = "1.6.1" rayon = "1.6.1"

View file

@ -33,6 +33,7 @@ use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
use librashader_cache::CachedCompilation; use librashader_cache::CachedCompilation;
use librashader_presets::context::VideoDriver;
use librashader_runtime::framebuffer::FramebufferInit; use librashader_runtime::framebuffer::FramebufferInit;
use librashader_runtime::render_target::RenderTarget; use librashader_runtime::render_target::RenderTarget;
use librashader_runtime::scaling::ScaleFramebuffer; use librashader_runtime::scaling::ScaleFramebuffer;
@ -236,7 +237,7 @@ impl FilterChainVulkan {
FilterChainError: From<E>, FilterChainError: From<E>,
{ {
// load passes from preset // load passes from preset
let preset = ShaderPreset::try_parse(path)?; let preset = ShaderPreset::try_parse_with_driver_context(path, VideoDriver::Vulkan)?;
unsafe { Self::load_from_preset(preset, vulkan, options) } unsafe { Self::load_from_preset(preset, vulkan, options) }
} }

View file

@ -2,7 +2,7 @@
name = "librashader-runtime-wgpu" name = "librashader-runtime-wgpu"
edition = "2021" edition = "2021"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
@ -14,11 +14,11 @@ description = "RetroArch shaders for all."
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", features = ["wgpu"], version = "0.2.0-beta.7" } librashader-common = { path = "../librashader-common", features = ["wgpu"], version = "0.2.0-beta.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.7", features = ["wgsl"], default-features = false } librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.8", features = ["wgsl"], default-features = false }
librashader-runtime = { path = "../librashader-runtime" , version = "0.2.0-beta.7" } librashader-runtime = { path = "../librashader-runtime" , version = "0.2.0-beta.8" }
wgpu = { version = "0.19.0", features = ["spirv"] } wgpu = { version = "0.19.0", features = ["spirv"] }
rustc-hash = "1.1.0" rustc-hash = "1.1.0"

View file

@ -3,7 +3,7 @@ name = "librashader-runtime"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -12,10 +12,10 @@ keywords = ["shader", "retroarch", "SPIR-V"]
description = "RetroArch shaders for all." description = "RetroArch shaders for all."
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", version = "0.2.0-beta.7" } librashader-common = { path = "../librashader-common", version = "0.2.0-beta.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.7" } librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.8" }
bytemuck = "1.12.3" bytemuck = "1.12.3"
rustc-hash = "1.1.0" rustc-hash = "1.1.0"
num-traits = "0.2.15" num-traits = "0.2.15"

View file

@ -4,7 +4,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.0-beta.7" version = "0.2.0-beta.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -13,18 +13,18 @@ keywords = ["shader", "retroarch", "SPIR-V"]
description = "RetroArch shaders for all." description = "RetroArch shaders for all."
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", version = "0.2.0-beta.7" } librashader-common = { path = "../librashader-common", version = "0.2.0-beta.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.0-beta.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.0-beta.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.7" } librashader-reflect = { path = "../librashader-reflect", version = "0.2.0-beta.8" }
librashader-runtime = { path = "../librashader-runtime", version = "0.2.0-beta.7" } librashader-runtime = { path = "../librashader-runtime", version = "0.2.0-beta.8" }
librashader-runtime-d3d11 = { path = "../librashader-runtime-d3d11", version = "0.2.0-beta.7", optional = true } librashader-runtime-d3d11 = { path = "../librashader-runtime-d3d11", version = "0.2.0-beta.8", optional = true }
librashader-runtime-d3d12 = { path = "../librashader-runtime-d3d12", version = "0.2.0-beta.7", optional = true } librashader-runtime-d3d12 = { path = "../librashader-runtime-d3d12", version = "0.2.0-beta.8", optional = true }
librashader-runtime-gl = { path = "../librashader-runtime-gl", version = "0.2.0-beta.7", optional = true } librashader-runtime-gl = { path = "../librashader-runtime-gl", version = "0.2.0-beta.8", optional = true }
librashader-runtime-vk = { path = "../librashader-runtime-vk", version = "0.2.0-beta.7", optional = true } librashader-runtime-vk = { path = "../librashader-runtime-vk", version = "0.2.0-beta.8", optional = true }
librashader-runtime-wgpu = { path = "../librashader-runtime-wgpu", version = "0.2.0-beta.7", optional = true } librashader-runtime-wgpu = { path = "../librashader-runtime-wgpu", version = "0.2.0-beta.8", optional = true }
librashader-cache = { path = "../librashader-cache", version = "0.2.0-beta.7" } librashader-cache = { path = "../librashader-cache", version = "0.2.0-beta.8" }
ash = { version = "0.37", optional = true } ash = { version = "0.37", optional = true }
wgpu = { version = "0.19", optional = true } wgpu = { version = "0.19", optional = true }

View file

@ -228,15 +228,6 @@ pub mod runtime {
options::{FilterChainOptionsGL as FilterChainOptions, FrameOptionsGL as FrameOptions}, options::{FilterChainOptionsGL as FilterChainOptions, FrameOptionsGL as FrameOptions},
FilterChainGL as FilterChain, GLFramebuffer, GLImage, FilterChainGL as FilterChain, GLFramebuffer, GLImage,
}; };
#[doc(hidden)]
#[cfg(feature = "internal")]
/// Re-exports names to deal with C API conflicts.
///
/// This is internal to librashader-capi and is exempt from semantic versioning.
pub mod capi {
pub use librashader_runtime_gl::*;
}
} }
#[cfg(all(target_os = "windows", feature = "runtime-d3d11"))] #[cfg(all(target_os = "windows", feature = "runtime-d3d11"))]
@ -250,15 +241,6 @@ pub mod runtime {
}, },
D3D11InputView, D3D11OutputView, FilterChainD3D11 as FilterChain, D3D11InputView, D3D11OutputView, FilterChainD3D11 as FilterChain,
}; };
#[doc(hidden)]
#[cfg(feature = "internal")]
/// Re-exports names to deal with C API conflicts.
///
/// This is internal to librashader-capi and is exempt from semantic versioning.
pub mod capi {
pub use librashader_runtime_d3d11::*;
}
} }
#[cfg(all(target_os = "windows", feature = "runtime-d3d12"))] #[cfg(all(target_os = "windows", feature = "runtime-d3d12"))]
@ -272,15 +254,6 @@ pub mod runtime {
}, },
D3D12InputImage, D3D12OutputView, FilterChainD3D12 as FilterChain, D3D12InputImage, D3D12OutputView, FilterChainD3D12 as FilterChain,
}; };
#[doc(hidden)]
#[cfg(feature = "internal")]
/// Re-exports names to deal with C API conflicts.
///
/// This is internal to librashader-capi and is exempt from semantic versioning.
pub mod capi {
pub use librashader_runtime_d3d12::*;
}
} }
#[cfg(feature = "runtime-vk")] #[cfg(feature = "runtime-vk")]
@ -294,15 +267,6 @@ pub mod runtime {
}, },
FilterChainVulkan as FilterChain, VulkanImage, VulkanInstance, VulkanObjects, FilterChainVulkan as FilterChain, VulkanImage, VulkanInstance, VulkanObjects,
}; };
#[doc(hidden)]
#[cfg(feature = "internal")]
/// Re-exports names to deal with C API conflicts.
///
/// This is internal to librashader-capi and is exempt from semantic versioning.
pub mod capi {
pub use librashader_runtime_vk::*;
}
} }
#[cfg(feature = "runtime-wgpu")] #[cfg(feature = "runtime-wgpu")]

View file

@ -15,10 +15,17 @@ int main()
std::cout << "Hello World!\n"; std::cout << "Hello World!\n";
std::cout << std::filesystem::current_path() << std::endl; std::cout << std::filesystem::current_path() << std::endl;
auto instance = librashader_load_instance(); auto instance = librashader_load_instance();
libra_preset_ctx_t context;
instance.preset_ctx_create(&context);
instance.preset_ctx_set_core_name(&context, "Hello");
libra_shader_preset_t preset; libra_shader_preset_t preset;
auto error = instance.preset_create( auto error = instance.preset_create_with_context(
"../../../shaders_slang/border/gameboy-player/" "../../../shaders_slang/border/gameboy-player/"
"gameboy-player-crt-royale.slangp", "gameboy-player-crt-royale.slangp",
&context,
&preset); &preset);
/* libra_shader_preset_t preset2; /* libra_shader_preset_t preset2;

@ -1 +1 @@
Subproject commit e04aa575febae5927db6b445a3c47b8f4221df78 Subproject commit a4e79022bb020294f8b155718829e18340364439