1
0
Fork 0
forked from wry/wry

vulkan: perform a queue transfer for external dmabuf buffers

This commit is contained in:
Julian Orth 2025-10-01 19:21:45 +02:00
parent 0fb318f5f7
commit 3e52e4266f
2 changed files with 57 additions and 41 deletions

View file

@ -22,11 +22,11 @@ use {
CopyImageToBufferInfo2, DependencyInfoKHR, DeviceSize, Extent3D, ImageAspectFlags, CopyImageToBufferInfo2, DependencyInfoKHR, DeviceSize, Extent3D, ImageAspectFlags,
ImageCreateInfo, ImageLayout, ImageSubresourceLayers, ImageSubresourceRange, ImageTiling, ImageCreateInfo, ImageLayout, ImageSubresourceLayers, ImageSubresourceRange, ImageTiling,
ImageType, ImageUsageFlags, ImageViewCreateInfo, ImageViewType, Offset3D, ImageType, ImageUsageFlags, ImageViewCreateInfo, ImageViewType, Offset3D,
PipelineStageFlags2, SampleCountFlags, SharingMode, SubmitInfo2, PipelineStageFlags2, QUEUE_FAMILY_FOREIGN_EXT, SampleCountFlags, SharingMode, SubmitInfo2,
}, },
gpu_alloc::UsageFlags, gpu_alloc::UsageFlags,
isnt::std_1::primitive::IsntSliceExt, isnt::std_1::primitive::IsntSliceExt,
std::{cell::Cell, ptr, rc::Rc, slice}, std::{cell::Cell, mem, ptr, rc::Rc, slice},
}; };
pub struct VulkanShmImage { pub struct VulkanShmImage {
@ -143,6 +143,7 @@ impl VulkanShmImage {
cpy, cpy,
false, false,
TransferType::Upload, TransferType::Upload,
false,
)?; )?;
let future = img.renderer.eng.spawn( let future = img.renderer.eng.spawn(
"await upload", "await upload",
@ -160,6 +161,7 @@ impl VulkanShmImage {
regions: &[BufferImageCopy2], regions: &[BufferImageCopy2],
use_transfer_queue: bool, use_transfer_queue: bool,
tt: TransferType, tt: TransferType,
foreign_buffer: bool,
) -> Result< ) -> Result<
( (
Rc<VulkanCommandBuffer>, Rc<VulkanCommandBuffer>,
@ -169,22 +171,50 @@ impl VulkanShmImage {
), ),
VulkanError, VulkanError,
> { > {
let memory_barrier = |sam, ssm, dam, dsm| {
BufferMemoryBarrier2::default()
.buffer(buffer)
.offset(0)
.size(size)
.src_access_mask(sam)
.src_stage_mask(ssm)
.dst_access_mask(dam)
.dst_stage_mask(dsm)
};
let mut transfer_queue_family_idx = img.renderer.device.graphics_queue_idx; let mut transfer_queue_family_idx = img.renderer.device.graphics_queue_idx;
if use_transfer_queue if use_transfer_queue
&& let Some(idx) = img.renderer.device.distinct_transfer_queue_family_idx && let Some(idx) = img.renderer.device.distinct_transfer_queue_family_idx
{ {
transfer_queue_family_idx = idx; transfer_queue_family_idx = idx;
} }
let memory_barrier = |release| {
let mut sq;
let mut sam;
let mut ssm;
if foreign_buffer {
sq = QUEUE_FAMILY_FOREIGN_EXT;
sam = AccessFlags2::NONE;
ssm = PipelineStageFlags2::NONE;
} else {
sq = transfer_queue_family_idx;
sam = match tt {
TransferType::Upload => AccessFlags2::HOST_WRITE,
TransferType::Download => AccessFlags2::HOST_READ,
};
ssm = PipelineStageFlags2::HOST;
}
let mut dq = transfer_queue_family_idx;
let mut dam = match tt {
TransferType::Upload => AccessFlags2::TRANSFER_READ,
TransferType::Download => AccessFlags2::TRANSFER_WRITE,
};
let mut dsm = PipelineStageFlags2::TRANSFER;
if release {
mem::swap(&mut sq, &mut dq);
mem::swap(&mut sam, &mut dam);
mem::swap(&mut ssm, &mut dsm);
}
BufferMemoryBarrier2::default()
.buffer(buffer)
.offset(0)
.size(size)
.src_queue_family_index(sq)
.src_access_mask(sam)
.src_stage_mask(ssm)
.dst_queue_family_index(dq)
.dst_access_mask(dam)
.dst_stage_mask(dsm)
};
let mut initial_image_barrier = image_barrier() let mut initial_image_barrier = image_barrier()
.image(img.image) .image(img.image)
.src_queue_family_index(img.renderer.device.graphics_queue_idx) .src_queue_family_index(img.renderer.device.graphics_queue_idx)
@ -208,18 +238,7 @@ impl VulkanShmImage {
.src_access_mask(AccessFlags2::SHADER_SAMPLED_READ) .src_access_mask(AccessFlags2::SHADER_SAMPLED_READ)
.src_stage_mask(PipelineStageFlags2::FRAGMENT_SHADER) .src_stage_mask(PipelineStageFlags2::FRAGMENT_SHADER)
} }
let initial_buffer_barrier = memory_barrier( let initial_buffer_barrier = memory_barrier(false);
match tt {
TransferType::Upload => AccessFlags2::HOST_WRITE,
TransferType::Download => AccessFlags2::HOST_READ,
},
PipelineStageFlags2::HOST,
match tt {
TransferType::Upload => AccessFlags2::TRANSFER_READ,
TransferType::Download => AccessFlags2::TRANSFER_WRITE,
},
PipelineStageFlags2::TRANSFER,
);
let initial_dep_info = DependencyInfoKHR::default() let initial_dep_info = DependencyInfoKHR::default()
.buffer_memory_barriers(slice::from_ref(&initial_buffer_barrier)) .buffer_memory_barriers(slice::from_ref(&initial_buffer_barrier))
.image_memory_barriers(slice::from_ref(&initial_image_barrier)); .image_memory_barriers(slice::from_ref(&initial_image_barrier));
@ -248,18 +267,7 @@ impl VulkanShmImage {
}) })
.dst_stage_mask(PipelineStageFlags2::FRAGMENT_SHADER); .dst_stage_mask(PipelineStageFlags2::FRAGMENT_SHADER);
} }
let final_buffer_barrier = memory_barrier( let final_buffer_barrier = memory_barrier(true);
match tt {
TransferType::Upload => AccessFlags2::TRANSFER_READ,
TransferType::Download => AccessFlags2::TRANSFER_WRITE,
},
PipelineStageFlags2::TRANSFER,
match tt {
TransferType::Upload => AccessFlags2::HOST_WRITE,
TransferType::Download => AccessFlags2::HOST_READ,
},
PipelineStageFlags2::HOST,
);
let final_dep_info = DependencyInfoKHR::default() let final_dep_info = DependencyInfoKHR::default()
.buffer_memory_barriers(slice::from_ref(&final_buffer_barrier)) .buffer_memory_barriers(slice::from_ref(&final_buffer_barrier))
.image_memory_barriers(slice::from_ref(&final_image_barrier)); .image_memory_barriers(slice::from_ref(&final_image_barrier));

