dmabuf tweaks
This commit is contained in:
@@ -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!(
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
Reference in New Issue
Block a user