atomictest: add NV12 support
Make atomictest support NV12 format.
Conversion from RGB to YUV is done in software using the same matrix
than for modetest.
Remove bbp parameter from create_sp_bo because it is link to plane format.
Change-Id: I2f844b24d11fca65310668522bca4427c2c5e4ef
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
diff --git a/tests/planetest/atomictest.c b/tests/planetest/atomictest.c
index 6df3f16..5fec911 100644
--- a/tests/planetest/atomictest.c
+++ b/tests/planetest/atomictest.c
@@ -91,8 +91,7 @@
goto out;
}
- plane[i]->bo = create_sp_bo(dev, plane_w, plane_h, 16, 32,
- plane[i]->format, 0);
+ plane[i]->bo = create_sp_bo(dev, plane_w, plane_h, 16, plane[i]->format, 0);
if (!plane[i]->bo) {
printf("failed to create plane bo\n");
goto out;
diff --git a/tests/planetest/bo.c b/tests/planetest/bo.c
index 9a71828..d4b82c6 100644
--- a/tests/planetest/bo.c
+++ b/tests/planetest/bo.c
@@ -13,9 +13,46 @@
#include "bo.h"
#include "dev.h"
+#define MAKE_YUV_601_Y(r, g, b) \
+ ((( 66 * (r) + 129 * (g) + 25 * (b) + 128) >> 8) + 16)
+#define MAKE_YUV_601_U(r, g, b) \
+ (((-38 * (r) - 74 * (g) + 112 * (b) + 128) >> 8) + 128)
+#define MAKE_YUV_601_V(r, g, b) \
+ (((112 * (r) - 94 * (g) - 18 * (b) + 128) >> 8) + 128)
+
+static void draw_rect_yuv(struct sp_bo *bo, uint32_t x, uint32_t y, uint32_t width,
+ uint32_t height, uint8_t a, uint8_t r, uint8_t g, uint8_t b)
+{
+ uint32_t i, j, xmax = x + width, ymax = y + height;
+
+ if (xmax > bo->width)
+ xmax = bo->width;
+ if (ymax > bo->height)
+ ymax = bo->height;
+
+ for (i = y; i < ymax; i++) {
+ uint8_t *luma = bo->map_addr + i * bo->pitch;
+
+ for (j = x; j < xmax; j++)
+ luma[j] = MAKE_YUV_601_Y(r, g, b);
+ }
+
+ for (i = y; i < ymax / 2; i++) {
+ uint8_t *chroma = bo->map_addr + (i + height) * bo->pitch;
+
+ for (j = x; j < xmax / 2; j++) {
+ chroma[j*2] = MAKE_YUV_601_U(r, g, b);
+ chroma[j*2 + 1] = MAKE_YUV_601_V(r, g, b);
+ }
+ }
+}
+
void fill_bo(struct sp_bo *bo, uint8_t a, uint8_t r, uint8_t g, uint8_t b)
{
- draw_rect(bo, 0, 0, bo->width, bo->height, a, r, g, b);
+ if (bo->format == DRM_FORMAT_NV12)
+ draw_rect_yuv(bo, 0, 0, bo->width, bo->height, a, r, g, b);
+ else
+ draw_rect(bo, 0, 0, bo->width, bo->height, a, r, g, b);
}
void draw_rect(struct sp_bo *bo, uint32_t x, uint32_t y, uint32_t width,
@@ -59,6 +96,11 @@
handles[0] = bo->handle;
pitches[0] = bo->pitch;
offsets[0] = 0;
+ if (bo->format == DRM_FORMAT_NV12) {
+ handles[1] = bo->handle;
+ pitches[1] = pitches[0];
+ offsets[1] = pitches[0] * bo->height;
+ }
ret = drmModeAddFB2(bo->dev->fd, bo->width, bo->height,
format, handles, pitches, offsets,
@@ -94,8 +136,21 @@
return 0;
}
+static int format_to_bpp(uint32_t format)
+{
+ switch (format) {
+ case DRM_FORMAT_NV12:
+ return 8;
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_RGBA8888:
+ default:
+ return 32;
+ }
+}
+
struct sp_bo *create_sp_bo(struct sp_dev *dev, uint32_t width, uint32_t height,
- uint32_t depth, uint32_t bpp, uint32_t format, uint32_t flags)
+ uint32_t depth, uint32_t format, uint32_t flags)
{
int ret;
struct drm_mode_create_dumb cd;
@@ -105,9 +160,13 @@
if (!bo)
return NULL;
- cd.height = height;
+ if (format == DRM_FORMAT_NV12)
+ cd.height = height * 3 / 2;
+ else
+ cd.height = height;
+
cd.width = width;
- cd.bpp = bpp;
+ cd.bpp = format_to_bpp(format);
cd.flags = flags;
ret = drmIoctl(dev->fd, DRM_IOCTL_MODE_CREATE_DUMB, &cd);
@@ -120,7 +179,7 @@
bo->width = width;
bo->height = height;
bo->depth = depth;
- bo->bpp = bpp;
+ bo->bpp = format_to_bpp(format);
bo->format = format;
bo->flags = flags;
diff --git a/tests/planetest/bo.h b/tests/planetest/bo.h
index 4c5ddf8..7471e12 100644
--- a/tests/planetest/bo.h
+++ b/tests/planetest/bo.h
@@ -23,7 +23,7 @@
};
struct sp_bo *create_sp_bo(struct sp_dev *dev, uint32_t width, uint32_t height,
- uint32_t depth, uint32_t bpp, uint32_t format, uint32_t flags);
+ uint32_t depth, uint32_t format, uint32_t flags);
void fill_bo(struct sp_bo *bo, uint8_t a, uint8_t r, uint8_t g, uint8_t b);
void draw_rect(struct sp_bo *bo, uint32_t x, uint32_t y, uint32_t width,
diff --git a/tests/planetest/dev.c b/tests/planetest/dev.c
index c8277df..bd0968c 100644
--- a/tests/planetest/dev.c
+++ b/tests/planetest/dev.c
@@ -93,7 +93,8 @@
for (i = 0; i < plane->plane->count_formats; i++) {
if (plane->plane->formats[i] == DRM_FORMAT_XRGB8888 ||
plane->plane->formats[i] == DRM_FORMAT_ARGB8888 ||
- plane->plane->formats[i] == DRM_FORMAT_RGBA8888) {
+ plane->plane->formats[i] == DRM_FORMAT_RGBA8888 ||
+ plane->plane->formats[i] == DRM_FORMAT_NV12) {
*format = plane->plane->formats[i];
return 0;
}
diff --git a/tests/planetest/planetest.c b/tests/planetest/planetest.c
index 7fcfca6..5e187c9 100644
--- a/tests/planetest/planetest.c
+++ b/tests/planetest/planetest.c
@@ -79,7 +79,7 @@
goto out;
}
- plane[i]->bo = create_sp_bo(dev, plane_w, plane_h, 16, 32,
+ plane[i]->bo = create_sp_bo(dev, plane_w, plane_h, 16,
plane[i]->format, 0);
if (!plane[i]->bo) {
printf("failed to create plane bo\n");