1
0
spogulis no https://github.com/bspeice/speice.io synced 2026-04-11 03:20:23 -04:00

8 Revīzijas

20 mainīti faili ar 5995 papildinājumiem un 0 dzēšanām

Bināro failu nav iespējams attēlot.

Pēc

Platums:  |  Augstums:  |  Izmērs: 3.3 KiB

Parādīt failu

@ -0,0 +1,2 @@
/.idea
target/

Failā izmaiņas netiks attēlotas, jo tās ir par lielu Ielādēt izmaiņas

Parādīt failu

@ -0,0 +1,14 @@
[package]
name = "draw-compute"
version = "0.1.0"
edition = "2021"
[dependencies]
bytemuck = { version = "1.22", features = ["derive"] }
eframe = { version = "0.31", features = ["wgpu"] }
egui = "0.31"
egui-wgpu = "0.31"
glam = { version = "0.30", default-features = false, features = ["bytemuck", "libm"] }
wgpu = { version = "24.0", features = ["spirv"] }
shader = { path = "shader" }

Parādīt failu

@ -0,0 +1,26 @@
use std::error::Error;
use std::path::PathBuf;
use std::{env, process};
pub fn main() -> Result<(), Box<dyn Error>> {
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("shader.spv");
let mut cargo = process::Command::new("cargo");
let mut shader_cli = cargo
.current_dir("./shader-cli")
.arg("run")
.arg("--")
.arg("../shader")
.arg(out_path);
// Clean all `RUST*`/`CARGO*` environment variables so `rust-toolchain.toml` takes over
for env_var in env::vars() {
if env_var.0.starts_with("RUST") || env_var.0.starts_with("CARGO") {
shader_cli = shader_cli.env_remove(env_var.0);
}
}
shader_cli.status()?;
Ok(())
}

Parādīt failu

