Commit 919d6890 authored by Chris Wilson's avatar Chris Wilson 🤔

kms_flips: Operate on an array of crtc

This should be no functional change as we operate on an array of
crtc[1]. Later we shall test clone mode across a number of crtc.
Signed-off-by: Chris Wilson's avatarChris Wilson <chris@chris-wilson.co.uk>
parent d0ed9121
...@@ -113,14 +113,15 @@ struct event_state { ...@@ -113,14 +113,15 @@ struct event_state {
}; };
struct test_output { struct test_output {
uint32_t id;
int mode_valid; int mode_valid;
drmModeModeInfo mode; drmModeModeInfo kmode[4];
drmModeEncoder *encoder; drmModeEncoder *kencoder[4];
drmModeConnector *connector; drmModeConnector *kconnector[4];
int crtc; uint32_t _connector[4];
int pipe; uint32_t _crtc[4];
int count; /* 1:1 mapping between crtc:connector */
int flags; int flags;
int pipe; /* primary pipe for vblank */
unsigned int current_fb_id; unsigned int current_fb_id;
unsigned int fb_width; unsigned int fb_width;
unsigned int fb_height; unsigned int fb_height;
...@@ -166,7 +167,7 @@ static void emit_dummy_load__bcs(struct test_output *o) ...@@ -166,7 +167,7 @@ static void emit_dummy_load__bcs(struct test_output *o)
(0xcc << 16) | /* copy ROP */ (0xcc << 16) | /* copy ROP */
pitch); pitch);
OUT_BATCH(0 << 16 | 0); OUT_BATCH(0 << 16 | 0);
OUT_BATCH((o->mode.vdisplay) << 16 | (o->mode.hdisplay)); OUT_BATCH(o->fb_height << 16 | o->fb_width);
OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
OUT_BATCH(0 << 16 | 0); OUT_BATCH(0 << 16 | 0);
OUT_BATCH(pitch); OUT_BATCH(pitch);
...@@ -210,7 +211,7 @@ static void emit_dummy_load__rcs(struct test_output *o) ...@@ -210,7 +211,7 @@ static void emit_dummy_load__rcs(struct test_output *o)
sb[0].tiling = I915_TILING_NONE; sb[0].tiling = I915_TILING_NONE;
sb[0].data = NULL; sb[0].data = NULL;
sb[0].num_tiles = sb[0].bo->size; sb[0].num_tiles = sb[0].bo->size;
sb[0].stride = 4 * o->mode.hdisplay; sb[0].stride = 4 * o->fb_width;
sb[1].bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "imported", fb_info->gem_handle); sb[1].bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "imported", fb_info->gem_handle);
igt_assert(sb[1].bo); igt_assert(sb[1].bo);
...@@ -228,7 +229,7 @@ static void emit_dummy_load__rcs(struct test_output *o) ...@@ -228,7 +229,7 @@ static void emit_dummy_load__rcs(struct test_output *o)
copyfunc(batch, copyfunc(batch,
src, 0, 0, src, 0, 0,
o->mode.hdisplay, o->mode.vdisplay, o->fb_width, o->fb_height,
dst, 0, 0); dst, 0, 0);
tmp = src; tmp = src;
...@@ -273,7 +274,15 @@ static int set_connector_dpms(drmModeConnector *connector, int mode) ...@@ -273,7 +274,15 @@ static int set_connector_dpms(drmModeConnector *connector, int mode)
static int set_dpms(struct test_output *o, int mode) static int set_dpms(struct test_output *o, int mode)
{ {
return set_connector_dpms(o->connector, mode); int n;
for (n = 0; n < o->count; n++) {
int ret = set_connector_dpms(o->kconnector[n], mode);
if (ret)
return ret;
}
return 0;
} }
static void set_flag(unsigned int *v, unsigned int flag) static void set_flag(unsigned int *v, unsigned int flag)
...@@ -290,12 +299,14 @@ static void clear_flag(unsigned int *v, unsigned int flag) ...@@ -290,12 +299,14 @@ static void clear_flag(unsigned int *v, unsigned int flag)
static int do_page_flip(struct test_output *o, int fb_id, bool event) static int do_page_flip(struct test_output *o, int fb_id, bool event)
{ {
int ret; int n, ret = 0;
ret = drmModePageFlip(drm_fd, o->crtc, fb_id, event ? DRM_MODE_PAGE_FLIP_EVENT : 0, for (n = 0; n < o->count; n++) {
event ? o : NULL); ret = drmModePageFlip(drm_fd, o->_crtc[n], fb_id, event ? DRM_MODE_PAGE_FLIP_EVENT : 0,
if (ret == 0 && event) event ? o : NULL);
set_flag(&o->pending_events, EVENT_FLIP); if (ret == 0 && event)
set_flag(&o->pending_events, EVENT_FLIP);
}
return ret; return ret;
} }
...@@ -358,7 +369,7 @@ static int do_wait_for_vblank(struct test_output *o, int pipe_id, ...@@ -358,7 +369,7 @@ static int do_wait_for_vblank(struct test_output *o, int pipe_id,
static bool static bool
analog_tv_connector(struct test_output *o) analog_tv_connector(struct test_output *o)
{ {
uint32_t connector_type = o->connector->connector_type; uint32_t connector_type = o->kconnector[0]->connector_type;
return connector_type == DRM_MODE_CONNECTOR_TV || return connector_type == DRM_MODE_CONNECTOR_TV ||
connector_type == DRM_MODE_CONNECTOR_9PinDIN || connector_type == DRM_MODE_CONNECTOR_9PinDIN ||
...@@ -398,7 +409,7 @@ static void page_flip_handler(int fd, unsigned int frame, unsigned int sec, ...@@ -398,7 +409,7 @@ static void page_flip_handler(int fd, unsigned int frame, unsigned int sec,
static double frame_time(struct test_output *o) static double frame_time(struct test_output *o)
{ {
return 1000.0 * 1000.0 / o->mode.vrefresh; return 1000.0 * 1000.0 / o->kmode[0].vrefresh;
} }
static void fixup_premature_vblank_ts(struct test_output *o, static void fixup_premature_vblank_ts(struct test_output *o,
...@@ -695,6 +706,19 @@ static void hang_gpu(struct test_output *o) ...@@ -695,6 +706,19 @@ static void hang_gpu(struct test_output *o)
close(fd); close(fd);
} }
static int set_mode(struct test_output *o, int fb, int x, int y)
{
int n;
for (n = 0; n < o->count; n++) {
if (drmModeSetCrtc(drm_fd, o->_crtc[n], fb,
x, y, &o->_connector[n], 1, &o->kmode[n]))
return -1;
}
return 0;
}
/* Return mask of completed events. */ /* Return mask of completed events. */
static unsigned int run_test_step(struct test_output *o) static unsigned int run_test_step(struct test_output *o)
{ {
...@@ -767,10 +791,7 @@ static unsigned int run_test_step(struct test_output *o) ...@@ -767,10 +791,7 @@ static unsigned int run_test_step(struct test_output *o)
do_or_die(set_dpms(o, DRM_MODE_DPMS_OFF)); do_or_die(set_dpms(o, DRM_MODE_DPMS_OFF));
if (o->flags & TEST_MODESET) { if (o->flags & TEST_MODESET) {
if (drmModeSetCrtc(drm_fd, o->crtc, if (set_mode(o, o->fb_ids[o->current_fb_id], 0, 0)) {
o->fb_ids[o->current_fb_id],
0, 0,
&o->id, 1, &o->mode)) {
fprintf(stderr, "failed to restore output mode: %s\n", fprintf(stderr, "failed to restore output mode: %s\n",
strerror(errno)); strerror(errno));
igt_fail(7); igt_fail(7);
...@@ -812,14 +833,12 @@ static unsigned int run_test_step(struct test_output *o) ...@@ -812,14 +833,12 @@ static unsigned int run_test_step(struct test_output *o)
if (o->flags & TEST_PAN) { if (o->flags & TEST_PAN) {
int count = do_flip ? int count = do_flip ?
o->flip_state.count : o->vblank_state.count; o->flip_state.count : o->vblank_state.count;
int x_ofs = count * 10 > o->mode.hdisplay ? int x_ofs = count * 10 > o->fb_width ? o->fb_width : count * 10;
o->mode.hdisplay : count * 10;
if (drmModeSetCrtc(drm_fd, o->crtc, o->fb_ids[o->current_fb_id], if (set_mode(o, o->fb_ids[o->current_fb_id], x_ofs, 0)){
x_ofs, 0, &o->id, 1, &o->mode)) {
fprintf(stderr, "failed to pan (%dx%d@%dHz): %s\n", fprintf(stderr, "failed to pan (%dx%d@%dHz): %s\n",
o->fb_width, o->fb_height, o->fb_width, o->fb_height,
o->mode.vrefresh, strerror(errno)); o->kmode[0].vrefresh, strerror(errno));
igt_fail(7); igt_fail(7);
} }
} }
...@@ -828,10 +847,7 @@ static unsigned int run_test_step(struct test_output *o) ...@@ -828,10 +847,7 @@ static unsigned int run_test_step(struct test_output *o)
do_or_die(set_dpms(o, DRM_MODE_DPMS_OFF)); do_or_die(set_dpms(o, DRM_MODE_DPMS_OFF));
if (o->flags & TEST_MODESET && !(o->flags & TEST_RMFB)) { if (o->flags & TEST_MODESET && !(o->flags & TEST_RMFB)) {
if (drmModeSetCrtc(drm_fd, o->crtc, if (set_mode(o, 0 /* no fb */, 0, 0)) {
0, /* no fb */
0, 0,
NULL, 0, NULL)) {
fprintf(stderr, "failed to disable output: %s\n", fprintf(stderr, "failed to disable output: %s\n",
strerror(errno)); strerror(errno));
igt_fail(7); igt_fail(7);
...@@ -883,12 +899,16 @@ static void connector_find_preferred_mode(uint32_t connector_id, int crtc_idx, ...@@ -883,12 +899,16 @@ static void connector_find_preferred_mode(uint32_t connector_id, int crtc_idx,
return; return;
} }
o->connector = config.connector;
o->encoder = config.encoder;
o->crtc = config.crtc->crtc_id;
o->pipe = config.pipe; o->pipe = config.pipe;
o->mode = config.default_mode; o->kconnector[0] = config.connector;
o->kencoder[0] = config.encoder;
o->_crtc[0] = config.crtc->crtc_id;
o->kmode[0] = config.default_mode;
o->mode_valid = 1; o->mode_valid = 1;
o->fb_width = o->kmode[0].hdisplay;
o->fb_height = o->kmode[0].vdisplay;
} }
static void paint_flip_mode(struct kmstest_fb *fb, bool odd_frame) static void paint_flip_mode(struct kmstest_fb *fb, bool odd_frame)
...@@ -913,13 +933,20 @@ static void paint_flip_mode(struct kmstest_fb *fb, bool odd_frame) ...@@ -913,13 +933,20 @@ static void paint_flip_mode(struct kmstest_fb *fb, bool odd_frame)
static int static int
fb_is_bound(struct test_output *o, int fb) fb_is_bound(struct test_output *o, int fb)
{ {
struct drm_mode_crtc mode; int n;
mode.crtc_id = o->crtc; for (n = 0; n < o->count; n++) {
if (drmIoctl(drm_fd, DRM_IOCTL_MODE_GETCRTC, &mode)) struct drm_mode_crtc mode;
return 0;
return mode.mode_valid && mode.fb_id == fb; mode.crtc_id = o->_crtc[n];
if (drmIoctl(drm_fd, DRM_IOCTL_MODE_GETCRTC, &mode))
return 0;
if (!mode.mode_valid || mode.fb_id != fb)
return false;
}
return true;
} }
static void check_final_state(struct test_output *o, struct event_state *es, static void check_final_state(struct test_output *o, struct event_state *es,
...@@ -937,10 +964,10 @@ static void check_final_state(struct test_output *o, struct event_state *es, ...@@ -937,10 +964,10 @@ static void check_final_state(struct test_output *o, struct event_state *es,
int count = es->count; int count = es->count;
count *= es->seq_step; count *= es->seq_step;
expected = ellapsed * o->mode.vrefresh / (1000 * 1000); expected = ellapsed * o->kmode[0].vrefresh / (1000 * 1000);
if (count < expected * 99/100) { if (count < expected * 99/100) {
fprintf(stderr, "dropped frames, expected %d, counted %d, encoder type %d\n", fprintf(stderr, "dropped frames, expected %d, counted %d, encoder type %d\n",
expected, count, o->encoder->encoder_type); expected, count, o->kencoder[0]->encoder_type);
igt_fail(3); igt_fail(3);
} }
} }
...@@ -1029,17 +1056,14 @@ static void run_test_on_crtc(struct test_output *o, int crtc_idx, int duration) ...@@ -1029,17 +1056,14 @@ static void run_test_on_crtc(struct test_output *o, int crtc_idx, int duration)
o->bpp = 32; o->bpp = 32;
o->depth = 24; o->depth = 24;
connector_find_preferred_mode(o->id, crtc_idx, o); connector_find_preferred_mode(o->_connector[0], crtc_idx, o);
if (!o->mode_valid) if (!o->mode_valid)
return; return;
last_connector = o->connector; last_connector = o->kconnector[0];
fprintf(stdout, "Beginning %s on crtc %d, connector %d\n", fprintf(stdout, "Beginning %s on crtc %d, connector %d\n",
igt_subtest_name(), o->crtc, o->id); igt_subtest_name(), o->_crtc[0], o->_connector[0]);
o->fb_width = o->mode.hdisplay;
o->fb_height = o->mode.vdisplay;
if (o->flags & TEST_PAN) if (o->flags & TEST_PAN)
o->fb_width *= 2; o->fb_width *= 2;
...@@ -1062,15 +1086,14 @@ static void run_test_on_crtc(struct test_output *o, int crtc_idx, int duration) ...@@ -1062,15 +1086,14 @@ static void run_test_on_crtc(struct test_output *o, int crtc_idx, int duration)
set_y_tiling(o, 2); set_y_tiling(o, 2);
kmstest_dump_mode(&o->mode); kmstest_dump_mode(&o->kmode[0]);
if (drmModeSetCrtc(drm_fd, o->crtc, o->fb_ids[0], 0, 0, if (set_mode(o, o->fb_ids[0], 0, 0)) {
&o->id, 1, &o->mode)) {
/* We may fail to apply the mode if there are hidden /* We may fail to apply the mode if there are hidden
* constraints, such as bandwidth on the third pipe. * constraints, such as bandwidth on the third pipe.
*/ */
if (0) { if (0) {
fprintf(stderr, "failed to set mode (%dx%d@%dHz): %s\n", fprintf(stderr, "failed to set mode (%dx%d@%dHz): %s\n",
o->fb_width, o->fb_height, o->mode.vrefresh, o->fb_width, o->fb_height, o->kmode[0].vrefresh,
strerror(errno)); strerror(errno));
} }
goto out; goto out;
...@@ -1102,7 +1125,7 @@ static void run_test_on_crtc(struct test_output *o, int crtc_idx, int duration) ...@@ -1102,7 +1125,7 @@ static void run_test_on_crtc(struct test_output *o, int crtc_idx, int duration)
check_final_state(o, &o->vblank_state, ellapsed); check_final_state(o, &o->vblank_state, ellapsed);
fprintf(stdout, "\n%s on crtc %d, connector %d: PASSED\n\n", fprintf(stdout, "\n%s on crtc %d, connector %d: PASSED\n\n",
igt_subtest_name(), o->crtc, o->id); igt_subtest_name(), o->_crtc[0], o->_connector[0]);
out: out:
kmstest_remove_fb(drm_fd, &o->fb_info[2]); kmstest_remove_fb(drm_fd, &o->fb_info[2]);
...@@ -1111,8 +1134,8 @@ out: ...@@ -1111,8 +1134,8 @@ out:
last_connector = NULL; last_connector = NULL;
drmModeFreeEncoder(o->encoder); drmModeFreeEncoder(o->kencoder[0]);
drmModeFreeConnector(o->connector); drmModeFreeConnector(o->kconnector[0]);
} }
static int run_test(int duration, int flags) static int run_test(int duration, int flags)
...@@ -1132,7 +1155,8 @@ static int run_test(int duration, int flags) ...@@ -1132,7 +1155,8 @@ static int run_test(int duration, int flags)
for (c = 0; c < resources->count_connectors; c++) { for (c = 0; c < resources->count_connectors; c++) {
for (crtc_idx = 0; crtc_idx < resources->count_crtcs; crtc_idx++) { for (crtc_idx = 0; crtc_idx < resources->count_crtcs; crtc_idx++) {
memset(&o, 0, sizeof(o)); memset(&o, 0, sizeof(o));
o.id = resources->connectors[c]; o.count = 1;
o._connector[0] = resources->connectors[c];
o.flags = flags; o.flags = flags;
o.flip_state.name = "flip"; o.flip_state.name = "flip";
o.vblank_state.name = "vblank"; o.vblank_state.name = "vblank";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment