From 84019305a9e127de44bab837c94d4fb1cbf244a9 Mon Sep 17 00:00:00 2001 From: zawz Date: Wed, 24 Jul 2024 12:41:00 +0200 Subject: [PATCH] Initial Commit --- .gitignore | 2 + Cargo.lock | 1763 +++++++++++++++++++++++++++++++++++++ Cargo.toml | 17 + shaders/shader.frag | 9 + shaders/shader.vert | 9 + src/frame_counter.rs | 39 + src/instance/debug.rs | 70 ++ src/instance/mod.rs | 375 ++++++++ src/instance/pipeline.rs | 130 +++ src/instance/pools.rs | 58 ++ src/instance/queue.rs | 107 +++ src/instance/surface.rs | 91 ++ src/instance/swapchain.rs | 141 +++ src/instance/window.rs | 59 ++ src/main.rs | 100 +++ src/render.rs | 40 + 16 files changed, 3010 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 shaders/shader.frag create mode 100644 shaders/shader.vert create mode 100644 src/frame_counter.rs create mode 100644 src/instance/debug.rs create mode 100644 src/instance/mod.rs create mode 100644 src/instance/pipeline.rs create mode 100644 src/instance/pools.rs create mode 100644 src/instance/queue.rs create mode 100644 src/instance/surface.rs create mode 100644 src/instance/swapchain.rs create mode 100644 src/instance/window.rs create mode 100644 src/main.rs create mode 100644 src/render.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fedaa2b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +.env diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..0d1b366 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1763 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ab_glyph" +version = "0.2.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79faae4620f45232f599d9bc7b290f88247a0834162c4495ab2f02d60004adfb" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" + +[[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 = "android-activity" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" +dependencies = [ + "android-properties", + "bitflags 2.6.0", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + +[[package]] +name = "ash" +version = "0.38.0+1.3.281" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" +dependencies = [ + "libloading", +] + +[[package]] +name = "ash-window" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52bca67b61cb81e5553babde81b8211f713cb6db79766f80168f3e5f40ea6c82" +dependencies = [ + "ash", + "raw-window-handle", + "raw-window-metal", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7" +dependencies = [ + "objc-sys", +] + +[[package]] +name = "block2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" +dependencies = [ + "block-sys", + "objc2", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytemuck" +version = "1.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" + +[[package]] +name = "bytes" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" + +[[package]] +name = "calloop" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" +dependencies = [ + "bitflags 2.6.0", + "log", + "polling", + "rustix", + "slab", + "thiserror", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" +dependencies = [ + "calloop", + "rustix", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "cc" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +dependencies = [ + "cc", +] + +[[package]] +name = "cocoa" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation", + "core-graphics-types", + "libc", + "objc", +] + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "cursor-icon" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + +[[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 = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "icrate" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" +dependencies = [ + "block2", + "dispatch", + "objc2", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libloading" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + +[[package]] +name = "libredox" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall 0.4.1", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memmap2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +dependencies = [ + "libc", +] + +[[package]] +name = "ndk" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +dependencies = [ + "bitflags 2.6.0", + "jni-sys", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "orbclient" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" +dependencies = [ + "libredox", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490d3a563d3122bf7c911a59b0add9389e5ec0f5f0c3ac6b91ff235a0e6a7f90" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "polling" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quick-xml" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "raw-window-metal" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e8caa82e31bb98fee12fa8f051c94a6aa36b07cddb03f0d4fc558988360ff1" +dependencies = [ + "cocoa", + "core-graphics", + "objc", + "raw-window-handle", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "roxmltree" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "921904a62e410e37e215c40381b7117f830d9d89ba60ab5236170541dd25646b" +dependencies = [ + "xmlparser", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "sctk-adwaita" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70b31447ca297092c5a9916fc3b955203157b37c19ca8edde4f52e9843e602c7" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit", + "tiny-skia", +] + +[[package]] +name = "serde" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "shaderc" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27e07913ada18607bb60d12431cbe3358d3bbebbe95948e1618851dc01e63b7b" +dependencies = [ + "libc", + "shaderc-sys", +] + +[[package]] +name = "shaderc-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73120d240fe22196300f39ca8547ca2d014960f27b19b47b21288b396272f7f7" +dependencies = [ + "cmake", + "libc", + "roxmltree", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "smithay-client-toolkit" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" +dependencies = [ + "bitflags 2.6.0", + "calloop", + "calloop-wayland-source", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix", + "thiserror", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" + +[[package]] +name = "syn" +version = "2.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tiny-skia" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" + +[[package]] +name = "ttf-parser" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8686b91785aff82828ed725225925b33b4fde44c4bb15876e5f7c832724c420a" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vk-mem" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cb12b79bcec57a3334d0284f1364c1846f378bb47df9779c6dbfcfc245c9404" +dependencies = [ + "ash", + "bitflags 2.6.0", + "cc", +] + +[[package]] +name = "vk-shader-macros" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35402054f41da7b8e45ff2551985ae7ead3b866cc7c9ba76406a732c2b65e410" +dependencies = [ + "proc-macro2", + "quote", + "shaderc", + "syn", +] + +[[package]] +name = "vulkan-intro" +version = "0.1.0" +dependencies = [ + "ash", + "ash-window", + "dotenvy", + "env_logger", + "log", + "thiserror", + "vk-mem", + "vk-shader-macros", + "winit", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wayland-backend" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "269c04f203640d0da2092d1b8d89a2d081714ae3ac2f1b53e99f205740517198" +dependencies = [ + "cc", + "downcast-rs", + "rustix", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bd0f46c069d3382a36c8666c1b9ccef32b8b04f41667ca1fef06a1adcc2982" +dependencies = [ + "bitflags 2.6.0", + "rustix", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.6.0", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09414bcf0fd8d9577d73e9ac4659ebc45bcc9cff1980a350543ad8e50ee263b2" +dependencies = [ + "rustix", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edf466fc49a4feb65a511ca403fec3601494d0dee85dbf37fff6fa0dd4eec3b6" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6754825230fa5b27bafaa28c30b3c9e72c55530581220cef401fa422c0fae7" +dependencies = [ + "dlib", + "log", + "once_cell", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[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.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[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.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[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.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[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.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[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.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[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.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winit" +version = "0.29.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca" +dependencies = [ + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.6.0", + "bytemuck", + "calloop", + "cfg_aliases", + "core-foundation", + "core-graphics", + "cursor-icon", + "icrate", + "js-sys", + "libc", + "log", + "memmap2", + "ndk", + "ndk-sys", + "objc2", + "once_cell", + "orbclient", + "percent-encoding", + "raw-window-handle", + "redox_syscall 0.3.5", + "rustix", + "sctk-adwaita", + "smithay-client-toolkit", + "smol_str", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-plasma", + "web-sys", + "web-time", + "windows-sys 0.48.0", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" + +[[package]] +name = "xcursor" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911" + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.6.0", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" + +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + +[[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", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..89c3699 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "vulkan-intro" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ash = "0.38.0" +ash-window = "0.13.0" +dotenvy = "0.15.7" +env_logger = "0.11.3" +log = "0.4.22" +thiserror = "1.0.62" +vk-mem = "0.4.0" +vk-shader-macros = "0.2.10" +winit = { version = "0.29", features = ["rwh_06"] } diff --git a/shaders/shader.frag b/shaders/shader.frag new file mode 100644 index 0000000..5e48a77 --- /dev/null +++ b/shaders/shader.frag @@ -0,0 +1,9 @@ +#version 450 + +layout(location = 0) out vec4 theColour; + +layout(location = 1) in vec4 colourdata_from_the_vertexshader; + +void main() { + theColour = colourdata_from_the_vertexshader; +} diff --git a/shaders/shader.vert b/shaders/shader.vert new file mode 100644 index 0000000..27bff2e --- /dev/null +++ b/shaders/shader.vert @@ -0,0 +1,9 @@ +#version 450 + +layout(location = 1) out vec4 colourdata_from_the_vertexshader; + +void main() { + gl_PointSize = 10.0; + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); + colourdata_from_the_vertexshader = vec4(0.0, 0.6, 1.0, 1.0); +} diff --git a/src/frame_counter.rs b/src/frame_counter.rs new file mode 100644 index 0000000..9167dae --- /dev/null +++ b/src/frame_counter.rs @@ -0,0 +1,39 @@ +use std::time::{Duration, Instant}; + +pub struct FrameCounter { + counter: usize, + frame_start: Instant, +} + +impl FrameCounter { + pub fn new() -> Self { + Self { + counter: 0, + frame_start: Instant::now(), + } + } + + pub fn reset(&mut self) { + self.counter = 0; + self.frame_start = Instant::now(); + } + + pub fn frame_count(&self) -> usize { + self.counter + } + + pub fn get_frame_start(&self) -> Instant { + self.frame_start + } + + pub fn frame_time(&self) -> Duration { + self.frame_start.elapsed() + } + + pub fn new_frame(&mut self) -> Duration { + self.counter += 1; + let r = self.frame_start.elapsed(); + self.frame_start = Instant::now(); + r + } +} diff --git a/src/instance/debug.rs b/src/instance/debug.rs new file mode 100644 index 0000000..f169db7 --- /dev/null +++ b/src/instance/debug.rs @@ -0,0 +1,70 @@ +use std::ffi::CStr; + +use ash::{ext, vk}; + +use super::EngineError; + +pub struct DebugInstance { + pub loader: ext::debug_utils::Instance, + pub debug_messenger: vk::DebugUtilsMessengerEXT, +} + +impl DebugInstance { + pub fn debug_utils_messenger_create_info() -> vk::DebugUtilsMessengerCreateInfoEXT<'static> { + // Setup debug utils + vk::DebugUtilsMessengerCreateInfoEXT::default() + .message_severity( + vk::DebugUtilsMessageSeverityFlagsEXT::WARNING + | vk::DebugUtilsMessageSeverityFlagsEXT::VERBOSE + | vk::DebugUtilsMessageSeverityFlagsEXT::INFO + | vk::DebugUtilsMessageSeverityFlagsEXT::ERROR, + ) + .message_type( + vk::DebugUtilsMessageTypeFlagsEXT::GENERAL + | vk::DebugUtilsMessageTypeFlagsEXT::PERFORMANCE + | vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION, + ) + .pfn_user_callback(Some(vulkan_debug_utils_callback)) + } + + pub fn init<'a>( + entry: &'a ash::Entry, + instance: &'a ash::Instance, + ) -> Result { + // start debug messenger + let loader = ext::debug_utils::Instance::new(entry, instance); + let debug_messenger = unsafe { + loader.create_debug_utils_messenger(&Self::debug_utils_messenger_create_info(), None)? + }; + Ok(Self { + loader, + debug_messenger, + }) + } + + pub fn destroy(&self) { + unsafe { + self.loader + .destroy_debug_utils_messenger(self.debug_messenger, None); + } + } +} + +impl Drop for DebugInstance { + fn drop(&mut self) { + self.destroy() + } +} + +unsafe extern "system" fn vulkan_debug_utils_callback( + message_severity: vk::DebugUtilsMessageSeverityFlagsEXT, + message_type: vk::DebugUtilsMessageTypeFlagsEXT, + p_callback_data: *const vk::DebugUtilsMessengerCallbackDataEXT, + _p_user_data: *mut std::ffi::c_void, +) -> vk::Bool32 { + let message = CStr::from_ptr((*p_callback_data).p_message); + let severity = format!("{:?}", message_severity).to_lowercase(); + let ty = format!("{:?}", message_type).to_lowercase(); + println!("[Debug][{}][{}] {:?}", severity, ty, message); + vk::FALSE +} diff --git a/src/instance/mod.rs b/src/instance/mod.rs new file mode 100644 index 0000000..69305e9 --- /dev/null +++ b/src/instance/mod.rs @@ -0,0 +1,375 @@ +use std::ffi::{c_char, CString}; + +use ash::vk; + +pub mod debug; +pub mod pipeline; +pub mod pools; +pub mod queue; +pub mod surface; +pub mod swapchain; +pub mod window; + +pub use debug::DebugInstance; +pub use pipeline::Pipeline; +use pools::Pools; +pub use queue::{Queue, QueueFamilies, Queues}; +pub use surface::Surface; +pub use swapchain::Swapchain; +pub use window::Window; + +use crate::frame_counter::FrameCounter; + +const ENGINE_NAME: &core::ffi::CStr = c"UnknownGameEngine"; +const APP_NAME: &core::ffi::CStr = c"Vulkan Tutorial"; + +#[derive(Debug, thiserror::Error)] +pub enum EngineError { + #[error(transparent)] + VkError(#[from] vk::Result), + #[error(transparent)] + AshLoadingError(#[from] ash::LoadingError), + #[error(transparent)] + WinitOsError(#[from] winit::error::OsError), + #[error(transparent)] + WinitEventLoopError(#[from] winit::error::EventLoopError), + #[error(transparent)] + RWHError(#[from] winit::raw_window_handle::HandleError), +} + +pub struct EngineInstance { + pub entry: ash::Entry, + pub ash_instance: ash::Instance, + pub debug: std::mem::ManuallyDrop, + pub surface: std::mem::ManuallyDrop, + pub surface_format: vk::SurfaceFormatKHR, + pub physical_device: vk::PhysicalDevice, + pub physical_device_properties: vk::PhysicalDeviceProperties, + pub physical_device_memory_properties: vk::PhysicalDeviceMemoryProperties, + pub device: ash::Device, + pub queues: Queues, + pub swapchain: Swapchain, + pub renderpass: vk::RenderPass, + pub pipeline: Pipeline, + pub pools: Pools, + pub commandbuffers: Vec, + pub framecount: FrameCounter, +} + +impl EngineInstance { + pub fn init(window: &Window) -> Result { + log::debug!("Init window"); + let entry = unsafe { ash::Entry::load()? }; + + let layers = Self::layer_names(); + let layers_pointers = as_pointers(&layers); + + // create ash instance + log::debug!("Init instance"); + let extensions = window.extension_names()?; + let ash_instance = Self::init_instance(&entry, &layers_pointers, &extensions)?; + + log::debug!("Init debugger"); + let debug = DebugInstance::init(&entry, &ash_instance)?; + + log::debug!("Init surface"); + let surface = Surface::init(&entry, &ash_instance, &window)?; + // let (surface, surface_loader) = Self::init_surface(&entry, &ash_instance, &window)?; + + log::debug!("Init device"); + let (physical_device, physical_device_properties) = + Self::select_physical_device(&ash_instance)?; + let physical_device_memory_properties = + unsafe { ash_instance.get_physical_device_memory_properties(physical_device) }; + dbg!(&physical_device_properties); + dbg!(&physical_device_memory_properties); + + log::debug!("Select surface properties"); + let surface_capabilities = surface.get_capabilities(physical_device)?; + let surface_formats = surface.get_formats(physical_device)?; + + let surface_resolution = Surface::select_resolution(&surface_capabilities, &window.res); + let surface_format = Surface::select_format(&surface_formats); + + log::debug!("Select queues"); + let queue_families = QueueFamilies::init(&ash_instance, physical_device, &surface)?; + let queueinfo = queue_families.make_creation_info()?; + + log::debug!("Create device"); + let device = + Self::create_device(&ash_instance, physical_device, &layers_pointers, &queueinfo)?; + + log::debug!("Create queues"); + let queues = queue_families.create_queues(&device)?; + + // create swapchain + log::debug!("Create swapchain"); + let mut swapchain = Swapchain::init( + &ash_instance, + &device, + &surface, + &surface_capabilities, + surface_format, + surface_resolution, + &queues.graphics_queue.as_ref().unwrap(), + )?; + + log::debug!("Create framebuffers"); + let renderpass = Self::init_renderpass(&device, surface_format.format)?; + swapchain.create_framebuffers(&device, renderpass)?; + + log::debug!("Init pipeline"); + let pipeline = Pipeline::init(&device, &swapchain, &renderpass)?; + + log::debug!("Init pools"); + let pools = Pools::init(&device, &queue_families)?; + + log::debug!("Create command buffers"); + let commandbuffers = pools.create_commandbuffers(&device, swapchain.framebuffers.len())?; + for (i, &commandbuffer) in commandbuffers.iter().enumerate() { + Self::fill_commandbuffer(&device, commandbuffer, renderpass, &swapchain, i, &pipeline)?; + } + + Ok(Self { + entry, + ash_instance, + surface: std::mem::ManuallyDrop::new(surface), + surface_format: *surface_format, + debug: std::mem::ManuallyDrop::new(debug), + physical_device, + physical_device_properties, + physical_device_memory_properties, + device, + queues, + swapchain, + renderpass, + pipeline, + pools, + commandbuffers, + framecount: FrameCounter::new(), + }) + } + + fn destroy(&mut self) { + unsafe { + self.device + .device_wait_idle() + .expect("something wrong while waiting"); + self.pools.cleanup(&self.device); + // self.queues.cleanup(); + self.pipeline.cleanup(&self.device); + self.device.destroy_render_pass(self.renderpass, None); + self.swapchain.cleanup(&self.device); + std::mem::ManuallyDrop::drop(&mut self.surface); + self.device.destroy_device(None); + std::mem::ManuallyDrop::drop(&mut self.debug); + self.ash_instance.destroy_instance(None); + }; + } + + fn application_info() -> vk::ApplicationInfo<'static> { + vk::ApplicationInfo::default() + .application_name(APP_NAME) + .application_version(0) + .engine_name(ENGINE_NAME) + .engine_version(0) + .api_version(vk::make_api_version(0, 1, 3, 281)) + } + + fn instance_create_info<'a>( + debugcreateinfo: &'a mut vk::DebugUtilsMessengerCreateInfoEXT, + app_info: &'a vk::ApplicationInfo, + layers: &'a [*const c_char], + extensions: &'a [*const c_char], + ) -> vk::InstanceCreateInfo<'a> { + // Creation info + vk::InstanceCreateInfo::default() + .push_next(debugcreateinfo) + .application_info(app_info) + .enabled_layer_names(layers) + .enabled_extension_names(extensions) + } + + fn init_instance( + entry: &ash::Entry, + layers: &[*const c_char], + extensions: &[*const c_char], + ) -> Result { + let app_info = Self::application_info(); + // enable debug for instance init + let mut debugcreateinfo = DebugInstance::debug_utils_messenger_create_info(); + let instance_create_info = + Self::instance_create_info(&mut debugcreateinfo, &app_info, &layers, &extensions); + + let instance = unsafe { entry.create_instance(&instance_create_info, None)? }; + Ok(instance) + } + + pub fn layer_names() -> Vec { + vec![CString::new("VK_LAYER_KHRONOS_validation").unwrap()] + } + + fn select_physical_device( + instance: &ash::Instance, + ) -> Result<(vk::PhysicalDevice, vk::PhysicalDeviceProperties), EngineError> { + let phys_devs: Vec = unsafe { instance.enumerate_physical_devices()? }; + + let mut primary = None; + let mut secondary = None; + let mut tertiary = None; + let mut fallback = None; + + for p in phys_devs { + let properties = unsafe { instance.get_physical_device_properties(p) }; + + match properties.device_type { + vk::PhysicalDeviceType::DISCRETE_GPU => { + // if a dedicated is present, prioritize it + primary = Some((p, properties)); + break; + } + vk::PhysicalDeviceType::INTEGRATED_GPU => { + // integrated as secondary + secondary = Some((p, properties)); + } + vk::PhysicalDeviceType::VIRTUAL_GPU => { + // virtual as tertiary + tertiary = Some((p, properties)); + } + _ => { + fallback = Some((p, properties)); + } + } + } + + let r = if let Some(v) = primary { + v + } else if let Some(v) = secondary { + v + } else if let Some(v) = tertiary { + v + } else { + fallback.unwrap() + }; + Ok(r) + } + + fn device_extensions() -> Vec { + vec![ash::khr::swapchain::NAME.into()] + } + + fn create_device( + instance: &ash::Instance, + physical_device: vk::PhysicalDevice, + enabled_layer_names: &[*const i8], + queue_infos: &[vk::DeviceQueueCreateInfo], + ) -> Result { + //TODO: dedicated function + let device_extension_names = Self::device_extensions(); + let device_extension_name_pointers = as_pointers(&device_extension_names); + + let device_create_info = vk::DeviceCreateInfo::default() + .queue_create_infos(&queue_infos) + .enabled_extension_names(&device_extension_name_pointers) + .enabled_layer_names(enabled_layer_names); //deprecated, only for compatibility reason + + let logical_device = + unsafe { instance.create_device(physical_device, &device_create_info, None)? }; + Ok(logical_device) + } + + fn init_renderpass( + device: &ash::Device, + surface_format: vk::Format, + ) -> Result { + let attachments = [vk::AttachmentDescription::default() + .format(surface_format) + .load_op(vk::AttachmentLoadOp::CLEAR) + .store_op(vk::AttachmentStoreOp::STORE) + .stencil_load_op(vk::AttachmentLoadOp::DONT_CARE) + .stencil_store_op(vk::AttachmentStoreOp::DONT_CARE) + .initial_layout(vk::ImageLayout::UNDEFINED) + .final_layout(vk::ImageLayout::PRESENT_SRC_KHR) + .samples(vk::SampleCountFlags::TYPE_1)]; + + let color_attachment_references = [vk::AttachmentReference { + attachment: 0, + layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, + }]; + + let subpasses = [vk::SubpassDescription::default() + .color_attachments(&color_attachment_references) + .pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS)]; + + let subpass_dependencies = [vk::SubpassDependency::default() + .src_subpass(vk::SUBPASS_EXTERNAL) + .src_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT) + .dst_subpass(0) + .dst_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT) + .dst_access_mask( + vk::AccessFlags::COLOR_ATTACHMENT_READ | vk::AccessFlags::COLOR_ATTACHMENT_WRITE, + )]; + + let renderpass_info = vk::RenderPassCreateInfo::default() + .attachments(&attachments) + .subpasses(&subpasses) + .dependencies(&subpass_dependencies); + let renderpass = unsafe { device.create_render_pass(&renderpass_info, None)? }; + Ok(renderpass) + } + + fn fill_commandbuffer( + device: &ash::Device, + commandbuffer: vk::CommandBuffer, + renderpass: vk::RenderPass, + swapchain: &Swapchain, + framebuffer_index: usize, + pipeline: &Pipeline, + ) -> Result<(), vk::Result> { + let commandbuffer_begininfo = vk::CommandBufferBeginInfo::default(); + unsafe { + device.begin_command_buffer(commandbuffer, &commandbuffer_begininfo)?; + } + + let clearvalues = [vk::ClearValue { + color: vk::ClearColorValue { + float32: [0.0, 0.0, 0.08, 1.0], + }, + }]; + let renderpass_begininfo = vk::RenderPassBeginInfo::default() + .render_pass(renderpass) + .framebuffer(swapchain.framebuffers[framebuffer_index]) + .render_area(vk::Rect2D { + offset: vk::Offset2D { x: 0, y: 0 }, + extent: swapchain.extent, + }) + .clear_values(&clearvalues); + + unsafe { + device.cmd_begin_render_pass( + commandbuffer, + &renderpass_begininfo, + vk::SubpassContents::INLINE, + ); + device.cmd_bind_pipeline( + commandbuffer, + vk::PipelineBindPoint::GRAPHICS, + pipeline.pipeline, + ); + device.cmd_draw(commandbuffer, 1, 1, 0, 0); + device.cmd_end_render_pass(commandbuffer); + device.end_command_buffer(commandbuffer)?; + } + Ok(()) + } +} + +impl Drop for EngineInstance { + fn drop(&mut self) { + self.destroy() + } +} + +fn as_pointers(value: &[CString]) -> Vec<*const i8> { + value.iter().map(|layer_name| layer_name.as_ptr()).collect() +} diff --git a/src/instance/pipeline.rs b/src/instance/pipeline.rs new file mode 100644 index 0000000..2a763d8 --- /dev/null +++ b/src/instance/pipeline.rs @@ -0,0 +1,130 @@ +use std::ffi::CString; + +use ash::vk; + +use super::Swapchain; + +pub struct Pipeline { + pub pipeline: vk::Pipeline, + pub layout: vk::PipelineLayout, +} + +impl Pipeline { + pub fn cleanup(&self, logical_device: &ash::Device) { + unsafe { + logical_device.destroy_pipeline(self.pipeline, None); + logical_device.destroy_pipeline_layout(self.layout, None); + } + } + + pub fn init( + logical_device: &ash::Device, + swapchain: &Swapchain, + renderpass: &vk::RenderPass, + ) -> Result { + let vertexshader_createinfo = vk::ShaderModuleCreateInfo::default() + .code(vk_shader_macros::include_glsl!("./shaders/shader.vert", kind: vert)); + let vertexshader_module = + unsafe { logical_device.create_shader_module(&vertexshader_createinfo, None)? }; + let fragmentshader_createinfo = vk::ShaderModuleCreateInfo::default() + .code(vk_shader_macros::include_glsl!("./shaders/shader.frag", kind: frag)); + let fragmentshader_module = + unsafe { logical_device.create_shader_module(&fragmentshader_createinfo, None)? }; + + let mainfunctionname = CString::new("main").unwrap(); + let vertexshader_stage = vk::PipelineShaderStageCreateInfo::default() + .stage(vk::ShaderStageFlags::VERTEX) + .module(vertexshader_module) + .name(&mainfunctionname); + let fragmentshader_stage = vk::PipelineShaderStageCreateInfo::default() + .stage(vk::ShaderStageFlags::FRAGMENT) + .module(fragmentshader_module) + .name(&mainfunctionname); + let shader_stages = vec![vertexshader_stage, fragmentshader_stage]; + + let vertex_attrib_descs = [vk::VertexInputAttributeDescription { + binding: 0, + location: 0, + offset: 0, + format: vk::Format::R32G32B32A32_SFLOAT, + }]; + let vertex_binding_descs = [vk::VertexInputBindingDescription { + binding: 0, + stride: 16, + input_rate: vk::VertexInputRate::VERTEX, + }]; + + let vertex_input_info = vk::PipelineVertexInputStateCreateInfo::default() + .vertex_attribute_descriptions(&vertex_attrib_descs) + .vertex_binding_descriptions(&vertex_binding_descs); + + let input_assembly_info = vk::PipelineInputAssemblyStateCreateInfo::default() + .topology(vk::PrimitiveTopology::POINT_LIST); + let viewports = [vk::Viewport { + x: 0., + y: 0., + width: swapchain.extent.width as f32, + height: swapchain.extent.height as f32, + min_depth: 0., + max_depth: 1., + }]; + let scissors = [vk::Rect2D { + offset: vk::Offset2D { x: 0, y: 0 }, + extent: swapchain.extent, + }]; + + let viewport_info = vk::PipelineViewportStateCreateInfo::default() + .viewports(&viewports) + .scissors(&scissors); + let rasterizer_info = vk::PipelineRasterizationStateCreateInfo::default() + .line_width(1.0) + .front_face(vk::FrontFace::COUNTER_CLOCKWISE) + .cull_mode(vk::CullModeFlags::NONE) + .polygon_mode(vk::PolygonMode::FILL); + let multisampler_info = vk::PipelineMultisampleStateCreateInfo::default() + .rasterization_samples(vk::SampleCountFlags::TYPE_1); + let colourblend_attachments = [vk::PipelineColorBlendAttachmentState::default() + .blend_enable(true) + .src_color_blend_factor(vk::BlendFactor::SRC_ALPHA) + .dst_color_blend_factor(vk::BlendFactor::ONE_MINUS_SRC_ALPHA) + .color_blend_op(vk::BlendOp::ADD) + .src_alpha_blend_factor(vk::BlendFactor::SRC_ALPHA) + .dst_alpha_blend_factor(vk::BlendFactor::ONE_MINUS_SRC_ALPHA) + .alpha_blend_op(vk::BlendOp::ADD) + .color_write_mask( + vk::ColorComponentFlags::R + | vk::ColorComponentFlags::G + | vk::ColorComponentFlags::B + | vk::ColorComponentFlags::A, + )]; + let colourblend_info = + vk::PipelineColorBlendStateCreateInfo::default().attachments(&colourblend_attachments); + let pipelinelayout_info = vk::PipelineLayoutCreateInfo::default(); + let pipelinelayout = + unsafe { logical_device.create_pipeline_layout(&pipelinelayout_info, None) }?; + let pipeline_info = vk::GraphicsPipelineCreateInfo::default() + .stages(&shader_stages) + .vertex_input_state(&vertex_input_info) + .input_assembly_state(&input_assembly_info) + .viewport_state(&viewport_info) + .rasterization_state(&rasterizer_info) + .multisample_state(&multisampler_info) + .color_blend_state(&colourblend_info) + .layout(pipelinelayout) + .render_pass(*renderpass) + .subpass(0); + let graphicspipeline = unsafe { + logical_device + .create_graphics_pipelines(vk::PipelineCache::null(), &[pipeline_info], None) + .expect("A problem with the pipeline creation") + }[0]; + unsafe { + logical_device.destroy_shader_module(fragmentshader_module, None); + logical_device.destroy_shader_module(vertexshader_module, None); + } + Ok(Pipeline { + pipeline: graphicspipeline, + layout: pipelinelayout, + }) + } +} diff --git a/src/instance/pools.rs b/src/instance/pools.rs new file mode 100644 index 0000000..7b15520 --- /dev/null +++ b/src/instance/pools.rs @@ -0,0 +1,58 @@ +use ash::vk; + +use super::QueueFamilies; + +pub struct Pools { + commandpool_graphics: Option, + commandpool_transfer: Option, +} + +impl Pools { + pub fn init( + logical_device: &ash::Device, + queue_families: &QueueFamilies, + ) -> Result { + let commandpool_graphics = if let Some(graphics_index) = queue_families.graphics_index { + let graphics_commandpool_info = vk::CommandPoolCreateInfo::default() + .queue_family_index(graphics_index) + .flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER); + Some(unsafe { logical_device.create_command_pool(&graphics_commandpool_info, None) }?) + } else { + None + }; + let commandpool_transfer = if let Some(transfer_index) = queue_families.transfer_index { + let transfer_commandpool_info = vk::CommandPoolCreateInfo::default() + .queue_family_index(transfer_index) + .flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER); + Some(unsafe { logical_device.create_command_pool(&transfer_commandpool_info, None) }?) + } else { + None + }; + + Ok(Pools { + commandpool_graphics, + commandpool_transfer, + }) + } + pub fn cleanup(&self, logical_device: &ash::Device) { + unsafe { + if let Some(v) = self.commandpool_graphics { + logical_device.destroy_command_pool(v, None); + } + if let Some(v) = self.commandpool_transfer { + logical_device.destroy_command_pool(v, None); + } + } + } + + pub fn create_commandbuffers( + &self, + logical_device: &ash::Device, + amount: usize, + ) -> Result, vk::Result> { + let commandbuf_allocate_info = vk::CommandBufferAllocateInfo::default() + .command_pool(self.commandpool_graphics.unwrap()) + .command_buffer_count(amount as u32); + unsafe { logical_device.allocate_command_buffers(&commandbuf_allocate_info) } + } +} diff --git a/src/instance/queue.rs b/src/instance/queue.rs new file mode 100644 index 0000000..e0db1c1 --- /dev/null +++ b/src/instance/queue.rs @@ -0,0 +1,107 @@ +use super::{EngineError, Surface}; + +use ash::vk; + +const PRIORITIES: [f32; 1] = [1.0f32]; + +pub struct Queue { + pub queue: vk::Queue, + pub index: u32, +} + +impl Queue { + pub fn new(queue: vk::Queue, index: u32) -> Self { + Self { queue, index } + } +} + +pub struct Queues { + pub graphics_queue: Option, + pub transfer_queue: Option, +} + +pub struct QueueFamilies { + pub graphics_index: Option, + pub transfer_index: Option, +} + +impl QueueFamilies { + pub fn init( + instance: &ash::Instance, + physical_device: vk::PhysicalDevice, + surface: &Surface, + ) -> Result { + let mut graphics_index = None; + let mut transfer_index = None; + let queue_families = + unsafe { instance.get_physical_device_queue_family_properties(physical_device) }; + dbg!(&queue_families); + + for (index, qfam) in queue_families.iter().enumerate() { + if qfam.queue_count > 0 + && qfam.queue_flags.contains(vk::QueueFlags::GRAPHICS) + // WARN: surface drawing capable queue could be different, but in our case it's not + && unsafe { + surface.surface_loader.get_physical_device_surface_support( + physical_device, + index as u32, + surface.surface, + )? + } + { + graphics_index = Some(index as u32); + if qfam.queue_flags.contains(vk::QueueFlags::TRANSFER) && qfam.queue_count > 1 { + transfer_index = Some(index as u32); + } + } else if qfam.queue_count > 0 && qfam.queue_flags.contains(vk::QueueFlags::TRANSFER) { + if transfer_index.is_none() || !qfam.queue_flags.contains(vk::QueueFlags::GRAPHICS) + { + transfer_index = Some(index as u32); + } + } + } + Ok(Self { + graphics_index, + transfer_index, + }) + } + + pub fn make_creation_info<'a>( + &self, + ) -> Result>, EngineError> { + let mut queue_infos = vec![vk::DeviceQueueCreateInfo::default() + .queue_family_index(self.graphics_index.unwrap()) + .queue_priorities(&PRIORITIES)]; + if let Some(v) = self.transfer_index { + queue_infos.push( + vk::DeviceQueueCreateInfo::default() + .queue_family_index(v) + .queue_priorities(&PRIORITIES), + ) + } + Ok(queue_infos) + } + + pub fn create_queues(&self, logical_device: &ash::Device) -> Result { + let graphics_queue = self + .graphics_index + .map(|x| unsafe { Queue::new(logical_device.get_device_queue(x, 0), x) }); + let transfer_queue = if let Some(v) = self.transfer_index { + Some(Queue::new( + if self.graphics_index.is_some() && self.graphics_index.unwrap() == v { + // Graphics and transfer queue family indexes are identical, pick a second queue + unsafe { logical_device.get_device_queue(v, 1) } + } else { + unsafe { logical_device.get_device_queue(v, 0) } + }, + v, + )) + } else { + None + }; + Ok(Queues { + graphics_queue, + transfer_queue, + }) + } +} diff --git a/src/instance/surface.rs b/src/instance/surface.rs new file mode 100644 index 0000000..a531885 --- /dev/null +++ b/src/instance/surface.rs @@ -0,0 +1,91 @@ +use ash::{khr, vk}; + +use super::window::Resolution; +use super::EngineError; +use super::Window; + +pub struct Surface { + pub surface: vk::SurfaceKHR, + pub surface_loader: khr::surface::Instance, +} + +impl Surface { + pub fn init( + entry: &ash::Entry, + instance: &ash::Instance, + window: &Window, + ) -> Result { + let surface = unsafe { + ash_window::create_surface( + entry, + instance, + window.raw_display_handle()?, + window.raw_window_handle()?, + None, + )? + }; + let surface_loader = khr::surface::Instance::new(&entry, &instance); + Ok(Self { + surface, + surface_loader, + }) + } + + pub fn get_capabilities( + &self, + physical_device: vk::PhysicalDevice, + ) -> Result { + Ok(unsafe { + self.surface_loader + .get_physical_device_surface_capabilities(physical_device, self.surface)? + }) + } + + pub fn get_present_modes( + &self, + physical_device: vk::PhysicalDevice, + ) -> Result, EngineError> { + Ok(unsafe { + self.surface_loader + .get_physical_device_surface_present_modes(physical_device, self.surface)? + }) + } + + pub fn get_formats( + &self, + physical_device: vk::PhysicalDevice, + ) -> Result, EngineError> { + Ok(unsafe { + self.surface_loader + .get_physical_device_surface_formats(physical_device, self.surface)? + }) + } + + pub fn select_resolution( + surface_capabilities: &vk::SurfaceCapabilitiesKHR, + res: &Resolution, + ) -> vk::Extent2D { + match surface_capabilities.current_extent.width { + u32::MAX => vk::Extent2D { + width: res.width, + height: res.height, + }, + _ => surface_capabilities.current_extent, + } + } + + pub fn select_format(surface_formats: &[vk::SurfaceFormatKHR]) -> &vk::SurfaceFormatKHR { + let selected_surface_format = surface_formats + .iter() + .filter(|x| x.format == vk::Format::R8G8B8A8_SRGB) + .collect::>() + .remove(0); + selected_surface_format + } +} + +impl Drop for Surface { + fn drop(&mut self) { + unsafe { self.surface_loader.destroy_surface(self.surface, None) }; + } +} diff --git a/src/instance/swapchain.rs b/src/instance/swapchain.rs new file mode 100644 index 0000000..ef8b09d --- /dev/null +++ b/src/instance/swapchain.rs @@ -0,0 +1,141 @@ +use ash::{khr, vk}; + +use super::{EngineError, Queue, Surface}; + +pub struct Swapchain { + pub swapchain_loader: khr::swapchain::Device, + pub swapchain: vk::SwapchainKHR, + pub extent: vk::Extent2D, + pub images: Vec, + pub image_views: Vec, + pub framebuffers: Vec, + pub image_available: Vec, + pub rendering_finished: Vec, + pub may_begin_drawing: Vec, + pub amount_of_images: u32, + pub current_image: usize, +} + +impl Swapchain { + pub fn init( + instance: &ash::Instance, + logical_device: &ash::Device, + surface: &Surface, + surface_capabilities: &vk::SurfaceCapabilitiesKHR, + surface_format: &vk::SurfaceFormatKHR, + extent: vk::Extent2D, + graphics_queue: &Queue, + ) -> Result { + let queuefamilies = [graphics_queue.index]; + let swapchain_create_info = vk::SwapchainCreateInfoKHR::default() + .surface(surface.surface) + .min_image_count( + 3.max(surface_capabilities.min_image_count), + // .min(surface_capabilities.max_image_count), // currently broken for this device ? + ) + .image_format(surface_format.format) + .image_color_space(surface_format.color_space) + .image_extent(extent) + .image_array_layers(1) + .image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT) + .image_sharing_mode(vk::SharingMode::EXCLUSIVE) + .queue_family_indices(&queuefamilies) + .pre_transform(surface_capabilities.current_transform) + .composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE) + .present_mode(vk::PresentModeKHR::FIFO); + let swapchain_loader = khr::swapchain::Device::new(&instance, &logical_device); + let swapchain = unsafe { swapchain_loader.create_swapchain(&swapchain_create_info, None)? }; + + let swapchain_images = unsafe { swapchain_loader.get_swapchain_images(swapchain)? }; + + // create views + let mut swapchain_imageviews = Vec::with_capacity(swapchain_images.len()); + for image in &swapchain_images { + let subresource_range = vk::ImageSubresourceRange::default() + .aspect_mask(vk::ImageAspectFlags::COLOR) + .base_mip_level(0) + .level_count(1) + .base_array_layer(0) + .layer_count(1); + let imageview_create_info = vk::ImageViewCreateInfo::default() + .image(*image) + .view_type(vk::ImageViewType::TYPE_2D) + .format(surface_format.format) + .subresource_range(subresource_range); + let imageview = + unsafe { logical_device.create_image_view(&imageview_create_info, None) }?; + swapchain_imageviews.push(imageview); + } + + let amount_of_images = swapchain_images.len() as u32; + + let mut image_available = vec![]; + let mut rendering_finished = vec![]; + let mut may_begin_drawing = vec![]; + let semaphoreinfo = vk::SemaphoreCreateInfo::default(); + let fenceinfo = vk::FenceCreateInfo::default().flags(vk::FenceCreateFlags::SIGNALED); + for _ in 0..amount_of_images { + let semaphore_available = + unsafe { logical_device.create_semaphore(&semaphoreinfo, None) }?; + let semaphore_finished = + unsafe { logical_device.create_semaphore(&semaphoreinfo, None) }?; + image_available.push(semaphore_available); + rendering_finished.push(semaphore_finished); + let fence = unsafe { logical_device.create_fence(&fenceinfo, None) }?; + may_begin_drawing.push(fence); + } + + Ok(Self { + swapchain_loader, + swapchain, + extent, + images: swapchain_images, + image_views: swapchain_imageviews, + framebuffers: vec![], + amount_of_images, + current_image: 0, + may_begin_drawing, + image_available, + rendering_finished, + }) + } + + pub unsafe fn cleanup(&mut self, logical_device: &ash::Device) { + for fence in &self.may_begin_drawing { + logical_device.destroy_fence(*fence, None); + } + for semaphore in &self.image_available { + logical_device.destroy_semaphore(*semaphore, None); + } + for semaphore in &self.rendering_finished { + logical_device.destroy_semaphore(*semaphore, None); + } + for fb in &self.framebuffers { + logical_device.destroy_framebuffer(*fb, None); + } + for iv in &self.image_views { + logical_device.destroy_image_view(*iv, None); + } + self.swapchain_loader + .destroy_swapchain(self.swapchain, None); + } + + pub fn create_framebuffers( + &mut self, + logical_device: &ash::Device, + renderpass: vk::RenderPass, + ) -> Result<(), vk::Result> { + for iv in &self.image_views { + let iview = [*iv]; + let framebuffer_info = vk::FramebufferCreateInfo::default() + .render_pass(renderpass) + .attachments(&iview) + .width(self.extent.width) + .height(self.extent.height) + .layers(1); + let fb = unsafe { logical_device.create_framebuffer(&framebuffer_info, None) }?; + self.framebuffers.push(fb); + } + Ok(()) + } +} diff --git a/src/instance/window.rs b/src/instance/window.rs new file mode 100644 index 0000000..73e38ec --- /dev/null +++ b/src/instance/window.rs @@ -0,0 +1,59 @@ +use std::cell::RefCell; + +use winit::event_loop::EventLoop as WinitEventLoop; +use winit::raw_window_handle::RawDisplayHandle; +use winit::raw_window_handle::RawWindowHandle; +use winit::window::Window as WinitWindow; +use winit::window::WindowBuilder as WinitWindowBuilder; + +use winit::raw_window_handle::{HasDisplayHandle, HasWindowHandle}; + +use super::EngineError; + +#[derive(Clone, Debug)] +pub struct Resolution { + pub width: u32, + pub height: u32, +} + +pub struct Window { + pub eventloop: RefCell>, + pub window: WinitWindow, + pub res: Resolution, +} + +impl Window { + pub fn init(res: Resolution) -> Result { + let eventloop = WinitEventLoop::new()?; + let window = WinitWindowBuilder::new() + .with_title("Vulkan tutorial") + .with_inner_size(winit::dpi::LogicalSize::new( + f64::from(res.width), + f64::from(res.height), + )) + .build(&eventloop)?; + + Ok(Self { + eventloop: RefCell::new(eventloop), + window, + res, + }) + } + + pub fn extension_names(&self) -> Result, EngineError> { + let mut extension_name_pointers = + ash_window::enumerate_required_extensions(self.window.display_handle()?.as_raw()) + .unwrap() + .to_vec(); + extension_name_pointers.push(ash::ext::debug_utils::NAME.as_ptr()); + Ok(extension_name_pointers) + } + + pub fn raw_display_handle(&self) -> Result { + Ok(self.window.display_handle()?.as_raw()) + } + + pub fn raw_window_handle(&self) -> Result { + Ok(self.window.window_handle()?.as_raw()) + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..c4e8e8a --- /dev/null +++ b/src/main.rs @@ -0,0 +1,100 @@ +pub mod instance; +pub mod render; + +pub mod frame_counter; + +pub use instance::EngineInstance; +use instance::{window::Resolution, Window}; + +use ash::vk; + +pub const WINDOW_WIDTH: u32 = 1280; +pub const WINDOW_HEIGHT: u32 = 720; + +pub const DEFAULT_RES: Resolution = Resolution { + width: WINDOW_WIDTH, + height: WINDOW_HEIGHT, +}; + +fn main() -> Result<(), Box> { + dotenvy::dotenv().ok(); + env_logger::init(); + + let window = Window::init(DEFAULT_RES.clone())?; + let mut instance = EngineInstance::init(&window)?; + + render::render_loop(&window, &mut instance, move |e| { + let next_image = (e.swapchain.current_image + 1) % e.swapchain.amount_of_images as usize; + + unsafe { + e.device + .wait_for_fences( + &[e.swapchain.may_begin_drawing[e.swapchain.current_image]], + true, + std::u64::MAX, + ) + .expect("fence-waiting"); + + e.device + .reset_fences(&[e.swapchain.may_begin_drawing[e.swapchain.current_image]]) + .expect("resetting fences"); + } + + let (image_index, _) = unsafe { + e.swapchain + .swapchain_loader + .acquire_next_image( + e.swapchain.swapchain, + std::u64::MAX, + e.swapchain.image_available[e.swapchain.current_image], + vk::Fence::null(), + ) + .expect("image acquisition trouble") + }; + + let semaphores_available = [e.swapchain.image_available[e.swapchain.current_image]]; + let waiting_stages = [vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT]; + let semaphores_finished = [ + e.swapchain.rendering_finished[e.swapchain.current_image], + // e.swapchain.next_frame[next_image], + ]; + let commandbuffers = [e.commandbuffers[image_index as usize]]; + let submit_info = [vk::SubmitInfo::default() + .wait_semaphores(&semaphores_available) + .wait_dst_stage_mask(&waiting_stages) + .command_buffers(&commandbuffers) + .signal_semaphores(&semaphores_finished)]; + + let queue = e.queues.graphics_queue.as_ref().unwrap().queue; + unsafe { + e.device + .queue_submit( + queue, + &submit_info, + e.swapchain.may_begin_drawing[e.swapchain.current_image], + ) + .expect("queue submission"); + }; + + let swapchains = [e.swapchain.swapchain]; + let indices = [image_index]; + let present_info = vk::PresentInfoKHR::default() + .wait_semaphores(&semaphores_finished) + .swapchains(&swapchains) + .image_indices(&indices); + unsafe { + e.swapchain + .swapchain_loader + .queue_present(queue, &present_info) + .expect("queue presentation"); + }; + + let frameid = e.framecount.frame_count(); + let frametime = e.framecount.new_frame(); + println!("frame {}: {} ms", frameid, frametime.as_secs_f32() * 1000.0); + + e.swapchain.current_image = next_image; + })?; + + Ok(()) +} diff --git a/src/render.rs b/src/render.rs new file mode 100644 index 0000000..66d1e0c --- /dev/null +++ b/src/render.rs @@ -0,0 +1,40 @@ +use crate::instance::{EngineInstance, Window}; +use winit::{ + event::{ElementState, Event, KeyEvent, WindowEvent}, + keyboard::{Key, NamedKey}, + platform::run_on_demand::EventLoopExtRunOnDemand, +}; + +pub fn render_loop( + window: &Window, + instance: &mut EngineInstance, + f: F, +) -> Result<(), impl std::error::Error> { + window + .eventloop + .borrow_mut() + .run_on_demand(move |event, elwp| { + elwp.set_control_flow(winit::event_loop::ControlFlow::Poll); + match event { + Event::WindowEvent { + event: + WindowEvent::CloseRequested + | WindowEvent::KeyboardInput { + event: + KeyEvent { + state: ElementState::Pressed, + logical_key: Key::Named(NamedKey::Escape), + .. + }, + .. + }, + .. + } + | Event::LoopExiting => { + elwp.exit(); + } + Event::AboutToWait => f(instance), + _ => (), + } + }) +}