286 lines
11 KiB
Diff
286 lines
11 KiB
Diff
commit cac2d7ed54918579418fc762558497d3ec547fad
|
|
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>
|
|
|
|
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,
|