[Mesa-dev] [PATCH v3 08/15] egl_dri2: add support for using modifier attributes in eglCreateImageKHR

Varad Gautam varadgautam at gmail.com
Wed May 10 17:45:35 UTC 2017


From: Varad Gautam <varad.gautam at collabora.com>

allow creating EGLImages with dmabuf format modifiers when target is
EGL_LINUX_DMA_BUF_EXT for EGL_EXT_image_dma_buf_import_modifiers.

v2:
 - clear modifier assembling and error label name (Eric Engestrom)
v3:
 - remove goto jumps within switch-case (Emil Velikov)
 - treat zero as valid modifier (Daniel Stone)
 - ensure same modifier across all dmabuf planes (Emil Velikov)

Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
Signed-off-by: Varad Gautam <varad.gautam at collabora.com>
Reviewed-by: Eric Engestrom <eric.engestrom at imgtec.com>
---
 src/egl/drivers/dri2/egl_dri2.c | 79 +++++++++++++++++++++++++++++++++++------
 src/egl/main/eglimage.c         | 48 +++++++++++++++++++++++++
 src/egl/main/eglimage.h         |  2 ++
 3 files changed, 118 insertions(+), 11 deletions(-)

diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index ceffd28..9139bd4 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1949,6 +1949,33 @@ dri2_check_dma_buf_attribs(const _EGLImageAttribs *attrs)
       }
    }
 
+   /**
+    * If <target> is EGL_LINUX_DMA_BUF_EXT, both or neither of the following
+    * attribute values may be given.
+    *
+    * This is referring to EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT and
+    * EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, and the same for other planes.
+    */
+   for (i = 0; i < DMA_BUF_MAX_PLANES; ++i) {
+      if (attrs->DMABufPlaneModifiersLo[i].IsPresent !=
+          attrs->DMABufPlaneModifiersHi[i].IsPresent) {
+         _eglError(EGL_BAD_PARAMETER, "modifier attribute lo or hi missing");
+         return EGL_FALSE;
+      }
+   }
+
+   for (i = 0; i < DMA_BUF_MAX_PLANES; ++i) {
+      if (attrs->DMABufPlaneModifiersLo[i].IsPresent) {
+         if ((attrs->DMABufPlaneModifiersLo[0].Value !=
+             attrs->DMABufPlaneModifiersLo[i].Value) ||
+             (attrs->DMABufPlaneModifiersHi[0].Value !=
+             attrs->DMABufPlaneModifiersHi[i].Value)) {
+            _eglError(EGL_BAD_PARAMETER, "modifier attributes not equal");
+            return EGL_FALSE;
+         }
+      }
+   }
+
    return EGL_TRUE;
 }
 
