intel: Make the option to control VSync and PageFlip explict

Too often our implementation of vsync or pageflip is buggy, or for some
other reason it is desired by the user to disable those code paths. Make
it possible once again by restoring the Options for the user to control.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2013-09-17 09:15:40 +01:00
parent 76790db4e6
commit f99e49f764
7 changed files with 60 additions and 12 deletions

View File

@ -196,13 +196,31 @@ i.e. perform synchronous rendering.
Default: Disabled
.TP
.TP
.BI "Option \*qVSync\*q \*q" boolean \*q
This option controls the use of commands to synchronise rendering with the
vertical refresh of the display. Some rendering commands have the option
to be performed in a "tear-free" fashion by stalling the GPU to wait for
the display to be outside of the region to be updated. This slows down all
rendering, and historically has been the source of many GPU hangs.
.IP
Default: enabled.
.TP
.BI "Option \*qPageFlip\*q \*q" boolean \*q
This option controls the use of commands to flip the scanout address on a
VBlank. This is used by glXSwapBuffers to efficiently perform the back-to-front
exchange at the end of a frame without incurring the penalty of a copy, or
stalling the render pipeline (the flip is performed asynchronrously to the
render command stream by the display engine). However, it has historically
been the source of many GPU hangs.
.IP
Default: enabled.
.TP
.BI "Option \*qSwapbuffersWait\*q \*q" boolean \*q
This option controls the behavior of glXSwapBuffers and glXCopySubBufferMESA
calls by GL applications. If enabled, the calls will avoid tearing by making
sure the display scanline is outside of the area to be copied before the copy
occurs. If disabled, no scanline synchronization is performed, meaning tearing
will likely occur. Note that when enabled, this option can adversely affect
the framerate of applications that render frames at less than refresh rate.
will likely occur.
.IP
Default: enabled.
.TP

View File

@ -13,6 +13,8 @@ const OptionInfoRec intel_options[] = {
{OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, 0},
{OPTION_TILING_2D, "Tiling", OPTV_BOOLEAN, {0}, 1},
{OPTION_TILING_FB, "LinearFramebuffer", OPTV_BOOLEAN, {0}, 0},
{OPTION_VSYNC, "VSync", OPTV_BOOLEAN, {0}, 1},
{OPTION_PAGEFLIP, "PageFlip", OPTV_BOOLEAN, {0}, 1},
{OPTION_SWAPBUFFERS_WAIT, "SwapbuffersWait", OPTV_BOOLEAN, {0}, 1},
{OPTION_TRIPLE_BUFFER, "TripleBuffer", OPTV_BOOLEAN, {0}, 1},
{OPTION_PREFER_OVERLAY, "XvPreferOverlay", OPTV_BOOLEAN, {0}, 0},

View File

@ -19,6 +19,8 @@ enum intel_options {
OPTION_COLOR_KEY,
OPTION_TILING_2D,
OPTION_TILING_FB,
OPTION_VSYNC,
OPTION_PAGEFLIP,
OPTION_SWAPBUFFERS_WAIT,
OPTION_TRIPLE_BUFFER,
OPTION_PREFER_OVERLAY,

View File

@ -226,7 +226,8 @@ struct sna {
unsigned flags;
#define SNA_NO_WAIT 0x1
#define SNA_NO_FLIP 0x2
#define SNA_TRIPLE_BUFFER 0x4
#define SNA_NO_VSYNC 0x4
#define SNA_TRIPLE_BUFFER 0x8
#define SNA_TEAR_FREE 0x10
#define SNA_FORCE_SHADOW 0x20
#define SNA_FLUSH_GTT 0x40

View File

@ -3627,6 +3627,9 @@ sna_wait_for_scanline(struct sna *sna,
assert(to_sna_crtc(crtc)->bo != NULL);
assert(pixmap == sna->front);
if (sna->flags & SNA_NO_VSYNC)
return false;
/*
* Make sure we don't wait for a scanline that will
* never occur

View File

@ -303,7 +303,7 @@ sna_dri_create_buffer(DrawablePtr draw,
case DRI2BufferBackLeft:
if (draw->width == sna->front->drawable.width &&
draw->height == sna->front->drawable.height &&
(sna->flags & SNA_NO_FLIP) == 0)
(sna->flags & (SNA_NO_WAIT | SNA_NO_FLIP)) == 0)
flags |= CREATE_SCANOUT;
case DRI2BufferBackRight:
case DRI2BufferFrontRight:
@ -1080,6 +1080,8 @@ can_flip(struct sna * sna,
WindowPtr win = (WindowPtr)draw;
PixmapPtr pixmap;
assert((sna->flags & SNA_NO_WAIT) == 0);
if (draw->type == DRAWABLE_PIXMAP)
return false;
@ -1967,7 +1969,9 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
assert(sna_pixmap_from_drawable(draw)->flush);
/* Drawable not displayed... just complete the swap */
pipe = sna_dri_get_pipe(draw);
pipe = -1;
if (sna->flags & SNA_NO_WAIT)
pipe = sna_dri_get_pipe(draw);
if (pipe == -1) {
DBG(("%s: off-screen, immediate update\n", __FUNCTION__));
goto blit;

View File

@ -294,12 +294,20 @@ static void sna_selftest(void)
sna_damage_selftest();
}
static bool has_vsync(struct sna *sna)
{
if (sna->flags & SNA_IS_HOSTED)
return false;
return true;
}
static bool has_pageflipping(struct sna *sna)
{
drm_i915_getparam_t gp;
int v;
if (sna->flags & (SNA_IS_HOSTED | SNA_NO_WAIT))
if (sna->flags & SNA_IS_HOSTED)
return false;
v = 0;
@ -508,13 +516,23 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
if (!xf86ReturnOptValBool(sna->Options, OPTION_SWAPBUFFERS_WAIT, TRUE))
sna->flags |= SNA_NO_WAIT;
if (xf86ReturnOptValBool(sna->Options, OPTION_TRIPLE_BUFFER, TRUE))
sna->flags |= SNA_TRIPLE_BUFFER;
if (has_pageflipping(sna)) {
if (xf86ReturnOptValBool(sna->Options, OPTION_TEAR_FREE, FALSE))
sna->flags |= SNA_TEAR_FREE;
} else
if (!has_vsync(sna) ||
!xf86ReturnOptValBool(sna->Options, OPTION_VSYNC, TRUE))
sna->flags |= SNA_NO_VSYNC;
if (!has_pageflipping(sna) ||
!xf86ReturnOptValBool(sna->Options, OPTION_PAGEFLIP, TRUE))
sna->flags |= SNA_NO_FLIP;
if ((sna->flags & (SNA_NO_VSYNC | SNA_NO_FLIP | SNA_NO_WAIT)) == 0 &&
xf86ReturnOptValBool(sna->Options, OPTION_TRIPLE_BUFFER, TRUE))
sna->flags |= SNA_TRIPLE_BUFFER;
if ((sna->flags & (SNA_NO_VSYNC | SNA_NO_FLIP)) == 0 &&
xf86ReturnOptValBool(sna->Options, OPTION_TEAR_FREE, FALSE))
sna->flags |= SNA_TEAR_FREE;
if (xf86ReturnOptValBool(sna->Options, OPTION_CRTC_PIXMAPS, FALSE))
sna->flags |= SNA_FORCE_SHADOW;