1
0
Fork 0
forked from wry/wry

render: add support for more formats

This commit is contained in:
Julian Orth 2024-04-03 21:18:44 +02:00
parent 9d78231cac
commit 551dafcce8
13 changed files with 348 additions and 491 deletions

View file

@ -190,6 +190,8 @@ enum RenderError {
ExportSyncFile,
#[error("Could not insert wait for EGLSyncKHR")]
WaitSync,
#[error("Buffer format {0} is not supported for shm buffers in OpenGL context")]
UnsupportedShmFormat(&'static str),
}
#[derive(Default)]

View file

@ -32,11 +32,14 @@ impl GlRenderBuffer {
height: i32,
format: &'static Format,
) -> Result<Rc<GlRenderBuffer>, RenderError> {
let Some(shm_info) = &format.shm_info else {
return Err(RenderError::UnsupportedShmFormat(format.name));
};
let gles = &ctx.dpy.gles;
let mut rbo = 0;
(gles.glGenRenderbuffers)(1, &mut rbo);
(gles.glBindRenderbuffer)(GL_RENDERBUFFER, rbo);
(gles.glRenderbufferStorage)(GL_RENDERBUFFER, format.gl_internal_format, width, height);
(gles.glRenderbufferStorage)(GL_RENDERBUFFER, shm_info.gl_internal_format, width, height);
(gles.glBindRenderbuffer)(GL_RENDERBUFFER, 0);
Ok(Rc::new(GlRenderBuffer {
_img: None,

View file

@ -73,6 +73,9 @@ impl GlTexture {
height: i32,
stride: i32,
) -> Result<GlTexture, RenderError> {
let Some(shm_info) = &format.shm_info else {
return Err(RenderError::UnsupportedShmFormat(format.name));
};
if (stride * height) as usize > data.len() {
return Err(RenderError::SmallImageBuffer);
}
@ -83,16 +86,16 @@ 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 / format.bpp as GLint);
(gles.glPixelStorei)(GL_UNPACK_ROW_LENGTH_EXT, stride / shm_info.bpp as GLint);
(gles.glTexImage2D)(
GL_TEXTURE_2D,
0,
format.gl_format,
shm_info.gl_format,
width,
height,
0,
format.gl_format as _,
format.gl_type as _,
shm_info.gl_format as _,
shm_info.gl_type as _,
data.as_ptr() as _,
);
(gles.glPixelStorei)(GL_UNPACK_ROW_LENGTH_EXT, 0);

View file

@ -43,7 +43,10 @@ impl Framebuffer {
height: i32,
format: &Format,
shm: &[Cell<u8>],
) {
) -> Result<(), RenderError> {
let Some(shm_info) = &format.shm_info else {
return Err(RenderError::UnsupportedShmFormat(format.name));
};
let gles = self.ctx.ctx.dpy.gles;
let y = self.gl.height - y - height;
let _ = self.ctx.ctx.with_current(|| {
@ -55,14 +58,15 @@ impl Framebuffer {
y,
width,
height,
format.gl_format as _,
format.gl_type as _,
shm_info.gl_format as _,
shm_info.gl_type as _,
shm.len() as _,
shm.as_ptr() as _,
);
}
Ok(())
});
Ok(())
}
pub fn render(
@ -126,8 +130,9 @@ impl GfxFramebuffer for Framebuffer {
format: &'static Format,
shm: &[Cell<u8>],
) -> Result<(), GfxError> {
(*self).copy_to_shm(x, y, width, height, format, shm);
Ok(())
(*self)
.copy_to_shm(x, y, width, height, format, shm)
.map_err(|e| e.into())
}
fn format(&self) -> &'static Format {

View file

@ -70,8 +70,8 @@ impl GfxTexture for Texture {
shm: &[Cell<u8>],
) -> Result<(), GfxError> {
self.to_framebuffer()?
.copy_to_shm(x, y, width, height, format, shm);
Ok(())
.copy_to_shm(x, y, width, height, format, shm)
.map_err(|e| e.into())
}
fn dmabuf(&self) -> Option<&DmaBuf> {

View file

@ -175,6 +175,8 @@ pub enum VulkanError {
},
#[error(transparent)]
GfxError(GfxError),
#[error("Buffer format {0} is not supported for shm buffers in Vulkan context")]
UnsupportedShmFormat(&'static str),
}
impl From<VulkanError> for GfxError {

View file

@ -130,6 +130,9 @@ impl VulkanInstance {
format: &Format,
props: &FormatProperties2,
) -> Result<Option<VulkanShmFormat>, VulkanError> {
if format.shm_info.is_none() {
return Ok(None);
}
if !props
.format_properties
.optimal_tiling_features

View file

@ -120,13 +120,16 @@ impl VulkanRenderer {
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 % format.bpp != 0 || stride / format.bpp < width {
if stride % shm_info.bpp != 0 || stride / shm_info.bpp < width {
return Err(VulkanError::InvalidStride);
}
let vk_format = self

View file

@ -294,9 +294,12 @@ impl VulkanRenderer {
fn copy_shm_to_image(&self, cmd: CommandBuffer) {
let memory = self.memory.borrow_mut();
for (img, staging) in &memory.flush_staging {
let Some(shm_info) = &img.format.shm_info else {
continue;
};
let cpy = BufferImageCopy2::builder()
.buffer_image_height(img.height)
.buffer_row_length(img.stride / img.format.bpp)
.buffer_row_length(img.stride / shm_info.bpp)
.image_extent(Extent3D {
width: img.width,
height: img.height,
@ -751,7 +754,10 @@ impl VulkanRenderer {
stride: u32,
dst: &[Cell<u8>],
) -> Result<(), VulkanError> {
if stride < tex.width * tex.format.bpp || stride % tex.format.bpp != 0 {
let Some(shm_info) = &tex.format.shm_info else {
return Err(VulkanError::UnsupportedShmFormat(tex.format.name));
};
if stride < tex.width * shm_info.bpp || stride % shm_info.bpp != 0 {
return Err(VulkanError::InvalidStride);
}
let size = stride as u64 * tex.height as u64;
@ -759,7 +765,7 @@ impl VulkanRenderer {
return Err(VulkanError::InvalidBufferSize);
}
let region = BufferImageCopy::builder()
.buffer_row_length(stride / tex.format.bpp)
.buffer_row_length(stride / shm_info.bpp)
.buffer_image_height(tex.height)
.image_subresource(ImageSubresourceLayers {
aspect_mask: ImageAspectFlags::COLOR,