mirror of
https://github.com/X11Libre/xf86-video-ati.git
synced 2026-03-24 01:24:43 +00:00
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:
committed by
Michel Dänzer
parent
305e2cbf33
commit
58cd160005
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user