diff --git a/src/graphics/mod.rs b/src/graphics/mod.rs index 6d6998b..db86111 100644 --- a/src/graphics/mod.rs +++ b/src/graphics/mod.rs @@ -80,8 +80,8 @@ use vulkano::{ }; use wlx_capture::frame::{ - DmabufFrame, FourCC, DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888, + DmabufFrame, DrmFormat, FourCC, DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR8888, + DRM_FORMAT_ARGB8888, DRM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888, }; pub type Vert2Buf = Subbuffer<[Vert2Uv]>; @@ -127,6 +127,7 @@ pub struct WlxGraphics { pub quad_indices: IndexBuf, pub shared_shaders: RwLock>>, + pub drm_formats: Vec, } const fn get_dmabuf_extensions() -> DeviceExtensions { @@ -368,6 +369,7 @@ impl WlxGraphics { )); let (quad_verts, quad_indices) = Self::default_quad(memory_allocator.clone())?; + let drm_formats = Self::get_drm_formats(device.clone()); let me = Self { instance, @@ -381,6 +383,7 @@ impl WlxGraphics { quad_indices, quad_verts, shared_shaders: RwLock::new(HashMap::new()), + drm_formats, }; Ok(Arc::new(me)) @@ -522,6 +525,7 @@ impl WlxGraphics { )); let (quad_verts, quad_indices) = Self::default_quad(memory_allocator.clone())?; + let drm_formats = Self::get_drm_formats(device.clone()); let me = Self { instance, @@ -535,6 +539,7 @@ impl WlxGraphics { quad_indices, quad_verts, shared_shaders: RwLock::new(HashMap::new()), + drm_formats, }; Ok(Arc::new(me)) @@ -665,6 +670,7 @@ impl WlxGraphics { )); let (quad_verts, quad_indices) = Self::default_quad(memory_allocator.clone())?; + let drm_formats = Self::get_drm_formats(device.clone()); let me = Self { instance, @@ -678,6 +684,7 @@ impl WlxGraphics { quad_indices, quad_verts, shared_shaders: RwLock::new(HashMap::new()), + drm_formats, }; Ok((Arc::new(me), event_loop, window, surface)) @@ -796,7 +803,46 @@ impl WlxGraphics { )?) } - pub fn dmabuf_texture_ex( + fn get_drm_formats(device: Arc) -> Vec { + let possible_formats = [ + DRM_FORMAT_ABGR8888.into(), + DRM_FORMAT_XBGR8888.into(), + DRM_FORMAT_ARGB8888.into(), + DRM_FORMAT_XRGB8888.into(), + DRM_FORMAT_ABGR2101010.into(), + DRM_FORMAT_XBGR2101010.into(), + ]; + + let mut final_formats = vec![]; + + for &f in &possible_formats { + let Ok(vk_fmt) = fourcc_to_vk(f) else { + continue; + }; + let Ok(props) = device.physical_device().format_properties(vk_fmt) else { + continue; + }; + let mut fmt = DrmFormat { + fourcc: f, + modifiers: props + .drm_format_modifier_properties + .iter() + // important bit: only allow single-plane + .filter(|m| m.drm_format_modifier_plane_count == 1) + .map(|m| m.drm_format_modifier) + .collect(), + }; + fmt.modifiers.push(DRM_FORMAT_MOD_INVALID); // implicit modifiers support + final_formats.push(fmt); + } + log::debug!("Supported DRM formats:"); + for f in &final_formats { + log::debug!(" {} {:?}", f.fourcc, f.modifiers); + } + final_formats + } + + fn dmabuf_texture_ex( &self, frame: DmabufFrame, tiling: ImageTiling, @@ -806,21 +852,19 @@ impl WlxGraphics { let extent = [frame.format.width, frame.format.height, 1]; let format = fourcc_to_vk(frame.format.fourcc)?; - let image = unsafe { - RawImage::new_unchecked( - self.device.clone(), - ImageCreateInfo { - format, - extent, - usage: ImageUsage::SAMPLED, - external_memory_handle_types: ExternalMemoryHandleTypes::DMA_BUF, - tiling, - drm_format_modifiers: modifiers.to_owned(), - drm_format_modifier_plane_layouts: layouts, - ..Default::default() - }, - )? - }; + let image = RawImage::new( + self.device.clone(), + ImageCreateInfo { + format, + extent, + usage: ImageUsage::SAMPLED, + external_memory_handle_types: ExternalMemoryHandleTypes::DMA_BUF, + tiling, + drm_format_modifiers: modifiers.to_owned(), + drm_format_modifier_plane_layouts: layouts, + ..Default::default() + }, + )?; let requirements = image.memory_requirements()[0]; let memory_type_index = self diff --git a/src/overlays/screen.rs b/src/overlays/screen.rs index 5a9c62e..afa0651 100644 --- a/src/overlays/screen.rs +++ b/src/overlays/screen.rs @@ -72,8 +72,6 @@ pub(crate) type WlxClientAlias = (); const CURSOR_SIZE: f32 = 16. / 1440.; -static DRM_FORMATS: once_cell::sync::OnceCell> = once_cell::sync::OnceCell::new(); - static START: Lazy = Lazy::new(Instant::now); static NEXT_MOVE: AtomicU64 = AtomicU64::new(0); @@ -521,59 +519,20 @@ impl OverlayRenderer for ScreenRenderer { let capture_method = app.session.config.capture_method.clone(); - let dmabuf_formats = DRM_FORMATS.get_or_init({ - let graphics = app.graphics.clone(); - move || { - if !supports_dmabuf { - log::info!("Capture method does not support DMA-buf"); - return vec![]; - } - if !allow_dmabuf { - log::info!("Not using DMA-buf capture due to {capture_method}"); - return vec![]; - } - log::warn!("Using DMA-buf capture. If screens are blank for you, switch to SHM using:"); - log::warn!("echo 'capture_method: pw_fallback' > ~/.config/wlxoverlay/conf.d/pw_fallback.yaml"); + let dmabuf_formats = if !supports_dmabuf { + log::info!("Capture method does not support DMA-buf"); + &Vec::new() + } else if !allow_dmabuf { + log::info!("Not using DMA-buf capture due to {capture_method}"); + &Vec::new() + } else { + log::warn!( + "Using DMA-buf capture. If screens are blank for you, switch to SHM using:" + ); + log::warn!("echo 'capture_method: pw_fallback' > ~/.config/wlxoverlay/conf.d/pw_fallback.yaml"); - let possible_formats = [ - DRM_FORMAT_ABGR8888.into(), - DRM_FORMAT_XBGR8888.into(), - DRM_FORMAT_ARGB8888.into(), - DRM_FORMAT_XRGB8888.into(), - DRM_FORMAT_ABGR2101010.into(), - DRM_FORMAT_XBGR2101010.into(), - ]; - - let mut final_formats = vec![]; - - for &f in &possible_formats { - let Ok(vk_fmt) = fourcc_to_vk(f) else { - continue; - }; - let Ok(props) = graphics.device.physical_device().format_properties(vk_fmt) - else { - continue; - }; - let mut fmt = DrmFormat { - fourcc: f, - modifiers: props - .drm_format_modifier_properties - .iter() - // important bit: only allow single-plane - .filter(|m| m.drm_format_modifier_plane_count == 1) - .map(|m| m.drm_format_modifier) - .collect(), - }; - fmt.modifiers.push(DRM_FORMAT_MOD_INVALID); // implicit modifiers support - final_formats.push(fmt); - } - log::debug!("Supported DRM formats:"); - for f in &final_formats { - log::debug!(" {} {:?}", f.fourcc, f.modifiers); - } - final_formats - } - }); + &app.graphics.drm_formats + }; let user_data = WlxCaptureIn { name: self.name.clone(), diff --git a/src/overlays/wayvr.rs b/src/overlays/wayvr.rs index c5b1af8..5ed722e 100644 --- a/src/overlays/wayvr.rs +++ b/src/overlays/wayvr.rs @@ -623,20 +623,7 @@ impl WayVRRenderer { drop(wayvr); - let layouts: Vec = vec![SubresourceLayout { - offset: data.offset as _, - size: 0, - row_pitch: data.stride as _, - array_pitch: None, - depth_pitch: None, - }]; - - let tex = self.graphics.dmabuf_texture_ex( - frame, - vulkano::image::ImageTiling::DrmFormatModifier, - layouts, - &data.mod_info.modifiers, - )?; + let tex = self.graphics.dmabuf_texture(frame)?; self.vk_image = Some(tex.clone()); self.vk_image_view = Some(vulkano::image::view::ImageView::new_default(tex).unwrap());