@ -0,0 +1,968 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "adler2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"getrandom",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "allocator-api2"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "ar"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d67af77d68a931ecd5cbd8a3b5987d63a1d1d1278f7f6a60ae33db485cdebb69"
[[package]]
name = "arrayvec"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "bitflags"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
name = "bytemuck"
version = "1.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
dependencies = [
"bytemuck_derive",
]
[[package]]
name = "bytemuck_derive"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "cc"
version = "1.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
dependencies = [
"jobserver",
"libc",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "convert_case"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if",
]
[[package]]
name = "derive_more"
version = "0.99.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3da29a38df43d6f156149c9b43ded5e018ddff2a855cf2cfd62e8cd7d079c69f"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"rustc_version",
"syn",
]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "elsa"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9abf33c656a7256451ebb7d0082c5a471820c31269e49d807c538c252352186e"
dependencies = [
"indexmap",
"stable_deref_trait",
]
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
dependencies = [
"libc",
"windows-sys 0.59.0",
]
[[package]]
name = "fallible-iterator"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
[[package]]
name = "flate2"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "gimli"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e1d97fbe9722ba9bbd0c97051c2956e726562b61f86a25a4360398a40edfc9"
dependencies = [
"fallible-iterator",
"indexmap",
"stable_deref_trait",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]]
name = "hashbrown"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
dependencies = [
"foldhash",
]
[[package]]
name = "indexmap"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
dependencies = [
"equivalent",
"hashbrown 0.15.2",
]
[[package]]
name = "internal-iterator"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "969ee3fc68ec2e88eb21434ce4d9b7e1600d1ce92ff974560a6c4a304f5124b9"
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "jobserver"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
dependencies = [
"libc",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "longest-increasing-subsequence"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86"
[[package]]
name = "matchers"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
dependencies = [
"regex-automata 0.1.10",
]
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "miniz_oxide"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
dependencies = [
"adler2",
]
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
dependencies = [
"overload",
"winapi",
]
[[package]]
name = "nu-ansi-term"
version = "0.50.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "object"
version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
dependencies = [
"crc32fast",
"flate2",
"hashbrown 0.15.2",
"indexmap",
"memchr",
"ruzstd",
"wasmparser",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "pin-project-lite"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "proc-macro2"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "raw-string"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0501e134c6905fee1f10fed25b0a7e1261bf676cffac9543a7d0730dec01af2"
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata 0.4.9",
"regex-syntax 0.8.5",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
dependencies = [
"regex-syntax 0.6.29",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.8.5",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[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",
"spirv",
]
[[package]]
name = "rustc-demangle"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc_codegen_spirv"
version = "0.9.0"
source = "git+https://github.com/rust-gpu/rust-gpu?rev=698f10ac14b7c952394ac5620004e4e973308902#698f10ac14b7c952394ac5620004e4e973308902"
dependencies = [
"ahash",
"ar",
"bytemuck",
"either",
"indexmap",
"itertools",
"lazy_static",
"libc",
"log",
"object",
"regex",
"rspirv",
"rustc-demangle",
"rustc_codegen_spirv-types",
"rustix",
"sanitize-filename",
"smallvec",
"spirt",
"spirv-tools",
"thorin-dwp",
"tracing",
"tracing-subscriber",
"tracing-tree",
]
[[package]]
name = "rustc_codegen_spirv-types"
version = "0.9.0"
source = "git+https://github.com/rust-gpu/rust-gpu?rev=698f10ac14b7c952394ac5620004e4e973308902#698f10ac14b7c952394ac5620004e4e973308902"
dependencies = [
"rspirv",
"serde",
"serde_json",
]
[[package]]
name = "rustc_version"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags",
"errno",
"itoa",
"libc",
"linux-raw-sys",
"once_cell",
"windows-sys 0.59.0",
]
[[package]]
name = "ruzstd"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad02996bfc73da3e301efe90b1837be9ed8f4a462b6ed410aa35d00381de89f"
dependencies = [
"twox-hash",
]
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "sanitize-filename"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c502bdb638f1396509467cb0580ef3b29aa2a45c5d43e5d84928241280296c"
dependencies = [
"lazy_static",
"regex",
]
[[package]]
name = "semver"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "shader-cli"
version = "0.1.0"
dependencies = [
"spirv-builder",
]
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "smallvec"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
dependencies = [
"serde",
]
[[package]]
name = "spirt"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2d5968bd2a36466468aac637b355776f080edfb0c6f769b2b99b9708260c42a"
dependencies = [
"arrayvec",
"bytemuck",
"derive_more",
"elsa",
"indexmap",
"internal-iterator",
"itertools",
"lazy_static",
"longest-increasing-subsequence",
"rustc-hash",
"serde",
"serde_json",
"smallvec",
]
[[package]]
name = "spirv"
version = "0.3.0+sdk-1.3.268.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844"
dependencies = [
"bitflags",
]
[[package]]
name = "spirv-builder"
version = "0.9.0"
source = "git+https://github.com/rust-gpu/rust-gpu?rev=698f10ac14b7c952394ac5620004e4e973308902#698f10ac14b7c952394ac5620004e4e973308902"
dependencies = [
"memchr",
"raw-string",
"rustc_codegen_spirv",
"rustc_codegen_spirv-types",
"serde",
"serde_json",
]
[[package]]
name = "spirv-tools"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcb3b0832881834994b7ec82b709ec5491043ceb4bf8101e27da6b5234b24261"
dependencies = [
"spirv-tools-sys",
]
[[package]]
name = "spirv-tools-sys"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48e68b55a97aa6856e010a6f2477425875a97873e147bb0232160e73c45bdae7"
dependencies = [
"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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thorin-dwp"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "813ba76597db32dc4f6992fd8bf8f394715b88d352fd97401da67dab6283b4c6"
dependencies = [
"gimli",
"hashbrown 0.14.5",
"object",
"tracing",
]
[[package]]
name = "thread_local"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "tracing"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]]
name = "tracing-serde"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1"
dependencies = [
"serde",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
dependencies = [
"matchers",
"nu-ansi-term 0.46.0",
"once_cell",
"regex",
"serde",
"serde_json",
"sharded-slab",
"smallvec",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
"tracing-serde",
]
[[package]]
name = "tracing-tree"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b56c62d2c80033cb36fae448730a2f2ef99410fe3ecbffc916681a32f6807dbe"
dependencies = [
"nu-ansi-term 0.50.1",
"tracing-core",
"tracing-log",
"tracing-subscriber",
]
[[package]]
name = "twox-hash"
version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
"cfg-if",
"static_assertions",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "valuable"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasmparser"
version = "0.222.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa210fd1788e6b37a1d1930f3389c48e1d6ebd1a013d34fa4b7f9e3e3bf03146"
dependencies = [
"bitflags",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

Parādīt failu

@ -0,0 +1,13 @@
[package]
name = "shader-cli"
version = "0.1.0"
edition = "2021"
[dependencies]
spirv-builder = { git = "https://github.com/rust-gpu/rust-gpu", rev = "698f10ac14b7c952394ac5620004e4e973308902" }
# On Windows, link.exe has a maximum of 65536 symbols.
# These options are required to stay within that limit
[profile.dev]
opt-level = 3
codegen-units = 256

Parādīt failu

@ -0,0 +1,4 @@
[toolchain]
channel = "nightly-2024-11-22"
components = ["rust-src", "rustc-dev", "llvm-tools"]
# commit_hash = b19329a37cedf2027517ae22c87cf201f93d776e

Parādīt failu

@ -0,0 +1,12 @@
use std::env::args;
use spirv_builder::SpirvBuilder;
fn main() {
let crate_path = args().nth(1).expect("Missing crate path");
let output_path = args().nth(2).expect("Missing output path");
let builder = SpirvBuilder::new(crate_path, "spirv-unknown-vulkan1.1");
let build_result = builder.build().expect("Could not compile shader");
let compile_path = build_result.module.unwrap_single();
std::fs::copy(compile_path, output_path).expect("Unable to copy shader to destination");
}

Parādīt failu

@ -0,0 +1,156 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bytemuck"
version = "1.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
dependencies = [
"bytemuck_derive",
]
[[package]]
name = "bytemuck_derive"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
]
[[package]]
name = "glam"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945"
dependencies = [
"libm",
]
[[package]]
name = "glam"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf3aa70d918d2b234126ff4f850f628f172542bf0603ded26b8ee36e5e22d5f9"
dependencies = [
"bytemuck",
"libm",
]
[[package]]
name = "libm"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
"libm",
]
[[package]]
name = "proc-macro2"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "shader"
version = "0.1.0"
dependencies = [
"bytemuck",
"glam 0.30.1",
"spirv-std",
]
[[package]]
name = "spirv-std"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68c3c0972a2df79abe2c8af2fe7f7937a9aa558b6a1f78fc5edf93f4d480d757"
dependencies = [
"bitflags",
"glam 0.24.2",
"num-traits",
"spirv-std-macros",
"spirv-std-types",
]
[[package]]
name = "spirv-std-macros"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73f776bf9f2897ea7acff15d7753711fdf1693592bd7459a01c394262b1df45c"
dependencies = [
"proc-macro2",
"quote",
"spirv-std-types",
"syn 1.0.109",
]
[[package]]
name = "spirv-std-types"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a73417b7d72d95b4995c840dceb4e3b4bcbad4ff7f35df9c1655b6826c18d3a9"
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"

