@@ -73,13 +73,22 @@
#define Yb_OPT 3
#define Yf_OPT 4
+#ifndef DRM_CLIENT_CAP_ASPECT_RATIO
+/**
+ * Taken from drm-uapi/drm.h
+ * DRM_CLIENT_CAP_ASPECT_RATIO
+ *
+ * If set to 1, the DRM core will expose aspect ratio to userspace
+ */
+#define DRM_CLIENT_CAP_ASPECT_RATIO 4
+#endif
static int tio_fd;
struct termios saved_tio;
drmModeRes *resources;
int drm_fd, modes;
int test_all_modes = 0, test_preferred_mode = 0, force_mode = 0, test_plane,
- test_stereo_modes;
+test_stereo_modes, test_aspect_ratio_modes = 0;
uint64_t tiling = LOCAL_DRM_FORMAT_MOD_NONE;
int sleep_between_modes = 5;
int do_dpms = 0; /* This aliases to DPMS_ON */
@@ -443,6 +452,62 @@ set_stereo_mode(struct connector *c)
drmModeFreeConnector(c->connector);
}
+static void
+set_aspect_ratio_mode(struct connector *c)
+{
+ int i, n;
+ uint32_t fb_id;
+ struct igt_fb fb_info = { };
+
+
+ if (specified_mode_num != -1)
+ n = 1;
+ else
+ n = c->connector->count_modes;
+
+ for (i = 0; i < n; i++) {
+ if (specified_mode_num == -1)
+ c->mode = c->connector->modes[i];
+
+ if (!c->mode_valid)
+ continue;
+
+ if (!(c->mode.flags & DRM_MODE_FLAG_PIC_AR_MASK))
+ continue;
+
+ igt_info("CRTC(%u): [%d]", c->crtc, i);
+ kmstest_dump_mode(&c->mode);
+ width = c->mode.hdisplay;
+ height = c->mode.vdisplay;
+
+ fb_id = igt_create_pattern_fb(drm_fd, width, height,
+ igt_bpp_depth_to_drm_format(bpp, depth),
+ tiling, &fb_info);
+ paint_output_info(c, &fb_info);
+ paint_color_key(&fb_info);
+
+ kmstest_dump_mode(&c->mode);
+ igt_warn_on_f(drmModeSetCrtc(drm_fd, c->crtc, fb_id, 0, 0, &c->id, 1, &c->mode),
+ "failed to set mode (%dx%d@%dHz): %s\n", width, height, c->mode.vrefresh, strerror(errno));
+ if (qr_code) {
+ set_single();
+ pause();
+ } else if (sleep_between_modes)
+ sleep(sleep_between_modes);
+
+ if (do_dpms) {
+ kmstest_set_connector_dpms(drm_fd, c->connector,
+ DRM_MODE_DPMS_OFF);
+ sleep(sleep_between_modes);
+ kmstest_set_connector_dpms(drm_fd, c->connector,
+ DRM_MODE_DPMS_ON);
+ }
+
+ igt_remove_fb(drm_fd, &fb_info);
+ }
+ drmModeFreeEncoder(c->encoder);
+ drmModeFreeConnector(c->connector);
+}
/*
* Re-probe outputs and light up as many as possible.
*
@@ -517,18 +582,39 @@ int update_display(bool probe)
}
}
+ if (test_aspect_ratio_modes) {
+ for (c = 0; c < resources->count_connectors; c++) {
+ 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,
+ -1UL,
+ specified_mode_num,
+ connector, probe);
+ if (!connector->mode_valid)
+ continue;
+
+ set_aspect_ratio_mode(connector);
+ }
+ }
+
free(connectors);
drmModeFreeResources(resources);
return 1;
}
-static char optstr[] = "3hiaf:s:d:p:mrto:j:y";
+static char optstr[] = "3hziaf:s:d:p:mrto:j:y";
static void __attribute__((noreturn)) usage(char *name, char opt)
{
igt_info("usage: %s [-hiasdpmtf]\n", name);
igt_info("\t-i\tdump info\n");
igt_info("\t-a\ttest all modes\n");
+ igt_info("\t-z\ttest aspect ratio modes\n");
igt_info("\t-s\t<duration>\tsleep between each mode test\n");
igt_info("\t-d\t<depth>\tbit depth of scanout buffer\n");
igt_info("\t-p\t<planew,h>,<crtcx,y>,<crtcw,h> test overlay plane\n");
@@ -637,6 +723,9 @@ int main(int argc, char **argv)
case '3':
test_stereo_modes = 1;
break;
+ case 'z':
+ test_aspect_ratio_modes = 1;
+ break;
case 'i':
opt_dump_info = true;
break;
@@ -716,7 +805,8 @@ int main(int argc, char **argv)
bpp = 32;
if (!test_all_modes && !force_mode && !test_preferred_mode &&
- specified_mode_num == -1 && !test_stereo_modes)
+ specified_mode_num == -1 && !test_stereo_modes &&
+ !test_aspect_ratio_modes)
test_all_modes = 1;
drm_fd = drm_open_driver(DRIVER_ANY);
@@ -727,6 +817,12 @@ int main(int argc, char **argv)
goto out_close;
}
+ if (test_aspect_ratio_modes &&
+ drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ASPECT_RATIO, 1) < 0) {
+ igt_warn("DRM_CLIENT_CAP_ASPECT_RATIO failed\n");
+ goto out_close;
+ }
+
if (opt_dump_info) {
dump_info();
goto out_close;
@@ -766,7 +862,7 @@ int main(int argc, char **argv)
goto out_stdio;
}
- if (test_all_modes)
+ if (test_all_modes || test_aspect_ratio_modes)
goto out_stdio;
g_main_loop_run(mainloop);