feat(wayland): add vulkano infra
Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
@@ -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<RenderDevice>) {
|
||||
|
||||
142
src/wayland/vulkano_data.rs
Normal file
142
src/wayland/vulkano_data.rs
Normal file
@@ -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<VulkanoContext> = OnceLock::new();
|
||||
|
||||
#[expect(dead_code)]
|
||||
pub struct VulkanoContext {
|
||||
pub instance: Arc<vulkano::instance::Instance>,
|
||||
pub phys_dev: Arc<vulkano::device::physical::PhysicalDevice>,
|
||||
pub dev: Arc<vulkano::device::Device>,
|
||||
pub queue: Arc<vulkano::device::Queue>,
|
||||
pub alloc: Arc<dyn MemoryAllocator>,
|
||||
pub command_buffer_alloc: Arc<dyn CommandBufferAllocator>,
|
||||
}
|
||||
|
||||
pub fn setup_vulkano_context(
|
||||
dev: Res<RenderDevice>,
|
||||
instance: Res<RenderInstance>,
|
||||
adapter: Res<RenderAdapter>,
|
||||
) {
|
||||
if VULKANO_CONTEXT.get().is_some() {
|
||||
return;
|
||||
}
|
||||
let hal_instance = unsafe { instance.as_hal::<VulkanHal>() }
|
||||
.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::<VulkanHal, _, _>(|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::<VulkanHal, _, _>(|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) }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user