<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, May 19, 2017 at 2:37 AM, Daniel Stone <span dir="ltr"><<a href="mailto:daniels@collabora.com" target="_blank">daniels@collabora.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Varad Gautam <<a href="mailto:varad.gautam@collabora.com">varad.gautam@collabora.com</a>><br>
<br>
Allow creating EGLImages with dmabuf format modifiers when target is<br>
EGL_LINUX_DMA_BUF_EXT for EGL_EXT_image_dma_buf_import_<wbr>modifiers.<br>
<br>
v2:<br>
 - clear modifier assembling and error label name (Eric Engestrom)<br>
v3:<br>
 - remove goto jumps within switch-case (Emil Velikov)<br>
 - treat zero as valid modifier (Daniel Stone)<br>
 - ensure same modifier across all dmabuf planes (Emil Velikov)<br>
v4:<br>
 - allow modifiers to add extra planes (Louis-Francis Ratté-Boulianne)<br>
<br>
Signed-off-by: Pekka Paalanen <<a href="mailto:pekka.paalanen@collabora.co.uk">pekka.paalanen@collabora.co.<wbr>uk</a>><br>
Signed-off-by: Varad Gautam <<a href="mailto:varad.gautam@collabora.com">varad.gautam@collabora.com</a>><br>
Signed-off-by: Louis-Francis Ratté-Boulianne <<a href="mailto:lfrb@collabora.com">lfrb@collabora.com</a>><br>
Reviewed-by: Eric Engestrom <<a href="mailto:eric.engestrom@imgtec.com">eric.engestrom@imgtec.com</a>><br>
Reviewed-by: Daniel Stone <<a href="mailto:daniels@collabora.com">daniels@collabora.com</a>><br>
Signed-off-by: Daniel Stone <<a href="mailto:daniels@collabora.com">daniels@collabora.com</a>><br>
---<br>
 src/egl/drivers/dri2/egl_dri2.<wbr>c | 95 ++++++++++++++++++++++++++++++<wbr>++++++-----<br>
 src/egl/main/eglimage.c         | 48 +++++++++++++++++++++<br>
 src/egl/main/eglimage.h         |  2 +<br>
 3 files changed, 134 insertions(+), 11 deletions(-)<br>
<br>
diff --git a/src/egl/drivers/dri2/egl_<wbr>dri2.c b/src/egl/drivers/dri2/egl_<wbr>dri2.c<br>
index ceffd281d5..f06b5535c7 100644<br>
--- a/src/egl/drivers/dri2/egl_<wbr>dri2.c<br>
+++ b/src/egl/drivers/dri2/egl_<wbr>dri2.c<br>
@@ -1949,6 +1949,33 @@ dri2_check_dma_buf_attribs(<wbr>const _EGLImageAttribs *attrs)<br>
       }<br>
    }<br>
<br>
+   /**<br>
+    * If <target> is EGL_LINUX_DMA_BUF_EXT, both or neither of the following<br>
+    * attribute values may be given.<br>
+    *<br>
+    * This is referring to EGL_DMA_BUF_PLANE0_MODIFIER_<wbr>LO_EXT and<br>
+    * EGL_DMA_BUF_PLANE0_MODIFIER_<wbr>HI_EXT, and the same for other planes.<br>
+    */<br>
+   for (i = 0; i < DMA_BUF_MAX_PLANES; ++i) {<br>
+      if (attrs-><wbr>DMABufPlaneModifiersLo[i].<wbr>IsPresent !=<br>
+          attrs->DMABufPlaneModifiersHi[<wbr>i].IsPresent) {<br>
+         _eglError(EGL_BAD_PARAMETER, "modifier attribute lo or hi missing");<br>
+         return EGL_FALSE;<br>
+      }<br>
+   }<br>
+<br>
+   for (i = 0; i < DMA_BUF_MAX_PLANES; ++i) {<br></blockquote><div><br></div><div>This loop could start at 1 instead of 0.  Also, you're checking that they all match but you aren't checking that they're all present if the 0th is present.  This also means that if 0 isn't present but 1 is, then you'll be checking 1 against uninitialized data in 0.  I think we want to fail if [0].IsPresent != [i].IsPresent.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+      if (attrs-><wbr>DMABufPlaneModifiersLo[i].<wbr>IsPresent) {<br>
+         if ((attrs-><wbr>DMABufPlaneModifiersLo[0].<wbr>Value !=<br>
+             attrs->DMABufPlaneModifiersLo[<wbr>i].Value) ||<br>
+             (attrs-><wbr>DMABufPlaneModifiersHi[0].<wbr>Value !=<br>
+             attrs->DMABufPlaneModifiersHi[<wbr>i].Value)) {<br>
+            _eglError(EGL_BAD_PARAMETER, "modifier attributes not equal");<br>
+            return EGL_FALSE;<br>
+         }<br>
+      }<br>
+   }<br>
+<br>
    return EGL_TRUE;<br>
 }<br>