Parādīt failu

@ -0,0 +1,12 @@
[package]
name = "shader"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["rlib", "cdylib"]
[dependencies]
bytemuck = { version = "1.22", features = ["derive"] }
glam = { version = "0.30", default-features = false, features = ["bytemuck", "libm"] }
spirv-std = "0.9.0"

Parādīt failu

@ -0,0 +1,133 @@
#![no_std]
use glam::Vec4Swizzles;
use spirv_std::spirv;
pub trait DrawSettings: Copy + Sized + bytemuck::Pod + bytemuck::Zeroable {}
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
#[repr(C)]
pub struct DrawSized {
pub image_size: glam::UVec2,
pub viewport_size: glam::UVec2,
}
impl DrawSettings for DrawSized {}
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
#[repr(C)]
pub struct DrawRect {
pub image_size: glam::UVec2,
pub viewport_size: glam::UVec2,
pub viewport_offset: glam::UVec2,
}
impl DrawSettings for DrawRect {}
const BLOCK_SIZE: usize = 16;
const BLACK: glam::Vec4 = glam::vec4(0.0, 0.0, 0.0, 1.0);
const WHITE: glam::Vec4 = glam::vec4(1.0, 1.0, 1.0, 1.0);
fn image_index(x: usize, y: usize, width: usize) -> usize {
y * width + x
}
fn in_bounds(image_coordinate: glam::Vec2, image_size: glam::Vec2) -> bool {
image_coordinate.cmpge(glam::Vec2::ZERO).all() && image_coordinate.cmplt(image_size).all()
}
#[spirv(compute(threads(1)))]
pub fn main_cs_bounding(
#[spirv(uniform, descriptor_set = 0, binding = 0)] viewport: &DrawSized,
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] image: &mut [glam::Vec4],
) {
let width = viewport.image_size.x as usize;
let height = viewport.image_size.y as usize;
for x in 0..width {
for y in 0..height {
image[image_index(x, y, width)] =
if x == 0 || x == width - 1 || y == 0 || y == height - 1 {
WHITE
} else {
BLACK
}
}
}
}
#[spirv(compute(threads(1)))]
pub fn main_cs_blocks(
#[spirv(uniform, descriptor_set = 0, binding = 0)] viewport: &DrawSized,
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] image: &mut [glam::Vec4],
) {
let width = viewport.image_size.x as usize;
let height = viewport.image_size.y as usize;
for x in 0..width {
let x_even = x / BLOCK_SIZE % 2 == 0;
for y in 0..height {
let y_even = y / BLOCK_SIZE % 2 == 0;
let color = if x_even == y_even { BLACK } else { WHITE };
let index = image_index(x, y, width);
image[index] = color;
}
}
}
#[spirv(vertex)]
pub fn main_vs(
#[spirv(vertex_index)] vert_id: u32,
#[spirv(position, invariant)] position: &mut glam::Vec4,
) {
let output_uv = glam::vec2(((vert_id << 1) & 2) as f32, (vert_id & 2) as f32);
*position = (output_uv * 2.0 - 1.0, 0.0, 1.0).into();
}
#[spirv(fragment)]
pub fn main_fs_size(
#[spirv(frag_coord)] frag_coord: glam::Vec4,
#[spirv(uniform, descriptor_set = 0, binding = 0)] draw_settings: &DrawSized,
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] image: &mut [glam::Vec4],
output: &mut glam::Vec4,
) {
let vp_size = draw_settings.viewport_size.as_vec2();
let img_size = draw_settings.image_size.as_vec2();
let scale = (vp_size / img_size).min_element();
let img_offset = (vp_size / scale - img_size) / 2.0;
let img_coord = frag_coord.xy() / scale - img_offset;
*output = if in_bounds(img_coord, img_size) {
image[image_index(
img_coord.x as usize,
img_coord.y as usize,
img_size.x as usize,
)]
} else {
BLACK
}
}
#[spirv(fragment)]
pub fn main_fs_rect(
#[spirv(frag_coord)] frag_coord: glam::Vec4,
#[spirv(uniform, descriptor_set = 0, binding = 0)] draw_settings: &DrawRect,
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] image: &mut [glam::Vec4],
output: &mut glam::Vec4,
) {
let vp_size = draw_settings.viewport_size.as_vec2();
let img_size = draw_settings.image_size.as_vec2();
let scale = (vp_size / img_size).min_element();
let img_offset = (vp_size / scale - img_size) / 2.0;
let img_coord =
(frag_coord.xy() - draw_settings.viewport_offset.as_vec2()) / scale - img_offset;
*output = if in_bounds(img_coord, img_size) {
image[image_index(
img_coord.x as usize,
img_coord.y as usize,
img_size.x as usize,
)]
} else {
BLACK
}
}

