summaryrefslogtreecommitdiff
path: root/lib/igt_vc4.c
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2019-04-02 16:54:30 +0200
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2019-05-16 14:49:23 +0200
commitfddfda656fc5d6add4c83f522cb891b582202e46 (patch)
tree35bb6600a33e1730ca4c9dad5b2d3c9a4bcae284 /lib/igt_vc4.c
parent2d41b51980257a7d0a3de30a9b3ea0e95b13df91 (diff)
lib/igt_fb: Use cairo conversion in igt_fb_convert_with_stride, v4.
Ever since commit 3fa65f4b532bd9a5b ("fb: Add support for conversions through pixman") we can generate a valid cairo surface for any plane, use this to avoid having to implement our own conversion routine. Instead of duplicating this functionality in igt_fb_convert_with_stride, we can simply convert this to a few cairo calls, because we now support cairo calls to any of the supported framebuffer formats. This is required to make this function more generic, and convert from any format/modifier to any other format/modifier. Changes since v1: - Return fb_id in the cairo case. Changes since v2: - Remove the manual conversion fallback. Changes since v3: - Integrate VC4 conversion routines. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Paul Kocialkowski <paul.kocialkowski@bootlin.com> Reviewed-by: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Diffstat (limited to 'lib/igt_vc4.c')
-rw-r--r--lib/igt_vc4.c278
1 files changed, 180 insertions, 98 deletions
diff --git a/lib/igt_vc4.c b/lib/igt_vc4.c
index 9a0ba30b..4415fa32 100644
--- a/lib/igt_vc4.c
+++ b/lib/igt_vc4.c
@@ -56,6 +56,23 @@
* tests.
*/
+bool igt_vc4_is_tiled(uint64_t modifier)
+{
+ if (modifier >> 56ULL != DRM_FORMAT_MOD_VENDOR_BROADCOM)
+ return false;
+
+ switch (fourcc_mod_broadcom_mod(modifier)) {
+ case DRM_FORMAT_MOD_BROADCOM_SAND32:
+ case DRM_FORMAT_MOD_BROADCOM_SAND64:
+ case DRM_FORMAT_MOD_BROADCOM_SAND128:
+ case DRM_FORMAT_MOD_BROADCOM_SAND256:
+ case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
+ return true;
+ default:
+ return false;
+ }
+}
+
/**
* igt_vc4_get_cleared_bo:
* @fd: device file descriptor
@@ -178,63 +195,12 @@ bool igt_vc4_purgeable_bo(int fd, int handle, bool purgeable)
return arg.retained;
}
-unsigned int igt_vc4_fb_t_tiled_convert(struct igt_fb *dst, struct igt_fb *src)
-{
- unsigned int fb_id;
- unsigned int i, j;
- void *src_buf;
- void *dst_buf;
- size_t bpp = src->plane_bpp[0];
- size_t dst_stride = ALIGN(src->strides[0], 128);
-
- fb_id = igt_create_fb_with_bo_size(src->fd, src->width, src->height,
- src->drm_format,
- DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED,
- dst, 0, dst_stride);
- igt_assert(fb_id > 0);
-
- igt_assert(bpp == 16 || bpp == 32);
-
- src_buf = igt_fb_map_buffer(src->fd, src);
- igt_assert(src_buf);
-
- dst_buf = igt_fb_map_buffer(dst->fd, dst);
- igt_assert(dst_buf);
-
- for (i = 0; i < src->height; i++) {
- for (j = 0; j < src->width; j++) {
- size_t src_offset = src->offsets[0];
- size_t dst_offset = dst->offsets[0];
-
- src_offset += src->strides[0] * i + j * bpp / 8;
- dst_offset += igt_vc4_t_tiled_offset(dst_stride,
- src->height,
- bpp, j, i);
-
- switch (bpp) {
- case 16:
- *(uint16_t *)(dst_buf + dst_offset) =
- *(uint16_t *)(src_buf + src_offset);
- break;
- case 32:
- *(uint32_t *)(dst_buf + dst_offset) =
- *(uint32_t *)(src_buf + src_offset);
- break;
- }
- }
- }
-
- igt_fb_unmap_buffer(src, src_buf);
- igt_fb_unmap_buffer(dst, dst_buf);
-
- return fb_id;
-}
/* Calculate the t-tile width so that size = width * height * bpp / 8. */
#define VC4_T_TILE_W(size, height, bpp) ((size) / (height) / ((bpp) / 8))
-size_t igt_vc4_t_tiled_offset(size_t stride, size_t height, size_t bpp,
- size_t x, size_t y)
+static size_t igt_vc4_t_tiled_offset(size_t stride, size_t height, size_t bpp,
+ size_t x, size_t y)
{
const size_t t1k_map_even[] = { 0, 3, 1, 2 };
const size_t t1k_map_odd[] = { 2, 1, 3, 0 };
@@ -308,18 +274,116 @@ size_t igt_vc4_t_tiled_offset(size_t stride, size_t height, size_t bpp,
return offset;
}
-static void vc4_fb_sand_tiled_convert_plane(struct igt_fb *dst, void *dst_buf,
+static void vc4_fb_convert_plane_to_t_tiled(struct igt_fb *dst, void *dst_buf,
struct igt_fb *src, void *src_buf,
- size_t column_width_bytes,
- size_t column_height,
unsigned int plane)
{
+ size_t bpp = src->plane_bpp[plane];
+ unsigned int i, j;
+
+ for (i = 0; i < src->height; i++) {
+ for (j = 0; j < src->width; j++) {
+ size_t src_offset = src->offsets[plane];
+ size_t dst_offset = dst->offsets[plane];
+
+ src_offset += src->strides[plane] * i + j * bpp / 8;
+ dst_offset += igt_vc4_t_tiled_offset(dst->strides[plane],
+ dst->height,
+ bpp, j, i);
+
+ switch (bpp) {
+ case 16:
+ *(uint16_t *)(dst_buf + dst_offset) =
+ *(uint16_t *)(src_buf + src_offset);
+ break;
+ case 32:
+ *(uint32_t *)(dst_buf + dst_offset) =
+ *(uint32_t *)(src_buf + src_offset);
+ break;
+ }
+ }
+ }
+}
+
+static void vc4_fb_convert_plane_from_t_tiled(struct igt_fb *dst, void *dst_buf,
+ struct igt_fb *src, void *src_buf,
+ unsigned int plane)
+{
+ size_t bpp = src->plane_bpp[plane];
+ unsigned int i, j;
+
+ for (i = 0; i < src->height; i++) {
+ for (j = 0; j < src->width; j++) {
+ size_t src_offset = src->offsets[plane];
+ size_t dst_offset = dst->offsets[plane];
+
+ src_offset += igt_vc4_t_tiled_offset(src->strides[plane],
+ src->height,
+ bpp, j, i);
+ src_offset += dst->strides[plane] * i + j * bpp / 8;
+
+ switch (bpp) {
+ case 16:
+ *(uint16_t *)(dst_buf + dst_offset) =
+ *(uint16_t *)(src_buf + src_offset);
+ break;
+ case 32:
+ *(uint32_t *)(dst_buf + dst_offset) =
+ *(uint32_t *)(src_buf + src_offset);
+ break;
+ }
+ }
+ }
+}
+
+static size_t vc4_sand_tiled_offset(size_t column_width, size_t column_size, size_t x,
+ size_t y, size_t bpp)
+{
+ size_t offset = 0;
+ size_t cols_x;
+ size_t pix_x;
+
+ /* Offset to the beginning of the relevant column. */
+ cols_x = x / column_width;
+ offset += cols_x * column_size;
+
+ /* Offset to the relevant pixel. */
+ pix_x = x % column_width;
+ offset += (column_width * y + pix_x) * bpp / 8;
+
+ return offset;
+}
+
+static void vc4_fb_convert_plane_to_sand_tiled(struct igt_fb *dst, void *dst_buf,
+ struct igt_fb *src, void *src_buf,
+ unsigned int plane)
+{
+ uint64_t modifier_base = fourcc_mod_broadcom_mod(dst->modifier);
+ uint32_t column_height = fourcc_mod_broadcom_param(dst->modifier);
+ uint32_t column_width_bytes, column_width, column_size;
size_t bpp = dst->plane_bpp[plane];
- size_t column_width = column_width_bytes * dst->plane_width[plane] /
- dst->width;
- size_t column_size = column_width_bytes * column_height;
unsigned int i, j;
+ switch (modifier_base) {
+ case DRM_FORMAT_MOD_BROADCOM_SAND32:
+ column_width_bytes = 32;
+ break;
+ case DRM_FORMAT_MOD_BROADCOM_SAND64:
+ column_width_bytes = 64;
+ break;
+ case DRM_FORMAT_MOD_BROADCOM_SAND128:
+ column_width_bytes = 128;
+ break;
+ case DRM_FORMAT_MOD_BROADCOM_SAND256:
+ column_width_bytes = 256;
+ break;
+ default:
+ igt_assert(false);
+ }
+
+ column_width = column_width_bytes * dst->plane_width[plane] / dst->width;
+ column_size = column_width_bytes * column_height;
+
for (i = 0; i < dst->plane_height[plane]; i++) {
for (j = 0; j < src->plane_width[plane]; j++) {
size_t src_offset = src->offsets[plane];
@@ -346,19 +410,15 @@ static void vc4_fb_sand_tiled_convert_plane(struct igt_fb *dst, void *dst_buf,
}
}
-unsigned int vc4_fb_sand_tiled_convert(struct igt_fb *dst, struct igt_fb *src,
- uint64_t modifier)
+static void vc4_fb_convert_plane_from_sand_tiled(struct igt_fb *dst, void *dst_buf,
+ struct igt_fb *src, void *src_buf,
+ unsigned int plane)
{
- uint64_t modifier_base;
- size_t column_width_bytes;
- size_t column_height;
- unsigned int fb_id;
- unsigned int i;
- void *src_buf;
- void *dst_buf;
-
- modifier_base = fourcc_mod_broadcom_mod(modifier);
- column_height = fourcc_mod_broadcom_param(modifier);
+ uint64_t modifier_base = fourcc_mod_broadcom_mod(src->modifier);
+ uint32_t column_height = fourcc_mod_broadcom_param(src->modifier);
+ uint32_t column_width_bytes, column_width, column_size;
+ size_t bpp = src->plane_bpp[plane];
+ unsigned int i, j;
switch (modifier_base) {
case DRM_FORMAT_MOD_BROADCOM_SAND32:
@@ -377,41 +437,63 @@ unsigned int vc4_fb_sand_tiled_convert(struct igt_fb *dst, struct igt_fb *src,
igt_assert(false);
}
- fb_id = igt_create_fb(src->fd, src->width, src->height, src->drm_format,
- modifier, dst);
- igt_assert(fb_id > 0);
+ column_width = column_width_bytes * src->plane_width[plane] / src->width;
+ column_size = column_width_bytes * column_height;
+
+ for (i = 0; i < dst->plane_height[plane]; i++) {
+ for (j = 0; j < src->plane_width[plane]; j++) {
+ size_t src_offset = src->offsets[plane];
+ size_t dst_offset = dst->offsets[plane];
- src_buf = igt_fb_map_buffer(src->fd, src);
- igt_assert(src_buf);
+ src_offset += vc4_sand_tiled_offset(column_width,
+ column_size, j, i,
+ bpp);
+ dst_offset += dst->strides[plane] * i + j * bpp / 8;
- dst_buf = igt_fb_map_buffer(dst->fd, dst);
- igt_assert(dst_buf);
+ switch (bpp) {
+ case 8:
+ *(uint8_t *)(dst_buf + dst_offset) =
+ *(uint8_t *)(src_buf + src_offset);
+ break;
+ case 16:
+ *(uint16_t *)(dst_buf + dst_offset) =
+ *(uint16_t *)(src_buf + src_offset);
+ break;
+ default:
+ igt_assert(false);
+ }
+ }
+ }
+}
- for (i = 0; i < dst->num_planes; i++)
- vc4_fb_sand_tiled_convert_plane(dst, dst_buf, src, src_buf,
- column_width_bytes,
- column_height, i);
+void vc4_fb_convert_plane_to_tiled(struct igt_fb *dst, void *dst_buf,
+ struct igt_fb *src, void *src_buf)
+{
+ unsigned int plane;
- igt_fb_unmap_buffer(src, src_buf);
- igt_fb_unmap_buffer(dst, dst_buf);
+ igt_assert(src->modifier == DRM_FORMAT_MOD_LINEAR);
+ igt_assert(igt_vc4_is_tiled(dst->modifier));
- return fb_id;
+ for (plane = 0; plane < src->num_planes; plane++) {
+ if (dst->modifier == DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED)
+ vc4_fb_convert_plane_to_t_tiled(dst, dst_buf, src, src_buf, plane);
+ else
+ vc4_fb_convert_plane_to_sand_tiled(dst, dst_buf, src, src_buf, plane);
+ }
}
-size_t vc4_sand_tiled_offset(size_t column_width, size_t column_size, size_t x,
- size_t y, size_t bpp)
+void vc4_fb_convert_plane_from_tiled(struct igt_fb *dst, void *dst_buf,
+ struct igt_fb *src, void *src_buf)
{
- size_t offset = 0;
- size_t cols_x;
- size_t pix_x;
-
- /* Offset to the beginning of the relevant column. */
- cols_x = x / column_width;
- offset += cols_x * column_size;
+ unsigned int plane;
- /* Offset to the relevant pixel. */
- pix_x = x % column_width;
- offset += (column_width * y + pix_x) * bpp / 8;
+ igt_assert(igt_vc4_is_tiled(src->modifier));
+ igt_assert(dst->modifier == DRM_FORMAT_MOD_LINEAR);
- return offset;
+ for (plane = 0; plane < src->num_planes; plane++) {
+ if (src->modifier == DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED)
+ vc4_fb_convert_plane_from_t_tiled(dst, dst_buf, src, src_buf, plane);
+ else
+ vc4_fb_convert_plane_from_sand_tiled(dst, dst_buf, src, src_buf, plane);
+ }
}