diff options
| -rw-r--r-- | Cargo.lock | 124 | ||||
| -rw-r--r-- | Cargo.toml | 6 | ||||
| -rw-r--r-- | flake.nix | 8 | ||||
| -rw-r--r-- | src/main.rs | 120 |
4 files changed, 228 insertions, 30 deletions
diff --git a/Cargo.lock b/Cargo.lock index db44fe4..f370fb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,6 +93,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] name = "block2" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -170,6 +176,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] +name = "cocoa" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad36507aeb7e16159dfe68db81ccc27571c3ccd4b76fb2fb72fc59e7a4b1b64c" +dependencies = [ + "bitflags 2.13.0", + "block", + "cocoa-foundation", + "core-foundation 0.10.1", + "core-graphics 0.24.0", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81411967c50ee9a1fc11365f8c585f863a22a9697c89239c452292c40ba79b0d" +dependencies = [ + "bitflags 2.13.0", + "block", + "core-foundation 0.10.1", + "core-graphics-types 0.2.0", + "objc", +] + +[[package]] name = "combine" version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -199,6 +234,16 @@ dependencies = [ ] [[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -211,8 +256,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", - "core-foundation", - "core-graphics-types", + "core-foundation 0.9.4", + "core-graphics-types 0.1.3", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" +dependencies = [ + "bitflags 2.13.0", + "core-foundation 0.10.1", + "core-graphics-types 0.2.0", "foreign-types", "libc", ] @@ -224,7 +282,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +dependencies = [ + "bitflags 2.13.0", + "core-foundation 0.10.1", "libc", ] @@ -510,6 +579,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[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.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -525,6 +603,21 @@ dependencies = [ ] [[package]] +name = "metal" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" +dependencies = [ + "bitflags 2.13.0", + "block", + "core-graphics-types 0.2.0", + "foreign-types", + "log", + "objc", + "paste", +] + +[[package]] name = "ndk" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -577,6 +670,15 @@ dependencies = [ ] [[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" @@ -805,6 +907,12 @@ dependencies = [ ] [[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] name = "percent-encoding" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1110,6 +1218,7 @@ checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" name = "surreality" version = "0.1.0" dependencies = [ + "libloading", "vulkanalia", "winit", ] @@ -1266,6 +1375,11 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebd71d6c64383bbdf1c260efa22e81e1a2a7dd832a3831af34495f47d7551d7b" dependencies = [ + "cocoa", + "libloading", + "metal", + "objc", + "raw-window-handle", "vulkanalia-sys", ] @@ -1602,8 +1716,8 @@ dependencies = [ "calloop", "cfg_aliases", "concurrent-queue", - "core-foundation", - "core-graphics", + "core-foundation 0.9.4", + "core-graphics 0.23.2", "cursor-icon", "dpi", "js-sys", diff --git a/Cargo.toml b/Cargo.toml index 81e881e..26435be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,8 +5,12 @@ authors = ["Irene Knapp <ireneista@irenes.space>"] edition = "2024" [dependencies] -vulkanalia = "0.35.0" +libloading = "0.8.9" winit = "0.30.13" + +[dependencies.vulkanalia] +version = "0.35.0" +features = [ "libloading", "window" ] #anyhow = "1" #log = "0.4" #cgmath = "0.18" diff --git a/flake.nix b/flake.nix index 4e03888..5a6b93f 100644 --- a/flake.nix +++ b/flake.nix @@ -27,7 +27,7 @@ libxkbcommon # mesa # wayland - # vulkan-loader + vulkan-loader ]; in { packages = forAllSystems (system: let pkgs = nixpkgsFor.${system}; in { @@ -39,7 +39,9 @@ nativeBuildInputs = with pkgs; [ autoPatchelfHook ]; }).overrideAttrs { preFixup = '' - patchelf --add-needed libxkbcommon-x11.so $out/bin/surreality + patchelf --add-needed libxkbcommon-x11.so \ + --add-needed libvulkan.so.1 \ + $out/bin/surreality ''; }; }); @@ -54,7 +56,7 @@ # This makes cargo run work; mind that you don't let it mask a # problem with the nix build. - LD_LIBRARY_PATH = "${pkgs.libxkbcommon}/lib"; + LD_LIBRARY_PATH = "${pkgs.libxkbcommon}/lib:${pkgs.vulkan-loader}/lib"; }; }); }; diff --git a/src/main.rs b/src/main.rs index 2ebdd28..4fcb01c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,10 @@ -#![forbid(unsafe_code)] -// use vulkanalia::vk::{ DeviceV1_4, EntryV1_4, InstanceV1_4 }; +#![deny(unsafe_code)] +use std::cell::OnceCell; +use vulkanalia::{ Entry, Instance }; +use vulkanalia::loader::{ LibloadingLoader, LIBRARY }; +use vulkanalia::vk::{ self, HasBuilder, + ApplicationInfo, InstanceCreateInfo, + DeviceV1_4, EntryV1_4, InstanceV1_4 }; use winit::dpi::LogicalSize; use winit::application::ApplicationHandler; use winit::event::WindowEvent; @@ -56,20 +61,95 @@ impl From<winit::error::OsError> for Error { } } +impl From<libloading::Error> for Error { + fn from(e: libloading::Error) -> Self { + Error { + message: format!("The dynamic object loader reported an error: {}", + e.to_string()) + } + } +} + +impl From<Box<dyn vulkanalia::loader::LoaderError>> for Error { + fn from(e: Box<dyn vulkanalia::loader::LoaderError>) -> Self { + Error { + message: format!("The Vulkan loader reported an error: {}", + e.to_string()) + } + } +} + +impl From<vulkanalia::vk::ErrorCode> for Error { + fn from(e: vulkanalia::vk::ErrorCode) -> Self { + Error { + message: format!("Vulkan gave an error code: {}", e.to_string()) + } + } +} + +fn ignore_errors(mut body: impl FnMut() -> Result<()>) -> () { + if let Err(e) = body() { + eprintln!("Error: {}", e); + } +} + struct Surreality { - window: Window + entry: OnceCell<Entry>, + instance: OnceCell<Instance>, + window: OnceCell<Window>, } impl Surreality { - fn new(window: Window) -> Result<Self> { - Ok(Surreality { - window - }) + fn new() -> Self { + Surreality { + entry: OnceCell::new(), + instance: OnceCell::new(), + window: OnceCell::new(), + } + } + + fn init_if_needed(&mut self, event_loop: &ActiveEventLoop) -> Result<()> { + if self.window.get().is_none() { + let window_attributes = WindowAttributes::default() + .with_title("Love, Curiosity, Justice") + .with_inner_size(LogicalSize::new(1024, 768)); + let window: Window = event_loop.create_window(window_attributes)?; + let _ = self.window.set(window); + + #[allow(unsafe_code)] + let loader = unsafe { LibloadingLoader::new(LIBRARY)? }; + #[allow(unsafe_code)] + let entry = unsafe { Entry::new(loader)? }; + + let application_info = ApplicationInfo::builder() + .application_name(b"Surreality\0") + .application_version(vk::make_version(1, 0, 0)) + .engine_name(b"Surreality\0") + .engine_version(vk::make_version(1, 0, 0)) + .api_version(vk::make_version(1, 0, 0)); + + let extensions = vulkanalia::window::get_required_instance_extensions( + self.window.get().unwrap()) + .iter().map(|item| item.as_ptr()).collect::<Vec<_>>(); + + let instance_create_info = InstanceCreateInfo::builder() + .application_info(&application_info) + .enabled_extension_names(&extensions); + + #[allow(unsafe_code)] + let instance = unsafe { + entry.create_instance(&instance_create_info, None)? + }; + } + + Ok(()) } fn render(&mut self, window_id: WindowId) -> Result<()> { - if window_id == self.window.id() { + if let Some(window) = self.window.get() + && window_id == window.id() + { println!("render the window"); } else { println!("render something unknown"); @@ -81,7 +161,12 @@ impl Surreality { impl ApplicationHandler for Surreality { fn resumed(&mut self, event_loop: &ActiveEventLoop) { - println!("resumed"); + ignore_errors(move || { + println!("resumed"); + self.init_if_needed(event_loop)?; + + Ok(()) + }); } fn window_event(&mut self, event_loop: &ActiveEventLoop, @@ -92,7 +177,9 @@ impl ApplicationHandler for Surreality { match event { WindowEvent::RedrawRequested => { if !event_loop.exiting() { - self.render(window_id).unwrap(); // TODO + if let Err(e) = self.render(window_id) { + eprintln!("Error: {}", e); + } } } WindowEvent::CloseRequested => { @@ -105,22 +192,13 @@ impl ApplicationHandler for Surreality { fn main() -> std::process::ExitCode { - let body: fn() -> Result<()> = || { + let body: fn() -> Result<()> = || { let event_loop = EventLoop::new()?; - - let window_attributes = WindowAttributes::default() - .with_title("Love, Curiosity, Justice") - .with_inner_size(LogicalSize::new(1024, 768)); - let window = event_loop.create_window(window_attributes)?; - - let mut surreality = Surreality::new(window)?; - + let mut surreality = Surreality::new(); event_loop.run_app(&mut surreality)?; - Ok(()) }; - println!("Hello!"); match body() { Ok(()) => std::process::ExitCode::SUCCESS, Err(e) => { |