i965/dri: Handle the linear fb modifier
authorBen Widawsky <ben@bwidawsk.net>
Fri, 13 Jan 2017 20:01:37 +0000 (12:01 -0800)
committerBen Widawsky <ben@bwidawsk.net>
Tue, 21 Mar 2017 21:48:12 +0000 (14:48 -0700)
At image creation create a path for dealing with the linear modifier.
This works exactly like the old usage flags where __DRI_IMAGE_USE_LINEAR
was specified.

During development of this patch series, it was decided that a lack of
modifier was an insufficient way to express the required modifiers. As a
result, 0 was repurposed to mean a modifier for a LINEAR layout.

NOTE: This patch was added for v3 of the patch series.

v2: Rework the algorithm for modifier selection to go from a bitmask
based selection to this priority value.

v3: Make DRM_FORMAT_MOD_INVALID allowed at selection as a way of
identifying no modifiers found (because 0 is LINEAR) (Jason)

v4: Remove the logic to prune unknown modifiers (like those from other
vendors) and simply handle is in select_best_modifier (Jason)

Requested-by: Jason Ekstrand <jason@jlekstrand.net>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/mesa/drivers/dri/i965/intel_screen.c

index 26ab5a8e19463637e988a0527fee822b3ac44a4e..a430964f029309080255c4a226f6f3efe61b1cb8 100644 (file)
 #define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1)
 #endif
 
+#ifndef DRM_FORMAT_MOD_LINEAR
+#define DRM_FORMAT_MOD_LINEAR 0
+#endif
+
 static const __DRIconfigOptionsExtension brw_config_options = {
    .base = { __DRI_CONFIG_OPTIONS, 1 },
    .xml =
@@ -511,13 +515,36 @@ intel_destroy_image(__DRIimage *image)
    free(image);
 }
 
+enum modifier_priority {
+   MODIFIER_PRIORITY_INVALID = 0,
+   MODIFIER_PRIORITY_LINEAR,
+};
+
+const uint64_t priority_to_modifier[] = {
+   [MODIFIER_PRIORITY_INVALID] = DRM_FORMAT_MOD_INVALID,
+   [MODIFIER_PRIORITY_LINEAR] = DRM_FORMAT_MOD_LINEAR,
+};
+
 static uint64_t
 select_best_modifier(struct gen_device_info *devinfo,
                      const uint64_t *modifiers,
                      const unsigned count)
 {
-   /* Modifiers are not supported by this DRI driver */
-   return DRM_FORMAT_MOD_INVALID;
+
+   enum modifier_priority prio = MODIFIER_PRIORITY_INVALID;
+
+   for (int i = 0; i < count; i++) {
+      switch (modifiers[i]) {
+      case DRM_FORMAT_MOD_LINEAR:
+         prio = MAX2(prio, MODIFIER_PRIORITY_LINEAR);
+         break;
+      case DRM_FORMAT_MOD_INVALID:
+      default:
+         break;
+      }
+   }
+
+   return priority_to_modifier[prio];
 }
 
 static __DRIimage *
@@ -530,7 +557,10 @@ intel_create_image_common(__DRIscreen *dri_screen,
 {
    __DRIimage *image;
    struct intel_screen *screen = dri_screen->driverPrivate;
-   uint32_t tiling;
+   /* Historically, X-tiled was the default, and so lack of modifier means
+    * X-tiled.
+    */
+   uint32_t tiling = I915_TILING_X;
    int cpp;
    unsigned long pitch;
 
@@ -541,15 +571,17 @@ intel_create_image_common(__DRIscreen *dri_screen,
    assert(!(use && count));
 
    uint64_t modifier = select_best_modifier(&screen->devinfo, modifiers, count);
-   assert(modifier == DRM_FORMAT_MOD_INVALID);
-
-   if (modifier == DRM_FORMAT_MOD_INVALID && modifiers)
-      return NULL;
+   switch (modifier) {
+   case DRM_FORMAT_MOD_LINEAR:
+      tiling = I915_TILING_NONE;
+      break;
+   case DRM_FORMAT_MOD_INVALID:
+      if (modifiers)
+         return NULL;
+   default:
+         break;
+   }
 
-   /* Historically, X-tiled was the default, and so lack of modifier means
-    * X-tiled.
-    */
-   tiling = I915_TILING_X;
    if (use & __DRI_IMAGE_USE_CURSOR) {
       if (width != 64 || height != 64)
         return NULL;
@@ -574,6 +606,7 @@ intel_create_image_common(__DRIscreen *dri_screen,
    image->width = width;
    image->height = height;
    image->pitch = pitch;
+   image->modifier = modifier;
 
    return image;
 }