From 62d516813afd36146df63746e7b83e86d2588c70 Mon Sep 17 00:00:00 2001 From: Hai Lan Date: Fri, 11 Feb 2011 11:14:15 -0500 Subject: [PATCH] Add a test case into intel-gpu-tools for intel display driver validation. We have not a unified tool to check Intel display driver and we plan to use intel-gpu-tools/testdisplay to check Intel display driver even though some function tests can be found in libdrm/test. 3 new features are added:test all supported modes, force mode and dump mode info(dump mode info is based on libdrm/tests/modetest). [ickle: attack the whitespacing!] Signed-off-by: Chris Wilson --- tests/testdisplay.c | 279 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 217 insertions(+), 62 deletions(-) diff --git a/tests/testdisplay.c b/tests/testdisplay.c index fe9ef36a..a7392106 100644 --- a/tests/testdisplay.c +++ b/tests/testdisplay.c @@ -69,6 +69,18 @@ struct udev_monitor *uevent_monitor; drmModeRes *resources; int fd, modes; +int dump_info = 0, test_all_modes =0, test_preferred_mode = 0, force_mode = 0; +int sleep_between_modes = 5; + +float force_clock; +int force_hdisplay; +int force_hsync_start; +int force_hsync_end; +int force_htotal; +int force_vdisplay; +int force_vsync_start; +int force_vsync_end; +int force_vtotal; #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) @@ -141,6 +153,86 @@ struct connector { int crtc; }; +static void dump_mode(drmModeModeInfo *mode) +{ + printf(" %s %d %d %d %d %d %d %d %d %d\n", + mode->name, + mode->vrefresh, + mode->hdisplay, + mode->hsync_start, + mode->hsync_end, + mode->htotal, + mode->vdisplay, + mode->vsync_start, + mode->vsync_end, + mode->vtotal); +} + +static void dump_connectors(void) +{ + int i, j; + + printf("Connectors:\n"); + printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\n"); + for (i = 0; i < resources->count_connectors; i++) { + drmModeConnector *connector; + + connector = drmModeGetConnector(fd, resources->connectors[i]); + if (!connector) { + fprintf(stderr, "could not get connector %i: %s\n", + resources->connectors[i], strerror(errno)); + continue; + } + + printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\n", + connector->connector_id, + connector->encoder_id, + connector_status_str(connector->connection), + connector_type_str(connector->connector_type), + connector->mmWidth, connector->mmHeight, + connector->count_modes); + + if (!connector->count_modes) + continue; + + printf(" modes:\n"); + printf(" name refresh (Hz) hdisp hss hse htot vdisp " + "vss vse vtot)\n"); + for (j = 0; j < connector->count_modes; j++) + dump_mode(&connector->modes[j]); + + drmModeFreeConnector(connector); + } + printf("\n"); +} + +static void dump_crtcs(void) +{ + int i; + + printf("CRTCs:\n"); + printf("id\tfb\tpos\tsize\n"); + for (i = 0; i < resources->count_crtcs; i++) { + drmModeCrtc *crtc; + + crtc = drmModeGetCrtc(fd, resources->crtcs[i]); + if (!crtc) { + fprintf(stderr, "could not get crtc %i: %s\n", + resources->crtcs[i], strerror(errno)); + continue; + } + printf("%d\t%d\t(%d,%d)\t(%dx%d)\n", + crtc->crtc_id, + crtc->buffer_id, + crtc->x, crtc->y, + crtc->width, crtc->height); + dump_mode(&crtc->mode); + + drmModeFreeCrtc(crtc); + } + printf("\n"); +} + static void connector_find_preferred_mode(struct connector *c) { drmModeConnector *connector; @@ -420,6 +512,7 @@ set_mode(struct connector *c) cairo_surface_t *surface; cairo_t *cr; char buf[128]; + int j, test_mode_num; width = 0; height = 0; @@ -427,62 +520,91 @@ set_mode(struct connector *c) if (!c->mode_valid) return; - width += c->mode.hdisplay; - if (height < c->mode.vdisplay) - height = c->mode.vdisplay; + if (test_preferred_mode || force_mode) + test_mode_num = 1; + if (test_all_modes) + test_mode_num = c->connector->count_modes; - bufmgr = drm_intel_bufmgr_gem_init(fd, 2<<20); - if (!bufmgr) { - fprintf(stderr, "failed to init bufmgr: %s\n", strerror(errno)); - return; + for (j = 0; j < test_mode_num; j++) { + if (test_all_modes) + c->mode = c->connector->modes[j]; + width = 0; + height = 0; + width += c->mode.hdisplay; + if (height < c->mode.vdisplay) + height = c->mode.vdisplay; + if (force_mode){ + width = force_hdisplay; + height = force_vdisplay; + c->mode.clock = force_clock*1000; + c->mode.hdisplay = force_hdisplay; + c->mode.hsync_start = force_hsync_start; + c->mode.hsync_end = force_hsync_end; + c->mode.htotal = force_htotal; + c->mode.vdisplay = force_vdisplay; + c->mode.vsync_start = force_vsync_start; + c->mode.vsync_end = force_vsync_end; + c->mode.vtotal = force_vtotal; + c->mode.vrefresh =(force_clock*1e6)/(force_htotal*force_vtotal); + sprintf(c->mode.name,"%d%s%d",width,"x",height); + } + + bufmgr = drm_intel_bufmgr_gem_init(fd, 2<<20); + if (!bufmgr) { + fprintf(stderr, "failed to init bufmgr: %s\n", strerror(errno)); + return; + } + + if (create_test_buffer(bufmgr, width, height, &stride, &bo)) + return; + + surface = cairo_image_surface_create_for_data(bo->virtual, + CAIRO_FORMAT_ARGB32, + width, height, + stride); + cr = cairo_create(surface); + cairo_surface_destroy(surface); + + cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE); + + /* Paint corner markers */ + snprintf(buf, sizeof buf, "(%d, %d)", 0, 0); + paint_marker(cr, 0, 0, buf, bottomright); + snprintf(buf, sizeof buf, "(%d, %d)", width, 0); + paint_marker(cr, width, 0, buf, bottomleft); + snprintf(buf, sizeof buf, "(%d, %d)", 0, height); + paint_marker(cr, 0, height, buf, topright); + snprintf(buf, sizeof buf, "(%d, %d)", width, height); + paint_marker(cr, width, height, buf, topleft); + + /* Paint output info */ + paint_output_info(cr, c, width, height); + + cairo_destroy(cr); + drm_intel_gem_bo_unmap_gtt(bo); + + ret = drmModeAddFB(fd, width, height, 32, 32, stride, bo->handle, + &fb_id); + if (ret) { + fprintf(stderr, "failed to add fb (width=%d, height=%d): %s\n", + width, height, strerror(errno)); + return; + } + + if (!c->mode_valid) + return; + + dump_mode(&c->mode); + ret = drmModeSetCrtc(fd, c->crtc, fb_id, 0, 0, + &c->id, 1, &c->mode); + if (ret) { + fprintf(stderr, "failed to set mode: %s\n", strerror(errno)); + return; + } + + if (sleep_between_modes && test_all_modes) + sleep(5); } - - if (create_test_buffer(bufmgr, width, height, &stride, &bo)) - return; - - surface = cairo_image_surface_create_for_data(bo->virtual, - CAIRO_FORMAT_ARGB32, - width, height, - stride); - cr = cairo_create(surface); - cairo_surface_destroy(surface); - - cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE); - - /* Paint corner markers */ - snprintf(buf, sizeof buf, "(%d, %d)", 0, 0); - paint_marker(cr, 0, 0, buf, bottomright); - snprintf(buf, sizeof buf, "(%d, %d)", width, 0); - paint_marker(cr, width, 0, buf, bottomleft); - snprintf(buf, sizeof buf, "(%d, %d)", 0, height); - paint_marker(cr, 0, height, buf, topright); - snprintf(buf, sizeof buf, "(%d, %d)", width, height); - paint_marker(cr, width, height, buf, topleft); - - /* Paint output info */ - paint_output_info(cr, c, width, height); - - cairo_destroy(cr); - drm_intel_gem_bo_unmap_gtt(bo); - - ret = drmModeAddFB(fd, width, height, 32, 32, stride, bo->handle, - &fb_id); - if (ret) { - fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); - return; - } - - if (!c->mode_valid) - return; - - ret = drmModeSetCrtc(fd, c->crtc, fb_id, 0, 0, - &c->id, 1, &c->mode); - - if (ret) { - fprintf(stderr, "failed to set mode: %s\n", strerror(errno)); - return; - } - drmModeFreeEncoder(c->encoder); drmModeFreeConnector(c->connector); } @@ -513,24 +635,41 @@ static void update_display(void) if (!connectors) return; - /* Find any connected displays */ - for (c = 0; c < resources->count_connectors; c++) { - connectors[c].id = resources->connectors[c]; - set_mode(&connectors[c]); + if (dump_info) { + dump_connectors(); + dump_crtcs(); + } + if (test_preferred_mode || test_all_modes || force_mode) { + /* Find any connected displays */ + for (c = 0; c < resources->count_connectors; c++) { + connectors[c].id = resources->connectors[c]; + set_mode(&connectors[c]); + } } drmModeFreeResources(resources); + if (dump_info || test_all_modes) + exit(0); } extern char *optarg; extern int optind, opterr, optopt; -static char optstr[] = "h"; +static char optstr[] = "hiaf:s:"; static void usage(char *name) { - fprintf(stderr, "usage: %s [-h]\n", name); + fprintf(stderr, "usage: %s [-hiafs]\n", name); + fprintf(stderr, "\t-i\tdump info\n"); + fprintf(stderr, "\t-a\ttest all modes\n"); + fprintf(stderr, "\t-s\t\tsleep between each mode test\n"); + fprintf(stderr, "\t-f\t,,,,,\n"); + fprintf(stderr, "\t\t,,,\n"); + fprintf(stderr, "\t\ttest force mode\n"); + fprintf(stderr, "\tDefault is to test the preferred mode.\n"); exit(0); } +#define dump_resource(res) if (res) dump_##res() + static gboolean hotplug_event(GIOChannel *source, GIOCondition condition, gpointer data) { @@ -590,6 +729,23 @@ int main(int argc, char **argv) opterr = 0; while ((c = getopt(argc, argv, optstr)) != -1) { switch (c) { + case 'i': + dump_info = 1; + encoders = connectors = crtcs = modes = framebuffers = 1; + break; + case 'a': + test_all_modes = 1; + break; + case 'f': + force_mode = 1; + if(sscanf(optarg,"%f,%d,%d,%d,%d,%d,%d,%d,%d", + &force_clock,&force_hdisplay, &force_hsync_start,&force_hsync_end,&force_htotal, + &force_vdisplay, &force_vsync_start, &force_vsync_end, &force_vtotal)!= 9) + usage(argv[0]); + break; + case 's': + sleep_between_modes = atoi(optarg); + break; default: fprintf(stderr, "unknown option %c\n", c); /* fall through */ @@ -598,9 +754,8 @@ int main(int argc, char **argv) break; } } - if (argc == 1) - encoders = connectors = crtcs = modes = framebuffers = 1; + test_preferred_mode = 1; for (i = 0; i < ARRAY_SIZE(modules); i++) { fd = drmOpen(modules[i], NULL);