- switch (format) {
- case DRV_FORMAT_NV12:
- width = ALIGN(width, 4);
- height = ALIGN(height, 4);
- bo->strides[0] = bo->strides[1] = width;
- bo->sizes[0] = height * bo->strides[0];
- bo->sizes[1] = height * bo->strides[1] / 2;
- bo->offsets[0] = 0;
- bo->offsets[1] = height * bo->strides[0];
- break;
- case DRV_FORMAT_XRGB8888:
- case DRV_FORMAT_ARGB8888:
- case DRV_FORMAT_ABGR8888:
- bo->strides[0] = drv_stride_from_format(format, width);
- bo->sizes[0] = height * bo->strides[0];
- bo->offsets[0] = 0;
- break;
- default:
- fprintf(stderr, "drv: rockchip: unsupported format %4.4s\n",
- (char*)&format);
- assert(0);
- return -EINVAL;
+ const uint32_t clump_width = 4;
+ const uint32_t clump_height = 4;
+
+#define AFBC_NARROW 1
+#if AFBC_NARROW == 1
+ const uint32_t block_width = 4 * clump_width;
+ const uint32_t block_height = 4 * clump_height;
+#else
+ const uint32_t block_width = 8 * clump_width;
+ const uint32_t block_height = 2 * clump_height;
+#endif
+
+ const uint32_t header_block_size = 16;
+ const uint32_t body_block_size = block_width * block_height * pixel_size;
+ const uint32_t width_in_blocks = DIV_ROUND_UP(width, block_width);
+ const uint32_t height_in_blocks = DIV_ROUND_UP(height, block_height);
+ const uint32_t total_blocks = width_in_blocks * height_in_blocks;
+
+ const uint32_t header_plane_size = total_blocks * header_block_size;
+ const uint32_t body_plane_size = total_blocks * body_block_size;
+
+ /* GPU requires 64 bytes, but EGL import code expects 1024 byte
+ * alignement for the body plane. */
+ const uint32_t body_plane_alignment = 1024;
+
+ const uint32_t body_plane_offset = ALIGN(header_plane_size, body_plane_alignment);
+ const uint32_t total_size = body_plane_offset + body_plane_size;
+
+ bo->strides[0] = width_in_blocks * block_width * pixel_size;
+ bo->sizes[0] = total_size;
+ bo->offsets[0] = 0;
+
+ bo->total_size = total_size;
+
+ bo->format_modifiers[0] = DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC;
+
+ return 0;
+}
+
+static int rockchip_add_kms_item(struct driver *drv, const struct kms_item *item)
+{
+ uint32_t i, j;
+ uint64_t use_flags;
+ struct combination *combo;
+ struct format_metadata metadata;
+
+ for (i = 0; i < drv_array_size(drv->combos); i++) {
+ combo = (struct combination *)drv_array_at_idx(drv->combos, i);
+ if (combo->format == item->format) {
+ if (item->modifier == DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC) {
+ use_flags = BO_USE_RENDERING | BO_USE_SCANOUT | BO_USE_TEXTURE;
+ metadata.modifier = item->modifier;
+ metadata.tiling = 0;
+ metadata.priority = 2;
+
+ for (j = 0; j < ARRAY_SIZE(texture_source_formats); j++) {
+ if (item->format == texture_source_formats[j])
+ use_flags &= ~BO_USE_RENDERING;
+ }
+
+ drv_add_combinations(drv, &item->format, 1, &metadata, use_flags);
+ } else {
+ combo->use_flags |= item->use_flags;
+ }
+ }