sna/dri2: Fix multimonitor swap elision

We were not updating the window->crtc for the immediate swaps with the
result that after switching CRTCs, we were requesting a vblank on the
wrong pipe and triggering an error path (forcing the blit and negating
the elision).

Testcase: test/dri2-speed
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2015-04-02 15:14:24 +01:00
parent 0814dc41c3
commit ef8f5236f2
2 changed files with 25 additions and 17 deletions

View File

@ -1450,7 +1450,10 @@ static bool add_event_to_client(struct sna_dri2_event *info, struct sna *sna, Cl
}
static struct sna_dri2_event *
sna_dri2_add_event(struct sna *sna, DrawablePtr draw, ClientPtr client)
sna_dri2_add_event(struct sna *sna,
DrawablePtr draw,
ClientPtr client,
xf86CrtcPtr crtc)
{
struct dri2_window *priv;
struct sna_dri2_event *info, *chain;
@ -1470,8 +1473,8 @@ sna_dri2_add_event(struct sna *sna, DrawablePtr draw, ClientPtr client)
list_init(&info->cache);
info->sna = sna;
info->draw = draw;
info->crtc = priv->crtc;
info->pipe = sna_crtc_to_pipe(priv->crtc);
info->crtc = crtc;
info->pipe = sna_crtc_to_pipe(crtc);
if (!add_event_to_client(info, sna, client)) {
free(info);
@ -2349,8 +2352,8 @@ sna_dri2_immediate_blit(struct sna *sna,
if (sna->flags & SNA_NO_WAIT)
sync = false;
DBG(("%s: emitting immediate blit, throttling client, synced? %d, chained? %d\n",
__FUNCTION__, sync, chain != info));
DBG(("%s: emitting immediate blit, throttling client, synced? %d, chained? %d, pipe %d\n",
__FUNCTION__, sync, chain != info, info->pipe));
info->type = SWAP_THROTTLE;
info->sync = sync;
@ -2557,13 +2560,15 @@ static uint64_t
get_current_msc(struct sna *sna, DrawablePtr draw, xf86CrtcPtr crtc)
{
union drm_wait_vblank vbl;
uint64_t ret = -1;
uint64_t ret;
VG_CLEAR(vbl);
vbl.request.type = _DRM_VBLANK_RELATIVE;
vbl.request.sequence = 0;
if (sna_wait_vblank(sna, &vbl, sna_crtc_to_pipe(crtc)) == 0)
ret = sna_crtc_record_vblank(crtc, &vbl);
else
ret = sna_crtc_last_swap(crtc)->msc;
return draw_current_msc(draw, crtc, ret);
}
@ -2703,7 +2708,7 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
goto new_back;
}
info = sna_dri2_add_event(sna, draw, client);
info = sna_dri2_add_event(sna, draw, client, crtc);
if (info == NULL)
return false;
@ -2761,7 +2766,7 @@ queue:
info->keepalive = 1;
}
info = sna_dri2_add_event(sna, draw, client);
info = sna_dri2_add_event(sna, draw, client, crtc);
if (info == NULL)
return false;
@ -2823,7 +2828,7 @@ sna_dri2_schedule_xchg(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
if (sync) {
struct sna_dri2_event *info;
info = sna_dri2_add_event(sna, draw, client);
info = sna_dri2_add_event(sna, draw, client, crtc);
if (!info)
goto complete;
@ -2885,7 +2890,7 @@ sna_dri2_schedule_xchg_crtc(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc
if (sync) {
struct sna_dri2_event *info;
info = sna_dri2_add_event(sna, draw, client);
info = sna_dri2_add_event(sna, draw, client, crtc);
if (!info)
goto complete;
@ -3067,7 +3072,7 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
VG_CLEAR(vbl);
info = sna_dri2_add_event(sna, draw, client);
info = sna_dri2_add_event(sna, draw, client, crtc);
if (!info)
goto blit;
@ -3218,7 +3223,7 @@ sna_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc
if (divisor == 0 && current_msc >= target_msc)
goto out_complete;
info = sna_dri2_add_event(sna, draw, client);
info = sna_dri2_add_event(sna, draw, client, crtc);
if (!info)
goto out_complete;

View File

@ -178,7 +178,7 @@ static bool sna_fake_vblank(struct sna_present_event *info)
delay = 0;
DBG(("%s(event=%lld, target_msc=%lld, msc=%lld, delay=%ums)\n",
__FUNCTION__, (long long)info->event_id[0], (long long)info->target_msc, msc, delay));
__FUNCTION__, (long long)info->event_id[0], (long long)info->target_msc, (long long)msc, delay));
if (delay == 0) {
const struct ust_msc *swap = sna_crtc_last_swap(info->crtc);
present_event_notify(info->event_id[0], swap_ust(swap), swap->msc);
@ -197,7 +197,10 @@ sna_present_get_crtc(WindowPtr window)
BoxRec box;
xf86CrtcPtr crtc;
DBG(("%s\n", __FUNCTION__));
DBG(("%s: window=%ld (pixmap=%ld), box=(%d, %d)x(%d, %d)\n",
__FUNCTION__, window->drawable.id, get_window_pixmap(window)->drawable.serialNumber,
window->drawable.x, window->drawable.y,
window->drawable.width, window->drawable.height));
box.x1 = window->drawable.x;
box.y1 = window->drawable.y;
@ -440,9 +443,9 @@ flip__async(struct sna *sna,
return FALSE;
}
DBG(("%s: pipe=%d tv=%d.%06d msc=%lld (target=%lld), event=%lld complete\n", __FUNCTION__,
DBG(("%s: pipe=%d tv=%ld.%06d msc=%lld (target=%lld), event=%lld complete\n", __FUNCTION__,
pipe_from_crtc(crtc),
gettime_ust64() / 1000000, gettime_ust64() % 1000000,
(long)(gettime_ust64() / 1000000), (int)(gettime_ust64() % 1000000),
crtc ? (long long)sna_crtc_last_swap(crtc->devPrivate)->msc : 0LL,
(long long)target_msc, (long long)event_id));
present_event_notify(event_id, gettime_ust64(), target_msc);
@ -474,7 +477,7 @@ present_flip_handler(struct drm_event_vblank *event, void *data)
present_event_notify(info->event_id[0], swap_ust(&swap), swap.msc);
if (info->sna->present.unflip) {
DBG(("%s: executing queued unflip (event=%lld)\n", __FUNCTION__, info->sna->present.unflip));
DBG(("%s: executing queued unflip (event=%lld)\n", __FUNCTION__, (long long)info->sna->present.unflip));
sna_present_unflip(xf86ScrnToScreen(info->sna->scrn),
info->sna->present.unflip);
info->sna->present.unflip = 0;