Allow toggling TearFree at runtime via output property

Option "TearFree" now sets the default value of the output property.
See the manpage update for details.

TearFree is now enabled by default for outputs using rotation or other
RandR transforms, and for RandR 1.4 slave outputs.

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Michel Dänzer
2016-12-01 18:37:57 +09:00
committed by Michel Dänzer
parent 305e2cbf33
commit 58cd160005
6 changed files with 216 additions and 42 deletions

View File

@@ -281,10 +281,17 @@ Enable DRI2 page flipping. The default is
Pageflipping is supported on all radeon hardware. Pageflipping is supported on all radeon hardware.
.TP .TP
.BI "Option \*qTearFree\*q \*q" boolean \*q .BI "Option \*qTearFree\*q \*q" boolean \*q
Enable tearing prevention using the hardware page flipping mechanism. Requires allocating two Set the default value of the per-output 'TearFree' property, which controls
separate scanout buffers for each CRTC. Enabling this option currently disables Option tearing prevention using the hardware page flipping mechanism. TearFree is
\*qEnablePageFlip\*q. The default is on for any CRTC associated with one or more outputs with TearFree on. Two
.B off. separate scanout buffers need to be allocated for each CRTC with TearFree
on. While TearFree is on for any CRTC, it currently prevents clients from using
DRI page flipping. If this option is set, the default value of the property is
'on' or 'off' accordingly. If this option isn't set, the default value of the
property is
.B auto,
which means that TearFree is on for outputs with rotation or other RandR
transforms, and for RandR 1.4 slave outputs, otherwise off.
.TP .TP
.BI "Option \*qAccelMethod\*q \*q" "string" \*q .BI "Option \*qAccelMethod\*q \*q" "string" \*q
Chooses between available acceleration architectures. Valid values are Chooses between available acceleration architectures. Valid values are

View File

