st/dri: implement createImageWithModifiers in DRIimage
authorVarad Gautam <varad.gautam@collabora.com>
Tue, 30 May 2017 11:53:43 +0000 (17:23 +0530)
committerEmil Velikov <emil.l.velikov@gmail.com>
Fri, 9 Jun 2017 13:12:37 +0000 (14:12 +0100)
adds a pscreen->resource_create_with_modifiers() to create textures
with modifier.

v2:
- stylefixes (Emil Velikov)
- don't return selected modifier from resource_create_with_modifiers. we can
  use the winsys_handle to get this.

Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de> (v1)
Cc: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
src/gallium/include/pipe/p_screen.h
src/gallium/state_trackers/dri/dri2.c

index 8b4239c61aedbf661ccc3f8ce238657ef5c3cf72..5102827440ee08185d3aa8850776129cb362e7ad 100644 (file)
@@ -328,6 +328,21 @@ struct pipe_screen {
     * driver doesn't support an on-disk shader cache.
     */
    struct disk_cache *(*get_disk_shader_cache)(struct pipe_screen *screen);
+
+   /**
+    * Create a new texture object from the given template info, taking
+    * format modifiers into account. \p modifiers specifies a list of format
+    * modifier tokens, as defined in drm_fourcc.h. The driver then picks the
+    * best modifier among these and creates the resource. \p count must
+    * contain the size of \p modifiers array.
+    *
+    * Returns NULL if an entry in \p modifiers is unsupported by the driver,
+    * or if only DRM_FORMAT_MOD_INVALID is provided.
+    */
+   struct pipe_resource * (*resource_create_with_modifiers)(
+                           struct pipe_screen *,
+                           const struct pipe_resource *templat,
+                           const uint64_t *modifiers, int count);
 };
 
 
index 465100b0edaf08fbae1a31fb7f8db94d7150a7ab..5f1cd0429e3c13214e4b9f0ad0126ccdc962a6a2 100644 (file)
@@ -971,9 +971,12 @@ dri2_create_image_from_renderbuffer(__DRIcontext *context,
 }
 
 static __DRIimage *
-dri2_create_image(__DRIscreen *_screen,
-                   int width, int height, int format,
-                   unsigned int use, void *loaderPrivate)
+dri2_create_image_common(__DRIscreen *_screen,
+                         int width, int height,
+                         int format, unsigned int use,
+                         const uint64_t *modifiers,
+                         const unsigned count,
+                         void *loaderPrivate)
 {
    struct dri_screen *screen = dri_screen(_screen);
    __DRIimage *img;
@@ -981,7 +984,13 @@ dri2_create_image(__DRIscreen *_screen,
    unsigned tex_usage;
    enum pipe_format pf;
 
+   /* createImageWithModifiers doesn't supply usage, and we should not get
+    * here with both modifiers and a usage flag.
+    */
+   assert(!(use && (modifiers != NULL)));
+
    tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+
    if (use & __DRI_IMAGE_USE_SCANOUT)
       tex_usage |= PIPE_BIND_SCANOUT;
    if (use & __DRI_IMAGE_USE_SHARE)
@@ -1012,7 +1021,16 @@ dri2_create_image(__DRIscreen *_screen,
    templ.depth0 = 1;
    templ.array_size = 1;
 
-   img->texture = screen->base.screen->resource_create(screen->base.screen, &templ);
+   if (modifiers)
+      img->texture =
+         screen->base.screen
+            ->resource_create_with_modifiers(screen->base.screen,
+                                             &templ,
+                                             modifiers,
+                                             count);
+   else
+      img->texture =
+         screen->base.screen->resource_create(screen->base.screen, &templ);
    if (!img->texture) {
       FREE(img);
       return NULL;
@@ -1028,6 +1046,28 @@ dri2_create_image(__DRIscreen *_screen,
    return img;
 }
 
+static __DRIimage *
+dri2_create_image(__DRIscreen *_screen,
+                   int width, int height, int format,
+                   unsigned int use, void *loaderPrivate)
+{
+   return dri2_create_image_common(_screen, width, height, format, use,
+                                   NULL /* modifiers */, 0 /* count */,
+                                   loaderPrivate);
+}
+
+static __DRIimage *
+dri2_create_image_with_modifiers(__DRIscreen *dri_screen,
+                                 int width, int height, int format,
+                                 const uint64_t *modifiers,
+                                 const unsigned count,
+                                 void *loaderPrivate)
+{
+   return dri2_create_image_common(dri_screen, width, height, format,
+                                   0 /* use */, modifiers, count,
+                                   loaderPrivate);
+}
+
 static GLboolean
 dri2_query_image(__DRIimage *image, int attrib, int *value)
 {
@@ -1414,7 +1454,7 @@ dri2_get_capabilities(__DRIscreen *_screen)
 
 /* The extension is modified during runtime if DRI_PRIME is detected */
 static __DRIimageExtension dri2ImageExtension = {
-    .base = { __DRI_IMAGE, 12 },
+    .base = { __DRI_IMAGE, 14 },
 
     .createImageFromName          = dri2_create_image_from_name,
     .createImageFromRenderbuffer  = dri2_create_image_from_renderbuffer,
@@ -1831,6 +1871,10 @@ dri2_init_screen(__DRIscreen * sPriv)
       screen->default_throttle_frames = throttle_ret->val.val_int;
    }
 
+   if (pscreen->resource_create_with_modifiers)
+      dri2ImageExtension.createImageWithModifiers =
+         dri2_create_image_with_modifiers;
+
    if (dmabuf_ret && dmabuf_ret->val.val_bool) {
       uint64_t cap;
 
@@ -1906,6 +1950,10 @@ dri_kms_init_screen(__DRIscreen * sPriv)
    if (!pscreen)
        goto release_pipe;
 
+   if (pscreen->resource_create_with_modifiers)
+      dri2ImageExtension.createImageWithModifiers =
+         dri2_create_image_with_modifiers;
+
    if (drmGetCap(sPriv->fd, DRM_CAP_PRIME, &cap) == 0 &&
           (cap & DRM_PRIME_CAP_IMPORT)) {
       dri2ImageExtension.createImageFromFds = dri2_from_fds;