PD#158474: sync chromiumos drm-tests
add atomictest tests:crtc_ctm&crtc_gamma
Change-Id: I58f6bbf0e2aa812d76f498d005f240f3df18c541
Signed-off-by: Yalong Liu <yalong.liu@amlogic.com>
diff --git a/drm-tests/atomictest.c b/drm-tests/atomictest.c
old mode 100644
new mode 100755
index 19e6570..e36f054
--- a/drm-tests/atomictest.c
+++ b/drm-tests/atomictest.c
@@ -46,10 +46,32 @@
#define DRM_REFLECT_Y (1UL << 5)
#endif
+#define TEST_COMMIT_FAIL 1
+
static const uint32_t yuv_formats[] = {
- DRM_FORMAT_NV12, DRM_FORMAT_YVU420,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_YVU420,
};
+/*
+ * The blob for the CTM propery is a drm_color_ctm.
+ * drm_color_ctm contains a 3x3 u64 matrix. Every element is represented as
+ * sign and U31.32. The sign is the MSB.
+ */
+// clang-format off
+static int64_t identity_ctm[9] = {
+ 0x100000000, 0x0, 0x0,
+ 0x0, 0x100000000, 0x0,
+ 0x0, 0x0, 0x100000000
+};
+static int64_t red_shift_ctm[9] = {
+ 0x140000000, 0x0, 0x0,
+ 0x0, 0xC0000000, 0x0,
+ 0x0, 0x0, 0xC0000000
+};
+// clang-format on
+
+static bool automatic = false;
static struct gbm_device *gbm = NULL;
static void page_flip_handler(int fd, unsigned int sequence, unsigned int tv_sec,
@@ -106,6 +128,9 @@
struct atomictest_plane *planes;
struct atomictest_property mode_id;
struct atomictest_property active;
+ struct atomictest_property ctm;
+ struct atomictest_property gamma_lut;
+ struct atomictest_property gamma_lut_size;
};
struct atomictest_mode {
@@ -140,9 +165,10 @@
enum draw_format_type {
DRAW_NONE = 0,
DRAW_STRIPE = 1,
- DRAW_ELLIPSE = 2,
- DRAW_CURSOR = 3,
- DRAW_LINES = 4,
+ DRAW_TRANSPARENT_HOLE = 2,
+ DRAW_ELLIPSE = 3,
+ DRAW_CURSOR = 4,
+ DRAW_LINES = 5,
};
// clang-format on
@@ -194,6 +220,9 @@
case DRAW_STRIPE:
CHECK(bs_draw_stripe(mapper, bo, draw_format));
break;
+ case DRAW_TRANSPARENT_HOLE:
+ CHECK(bs_draw_transparent_hole(mapper, bo, draw_format));
+ break;
case DRAW_ELLIPSE:
CHECK(bs_draw_ellipse(mapper, bo, draw_format, 0));
break;
@@ -262,6 +291,15 @@
{
CHECK_RESULT(get_prop(fd, props, "MODE_ID", &crtc->mode_id));
CHECK_RESULT(get_prop(fd, props, "ACTIVE", &crtc->active));
+
+ /*
+ * The atomic API makes no guarantee a property is present in object. This test
+ * requires the above common properties since a plane is undefined without them.
+ * Other properties (i.e: ctm) are optional.
+ */
+ get_prop(fd, props, "CTM", &crtc->ctm);
+ get_prop(fd, props, "GAMMA_LUT", &crtc->gamma_lut);
+ get_prop(fd, props, "GAMMA_LUT_SIZE", &crtc->gamma_lut_size);
return 0;
}
@@ -301,6 +339,11 @@
uint32_t id = crtc->crtc_id;
CHECK_RESULT(drmModeAtomicAddProperty(pset, id, crtc->mode_id.pid, crtc->mode_id.value));
CHECK_RESULT(drmModeAtomicAddProperty(pset, id, crtc->active.pid, crtc->active.value));
+ if (crtc->ctm.pid)
+ CHECK_RESULT(drmModeAtomicAddProperty(pset, id, crtc->ctm.pid, crtc->ctm.value));
+ if (crtc->gamma_lut.pid)
+ CHECK_RESULT(
+ drmModeAtomicAddProperty(pset, id, crtc->gamma_lut.pid, crtc->gamma_lut.value));
return 0;
}
@@ -379,14 +422,32 @@
return 0;
}
-static int init_yuv_plane(struct atomictest_context *ctx, struct atomictest_plane *plane,
- uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t crtc_id)
+static int init_plane_any_format(struct atomictest_context *ctx, struct atomictest_plane *plane,
+ uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t crtc_id,
+ bool yuv)
{
- uint32_t i;
- for (i = 0; i < BS_ARRAY_LEN(yuv_formats); i++)
- if (!init_plane(ctx, plane, yuv_formats[i], x, y, w, h, crtc_id))
+ if (yuv) {
+ uint32_t i;
+ for (i = 0; i < BS_ARRAY_LEN(yuv_formats); i++)
+ if (!init_plane(ctx, plane, yuv_formats[i], x, y, w, h, crtc_id))
+ return 0;
+ } else {
+ // XRGB888 works well with our draw code, so try that first.
+ if (!init_plane(ctx, plane, DRM_FORMAT_XRGB8888, x, y, w, h, crtc_id))
return 0;
+ for (uint32_t format_idx = 0; format_idx < plane->drm_plane.count_formats;
+ format_idx++) {
+ if (!gbm_device_is_format_supported(
+ gbm, plane->drm_plane.formats[format_idx], GBM_BO_USE_SCANOUT))
+ continue;
+
+ if (!init_plane(ctx, plane, plane->drm_plane.formats[format_idx], x, y, w,
+ h, crtc_id))
+ return 0;
+ }
+ }
+
return -EINVAL;
}
@@ -483,7 +544,8 @@
static int test_commit(struct atomictest_context *ctx)
{
- return drmModeAtomicCommit(ctx->fd, ctx->pset, DRM_MODE_ATOMIC_TEST_ONLY, NULL);
+ return drmModeAtomicCommit(ctx->fd, ctx->pset,
+ DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_TEST_ONLY, NULL);
}
static int commit(struct atomictest_context *ctx)
@@ -508,9 +570,23 @@
return 0;
}
+static int test_and_commit(struct atomictest_context *ctx, uint32_t sleep_micro_secs)
+{
+ sleep_micro_secs = automatic ? 0 : sleep_micro_secs;
+ if (!test_commit(ctx)) {
+ CHECK_RESULT(commit(ctx));
+ usleep(sleep_micro_secs);
+ } else {
+ return TEST_COMMIT_FAIL;
+ }
+
+ return 0;
+}
+
static int pageflip_formats(struct atomictest_context *ctx, struct atomictest_crtc *crtc,
struct atomictest_plane *plane)
{
+ int ret = 0;
uint32_t flags;
for (uint32_t i = 0; i < plane->drm_plane.count_formats; i++) {
flags = (plane->type.value == DRM_PLANE_TYPE_CURSOR) ? GBM_BO_USE_CURSOR
@@ -521,14 +597,13 @@
CHECK_RESULT(init_plane(ctx, plane, plane->drm_plane.formats[i], 0, 0, crtc->width,
crtc->height, crtc->crtc_id));
CHECK_RESULT(draw_to_plane(ctx->mapper, plane, DRAW_ELLIPSE));
- CHECK_RESULT(commit(ctx));
- usleep(1e6);
+ ret |= test_and_commit(ctx, 1e6);
// disable, but don't commit, since we can't have an active CRTC without any planes.
CHECK_RESULT(disable_plane(ctx, plane));
}
- return 0;
+ return ret;
}
static uint32_t get_connection(struct atomictest_crtc *crtc, uint32_t crtc_index)
@@ -603,6 +678,11 @@
crtc->mode_id.value = 0;
crtc->active.value = 0;
+ if (crtc->ctm.pid)
+ crtc->ctm.value = 0;
+ if (crtc->gamma_lut.pid)
+ crtc->gamma_lut.value = 0;
+
set_crtc_props(crtc, ctx->pset);
int ret = drmModeAtomicCommit(ctx->fd, ctx->pset, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
CHECK_RESULT(ret);
@@ -790,6 +870,7 @@
static int test_multiple_planes(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
{
+ int ret = 0;
struct atomictest_plane *primary, *overlay, *cursor;
for (uint32_t i = 0; i < crtc->num_primary; i++) {
bool video = true;
@@ -802,12 +883,13 @@
// formats.
x = BS_ALIGN(x, 2);
y = BS_ALIGN(y, 2);
- if (video && !init_yuv_plane(ctx, overlay, x, y, x, y, crtc->crtc_id)) {
+ if (video &&
+ !init_plane_any_format(ctx, overlay, x, y, x, y, crtc->crtc_id, true)) {
CHECK_RESULT(draw_to_plane(ctx->mapper, overlay, DRAW_STRIPE));
video = false;
} else {
- CHECK_RESULT(init_plane(ctx, overlay, DRM_FORMAT_XRGB8888, x, y, x,
- y, crtc->crtc_id));
+ CHECK_RESULT(init_plane_any_format(ctx, overlay, x, y, x, y,
+ crtc->crtc_id, false));
CHECK_RESULT(draw_to_plane(ctx->mapper, overlay, DRAW_LINES));
}
}
@@ -822,8 +904,8 @@
}
primary = get_plane(crtc, i, DRM_PLANE_TYPE_PRIMARY);
- CHECK_RESULT(init_plane(ctx, primary, DRM_FORMAT_XRGB8888, 0, 0, crtc->width,
- crtc->height, crtc->crtc_id));
+ CHECK_RESULT(init_plane_any_format(ctx, primary, 0, 0, crtc->width, crtc->height,
+ crtc->crtc_id, false));
CHECK_RESULT(draw_to_plane(ctx->mapper, primary, DRAW_ELLIPSE));
uint32_t num_planes = crtc->num_primary + crtc->num_cursor + crtc->num_overlay;
@@ -834,66 +916,58 @@
for (uint32_t j = 0; j < num_planes; j++) {
plane = &crtc->planes[j];
if (plane->type.value != DRM_PLANE_TYPE_PRIMARY)
- done &= move_plane(ctx, crtc, plane, 20, 20);
+ done &= move_plane(ctx, crtc, plane, 40, 40);
}
- CHECK_RESULT(commit(ctx));
- usleep(1e6 / 60);
+ ret |= test_and_commit(ctx, 1e6 / 60);
}
- CHECK_RESULT(commit(ctx));
- usleep(1e6);
+ ret |= test_and_commit(ctx, 1e6);
/* Disable primary plane and verify overlays show up. */
CHECK_RESULT(disable_plane(ctx, primary));
- CHECK_RESULT(commit(ctx));
- usleep(1e6);
+ ret |= test_and_commit(ctx, 1e6);
}
- return 0;
+ return ret;
}
static int test_video_overlay(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
{
+ int ret = 0;
struct atomictest_plane *overlay;
for (uint32_t i = 0; i < crtc->num_overlay; i++) {
overlay = get_plane(crtc, i, DRM_PLANE_TYPE_OVERLAY);
- if (init_yuv_plane(ctx, overlay, 0, 0, 800, 800, crtc->crtc_id))
+ if (init_plane_any_format(ctx, overlay, 0, 0, 800, 800, crtc->crtc_id, true))
continue;
CHECK_RESULT(draw_to_plane(ctx->mapper, overlay, DRAW_STRIPE));
- while (!move_plane(ctx, crtc, overlay, 20, 20)) {
- CHECK_RESULT(commit(ctx));
- usleep(1e6 / 60);
- }
+ while (!move_plane(ctx, crtc, overlay, 40, 40))
+ ret |= test_and_commit(ctx, 1e6 / 60);
}
- return 0;
+ return ret;
}
static int test_orientation(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
{
+ int ret = 0;
struct atomictest_plane *primary, *overlay;
for (uint32_t i = 0; i < crtc->num_overlay; i++) {
overlay = get_plane(crtc, i, DRM_PLANE_TYPE_OVERLAY);
if (!overlay->rotation.pid)
continue;
- CHECK_RESULT(init_plane(ctx, overlay, DRM_FORMAT_XRGB8888, 0, 0, crtc->width,
- crtc->height, crtc->crtc_id));
-
+ CHECK_RESULT(init_plane_any_format(ctx, overlay, 0, 0, crtc->width, crtc->height,
+ crtc->crtc_id, false));
overlay->rotation.value = DRM_ROTATE_0;
set_plane_props(overlay, ctx->pset);
CHECK_RESULT(draw_to_plane(ctx->mapper, overlay, DRAW_LINES));
- CHECK_RESULT(commit(ctx));
- usleep(1e6);
+ ret |= test_and_commit(ctx, 1e6);
overlay->rotation.value = DRM_REFLECT_Y;
set_plane_props(overlay, ctx->pset);
- if (!test_commit(ctx)) {
- CHECK_RESULT(commit(ctx));
- usleep(1e6);
- }
+ ret |= test_and_commit(ctx, 1e6);
CHECK_RESULT(disable_plane(ctx, overlay));
}
@@ -903,40 +977,28 @@
if (!primary->rotation.pid)
continue;
- CHECK_RESULT(init_plane(ctx, primary, DRM_FORMAT_XRGB8888, 0, 0, crtc->width,
- crtc->height, crtc->crtc_id));
+ CHECK_RESULT(init_plane_any_format(ctx, primary, 0, 0, crtc->width, crtc->height,
+ crtc->crtc_id, false));
primary->rotation.value = DRM_ROTATE_0;
set_plane_props(primary, ctx->pset);
CHECK_RESULT(draw_to_plane(ctx->mapper, primary, DRAW_LINES));
- CHECK_RESULT(commit(ctx));
- usleep(1e6);
+ ret |= test_and_commit(ctx, 1e6);
primary->rotation.value = DRM_REFLECT_Y;
set_plane_props(primary, ctx->pset);
- if (!test_commit(ctx)) {
- CHECK_RESULT(commit(ctx));
- usleep(1e6);
- }
+ ret |= test_and_commit(ctx, 1e6);
CHECK_RESULT(disable_plane(ctx, primary));
}
- return 0;
+ return ret;
}
static int test_plane_ctm(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
{
+ int ret = 0;
struct atomictest_plane *primary, *overlay;
- /*
- * The blob for the PLANE_CTM propery is a drm_color_ctm.
- * drm_color_ctm contains a 3x3 u64 matrix, where every element
- * represents a S31.32 fixed point number.
- */
- int64_t identity_ctm[9] = { 0x100000000, 0x0, 0x0, 0x0, 0x100000000,
- 0x0, 0x0, 0x0, 0x100000000 };
- int64_t red_shift_ctm[9] = { 0x140000000, 0x0, 0x0, 0x0, 0xC0000000,
- 0x0, 0x0, 0x0, 0xC0000000 };
for (uint32_t i = 0; i < crtc->num_overlay; i++) {
overlay = get_plane(crtc, i, DRM_PLANE_TYPE_OVERLAY);
@@ -950,16 +1012,14 @@
&overlay->ctm.value));
set_plane_props(overlay, ctx->pset);
CHECK_RESULT(draw_to_plane(ctx->mapper, overlay, DRAW_LINES));
- CHECK_RESULT(commit(ctx));
+ ret |= test_and_commit(ctx, 1e6);
CHECK_RESULT(drmModeDestroyPropertyBlob(ctx->fd, overlay->ctm.value));
- usleep(1e6);
CHECK_RESULT(drmModeCreatePropertyBlob(ctx->fd, red_shift_ctm,
sizeof(red_shift_ctm), &overlay->ctm.value));
set_plane_props(overlay, ctx->pset);
- CHECK_RESULT(commit(ctx));
+ ret |= test_and_commit(ctx, 1e6);
CHECK_RESULT(drmModeDestroyPropertyBlob(ctx->fd, overlay->ctm.value));
- usleep(1e6);
CHECK_RESULT(disable_plane(ctx, overlay));
}
@@ -969,72 +1029,121 @@
if (!primary->ctm.pid)
continue;
- CHECK_RESULT(init_plane(ctx, primary, DRM_FORMAT_XRGB8888, 0, 0, crtc->width,
- crtc->height, crtc->crtc_id));
+ CHECK_RESULT(init_plane_any_format(ctx, primary, 0, 0, crtc->width, crtc->height,
+ crtc->crtc_id, false));
CHECK_RESULT(drmModeCreatePropertyBlob(ctx->fd, identity_ctm, sizeof(identity_ctm),
&primary->ctm.value));
set_plane_props(primary, ctx->pset);
CHECK_RESULT(draw_to_plane(ctx->mapper, primary, DRAW_LINES));
- CHECK_RESULT(commit(ctx));
+ ret |= test_and_commit(ctx, 1e6);
CHECK_RESULT(drmModeDestroyPropertyBlob(ctx->fd, primary->ctm.value));
- usleep(1e6);
CHECK_RESULT(drmModeCreatePropertyBlob(ctx->fd, red_shift_ctm,
sizeof(red_shift_ctm), &primary->ctm.value));
set_plane_props(primary, ctx->pset);
- CHECK_RESULT(commit(ctx));
+ ret |= test_and_commit(ctx, 1e6);
CHECK_RESULT(drmModeDestroyPropertyBlob(ctx->fd, primary->ctm.value));
- usleep(1e6);
CHECK_RESULT(disable_plane(ctx, primary));
}
- return 0;
+ return ret;
+}
+
+static int test_video_underlay(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
+{
+ int ret = 0;
+ int i = 0;
+ struct atomictest_plane *underlay = 0;
+ struct atomictest_plane *primary = 0;
+
+ for (; i < crtc->num_primary + crtc->num_overlay; ++i) {
+ if (crtc->planes[i].type.value != DRM_PLANE_TYPE_CURSOR) {
+ if (!underlay) {
+ underlay = &crtc->planes[i];
+ } else {
+ primary = &crtc->planes[i];
+ break;
+ }
+ }
+ }
+ if (!underlay || !primary)
+ return 0;
+
+ CHECK_RESULT(init_plane_any_format(ctx, underlay, 0, 0, crtc->width >> 2, crtc->height >> 2,
+ crtc->crtc_id, true));
+ CHECK_RESULT(draw_to_plane(ctx->mapper, underlay, DRAW_LINES));
+
+ CHECK_RESULT(init_plane(ctx, primary, DRM_FORMAT_ARGB8888, 0, 0, crtc->width, crtc->height,
+ crtc->crtc_id));
+ CHECK_RESULT(draw_to_plane(ctx->mapper, primary, DRAW_TRANSPARENT_HOLE));
+
+ while (!move_plane(ctx, crtc, underlay, 50, 20))
+ ret |= test_and_commit(ctx, 1e6 / 60);
+
+ return ret;
}
static int test_fullscreen_video(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
{
+ int ret = 0;
struct atomictest_plane *primary;
for (uint32_t i = 0; i < crtc->num_primary; i++) {
primary = get_plane(crtc, i, DRM_PLANE_TYPE_PRIMARY);
- if (init_yuv_plane(ctx, primary, 0, 0, crtc->width, crtc->height, crtc->crtc_id))
+ if (init_plane_any_format(ctx, primary, 0, 0, crtc->width, crtc->height,
+ crtc->crtc_id, true))
continue;
CHECK_RESULT(draw_to_plane(ctx->mapper, primary, DRAW_STRIPE));
- CHECK_RESULT(commit(ctx));
- usleep(1e6);
+ ret |= test_and_commit(ctx, 1e6);
}
- return 0;
+ return ret;
}
static int test_disable_primary(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
{
+ int ret = 0;
struct atomictest_plane *primary, *overlay;
for (uint32_t i = 0; i < crtc->num_primary; i++) {
for (uint32_t j = 0; j < crtc->num_overlay; j++) {
overlay = get_plane(crtc, j, DRM_PLANE_TYPE_OVERLAY);
uint32_t x = crtc->width >> (j + 2);
uint32_t y = crtc->height >> (j + 2);
- CHECK_RESULT(init_plane(ctx, overlay, DRM_FORMAT_XRGB8888, x, y, x, y,
- crtc->crtc_id));
+ CHECK_RESULT(
+ init_plane_any_format(ctx, overlay, x, y, x, y, crtc->crtc_id, false));
CHECK_RESULT(draw_to_plane(ctx->mapper, overlay, DRAW_LINES));
}
primary = get_plane(crtc, i, DRM_PLANE_TYPE_PRIMARY);
- CHECK_RESULT(init_plane(ctx, primary, DRM_FORMAT_XRGB8888, 0, 0, crtc->width,
- crtc->height, crtc->crtc_id));
+ CHECK_RESULT(init_plane_any_format(ctx, primary, 0, 0, crtc->width, crtc->height,
+ crtc->crtc_id, false));
CHECK_RESULT(draw_to_plane(ctx->mapper, primary, DRAW_ELLIPSE));
- CHECK_RESULT(commit(ctx));
- usleep(1e6);
+ ret |= test_and_commit(ctx, 1e6);
/* Disable primary plane. */
disable_plane(ctx, primary);
- CHECK_RESULT(commit(ctx));
- usleep(1e6);
+ ret |= test_and_commit(ctx, 1e6);
}
- return 0;
+ return ret;
+}
+
+static int test_rgba_primary(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
+{
+ int ret = 0;
+ struct atomictest_plane *primary;
+ for (uint32_t i = 0; i < crtc->num_primary; i++) {
+ primary = get_plane(crtc, i, DRM_PLANE_TYPE_PRIMARY);
+ CHECK_RESULT(init_plane(ctx, primary, DRM_FORMAT_ARGB8888, 0, 0, crtc->width,
+ crtc->height, crtc->crtc_id));
+
+ CHECK_RESULT(draw_to_plane(ctx->mapper, primary, DRAW_LINES));
+
+ ret |= test_and_commit(ctx, 1e6);
+ }
+
+ return ret;
}
static int test_overlay_pageflip(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
@@ -1050,19 +1159,17 @@
static int test_overlay_downscaling(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
{
+ int ret = 0;
struct atomictest_plane *overlay;
uint32_t w = BS_ALIGN(crtc->width / 2, 2);
uint32_t h = BS_ALIGN(crtc->height / 2, 2);
for (uint32_t i = 0; i < crtc->num_overlay; i++) {
overlay = get_plane(crtc, i, DRM_PLANE_TYPE_OVERLAY);
- if (init_yuv_plane(ctx, overlay, 0, 0, w, h, crtc->crtc_id)) {
+ if (init_plane_any_format(ctx, overlay, 0, 0, w, h, crtc->crtc_id, true))
CHECK_RESULT(init_plane(ctx, overlay, DRM_FORMAT_XRGB8888, 0, 0, w, h,
crtc->crtc_id));
- }
-
CHECK_RESULT(draw_to_plane(ctx->mapper, overlay, DRAW_LINES));
- CHECK_RESULT(commit(ctx));
- usleep(1e6);
+ ret |= test_and_commit(ctx, 1e6);
while (!scale_plane(ctx, crtc, overlay, -.1f, -.1f) && !test_commit(ctx)) {
CHECK_RESULT(commit(ctx));
@@ -1072,24 +1179,22 @@
disable_plane(ctx, overlay);
}
- return 0;
+ return ret;
}
static int test_overlay_upscaling(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
{
+ int ret = 0;
struct atomictest_plane *overlay;
uint32_t w = BS_ALIGN(crtc->width / 4, 2);
uint32_t h = BS_ALIGN(crtc->height / 4, 2);
for (uint32_t i = 0; i < crtc->num_overlay; i++) {
overlay = get_plane(crtc, i, DRM_PLANE_TYPE_OVERLAY);
- if (init_yuv_plane(ctx, overlay, 0, 0, w, h, crtc->crtc_id)) {
+ if (init_plane_any_format(ctx, overlay, 0, 0, w, h, crtc->crtc_id, true))
CHECK_RESULT(init_plane(ctx, overlay, DRM_FORMAT_XRGB8888, 0, 0, w, h,
crtc->crtc_id));
- }
-
CHECK_RESULT(draw_to_plane(ctx->mapper, overlay, DRAW_LINES));
- CHECK_RESULT(commit(ctx));
- usleep(1e6);
+ ret |= test_and_commit(ctx, 1e6);
while (!scale_plane(ctx, crtc, overlay, .1f, .1f) && !test_commit(ctx)) {
CHECK_RESULT(commit(ctx));
@@ -1099,7 +1204,7 @@
disable_plane(ctx, overlay);
}
- return 0;
+ return ret;
}
static int test_primary_pageflip(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
@@ -1113,8 +1218,131 @@
return 0;
}
+static int test_crtc_ctm(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
+{
+ int ret = 0;
+ struct atomictest_plane *primary;
+ if (!crtc->ctm.pid)
+ return 0;
+
+ CHECK_RESULT(drmModeCreatePropertyBlob(ctx->fd, identity_ctm, sizeof(identity_ctm),
+ &crtc->ctm.value));
+ set_crtc_props(crtc, ctx->pset);
+ for (uint32_t i = 0; i < crtc->num_primary; i++) {
+ primary = get_plane(crtc, i, DRM_PLANE_TYPE_PRIMARY);
+
+ CHECK_RESULT(init_plane(ctx, primary, DRM_FORMAT_XRGB8888, 0, 0, crtc->width,
+ crtc->height, crtc->crtc_id));
+ CHECK_RESULT(draw_to_plane(ctx->mapper, primary, DRAW_LINES));
+ ret |= test_and_commit(ctx, 1e6);
+
+ primary->crtc_id.value = 0;
+ CHECK_RESULT(set_plane_props(primary, ctx->pset));
+ }
+
+ CHECK_RESULT(drmModeDestroyPropertyBlob(ctx->fd, crtc->ctm.value));
+
+ CHECK_RESULT(drmModeCreatePropertyBlob(ctx->fd, red_shift_ctm, sizeof(red_shift_ctm),
+ &crtc->ctm.value));
+ set_crtc_props(crtc, ctx->pset);
+ for (uint32_t i = 0; i < crtc->num_primary; i++) {
+ primary = get_plane(crtc, i, DRM_PLANE_TYPE_PRIMARY);
+ primary->crtc_id.value = crtc->crtc_id;
+ CHECK_RESULT(set_plane_props(primary, ctx->pset));
+
+ ret |= test_and_commit(ctx, 1e6);
+
+ primary->crtc_id.value = 0;
+ CHECK_RESULT(disable_plane(ctx, primary));
+ }
+
+ CHECK_RESULT(drmModeDestroyPropertyBlob(ctx->fd, crtc->ctm.value));
+
+ return ret;
+}
+
+static void gamma_linear(struct drm_color_lut *table, int size)
+{
+ for (int i = 0; i < size; i++) {
+ float v = (float)(i) / (float)(size - 1);
+ v *= 65535.0f;
+ table[i].red = (uint16_t)v;
+ table[i].green = (uint16_t)v;
+ table[i].blue = (uint16_t)v;
+ }
+}
+
+static void gamma_step(struct drm_color_lut *table, int size)
+{
+ for (int i = 0; i < size; i++) {
+ float v = (i < size / 2) ? 0 : 65535;
+ table[i].red = (uint16_t)v;
+ table[i].green = (uint16_t)v;
+ table[i].blue = (uint16_t)v;
+ }
+}
+
+static int test_crtc_gamma(struct atomictest_context *ctx, struct atomictest_crtc *crtc)
+{
+ int ret = 0;
+ struct atomictest_plane *primary;
+ printf("[ test_crtc_gamma ] gamma_lut.pid %d\n", crtc->gamma_lut.pid);
+ printf("[ test_crtc_gamma ] gamma_lut_size.pid %d\n", crtc->gamma_lut_size.pid);
+ printf("[ test_crtc_gamma ] gamma_lut_size.value %d\n", crtc->gamma_lut_size.value);
+ if (!crtc->gamma_lut.pid || !crtc->gamma_lut_size.pid)
+ return 0;
+
+ if (crtc->gamma_lut_size.value == 0)
+ return 0;
+
+ struct drm_color_lut *gamma_table =
+ calloc(crtc->gamma_lut_size.value, sizeof(*gamma_table));
+
+ gamma_linear(gamma_table, crtc->gamma_lut_size.value);
+ CHECK_RESULT(drmModeCreatePropertyBlob(
+ ctx->fd, gamma_table, sizeof(struct drm_color_lut) * crtc->gamma_lut_size.value,
+ &crtc->gamma_lut.value));
+
+ for (uint32_t i = 0; i < crtc->num_primary; i++) {
+ primary = get_plane(crtc, i, DRM_PLANE_TYPE_PRIMARY);
+
+ CHECK_RESULT(init_plane(ctx, primary, DRM_FORMAT_XRGB8888, 0, 0, crtc->width,
+ crtc->height, crtc->crtc_id));
+ set_crtc_props(crtc, ctx->pset);
+
+ CHECK_RESULT(draw_to_plane(ctx->mapper, primary, DRAW_STRIPE));
+ ret |= test_and_commit(ctx, 1e6);
+
+ CHECK_RESULT(disable_plane(ctx, primary));
+ }
+
+ gamma_step(gamma_table, crtc->gamma_lut_size.value);
+ CHECK_RESULT(drmModeCreatePropertyBlob(
+ ctx->fd, gamma_table, sizeof(struct drm_color_lut) * crtc->gamma_lut_size.value,
+ &crtc->gamma_lut.value));
+
+ for (uint32_t i = 0; i < crtc->num_primary; i++) {
+ primary = get_plane(crtc, i, DRM_PLANE_TYPE_PRIMARY);
+
+ CHECK_RESULT(init_plane(ctx, primary, DRM_FORMAT_XRGB8888, 0, 0, crtc->width,
+ crtc->height, crtc->crtc_id));
+ set_crtc_props(crtc, ctx->pset);
+
+ CHECK_RESULT(draw_to_plane(ctx->mapper, primary, DRAW_STRIPE));
+ ret |= test_and_commit(ctx, 1e6);
+
+ CHECK_RESULT(disable_plane(ctx, primary));
+ }
+
+ CHECK_RESULT(drmModeDestroyPropertyBlob(ctx->fd, crtc->gamma_lut.value));
+ free(gamma_table);
+
+ return ret;
+}
+
static const struct atomictest_testcase cases[] = {
{ "disable_primary", test_disable_primary },
+ { "rgba_primary", test_rgba_primary },
{ "fullscreen_video", test_fullscreen_video },
{ "multiple_planes", test_multiple_planes },
{ "overlay_pageflip", test_overlay_pageflip },
@@ -1123,8 +1351,11 @@
{ "primary_pageflip", test_primary_pageflip },
{ "video_overlay", test_video_overlay },
{ "orientation", test_orientation },
+ { "video_underlay", test_video_underlay },
/* CTM stands for Color Transform Matrix. */
{ "plane_ctm", test_plane_ctm },
+ { "crtc_ctm", test_crtc_ctm },
+ { "crtc_gamma", test_crtc_gamma },
};
static int run_testcase(struct atomictest_context *ctx, struct atomictest_crtc *crtc,
@@ -1197,8 +1428,11 @@
goto out;
ret = run_testcase(ctx, crtc, cases[i].test_func);
- if (ret)
+ if (ret < 0)
goto out;
+ else if (ret == TEST_COMMIT_FAIL)
+ bs_debug_warning("%s failed test commit, testcase not run.",
+ cases[i].name);
ret = disable_crtc(ctx, crtc);
if (ret)
@@ -1222,12 +1456,13 @@
{ "crtc", required_argument, NULL, 'c' },
{ "test_name", required_argument, NULL, 't' },
{ "help", no_argument, NULL, 'h' },
+ { "automatic", no_argument, NULL, 'a' },
{ 0, 0, 0, 0 },
};
static void print_help(const char *argv0)
{
- printf("usage: %s -t <test_name> -c <crtc_index>\n", argv0);
+ printf("usage: %s -t <test_name> -c <crtc_index> -a (if running automatically)\n", argv0);
printf("A valid name test is one the following:\n");
for (uint32_t i = 0; i < BS_ARRAY_LEN(cases); i++)
printf("%s\n", cases[i].name);
@@ -1240,8 +1475,11 @@
char *name = NULL;
int32_t crtc_idx = -1;
uint32_t crtc_mask = ~0;
- while ((c = getopt_long(argc, argv, "c:t:h", longopts, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "c:t:h:a", longopts, NULL)) != -1) {
switch (c) {
+ case 'a':
+ automatic = true;
+ break;
case 'c':
if (sscanf(optarg, "%d", &crtc_idx) != 1)
goto print;