@@ -670,6 +670,34 @@ drmmode_can_use_hw_cursor(xf86CrtcPtr crtc)
return TRUE; return TRUE;
} }
static void
drmmode_crtc_update_tear_free(xf86CrtcPtr crtc)
{
RADEONInfoPtr info = RADEONPTR(crtc->scrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
int i;
drmmode_crtc->tear_free = FALSE;
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
drmmode_output_private_ptr drmmode_output = output->driver_private;
if (output->crtc != crtc)
continue;
if (drmmode_output->tear_free == 1 ||
(drmmode_output->tear_free == 2 &&
(radeon_is_gpu_screen(crtc->scrn->pScreen) ||
info->shadow_primary ||
crtc->transformPresent || crtc->rotation != RR_Rotate_0))) {
drmmode_crtc->tear_free = TRUE;
return;
}
}
}
#if XF86_CRTC_VERSION >= 4 #if XF86_CRTC_VERSION >= 4
static Bool static Bool
@@ -683,10 +711,11 @@ drmmode_handle_transform(xf86CrtcPtr crtc)
else else
crtc->driverIsPerformingTransform = XF86DriverTransformNone; crtc->driverIsPerformingTransform = XF86DriverTransformNone;
#else #else
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
RADEONInfoPtr info = RADEONPTR(crtc->scrn); RADEONInfoPtr info = RADEONPTR(crtc->scrn);
crtc->driverIsPerformingTransform = crtc->transformPresent || crtc->driverIsPerformingTransform = crtc->transformPresent ||
(info->tear_free && crtc->rotation != RR_Rotate_0); (drmmode_crtc->tear_free && crtc->rotation != RR_Rotate_0);
#endif #endif
ret = xf86CrtcRotate(crtc); ret = xf86CrtcRotate(crtc);
@@ -706,24 +735,87 @@ drmmode_handle_transform(xf86CrtcPtr crtc)
#endif #endif
#ifdef RADEON_PIXMAP_SHARING
static void static void
drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
unsigned scanout_id, int *fb_id, int *x,
int *y)
{
ScrnInfoPtr scrn = crtc->scrn;
ScreenPtr screen = scrn->pScreen;
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
if (drmmode_crtc->tear_free &&
!drmmode_crtc->scanout[1].pixmap) {
RegionPtr region;
BoxPtr box;
drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
mode->HDisplay,
mode->VDisplay);
region = &drmmode_crtc->scanout_last_region;
RegionUninit(region);
region->data = NULL;
box = RegionExtents(region);
box->x1 = crtc->x;
box->y1 = crtc->y;
box->x2 = crtc->x + mode->HDisplay;
box->y2 = crtc->y + mode->VDisplay;
}
if (scanout_id != drmmode_crtc->scanout_id) {
PixmapDirtyUpdatePtr dirty = NULL;
xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list,
ent) {
if (dirty->src == crtc->randr_crtc->scanout_pixmap &&
dirty->slave_dst ==
drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap) {
dirty->slave_dst =
drmmode_crtc->scanout[scanout_id].pixmap;
break;
}
}
if (!drmmode_crtc->tear_free) {
GCPtr gc = GetScratchGC(scrn->depth, screen);
ValidateGC(&drmmode_crtc->scanout[0].pixmap->drawable, gc);
gc->ops->CopyArea(&drmmode_crtc->scanout[1].pixmap->drawable,
&drmmode_crtc->scanout[0].pixmap->drawable,
gc, 0, 0, mode->HDisplay, mode->VDisplay,
0, 0);
FreeScratchGC(gc);
radeon_cs_flush_indirect(scrn);
radeon_bo_wait(drmmode_crtc->scanout[0].bo);
}
}
*fb_id = drmmode_crtc->scanout[scanout_id].fb_id;
*x = *y = 0;
drmmode_crtc->scanout_id = scanout_id;
}
#endif /* RADEON_PIXMAP_SHARING */
static void
drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
unsigned scanout_id, int *fb_id, int *x, int *y) unsigned scanout_id, int *fb_id, int *x, int *y)
{ {
ScrnInfoPtr scrn = crtc->scrn; ScrnInfoPtr scrn = crtc->scrn;
ScreenPtr screen = scrn->pScreen; ScreenPtr screen = scrn->pScreen;
RADEONInfoPtr info = RADEONPTR(scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0], drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0],
mode->HDisplay, mode->VDisplay); mode->HDisplay, mode->VDisplay);
if (info->tear_free) { if (drmmode_crtc->tear_free) {
drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1], drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
mode->HDisplay, mode->VDisplay); mode->HDisplay, mode->VDisplay);
} }
if (drmmode_crtc->scanout[0].pixmap && if (drmmode_crtc->scanout[0].pixmap &&
(!info->tear_free || drmmode_crtc->scanout[1].pixmap)) { (!drmmode_crtc->tear_free || drmmode_crtc->scanout[1].pixmap)) {
RegionPtr region; RegionPtr region;
BoxPtr box; BoxPtr box;
@@ -762,7 +854,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
RADEONInfoPtr info = RADEONPTR(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
unsigned scanout_id = drmmode_crtc->scanout_id ^ info->tear_free; unsigned scanout_id = 0;
drmmode_ptr drmmode = drmmode_crtc->drmmode; drmmode_ptr drmmode = drmmode_crtc->drmmode;
int saved_x, saved_y; int saved_x, saved_y;
Rotation saved_rotation; Rotation saved_rotation;
@@ -804,6 +896,10 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
if (!drmmode_handle_transform(crtc)) if (!drmmode_handle_transform(crtc))
goto done; goto done;
drmmode_crtc_update_tear_free(crtc);
if (drmmode_crtc->tear_free)
scanout_id = drmmode_crtc->scanout_id;
crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
crtc->gamma_blue, crtc->gamma_size); crtc->gamma_blue, crtc->gamma_size);
@@ -812,8 +908,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
fb_id = drmmode->fb_id; fb_id = drmmode->fb_id;
#ifdef RADEON_PIXMAP_SHARING #ifdef RADEON_PIXMAP_SHARING
if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) { if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) {
fb_id = drmmode_crtc->scanout[scanout_id].fb_id; drmmode_crtc_prime_scanout_update(crtc, mode, scanout_id,
x = y = 0; &fb_id, &x, &y);
} else } else
#endif #endif
if (drmmode_crtc->rotate.fb_id) { if (drmmode_crtc->rotate.fb_id) {
@@ -821,7 +917,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
x = y = 0; x = y = 0;
} else if (!radeon_is_gpu_screen(pScreen) && } else if (!radeon_is_gpu_screen(pScreen) &&
(info->tear_free || (drmmode_crtc->tear_free ||
#if XF86_CRTC_VERSION >= 4 #if XF86_CRTC_VERSION >= 4
crtc->driverIsPerformingTransform || crtc->driverIsPerformingTransform ||
#endif #endif
@@ -905,6 +1001,10 @@ done:
if (fb_id != drmmode_crtc->scanout[scanout_id].fb_id) if (fb_id != drmmode_crtc->scanout[scanout_id].fb_id)
drmmode_crtc_scanout_free(drmmode_crtc); drmmode_crtc_scanout_free(drmmode_crtc);
else if (!drmmode_crtc->tear_free) {
drmmode_crtc_scanout_destroy(drmmode,
&drmmode_crtc->scanout[1]);
}
} }
free(output_ids); free(output_ids);
@@ -1142,7 +1242,6 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
{ {
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
unsigned scanout_id = drmmode_crtc->scanout_id; unsigned scanout_id = drmmode_crtc->scanout_id;
RADEONInfoPtr info = RADEONPTR(crtc->scrn);
ScreenPtr screen = crtc->scrn->pScreen; ScreenPtr screen = crtc->scrn->pScreen;
PixmapDirtyUpdatePtr dirty; PixmapDirtyUpdatePtr dirty;
@@ -1163,7 +1262,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
ppix->drawable.height)) ppix->drawable.height))
return FALSE; return FALSE;
if (info->tear_free && if (drmmode_crtc->tear_free &&
!drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1], !drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
ppix->drawable.width, ppix->drawable.width,
ppix->drawable.height)) { ppix->drawable.height)) {
@@ -1418,13 +1517,14 @@ drmmode_property_ignore(drmModePropertyPtr prop)
static void static void
drmmode_output_create_resources(xf86OutputPtr output) drmmode_output_create_resources(xf86OutputPtr output)
{ {
RADEONInfoPtr info = RADEONPTR(output->scrn);
drmmode_output_private_ptr drmmode_output = output->driver_private; drmmode_output_private_ptr drmmode_output = output->driver_private;
drmModeConnectorPtr mode_output = drmmode_output->mode_output; drmModeConnectorPtr mode_output = drmmode_output->mode_output;
drmmode_ptr drmmode = drmmode_output->drmmode; drmmode_ptr drmmode = drmmode_output->drmmode;
drmModePropertyPtr drmmode_prop; drmModePropertyPtr drmmode_prop, tearfree_prop;
int i, j, err; int i, j, err;
drmmode_output->props = calloc(mode_output->count_props, sizeof(drmmode_prop_rec)); drmmode_output->props = calloc(mode_output->count_props + 1, sizeof(drmmode_prop_rec));
if (!drmmode_output->props) if (!drmmode_output->props)
return; return;
@@ -1441,6 +1541,23 @@ drmmode_output_create_resources(xf86OutputPtr output)
j++; j++;
} }
/* Userspace-only property for TearFree */
tearfree_prop = calloc(1, sizeof(*tearfree_prop));
tearfree_prop->flags = DRM_MODE_PROP_ENUM;
strncpy(tearfree_prop->name, "TearFree", 8);
tearfree_prop->count_enums = 3;
tearfree_prop->enums = calloc(tearfree_prop->count_enums,
sizeof(*tearfree_prop->enums));
strncpy(tearfree_prop->enums[0].name, "off", 3);
strncpy(tearfree_prop->enums[1].name, "on", 2);
tearfree_prop->enums[1].value = 1;
strncpy(tearfree_prop->enums[2].name, "auto", 4);
tearfree_prop->enums[2].value = 2;
drmmode_output->props[j].mode_prop = tearfree_prop;
drmmode_output->props[j].value = info->tear_free;
drmmode_output->tear_free = info->tear_free;
drmmode_output->num_props++;
for (i = 0; i < drmmode_output->num_props; i++) { for (i = 0; i < drmmode_output->num_props; i++) {
drmmode_prop_ptr p = &drmmode_output->props[i]; drmmode_prop_ptr p = &drmmode_output->props[i];
drmmode_prop = p->mode_prop; drmmode_prop = p->mode_prop;
@@ -1540,8 +1657,24 @@ drmmode_output_set_property(xf86OutputPtr output, Atom property,
/* search for matching name string, then set its value down */ /* search for matching name string, then set its value down */
for (j = 0; j < p->mode_prop->count_enums; j++) { for (j = 0; j < p->mode_prop->count_enums; j++) {
if (!strcmp(p->mode_prop->enums[j].name, name)) { if (!strcmp(p->mode_prop->enums[j].name, name)) {
drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, if (i == (drmmode_output->num_props - 1)) {
p->mode_prop->prop_id, p->mode_prop->enums[j].value); if (drmmode_output->tear_free != j) {
xf86CrtcPtr crtc = output->crtc;
drmmode_output->tear_free = j;
if (crtc) {
drmmode_set_mode_major(crtc, &crtc->mode,
crtc->rotation,
crtc->x, crtc->y);
}
}
} else {
drmModeConnectorSetProperty(drmmode->fd,
drmmode_output->output_id,
p->mode_prop->prop_id,
p->mode_prop->enums[j].value);
}
return TRUE; return TRUE;
} }
} }

View File

@@ -89,6 +89,7 @@ typedef struct {
RegionRec scanout_last_region; RegionRec scanout_last_region;
unsigned scanout_id; unsigned scanout_id;
Bool scanout_update_pending; Bool scanout_update_pending;
Bool tear_free;
int dpms_mode; int dpms_mode;
/* For when a flip is pending when DPMS off requested */ /* For when a flip is pending when DPMS off requested */
int pending_dpms_mode; int pending_dpms_mode;
@@ -124,6 +125,7 @@ typedef struct {
drmmode_prop_ptr props; drmmode_prop_ptr props;
int enc_mask; int enc_mask;
int enc_clone_mask; int enc_clone_mask;
int tear_free;
} drmmode_output_private_rec, *drmmode_output_private_ptr; } drmmode_output_private_rec, *drmmode_output_private_ptr;

View File

@@ -507,7 +507,7 @@ typedef struct {
Bool accelOn; Bool accelOn;
Bool use_glamor; Bool use_glamor;
Bool shadow_primary; Bool shadow_primary;
Bool tear_free; int tear_free;
Bool exa_pixmaps; Bool exa_pixmaps;
Bool exa_force_create; Bool exa_force_create;
XF86ModReqInfo exaReq; XF86ModReqInfo exaReq;

View File

@@ -47,6 +47,7 @@
#include "radeon_bo_gem.h" #include "radeon_bo_gem.h"
#include <xf86Priv.h> #include <xf86Priv.h>
#include <X11/extensions/dpmsconst.h>
#if DRI2INFOREC_VERSION >= 9 #if DRI2INFOREC_VERSION >= 9
#define USE_DRI2_PRIME #define USE_DRI2_PRIME
@@ -756,14 +757,34 @@ can_flip(ScrnInfoPtr pScrn, DrawablePtr draw,
DRI2BufferPtr front, DRI2BufferPtr back) DRI2BufferPtr front, DRI2BufferPtr back)
{ {
RADEONInfoPtr info = RADEONPTR(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int num_crtcs_on;
int i;
return draw->type == DRAWABLE_WINDOW && if (draw->type != DRAWABLE_WINDOW ||
info->allowPageFlip && !info->allowPageFlip ||
!info->hwcursor_disabled && info->hwcursor_disabled ||
!info->drmmode.present_flipping && info->drmmode.present_flipping ||
pScrn->vtSema && !pScrn->vtSema ||
DRI2CanFlip(draw) && !DRI2CanFlip(draw))
can_exchange(pScrn, draw, front, back); return FALSE;
for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) {
xf86CrtcPtr crtc = config->crtc[i];
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
if (!crtc->enabled)
continue;
if (!drmmode_crtc || drmmode_crtc->rotate.bo ||
drmmode_crtc->scanout[0].bo)
return FALSE;
if (drmmode_crtc->pending_dpms_mode == DPMSModeOn)
num_crtcs_on++;
}
return num_crtcs_on > 0 && can_exchange(pScrn, draw, front, back);
} }
static void static void

View File

@@ -669,7 +669,6 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
{ {
ScrnInfoPtr scrn = crtc->scrn; ScrnInfoPtr scrn = crtc->scrn;
ScreenPtr screen = scrn->pScreen; ScreenPtr screen = scrn->pScreen;
RADEONInfoPtr info = RADEONPTR(scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap; PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap;
PixmapDirtyUpdatePtr dirty; PixmapDirtyUpdatePtr dirty;
@@ -677,7 +676,7 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
if (dirty->src == scanoutpix && dirty->slave_dst == if (dirty->src == scanoutpix && dirty->slave_dst ==
drmmode_crtc->scanout[scanout_id ^ info->tear_free].pixmap) { drmmode_crtc->scanout[scanout_id ^ drmmode_crtc->tear_free].pixmap) {
RegionPtr region; RegionPtr region;
if (master_has_sync_shared_pixmap(scrn, dirty)) if (master_has_sync_shared_pixmap(scrn, dirty))
@@ -687,7 +686,7 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
if (RegionNil(region)) if (RegionNil(region))
goto destroy; goto destroy;
if (info->tear_free) { if (drmmode_crtc->tear_free) {
RegionTranslate(region, crtc->x, crtc->y); RegionTranslate(region, crtc->x, crtc->y);
radeon_sync_scanout_pixmaps(crtc, region, scanout_id); radeon_sync_scanout_pixmaps(crtc, region, scanout_id);
radeon_cs_flush_indirect(scrn); radeon_cs_flush_indirect(scrn);
@@ -823,7 +822,6 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent)
static void static void
radeon_dirty_update(ScrnInfoPtr scrn) radeon_dirty_update(ScrnInfoPtr scrn)
{ {
RADEONInfoPtr info = RADEONPTR(scrn);
ScreenPtr screen = scrn->pScreen; ScreenPtr screen = scrn->pScreen;
PixmapDirtyUpdatePtr ent; PixmapDirtyUpdatePtr ent;
RegionPtr region; RegionPtr region;
@@ -844,7 +842,13 @@ radeon_dirty_update(ScrnInfoPtr scrn)
region = dirty_region(region_ent); region = dirty_region(region_ent);
if (RegionNotEmpty(region)) { if (RegionNotEmpty(region)) {
if (info->tear_free) xf86CrtcPtr crtc = radeon_prime_dirty_to_crtc(ent);
drmmode_crtc_private_ptr drmmode_crtc = NULL;
if (crtc)
drmmode_crtc = crtc->driver_private;
if (drmmode_crtc && drmmode_crtc->tear_free)
radeon_prime_scanout_flip(ent); radeon_prime_scanout_flip(ent);
else else
radeon_prime_scanout_update(ent); radeon_prime_scanout_update(ent);
@@ -890,7 +894,7 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
if (!radeon_scanout_extents_intersect(xf86_crtc, &extents)) if (!radeon_scanout_extents_intersect(xf86_crtc, &extents))
return FALSE; return FALSE;
if (info->tear_free) { if (drmmode_crtc->tear_free) {
radeon_sync_scanout_pixmaps(xf86_crtc, pRegion, scanout_id); radeon_sync_scanout_pixmaps(xf86_crtc, pRegion, scanout_id);
RegionCopy(&drmmode_crtc->scanout_last_region, pRegion); RegionCopy(&drmmode_crtc->scanout_last_region, pRegion);
} }
@@ -1112,14 +1116,17 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
if (!radeon_is_gpu_screen(pScreen)) if (!radeon_is_gpu_screen(pScreen))
{ {
for (c = 0; c < xf86_config->num_crtc; c++) { for (c = 0; c < xf86_config->num_crtc; c++) {
if (info->tear_free) xf86CrtcPtr crtc = xf86_config->crtc[c];
radeon_scanout_flip(pScreen, info, xf86_config->crtc[c]); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
if (drmmode_crtc->tear_free)
radeon_scanout_flip(pScreen, info, crtc);
else if (info->shadow_primary else if (info->shadow_primary
#if XF86_CRTC_VERSION >= 4 #if XF86_CRTC_VERSION >= 4
|| xf86_config->crtc[c]->driverIsPerformingTransform || crtc->driverIsPerformingTransform
#endif #endif
) )
radeon_scanout_update(xf86_config->crtc[c]); radeon_scanout_update(crtc);
} }
} }
@@ -1633,6 +1640,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
{ {
RADEONInfoPtr info; RADEONInfoPtr info;
RADEONEntPtr pRADEONEnt; RADEONEntPtr pRADEONEnt;
MessageType from;
DevUnion* pPriv; DevUnion* pPriv;
Gamma zeros = { 0.0, 0.0, 0.0 }; Gamma zeros = { 0.0, 0.0, 0.0 };
uint32_t tiling = 0; uint32_t tiling = 0;
@@ -1778,11 +1786,14 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
#endif #endif
if (!info->r600_shadow_fb) { if (!info->r600_shadow_fb) {
info->tear_free = xf86ReturnOptValBool(info->Options, OPTION_TEAR_FREE, from = X_DEFAULT;
FALSE);
if (info->tear_free) info->tear_free = 2;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TearFree enabled\n"); if (xf86GetOptValBool(info->Options, OPTION_TEAR_FREE,
&info->tear_free))
from = X_CONFIG;
xf86DrvMsg(pScrn->scrnIndex, from, "TearFree property default: %s\n",
info->tear_free == 2 ? "auto" : (info->tear_free ? "on" : "off"));
} }
if (info->dri2.pKernelDRMVersion->version_minor >= 8) { if (info->dri2.pKernelDRMVersion->version_minor >= 8) {
@@ -1791,13 +1802,13 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
info->allowPageFlip = xf86ReturnOptValBool(info->Options, info->allowPageFlip = xf86ReturnOptValBool(info->Options,
OPTION_PAGE_FLIP, TRUE); OPTION_PAGE_FLIP, TRUE);
if (sw_cursor || info->tear_free || info->shadow_primary) { if (sw_cursor || info->shadow_primary) {
xf86DrvMsg(pScrn->scrnIndex, xf86DrvMsg(pScrn->scrnIndex,
info->allowPageFlip ? X_WARNING : X_DEFAULT, info->allowPageFlip ? X_WARNING : X_DEFAULT,
"KMS Pageflipping: disabled%s\n", "KMS Pageflipping: disabled%s\n",
info->allowPageFlip ? info->allowPageFlip ?
(sw_cursor ? " because of SWcursor" : (sw_cursor ? " because of SWcursor" :
" because of ShadowPrimary/TearFree") : ""); " because of ShadowPrimary") : "");
info->allowPageFlip = FALSE; info->allowPageFlip = FALSE;
} else { } else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, xf86DrvMsg(pScrn->scrnIndex, X_INFO,