From ede03a848693ebe3d3f46e75cfcac11f7dcfe482 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Fri, 20 Apr 2012 16:10:51 +0200 Subject: [PATCH] xf86-video-ati: add patches from upstream to fix EXA corruption with cairo-1.12. --- ...000-force-1d-tiling-for-r6xx-to-r9xx.patch | 32 + ...port-acceleration-pictures-evergreen.patch | 286 +++++++++ ...a-support-acceleration-pictures-r1xx.patch | 178 ++++++ ...a-support-acceleration-pictures-r2xx.patch | 175 ++++++ ...t-acceleration-pictures-r3xx-to-r7xx.patch | 562 ++++++++++++++++++ srcpkgs/xf86-video-ati/template | 2 + 6 files changed, 1235 insertions(+) create mode 100644 srcpkgs/xf86-video-ati/patches/0000-force-1d-tiling-for-r6xx-to-r9xx.patch create mode 100644 srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-evergreen.patch create mode 100644 srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-r1xx.patch create mode 100644 srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-r2xx.patch create mode 100644 srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-r3xx-to-r7xx.patch diff --git a/srcpkgs/xf86-video-ati/patches/0000-force-1d-tiling-for-r6xx-to-r9xx.patch b/srcpkgs/xf86-video-ati/patches/0000-force-1d-tiling-for-r6xx-to-r9xx.patch new file mode 100644 index 00000000000..e162c7e86b2 --- /dev/null +++ b/srcpkgs/xf86-video-ati/patches/0000-force-1d-tiling-for-r6xx-to-r9xx.patch @@ -0,0 +1,32 @@ +commit d282719a9c2fb0ee32830aa75b8dfbb9392954ed +Author: Jerome Glisse +Date: Wed Apr 4 17:08:30 2012 -0400 + + 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 + +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); diff --git a/srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-evergreen.patch b/srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-evergreen.patch new file mode 100644 index 00000000000..36022bfd157 --- /dev/null +++ b/srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-evergreen.patch @@ -0,0 +1,286 @@ +commit cac2d7ed54918579418fc762558497d3ec547fad +Author: Alex Deucher +Date: Sat Apr 14 08:53:39 2012 -0400 + + EXA: Support acceleration of solid pictures on Evergreen/NI. + + Signed-off-by: Alex Deucher + Reviewed-by: Michel Dänzer + +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, diff --git a/srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-r1xx.patch b/srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-r1xx.patch new file mode 100644 index 00000000000..be350553c43 --- /dev/null +++ b/srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-r1xx.patch @@ -0,0 +1,178 @@ +commit a7754b076e355fef3aea082b6e2d3aefbb8e7a9b +Author: Alex Deucher +Date: Fri Apr 13 13:24:46 2012 -0400 + + EXA: Support acceleration of solid pictures on R1xx. + + Signed-off-by: Alex Deucher + Reviewed-by: Michel Dänzer + +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); + diff --git a/srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-r2xx.patch b/srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-r2xx.patch new file mode 100644 index 00000000000..9b64565ba69 --- /dev/null +++ b/srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-r2xx.patch @@ -0,0 +1,175 @@ +commit 0bda305f7ab2a4720b3fea3f318ab2a73be151e5 +Author: Alex Deucher +Date: Fri Apr 13 13:28:10 2012 -0400 + + EXA: Support acceleration of solid pictures on R2xx. + + Signed-off-by: Alex Deucher + Reviewed-by: Michel Dänzer + +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); + diff --git a/srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-r3xx-to-r7xx.patch b/srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-r3xx-to-r7xx.patch new file mode 100644 index 00000000000..563dac456d1 --- /dev/null +++ b/srcpkgs/xf86-video-ati/patches/0001-exa-support-acceleration-pictures-r3xx-to-r7xx.patch @@ -0,0 +1,562 @@ +commit d88b9700137ee407c483f263bb55c77cd6f92fef +Author: Michel Dänzer +Date: Fri Apr 13 09:35:38 2012 +0200 + + EXA: Support acceleration of solid pictures on R3xx-R7xx. + + Allocate 1x1 scratch pixmaps to hold the solid picture colours. + + This works around https://bugs.freedesktop.org/show_bug.cgi?id=47266 and might + improve performance in other cases as well. + + Signed-off-by: Michel Dänzer + +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 diff --git a/srcpkgs/xf86-video-ati/template b/srcpkgs/xf86-video-ati/template index a1b3f9940d3..c2c03047bdb 100644 --- a/srcpkgs/xf86-video-ati/template +++ b/srcpkgs/xf86-video-ati/template @@ -1,6 +1,8 @@ # Template build file for 'xf86-video-ati'. pkgname=xf86-video-ati version=6.14.4 +revision=1 +patch_args="-Np1" distfiles="${XORG_SITE}/driver/$pkgname-$version.tar.bz2" build_style=gnu-configure short_desc="Xorg ATI Radeon video driver"