summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/radeon_exa_render.c101
1 files changed, 58 insertions, 43 deletions
diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
index b6cc9e4c..451a625e 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);