Accepting request 438260 from home:mstaudt:branches:X11:XOrg
- U_01-* ... U_20-* : Include patches that haven't made it into the 7.7.1 release. This means almost all commits between xf86-video-ati-7.7.0 and 12d30eeb9711bd2b1609d6bbb74c4a1760596f72. Fixes (bsc#990066). OBS-URL: https://build.opensuse.org/request/show/438260 OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xf86-video-ati?expand=0&rev=51
This commit is contained in:
parent
c75de0aff0
commit
84a4590c79
@ -0,0 +1,27 @@
|
||||
From: Tom St Denis <tom.stdenis@amd.com>
|
||||
Date: Fri Apr 8 10:22:11 2016 -0400
|
||||
Subject: [PATCH 1/20]dri3: Return NULL from radeon_dri3_pixmap_from_fd if calloc fails.
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: bd4c72c8625996d842824ce4963f2d759fe2954a
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
Signed-off-by: Tom St Denis <tom.stdenis@amd.com>
|
||||
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
|
||||
---
|
||||
src/radeon_dri3.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/radeon_dri3.c b/src/radeon_dri3.c
|
||||
index 43a073b..c567024 100644
|
||||
--- a/src/radeon_dri3.c
|
||||
+++ b/src/radeon_dri3.c
|
||||
@@ -144,6 +144,7 @@ static PixmapPtr radeon_dri3_pixmap_from_fd(ScreenPtr screen,
|
||||
}
|
||||
|
||||
screen->DestroyPixmap(pixmap);
|
||||
+ return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
123
U_02-Add-support-for-async-flips-to-radeon_do_pageflip.patch
Normal file
123
U_02-Add-support-for-async-flips-to-radeon_do_pageflip.patch
Normal file
@ -0,0 +1,123 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Tue Mar 15 16:42:16 2016 +0900
|
||||
Subject: [PATCH 2/20]Add support for async flips to radeon_do_pageflip
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 90a915c62d012e99193833aecc93974e68880c60
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
Will be used by the next change. No functional change here.
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
src/drmmode_display.c | 9 +++++++--
|
||||
src/drmmode_display.h | 9 ++++++++-
|
||||
src/radeon_dri2.c | 2 +-
|
||||
src/radeon_present.c | 5 +++--
|
||||
4 files changed, 19 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
|
||||
index 0f57292..34b76e9 100644
|
||||
--- a/src/drmmode_display.c
|
||||
+++ b/src/drmmode_display.c
|
||||
@@ -2741,7 +2741,8 @@ void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
|
||||
Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
|
||||
uint32_t new_front_handle, uint64_t id, void *data,
|
||||
int ref_crtc_hw_id, radeon_drm_handler_proc handler,
|
||||
- radeon_drm_abort_proc abort)
|
||||
+ radeon_drm_abort_proc abort,
|
||||
+ enum drmmode_flip_sync flip_sync)
|
||||
{
|
||||
RADEONInfoPtr info = RADEONPTR(scrn);
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
|
||||
@@ -2751,6 +2752,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
|
||||
unsigned int pitch;
|
||||
int i;
|
||||
uint32_t tiling_flags = 0;
|
||||
+ uint32_t flip_flags = DRM_MODE_PAGE_FLIP_EVENT;
|
||||
drmmode_flipdata_ptr flipdata;
|
||||
uintptr_t drm_queue_seq = 0;
|
||||
|
||||
@@ -2797,6 +2799,9 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
|
||||
flipdata->handler = handler;
|
||||
flipdata->abort = abort;
|
||||
|
||||
+ if (flip_sync == FLIP_ASYNC)
|
||||
+ flip_flags |= DRM_MODE_PAGE_FLIP_ASYNC;
|
||||
+
|
||||
for (i = 0; i < config->num_crtc; i++) {
|
||||
crtc = config->crtc[i];
|
||||
|
||||
@@ -2823,7 +2828,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
|
||||
}
|
||||
|
||||
if (drmModePageFlip(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
|
||||
- drmmode->fb_id, DRM_MODE_PAGE_FLIP_EVENT,
|
||||
+ drmmode->fb_id, flip_flags,
|
||||
(void*)drm_queue_seq)) {
|
||||
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
|
||||
"flip queue failed: %s\n", strerror(errno));
|
||||
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
|
||||
index bbb827c..63b96ac 100644
|
||||
--- a/src/drmmode_display.h
|
||||
+++ b/src/drmmode_display.h
|
||||
@@ -127,6 +127,12 @@ typedef struct {
|
||||
} drmmode_output_private_rec, *drmmode_output_private_ptr;
|
||||
|
||||
|
||||
+enum drmmode_flip_sync {
|
||||
+ FLIP_VSYNC,
|
||||
+ FLIP_ASYNC,
|
||||
+};
|
||||
+
|
||||
+
|
||||
extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);
|
||||
extern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
|
||||
extern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
|
||||
@@ -154,7 +160,8 @@ extern void drmmode_clear_pending_flip(xf86CrtcPtr crtc);
|
||||
Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
|
||||
uint32_t new_front_handle, uint64_t id, void *data,
|
||||
int ref_crtc_hw_id, radeon_drm_handler_proc handler,
|
||||
- radeon_drm_abort_proc abort);
|
||||
+ radeon_drm_abort_proc abort,
|
||||
+ enum drmmode_flip_sync flip_sync);
|
||||
int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc);
|
||||
int drmmode_get_current_ust(int drm_fd, CARD64 *ust);
|
||||
|
||||
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
|
||||
index 0cd6b24..5ebc9b7 100644
|
||||
--- a/src/radeon_dri2.c
|
||||
+++ b/src/radeon_dri2.c
|
||||
@@ -678,7 +678,7 @@ radeon_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client,
|
||||
RADEON_DRM_QUEUE_ID_DEFAULT, flip_info,
|
||||
ref_crtc_hw_id,
|
||||
radeon_dri2_flip_event_handler,
|
||||
- radeon_dri2_flip_event_abort)) {
|
||||
+ radeon_dri2_flip_event_abort, FLIP_VSYNC)) {
|
||||
info->drmmode.dri2_flipping = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
diff --git a/src/radeon_present.c b/src/radeon_present.c
|
||||
index 2389c7f..1a0e06a 100644
|
||||
--- a/src/radeon_present.c
|
||||
+++ b/src/radeon_present.c
|
||||
@@ -338,7 +338,8 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc,
|
||||
ret = radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle,
|
||||
event_id, event, crtc_id,
|
||||
radeon_present_flip_event,
|
||||
- radeon_present_flip_abort);
|
||||
+ radeon_present_flip_abort,
|
||||
+ FLIP_VSYNC);
|
||||
if (!ret)
|
||||
xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present flip failed\n");
|
||||
else
|
||||
@@ -381,7 +382,7 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id)
|
||||
|
||||
if (radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle,
|
||||
event_id, event, -1, radeon_present_flip_event,
|
||||
- radeon_present_flip_abort))
|
||||
+ radeon_present_flip_abort, FLIP_VSYNC))
|
||||
return;
|
||||
|
||||
modeset:
|
42
U_03-present-Support-async-flips.patch
Normal file
42
U_03-present-Support-async-flips.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Tue Mar 15 16:47:35 2016 +0900
|
||||
Subject: [PATCH 3/20]present: Support async flips
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 1ca677309720e2f6c953c9e76f5b34c22a4416c6
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
The xserver Present code only calls radeon_present_flip with
|
||||
sync_flip=FALSE if radeon_present_screen_init sets
|
||||
PresentCapabilityAsync, and the latter only sets it if the kernel driver
|
||||
advertises support for async flips.
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
src/radeon_present.c | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/radeon_present.c b/src/radeon_present.c
|
||||
index 1a0e06a..69a0532 100644
|
||||
--- a/src/radeon_present.c
|
||||
+++ b/src/radeon_present.c
|
||||
@@ -248,9 +248,6 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
|
||||
if (info->hwcursor_disabled)
|
||||
return FALSE;
|
||||
|
||||
- if (!sync_flip)
|
||||
- return FALSE;
|
||||
-
|
||||
if (info->drmmode.dri2_flipping)
|
||||
return FALSE;
|
||||
|
||||
@@ -339,7 +336,7 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc,
|
||||
event_id, event, crtc_id,
|
||||
radeon_present_flip_event,
|
||||
radeon_present_flip_abort,
|
||||
- FLIP_VSYNC);
|
||||
+ sync_flip ? FLIP_VSYNC : FLIP_ASYNC);
|
||||
if (!ret)
|
||||
xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present flip failed\n");
|
||||
else
|
@ -0,0 +1,46 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Tue May 10 19:02:20 2016 +0900
|
||||
Subject: [PATCH 4/20]Enable DRI3 by default when building for Xorg >= 1.18.3
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 1181b9c582f10b6c523e4b2988e2ce87ecf3d367
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
Seems to work well enough in general now.
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
man/radeon.man | 2 ++
|
||||
src/radeon_kms.c | 4 ++++
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
diff --git a/man/radeon.man b/man/radeon.man
|
||||
index 1acdc63..cacafb5 100644
|
||||
--- a/man/radeon.man
|
||||
+++ b/man/radeon.man
|
||||
@@ -270,6 +270,8 @@ Sea Islands.
|
||||
.BI "Option \*qDRI\*q \*q" integer \*q
|
||||
Define the maximum level of DRI to enable. Valid values are 2 for DRI2 or 3 for DRI3.
|
||||
The default is
|
||||
+.B 3 for DRI3
|
||||
+if the driver was compiled for Xorg >= 1.18.3, otherwise
|
||||
.B 2 for DRI2.
|
||||
.TP
|
||||
.BI "Option \*qEnablePageFlip\*q \*q" boolean \*q
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index f9abc09..0ced370 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -1725,7 +1725,11 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
|
||||
}
|
||||
#endif
|
||||
|
||||
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,18,3,0,0)
|
||||
+ value = TRUE;
|
||||
+#else
|
||||
value = FALSE;
|
||||
+#endif
|
||||
from = X_DEFAULT;
|
||||
|
||||
if (!info->r600_shadow_fb) {
|
944
U_05-EXA-6xx-7xx-fast-solid-pixmap-support.patch
Normal file
944
U_05-EXA-6xx-7xx-fast-solid-pixmap-support.patch
Normal file
@ -0,0 +1,944 @@
|
||||
From: Tan Hu <tan.hu@zte.com.cn>
|
||||
Date: Fri May 27 17:05:14 2016 +0800
|
||||
Subject: [PATCH 5/20]EXA/6xx/7xx: fast solid pixmap support
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 9b9ad669c748f53247e53fa3f3b03a77da5e5cb3
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
Solid pixmaps are currently implemented with scratch pixmaps, which
|
||||
is slow. This replaces the hack with a proper implementation. The
|
||||
Composite shader can now either sample a src/mask or use a constant
|
||||
value.
|
||||
|
||||
r6xx still be used on some machine,
|
||||
Ported from commit 94d0d14914a025525a0766669b556eaa6681def7.
|
||||
|
||||
Signed-off-by: Tan Hu <tan.hu@zte.com.cn>
|
||||
Reviewed-by: Grigori Goronzy <greg@chown.ath.cx>
|
||||
---
|
||||
src/r600_exa.c | 257 ++++++++++++++++++++++++---------
|
||||
src/r600_shader.c | 418 +++++++++++++++++++++++++++++++++++++++++++-----------
|
||||
2 files changed, 526 insertions(+), 149 deletions(-)
|
||||
|
||||
diff --git a/src/r600_exa.c b/src/r600_exa.c
|
||||
index 8d11ce7..10df4ec 100644
|
||||
--- a/src/r600_exa.c
|
||||
+++ b/src/r600_exa.c
|
||||
@@ -1165,6 +1165,134 @@ static Bool R600CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP
|
||||
|
||||
}
|
||||
|
||||
+static void R600SetSolidConsts(ScrnInfoPtr pScrn, float *buf, int format, uint32_t fg, int unit)
|
||||
+{
|
||||
+ RADEONInfoPtr info = RADEONPTR(pScrn);
|
||||
+ struct radeon_accel_state *accel_state = info->accel_state;
|
||||
+ float pix_r = 0, pix_g = 0, pix_b = 0, pix_a = 0;
|
||||
+
|
||||
+ uint32_t w = (fg >> 24) & 0xff;
|
||||
+ uint32_t z = (fg >> 16) & 0xff;
|
||||
+ uint32_t y = (fg >> 8) & 0xff;
|
||||
+ uint32_t x = (fg >> 0) & 0xff;
|
||||
+ float xf = (float)x / 255; /* R */
|
||||
+ float yf = (float)y / 255; /* G */
|
||||
+ float zf = (float)z / 255; /* B */
|
||||
+ float wf = (float)w / 255; /* A */
|
||||
+
|
||||
+ /* component swizzles */
|
||||
+ switch (format) {
|
||||
+ case PICT_a1r5g5b5:
|
||||
+ case PICT_a8r8g8b8:
|
||||
+ pix_r = zf; /* R */
|
||||
+ pix_g = yf; /* G */
|
||||
+ pix_b = xf; /* B */
|
||||
+ pix_a = wf; /* A */
|
||||
+ break;
|
||||
+ case PICT_a8b8g8r8:
|
||||
+ pix_r = xf; /* R */
|
||||
+ pix_g = yf; /* G */
|
||||
+ pix_b = zf; /* B */
|
||||
+ pix_a = wf; /* A */
|
||||
+ break;
|
||||
+ case PICT_x8b8g8r8:
|
||||
+ pix_r = xf; /* R */
|
||||
+ pix_g = yf; /* G */
|
||||
+ pix_b = zf; /* B */
|
||||
+ pix_a = 1.0; /* A */
|
||||
+ break;
|
||||
+ case PICT_b8g8r8a8:
|
||||
+ pix_r = yf; /* R */
|
||||
+ pix_g = zf; /* G */
|
||||
+ pix_b = wf; /* B */
|
||||
+ pix_a = xf; /* A */
|
||||
+ break;
|
||||
+ case PICT_b8g8r8x8:
|
||||
+ pix_r = yf; /* R */
|
||||
+ pix_g = zf; /* G */
|
||||
+ pix_b = wf; /* B */
|
||||
+ pix_a = 1.0; /* A */
|
||||
+ break;
|
||||
+ case PICT_x1r5g5b5:
|
||||
+ case PICT_x8r8g8b8:
|
||||
+ case PICT_r5g6b5:
|
||||
+ pix_r = zf; /* R */
|
||||
+ pix_g = yf; /* G */
|
||||
+ pix_b = xf; /* B */
|
||||
+ pix_a = 1.0; /* A */
|
||||
+ break;
|
||||
+ case PICT_a8:
|
||||
+ pix_r = 0.0; /* R */
|
||||
+ pix_g = 0.0; /* G */
|
||||
+ pix_b = 0.0; /* B */
|
||||
+ pix_a = xf; /* A */
|
||||
+ break;
|
||||
+ default:
|
||||
+ ErrorF("Bad format 0x%x\n", format);
|
||||
+ }
|
||||
+
|
||||
+ if (unit == 0) {
|
||||
+ if (!accel_state->msk_pic) {
|
||||
+ if (PICT_FORMAT_RGB(format) == 0) {
|
||||
+ pix_r = 0.0;
|
||||
+ pix_g = 0.0;
|
||||
+ pix_b = 0.0;
|
||||
+ }
|
||||
+
|
||||
+ if (PICT_FORMAT_A(format) == 0)
|
||||
+ pix_a = 1.0;
|
||||
+ } else {
|
||||
+ if (accel_state->component_alpha) {
|
||||
+ if (accel_state->src_alpha) {
|
||||
+ if (PICT_FORMAT_A(format) == 0) {
|
||||
+ pix_r = 1.0;
|
||||
+ pix_g = 1.0;
|
||||
+ pix_b = 1.0;
|
||||
+ pix_a = 1.0;
|
||||
+ } else {
|
||||
+ pix_r = pix_a;
|
||||
+ pix_g = pix_a;
|
||||
+ pix_b = pix_a;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (PICT_FORMAT_A(format) == 0)
|
||||
+ pix_a = 1.0;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (PICT_FORMAT_RGB(format) == 0) {
|
||||
+ pix_r = 0;
|
||||
+ pix_g = 0;
|
||||
+ pix_b = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (PICT_FORMAT_A(format) == 0)
|
||||
+ pix_a = 1.0;
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (accel_state->component_alpha) {
|
||||
+ if (PICT_FORMAT_A(format) == 0)
|
||||
+ pix_a = 1.0;
|
||||
+ } else {
|
||||
+ if (PICT_FORMAT_A(format) == 0) {
|
||||
+ pix_r = 1.0;
|
||||
+ pix_g = 1.0;
|
||||
+ pix_b = 1.0;
|
||||
+ pix_a = 1.0;
|
||||
+ } else {
|
||||
+ pix_r = pix_a;
|
||||
+ pix_g = pix_a;
|
||||
+ pix_b = pix_a;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ buf[0] = pix_r;
|
||||
+ buf[1] = pix_g;
|
||||
+ buf[2] = pix_b;
|
||||
+ buf[3] = pix_a;
|
||||
+}
|
||||
+
|
||||
static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
|
||||
PicturePtr pMaskPicture, PicturePtr pDstPicture,
|
||||
PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
|
||||
@@ -1177,31 +1305,27 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
|
||||
cb_config_t cb_conf;
|
||||
shader_config_t vs_conf, ps_conf;
|
||||
struct r600_accel_object src_obj, mask_obj, dst_obj;
|
||||
+ uint32_t ps_bool_consts = 0;
|
||||
+ float ps_alu_consts[8];
|
||||
|
||||
if (pDst->drawable.bitsPerPixel < 8 || (pSrc && pSrc->drawable.bitsPerPixel < 8))
|
||||
return FALSE;
|
||||
|
||||
- if (!pSrc) {
|
||||
- pSrc = RADEONSolidPixmap(pScreen, pSrcPicture->pSourcePict->solidFill.color);
|
||||
- if (!pSrc)
|
||||
- RADEON_FALLBACK(("Failed to create solid scratch pixmap\n"));
|
||||
+ if (pSrc) {
|
||||
+ src_obj.bo = radeon_get_pixmap_bo(pSrc);
|
||||
+ src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc);
|
||||
+ src_obj.surface = radeon_get_pixmap_surface(pSrc);
|
||||
+ src_obj.pitch = exaGetPixmapPitch(pSrc) / (pSrc->drawable.bitsPerPixel / 8);
|
||||
+ src_obj.width = pSrc->drawable.width;
|
||||
+ src_obj.height = pSrc->drawable.height;
|
||||
+ src_obj.bpp = pSrc->drawable.bitsPerPixel;
|
||||
+ src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT;
|
||||
}
|
||||
|
||||
dst_obj.bo = radeon_get_pixmap_bo(pDst);
|
||||
- src_obj.bo = radeon_get_pixmap_bo(pSrc);
|
||||
dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst);
|
||||
- src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc);
|
||||
dst_obj.surface = radeon_get_pixmap_surface(pDst);
|
||||
- src_obj.surface = radeon_get_pixmap_surface(pSrc);
|
||||
-
|
||||
- src_obj.pitch = exaGetPixmapPitch(pSrc) / (pSrc->drawable.bitsPerPixel / 8);
|
||||
dst_obj.pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel / 8);
|
||||
-
|
||||
- src_obj.width = pSrc->drawable.width;
|
||||
- src_obj.height = pSrc->drawable.height;
|
||||
- src_obj.bpp = pSrc->drawable.bitsPerPixel;
|
||||
- src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT;
|
||||
-
|
||||
dst_obj.width = pDst->drawable.width;
|
||||
dst_obj.height = pDst->drawable.height;
|
||||
dst_obj.bpp = pDst->drawable.bitsPerPixel;
|
||||
@@ -1211,34 +1335,17 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
|
||||
dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
|
||||
|
||||
if (pMaskPicture) {
|
||||
- if (!pMask) {
|
||||
- pMask = RADEONSolidPixmap(pScreen, pMaskPicture->pSourcePict->solidFill.color);
|
||||
- if (!pMask) {
|
||||
- if (!pSrcPicture->pDrawable)
|
||||
- pScreen->DestroyPixmap(pSrc);
|
||||
- RADEON_FALLBACK(("Failed to create solid scratch pixmap\n"));
|
||||
- }
|
||||
+ if (pMask) {
|
||||
+ mask_obj.bo = radeon_get_pixmap_bo(pMask);
|
||||
+ mask_obj.tiling_flags = radeon_get_pixmap_tiling(pMask);
|
||||
+ mask_obj.surface = radeon_get_pixmap_surface(pMask);
|
||||
+ mask_obj.pitch = exaGetPixmapPitch(pMask) / (pMask->drawable.bitsPerPixel / 8);
|
||||
+ mask_obj.width = pMask->drawable.width;
|
||||
+ mask_obj.height = pMask->drawable.height;
|
||||
+ mask_obj.bpp = pMask->drawable.bitsPerPixel;
|
||||
+ mask_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT;
|
||||
}
|
||||
|
||||
- mask_obj.bo = radeon_get_pixmap_bo(pMask);
|
||||
- mask_obj.tiling_flags = radeon_get_pixmap_tiling(pMask);
|
||||
- mask_obj.surface = radeon_get_pixmap_surface(pMask);
|
||||
-
|
||||
- mask_obj.pitch = exaGetPixmapPitch(pMask) / (pMask->drawable.bitsPerPixel / 8);
|
||||
-
|
||||
- mask_obj.width = pMask->drawable.width;
|
||||
- mask_obj.height = pMask->drawable.height;
|
||||
- mask_obj.bpp = pMask->drawable.bitsPerPixel;
|
||||
- mask_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT;
|
||||
-
|
||||
- if (!R600SetAccelState(pScrn,
|
||||
- &src_obj,
|
||||
- &mask_obj,
|
||||
- &dst_obj,
|
||||
- accel_state->comp_vs_offset, accel_state->comp_ps_offset,
|
||||
- 3, 0xffffffff))
|
||||
- return FALSE;
|
||||
-
|
||||
accel_state->msk_pic = pMaskPicture;
|
||||
if (pMaskPicture->componentAlpha) {
|
||||
accel_state->component_alpha = TRUE;
|
||||
@@ -1251,19 +1358,19 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
|
||||
accel_state->src_alpha = FALSE;
|
||||
}
|
||||
} else {
|
||||
- if (!R600SetAccelState(pScrn,
|
||||
- &src_obj,
|
||||
- NULL,
|
||||
- &dst_obj,
|
||||
- accel_state->comp_vs_offset, accel_state->comp_ps_offset,
|
||||
- 3, 0xffffffff))
|
||||
- return FALSE;
|
||||
-
|
||||
accel_state->msk_pic = NULL;
|
||||
accel_state->component_alpha = FALSE;
|
||||
accel_state->src_alpha = FALSE;
|
||||
}
|
||||
|
||||
+ if (!R600SetAccelState(pScrn,
|
||||
+ pSrc ? &src_obj : NULL,
|
||||
+ (pMaskPicture && pMask) ? &mask_obj : NULL,
|
||||
+ &dst_obj,
|
||||
+ accel_state->comp_vs_offset, accel_state->comp_ps_offset,
|
||||
+ 3, 0xffffffff))
|
||||
+ return FALSE;
|
||||
+
|
||||
if (!R600GetDestFormat(pDstPicture, &dst_format))
|
||||
return FALSE;
|
||||
|
||||
@@ -1284,10 +1391,13 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
|
||||
r600_set_screen_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height);
|
||||
r600_set_window_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height);
|
||||
|
||||
- if (!R600TextureSetup(pSrcPicture, pSrc, 0)) {
|
||||
- R600IBDiscard(pScrn);
|
||||
- return FALSE;
|
||||
- }
|
||||
+ if (pSrc) {
|
||||
+ if (!R600TextureSetup(pSrcPicture, pSrc, 0)) {
|
||||
+ R600IBDiscard(pScrn);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ } else
|
||||
+ accel_state->is_transform[0] = FALSE;
|
||||
|
||||
if (pMask) {
|
||||
if (!R600TextureSetup(pMaskPicture, pMask, 1)) {
|
||||
@@ -1297,12 +1407,16 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
|
||||
} else
|
||||
accel_state->is_transform[1] = FALSE;
|
||||
|
||||
+ if (pSrc)
|
||||
+ ps_bool_consts |= (1 << 0);
|
||||
+ if (pMask)
|
||||
+ ps_bool_consts |= (1 << 1);
|
||||
+ r600_set_bool_consts(pScrn, SQ_BOOL_CONST_ps, ps_bool_consts);
|
||||
+
|
||||
if (pMask) {
|
||||
r600_set_bool_consts(pScrn, SQ_BOOL_CONST_vs, (1 << 0));
|
||||
- r600_set_bool_consts(pScrn, SQ_BOOL_CONST_ps, (1 << 0));
|
||||
} else {
|
||||
r600_set_bool_consts(pScrn, SQ_BOOL_CONST_vs, (0 << 0));
|
||||
- r600_set_bool_consts(pScrn, SQ_BOOL_CONST_ps, (0 << 0));
|
||||
}
|
||||
|
||||
/* Shader */
|
||||
@@ -1315,7 +1429,7 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
|
||||
|
||||
ps_conf.shader_addr = accel_state->ps_mc_addr;
|
||||
ps_conf.shader_size = accel_state->ps_size;
|
||||
- ps_conf.num_gprs = 3;
|
||||
+ ps_conf.num_gprs = 2;
|
||||
ps_conf.stack_size = 1;
|
||||
ps_conf.uncached_first_inst = 1;
|
||||
ps_conf.clamp_consts = 0;
|
||||
@@ -1381,6 +1495,27 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
|
||||
else
|
||||
r600_set_spi(pScrn, (1 - 1), 1);
|
||||
|
||||
+ if (!pSrc) {
|
||||
+ /* solid src color */
|
||||
+ R600SetSolidConsts(pScrn, &ps_alu_consts[0], pSrcPicture->format,
|
||||
+ pSrcPicture->pSourcePict->solidFill.color, 0);
|
||||
+ }
|
||||
+
|
||||
+ if (!pMaskPicture) {
|
||||
+ /* use identity constant if there is no mask */
|
||||
+ ps_alu_consts[4] = 1.0;
|
||||
+ ps_alu_consts[5] = 1.0;
|
||||
+ ps_alu_consts[6] = 1.0;
|
||||
+ ps_alu_consts[7] = 1.0;
|
||||
+ } else if (!pMask) {
|
||||
+ /* solid mask color */
|
||||
+ R600SetSolidConsts(pScrn, &ps_alu_consts[4], pMaskPicture->format,
|
||||
+ pMaskPicture->pSourcePict->solidFill.color, 1);
|
||||
+ }
|
||||
+
|
||||
+ r600_set_alu_consts(pScrn, SQ_ALU_CONSTANT_ps,
|
||||
+ sizeof(ps_alu_consts) / SQ_ALU_CONSTANT_offset, ps_alu_consts);
|
||||
+
|
||||
if (accel_state->vsync)
|
||||
RADEONVlineHelperClear(pScrn);
|
||||
|
||||
@@ -1405,7 +1540,7 @@ static void R600FinishComposite(ScrnInfoPtr pScrn, PixmapPtr pDst,
|
||||
accel_state->vline_y1,
|
||||
accel_state->vline_y2);
|
||||
|
||||
- vtx_size = accel_state->msk_pic ? 24 : 16;
|
||||
+ vtx_size = accel_state->msk_pix ? 24 : 16;
|
||||
|
||||
r600_finish_op(pScrn, vtx_size);
|
||||
}
|
||||
@@ -1418,12 +1553,6 @@ static void R600DoneComposite(PixmapPtr pDst)
|
||||
struct radeon_accel_state *accel_state = info->accel_state;
|
||||
|
||||
R600FinishComposite(pScrn, pDst, accel_state);
|
||||
-
|
||||
- if (!accel_state->src_pic->pDrawable)
|
||||
- pScreen->DestroyPixmap(accel_state->src_pix);
|
||||
-
|
||||
- if (accel_state->msk_pic && !accel_state->msk_pic->pDrawable)
|
||||
- pScreen->DestroyPixmap(accel_state->msk_pix);
|
||||
}
|
||||
|
||||
static void R600Composite(PixmapPtr pDst,
|
||||
@@ -1455,7 +1584,7 @@ static void R600Composite(PixmapPtr pDst,
|
||||
if (accel_state->vsync)
|
||||
RADEONVlineHelperSet(pScrn, dstX, dstY, dstX + w, dstY + h);
|
||||
|
||||
- if (accel_state->msk_pic) {
|
||||
+ if (accel_state->msk_pix) {
|
||||
|
||||
vb = radeon_vbo_space(pScrn, &accel_state->vbo, 24);
|
||||
|
||||
diff --git a/src/r600_shader.c b/src/r600_shader.c
|
||||
index 4cb2fc8..26a6ab6 100644
|
||||
--- a/src/r600_shader.c
|
||||
+++ b/src/r600_shader.c
|
||||
@@ -2318,9 +2318,10 @@ int R600_comp_ps(RADEONChipFamily ChipSet, uint32_t* shader)
|
||||
int i = 0;
|
||||
|
||||
/* 0 */
|
||||
- shader[i++] = CF_DWORD0(ADDR(3));
|
||||
+ /* call fetch-mask if boolean1 == true */
|
||||
+ shader[i++] = CF_DWORD0(ADDR(10));
|
||||
shader[i++] = CF_DWORD1(POP_COUNT(0),
|
||||
- CF_CONST(0),
|
||||
+ CF_CONST(1),
|
||||
COND(SQ_CF_COND_BOOL),
|
||||
I_COUNT(0),
|
||||
CALL_COUNT(0),
|
||||
@@ -2330,9 +2331,10 @@ int R600_comp_ps(RADEONChipFamily ChipSet, uint32_t* shader)
|
||||
WHOLE_QUAD_MODE(0),
|
||||
BARRIER(0));
|
||||
/* 1 */
|
||||
- shader[i++] = CF_DWORD0(ADDR(7));
|
||||
+ /* call read-constant-mask if boolean1 == false */
|
||||
+ shader[i++] = CF_DWORD0(ADDR(12));
|
||||
shader[i++] = CF_DWORD1(POP_COUNT(0),
|
||||
- CF_CONST(0),
|
||||
+ CF_CONST(1),
|
||||
COND(SQ_CF_COND_NOT_BOOL),
|
||||
I_COUNT(0),
|
||||
CALL_COUNT(0),
|
||||
@@ -2342,33 +2344,36 @@ int R600_comp_ps(RADEONChipFamily ChipSet, uint32_t* shader)
|
||||
WHOLE_QUAD_MODE(0),
|
||||
BARRIER(0));
|
||||
/* 2 */
|
||||
- shader[i++] = CF_DWORD0(ADDR(0));
|
||||
+ /* call fetch-src if boolean0 == true */
|
||||
+ shader[i++] = CF_DWORD0(ADDR(6));
|
||||
shader[i++] = CF_DWORD1(POP_COUNT(0),
|
||||
CF_CONST(0),
|
||||
- COND(SQ_CF_COND_ACTIVE),
|
||||
+ COND(SQ_CF_COND_BOOL),
|
||||
I_COUNT(0),
|
||||
CALL_COUNT(0),
|
||||
- END_OF_PROGRAM(1),
|
||||
+ END_OF_PROGRAM(0),
|
||||
VALID_PIXEL_MODE(0),
|
||||
- CF_INST(SQ_CF_INST_NOP),
|
||||
+ CF_INST(SQ_CF_INST_CALL),
|
||||
WHOLE_QUAD_MODE(0),
|
||||
- BARRIER(1));
|
||||
+ BARRIER(0));
|
||||
|
||||
- /* 3 - mask sub */
|
||||
- shader[i++] = CF_DWORD0(ADDR(14));
|
||||
+ /* 3 */
|
||||
+ /* call read-constant-src if boolean0 == false */
|
||||
+ shader[i++] = CF_DWORD0(ADDR(8));
|
||||
shader[i++] = CF_DWORD1(POP_COUNT(0),
|
||||
CF_CONST(0),
|
||||
- COND(SQ_CF_COND_ACTIVE),
|
||||
- I_COUNT(2),
|
||||
+ COND(SQ_CF_COND_NOT_BOOL),
|
||||
+ I_COUNT(0),
|
||||
CALL_COUNT(0),
|
||||
END_OF_PROGRAM(0),
|
||||
VALID_PIXEL_MODE(0),
|
||||
- CF_INST(SQ_CF_INST_TEX),
|
||||
+ CF_INST(SQ_CF_INST_CALL),
|
||||
WHOLE_QUAD_MODE(0),
|
||||
- BARRIER(1));
|
||||
+ BARRIER(0));
|
||||
|
||||
/* 4 */
|
||||
- shader[i++] = CF_ALU_DWORD0(ADDR(10),
|
||||
+ /* src IN mask (GPR0 := GPR1 .* GPR0) */
|
||||
+ shader[i++] = CF_ALU_DWORD0(ADDR(14),
|
||||
KCACHE_BANK0(0),
|
||||
KCACHE_BANK1(0),
|
||||
KCACHE_MODE0(SQ_CF_KCACHE_NOP));
|
||||
@@ -2382,9 +2387,10 @@ int R600_comp_ps(RADEONChipFamily ChipSet, uint32_t* shader)
|
||||
BARRIER(1));
|
||||
|
||||
/* 5 */
|
||||
+ /* export pixel data */
|
||||
shader[i++] = CF_ALLOC_IMP_EXP_DWORD0(ARRAY_BASE(CF_PIXEL_MRT0),
|
||||
TYPE(SQ_EXPORT_PIXEL),
|
||||
- RW_GPR(2),
|
||||
+ RW_GPR(0),
|
||||
RW_REL(ABSOLUTE),
|
||||
INDEX_GPR(0),
|
||||
ELEM_SIZE(1));
|
||||
@@ -2394,55 +2400,57 @@ int R600_comp_ps(RADEONChipFamily ChipSet, uint32_t* shader)
|
||||
SRC_SEL_W(SQ_SEL_W),
|
||||
R6xx_ELEM_LOOP(0),
|
||||
BURST_COUNT(1),
|
||||
- END_OF_PROGRAM(0),
|
||||
+ END_OF_PROGRAM(1),
|
||||
VALID_PIXEL_MODE(0),
|
||||
CF_INST(SQ_CF_INST_EXPORT_DONE),
|
||||
WHOLE_QUAD_MODE(0),
|
||||
BARRIER(1));
|
||||
+ /* subroutine fetch src */
|
||||
/* 6 */
|
||||
- shader[i++] = CF_DWORD0(ADDR(0));
|
||||
+ /* fetch src into GPR0*/
|
||||
+ shader[i++] = CF_DWORD0(ADDR(26));
|
||||
shader[i++] = CF_DWORD1(POP_COUNT(0),
|
||||
CF_CONST(0),
|
||||
COND(SQ_CF_COND_ACTIVE),
|
||||
- I_COUNT(0),
|
||||
+ I_COUNT(1),
|
||||
CALL_COUNT(0),
|
||||
END_OF_PROGRAM(0),
|
||||
VALID_PIXEL_MODE(0),
|
||||
- CF_INST(SQ_CF_INST_RETURN),
|
||||
+ CF_INST(SQ_CF_INST_TEX),
|
||||
WHOLE_QUAD_MODE(0),
|
||||
BARRIER(1));
|
||||
|
||||
- /* 7 non-mask sub */
|
||||
- shader[i++] = CF_DWORD0(ADDR(18));
|
||||
+ /* 7 */
|
||||
+ /* return */
|
||||
+ shader[i++] = CF_DWORD0(ADDR(0));
|
||||
shader[i++] = CF_DWORD1(POP_COUNT(0),
|
||||
CF_CONST(0),
|
||||
COND(SQ_CF_COND_ACTIVE),
|
||||
- I_COUNT(1),
|
||||
+ I_COUNT(0),
|
||||
CALL_COUNT(0),
|
||||
END_OF_PROGRAM(0),
|
||||
VALID_PIXEL_MODE(0),
|
||||
- CF_INST(SQ_CF_INST_TEX),
|
||||
+ CF_INST(SQ_CF_INST_RETURN),
|
||||
WHOLE_QUAD_MODE(0),
|
||||
BARRIER(1));
|
||||
+
|
||||
+ /* subroutine read-constant-src*/
|
||||
/* 8 */
|
||||
- shader[i++] = CF_ALLOC_IMP_EXP_DWORD0(ARRAY_BASE(CF_PIXEL_MRT0),
|
||||
- TYPE(SQ_EXPORT_PIXEL),
|
||||
- RW_GPR(0),
|
||||
- RW_REL(ABSOLUTE),
|
||||
- INDEX_GPR(0),
|
||||
- ELEM_SIZE(1));
|
||||
- shader[i++] = CF_ALLOC_IMP_EXP_DWORD1_SWIZ(SRC_SEL_X(SQ_SEL_X),
|
||||
- SRC_SEL_Y(SQ_SEL_Y),
|
||||
- SRC_SEL_Z(SQ_SEL_Z),
|
||||
- SRC_SEL_W(SQ_SEL_W),
|
||||
- R6xx_ELEM_LOOP(0),
|
||||
- BURST_COUNT(1),
|
||||
- END_OF_PROGRAM(0),
|
||||
- VALID_PIXEL_MODE(0),
|
||||
- CF_INST(SQ_CF_INST_EXPORT_DONE),
|
||||
- WHOLE_QUAD_MODE(0),
|
||||
- BARRIER(1));
|
||||
+ /* read constants into GPR0 */
|
||||
+ shader[i++] = CF_ALU_DWORD0(ADDR(18),
|
||||
+ KCACHE_BANK0(0),
|
||||
+ KCACHE_BANK1(0),
|
||||
+ KCACHE_MODE0(SQ_CF_KCACHE_NOP));
|
||||
+ shader[i++] = CF_ALU_DWORD1(KCACHE_MODE1(SQ_CF_KCACHE_NOP),
|
||||
+ KCACHE_ADDR0(0),
|
||||
+ KCACHE_ADDR1(0),
|
||||
+ I_COUNT(4),
|
||||
+ USES_WATERFALL(0),
|
||||
+ CF_INST(SQ_CF_INST_ALU),
|
||||
+ WHOLE_QUAD_MODE(0),
|
||||
+ BARRIER(1));
|
||||
/* 9 */
|
||||
+ /* return */
|
||||
shader[i++] = CF_DWORD0(ADDR(0));
|
||||
shader[i++] = CF_DWORD1(POP_COUNT(0),
|
||||
CF_CONST(0),
|
||||
@@ -2455,8 +2463,67 @@ int R600_comp_ps(RADEONChipFamily ChipSet, uint32_t* shader)
|
||||
WHOLE_QUAD_MODE(0),
|
||||
BARRIER(1));
|
||||
|
||||
- /* 10 - alu 0 */
|
||||
- /* MUL gpr[2].x gpr[1].x gpr[0].x */
|
||||
+ /* subroutine fetch mask */
|
||||
+ /* 10 */
|
||||
+ /* fetch mask into GPR1*/
|
||||
+ shader[i++] = CF_DWORD0(ADDR(28));
|
||||
+ shader[i++] = CF_DWORD1(POP_COUNT(0),
|
||||
+ CF_CONST(0),
|
||||
+ COND(SQ_CF_COND_ACTIVE),
|
||||
+ I_COUNT(1),
|
||||
+ CALL_COUNT(0),
|
||||
+ END_OF_PROGRAM(0),
|
||||
+ VALID_PIXEL_MODE(0),
|
||||
+ CF_INST(SQ_CF_INST_TEX),
|
||||
+ WHOLE_QUAD_MODE(0),
|
||||
+ BARRIER(1));
|
||||
+
|
||||
+ /* 11 */
|
||||
+ /* return */
|
||||
+ shader[i++] = CF_DWORD0(ADDR(0));
|
||||
+ shader[i++] = CF_DWORD1(POP_COUNT(0),
|
||||
+ CF_CONST(0),
|
||||
+ COND(SQ_CF_COND_ACTIVE),
|
||||
+ I_COUNT(0),
|
||||
+ CALL_COUNT(0),
|
||||
+ END_OF_PROGRAM(0),
|
||||
+ VALID_PIXEL_MODE(0),
|
||||
+ CF_INST(SQ_CF_INST_RETURN),
|
||||
+ WHOLE_QUAD_MODE(0),
|
||||
+ BARRIER(1));
|
||||
+
|
||||
+ /* subroutine read-constant-mask*/
|
||||
+ /* 12 */
|
||||
+ /* read constants into GPR1 */
|
||||
+ shader[i++] = CF_ALU_DWORD0(ADDR(22),
|
||||
+ KCACHE_BANK0(0),
|
||||
+ KCACHE_BANK1(0),
|
||||
+ KCACHE_MODE0(SQ_CF_KCACHE_NOP));
|
||||
+ shader[i++] = CF_ALU_DWORD1(KCACHE_MODE1(SQ_CF_KCACHE_NOP),
|
||||
+ KCACHE_ADDR0(0),
|
||||
+ KCACHE_ADDR1(0),
|
||||
+ I_COUNT(4),
|
||||
+ USES_WATERFALL(0),
|
||||
+ CF_INST(SQ_CF_INST_ALU),
|
||||
+ WHOLE_QUAD_MODE(0),
|
||||
+ BARRIER(1));
|
||||
+ /* 13 */
|
||||
+ /* return */
|
||||
+ shader[i++] = CF_DWORD0(ADDR(0));
|
||||
+ shader[i++] = CF_DWORD1(POP_COUNT(0),
|
||||
+ CF_CONST(0),
|
||||
+ COND(SQ_CF_COND_ACTIVE),
|
||||
+ I_COUNT(0),
|
||||
+ CALL_COUNT(0),
|
||||
+ END_OF_PROGRAM(0),
|
||||
+ VALID_PIXEL_MODE(0),
|
||||
+ CF_INST(SQ_CF_INST_RETURN),
|
||||
+ WHOLE_QUAD_MODE(0),
|
||||
+ BARRIER(1));
|
||||
+ /* ALU clauses */
|
||||
+
|
||||
+ /* 14 - alu 0 */
|
||||
+ /* MUL gpr[0].x gpr[1].x gpr[0].x */
|
||||
shader[i++] = ALU_DWORD0(SRC0_SEL(ALU_SRC_GPR_BASE + 1),
|
||||
SRC0_REL(ABSOLUTE),
|
||||
SRC0_ELEM(ELEM_X),
|
||||
@@ -2478,12 +2545,12 @@ int R600_comp_ps(RADEONChipFamily ChipSet, uint32_t* shader)
|
||||
OMOD(SQ_ALU_OMOD_OFF),
|
||||
ALU_INST(SQ_OP2_INST_MUL),
|
||||
BANK_SWIZZLE(SQ_ALU_VEC_012),
|
||||
- DST_GPR(2),
|
||||
+ DST_GPR(0),
|
||||
DST_REL(ABSOLUTE),
|
||||
DST_ELEM(ELEM_X),
|
||||
CLAMP(1));
|
||||
- /* 11 - alu 1 */
|
||||
- /* MUL gpr[2].y gpr[1].y gpr[0].y */
|
||||
+ /* 15 - alu 1 */
|
||||
+ /* MUL gpr[0].y gpr[1].y gpr[0].y */
|
||||
shader[i++] = ALU_DWORD0(SRC0_SEL(ALU_SRC_GPR_BASE + 1),
|
||||
SRC0_REL(ABSOLUTE),
|
||||
SRC0_ELEM(ELEM_Y),
|
||||
@@ -2505,12 +2572,12 @@ int R600_comp_ps(RADEONChipFamily ChipSet, uint32_t* shader)
|
||||
OMOD(SQ_ALU_OMOD_OFF),
|
||||
ALU_INST(SQ_OP2_INST_MUL),
|
||||
BANK_SWIZZLE(SQ_ALU_VEC_012),
|
||||
- DST_GPR(2),
|
||||
+ DST_GPR(0),
|
||||
DST_REL(ABSOLUTE),
|
||||
DST_ELEM(ELEM_Y),
|
||||
CLAMP(1));
|
||||
- /* 12 - alu 2 */
|
||||
- /* MUL gpr[2].z gpr[1].z gpr[0].z */
|
||||
+ /* 16 - alu 2 */
|
||||
+ /* MUL gpr[0].z gpr[1].z gpr[0].z */
|
||||
shader[i++] = ALU_DWORD0(SRC0_SEL(ALU_SRC_GPR_BASE + 1),
|
||||
SRC0_REL(ABSOLUTE),
|
||||
SRC0_ELEM(ELEM_Z),
|
||||
@@ -2532,12 +2599,12 @@ int R600_comp_ps(RADEONChipFamily ChipSet, uint32_t* shader)
|
||||
OMOD(SQ_ALU_OMOD_OFF),
|
||||
ALU_INST(SQ_OP2_INST_MUL),
|
||||
BANK_SWIZZLE(SQ_ALU_VEC_012),
|
||||
- DST_GPR(2),
|
||||
+ DST_GPR(0),
|
||||
DST_REL(ABSOLUTE),
|
||||
DST_ELEM(ELEM_Z),
|
||||
CLAMP(1));
|
||||
- /* 13 - alu 3 */
|
||||
- /* MUL gpr[2].w gpr[1].w gpr[0].w */
|
||||
+ /* 17 - alu 3 */
|
||||
+ /* MUL gpr[0].w gpr[1].w gpr[0].w */
|
||||
shader[i++] = ALU_DWORD0(SRC0_SEL(ALU_SRC_GPR_BASE + 1),
|
||||
SRC0_REL(ABSOLUTE),
|
||||
SRC0_ELEM(ELEM_W),
|
||||
@@ -2559,12 +2626,222 @@ int R600_comp_ps(RADEONChipFamily ChipSet, uint32_t* shader)
|
||||
OMOD(SQ_ALU_OMOD_OFF),
|
||||
ALU_INST(SQ_OP2_INST_MUL),
|
||||
BANK_SWIZZLE(SQ_ALU_VEC_012),
|
||||
- DST_GPR(2),
|
||||
+ DST_GPR(0),
|
||||
+ DST_REL(ABSOLUTE),
|
||||
+ DST_ELEM(ELEM_W),
|
||||
+ CLAMP(1));
|
||||
+
|
||||
+ /* 18 */
|
||||
+ shader[i++] = ALU_DWORD0(SRC0_SEL(ALU_SRC_CFILE_BASE + 0),
|
||||
+ SRC0_REL(ABSOLUTE),
|
||||
+ SRC0_ELEM(ELEM_X),
|
||||
+ SRC0_NEG(0),
|
||||
+ SRC1_SEL(ALU_SRC_GPR_BASE + 0),
|
||||
+ SRC1_REL(ABSOLUTE),
|
||||
+ SRC1_ELEM(ELEM_X),
|
||||
+ SRC1_NEG(0),
|
||||
+ INDEX_MODE(SQ_INDEX_AR_X),
|
||||
+ PRED_SEL(SQ_PRED_SEL_OFF),
|
||||
+ LAST(0));
|
||||
+ shader[i++] = ALU_DWORD1_OP2(ChipSet,
|
||||
+ SRC0_ABS(0),
|
||||
+ SRC1_ABS(0),
|
||||
+ UPDATE_EXECUTE_MASK(0),
|
||||
+ UPDATE_PRED(0),
|
||||
+ WRITE_MASK(1),
|
||||
+ FOG_MERGE(0),
|
||||
+ OMOD(SQ_ALU_OMOD_OFF),
|
||||
+ ALU_INST(SQ_OP2_INST_MOV),
|
||||
+ BANK_SWIZZLE(SQ_ALU_VEC_012),
|
||||
+ DST_GPR(0),
|
||||
+ DST_REL(ABSOLUTE),
|
||||
+ DST_ELEM(ELEM_X),
|
||||
+ CLAMP(1));
|
||||
+ /* 19 */
|
||||
+ shader[i++] = ALU_DWORD0(SRC0_SEL(ALU_SRC_CFILE_BASE + 0),
|
||||
+ SRC0_REL(ABSOLUTE),
|
||||
+ SRC0_ELEM(ELEM_Y),
|
||||
+ SRC0_NEG(0),
|
||||
+ SRC1_SEL(ALU_SRC_GPR_BASE + 0),
|
||||
+ SRC1_REL(ABSOLUTE),
|
||||
+ SRC1_ELEM(ELEM_Y),
|
||||
+ SRC1_NEG(0),
|
||||
+ INDEX_MODE(SQ_INDEX_AR_X),
|
||||
+ PRED_SEL(SQ_PRED_SEL_OFF),
|
||||
+ LAST(0));
|
||||
+ shader[i++] = ALU_DWORD1_OP2(ChipSet,
|
||||
+ SRC0_ABS(0),
|
||||
+ SRC1_ABS(0),
|
||||
+ UPDATE_EXECUTE_MASK(0),
|
||||
+ UPDATE_PRED(0),
|
||||
+ WRITE_MASK(1),
|
||||
+ FOG_MERGE(0),
|
||||
+ OMOD(SQ_ALU_OMOD_OFF),
|
||||
+ ALU_INST(SQ_OP2_INST_MOV),
|
||||
+ BANK_SWIZZLE(SQ_ALU_VEC_012),
|
||||
+ DST_GPR(0),
|
||||
+ DST_REL(ABSOLUTE),
|
||||
+ DST_ELEM(ELEM_Y),
|
||||
+ CLAMP(1));
|
||||
+ /* 20 */
|
||||
+ shader[i++] = ALU_DWORD0(SRC0_SEL(ALU_SRC_CFILE_BASE + 0),
|
||||
+ SRC0_REL(ABSOLUTE),
|
||||
+ SRC0_ELEM(ELEM_Z),
|
||||
+ SRC0_NEG(0),
|
||||
+ SRC1_SEL(ALU_SRC_GPR_BASE + 0),
|
||||
+ SRC1_REL(ABSOLUTE),
|
||||
+ SRC1_ELEM(ELEM_Z),
|
||||
+ SRC1_NEG(0),
|
||||
+ INDEX_MODE(SQ_INDEX_AR_X),
|
||||
+ PRED_SEL(SQ_PRED_SEL_OFF),
|
||||
+ LAST(0));
|
||||
+ shader[i++] = ALU_DWORD1_OP2(ChipSet,
|
||||
+ SRC0_ABS(0),
|
||||
+ SRC1_ABS(0),
|
||||
+ UPDATE_EXECUTE_MASK(0),
|
||||
+ UPDATE_PRED(0),
|
||||
+ WRITE_MASK(1),
|
||||
+ FOG_MERGE(0),
|
||||
+ OMOD(SQ_ALU_OMOD_OFF),
|
||||
+ ALU_INST(SQ_OP2_INST_MOV),
|
||||
+ BANK_SWIZZLE(SQ_ALU_VEC_012),
|
||||
+ DST_GPR(0),
|
||||
+ DST_REL(ABSOLUTE),
|
||||
+ DST_ELEM(ELEM_Z),
|
||||
+ CLAMP(1));
|
||||
+ /* 21 */
|
||||
+ shader[i++] = ALU_DWORD0(SRC0_SEL(ALU_SRC_CFILE_BASE + 0),
|
||||
+ SRC0_REL(ABSOLUTE),
|
||||
+ SRC0_ELEM(ELEM_W),
|
||||
+ SRC0_NEG(0),
|
||||
+ SRC1_SEL(ALU_SRC_GPR_BASE + 0),
|
||||
+ SRC1_REL(ABSOLUTE),
|
||||
+ SRC1_ELEM(ELEM_W),
|
||||
+ SRC1_NEG(0),
|
||||
+ INDEX_MODE(SQ_INDEX_AR_X),
|
||||
+ PRED_SEL(SQ_PRED_SEL_OFF),
|
||||
+ LAST(1));
|
||||
+ shader[i++] = ALU_DWORD1_OP2(ChipSet,
|
||||
+ SRC0_ABS(0),
|
||||
+ SRC1_ABS(0),
|
||||
+ UPDATE_EXECUTE_MASK(0),
|
||||
+ UPDATE_PRED(0),
|
||||
+ WRITE_MASK(1),
|
||||
+ FOG_MERGE(0),
|
||||
+ OMOD(SQ_ALU_OMOD_OFF),
|
||||
+ ALU_INST(SQ_OP2_INST_MOV),
|
||||
+ BANK_SWIZZLE(SQ_ALU_VEC_012),
|
||||
+ DST_GPR(0),
|
||||
DST_REL(ABSOLUTE),
|
||||
DST_ELEM(ELEM_W),
|
||||
CLAMP(1));
|
||||
|
||||
- /* 14/15 - src - mask */
|
||||
+ /* 22 */
|
||||
+ shader[i++] = ALU_DWORD0(SRC0_SEL(ALU_SRC_CFILE_BASE + 1),
|
||||
+ SRC0_REL(ABSOLUTE),
|
||||
+ SRC0_ELEM(ELEM_X),
|
||||
+ SRC0_NEG(0),
|
||||
+ SRC1_SEL(ALU_SRC_GPR_BASE + 0),
|
||||
+ SRC1_REL(ABSOLUTE),
|
||||
+ SRC1_ELEM(ELEM_X),
|
||||
+ SRC1_NEG(0),
|
||||
+ INDEX_MODE(SQ_INDEX_AR_X),
|
||||
+ PRED_SEL(SQ_PRED_SEL_OFF),
|
||||
+ LAST(0));
|
||||
+ shader[i++] = ALU_DWORD1_OP2(ChipSet,
|
||||
+ SRC0_ABS(0),
|
||||
+ SRC1_ABS(0),
|
||||
+ UPDATE_EXECUTE_MASK(0),
|
||||
+ UPDATE_PRED(0),
|
||||
+ WRITE_MASK(1),
|
||||
+ FOG_MERGE(0),
|
||||
+ OMOD(SQ_ALU_OMOD_OFF),
|
||||
+ ALU_INST(SQ_OP2_INST_MOV),
|
||||
+ BANK_SWIZZLE(SQ_ALU_VEC_012),
|
||||
+ DST_GPR(1),
|
||||
+ DST_REL(ABSOLUTE),
|
||||
+ DST_ELEM(ELEM_X),
|
||||
+ CLAMP(1));
|
||||
+ /* 23 */
|
||||
+ shader[i++] = ALU_DWORD0(SRC0_SEL(ALU_SRC_CFILE_BASE + 1),
|
||||
+ SRC0_REL(ABSOLUTE),
|
||||
+ SRC0_ELEM(ELEM_Y),
|
||||
+ SRC0_NEG(0),
|
||||
+ SRC1_SEL(ALU_SRC_GPR_BASE + 0),
|
||||
+ SRC1_REL(ABSOLUTE),
|
||||
+ SRC1_ELEM(ELEM_Y),
|
||||
+ SRC1_NEG(0),
|
||||
+ INDEX_MODE(SQ_INDEX_AR_X),
|
||||
+ PRED_SEL(SQ_PRED_SEL_OFF),
|
||||
+ LAST(0));
|
||||
+ shader[i++] = ALU_DWORD1_OP2(ChipSet,
|
||||
+ SRC0_ABS(0),
|
||||
+ SRC1_ABS(0),
|
||||
+ UPDATE_EXECUTE_MASK(0),
|
||||
+ UPDATE_PRED(0),
|
||||
+ WRITE_MASK(1),
|
||||
+ FOG_MERGE(0),
|
||||
+ OMOD(SQ_ALU_OMOD_OFF),
|
||||
+ ALU_INST(SQ_OP2_INST_MOV),
|
||||
+ BANK_SWIZZLE(SQ_ALU_VEC_012),
|
||||
+ DST_GPR(1),
|
||||
+ DST_REL(ABSOLUTE),
|
||||
+ DST_ELEM(ELEM_Y),
|
||||
+ CLAMP(1));
|
||||
+ /* 24 */
|
||||
+ shader[i++] = ALU_DWORD0(SRC0_SEL(ALU_SRC_CFILE_BASE + 1),
|
||||
+ SRC0_REL(ABSOLUTE),
|
||||
+ SRC0_ELEM(ELEM_Z),
|
||||
+ SRC0_NEG(0),
|
||||
+ SRC1_SEL(ALU_SRC_GPR_BASE + 0),
|
||||
+ SRC1_REL(ABSOLUTE),
|
||||
+ SRC1_ELEM(ELEM_Z),
|
||||
+ SRC1_NEG(0),
|
||||
+ INDEX_MODE(SQ_INDEX_AR_X),
|
||||
+ PRED_SEL(SQ_PRED_SEL_OFF),
|
||||
+ LAST(0));
|
||||
+ shader[i++] = ALU_DWORD1_OP2(ChipSet,
|
||||
+ SRC0_ABS(0),
|
||||
+ SRC1_ABS(0),
|
||||
+ UPDATE_EXECUTE_MASK(0),
|
||||
+ UPDATE_PRED(0),
|
||||
+ WRITE_MASK(1),
|
||||
+ FOG_MERGE(0),
|
||||
+ OMOD(SQ_ALU_OMOD_OFF),
|
||||
+ ALU_INST(SQ_OP2_INST_MOV),
|
||||
+ BANK_SWIZZLE(SQ_ALU_VEC_012),
|
||||
+ DST_GPR(1),
|
||||
+ DST_REL(ABSOLUTE),
|
||||
+ DST_ELEM(ELEM_Z),
|
||||
+ CLAMP(1));
|
||||
+ /* 25 */
|
||||
+ shader[i++] = ALU_DWORD0(SRC0_SEL(ALU_SRC_CFILE_BASE + 1),
|
||||
+ SRC0_REL(ABSOLUTE),
|
||||
+ SRC0_ELEM(ELEM_W),
|
||||
+ SRC0_NEG(0),
|
||||
+ SRC1_SEL(ALU_SRC_GPR_BASE + 0),
|
||||
+ SRC1_REL(ABSOLUTE),
|
||||
+ SRC1_ELEM(ELEM_W),
|
||||
+ SRC1_NEG(0),
|
||||
+ INDEX_MODE(SQ_INDEX_AR_X),
|
||||
+ PRED_SEL(SQ_PRED_SEL_OFF),
|
||||
+ LAST(1));
|
||||
+ shader[i++] = ALU_DWORD1_OP2(ChipSet,
|
||||
+ SRC0_ABS(0),
|
||||
+ SRC1_ABS(0),
|
||||
+ UPDATE_EXECUTE_MASK(0),
|
||||
+ UPDATE_PRED(0),
|
||||
+ WRITE_MASK(1),
|
||||
+ FOG_MERGE(0),
|
||||
+ OMOD(SQ_ALU_OMOD_OFF),
|
||||
+ ALU_INST(SQ_OP2_INST_MOV),
|
||||
+ BANK_SWIZZLE(SQ_ALU_VEC_012),
|
||||
+ DST_GPR(1),
|
||||
+ DST_REL(ABSOLUTE),
|
||||
+ DST_ELEM(ELEM_W),
|
||||
+ CLAMP(1));
|
||||
+
|
||||
+ /* 26/27 - src */
|
||||
shader[i++] = TEX_DWORD0(TEX_INST(SQ_TEX_INST_SAMPLE),
|
||||
BC_FRAC_MODE(0),
|
||||
FETCH_WHOLE_QUAD(0),
|
||||
@@ -2592,7 +2869,7 @@ int R600_comp_ps(RADEONChipFamily ChipSet, uint32_t* shader)
|
||||
SRC_SEL_Z(SQ_SEL_0),
|
||||
SRC_SEL_W(SQ_SEL_1));
|
||||
shader[i++] = TEX_DWORD_PAD;
|
||||
- /* 16/17 - mask */
|
||||
+ /* 28/29 - mask */
|
||||
shader[i++] = TEX_DWORD0(TEX_INST(SQ_TEX_INST_SAMPLE),
|
||||
BC_FRAC_MODE(0),
|
||||
FETCH_WHOLE_QUAD(0),
|
||||
@@ -2621,34 +2898,5 @@ int R600_comp_ps(RADEONChipFamily ChipSet, uint32_t* shader)
|
||||
SRC_SEL_W(SQ_SEL_1));
|
||||
shader[i++] = TEX_DWORD_PAD;
|
||||
|
||||
- /* 18/19 - src - non-mask */
|
||||
- shader[i++] = TEX_DWORD0(TEX_INST(SQ_TEX_INST_SAMPLE),
|
||||
- BC_FRAC_MODE(0),
|
||||
- FETCH_WHOLE_QUAD(0),
|
||||
- RESOURCE_ID(0),
|
||||
- SRC_GPR(0),
|
||||
- SRC_REL(ABSOLUTE),
|
||||
- R7xx_ALT_CONST(0));
|
||||
- shader[i++] = TEX_DWORD1(DST_GPR(0),
|
||||
- DST_REL(ABSOLUTE),
|
||||
- DST_SEL_X(SQ_SEL_X),
|
||||
- DST_SEL_Y(SQ_SEL_Y),
|
||||
- DST_SEL_Z(SQ_SEL_Z),
|
||||
- DST_SEL_W(SQ_SEL_W),
|
||||
- LOD_BIAS(0),
|
||||
- COORD_TYPE_X(TEX_NORMALIZED),
|
||||
- COORD_TYPE_Y(TEX_NORMALIZED),
|
||||
- COORD_TYPE_Z(TEX_NORMALIZED),
|
||||
- COORD_TYPE_W(TEX_NORMALIZED));
|
||||
- shader[i++] = TEX_DWORD2(OFFSET_X(0),
|
||||
- OFFSET_Y(0),
|
||||
- OFFSET_Z(0),
|
||||
- SAMPLER_ID(0),
|
||||
- SRC_SEL_X(SQ_SEL_X),
|
||||
- SRC_SEL_Y(SQ_SEL_Y),
|
||||
- SRC_SEL_Z(SQ_SEL_0),
|
||||
- SRC_SEL_W(SQ_SEL_1));
|
||||
- shader[i++] = TEX_DWORD_PAD;
|
||||
-
|
||||
return i;
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
From: Tan Hu <tan.hu@zte.com.cn>
|
||||
Date: Fri May 27 17:05:15 2016 +0800
|
||||
Subject: [PATCH 6/20]EXA/6xx/7xx: accelerate PictOpOver with component alpha
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 0945db4d902056bda3d9ad4a4de2dfa685d10a70
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
Subpixel text rendering is typically done with a solid src and
|
||||
a pixmap mask. Traditionally, this cannot be accelerated in a single
|
||||
pass and requires two passes [1]. However, we can cheat a little
|
||||
with a constant blend color.
|
||||
|
||||
We can use:
|
||||
const.A = src.A / src.A
|
||||
const.R = src.R / src.A
|
||||
const.G = src.G / src.A
|
||||
const.B = src.B / src.A
|
||||
|
||||
dst.A = const.A * (src.A * mask.A) + (1 - (src.A * mask.A)) * dst.A
|
||||
dst.R = const.R * (src.A * mask.R) + (1 - (src.A * mask.R)) * dst.R
|
||||
dst.G = const.G * (src.A * mask.G) + (1 - (src.A * mask.G)) * dst.G
|
||||
dst.B = const.B * (src.A * mask.B) + (1 - (src.A * mask.B)) * dst.B
|
||||
|
||||
This only needs a single source value. src.A is cancelled down in
|
||||
the right places.
|
||||
|
||||
[1] http://anholt.livejournal.com/32058.html
|
||||
|
||||
r6xx still be used on some machine,
|
||||
Ported from commit 4375a6e75e5d41139be7031a0dee58c057ecbd07.
|
||||
|
||||
Signed-off-by: Tan Hu <tan.hu@zte.com.cn>
|
||||
Reviewed-by: Grigori Goronzy <greg@chown.ath.cx>
|
||||
---
|
||||
src/r600_exa.c | 22 ++++++++++++++++++++--
|
||||
src/r600_state.h | 2 ++
|
||||
src/r6xx_accel.c | 14 ++++++++++++++
|
||||
3 files changed, 36 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/r600_exa.c b/src/r600_exa.c
|
||||
index 10df4ec..e9ac721 100644
|
||||
--- a/src/r600_exa.c
|
||||
+++ b/src/r600_exa.c
|
||||
@@ -766,6 +766,14 @@ static uint32_t R600GetBlendCntl(int op, PicturePtr pMask, uint32_t dst_format)
|
||||
} else if (dblend == (BLEND_ONE_MINUS_SRC_ALPHA << COLOR_DESTBLEND_shift)) {
|
||||
dblend = (BLEND_ONE_MINUS_SRC_COLOR << COLOR_DESTBLEND_shift);
|
||||
}
|
||||
+
|
||||
+ /* With some tricks, we can still accelerate PictOpOver with solid src.
|
||||
+ * This is commonly used for text rendering, so it's worth the extra
|
||||
+ * effort.
|
||||
+ */
|
||||
+ if (sblend == (BLEND_ONE << COLOR_SRCBLEND_shift)) {
|
||||
+ sblend = (BLEND_CONSTANT_COLOR << COLOR_SRCBLEND_shift);
|
||||
+ }
|
||||
}
|
||||
|
||||
return sblend | dblend;
|
||||
@@ -1143,12 +1151,17 @@ static Bool R600CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP
|
||||
/* Check if it's component alpha that relies on a source alpha and
|
||||
* on the source value. We can only get one of those into the
|
||||
* single source value that we get to blend with.
|
||||
+ *
|
||||
+ * We can cheat a bit if the src is solid, though. PictOpOver
|
||||
+ * can use the constant blend color to sneak a second blend
|
||||
+ * source in.
|
||||
*/
|
||||
if (R600BlendOp[op].src_alpha &&
|
||||
(R600BlendOp[op].blend_cntl & COLOR_SRCBLEND_mask) !=
|
||||
(BLEND_ZERO << COLOR_SRCBLEND_shift)) {
|
||||
- RADEON_FALLBACK(("Component alpha not supported with source "
|
||||
- "alpha and source value blending.\n"));
|
||||
+ if (pSrcPicture->pDrawable || op != PictOpOver)
|
||||
+ RADEON_FALLBACK(("Component alpha not supported with source "
|
||||
+ "alpha and source value blending.\n"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1244,6 +1257,11 @@ static void R600SetSolidConsts(ScrnInfoPtr pScrn, float *buf, int format, uint32
|
||||
} else {
|
||||
if (accel_state->component_alpha) {
|
||||
if (accel_state->src_alpha) {
|
||||
+ /* required for PictOpOver */
|
||||
+ float cblend[4] = { pix_r / pix_a, pix_g / pix_a,
|
||||
+ pix_b / pix_a, pix_a / pix_a };
|
||||
+ r600_set_blend_color(pScrn, cblend);
|
||||
+
|
||||
if (PICT_FORMAT_A(format) == 0) {
|
||||
pix_r = 1.0;
|
||||
pix_g = 1.0;
|
||||
diff --git a/src/r600_state.h b/src/r600_state.h
|
||||
index fa777e8..fda297d 100644
|
||||
--- a/src/r600_state.h
|
||||
+++ b/src/r600_state.h
|
||||
@@ -266,6 +266,8 @@ r600_wait_3d_idle(ScrnInfoPtr pScrn);
|
||||
void
|
||||
r600_start_3d(ScrnInfoPtr pScrn);
|
||||
void
|
||||
+r600_set_blend_color(ScrnInfoPtr pScrn, float *color);
|
||||
+void
|
||||
r600_set_render_target(ScrnInfoPtr pScrn, cb_config_t *cb_conf, uint32_t domain);
|
||||
void
|
||||
r600_cp_wait_vline_sync(ScrnInfoPtr pScrn, PixmapPtr pPix, xf86CrtcPtr crtc, int start, int stop);
|
||||
diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c
|
||||
index a97c84b..1f5c052 100644
|
||||
--- a/src/r6xx_accel.c
|
||||
+++ b/src/r6xx_accel.c
|
||||
@@ -174,6 +174,20 @@ r600_sq_setup(ScrnInfoPtr pScrn, sq_config_t *sq_conf)
|
||||
END_BATCH();
|
||||
}
|
||||
|
||||
+void r600_set_blend_color(ScrnInfoPtr pScrn, float *color)
|
||||
+{
|
||||
+ RADEONInfoPtr info = RADEONPTR(pScrn);
|
||||
+
|
||||
+ BEGIN_BATCH(2 + 4);
|
||||
+ PACK0(CB_BLEND_RED, 4);
|
||||
+ EFLOAT(color[0]); /* R */
|
||||
+ EFLOAT(color[1]); /* G */
|
||||
+ EFLOAT(color[2]); /* B */
|
||||
+ EFLOAT(color[3]); /* A */
|
||||
+ END_BATCH();
|
||||
+}
|
||||
+
|
||||
+
|
||||
void
|
||||
r600_set_render_target(ScrnInfoPtr pScrn, cb_config_t *cb_conf, uint32_t domain)
|
||||
{
|
80
U_07-Adapt-to-XF86_CRTC_VERSION-7.patch
Normal file
80
U_07-Adapt-to-XF86_CRTC_VERSION-7.patch
Normal file
@ -0,0 +1,80 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Mon Mar 28 18:49:15 2016 +0900
|
||||
Subject: [PATCH 7/20]Adapt to XF86_CRTC_VERSION 7
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 7835558acdce318130ba4a09ef936fd675e3197d
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
Now the HW cursor can be used with TearFree rotation.
|
||||
|
||||
This also allows always using the separate scanout pixmap mechanism for
|
||||
rotation, so that should be much smoother even without TearFree enabled.
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
src/drmmode_display.c | 18 +++++++++++++-----
|
||||
1 file changed, 13 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
|
||||
index 34b76e9..e32791d 100644
|
||||
--- a/src/drmmode_display.c
|
||||
+++ b/src/drmmode_display.c
|
||||
@@ -643,7 +643,7 @@ drmmode_can_use_hw_cursor(xf86CrtcPtr crtc)
|
||||
if (crtc->transformPresent)
|
||||
return FALSE;
|
||||
|
||||
-#if XF86_CRTC_VERSION >= 4
|
||||
+#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7
|
||||
/* Xorg doesn't correctly handle cursor position transform in the
|
||||
* rotation case
|
||||
*/
|
||||
@@ -666,11 +666,19 @@ drmmode_can_use_hw_cursor(xf86CrtcPtr crtc)
|
||||
static Bool
|
||||
drmmode_handle_transform(xf86CrtcPtr crtc)
|
||||
{
|
||||
- RADEONInfoPtr info = RADEONPTR(crtc->scrn);
|
||||
Bool ret;
|
||||
|
||||
+#if XF86_CRTC_VERSION >= 7
|
||||
+ if (!crtc->transformPresent && crtc->rotation != RR_Rotate_0)
|
||||
+ crtc->driverIsPerformingTransform = XF86DriverTransformOutput;
|
||||
+ else
|
||||
+ crtc->driverIsPerformingTransform = XF86DriverTransformNone;
|
||||
+#else
|
||||
+ RADEONInfoPtr info = RADEONPTR(crtc->scrn);
|
||||
+
|
||||
crtc->driverIsPerformingTransform = info->tear_free &&
|
||||
!crtc->transformPresent && crtc->rotation != RR_Rotate_0;
|
||||
+#endif
|
||||
|
||||
ret = xf86CrtcRotate(crtc);
|
||||
|
||||
@@ -921,7 +929,7 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
drmmode_ptr drmmode = drmmode_crtc->drmmode;
|
||||
|
||||
-#if XF86_CRTC_VERSION >= 4
|
||||
+#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7
|
||||
if (crtc->driverIsPerformingTransform) {
|
||||
x += crtc->x;
|
||||
y += crtc->y;
|
||||
@@ -932,7 +940,7 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
|
||||
drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
|
||||
}
|
||||
|
||||
-#if XF86_CRTC_VERSION >= 4
|
||||
+#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7
|
||||
|
||||
static int
|
||||
drmmode_cursor_src_offset(Rotation rotation, int width, int height,
|
||||
@@ -978,7 +986,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
|
||||
/* cursor should be mapped already */
|
||||
ptr = (uint32_t *)(drmmode_crtc->cursor_bo->ptr);
|
||||
|
||||
-#if XF86_CRTC_VERSION >= 4
|
||||
+#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7
|
||||
if (crtc->driverIsPerformingTransform) {
|
||||
uint32_t cursor_w = info->cursor_w, cursor_h = info->cursor_h;
|
||||
int dstx, dsty;
|
124
U_08-Add-explicit-RADEON_DRM_QUEUE_ERROR-define.patch
Normal file
124
U_08-Add-explicit-RADEON_DRM_QUEUE_ERROR-define.patch
Normal file
@ -0,0 +1,124 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Wed Jul 6 12:46:01 2016 +0900
|
||||
Subject: [PATCH 8/20]Add explicit RADEON_DRM_QUEUE_ERROR define
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: a37af701768b12d86868a831a79f1e02ee4968cf
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
Should make the radeon_drm_queue_alloc error handling clearer, and gets
|
||||
rid of a compile warning about it returning NULL.
|
||||
|
||||
Reviewed-by: Alexandre Demers <alexandre.f.demers@gmail.com>
|
||||
---
|
||||
src/drmmode_display.c | 2 +-
|
||||
src/radeon_dri2.c | 4 ++--
|
||||
src/radeon_drm_queue.c | 7 ++++---
|
||||
src/radeon_drm_queue.h | 2 ++
|
||||
src/radeon_kms.c | 4 ++--
|
||||
src/radeon_present.c | 2 +-
|
||||
6 files changed, 12 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
|
||||
index e32791d..b9c8097 100644
|
||||
--- a/src/drmmode_display.c
|
||||
+++ b/src/drmmode_display.c
|
||||
@@ -2829,7 +2829,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
|
||||
flipdata,
|
||||
drmmode_flip_handler,
|
||||
drmmode_flip_abort);
|
||||
- if (!drm_queue_seq) {
|
||||
+ if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
|
||||
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
|
||||
"Allocating DRM queue event entry failed.\n");
|
||||
goto error;
|
||||
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
|
||||
index 5ebc9b7..69fd0ea 100644
|
||||
--- a/src/radeon_dri2.c
|
||||
+++ b/src/radeon_dri2.c
|
||||
@@ -1143,7 +1143,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
|
||||
drm_queue_seq = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT,
|
||||
wait_info, radeon_dri2_frame_event_handler,
|
||||
radeon_dri2_frame_event_abort);
|
||||
- if (!drm_queue_seq) {
|
||||
+ if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
|
||||
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
|
||||
"Allocating DRM queue event entry failed.\n");
|
||||
goto out_complete;
|
||||
@@ -1290,7 +1290,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
|
||||
drm_queue_seq = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT,
|
||||
swap_info, radeon_dri2_frame_event_handler,
|
||||
radeon_dri2_frame_event_abort);
|
||||
- if (!drm_queue_seq) {
|
||||
+ if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
|
||||
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
|
||||
"Allocating DRM queue entry failed.\n");
|
||||
goto blit_fallback;
|
||||
diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c
|
||||
index 0d999dd..31f2435 100644
|
||||
--- a/src/radeon_drm_queue.c
|
||||
+++ b/src/radeon_drm_queue.c
|
||||
@@ -92,10 +92,11 @@ radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client,
|
||||
|
||||
e = calloc(1, sizeof(struct radeon_drm_queue_entry));
|
||||
if (!e)
|
||||
- return NULL;
|
||||
+ return RADEON_DRM_QUEUE_ERROR;
|
||||
+
|
||||
+ if (_X_UNLIKELY(radeon_drm_queue_seq == RADEON_DRM_QUEUE_ERROR))
|
||||
+ radeon_drm_queue_seq++;
|
||||
|
||||
- if (!radeon_drm_queue_seq)
|
||||
- radeon_drm_queue_seq = 1;
|
||||
e->seq = radeon_drm_queue_seq++;
|
||||
e->client = client;
|
||||
e->crtc = crtc;
|
||||
diff --git a/src/radeon_drm_queue.h b/src/radeon_drm_queue.h
|
||||
index 0d9d278..c3e2076 100644
|
||||
--- a/src/radeon_drm_queue.h
|
||||
+++ b/src/radeon_drm_queue.h
|
||||
@@ -29,6 +29,8 @@
|
||||
#ifndef _RADEON_DRM_QUEUE_H_
|
||||
#define _RADEON_DRM_QUEUE_H_
|
||||
|
||||
+#define RADEON_DRM_QUEUE_ERROR 0
|
||||
+
|
||||
#define RADEON_DRM_QUEUE_CLIENT_DEFAULT serverClient
|
||||
#define RADEON_DRM_QUEUE_ID_DEFAULT ~0ULL
|
||||
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index 0ced370..3ba9945 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -529,7 +529,7 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc)
|
||||
drmmode_crtc,
|
||||
radeon_scanout_update_handler,
|
||||
radeon_scanout_update_abort);
|
||||
- if (!drm_queue_seq) {
|
||||
+ if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
|
||||
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
|
||||
"radeon_drm_queue_alloc failed for scanout update\n");
|
||||
return;
|
||||
@@ -581,7 +581,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info,
|
||||
RADEON_DRM_QUEUE_ID_DEFAULT,
|
||||
drmmode_crtc, NULL,
|
||||
radeon_scanout_flip_abort);
|
||||
- if (!drm_queue_seq) {
|
||||
+ if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
|
||||
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
|
||||
"Allocating DRM event queue entry failed.\n");
|
||||
return;
|
||||
diff --git a/src/radeon_present.c b/src/radeon_present.c
|
||||
index 69a0532..93c18a8 100644
|
||||
--- a/src/radeon_present.c
|
||||
+++ b/src/radeon_present.c
|
||||
@@ -169,7 +169,7 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
|
||||
event_id, event,
|
||||
radeon_present_vblank_handler,
|
||||
radeon_present_vblank_abort);
|
||||
- if (!drm_queue_seq) {
|
||||
+ if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
|
||||
free(event);
|
||||
return BadAlloc;
|
||||
}
|
48
U_09-Don-t-enable-DRI3-by-default-with-EXA.patch
Normal file
48
U_09-Don-t-enable-DRI3-by-default-with-EXA.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Tue Jul 12 17:36:27 2016 +0900
|
||||
Subject: [PATCH 9/20]Don't enable DRI3 by default with EXA
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 94fe42f29e0b00a26e810581d6c438ac6d8ecd8a
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
It doesn't work correctly in all cases, see e.g.
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=95475 . I'm not sure this
|
||||
is fixable, given EXA's architecture.
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
man/radeon.man | 5 +++--
|
||||
src/radeon_kms.c | 2 +-
|
||||
2 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/man/radeon.man b/man/radeon.man
|
||||
index cacafb5..44603a5 100644
|
||||
--- a/man/radeon.man
|
||||
+++ b/man/radeon.man
|
||||
@@ -271,8 +271,9 @@ Sea Islands.
|
||||
Define the maximum level of DRI to enable. Valid values are 2 for DRI2 or 3 for DRI3.
|
||||
The default is
|
||||
.B 3 for DRI3
|
||||
-if the driver was compiled for Xorg >= 1.18.3, otherwise
|
||||
-.B 2 for DRI2.
|
||||
+if the driver was compiled for Xorg >= 1.18.3 and glamor is enabled, otherwise
|
||||
+.B 2 for DRI2. Note:
|
||||
+DRI3 may not work correctly in all cases with EXA, enable at your own risk.
|
||||
.TP
|
||||
.BI "Option \*qEnablePageFlip\*q \*q" boolean \*q
|
||||
Enable DRI2 page flipping. The default is
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index 3ba9945..a618513 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -1726,7 +1726,7 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
|
||||
#endif
|
||||
|
||||
#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,18,3,0,0)
|
||||
- value = TRUE;
|
||||
+ value = info->use_glamor;
|
||||
#else
|
||||
value = FALSE;
|
||||
#endif
|
@ -0,0 +1,170 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Mon Jul 11 12:22:09 2016 +0900
|
||||
Subject: [PATCH 10/20]Use EventCallback to avoid flushing every time in the FlushCallback
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 9a1afbf61fbb2827c86bd86d295fa0848980d60b
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
We only need to flush for XDamageNotify events.
|
||||
|
||||
Significantly reduces compositing slowdown due to flushing overhead, in
|
||||
particular with glamor.
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
src/radeon.h | 2 ++
|
||||
src/radeon_kms.c | 79 +++++++++++++++++++++++++++++++++++++++++++++-----------
|
||||
2 files changed, 66 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/radeon.h b/src/radeon.h
|
||||
index 37d5fb6..25ff61c 100644
|
||||
--- a/src/radeon.h
|
||||
+++ b/src/radeon.h
|
||||
@@ -473,6 +473,8 @@ typedef struct {
|
||||
Bool RenderAccel; /* Render */
|
||||
Bool allowColorTiling;
|
||||
Bool allowColorTiling2D;
|
||||
+ int callback_event_type;
|
||||
+ uint_fast32_t callback_needs_flush;
|
||||
uint_fast32_t gpu_flushed;
|
||||
uint_fast32_t gpu_synced;
|
||||
struct radeon_accel_state *accel_state;
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index a618513..f778d30 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -51,6 +51,8 @@
|
||||
#include <X11/extensions/dpms.h>
|
||||
#endif
|
||||
|
||||
+#include <X11/extensions/damageproto.h>
|
||||
+
|
||||
#include "radeon_chipinfo_gen.h"
|
||||
|
||||
#include "radeon_bo_gem.h"
|
||||
@@ -91,10 +93,11 @@ void radeon_cs_flush_indirect(ScrnInfoPtr pScrn)
|
||||
struct radeon_accel_state *accel_state;
|
||||
int ret;
|
||||
|
||||
+ info->gpu_flushed++;
|
||||
+
|
||||
#ifdef USE_GLAMOR
|
||||
if (info->use_glamor) {
|
||||
glamor_block_handler(pScrn->pScreen);
|
||||
- info->gpu_flushed++;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -237,8 +240,51 @@ radeonUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
|
||||
shadowUpdatePacked(pScreen, pBuf);
|
||||
}
|
||||
|
||||
+static Bool
|
||||
+callback_needs_flush(RADEONInfoPtr info)
|
||||
+{
|
||||
+ return (int)(info->callback_needs_flush - info->gpu_flushed) > 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+radeon_event_callback(CallbackListPtr *list,
|
||||
+ pointer user_data, pointer call_data)
|
||||
+{
|
||||
+ EventInfoRec *eventinfo = call_data;
|
||||
+ ScrnInfoPtr pScrn = user_data;
|
||||
+ RADEONInfoPtr info = RADEONPTR(pScrn);
|
||||
+ int i;
|
||||
+
|
||||
+ if (callback_needs_flush(info))
|
||||
+ return;
|
||||
+
|
||||
+ /* Don't let gpu_flushed get too far ahead of callback_needs_flush,
|
||||
+ * in order to prevent false positives in callback_needs_flush()
|
||||
+ */
|
||||
+ info->callback_needs_flush = info->gpu_flushed;
|
||||
+
|
||||
+ for (i = 0; i < eventinfo->count; i++) {
|
||||
+ if (eventinfo->events[i].u.u.type == info->callback_event_type) {
|
||||
+ info->callback_needs_flush++;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+radeon_flush_callback(CallbackListPtr *list,
|
||||
+ pointer user_data, pointer call_data)
|
||||
+{
|
||||
+ ScrnInfoPtr pScrn = user_data;
|
||||
+ RADEONInfoPtr info = RADEONPTR(pScrn);
|
||||
+
|
||||
+ if (pScrn->vtSema && callback_needs_flush(info))
|
||||
+ radeon_cs_flush_indirect(pScrn);
|
||||
+}
|
||||
+
|
||||
static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
|
||||
{
|
||||
+ ExtensionEntry *damage_ext = CheckExtension("DAMAGE");
|
||||
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
|
||||
RADEONInfoPtr info = RADEONPTR(pScrn);
|
||||
PixmapPtr pixmap;
|
||||
@@ -294,6 +340,19 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
|
||||
if (info->use_glamor)
|
||||
radeon_glamor_create_screen_resources(pScreen);
|
||||
|
||||
+ info->callback_event_type = -1;
|
||||
+ if (damage_ext) {
|
||||
+ info->callback_event_type = damage_ext->eventBase + XDamageNotify;
|
||||
+
|
||||
+ if (!AddCallback(&FlushCallback, radeon_flush_callback, pScrn))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!AddCallback(&EventCallback, radeon_event_callback, pScrn)) {
|
||||
+ DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -641,16 +700,6 @@ static void RADEONBlockHandler_oneshot(BLOCKHANDLER_ARGS_DECL)
|
||||
drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE);
|
||||
}
|
||||
|
||||
-static void
|
||||
-radeon_flush_callback(CallbackListPtr *list,
|
||||
- pointer user_data, pointer call_data)
|
||||
-{
|
||||
- ScrnInfoPtr pScrn = user_data;
|
||||
-
|
||||
- if (pScrn->vtSema)
|
||||
- radeon_cs_flush_indirect(pScrn);
|
||||
-}
|
||||
-
|
||||
static Bool RADEONIsFastFBWorking(ScrnInfoPtr pScrn)
|
||||
{
|
||||
RADEONInfoPtr info = RADEONPTR(pScrn);
|
||||
@@ -1564,7 +1613,10 @@ static Bool RADEONCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL)
|
||||
radeon_drm_queue_close(pScrn);
|
||||
radeon_cs_flush_indirect(pScrn);
|
||||
|
||||
- DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
|
||||
+ if (info->callback_event_type != -1) {
|
||||
+ DeleteCallback(&EventCallback, radeon_event_callback, pScrn);
|
||||
+ DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
|
||||
+ }
|
||||
|
||||
if (info->accel_state->exa) {
|
||||
exaDriverFini(pScreen);
|
||||
@@ -1838,9 +1890,6 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
|
||||
info->BlockHandler = pScreen->BlockHandler;
|
||||
pScreen->BlockHandler = RADEONBlockHandler_oneshot;
|
||||
|
||||
- if (!AddCallback(&FlushCallback, radeon_flush_callback, pScrn))
|
||||
- return FALSE;
|
||||
-
|
||||
info->CreateScreenResources = pScreen->CreateScreenResources;
|
||||
pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;
|
||||
|
@ -0,0 +1,142 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Mon Jul 11 12:51:46 2016 +0900
|
||||
Subject: [PATCH 11/20]Keep track of damage event related flushes per-client v2
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 121a6de72da5fcf9a32408eff36b2235f3dfbcfe
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
This further reduces the compositing slowdown due to flushing overhead,
|
||||
by only flushing when the X server actually sends XDamageNotify events
|
||||
to a client, and there hasn't been a flush yet in the meantime.
|
||||
|
||||
v2: Use ScreenPrivateKey, fixes invalid memory access with GPU screens
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
src/radeon.h | 5 ++++-
|
||||
src/radeon_kms.c | 41 +++++++++++++++++++++++++++++++++--------
|
||||
2 files changed, 37 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/radeon.h b/src/radeon.h
|
||||
index 25ff61c..f3a3e1c 100644
|
||||
--- a/src/radeon.h
|
||||
+++ b/src/radeon.h
|
||||
@@ -448,6 +448,10 @@ struct radeon_accel_state {
|
||||
Bool force;
|
||||
};
|
||||
|
||||
+struct radeon_client_priv {
|
||||
+ uint_fast32_t needs_flush;
|
||||
+};
|
||||
+
|
||||
typedef struct {
|
||||
EntityInfoPtr pEnt;
|
||||
pciVideoPtr PciInfo;
|
||||
@@ -474,7 +478,6 @@ typedef struct {
|
||||
Bool allowColorTiling;
|
||||
Bool allowColorTiling2D;
|
||||
int callback_event_type;
|
||||
- uint_fast32_t callback_needs_flush;
|
||||
uint_fast32_t gpu_flushed;
|
||||
uint_fast32_t gpu_synced;
|
||||
struct radeon_accel_state *accel_state;
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index f778d30..136c46c 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
#include "radeon_version.h"
|
||||
#include "shadow.h"
|
||||
+#include <xf86Priv.h>
|
||||
|
||||
#include "atipciids.h"
|
||||
|
||||
@@ -59,6 +60,8 @@
|
||||
#include "radeon_cs_gem.h"
|
||||
#include "radeon_vbo.h"
|
||||
|
||||
+static DevScreenPrivateKeyRec radeon_client_private_key;
|
||||
+
|
||||
extern SymTabRec RADEONChipsets[];
|
||||
static Bool radeon_setup_kernel_mem(ScreenPtr pScreen);
|
||||
|
||||
@@ -241,9 +244,9 @@ radeonUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
|
||||
}
|
||||
|
||||
static Bool
|
||||
-callback_needs_flush(RADEONInfoPtr info)
|
||||
+callback_needs_flush(RADEONInfoPtr info, struct radeon_client_priv *client_priv)
|
||||
{
|
||||
- return (int)(info->callback_needs_flush - info->gpu_flushed) > 0;
|
||||
+ return (int)(client_priv->needs_flush - info->gpu_flushed) > 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -252,20 +255,30 @@ radeon_event_callback(CallbackListPtr *list,
|
||||
{
|
||||
EventInfoRec *eventinfo = call_data;
|
||||
ScrnInfoPtr pScrn = user_data;
|
||||
+ ScreenPtr pScreen = pScrn->pScreen;
|
||||
+ struct radeon_client_priv *client_priv =
|
||||
+ dixLookupScreenPrivate(&eventinfo->client->devPrivates,
|
||||
+ &radeon_client_private_key, pScreen);
|
||||
+ struct radeon_client_priv *server_priv =
|
||||
+ dixLookupScreenPrivate(&serverClient->devPrivates,
|
||||
+ &radeon_client_private_key, pScreen);
|
||||
RADEONInfoPtr info = RADEONPTR(pScrn);
|
||||
int i;
|
||||
|
||||
- if (callback_needs_flush(info))
|
||||
+ if (callback_needs_flush(info, client_priv) ||
|
||||
+ callback_needs_flush(info, server_priv))
|
||||
return;
|
||||
|
||||
- /* Don't let gpu_flushed get too far ahead of callback_needs_flush,
|
||||
- * in order to prevent false positives in callback_needs_flush()
|
||||
+ /* Don't let gpu_flushed get too far ahead of needs_flush, in order
|
||||
+ * to prevent false positives in callback_needs_flush()
|
||||
*/
|
||||
- info->callback_needs_flush = info->gpu_flushed;
|
||||
+ client_priv->needs_flush = info->gpu_flushed;
|
||||
+ server_priv->needs_flush = info->gpu_flushed;
|
||||
|
||||
for (i = 0; i < eventinfo->count; i++) {
|
||||
if (eventinfo->events[i].u.u.type == info->callback_event_type) {
|
||||
- info->callback_needs_flush++;
|
||||
+ client_priv->needs_flush++;
|
||||
+ server_priv->needs_flush++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -276,9 +289,14 @@ radeon_flush_callback(CallbackListPtr *list,
|
||||
pointer user_data, pointer call_data)
|
||||
{
|
||||
ScrnInfoPtr pScrn = user_data;
|
||||
+ ScreenPtr pScreen = pScrn->pScreen;
|
||||
+ ClientPtr client = call_data ? call_data : serverClient;
|
||||
+ struct radeon_client_priv *client_priv =
|
||||
+ dixLookupScreenPrivate(&client->devPrivates,
|
||||
+ &radeon_client_private_key, pScreen);
|
||||
RADEONInfoPtr info = RADEONPTR(pScrn);
|
||||
|
||||
- if (pScrn->vtSema && callback_needs_flush(info))
|
||||
+ if (pScrn->vtSema && callback_needs_flush(info, client_priv))
|
||||
radeon_cs_flush_indirect(pScrn);
|
||||
}
|
||||
|
||||
@@ -351,6 +369,13 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
|
||||
DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
|
||||
return FALSE;
|
||||
}
|
||||
+
|
||||
+ if (!dixRegisterScreenPrivateKey(&radeon_client_private_key, pScreen,
|
||||
+ PRIVATE_CLIENT, sizeof(struct radeon_client_priv))) {
|
||||
+ DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
|
||||
+ DeleteCallback(&EventCallback, radeon_event_callback, pScrn);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
}
|
||||
|
||||
return TRUE;
|
@ -0,0 +1,170 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Fri Nov 27 16:53:30 2015 +0900
|
||||
Subject: [PATCH 12/20]Use drmmode_crtc_scanout_* helpers for RandR 1.4 scanout pixmaps
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 4cfa4615f79f64062e5e771cd45dd7048f48b4f6
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
This should allow using multiple CRTCs via RandR 1.4 even with xserver
|
||||
< 1.17. It also simplifies the code a little, and paves the way for
|
||||
following changes.
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
src/drmmode_display.c | 71 ++++++++++++++-------------------------------------
|
||||
src/drmmode_display.h | 1 -
|
||||
src/radeon_kms.c | 16 +++++++-----
|
||||
3 files changed, 28 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
|
||||
index b9c8097..383c8a0 100644
|
||||
--- a/src/drmmode_display.c
|
||||
+++ b/src/drmmode_display.c
|
||||
@@ -785,11 +785,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||
fb_id = drmmode->fb_id;
|
||||
#ifdef RADEON_PIXMAP_SHARING
|
||||
if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) {
|
||||
- x = drmmode_crtc->prime_pixmap_x;
|
||||
- y = 0;
|
||||
-
|
||||
- drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[0]);
|
||||
- drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[1]);
|
||||
+ fb_id = drmmode_crtc->scanout[0].fb_id;
|
||||
+ x = y = 0;
|
||||
} else
|
||||
#endif
|
||||
if (drmmode_crtc->rotate.fb_id) {
|
||||
@@ -798,11 +795,12 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||
|
||||
drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[0]);
|
||||
drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[1]);
|
||||
- } else if (info->tear_free ||
|
||||
+ } else if (!pScreen->isGPU &&
|
||||
+ (info->tear_free ||
|
||||
#if XF86_CRTC_VERSION >= 4
|
||||
- crtc->driverIsPerformingTransform ||
|
||||
+ crtc->driverIsPerformingTransform ||
|
||||
#endif
|
||||
- info->shadow_primary) {
|
||||
+ info->shadow_primary)) {
|
||||
for (i = 0; i < (info->tear_free ? 2 : 1); i++) {
|
||||
drmmode_crtc_scanout_create(crtc,
|
||||
&drmmode_crtc->scanout[i],
|
||||
@@ -1114,61 +1112,30 @@ drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green,
|
||||
static Bool
|
||||
drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
|
||||
{
|
||||
- ScreenPtr screen = xf86ScrnToScreen(crtc->scrn);
|
||||
- PixmapPtr screenpix = screen->GetScreenPixmap(screen);
|
||||
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
- int c, total_width = 0, max_height = 0, this_x = 0;
|
||||
|
||||
if (!ppix) {
|
||||
if (crtc->randr_crtc->scanout_pixmap)
|
||||
- PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap, screenpix);
|
||||
- drmmode_crtc->prime_pixmap_x = 0;
|
||||
+ PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap,
|
||||
+ drmmode_crtc->scanout[0].pixmap);
|
||||
+ drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
+ &drmmode_crtc->scanout[0]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
- /* iterate over all the attached crtcs -
|
||||
- work out bounding box */
|
||||
- for (c = 0; c < xf86_config->num_crtc; c++) {
|
||||
- xf86CrtcPtr iter = xf86_config->crtc[c];
|
||||
- if (!iter->enabled && iter != crtc)
|
||||
- continue;
|
||||
- if (iter == crtc) {
|
||||
- this_x = total_width;
|
||||
- total_width += ppix->drawable.width;
|
||||
- if (max_height < ppix->drawable.height)
|
||||
- max_height = ppix->drawable.height;
|
||||
- } else {
|
||||
- total_width += iter->mode.HDisplay;
|
||||
- if (max_height < iter->mode.VDisplay)
|
||||
- max_height = iter->mode.VDisplay;
|
||||
- }
|
||||
-#if !defined(HAS_DIRTYTRACKING_ROTATION) && !defined(HAS_DIRTYTRACKING2)
|
||||
- if (iter != crtc) {
|
||||
- ErrorF("Cannot do multiple crtcs without X server dirty tracking 2 interface\n");
|
||||
- return FALSE;
|
||||
- }
|
||||
-#endif
|
||||
- }
|
||||
-
|
||||
- if (total_width != screenpix->drawable.width ||
|
||||
- max_height != screenpix->drawable.height) {
|
||||
- Bool ret;
|
||||
- ret = drmmode_xf86crtc_resize(crtc->scrn, total_width, max_height);
|
||||
- if (ret == FALSE)
|
||||
- return FALSE;
|
||||
+ if (!drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0],
|
||||
+ ppix->drawable.width,
|
||||
+ ppix->drawable.height))
|
||||
+ return FALSE;
|
||||
|
||||
- screenpix = screen->GetScreenPixmap(screen);
|
||||
- screen->width = screenpix->drawable.width = total_width;
|
||||
- screen->height = screenpix->drawable.height = max_height;
|
||||
- }
|
||||
- drmmode_crtc->prime_pixmap_x = this_x;
|
||||
#ifdef HAS_DIRTYTRACKING_ROTATION
|
||||
- PixmapStartDirtyTracking(ppix, screenpix, 0, 0, this_x, 0, RR_Rotate_0);
|
||||
+ PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[0].pixmap,
|
||||
+ 0, 0, 0, 0, RR_Rotate_0);
|
||||
#elif defined(HAS_DIRTYTRACKING2)
|
||||
- PixmapStartDirtyTracking2(ppix, screenpix, 0, 0, this_x, 0);
|
||||
+ PixmapStartDirtyTracking2(ppix, drmmode_crtc->scanout[0].pixmap,
|
||||
+ 0, 0, 0, 0);
|
||||
#else
|
||||
- PixmapStartDirtyTracking(ppix, screenpix, 0, 0);
|
||||
+ PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[0].pixmap, 0, 0);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
|
||||
index 63b96ac..53c7926 100644
|
||||
--- a/src/drmmode_display.h
|
||||
+++ b/src/drmmode_display.h
|
||||
@@ -95,7 +95,6 @@ typedef struct {
|
||||
int dpms_last_fps;
|
||||
uint32_t interpolated_vblanks;
|
||||
uint16_t lut_r[256], lut_g[256], lut_b[256];
|
||||
- int prime_pixmap_x;
|
||||
|
||||
/* Modeset needed (for DPMS on or after a page flip crossing with a
|
||||
* modeset)
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index 136c46c..53994c9 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -696,15 +696,17 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
|
||||
(*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
|
||||
pScreen->BlockHandler = RADEONBlockHandler_KMS;
|
||||
|
||||
- for (c = 0; c < xf86_config->num_crtc; c++) {
|
||||
- if (info->tear_free)
|
||||
- radeon_scanout_flip(pScreen, info, xf86_config->crtc[c]);
|
||||
- else if (info->shadow_primary
|
||||
+ if (!pScreen->isGPU) {
|
||||
+ for (c = 0; c < xf86_config->num_crtc; c++) {
|
||||
+ if (info->tear_free)
|
||||
+ radeon_scanout_flip(pScreen, info, xf86_config->crtc[c]);
|
||||
+ else if (info->shadow_primary
|
||||
#if XF86_CRTC_VERSION >= 4
|
||||
- || xf86_config->crtc[c]->driverIsPerformingTransform
|
||||
+ || xf86_config->crtc[c]->driverIsPerformingTransform
|
||||
#endif
|
||||
- )
|
||||
- radeon_scanout_update(xf86_config->crtc[c]);
|
||||
+ )
|
||||
+ radeon_scanout_update(xf86_config->crtc[c]);
|
||||
+ }
|
||||
}
|
||||
|
||||
radeon_cs_flush_indirect(pScrn);
|
@ -0,0 +1,136 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Fri Nov 27 16:31:21 2015 +0900
|
||||
Subject: [PATCH 13/20]Handle RandR 1.4 slave dirty updates via radeon_drm_queue
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: ad0a0656dd0e74683e6d7789decba827aa29c221
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
This reduces PCIe bandwidth usage and tearing.
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
src/radeon_kms.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 90 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index 53994c9..07ba362 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -383,9 +383,9 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
|
||||
|
||||
#ifdef RADEON_PIXMAP_SHARING
|
||||
static void
|
||||
-redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
|
||||
+redisplay_dirty(PixmapDirtyUpdatePtr dirty)
|
||||
{
|
||||
- ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
|
||||
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(dirty->src->drawable.pScreen);
|
||||
RegionRec pixregion;
|
||||
|
||||
PixmapRegionInit(&pixregion, dirty->slave_dst);
|
||||
@@ -399,6 +399,90 @@ redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
|
||||
radeon_cs_flush_indirect(pScrn);
|
||||
DamageRegionProcessPending(&dirty->slave_dst->drawable);
|
||||
RegionUninit(&pixregion);
|
||||
+
|
||||
+ DamageEmpty(dirty->damage);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+radeon_prime_scanout_update_abort(xf86CrtcPtr crtc, void *event_data)
|
||||
+{
|
||||
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
+
|
||||
+ drmmode_crtc->scanout_update_pending = FALSE;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
|
||||
+ void *event_data)
|
||||
+{
|
||||
+ ScrnInfoPtr scrn = crtc->scrn;
|
||||
+ ScreenPtr screen = scrn->pScreen;
|
||||
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
+ PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap;
|
||||
+ PixmapDirtyUpdatePtr dirty;
|
||||
+
|
||||
+ xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
|
||||
+ if (dirty->src == scanoutpix &&
|
||||
+ dirty->slave_dst == drmmode_crtc->scanout[0].pixmap) {
|
||||
+ redisplay_dirty(dirty);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ drmmode_crtc->scanout_update_pending = FALSE;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
|
||||
+{
|
||||
+ ScreenPtr screen = dirty->slave_dst->drawable.pScreen;
|
||||
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
|
||||
+ xf86CrtcPtr xf86_crtc = NULL;
|
||||
+ drmmode_crtc_private_ptr drmmode_crtc = NULL;
|
||||
+ uintptr_t drm_queue_seq;
|
||||
+ drmVBlank vbl;
|
||||
+ int c;
|
||||
+
|
||||
+ /* Find the CRTC which is scanning out from this slave pixmap */
|
||||
+ for (c = 0; c < xf86_config->num_crtc; c++) {
|
||||
+ xf86_crtc = xf86_config->crtc[c];
|
||||
+ drmmode_crtc = xf86_crtc->driver_private;
|
||||
+ if (drmmode_crtc->scanout[0].pixmap == dirty->slave_dst)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (c == xf86_config->num_crtc ||
|
||||
+ !xf86_crtc->enabled ||
|
||||
+ drmmode_crtc->scanout_update_pending ||
|
||||
+ !drmmode_crtc->scanout[0].pixmap ||
|
||||
+ drmmode_crtc->pending_dpms_mode != DPMSModeOn)
|
||||
+ return;
|
||||
+
|
||||
+ drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc,
|
||||
+ RADEON_DRM_QUEUE_CLIENT_DEFAULT,
|
||||
+ RADEON_DRM_QUEUE_ID_DEFAULT, NULL,
|
||||
+ radeon_prime_scanout_update_handler,
|
||||
+ radeon_prime_scanout_update_abort);
|
||||
+ if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
|
||||
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
|
||||
+ "radeon_drm_queue_alloc failed for PRIME update\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT;
|
||||
+ vbl.request.type |= radeon_populate_vbl_request_type(xf86_crtc);
|
||||
+ vbl.request.sequence = 1;
|
||||
+ vbl.request.signal = drm_queue_seq;
|
||||
+ if (drmWaitVBlank(RADEONPTR(scrn)->dri2.drm_fd, &vbl)) {
|
||||
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
|
||||
+ "drmWaitVBlank failed for PRIME update: %s\n",
|
||||
+ strerror(errno));
|
||||
+ radeon_drm_abort_entry(drm_queue_seq);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ drmmode_crtc->scanout_update_pending = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -413,8 +497,10 @@ radeon_dirty_update(ScreenPtr screen)
|
||||
xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
|
||||
region = DamageRegion(ent->damage);
|
||||
if (RegionNotEmpty(region)) {
|
||||
- redisplay_dirty(screen, ent);
|
||||
- DamageEmpty(ent->damage);
|
||||
+ if (screen->isGPU)
|
||||
+ radeon_prime_scanout_update(ent);
|
||||
+ else
|
||||
+ redisplay_dirty(ent);
|
||||
}
|
||||
}
|
||||
}
|
144
U_14-Track-damage-accurately-for-RandR-1.4-slave-scanout.patch
Normal file
144
U_14-Track-damage-accurately-for-RandR-1.4-slave-scanout.patch
Normal file
@ -0,0 +1,144 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Mon Nov 30 18:54:12 2015 +0900
|
||||
Subject: [PATCH 14/20]Track damage accurately for RandR 1.4 slave scanout
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: b0867063abb197b9134166706d99fcbe5f204bb5
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
This further reduces the PCIe bandwidth usage.
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
src/radeon_kms.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 71 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index 07ba362..c10fb42 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -382,23 +382,76 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
|
||||
}
|
||||
|
||||
#ifdef RADEON_PIXMAP_SHARING
|
||||
+static RegionPtr
|
||||
+dirty_region(PixmapDirtyUpdatePtr dirty)
|
||||
+{
|
||||
+ RegionPtr damageregion = DamageRegion(dirty->damage);
|
||||
+ RegionPtr dstregion;
|
||||
+
|
||||
+#ifdef HAS_DIRTYTRACKING_ROTATION
|
||||
+ if (dirty->rotation != RR_Rotate_0) {
|
||||
+ BoxPtr boxes = RegionRects(damageregion);
|
||||
+ int nboxes = RegionNumRects(damageregion);
|
||||
+ xRectanglePtr rects = malloc(nboxes * sizeof(*rects));
|
||||
+ int dst_w = dirty->slave_dst->drawable.width;
|
||||
+ int dst_h = dirty->slave_dst->drawable.height;
|
||||
+ int nrects = 0;
|
||||
+ BoxRec box;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < nboxes; i++) {
|
||||
+ box.x1 = boxes[i].x1;
|
||||
+ box.x2 = boxes[i].x2;
|
||||
+ box.y1 = boxes[i].y1;
|
||||
+ box.y2 = boxes[i].y2;
|
||||
+ pixman_f_transform_bounds(&dirty->f_inverse, &box);
|
||||
+
|
||||
+ box.x1 = max(box.x1, 0);
|
||||
+ box.y1 = max(box.y1, 0);
|
||||
+ box.x2 = min(box.x2, dst_w);
|
||||
+ box.y2 = min(box.y2, dst_h);
|
||||
+ if (box.x1 >= box.x2 || box.y1 >= box.y2)
|
||||
+ continue;
|
||||
+
|
||||
+ rects[nrects].x = box.x1;
|
||||
+ rects[nrects].y = box.y1;
|
||||
+ rects[nrects].width = box.x2 - box.x1;
|
||||
+ rects[nrects].height = box.y2 - box.y1;
|
||||
+ nrects++;
|
||||
+ }
|
||||
+ dstregion = RegionFromRects(nrects, rects, CT_UNSORTED);
|
||||
+ } else
|
||||
+#endif
|
||||
+ {
|
||||
+ RegionRec pixregion;
|
||||
+
|
||||
+ dstregion = RegionDuplicate(damageregion);
|
||||
+ RegionTranslate(dstregion, -dirty->x, -dirty->y);
|
||||
+ PixmapRegionInit(&pixregion, dirty->slave_dst);
|
||||
+ RegionIntersect(dstregion, dstregion, &pixregion);
|
||||
+ RegionUninit(&pixregion);
|
||||
+ }
|
||||
+
|
||||
+ return dstregion;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
-redisplay_dirty(PixmapDirtyUpdatePtr dirty)
|
||||
+redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86ScreenToScrn(dirty->src->drawable.pScreen);
|
||||
- RegionRec pixregion;
|
||||
|
||||
- PixmapRegionInit(&pixregion, dirty->slave_dst);
|
||||
- DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
|
||||
+ if (dirty->slave_dst->master_pixmap)
|
||||
+ DamageRegionAppend(&dirty->slave_dst->drawable, region);
|
||||
+
|
||||
#ifdef HAS_DIRTYTRACKING_ROTATION
|
||||
PixmapSyncDirtyHelper(dirty);
|
||||
#else
|
||||
- PixmapSyncDirtyHelper(dirty, &pixregion);
|
||||
+ PixmapSyncDirtyHelper(dirty, region);
|
||||
#endif
|
||||
|
||||
radeon_cs_flush_indirect(pScrn);
|
||||
- DamageRegionProcessPending(&dirty->slave_dst->drawable);
|
||||
- RegionUninit(&pixregion);
|
||||
+ if (dirty->slave_dst->master_pixmap)
|
||||
+ DamageRegionProcessPending(&dirty->slave_dst->drawable);
|
||||
|
||||
DamageEmpty(dirty->damage);
|
||||
}
|
||||
@@ -424,7 +477,10 @@ radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t u
|
||||
xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
|
||||
if (dirty->src == scanoutpix &&
|
||||
dirty->slave_dst == drmmode_crtc->scanout[0].pixmap) {
|
||||
- redisplay_dirty(dirty);
|
||||
+ RegionPtr region = dirty_region(dirty);
|
||||
+
|
||||
+ redisplay_dirty(dirty, region);
|
||||
+ RegionDestroy(region);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -488,20 +544,24 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
|
||||
static void
|
||||
radeon_dirty_update(ScreenPtr screen)
|
||||
{
|
||||
- RegionPtr region;
|
||||
PixmapDirtyUpdatePtr ent;
|
||||
|
||||
if (xorg_list_is_empty(&screen->pixmap_dirty_list))
|
||||
return;
|
||||
|
||||
xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
|
||||
- region = DamageRegion(ent->damage);
|
||||
+ RegionPtr region = dirty_region(ent);
|
||||
+
|
||||
if (RegionNotEmpty(region)) {
|
||||
if (screen->isGPU)
|
||||
radeon_prime_scanout_update(ent);
|
||||
else
|
||||
- redisplay_dirty(ent);
|
||||
+ redisplay_dirty(ent, region);
|
||||
+ } else {
|
||||
+ DamageEmpty(ent->damage);
|
||||
}
|
||||
+
|
||||
+ RegionDestroy(region);
|
||||
}
|
||||
}
|
||||
#endif
|
50
U_15-Fix-build-against-xserver-1.13.patch
Normal file
50
U_15-Fix-build-against-xserver-1.13.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Fri Aug 26 18:09:03 2016 +0900
|
||||
Subject: [PATCH 15/20]Fix build against xserver < 1.13
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: a92c27484703abc7c410b6ae0e4b8d1efbbb8e6f
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
pScreen->isGPU was only introduced in 1.13.
|
||||
|
||||
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97490
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
src/drmmode_display.c | 5 ++++-
|
||||
src/radeon_kms.c | 5 ++++-
|
||||
2 files changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
|
||||
index 383c8a0..1fcd7c3 100644
|
||||
--- a/src/drmmode_display.c
|
||||
+++ b/src/drmmode_display.c
|
||||
@@ -795,7 +795,10 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||
|
||||
drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[0]);
|
||||
drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[1]);
|
||||
- } else if (!pScreen->isGPU &&
|
||||
+ } else if (
|
||||
+#ifdef RADEON_PIXMAP_SHARING
|
||||
+ !pScreen->isGPU &&
|
||||
+#endif
|
||||
(info->tear_free ||
|
||||
#if XF86_CRTC_VERSION >= 4
|
||||
crtc->driverIsPerformingTransform ||
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index c10fb42..51f320c 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -842,7 +842,10 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
|
||||
(*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
|
||||
pScreen->BlockHandler = RADEONBlockHandler_KMS;
|
||||
|
||||
- if (!pScreen->isGPU) {
|
||||
+#ifdef RADEON_PIXMAP_SHARING
|
||||
+ if (!pScreen->isGPU)
|
||||
+#endif
|
||||
+ {
|
||||
for (c = 0; c < xf86_config->num_crtc; c++) {
|
||||
if (info->tear_free)
|
||||
radeon_scanout_flip(pScreen, info, xf86_config->crtc[c]);
|
@ -0,0 +1,163 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Tue Dec 1 17:58:13 2015 +0900
|
||||
Subject: [PATCH 16/20]Only copy from screen pixmap to shared pixmap on demand for slave scanout
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 99232f64db52812a843cd616d263d3a6b90eef3d
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
Only copy once for each time we update the corresponding scanout pixmap.
|
||||
This can significantly reduce the bandwidth usage when there are
|
||||
frequent updates to the screen pixmap.
|
||||
|
||||
This initial implementation only works when both the master and slave
|
||||
screens use this driver.
|
||||
|
||||
v2:
|
||||
* Reduce churn in radeon_prime_scanout_update_handler
|
||||
* Clear the correct damage in radeon_dirty_update
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
src/radeon_kms.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 69 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index 51f320c..711e84a 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -440,6 +440,9 @@ redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86ScreenToScrn(dirty->src->drawable.pScreen);
|
||||
|
||||
+ if (RegionNil(region))
|
||||
+ goto out;
|
||||
+
|
||||
if (dirty->slave_dst->master_pixmap)
|
||||
DamageRegionAppend(&dirty->slave_dst->drawable, region);
|
||||
|
||||
@@ -453,6 +456,7 @@ redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region)
|
||||
if (dirty->slave_dst->master_pixmap)
|
||||
DamageRegionProcessPending(&dirty->slave_dst->drawable);
|
||||
|
||||
+out:
|
||||
DamageEmpty(dirty->damage);
|
||||
}
|
||||
|
||||
@@ -465,6 +469,39 @@ radeon_prime_scanout_update_abort(xf86CrtcPtr crtc, void *event_data)
|
||||
}
|
||||
|
||||
void
|
||||
+radeon_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty)
|
||||
+{
|
||||
+ ScreenPtr master_screen = dirty->src->master_pixmap->drawable.pScreen;
|
||||
+ PixmapDirtyUpdatePtr ent;
|
||||
+ RegionPtr region;
|
||||
+
|
||||
+ xorg_list_for_each_entry(ent, &master_screen->pixmap_dirty_list, ent) {
|
||||
+ if (ent->slave_dst != dirty->src)
|
||||
+ continue;
|
||||
+
|
||||
+ region = dirty_region(ent);
|
||||
+ redisplay_dirty(ent, region);
|
||||
+ RegionDestroy(region);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static Bool
|
||||
+master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
|
||||
+{
|
||||
+ ScrnInfoPtr master_scrn = xf86ScreenToScrn(dirty->src->master_pixmap->drawable.pScreen);
|
||||
+
|
||||
+ return master_scrn->driverName == scrn->driverName;
|
||||
+}
|
||||
+
|
||||
+static Bool
|
||||
+slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
|
||||
+{
|
||||
+ ScrnInfoPtr slave_scrn = xf86ScreenToScrn(dirty->slave_dst->drawable.pScreen);
|
||||
+
|
||||
+ return slave_scrn->driverName == scrn->driverName;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
|
||||
void *event_data)
|
||||
{
|
||||
@@ -477,8 +514,12 @@ radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t u
|
||||
xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
|
||||
if (dirty->src == scanoutpix &&
|
||||
dirty->slave_dst == drmmode_crtc->scanout[0].pixmap) {
|
||||
- RegionPtr region = dirty_region(dirty);
|
||||
+ RegionPtr region;
|
||||
|
||||
+ if (master_has_sync_shared_pixmap(scrn, dirty))
|
||||
+ radeon_sync_shared_pixmap(dirty);
|
||||
+
|
||||
+ region = dirty_region(dirty);
|
||||
redisplay_dirty(dirty, region);
|
||||
RegionDestroy(region);
|
||||
break;
|
||||
@@ -542,26 +583,41 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
|
||||
}
|
||||
|
||||
static void
|
||||
-radeon_dirty_update(ScreenPtr screen)
|
||||
+radeon_dirty_update(ScrnInfoPtr scrn)
|
||||
{
|
||||
+ ScreenPtr screen = scrn->pScreen;
|
||||
PixmapDirtyUpdatePtr ent;
|
||||
-
|
||||
- if (xorg_list_is_empty(&screen->pixmap_dirty_list))
|
||||
- return;
|
||||
+ RegionPtr region;
|
||||
|
||||
xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
|
||||
- RegionPtr region = dirty_region(ent);
|
||||
+ if (screen->isGPU) {
|
||||
+ PixmapDirtyUpdatePtr region_ent = ent;
|
||||
+
|
||||
+ if (master_has_sync_shared_pixmap(scrn, ent)) {
|
||||
+ ScreenPtr master_screen = ent->src->master_pixmap->drawable.pScreen;
|
||||
|
||||
- if (RegionNotEmpty(region)) {
|
||||
- if (screen->isGPU)
|
||||
+ xorg_list_for_each_entry(region_ent, &master_screen->pixmap_dirty_list, ent) {
|
||||
+ if (region_ent->slave_dst == ent->src)
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ region = dirty_region(region_ent);
|
||||
+
|
||||
+ if (RegionNotEmpty(region))
|
||||
radeon_prime_scanout_update(ent);
|
||||
else
|
||||
- redisplay_dirty(ent, region);
|
||||
+ DamageEmpty(region_ent->damage);
|
||||
+
|
||||
+ RegionDestroy(region);
|
||||
} else {
|
||||
- DamageEmpty(ent->damage);
|
||||
- }
|
||||
+ if (slave_has_sync_shared_pixmap(scrn, ent))
|
||||
+ continue;
|
||||
|
||||
- RegionDestroy(region);
|
||||
+ region = dirty_region(ent);
|
||||
+ redisplay_dirty(ent, region);
|
||||
+ RegionDestroy(region);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -861,7 +917,7 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
|
||||
radeon_cs_flush_indirect(pScrn);
|
||||
|
||||
#ifdef RADEON_PIXMAP_SHARING
|
||||
- radeon_dirty_update(pScreen);
|
||||
+ radeon_dirty_update(pScrn);
|
||||
#endif
|
||||
}
|
||||
|
107
U_17-Factor-out-transform_region-helper.patch
Normal file
107
U_17-Factor-out-transform_region-helper.patch
Normal file
@ -0,0 +1,107 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Thu Sep 1 17:19:27 2016 +0900
|
||||
Subject: [PATCH 17/20]Factor out transform_region helper
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 5a57005178fc13b6f7e513458ca6dae72a3e5783
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
While we're at it, fix leaking the memory allocated for xRectangles.
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
src/radeon_kms.c | 73 +++++++++++++++++++++++++++++++++-----------------------
|
||||
1 file changed, 43 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index 711e84a..7173b77 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -382,6 +382,45 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
|
||||
}
|
||||
|
||||
#ifdef RADEON_PIXMAP_SHARING
|
||||
+
|
||||
+static RegionPtr
|
||||
+transform_region(RegionPtr region, struct pict_f_transform *transform,
|
||||
+ int w, int h)
|
||||
+{
|
||||
+ BoxPtr boxes = RegionRects(region);
|
||||
+ int nboxes = RegionNumRects(region);
|
||||
+ xRectanglePtr rects = malloc(nboxes * sizeof(*rects));
|
||||
+ RegionPtr transformed;
|
||||
+ int nrects = 0;
|
||||
+ BoxRec box;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < nboxes; i++) {
|
||||
+ box.x1 = boxes[i].x1;
|
||||
+ box.x2 = boxes[i].x2;
|
||||
+ box.y1 = boxes[i].y1;
|
||||
+ box.y2 = boxes[i].y2;
|
||||
+ pixman_f_transform_bounds(transform, &box);
|
||||
+
|
||||
+ box.x1 = max(box.x1, 0);
|
||||
+ box.y1 = max(box.y1, 0);
|
||||
+ box.x2 = min(box.x2, w);
|
||||
+ box.y2 = min(box.y2, h);
|
||||
+ if (box.x1 >= box.x2 || box.y1 >= box.y2)
|
||||
+ continue;
|
||||
+
|
||||
+ rects[nrects].x = box.x1;
|
||||
+ rects[nrects].y = box.y1;
|
||||
+ rects[nrects].width = box.x2 - box.x1;
|
||||
+ rects[nrects].height = box.y2 - box.y1;
|
||||
+ nrects++;
|
||||
+ }
|
||||
+
|
||||
+ transformed = RegionFromRects(nrects, rects, CT_UNSORTED);
|
||||
+ free(rects);
|
||||
+ return transformed;
|
||||
+}
|
||||
+
|
||||
static RegionPtr
|
||||
dirty_region(PixmapDirtyUpdatePtr dirty)
|
||||
{
|
||||
@@ -390,36 +429,10 @@ dirty_region(PixmapDirtyUpdatePtr dirty)
|
||||
|
||||
#ifdef HAS_DIRTYTRACKING_ROTATION
|
||||
if (dirty->rotation != RR_Rotate_0) {
|
||||
- BoxPtr boxes = RegionRects(damageregion);
|
||||
- int nboxes = RegionNumRects(damageregion);
|
||||
- xRectanglePtr rects = malloc(nboxes * sizeof(*rects));
|
||||
- int dst_w = dirty->slave_dst->drawable.width;
|
||||
- int dst_h = dirty->slave_dst->drawable.height;
|
||||
- int nrects = 0;
|
||||
- BoxRec box;
|
||||
- int i;
|
||||
-
|
||||
- for (i = 0; i < nboxes; i++) {
|
||||
- box.x1 = boxes[i].x1;
|
||||
- box.x2 = boxes[i].x2;
|
||||
- box.y1 = boxes[i].y1;
|
||||
- box.y2 = boxes[i].y2;
|
||||
- pixman_f_transform_bounds(&dirty->f_inverse, &box);
|
||||
-
|
||||
- box.x1 = max(box.x1, 0);
|
||||
- box.y1 = max(box.y1, 0);
|
||||
- box.x2 = min(box.x2, dst_w);
|
||||
- box.y2 = min(box.y2, dst_h);
|
||||
- if (box.x1 >= box.x2 || box.y1 >= box.y2)
|
||||
- continue;
|
||||
-
|
||||
- rects[nrects].x = box.x1;
|
||||
- rects[nrects].y = box.y1;
|
||||
- rects[nrects].width = box.x2 - box.x1;
|
||||
- rects[nrects].height = box.y2 - box.y1;
|
||||
- nrects++;
|
||||
- }
|
||||
- dstregion = RegionFromRects(nrects, rects, CT_UNSORTED);
|
||||
+ dstregion = transform_region(damageregion,
|
||||
+ &dirty->f_inverse,
|
||||
+ dirty->slave_dst->drawable.width,
|
||||
+ dirty->slave_dst->drawable.height);
|
||||
} else
|
||||
#endif
|
||||
{
|
76
U_18-Move-up-radeon_scanout_extents_intersect.patch
Normal file
76
U_18-Move-up-radeon_scanout_extents_intersect.patch
Normal file
@ -0,0 +1,76 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Fri Sep 2 17:23:16 2016 +0900
|
||||
Subject: [PATCH 18/20]Move up radeon_scanout_extents_intersect
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 2f6e5fb15f1a9ce523c85550e493f8bda9d0c00f
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
Will be needed higher up by the following changes. No functional change.
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
src/radeon_kms.c | 42 +++++++++++++++++++++---------------------
|
||||
1 file changed, 21 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index 7173b77..568c49e 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -381,6 +381,27 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static Bool
|
||||
+radeon_scanout_extents_intersect(xf86CrtcPtr xf86_crtc, BoxPtr extents, int w,
|
||||
+ int h)
|
||||
+{
|
||||
+ extents->x1 = max(extents->x1 - xf86_crtc->x, 0);
|
||||
+ extents->y1 = max(extents->y1 - xf86_crtc->y, 0);
|
||||
+
|
||||
+ switch (xf86_crtc->rotation & 0xf) {
|
||||
+ case RR_Rotate_90:
|
||||
+ case RR_Rotate_270:
|
||||
+ extents->x2 = min(extents->x2 - xf86_crtc->x, h);
|
||||
+ extents->y2 = min(extents->y2 - xf86_crtc->y, w);
|
||||
+ break;
|
||||
+ default:
|
||||
+ extents->x2 = min(extents->x2 - xf86_crtc->x, w);
|
||||
+ extents->y2 = min(extents->y2 - xf86_crtc->y, h);
|
||||
+ }
|
||||
+
|
||||
+ return (extents->x1 < extents->x2 && extents->y1 < extents->y2);
|
||||
+}
|
||||
+
|
||||
#ifdef RADEON_PIXMAP_SHARING
|
||||
|
||||
static RegionPtr
|
||||
@@ -636,27 +657,6 @@ radeon_dirty_update(ScrnInfoPtr scrn)
|
||||
#endif
|
||||
|
||||
static Bool
|
||||
-radeon_scanout_extents_intersect(xf86CrtcPtr xf86_crtc, BoxPtr extents, int w,
|
||||
- int h)
|
||||
-{
|
||||
- extents->x1 = max(extents->x1 - xf86_crtc->x, 0);
|
||||
- extents->y1 = max(extents->y1 - xf86_crtc->y, 0);
|
||||
-
|
||||
- switch (xf86_crtc->rotation & 0xf) {
|
||||
- case RR_Rotate_90:
|
||||
- case RR_Rotate_270:
|
||||
- extents->x2 = min(extents->x2 - xf86_crtc->x, h);
|
||||
- extents->y2 = min(extents->y2 - xf86_crtc->y, w);
|
||||
- break;
|
||||
- default:
|
||||
- extents->x2 = min(extents->x2 - xf86_crtc->x, w);
|
||||
- extents->y2 = min(extents->y2 - xf86_crtc->y, h);
|
||||
- }
|
||||
-
|
||||
- return (extents->x1 < extents->x2 && extents->y1 < extents->y2);
|
||||
-}
|
||||
-
|
||||
-static Bool
|
||||
radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
|
||||
{
|
||||
drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
|
327
U_19-Synchronize-scanout-pixmaps-for-TearFree.patch
Normal file
327
U_19-Synchronize-scanout-pixmaps-for-TearFree.patch
Normal file
@ -0,0 +1,327 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Thu Sep 1 12:54:13 2016 +0900
|
||||
Subject: [PATCH 19/20]Synchronize scanout pixmaps for TearFree
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: eda1f3df6aaed683036369fe8820da4dac3c2ae2
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
Copy the damaged areas which are still valid in the other scanout pixmap
|
||||
from there, then only copy the remaining damaged area from the screen
|
||||
pixmap.
|
||||
|
||||
This is slightly more efficient (only needs one Damage record instead of
|
||||
two, and only needs to copy each screen update across PCIe once with
|
||||
ShadowPrimary and a discrete GPU), and will be significantly more
|
||||
efficient for PRIME with the following change.
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
src/drmmode_display.c | 95 +++++++++++++++++++++++++--------------------------
|
||||
src/drmmode_display.h | 3 +-
|
||||
src/radeon_kms.c | 92 ++++++++++++++++++++++++++++++++++++++++---------
|
||||
3 files changed, 124 insertions(+), 66 deletions(-)
|
||||
|
||||
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
|
||||
index 1fcd7c3..44a4032 100644
|
||||
--- a/src/drmmode_display.c
|
||||
+++ b/src/drmmode_display.c
|
||||
@@ -519,10 +519,20 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
|
||||
radeon_bo_unref(scanout->bo);
|
||||
scanout->bo = NULL;
|
||||
}
|
||||
+}
|
||||
|
||||
- if (scanout->damage) {
|
||||
- DamageDestroy(scanout->damage);
|
||||
- scanout->damage = NULL;
|
||||
+static void
|
||||
+drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc)
|
||||
+{
|
||||
+ drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
+ &drmmode_crtc->scanout[0]);
|
||||
+ drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
+ &drmmode_crtc->scanout[1]);
|
||||
+
|
||||
+ if (drmmode_crtc->scanout_damage) {
|
||||
+ DamageDestroy(drmmode_crtc->scanout_damage);
|
||||
+ drmmode_crtc->scanout_damage = NULL;
|
||||
+ RegionUninit(&drmmode_crtc->scanout_last_region);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -532,15 +542,8 @@ drmmode_scanout_free(ScrnInfoPtr scrn)
|
||||
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
|
||||
int c;
|
||||
|
||||
- for (c = 0; c < xf86_config->num_crtc; c++) {
|
||||
- drmmode_crtc_private_ptr drmmode_crtc =
|
||||
- xf86_config->crtc[c]->driver_private;
|
||||
-
|
||||
- drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
- &drmmode_crtc->scanout[0]);
|
||||
- drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
- &drmmode_crtc->scanout[1]);
|
||||
- }
|
||||
+ for (c = 0; c < xf86_config->num_crtc; c++)
|
||||
+ drmmode_crtc_scanout_free(xf86_config->crtc[c]->driver_private);
|
||||
}
|
||||
|
||||
static void *
|
||||
@@ -793,8 +796,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||
fb_id = drmmode_crtc->rotate.fb_id;
|
||||
x = y = 0;
|
||||
|
||||
- drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[0]);
|
||||
- drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[1]);
|
||||
+ drmmode_crtc_scanout_free(drmmode_crtc);
|
||||
} else if (
|
||||
#ifdef RADEON_PIXMAP_SHARING
|
||||
!pScreen->isGPU &&
|
||||
@@ -809,42 +811,40 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||
&drmmode_crtc->scanout[i],
|
||||
mode->HDisplay,
|
||||
mode->VDisplay);
|
||||
-
|
||||
- if (drmmode_crtc->scanout[i].pixmap) {
|
||||
- RegionPtr pRegion;
|
||||
- BoxPtr pBox;
|
||||
-
|
||||
- if (!drmmode_crtc->scanout[i].damage) {
|
||||
- drmmode_crtc->scanout[i].damage =
|
||||
- DamageCreate(radeon_screen_damage_report,
|
||||
- NULL, DamageReportRawRegion,
|
||||
- TRUE, pScreen, NULL);
|
||||
- DamageRegister(&pScreen->GetScreenPixmap(pScreen)->drawable,
|
||||
- drmmode_crtc->scanout[i].damage);
|
||||
- }
|
||||
-
|
||||
- pRegion = DamageRegion(drmmode_crtc->scanout[i].damage);
|
||||
- RegionUninit(pRegion);
|
||||
- pRegion->data = NULL;
|
||||
- pBox = RegionExtents(pRegion);
|
||||
- pBox->x1 = min(pBox->x1, x);
|
||||
- pBox->y1 = min(pBox->y1, y);
|
||||
-
|
||||
- switch (crtc->rotation & 0xf) {
|
||||
- case RR_Rotate_90:
|
||||
- case RR_Rotate_270:
|
||||
- pBox->x2 = max(pBox->x2, x + mode->VDisplay);
|
||||
- pBox->y2 = max(pBox->y2, y + mode->HDisplay);
|
||||
- break;
|
||||
- default:
|
||||
- pBox->x2 = max(pBox->x2, x + mode->HDisplay);
|
||||
- pBox->y2 = max(pBox->y2, y + mode->VDisplay);
|
||||
- }
|
||||
- }
|
||||
}
|
||||
|
||||
if (drmmode_crtc->scanout[0].pixmap &&
|
||||
(!info->tear_free || drmmode_crtc->scanout[1].pixmap)) {
|
||||
+ RegionPtr pRegion;
|
||||
+ BoxPtr pBox;
|
||||
+
|
||||
+ if (!drmmode_crtc->scanout_damage) {
|
||||
+ drmmode_crtc->scanout_damage =
|
||||
+ DamageCreate(radeon_screen_damage_report,
|
||||
+ NULL, DamageReportRawRegion,
|
||||
+ TRUE, pScreen, NULL);
|
||||
+ DamageRegister(&pScreen->GetScreenPixmap(pScreen)->drawable,
|
||||
+ drmmode_crtc->scanout_damage);
|
||||
+ }
|
||||
+
|
||||
+ pRegion = DamageRegion(drmmode_crtc->scanout_damage);
|
||||
+ RegionUninit(pRegion);
|
||||
+ pRegion->data = NULL;
|
||||
+ pBox = RegionExtents(pRegion);
|
||||
+ pBox->x1 = min(pBox->x1, x);
|
||||
+ pBox->y1 = min(pBox->y1, y);
|
||||
+
|
||||
+ switch (crtc->rotation & 0xf) {
|
||||
+ case RR_Rotate_90:
|
||||
+ case RR_Rotate_270:
|
||||
+ pBox->x2 = max(pBox->x2, x + mode->VDisplay);
|
||||
+ pBox->y2 = max(pBox->y2, y + mode->HDisplay);
|
||||
+ break;
|
||||
+ default:
|
||||
+ pBox->x2 = max(pBox->x2, x + mode->HDisplay);
|
||||
+ pBox->y2 = max(pBox->y2, y + mode->VDisplay);
|
||||
+ }
|
||||
+
|
||||
drmmode_crtc->scanout_id = 0;
|
||||
fb_id = drmmode_crtc->scanout[0].fb_id;
|
||||
x = y = 0;
|
||||
@@ -1121,8 +1121,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
|
||||
if (crtc->randr_crtc->scanout_pixmap)
|
||||
PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap,
|
||||
drmmode_crtc->scanout[0].pixmap);
|
||||
- drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
- &drmmode_crtc->scanout[0]);
|
||||
+ drmmode_crtc_scanout_free(drmmode_crtc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
|
||||
index 53c7926..5df9773 100644
|
||||
--- a/src/drmmode_display.h
|
||||
+++ b/src/drmmode_display.h
|
||||
@@ -73,7 +73,6 @@ typedef struct {
|
||||
struct drmmode_scanout {
|
||||
struct radeon_bo *bo;
|
||||
PixmapPtr pixmap;
|
||||
- DamagePtr damage;
|
||||
unsigned fb_id;
|
||||
int width, height;
|
||||
};
|
||||
@@ -85,6 +84,8 @@ typedef struct {
|
||||
struct radeon_bo *cursor_bo;
|
||||
struct drmmode_scanout rotate;
|
||||
struct drmmode_scanout scanout[2];
|
||||
+ DamagePtr scanout_damage;
|
||||
+ RegionRec scanout_last_region;
|
||||
unsigned scanout_id;
|
||||
Bool scanout_update_pending;
|
||||
int dpms_mode;
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index 568c49e..bcaa024 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -402,8 +402,6 @@ radeon_scanout_extents_intersect(xf86CrtcPtr xf86_crtc, BoxPtr extents, int w,
|
||||
return (extents->x1 < extents->x2 && extents->y1 < extents->y2);
|
||||
}
|
||||
|
||||
-#ifdef RADEON_PIXMAP_SHARING
|
||||
-
|
||||
static RegionPtr
|
||||
transform_region(RegionPtr region, struct pict_f_transform *transform,
|
||||
int w, int h)
|
||||
@@ -442,6 +440,70 @@ transform_region(RegionPtr region, struct pict_f_transform *transform,
|
||||
return transformed;
|
||||
}
|
||||
|
||||
+static void
|
||||
+radeon_sync_scanout_pixmaps(xf86CrtcPtr xf86_crtc, RegionPtr new_region,
|
||||
+ int scanout_id)
|
||||
+{
|
||||
+ drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
|
||||
+ DrawablePtr dst = &drmmode_crtc->scanout[scanout_id].pixmap->drawable;
|
||||
+ DrawablePtr src = &drmmode_crtc->scanout[scanout_id ^ 1].pixmap->drawable;
|
||||
+ RegionPtr last_region = &drmmode_crtc->scanout_last_region;
|
||||
+ ScrnInfoPtr scrn = xf86_crtc->scrn;
|
||||
+ ScreenPtr pScreen = scrn->pScreen;
|
||||
+ RADEONInfoPtr info = RADEONPTR(scrn);
|
||||
+ RegionRec remaining;
|
||||
+ RegionPtr sync_region = NULL;
|
||||
+ BoxRec extents;
|
||||
+ Bool force;
|
||||
+ GCPtr gc;
|
||||
+
|
||||
+ if (RegionNil(last_region))
|
||||
+ return;
|
||||
+
|
||||
+ RegionNull(&remaining);
|
||||
+ RegionSubtract(&remaining, last_region, new_region);
|
||||
+ if (RegionNil(&remaining))
|
||||
+ goto uninit;
|
||||
+
|
||||
+ extents = *RegionExtents(&remaining);
|
||||
+ if (!radeon_scanout_extents_intersect(xf86_crtc, &extents, dst->width,
|
||||
+ dst->height))
|
||||
+ goto uninit;
|
||||
+
|
||||
+#if XF86_CRTC_VERSION >= 4
|
||||
+ if (xf86_crtc->driverIsPerformingTransform) {
|
||||
+ sync_region = transform_region(&remaining,
|
||||
+ &xf86_crtc->f_framebuffer_to_crtc,
|
||||
+ dst->width, dst->height);
|
||||
+ } else
|
||||
+#endif /* XF86_CRTC_VERSION >= 4 */
|
||||
+ {
|
||||
+ sync_region = RegionDuplicate(&remaining);
|
||||
+ RegionTranslate(sync_region, -xf86_crtc->x, -xf86_crtc->y);
|
||||
+ }
|
||||
+
|
||||
+ force = info->accel_state->force;
|
||||
+ info->accel_state->force = TRUE;
|
||||
+
|
||||
+ gc = GetScratchGC(dst->depth, pScreen);
|
||||
+ if (gc) {
|
||||
+ ValidateGC(dst, gc);
|
||||
+ gc->funcs->ChangeClip(gc, CT_REGION, sync_region, 0);
|
||||
+ sync_region = NULL;
|
||||
+ gc->ops->CopyArea(src, dst, gc, 0, 0, dst->width, dst->height, 0, 0);
|
||||
+ FreeScratchGC(gc);
|
||||
+ }
|
||||
+
|
||||
+ info->accel_state->force = force;
|
||||
+
|
||||
+ uninit:
|
||||
+ if (sync_region)
|
||||
+ RegionDestroy(sync_region);
|
||||
+ RegionUninit(&remaining);
|
||||
+}
|
||||
+
|
||||
+#ifdef RADEON_PIXMAP_SHARING
|
||||
+
|
||||
static RegionPtr
|
||||
dirty_region(PixmapDirtyUpdatePtr dirty)
|
||||
{
|
||||
@@ -660,13 +722,12 @@ static Bool
|
||||
radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
|
||||
{
|
||||
drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
|
||||
- ScrnInfoPtr scrn;
|
||||
- DamagePtr pDamage;
|
||||
- RegionPtr pRegion;
|
||||
+ RegionPtr pRegion = DamageRegion(drmmode_crtc->scanout_damage);
|
||||
+ ScrnInfoPtr scrn = xf86_crtc->scrn;
|
||||
+ ScreenPtr pScreen = scrn->pScreen;
|
||||
+ RADEONInfoPtr info = RADEONPTR(scrn);
|
||||
DrawablePtr pDraw;
|
||||
- ScreenPtr pScreen;
|
||||
BoxRec extents;
|
||||
- RADEONInfoPtr info;
|
||||
Bool force;
|
||||
|
||||
if (!xf86_crtc->enabled ||
|
||||
@@ -674,24 +735,21 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
|
||||
!drmmode_crtc->scanout[scanout_id].pixmap)
|
||||
return FALSE;
|
||||
|
||||
- pDamage = drmmode_crtc->scanout[scanout_id].damage;
|
||||
- if (!pDamage)
|
||||
- return FALSE;
|
||||
-
|
||||
- pRegion = DamageRegion(pDamage);
|
||||
if (!RegionNotEmpty(pRegion))
|
||||
return FALSE;
|
||||
|
||||
pDraw = &drmmode_crtc->scanout[scanout_id].pixmap->drawable;
|
||||
- pScreen = pDraw->pScreen;
|
||||
extents = *RegionExtents(pRegion);
|
||||
- RegionEmpty(pRegion);
|
||||
if (!radeon_scanout_extents_intersect(xf86_crtc, &extents, pDraw->width,
|
||||
pDraw->height))
|
||||
return FALSE;
|
||||
|
||||
- scrn = xf86_crtc->scrn;
|
||||
- info = RADEONPTR(scrn);
|
||||
+ if (info->tear_free) {
|
||||
+ radeon_sync_scanout_pixmaps(xf86_crtc, pRegion, scanout_id);
|
||||
+ RegionCopy(&drmmode_crtc->scanout_last_region, pRegion);
|
||||
+ }
|
||||
+ RegionEmpty(pRegion);
|
||||
+
|
||||
force = info->accel_state->force;
|
||||
info->accel_state->force = TRUE;
|
||||
|
||||
@@ -807,7 +865,7 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc)
|
||||
drmmode_crtc->pending_dpms_mode != DPMSModeOn)
|
||||
return;
|
||||
|
||||
- pDamage = drmmode_crtc->scanout[0].damage;
|
||||
+ pDamage = drmmode_crtc->scanout_damage;
|
||||
if (!pDamage)
|
||||
return;
|
||||
|
265
U_20-Make-TearFree-effective-with-PRIME-slave-scanout.patch
Normal file
265
U_20-Make-TearFree-effective-with-PRIME-slave-scanout.patch
Normal file
@ -0,0 +1,265 @@
|
||||
From: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Date: Fri Sep 2 11:08:28 2016 +0900
|
||||
Subject: [PATCH 20/20]Make TearFree effective with PRIME slave scanout
|
||||
Patch-mainline: Upstream
|
||||
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
||||
Git-commit: 38797a33117222dadbc89e5f21ed8cd5deef9bea
|
||||
References: bsc#990066
|
||||
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
||||
|
||||
TearFree can now prevent tearing with any possible display
|
||||
configuration.
|
||||
|
||||
Note that there may still be inter-GPU tearing if the primary GPU uses
|
||||
a different driver.
|
||||
|
||||
v2:
|
||||
* Also test dirty->slave_dst in radeon_prime_scanout_do_update
|
||||
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com> [v1]
|
||||
---
|
||||
src/drmmode_display.c | 33 ++++++++++++---
|
||||
src/drmmode_display.h | 1 +
|
||||
src/radeon_kms.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++----
|
||||
3 files changed, 132 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
|
||||
index 44a4032..44615d3 100644
|
||||
--- a/src/drmmode_display.c
|
||||
+++ b/src/drmmode_display.c
|
||||
@@ -524,10 +524,19 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
|
||||
static void
|
||||
drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc)
|
||||
{
|
||||
- drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
- &drmmode_crtc->scanout[0]);
|
||||
- drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
- &drmmode_crtc->scanout[1]);
|
||||
+ if (drmmode_crtc->flip_pending) {
|
||||
+ drmmode_crtc->scanout_destroy[0] = drmmode_crtc->scanout[0];
|
||||
+ drmmode_crtc->scanout[0].pixmap = NULL;
|
||||
+ drmmode_crtc->scanout[0].bo = NULL;
|
||||
+ drmmode_crtc->scanout_destroy[1] = drmmode_crtc->scanout[1];
|
||||
+ drmmode_crtc->scanout[1].pixmap = NULL;
|
||||
+ drmmode_crtc->scanout[1].bo = NULL;
|
||||
+ } else {
|
||||
+ drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
+ &drmmode_crtc->scanout[0]);
|
||||
+ drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
+ &drmmode_crtc->scanout[1]);
|
||||
+ }
|
||||
|
||||
if (drmmode_crtc->scanout_damage) {
|
||||
DamageDestroy(drmmode_crtc->scanout_damage);
|
||||
@@ -1116,11 +1125,12 @@ static Bool
|
||||
drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
|
||||
{
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
+ RADEONInfoPtr info = RADEONPTR(crtc->scrn);
|
||||
|
||||
if (!ppix) {
|
||||
if (crtc->randr_crtc->scanout_pixmap)
|
||||
PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap,
|
||||
- drmmode_crtc->scanout[0].pixmap);
|
||||
+ drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap);
|
||||
drmmode_crtc_scanout_free(drmmode_crtc);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1130,6 +1140,14 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
|
||||
ppix->drawable.height))
|
||||
return FALSE;
|
||||
|
||||
+ if (info->tear_free &&
|
||||
+ !drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
|
||||
+ ppix->drawable.width,
|
||||
+ ppix->drawable.height)) {
|
||||
+ drmmode_crtc_scanout_free(drmmode_crtc);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
#ifdef HAS_DIRTYTRACKING_ROTATION
|
||||
PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[0].pixmap,
|
||||
0, 0, 0, 0, RR_Rotate_0);
|
||||
@@ -2196,6 +2214,11 @@ drmmode_clear_pending_flip(xf86CrtcPtr crtc)
|
||||
|
||||
drmmode_crtc_dpms(crtc, drmmode_crtc->pending_dpms_mode);
|
||||
}
|
||||
+
|
||||
+ drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
+ &drmmode_crtc->scanout_destroy[0]);
|
||||
+ drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
+ &drmmode_crtc->scanout_destroy[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
|
||||
index 5df9773..7602eb8 100644
|
||||
--- a/src/drmmode_display.h
|
||||
+++ b/src/drmmode_display.h
|
||||
@@ -84,6 +84,7 @@ typedef struct {
|
||||
struct radeon_bo *cursor_bo;
|
||||
struct drmmode_scanout rotate;
|
||||
struct drmmode_scanout scanout[2];
|
||||
+ struct drmmode_scanout scanout_destroy[2];
|
||||
DamagePtr scanout_damage;
|
||||
RegionRec scanout_last_region;
|
||||
unsigned scanout_id;
|
||||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
||||
index bcaa024..9bcf657 100644
|
||||
--- a/src/radeon_kms.c
|
||||
+++ b/src/radeon_kms.c
|
||||
@@ -597,31 +597,56 @@ slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
|
||||
return slave_scrn->driverName == scrn->driverName;
|
||||
}
|
||||
|
||||
-void
|
||||
-radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
|
||||
- void *event_data)
|
||||
+static Bool
|
||||
+radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
|
||||
{
|
||||
ScrnInfoPtr scrn = crtc->scrn;
|
||||
ScreenPtr screen = scrn->pScreen;
|
||||
+ RADEONInfoPtr info = RADEONPTR(scrn);
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap;
|
||||
PixmapDirtyUpdatePtr dirty;
|
||||
+ Bool ret = FALSE;
|
||||
|
||||
xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
|
||||
- if (dirty->src == scanoutpix &&
|
||||
- dirty->slave_dst == drmmode_crtc->scanout[0].pixmap) {
|
||||
+ if (dirty->src == scanoutpix && dirty->slave_dst ==
|
||||
+ drmmode_crtc->scanout[scanout_id ^ info->tear_free].pixmap) {
|
||||
RegionPtr region;
|
||||
|
||||
if (master_has_sync_shared_pixmap(scrn, dirty))
|
||||
radeon_sync_shared_pixmap(dirty);
|
||||
|
||||
region = dirty_region(dirty);
|
||||
+ if (RegionNil(region))
|
||||
+ goto destroy;
|
||||
+
|
||||
+ if (info->tear_free) {
|
||||
+ RegionTranslate(region, crtc->x, crtc->y);
|
||||
+ radeon_sync_scanout_pixmaps(crtc, region, scanout_id);
|
||||
+ radeon_cs_flush_indirect(scrn);
|
||||
+ RegionCopy(&drmmode_crtc->scanout_last_region, region);
|
||||
+ RegionTranslate(region, -crtc->x, -crtc->y);
|
||||
+ dirty->slave_dst = drmmode_crtc->scanout[scanout_id].pixmap;
|
||||
+ }
|
||||
+
|
||||
redisplay_dirty(dirty, region);
|
||||
+ ret = TRUE;
|
||||
+ destroy:
|
||||
RegionDestroy(region);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
|
||||
+ void *event_data)
|
||||
+{
|
||||
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
+
|
||||
+ radeon_prime_scanout_do_update(crtc, 0);
|
||||
drmmode_crtc->scanout_update_pending = FALSE;
|
||||
}
|
||||
|
||||
@@ -679,8 +704,74 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
|
||||
}
|
||||
|
||||
static void
|
||||
+radeon_prime_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data)
|
||||
+{
|
||||
+ drmmode_crtc_private_ptr drmmode_crtc = event_data;
|
||||
+
|
||||
+ drmmode_crtc->scanout_update_pending = FALSE;
|
||||
+ drmmode_clear_pending_flip(crtc);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent)
|
||||
+{
|
||||
+ ScreenPtr screen = ent->slave_dst->drawable.pScreen;
|
||||
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
|
||||
+ xf86CrtcPtr crtc = NULL;
|
||||
+ drmmode_crtc_private_ptr drmmode_crtc = NULL;
|
||||
+ uintptr_t drm_queue_seq;
|
||||
+ unsigned scanout_id;
|
||||
+ int c;
|
||||
+
|
||||
+ /* Find the CRTC which is scanning out from this slave pixmap */
|
||||
+ for (c = 0; c < xf86_config->num_crtc; c++) {
|
||||
+ crtc = xf86_config->crtc[c];
|
||||
+ drmmode_crtc = crtc->driver_private;
|
||||
+ scanout_id = drmmode_crtc->scanout_id;
|
||||
+ if (drmmode_crtc->scanout[scanout_id].pixmap == ent->slave_dst)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (c == xf86_config->num_crtc ||
|
||||
+ !crtc->enabled ||
|
||||
+ drmmode_crtc->scanout_update_pending ||
|
||||
+ !drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap ||
|
||||
+ drmmode_crtc->pending_dpms_mode != DPMSModeOn)
|
||||
+ return;
|
||||
+
|
||||
+ scanout_id = drmmode_crtc->scanout_id ^ 1;
|
||||
+ if (!radeon_prime_scanout_do_update(crtc, scanout_id))
|
||||
+ return;
|
||||
+
|
||||
+ drm_queue_seq = radeon_drm_queue_alloc(crtc,
|
||||
+ RADEON_DRM_QUEUE_CLIENT_DEFAULT,
|
||||
+ RADEON_DRM_QUEUE_ID_DEFAULT,
|
||||
+ drmmode_crtc, NULL,
|
||||
+ radeon_prime_scanout_flip_abort);
|
||||
+ if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
|
||||
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
|
||||
+ "Allocating DRM event queue entry failed for PRIME flip.\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (drmModePageFlip(drmmode_crtc->drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
|
||||
+ drmmode_crtc->scanout[scanout_id].fb_id,
|
||||
+ DRM_MODE_PAGE_FLIP_EVENT, (void*)drm_queue_seq)) {
|
||||
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n",
|
||||
+ __func__, strerror(errno));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ drmmode_crtc->scanout_id = scanout_id;
|
||||
+ drmmode_crtc->scanout_update_pending = TRUE;
|
||||
+ drmmode_crtc->flip_pending = TRUE;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
radeon_dirty_update(ScrnInfoPtr scrn)
|
||||
{
|
||||
+ RADEONInfoPtr info = RADEONPTR(scrn);
|
||||
ScreenPtr screen = scrn->pScreen;
|
||||
PixmapDirtyUpdatePtr ent;
|
||||
RegionPtr region;
|
||||
@@ -700,10 +791,14 @@ radeon_dirty_update(ScrnInfoPtr scrn)
|
||||
|
||||
region = dirty_region(region_ent);
|
||||
|
||||
- if (RegionNotEmpty(region))
|
||||
- radeon_prime_scanout_update(ent);
|
||||
- else
|
||||
+ if (RegionNotEmpty(region)) {
|
||||
+ if (info->tear_free)
|
||||
+ radeon_prime_scanout_flip(ent);
|
||||
+ else
|
||||
+ radeon_prime_scanout_update(ent);
|
||||
+ } else {
|
||||
DamageEmpty(region_ent->damage);
|
||||
+ }
|
||||
|
||||
RegionDestroy(region);
|
||||
} else {
|
@ -1,3 +1,14 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Oct 14 15:12:36 UTC 2016 - mstaudt@suse.com
|
||||
|
||||
- U_01-* ... U_20-* :
|
||||
Include patches that haven't made it into the 7.7.1 release.
|
||||
|
||||
This means almost all commits between xf86-video-ati-7.7.0
|
||||
and 12d30eeb9711bd2b1609d6bbb74c4a1760596f72.
|
||||
|
||||
Fixes (bsc#990066).
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Sep 19 13:32:04 UTC 2016 - tobias.johannes.klausmann@mni.thm.de
|
||||
|
||||
|
@ -28,6 +28,26 @@ Url: http://xorg.freedesktop.org/
|
||||
Source0: http://xorg.freedesktop.org/releases/individual/driver/%{name}-%{version}.tar.bz2
|
||||
Source1: http://xorg.freedesktop.org/releases/individual/driver/%{name}-%{version}.tar.bz2.sig
|
||||
Source2: %{name}.keyring
|
||||
Patch1: U_01-dri3-Return-NULL-from-radeon_dri3_pixmap_from_fd-if-calloc-fails.patch
|
||||
Patch2: U_02-Add-support-for-async-flips-to-radeon_do_pageflip.patch
|
||||
Patch3: U_03-present-Support-async-flips.patch
|
||||
Patch4: U_04-Enable-DRI3-by-default-when-building-for-Xorg-1.18.3.patch
|
||||
Patch5: U_05-EXA-6xx-7xx-fast-solid-pixmap-support.patch
|
||||
Patch6: U_06-EXA-6xx-7xx-accelerate-PictOpOver-with-component-alpha.patch
|
||||
Patch7: U_07-Adapt-to-XF86_CRTC_VERSION-7.patch
|
||||
Patch8: U_08-Add-explicit-RADEON_DRM_QUEUE_ERROR-define.patch
|
||||
Patch9: U_09-Don-t-enable-DRI3-by-default-with-EXA.patch
|
||||
Patch10: U_10-Use-EventCallback-to-avoid-flushing-every-time-in-the-FlushCallback.patch
|
||||
Patch11: U_11-Keep-track-of-damage-event-related-flushes-per-client-v2.patch
|
||||
Patch12: U_12-Use-drmmode_crtc_scanout_-helpers-for-RandR-1.4-scanout-pixmaps.patch
|
||||
Patch13: U_13-Handle-RandR-1.4-slave-dirty-updates-via-radeon_drm_queue.patch
|
||||
Patch14: U_14-Track-damage-accurately-for-RandR-1.4-slave-scanout.patch
|
||||
Patch15: U_15-Fix-build-against-xserver-1.13.patch
|
||||
Patch16: U_16-Only-copy-from-screen-pixmap-to-shared-pixmap-on-demand-for-slave-scanout.patch
|
||||
Patch17: U_17-Factor-out-transform_region-helper.patch
|
||||
Patch18: U_18-Move-up-radeon_scanout_extents_intersect.patch
|
||||
Patch19: U_19-Synchronize-scanout-pixmaps-for-TearFree.patch
|
||||
Patch20: U_20-Make-TearFree-effective-with-PRIME-slave-scanout.patch
|
||||
|
||||
BuildRequires: Mesa-devel
|
||||
BuildRequires: autoconf >= 2.60
|
||||
@ -69,6 +89,26 @@ driver as appropriate.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch13 -p1
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
%patch18 -p1
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
|
||||
%build
|
||||
autoreconf -fiv
|
||||
|
Loading…
x
Reference in New Issue
Block a user