<br>
@@ -2057,7 +2084,25 @@ dri2_check_dma_buf_format(<wbr>const _EGLImageAttribs *attrs)<br>
    for (i = plane_n; i < DMA_BUF_MAX_PLANES; ++i) {<br>
       if (attrs->DMABufPlaneFds[i].<wbr>IsPresent ||<br>
           attrs->DMABufPlaneOffsets[i].<wbr>IsPresent ||<br>
-          attrs->DMABufPlanePitches[i].<wbr>IsPresent) {<br>
+          attrs->DMABufPlanePitches[i].<wbr>IsPresent ||<br>
+          attrs->DMABufPlaneModifiersLo[<wbr>i].IsPresent ||<br>
+          attrs->DMABufPlaneModifiersHi[<wbr>i].IsPresent) {<br>
+<br>
+         /**<br>
+          * The modifiers extension spec says:<br>
+          *<br>
+          * "Modifiers may modify any attribute of a buffer import, including<br>
+          *  but not limited to adding extra planes to a format which<br>
+          *  otherwise does not have those planes. As an example, a modifier<br>
+          *  may add a plane for an external compression buffer to a<br>
+          *  single-plane format. The exact meaning and effect of any<br>
+          *  modifier is canonically defined by drm_fourcc.h, not as part of<br>
+          *  this extension."<br>
+          */<br>
+         if (attrs-><wbr>DMABufPlaneModifiersLo[i].<wbr>IsPresent &&<br>
+             attrs->DMABufPlaneModifiersHi[<wbr>i].IsPresent)<br>
+            continue;<br>
+<br>
          _eglError(EGL_BAD_ATTRIBUTE, "too many plane attributes");<br>
          return 0;<br>
       }<br>
@@ -2090,6 +2135,8 @@ dri2_create_image_dma_buf(_<wbr>EGLDisplay *disp, _EGLContext *ctx,<br>
    int fds[DMA_BUF_MAX_PLANES];<br>
    int pitches[DMA_BUF_MAX_PLANES];<br>
    int offsets[DMA_BUF_MAX_PLANES];<br>
+   uint64_t modifiers[DMA_BUF_MAX_PLANES];<br>
+   bool has_modifier = false;<br>
    unsigned error;<br>
<br>
    /**<br>
@@ -2120,18 +2167,44 @@ dri2_create_image_dma_buf(_<wbr>EGLDisplay *disp, _EGLContext *ctx,<br>
       fds[i] = attrs.DMABufPlaneFds[i].Value;<br>
       pitches[i] = attrs.DMABufPlanePitches[i].<wbr>Value;<br>
       offsets[i] = attrs.DMABufPlaneOffsets[i].<wbr>Value;<br>
+      if (attrs.DMABufPlaneModifiersLo[<wbr>i].IsPresent) {<br>
+         modifiers[i] =<br>
+            ((uint64_t) attrs.DMABufPlaneModifiersHi[<wbr>i].Value << 32) |<br>
+            attrs.DMABufPlaneModifiersLo[<wbr>i].Value;<br>
+         has_modifier = true;<br>
+      } else {<br>
+         modifiers[i] = 0;<br></blockquote><div><br></div><div>Do we really want 0 here?  How about INVALID?  Not that it matters since they're all required to be the same...<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+      }<br>
    }<br>
<br>
-   dri_image =<br>
-      dri2_dpy->image-><wbr>createImageFromDmaBufs(dri2_<wbr>dpy->dri_screen,<br>
-         attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,<br>
-         fds, num_fds, pitches, offsets,<br>
-         attrs.DMABufYuvColorSpaceHint.<wbr>Value,<br>
-         attrs.DMABufSampleRangeHint.<wbr>Value,<br>
-         attrs.<wbr>DMABufChromaHorizontalSiting.<wbr>Value,<br>
-         attrs.<wbr>DMABufChromaVerticalSiting.<wbr>Value,<br>
-         &error,<br>
-         NULL);<br>
+   if (has_modifier && dri2_dpy->image-><wbr>createImageFromDmaBufs2) {<br></blockquote><div><br></div><div>I think we need a version check here as well.  How about<br><br></div><div>if (has_modifier) {<br></div><div>   if (dri2_dpy->image->base.version < 15 ||<br>       dri2_dpy->image-><wbr>createImageFromDmaBufs2 == NULL) {<br>        _eglError(EGL_BAD_MATCH, "unsupported dma_buf format modifier");<br>
        return EGL_NO_IMAGE_KHR;<br>   }<br><br></div><div>   /* Do the import */<br></div><div>} else {<br></div><div>   /* Do the import without modifiers */<br></div><div>}<br><br></div><div>That also makes the check conditional on has_modifier which, IMHO, is easier to read than putting the error for "you don't have the DRI extension" right before the fallback.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+      dri_image =<br>
+         dri2_dpy->image-><wbr>createImageFromDmaBufs2(dri2_<wbr>dpy->dri_screen,<br>
+            attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,<br>
+            fds, num_fds, pitches, offsets, modifiers,<br>
+            attrs.DMABufYuvColorSpaceHint.<wbr>Value,<br>
+            attrs.DMABufSampleRangeHint.<wbr>Value,<br>
+            attrs.<wbr>DMABufChromaHorizontalSiting.<wbr>Value,<br>
+            attrs.<wbr>DMABufChromaVerticalSiting.<wbr>Value,<br>
+            &error,<br>
+            NULL);<br>
+   } else {<br>
+      if (has_modifier) {<br>
+         _eglError(EGL_BAD_MATCH, "unsupported dma_buf format modifier");<br>
+         return EGL_NO_IMAGE_KHR;<br>
+      }<br>
+<br>
+      dri_image =<br>
+         dri2_dpy->image-><wbr>createImageFromDmaBufs(dri2_<wbr>dpy->dri_screen,<br>
+            attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,<br>
+            fds, num_fds, pitches, offsets,<br>
+            attrs.DMABufYuvColorSpaceHint.<wbr>Value,<br>
+            attrs.DMABufSampleRangeHint.<wbr>Value,<br>
+            attrs.<wbr>DMABufChromaHorizontalSiting.<wbr>Value,<br>
+            attrs.<wbr>DMABufChromaVerticalSiting.<wbr>Value,<br>
+            &error,<br>
+            NULL);<br>
+   }<br>
    dri2_create_image_khr_texture_<wbr>error(error);<br>
