OSDN Git Service

minigbm/i915: Add support for I915_FORMAT_MOD_Y_TILED_CCS.
authorYuanjun Huang <yuanjun.huang@intel.com>
Tue, 23 Jan 2018 07:56:19 +0000 (15:56 +0800)
committerKalyan Kondapally <kalyan.kondapally@intel.com>
Tue, 23 Jan 2018 08:38:57 +0000 (00:38 -0800)
This adds support for allocating buffers with the
I915_FORMAT_MOD_Y_TILED_CCS modifier, which enables Intels render
buffer compression.

Jira: https://jira01.devtools.intel.com/browse/AREQ-23273
Test: Build passes and validates with hwcomposer testlayer APP.
Signed-off-by: Yuanjun Huang <yuanjun.huang@intel.com>
i915.c

diff --git a/i915.c b/i915.c
index d061024..35d98af 100644 (file)
--- a/i915.c
+++ b/i915.c
@@ -320,6 +320,7 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h
                bo->tiling = I915_TILING_X;
                break;
        case I915_FORMAT_MOD_Y_TILED:
+        case I915_FORMAT_MOD_Y_TILED_CCS:
                bo->tiling = I915_TILING_Y;
                break;
        }
@@ -368,6 +369,39 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h
                drv_bo_from_format(bo, stride, height, format);
        }
 
+       if (modifier == I915_FORMAT_MOD_Y_TILED_CCS) {
+               /*
+                * For compressed surfaces, we need a color control surface
+                * (CCS). Color compression is only supported for Y tiled
+                * surfaces, and for each 32x16 tiles in the main surface we
+                * need a tile in the control surface.  Y tiles are 128 bytes
+                * wide and 32 lines tall and we use that to first compute the
+                * width and height in tiles of the main surface. stride and
+                * height are already multiples of 128 and 32, respectively:
+                */
+               uint32_t width_in_tiles = stride / 128;
+               uint32_t height_in_tiles = height / 32;
+
+               /*
+                * Now, compute the width and height in tiles of the control
+                * surface by dividing and rounding up.
+                */
+               uint32_t ccs_width_in_tiles = DIV_ROUND_UP(width_in_tiles, 32);
+               uint32_t ccs_height_in_tiles = DIV_ROUND_UP(height_in_tiles, 16);
+               uint32_t ccs_size = ccs_width_in_tiles * ccs_height_in_tiles * 4096;
+
+               /*
+                * With stride and height aligned to y tiles, bo->total_size
+                * is already a multiple of 4096, which is the required
+                * alignment of the CCS.
+                */
+               bo->num_planes = 2;
+               bo->strides[1] = ccs_width_in_tiles * 128;
+               bo->sizes[1] = ccs_size;
+               bo->offsets[1] = bo->total_size;
+               bo->total_size += ccs_size;
+       }
+
        /*
         * Quoting Mesa ISL library:
         *
@@ -432,7 +466,7 @@ static int i915_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t
                                         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,
+               I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR,
        };
        uint64_t modifier;