1
0
Fork 0
forked from wry/wry

Merge pull request #195 from mahkoh/jorth/vulkan-linear

Add support for hardware cursors on nvidia + vulkan
This commit is contained in:
mahkoh 2024-05-05 12:47:38 +02:00 committed by GitHub
commit 5ce9d38c59
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 314 additions and 82 deletions

View file

@ -8,6 +8,7 @@
- Add support for pointer-gestures-unstable-v1.
- Configs can now handle switch events (laptop lid closed/opened).
- Add support for tablet-v2.
- Add support for linear framebuffers (hardware cursors/screensharing) on NVIDIA if the Vulkan renderer is used. (The OpenGL renderer does not support this.)
# 1.1.0 (2024-04-22)

View file

@ -2,7 +2,7 @@ use {
crate::{
format::{Format, FORMATS},
gfx_apis::vulkan::{instance::VulkanInstance, VulkanError},
video::Modifier,
video::{Modifier, LINEAR_MODIFIER},
},
ahash::AHashMap,
ash::{
@ -17,14 +17,14 @@ use {
},
},
isnt::std_1::collections::IsntHashMapExt,
std::cmp::min,
};
#[derive(Debug)]
pub struct VulkanFormat {
pub format: &'static Format,
pub modifiers: AHashMap<Modifier, VulkanModifier>,
pub shm: Option<VulkanShmFormat>,
pub features: FormatFeatureFlags,
pub shm: Option<VulkanInternalFormat>,
}
#[derive(Debug)]
@ -34,6 +34,7 @@ pub struct VulkanModifier {
pub features: FormatFeatureFlags,
pub render_max_extents: Option<VulkanMaxExtents>,
pub texture_max_extents: Option<VulkanMaxExtents>,
pub render_needs_bridge: bool,
}
#[derive(Copy, Clone, Debug)]
@ -43,7 +44,7 @@ pub struct VulkanMaxExtents {
}
#[derive(Debug)]
pub struct VulkanShmFormat {
pub struct VulkanInternalFormat {
pub max_extents: VulkanMaxExtents,
}
@ -51,6 +52,7 @@ const FRAMEBUFFER_FEATURES: FormatFeatureFlags = FormatFeatureFlags::from_raw(
0 | FormatFeatureFlags::COLOR_ATTACHMENT.as_raw()
| FormatFeatureFlags::COLOR_ATTACHMENT_BLEND.as_raw(),
);
const FRAMEBUFFER_BRIDGED_FEATURES: FormatFeatureFlags = FormatFeatureFlags::TRANSFER_DST;
const TEX_FEATURES: FormatFeatureFlags = FormatFeatureFlags::from_raw(
0 | FormatFeatureFlags::SAMPLED_IMAGE.as_raw()
| FormatFeatureFlags::TRANSFER_SRC.as_raw()
@ -65,6 +67,7 @@ const SHM_FEATURES: FormatFeatureFlags = FormatFeatureFlags::from_raw(
const FRAMEBUFFER_USAGE: ImageUsageFlags = ImageUsageFlags::from_raw(
0 | ImageUsageFlags::COLOR_ATTACHMENT.as_raw() | ImageUsageFlags::TRANSFER_SRC.as_raw(),
);
const FRAMEBUFFER_BRIDGED_USAGE: ImageUsageFlags = ImageUsageFlags::TRANSFER_DST;
const TEX_USAGE: ImageUsageFlags = ImageUsageFlags::from_raw(
0 | ImageUsageFlags::SAMPLED.as_raw() | ImageUsageFlags::TRANSFER_SRC.as_raw(),
);
@ -104,7 +107,8 @@ impl VulkanInstance {
);
}
let shm = self.load_shm_format(phy_dev, format, &format_properties)?;
let modifiers = self.load_drm_format(phy_dev, format, &modifier_props)?;
let modifiers =
self.load_drm_format(phy_dev, format, &format_properties, &modifier_props)?;
if shm.is_some() || modifiers.is_not_empty() {
dst.insert(
format.drm,
@ -112,7 +116,6 @@ impl VulkanInstance {
format,
modifiers,
shm,
features: format_properties.format_properties.optimal_tiling_features,
},
);
}
@ -124,14 +127,25 @@ impl VulkanInstance {
phy_dev: PhysicalDevice,
format: &Format,
props: &FormatProperties2,
) -> Result<Option<VulkanShmFormat>, VulkanError> {
) -> Result<Option<VulkanInternalFormat>, VulkanError> {
if format.shm_info.is_none() {
return Ok(None);
}
self.load_internal_format(phy_dev, format, props, SHM_FEATURES, SHM_USAGE)
}
fn load_internal_format(
&self,
phy_dev: PhysicalDevice,
format: &Format,
props: &FormatProperties2,
features: FormatFeatureFlags,
usage: ImageUsageFlags,
) -> Result<Option<VulkanInternalFormat>, VulkanError> {
if !props
.format_properties
.optimal_tiling_features
.contains(SHM_FEATURES)
.contains(features)
{
return Ok(None);
}
@ -139,7 +153,7 @@ impl VulkanInstance {
.ty(ImageType::TYPE_2D)
.format(format.vk_format)
.tiling(ImageTiling::OPTIMAL)
.usage(SHM_USAGE);
.usage(usage);
let mut format_properties = ImageFormatProperties2::builder();
let res = unsafe {
self.instance.get_physical_device_image_format_properties2(
@ -154,7 +168,7 @@ impl VulkanInstance {
_ => Err(VulkanError::LoadImageProperties(e)),
};
}
Ok(Some(VulkanShmFormat {
Ok(Some(VulkanInternalFormat {
max_extents: VulkanMaxExtents {
width: format_properties.image_format_properties.max_extent.width,
height: format_properties.image_format_properties.max_extent.height,
@ -166,6 +180,7 @@ impl VulkanInstance {
&self,
phy_dev: PhysicalDevice,
format: &Format,
internal_format_properties: &FormatProperties2,
props: &DrmFormatModifierPropertiesListEXT,
) -> Result<AHashMap<Modifier, VulkanModifier>, VulkanError> {
if props.drm_format_modifier_count == 0 {
@ -190,7 +205,7 @@ impl VulkanInstance {
};
let mut mods = AHashMap::new();
for modifier in drm_mods {
let render_max_extents = self.get_max_extents(
let mut render_max_extents = self.get_max_extents(
phy_dev,
format,
FRAMEBUFFER_FEATURES,
@ -199,6 +214,18 @@ impl VulkanInstance {
)?;
let texture_max_extents =
self.get_max_extents(phy_dev, format, TEX_FEATURES, TEX_USAGE, &modifier)?;
let mut render_needs_bridge = false;
if render_max_extents.is_none() && modifier.drm_format_modifier == LINEAR_MODIFIER {
render_max_extents = self.get_fb_bridged_max_extents(
phy_dev,
format,
internal_format_properties,
&modifier,
)?;
if render_max_extents.is_some() {
render_needs_bridge = true;
}
}
mods.insert(
modifier.drm_format_modifier,
VulkanModifier {
@ -207,12 +234,52 @@ impl VulkanInstance {
features: modifier.drm_format_modifier_tiling_features,
render_max_extents,
texture_max_extents,
render_needs_bridge,
},
);
}
Ok(mods)
}
fn get_fb_bridged_max_extents(
&self,
phy_dev: PhysicalDevice,
format: &Format,
internal_format_properties: &FormatProperties2,
modifier: &DrmFormatModifierPropertiesEXT,
) -> Result<Option<VulkanMaxExtents>, VulkanError> {
let transfer_dst_max_extents = self.get_max_extents(
phy_dev,
format,
FRAMEBUFFER_BRIDGED_FEATURES,
FRAMEBUFFER_BRIDGED_USAGE,
&modifier,
)?;
let Some(transfer_dst_max_extents) = transfer_dst_max_extents else {
return Ok(None);
};
let bridge_format = self.load_internal_format(
phy_dev,
format,
internal_format_properties,
FRAMEBUFFER_FEATURES,
FRAMEBUFFER_USAGE,
)?;
let Some(bridge_format) = bridge_format else {
return Ok(None);
};
Ok(Some(VulkanMaxExtents {
width: min(
transfer_dst_max_extents.width,
bridge_format.max_extents.width,
),
height: min(
transfer_dst_max_extents.height,
bridge_format.max_extents.height,
),
}))
}
fn get_max_extents(
&self,
phy_dev: PhysicalDevice,

View file

@ -39,6 +39,7 @@ pub struct VulkanDmaBufImageTemplate {
pub(super) dmabuf: DmaBuf,
pub(super) render_max_extents: Option<VulkanMaxExtents>,
pub(super) texture_max_extents: Option<VulkanMaxExtents>,
pub(super) render_needs_bridge: bool,
}
pub struct VulkanImage {
@ -53,6 +54,7 @@ pub struct VulkanImage {
pub(super) is_undefined: Cell<bool>,
pub(super) ty: VulkanImageMemory,
pub(super) render_ops: CloneCell<Vec<GfxApiOpt>>,
pub(super) bridge: Option<VulkanFramebufferBridge>,
}
pub enum VulkanImageMemory {
@ -72,6 +74,11 @@ pub struct VulkanShmImage {
pub(super) _allocation: VulkanAllocation,
}
pub struct VulkanFramebufferBridge {
pub(super) dmabuf_image: Image,
pub(super) _allocation: VulkanAllocation,
}
impl Drop for VulkanDmaBufImage {
fn drop(&mut self) {
unsafe {
@ -96,6 +103,12 @@ impl Drop for VulkanImage {
.destroy_image_view(render_view, None);
}
self.renderer.device.device.destroy_image(self.image, None);
if let Some(bridge) = &self.bridge {
self.renderer
.device
.device
.destroy_image(bridge.dmabuf_image, None);
}
}
}
}
@ -214,6 +227,7 @@ impl VulkanRenderer {
is_undefined: Cell::new(true),
ty: VulkanImageMemory::Internal(shm),
render_ops: Default::default(),
bridge: None,
}))
}
@ -264,6 +278,7 @@ impl VulkanRenderer {
dmabuf: dmabuf.clone(),
render_max_extents: modifier.render_max_extents,
texture_max_extents: modifier.texture_max_extents,
render_needs_bridge: modifier.render_needs_bridge,
}))
}
}
@ -302,21 +317,14 @@ impl VulkanDevice {
impl VulkanDmaBufImageTemplate {
pub fn create_framebuffer(self: &Rc<Self>) -> Result<Rc<VulkanImage>, VulkanError> {
self.create_image(true, None)
self.create_image(true)
}
pub fn create_texture(
self: &Rc<Self>,
shm: Option<VulkanShmImage>,
) -> Result<Rc<VulkanImage>, VulkanError> {
self.create_image(false, shm)
pub fn create_texture(self: &Rc<Self>) -> Result<Rc<VulkanImage>, VulkanError> {
self.create_image(false)
}
fn create_image(
self: &Rc<Self>,
for_rendering: bool,
shm: Option<VulkanShmImage>,
) -> Result<Rc<VulkanImage>, VulkanError> {
fn create_image(self: &Rc<Self>, for_rendering: bool) -> Result<Rc<VulkanImage>, VulkanError> {
let device = &self.renderer.device;
let max_extents = match for_rendering {
true => self.render_max_extents,
@ -350,12 +358,13 @@ impl VulkanDmaBufImageTemplate {
true => ImageCreateFlags::DISJOINT,
false => ImageCreateFlags::empty(),
};
let usage = ImageUsageFlags::TRANSFER_SRC
| match (for_rendering, shm.is_some()) {
(true, _) => ImageUsageFlags::COLOR_ATTACHMENT,
(false, false) => ImageUsageFlags::SAMPLED,
(false, true) => ImageUsageFlags::SAMPLED | ImageUsageFlags::TRANSFER_DST,
};
let usage = match for_rendering {
true => match self.render_needs_bridge {
true => ImageUsageFlags::TRANSFER_DST,
false => ImageUsageFlags::TRANSFER_SRC | ImageUsageFlags::COLOR_ATTACHMENT,
},
false => ImageUsageFlags::TRANSFER_SRC | ImageUsageFlags::SAMPLED,
};
let create_info = ImageCreateInfo::builder()
.image_type(ImageType::TYPE_2D)
.format(self.dmabuf.format.vk_format)
@ -464,15 +473,30 @@ impl VulkanDmaBufImageTemplate {
}
let res = unsafe { device.device.bind_image_memory2(&bind_image_memory_infos) };
res.map_err(VulkanError::BindImageMemory)?;
let texture_view = device.create_image_view(image, self.dmabuf.format, false)?;
let render_view = device.create_image_view(image, self.dmabuf.format, true)?;
let mut primary_image = image;
let mut destroy_bridge_image = None;
let mut bridge = None;
if for_rendering && self.render_needs_bridge {
let (bridge_image, allocation) = self.create_bridge()?;
primary_image = bridge_image;
destroy_bridge_image = Some(OnDrop(|| unsafe {
device.device.destroy_image(primary_image, None)
}));
bridge = Some(VulkanFramebufferBridge {
dmabuf_image: image,
_allocation: allocation,
});
}
let texture_view = device.create_image_view(primary_image, self.dmabuf.format, false)?;
let render_view = device.create_image_view(primary_image, self.dmabuf.format, true)?;
free_device_memories.drain(..).for_each(mem::forget);
mem::forget(destroy_image);
mem::forget(destroy_bridge_image);
Ok(Rc::new(VulkanImage {
renderer: self.renderer.clone(),
texture_view,
render_view: Some(render_view),
image,
image: primary_image,
width: self.width,
height: self.height,
stride: 0,
@ -483,8 +507,53 @@ impl VulkanDmaBufImageTemplate {
}),
format: self.dmabuf.format,
is_undefined: Cell::new(true),
bridge,
}))
}
fn create_bridge(&self) -> Result<(Image, VulkanAllocation), VulkanError> {
let create_info = ImageCreateInfo::builder()
.image_type(ImageType::TYPE_2D)
.format(self.dmabuf.format.vk_format)
.mip_levels(1)
.array_layers(1)
.tiling(ImageTiling::OPTIMAL)
.samples(SampleCountFlags::TYPE_1)
.sharing_mode(SharingMode::EXCLUSIVE)
.initial_layout(ImageLayout::UNDEFINED)
.extent(Extent3D {
width: self.width,
height: self.height,
depth: 1,
})
.usage(ImageUsageFlags::COLOR_ATTACHMENT | ImageUsageFlags::TRANSFER_SRC)
.build();
let image = unsafe { self.renderer.device.device.create_image(&create_info, None) };
let image = image.map_err(VulkanError::CreateImage)?;
let destroy_image =
OnDrop(|| unsafe { self.renderer.device.device.destroy_image(image, None) });
let memory_requirements = unsafe {
self.renderer
.device
.device
.get_image_memory_requirements(image)
};
let allocation = self.renderer.allocator.alloc(
&memory_requirements,
UsageFlags::FAST_DEVICE_ACCESS,
false,
)?;
let res = unsafe {
self.renderer.device.device.bind_image_memory(
image,
allocation.memory,
allocation.offset,
)
};
res.map_err(VulkanError::BindImageMemory)?;
destroy_image.forget();
Ok((image, allocation))
}
}
impl GfxImage for VulkanDmaBufImageTemplate {
@ -495,9 +564,7 @@ impl GfxImage for VulkanDmaBufImageTemplate {
}
fn to_texture(self: Rc<Self>) -> Result<Rc<dyn GfxTexture>, GfxError> {
self.create_texture(None)
.map(|v| v as _)
.map_err(|e| e.into())
self.create_texture().map(|v| v as _).map_err(|e| e.into())
}
fn width(&self) -> i32 {

View file

@ -33,12 +33,13 @@ use {
AccessFlags2, AttachmentLoadOp, AttachmentStoreOp, BufferImageCopy, BufferImageCopy2,
BufferMemoryBarrier2, ClearColorValue, ClearValue, CommandBuffer,
CommandBufferBeginInfo, CommandBufferSubmitInfo, CommandBufferUsageFlags,
CopyBufferToImageInfo2, DependencyInfo, DependencyInfoKHR, DescriptorImageInfo,
DescriptorType, Extent2D, Extent3D, Fence, ImageAspectFlags, ImageLayout,
ImageMemoryBarrier2, ImageMemoryBarrier2Builder, ImageSubresourceLayers,
ImageSubresourceRange, PipelineBindPoint, PipelineStageFlags2, Rect2D,
RenderingAttachmentInfo, RenderingInfo, SemaphoreSubmitInfo, SemaphoreSubmitInfoKHR,
ShaderStageFlags, SubmitInfo2, Viewport, WriteDescriptorSet, QUEUE_FAMILY_FOREIGN_EXT,
CopyBufferToImageInfo2, CopyImageInfo2, DependencyInfo, DependencyInfoKHR,
DescriptorImageInfo, DescriptorType, Extent2D, Extent3D, Fence, ImageAspectFlags,
ImageCopy2, ImageLayout, ImageMemoryBarrier2, ImageMemoryBarrier2Builder,
ImageSubresourceLayers, ImageSubresourceRange, PipelineBindPoint, PipelineStageFlags2,
Rect2D, RenderingAttachmentInfo, RenderingInfo, SemaphoreSubmitInfo,
SemaphoreSubmitInfoKHR, ShaderStageFlags, SubmitInfo2, Viewport, WriteDescriptorSet,
QUEUE_FAMILY_FOREIGN_EXT,
},
Device,
},
@ -266,19 +267,33 @@ impl VulkanRenderer {
let memory = &mut *memory;
memory.image_barriers.clear();
memory.shm_barriers.clear();
let fb_image_memory_barrier = image_barrier()
.src_queue_family_index(QUEUE_FAMILY_FOREIGN_EXT)
.dst_queue_family_index(self.device.graphics_queue_idx)
let mut fb_image_memory_barrier = image_barrier()
.image(fb.image)
.old_layout(if fb.is_undefined.get() {
ImageLayout::UNDEFINED
} else {
ImageLayout::GENERAL
})
.new_layout(ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
.dst_access_mask(AccessFlags2::COLOR_ATTACHMENT_WRITE)
.dst_stage_mask(PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT)
.build();
.dst_access_mask(
AccessFlags2::COLOR_ATTACHMENT_WRITE | AccessFlags2::COLOR_ATTACHMENT_READ,
)
.dst_stage_mask(PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT);
if fb.bridge.is_some() {
fb_image_memory_barrier = fb_image_memory_barrier
.src_access_mask(AccessFlags2::TRANSFER_READ)
.src_stage_mask(PipelineStageFlags2::TRANSFER)
.old_layout(if fb.is_undefined.get() {
ImageLayout::UNDEFINED
} else {
ImageLayout::TRANSFER_SRC_OPTIMAL
});
} else {
fb_image_memory_barrier = fb_image_memory_barrier
.src_queue_family_index(QUEUE_FAMILY_FOREIGN_EXT)
.dst_queue_family_index(self.device.graphics_queue_idx)
.old_layout(if fb.is_undefined.get() {
ImageLayout::UNDEFINED
} else {
ImageLayout::GENERAL
});
}
let fb_image_memory_barrier = fb_image_memory_barrier.build();
memory.image_barriers.push(fb_image_memory_barrier);
for img in &memory.sample {
let image_memory_barrier = image_barrier()
@ -542,22 +557,95 @@ impl VulkanRenderer {
}
}
fn copy_bridge_to_dmabuf(&self, buf: CommandBuffer, fb: &VulkanImage) {
let Some(bridge) = &fb.bridge else {
return;
};
let mut memory = self.memory.borrow_mut();
let memory = &mut *memory;
memory.image_barriers.clear();
let bridge_image_memory_barrier = image_barrier()
.image(fb.image)
.old_layout(ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
.new_layout(ImageLayout::TRANSFER_SRC_OPTIMAL)
.src_access_mask(
AccessFlags2::COLOR_ATTACHMENT_WRITE | AccessFlags2::COLOR_ATTACHMENT_READ,
)
.src_stage_mask(PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT)
.dst_access_mask(AccessFlags2::TRANSFER_READ)
.dst_stage_mask(PipelineStageFlags2::TRANSFER)
.build();
memory.image_barriers.push(bridge_image_memory_barrier);
let dmabuf_image_memory_barrier = image_barrier()
.src_queue_family_index(QUEUE_FAMILY_FOREIGN_EXT)
.dst_queue_family_index(self.device.graphics_queue_idx)
.image(bridge.dmabuf_image)
.old_layout(if fb.is_undefined.get() {
ImageLayout::UNDEFINED
} else {
ImageLayout::GENERAL
})
.new_layout(ImageLayout::TRANSFER_DST_OPTIMAL)
.dst_access_mask(AccessFlags2::TRANSFER_WRITE)
.dst_stage_mask(PipelineStageFlags2::TRANSFER)
.build();
memory.image_barriers.push(dmabuf_image_memory_barrier);
let dep_info = DependencyInfoKHR::builder().image_memory_barriers(&memory.image_barriers);
unsafe {
self.device.device.cmd_pipeline_barrier2(buf, &dep_info);
}
let image_subresource_layers = ImageSubresourceLayers::builder()
.aspect_mask(ImageAspectFlags::COLOR)
.layer_count(1)
.base_array_layer(0)
.mip_level(0)
.build();
let image_copy = ImageCopy2::builder()
.src_subresource(image_subresource_layers)
.dst_subresource(image_subresource_layers)
.extent(Extent3D {
width: fb.width,
height: fb.height,
depth: 1,
})
.build();
let copy_image_info = CopyImageInfo2::builder()
.src_image(fb.image)
.src_image_layout(ImageLayout::TRANSFER_SRC_OPTIMAL)
.dst_image(bridge.dmabuf_image)
.dst_image_layout(ImageLayout::TRANSFER_DST_OPTIMAL)
.regions(slice::from_ref(&image_copy))
.build();
unsafe {
self.device.device.cmd_copy_image2(buf, &copy_image_info);
}
}
fn final_barriers(&self, buf: CommandBuffer, fb: &VulkanImage) {
let mut memory = self.memory.borrow_mut();
let memory = &mut *memory;
memory.image_barriers.clear();
memory.shm_barriers.clear();
let fb_image_memory_barrier = image_barrier()
let mut fb_image_memory_barrier = image_barrier()
.src_queue_family_index(self.device.graphics_queue_idx)
.dst_queue_family_index(QUEUE_FAMILY_FOREIGN_EXT)
.image(fb.image)
.old_layout(ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
.new_layout(ImageLayout::GENERAL)
.src_access_mask(
AccessFlags2::COLOR_ATTACHMENT_WRITE | AccessFlags2::COLOR_ATTACHMENT_READ,
)
.src_stage_mask(PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT)
.build();
.new_layout(ImageLayout::GENERAL);
if let Some(bridge) = &fb.bridge {
fb_image_memory_barrier = fb_image_memory_barrier
.image(bridge.dmabuf_image)
.old_layout(ImageLayout::TRANSFER_DST_OPTIMAL)
.src_access_mask(AccessFlags2::TRANSFER_WRITE)
.src_stage_mask(PipelineStageFlags2::TRANSFER);
} else {
fb_image_memory_barrier = fb_image_memory_barrier
.image(fb.image)
.old_layout(ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
.src_access_mask(
AccessFlags2::COLOR_ATTACHMENT_WRITE | AccessFlags2::COLOR_ATTACHMENT_READ,
)
.src_stage_mask(PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT);
}
let fb_image_memory_barrier = fb_image_memory_barrier.build();
memory.image_barriers.push(fb_image_memory_barrier);
for img in &memory.sample {
let image_memory_barrier = image_barrier()
@ -828,31 +916,28 @@ impl VulkanRenderer {
})
.build();
let staging = self.create_staging_buffer(size, false, true, true)?;
let initial_tex_barrier = image_barrier()
.src_queue_family_index(QUEUE_FAMILY_FOREIGN_EXT)
.dst_queue_family_index(self.device.graphics_queue_idx)
.image(tex.image)
.old_layout(ImageLayout::GENERAL)
.new_layout(ImageLayout::TRANSFER_SRC_OPTIMAL)
.dst_access_mask(AccessFlags2::TRANSFER_READ)
.dst_stage_mask(PipelineStageFlags2::TRANSFER);
let initial_tex_barrier;
let initial_buffer_barrier = BufferMemoryBarrier2::builder()
.buffer(staging.buffer)
.offset(0)
.size(staging.size)
.dst_access_mask(AccessFlags2::TRANSFER_WRITE)
.dst_stage_mask(PipelineStageFlags2::TRANSFER);
let initial_barriers = DependencyInfo::builder()
.buffer_memory_barriers(slice::from_ref(&initial_buffer_barrier))
.image_memory_barriers(slice::from_ref(&initial_tex_barrier));
let final_tex_barrier = image_barrier()
.src_queue_family_index(self.device.graphics_queue_idx)
.dst_queue_family_index(QUEUE_FAMILY_FOREIGN_EXT)
.image(tex.image)
.old_layout(ImageLayout::TRANSFER_SRC_OPTIMAL)
.new_layout(ImageLayout::GENERAL)
.src_access_mask(AccessFlags2::TRANSFER_READ)
.src_stage_mask(PipelineStageFlags2::TRANSFER);
let mut initial_barriers = DependencyInfo::builder()
.buffer_memory_barriers(slice::from_ref(&initial_buffer_barrier));
if tex.bridge.is_none() {
initial_tex_barrier = image_barrier()
.src_queue_family_index(QUEUE_FAMILY_FOREIGN_EXT)
.dst_queue_family_index(self.device.graphics_queue_idx)
.image(tex.image)
.old_layout(ImageLayout::GENERAL)
.new_layout(ImageLayout::TRANSFER_SRC_OPTIMAL)
.dst_access_mask(AccessFlags2::TRANSFER_READ)
.dst_stage_mask(PipelineStageFlags2::TRANSFER);
initial_barriers =
initial_barriers.image_memory_barriers(slice::from_ref(&initial_tex_barrier));
}
let final_tex_barrier;
let final_buffer_barrier = BufferMemoryBarrier2::builder()
.buffer(staging.buffer)
.offset(0)
@ -861,9 +946,20 @@ impl VulkanRenderer {
.src_stage_mask(PipelineStageFlags2::TRANSFER)
.dst_access_mask(AccessFlags2::HOST_READ)
.dst_stage_mask(PipelineStageFlags2::HOST);
let final_barriers = DependencyInfo::builder()
.buffer_memory_barriers(slice::from_ref(&final_buffer_barrier))
.image_memory_barriers(slice::from_ref(&final_tex_barrier));
let mut final_barriers = DependencyInfo::builder()
.buffer_memory_barriers(slice::from_ref(&final_buffer_barrier));
if tex.bridge.is_none() {
final_tex_barrier = image_barrier()
.src_queue_family_index(self.device.graphics_queue_idx)
.dst_queue_family_index(QUEUE_FAMILY_FOREIGN_EXT)
.image(tex.image)
.old_layout(ImageLayout::TRANSFER_SRC_OPTIMAL)
.new_layout(ImageLayout::GENERAL)
.src_access_mask(AccessFlags2::TRANSFER_READ)
.src_stage_mask(PipelineStageFlags2::TRANSFER);
final_barriers =
final_barriers.image_memory_barriers(slice::from_ref(&final_tex_barrier));
}
let buf = self.allocate_command_buffer()?;
let mut semaphores = vec![];
let mut semaphore_infos = vec![];
@ -985,6 +1081,7 @@ impl VulkanRenderer {
self.set_viewport(buf.buffer, fb);
self.record_draws(buf.buffer, opts)?;
self.end_rendering(buf.buffer);
self.copy_bridge_to_dmabuf(buf.buffer, fb);
self.final_barriers(buf.buffer, fb);
self.end_command_buffer(buf.buffer)?;
self.create_wait_semaphores(fb)?;