diff --git a/Cargo.lock b/Cargo.lock index e538714..1f58cce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,6 +117,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + [[package]] name = "arrayref" version = "0.3.9" @@ -144,48 +150,11 @@ dependencies = [ "libloading", ] -[[package]] -name = "assert_type_match" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f548ad2c4031f2902e3edc1f29c29e835829437de49562d8eb5dc5584d3a1043" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-executor" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "pin-project-lite", - "slab", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" -dependencies = [ - "portable-atomic", -] - [[package]] name = "atomic-waker" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -dependencies = [ - "portable-atomic", -] [[package]] name = "autocfg" @@ -193,178 +162,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" -[[package]] -name = "bevy_app" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2b6267ac23a9947d5b2725ff047a1e1add70076d85fa9fb73d044ab9bea1f3c" -dependencies = [ - "bevy_derive", - "bevy_ecs", - "bevy_platform", - "bevy_reflect", - "bevy_tasks", - "bevy_utils", - "cfg-if", - "ctrlc", - "downcast-rs 2.0.1", - "log", - "thiserror 2.0.12", - "variadics_please", -] - -[[package]] -name = "bevy_derive" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f626531b9c05c25a758ede228727bd11c2c2c8498ecbed9925044386d525a2a3" -dependencies = [ - "bevy_macro_utils", - "quote", - "syn", -] - -[[package]] -name = "bevy_ecs" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9e807b5d9aab3bb8dfe47e7a44c9ff088bad2ceefe299b80ac77609a87fe9d4" -dependencies = [ - "arrayvec", - "bevy_ecs_macros", - "bevy_platform", - "bevy_ptr", - "bevy_reflect", - "bevy_tasks", - "bevy_utils", - "bitflags 2.9.1", - "bumpalo", - "concurrent-queue", - "derive_more", - "disqualified", - "fixedbitset", - "indexmap", - "log", - "nonmax", - "serde", - "smallvec", - "thiserror 2.0.12", - "variadics_please", -] - -[[package]] -name = "bevy_ecs_macros" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "467d7bb98aeb8dd30f36e6a773000c12a891d4f1bee2adc3841ec89cc8eaf54e" -dependencies = [ - "bevy_macro_utils", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "bevy_macro_utils" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2473db70d8785b5c75d6dd951a2e51e9be2c2311122db9692c79c9d887517b" -dependencies = [ - "parking_lot", - "proc-macro2", - "quote", - "syn", - "toml_edit", -] - -[[package]] -name = "bevy_platform" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704db2c11b7bc31093df4fbbdd3769f9606a6a5287149f4b51f2680f25834ebc" -dependencies = [ - "cfg-if", - "critical-section", - "foldhash", - "hashbrown", - "portable-atomic", - "portable-atomic-util", - "serde", - "spin", -] - -[[package]] -name = "bevy_ptr" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f1275dfb4cfef4ffc90c3fa75408964864facf833acc932413d52aa5364ba4" - -[[package]] -name = "bevy_reflect" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "607ebacc31029cf2f39ac330eabf1d4bc411b159528ec08dbe6b0593eaccfd41" -dependencies = [ - "assert_type_match", - "bevy_platform", - "bevy_ptr", - "bevy_reflect_derive", - "bevy_utils", - "derive_more", - "disqualified", - "downcast-rs 2.0.1", - "erased-serde", - "foldhash", - "glam 0.29.3", - "serde", - "smallvec", - "smol_str", - "thiserror 2.0.12", - "uuid", - "variadics_please", - "wgpu-types", -] - -[[package]] -name = "bevy_reflect_derive" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf35e45e4eb239018369f63f2adc2107a54c329f9276d020e01eee1625b0238b" -dependencies = [ - "bevy_macro_utils", - "proc-macro2", - "quote", - "syn", - "uuid", -] - -[[package]] -name = "bevy_tasks" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444c450b65e108855f42ecb6db0c041a56ea7d7f10cc6222f0ca95e9536a7d19" -dependencies = [ - "async-executor", - "async-task", - "atomic-waker", - "bevy_platform", - "cfg-if", - "crossbeam-queue", - "derive_more", - "futures-lite", - "heapless", -] - -[[package]] -name = "bevy_utils" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac2da3b3c1f94dadefcbe837aaa4aa119fcea37f7bdc5307eb05b4ede1921e24" -dependencies = [ - "bevy_platform", - "thread_local", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -376,9 +173,6 @@ name = "bitflags" version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" -dependencies = [ - "serde", -] [[package]] name = "block2" @@ -415,12 +209,6 @@ dependencies = [ "syn", ] -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.10.1" @@ -514,7 +302,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", - "portable-atomic", ] [[package]] @@ -557,12 +344,6 @@ dependencies = [ "libc", ] -[[package]] -name = "critical-section" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" - [[package]] name = "crossbeam-queue" version = "0.3.12" @@ -584,43 +365,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" -[[package]] -name = "ctrlc" -version = "3.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f93780a459b7d656ef7f071fe699c4d3d2cb201c4b24d085b6ddc505276e73" -dependencies = [ - "nix", - "windows-sys 0.59.0", -] - [[package]] name = "cursor-icon" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" -[[package]] -name = "derive_more" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - [[package]] name = "dispatch" version = "0.2.0" @@ -637,12 +387,6 @@ dependencies = [ "objc2 0.6.1", ] -[[package]] -name = "disqualified" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9c272297e804878a2a4b707cfcfc6d2328b5bb936944613b4fdf2b9269afdfd" - [[package]] name = "dlib" version = "0.5.2" @@ -658,55 +402,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" -[[package]] -name = "downcast-rs" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8a8b81cacc08888170eef4d13b775126db426d0b348bee9d18c2c1eaf123cf" - [[package]] name = "dpi" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" -[[package]] -name = "engine_render" -version = "0.1.0" -dependencies = [ - "bevy_app", - "bevy_ecs", - "engine_vulkan", - "engine_window", - "log", - "vulkano", -] - -[[package]] -name = "engine_vulkan" -version = "0.1.0" -dependencies = [ - "bevy_app", - "bevy_ecs", - "engine_window", - "env_logger", - "log", - "thiserror 2.0.12", - "vulkano", - "winit", -] - -[[package]] -name = "engine_window" -version = "0.1.0" -dependencies = [ - "bevy_app", - "bevy_ecs", - "log", - "thiserror 2.0.12", - "winit", -] - [[package]] name = "env_filter" version = "0.1.3" @@ -736,16 +437,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" -[[package]] -name = "erased-serde" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" -dependencies = [ - "serde", - "typeid", -] - [[package]] name = "errno" version = "0.3.12" @@ -756,18 +447,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" - [[package]] name = "foldhash" version = "0.1.5" @@ -801,31 +480,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-lite" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - [[package]] name = "gethostname" version = "0.4.3" @@ -848,15 +502,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "glam" -version = "0.29.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee" -dependencies = [ - "serde", -] - [[package]] name = "glam" version = "0.30.3" @@ -874,35 +519,11 @@ dependencies = [ "crunchy", ] -[[package]] -name = "hash32" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" -dependencies = [ - "byteorder", -] - [[package]] name = "hashbrown" version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" -dependencies = [ - "equivalent", - "serde", -] - -[[package]] -name = "heapless" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" -dependencies = [ - "hash32", - "portable-atomic", - "stable_deref_trait", -] [[package]] name = "heck" @@ -1104,18 +725,6 @@ dependencies = [ "jni-sys", ] -[[package]] -name = "nix" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" -dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "cfg_aliases", - "libc", -] - [[package]] name = "nom" version = "7.1.3" @@ -1126,12 +735,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "nonmax" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51" - [[package]] name = "num_enum" version = "0.7.3" @@ -1435,12 +1038,6 @@ dependencies = [ "ttf-parser", ] -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - [[package]] name = "parking_lot" version = "0.12.3" @@ -1652,14 +1249,11 @@ dependencies = [ name = "rust_vulkan_test" version = "0.1.0" dependencies = [ - "bevy_app", - "bevy_ecs", - "engine_render", - "engine_vulkan", - "engine_window", + "anyhow", "env_logger", - "glam 0.30.3", + "glam", "log", + "thiserror 2.0.12", "vulkano", "vulkano-shaders", "winit", @@ -1838,21 +1432,6 @@ dependencies = [ "serde", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "strict-num" version = "0.1.1" @@ -1984,12 +1563,6 @@ version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" -[[package]] -name = "typeid" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" - [[package]] name = "unicode-ident" version = "1.0.18" @@ -2002,41 +1575,12 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "uuid" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" -dependencies = [ - "getrandom", - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "variadics_please" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41b6d82be61465f97d42bd1d15bf20f3b0a3a0905018f38f9d6f6962055b0b5c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "version_check" version = "0.9.5" @@ -2208,7 +1752,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" dependencies = [ "cc", - "downcast-rs 1.2.1", + "downcast-rs", "rustix", "scoped-tls", "smallvec", @@ -2330,19 +1874,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "wgpu-types" -version = "24.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c" -dependencies = [ - "bitflags 2.9.1", - "js-sys", - "log", - "serde", - "web-sys", -] - [[package]] name = "winapi-util" version = "0.1.9" diff --git a/Cargo.toml b/Cargo.toml index d8c8792..ce36410 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,11 +5,7 @@ edition = "2024" authors = ["Florian RICHER "] publish = false -[workspace] -resolver = "2" -members = ["crates/*"] - -[workspace.dependencies] +[dependencies] anyhow = "1.0" thiserror = "2.0" winit = { version = "0.30", features = ["rwh_06"] } @@ -20,28 +16,7 @@ vulkano-shaders = "0.35" # Math glam = { version = "0.30" } -# ECS -bevy_ecs = "0.16" -bevy_app = "0.16" # Log and tracing log = "0.4" env_logger = "0.11" - -engine_vulkan = { path = "crates/engine_vulkan" } -engine_window = { path = "crates/engine_window" } -engine_render = { path = "crates/engine_render" } - -[dependencies] -log = { workspace = true } -env_logger = { workspace = true } -bevy_app = { workspace = true } -bevy_ecs = { workspace = true } -winit = { workspace = true } -vulkano = { workspace = true } -vulkano-shaders = { workspace = true } -glam = { workspace = true } - -engine_vulkan = { workspace = true } -engine_window = { workspace = true } -engine_render = { workspace = true } diff --git a/crates/engine_render/Cargo.toml b/crates/engine_render/Cargo.toml deleted file mode 100644 index 5016279..0000000 --- a/crates/engine_render/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "engine_render" -version = "0.1.0" -edition = "2024" - -[dependencies] -log = { workspace = true } -bevy_app = { workspace = true } -bevy_ecs = { workspace = true } -vulkano = { workspace = true } -engine_vulkan = { workspace = true } -engine_window = { workspace = true } diff --git a/crates/engine_render/src/lib.rs b/crates/engine_render/src/lib.rs deleted file mode 100644 index 8c869e9..0000000 --- a/crates/engine_render/src/lib.rs +++ /dev/null @@ -1,120 +0,0 @@ -use bevy_app::{App, AppLabel, Last, Plugin, SubApp}; -use bevy_ecs::{ - schedule::{IntoScheduleConfigs, Schedule, ScheduleLabel, SystemSet}, - system::{Commands, Res}, - world::World, -}; -use engine_vulkan::{ - VulkanCommandBufferAllocator, VulkanDescriptorSetAllocator, VulkanDevice, VulkanGraphicsQueue, - VulkanInstance, VulkanMemoryAllocator, -}; -use engine_window::raw_handle::WindowWrapper; -use window::WindowRenderPlugin; - -pub mod render; -pub mod window; - -#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] -pub enum RenderSystems { - ManageViews, - Prepare, - Queue, - Render, - Present, -} - -#[derive(ScheduleLabel, Debug, Hash, PartialEq, Eq, Clone, Default)] -pub struct Render; - -impl Render { - pub fn base_schedule() -> Schedule { - use RenderSystems::*; - - let mut schedule = Schedule::new(Self); - - schedule.configure_sets((ManageViews, Prepare, Queue, Render, Present).chain()); - - schedule - } -} - -#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, AppLabel)] -pub struct RenderApp; - -pub struct RenderPlugin; - -impl Plugin for RenderPlugin { - fn build(&self, _app: &mut App) {} - - fn ready(&self, app: &App) -> bool { - let world = app.world(); - - world.get_resource::().is_some() - && world.get_resource::().is_some() - && world.get_resource::().is_some() - && world.get_resource::().is_some() - && world.get_resource::().is_some() - && world - .get_resource::() - .is_some() - && world - .get_resource::() - .is_some() - } - - fn finish(&self, app: &mut App) { - let mut render_app = SubApp::new(); - render_app.update_schedule = Some(Render.intern()); - render_app.add_schedule(Render::base_schedule()); - render_app.add_systems( - Render, - render::render_system - .in_set(RenderSystems::Render) - .run_if(render::can_render), - ); - - extract_app_resources(app.world_mut(), render_app.world_mut()); - - app.insert_sub_app(RenderApp, render_app); - - app.add_plugins(WindowRenderPlugin); - } -} - -fn extract_app_resources(world: &mut World, render_world: &mut World) { - let window_wrapper = world - .get_resource::() - .expect("Failed to get WindowWrapper. Check is WindowPlugin is added before RenderPlugin."); - - let vulkan_instance = world.get_resource::().expect( - "Failed to get Vulkan instance. Check is VulkanPlugin is added before RenderPlugin.", - ); - - let vulkan_device = world - .get_resource::() - .expect("Failed to get Vulkan device. Check is VulkanPlugin is added before RenderPlugin."); - - let vulkan_graphics_queue = world.get_resource::().expect( - "Failed to get Vulkan graphics queue. Check is VulkanPlugin is added before RenderPlugin.", - ); - - let vulkan_memory_allocator = world - .get_resource::() - .expect("Failed to get Vulkan memory allocator. Check is VulkanPlugin is added before RenderPlugin."); - - let vulkan_command_buffer_allocator = world - .get_resource::() - .expect("Failed to get Vulkan command buffer allocator. Check is VulkanPlugin is added before RenderPlugin."); - - let vulkan_descriptor_set_allocator = world - .get_resource::() - .expect("Failed to get Vulkan descriptor set allocator. Check is VulkanPlugin is added before RenderPlugin."); - - render_world.insert_resource(vulkan_instance.clone()); - render_world.insert_resource(vulkan_device.clone()); - render_world.insert_resource(vulkan_graphics_queue.clone()); - render_world.insert_resource(vulkan_memory_allocator.clone()); - render_world.insert_resource(vulkan_command_buffer_allocator.clone()); - render_world.insert_resource(vulkan_descriptor_set_allocator.clone()); - render_world.insert_resource(window_wrapper.clone()); -} diff --git a/crates/engine_render/src/render.rs b/crates/engine_render/src/render.rs deleted file mode 100644 index 1a8c95e..0000000 --- a/crates/engine_render/src/render.rs +++ /dev/null @@ -1,122 +0,0 @@ -use bevy_ecs::system::{Res, ResMut}; -use engine_vulkan::{VulkanCommandBufferAllocator, VulkanDevice, VulkanGraphicsQueue}; -use vulkano::{ - Validated, VulkanError, - command_buffer::{ - AutoCommandBufferBuilder, CommandBufferUsage, RenderingAttachmentInfo, RenderingInfo, - }, - render_pass::{AttachmentLoadOp, AttachmentStoreOp}, - swapchain::{SwapchainAcquireFuture, SwapchainPresentInfo, acquire_next_image}, - sync::{self, GpuFuture}, -}; - -use crate::window::{WindowSurface, WindowSurfaceData}; - -pub fn can_render(window_surface: Res) -> bool { - window_surface.surface.is_some() -} - -pub fn render_system( - mut window_surface: ResMut, - command_buffer_allocator: Res, - graphics_queue: Res, - device: Res, -) { - { - let surface = window_surface.surface.as_ref().unwrap(); - if surface.viewport.extent[0] == 0.0 || surface.viewport.extent[1] == 0.0 { - return; - } - } - - let (image_index, acquire_future) = - match acquire_image(&mut window_surface.surface.as_mut().unwrap()) { - Some(r) => r, - None => return, - }; - - let mut builder = AutoCommandBufferBuilder::primary( - command_buffer_allocator.0.clone(), - graphics_queue.0.queue_family_index(), - CommandBufferUsage::OneTimeSubmit, - ) - .expect("failed to create command buffer builder"); - - { - let surface = window_surface.surface.as_ref().unwrap(); - builder - .begin_rendering(RenderingInfo { - color_attachments: vec![Some(RenderingAttachmentInfo { - load_op: AttachmentLoadOp::Clear, - store_op: AttachmentStoreOp::Store, - clear_value: Some([0.0, 0.0, 0.0, 0.0].into()), - ..RenderingAttachmentInfo::image_view( - surface.attachment_image_views[image_index as usize].clone(), - ) - })], - ..Default::default() - }) - .unwrap() - .set_viewport(0, [surface.viewport.clone()].into_iter().collect()) - .unwrap(); - } - - builder.end_rendering().unwrap(); - - let command_buffer = builder.build().unwrap(); - - { - let surface = window_surface.surface.as_mut().unwrap(); - - let future = surface - .previous_frame_end - .take() - .unwrap() - .join(acquire_future) - .then_execute(graphics_queue.0.clone(), command_buffer) - .unwrap() - .then_swapchain_present( - graphics_queue.0.clone(), - SwapchainPresentInfo::swapchain_image_index(surface.swapchain.clone(), image_index), - ) - .then_signal_fence_and_flush(); - - match future.map_err(Validated::unwrap) { - Ok(future) => { - surface.previous_frame_end = Some(future.boxed_send_sync()); - } - Err(VulkanError::OutOfDate) => { - surface.recreate_swapchain = true; - surface.previous_frame_end = Some(sync::now(device.0.clone()).boxed_send_sync()); - } - Err(e) => { - println!("failed to flush future: {e}"); - surface.previous_frame_end = Some(sync::now(device.0.clone()).boxed_send_sync()); - } - } - } -} - -fn acquire_image(surface: &mut WindowSurfaceData) -> Option<(u32, SwapchainAcquireFuture)> { - surface - .previous_frame_end - .as_mut() - .unwrap() - .cleanup_finished(); - - let (image_index, suboptimal, acquire_future) = - match acquire_next_image(surface.swapchain.clone(), None).map_err(Validated::unwrap) { - Ok(r) => r, - Err(VulkanError::OutOfDate) => { - surface.recreate_swapchain = true; - return None; - } - Err(e) => panic!("failed to acquire next image: {e}"), - }; - - if suboptimal { - surface.recreate_swapchain = true; - } - - Some((image_index, acquire_future)) -} diff --git a/crates/engine_render/src/window/mod.rs b/crates/engine_render/src/window/mod.rs deleted file mode 100644 index d019444..0000000 --- a/crates/engine_render/src/window/mod.rs +++ /dev/null @@ -1,222 +0,0 @@ -use std::sync::Arc; - -use bevy_app::{App, Plugin}; -use bevy_ecs::{ - resource::Resource, - schedule::IntoScheduleConfigs, - system::{Res, ResMut}, -}; -use engine_vulkan::{VulkanDevice, VulkanInstance}; -use engine_window::raw_handle::WindowWrapper; -use vulkano::{ - image::{Image, ImageUsage, view::ImageView}, - pipeline::graphics::viewport::Viewport, - swapchain::{Surface, Swapchain, SwapchainCreateInfo}, - sync::{self, GpuFuture}, -}; - -use super::{Render, RenderApp, RenderSystems}; - -pub struct WindowSurfaceData { - pub swapchain: Arc, - pub attachment_image_views: Vec>, - pub viewport: Viewport, - pub recreate_swapchain: bool, - pub previous_frame_end: Option>, -} - -#[derive(Resource, Default)] -pub struct WindowSurface { - pub surface: Option, -} - -pub struct WindowRenderPlugin; - -impl Plugin for WindowRenderPlugin { - fn build(&self, app: &mut App) { - let render_app = app - .get_sub_app_mut(RenderApp) - .expect("Failed to get RenderApp. Check is RenderPlugin is added."); - - render_app.init_resource::(); - - render_app.add_systems( - Render, - create_window_surface - .in_set(RenderSystems::ManageViews) - .run_if(need_create_window_surface) - .before(need_update_window_surface), - ); - - render_app.add_systems( - Render, - update_window_surface - .in_set(RenderSystems::ManageViews) - .run_if(need_update_window_surface), - ); - } -} - -fn need_create_window_surface(window_surface: Res) -> bool { - window_surface.surface.is_none() -} - -fn create_window_surface( - mut window_surface: ResMut, - window_handle: Res, - vulkan_instance: Res, - vulkan_device: Res, -) { - let window_size = window_handle.0.inner_size(); - - let surface = Surface::from_window(vulkan_instance.0.clone(), window_handle.0.clone()) - .expect("Failed to create surface"); - log::debug!("Surface created"); - - let (swapchain, images) = { - let surface_capabilities = vulkan_device - .0 - .physical_device() - .surface_capabilities(&surface, Default::default()) - .unwrap(); - - let (image_format, _) = vulkan_device - .0 - .physical_device() - .surface_formats(&surface, Default::default()) - .unwrap()[0]; - - Swapchain::new( - vulkan_device.0.clone(), - surface, - SwapchainCreateInfo { - // 2 because with some graphics driver, it crash on fullscreen because fullscreen need to min image to works. - min_image_count: surface_capabilities.min_image_count.max(2), - image_format, - image_extent: window_size.into(), - image_usage: ImageUsage::COLOR_ATTACHMENT, - composite_alpha: surface_capabilities - .supported_composite_alpha - .into_iter() - .next() - .unwrap(), - - ..Default::default() - }, - ) - .unwrap() - }; - log_swapchain_info(&swapchain, false); - - let attachment_image_views = window_size_dependent_setup(&images); - - let viewport = Viewport { - offset: [0.0, 0.0], - extent: window_size.into(), - depth_range: 0.0..=1.0, - }; - log_viewport_info(&viewport, false); - - let recreate_swapchain = false; - let previous_frame_end = Some(sync::now(vulkan_device.0.clone()).boxed_send_sync()); - - window_surface.surface = Some(WindowSurfaceData { - swapchain, - attachment_image_views, - viewport, - recreate_swapchain, - previous_frame_end, - }); -} - -fn window_size_dependent_setup(images: &[Arc]) -> Vec> { - images - .iter() - .map(|image| ImageView::new_default(image.clone()).unwrap()) - .collect::>() -} - -fn need_update_window_surface( - window_surface: Res, - window_handle: Res, -) -> bool { - match &window_surface.surface { - Some(surface) => { - let window_size: [f32; 2] = window_handle.0.inner_size().into(); - surface.recreate_swapchain || surface.viewport.extent != window_size - } - None => false, - } -} - -fn update_window_surface( - mut window_surface: ResMut, - window_handle: Res, -) { - let window_surface = window_surface.surface.as_mut().unwrap(); - - let window_size = window_handle.0.inner_size(); - let (new_swapchain, new_images) = window_surface - .swapchain - .recreate(SwapchainCreateInfo { - image_extent: window_size.into(), - ..window_surface.swapchain.create_info() - }) - .expect("Failed to recreate swapchain"); - - window_surface.swapchain = new_swapchain; - window_surface.attachment_image_views = window_size_dependent_setup(&new_images); - window_surface.viewport.extent = window_size.into(); - window_surface.recreate_swapchain = false; - - log_swapchain_info(&window_surface.swapchain, true); - log_viewport_info(&window_surface.viewport, true); -} - -fn log_swapchain_info(swapchain: &Swapchain, recreate_swapchain: bool) { - if recreate_swapchain { - log::debug!("Swapchain recreated"); - } else { - log::debug!("Swapchain created"); - } - log::debug!( - "\tMin image count: {}", - swapchain.create_info().min_image_count - ); - log::debug!("\tImage format: {:?}", swapchain.create_info().image_format); - log::debug!("\tImage extent: {:?}", swapchain.create_info().image_extent); - log::debug!("\tImage usage: {:?}", swapchain.create_info().image_usage); - log::debug!( - "\tComposite alpha: {:?}", - swapchain.create_info().composite_alpha - ); - log::debug!("\tPresent mode: {:?}", swapchain.create_info().present_mode); - log::debug!( - "\tImage sharing: {:?}", - swapchain.create_info().image_sharing - ); - log::debug!( - "\tPre transform: {:?}", - swapchain.create_info().pre_transform - ); - log::debug!( - "\tComposite alpha: {:?}", - swapchain.create_info().composite_alpha - ); - log::debug!("\tPresent mode: {:?}", swapchain.create_info().present_mode); - log::debug!( - "\tFull screen exclusive: {:?}", - swapchain.create_info().full_screen_exclusive - ); -} - -fn log_viewport_info(viewport: &Viewport, recreate_viewport: bool) { - if recreate_viewport { - log::debug!("Viewport recreated"); - } else { - log::debug!("Viewport created"); - } - log::debug!("\tOffset: {:?}", viewport.offset); - log::debug!("\tExtent: {:?}", viewport.extent); - log::debug!("\tDepth range: {:?}", viewport.depth_range); -} diff --git a/crates/engine_vulkan/Cargo.toml b/crates/engine_vulkan/Cargo.toml deleted file mode 100644 index c0fe35b..0000000 --- a/crates/engine_vulkan/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "engine_vulkan" -version = "0.1.0" -edition = "2024" - -[dependencies] -thiserror = { workspace = true } -log = { workspace = true } -env_logger = { workspace = true } -bevy_app = { workspace = true } -bevy_ecs = { workspace = true } -winit = { workspace = true } -vulkano = { workspace = true } -engine_window = { workspace = true } diff --git a/crates/engine_vulkan/src/device.rs b/crates/engine_vulkan/src/device.rs deleted file mode 100644 index f20335f..0000000 --- a/crates/engine_vulkan/src/device.rs +++ /dev/null @@ -1,214 +0,0 @@ -use std::sync::Arc; - -use bevy_ecs::world::World; -use engine_window::raw_handle::DisplayHandleWrapper; -use vulkano::{ - command_buffer::allocator::StandardCommandBufferAllocator, - descriptor_set::allocator::StandardDescriptorSetAllocator, - device::{ - Device, DeviceCreateInfo, DeviceExtensions, Queue, - physical::{PhysicalDevice, PhysicalDeviceType}, - }, - memory::allocator::StandardMemoryAllocator, -}; - -use crate::{ - VulkanCommandBufferAllocator, VulkanComputeQueue, VulkanConfig, VulkanDescriptorSetAllocator, - VulkanDevice, VulkanGraphicsQueue, VulkanInstance, VulkanMemoryAllocator, VulkanTransferQueue, - queues::{VulkanQueueFamilyIndices, VulkanQueuesQuery, find_queues_family_indices}, -}; - -pub fn create_and_insert_device(world: &mut World, config: &VulkanConfig) { - let picked_device = - pick_physical_device(world, &config).expect("Failed to pick physical device"); - - let device = picked_device.device; - let physical_device = device.physical_device(); - - log::debug!("Vulkan device created"); - log::debug!( - "\tPhysical device: {:?} ({:?})", - physical_device.properties().device_name, - physical_device.properties().device_type - ); - log::debug!("\tDevice extensions: {:?}", device.enabled_extensions()); - log::debug!("\tDevice features: {:?}", device.enabled_features()); - - world.insert_resource(VulkanDevice(device.clone())); - - log::debug!("\tDevice selected queues:"); - if config.with_graphics_queue { - world.insert_resource(VulkanGraphicsQueue( - picked_device - .graphics_queue - .expect("Failed to get graphics queue"), - )); - log::debug!("\t\t- Graphics queue"); - } - - if config.with_compute_queue { - world.insert_resource(VulkanComputeQueue( - picked_device - .compute_queue - .expect("Failed to get compute queue"), - )); - log::debug!("\t\t- Compute queue"); - } - - if config.with_transfer_queue { - world.insert_resource(VulkanTransferQueue( - picked_device - .transfer_queue - .expect("Failed to get transfer queue"), - )); - log::debug!("\t\t- Transfer queue"); - } - - world.insert_resource(VulkanMemoryAllocator(Arc::new( - StandardMemoryAllocator::new_default(device.clone()), - ))); - world.insert_resource(VulkanCommandBufferAllocator(Arc::new( - StandardCommandBufferAllocator::new(device.clone(), Default::default()), - ))); - world.insert_resource(VulkanDescriptorSetAllocator(Arc::new( - StandardDescriptorSetAllocator::new(device.clone(), Default::default()), - ))); -} - -struct PickedDevice { - pub device: Arc, - pub graphics_queue: Option>, - pub compute_queue: Option>, - pub transfer_queue: Option>, -} - -fn pick_physical_device(world: &World, config: &VulkanConfig) -> Option { - let instance = world - .get_resource::() - .expect("Failed to get VulkanInstance during vulkan plugin initialization"); - - instance - .0 - .enumerate_physical_devices() - .expect("Failed to enumerate physical devices") - .filter_map(|p| check_physical_device_support(world, &p, config).and_then(|r| Some((p, r)))) - .min_by_key(|(p, _)| match p.properties().device_type { - PhysicalDeviceType::DiscreteGpu => 0, - PhysicalDeviceType::IntegratedGpu => 1, - PhysicalDeviceType::VirtualGpu => 2, - PhysicalDeviceType::Cpu => 3, - PhysicalDeviceType::Other => 4, - _ => 5, - }) - .take() - .and_then(|(p, (device_extensions, queue_family_indices))| { - Some(create_device( - config, - &p, - device_extensions, - queue_family_indices, - )) - }) -} - -fn check_device_extensions_support( - physical_device: &Arc, - config: &VulkanConfig, -) -> Option { - let device_extensions = DeviceExtensions { - khr_swapchain: config.with_window_surface, - ..config.device_extensions - }; - - if physical_device - .supported_extensions() - .contains(&device_extensions) - { - log::debug!( - "\t\t[OK] Device supports required extensions {:?}", - device_extensions - ); - Some(device_extensions) - } else { - log::debug!( - "\t\t[FAILED] Device does not support required extensions {:?}", - device_extensions - ); - None - } -} - -fn check_physical_device_support( - world: &World, - physical_device: &Arc, - config: &VulkanConfig, -) -> Option<(DeviceExtensions, VulkanQueueFamilyIndices)> { - log::debug!("Checking physical device"); - log::debug!("\tProperties"); - log::debug!("\t\tName: {}", physical_device.properties().device_name); - log::debug!("\t\tAPI version: {}", physical_device.api_version()); - log::debug!( - "\t\tDevice type: {:?}", - physical_device.properties().device_type - ); - log::debug!("\tRequired supports checking report"); - - let device_extensions = check_device_extensions_support(physical_device, config)?; - - let display_handle = world - .get_resource::() - .expect("DisplayHandleWrapper must be added before VulkanPlugin"); - - let queue_support_query = VulkanQueuesQuery { - with_surface: Some(&display_handle), - with_graphics_queue: config.with_graphics_queue, - with_compute_queue: config.with_compute_queue, - with_transfer_queue: config.with_transfer_queue, - }; - - let queue_family_indices = find_queues_family_indices(physical_device, &queue_support_query); - log::debug!("\t\tQueue family indices: {:#?}", queue_family_indices); - - Some((device_extensions, queue_family_indices)) -} - -fn create_device( - config: &VulkanConfig, - physical_device: &Arc, - device_extensions: DeviceExtensions, - queue_family_indices: VulkanQueueFamilyIndices, -) -> PickedDevice { - let (device, mut queues) = Device::new( - physical_device.clone(), - DeviceCreateInfo { - queue_create_infos: queue_family_indices.into(), - enabled_extensions: device_extensions, - enabled_features: config.device_features, - ..Default::default() - }, - ) - .expect("Failed to create device"); - - let mut graphics_queue = None; - let mut compute_queue = None; - let mut transfer_queue = None; - - if config.with_graphics_queue { - graphics_queue = queues.next(); - } - - if config.with_compute_queue { - compute_queue = queues.next(); - } - - if config.with_transfer_queue { - transfer_queue = queues.next(); - } - - PickedDevice { - device, - graphics_queue, - compute_queue, - transfer_queue, - } -} diff --git a/crates/engine_vulkan/src/instance.rs b/crates/engine_vulkan/src/instance.rs deleted file mode 100644 index dcda857..0000000 --- a/crates/engine_vulkan/src/instance.rs +++ /dev/null @@ -1,70 +0,0 @@ -use std::sync::Arc; - -use bevy_ecs::world::World; -use engine_window::raw_handle::DisplayHandleWrapper; -use vulkano::{ - VulkanLibrary, - instance::{Instance, InstanceCreateFlags, InstanceCreateInfo, InstanceExtensions}, - swapchain::Surface, -}; - -use crate::{VulkanConfig, VulkanInstance}; - -fn load_library() -> Arc { - let library = VulkanLibrary::new().unwrap(); - - log::debug!("Available Instance layers:"); - for layer in library.layer_properties().unwrap() { - log::debug!( - "\t - Layer name: {}, Description: {}, Implementation Version: {}, Vulkan Version: {}", - layer.name(), - layer.description(), - layer.implementation_version(), - layer.vulkan_version() - ); - } - - library -} - -pub fn create_and_insert_instance(world: &mut World, config: &VulkanConfig) { - let library = load_library(); - - let instance_extensions = { - if config.with_window_surface { - let display_handle = world - .get_resource::() - .expect("DisplayHandleWrapper must be added before VulkanPlugin"); - - Surface::required_extensions(&display_handle.0) - .expect("Failed to get surface required extensions") - } else { - InstanceExtensions::default() - } - }; - - let instance = Instance::new( - library, - InstanceCreateInfo { - // Enable enumerating devices that use non-conformant Vulkan implementations. - // (e.g. MoltenVK) - flags: InstanceCreateFlags::ENUMERATE_PORTABILITY, - enabled_extensions: instance_extensions, - enabled_layers: config.instance_layers.clone(), - ..Default::default() - }, - ) - .expect("Failed to create vulkan instance"); - - log::debug!("Instance created"); - log::debug!( - "\t- Enabled extensions: {:?}", - instance.enabled_extensions() - ); - log::debug!("\t- Enabled layers: {:?}", instance.enabled_layers()); - log::debug!("\t- API version: {:?}", instance.api_version()); - log::debug!("\t- Max API version: {:?}", instance.max_api_version()); - log::debug!("\t- Flags: {:?}", instance.flags()); - - world.insert_resource(VulkanInstance(instance)); -} diff --git a/crates/engine_vulkan/src/lib.rs b/crates/engine_vulkan/src/lib.rs deleted file mode 100644 index 38cb456..0000000 --- a/crates/engine_vulkan/src/lib.rs +++ /dev/null @@ -1,85 +0,0 @@ -use std::sync::Arc; - -use bevy_app::{App, Plugin}; -use bevy_ecs::resource::Resource; -use vulkano::{ - command_buffer::allocator::StandardCommandBufferAllocator, - descriptor_set::allocator::StandardDescriptorSetAllocator, - device::{Device, DeviceExtensions, DeviceFeatures, Queue}, - instance::Instance, - memory::allocator::StandardMemoryAllocator, -}; - -mod device; -mod instance; -mod queues; - -use crate::{device::create_and_insert_device, instance::create_and_insert_instance}; - -#[derive(Resource, Clone)] -pub struct VulkanInstance(pub Arc); - -#[derive(Resource, Clone)] -pub struct VulkanDevice(pub Arc); - -#[derive(Resource, Clone)] -pub struct VulkanGraphicsQueue(pub Arc); - -#[derive(Resource, Clone)] -pub struct VulkanComputeQueue(pub Arc); - -#[derive(Resource, Clone)] -pub struct VulkanTransferQueue(pub Arc); - -#[derive(Resource, Clone)] -pub struct VulkanMemoryAllocator(pub Arc); - -#[derive(Resource, Clone)] -pub struct VulkanCommandBufferAllocator(pub Arc); - -#[derive(Resource, Clone)] -pub struct VulkanDescriptorSetAllocator(pub Arc); - -#[derive(Debug, thiserror::Error)] -pub enum VulkanError { - #[error("Failed to create vulkan context")] - FailedToCreateVulkanContext, -} - -pub struct VulkanConfig { - pub instance_layers: Vec, - pub device_extensions: DeviceExtensions, - pub device_features: DeviceFeatures, - pub with_window_surface: bool, - pub with_graphics_queue: bool, - pub with_compute_queue: bool, - pub with_transfer_queue: bool, -} - -impl Default for VulkanConfig { - fn default() -> Self { - Self { - instance_layers: Vec::default(), - device_extensions: DeviceExtensions::default(), - device_features: DeviceFeatures::default(), - with_window_surface: true, - with_graphics_queue: true, - with_compute_queue: true, - with_transfer_queue: true, - } - } -} - -#[derive(Default)] -pub struct VulkanPlugin { - pub vulkan_config: VulkanConfig, -} - -impl Plugin for VulkanPlugin { - fn build(&self, app: &mut App) { - let world = app.world_mut(); - - create_and_insert_instance(world, &self.vulkan_config); - create_and_insert_device(world, &self.vulkan_config); - } -} diff --git a/crates/engine_vulkan/src/queues.rs b/crates/engine_vulkan/src/queues.rs deleted file mode 100644 index 17e6c08..0000000 --- a/crates/engine_vulkan/src/queues.rs +++ /dev/null @@ -1,176 +0,0 @@ -use std::{collections::HashMap, sync::Arc}; - -use engine_window::raw_handle::DisplayHandleWrapper; -use vulkano::device::{ - QueueCreateInfo, QueueFamilyProperties, QueueFlags, physical::PhysicalDevice, -}; - -#[derive(Debug)] -pub enum VulkanQueueFamilyStatus { - Unused, - NotSupported, - Supported(u32), -} - -impl VulkanQueueFamilyStatus { - pub fn can_be_set(&self) -> bool { - match self { - VulkanQueueFamilyStatus::NotSupported => true, - _ => false, - } - } -} - -/// Convert a boolean to a VulkanQueueFamilyStatus as default value -impl From for VulkanQueueFamilyStatus { - fn from(value: bool) -> Self { - if value { - VulkanQueueFamilyStatus::NotSupported - } else { - VulkanQueueFamilyStatus::Unused - } - } -} - -/// Convert a DisplayHandleWrapper Option to a VulkanQueueFamilyStatus as default value -impl From> for VulkanQueueFamilyStatus { - fn from(value: Option<&DisplayHandleWrapper>) -> Self { - if value.is_some() { - VulkanQueueFamilyStatus::NotSupported - } else { - VulkanQueueFamilyStatus::Unused - } - } -} - -#[derive(Debug)] -pub struct VulkanQueueFamilyIndices { - pub graphics_queue_family_index: VulkanQueueFamilyStatus, - pub compute_queue_family_index: VulkanQueueFamilyStatus, - pub transfer_queue_family_index: VulkanQueueFamilyStatus, -} - -impl From for Vec<(VulkanQueueFamilyStatus, f32)> { - fn from(indices: VulkanQueueFamilyIndices) -> Self { - vec![ - (indices.graphics_queue_family_index, 1.0), - (indices.compute_queue_family_index, 0.5), - (indices.transfer_queue_family_index, 0.5), - ] - } -} - -impl From for Vec { - fn from(indices: VulkanQueueFamilyIndices) -> Self { - let mut queue_create_infos = HashMap::::new(); - - let statuses: Vec<(VulkanQueueFamilyStatus, f32)> = indices.into(); - - for (status, priority) in statuses.iter() { - match status { - VulkanQueueFamilyStatus::Supported(index) => { - let entry = queue_create_infos.entry(*index).or_insert(QueueCreateInfo { - queue_family_index: *index, - queues: Vec::new(), - ..Default::default() - }); - - entry.queues.push(*priority); - } - _ => {} - } - } - - queue_create_infos - .into_iter() - .map(|(_, value)| value) - .collect() - } -} - -/// Convert a VulkanQueuesQuery to a VulkanQueuesFamilyIndices as default value -impl<'a> From<&'a VulkanQueuesQuery<'a>> for VulkanQueueFamilyIndices { - fn from(query: &'a VulkanQueuesQuery<'a>) -> Self { - VulkanQueueFamilyIndices { - graphics_queue_family_index: query.with_graphics_queue.into(), - compute_queue_family_index: query.with_compute_queue.into(), - transfer_queue_family_index: query.with_transfer_queue.into(), - } - } -} - -pub struct VulkanQueuesQuery<'a> { - pub with_surface: Option<&'a DisplayHandleWrapper>, - pub with_graphics_queue: bool, - pub with_compute_queue: bool, - pub with_transfer_queue: bool, -} - -pub fn find_queues_family_indices( - physical_device: &Arc, - query: &VulkanQueuesQuery, -) -> VulkanQueueFamilyIndices { - let mut indices: VulkanQueueFamilyIndices = query.into(); - - for (i, queue_family_properties) in physical_device.queue_family_properties().iter().enumerate() - { - let mut available_queue_count = queue_family_properties.queue_count; - - if indices.graphics_queue_family_index.can_be_set() - && check_queue_support(queue_family_properties, QueueFlags::GRAPHICS) - && available_queue_count > 0 - { - if query.with_surface.is_none() - || check_presentation_support( - physical_device, - i as u32, - &query.with_surface.as_ref().unwrap(), - ) - { - indices.graphics_queue_family_index = VulkanQueueFamilyStatus::Supported(i as u32); - available_queue_count -= 1; - } - } - - if indices.compute_queue_family_index.can_be_set() - && check_queue_support(queue_family_properties, QueueFlags::COMPUTE) - && available_queue_count > 0 - { - indices.compute_queue_family_index = VulkanQueueFamilyStatus::Supported(i as u32); - available_queue_count -= 1; - } - - if indices.transfer_queue_family_index.can_be_set() - && check_queue_support(queue_family_properties, QueueFlags::TRANSFER) - && available_queue_count > 0 - { - indices.transfer_queue_family_index = VulkanQueueFamilyStatus::Supported(i as u32); - } - - if !indices.graphics_queue_family_index.can_be_set() - && !indices.compute_queue_family_index.can_be_set() - && !indices.transfer_queue_family_index.can_be_set() - { - break; - } - } - - return indices; -} - -fn check_presentation_support( - physical_device: &Arc, - queue_family_index: u32, - surface: &DisplayHandleWrapper, -) -> bool { - physical_device - .presentation_support(queue_family_index, &surface.0) - .unwrap() -} - -fn check_queue_support( - queue_family_property: &QueueFamilyProperties, - queue_flags: QueueFlags, -) -> bool { - queue_family_property.queue_flags.intersects(queue_flags) -} diff --git a/crates/engine_window/Cargo.toml b/crates/engine_window/Cargo.toml deleted file mode 100644 index b5016cc..0000000 --- a/crates/engine_window/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "engine_window" -version = "0.1.0" -edition = "2024" - -[dependencies] -thiserror = { workspace = true } -log = { workspace = true } -bevy_app = { workspace = true } -bevy_ecs = { workspace = true } -winit = { workspace = true } diff --git a/crates/engine_window/src/config.rs b/crates/engine_window/src/config.rs deleted file mode 100644 index 487140c..0000000 --- a/crates/engine_window/src/config.rs +++ /dev/null @@ -1,17 +0,0 @@ -use bevy_ecs::resource::Resource; -use winit::{dpi::PhysicalSize, window::WindowAttributes}; - -#[derive(Resource, Clone)] -pub struct WindowConfig { - pub title: String, - pub width: u32, - pub height: u32, -} - -impl Into for &WindowConfig { - fn into(self) -> WindowAttributes { - WindowAttributes::default() - .with_title(self.title.clone()) - .with_inner_size(PhysicalSize::new(self.width as f64, self.height as f64)) - } -} diff --git a/crates/engine_window/src/lib.rs b/crates/engine_window/src/lib.rs deleted file mode 100644 index 33e150c..0000000 --- a/crates/engine_window/src/lib.rs +++ /dev/null @@ -1,56 +0,0 @@ -use bevy_app::{App, AppExit, Plugin, PluginsState}; -use config::WindowConfig; -use raw_handle::{DisplayHandleWrapper, EventLoopProxyWrapper, WindowWrapper}; -use state::WindowState; -use winit::event_loop::EventLoop; - -pub mod config; -pub mod raw_handle; -pub mod state; - -#[derive(Debug, thiserror::Error)] -pub enum WindowError { - #[error("Failed to create event loop")] - FailedToCreateEventLoop, -} - -pub struct WindowPlugin { - pub window_config: WindowConfig, -} - -impl Plugin for WindowPlugin { - fn build(&self, app: &mut App) { - let world = app.world_mut(); - world.insert_resource(self.window_config.clone()); - - let mut event_loop_builder = EventLoop::with_user_event(); - let event_loop = event_loop_builder - .build() - .map_err(|_| WindowError::FailedToCreateEventLoop) - .expect("Failed to create event loop"); - - world.insert_resource(DisplayHandleWrapper(event_loop.owned_display_handle())); - - app.set_runner(Box::new(move |app| runner(app, event_loop))); - } -} - -fn runner(mut app: App, event_loop: EventLoop<()>) -> AppExit { - if app.plugins_state() == PluginsState::Ready { - app.finish(); - app.cleanup(); - } - - app.world_mut() - .insert_resource(EventLoopProxyWrapper::new(event_loop.create_proxy())); - - let mut window_state = WindowState::new(app); - - match event_loop.run_app(&mut window_state) { - Ok(_) => AppExit::Success, - Err(e) => { - log::error!("Error running window state: {e}"); - AppExit::error() - } - } -} diff --git a/crates/engine_window/src/raw_handle.rs b/crates/engine_window/src/raw_handle.rs deleted file mode 100644 index 87d5988..0000000 --- a/crates/engine_window/src/raw_handle.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::sync::Arc; - -use bevy_ecs::resource::Resource; -use winit::{event_loop::EventLoopProxy, window::Window}; - -#[derive(Resource)] -pub struct EventLoopProxyWrapper(EventLoopProxy); - -impl EventLoopProxyWrapper { - pub fn new(event_loop: EventLoopProxy) -> Self { - Self(event_loop) - } - - pub fn proxy(&self) -> &EventLoopProxy { - &self.0 - } -} - -#[derive(Resource, Clone)] -pub struct DisplayHandleWrapper(pub winit::event_loop::OwnedDisplayHandle); - -#[derive(Resource, Clone)] -pub struct WindowWrapper(pub Arc); diff --git a/crates/engine_window/src/state.rs b/crates/engine_window/src/state.rs deleted file mode 100644 index 0f708fd..0000000 --- a/crates/engine_window/src/state.rs +++ /dev/null @@ -1,63 +0,0 @@ -use std::sync::Arc; - -use bevy_app::{App, PluginsState}; -use bevy_ecs::world::World; -use winit::{ - application::ApplicationHandler, event::WindowEvent, event_loop::ActiveEventLoop, - window::WindowId, -}; - -use super::{config::WindowConfig, raw_handle::WindowWrapper}; - -pub struct WindowState { - app: App, -} - -impl WindowState { - pub fn new(app: App) -> Self { - Self { app } - } - - fn world(&self) -> &World { - self.app.world() - } -} - -impl ApplicationHandler for WindowState { - fn resumed(&mut self, event_loop: &ActiveEventLoop) { - let window_config = self.world().get_resource::().unwrap(); - - let window = event_loop.create_window(window_config.into()).unwrap(); - self.app - .world_mut() - .insert_resource(WindowWrapper(Arc::new(window))); - } - - fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: winit::event::StartCause) { - if self.app.plugins_state() == PluginsState::Ready { - self.app.finish(); - self.app.cleanup(); - } - } - - fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) { - match event { - WindowEvent::CloseRequested => { - log::debug!("The close button was pressed; stopping"); - event_loop.exit(); - } - WindowEvent::RedrawRequested => { - if self.app.plugins_state() == PluginsState::Cleaned { - self.app.update(); - } - - let window_wrapper = self.app.world().get_resource::().unwrap(); - - window_wrapper.0.request_redraw(); - } - _ => {} - } - } - - fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) {} -} diff --git a/flake.nix b/flake.nix index 9cef9c1..dbd8d4c 100644 --- a/flake.nix +++ b/flake.nix @@ -76,7 +76,7 @@ packages = { default = rustPlatform.buildRustPackage { - pname = "rust_ash_test"; + pname = "vulkan_test"; version = "0.1.0"; src = self; diff --git a/src/core/camera/mod.rs b/src/core/camera/mod.rs deleted file mode 100644 index f9b6925..0000000 --- a/src/core/camera/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -use bevy_ecs::component::Component; -use glam::{Mat4, Quat, Vec3}; - -pub trait Camera: Into + Component {} - -#[derive(Component)] -pub struct Camera3D { - pub projection: Mat4, - pub position: Vec3, - pub rotation: Quat, -} - -impl Into for Camera3D { - fn into(self) -> Mat4 { - Mat4::from_rotation_translation(self.rotation, self.position) * self.projection - } -} - -impl Camera for Camera3D {} diff --git a/src/core/mod.rs b/src/core/mod.rs deleted file mode 100644 index a8707c6..0000000 --- a/src/core/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod camera; -pub mod render; diff --git a/src/core/render/material.rs b/src/core/render/material.rs deleted file mode 100644 index 539d4bc..0000000 --- a/src/core/render/material.rs +++ /dev/null @@ -1,7 +0,0 @@ -use std::sync::Arc; - -use bevy_ecs::component::Component; -use vulkano::pipeline::GraphicsPipeline; - -#[derive(Component)] -pub struct Material(pub Arc); diff --git a/src/core/render/mesh.rs b/src/core/render/mesh.rs deleted file mode 100644 index ca5ec0f..0000000 --- a/src/core/render/mesh.rs +++ /dev/null @@ -1,14 +0,0 @@ -use bevy_ecs::component::Component; - -use super::vertex::Vertex2D; - -#[derive(Component)] -pub struct Mesh2D { - pub vertices: Vec, -} - -impl Mesh2D { - pub fn new(vertices: Vec) -> Self { - Self { vertices } - } -} diff --git a/src/core/render/mod.rs b/src/core/render/mod.rs deleted file mode 100644 index 5d003a8..0000000 --- a/src/core/render/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod material; -pub mod mesh; -pub mod vertex; diff --git a/src/game/mod.rs b/src/game/mod.rs deleted file mode 100644 index e04b2a7..0000000 --- a/src/game/mod.rs +++ /dev/null @@ -1,36 +0,0 @@ -use bevy_app::App; -use engine_render::RenderPlugin; -use engine_vulkan::{VulkanConfig, VulkanPlugin}; -use engine_window::{WindowPlugin, config::WindowConfig}; -use vulkano::device::{DeviceExtensions, DeviceFeatures}; - -pub fn init(app: &mut App) { - let window_config = WindowConfig { - title: "Rust ASH Test".to_string(), - width: 800, - height: 600, - }; - - let device_extensions = DeviceExtensions { - khr_dynamic_rendering: true, - ..Default::default() - }; - - let device_features = DeviceFeatures { - dynamic_rendering: true, - ..Default::default() - }; - - let vulkan_config = VulkanConfig { - instance_layers: vec![String::from("VK_LAYER_KHRONOS_validation")], - device_extensions, - device_features, - ..Default::default() - }; - - app.add_plugins(( - WindowPlugin { window_config }, - VulkanPlugin { vulkan_config }, - RenderPlugin, - )); -} diff --git a/src/main.rs b/src/main.rs index 34fad4b..ca3f901 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,35 +1,14 @@ use winit::event_loop::{ControlFlow, EventLoop}; -use bevy_app::{App, AppExit}; - -pub mod core; -pub mod game; -pub mod old_app; - +mod render; fn main() { env_logger::init(); - run_new_app(); - // run_old_app(); -} - -fn run_new_app() { - let mut app = App::default(); - game::init(&mut app); - match app.run() { - AppExit::Success => {} - AppExit::Error(e) => { - log::error!("Error running new app: {e}"); - } - } -} - -fn run_old_app() { let event_loop = EventLoop::new().unwrap(); event_loop.set_control_flow(ControlFlow::Poll); - let vulkan_context = old_app::vulkan_context::VulkanContext::from(&event_loop); - let mut app = old_app::app::App::from(vulkan_context); + let vulkan_context = render::vulkan_context::VulkanContext::from(&event_loop); + let mut app = render::app::App::from(vulkan_context); match event_loop.run_app(&mut app) { Ok(_) => {} diff --git a/src/old_app/app.rs b/src/render/app.rs similarity index 97% rename from src/old_app/app.rs rename to src/render/app.rs index cfcf038..d46757e 100644 --- a/src/old_app/app.rs +++ b/src/render/app.rs @@ -1,6 +1,6 @@ -use crate::old_app::scene::Scene; -use crate::old_app::vulkan_context::VulkanContext; -use crate::old_app::window_render_context::WindowRenderContext; +use crate::render::scene::Scene; +use crate::render::vulkan_context::VulkanContext; +use crate::render::window_render_context::WindowRenderContext; use std::sync::Arc; use vulkano::command_buffer::{RenderingAttachmentInfo, RenderingInfo}; use vulkano::render_pass::{AttachmentLoadOp, AttachmentStoreOp}; diff --git a/src/old_app/mod.rs b/src/render/mod.rs similarity index 86% rename from src/old_app/mod.rs rename to src/render/mod.rs index 9fce0a9..c1bda07 100644 --- a/src/old_app/mod.rs +++ b/src/render/mod.rs @@ -3,3 +3,4 @@ pub mod pipelines; pub mod scene; pub mod vulkan_context; pub mod window_render_context; +pub mod vertex; diff --git a/src/old_app/pipelines/mod.rs b/src/render/pipelines/mod.rs similarity index 100% rename from src/old_app/pipelines/mod.rs rename to src/render/pipelines/mod.rs diff --git a/src/old_app/pipelines/triangle_pipeline.rs b/src/render/pipelines/triangle_pipeline.rs similarity index 98% rename from src/old_app/pipelines/triangle_pipeline.rs rename to src/render/pipelines/triangle_pipeline.rs index e573747..04aef22 100644 --- a/src/old_app/pipelines/triangle_pipeline.rs +++ b/src/render/pipelines/triangle_pipeline.rs @@ -20,7 +20,7 @@ use vulkano::pipeline::{ use vulkano::shader::{EntryPoint, ShaderStages}; use vulkano::swapchain::Swapchain; -use crate::core::render::vertex::Vertex2D; +use crate::render::vertex::Vertex2D; pub mod shaders { pub mod vs { diff --git a/src/old_app/scene.rs b/src/render/scene.rs similarity index 96% rename from src/old_app/scene.rs rename to src/render/scene.rs index 72e3f48..9dc7bf9 100644 --- a/src/old_app/scene.rs +++ b/src/render/scene.rs @@ -1,4 +1,4 @@ -use crate::old_app::pipelines::triangle_pipeline::shaders::vs; +use crate::render::pipelines::triangle_pipeline::shaders::vs; use glam::{Mat3, Mat4, Vec3}; use std::error::Error; use std::sync::Arc; @@ -9,8 +9,8 @@ use vulkano::descriptor_set::{DescriptorSet, WriteDescriptorSet}; use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter}; use vulkano::pipeline::{GraphicsPipeline, Pipeline, PipelineBindPoint}; -use crate::core::render::vertex::Vertex2D; -use crate::old_app::pipelines::triangle_pipeline::create_triangle_pipeline; +use crate::render::vertex::Vertex2D; +use crate::render::pipelines::triangle_pipeline::create_triangle_pipeline; use super::vulkan_context::VulkanContext; use super::window_render_context::WindowRenderContext; diff --git a/src/core/render/vertex.rs b/src/render/vertex.rs similarity index 100% rename from src/core/render/vertex.rs rename to src/render/vertex.rs diff --git a/src/old_app/vulkan_context.rs b/src/render/vulkan_context.rs similarity index 100% rename from src/old_app/vulkan_context.rs rename to src/render/vulkan_context.rs diff --git a/src/old_app/window_render_context.rs b/src/render/window_render_context.rs similarity index 100% rename from src/old_app/window_render_context.rs rename to src/render/window_render_context.rs