Parādīt failu

@ -0,0 +1,16 @@
use draw_compute::draw_shaders::ShaderBounding;
use draw_compute::ComputeDraw;
fn main() {
let native_options = eframe::NativeOptions {
renderer: eframe::Renderer::Wgpu,
..Default::default()
};
eframe::run_native(
"Compute Draw",
native_options,
Box::new(|_cc| Ok(Box::new(ComputeDraw::<ShaderBounding>::new()))),
)
.unwrap()
}

Parādīt failu

@ -0,0 +1,15 @@
use draw_compute::draw_shaders::ShaderOffset;
use draw_compute::ComputeDraw;
fn main() {
let native_options = eframe::NativeOptions {
renderer: eframe::Renderer::Wgpu,
..Default::default()
};
eframe::run_native(
"Compute Draw",
native_options,
Box::new(|_cc| Ok(Box::new(ComputeDraw::<ShaderOffset>::new()))),
).unwrap()
}

Parādīt failu

@ -0,0 +1,15 @@
use draw_compute::draw_shaders::ShaderOffsetBlocks;
use draw_compute::ComputeDraw;
fn main() {
let native_options = eframe::NativeOptions {
renderer: eframe::Renderer::Wgpu,
..Default::default()
};
eframe::run_native(
"Compute Draw",
native_options,
Box::new(|_cc| Ok(Box::new(ComputeDraw::<ShaderOffsetBlocks>::new()))),
).unwrap()
}

