xserver-xorg-video-ati: Changes to 'debian-unstable'
debian/changelog | 15 ++
src/evergreen_exa.c | 163 ++++++++++++++----------
src/r600_exa.c | 160 +++++++++++++-----------
src/radeon_accel.c | 5
src/radeon_exa.c | 7 +
src/radeon_exa_render.c | 317 ++++++++++++++++++++++++++++--------------------
src/radeon_exa_shared.c | 19 ++
src/radeon_exa_shared.h | 1
src/radeon_kms.c | 14 +-
9 files changed, 426 insertions(+), 275 deletions(-)
New commits:
commit 9178ac42b012258da6583c34bf4ef06471162ddc
Author: Julien Cristau <jcristau@debian.org>
Date: Mon Apr 16 20:02:46 2012 +0200
Changelog entry for upload to unstable.
diff --git a/debian/changelog b/debian/changelog
index 99b4bb5..d42f0c0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,18 @@
+xserver-xorg-video-ati (1:6.14.4-2) unstable; urgency=medium
+
+ * Cherry-picks from upstream git:
+ - r6xx-r9xx: force 1D tiling for buffer with height < 64
+ - Make radeon_setup_kernel_mem failures more graceful and verbose
+ - RADEONCopySwap: Fix RADEON_HOST_DATA_SWAP_16BIT case
+ - EXA: Support acceleration of solid pictures on R3xx-R7xx
+ - EXA: Support acceleration of solid pictures on Evergreen/NI
+ - EXA: Support acceleration of solid pictures on R1xx
+ - EXA: Support acceleration of solid pictures on R2xx
+ * The solid picture acceleration should fix the rendering mess people have
+ been seeing with cairo 1.12, and thus closes: #666982.
+
+ -- Julien Cristau <jcristau@debian.org> Mon, 16 Apr 2012 20:03:31 +0200
+
xserver-xorg-video-ati (1:6.14.4-1) unstable; urgency=low
* New upstream release:
commit 1cf032f4675e5d1db3ea1cfb5802072e8104de2a
Author: Alex Deucher <alexander.deucher@amd.com>
Date: Fri Apr 13 13:28:10 2012 -0400
EXA: Support acceleration of solid pictures on R2xx.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
(cherry picked from commit 0bda305f7ab2a4720b3fea3f318ab2a73be151e5)
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);
commit 3949d4d76e68ea23b8772ac4f106dcebaa33c5a5
Author: Alex Deucher <alexander.deucher@amd.com>
Date: Fri Apr 13 13:24:46 2012 -0400
EXA: Support acceleration of solid pictures on R1xx.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
(cherry picked from commit a7754b076e355fef3aea082b6e2d3aefbb8e7a9b)
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);
commit 739c794e0ecbea0d09ba10c06eeacf5c02029698
Author: Alex Deucher <alexander.deucher@amd.com>
Date: Sat Apr 14 08:53:39 2012 -0400
EXA: Support acceleration of solid pictures on Evergreen/NI.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
(cherry picked from commit cac2d7ed54918579418fc762558497d3ec547fad)
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,
commit d8a043a150761cbf8d6202ab7f94158f83e9c6dd
Author: Michel Dänzer <michel.daenzer@amd.com>
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 <michel.daenzer@amd.com>
(cherry picked from commit d88b9700137ee407c483f263bb55c77cd6f92fef)
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;
Reply to: