From cd3cf3721a672da055a4d85b140f6d3a9596af88 Mon Sep 17 00:00:00 2001 From: Schmarni Date: Sun, 27 Jul 2025 02:02:47 +0200 Subject: [PATCH] refactor(waylan): WIP, use a basic bevy image for shm again Signed-off-by: Schmarni --- src/wayland/core/buffer.rs | 2 +- src/wayland/core/shm_buffer_backing.rs | 242 +++---------------------- src/wayland/core/surface.rs | 5 +- src/wayland/dmabuf/buffer_backing.rs | 19 +- 4 files changed, 36 insertions(+), 232 deletions(-) diff --git a/src/wayland/core/buffer.rs b/src/wayland/core/buffer.rs index 00f9476..214d718 100644 --- a/src/wayland/core/buffer.rs +++ b/src/wayland/core/buffer.rs @@ -62,7 +62,7 @@ impl Buffer { ) -> Option> { tracing::debug!("Updating texture for buffer {:?}", self.id); match &self.backing { - BufferBacking::Shm(backing) => backing.update_tex(dmatexes, images), + BufferBacking::Shm(backing) => backing.update_tex(images), BufferBacking::Dmabuf(backing) => backing.update_tex(dmatexes, images), } } diff --git a/src/wayland/core/shm_buffer_backing.rs b/src/wayland/core/shm_buffer_backing.rs index e9b7b21..f86523d 100644 --- a/src/wayland/core/shm_buffer_backing.rs +++ b/src/wayland/core/shm_buffer_backing.rs @@ -1,155 +1,20 @@ use super::shm_pool::ShmPool; -use crate::wayland::{ - RENDER_DEVICE, - vulkano_data::{VULKANO_CONTEXT, VulkanoContext}, -}; use bevy::{ - asset::{Assets, Handle}, - image::Image as BevyImage, -}; -use bevy_dmabuf::{ - dmatex::{Dmatex, DmatexPlane, Resolution}, - format_mapping::vk_format_to_drm_fourcc, - import::{DropCallback, ImportedDmatexs, ImportedTexture, import_texture}, + asset::{Assets, Handle, RenderAssetUsages}, + image::Image, + render::render_resource::{Extent3d, TextureDimension, TextureFormat}, }; use mint::Vector2; -use parking_lot::Mutex; -use std::{ - os::fd::OwnedFd, - sync::{Arc, OnceLock}, -}; -use tracing::debug_span; -use vulkano::{ - ValidationError, - buffer::{BufferCreateFlags, BufferCreateInfo, BufferUsage}, - command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, CopyBufferToImageInfo}, - image::{ - Image, ImageAspect, ImageCreateFlags, ImageCreateInfo, ImageLayout, ImageMemory, - ImageTiling, ImageUsage, sys::RawImage, - }, - memory::{ - DedicatedAllocation, DeviceMemory, ExternalMemoryHandleType, ExternalMemoryHandleTypes, - MemoryAllocateInfo, ResourceMemory, allocator::AllocationCreateInfo, - }, - sync::{self, GpuFuture, Sharing}, -}; +use std::sync::Arc; use waynest::server::protocol::core::wayland::wl_shm::Format; - -fn create_vk_dmatex( - vulkano_context: &VulkanoContext, - size: Vector2, -) -> Result<(Arc, Dmatex), Box> { - let vk_format = vulkano::format::Format::R8G8B8A8_UNORM; - - let modifiers = vulkano_context - .phys_dev - .format_properties(vk_format)? - .drm_format_modifier_properties - .into_iter() - .map(|v| v.drm_format_modifier) - .collect::>(); - - let raw_image = RawImage::new( - vulkano_context.dev.clone(), - ImageCreateInfo { - flags: ImageCreateFlags::empty(), - image_type: vulkano::image::ImageType::Dim2d, - format: vk_format, - view_formats: Vec::new(), - extent: [size.x as u32, size.y as u32, 1], - tiling: ImageTiling::DrmFormatModifier, - usage: ImageUsage::COLOR_ATTACHMENT | ImageUsage::SAMPLED | ImageUsage::TRANSFER_DST, - initial_layout: ImageLayout::Undefined, - drm_format_modifiers: modifiers, - external_memory_handle_types: ExternalMemoryHandleTypes::DMA_BUF, - ..Default::default() - }, - ) - .unwrap(); - let (modifier, num_planes) = raw_image.drm_format_modifier().unwrap(); - let mem_reqs = raw_image.memory_requirements()[0]; - let index = vulkano_context - .phys_dev - .memory_properties() - .memory_types - .iter() - .enumerate() - .map(|(i, _v)| i as u32) - .find(|i| mem_reqs.memory_type_bits & (1 << i) != 0) - .expect("no valid memory type"); - let mem = ResourceMemory::new_dedicated( - DeviceMemory::allocate( - vulkano_context.dev.clone(), - MemoryAllocateInfo { - allocation_size: mem_reqs.layout.size(), - memory_type_index: index, - dedicated_allocation: Some(DedicatedAllocation::Image(&raw_image)), - export_handle_types: ExternalMemoryHandleTypes::DMA_BUF, - ..Default::default() - }, - ) - .unwrap(), - ); - - let image = Arc::new(match raw_image.bind_memory([mem]) { - Ok(v) => v, - Err(_) => panic!("unable to bind memory"), - }); - let ImageMemory::Normal(mem) = image.memory() else { - unreachable!() - }; - let [mem] = mem.as_slice() else { - unreachable!() - }; - let fd = OwnedFd::from( - mem.device_memory() - .export_fd(ExternalMemoryHandleType::DmaBuf) - .unwrap(), - ); - let planes = (0..num_planes) - .filter_map(|i| { - Some(match i { - 0 => ImageAspect::MemoryPlane0, - 1 => ImageAspect::MemoryPlane1, - 2 => ImageAspect::MemoryPlane2, - 3 => ImageAspect::MemoryPlane3, - _ => return None, - }) - }) - .map(|aspect| { - let plane_layout = image.subresource_layout(aspect, 0, 0).unwrap(); - - DmatexPlane { - dmabuf_fd: fd.try_clone().unwrap().into(), - modifier, - offset: plane_layout.offset as u32, - stride: plane_layout.row_pitch as i32, - } - }) - .collect::>(); - let dmatex = Dmatex { - planes, - res: Resolution { - x: size.x as u32, - y: size.y as u32, - }, - format: vk_format_to_drm_fourcc(vk_format.into()).unwrap() as u32, - flip_y: false, - srgb: true, - }; - Ok((image, dmatex)) -} - /// Parameters for a shared memory buffer +#[derive(Debug)] pub struct ShmBufferBacking { pool: Arc, offset: usize, stride: usize, size: Vector2, format: Format, - image: Arc, - image_handle: OnceLock>, - pending_imported_dmatex: Mutex>, } impl ShmBufferBacking { @@ -160,39 +25,17 @@ impl ShmBufferBacking { size: Vector2, format: Format, ) -> Self { - // TODO: this might cause a freeze? - let vulkano_context = VULKANO_CONTEXT.wait(); - let bevy_render_dev = RENDER_DEVICE.wait(); - let (image, dmatex) = create_vk_dmatex(vulkano_context, size).unwrap(); - - let imported_texture = import_texture(bevy_render_dev, dmatex, DropCallback(None)).unwrap(); - Self { pool, offset, stride, size, format, - image, - image_handle: OnceLock::new(), - pending_imported_dmatex: Mutex::new(Some(imported_texture)), } } #[tracing::instrument("debug", skip_all)] - pub fn update_tex( - &self, - dmatexes: &ImportedDmatexs, - images: &mut Assets, - ) -> Option> { - if let Some(tex) = self.pending_imported_dmatex.lock().take() { - self.image_handle - .set(dmatexes.insert_imported_dmatex(images, tex)) - .unwrap(); - } - let vk = VULKANO_CONTEXT.wait(); - let image_handle = self.image_handle.get().unwrap(); - + pub fn update_tex(&self, images: &mut Assets) -> Option> { let src_data_lock = self.pool.data_lock(); let mut src_cursor = self.offset; @@ -203,26 +46,13 @@ impl ShmBufferBacking { if max_cursor > src_data_lock.len() { return None; } - let data_len = (self.size.x * self.size.y * 4) as u64; + let data_len = self.size.x * self.size.y * 4; + if src_data_lock.len() != data_len { + return None; + } let mut dst_cursor = 0; - let buffer = vulkano::buffer::Buffer::new_slice::( - vk.alloc.clone(), - BufferCreateInfo { - flags: BufferCreateFlags::empty(), - sharing: Sharing::Exclusive, - usage: BufferUsage::TRANSFER_SRC, - ..Default::default() - }, - AllocationCreateInfo { - memory_type_filter: - vulkano::memory::allocator::MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, - ..Default::default() - }, - data_len, - ) - .unwrap(); - let mut dst_data = buffer.write().unwrap(); + let mut dst_data = vec![0u8; data_len]; for _y in 0..self.size.y { for _x in 0..self.size.x { match self.format { @@ -239,32 +69,20 @@ impl ShmBufferBacking { } src_cursor += self.stride - (self.size.x * 4); } - drop(dst_data); - let mut command_buffer = AutoCommandBufferBuilder::primary( - vk.command_buffer_alloc.clone(), - vk.queue.queue_family_index(), - CommandBufferUsage::OneTimeSubmit, - ) - .unwrap(); - command_buffer - .copy_buffer_to_image(CopyBufferToImageInfo::buffer_image( - buffer.clone(), - self.image.clone(), - )) - .unwrap(); - let command_buffer = command_buffer.build().unwrap(); - debug_span!("waiting for buffer copy").in_scope(|| { - sync::now(vk.dev.clone()) - .then_execute(vk.queue.clone(), command_buffer) - .unwrap() - .then_signal_fence_and_flush() - .unwrap() - .wait(None) - .unwrap() - }); + let image = Image::new( + Extent3d { + width: self.size().x as u32, + height: self.size().y as u32, + depth_or_array_layers: 1, + }, + TextureDimension::D2, + dst_data, + TextureFormat::Rgba8UnormSrgb, + RenderAssetUsages::RENDER_WORLD, + ); - Some(image_handle.clone()) + Some(images.add(image)) } pub fn is_transparent(&self) -> bool { @@ -279,17 +97,3 @@ impl ShmBufferBacking { self.size } } - -impl std::fmt::Debug for ShmBufferBacking { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("ShmBufferBacking") - .field("pool", &self.pool) - .field("offset", &self.offset) - .field("stride", &self.stride) - .field("size", &self.size) - .field("format", &self.format) - .field("image", &self.image) - .field("image_handle", &self.image_handle) - .finish() - } -} diff --git a/src/wayland/core/surface.rs b/src/wayland/core/surface.rs index 20e3eb1..fbfe511 100644 --- a/src/wayland/core/surface.rs +++ b/src/wayland/core/surface.rs @@ -231,10 +231,9 @@ impl WlSurface for Surface { ) -> Result<()> { self.state.lock().pending.buffer = buffer.and_then(|b| { let buffer = client.get::(b)?; + let mut usage = Some(BufferUsage::new(client, &buffer)); Some(BufferState { - usage: buffer - .uses_buffer_usage() - .then(|| BufferUsage::new(client, &buffer)), + usage: usage.take_if(|_| buffer.uses_buffer_usage()), buffer, }) }); diff --git a/src/wayland/dmabuf/buffer_backing.rs b/src/wayland/dmabuf/buffer_backing.rs index c09ae20..9944f44 100644 --- a/src/wayland/dmabuf/buffer_backing.rs +++ b/src/wayland/dmabuf/buffer_backing.rs @@ -23,7 +23,7 @@ pub struct DmabufBacking { format: DrmFourcc, _flags: Flags, tex: OnceLock>, - pending_imported_dmatex: Mutex>, + // pending_imported_dmatex: Mutex>, } impl std::fmt::Debug for DmabufBacking { @@ -73,7 +73,7 @@ impl DmabufBacking { format, _flags: flags, tex: OnceLock::new(), - pending_imported_dmatex: Mutex::new(Some(imported_tex)), + // pending_imported_dmatex: Mutex::new(Some(imported_tex)), }) } @@ -84,13 +84,14 @@ impl DmabufBacking { images: &mut Assets, ) -> Option> { info!("updating dmabuf tex"); - self.pending_imported_dmatex - .lock() - .take() - .map(|tex| dmatexes.insert_imported_dmatex(images, tex)) - .inspect(|handle| { - _ = self.tex.set(handle.clone()); - }) + // self.pending_imported_dmatex + // .lock() + // .take() + // .map(|tex| dmatexes.insert_imported_dmatex(images, tex)) + // .inspect(|handle| { + // _ = self.tex.set(handle.clone()); + // }) + None } pub fn is_transparent(&self) -> bool {