Parādīt failu

@ -0,0 +1,196 @@
use shader::DrawSettings;
use std::marker::PhantomData;
pub trait ShaderSettings: Send + Sync {
type DrawSettings: DrawSettings;
fn compute_shader() -> &'static str;
fn fragment_shader() -> &'static str;
fn new(interact_rect: egui::Rect) -> Self;
fn write_buffer(&self, queue: &wgpu::Queue, buffer: &wgpu::Buffer, image_size: glam::UVec2);
}
pub struct DrawResources<S: ShaderSettings> {
bind_group_layout: wgpu::BindGroupLayout,
pub bind_group: wgpu::BindGroup,
pub viewport_buffer: wgpu::Buffer,
image_buffer: wgpu::Buffer,
pub image_size: glam::UVec2,
pub compute_pipeline: wgpu::ComputePipeline,
pub render_pipeline: wgpu::RenderPipeline,
settings: PhantomData<S>,
}
impl<S: ShaderSettings> DrawResources<S> {
fn bind_group_layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: Some("compute_draw"),
entries: &[
// draw_settings
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::COMPUTE | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
},
// image
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStages::COMPUTE | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Storage { read_only: false },
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
},
],
})
}
fn bind_group(
device: &wgpu::Device,
bind_group_layout: &wgpu::BindGroupLayout,
viewport_buffer: &wgpu::Buffer,
image_buffer: &wgpu::Buffer,
) -> wgpu::BindGroup {
device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("compute_draw"),
layout: bind_group_layout,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: viewport_buffer.as_entire_binding(),
},
wgpu::BindGroupEntry {
binding: 1,
resource: image_buffer.as_entire_binding(),
},
],
})
}
fn viewport_buffer(device: &wgpu::Device) -> wgpu::Buffer {
device.create_buffer(&wgpu::BufferDescriptor {
label: Some("viewport"),
size: size_of::<S::DrawSettings>() as u64,
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::UNIFORM,
mapped_at_creation: false,
})
}
fn image_buffer(device: &wgpu::Device, width: u64, height: u64) -> wgpu::Buffer {
device.create_buffer(&wgpu::BufferDescriptor {
label: Some("image"),
size: width * height * 4 * size_of::<f32>() as u64,
usage: wgpu::BufferUsages::STORAGE,
mapped_at_creation: false,
})
}
fn module(device: &wgpu::Device) -> wgpu::ShaderModule {
let module_descriptor = wgpu::include_spirv!(concat!(env!("OUT_DIR"), "/shader.spv"));
device.create_shader_module(module_descriptor)
}
fn compute_pipeline(
device: &wgpu::Device,
module: &wgpu::ShaderModule,
bind_group_layout: &wgpu::BindGroupLayout,
) -> wgpu::ComputePipeline {
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("compute"),
bind_group_layouts: &[bind_group_layout],
push_constant_ranges: &[],
});
device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
label: Some("compute"),
layout: Some(&pipeline_layout),
module: &module,
entry_point: Some(S::compute_shader()),
compilation_options: Default::default(),
cache: None,
})
}
fn render_pipeline(
device: &wgpu::Device,
module: &wgpu::ShaderModule,
bind_group_layout: &wgpu::BindGroupLayout,
format: &wgpu::TextureFormat,
) -> wgpu::RenderPipeline {
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("draw"),
bind_group_layouts: &[bind_group_layout],
push_constant_ranges: &[],
});
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("draw"),
layout: Some(&pipeline_layout),
vertex: wgpu::VertexState {
module,
entry_point: Some("main_vs"),
compilation_options: Default::default(),
buffers: &[],
},
primitive: Default::default(),
depth_stencil: None,
multisample: Default::default(),
fragment: Some(wgpu::FragmentState {
module,
entry_point: Some(S::fragment_shader()),
compilation_options: Default::default(),
targets: &[Some((*format).into())],
}),
multiview: None,
cache: None,
})
}
pub fn new(
device: &wgpu::Device,
format: &wgpu::TextureFormat,
width: u64,
height: u64,
) -> Self {
let bind_group_layout = Self::bind_group_layout(device);
let viewport_buffer = Self::viewport_buffer(device);
let image_buffer = Self::image_buffer(device, width, height);
let image_size = glam::uvec2(width as u32, height as u32);
let bind_group =
Self::bind_group(device, &bind_group_layout, &viewport_buffer, &image_buffer);
let module = Self::module(device);
let compute_pipeline = Self::compute_pipeline(device, &module, &bind_group_layout);
let render_pipeline = Self::render_pipeline(device, &module, &bind_group_layout, format);
Self {
bind_group_layout,
bind_group,
viewport_buffer,
image_buffer,
image_size,
compute_pipeline,
render_pipeline,
settings: PhantomData,
}
}
pub fn resize(&mut self, device: &wgpu::Device, width: u64, height: u64) {
self.image_buffer = Self::image_buffer(device, width, height);
self.image_size = glam::uvec2(width as u32, height as u32);
self.bind_group = Self::bind_group(
device,
&self.bind_group_layout,
&self.viewport_buffer,
&self.image_buffer,
);
}
}

