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;
}
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:
*
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;