<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Mar 9, 2017 at 5:48 PM, Ben Widawsky <span dir="ltr"><<a href="mailto:ben@bwidawsk.net" target="_blank">ben@bwidawsk.net</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">The idea behind modifiers like this is that the user of GBM will have<br>
some mechanism to query what properties the hardware supports for its BO<br>
or surface. This information is directly passed in (and stored) so that<br>
the DRI implementation can create an image with the appropriate<br>
attributes.<br>
<br>
A getter() will be added later so that the user GBM will be able to<br>
query what modifier should be used.<br>
<br>
Only in surface creation, the modifiers are stored until the BO is<br>
actually allocated. In regular buffer allocation, the correct modifier<br>
can (will be, in future patches be chosen at creation time.<br>
<br>
v2: Make sure to check if count is non-zero in addition to testing if<br>
calloc fails. (Daniel)<br>
<br>
v3: Remove "usage" and "flags" from modifier creation. Requested by<br>
Kristian.<br>
<br>
v4: Take advantage of the "INVALID" modifier added by the GET_PLANE2<br>
series.<br>
<br>
v5: Don't bother with storing modifiers for gbm_bo_create because that's<br>
a synchronous operation and we can actually select the correct modifier<br>
at create time (done in a later patch) (Jason)<br>
<br>
Cc: Kristian Høgsberg <<a href="mailto:krh@bitplanet.net" target="_blank">krh@bitplanet.net</a>><br>
Cc: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>><br>
References (v4): <a href="https://lists.freedesktop.org/archives/intel-gfx/2017-January/116636.html" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>archives/intel-gfx/2017-Januar<wbr>y/116636.html</a><br>
Signed-off-by: Ben Widawsky <<a href="mailto:ben@bwidawsk.net" target="_blank">ben@bwidawsk.net</a>><br>
Reviewed-by: Eric Engestrom <<a href="mailto:eric.engestrom@imgtec.com" target="_blank">eric.engestrom@imgtec.com</a>> (v1)<br>
Acked-by: Daniel Stone <<a href="mailto:daniels@collabora.com" target="_blank">daniels@collabora.com</a>><br>
---<br>
 src/egl/drivers/dri2/<wbr>platform_drm.c      | 19 ++++++++++++---<br>
 src/gbm/backends/dri/gbm_dri.<wbr>c           | 42 ++++++++++++++++++++++++++----<wbr>--<br>
 src/gbm/gbm-symbols-check                |  2 ++<br>
 src/gbm/main/gbm.c                       | 29 ++++++++++++++++++++--<br>
 src/gbm/main/gbm.h                       | 12 +++++++++<br>
 src/gbm/main/gbmint.h                    | 12 +++++++--<br>
 src/mesa/drivers/dri/i965/int<wbr>el_screen.c | 18 ++++++++++++++<br>
 7 files changed, 119 insertions(+), 15 deletions(-)<br>
<br>
diff --git a/src/egl/drivers/dri2/platfor<wbr>m_drm.c b/src/egl/drivers/dri2/platfor<wbr>m_drm.c<br>
index e5e8c60596..cf35ce8a1f 100644<br>
--- a/src/egl/drivers/dri2/platfor<wbr>m_drm.c<br>
+++ b/src/egl/drivers/dri2/platfor<wbr>m_drm.c<br>
@@ -230,10 +230,21 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)<br>
<br>
    if (dri2_surf->back == NULL)<br>
       return -1;<br>
-   if (dri2_surf->back->bo == NULL)<br>
-      dri2_surf->back->bo = gbm_bo_create(&dri2_dpy->gbm_d<wbr>ri->base.base,<br>
-                                         surf->base.width, surf->base.height,<br>
-                                         surf->base.format, surf->base.flags);<br>
+   if (dri2_surf->back->bo == NULL) {<br>
+      if (surf->base.modifiers)<br>
+         dri2_surf->back->bo = gbm_bo_create_with_modifiers(&<wbr>dri2_dpy->gbm_dri->base.base,<br>
+                                                            surf->base.width, surf->base.height,<br>
+                                                            surf->base.format,<br>
+                                                            surf->base.modifiers,<br>
+                                                            surf->base.count);<br>
+      else<br>
+         dri2_surf->back->bo = gbm_bo_create(&dri2_dpy->gbm_d<wbr>ri->base.base,<br>
+                                             surf->base.width,<br>
+                                             surf->base.height,<br>
+                                             surf->base.format,<br>
+                                             surf->base.flags);<br>
+<br>
+   }<br>
    if (dri2_surf->back->bo == NULL)<br>
       return -1;<br>