Parādīt failu

@ -0,0 +1,96 @@
use crate::draw_resources::ShaderSettings;
use glam::UVec2;
use shader::{DrawRect, DrawSized};
use wgpu::{Buffer, Queue};
pub struct ShaderBounding {
draw_size: egui::Vec2,
}
impl ShaderSettings for ShaderBounding {
type DrawSettings = DrawSized;
fn compute_shader() -> &'static str {
"main_cs_bounding"
}
fn fragment_shader() -> &'static str {
"main_fs_size"
}
fn new(interact_rect: egui::Rect) -> Self {
Self {
draw_size: interact_rect.size()
}
}
fn write_buffer(&self, queue: &Queue, buffer: &Buffer, image_size: glam::UVec2) {
let draw_settings = DrawSized {
image_size,
viewport_size: glam::uvec2(self.draw_size.x as u32, self.draw_size.y as u32),
};
queue.write_buffer(&buffer, 0, bytemuck::cast_slice(&[draw_settings]));
}
}
pub struct ShaderOffset {
draw_rect: egui::Rect,
}
impl ShaderSettings for ShaderOffset {
type DrawSettings = DrawRect;
fn compute_shader() -> &'static str {
"main_cs_bounding"
}
fn fragment_shader() -> &'static str {
"main_fs_rect"
}
fn new(interact_rect: egui::Rect) -> Self {
Self { draw_rect: interact_rect }
}
fn write_buffer(&self, queue: &Queue, buffer: &Buffer, image_size: UVec2) {
let viewport_size = glam::uvec2(self.draw_rect.size().x as u32, self.draw_rect.size().y as u32);
let viewport_offset = glam::uvec2(self.draw_rect.min.x as u32, self.draw_rect.min.y as u32);
let draw_settings = DrawRect {
image_size,
viewport_size,
viewport_offset
};
queue.write_buffer(&buffer, 0, bytemuck::cast_slice(&[draw_settings]));
}
}
pub struct ShaderOffsetBlocks {
draw_rect: egui::Rect,
}
impl ShaderSettings for ShaderOffsetBlocks {
type DrawSettings = DrawRect;
fn compute_shader() -> &'static str {
"main_cs_blocks"
}
fn fragment_shader() -> &'static str {
"main_fs_rect"
}
fn new(interact_rect: egui::Rect) -> Self {
Self { draw_rect: interact_rect }
}
fn write_buffer(&self, queue: &Queue, buffer: &Buffer, image_size: UVec2) {
let viewport_size = glam::uvec2(self.draw_rect.size().x as u32, self.draw_rect.size().y as u32);
let viewport_offset = glam::uvec2(self.draw_rect.min.x as u32, self.draw_rect.min.y as u32);
let draw_settings = DrawRect {
image_size,
viewport_size,
viewport_offset
};
queue.write_buffer(&buffer, 0, bytemuck::cast_slice(&[draw_settings]));
}
}

Parādīt failu

