diff --git a/src/graphics.rs b/src/graphics.rs index 30b8c68..227b4bc 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -8,7 +8,7 @@ use std::{ }; use ash::vk::{self, SubmitInfo}; -use smallvec::{smallvec, SmallVec}; +use smallvec::smallvec; use vulkano::instance::InstanceCreateFlags; use vulkano::{ buffer::{ @@ -531,30 +531,32 @@ impl WlxGraphics { }) .collect(); - let external_memory_handle_types = ExternalMemoryHandleTypes::DMA_BUF; - - let image = RawImage::new( - self.device.clone(), - ImageCreateInfo { - image_type: ImageType::Dim2d, - format, - extent, - usage: ImageUsage::SAMPLED | ImageUsage::TRANSFER_SRC, - external_memory_handle_types, - tiling: ImageTiling::DrmFormatModifier, - drm_format_modifiers: vec![frame.format.modifier], - drm_format_modifier_plane_layouts: layouts, - ..Default::default() - }, - ) - .unwrap(); + let image = unsafe { + RawImage::new_unchecked( + self.device.clone(), + ImageCreateInfo { + format, + extent, + usage: ImageUsage::SAMPLED, + external_memory_handle_types: ExternalMemoryHandleTypes::DMA_BUF, + tiling: ImageTiling::DrmFormatModifier, + drm_format_modifiers: vec![frame.format.modifier], + drm_format_modifier_plane_layouts: layouts, + ..Default::default() + }, + ) + .unwrap() + }; let requirements = image.memory_requirements()[0]; let memory_type_index = self .memory_allocator .find_memory_type_index( requirements.memory_type_bits, - MemoryTypeFilter::PREFER_DEVICE, + MemoryTypeFilter { + required_flags: MemoryPropertyFlags::DEVICE_LOCAL, + ..Default::default() + }, ) .unwrap(); @@ -562,8 +564,7 @@ impl WlxGraphics { debug_assert!(self.device.enabled_extensions().khr_external_memory); debug_assert!(self.device.enabled_extensions().ext_external_memory_dma_buf); - let mut allocations: SmallVec<[ResourceMemory; 4]> = smallvec![]; - + // only do the 1st unsafe { let Some(fd) = frame.planes[0].fd else { log::error!("DMA-buf plane has no FD"); @@ -574,7 +575,7 @@ impl WlxGraphics { let new_file = file.try_clone().unwrap(); file.into_raw_fd(); - let memory = DeviceMemory::import( + let memory = DeviceMemory::allocate_unchecked( self.device.clone(), MemoryAllocateInfo { allocation_size: requirements.layout.size(), @@ -582,21 +583,20 @@ impl WlxGraphics { dedicated_allocation: Some(DedicatedAllocation::Image(&image)), ..Default::default() }, - MemoryImportInfo::Fd { + Some(MemoryImportInfo::Fd { file: new_file, handle_type: ExternalMemoryHandleType::DmaBuf, - }, + }), ) .unwrap(); - allocations.push(ResourceMemory::new_dedicated(memory)); - } - - match unsafe { image.bind_memory(allocations) } { - Ok(image) => Some(Arc::new(image)), - Err(e) => { - log::warn!("Failed to bind memory to image: {}", e.0.to_string()); - return None; + let mem_alloc = ResourceMemory::new_dedicated(memory); + match image.bind_memory_unchecked([mem_alloc]) { + Ok(image) => Some(Arc::new(image)), + Err(e) => { + log::error!("Failed to bind memory to image: {}", e.0); + return None; + } } } } diff --git a/src/overlays/screen.rs b/src/overlays/screen.rs index fe3f8a3..3a788c1 100644 --- a/src/overlays/screen.rs +++ b/src/overlays/screen.rs @@ -11,18 +11,15 @@ use std::{ time::{Duration, Instant}, }; use vulkano::{ - buffer::Subbuffer, command_buffer::CommandBufferUsage, format::Format, image::{sampler::Filter, view::ImageView, Image, ImageLayout}, - sync::GpuFuture, - Handle, VulkanObject, }; use wlx_capture::{ frame::WlxFrame, pipewire::{pipewire_select_screen, PipewireCapture}, - wayland::{Transform, WlxClient, WlxOutput}, - wlr::WlrDmabufCapture, + wayland::{wayland_client::protocol::wl_output::Transform, WlxClient, WlxOutput}, + wlr_dmabuf::WlrDmabufCapture, WlxCapture, }; @@ -35,7 +32,7 @@ use crate::{ }, config::def_pw_tokens, config_io, - graphics::{fourcc_to_vk, Vert2Uv, WlxGraphics, WlxPipeline}, + graphics::{fourcc_to_vk, WlxGraphics, WlxPipeline}, hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT}, state::{AppSession, AppState}, }; @@ -113,16 +110,10 @@ impl InteractionHandler for ScreenInteractionHandler { struct ScreenPipeline { graphics: Arc, pipeline: Arc, - vertex_buffer: Subbuffer<[Vert2Uv]>, } impl ScreenPipeline { - fn new(graphics: Arc, image: &Image, extent: &[u32; 3]) -> Self { - let dim = image.extent(); - - let vertex_buffer = - graphics.upload_verts(dim[0] as _, dim[1] as _, 0.0, 0.0, dim[0] as _, dim[1] as _); - + fn new(graphics: Arc, extent: &[u32; 3]) -> Self { let render_texture = graphics.render_texture(extent[0], extent[1], Format::R8G8B8A8_UNORM); let view = ImageView::new_default(render_texture).unwrap(); @@ -130,36 +121,30 @@ impl ScreenPipeline { let pipeline = { let shaders = graphics.shared_shaders.read().unwrap(); - graphics.create_pipeline( + graphics.create_pipeline_with_layouts( view, shaders.get("vert_common").unwrap().clone(), shaders.get("frag_sprite").unwrap().clone(), Format::R8G8B8A8_UNORM, - // ImageLayout::TransferSrcOptimal, - // ImageLayout::TransferSrcOptimal, + ImageLayout::TransferSrcOptimal, + ImageLayout::TransferSrcOptimal, ) }; - Self { - graphics, - pipeline, - vertex_buffer, - } + Self { graphics, pipeline } } fn render(&mut self, image: Arc) { - if image.handle().as_raw() == self.pipeline.view.image().handle().as_raw() { - return; - } - + /* self.graphics .transition_layout( self.pipeline.view.image().clone(), ImageLayout::TransferSrcOptimal, - ImageLayout::General, + ImageLayout::ColorAttachmentOptimal, ) .wait(None) .unwrap(); + */ let mut command_buffer = self .graphics @@ -173,31 +158,27 @@ impl ScreenPipeline { ); let dim = self.pipeline.view.image().extent(); - let dim = [dim[0] as f32, dim[1] as f32]; let pass = self.pipeline.create_pass( - dim, - self.vertex_buffer.clone(), + [dim[0] as _, dim[1] as _], + self.graphics.quad_verts.clone(), self.graphics.quad_indices.clone(), vec![set0], ); + command_buffer.run_ref(&pass); command_buffer.end_render_pass(); - - { - let mut exec = command_buffer.build_and_execute(); - exec.flush().unwrap(); - exec.cleanup_finished(); - } - + command_buffer.build_and_execute_now(); + /* self.graphics .transition_layout( self.pipeline.view.image().clone(), - ImageLayout::General, + ImageLayout::ColorAttachmentOptimal, ImageLayout::TransferSrcOptimal, ) .wait(None) .unwrap(); + */ } pub(super) fn view(&self) -> Arc { @@ -256,6 +237,7 @@ impl OverlayRenderer for ScreenRenderer { fn init(&mut self, app: &mut AppState) { let images = app.graphics.shared_images.read().unwrap(); self.last_image = Some(images.get("fallback").unwrap().clone()); + self.pipeline = Some(ScreenPipeline::new(app.graphics.clone(), &self.extent)); } fn render(&mut self, app: &mut AppState) { let receiver = self.receiver.get_or_insert_with(|| self.capture.init()); @@ -267,11 +249,11 @@ impl OverlayRenderer for ScreenRenderer { log::error!("Invalid frame"); continue; } - if let Some(new) = app.graphics.dmabuf_texture(frame) { - let pipeline = self.pipeline.get_or_insert_with(|| { - ScreenPipeline::new(app.graphics.clone(), &new, &self.extent) - }); + if let (Some(new), Some(pipeline)) = + (app.graphics.dmabuf_texture(frame), self.pipeline.as_mut()) + { log::debug!("{}: New DMA-buf frame", self.name); + pipeline.render(new); self.last_image = Some(pipeline.view()); } @@ -371,7 +353,7 @@ where if session.capture_method == "auto" && wl.maybe_wlr_dmabuf_mgr.is_some() { log::info!("{}: Using Wlr DMA-Buf", &output.name); - //capture = ScreenRenderer::new_wlr(output); + capture = ScreenRenderer::new_wlr(output); } if capture.is_none() {