1
0
Fork 0
forked from wry/wry

wl-shm: add support for more formats

This commit is contained in:
Julian Orth 2025-10-01 20:31:00 +02:00
parent 09a56edd47
commit 0570669af2
20 changed files with 114 additions and 81 deletions

View file

@ -201,13 +201,17 @@ impl EglDisplay {
}
read_modifiers.insert(modifier.modifier);
}
if !read_modifiers.is_empty() || !write_modifiers.is_empty() {
if !read_modifiers.is_empty()
|| !write_modifiers.is_empty()
|| format.format.shm_info.is_some()
{
formats.insert(
drm,
GfxFormat {
format: format.format,
read_modifiers,
write_modifiers,
supports_shm: format.format.shm_info.is_some(),
},
);
}

View file

@ -90,7 +90,7 @@ impl GlTexture {
(gles.glBindTexture)(GL_TEXTURE_2D, tex);
(gles.glTexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
(gles.glTexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
(gles.glPixelStorei)(GL_UNPACK_ROW_LENGTH_EXT, stride / shm_info.bpp as GLint);
(gles.glPixelStorei)(GL_UNPACK_ROW_LENGTH_EXT, stride / format.bpp as GLint);
(gles.glTexImage2D)(
GL_TEXTURE_2D,
0,

View file

@ -90,7 +90,7 @@ impl AsyncShmGfxTexture for Texture {
(gles.glTexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
(gles.glPixelStorei)(
GL_UNPACK_ROW_LENGTH_EXT,
self.gl.stride / shm_info.bpp as GLint,
self.gl.stride / self.format.bpp as GLint,
);
(gles.glTexImage2D)(
GL_TEXTURE_2D,

View file

@ -179,8 +179,6 @@ pub enum VulkanError {
InvalidStride,
#[error("Shm stride and height do not match buffer size")]
InvalidBufferSize,
#[error("Buffer format {0} is not supported for shm buffers in Vulkan context")]
UnsupportedShmFormat(&'static str),
#[error("Only BO_USE_RENDERING and BO_USE_WRITE are supported")]
UnsupportedBufferUsage,
#[error("None of the supplied modifiers are supported")]
@ -223,7 +221,7 @@ pub enum VulkanError {
GetFl(#[source] OsError),
#[error("GBM implementation cannot be used with software renderer")]
SoftwareRendererNotUsable,
#[error("DMABUF buffer offsets must be aligned to 4 bytes")]
#[error("DMABUF buffer offsets must be aligned to 4 bytes and the pixel size")]
DmaBufBufferOffsetAlignment,
}
@ -403,12 +401,13 @@ impl GfxContext for Context {
dmabuf: &OwnedFd,
offset: usize,
size: usize,
format: &'static Format,
) -> Result<Rc<dyn GfxBuffer>, GfxError> {
self.0.check_defunct()?;
let buffer = self
.0
.device
.create_dmabuf_buffer(dmabuf, offset as u64, size as u64)?;
let buffer =
self.0
.device
.create_dmabuf_buffer(dmabuf, offset as u64, size as u64, format)?;
Ok(buffer)
}
}

View file

@ -457,10 +457,7 @@ impl Allocator for VulkanBoAllocator {
impl VulkanBo {
fn map(self: &Rc<Self>, write: bool) -> Result<VulkanBoMapping, VulkanError> {
let format = self.buf.format;
let Some(shm_info) = &format.shm_info else {
return Err(VulkanError::ShmNotSupported);
};
let stride = self.buf.width as u32 * shm_info.bpp;
let stride = self.buf.width as u32 * format.bpp;
let size = self.buf.height as u32 * stride;
let data = &self.allocator;
let staging =

View file

@ -1,5 +1,6 @@
use {
crate::{
format::Format,
gfx_api::GfxBuffer,
gfx_apis::vulkan::{VulkanError, device::VulkanDevice},
utils::on_drop::OnDrop,
@ -32,8 +33,9 @@ impl VulkanDevice {
dmabuf: &OwnedFd,
offset: u64,
size: u64,
format: &'static Format,
) -> Result<Rc<VulkanDmabufBuffer>, VulkanError> {
if offset % TRANSFER_QUEUE_BUFFER_ALIGNMENT != 0 {
if offset % TRANSFER_QUEUE_BUFFER_ALIGNMENT != 0 || offset % format.bpp as u64 != 0 {
return Err(VulkanError::DmaBufBufferOffsetAlignment);
}
let mut memory_fd_properties = MemoryFdPropertiesKHR::default();

View file

@ -171,9 +171,6 @@ impl VulkanInstance {
format: &Format,
props: &FormatProperties,
) -> 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)
}

View file

@ -345,6 +345,7 @@ impl VulkanDevice {
)
})
.collect(),
supports_shm: vk.shm.is_some(),
},
)
})

View file

@ -1,7 +1,7 @@
use {
crate::{
cpu_worker::CpuWorker,
format::{Format, FormatShmInfo},
format::Format,
gfx_api::SyncFile,
gfx_apis::vulkan::{
VulkanError,
@ -33,7 +33,6 @@ pub struct VulkanShmImage {
pub(super) size: DeviceSize,
pub(super) stride: u32,
pub(super) _allocation: VulkanAllocation,
pub(super) shm_info: &'static FormatShmInfo,
pub(super) async_data: Option<VulkanShmImageAsyncData>,
}
@ -68,7 +67,7 @@ impl VulkanShmImage {
if full {
builder = builder
.buffer_image_height(img.height)
.buffer_row_length(img.stride / self.shm_info.bpp);
.buffer_row_length(img.stride / img.format.bpp);
}
builder
};
@ -99,7 +98,7 @@ impl VulkanShmImage {
damage.width() as u32,
damage.height() as u32,
));
total_size += damage.width() as u32 * damage.height() as u32 * self.shm_info.bpp;
total_size += damage.width() as u32 * damage.height() as u32 * img.format.bpp;
}
cpy = &cpy_many[..];
} else {
@ -124,7 +123,7 @@ impl VulkanShmImage {
let width = cpy.image_extent.width as usize;
let height = cpy.image_extent.height as usize;
let stride = self.stride as usize;
let bpp = self.shm_info.bpp as usize;
let bpp = img.format.bpp as usize;
for dy in 0..height {
let lo = (y + dy) * stride + x * bpp;
let len = width * bpp;
@ -367,16 +366,13 @@ impl VulkanRenderer {
for_download: bool,
cpu_worker: Option<&Rc<CpuWorker>>,
) -> 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 {
if stride % format.bpp != 0 || stride / format.bpp < width {
return Err(VulkanError::InvalidStride);
}
let vk_format = self
@ -461,7 +457,6 @@ impl VulkanRenderer {
size,
stride,
_allocation: allocation,
shm_info,
async_data,
};
destroy_image.forget();

View file

@ -13,7 +13,7 @@ use {
gfx_apis::vulkan::{
VulkanError,
command::VulkanCommandBuffer,
dmabuf_buffer::VulkanDmabufBuffer,
dmabuf_buffer::{TRANSFER_QUEUE_BUFFER_ALIGNMENT, VulkanDmabufBuffer},
fence::VulkanFence,
image::{QueueFamily, QueueState, QueueTransfer, VulkanImage, VulkanImageMemory},
renderer::image_barrier,
@ -227,8 +227,25 @@ impl VulkanShmImage {
let mut copies_ref = data.regions.borrow_mut();
let copies = &mut *copies_ref;
copies.clear();
let mut copy = |x, y, width, height| {
let buffer_offset = (y as u32 * img.stride + x as u32 * self.shm_info.bpp) as u64;
let mut copy = |mut x, mut y, mut width, mut height| {
let x_orig = x;
let width_orig = width;
let mut buffer_offset;
loop {
buffer_offset = (y as u32 * img.stride + x as u32 * img.format.bpp) as u64;
if buffer_offset.is_multiple_of(TRANSFER_QUEUE_BUFFER_ALIGNMENT) {
break;
}
if x > 0 {
x -= 1;
width += 1;
} else {
y -= 1;
height += 1;
x = x_orig;
width = width_orig;
}
}
let copy = BufferImageCopy2::default()
.buffer_offset(buffer_offset + extra_offset)
.image_offset(Offset3D { x, y, z: 0 })
@ -244,7 +261,7 @@ impl VulkanShmImage {
layer_count: 1,
})
.buffer_image_height(img.height)
.buffer_row_length(img.stride / self.shm_info.bpp);
.buffer_row_length(img.stride / img.format.bpp);
copies.push(copy);
};
let (width_mask, height_mask) = img.renderer.device.transfer_granularity_mask;
@ -451,7 +468,7 @@ impl VulkanShmImage {
}
job.work.width = img.width as _;
job.work.stride = img.stride as _;
job.work.bpp = self.shm_info.bpp as _;
job.work.bpp = img.format.bpp as _;
job.work.rects.clear();
for copy in copies {
job.work.rects.push(
@ -472,7 +489,7 @@ impl VulkanShmImage {
for copy in copies {
min_offset = min_offset.min(copy.buffer_offset);
let len = img.stride * (copy.image_extent.height - 1)
+ copy.image_extent.width * self.shm_info.bpp;
+ copy.image_extent.width * img.format.bpp;
max_offset = max_offset.max(copy.buffer_offset + len as u64);
}
let mut job = data.io_job.take().unwrap_or_else(|| {