[RFC] Poor man's acceleration of solid pictures for R3xx-R7xx

Alex Deucher alexdeucher at gmail.com
Fri Apr 13 10:30:04 PDT 2012


2012/4/13 Michel Dänzer <michel at daenzer.net>:
>
> The patch below implements basic acceleration of solid pictures via
> scratch 1x1 pixmaps. It seems to at least alleviate some of the
> corruption and performance issues exposed by Cairo 1.12, and should also
> improve performance for other toolkits/apps using solid pictures.
>
> If there are no objections to this approach, maybe someone else can beat
> me to extending this for Evergreen+ and R1/2xx.

Attached.  Compile tested only ATM.

Alex

>
>
> 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
>
>
> --
> Earthling Michel Dänzer           |                   http://www.amd.com
> Libre software enthusiast         |          Debian, X and DRI developer
> _______________________________________________
> xorg-driver-ati mailing list
> xorg-driver-ati at lists.x.org
> http://lists.x.org/mailman/listinfo/xorg-driver-ati
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-poor-man-s-solid-picture-support-for-evergreen.patch
Type: text/x-patch
Size: 12224 bytes
Desc: not available
URL: <http://lists.x.org/archives/xorg-driver-ati/attachments/20120413/e3fc8d7c/attachment-0003.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-poor-man-s-solid-picture-support-for-r100.patch
Type: text/x-patch
Size: 6595 bytes
Desc: not available
URL: <http://lists.x.org/archives/xorg-driver-ati/attachments/20120413/e3fc8d7c/attachment-0004.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-poor-man-s-solid-picture-support-for-r200.patch
Type: text/x-patch
Size: 6616 bytes
Desc: not available
URL: <http://lists.x.org/archives/xorg-driver-ati/attachments/20120413/e3fc8d7c/attachment-0005.bin>


More information about the xorg-driver-ati mailing list