Reviewed-by: Rodrigo Vivi <rodrigo.vivi at gmail.com> On Fri, May 31, 2013 at 6:23 AM, Imre Deak <imre.deak at intel.com> wrote: > This is used by multiple test cases, so make it shared. > > Signed-off-by: Imre Deak <imre.deak at intel.com> > --- > lib/drmtest.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > lib/drmtest.h | 14 ++++++ > tests/kms_flip.c | 115 ++++++++------------------------------------ > tests/testdisplay.c | 134 +++++++++++++++------------------------------------- > 4 files changed, 206 insertions(+), 191 deletions(-) > > diff --git a/lib/drmtest.c b/lib/drmtest.c > index 3ad77a8..7368077 100644 > --- a/lib/drmtest.c > +++ b/lib/drmtest.c > @@ -1317,3 +1317,137 @@ int drmtest_set_vt_graphics_mode(void) > return orig_vt_mode < 0 ? -1 : 0; > } > > +static int get_connector_default_mode(int drm_fd, drmModeConnector *connector, > + drmModeModeInfo *mode) > +{ > + drmModeRes *resources; > + int i; > + > + resources = drmModeGetResources(drm_fd); > + if (!resources) { > + perror("drmModeGetResources failed"); > + > + return -1; > + } > + > + if (!connector->count_modes) { > + fprintf(stderr, "no modes for connector %d\n", > + connector->connector_id); > + drmModeFreeResources(resources); > + > + return -1; > + } > + > + for (i = 0; i < connector->count_modes; i++) { > + if (i == 0 || > + connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) { > + *mode = connector->modes[i]; > + if (mode->type & DRM_MODE_TYPE_PREFERRED) > + break; > + } > + } > + > + drmModeFreeResources(resources); > + > + return 0; > +} > + > +int kmstest_get_connector_config(int drm_fd, uint32_t connector_id, > + unsigned long crtc_idx_mask, > + struct kmstest_connector_config *config) > +{ > + drmModeRes *resources; > + drmModeConnector *connector; > + drmModeEncoder *encoder; > + int i, j; > + > + resources = drmModeGetResources(drm_fd); > + if (!resources) { > + perror("drmModeGetResources failed"); > + goto err1; > + } > + > + /* First, find the connector & mode */ > + connector = drmModeGetConnector(drm_fd, connector_id); > + if (!connector) > + goto err2; > + > + if (connector->connection != DRM_MODE_CONNECTED) > + goto err3; > + > + if (!connector->count_modes) { > + fprintf(stderr, "connector %d has no modes\n", connector_id); > + goto err3; > + } > + > + if (connector->connector_id != connector_id) { > + fprintf(stderr, "connector id doesn't match (%d != %d)\n", > + connector->connector_id, connector_id); > + goto err3; > + } > + > + /* > + * Find given CRTC if crtc_id != 0 or else the first CRTC not in use. > + * In both cases find the first compatible encoder and skip the CRTC > + * if there is non such. > + */ > + encoder = NULL; /* suppress GCC warning */ > + for (i = 0; i < resources->count_crtcs; i++) { > + if (!resources->crtcs[i] || !(crtc_idx_mask & (1 << i))) > + continue; > + > + /* Now get a compatible encoder */ > + for (j = 0; j < connector->count_encoders; j++) { > + encoder = drmModeGetEncoder(drm_fd, > + connector->encoders[j]); > + > + if (!encoder) { > + fprintf(stderr, "could not get encoder %d: %s\n", > + resources->encoders[j], strerror(errno)); > + > + continue; > + } > + > + if (encoder->possible_crtcs & (1 << i)) > + goto found; > + > + drmModeFreeEncoder(encoder); > + } > + } > + > + fprintf(stderr, > + "no crtc with a compatible encoder (crtc_idx_mask %08lx)\n", > + crtc_idx_mask); > + goto err3; > + > +found: > + if (get_connector_default_mode(drm_fd, connector, > + &config->default_mode) < 0) > + goto err4; > + > + config->connector = connector; > + config->encoder = encoder; > + config->crtc = drmModeGetCrtc(drm_fd, resources->crtcs[i]); > + config->crtc_idx = i; > + config->pipe = kmstest_get_pipe_from_crtc_id(drm_fd, > + config->crtc->crtc_id); > + > + drmModeFreeResources(resources); > + > + return 0; > +err4: > + drmModeFreeEncoder(encoder); > +err3: > + drmModeFreeConnector(connector); > +err2: > + drmModeFreeResources(resources); > +err1: > + return -1; > +} > + > +void kmstest_free_connector_config(struct kmstest_connector_config *config) > +{ > + drmModeFreeCrtc(config->crtc); > + drmModeFreeEncoder(config->encoder); > + drmModeFreeConnector(config->connector); > +} > diff --git a/lib/drmtest.h b/lib/drmtest.h > index 3c1368d..89ded11 100644 > --- a/lib/drmtest.h > +++ b/lib/drmtest.h > @@ -101,6 +101,20 @@ void drmtest_init_aperture_trashers(drm_intel_bufmgr *bufmgr); > void drmtest_trash_aperture(void); > void drmtest_cleanup_aperture_trashers(void); > > +struct kmstest_connector_config { > + drmModeCrtc *crtc; > + drmModeConnector *connector; > + drmModeEncoder *encoder; > + drmModeModeInfo default_mode; > + int crtc_idx; > + int pipe; > +}; > + > +int kmstest_get_connector_config(int drm_fd, uint32_t connector_id, > + unsigned long crtc_idx_mask, > + struct kmstest_connector_config *config); > +void kmstest_free_connector_config(struct kmstest_connector_config *config); > + > /* helpers to create nice-looking framebuffers */ > struct kmstest_fb { > uint32_t fb_id; > diff --git a/tests/kms_flip.c b/tests/kms_flip.c > index 735b4dd..c9b3d8a 100644 > --- a/tests/kms_flip.c > +++ b/tests/kms_flip.c > @@ -825,97 +825,23 @@ static void update_all_state(struct test_output *o, > update_state(&o->vblank_state); > } > > -static void connector_find_preferred_mode(struct test_output *o, int crtc_id) > +static void connector_find_preferred_mode(uint32_t connector_id, int crtc_idx, > + struct test_output *o) > { > - drmModeConnector *connector; > - drmModeEncoder *encoder = NULL; > - int i, j; > - > - /* First, find the connector & mode */ > - o->mode_valid = 0; > - o->crtc = 0; > - connector = drmModeGetConnector(drm_fd, o->id); > - assert(connector); > - > - if (connector->connection != DRM_MODE_CONNECTED) { > - drmModeFreeConnector(connector); > - return; > - } > - > - if (!connector->count_modes) { > - fprintf(stderr, "connector %d has no modes\n", o->id); > - drmModeFreeConnector(connector); > - return; > - } > - > - if (connector->connector_id != o->id) { > - fprintf(stderr, "connector id doesn't match (%d != %d)\n", > - connector->connector_id, o->id); > - drmModeFreeConnector(connector); > - return; > - } > - > - for (j = 0; j < connector->count_modes; j++) { > - o->mode = connector->modes[j]; > - if (o->mode.type & DRM_MODE_TYPE_PREFERRED) { > - o->mode_valid = 1; > - break; > - } > - } > - > - if (!o->mode_valid) { > - if (connector->count_modes > 0) { > - /* use the first mode as test mode */ > - o->mode = connector->modes[0]; > - o->mode_valid = 1; > - } > - else { > - fprintf(stderr, "failed to find any modes on connector %d\n", > - o->id); > - return; > - } > - } > + struct kmstest_connector_config config; > > - /* Now get the encoder */ > - for (i = 0; i < connector->count_encoders; i++) { > - encoder = drmModeGetEncoder(drm_fd, connector->encoders[i]); > - > - if (!encoder) { > - fprintf(stderr, "could not get encoder %i: %s\n", > - resources->encoders[i], strerror(errno)); > - drmModeFreeEncoder(encoder); > - continue; > - } > - > - break; > - } > - > - o->encoder = encoder; > - > - if (i == resources->count_encoders) { > - fprintf(stderr, "failed to find encoder\n"); > - o->mode_valid = 0; > - return; > - } > - > - /* Find first CRTC not in use */ > - for (i = 0; i < resources->count_crtcs; i++) { > - if (resources->crtcs[i] != crtc_id) > - continue; > - if (resources->crtcs[i] && > - (o->encoder->possible_crtcs & (1<<i))) { > - o->crtc = resources->crtcs[i]; > - break; > - } > - } > - > - if (!o->crtc) { > - fprintf(stderr, "could not find requested crtc %d\n", crtc_id); > + if (kmstest_get_connector_config(drm_fd, connector_id, 1 << crtc_idx, > + &config) < 0) { > o->mode_valid = 0; > return; > } > > - o->connector = connector; > + o->connector = config.connector; > + o->encoder = config.encoder; > + o->crtc = config.crtc->crtc_id; > + o->pipe = config.pipe; > + o->mode = config.default_mode; > + o->mode_valid = 1; > } > > static void > @@ -1042,21 +968,21 @@ static unsigned event_loop(struct test_output *o, unsigned duration_sec) > return end - start; > } > > -static void run_test_on_crtc(struct test_output *o, int crtc, int duration) > +static void run_test_on_crtc(struct test_output *o, int crtc_idx, int duration) > { > unsigned ellapsed; > > o->bpp = 32; > o->depth = 24; > > - connector_find_preferred_mode(o, crtc); > + connector_find_preferred_mode(o->id, crtc_idx, o); > if (!o->mode_valid) > return; > > last_connector = o->connector; > > fprintf(stdout, "Beginning %s on crtc %d, connector %d\n", > - o->test_name, crtc, o->id); > + o->test_name, o->crtc, o->id); > > o->fb_width = o->mode.hdisplay; > o->fb_height = o->mode.vdisplay; > @@ -1116,7 +1042,7 @@ static void run_test_on_crtc(struct test_output *o, int crtc, int duration) > check_final_state(o, &o->vblank_state, ellapsed); > > fprintf(stdout, "\n%s on crtc %d, connector %d: PASSED\n\n", > - o->test_name, crtc, o->id); > + o->test_name, o->crtc, o->id); > > kmstest_remove_fb(drm_fd, o->fb_ids[2]); > kmstest_remove_fb(drm_fd, o->fb_ids[1]); > @@ -1131,7 +1057,8 @@ static void run_test_on_crtc(struct test_output *o, int crtc, int duration) > static int run_test(int duration, int flags, const char *test_name) > { > struct test_output o; > - int c, i; > + int c; > + int crtc_idx; > > resources = drmModeGetResources(drm_fd); > if (!resources) { > @@ -1142,19 +1069,15 @@ static int run_test(int duration, int flags, const char *test_name) > > /* Find any connected displays */ > for (c = 0; c < resources->count_connectors; c++) { > - for (i = 0; i < resources->count_crtcs; i++) { > - int crtc; > - > + for (crtc_idx = 0; crtc_idx < resources->count_crtcs; crtc_idx++) { > memset(&o, 0, sizeof(o)); > o.test_name = test_name; > o.id = resources->connectors[c]; > o.flags = flags; > o.flip_state.name = "flip"; > o.vblank_state.name = "vblank"; > - crtc = resources->crtcs[i]; > - o.pipe = kmstest_get_pipe_from_crtc_id(drm_fd, crtc); > > - run_test_on_crtc(&o, crtc, duration); > + run_test_on_crtc(&o, crtc_idx, duration); > } > } > > diff --git a/tests/testdisplay.c b/tests/testdisplay.c > index b10c3b9..4470339 100644 > --- a/tests/testdisplay.c > +++ b/tests/testdisplay.c > @@ -102,6 +102,7 @@ struct connector { > drmModeEncoder *encoder; > drmModeConnector *connector; > int crtc; > + int crtc_idx; > int pipe; > }; > > @@ -185,101 +186,31 @@ static void dump_crtcs_fd(int drmfd) > drmModeFreeResources(mode_resources); > } > > -static void connector_find_preferred_mode(struct connector *c) > +static void connector_find_preferred_mode(uint32_t connector_id, > + unsigned long crtc_idx_mask, > + int mode_num, struct connector *c) > { > - drmModeConnector *connector; > - drmModeEncoder *encoder = NULL; > - int i, j; > - > - /* First, find the connector & mode */ > - c->mode_valid = 0; > - connector = drmModeGetConnector(drm_fd, c->id); > - if (!connector) { > - fprintf(stderr, "could not get connector %d: %s\n", > - c->id, strerror(errno)); > - drmModeFreeConnector(connector); > - return; > - } > - > - if (connector->connection != DRM_MODE_CONNECTED) { > - drmModeFreeConnector(connector); > - return; > - } > - > - if (!connector->count_modes) { > - fprintf(stderr, "connector %d has no modes\n", c->id); > - drmModeFreeConnector(connector); > - return; > - } > - > - if (connector->connector_id != c->id) { > - fprintf(stderr, "connector id doesn't match (%d != %d)\n", > - connector->connector_id, c->id); > - drmModeFreeConnector(connector); > - return; > - } > - > - for (j = 0; j < connector->count_modes; j++) { > - c->mode = connector->modes[j]; > - if (c->mode.type & DRM_MODE_TYPE_PREFERRED) { > - c->mode_valid = 1; > - break; > - } > - } > - > - if ( specified_mode_num != -1 ){ > - c->mode = connector->modes[specified_mode_num]; > - if (c->mode.type & DRM_MODE_TYPE_PREFERRED) > - c->mode_valid = 1; > - } > - > - if (!c->mode_valid) { > - if (connector->count_modes > 0) { > - /* use the first mode as test mode */ > - c->mode = connector->modes[0]; > - c->mode_valid = 1; > - } > - else { > - fprintf(stderr, "failed to find any modes on connector %d\n", > - c->id); > - return; > - } > - } > - > - /* Now get the encoder */ > - for (i = 0; i < connector->count_encoders; i++) { > - encoder = drmModeGetEncoder(drm_fd, connector->encoders[i]); > - > - if (!encoder) { > - fprintf(stderr, "could not get encoder %i: %s\n", > - resources->encoders[i], strerror(errno)); > - drmModeFreeEncoder(encoder); > - continue; > - } > - > - break; > - } > - > - c->encoder = encoder; > + struct kmstest_connector_config config; > > - if (i == resources->count_encoders) { > - fprintf(stderr, "failed to find encoder\n"); > + if (kmstest_get_connector_config(drm_fd, connector_id, crtc_idx_mask, > + &config) < 0) { > c->mode_valid = 0; > return; > } > > - /* Find first CRTC not in use */ > - for (i = 0; i < resources->count_crtcs; i++) { > - if (resources->crtcs[i] && (c->encoder->possible_crtcs & (1<<i))) > - break; > + c->connector = config.connector; > + c->encoder = config.encoder; > + c->crtc = config.crtc->crtc_id; > + c->crtc_idx = config.crtc_idx; > + c->pipe = config.pipe; > + > + if (mode_num != -1) { > + assert(mode_num < config.connector->count_modes); > + c->mode = config.connector->modes[mode_num]; > + } else { > + c->mode = config.default_mode; > } > - c->crtc = resources->crtcs[i]; > - c->pipe = i; > - > - if(test_preferred_mode || force_mode || specified_mode_num != -1) > - resources->crtcs[i] = 0; > - > - c->connector = connector; > + c->mode_valid = 1; > } > > static void > @@ -409,10 +340,6 @@ set_mode(struct connector *c) > else if (depth > 16 && depth <= 32) > bpp = 32; > > - connector_find_preferred_mode(c); > - if (!c->mode_valid) > - return; > - > test_mode_num = 1; > if (force_mode){ > memcpy( &c->mode, &force_timing, sizeof(force_timing)); > @@ -506,13 +433,30 @@ int update_display(void) > } > > if (test_preferred_mode || test_all_modes || force_mode || specified_disp_id != -1) { > + unsigned long crtc_idx_mask = -1UL; > + > /* Find any connected displays */ > for (c = 0; c < resources->count_connectors; c++) { > - connectors[c].id = resources->connectors[c]; > - if ( specified_disp_id != -1 && connectors[c].id != specified_disp_id ) > + struct connector *connector = &connectors[c]; > + > + connector->id = resources->connectors[c]; > + if (specified_disp_id != -1 && > + connector->id != specified_disp_id) > + continue; > + > + connector_find_preferred_mode(connector->id, > + crtc_idx_mask, > + specified_mode_num, > + connector); > + if (!connector->mode_valid) > continue; > > - set_mode(&connectors[c]); > + set_mode(connector); > + > + if (test_preferred_mode || force_mode || > + specified_mode_num != -1) > + crtc_idx_mask &= ~(1 << connector->crtc_idx); > + > } > } > drmModeFreeResources(resources); > -- > 1.8.1.2 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Rodrigo Vivi Blog: http://blog.vivi.eng.br