summaryrefslogtreecommitdiff
path: root/src/radeon_exa_render.c
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2012-04-13 09:35:38 +0200
committerMichel Dänzer <michel@daenzer.net>2012-04-16 15:54:26 +0200
commitd88b9700137ee407c483f263bb55c77cd6f92fef (patch)
tree04202d50791f6cd06d3582a9cb97194934a4420f /src/radeon_exa_render.c
parent66b586b9b9cdaf70f0fcd547b5a04f044d848d44 (diff)
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>
Diffstat (limited to 'src/radeon_exa_render.c')
-rw-r--r--src/radeon_exa_render.c115
1 files changed, 69 insertions, 46 deletions
diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
index e5c231fa..b6cc9e4c 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