From f535d5c58fec1bc20792f9df9b1f6fa91641b944 Mon Sep 17 00:00:00 2001 From: igorsaux Date: Wed, 16 Oct 2024 18:26:16 +0300 Subject: [PATCH] retroarch shaders support --- Cargo.lock | 887 +++++++++++++++++- frontends/rioterm/src/application.rs | 4 + frontends/rioterm/src/context.rs | 6 +- frontends/rioterm/src/screen/mod.rs | 4 + rio-backend/src/config/defaults.rs | 9 + rio-backend/src/config/renderer.rs | 6 + sugarloaf/Cargo.toml | 1 + sugarloaf/src/components/text/mod.rs | 14 +- sugarloaf/src/components/text/pipeline.rs | 10 +- .../src/components/text/pipeline/cache.rs | 2 +- sugarloaf/src/context/mod.rs | 29 +- sugarloaf/src/sugarloaf.rs | 171 +++- 12 files changed, 1089 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0d573031ff..51723aab98 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -137,6 +137,24 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + +[[package]] +name = "array-concat" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b4d2c47ea522f4135657904891e533727daca3d2d852f29f5e4cc50960c77c" + +[[package]] +name = "array-init" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" + [[package]] name = "arrayref" version = "0.3.9" @@ -182,6 +200,25 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bincode" +version = "2.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f11ea1a0346b94ef188834a65c068a03aec181c94896d481d7a0a40d85b0ce95" +dependencies = [ + "bincode_derive", + "serde", +] + +[[package]] +name = "bincode_derive" +version = "2.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e30759b3b99a1b802a7a3aa21c85c3ded5c28e1c83170d82d70f08bbf7f3e4c" +dependencies = [ + "virtue", +] + [[package]] name = "bit-set" version = "0.6.0" @@ -214,6 +251,34 @@ name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake3" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if 1.0.0", + "constant_time_eq", +] [[package]] name = "block" @@ -239,12 +304,24 @@ dependencies = [ "cfg_aliases 0.2.1", ] +[[package]] +name = "build-target" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "832133bbabbbaa9fbdba793456a2827627a7d2b8fb96032fa1e7666d7895832b" + [[package]] name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "bytecount" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" + [[package]] name = "bytemuck" version = "1.18.0" @@ -321,6 +398,8 @@ version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" dependencies = [ + "jobserver", + "libc", "shlex", ] @@ -537,6 +616,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "copa" version = "0.1.14" @@ -675,6 +760,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" version = "1.4.2" @@ -816,6 +916,25 @@ dependencies = [ "winapi", ] +[[package]] +name = "d3d12-descriptor-heap" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0c31f7c86252e0198223a23394da4fc5ba5d381734a8c12551c94accc3ead7b" +dependencies = [ + "array-init", + "bitvec", + "thiserror", + "triomphe", + "windows 0.58.0", +] + +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + [[package]] name = "deflate" version = "1.0.0" @@ -834,6 +953,16 @@ dependencies = [ "dirs-sys", ] +[[package]] +name = "dirs-next" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf36e65a80337bea855cd4ef9b8401ffce06a7baedf2e85ec467b1ac3f6e82b6" +dependencies = [ + "cfg-if 1.0.0", + "dirs-sys-next", +] + [[package]] name = "dirs-sys" version = "0.4.1" @@ -846,6 +975,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -902,6 +1042,15 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "env_logger" version = "0.4.3" @@ -979,6 +1128,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.0.33" @@ -1080,6 +1235,16 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -1111,6 +1276,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futures" version = "0.3.30" @@ -1242,6 +1413,12 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "glow" version = "0.13.1" @@ -1254,6 +1431,41 @@ dependencies = [ "web-sys", ] +[[package]] +name = "glow" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51fa363f025f5c111e03f13eda21162faeacb6911fe8caa0c0349f9cf0c4483" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glslang" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4cc03ec3cde52c8e698ed6c0ed415afca69d6f89bf62034753c08e8a3bfb18f" +dependencies = [ + "bitflags 2.6.0", + "glslang-sys", + "rustc-hash 2.0.0", + "smartstring", + "thiserror", +] + +[[package]] +name = "glslang-sys" +version = "0.6.1+46ef757" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad4a20351d34b8185981fe9e00c2934f061b59f54705dc497e7ae9cbecec0a07" +dependencies = [ + "cc", + "glob", +] + [[package]] name = "glutin_wgl_sys" version = "0.6.0" @@ -1295,6 +1507,19 @@ dependencies = [ "windows 0.52.0", ] +[[package]] +name = "gpu-allocator" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" +dependencies = [ + "ash", + "log 0.4.22", + "presser", + "thiserror", + "windows 0.58.0", +] + [[package]] name = "gpu-descriptor" version = "0.3.0" @@ -1335,6 +1560,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "halfbrown" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8588661a8607108a5ca69cab034063441a0413a0b041c13618a7dd348021ef6f" +dependencies = [ + "hashbrown", + "serde", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -1419,6 +1654,7 @@ dependencies = [ "image-webp", "num-traits", "png", + "tiff", "zune-core", "zune-jpeg", ] @@ -1510,6 +1746,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + [[package]] name = "jpeg-decoder" version = "0.3.1" @@ -1566,37 +1811,336 @@ dependencies = [ ] [[package]] -name = "lazy-bytes-cast" -version = "5.0.1" +name = "lazy-bytes-cast" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10257499f089cd156ad82d0a9cd57d9501fa2c989068992a97eb3c27836f206b" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if 1.0.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "librashader" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7c758f9faf3f9ddc7e23bee4ee0ca6c23f2d010fded0baaff9607aeb2697df9" +dependencies = [ + "halfbrown", + "librashader-cache", + "librashader-common", + "librashader-pack", + "librashader-preprocess", + "librashader-presets", + "librashader-reflect", + "librashader-runtime", + "librashader-runtime-d3d11", + "librashader-runtime-d3d12", + "librashader-runtime-d3d9", + "librashader-runtime-gl", + "librashader-runtime-mtl", + "librashader-runtime-vk", + "librashader-runtime-wgpu", + "wgpu", + "wgpu-types", +] + +[[package]] +name = "librashader-cache" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e9027ac58b3fda9b8072737dff0ce38db49c2daf73308072e5b2d33a832ef7" +dependencies = [ + "bincode", + "blake3", + "bytemuck", + "librashader-preprocess", + "librashader-reflect", + "persy", + "platform-dirs", + "serde", + "thiserror", + "windows 0.58.0", +] + +[[package]] +name = "librashader-common" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f864ae711eebbba99dc3a674ebed13dcd46bf1537a13a102f9c98d89387c40c2" +dependencies = [ + "ash", + "glow 0.14.2", + "halfbrown", + "num-traits", + "objc2", + "objc2-metal", + "rustc-hash 2.0.0", + "serde", + "smartstring", + "wgpu-types", + "windows 0.58.0", +] + +[[package]] +name = "librashader-pack" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c47110b7f0756c22713392602b6d555087241a245de25d8561a5b726877ffb9a" +dependencies = [ + "image 0.25.2", + "librashader-preprocess", + "librashader-presets", + "rayon", + "thiserror", +] + +[[package]] +name = "librashader-preprocess" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad2fe98e3b738746306f303c5eb900de94fcc680d8ca4005ac853c29b3c1968" +dependencies = [ + "encoding_rs", + "librashader-common", + "nom", + "serde", + "thiserror", +] + +[[package]] +name = "librashader-presets" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2063c4e3f9e42e134543d6bfb15a2c79dafa0cc29d6ee3159774e88d84fe461" +dependencies = [ + "librashader-common", + "nom", + "nom_locate", + "num-traits", + "once_cell", + "regex", + "serde", + "thiserror", + "vec_extract_if_polyfill", +] + +[[package]] +name = "librashader-reflect" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d7d27947c53a1a87869aca9102efbd08bb73c0f8dbca60ea23da8708cd071d5" +dependencies = [ + "bitflags 2.6.0", + "bytemuck", + "glslang", + "librashader-common", + "librashader-pack", + "librashader-preprocess", + "librashader-presets", + "naga", + "rspirv", + "rustc-hash 2.0.0", + "serde", + "spirv", + "spirv-cross2", + "spirv-to-dxil", + "thiserror", +] + +[[package]] +name = "librashader-runtime" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b585e89c867bdce240296f3812350d0417b6afc2ce9aa2c05e623cb608fdc278" +dependencies = [ + "arc-swap", + "array-concat", + "bytemuck", + "image 0.25.2", + "librashader-common", + "librashader-pack", + "librashader-preprocess", + "librashader-presets", + "librashader-reflect", + "num-traits", +] + +[[package]] +name = "librashader-runtime-d3d11" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10c446ae964fe1430ab5ce0709860897ee977176bb06e542ad806fbdb543f1cd" +dependencies = [ + "array-concat", + "bytemuck", + "librashader-cache", + "librashader-common", + "librashader-pack", + "librashader-preprocess", + "librashader-presets", + "librashader-reflect", + "librashader-runtime", + "rayon", + "thiserror", + "windows 0.58.0", +] + +[[package]] +name = "librashader-runtime-d3d12" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49686f7e1c17084afe93337fea7046cd34618e6250a3819915a692d3cdc73169" +dependencies = [ + "array-concat", + "array-init", + "bitvec", + "bytemuck", + "d3d12-descriptor-heap", + "gpu-allocator 0.27.0", + "librashader-cache", + "librashader-common", + "librashader-pack", + "librashader-preprocess", + "librashader-presets", + "librashader-reflect", + "librashader-runtime", + "mach-siegbert-vogt-dxcsa", + "parking_lot", + "rayon", + "thiserror", + "widestring", + "windows 0.58.0", +] + +[[package]] +name = "librashader-runtime-d3d9" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10257499f089cd156ad82d0a9cd57d9501fa2c989068992a97eb3c27836f206b" +checksum = "f02b608bdf70d1b740fe303fe419245a11f69cef87331460741419b58f7a2f2f" +dependencies = [ + "array-concat", + "bytemuck", + "librashader-cache", + "librashader-common", + "librashader-pack", + "librashader-preprocess", + "librashader-presets", + "librashader-reflect", + "librashader-runtime", + "num-traits", + "rayon", + "thiserror", + "windows 0.58.0", + "windows-core 0.58.0", +] [[package]] -name = "lazy_static" -version = "1.5.0" +name = "librashader-runtime-gl" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "fe280f2b6f73ea05648812dfa7f7c49d0a5f33d2b9fc38d3d0fa2c58283a0e15" +dependencies = [ + "array-init", + "bytemuck", + "glow 0.14.2", + "librashader-cache", + "librashader-common", + "librashader-pack", + "librashader-preprocess", + "librashader-presets", + "librashader-reflect", + "librashader-runtime", + "rayon", + "spirv-cross2", + "thiserror", +] [[package]] -name = "lebe" -version = "0.5.2" +name = "librashader-runtime-mtl" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" +checksum = "adb16a9dac9735096008f92b32b55f36578da8b459bf92ace2bc76186ec9f9ce" +dependencies = [ + "array-concat", + "bytemuck", + "librashader-common", + "librashader-pack", + "librashader-preprocess", + "librashader-presets", + "librashader-reflect", + "librashader-runtime", + "objc2", + "objc2-foundation", + "objc2-metal", + "rayon", + "thiserror", +] [[package]] -name = "libc" -version = "0.2.158" +name = "librashader-runtime-vk" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "aaa50ec683e7a0c88c0e8790b77cdcd2e56e5cbfac6ec8378d1f93233a1efde0" +dependencies = [ + "array-concat", + "ash", + "bytemuck", + "gpu-allocator 0.27.0", + "librashader-cache", + "librashader-common", + "librashader-pack", + "librashader-preprocess", + "librashader-presets", + "librashader-reflect", + "librashader-runtime", + "parking_lot", + "rayon", + "thiserror", +] [[package]] -name = "libloading" -version = "0.8.5" +name = "librashader-runtime-wgpu" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "d46aaac03bd260aaac8555c04da0164678bf60eac9c302bdff1c06f096078dc1" dependencies = [ - "cfg-if 1.0.0", - "windows-targets 0.52.6", + "array-concat", + "bytemuck", + "librashader-cache", + "librashader-common", + "librashader-pack", + "librashader-preprocess", + "librashader-presets", + "librashader-reflect", + "librashader-runtime", + "rayon", + "thiserror", + "wgpu", ] [[package]] @@ -1673,6 +2217,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "mach-siegbert-vogt-dxcsa" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d3e62358869047ad84e507d5bcd47e7f3917629947ba34ac0b3e5969db00a7b" +dependencies = [ + "bytemuck", +] + [[package]] name = "malloc_buf" version = "0.0.6" @@ -1731,6 +2284,12 @@ dependencies = [ "walkdir", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.4" @@ -1794,6 +2353,7 @@ dependencies = [ "hexf-parse", "indexmap", "log 0.4.22", + "petgraph", "rustc-hash 1.1.0", "spirv", "termcolor", @@ -1821,6 +2381,27 @@ dependencies = [ "winapi", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nom_locate" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e3c83c053b0713da60c5b8de47fe8e494fe3ece5267b2f23090a07a053ba8f3" +dependencies = [ + "bytecount", + "memchr", + "nom", +] + [[package]] name = "notify" version = "6.1.1" @@ -1850,6 +2431,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -2074,6 +2666,32 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "persy" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58070b019476f812f780e0503b63207c256603f7e8703fdbe15bea7c692bc5be" +dependencies = [ + "crc", + "data-encoding", + "fs2", + "linked-hash-map", + "rand 0.8.5", + "thiserror", + "unsigned-varint", + "zigzag", +] + +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap", +] + [[package]] name = "pin-project" version = "1.1.5" @@ -2112,6 +2730,15 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "platform-dirs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e188d043c1a692985f78b5464853a263f1a27e5bd6322bad3a4078ee3c998a38" +dependencies = [ + "dirs-next", +] + [[package]] name = "plotters" version = "0.3.7" @@ -2231,6 +2858,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" version = "0.4.6" @@ -2566,6 +3199,16 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" +[[package]] +name = "rspirv" +version = "0.12.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cf3a93856b6e5946537278df0d3075596371b1950ccff012f02b0f7eafec8d" +dependencies = [ + "rustc-hash 1.1.0", + "spirv", +] + [[package]] name = "rustc-hash" version = "1.1.0" @@ -2747,6 +3390,18 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "serde", + "static_assertions", + "version_check", +] + [[package]] name = "smithay-client-toolkit" version = "0.19.2" @@ -2842,6 +3497,73 @@ dependencies = [ "bitflags 2.6.0", ] +[[package]] +name = "spirv-cross-sys" +version = "0.4.3+e670b39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a1966fed47a227b129a34440657270dd1b47c7771f2b2637b82ff6dfcbde0b" +dependencies = [ + "bytemuck", + "cc", + "num-derive", + "num-traits", +] + +[[package]] +name = "spirv-cross2" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c248b63ebea5a3153214091875d63cc0bacbe4743c13e20dc54bd73ba847972" +dependencies = [ + "bitflags 2.6.0", + "bytemuck", + "memchr", + "spirv", + "spirv-cross-sys", + "spirv-cross2-derive", + "thiserror", +] + +[[package]] +name = "spirv-cross2-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18017a288e6ce64dd5d56510166baeabb01849483555c031f573c091b6934a64" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "spirv-to-dxil" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3fb4188c288f0bcf2d6e18a74647a6346ce974c7751ca075de89e4949d4b0e" +dependencies = [ + "bytemuck", + "mach-siegbert-vogt-dxcsa", + "spirv-to-dxil-sys", + "thiserror", +] + +[[package]] +name = "spirv-to-dxil-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037a06e11f21b121d2aff4575185e1f61486908d1202f91d55997b05fdc51140" +dependencies = [ + "build-target", + "bytemuck", + "cc", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -2879,6 +3601,7 @@ dependencies = [ "image 0.24.9", "image 0.25.2", "js-sys", + "librashader", "linked-hash-map", "lru", "memmap2", @@ -2935,6 +3658,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "teletypewriter" version = "0.1.17" @@ -2971,18 +3700,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", @@ -3182,6 +3911,16 @@ dependencies = [ "web-sys", ] +[[package]] +name = "triomphe" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" +dependencies = [ + "serde", + "stable_deref_trait", +] + [[package]] name = "ttf-parser" version = "0.21.1" @@ -3244,6 +3983,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +[[package]] +name = "unsigned-varint" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" + [[package]] name = "url" version = "2.5.2" @@ -3267,12 +4012,24 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vec_extract_if_polyfill" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c9cb5fb67c2692310b6eb3fce7dd4b6e4c9a75be4f2f46b27f0b2b7799759c" + [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "virtue" +version = "0.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dcc60c0624df774c82a0ef104151231d37da4962957d691c011c852b2473314" + [[package]] name = "wa" version = "0.1.17" @@ -3599,10 +4356,10 @@ dependencies = [ "cfg_aliases 0.1.1", "core-graphics-types 0.1.3", "d3d12", - "glow", + "glow 0.13.1", "glutin_wgl_sys", "gpu-alloc", - "gpu-allocator", + "gpu-allocator 0.26.0", "gpu-descriptor", "hassle-rs", "js-sys", @@ -3698,7 +4455,17 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ - "windows-core", + "windows-core 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", "windows-targets 0.52.6", ] @@ -3711,6 +4478,60 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.42.0" @@ -3934,6 +4755,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "x11-clipboard" version = "0.9.2" @@ -4058,6 +4888,15 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "zigzag" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70b40401a28d86ce16a330b863b86fd7dbee4d7c940587ab09ab8c019f9e3fdf" +dependencies = [ + "num-traits", +] + [[package]] name = "zune-core" version = "0.4.12" diff --git a/frontends/rioterm/src/application.rs b/frontends/rioterm/src/application.rs index c6c603e73e..1ed1157c80 100644 --- a/frontends/rioterm/src/application.rs +++ b/frontends/rioterm/src/application.rs @@ -1044,6 +1044,10 @@ impl ApplicationHandler for Application<'_> { } RoutePath::Terminal => { route.window.screen.render(); + + if self.config.renderer.continuous_rendering { + route.request_redraw(); + } } RoutePath::ConfirmQuit => { route diff --git a/frontends/rioterm/src/context.rs b/frontends/rioterm/src/context.rs index aa96356fea..113df1d939 100644 --- a/frontends/rioterm/src/context.rs +++ b/frontends/rioterm/src/context.rs @@ -548,8 +548,7 @@ impl ContextManager { } } - id = - id.to_owned() + &(format!("{}{}{};", i, program, terminal_title)); + id.push_str(&format!("{}{}{};", i, program, terminal_title)); self.titles.set_key_val(i, program, terminal_title, path); } self.titles.set_key(id); @@ -563,8 +562,7 @@ impl ContextManager { let mut id = String::from(""); for (i, _context) in self.contexts.iter().enumerate() { let program = self.config.shell.program.to_owned(); - id = id.to_owned() - + &(format!("{}{}{};", i, program, String::default())); + id.push_str(&format!("{}{}{};", i, program, String::default())); self.titles.set_key_val( i, program, diff --git a/frontends/rioterm/src/screen/mod.rs b/frontends/rioterm/src/screen/mod.rs index 97dc3fc48a..1875f56981 100644 --- a/frontends/rioterm/src/screen/mod.rs +++ b/frontends/rioterm/src/screen/mod.rs @@ -175,6 +175,8 @@ impl Screen<'_> { } }; + sugarloaf.update_filters(config.renderer.filters.as_slice()); + let renderer = Renderer::new(config, font_library); let bindings = crate::bindings::default_key_bindings( @@ -325,6 +327,8 @@ impl Screen<'_> { ); self.sugarloaf.layout_mut().update(); + self.sugarloaf + .update_filters(config.renderer.filters.as_slice()); self.renderer = Renderer::new(config, font_library); for context in self.ctx().contexts() { diff --git a/rio-backend/src/config/defaults.rs b/rio-backend/src/config/defaults.rs index db1541113d..7b6366342a 100644 --- a/rio-backend/src/config/defaults.rs +++ b/rio-backend/src/config/defaults.rs @@ -282,12 +282,21 @@ pub fn default_config_file_content() -> String { # will be done like enable font ligatures or emoji support. # For more information please check the docs. # +# • filters: A list of paths to RetroArch slang shaders +# +# • continuous-rendering: Configure continuous rendering +# - Available options: true and false. +# When set to true, the renderer will continuously render. +# When set to false, the renderer will render as rare as possible. +# # Example: # [renderer] # performance = "high" # backend = "automatic" # disable-unfocused-render = false # level = 1 +# filters = [] +# continuous-rendering = false # Keyboard # diff --git a/rio-backend/src/config/renderer.rs b/rio-backend/src/config/renderer.rs index fcec4d28bb..f5fa3ff0af 100644 --- a/rio-backend/src/config/renderer.rs +++ b/rio-backend/src/config/renderer.rs @@ -11,6 +11,10 @@ pub struct Renderer { pub disable_unfocused_render: bool, #[serde(default = "Option::default", rename = "target-fps")] pub target_fps: Option, + #[serde(default = "Vec::default")] + pub filters: Vec, + #[serde(default = "bool::default", rename = "continuous-rendering")] + pub continuous_rendering: bool, } #[allow(clippy::derivable_impls)] @@ -21,6 +25,8 @@ impl Default for Renderer { backend: Backend::default(), disable_unfocused_render: false, target_fps: None, + filters: Vec::default(), + continuous_rendering: false, } } } diff --git a/sugarloaf/Cargo.toml b/sugarloaf/Cargo.toml index de6841912f..8171aa8dd8 100644 --- a/sugarloaf/Cargo.toml +++ b/sugarloaf/Cargo.toml @@ -51,6 +51,7 @@ skrifa = "0.22.3" yazi = { version = "0.1.6", optional = true } zeno = { version = "0.2.2", optional = true, default-features = false } futures = { workspace = true } +librashader = { version = "0.5.1", features = ["preprocess", "runtime-wgpu", "stable"], default-features = false } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] crossbeam-channel = "0.5.13" diff --git a/sugarloaf/src/components/text/mod.rs b/sugarloaf/src/components/text/mod.rs index 77ca5cae3c..21891e8da5 100644 --- a/sugarloaf/src/components/text/mod.rs +++ b/sugarloaf/src/components/text/mod.rs @@ -27,7 +27,7 @@ pub use glyph::{ use crate::components::core::orthographic_projection; use ab_glyph::{Font, Rect}; use core::hash::BuildHasher; -use std::borrow::Cow; +use std::{borrow::Cow, sync::Arc}; use glyph::{BrushAction, BrushError, DefaultSectionHasher}; @@ -87,7 +87,7 @@ where F: Font + Sync, H: BuildHasher, { - fn process_queued(&mut self, device: &wgpu::Device, queue: &mut wgpu::Queue) { + fn process_queued(&mut self, device: &wgpu::Device, queue: &wgpu::Queue) { let pipeline = &mut self.pipeline; let mut brush_action; @@ -98,7 +98,7 @@ where let offset = [rect.min[0] as u16, rect.min[1] as u16]; let size = [rect.width() as u16, rect.height() as u16]; - pipeline.update_cache(queue, offset, size, tex_data); + pipeline.update_cache(&queue, offset, size, tex_data); }, Instance::from_vertex, ); @@ -130,7 +130,7 @@ where match brush_action.unwrap() { BrushAction::Draw(mut verts) => { - self.pipeline.upload(device, queue, &mut verts); + self.pipeline.upload(device, &queue, &mut verts); } BrushAction::ReDraw => {} }; @@ -177,7 +177,7 @@ impl GlyphBrush<(), F, H> { rpass: &mut wgpu::RenderPass<'pass>, ) { let device = &context.device; - let queue = &mut context.queue; + let queue = &context.queue; self.draw_queued_with_transform( device, queue, @@ -200,8 +200,8 @@ impl GlyphBrush<(), F, H> { #[inline] pub fn draw_queued_with_transform<'pass>( &'pass mut self, - device: &wgpu::Device, - queue: &mut wgpu::Queue, + device: &Arc, + queue: &wgpu::Queue, rpass: &mut wgpu::RenderPass<'pass>, transform: [f32; 16], ) { diff --git a/sugarloaf/src/components/text/pipeline.rs b/sugarloaf/src/components/text/pipeline.rs index 7517537394..177553bcc6 100644 --- a/sugarloaf/src/components/text/pipeline.rs +++ b/sugarloaf/src/components/text/pipeline.rs @@ -58,7 +58,7 @@ impl Pipeline<()> { pub fn draw<'pass>( &'pass mut self, - queue: &mut wgpu::Queue, + queue: &wgpu::Queue, rpass: &mut wgpu::RenderPass<'pass>, transform: [f32; 16], region: Option, @@ -100,12 +100,12 @@ impl Pipeline { impl Pipeline { pub fn update_cache( &mut self, - queue: &mut wgpu::Queue, + queue: &wgpu::Queue, offset: [u16; 2], size: [u16; 2], data: &[u8], ) { - self.cache.update(queue, offset, size, data); + self.cache.update(&queue, offset, size, data); } pub fn increase_cache_size( @@ -128,7 +128,7 @@ impl Pipeline { pub fn upload( &mut self, device: &wgpu::Device, - queue: &mut wgpu::Queue, + queue: &wgpu::Queue, instances: &mut [Instance], ) { if instances.is_empty() { @@ -315,7 +315,7 @@ fn build( fn draw<'pass, D>( pipeline: &'pass mut Pipeline, - config: (&mut wgpu::Queue, &mut wgpu::RenderPass<'pass>), + config: (&wgpu::Queue, &mut wgpu::RenderPass<'pass>), transform: [f32; 16], region: Option, ) { diff --git a/sugarloaf/src/components/text/pipeline/cache.rs b/sugarloaf/src/components/text/pipeline/cache.rs index 22ab8fd5f7..9d6603aefb 100644 --- a/sugarloaf/src/components/text/pipeline/cache.rs +++ b/sugarloaf/src/components/text/pipeline/cache.rs @@ -27,7 +27,7 @@ impl Cache { pub fn update( &mut self, - queue: &mut wgpu::Queue, + queue: &wgpu::Queue, offset: [u16; 2], size: [u16; 2], data: &[u8], diff --git a/sugarloaf/src/context/mod.rs b/sugarloaf/src/context/mod.rs index a15c4251b3..70dc4a9829 100644 --- a/sugarloaf/src/context/mod.rs +++ b/sugarloaf/src/context/mod.rs @@ -1,10 +1,11 @@ use crate::sugarloaf::{SugarloafWindow, SugarloafWindowSize}; use crate::SugarloafRenderer; +use std::sync::Arc; pub struct Context<'a> { - pub device: wgpu::Device, + pub device: Arc, pub surface: wgpu::Surface<'a>, - pub queue: wgpu::Queue, + pub queue: Arc, pub format: wgpu::TextureFormat, pub size: SugarloafWindowSize, pub scale: f32, @@ -111,9 +112,15 @@ impl Context<'_> { let (device, queue) = { { - if let Ok(result) = futures::executor::block_on( - adapter.request_device(&wgpu::DeviceDescriptor::default(), None), - ) { + if let Ok(result) = futures::executor::block_on(adapter.request_device( + // ADDRESS_MODE_CLAMP_TO_BORDER is required for librashader + &wgpu::DeviceDescriptor { + required_features: wgpu::Features::empty() + | wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER, + ..Default::default() + }, + None, + )) { result } else { // These downlevel limits will allow the code to run on all possible hardware @@ -148,7 +155,9 @@ impl Context<'_> { surface.configure( &device, &wgpu::SurfaceConfiguration { - usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + // COPY_DST is required for rendering filter chains + usage: wgpu::TextureUsages::RENDER_ATTACHMENT + | wgpu::TextureUsages::COPY_DST, format, width: size.width as u32, height: size.height as u32, @@ -160,8 +169,8 @@ impl Context<'_> { ); Context { - device, - queue, + device: Arc::new(device), + queue: Arc::new(queue), surface, format, alpha_mode, @@ -180,7 +189,9 @@ impl Context<'_> { self.surface.configure( &self.device, &wgpu::SurfaceConfiguration { - usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + // COPY_DST is required for rendering filter chains + usage: wgpu::TextureUsages::RENDER_ATTACHMENT + | wgpu::TextureUsages::COPY_DST, format: self.format, width, height, diff --git a/sugarloaf/src/sugarloaf.rs b/sugarloaf/src/sugarloaf.rs index 1554702545..49cccf1344 100644 --- a/sugarloaf/src/sugarloaf.rs +++ b/sugarloaf/src/sugarloaf.rs @@ -21,6 +21,7 @@ use raw_window_handle::{ DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, WindowHandle, }; use state::SugarState; +use std::sync::Arc; pub struct Sugarloaf<'a> { pub ctx: Context<'a>, @@ -33,6 +34,9 @@ pub struct Sugarloaf<'a> { pub background_color: Option, pub background_image: Option, pub graphics: Graphics, + pub filter_chains: Vec, + framecount: usize, + filter_intermediates: Vec>, } #[derive(Debug)] @@ -145,6 +149,9 @@ impl Sugarloaf<'_> { rich_text_brush, text_brush, graphics: Graphics::default(), + filter_chains: Vec::default(), + framecount: 0, + filter_intermediates: Vec::default(), }; Ok(instance) @@ -179,6 +186,61 @@ impl Sugarloaf<'_> { &mut self.state.layout } + #[inline] + pub fn update_filters(&mut self, filter_paths: &[String]) { + self.filter_chains.clear(); + self.filter_intermediates.clear(); + + for path in filter_paths { + tracing::debug!("Loading filter {}", path); + + match librashader::runtime::wgpu::FilterChain::load_from_path( + path, + self.ctx.device.clone(), + self.ctx.queue.clone(), + None, + ) { + Ok(f) => self.filter_chains.push(f), + Err(e) => tracing::error!("Failed to load filter {}: {}", path, e), + } + } + + self.filter_intermediates.reserve(self.filter_chains.len()); + + // If we have an odd number of filters, the last filter can be + // renderer directly to the output texture. + let skip = if self.filter_chains.len() % 2 == 1 { + 1 + } else { + 0 + }; + + let size = wgpu::Extent3d { + depth_or_array_layers: 1, + width: self.ctx.size.width as u32, + height: self.ctx.size.height as u32, + }; + + for _ in self.filter_chains.iter().skip(skip) { + let intermediate_texture = + Arc::new(self.ctx.device.create_texture(&wgpu::TextureDescriptor { + label: Some("Filter Intermediate Texture"), + size: size, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: self.ctx.format, + usage: wgpu::TextureUsages::TEXTURE_BINDING + | wgpu::TextureUsages::RENDER_ATTACHMENT + | wgpu::TextureUsages::COPY_SRC + | wgpu::TextureUsages::COPY_DST, + view_formats: &[self.ctx.format], + })); + + self.filter_intermediates.push(intermediate_texture); + } + } + #[inline] pub fn update_font_size(&mut self, operation: u8) { self.state.compute_layout_font_size(operation); @@ -272,9 +334,55 @@ impl Sugarloaf<'_> { &wgpu::CommandEncoderDescriptor { label: None }, ); - let view = &frame - .texture - .create_view(&wgpu::TextureViewDescriptor::default()); + // We have two ways to render things: + // - If not using filters: + // 1. Render directly to the our next texture. + // - Otherwise: + // 1. Render the terminal into a separate texture - `first_pass_texture`. + // 2. Render each filter into its corresponding intermediate texture - `filter_intermediates`. + // 3. Copy the texture of the last filter to the output texture. + // + // WPGU doesn't allow us to use the same texture as src and dst, so we need to + // separate textures for src and dst. At least with the current + // librashader implementation. + // + // For the first filter, we will use `first_pass_texture' as the src texture, + // as dst texture - filter_intermediates[0]. + // Then at the second filter as src texture we will use filter_intermediates[1], + // as dst texture - filter_intermediates[2] and so on. At the last filter we will + // render directly to the texture obtained by get_current_texture(). + + // Do not create this texture if we do not use filters. + let first_pass_texture: Option>; + let view: wgpu::TextureView; + + if !self.filter_chains.is_empty() { + first_pass_texture = Some(Arc::new(self.ctx.device.create_texture( + &wgpu::TextureDescriptor { + label: Some("First Pass Texture"), + size: frame.texture.size(), + mip_level_count: frame.texture.mip_level_count(), + sample_count: frame.texture.sample_count(), + dimension: frame.texture.dimension(), + format: frame.texture.format(), + usage: wgpu::TextureUsages::TEXTURE_BINDING + | wgpu::TextureUsages::RENDER_ATTACHMENT + | wgpu::TextureUsages::COPY_SRC + | wgpu::TextureUsages::COPY_DST, + view_formats: &[frame.texture.format()], + }, + ))); + + view = first_pass_texture + .as_ref() + .unwrap() + .create_view(&wgpu::TextureViewDescriptor::default()) + } else { + first_pass_texture = None; + view = frame + .texture + .create_view(&wgpu::TextureViewDescriptor::default()); + } if let Some(layer) = &self.graphics.bottom_layer { self.layer_brush @@ -312,7 +420,7 @@ impl Sugarloaf<'_> { occlusion_query_set: None, label: None, color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view, + view: &view, resolve_target: None, ops: wgpu::Operations { load, @@ -356,8 +464,63 @@ impl Sugarloaf<'_> { self.graphics.clear_top_layer(); } + if !self.filter_chains.is_empty() { + let view_size = librashader::runtime::Size::new( + self.ctx.size.width as u32, + self.ctx.size.height as u32, + ); + let filters_count = self.filter_chains.len(); + + for (idx, filter) in self.filter_chains.iter_mut().enumerate() { + let src_texture: Arc; + let dst_texture: &wgpu::Texture; + + if idx == 0 { + src_texture = first_pass_texture.as_ref().unwrap().clone(); + + if filters_count == 1 { + dst_texture = &frame.texture; + } else { + dst_texture = &self.filter_intermediates[0]; + } + } else if idx == filters_count - 1 { + src_texture = self.filter_intermediates[idx - 1].clone(); + dst_texture = &frame.texture; + } else { + src_texture = self.filter_intermediates[idx - 1].clone(); + dst_texture = &self.filter_intermediates[idx]; + } + + let dst_texture_view = dst_texture + .create_view(&wgpu::TextureViewDescriptor::default()); + let dst_output_view = + librashader::runtime::wgpu::WgpuOutputView::new_from_raw( + &dst_texture_view, + view_size, + self.ctx.format, + ); + let dst_viewport = + librashader::runtime::Viewport::new_render_target_sized_origin( + dst_output_view, + None, + ) + .unwrap(); + + if let Err(err) = filter.frame( + src_texture, + &dst_viewport, + &mut encoder, + self.framecount, + None, + ) { + tracing::error!("Filter rendering failed: {err}"); + } + } + } + self.ctx.queue.submit(Some(encoder.finish())); frame.present(); + self.framecount = self.framecount.wrapping_add(1); } Err(error) => { if error == wgpu::SurfaceError::OutOfMemory {