@ -0,0 +1,158 @@
mod draw_resources;
pub mod draw_shaders;
use std::marker::PhantomData;
use eframe::Frame;
use egui::{Context, Sense};
use crate::draw_resources::{DrawResources, ShaderSettings};
use eframe::epaint::PaintCallbackInfo;
use egui_wgpu::{CallbackResources, CallbackTrait, ScreenDescriptor};
use wgpu::{CommandBuffer, CommandEncoder, Device, Queue, RenderPass};
struct DrawCallback<S> {
interact_rect: egui::Rect,
interact_resize: bool,
settings: S,
}
impl<S: ShaderSettings> DrawCallback<S> {
fn new(interact_rect: egui::Rect, interact_resize: bool) -> Self {
Self {
interact_rect,
interact_resize,
settings: S::new(interact_rect),
}
}
}
impl<S: ShaderSettings + Send + Sync + 'static> CallbackTrait for DrawCallback<S> {
fn prepare(
&self,
device: &Device,
queue: &Queue,
_screen_descriptor: &ScreenDescriptor,
egui_encoder: &mut CommandEncoder,
callback_resources: &mut CallbackResources,
) -> Vec<CommandBuffer> {
let resources = callback_resources
.get_mut::<DrawResources<S>>()
.expect("missing draw resources");
if self.interact_resize {
resources.resize(
device,
self.interact_rect.width() as u64,
self.interact_rect.height() as u64,
);
}
self.settings.write_buffer(queue, &resources.viewport_buffer, resources.image_size);
if self.interact_resize {
let mut compute_pass = egui_encoder.begin_compute_pass(&wgpu::ComputePassDescriptor {
label: Some("compute"),
timestamp_writes: None,
});
compute_pass.set_pipeline(&resources.compute_pipeline);
compute_pass.set_bind_group(0, &resources.bind_group, &[]);
compute_pass.dispatch_workgroups(1, 1, 1);
}
vec![]
}
fn paint(
&self,
_info: PaintCallbackInfo,
render_pass: &mut RenderPass<'static>,
callback_resources: &CallbackResources,
) {
let resources = callback_resources.get::<DrawResources<S>>().unwrap();
render_pass.set_pipeline(&resources.render_pipeline);
render_pass.set_bind_group(0, &resources.bind_group, &[]);
render_pass.draw(0..3, 0..1);
}
}
#[derive(Copy, Clone)]
pub struct ComputeDraw<S> {
initial_draw: bool,
settings: PhantomData<S>,
}
impl <S: ShaderSettings> ComputeDraw<S> {
pub fn new() -> Self {
ComputeDraw {
initial_draw: true,
settings: PhantomData,
}
}
}
impl<S: ShaderSettings + 'static> eframe::App for ComputeDraw<S> {
fn update(&mut self, ctx: &Context, frame: &mut Frame) {
let initial_draw = self.initial_draw;
self.initial_draw = false;
if initial_draw {
let wgpu_render_state = frame.wgpu_render_state().expect("missing WGPU state");
let device = wgpu_render_state.device.clone();
let format = wgpu_render_state.target_format.clone();
let callback_resources = &mut wgpu_render_state
.renderer
.as_ref()
.write()
.callback_resources;
// Guess an initial size for initializing GPU resources, it will be adjusted later
callback_resources.insert(DrawResources::<S>::new(&device, &format, 800, 600));
}
/*
egui::TopBottomPanel::bottom("bottom").show(ctx, |ui| {
let wgpu_render_state = frame.wgpu_render_state().expect("missing WGPU state");
let image_size = wgpu_render_state
.renderer
.as_ref()
.read()
.callback_resources
.get::<DrawResources<DrawSimple>>()
.unwrap()
.image_size;
ui.label(format!("Viewport: image={image_size}"))
});
*/
egui::CentralPanel::default().show(ctx, |ui| {
egui::Frame::canvas(ui.style()).show(ui, |ui| {
let interact_rect = ui.available_rect_before_wrap();
let (response, painter) = ui.allocate_painter(interact_rect.size(), Sense::click());
painter.add(egui_wgpu::Callback::new_paint_callback(
interact_rect,
DrawCallback::<S>::new(interact_rect, initial_draw || response.clicked()),
))
});
});
}
}
/*
fn main() {
let native_options = eframe::NativeOptions {
renderer: eframe::Renderer::Wgpu,
..Default::default()
};
eframe::run_native(
"Compute Draw",
native_options,
Box::new(|_cc| Ok(Box::new(ComputeDraw { initial_draw: true }))),
)
.unwrap()
}
*/

Parādīt failu

