sna: Allow flips to continue after successfully fixing up the CRTC
If we receive an error from the pageflip ioctl, we attempt to set the framebuffer using SETCRTC instead. This is so that we can transition between pitches and offsets for a CRTC. However, the kernel may reject a flip also for tiling changes, or for any reason, which we also want to transparently handle. Rearrange the error message and flip->blit fallback handling to only do so if we try to flip twice (i.e. after resetting the CRTC) and we still fail. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
54770d46f1
commit
37cf561fd2
|
|
@ -5928,6 +5928,7 @@ sna_page_flip(struct sna *sna,
|
|||
struct sna_crtc *crtc = config->crtc[i]->driver_private;
|
||||
struct drm_mode_crtc_page_flip arg;
|
||||
uint32_t crtc_offset;
|
||||
int fixup;
|
||||
|
||||
DBG(("%s: crtc %d id=%d, pipe=%d active? %d\n",
|
||||
__FUNCTION__, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->bo != NULL));
|
||||
|
|
@ -5949,6 +5950,7 @@ sna_page_flip(struct sna *sna,
|
|||
return 0;
|
||||
}
|
||||
|
||||
fixup = 0;
|
||||
crtc_offset = crtc->base->y << 16 | crtc->base->x;
|
||||
|
||||
if (bo->pitch != crtc->bo->pitch || crtc_offset != crtc->offset) {
|
||||
|
|
@ -5957,6 +5959,7 @@ sna_page_flip(struct sna *sna,
|
|||
bo->pitch, crtc->bo->pitch,
|
||||
crtc_offset, crtc->offset));
|
||||
fixup_flip:
|
||||
fixup = 1;
|
||||
if (crtc->bo != bo && sna_crtc_flip(sna, crtc, bo, crtc->base->x, crtc->base->y)) {
|
||||
update_scanout:
|
||||
DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n",
|
||||
|
|
@ -5979,11 +5982,8 @@ update_scanout:
|
|||
goto next_crtc;
|
||||
|
||||
/* queue a flip in order to send the event */
|
||||
} else {
|
||||
if (count)
|
||||
sna_mode_restore(sna);
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Only the reference crtc will finally deliver its page flip
|
||||
|
|
@ -6029,16 +6029,18 @@ retry_flip:
|
|||
goto retry_flip;
|
||||
}
|
||||
|
||||
if (sna->flags & (data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP)) {
|
||||
xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
|
||||
"page flipping failed, on CRTC:%d (pipe=%d), disabling %s page flips\n",
|
||||
__sna_crtc_id(crtc), __sna_crtc_pipe(crtc), data ? "synchronous": "asynchronous");
|
||||
sna->flags &= ~(data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP);
|
||||
if (!fixup)
|
||||
goto fixup_flip;
|
||||
}
|
||||
|
||||
error:
|
||||
xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
|
||||
"page flipping failed, on CRTC:%d (pipe=%d), disabling %s page flips\n",
|
||||
__sna_crtc_id(crtc), __sna_crtc_pipe(crtc), data ? "synchronous": "asynchronous");
|
||||
|
||||
if (count)
|
||||
sna_mode_restore(sna);
|
||||
|
||||
sna->flags &= ~(data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue