Skip to content

Commit

Permalink
Merge pull request #203 from mahkoh/jorth/various-fixes2
Browse files Browse the repository at this point in the history
vulkan: optimize shm handling
  • Loading branch information
mahkoh authored May 24, 2024
2 parents 03c02be + af80fad commit 3716d09
Show file tree
Hide file tree
Showing 14 changed files with 625 additions and 409 deletions.
2 changes: 1 addition & 1 deletion src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ impl CursorImageScaled {
extents: Rect::new_sized(-xhot, -yhot, width, height).unwrap(),
tex: ctx
.clone()
.shmem_texture(None, data, ARGB8888, width, height, width * 4)?,
.shmem_texture(None, data, ARGB8888, width, height, width * 4, None)?,
}))
}
}
Expand Down
1 change: 1 addition & 0 deletions src/gfx_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,7 @@ pub trait GfxContext: Debug {
width: i32,
height: i32,
stride: i32,
damage: Option<&[Rect]>,
) -> Result<Rc<dyn GfxTexture>, GfxError>;

fn gbm(&self) -> &GbmDevice;
Expand Down
2 changes: 2 additions & 0 deletions src/gfx_apis/gl/renderer/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use {
renderer::{framebuffer::Framebuffer, image::Image},
GfxGlState, RenderError, Texture,
},
rect::Rect,
video::{
dmabuf::DmaBuf,
drm::{sync_obj::SyncObjCtx, Drm},
Expand Down Expand Up @@ -270,6 +271,7 @@ impl GfxContext for GlRenderContext {
width: i32,
height: i32,
stride: i32,
_damage: Option<&[Rect]>,
) -> Result<Rc<dyn GfxTexture>, GfxError> {
(&self)
.shmem_texture(data, format, width, height, stride)
Expand Down
5 changes: 4 additions & 1 deletion src/gfx_apis/vulkan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod renderer;
mod sampler;
mod semaphore;
mod shaders;
mod shm_image;
mod staging;
mod util;

Expand All @@ -25,6 +26,7 @@ use {
image::VulkanImageMemory, instance::VulkanInstance, renderer::VulkanRenderer,
},
io_uring::IoUring,
rect::Rect,
utils::oserror::OsError,
video::{
dmabuf::DmaBuf,
Expand Down Expand Up @@ -230,6 +232,7 @@ impl GfxContext for Context {
width: i32,
height: i32,
stride: i32,
damage: Option<&[Rect]>,
) -> Result<Rc<dyn GfxTexture>, GfxError> {
if let Some(old) = old {
let old = old.into_vk(&self.0.device.device);
Expand All @@ -242,7 +245,7 @@ impl GfxContext for Context {
&& shm.stride as i32 == stride
&& old.format.vk_format == format.vk_format
{
shm.upload(data)?;
shm.upload(&old, data, damage)?;
return Ok(old);
}
}
Expand Down
143 changes: 9 additions & 134 deletions src/gfx_apis/vulkan/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,26 @@ use {
gfx_api::{GfxApiOpt, GfxError, GfxFramebuffer, GfxImage, GfxTexture, SyncFile},
gfx_apis::vulkan::{
allocator::VulkanAllocation, device::VulkanDevice, format::VulkanMaxExtents,
renderer::VulkanRenderer, util::OnDrop, VulkanError,
renderer::VulkanRenderer, shm_image::VulkanShmImage, util::OnDrop, VulkanError,
},
theme::Color,
utils::clonecell::CloneCell,
video::dmabuf::{DmaBuf, PlaneVec},
},
ash::vk::{
BindImageMemoryInfo, BindImagePlaneMemoryInfo, ComponentMapping, ComponentSwizzle,
DeviceMemory, DeviceSize, Extent3D, ExternalMemoryHandleTypeFlags,
ExternalMemoryImageCreateInfo, FormatFeatureFlags, Image, ImageAspectFlags,
ImageCreateFlags, ImageCreateInfo, ImageDrmFormatModifierExplicitCreateInfoEXT,
ImageLayout, ImageMemoryRequirementsInfo2, ImagePlaneMemoryRequirementsInfo,
ImageSubresourceRange, ImageTiling, ImageType, ImageUsageFlags, ImageView,
ImageViewCreateInfo, ImageViewType, ImportMemoryFdInfoKHR, MemoryAllocateInfo,
MemoryDedicatedAllocateInfo, MemoryPropertyFlags, MemoryRequirements2, SampleCountFlags,
SharingMode, SubresourceLayout,
DeviceMemory, Extent3D, ExternalMemoryHandleTypeFlags, ExternalMemoryImageCreateInfo,
FormatFeatureFlags, Image, ImageAspectFlags, ImageCreateFlags, ImageCreateInfo,
ImageDrmFormatModifierExplicitCreateInfoEXT, ImageLayout, ImageMemoryRequirementsInfo2,
ImagePlaneMemoryRequirementsInfo, ImageSubresourceRange, ImageTiling, ImageType,
ImageUsageFlags, ImageView, ImageViewCreateInfo, ImageViewType, ImportMemoryFdInfoKHR,
MemoryAllocateInfo, MemoryDedicatedAllocateInfo, MemoryPropertyFlags, MemoryRequirements2,
SampleCountFlags, SharingMode, SubresourceLayout,
},
gpu_alloc::UsageFlags,
std::{
any::Any,
cell::{Cell, RefCell},
cell::Cell,
fmt::{Debug, Formatter},
mem,
rc::Rc,
Expand Down Expand Up @@ -67,13 +66,6 @@ pub struct VulkanDmaBufImage {
pub(super) mems: PlaneVec<DeviceMemory>,
}

pub struct VulkanShmImage {
pub(super) to_flush: RefCell<Option<Vec<u8>>>,
pub(super) size: DeviceSize,
pub(super) stride: u32,
pub(super) _allocation: VulkanAllocation,
}

pub struct VulkanFramebufferBridge {
pub(super) dmabuf_image: Image,
pub(super) _allocation: VulkanAllocation,
Expand Down Expand Up @@ -113,124 +105,7 @@ impl Drop for VulkanImage {
}
}

impl VulkanShmImage {
pub fn upload(&self, buffer: &[Cell<u8>]) -> Result<(), VulkanError> {
let buffer = unsafe {
std::slice::from_raw_parts(buffer.as_ptr() as *const u8, buffer.len()).to_vec()
};
*self.to_flush.borrow_mut() = Some(buffer);
Ok(())
}
}

impl VulkanRenderer {
pub fn create_shm_texture(
self: &Rc<Self>,
format: &'static Format,
width: i32,
height: i32,
stride: i32,
data: &[Cell<u8>],
for_download: bool,
) -> Result<Rc<VulkanImage>, VulkanError> {
let Some(shm_info) = &format.shm_info else {
return Err(VulkanError::UnsupportedShmFormat(format.name));
};
if width <= 0 || height <= 0 || stride <= 0 {
return Err(VulkanError::NonPositiveImageSize);
}
let width = width as u32;
let height = height as u32;
let stride = stride as u32;
if stride % shm_info.bpp != 0 || stride / shm_info.bpp < width {
return Err(VulkanError::InvalidStride);
}
let vk_format = self
.device
.formats
.get(&format.drm)
.ok_or(VulkanError::FormatNotSupported)?;
let shm = vk_format.shm.as_ref().ok_or(VulkanError::ShmNotSupported)?;
if width > shm.max_extents.width || height > shm.max_extents.height {
return Err(VulkanError::ImageTooLarge);
}
let size = stride.checked_mul(height).ok_or(VulkanError::ShmOverflow)?;
let usage = ImageUsageFlags::TRANSFER_SRC
| match for_download {
true => ImageUsageFlags::COLOR_ATTACHMENT,
false => ImageUsageFlags::SAMPLED | ImageUsageFlags::TRANSFER_DST,
};
let create_info = ImageCreateInfo::builder()
.image_type(ImageType::TYPE_2D)
.format(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,
height,
depth: 1,
})
.usage(usage)
.build();
let image = unsafe { self.device.device.create_image(&create_info, None) };
let image = image.map_err(VulkanError::CreateImage)?;
let destroy_image = OnDrop(|| unsafe { self.device.device.destroy_image(image, None) });
let memory_requirements =
unsafe { self.device.device.get_image_memory_requirements(image) };
let allocation =
self.allocator
.alloc(&memory_requirements, UsageFlags::FAST_DEVICE_ACCESS, false)?;
let res = unsafe {
self.device
.device
.bind_image_memory(image, allocation.memory, allocation.offset)
};
res.map_err(VulkanError::BindImageMemory)?;
let image_view_create_info = ImageViewCreateInfo::builder()
.image(image)
.format(format.vk_format)
.view_type(ImageViewType::TYPE_2D)
.subresource_range(ImageSubresourceRange {
aspect_mask: ImageAspectFlags::COLOR,
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
layer_count: 1,
});
let view = unsafe {
self.device
.device
.create_image_view(&image_view_create_info, None)
};
let view = view.map_err(VulkanError::CreateImageView)?;
let shm = VulkanShmImage {
to_flush: Default::default(),
size: size as u64,
stride,
_allocation: allocation,
};
shm.upload(data)?;
destroy_image.forget();
Ok(Rc::new(VulkanImage {
renderer: self.clone(),
format,
width,
height,
stride,
texture_view: view,
render_view: None,
image,
is_undefined: Cell::new(true),
ty: VulkanImageMemory::Internal(shm),
render_ops: Default::default(),
bridge: None,
}))
}

pub fn import_dmabuf(
self: &Rc<Self>,
dmabuf: &DmaBuf,
Expand Down
Loading

0 comments on commit 3716d09

Please sign in to comment.