From f855ca9820e85a06eac02fb4fa408e44193f6e2c Mon Sep 17 00:00:00 2001 From: Schmarni Date: Mon, 14 Jul 2025 18:20:51 +0200 Subject: [PATCH] feat(wayland): add vulkano infra Signed-off-by: Schmarni --- Cargo.lock | 226 +++++++++++++++++++++++++++++------- Cargo.toml | 6 + src/wayland/mod.rs | 6 + src/wayland/vulkano_data.rs | 142 ++++++++++++++++++++++ 4 files changed, 340 insertions(+), 40 deletions(-) create mode 100644 src/wayland/vulkano_data.rs diff --git a/Cargo.lock b/Cargo.lock index 26946cc..697f98f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,9 +48,9 @@ dependencies = [ "accesskit", "accesskit_consumer", "hashbrown 0.15.4", - "objc2", + "objc2 0.5.2", "objc2-app-kit", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -1692,7 +1692,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "objc2", + "objc2 0.5.2", ] [[package]] @@ -1861,7 +1861,7 @@ version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.104", @@ -2340,6 +2340,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.9.1", + "objc2 0.6.1", +] + [[package]] name = "disqualified" version = "1.0.0" @@ -3007,6 +3017,7 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ + "bytemuck", "cfg-if", "crunchy", ] @@ -3067,6 +3078,12 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "heck" version = "0.5.0" @@ -4013,7 +4030,7 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.3.0", "proc-macro2", "quote", "syn 2.0.104", @@ -4044,6 +4061,15 @@ dependencies = [ "objc2-encode", ] +[[package]] +name = "objc2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88c6597e14493ab2e44ce58f2fdecf095a51f12ca57bec060a11c57332520551" +dependencies = [ + "objc2-encode", +] + [[package]] name = "objc2-app-kit" version = "0.2.2" @@ -4053,11 +4079,11 @@ dependencies = [ "bitflags 2.9.1", "block2", "libc", - "objc2", + "objc2 0.5.2", "objc2-core-data", "objc2-core-image", - "objc2-foundation", - "objc2-quartz-core", + "objc2-foundation 0.2.2", + "objc2-quartz-core 0.2.2", ] [[package]] @@ -4068,9 +4094,9 @@ checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ "bitflags 2.9.1", "block2", - "objc2", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -4080,8 +4106,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -4092,8 +4118,19 @@ checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ "bitflags 2.9.1", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +dependencies = [ + "bitflags 2.9.1", + "dispatch2", + "objc2 0.6.1", ] [[package]] @@ -4103,9 +4140,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ "block2", - "objc2", - "objc2-foundation", - "objc2-metal", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal 0.2.2", ] [[package]] @@ -4115,9 +4152,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ "block2", - "objc2", + "objc2 0.5.2", "objc2-contacts", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -4136,7 +4173,18 @@ dependencies = [ "block2", "dispatch", "libc", - "objc2", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +dependencies = [ + "bitflags 2.9.1", + "objc2 0.6.1", + "objc2-core-foundation", ] [[package]] @@ -4146,9 +4194,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ "block2", - "objc2", + "objc2 0.5.2", "objc2-app-kit", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -4159,8 +4207,19 @@ checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ "bitflags 2.9.1", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-metal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f246c183239540aab1782457b35ab2040d4259175bd1d0c58e46ada7b47a874" +dependencies = [ + "bitflags 2.9.1", + "objc2 0.6.1", + "objc2-foundation 0.3.1", ] [[package]] @@ -4171,9 +4230,22 @@ checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ "bitflags 2.9.1", "block2", - "objc2", - "objc2-foundation", - "objc2-metal", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal 0.2.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ffb6a0cd5f182dc964334388560b12a57f7b74b3e2dec5e2722aa2dfb2ccd5" +dependencies = [ + "bitflags 2.9.1", + "objc2 0.6.1", + "objc2-core-foundation", + "objc2-foundation 0.3.1", + "objc2-metal 0.3.1", ] [[package]] @@ -4182,8 +4254,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" dependencies = [ - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -4194,14 +4266,14 @@ checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ "bitflags 2.9.1", "block2", - "objc2", + "objc2 0.5.2", "objc2-cloud-kit", "objc2-core-data", "objc2-core-image", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-link-presentation", - "objc2-quartz-core", + "objc2-quartz-core 0.2.2", "objc2-symbols", "objc2-uniform-type-identifiers", "objc2-user-notifications", @@ -4214,8 +4286,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -4226,9 +4298,9 @@ checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ "bitflags 2.9.1", "block2", - "objc2", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -4808,6 +4880,18 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +[[package]] +name = "raw-window-metal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" +dependencies = [ + "objc2 0.6.1", + "objc2-core-foundation", + "objc2-foundation 0.3.1", + "objc2-quartz-core 0.3.1", +] + [[package]] name = "read-fonts" version = "0.29.3" @@ -5201,6 +5285,12 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" +[[package]] +name = "slabbin" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9db491c0d4152a069911a0fbdaca959691bf0b9d7110d98a7ed1c8e59b79ab30" + [[package]] name = "slotmap" version = "1.0.7" @@ -5356,6 +5446,7 @@ dependencies = [ name = "stardust-xr-server" version = "0.45.0" dependencies = [ + "ash", "bevy", "bevy-dmabuf", "bevy-mesh-text-3d", @@ -5396,8 +5487,10 @@ dependencies = [ "tracing", "tracing-subscriber", "tracing-tracy", + "vulkano", "wayland-scanner", "waynest", + "wgpu-hal", "xkbcommon-rs", "zbus", ] @@ -5459,7 +5552,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", @@ -6179,6 +6272,59 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "vk-parse" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3859da4d7b98bec73e68fb65815d47a263819c415c90eed42b80440a02cbce8c" +dependencies = [ + "xml-rs", +] + +[[package]] +name = "vulkano" +version = "0.35.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08840c2b51759a6f88f26f5ea378bc8b5c199a5b4760ddda292304be087249c4" +dependencies = [ + "ash", + "bytemuck", + "crossbeam-queue", + "foldhash", + "half 2.6.0", + "heck 0.4.1", + "indexmap 2.10.0", + "libloading", + "nom", + "once_cell", + "parking_lot 0.12.4", + "proc-macro2", + "quote", + "raw-window-handle", + "raw-window-metal", + "serde", + "serde_json", + "slabbin", + "smallvec", + "thread_local", + "vk-parse", + "vulkano-macros", + "x11-dl", + "x11rb", +] + +[[package]] +name = "vulkano-macros" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dc929c42c9336fd082079ac3ea30126e4a0dfe36fd2e2b3581303f7d140d20f" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "walkdir" version = "2.5.0" @@ -6571,7 +6717,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -7094,9 +7240,9 @@ dependencies = [ "libc", "memmap2", "ndk 0.9.0", - "objc2", + "objc2 0.5.2", "objc2-app-kit", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-ui-kit", "orbclient", "percent-encoding", diff --git a/Cargo.toml b/Cargo.toml index 5aed0d2..4488ef9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,9 @@ wayland = [ "dep:memmap2", "dep:drm-fourcc", "dep:memfd", + "dep:vulkano", + "dep:wgpu-hal", + "dep:ash", ] profile_tokio = ["dep:console-subscriber", "tokio/tracing"] profile_app = ["dep:tracing-tracy", "bevy/trace_tracy", "bevy/trace"] @@ -139,6 +142,9 @@ tokio-stream = { version = "0.1.17", optional = true } memmap2 = { version = "0.9.5", optional = true } drm-fourcc = { version = "2.2.0", optional = true } memfd = { version = "0.6.4", optional = true } +vulkano = { version = "0.35.1", optional = true } +wgpu-hal = { version = "24", optional = true, features = ["vulkan"] } +ash = { version = "0.38.0", optional = true, default-features = false } [dependencies.stardust-xr] workspace = true diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs index ff7007e..6afbda7 100644 --- a/src/wayland/mod.rs +++ b/src/wayland/mod.rs @@ -1,6 +1,7 @@ pub mod core; pub mod dmabuf; pub mod util; +pub mod vulkano_data; pub mod xdg; use crate::PreFrameWait; @@ -39,6 +40,7 @@ use std::{ use tokio::{net::UnixStream, sync::mpsc, task::AbortHandle}; use tokio_stream::StreamExt; use tracing::{debug_span, instrument}; +use vulkano_data::setup_vulkano_context; use waynest::{ server::{ self, @@ -294,6 +296,10 @@ impl Plugin for WaylandPlugin { init_render_device.run_if(|| RENDER_DEVICE.get().is_none()), ); } + fn finish(&self, app: &mut App) { + app.sub_app_mut(RenderApp) + .add_systems(Render, setup_vulkano_context); + } } fn init_render_device(dev: Res) { diff --git a/src/wayland/vulkano_data.rs b/src/wayland/vulkano_data.rs new file mode 100644 index 0000000..d4de7f1 --- /dev/null +++ b/src/wayland/vulkano_data.rs @@ -0,0 +1,142 @@ +use std::sync::{Arc, OnceLock}; + +use bevy::{ + ecs::system::Res, + render::renderer::{RenderAdapter, RenderDevice, RenderInstance}, +}; +use vulkano::{ + VulkanLibrary, + command_buffer::allocator::{ + CommandBufferAllocator, StandardCommandBufferAllocator, + StandardCommandBufferAllocatorCreateInfo, + }, + device::{DeviceCreateInfo, QueueCreateInfo}, + instance::InstanceCreateFlags, + memory::allocator::{MemoryAllocator, StandardMemoryAllocator}, +}; +use wgpu_hal::vulkan::Api as VulkanHal; + +pub static VULKANO_CONTEXT: OnceLock = OnceLock::new(); + +#[expect(dead_code)] +pub struct VulkanoContext { + pub instance: Arc, + pub phys_dev: Arc, + pub dev: Arc, + pub queue: Arc, + pub alloc: Arc, + pub command_buffer_alloc: Arc, +} + +pub fn setup_vulkano_context( + dev: Res, + instance: Res, + adapter: Res, +) { + if VULKANO_CONTEXT.get().is_some() { + return; + } + let hal_instance = unsafe { instance.as_hal::() } + .unwrap() + .shared_instance(); + + let ash_instance = hal_instance.raw_instance(); + let vulkan_lib = + VulkanLibrary::with_loader(AshEntryVulkanoLoader(hal_instance.entry().clone())).unwrap(); + + let vulkano_instance = unsafe { + vulkano::instance::Instance::from_handle( + vulkan_lib, + ash_instance.handle(), + vulkano::instance::InstanceCreateInfo { + flags: InstanceCreateFlags::empty(), + max_api_version: Some(vulkano::Version::from(hal_instance.instance_api_version())), + enabled_extensions: vulkano::instance::InstanceExtensions::from_iter( + hal_instance + .extensions() + .iter() + .map(|s| s.to_str().unwrap()), + ), + ..Default::default() + }, + ) + }; + + let ash_phys_dev_handle = unsafe { + adapter.as_hal::(|adapter| adapter.unwrap().raw_physical_device()) + }; + + let vulkano_phys_dev = unsafe { + vulkano::device::physical::PhysicalDevice::from_handle( + vulkano_instance.clone(), + ash_phys_dev_handle, + ) + } + .unwrap(); + let (ash_dev_handle, dev_create_info) = unsafe { + dev.wgpu_device().as_hal::(|dev| { + let dev = dev.unwrap(); + ( + dev.raw_device().handle(), + DeviceCreateInfo { + queue_create_infos: vec![QueueCreateInfo { + queue_family_index: dev.queue_family_index(), + ..Default::default() + }], + enabled_extensions: dbg!(vulkano::device::DeviceExtensions::from_iter( + dev.enabled_device_extensions() + .iter() + // TODO: remove this hack by telling wgpu about the actual exts used in + // bevy_mod_openxr + .chain(bevy_dmabuf::required_device_extensions().iter()) + .map(|v| v.to_str().unwrap()), + )), + // this is def wrong, lets hope it doesn't cause issues.... + enabled_features: vulkano::device::DeviceFeatures::empty(), + ..Default::default() + }, + ) + }) + }; + let (vulkano_dev, mut queues) = unsafe { + vulkano::device::Device::from_handle( + vulkano_phys_dev.clone(), + ash_dev_handle, + dev_create_info, + ) + }; + + let alloc = Arc::new(StandardMemoryAllocator::new_default(vulkano_dev.clone())); + + let command_buffer_alloc = Arc::new(StandardCommandBufferAllocator::new( + vulkano_dev.clone(), + StandardCommandBufferAllocatorCreateInfo::default(), + )); + _ = VULKANO_CONTEXT.set(VulkanoContext { + instance: vulkano_instance, + phys_dev: vulkano_phys_dev, + dev: vulkano_dev, + queue: queues.next().unwrap(), + alloc, + command_buffer_alloc, + }); +} + +// ensures that we don't destroy the vulkan handles wgpu/bevy use +// TODO: remove once we don't use bevys wgpu instance/device/physical_device +impl Drop for VulkanoContext { + fn drop(&mut self) { + panic!("the vulkano context shall never be dropped"); + } +} + +struct AshEntryVulkanoLoader(ash::Entry); +unsafe impl vulkano::library::Loader for AshEntryVulkanoLoader { + unsafe fn get_instance_proc_addr( + &self, + instance: ash::vk::Instance, + name: *const std::os::raw::c_char, + ) -> ash::vk::PFN_vkVoidFunction { + unsafe { self.0.get_instance_proc_addr(instance, name) } + } +}