OSDN Git Service

minigbm/i915: Implement bo_create_with_modifiers
authorKristian H. Kristensen <hoegsberg@chromium.org>
Tue, 3 Oct 2017 20:53:19 +0000 (13:53 -0700)
committerchrome-bot <chrome-bot@chromium.org>
Thu, 26 Oct 2017 20:45:03 +0000 (13:45 -0700)
This implements the bo_create_with_modifiers driver functions, which
enables the gbm_bo_create_with_modifiers() entry point. This will
allow ozone to allocate with the modifiers it queries from KMS.

BUG=chromium:763760
TEST=Allocates Y-tiled scanout on SKL+

Change-Id: Id770e571a51aef4d753b30e12cd67d935c5228b7
Reviewed-on: https://chromium-review.googlesource.com/729279
Commit-Ready: Kristian H. Kristensen <hoegsberg@chromium.org>
Tested-by: Kristian H. Kristensen <hoegsberg@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
helpers.c
helpers.h
i915.c

index 07044da..bdae73d 100644 (file)
--- a/helpers.c
+++ b/helpers.c
@@ -605,3 +605,23 @@ int drv_modify_linear_combinations(struct driver *drv)
        free(items);
        return 0;
 }
+
+/*
+ * Pick the best modifier from modifiers, according to the ordering
+ * given by modifier_order.
+ */
+uint64_t drv_pick_modifier(const uint64_t *modifiers, uint32_t count,
+                          const uint64_t *modifier_order, uint32_t order_count)
+{
+       uint32_t i, j;
+
+       for (i = 0; i < order_count; i++) {
+               for (j = 0; j < count; j++) {
+                       if (modifiers[j] == modifier_order[i]) {
+                               return modifiers[j];
+                       }
+               }
+       }
+
+       return DRM_FORMAT_MOD_LINEAR;
+}
index 766b7d1..0e3fd14 100644 (file)
--- a/helpers.h
+++ b/helpers.h
@@ -33,4 +33,7 @@ void drv_modify_combination(struct driver *drv, uint32_t format, struct format_m
                            uint64_t usage);
 struct kms_item *drv_query_kms(struct driver *drv, uint32_t *num_items);
 int drv_modify_linear_combinations(struct driver *drv);
+uint64_t drv_pick_modifier(const uint64_t *modifiers, uint32_t count,
+                          const uint64_t *modifier_order, uint32_t order_count);
+
 #endif
diff --git a/i915.c b/i915.c
index 3836012..e25b068 100644 (file)
--- a/i915.c
+++ b/i915.c
@@ -291,21 +291,26 @@ static int i915_init(struct driver *drv)
        return i915_add_combinations(drv);
 }
 
-static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
-                         uint64_t use_flags)
+static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t height,
+                                      uint32_t format, uint64_t modifier)
 {
        int ret;
        size_t plane;
        uint32_t stride;
        struct drm_i915_gem_create gem_create;
        struct drm_i915_gem_set_tiling gem_set_tiling;
-       struct combination *combo;
-
-       combo = drv_get_combination(bo->drv, format, use_flags);
-       if (!combo)
-               return -EINVAL;
 
-       bo->tiling = combo->metadata.tiling;
+       switch (modifier) {
+       case DRM_FORMAT_MOD_LINEAR:
+               bo->tiling = I915_TILING_NONE;
+               break;
+       case I915_FORMAT_MOD_X_TILED:
+               bo->tiling = I915_TILING_X;
+               break;
+       case I915_FORMAT_MOD_Y_TILED:
+               bo->tiling = I915_TILING_Y;
+               break;
+       }
 
        stride = drv_stride_from_format(format, width, 0);
 
@@ -383,6 +388,33 @@ static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32
        return 0;
 }
 
+static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
+                         uint64_t use_flags)
+{
+       struct combination *combo;
+
+       combo = drv_get_combination(bo->drv, format, use_flags);
+       if (!combo)
+               return -EINVAL;
+
+       return i915_bo_create_for_modifier(bo, width, height, format, combo->metadata.modifier);
+}
+
+static int i915_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height,
+                                        uint32_t format, const uint64_t *modifiers, uint32_t count)
+{
+       static const uint64_t modifier_order[] = {
+               I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR,
+       };
+       uint64_t modifier;
+
+       modifier = drv_pick_modifier(modifiers, count, modifier_order, ARRAY_SIZE(modifier_order));
+
+       bo->format_modifiers[0] = modifier;
+
+       return i915_bo_create_for_modifier(bo, width, height, format, modifier);
+}
+
 static void i915_close(struct driver *drv)
 {
        free(drv->priv);
@@ -520,6 +552,7 @@ struct backend backend_i915 = {
        .init = i915_init,
        .close = i915_close,
        .bo_create = i915_bo_create,
+       .bo_create_with_modifiers = i915_bo_create_with_modifiers,
        .bo_destroy = drv_gem_bo_destroy,
        .bo_import = i915_bo_import,
        .bo_map = i915_bo_map,