- 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
131 lines
4.5 KiB
Diff
131 lines
4.5 KiB
Diff
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)
|
|
{
|