Treat disabled CRTCs as "not covering" for scanline wait purposes
Now that swapbuffers does a scanline wait to avoid tearing, it's important to take into account the CRTC status to avoid hangs. If we do a scanline wait when the CRTC is off (due to DPMS for example) we'll hang the GPU. So add some code to check the CRTC DPMS status to the i830_covering_crtc function, returning NULL if none of the covering CRTCs are actually active. KMS vs UMS logic is hidden in new i830* functions, cleaning up both DRI2 & video paths a bit. Fixes fdo bug #22383. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
This commit is contained in:
parent
6d025e679a
commit
5d80e24b5f
|
|
@ -71,7 +71,7 @@ typedef struct {
|
|||
int num_props;
|
||||
drmmode_prop_ptr props;
|
||||
void *private_data;
|
||||
/* this is used to store private data */
|
||||
int dpms_mode;
|
||||
} drmmode_output_private_rec, *drmmode_output_private_ptr;
|
||||
|
||||
static void
|
||||
|
|
@ -727,6 +727,7 @@ drmmode_output_dpms(xf86OutputPtr output, int mode)
|
|||
drmmode_output->output_id,
|
||||
props->prop_id,
|
||||
mode);
|
||||
drmmode_output->dpms_mode = mode;
|
||||
drmModeFreeProperty(props);
|
||||
return;
|
||||
}
|
||||
|
|
@ -734,6 +735,14 @@ drmmode_output_dpms(xf86OutputPtr output, int mode)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
drmmode_output_dpms_status(xf86OutputPtr output)
|
||||
{
|
||||
drmmode_output_private_ptr drmmode_output = output->driver_private;
|
||||
|
||||
return drmmode_output->dpms_mode;
|
||||
}
|
||||
|
||||
static Bool
|
||||
drmmode_property_ignore(drmModePropertyPtr prop)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -691,7 +691,10 @@ void I830DRI2CloseScreen(ScreenPtr pScreen);
|
|||
|
||||
extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp);
|
||||
extern int drmmode_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc);
|
||||
extern int drmmode_output_dpms_status(xf86OutputPtr output);
|
||||
|
||||
extern Bool i830_crtc_on(xf86CrtcPtr crtc);
|
||||
extern int i830_crtc_to_pipe(xf86CrtcPtr crtc);
|
||||
extern Bool I830AccelInit(ScreenPtr pScreen);
|
||||
extern void I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
|
||||
int ydir, int rop,
|
||||
|
|
|
|||
|
|
@ -311,12 +311,7 @@ I830DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
|
|||
|
||||
/* Make sure the CRTC is valid and this is the real front buffer */
|
||||
if (crtc != NULL && !crtc->rotatedData) {
|
||||
if (pI830->use_drm_mode)
|
||||
pipe = drmmode_get_pipe_from_crtc_id(pI830->bufmgr, crtc);
|
||||
else {
|
||||
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
|
||||
pipe = intel_crtc->pipe;
|
||||
}
|
||||
pipe = i830_crtc_to_pipe(crtc);
|
||||
|
||||
if (pipe == 0) {
|
||||
event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
|
||||
|
|
|
|||
|
|
@ -2456,6 +2456,49 @@ i830_init_bufmgr(ScrnInfoPtr pScrn)
|
|||
}
|
||||
}
|
||||
|
||||
Bool i830_crtc_on(xf86CrtcPtr crtc)
|
||||
{
|
||||
ScrnInfoPtr pScrn = crtc->scrn;
|
||||
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
if (pI830->use_drm_mode) {
|
||||
int i, active_outputs = 0;
|
||||
|
||||
/* Kernel manages CRTC status based out output config */
|
||||
for (i = 0; i < xf86_config->num_output; i++) {
|
||||
xf86OutputPtr output = xf86_config->output[i];
|
||||
if (drmmode_output_dpms_status(output) == DPMSModeOn)
|
||||
active_outputs++;
|
||||
}
|
||||
|
||||
if (active_outputs)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
} else {
|
||||
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
|
||||
|
||||
if (intel_crtc->dpms_mode == DPMSModeOn)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
int i830_crtc_to_pipe(xf86CrtcPtr crtc)
|
||||
{
|
||||
ScrnInfoPtr pScrn = crtc->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
int pipe;
|
||||
|
||||
if (pI830->use_drm_mode) {
|
||||
pipe = drmmode_get_pipe_from_crtc_id(pI830->bufmgr, crtc);
|
||||
} else {
|
||||
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
|
||||
pipe = intel_crtc->pipe;
|
||||
}
|
||||
|
||||
return pipe;
|
||||
}
|
||||
|
||||
static void
|
||||
I830AdjustMemory(ScreenPtr pScreen)
|
||||
|
|
|
|||
|
|
@ -1734,6 +1734,11 @@ i830_covering_crtc (ScrnInfoPtr pScrn,
|
|||
for (c = 0; c < xf86_config->num_crtc; c++)
|
||||
{
|
||||
crtc = xf86_config->crtc[c];
|
||||
|
||||
/* If the CRTC is off, treat it as not covering */
|
||||
if (!i830_crtc_on(crtc))
|
||||
continue;
|
||||
|
||||
i830_crtc_box (crtc, &crtc_box);
|
||||
i830_box_intersect (&cover_box, &crtc_box, box);
|
||||
coverage = i830_box_area (&cover_box);
|
||||
|
|
@ -2491,14 +2496,8 @@ I830PutImage(ScrnInfoPtr pScrn,
|
|||
int y1, y2;
|
||||
int pipe = -1, event, load_scan_lines_pipe;
|
||||
|
||||
if (pixmap_is_scanout(pPixmap)) {
|
||||
if (pI830->use_drm_mode)
|
||||
pipe = drmmode_get_pipe_from_crtc_id(pI830->bufmgr, crtc);
|
||||
else {
|
||||
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
|
||||
pipe = intel_crtc->pipe;
|
||||
}
|
||||
}
|
||||
if (pixmap_is_scanout(pPixmap))
|
||||
pipe = i830_crtc_to_pipe(crtc);
|
||||
|
||||
if (pipe >= 0) {
|
||||
if (pipe == 0) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue