summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2009-02-03 14:00:00 -0500
committerKristian Høgsberg <krh@redhat.com>2009-02-03 14:00:00 -0500
commit669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5 (patch)
tree7b2f5247d47bdaab6abc8488977dec8146e16512
parentd9c55a6becb530dcf11bc980cb6b31843be0b8c2 (diff)
modetest: Handle setting modes on multiple crtcs with one fb.
-rw-r--r--tests/modetest/modetest.c110
1 files changed, 70 insertions, 40 deletions
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index d750f4c3..7711e32b 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -242,18 +242,21 @@ void dump_framebuffers(void)
* Then you need to find the encoder attached to that connector so you
* can bind it with a free crtc.
*/
-void set_mode(int connector_id, char *mode_str)
+struct connector {
+ int id;
+ char mode_str[64];
+ struct drm_mode_modeinfo *mode;
+ drmModeEncoder *encoder;
+};
+
+static void
+connector_find_mode(struct connector *c)
{
drmModeConnector *connector;
- drmModeEncoder *encoder = NULL;
- struct drm_mode_modeinfo *mode = NULL;
- drm_intel_bufmgr *bufmgr;
- drm_intel_bo *bo;
- unsigned int fb_id, *fb_ptr;
int i, j, size, ret, width, height;
- div_t d;
/* First, find the connector & mode */
+ c->mode = NULL;
for (i = 0; i < resources->count_connectors; i++) {
connector = drmModeGetConnector(fd, resources->connectors[i]);
@@ -269,47 +272,68 @@ void set_mode(int connector_id, char *mode_str)
continue;
}
- if (connector->connector_id != connector_id) {
+ if (connector->connector_id != c->id) {
drmModeFreeConnector(connector);
continue;
}
for (j = 0; j < connector->count_modes; j++) {
- mode = &connector->modes[j];
- if (!strcmp(mode->name, mode_str))
+ c->mode = &connector->modes[j];
+ if (!strcmp(c->mode->name, c->mode_str))
break;
}
/* Found it, break out */
- if (mode)
+ if (c->mode)
break;
drmModeFreeConnector(connector);
}
- if (!mode) {
- fprintf(stderr, "failed to find mode \"%s\"\n", mode_str);
+ if (!c->mode) {
+ fprintf(stderr, "failed to find mode \"%s\"\n", c->mode_str);
return;
}
- width = mode->hdisplay;
- height = mode->vdisplay;
-
/* Now get the encoder */
for (i = 0; i < resources->count_encoders; i++) {
- encoder = drmModeGetEncoder(fd, resources->encoders[i]);
+ c->encoder = drmModeGetEncoder(fd, resources->encoders[i]);
- if (!encoder) {
+ if (!c->encoder) {
fprintf(stderr, "could not get encoder %i: %s\n",
resources->encoders[i], strerror(errno));
- drmModeFreeEncoder(encoder);
+ drmModeFreeEncoder(c->encoder);
continue;
}
- if (encoder->encoder_id == connector->encoder_id)
+ if (c->encoder->encoder_id == connector->encoder_id)
break;
- drmModeFreeEncoder(encoder);
+ drmModeFreeEncoder(c->encoder);
+ }
+}
+
+static void
+set_mode(struct connector *c, int count)
+{
+ drmModeConnector *connector;
+ drmModeEncoder *encoder = NULL;
+ struct drm_mode_modeinfo *mode = NULL;
+ drm_intel_bufmgr *bufmgr;
+ drm_intel_bo *bo;
+ unsigned int fb_id, *fb_ptr;
+ int i, j, size, ret, width, height, x;
+ div_t d;
+
+ width = 0;
+ height = 0;
+ for (i = 0; i < count; i++) {
+ connector_find_mode(&c[i]);
+ if (c[i].mode == NULL)
+ continue;
+ width += c[i].mode->hdisplay;
+ if (height < c[i].mode->vdisplay)
+ height = c[i].mode->vdisplay;
}
bufmgr = drm_intel_bufmgr_gem_init(fd, 2<<20);
@@ -350,11 +374,18 @@ void set_mode(int connector_id, char *mode_str)
return;
}
- ret = drmModeSetCrtc(fd, encoder->crtc_id, fb_id, 0, 0,
- &connector->connector_id, 1, mode);
- if (ret) {
- fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
- return;
+ x = 0;
+ for (i = 0; i < count; i++) {
+ if (c[i].mode == NULL)
+ continue;
+ ret = drmModeSetCrtc(fd, c[i].encoder->crtc_id, fb_id, x, 0,
+ &c[i].id, 1, c[i].mode);
+ x += c[i].mode->hdisplay;
+
+ if (ret) {
+ fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
+ return;
+ }
}
}
@@ -383,8 +414,9 @@ int main(int argc, char **argv)
int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0;
char *modules[] = { "i915", "radeon" };
char *modeset = NULL, *mode, *connector;
- int i, connector_id;
-
+ int i, connector_id, count = 0;
+ struct connector con_args[2];
+
opterr = 0;
while ((c = getopt(argc, argv, optstr)) != -1) {
switch (c) {
@@ -405,6 +437,14 @@ int main(int argc, char **argv)
break;
case 's':
modeset = strdup(optarg);
+ if (sscanf(optarg, "%d:%64s",
+ &con_args[count].id,
+ &con_args[count].mode_str) != 2)
+ usage(argv[0]);
+ printf("setting mode %s on connector %d\n",
+ con_args[count].mode_str,
+ con_args[count].id);
+ count++;
break;
default:
usage(argv[0]);
@@ -444,18 +484,8 @@ int main(int argc, char **argv)
dump_resource(crtcs);
dump_resource(framebuffers);
- if (modeset) {
- connector = strtok(modeset, ":");
- if (!connector)
- usage(argv[0]);
- connector_id = atoi(connector);
-
- mode = strtok(NULL, ":");
- if (!mode)
- usage(argv[0]);
- printf("setting connector %d to mode %s\n", connector_id,
- mode);
- set_mode(connector_id, mode);
+ if (count > 0) {
+ set_mode(con_args, count);
sleep(3);
}