drm-tests: create EGL Image backed by multiple memory planes
EGL_EXT_image_dma_buf_import allows EGL image backed by multiple memory planes.
NV12 and YVU420 (i.e. YV12) are the format with multiple planes. This CL makes
drm-tests cover those formats.
BUG=chromium:356871
Change-Id: I80afadda69156a57a6694ff96d4ed9750ac221f5
Reviewed-on: https://chromium-review.googlesource.com/470466
Commit-Ready: Dongseong Hwang <dongseong.hwang@intel.com>
Tested-by: Dongseong Hwang <dongseong.hwang@intel.com>
Reviewed-by: Dongseong Hwang <dongseong.hwang@intel.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
diff --git a/bsdrm/include/bs_drm.h b/bsdrm/include/bs_drm.h
index 0e9f36d..394adbf 100644
--- a/bsdrm/include/bs_drm.h
+++ b/bsdrm/include/bs_drm.h
@@ -152,11 +152,6 @@
bool bs_egl_setup(struct bs_egl *self);
bool bs_egl_make_current(struct bs_egl *self);
-EGLImageKHR bs_egl_image_create(struct bs_egl *self, int prime_fd, int width, int height,
- uint32_t format, int pitch, int offset);
-EGLImageKHR bs_egl_image_create_with_modifier(struct bs_egl *self, int prime_fd, int width,
- int height, uint32_t format, int pitch, int offset,
- uint64_t format_modifier);
EGLImageKHR bs_egl_image_create_gbm(struct bs_egl *self, struct gbm_bo *bo);
void bs_egl_image_destroy(struct bs_egl *self, EGLImageKHR *image);
bool bs_egl_image_flush_external(struct bs_egl *self, EGLImageKHR image);
diff --git a/bsdrm/src/draw.c b/bsdrm/src/draw.c
index 4a834d7..7602dc2 100644
--- a/bsdrm/src/draw.c
+++ b/bsdrm/src/draw.c
@@ -37,6 +37,15 @@
},
},
{
+ PIXEL_FORMAT_AND_NAME(YVU420),
+ 3,
+ {
+ { { 0.2567890625f, 0.50412890625f, 0.09790625f }, 16.0f, 1, 1, 1, 0, 0 },
+ { { 0.43921484375f, -0.3677890625f, -0.07142578125f }, 128.0f, 2, 2, 1, 1, 0 },
+ { { -0.14822265625f, -0.2909921875f, 0.43921484375f }, 128.0f, 2, 2, 1, 2, 0 },
+ },
+ },
+ {
PIXEL_FORMAT_AND_NAME(XRGB8888),
3,
{
diff --git a/bsdrm/src/egl.c b/bsdrm/src/egl.c
index 485afc0..d868b11 100644
--- a/bsdrm/src/egl.c
+++ b/bsdrm/src/egl.c
@@ -163,37 +163,54 @@
EGL_NO_SURFACE /* No default draw read */, self->ctx);
}
-static EGLImageKHR _bs_egl_image_create(struct bs_egl *self, int prime_fd, int width, int height,
- uint32_t format, int pitch, int offset,
- uint64_t *format_modifier)
+EGLImageKHR bs_egl_image_create_gbm(struct bs_egl *self, struct gbm_bo *bo)
{
assert(self);
assert(self->CreateImageKHR);
assert(self->display != EGL_NO_DISPLAY);
- EGLint khr_image_attrs[17] = { EGL_DMA_BUF_PLANE0_FD_EXT,
- prime_fd,
- EGL_WIDTH,
- width,
- EGL_HEIGHT,
- height,
- EGL_LINUX_DRM_FOURCC_EXT,
- (int)format,
- EGL_DMA_BUF_PLANE0_PITCH_EXT,
- pitch,
- EGL_DMA_BUF_PLANE0_OFFSET_EXT,
- offset,
- EGL_NONE };
+ assert(bo);
- if (self->use_dma_buf_import_modifiers) {
- assert(format_modifier);
- uint64_t modifier = format_modifier ? *format_modifier : 0;
- khr_image_attrs[12] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
- khr_image_attrs[13] = modifier & 0xfffffffful;
- khr_image_attrs[14] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
- khr_image_attrs[15] = modifier >> 32;
- khr_image_attrs[16] = EGL_NONE;
+ int fds[GBM_MAX_PLANES];
+ for (size_t plane = 0; plane < gbm_bo_get_num_planes(bo); plane++) {
+ fds[plane] = gbm_bo_get_plane_fd(bo, plane);
+ if (fds[plane] < 0) {
+ bs_debug_error("failed to get fb for bo: %d", fds[plane]);
+ return EGL_NO_IMAGE_KHR;
+ }
}
+ // When the bo has 3 planes with modifier support, it requires 37 components.
+ EGLint khr_image_attrs[37] = {
+ EGL_WIDTH,
+ gbm_bo_get_width(bo),
+ EGL_HEIGHT,
+ gbm_bo_get_height(bo),
+ EGL_LINUX_DRM_FOURCC_EXT,
+ (int)gbm_bo_get_format(bo),
+ EGL_NONE,
+ };
+
+ size_t attrs_index = 6;
+ for (size_t plane = 0; plane < gbm_bo_get_num_planes(bo); plane++) {
+ khr_image_attrs[attrs_index++] = EGL_DMA_BUF_PLANE0_FD_EXT + plane * 3;
+ khr_image_attrs[attrs_index++] = fds[plane];
+ khr_image_attrs[attrs_index++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT + plane * 3;
+ khr_image_attrs[attrs_index++] = gbm_bo_get_plane_offset(bo, plane);
+ khr_image_attrs[attrs_index++] = EGL_DMA_BUF_PLANE0_PITCH_EXT + plane * 3;
+ khr_image_attrs[attrs_index++] = gbm_bo_get_plane_stride(bo, plane);
+ if (self->use_dma_buf_import_modifiers) {
+ const uint64_t modifier = gbm_bo_get_format_modifier(bo);
+ khr_image_attrs[attrs_index++] =
+ EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT + plane * 2;
+ khr_image_attrs[attrs_index++] = modifier & 0xfffffffful;
+ khr_image_attrs[attrs_index++] =
+ EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT + plane * 2;
+ khr_image_attrs[attrs_index++] = modifier >> 32;
+ }
+ }
+
+ khr_image_attrs[attrs_index++] = EGL_NONE;
+
EGLImageKHR image =
self->CreateImageKHR(self->display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT,
NULL /* no client buffer */, khr_image_attrs);
@@ -203,35 +220,11 @@
return EGL_NO_IMAGE_KHR;
}
- return image;
-}
-
-EGLImageKHR bs_egl_image_create(struct bs_egl *self, int prime_fd, int width, int height,
- uint32_t format, int pitch, int offset)
-{
- return _bs_egl_image_create(self, prime_fd, width, height, format, pitch, offset, NULL);
-}
-
-EGLImageKHR bs_egl_image_create_with_modifier(struct bs_egl *self, int prime_fd, int width,
- int height, uint32_t format, int pitch, int offset,
- uint64_t format_modifier)
-{
- return _bs_egl_image_create(self, prime_fd, width, height, format, pitch, offset,
- &format_modifier);
-}
-
-EGLImageKHR bs_egl_image_create_gbm(struct bs_egl *self, struct gbm_bo *bo)
-{
- assert(bo);
- int fd = gbm_bo_get_fd(bo);
- if (fd < 0) {
- bs_debug_error("failed to get fb for bo: %d", fd);
- return EGL_NO_IMAGE_KHR;
+ for (size_t plane = 0; plane < gbm_bo_get_num_planes(bo); plane++) {
+ close(fds[plane]);
}
- uint64_t modifier = self->use_dma_buf_import_modifiers ? gbm_bo_get_format_modifier(bo) : 0;
- return bs_egl_image_create_with_modifier(
- self, fd, gbm_bo_get_width(bo), gbm_bo_get_height(bo), gbm_bo_get_format(bo),
- gbm_bo_get_stride(bo), 0 /* no offset */, modifier);
+
+ return image;
}
void bs_egl_image_destroy(struct bs_egl *self, EGLImageKHR *image)