<br>
    if (!dri_image)<br>
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c<br>
index fed390a498..c558f2f02b 100644<br>
--- a/src/egl/main/eglimage.c<br>
+++ b/src/egl/main/eglimage.c<br>
@@ -106,6 +106,18 @@ _eglParseImageAttribList(_<wbr>EGLImageAttribs *attrs, _EGLDisplay *dpy,<br>
          attrs->DMABufPlanePitches[0].<wbr>Value = val;<br>
          attrs->DMABufPlanePitches[0].<wbr>IsPresent = EGL_TRUE;<br>
          break;<br>
+      case EGL_DMA_BUF_PLANE0_MODIFIER_<wbr>LO_EXT:<br>
+         if (!dpy->Extensions.EXT_image_<wbr>dma_buf_import_modifiers)<br>
+            err = EGL_BAD_PARAMETER;<br>
+         attrs->DMABufPlaneModifiersLo[<wbr>0].Value = val;<br>
+         attrs->DMABufPlaneModifiersLo[<wbr>0].IsPresent = EGL_TRUE;<br>
+         break;<br>
+      case EGL_DMA_BUF_PLANE0_MODIFIER_<wbr>HI_EXT:<br>
+         if (!dpy->Extensions.EXT_image_<wbr>dma_buf_import_modifiers)<br>
+            err = EGL_BAD_PARAMETER;<br>
+         attrs->DMABufPlaneModifiersHi[<wbr>0].Value = val;<br>
+         attrs->DMABufPlaneModifiersHi[<wbr>0].IsPresent = EGL_TRUE;<br>
+         break;<br></blockquote><div><br></div><div>This code looks like it's badly in need of a macro... Not that you need to add one in this patch, but ouch...<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
       case EGL_DMA_BUF_PLANE1_FD_EXT:<br>
          attrs->DMABufPlaneFds[1].Value = val;<br>
          attrs->DMABufPlaneFds[1].<wbr>IsPresent = EGL_TRUE;<br>
@@ -118,6 +130,18 @@ _eglParseImageAttribList(_<wbr>EGLImageAttribs *attrs, _EGLDisplay *dpy,<br>
          attrs->DMABufPlanePitches[1].<wbr>Value = val;<br>
          attrs->DMABufPlanePitches[1].<wbr>IsPresent = EGL_TRUE;<br>
          break;<br>
+      case EGL_DMA_BUF_PLANE1_MODIFIER_<wbr>LO_EXT:<br>
+         if (!dpy->Extensions.EXT_image_<wbr>dma_buf_import_modifiers)<br>
+            err = EGL_BAD_PARAMETER;<br>
+         attrs->DMABufPlaneModifiersLo[<wbr>1].Value = val;<br>
+         attrs->DMABufPlaneModifiersLo[<wbr>1].IsPresent = EGL_TRUE;<br>
+         break;<br>
+      case EGL_DMA_BUF_PLANE1_MODIFIER_<wbr>HI_EXT:<br>
+         if (!dpy->Extensions.EXT_image_<wbr>dma_buf_import_modifiers)<br>
+            err = EGL_BAD_PARAMETER;<br>
+         attrs->DMABufPlaneModifiersHi[<wbr>1].Value = val;<br>
+         attrs->DMABufPlaneModifiersHi[<wbr>1].IsPresent = EGL_TRUE;<br>
+         break;<br>
       case EGL_DMA_BUF_PLANE2_FD_EXT:<br>
          attrs->DMABufPlaneFds[2].Value = val;<br>
          attrs->DMABufPlaneFds[2].<wbr>IsPresent = EGL_TRUE;<br>
@@ -130,6 +154,18 @@ _eglParseImageAttribList(_<wbr>EGLImageAttribs *attrs, _EGLDisplay *dpy,<br>
          attrs->DMABufPlanePitches[2].<wbr>Value = val;<br>
          attrs->DMABufPlanePitches[2].<wbr>IsPresent = EGL_TRUE;<br>
          break;<br>
+      case EGL_DMA_BUF_PLANE2_MODIFIER_<wbr>LO_EXT:<br>
+         if (!dpy->Extensions.EXT_image_<wbr>dma_buf_import_modifiers)<br>
+            err = EGL_BAD_PARAMETER;<br>
+         attrs->DMABufPlaneModifiersLo[<wbr>2].Value = val;<br>
+         attrs->DMABufPlaneModifiersLo[<wbr>2].IsPresent = EGL_TRUE;<br>
+         break;<br>
+      case EGL_DMA_BUF_PLANE2_MODIFIER_<wbr>HI_EXT:<br>
+         if (!dpy->Extensions.EXT_image_<wbr>dma_buf_import_modifiers)<br>
+            err = EGL_BAD_PARAMETER;<br>
+         attrs->DMABufPlaneModifiersHi[<wbr>2].Value = val;<br>
+         attrs->DMABufPlaneModifiersHi[<wbr>2].IsPresent = EGL_TRUE;<br>
+         break;<br>
       case EGL_DMA_BUF_PLANE3_FD_EXT:<br>
          if (!dpy->Extensions.EXT_image_<wbr>dma_buf_import_modifiers)<br>
             err = EGL_BAD_PARAMETER;<br>
@@ -148,6 +184,18 @@ _eglParseImageAttribList(_<wbr>EGLImageAttribs *attrs, _EGLDisplay *dpy,<br>
          attrs->DMABufPlanePitches[3].<wbr>Value = val;<br>
          attrs->DMABufPlanePitches[3].<wbr>IsPresent = EGL_TRUE;<br>
          break;<br>
+      case EGL_DMA_BUF_PLANE3_MODIFIER_<wbr>LO_EXT:<br>
+         if (!dpy->Extensions.EXT_image_<wbr>dma_buf_import_modifiers)<br>
+            err = EGL_BAD_PARAMETER;<br>
+         attrs->DMABufPlaneModifiersLo[<wbr>3].Value = val;<br>
+         attrs->DMABufPlaneModifiersLo[<wbr>3].IsPresent = EGL_TRUE;<br>
+         break;<br>
+      case EGL_DMA_BUF_PLANE3_MODIFIER_<wbr>HI_EXT:<br>
+         if (!dpy->Extensions.EXT_image_<wbr>dma_buf_import_modifiers)<br>
+            err = EGL_BAD_PARAMETER;<br>
+         attrs->DMABufPlaneModifiersHi[<wbr>3].Value = val;<br>
+         attrs->DMABufPlaneModifiersHi[<wbr>3].IsPresent = EGL_TRUE;<br>
+         break;<br>
       case EGL_YUV_COLOR_SPACE_HINT_EXT:<br>
          if (val != EGL_ITU_REC601_EXT && val != EGL_ITU_REC709_EXT &&<br>
              val != EGL_ITU_REC2020_EXT) {<br>
diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h<br>
index a909d9b588..eb66280ff9 100644<br>
--- a/src/egl/main/eglimage.h<br>
+++ b/src/egl/main/eglimage.h<br>
@@ -73,6 +73,8 @@ struct _egl_image_attribs<br>
    struct _egl_image_attrib_int DMABufPlaneFds[DMA_BUF_MAX_<wbr>PLANES];<br>
    struct _egl_image_attrib_int DMABufPlaneOffsets[DMA_BUF_<wbr>MAX_PLANES];<br>
    struct _egl_image_attrib_int DMABufPlanePitches[DMA_BUF_<wbr>MAX_PLANES];<br>
+   struct _egl_image_attrib_int DMABufPlaneModifiersLo[DMA_<wbr>BUF_MAX_PLANES];<br>
+   struct _egl_image_attrib_int DMABufPlaneModifiersHi[DMA_<wbr>BUF_MAX_PLANES];<br>
    struct _egl_image_attrib_int DMABufYuvColorSpaceHint;<br>
    struct _egl_image_attrib_int DMABufSampleRangeHint;<br>
    struct _egl_image_attrib_int DMABufChromaHorizontalSiting;<br>
<span class="gmail-HOEnZb"><font color="#888888">--<br>
2.13.0<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>