summaryrefslogtreecommitdiff
path: root/extra/xf86-video-ati
diff options
context:
space:
mode:
authorroot <root@rshg054.dnsready.net>2012-05-14 00:02:14 +0000
committerroot <root@rshg054.dnsready.net>2012-05-14 00:02:14 +0000
commitd3af8dc0117dc1ce4fea3d05c7a2d7786bd78986 (patch)
tree31feb3c3623dd48f13ce1cdbdf10d870ea5b5678 /extra/xf86-video-ati
parente8aea505d7f36277edd02ef965bc3f8e1c81ee5d (diff)
Mon May 14 00:02:13 UTC 2012
Diffstat (limited to 'extra/xf86-video-ati')
-rw-r--r--extra/xf86-video-ati/0000-poor-man-s-solid-picture-support-for-r300-r600.patch571
-rw-r--r--extra/xf86-video-ati/0001-poor-man-s-solid-picture-support-for-evergreen.patch290
-rw-r--r--extra/xf86-video-ati/0002-poor-man-s-solid-picture-support-for-r100.patch182
-rw-r--r--extra/xf86-video-ati/0003-poor-man-s-solid-picture-support-for-r200.patch179
-rw-r--r--extra/xf86-video-ati/PKGBUILD27
-rw-r--r--extra/xf86-video-ati/git_fixes.diff33
6 files changed, 1278 insertions, 4 deletions
diff --git a/extra/xf86-video-ati/0000-poor-man-s-solid-picture-support-for-r300-r600.patch b/extra/xf86-video-ati/0000-poor-man-s-solid-picture-support-for-r300-r600.patch
new file mode 100644
index 000000000..bcfbf94db
--- /dev/null
+++ b/extra/xf86-video-ati/0000-poor-man-s-solid-picture-support-for-r300-r600.patch
@@ -0,0 +1,571 @@
+From 837149c63929d7d5a8ef6f8204d396f8e6d5acd7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel@daenzer.net>
+Date: Fri, 13 Apr 2012 11:12:51 +0200
+Subject: [PATCH 1/4] Poor man's acceleration of solid pictures for R3xx-R7xx
+
+The patch below implements basic acceleration of solid pictures via
+scratch 1x1 pixmaps. It seems to at least alleviate some of the
+corruption and performance issues exposed by Cairo 1.12, and should also
+improve performance for other toolkits/apps using solid pictures.
+
+If there are no objections to this approach, maybe someone else can beat
+me to extending this for Evergreen+ and R1/2xx.
+---
+ src/r600_exa.c | 160 ++++++++++++++++++++++++++--------------------
+ src/radeon_exa_render.c | 115 ++++++++++++++++++++--------------
+ src/radeon_exa_shared.c | 19 ++++++
+ src/radeon_exa_shared.h | 1 +
+ 4 files changed, 179 insertions(+), 116 deletions(-)
+
+diff --git a/src/r600_exa.c b/src/r600_exa.c
+index e1eb62f..c3ae553 100644
+--- a/src/r600_exa.c
++++ b/src/r600_exa.c
+@@ -901,17 +901,8 @@ static Bool R600CheckCompositeTexture(PicturePtr pPict,
+ int op,
+ int unit)
+ {
+- int w = pPict->pDrawable->width;
+- int h = pPict->pDrawable->height;
+ unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
+ unsigned int i;
+- int max_tex_w, max_tex_h;
+-
+- max_tex_w = 8192;
+- max_tex_h = 8192;
+-
+- if ((w > max_tex_w) || (h > max_tex_h))
+- RADEON_FALLBACK(("Picture w/h too large (%dx%d)\n", w, h));
+
+ for (i = 0; i < sizeof(R600TexFormats) / sizeof(R600TexFormats[0]); i++) {
+ if (R600TexFormats[i].fmt == pPict->format)
+@@ -951,9 +942,7 @@ static Bool R600TextureSetup(PicturePtr pPict, PixmapPtr pPix,
+ ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+- int w = pPict->pDrawable->width;
+- int h = pPict->pDrawable->height;
+- unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
++ unsigned int repeatType;
+ unsigned int i;
+ tex_resource_t tex_res;
+ tex_sampler_t tex_samp;
+@@ -969,9 +958,16 @@ static Bool R600TextureSetup(PicturePtr pPict, PixmapPtr pPix,
+ }
+
+ /* Texture */
++ if (pPict->pDrawable) {
++ tex_res.w = pPict->pDrawable->width;
++ tex_res.h = pPict->pDrawable->height;
++ repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
++ } else {
++ tex_res.w = 1;
++ tex_res.h = 1;
++ repeatType = RepeatNormal;
++ }
+ tex_res.id = unit;
+- tex_res.w = w;
+- tex_res.h = h;
+ tex_res.pitch = accel_state->src_obj[unit].pitch;
+ tex_res.depth = 0;
+ tex_res.dim = SQ_TEX_DIM_2D;
+@@ -1170,24 +1166,24 @@ static Bool R600TextureSetup(PicturePtr pPict, PixmapPtr pPix,
+ vs_alu_consts[0] = xFixedToFloat(pPict->transform->matrix[0][0]);
+ vs_alu_consts[1] = xFixedToFloat(pPict->transform->matrix[0][1]);
+ vs_alu_consts[2] = xFixedToFloat(pPict->transform->matrix[0][2]);
+- vs_alu_consts[3] = 1.0 / w;
++ vs_alu_consts[3] = 1.0 / tex_res.w;
+
+ vs_alu_consts[4] = xFixedToFloat(pPict->transform->matrix[1][0]);
+ vs_alu_consts[5] = xFixedToFloat(pPict->transform->matrix[1][1]);
+ vs_alu_consts[6] = xFixedToFloat(pPict->transform->matrix[1][2]);
+- vs_alu_consts[7] = 1.0 / h;
++ vs_alu_consts[7] = 1.0 / tex_res.h;
+ } else {
+ accel_state->is_transform[unit] = FALSE;
+
+ vs_alu_consts[0] = 1.0;
+ vs_alu_consts[1] = 0.0;
+ vs_alu_consts[2] = 0.0;
+- vs_alu_consts[3] = 1.0 / w;
++ vs_alu_consts[3] = 1.0 / tex_res.w;
+
+ vs_alu_consts[4] = 0.0;
+ vs_alu_consts[5] = 1.0;
+ vs_alu_consts[6] = 0.0;
+- vs_alu_consts[7] = 1.0 / h;
++ vs_alu_consts[7] = 1.0 / tex_res.h;
+ }
+
+ /* VS alu constants */
+@@ -1202,33 +1198,30 @@ static Bool R600CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP
+ {
+ uint32_t tmp1;
+ PixmapPtr pSrcPixmap, pDstPixmap;
+- int max_tex_w, max_tex_h, max_dst_w, max_dst_h;
+
+ /* Check for unsupported compositing operations. */
+ if (op >= (int) (sizeof(R600BlendOp) / sizeof(R600BlendOp[0])))
+ RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op));
+
+- if (!pSrcPicture->pDrawable)
+- RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n"));
+-
+- pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
++ if (pSrcPicture->pDrawable) {
++ pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
+
+- max_tex_w = 8192;
+- max_tex_h = 8192;
+- max_dst_w = 8192;
+- max_dst_h = 8192;
++ if (pSrcPixmap->drawable.width >= 8192 ||
++ pSrcPixmap->drawable.height >= 8192) {
++ RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
++ pSrcPixmap->drawable.width,
++ pSrcPixmap->drawable.height));
++ }
+
+- if (pSrcPixmap->drawable.width >= max_tex_w ||
+- pSrcPixmap->drawable.height >= max_tex_h) {
+- RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
+- pSrcPixmap->drawable.width,
+- pSrcPixmap->drawable.height));
+- }
++ if (!R600CheckCompositeTexture(pSrcPicture, pDstPicture, op, 0))
++ return FALSE;
++ } else if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill)
++ RADEON_FALLBACK(("Gradient pictures not supported yet\n"));
+
+ pDstPixmap = RADEONGetDrawablePixmap(pDstPicture->pDrawable);
+
+- if (pDstPixmap->drawable.width >= max_dst_w ||
+- pDstPixmap->drawable.height >= max_dst_h) {
++ if (pDstPixmap->drawable.width >= 8192 ||
++ pDstPixmap->drawable.height >= 8192) {
+ RADEON_FALLBACK(("Dest w/h too large (%d,%d).\n",
+ pDstPixmap->drawable.width,
+ pDstPixmap->drawable.height));
+@@ -1237,38 +1230,35 @@ static Bool R600CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP
+ if (pMaskPicture) {
+ PixmapPtr pMaskPixmap;
+
+- if (!pMaskPicture->pDrawable)
+- RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n"));
++ if (pMaskPicture->pDrawable) {
++ pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
+
+- pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
+-
+- if (pMaskPixmap->drawable.width >= max_tex_w ||
+- pMaskPixmap->drawable.height >= max_tex_h) {
+- RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
+- pMaskPixmap->drawable.width,
+- pMaskPixmap->drawable.height));
+- }
++ if (pMaskPixmap->drawable.width >= 8192 ||
++ pMaskPixmap->drawable.height >= 8192) {
++ RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
++ pMaskPixmap->drawable.width,
++ pMaskPixmap->drawable.height));
++ }
+
+- if (pMaskPicture->componentAlpha) {
+- /* 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.
+- */
+- 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 (pMaskPicture->componentAlpha) {
++ /* 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.
++ */
++ 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 (!R600CheckCompositeTexture(pMaskPicture, pDstPicture, op, 1))
+- return FALSE;
++ if (!R600CheckCompositeTexture(pMaskPicture, pDstPicture, op, 1))
++ return FALSE;
++ } else if (pMaskPicture->pSourcePict->type != SourcePictTypeSolidFill)
++ RADEON_FALLBACK(("Gradient pictures not supported yet\n"));
+ }
+
+- if (!R600CheckCompositeTexture(pSrcPicture, pDstPicture, op, 0))
+- return FALSE;
+-
+ if (!R600GetDestFormat(pDstPicture, &tmp1))
+ return FALSE;
+
+@@ -1280,7 +1270,8 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture, PicturePtr pDstPicture,
+ PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
+ {
+- ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
++ ScreenPtr pScreen = pDst->drawable.pScreen;
++ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+ uint32_t dst_format;
+@@ -1288,15 +1279,21 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
+ shader_config_t vs_conf, ps_conf;
+ struct r600_accel_object src_obj, mask_obj, dst_obj;
+
+- if (pDst->drawable.bitsPerPixel < 8 || pSrc->drawable.bitsPerPixel < 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 defined(XF86DRM_MODE)
+ if (info->cs) {
+ src_obj.offset = 0;
+ dst_obj.offset = 0;
+- src_obj.bo = radeon_get_pixmap_bo(pSrc);
+ 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);
+@@ -1322,7 +1319,16 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
+ dst_obj.bpp = pDst->drawable.bitsPerPixel;
+ dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
+
+- if (pMask) {
++ 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 defined(XF86DRM_MODE)
+ if (info->cs) {
+ mask_obj.offset = 0;
+@@ -1509,11 +1515,9 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
+ return TRUE;
+ }
+
+-static void R600DoneComposite(PixmapPtr pDst)
++static void R600FinishComposite(ScrnInfoPtr pScrn, PixmapPtr pDst,
++ struct radeon_accel_state *accel_state)
+ {
+- ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+- RADEONInfoPtr info = RADEONPTR(pScrn);
+- struct radeon_accel_state *accel_state = info->accel_state;
+ int vtx_size;
+
+ if (accel_state->vsync)
+@@ -1527,6 +1531,22 @@ static void R600DoneComposite(PixmapPtr pDst)
+ r600_finish_op(pScrn, vtx_size);
+ }
+
++static void R600DoneComposite(PixmapPtr pDst)
++{
++ ScreenPtr pScreen = pDst->drawable.pScreen;
++ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
++ RADEONInfoPtr info = RADEONPTR(pScrn);
++ 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,
+ int srcX, int srcY,
+ int maskX, int maskY,
+@@ -1543,7 +1563,7 @@ static void R600Composite(PixmapPtr pDst,
+
+ #ifdef XF86DRM_MODE
+ if (info->cs && CS_FULL(info->cs)) {
+- R600DoneComposite(info->accel_state->dst_pix);
++ R600FinishComposite(pScrn, pDst, info->accel_state);
+ radeon_cs_flush_indirect(pScrn);
+ R600PrepareComposite(info->accel_state->composite_op,
+ info->accel_state->src_pic,
+diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
+index e5c231f..b6cc9e4 100644
+--- a/src/radeon_exa_render.c
++++ b/src/radeon_exa_render.c
+@@ -299,8 +299,8 @@ static Bool RADEONSetupSourceTile(PicturePtr pPict,
+ if (repeatType == RepeatNormal || repeatType == RepeatReflect) {
+ Bool badPitch = needMatchingPitch && !RADEONPitchMatches(pPix);
+
+- int w = pPict->pDrawable->width;
+- int h = pPict->pDrawable->height;
++ int w = pPict->pDrawable ? pPict->pDrawable->width : 1;
++ int h = pPict->pDrawable ? pPict->pDrawable->height : 1;
+
+ if (pPict->transform) {
+ if (badPitch)
+@@ -1112,23 +1112,8 @@ static Bool R300CheckCompositeTexture(PicturePtr pPict,
+ ScreenPtr pScreen = pDstPict->pDrawable->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+-
+ unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
+- int w = pPict->pDrawable->width;
+- int h = pPict->pDrawable->height;
+ int i;
+- int max_tex_w, max_tex_h;
+-
+- if (is_r500) {
+- max_tex_w = 4096;
+- max_tex_h = 4096;
+- } else {
+- max_tex_w = 2048;
+- max_tex_h = 2048;
+- }
+-
+- if ((w > max_tex_w) || (h > max_tex_h))
+- RADEON_FALLBACK(("Picture w/h too large (%dx%d)\n", w, h));
+
+ for (i = 0; i < sizeof(R300TexFormats) / sizeof(R300TexFormats[0]); i++)
+ {
+@@ -1139,7 +1124,7 @@ static Bool R300CheckCompositeTexture(PicturePtr pPict,
+ RADEON_FALLBACK(("Unsupported picture format 0x%x\n",
+ (int)pPict->format));
+
+- if (!RADEONCheckTexturePOT(pPict, unit == 0)) {
++ if (pPict->pDrawable && !RADEONCheckTexturePOT(pPict, unit == 0)) {
+ if (info->cs) {
+ struct radeon_exa_pixmap_priv *driver_priv;
+ PixmapPtr pPix;
+@@ -1181,15 +1166,23 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
+ {
+ RINFO_FROM_SCREEN(pPix->drawable.pScreen);
+ uint32_t txfilter, txformat0, txformat1, txoffset, txpitch, us_format = 0;
+- int w = pPict->pDrawable->width;
+- int h = pPict->pDrawable->height;
++ int w, h;
+ int i, pixel_shift, out_size = 6;
+- unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
++ unsigned int repeatType;
+ struct radeon_exa_pixmap_priv *driver_priv;
+ ACCEL_PREAMBLE();
+
+ TRACE;
+
++ if (pPict->pDrawable) {
++ w = pPict->pDrawable->width;
++ h = pPict->pDrawable->height;
++ repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
++ } else {
++ w = h = 1;
++ repeatType = RepeatNormal;
++ }
++
+ txpitch = exaGetPixmapPitch(pPix);
+ txoffset = 0;
+
+@@ -1394,11 +1387,6 @@ static Bool R300CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP
+ if (op >= sizeof(RadeonBlendOp) / sizeof(RadeonBlendOp[0]))
+ RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op));
+
+- if (!pSrcPicture->pDrawable)
+- RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n"));
+-
+- pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
+-
+ if (IS_R500_3D) {
+ max_tex_w = 4096;
+ max_tex_h = 4096;
+@@ -1416,13 +1404,6 @@ static Bool R300CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP
+ }
+ }
+
+- if (pSrcPixmap->drawable.width > max_tex_w ||
+- pSrcPixmap->drawable.height > max_tex_h) {
+- RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
+- pSrcPixmap->drawable.width,
+- pSrcPixmap->drawable.height));
+- }
+-
+ pDstPixmap = RADEONGetDrawablePixmap(pDstPicture->pDrawable);
+
+ if (pDstPixmap->drawable.width > max_dst_w ||
+@@ -1432,20 +1413,32 @@ static Bool R300CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP
+ pDstPixmap->drawable.height));
+ }
+
++ if (pSrcPicture->pDrawable) {
++ pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
++
++ if (pSrcPixmap->drawable.width > max_tex_w ||
++ pSrcPixmap->drawable.height > max_tex_h) {
++ RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
++ pSrcPixmap->drawable.width,
++ pSrcPixmap->drawable.height));
++ }
++ } else if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill)
++ RADEON_FALLBACK(("Gradient pictures not supported yet\n"));
++
+ if (pMaskPicture) {
+ PixmapPtr pMaskPixmap;
+
+- if (!pMaskPicture->pDrawable)
+- RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n"));
++ if (pMaskPicture->pDrawable) {
++ pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
+
+- pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
+-
+- if (pMaskPixmap->drawable.width > max_tex_w ||
+- pMaskPixmap->drawable.height > max_tex_h) {
+- RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
+- pMaskPixmap->drawable.width,
+- pMaskPixmap->drawable.height));
+- }
++ if (pMaskPixmap->drawable.width > max_tex_w ||
++ pMaskPixmap->drawable.height > max_tex_h) {
++ RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
++ pMaskPixmap->drawable.width,
++ pMaskPixmap->drawable.height));
++ }
++ } else if (pMaskPicture->pSourcePict->type != SourcePictTypeSolidFill)
++ RADEON_FALLBACK(("Gradient pictures not supported yet\n"));
+
+ if (pMaskPicture->componentAlpha) {
+ /* Check if it's component alpha that relies on a source alpha and
+@@ -1479,7 +1472,8 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture, PicturePtr pDstPicture,
+ PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
+ {
+- RINFO_FROM_SCREEN(pDst->drawable.pScreen);
++ ScreenPtr pScreen = pDst->drawable.pScreen;
++ RINFO_FROM_SCREEN(pScreen);
+ uint32_t dst_format, dst_pitch;
+ uint32_t txenable, colorpitch;
+ uint32_t blendcntl, output_fmt;
+@@ -1508,9 +1502,24 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
+ if (((dst_pitch >> pixel_shift) & 0x7) != 0)
+ RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch));
+
++ if (!pSrc) {
++ pSrc = RADEONSolidPixmap(pScreen, cpu_to_le32(pSrcPicture->pSourcePict->solidFill.color));
++ if (!pSrc)
++ RADEON_FALLBACK("Failed to create solid scratch pixmap\n");
++ }
++
+ if (!RADEONSetupSourceTile(pSrcPicture, pSrc, TRUE, FALSE))
+ return FALSE;
+
++ if (pMaskPicture && !pMask) {
++ pMask = RADEONSolidPixmap(pScreen, cpu_to_le32(pMaskPicture->pSourcePict->solidFill.color));
++ if (!pMask) {
++ if (!pSrcPicture->pDrawable)
++ pScreen->DestroyPixmap(pSrc);
++ RADEON_FALLBACK("Failed to create solid scratch pixmap\n");
++ }
++ }
++
+ RADEONPrepareCompositeCS(op, pSrcPicture, pMaskPicture, pDstPicture,
+ pSrc, pMask, pDst);
+
+@@ -2132,7 +2141,7 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
+ return TRUE;
+ }
+
+-static void FUNC_NAME(RadeonDoneComposite)(PixmapPtr pDst)
++static void FUNC_NAME(RadeonFinishComposite)(PixmapPtr pDst)
+ {
+ RINFO_FROM_SCREEN(pDst->drawable.pScreen);
+ ACCEL_PREAMBLE();
+@@ -2179,6 +2188,20 @@ static void FUNC_NAME(RadeonDoneComposite)(PixmapPtr pDst)
+ LEAVE_DRAW(0);
+ }
+
++static void FUNC_NAME(RadeonDoneComposite)(PixmapPtr pDst)
++{
++ ScreenPtr pScreen = pDst->drawable.pScreen;
++ RINFO_FROM_SCREEN(pScreen);
++ struct radeon_accel_state *accel_state = info->accel_state;
++
++ FUNC_NAME(RadeonFinishComposite)(pDst);
++
++ 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);
++}
+
+ #ifdef ACCEL_CP
+
+@@ -2257,7 +2280,7 @@ static void FUNC_NAME(RadeonCompositeTile)(ScrnInfoPtr pScrn,
+ if ((info->cs && CS_FULL(info->cs)) ||
+ (!info->cs && (info->cp->indirectBuffer->used + 4 * 32) >
+ info->cp->indirectBuffer->total)) {
+- FUNC_NAME(RadeonDoneComposite)(info->accel_state->dst_pix);
++ FUNC_NAME(RadeonFinishComposite)(info->accel_state->dst_pix);
+ if (info->cs)
+ radeon_cs_flush_indirect(pScrn);
+ else
+diff --git a/src/radeon_exa_shared.c b/src/radeon_exa_shared.c
+index be1d2fa..28dc335 100644
+--- a/src/radeon_exa_shared.c
++++ b/src/radeon_exa_shared.c
+@@ -126,6 +126,25 @@ Bool RADEONCheckBPP(int bpp)
+ return FALSE;
+ }
+
++PixmapPtr RADEONSolidPixmap(ScreenPtr pScreen, uint32_t solid)
++{
++ PixmapPtr pPix = pScreen->CreatePixmap(pScreen, 1, 1, 32, 0);
++ struct radeon_bo *bo;
++
++ exaMoveInPixmap(pPix);
++ bo = radeon_get_pixmap_bo(pPix);
++
++ if (radeon_bo_map(bo, 1)) {
++ pScreen->DestroyPixmap(pPix);
++ return NULL;
++ }
++
++ memcpy(bo->ptr, &solid, 4);
++ radeon_bo_unmap(bo);
++
++ return pPix;
++}
++
+ static Bool radeon_vb_get(ScrnInfoPtr pScrn)
+ {
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+diff --git a/src/radeon_exa_shared.h b/src/radeon_exa_shared.h
+index 7b8b5ca..60a1045 100644
+--- a/src/radeon_exa_shared.h
++++ b/src/radeon_exa_shared.h
+@@ -40,6 +40,7 @@ extern void RADEONVlineHelperClear(ScrnInfoPtr pScrn);
+ extern void RADEONVlineHelperSet(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2);
+ extern Bool RADEONValidPM(uint32_t pm, int bpp);
+ extern Bool RADEONCheckBPP(int bpp);
++extern PixmapPtr RADEONSolidPixmap(ScreenPtr pScreen, uint32_t solid);
+
+ #define RADEON_TRACE_FALL 0
+ #define RADEON_TRACE_DRAW 0
+--
+1.7.7.5
+
diff --git a/extra/xf86-video-ati/0001-poor-man-s-solid-picture-support-for-evergreen.patch b/extra/xf86-video-ati/0001-poor-man-s-solid-picture-support-for-evergreen.patch
new file mode 100644
index 000000000..e6b5433e1
--- /dev/null
+++ b/extra/xf86-video-ati/0001-poor-man-s-solid-picture-support-for-evergreen.patch
@@ -0,0 +1,290 @@
+From 761ef4b340e689490a76ec5ce520c858335e2106 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Sat, 14 Apr 2012 08:53:39 -0400
+Subject: [PATCH] poor man's solid picture support for evergreen
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/evergreen_exa.c | 163 ++++++++++++++++++++++++++++++---------------------
+ 1 files changed, 95 insertions(+), 68 deletions(-)
+
+diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c
+index cee3ec2..61b47a4 100644
+--- a/src/evergreen_exa.c
++++ b/src/evergreen_exa.c
+@@ -748,17 +748,8 @@ static Bool EVERGREENCheckCompositeTexture(PicturePtr pPict,
+ int op,
+ int unit)
+ {
+- int w = pPict->pDrawable->width;
+- int h = pPict->pDrawable->height;
+ unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
+ unsigned int i;
+- int max_tex_w, max_tex_h;
+-
+- max_tex_w = 16384;
+- max_tex_h = 16384;
+-
+- if ((w > max_tex_w) || (h > max_tex_h))
+- RADEON_FALLBACK(("Picture w/h too large (%dx%d)\n", w, h));
+
+ for (i = 0; i < sizeof(EVERGREENTexFormats) / sizeof(EVERGREENTexFormats[0]); i++) {
+ if (EVERGREENTexFormats[i].fmt == pPict->format)
+@@ -798,9 +789,16 @@ static void EVERGREENXFormSetup(PicturePtr pPict, PixmapPtr pPix,
+ ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+- int w = pPict->pDrawable->width;
+- int h = pPict->pDrawable->height;
+ int const_offset = unit * 8;
++ int w, h;
++
++ if (pPict->pDrawable) {
++ w = pPict->pDrawable->width;
++ h = pPict->pDrawable->height;
++ } else {
++ w = 1;
++ h = 1;
++ }
+
+ if (pPict->transform != 0) {
+ accel_state->is_transform[unit] = TRUE;
+@@ -837,9 +835,7 @@ static Bool EVERGREENTextureSetup(PicturePtr pPict, PixmapPtr pPix,
+ ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+- int w = pPict->pDrawable->width;
+- int h = pPict->pDrawable->height;
+- unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
++ unsigned int repeatType;
+ unsigned int i;
+ tex_resource_t tex_res;
+ tex_sampler_t tex_samp;
+@@ -854,9 +850,17 @@ static Bool EVERGREENTextureSetup(PicturePtr pPict, PixmapPtr pPix,
+ }
+
+ /* Texture */
++ if (pPict->pDrawable) {
++ tex_res.w = pPict->pDrawable->width;
++ tex_res.h = pPict->pDrawable->height;
++ repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
++ } else {
++ tex_res.w = 1;
++ tex_res.h = 1;
++ repeatType = RepeatNormal;
++ }
++
+ tex_res.id = unit;
+- tex_res.w = w;
+- tex_res.h = h;
+ tex_res.pitch = accel_state->src_obj[unit].pitch;
+ tex_res.depth = 0;
+ tex_res.dim = SQ_TEX_DIM_2D;
+@@ -1054,33 +1058,30 @@ static Bool EVERGREENCheckComposite(int op, PicturePtr pSrcPicture,
+ {
+ uint32_t tmp1;
+ PixmapPtr pSrcPixmap, pDstPixmap;
+- int max_tex_w, max_tex_h, max_dst_w, max_dst_h;
+
+ /* Check for unsupported compositing operations. */
+ if (op >= (int) (sizeof(EVERGREENBlendOp) / sizeof(EVERGREENBlendOp[0])))
+ RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op));
+
+- if (!pSrcPicture->pDrawable)
+- RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n"));
++ if (pSrcPicture->pDrawable) {
++ pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
+
+- pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
+-
+- max_tex_w = 8192;
+- max_tex_h = 8192;
+- max_dst_w = 8192;
+- max_dst_h = 8192;
++ if (pSrcPixmap->drawable.width >= 16384 ||
++ pSrcPixmap->drawable.height >= 16384) {
++ RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
++ pSrcPixmap->drawable.width,
++ pSrcPixmap->drawable.height));
++ }
+
+- if (pSrcPixmap->drawable.width >= max_tex_w ||
+- pSrcPixmap->drawable.height >= max_tex_h) {
+- RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
+- pSrcPixmap->drawable.width,
+- pSrcPixmap->drawable.height));
+- }
++ if (!EVERGREENCheckCompositeTexture(pSrcPicture, pDstPicture, op, 0))
++ return FALSE;
++ } else if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill)
++ RADEON_FALLBACK(("Gradient pictures not supported yet\n"));
+
+ pDstPixmap = RADEONGetDrawablePixmap(pDstPicture->pDrawable);
+
+- if (pDstPixmap->drawable.width >= max_dst_w ||
+- pDstPixmap->drawable.height >= max_dst_h) {
++ if (pDstPixmap->drawable.width >= 16384 ||
++ pDstPixmap->drawable.height >= 16384) {
+ RADEON_FALLBACK(("Dest w/h too large (%d,%d).\n",
+ pDstPixmap->drawable.width,
+ pDstPixmap->drawable.height));
+@@ -1089,38 +1090,35 @@ static Bool EVERGREENCheckComposite(int op, PicturePtr pSrcPicture,
+ if (pMaskPicture) {
+ PixmapPtr pMaskPixmap;
+
+- if (!pMaskPicture->pDrawable)
+- RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n"));
+-
+- pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
++ if (pMaskPicture->pDrawable) {
++ pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
+
+- if (pMaskPixmap->drawable.width >= max_tex_w ||
+- pMaskPixmap->drawable.height >= max_tex_h) {
+- RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
+- pMaskPixmap->drawable.width,
+- pMaskPixmap->drawable.height));
+- }
++ if (pMaskPixmap->drawable.width >= 16384 ||
++ pMaskPixmap->drawable.height >= 16384) {
++ RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
++ pMaskPixmap->drawable.width,
++ pMaskPixmap->drawable.height));
++ }
+
+- if (pMaskPicture->componentAlpha) {
+- /* 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.
+- */
+- if (EVERGREENBlendOp[op].src_alpha &&
+- (EVERGREENBlendOp[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 (pMaskPicture->componentAlpha) {
++ /* 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.
++ */
++ if (EVERGREENBlendOp[op].src_alpha &&
++ (EVERGREENBlendOp[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 (!EVERGREENCheckCompositeTexture(pMaskPicture, pDstPicture, op, 1))
+- return FALSE;
++ if (!EVERGREENCheckCompositeTexture(pMaskPicture, pDstPicture, op, 1))
++ return FALSE;
++ } else if (pMaskPicture->pSourcePict->type != SourcePictTypeSolidFill)
++ RADEON_FALLBACK(("Gradient pictures not supported yet\n"));
+ }
+
+- if (!EVERGREENCheckCompositeTexture(pSrcPicture, pDstPicture, op, 0))
+- return FALSE;
+-
+ if (!EVERGREENGetDestFormat(pDstPicture, &tmp1))
+ return FALSE;
+
+@@ -1132,7 +1130,8 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture, PicturePtr pDstPicture,
+ PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
+ {
+- ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
++ ScreenPtr pScreen = pDst->drawable.pScreen;
++ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+ uint32_t dst_format;
+@@ -1142,13 +1141,19 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture,
+ struct r600_accel_object src_obj, mask_obj, dst_obj;
+ float *cbuf;
+
+- if (pDst->drawable.bitsPerPixel < 8 || pSrc->drawable.bitsPerPixel < 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");
++ }
++
+ src_obj.offset = 0;
+ dst_obj.offset = 0;
+- src_obj.bo = radeon_get_pixmap_bo(pSrc);
+ dst_obj.bo = radeon_get_pixmap_bo(pDst);
++ src_obj.bo = radeon_get_pixmap_bo(pSrc);
+ dst_obj.surface = radeon_get_pixmap_surface(pDst);
+ src_obj.surface = radeon_get_pixmap_surface(pSrc);
+ dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst);
+@@ -1166,7 +1171,15 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture,
+ dst_obj.bpp = pDst->drawable.bitsPerPixel;
+ dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
+
+- if (pMask) {
++ 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");
++ }
++ }
+ mask_obj.offset = 0;
+ mask_obj.bo = radeon_get_pixmap_bo(pMask);
+ mask_obj.tiling_flags = radeon_get_pixmap_tiling(pMask);
+@@ -1363,11 +1376,9 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture,
+ return TRUE;
+ }
+
+-static void EVERGREENDoneComposite(PixmapPtr pDst)
++static void EVERGREENFinishComposite(ScrnInfoPtr pScrn, PixmapPtr pDst,
++ struct radeon_accel_state *accel_state)
+ {
+- ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+- RADEONInfoPtr info = RADEONPTR(pScrn);
+- struct radeon_accel_state *accel_state = info->accel_state;
+ int vtx_size;
+
+ if (accel_state->vsync)
+@@ -1381,6 +1392,22 @@ static void EVERGREENDoneComposite(PixmapPtr pDst)
+ evergreen_finish_op(pScrn, vtx_size);
+ }
+
++static void EVERGREENDoneComposite(PixmapPtr pDst)
++{
++ ScreenPtr pScreen = pDst->drawable.pScreen;
++ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
++ RADEONInfoPtr info = RADEONPTR(pScrn);
++ struct radeon_accel_state *accel_state = info->accel_state;
++
++ EVERGREENFinishComposite(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 EVERGREENComposite(PixmapPtr pDst,
+ int srcX, int srcY,
+ int maskX, int maskY,
+@@ -1393,7 +1420,7 @@ static void EVERGREENComposite(PixmapPtr pDst,
+ float *vb;
+
+ if (CS_FULL(info->cs)) {
+- EVERGREENDoneComposite(info->accel_state->dst_pix);
++ EVERGREENFinishComposite(pScrn, pDst, info->accel_state);
+ radeon_cs_flush_indirect(pScrn);
+ EVERGREENPrepareComposite(info->accel_state->composite_op,
+ info->accel_state->src_pic,
+--
+1.7.7.5
+
diff --git a/extra/xf86-video-ati/0002-poor-man-s-solid-picture-support-for-r100.patch b/extra/xf86-video-ati/0002-poor-man-s-solid-picture-support-for-r100.patch
new file mode 100644
index 000000000..3a2779446
--- /dev/null
+++ b/extra/xf86-video-ati/0002-poor-man-s-solid-picture-support-for-r100.patch
@@ -0,0 +1,182 @@
+From f36b911ecc31f689ddceeeb11d10eb7cb4a3428d Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Fri, 13 Apr 2012 13:24:46 -0400
+Subject: [PATCH 2/3] poor man's solid picture support for r100
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/radeon_exa_render.c | 101 +++++++++++++++++++++++++++--------------------
+ 1 files changed, 58 insertions(+), 43 deletions(-)
+
+diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
+index b6cc9e4..451a625 100644
+--- a/src/radeon_exa_render.c
++++ b/src/radeon_exa_render.c
+@@ -338,17 +338,8 @@ static Bool R100CheckCompositeTexture(PicturePtr pPict,
+ int unit)
+ {
+ unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
+- int w = pPict->pDrawable->width;
+- int h = pPict->pDrawable->height;
+ int i;
+
+- /* r100 limit should be 2048, there are issues with 2048
+- * see 197a62704742a4a19736c2637ac92d1dc5ab34ed
+- */
+-
+- if ((w > 2047) || (h > 2047))
+- RADEON_FALLBACK(("Picture w/h too large (%dx%d)\n", w, h));
+-
+ for (i = 0; i < sizeof(R100TexFormats) / sizeof(R100TexFormats[0]); i++) {
+ if (R100TexFormats[i].fmt == pPict->format)
+ break;
+@@ -357,7 +348,7 @@ static Bool R100CheckCompositeTexture(PicturePtr pPict,
+ RADEON_FALLBACK(("Unsupported picture format 0x%x\n",
+ (int)pPict->format));
+
+- if (!RADEONCheckTexturePOT(pPict, unit == 0))
++ if (pPict->pDrawable && !RADEONCheckTexturePOT(pPict, unit == 0))
+ return FALSE;
+
+ if (pPict->filter != PictFilterNearest &&
+@@ -392,15 +383,24 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
+ {
+ RINFO_FROM_SCREEN(pPix->drawable.pScreen);
+ uint32_t txfilter, txformat, txoffset, txpitch;
+- int w = pPict->pDrawable->width;
+- int h = pPict->pDrawable->height;
+- unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
+- Bool repeat = (repeatType == RepeatNormal || repeatType == RepeatReflect) &&
+- !(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y));
+- int i;
++ unsigned int repeatType;
++ Bool repeat;
++ int i, w, h;
+ struct radeon_exa_pixmap_priv *driver_priv;
+ ACCEL_PREAMBLE();
+
++ if (pPict->pDrawable) {
++ w = pPict->pDrawable->width;
++ h = pPict->pDrawable->height;
++ repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
++ } else {
++ w = h = 1;
++ repeatType = RepeatNormal;
++ }
++
++ repeat = (repeatType == RepeatNormal || repeatType == RepeatReflect) &&
++ !(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y));
++
+ txpitch = exaGetPixmapPitch(pPix);
+ txoffset = 0;
+
+@@ -510,22 +510,6 @@ static Bool R100CheckComposite(int op, PicturePtr pSrcPicture,
+ if (op >= sizeof(RadeonBlendOp) / sizeof(RadeonBlendOp[0]))
+ RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op));
+
+- if (!pSrcPicture->pDrawable)
+- RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n"));
+-
+- /* r100 limit should be 2048, there are issues with 2048
+- * see 197a62704742a4a19736c2637ac92d1dc5ab34ed
+- */
+-
+- pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
+-
+- if (pSrcPixmap->drawable.width > 2047 ||
+- pSrcPixmap->drawable.height > 2047) {
+- RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
+- pSrcPixmap->drawable.width,
+- pSrcPixmap->drawable.height));
+- }
+-
+ pDstPixmap = RADEONGetDrawablePixmap(pDstPicture->pDrawable);
+
+ if (pDstPixmap->drawable.width > 2047 ||
+@@ -535,20 +519,35 @@ static Bool R100CheckComposite(int op, PicturePtr pSrcPicture,
+ pDstPixmap->drawable.height));
+ }
+
++ if (pSrcPicture->pDrawable) {
++ /* r100 limit should be 2048, there are issues with 2048
++ * see 197a62704742a4a19736c2637ac92d1dc5ab34ed
++ */
++ pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
++
++ if (pSrcPixmap->drawable.width > 2047 ||
++ pSrcPixmap->drawable.height > 2047) {
++ RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
++ pSrcPixmap->drawable.width,
++ pSrcPixmap->drawable.height));
++ }
++ } else if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill)
++ RADEON_FALLBACK(("Gradient pictures not supported yet\n"));
++
+ if (pMaskPicture) {
+ PixmapPtr pMaskPixmap;
+
+- if (!pMaskPicture->pDrawable)
+- RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n"));
+-
+- pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
++ if (pMaskPicture->pDrawable) {
++ pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
+
+- if (pMaskPixmap->drawable.width > 2047 ||
+- pMaskPixmap->drawable.height > 2047) {
+- RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
+- pMaskPixmap->drawable.width,
+- pMaskPixmap->drawable.height));
+- }
++ if (pMaskPixmap->drawable.width > 2047 ||
++ pMaskPixmap->drawable.height > 2047) {
++ RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
++ pMaskPixmap->drawable.width,
++ pMaskPixmap->drawable.height));
++ }
++ } else if (pMaskPicture->pSourcePict->type != SourcePictTypeSolidFill)
++ RADEON_FALLBACK(("Gradient pictures not supported yet\n"));
+
+ if (pMaskPicture->componentAlpha) {
+ /* Check if it's component alpha that relies on a source alpha and
+@@ -624,7 +623,8 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
+ PixmapPtr pMask,
+ PixmapPtr pDst)
+ {
+- RINFO_FROM_SCREEN(pDst->drawable.pScreen);
++ ScreenPtr pScreen = pDst->drawable.pScreen;
++ RINFO_FROM_SCREEN(pScreen);
+ uint32_t dst_format, dst_pitch, colorpitch;
+ uint32_t pp_cntl, blendcntl, cblend, ablend;
+ int pixel_shift;
+@@ -648,12 +648,27 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
+
+ CHECK_OFFSET(pDst, 0x0f, "destination");
+
++ if (!pSrc) {
++ pSrc = RADEONSolidPixmap(pScreen, cpu_to_le32(pSrcPicture->pSourcePict->solidFill.color));
++ if (!pSrc)
++ RADEON_FALLBACK("Failed to create solid scratch pixmap\n");
++ }
++
+ if (((dst_pitch >> pixel_shift) & 0x7) != 0)
+ RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch));
+
+ if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE))
+ return FALSE;
+
++ if (pMaskPicture && !pMask) {
++ pMask = RADEONSolidPixmap(pScreen, cpu_to_le32(pMaskPicture->pSourcePict->solidFill.color));
++ if (!pMask) {
++ if (!pSrcPicture->pDrawable)
++ pScreen->DestroyPixmap(pSrc);
++ RADEON_FALLBACK("Failed to create solid scratch pixmap\n");
++ }
++ }
++
+ RADEONPrepareCompositeCS(op, pSrcPicture, pMaskPicture, pDstPicture,
+ pSrc, pMask, pDst);
+
+--
+1.7.7.5
+
diff --git a/extra/xf86-video-ati/0003-poor-man-s-solid-picture-support-for-r200.patch b/extra/xf86-video-ati/0003-poor-man-s-solid-picture-support-for-r200.patch
new file mode 100644
index 000000000..0a448fc93
--- /dev/null
+++ b/extra/xf86-video-ati/0003-poor-man-s-solid-picture-support-for-r200.patch
@@ -0,0 +1,179 @@
+From c5c8310858f8018a1754f2457d7b102dc7d62b23 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Fri, 13 Apr 2012 13:28:10 -0400
+Subject: [PATCH 3/3] poor man's solid picture support for r200
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/radeon_exa_render.c | 101 +++++++++++++++++++++++++++--------------------
+ 1 files changed, 58 insertions(+), 43 deletions(-)
+
+diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
+index 451a625..7f1a3ff 100644
+--- a/src/radeon_exa_render.c
++++ b/src/radeon_exa_render.c
+@@ -756,17 +756,8 @@ static Bool R200CheckCompositeTexture(PicturePtr pPict,
+ int unit)
+ {
+ unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
+- int w = pPict->pDrawable->width;
+- int h = pPict->pDrawable->height;
+ int i;
+
+- /* r200 limit should be 2048, there are issues with 2048
+- * see bug 19269
+- */
+-
+- if ((w > 2047) || (h > 2047))
+- RADEON_FALLBACK(("Picture w/h too large (%dx%d)\n", w, h));
+-
+ for (i = 0; i < sizeof(R200TexFormats) / sizeof(R200TexFormats[0]); i++)
+ {
+ if (R200TexFormats[i].fmt == pPict->format)
+@@ -776,7 +767,7 @@ static Bool R200CheckCompositeTexture(PicturePtr pPict,
+ RADEON_FALLBACK(("Unsupported picture format 0x%x\n",
+ (int)pPict->format));
+
+- if (!RADEONCheckTexturePOT(pPict, unit == 0))
++ if (pPict->pDrawable && !RADEONCheckTexturePOT(pPict, unit == 0))
+ return FALSE;
+
+ if (pPict->filter != PictFilterNearest &&
+@@ -809,15 +800,24 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
+ {
+ RINFO_FROM_SCREEN(pPix->drawable.pScreen);
+ uint32_t txfilter, txformat, txoffset, txpitch;
+- int w = pPict->pDrawable->width;
+- int h = pPict->pDrawable->height;
+- unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
+- Bool repeat = (repeatType == RepeatNormal || repeatType == RepeatReflect) &&
+- !(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y));
+- int i;
++ unsigned int repeatType;
++ Bool repeat;
++ int i, w, h;
+ struct radeon_exa_pixmap_priv *driver_priv;
+ ACCEL_PREAMBLE();
+
++ if (pPict->pDrawable) {
++ w = pPict->pDrawable->width;
++ h = pPict->pDrawable->height;
++ repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
++ } else {
++ w = h = 1;
++ repeatType = RepeatNormal;
++ }
++
++ repeat = (repeatType == RepeatNormal || repeatType == RepeatReflect) &&
++ !(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y));
++
+ txpitch = exaGetPixmapPitch(pPix);
+
+ txoffset = 0;
+@@ -926,22 +926,6 @@ static Bool R200CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP
+ if (op >= sizeof(RadeonBlendOp) / sizeof(RadeonBlendOp[0]))
+ RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op));
+
+- if (!pSrcPicture->pDrawable)
+- RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n"));
+-
+- /* r200 limit should be 2048, there are issues with 2048
+- * see bug 19269
+- */
+-
+- pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
+-
+- if (pSrcPixmap->drawable.width > 2047 ||
+- pSrcPixmap->drawable.height > 2047) {
+- RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
+- pSrcPixmap->drawable.width,
+- pSrcPixmap->drawable.height));
+- }
+-
+ pDstPixmap = RADEONGetDrawablePixmap(pDstPicture->pDrawable);
+
+ if (pDstPixmap->drawable.width > 2047 ||
+@@ -951,20 +935,35 @@ static Bool R200CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP
+ pDstPixmap->drawable.height));
+ }
+
++ if (pSrcPicture->pDrawable) {
++ /* r200 limit should be 2048, there are issues with 2048
++ * see 197a62704742a4a19736c2637ac92d1dc5ab34ed
++ */
++ pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
++
++ if (pSrcPixmap->drawable.width > 2047 ||
++ pSrcPixmap->drawable.height > 2047) {
++ RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
++ pSrcPixmap->drawable.width,
++ pSrcPixmap->drawable.height));
++ }
++ } else if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill)
++ RADEON_FALLBACK(("Gradient pictures not supported yet\n"));
++
+ if (pMaskPicture) {
+ PixmapPtr pMaskPixmap;
+
+- if (!pMaskPicture->pDrawable)
+- RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n"));
+-
+- pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
++ if (pMaskPicture->pDrawable) {
++ pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
+
+- if (pMaskPixmap->drawable.width > 2047 ||
+- pMaskPixmap->drawable.height > 2047) {
+- RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
+- pMaskPixmap->drawable.width,
+- pMaskPixmap->drawable.height));
+- }
++ if (pMaskPixmap->drawable.width > 2047 ||
++ pMaskPixmap->drawable.height > 2047) {
++ RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
++ pMaskPixmap->drawable.width,
++ pMaskPixmap->drawable.height));
++ }
++ } else if (pMaskPicture->pSourcePict->type != SourcePictTypeSolidFill)
++ RADEON_FALLBACK(("Gradient pictures not supported yet\n"));
+
+ if (pMaskPicture->componentAlpha) {
+ /* Check if it's component alpha that relies on a source alpha and
+@@ -997,7 +996,8 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture, PicturePtr pDstPicture,
+ PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
+ {
+- RINFO_FROM_SCREEN(pDst->drawable.pScreen);
++ ScreenPtr pScreen = pDst->drawable.pScreen;
++ RINFO_FROM_SCREEN(pScreen);
+ uint32_t dst_format, dst_pitch;
+ uint32_t pp_cntl, blendcntl, cblend, ablend, colorpitch;
+ int pixel_shift;
+@@ -1024,9 +1024,24 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
+ if (((dst_pitch >> pixel_shift) & 0x7) != 0)
+ RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch));
+
++ if (!pSrc) {
++ pSrc = RADEONSolidPixmap(pScreen, cpu_to_le32(pSrcPicture->pSourcePict->solidFill.color));
++ if (!pSrc)
++ RADEON_FALLBACK("Failed to create solid scratch pixmap\n");
++ }
++
+ if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE))
+ return FALSE;
+
++ if (pMaskPicture && !pMask) {
++ pMask = RADEONSolidPixmap(pScreen, cpu_to_le32(pMaskPicture->pSourcePict->solidFill.color));
++ if (!pMask) {
++ if (!pSrcPicture->pDrawable)
++ pScreen->DestroyPixmap(pSrc);
++ RADEON_FALLBACK("Failed to create solid scratch pixmap\n");
++ }
++ }
++
+ RADEONPrepareCompositeCS(op, pSrcPicture, pMaskPicture, pDstPicture,
+ pSrc, pMask, pDst);
+
+--
+1.7.7.5
+
diff --git a/extra/xf86-video-ati/PKGBUILD b/extra/xf86-video-ati/PKGBUILD
index 09c47f815..341982471 100644
--- a/extra/xf86-video-ati/PKGBUILD
+++ b/extra/xf86-video-ati/PKGBUILD
@@ -1,10 +1,10 @@
-# $Id: PKGBUILD 154644 2012-03-30 13:39:00Z andyrtr $
+# $Id: PKGBUILD 158858 2012-05-12 13:09:32Z andyrtr $
# Maintainer: Jan de Groot <jgc@archlinux.org>
# Contributor: Alexander Baldeck <alexander@archlinux.org>
pkgname=xf86-video-ati
pkgver=6.14.4
-pkgrel=2
+pkgrel=4
pkgdesc="X.org ati video driver"
arch=('i686' 'x86_64')
url="http://xorg.freedesktop.org/"
@@ -14,11 +14,30 @@ makedepends=('xorg-server-devel>=1.11.99.902' 'xf86driproto' 'mesa' 'glproto')
conflicts=('xorg-server<1.11.99.902')
groups=('xorg-drivers' 'xorg')
options=('!libtool')
-source=(${url}/releases/individual/driver/${pkgname}-${pkgver}.tar.bz2)
-sha1sums=('75ad000bc00599e1797134f2d20d3094cba6af92')
+source=(${url}/releases/individual/driver/${pkgname}-${pkgver}.tar.bz2
+ git_fixes.diff
+ 0000-poor-man-s-solid-picture-support-for-r300-r600.patch
+ 0001-poor-man-s-solid-picture-support-for-evergreen.patch
+ 0002-poor-man-s-solid-picture-support-for-r100.patch
+ 0003-poor-man-s-solid-picture-support-for-r200.patch)
+sha1sums=('75ad000bc00599e1797134f2d20d3094cba6af92'
+ '8b774e2f0310075cff2b7d874b0bed38d6245769'
+ '787f88c428f56ca6e96ba5eaf043a30bddfd0e23'
+ '69359a6623fe0f2214790c8ad40cac1a680a3825'
+ 'c0709ab82728e34838a8aeead7d1b79b7faf09bd'
+ '77a519e250c27a9fb94eeb52da655eed7c5f2eca')
build() {
cd "${srcdir}/${pkgname}-${pkgver}"
+ patch -Np1 -i ${srcdir}/git_fixes.diff
+
+ # fix rendering issues with recent cairo - testing attemp taken from https://bugs.freedesktop.org/show_bug.cgi?id=47266
+ # and http://lists.x.org/archives/xorg-driver-ati/2012-April/022724.html
+ patch -Np1 -i ${srcdir}/0000-poor-man-s-solid-picture-support-for-r300-r600.patch
+ patch -Np1 -i ${srcdir}/0001-poor-man-s-solid-picture-support-for-evergreen.patch
+ patch -Np1 -i ${srcdir}/0002-poor-man-s-solid-picture-support-for-r100.patch
+ patch -Np1 -i ${srcdir}/0003-poor-man-s-solid-picture-support-for-r200.patch
+
./configure --prefix=/usr --enable-dri
make
}
diff --git a/extra/xf86-video-ati/git_fixes.diff b/extra/xf86-video-ati/git_fixes.diff
new file mode 100644
index 000000000..0c4518319
--- /dev/null
+++ b/extra/xf86-video-ati/git_fixes.diff
@@ -0,0 +1,33 @@
+From d282719a9c2fb0ee32830aa75b8dfbb9392954ed Mon Sep 17 00:00:00 2001
+From: Jerome Glisse <jglisse@redhat.com>
+Date: Wed, 04 Apr 2012 21:08:30 +0000
+Subject: r6xx-r9xx: force 1D tiling for buffer with height < 64
+
+Due to some old kernel issue, height is 8 aligned insided the ddx
+For buffer with height btw 57 & 63 this lead ddx to believe it can
+allocate a 2D tiled surface while mesa will not align height and
+will assume 1D tiled leading to disagreement and rendering issue.
+This patch force buffer with height < 64 to be 1D tiled.
+
+Signed-off-by: Jerome Glisse <jglisse@redhat.com>
+---
+diff --git a/src/radeon_exa.c b/src/radeon_exa.c
+index 99a5806..270dad4 100644
+--- a/src/radeon_exa.c
++++ b/src/radeon_exa.c
+@@ -511,6 +511,13 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height,
+ surface.last_level = 0;
+ surface.bpe = cpp;
+ surface.nsamples = 1;
++ if (height < 64) {
++ /* disable 2d tiling for small surface to work around
++ * the fact that ddx align height to 8 pixel for old
++ * obscure reason i can't remember
++ */
++ tiling &= ~RADEON_TILING_MACRO;
++ }
+ surface.flags = RADEON_SURF_SCANOUT;
+ surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
+ surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
+--
+cgit v0.9.0.2-2-gbebe