summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2008-12-05 08:15:59 +0100
committerPierre Ossman <pierre@ossman.eu>2008-12-05 08:15:59 +0100
commitbae30856f2cb3884387ef347327af6ff00b75854 (patch)
tree2dc9e10ddc41193837b43dbdbdf3e985eccde657
parent33638d9e388b330e2f4eb4debd05ba09924cf176 (diff)
Make VSync for EXA and Xv configurable
-rw-r--r--man/radeon.man6
-rw-r--r--src/radeon.h9
-rw-r--r--src/radeon_commonfuncs.c5
-rw-r--r--src/radeon_driver.c1
-rw-r--r--src/radeon_exa_funcs.c12
-rw-r--r--src/radeon_exa_render.c2
-rw-r--r--src/radeon_textured_video.c25
-rw-r--r--src/radeon_textured_videofuncs.c3
-rw-r--r--src/radeon_video.h1
9 files changed, 53 insertions, 11 deletions
diff --git a/man/radeon.man b/man/radeon.man
index e18c8205..b347001e 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -516,6 +516,12 @@ This option allows you to disable int10 initialization. Set this to
False if you are experiencing a hang when initializing a secondary card.
The default is
.B on.
+.BI "Option \*qEXAVSync\*q \*q" boolean \*q
+This option attempts to avoid tearing by stalling the engine until the display
+controller has passed the destination region. It reduces tearing at the cost
+of performance.
+The default is
+.B off.
.SH SEE ALSO
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
diff --git a/src/radeon.h b/src/radeon.h
index 051b7658..8427e84c 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -205,7 +205,8 @@ typedef enum {
OPTION_TVSTD,
OPTION_IGNORE_LID_STATUS,
OPTION_DEFAULT_TVDAC_ADJ,
- OPTION_INT10
+ OPTION_INT10,
+ OPTION_EXA_VSYNC
} RADEONOpts;
@@ -601,6 +602,8 @@ struct radeon_accel_state {
/* Size of tiles ... set to 65536x65536 if not tiling in that direction */
Bool src_tile_width;
Bool src_tile_height;
+
+ Bool vsync;
#endif
#ifdef USE_XAA
@@ -942,11 +945,11 @@ extern Bool radeon_card_posted(ScrnInfoPtr pScrn);
#ifdef XF86DRI
extern void RADEONWaitForIdleCP(ScrnInfoPtr pScrn);
extern void RADEONWaitForVLineCP(ScrnInfoPtr pScrn, PixmapPtr pPix,
- int crtc, int start, int stop);
+ int crtc, int start, int stop, int enable);
#endif
extern void RADEONWaitForIdleMMIO(ScrnInfoPtr pScrn);
extern void RADEONWaitForVLineMMIO(ScrnInfoPtr pScrn, PixmapPtr pPix,
- int crtc, int start, int stop);
+ int crtc, int start, int stop, int enable);
/* radeon_crtc.c */
extern void radeon_crtc_dpms(xf86CrtcPtr crtc, int mode);
diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c
index c2f34511..92e10d29 100644
--- a/src/radeon_commonfuncs.c
+++ b/src/radeon_commonfuncs.c
@@ -637,13 +637,16 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
/* inserts a wait for vline in the command stream */
void FUNC_NAME(RADEONWaitForVLine)(ScrnInfoPtr pScrn, PixmapPtr pPix,
- int crtc, int start, int stop)
+ int crtc, int start, int stop, Bool enable)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
uint32_t offset;
ACCEL_PREAMBLE();
+ if (!enable)
+ return;
+
if ((crtc < 0) || (crtc > 1))
return;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index a8884362..843e9ff6 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -192,6 +192,7 @@ static const OptionInfoRec RADEONOptions[] = {
{ OPTION_IGNORE_LID_STATUS, "IgnoreLidStatus", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_DEFAULT_TVDAC_ADJ, "DefaultTVDACAdj", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_INT10, "Int10", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_EXA_VSYNC, "EXAVSync", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index fe487016..55710ff5 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -129,7 +129,7 @@ FUNC_NAME(RADEONSolid)(PixmapPtr pPix, int x1, int y1, int x2, int y2)
TRACE;
- FUNC_NAME(RADEONWaitForVLine)(pScrn, pPix, RADEONBiggerCrtcArea(pPix), y1, y2);
+ FUNC_NAME(RADEONWaitForVLine)(pScrn, pPix, RADEONBiggerCrtcArea(pPix), y1, y2, info->accel_state->vsync);
BEGIN_ACCEL(2);
OUT_ACCEL_REG(RADEON_DST_Y_X, (y1 << 16) | x1);
@@ -230,7 +230,7 @@ FUNC_NAME(RADEONCopy)(PixmapPtr pDst,
dstY += h - 1;
}
- FUNC_NAME(RADEONWaitForVLine)(pScrn, pDst, RADEONBiggerCrtcArea(pDst), dstY, dstY + h);
+ FUNC_NAME(RADEONWaitForVLine)(pScrn, pDst, RADEONBiggerCrtcArea(pDst), dstY, dstY + h, info->accel_state->vsync);
BEGIN_ACCEL(3);
@@ -289,7 +289,7 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h,
RADEON_SWITCH_TO_2D();
- FUNC_NAME(RADEONWaitForVLine)(pScrn, pDst, RADEONBiggerCrtcArea(pDst), y, y + h);
+ FUNC_NAME(RADEONWaitForVLine)(pScrn, pDst, RADEONBiggerCrtcArea(pDst), y, y + h, info->accel_state->vsync);
while ((buf = RADEONHostDataBlit(pScrn,
cpp, w, dst_pitch_off, &buf_pitch,
@@ -612,6 +612,12 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
#endif
info->accel_state->exa->maxY = 8192;
+ if (xf86ReturnOptValBool(info->Options, OPTION_EXA_VSYNC, FALSE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EXA VSync enabled\n");
+ info->accel_state->vsync = TRUE;
+ } else
+ info->accel_state->vsync = FALSE;
+
RADEONEngineInit(pScrn);
if (!exaDriverInit(pScreen, info->accel_state->exa)) {
diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
index 4b918c4c..b5f01970 100644
--- a/src/radeon_exa_render.c
+++ b/src/radeon_exa_render.c
@@ -1997,7 +1997,7 @@ static void FUNC_NAME(RadeonCompositeTile)(PixmapPtr pDst,
else
vtx_count = 4;
- FUNC_NAME(RADEONWaitForVLine)(pScrn, pDst, RADEONBiggerCrtcArea(pDst), dstY, dstY + h);
+ FUNC_NAME(RADEONWaitForVLine)(pScrn, pDst, RADEONBiggerCrtcArea(pDst), dstY, dstY + h, info->accel_state->vsync);
#ifdef ACCEL_CP
if (info->ChipFamily < CHIP_FAMILY_R200) {
diff --git a/src/radeon_textured_video.c b/src/radeon_textured_video.c
index cf6999cf..7712344b 100644
--- a/src/radeon_textured_video.c
+++ b/src/radeon_textured_video.c
@@ -381,11 +381,21 @@ static XF86VideoFormatRec Formats[NUM_FORMATS] =
static XF86AttributeRec Attributes[NUM_ATTRIBUTES+1] =
{
+ {XvSettable | XvGettable, 0, 1, "XV_VSYNC"},
+ {0, 0, 0, NULL}
+};
+
+#define NUM_ATTRIBUTES_R300 2
+
+static XF86AttributeRec Attributes_r300[NUM_ATTRIBUTES_R300+1] =
+{
{XvSettable | XvGettable, 0, 2, "XV_BICUBIC"},
+ {XvSettable | XvGettable, 0, 1, "XV_VSYNC"},
{0, 0, 0, NULL}
};
static Atom xvBicubic;
+static Atom xvVSync;
#define NUM_IMAGES 4
@@ -410,6 +420,8 @@ RADEONGetTexPortAttribute(ScrnInfoPtr pScrn,
if (attribute == xvBicubic)
*value = pPriv->bicubic_state;
+ else if (attribute == xvVSync)
+ *value = pPriv->vsync;
else
return BadMatch;
@@ -429,6 +441,8 @@ RADEONSetTexPortAttribute(ScrnInfoPtr pScrn,
if (attribute == xvBicubic)
pPriv->bicubic_state = ClipValue (value, 0, 2);
+ else if (attribute == xvVSync)
+ pPriv->vsync = ClipValue (value, 0, 1);
else
return BadMatch;
@@ -451,6 +465,7 @@ RADEONSetupImageTexturedVideo(ScreenPtr pScreen)
return NULL;
xvBicubic = MAKE_ATOM("XV_BICUBIC");
+ xvVSync = MAKE_ATOM("XV_VSYNC");
adapt->type = XvWindowMask | XvInputMask | XvImageMask;
adapt->flags = 0;
@@ -468,8 +483,13 @@ RADEONSetupImageTexturedVideo(ScreenPtr pScreen)
pPortPriv =
(RADEONPortPrivPtr)(&adapt->pPortPrivates[num_texture_ports]);
- adapt->pAttributes = Attributes;
- adapt->nAttributes = NUM_ATTRIBUTES;
+ if (IS_R300_3D || IS_R500_3D) {
+ adapt->pAttributes = Attributes_r300;
+ adapt->nAttributes = NUM_ATTRIBUTES_R300;
+ } else {
+ adapt->pAttributes = Attributes;
+ adapt->nAttributes = NUM_ATTRIBUTES;
+ }
adapt->pImages = Images;
adapt->nImages = NUM_IMAGES;
adapt->PutVideo = NULL;
@@ -492,6 +512,7 @@ RADEONSetupImageTexturedVideo(ScreenPtr pScreen)
pPriv->currentBuffer = 0;
pPriv->doubleBuffer = 0;
pPriv->bicubic_state = BICUBIC_AUTO;
+ pPriv->vsync = TRUE;
/* gotta uninit this someplace, XXX: shouldn't be necessary for textured */
REGION_NULL(pScreen, &pPriv->clip);
diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c
index 06387511..e324fd96 100644
--- a/src/radeon_textured_videofuncs.c
+++ b/src/radeon_textured_videofuncs.c
@@ -1521,7 +1521,8 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
pPriv->drw_y + pPriv->dst_h,
pPriv->desired_crtc),
pPriv->drw_y,
- pPriv->drw_y + pPriv->dst_h);
+ pPriv->drw_y + pPriv->dst_h,
+ pPriv->vsync);
while (nBox--) {
int srcX, srcY, srcw, srch;
diff --git a/src/radeon_video.h b/src/radeon_video.h
index 7c4151f0..7f1891e4 100644
--- a/src/radeon_video.h
+++ b/src/radeon_video.h
@@ -115,6 +115,7 @@ typedef struct {
int src_w, src_h, dst_w, dst_h;
int w, h;
int drw_x, drw_y;
+ int vsync;
} RADEONPortPrivRec, *RADEONPortPrivPtr;
int