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,
ImageCreateInfo, ImageLayout, ImageSubresourceLayers, ImageSubresourceRange, ImageTiling,
ImageType, ImageUsageFlags, ImageViewCreateInfo, ImageViewType, Offset3D,
PipelineStageFlags2, SampleCountFlags, SharingMode, SubmitInfo2,
PipelineStageFlags2, QUEUE_FAMILY_FOREIGN_EXT, SampleCountFlags, SharingMode, SubmitInfo2,
},
gpu_alloc::UsageFlags,
isnt::std_1::primitive::IsntSliceExt,
std::{cell::Cell, ptr, rc::Rc, slice},
std::{cell::Cell, mem, ptr, rc::Rc, slice},
};
pub struct VulkanShmImage {
@ -143,6 +143,7 @@ impl VulkanShmImage {
cpy,
false,
TransferType::Upload,
false,
)?;
let future = img.renderer.eng.spawn(
"await upload",
@ -160,6 +161,7 @@ impl VulkanShmImage {
regions: &[BufferImageCopy2],
use_transfer_queue: bool,
tt: TransferType,
foreign_buffer: bool,
) -> Result<
(
Rc<VulkanCommandBuffer>,
@ -169,22 +171,50 @@ impl VulkanShmImage {
),
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;
if use_transfer_queue
&& let Some(idx) = img.renderer.device.distinct_transfer_queue_family_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()
.image(img.image)
.src_queue_family_index(img.renderer.device.graphics_queue_idx)
@ -208,18 +238,7 @@ impl VulkanShmImage {
.src_access_mask(AccessFlags2::SHADER_SAMPLED_READ)
.src_stage_mask(PipelineStageFlags2::FRAGMENT_SHADER)
}
let initial_buffer_barrier = memory_barrier(
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_buffer_barrier = memory_barrier(false);
let initial_dep_info = DependencyInfoKHR::default()
.buffer_memory_barriers(slice::from_ref(&initial_buffer_barrier))
.image_memory_barriers(slice::from_ref(&initial_image_barrier));
@ -248,18 +267,7 @@ impl VulkanShmImage {
})
.dst_stage_mask(PipelineStageFlags2::FRAGMENT_SHADER);
}
let final_buffer_barrier = memory_barrier(
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_buffer_barrier = memory_barrier(true);
let final_dep_info = DependencyInfoKHR::default()
.buffer_memory_barriers(slice::from_ref(&final_buffer_barrier))
.image_memory_barriers(slice::from_ref(&final_image_barrier));

View file

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