View file

@ -520,19 +520,26 @@ impl VulkanShmImage {
} }
img.renderer.check_defunct()?; img.renderer.check_defunct()?;
let regions = &*data.regions.borrow(); let regions = &*data.regions.borrow();
let (buffer, size) = match data.staging.get() { let (buffer, size, foreign_buffer) = match data.staging.get() {
Some(s) => { Some(s) => {
let staging = s.staging.get().unwrap(); let staging = s.staging.get().unwrap();
staging.upload(|_, _| ())?; staging.upload(|_, _| ())?;
(staging.buffer, staging.size) (staging.buffer, staging.size, false)
} }
_ => { _ => {
let host_buffer = data.buffer.get().unwrap(); let host_buffer = data.buffer.get().unwrap();
(host_buffer.buffer, host_buffer.size) (host_buffer.buffer, host_buffer.size, true)
} }
}; };
let (cmd, fence, sync_file, point) = let (cmd, fence, sync_file, point) = self.submit_buffer_image_copy(
self.submit_buffer_image_copy(img, buffer, size, regions, true, TransferType::Upload)?; img,
buffer,
size,
regions,
true,
TransferType::Upload,
foreign_buffer,
)?;
img.queue_state.set(QueueState::Releasing); img.queue_state.set(QueueState::Releasing);
let future = img.renderer.eng.spawn( let future = img.renderer.eng.spawn(
"await async upload", "await async upload",
@ -566,6 +573,7 @@ impl VulkanShmImage {
copies, copies,
true, true,
TransferType::Download, TransferType::Download,
false,
)?; )?;
img.queue_state.set(QueueState::Releasing); img.queue_state.set(QueueState::Releasing);
let future = img.renderer.eng.spawn( let future = img.renderer.eng.spawn(