@ -0,0 +1,107 @@
---
slug: 2025/04/drawing-compute-shader
title: "Drawing with a compute shader"
date: 2025-04-27 12:00:00
authors: [bspeice]
tags: []
---
My goal studying the [fractal flame algorithm](../2024-11-15-playing-with-fire/1-introduction/index.mdx) was not just
to satisfy an inner curiosity. The algorithm has been ported to GPUs, but those implementations require either CUDA
(for [flam4](https://sourceforge.net/projects/flam4/)) or OpenCL (for [Fractorium](http://fractorium.com/)).
I'd like to try implementing a fractal flame editor using standard GPU shaders.
The first step is showing an application window and drawing to it using a GPU. This post covers:
- Setting up an application window using [`egui`](https://github.com/emilk/egui)
- Writing and compiling shaders written in Rust with [Rust GPU](https://rust-gpu.github.io/)
- Rendering an image using a compute shader, and displaying the image using a fragment shader
Not that interesting if you're already familiar with shaders and GPU programming, but I found myself wishing
there were more detailed resources on how to get started.
TODO: Image of the end goal here?
<!-- truncate -->
## GUIs in Rust with `egui`
:::note
This section focuses on creating an application that displays the GPU results. If that's not your style,
you can [skip ahead to the shaders](#shaders-in-rust).
:::
## Shaders in Rust
All the code in this post is written in Rust - including the parts that run on a GPU. Rust GPU
compiles Rust code into a shader that runs on a graphics card. There are three primary shader types used:
- [Compute shader](https://www.khronos.org/opengl/wiki/Compute_Shader); can run arbitrary computation, but can't
display to a screen
- [Vertex shader](https://www.khronos.org/opengl/wiki/Vertex_Shader); used to define the output image area
- [Fragment shader](https://www.khronos.org/opengl/wiki/Fragment_Shader); draws an image by returning
a color for each pixel
The application will output pixel information into an image buffer using a compute shader, then display that image
using a combination of vertex and fragment shaders.
### Compute shader
<details>
<summary>Why the focus on compute shaders if they can't display an image on screen? Why not use a fragment shader?</summary>
The answer is related to how fragment shaders run on a graphics card. Fragment shaders are functions that receive
an input coordinate and return the color of that coordinate in the output. By running the fragment shader once per
pixel, we build up an image to display.
This "run once per pixel" mode maps poorly to the fractal flame algorithm. Specifically, the "[chaos game](https://en.wikipedia.org/wiki/Chaos_game)"
jumps around to random locations; only by iterating many times can we figure out what the color of a pixel
should be. However, once the fragment shader ends, we'd lose all the information gathered about the other pixels.
Using a compute shader avoids this "discarded information" problem. Because it can run arbitrary computations,
we can record information about the whole image and make it available later. Compute shaders are overkill
for the examples in this blog post, but are important to a GPU implementation of the fractal flame algorithm.
</details>
The first compute shader example is nothing special; it draws a white rectangle at the edges of an image:
```rust
const BLACK: glam::Vec4 = glam::vec4(0.0, 0.0, 0.0, 1.0);
const WHITE: glam::Vec4 = glam::vec4(1.0, 1.0, 1.0, 1.0);
pub struct DrawSized {
pub image_size: glam::UVec2,
pub viewport_size: glam::UVec2,
}
// The `#[spirv]` annotations describe some details of how this code should run
// on the GPU; they can be ignored for now
#[spirv(compute(threads(1)))]
pub fn main_cs_bounding(
#[spirv(uniform, descriptor_set = 0, binding = 0)] viewport: &DrawSized,
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] image: &mut [glam::Vec4],
) {
let width = viewport.image_size.x as usize;
let height = viewport.image_size.y as usize;
for x in 0..width {
for y in 0..height {
image[image_index(x, y, width)] =
if x == 0 || x == width - 1 || y == 0 || y == height - 1 {
WHITE
} else {
BLACK
}
}
}
}
```
After running this code, the contents of the `image` buffer should look something like this:
![White square with black interior](./bounding%20box.png)
## Vertex/Fragment shaders

Parādīt failu

@ -37,6 +37,10 @@ const config: Config = {
docs: false,
blog: {
routeBasePath: '/',
exclude: [
"**/_*.md",
"**/target/**"
],
blogSidebarTitle: 'All posts',
blogSidebarCount: 'ALL',
showReadingTime: true,