<br>
diff --git a/src/gbm/backends/dri/gbm_dri<wbr>.c b/src/gbm/backends/dri/gbm_dri<wbr>.c<br>
index 7106dc1229..d45ba94080 100644<br>
--- a/src/gbm/backends/dri/gbm_dri<wbr>.c<br>
+++ b/src/gbm/backends/dri/gbm_dri<wbr>.c<br>
@@ -1023,13 +1023,20 @@ free_bo:<br>
 static struct gbm_bo *<br>
 gbm_dri_bo_create(struct gbm_device *gbm,<br>
                   uint32_t width, uint32_t height,<br>
-                  uint32_t format, uint32_t usage)<br>
+                  uint32_t format, uint32_t usage,<br>
+                  const uint64_t *modifiers,<br>
+                  const unsigned int count)<br>
 {<br>
    struct gbm_dri_device *dri = gbm_dri_device(gbm);<br>
    struct gbm_dri_bo *bo;<br>
    int dri_format;<br>
    unsigned dri_use = 0;<br>
<br>
+   /* Callers of this may specify a modifier, or a dri usage, but not both. The<br>
+    * newer modifier interface deprecates the older usage flags.<br>
+    */<br>
+   assert(!(usage && count));<br>
+<br>
    if (usage & GBM_BO_USE_WRITE || dri->image == NULL)<br>
       return create_dumb(gbm, width, height, format, usage);<br>
<br>
@@ -1087,11 +1094,21 @@ gbm_dri_bo_create(struct gbm_device *gbm,<br>
    /* Gallium drivers requires shared in order to get the handle/stride */<br>
    dri_use |= __DRI_IMAGE_USE_SHARE;<br>
<br>
-   bo->image =<br>
-      dri->image->createImage(dri->s<wbr>creen,<br>
-                              width, height,<br>
-                              dri_format, dri_use,<br>
-                              bo);<br>
+   if (!dri->image || dri->image->base.version < 14 ||<br>
+       !dri->image->createImageWithM<wbr>odifiers) {<br>
+      if (modifiers)<br>
+         fprintf(stderr, "Modifiers specified, but DRI is too old\n");<br></blockquote><div><br></div><div>This seems a bit on the sketchy side.  Do we want to fail, set errno to ENOSYS, and return NULL in this case?  I'm not really sure how GBM versioning works.  Daniel?  Kristian?<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>
+      bo->image = dri->image->createImage(dri->s<wbr>creen, width, height,<br>
+                                          dri_format, dri_use, bo);<br>
+   } else {<br>
+      bo->image =<br>
+         dri->image->createImageWithMo<wbr>difiers(dri->screen,<br>
+                                              width, height,<br>
+                                              dri_format,<br>
+                                              modifiers, count,<br>
+                                              bo);<br>
+   }<br>
    if (bo->image == NULL)<br>
       goto failed;<br>
<br>
@@ -1165,7 +1182,8 @@ gbm_dri_bo_unmap(struct gbm_bo *_bo, void *map_data)<br>
 static struct gbm_surface *<br>
 gbm_dri_surface_create(struct gbm_device *gbm,<br>
                        uint32_t width, uint32_t height,<br>
-                      uint32_t format, uint32_t flags)<br>
+                      uint32_t format, uint32_t flags,<br>
+                       const uint64_t *modifiers, const unsigned count)<br>
 {<br>
    struct gbm_dri_surface *surf;<br>
<br>
@@ -1179,6 +1197,15 @@ gbm_dri_surface_create(struct gbm_device *gbm,<br>
    surf->base.format = format;<br>
    surf->base.flags = flags;<br></blockquote><div><br>Dumb question, but do we also want to check the DRI version here as well?  Maybe something like<br><br></div><div>if (modifiers &&<br>    (!dri->image || dri->image->base.version < 14 ||<br>     !dri->image->createImageWithMo<wbr>difiers)) {<br></div><div>   errno = ENOSYS;<br></div><div>   return NULL;<br>}<br><br></div><div>That way the user can't create a surface that will fail to get a back buffer above.  Also, do we want to set errno?<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">
+   surf->base.modifiers = calloc(count, sizeof(*modifiers));<br>
+   if (count && !surf->base.modifiers) {<br>
+      free(surf);<br>
+      return NULL;<br>
+   }<br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+   surf->base.count = count;<br>
+   memcpy(surf->base.modifiers, modifiers, count * sizeof(*modifiers));<br>
+<br>
    return &surf->base;<br>
 }<br>
<br>
@@ -1187,6 +1214,7 @@ gbm_dri_surface_destroy(struct gbm_surface *_surf)<br>
 {<br>
    struct gbm_dri_surface *surf = gbm_dri_surface(_surf);<br>
<br>
+   free(surf->base.modifiers);<br>
    free(surf);<br>
 }<br>
<br>
diff --git a/src/gbm/gbm-symbols-check b/src/gbm/gbm-symbols-check<br>
index 7ff78ab400..c137c6cd93 100755<br>
--- a/src/gbm/gbm-symbols-check<br>
+++ b/src/gbm/gbm-symbols-check<br>
@@ -8,6 +8,7 @@ gbm_device_is_format_supported<br>
 gbm_device_destroy<br>
 gbm_create_device<br>
 gbm_bo_create<br>
+gbm_bo_create_with_modifiers<br>
 gbm_bo_import<br>
 gbm_bo_map<br>
 gbm_bo_unmap<br>
@@ -27,6 +28,7 @@ gbm_bo_set_user_data<br>
 gbm_bo_get_user_data<br>
 gbm_bo_destroy<br>
 gbm_surface_create<br>
+gbm_surface_create_with_modif<wbr>iers<br>
 gbm_surface_needs_lock_front_<wbr>buffer<br>
 gbm_surface_lock_front_buffer<br>
 gbm_surface_release_buffer<br>
diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c<br>
index afcca63da3..0fb62657ed 100644<br>
--- a/src/gbm/main/gbm.c<br>
+++ b/src/gbm/main/gbm.c<br>
@@ -369,9 +369,23 @@ gbm_bo_create(struct gbm_device *gbm,<br>
       return NULL;<br>
    }<br>
<br>
-   return gbm->bo_create(gbm, width, height, format, usage);<br>
+   return gbm->bo_create(gbm, width, height, format, usage, NULL, 0);<br>
 }<br>
<br>
+GBM_EXPORT struct gbm_bo *<br>
+gbm_bo_create_with_modifiers(<wbr>struct gbm_device *gbm,<br>
+                             uint32_t width, uint32_t height,<br>
+                             uint32_t format,<br>
+                             const uint64_t *modifiers,<br>
+                             const unsigned int count)<br>
+{<br>
+   if (width == 0 || height == 0) {<br>
+      errno = EINVAL;<br>
+      return NULL;<br>
+   }<br>
+<br>
+   return gbm->bo_create(gbm, width, height, format, 0, modifiers, count);<br>
+}<br>
 /**<br>
  * Create a gbm buffer object from an foreign object<br>
  *<br>
@@ -477,7 +491,18 @@ gbm_surface_create(struct gbm_device *gbm,<br>
                    uint32_t width, uint32_t height,<br>
                   uint32_t format, uint32_t flags)<br>
 {<br>
-   return gbm->surface_create(gbm, width, height, format, flags);<br>
+   return gbm->surface_create(gbm, width, height, format, flags, NULL, 0);<br>
+}<br>
+<br>
+GBM_EXPORT struct gbm_surface *<br>
+gbm_surface_create_with_modif<wbr>iers(struct gbm_device *gbm,<br>
+                                  uint32_t width, uint32_t height,<br>
+                                  uint32_t format,<br>
+                                  const uint64_t *modifiers,<br>
+                                  const unsigned int count)<br>
+{<br>
+   return gbm->surface_create(gbm, width, height, format, 0,<br>
+                              modifiers, count);<br>
 }<br>
<br>
 /**<br>
diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h<br>
index e3e5d34d97..5f588dab58 100644<br>
--- a/src/gbm/main/gbm.h<br>
+++ b/src/gbm/main/gbm.h<br>
@@ -243,6 +243,12 @@ gbm_bo_create(struct gbm_device *gbm,<br>
               uint32_t width, uint32_t height,<br>
               uint32_t format, uint32_t flags);<br>
<br>
+struct gbm_bo *<br>
+gbm_bo_create_with_modifiers(<wbr>struct gbm_device *gbm,<br>
+                             uint32_t width, uint32_t height,<br>
+                             uint32_t format,<br>
+                             const uint64_t *modifiers,<br>
+                             const unsigned int count);<br>
 #define GBM_BO_IMPORT_WL_BUFFER         0x5501<br>
 #define GBM_BO_IMPORT_EGL_IMAGE         0x5502<br>
 #define GBM_BO_IMPORT_FD                0x5503<br>
@@ -345,6 +351,12 @@ gbm_surface_create(struct gbm_device *gbm,<br>
                    uint32_t width, uint32_t height,<br>
                   uint32_t format, uint32_t flags);<br>
<br>
+struct gbm_surface *<br>
+gbm_surface_create_with_modif<wbr>iers(struct gbm_device *gbm,<br>
+                                  uint32_t width, uint32_t height,<br>
+                                  uint32_t format,<br>
+                                  const uint64_t *modifiers,<br>
+                                  const unsigned int count);<br>
 int<br>
 gbm_surface_needs_lock_front_<wbr>buffer(struct gbm_surface *surface);<br>
<br>
diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h<br>
index a6541d91c5..d8c9f6e5d7 100644<br>
--- a/src/gbm/main/gbmint.h<br>
+++ b/src/gbm/main/gbmint.h<br>
@@ -65,7 +65,9 @@ struct gbm_device {<br>
    struct gbm_bo *(*bo_create)(struct gbm_device *gbm,<br>
                                uint32_t width, uint32_t height,<br>
                                uint32_t format,<br>
-                               uint32_t usage);<br>
+                               uint32_t usage,<br>
+                               const uint64_t *modifiers,<br>
+                               const unsigned int count);<br>
    struct gbm_bo *(*bo_import)(struct gbm_device *gbm, uint32_t type,<br>
                                void *buffer, uint32_t usage);<br>
    void *(*bo_map)(struct gbm_bo *bo,<br>
@@ -84,7 +86,9 @@ struct gbm_device {<br>
<br>
    struct gbm_surface *(*surface_create)(struct gbm_device *gbm,<br>
                                          uint32_t width, uint32_t height,<br>
-                                         uint32_t format, uint32_t flags);<br>
+                                         uint32_t format, uint32_t flags,<br>
+                                         const uint64_t *modifiers,<br>
+                                         const unsigned count);<br>
    struct gbm_bo *(*surface_lock_front_buffer)(<wbr>struct gbm_surface *surface);<br>
    void (*surface_release_buffer)(stru<wbr>ct gbm_surface *surface,<br>
                                   struct gbm_bo *bo);<br>
@@ -114,6 +118,10 @@ struct gbm_surface {<br>
    uint32_t height;<br>
    uint32_t format;<br>
    uint32_t flags;<br>
+   struct {<br>
+      uint64_t *modifiers;<br>
+      unsigned count;<br>
+   };<br>
 };<br>
<br>
 struct gbm_backend {<br>
diff --git a/src/mesa/drivers/dri/i965/in<wbr>tel_screen.c b/src/mesa/drivers/dri/i965/in<wbr>tel_screen.c<br>
index 3452572874..395a71b3b3 100644<br>
--- a/src/mesa/drivers/dri/i965/in<wbr>tel_screen.c<br>
+++ b/src/mesa/drivers/dri/i965/in<wbr>tel_screen.c<br>
@@ -41,6 +41,10 @@<br>
 #include "utils.h"<br>
 #include "xmlpool.h"<br>
<br>
+#ifndef DRM_FORMAT_MOD_INVALID<br>
+#define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1)<br>
+#endif<br>
+<br>
 static const __DRIconfigOptionsExtension brw_config_options = {<br>
    .base = { __DRI_CONFIG_OPTIONS, 1 },<br>
    .xml =<br>
@@ -509,6 +513,14 @@ intel_destroy_image(__DRIimage *image)<br>
    free(image);<br>
 }<br>
<br>
+static uint64_t<br>
+select_best_modifier(struct gen_device_info *devinfo,<br>
+                     const uint64_t *modifiers,<br>
+                     const unsigned count)<br>
+{<br>
+   return DRM_FORMAT_MOD_INVALID;<br>
+}<br>
+<br>
 static __DRIimage *<br>
 __intel_create_image(__DRIscr<wbr>een *dri_screen,<br>
                   int width, int height, int format,<br>
@@ -529,6 +541,12 @@ __intel_create_image(__DRIscre<wbr>en *dri_screen,<br>
     */<br>
    assert(!(use && count));<br>
<br>
+   uint64_t modifier = select_best_modifier(&screen-><wbr>devinfo, modifiers, count);<br>
+   assert(modifier == DRM_FORMAT_MOD_INVALID);<br>
+<br>
+   /* Historically, X-tiled was the default, and so lack of modifier means<br>
+    * X-tiled.<br>
+    */<br>
    tiling = I915_TILING_X;<br>
    if (use & __DRI_IMAGE_USE_CURSOR) {<br>
       if (width != 64 || height != 64)<br>
<span class="m_-3364312239593630779gmail-HOEnZb"><font color="#888888">--<br>
2.12.0<br>
<br>
</font></span></blockquote></div><br></div></div>