dmabuf tweaks

This commit is contained in:
galister
2024-01-31 11:52:58 +01:00
parent 9f0856998a
commit 0822f25927
2 changed files with 56 additions and 74 deletions

View File

@@ -8,7 +8,7 @@ use std::{
}; };
use ash::vk::{self, SubmitInfo}; use ash::vk::{self, SubmitInfo};
use smallvec::{smallvec, SmallVec}; use smallvec::smallvec;
use vulkano::instance::InstanceCreateFlags; use vulkano::instance::InstanceCreateFlags;
use vulkano::{ use vulkano::{
buffer::{ buffer::{
@@ -531,30 +531,32 @@ impl WlxGraphics {
}) })
.collect(); .collect();
let external_memory_handle_types = ExternalMemoryHandleTypes::DMA_BUF; let image = unsafe {
RawImage::new_unchecked(
let image = RawImage::new(
self.device.clone(), self.device.clone(),
ImageCreateInfo { ImageCreateInfo {
image_type: ImageType::Dim2d,
format, format,
extent, extent,
usage: ImageUsage::SAMPLED | ImageUsage::TRANSFER_SRC, usage: ImageUsage::SAMPLED,
external_memory_handle_types, external_memory_handle_types: ExternalMemoryHandleTypes::DMA_BUF,
tiling: ImageTiling::DrmFormatModifier, tiling: ImageTiling::DrmFormatModifier,
drm_format_modifiers: vec![frame.format.modifier], drm_format_modifiers: vec![frame.format.modifier],
drm_format_modifier_plane_layouts: layouts, drm_format_modifier_plane_layouts: layouts,
..Default::default() ..Default::default()
}, },
) )
.unwrap(); .unwrap()
};
let requirements = image.memory_requirements()[0]; let requirements = image.memory_requirements()[0];
let memory_type_index = self let memory_type_index = self
.memory_allocator .memory_allocator
.find_memory_type_index( .find_memory_type_index(
requirements.memory_type_bits, requirements.memory_type_bits,
MemoryTypeFilter::PREFER_DEVICE, MemoryTypeFilter {
required_flags: MemoryPropertyFlags::DEVICE_LOCAL,
..Default::default()
},
) )
.unwrap(); .unwrap();
@@ -562,8 +564,7 @@ impl WlxGraphics {
debug_assert!(self.device.enabled_extensions().khr_external_memory); debug_assert!(self.device.enabled_extensions().khr_external_memory);
debug_assert!(self.device.enabled_extensions().ext_external_memory_dma_buf); debug_assert!(self.device.enabled_extensions().ext_external_memory_dma_buf);
let mut allocations: SmallVec<[ResourceMemory; 4]> = smallvec![]; // only do the 1st
unsafe { unsafe {
let Some(fd) = frame.planes[0].fd else { let Some(fd) = frame.planes[0].fd else {
log::error!("DMA-buf plane has no FD"); log::error!("DMA-buf plane has no FD");
@@ -574,7 +575,7 @@ impl WlxGraphics {
let new_file = file.try_clone().unwrap(); let new_file = file.try_clone().unwrap();
file.into_raw_fd(); file.into_raw_fd();
let memory = DeviceMemory::import( let memory = DeviceMemory::allocate_unchecked(
self.device.clone(), self.device.clone(),
MemoryAllocateInfo { MemoryAllocateInfo {
allocation_size: requirements.layout.size(), allocation_size: requirements.layout.size(),
@@ -582,24 +583,23 @@ impl WlxGraphics {
dedicated_allocation: Some(DedicatedAllocation::Image(&image)), dedicated_allocation: Some(DedicatedAllocation::Image(&image)),
..Default::default() ..Default::default()
}, },
MemoryImportInfo::Fd { Some(MemoryImportInfo::Fd {
file: new_file, file: new_file,
handle_type: ExternalMemoryHandleType::DmaBuf, handle_type: ExternalMemoryHandleType::DmaBuf,
}, }),
) )
.unwrap(); .unwrap();
allocations.push(ResourceMemory::new_dedicated(memory)); let mem_alloc = ResourceMemory::new_dedicated(memory);
} match image.bind_memory_unchecked([mem_alloc]) {
match unsafe { image.bind_memory(allocations) } {
Ok(image) => Some(Arc::new(image)), Ok(image) => Some(Arc::new(image)),
Err(e) => { Err(e) => {
log::warn!("Failed to bind memory to image: {}", e.0.to_string()); log::error!("Failed to bind memory to image: {}", e.0);
return None; return None;
} }
} }
} }
}
pub fn render_texture(&self, width: u32, height: u32, format: Format) -> Arc<Image> { pub fn render_texture(&self, width: u32, height: u32, format: Format) -> Arc<Image> {
log::debug!( log::debug!(

View File

@@ -11,18 +11,15 @@ use std::{
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use vulkano::{ use vulkano::{
buffer::Subbuffer,
command_buffer::CommandBufferUsage, command_buffer::CommandBufferUsage,
format::Format, format::Format,
image::{sampler::Filter, view::ImageView, Image, ImageLayout}, image::{sampler::Filter, view::ImageView, Image, ImageLayout},
sync::GpuFuture,
Handle, VulkanObject,
}; };
use wlx_capture::{ use wlx_capture::{
frame::WlxFrame, frame::WlxFrame,
pipewire::{pipewire_select_screen, PipewireCapture}, pipewire::{pipewire_select_screen, PipewireCapture},
wayland::{Transform, WlxClient, WlxOutput}, wayland::{wayland_client::protocol::wl_output::Transform, WlxClient, WlxOutput},
wlr::WlrDmabufCapture, wlr_dmabuf::WlrDmabufCapture,
WlxCapture, WlxCapture,
}; };
@@ -35,7 +32,7 @@ use crate::{
}, },
config::def_pw_tokens, config::def_pw_tokens,
config_io, config_io,
graphics::{fourcc_to_vk, Vert2Uv, WlxGraphics, WlxPipeline}, graphics::{fourcc_to_vk, WlxGraphics, WlxPipeline},
hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT}, hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT},
state::{AppSession, AppState}, state::{AppSession, AppState},
}; };
@@ -113,16 +110,10 @@ impl InteractionHandler for ScreenInteractionHandler {
struct ScreenPipeline { struct ScreenPipeline {
graphics: Arc<WlxGraphics>, graphics: Arc<WlxGraphics>,
pipeline: Arc<WlxPipeline>, pipeline: Arc<WlxPipeline>,
vertex_buffer: Subbuffer<[Vert2Uv]>,
} }
impl ScreenPipeline { impl ScreenPipeline {
fn new(graphics: Arc<WlxGraphics>, image: &Image, extent: &[u32; 3]) -> Self { fn new(graphics: Arc<WlxGraphics>, 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 _);
let render_texture = graphics.render_texture(extent[0], extent[1], Format::R8G8B8A8_UNORM); let render_texture = graphics.render_texture(extent[0], extent[1], Format::R8G8B8A8_UNORM);
let view = ImageView::new_default(render_texture).unwrap(); let view = ImageView::new_default(render_texture).unwrap();
@@ -130,36 +121,30 @@ impl ScreenPipeline {
let pipeline = { let pipeline = {
let shaders = graphics.shared_shaders.read().unwrap(); let shaders = graphics.shared_shaders.read().unwrap();
graphics.create_pipeline( graphics.create_pipeline_with_layouts(
view, view,
shaders.get("vert_common").unwrap().clone(), shaders.get("vert_common").unwrap().clone(),
shaders.get("frag_sprite").unwrap().clone(), shaders.get("frag_sprite").unwrap().clone(),
Format::R8G8B8A8_UNORM, Format::R8G8B8A8_UNORM,
// ImageLayout::TransferSrcOptimal, ImageLayout::TransferSrcOptimal,
// ImageLayout::TransferSrcOptimal, ImageLayout::TransferSrcOptimal,
) )
}; };
Self { Self { graphics, pipeline }
graphics,
pipeline,
vertex_buffer,
}
} }
fn render(&mut self, image: Arc<Image>) { fn render(&mut self, image: Arc<Image>) {
if image.handle().as_raw() == self.pipeline.view.image().handle().as_raw() { /*
return;
}
self.graphics self.graphics
.transition_layout( .transition_layout(
self.pipeline.view.image().clone(), self.pipeline.view.image().clone(),
ImageLayout::TransferSrcOptimal, ImageLayout::TransferSrcOptimal,
ImageLayout::General, ImageLayout::ColorAttachmentOptimal,
) )
.wait(None) .wait(None)
.unwrap(); .unwrap();
*/
let mut command_buffer = self let mut command_buffer = self
.graphics .graphics
@@ -173,31 +158,27 @@ impl ScreenPipeline {
); );
let dim = self.pipeline.view.image().extent(); let dim = self.pipeline.view.image().extent();
let dim = [dim[0] as f32, dim[1] as f32];
let pass = self.pipeline.create_pass( let pass = self.pipeline.create_pass(
dim, [dim[0] as _, dim[1] as _],
self.vertex_buffer.clone(), self.graphics.quad_verts.clone(),
self.graphics.quad_indices.clone(), self.graphics.quad_indices.clone(),
vec![set0], vec![set0],
); );
command_buffer.run_ref(&pass); command_buffer.run_ref(&pass);
command_buffer.end_render_pass(); command_buffer.end_render_pass();
command_buffer.build_and_execute_now();
{ /*
let mut exec = command_buffer.build_and_execute();
exec.flush().unwrap();
exec.cleanup_finished();
}
self.graphics self.graphics
.transition_layout( .transition_layout(
self.pipeline.view.image().clone(), self.pipeline.view.image().clone(),
ImageLayout::General, ImageLayout::ColorAttachmentOptimal,
ImageLayout::TransferSrcOptimal, ImageLayout::TransferSrcOptimal,
) )
.wait(None) .wait(None)
.unwrap(); .unwrap();
*/
} }
pub(super) fn view(&self) -> Arc<ImageView> { pub(super) fn view(&self) -> Arc<ImageView> {
@@ -256,6 +237,7 @@ impl OverlayRenderer for ScreenRenderer {
fn init(&mut self, app: &mut AppState) { fn init(&mut self, app: &mut AppState) {
let images = app.graphics.shared_images.read().unwrap(); let images = app.graphics.shared_images.read().unwrap();
self.last_image = Some(images.get("fallback").unwrap().clone()); 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) { fn render(&mut self, app: &mut AppState) {
let receiver = self.receiver.get_or_insert_with(|| self.capture.init()); let receiver = self.receiver.get_or_insert_with(|| self.capture.init());
@@ -267,11 +249,11 @@ impl OverlayRenderer for ScreenRenderer {
log::error!("Invalid frame"); log::error!("Invalid frame");
continue; continue;
} }
if let Some(new) = app.graphics.dmabuf_texture(frame) { if let (Some(new), Some(pipeline)) =
let pipeline = self.pipeline.get_or_insert_with(|| { (app.graphics.dmabuf_texture(frame), self.pipeline.as_mut())
ScreenPipeline::new(app.graphics.clone(), &new, &self.extent) {
});
log::debug!("{}: New DMA-buf frame", self.name); log::debug!("{}: New DMA-buf frame", self.name);
pipeline.render(new); pipeline.render(new);
self.last_image = Some(pipeline.view()); self.last_image = Some(pipeline.view());
} }
@@ -371,7 +353,7 @@ where
if session.capture_method == "auto" && wl.maybe_wlr_dmabuf_mgr.is_some() { if session.capture_method == "auto" && wl.maybe_wlr_dmabuf_mgr.is_some() {
log::info!("{}: Using Wlr DMA-Buf", &output.name); log::info!("{}: Using Wlr DMA-Buf", &output.name);
//capture = ScreenRenderer::new_wlr(output); capture = ScreenRenderer::new_wlr(output);
} }
if capture.is_none() { if capture.is_none() {