@@ -2057,7 +2084,9 @@ dri2_check_dma_buf_format(const _EGLImageAttribs *attrs)
    for (i = plane_n; i < DMA_BUF_MAX_PLANES; ++i) {
       if (attrs->DMABufPlaneFds[i].IsPresent ||
           attrs->DMABufPlaneOffsets[i].IsPresent ||
-          attrs->DMABufPlanePitches[i].IsPresent) {
+          attrs->DMABufPlanePitches[i].IsPresent ||
+          attrs->DMABufPlaneModifiersLo[i].IsPresent ||
+          attrs->DMABufPlaneModifiersHi[i].IsPresent) {
          _eglError(EGL_BAD_ATTRIBUTE, "too many plane attributes");
          return 0;
       }
@@ -2090,6 +2119,8 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
    int fds[DMA_BUF_MAX_PLANES];
    int pitches[DMA_BUF_MAX_PLANES];
    int offsets[DMA_BUF_MAX_PLANES];
+   uint64_t modifiers[DMA_BUF_MAX_PLANES];
+   bool has_modifier = false;
    unsigned error;
 
    /**
@@ -2120,18 +2151,44 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
       fds[i] = attrs.DMABufPlaneFds[i].Value;
       pitches[i] = attrs.DMABufPlanePitches[i].Value;
       offsets[i] = attrs.DMABufPlaneOffsets[i].Value;
+      if (attrs.DMABufPlaneModifiersLo[i].IsPresent) {
+         modifiers[i] =
+            ((uint64_t) attrs.DMABufPlaneModifiersHi[i].Value << 32) |
+            attrs.DMABufPlaneModifiersLo[i].Value;
+         has_modifier = true;
+      } else {
+         modifiers[i] = 0;
+      }
    }
 
-   dri_image =
-      dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
-         attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
-         fds, num_fds, pitches, offsets,
-         attrs.DMABufYuvColorSpaceHint.Value,
-         attrs.DMABufSampleRangeHint.Value,
-         attrs.DMABufChromaHorizontalSiting.Value,
-         attrs.DMABufChromaVerticalSiting.Value,
-         &error,
-         NULL);
+   if (has_modifier && dri2_dpy->image->createImageFromDmaBufs2) {
+      dri_image =
+         dri2_dpy->image->createImageFromDmaBufs2(dri2_dpy->dri_screen,
+            attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
+            fds, num_fds, pitches, offsets, modifiers,
+            attrs.DMABufYuvColorSpaceHint.Value,
+            attrs.DMABufSampleRangeHint.Value,
+            attrs.DMABufChromaHorizontalSiting.Value,
+            attrs.DMABufChromaVerticalSiting.Value,
+            &error,
+            NULL);
+   } else {
+      if (has_modifier) {
+         _eglError(EGL_BAD_MATCH, "unsupported dma_buf format modifier");
+         return EGL_NO_IMAGE_KHR;
+      }
+
+      dri_image =
+         dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
+            attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
+            fds, num_fds, pitches, offsets,
+            attrs.DMABufYuvColorSpaceHint.Value,
+            attrs.DMABufSampleRangeHint.Value,
+            attrs.DMABufChromaHorizontalSiting.Value,
+            attrs.DMABufChromaVerticalSiting.Value,
+            &error,
+            NULL);
+   }
    dri2_create_image_khr_texture_error(error);
 
    if (!dri_image)
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c
index fed390a..c558f2f 100644
--- a/src/egl/main/eglimage.c
+++ b/src/egl/main/eglimage.c
@@ -106,6 +106,18 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
          attrs->DMABufPlanePitches[0].Value = val;
          attrs->DMABufPlanePitches[0].IsPresent = EGL_TRUE;
          break;
+      case EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT:
+         if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
+            err = EGL_BAD_PARAMETER;
+         attrs->DMABufPlaneModifiersLo[0].Value = val;
+         attrs->DMABufPlaneModifiersLo[0].IsPresent = EGL_TRUE;
+         break;
+      case EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT:
+         if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
+            err = EGL_BAD_PARAMETER;
+         attrs->DMABufPlaneModifiersHi[0].Value = val;
+         attrs->DMABufPlaneModifiersHi[0].IsPresent = EGL_TRUE;
+         break;
       case EGL_DMA_BUF_PLANE1_FD_EXT:
          attrs->DMABufPlaneFds[1].Value = val;
          attrs->DMABufPlaneFds[1].IsPresent = EGL_TRUE;
@@ -118,6 +130,18 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
          attrs->DMABufPlanePitches[1].Value = val;
          attrs->DMABufPlanePitches[1].IsPresent = EGL_TRUE;
          break;
+      case EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT:
+         if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
+            err = EGL_BAD_PARAMETER;
+         attrs->DMABufPlaneModifiersLo[1].Value = val;
+         attrs->DMABufPlaneModifiersLo[1].IsPresent = EGL_TRUE;
+         break;
+      case EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT:
+         if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
+            err = EGL_BAD_PARAMETER;
+         attrs->DMABufPlaneModifiersHi[1].Value = val;
+         attrs->DMABufPlaneModifiersHi[1].IsPresent = EGL_TRUE;
+         break;
       case EGL_DMA_BUF_PLANE2_FD_EXT:
          attrs->DMABufPlaneFds[2].Value = val;
          attrs->DMABufPlaneFds[2].IsPresent = EGL_TRUE;
@@ -130,6 +154,18 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
          attrs->DMABufPlanePitches[2].Value = val;
          attrs->DMABufPlanePitches[2].IsPresent = EGL_TRUE;
          break;
+      case EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT:
+         if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
+            err = EGL_BAD_PARAMETER;
+         attrs->DMABufPlaneModifiersLo[2].Value = val;
+         attrs->DMABufPlaneModifiersLo[2].IsPresent = EGL_TRUE;
+         break;
+      case EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT:
+         if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
+            err = EGL_BAD_PARAMETER;
+         attrs->DMABufPlaneModifiersHi[2].Value = val;
+         attrs->DMABufPlaneModifiersHi[2].IsPresent = EGL_TRUE;
+         break;
       case EGL_DMA_BUF_PLANE3_FD_EXT:
          if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
             err = EGL_BAD_PARAMETER;
@@ -148,6 +184,18 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
          attrs->DMABufPlanePitches[3].Value = val;
          attrs->DMABufPlanePitches[3].IsPresent = EGL_TRUE;
          break;
+      case EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT:
+         if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
+            err = EGL_BAD_PARAMETER;
+         attrs->DMABufPlaneModifiersLo[3].Value = val;
+         attrs->DMABufPlaneModifiersLo[3].IsPresent = EGL_TRUE;
+         break;
+      case EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT:
+         if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
+            err = EGL_BAD_PARAMETER;
+         attrs->DMABufPlaneModifiersHi[3].Value = val;
+         attrs->DMABufPlaneModifiersHi[3].IsPresent = EGL_TRUE;
+         break;
       case EGL_YUV_COLOR_SPACE_HINT_EXT:
          if (val != EGL_ITU_REC601_EXT && val != EGL_ITU_REC709_EXT &&
              val != EGL_ITU_REC2020_EXT) {
diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h
index a909d9b..eb66280 100644
--- a/src/egl/main/eglimage.h
+++ b/src/egl/main/eglimage.h
@@ -73,6 +73,8 @@ struct _egl_image_attribs
    struct _egl_image_attrib_int DMABufPlaneFds[DMA_BUF_MAX_PLANES];
    struct _egl_image_attrib_int DMABufPlaneOffsets[DMA_BUF_MAX_PLANES];
    struct _egl_image_attrib_int DMABufPlanePitches[DMA_BUF_MAX_PLANES];
+   struct _egl_image_attrib_int DMABufPlaneModifiersLo[DMA_BUF_MAX_PLANES];
+   struct _egl_image_attrib_int DMABufPlaneModifiersHi[DMA_BUF_MAX_PLANES];
    struct _egl_image_attrib_int DMABufYuvColorSpaceHint;
    struct _egl_image_attrib_int DMABufSampleRangeHint;
    struct _egl_image_attrib_int DMABufChromaHorizontalSiting;
-- 
2.10.0



More information about the mesa-dev mailing list