[PATCH] EXA >= R6xx / KMS: Avoid running out of CS space at inconvenient times.

Alex Deucher alexdeucher at gmail.com
Thu Oct 27 13:25:55 PDT 2011


2011/10/27 Michel Dänzer <michel at daenzer.net>:
> From: Michel Dänzer <michel.daenzer at amd.com>
>
> Otherwise we may end up with things not properly set up at the beginning of the
> next CS.
>
> Fixes http://bugs.debian.org/645007 .
>
> In contrast to the Composite code for < R6xx, this isn't necessary with UMS,
> as the draw packet only uses constant space in the indirect buffer, and nothing
> else can mess with the 3D state between indirect buffers.
>
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>

Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  src/evergreen_exa.c |  147 +++++++++++++++++++++++++++++----------------
>  src/r600_exa.c      |  164 ++++++++++++++++++++++++++++++++++-----------------
>  src/radeon.h        |    3 +-
>  3 files changed, 206 insertions(+), 108 deletions(-)
>
> diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c
> index 306e90f..6becbb3 100644
> --- a/src/evergreen_exa.c
> +++ b/src/evergreen_exa.c
> @@ -55,9 +55,6 @@ extern int cayman_xv_ps(RADEONChipFamily ChipSet, uint32_t* shader);
>  extern int cayman_comp_vs(RADEONChipFamily ChipSet, uint32_t* vs);
>  extern int cayman_comp_ps(RADEONChipFamily ChipSet, uint32_t* ps);
>
> -static void
> -EVERGREENDoneSolid(PixmapPtr pPix);
> -
>  static Bool
>  EVERGREENPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
>  {
> @@ -205,9 +202,27 @@ EVERGREENPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
>     if (accel_state->vsync)
>        RADEONVlineHelperClear(pScrn);
>
> +    accel_state->dst_pix = pPix;
> +    accel_state->fg = fg;
> +
>     return TRUE;
>  }
>
> +static void
> +EVERGREENDoneSolid(PixmapPtr pPix)
> +{
> +    ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
> +    RADEONInfoPtr info = RADEONPTR(pScrn);
> +    struct radeon_accel_state *accel_state = info->accel_state;
> +
> +    if (accel_state->vsync)
> +       evergreen_cp_wait_vline_sync(pScrn, pPix,
> +                                    accel_state->vline_crtc,
> +                                    accel_state->vline_y1,
> +                                    accel_state->vline_y2);
> +
> +    evergreen_finish_op(pScrn, 8);
> +}
>
>  static void
>  EVERGREENSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
> @@ -217,6 +232,15 @@ EVERGREENSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
>     struct radeon_accel_state *accel_state = info->accel_state;
>     float *vb;
>
> +    if (CS_FULL(info->cs)) {
> +       EVERGREENDoneSolid(info->accel_state->dst_pix);
> +       radeon_cs_flush_indirect(pScrn);
> +       EVERGREENPrepareSolid(accel_state->dst_pix,
> +                             accel_state->rop,
> +                             accel_state->planemask,
> +                             accel_state->fg);
> +    }
> +
>     if (accel_state->vsync)
>        RADEONVlineHelperSet(pScrn, x1, y1, x2, y2);
>
> @@ -235,22 +259,6 @@ EVERGREENSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
>  }
>
>  static void
> -EVERGREENDoneSolid(PixmapPtr pPix)
> -{
> -    ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
> -    RADEONInfoPtr info = RADEONPTR(pScrn);
> -    struct radeon_accel_state *accel_state = info->accel_state;
> -
> -    if (accel_state->vsync)
> -       evergreen_cp_wait_vline_sync(pScrn, pPix,
> -                                    accel_state->vline_crtc,
> -                                    accel_state->vline_y1,
> -                                    accel_state->vline_y2);
> -
> -    evergreen_finish_op(pScrn, 8);
> -}
> -
> -static void
>  EVERGREENDoPrepareCopy(ScrnInfoPtr pScrn)
>  {
>     RADEONInfoPtr info = RADEONPTR(pScrn);
> @@ -510,10 +518,30 @@ EVERGREENPrepareCopy(PixmapPtr pSrc,   PixmapPtr pDst,
>     if (accel_state->vsync)
>        RADEONVlineHelperClear(pScrn);
>
> +    accel_state->dst_pix = pDst;
> +    accel_state->src_pix = pSrc;
> +    accel_state->xdir = xdir;
> +    accel_state->ydir = ydir;
> +
>     return TRUE;
>  }
>
>  static void
> +EVERGREENDoneCopy(PixmapPtr pDst)
> +{
> +    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
> +    RADEONInfoPtr info = RADEONPTR(pScrn);
> +    struct radeon_accel_state *accel_state = info->accel_state;
> +
> +    if (!accel_state->same_surface)
> +       EVERGREENDoCopyVline(pDst);
> +
> +    if (accel_state->copy_area)
> +       accel_state->copy_area = NULL;
> +
> +}
> +
> +static void
>  EVERGREENCopy(PixmapPtr pDst,
>              int srcX, int srcY,
>              int dstX, int dstY,
> @@ -526,6 +554,17 @@ EVERGREENCopy(PixmapPtr pDst,
>     if (accel_state->same_surface && (srcX == dstX) && (srcY == dstY))
>        return;
>
> +    if (CS_FULL(info->cs)) {
> +       EVERGREENDoneCopy(info->accel_state->dst_pix);
> +       radeon_cs_flush_indirect(pScrn);
> +       EVERGREENPrepareCopy(accel_state->src_pix,
> +                            accel_state->dst_pix,
> +                            accel_state->xdir,
> +                            accel_state->ydir,
> +                            accel_state->rop,
> +                            accel_state->planemask);
> +    }
> +
>     if (accel_state->vsync)
>        RADEONVlineHelperSet(pScrn, dstX, dstY, dstX + w, dstY + h);
>
> @@ -568,21 +607,6 @@ EVERGREENCopy(PixmapPtr pDst,
>
>  }
>
> -static void
> -EVERGREENDoneCopy(PixmapPtr pDst)
> -{
> -    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
> -    RADEONInfoPtr info = RADEONPTR(pScrn);
> -    struct radeon_accel_state *accel_state = info->accel_state;
> -
> -    if (!accel_state->same_surface)
> -       EVERGREENDoCopyVline(pDst);
> -
> -    if (accel_state->copy_area)
> -       accel_state->copy_area = NULL;
> -
> -}
> -
>  struct blendinfo {
>     Bool dst_alpha;
>     Bool src_alpha;
> @@ -1306,9 +1330,34 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture,
>     if (accel_state->vsync)
>        RADEONVlineHelperClear(pScrn);
>
> +    accel_state->composite_op = op;
> +    accel_state->dst_pic = pDstPicture;
> +    accel_state->src_pic = pSrcPicture;
> +    accel_state->dst_pix = pDst;
> +    accel_state->msk_pix = pMask;
> +    accel_state->src_pix = pSrc;
> +
>     return TRUE;
>  }
>
> +static void EVERGREENDoneComposite(PixmapPtr pDst)
> +{
> +    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)
> +       evergreen_cp_wait_vline_sync(pScrn, pDst,
> +                                   accel_state->vline_crtc,
> +                                   accel_state->vline_y1,
> +                                   accel_state->vline_y2);
> +
> +    vtx_size = accel_state->msk_pic ? 24 : 16;
> +
> +    evergreen_finish_op(pScrn, vtx_size);
> +}
> +
>  static void EVERGREENComposite(PixmapPtr pDst,
>                               int srcX, int srcY,
>                               int maskX, int maskY,
> @@ -1320,6 +1369,18 @@ static void EVERGREENComposite(PixmapPtr pDst,
>     struct radeon_accel_state *accel_state = info->accel_state;
>     float *vb;
>
> +    if (CS_FULL(info->cs)) {
> +       EVERGREENDoneComposite(info->accel_state->dst_pix);
> +       radeon_cs_flush_indirect(pScrn);
> +       EVERGREENPrepareComposite(info->accel_state->composite_op,
> +                                 info->accel_state->src_pic,
> +                                 info->accel_state->msk_pic,
> +                                 info->accel_state->dst_pic,
> +                                 info->accel_state->src_pix,
> +                                 info->accel_state->msk_pix,
> +                                 info->accel_state->dst_pix);
> +    }
> +
>     if (accel_state->vsync)
>        RADEONVlineHelperSet(pScrn, dstX, dstY, dstX + w, dstY + h);
>
> @@ -1375,24 +1436,6 @@ static void EVERGREENComposite(PixmapPtr pDst,
>
>  }
>
> -static void EVERGREENDoneComposite(PixmapPtr pDst)
> -{
> -    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)
> -       evergreen_cp_wait_vline_sync(pScrn, pDst,
> -                                   accel_state->vline_crtc,
> -                                   accel_state->vline_y1,
> -                                   accel_state->vline_y2);
> -
> -    vtx_size = accel_state->msk_pic ? 24 : 16;
> -
> -    evergreen_finish_op(pScrn, vtx_size);
> -}
> -
>  static Bool
>  EVERGREENUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
>                        char *src, int src_pitch)
> diff --git a/src/r600_exa.c b/src/r600_exa.c
> index 2673599..71e1393 100644
> --- a/src/r600_exa.c
> +++ b/src/r600_exa.c
> @@ -132,6 +132,11 @@ R600SetAccelState(ScrnInfoPtr pScrn,
>        accel_state->dst_size = 0;
>     }
>
> +#ifdef XF86DRM_MODE
> +    if (info->cs && CS_FULL(info->cs))
> +       radeon_cs_flush_indirect(pScrn);
> +#endif
> +
>     accel_state->rop = rop;
>     accel_state->planemask = planemask;
>
> @@ -170,9 +175,6 @@ R600SetAccelState(ScrnInfoPtr pScrn,
>     return TRUE;
>  }
>
> -static void
> -R600DoneSolid(PixmapPtr pPix);
> -
>  static Bool
>  R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
>  {
> @@ -318,9 +320,27 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
>     if (accel_state->vsync)
>        RADEONVlineHelperClear(pScrn);
>
> +    accel_state->dst_pix = pPix;
> +    accel_state->fg = fg;
> +
>     return TRUE;
>  }
>
> +static void
> +R600DoneSolid(PixmapPtr pPix)
> +{
> +    ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
> +    RADEONInfoPtr info = RADEONPTR(pScrn);
> +    struct radeon_accel_state *accel_state = info->accel_state;
> +
> +    if (accel_state->vsync)
> +       r600_cp_wait_vline_sync(pScrn, accel_state->ib, pPix,
> +                               accel_state->vline_crtc,
> +                               accel_state->vline_y1,
> +                               accel_state->vline_y2);
> +
> +    r600_finish_op(pScrn, 8);
> +}
>
>  static void
>  R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
> @@ -330,6 +350,17 @@ R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
>     struct radeon_accel_state *accel_state = info->accel_state;
>     float *vb;
>
> +#ifdef XF86DRM_MODE
> +    if (info->cs && CS_FULL(info->cs)) {
> +       R600DoneSolid(info->accel_state->dst_pix);
> +       radeon_cs_flush_indirect(pScrn);
> +       R600PrepareSolid(accel_state->dst_pix,
> +                        accel_state->rop,
> +                        accel_state->planemask,
> +                        accel_state->fg);
> +    }
> +#endif
> +
>     if (accel_state->vsync)
>        RADEONVlineHelperSet(pScrn, x1, y1, x2, y2);
>
> @@ -348,22 +379,6 @@ R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
>  }
>
>  static void
> -R600DoneSolid(PixmapPtr pPix)
> -{
> -    ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
> -    RADEONInfoPtr info = RADEONPTR(pScrn);
> -    struct radeon_accel_state *accel_state = info->accel_state;
> -
> -    if (accel_state->vsync)
> -       r600_cp_wait_vline_sync(pScrn, accel_state->ib, pPix,
> -                               accel_state->vline_crtc,
> -                               accel_state->vline_y1,
> -                               accel_state->vline_y2);
> -
> -    r600_finish_op(pScrn, 8);
> -}
> -
> -static void
>  R600DoPrepareCopy(ScrnInfoPtr pScrn)
>  {
>     RADEONInfoPtr info = RADEONPTR(pScrn);
> @@ -653,10 +668,33 @@ R600PrepareCopy(PixmapPtr pSrc,   PixmapPtr pDst,
>     if (accel_state->vsync)
>        RADEONVlineHelperClear(pScrn);
>
> +    accel_state->dst_pix = pDst;
> +    accel_state->src_pix = pSrc;
> +    accel_state->xdir = xdir;
> +    accel_state->ydir = ydir;
> +
>     return TRUE;
>  }
>
>  static void
> +R600DoneCopy(PixmapPtr pDst)
> +{
> +    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
> +    RADEONInfoPtr info = RADEONPTR(pScrn);
> +    struct radeon_accel_state *accel_state = info->accel_state;
> +
> +    if (!accel_state->same_surface)
> +       R600DoCopyVline(pDst);
> +
> +    if (accel_state->copy_area) {
> +       if (!info->cs)
> +           exaOffscreenFree(pDst->drawable.pScreen, accel_state->copy_area);
> +       accel_state->copy_area = NULL;
> +    }
> +
> +}
> +
> +static void
>  R600Copy(PixmapPtr pDst,
>         int srcX, int srcY,
>         int dstX, int dstY,
> @@ -669,6 +707,19 @@ R600Copy(PixmapPtr pDst,
>     if (accel_state->same_surface && (srcX == dstX) && (srcY == dstY))
>        return;
>
> +#ifdef XF86DRM_MODE
> +    if (info->cs && CS_FULL(info->cs)) {
> +       R600DoneCopy(info->accel_state->dst_pix);
> +       radeon_cs_flush_indirect(pScrn);
> +       R600PrepareCopy(accel_state->src_pix,
> +                       accel_state->dst_pix,
> +                       accel_state->xdir,
> +                       accel_state->ydir,
> +                       accel_state->rop,
> +                       accel_state->planemask);
> +    }
> +#endif
> +
>     if (accel_state->vsync)
>        RADEONVlineHelperSet(pScrn, dstX, dstY, dstX + w, dstY + h);
>
> @@ -723,24 +774,6 @@ R600Copy(PixmapPtr pDst,
>
>  }
>
> -static void
> -R600DoneCopy(PixmapPtr pDst)
> -{
> -    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
> -    RADEONInfoPtr info = RADEONPTR(pScrn);
> -    struct radeon_accel_state *accel_state = info->accel_state;
> -
> -    if (!accel_state->same_surface)
> -       R600DoCopyVline(pDst);
> -
> -    if (accel_state->copy_area) {
> -       if (!info->cs)
> -           exaOffscreenFree(pDst->drawable.pScreen, accel_state->copy_area);
> -       accel_state->copy_area = NULL;
> -    }
> -
> -}
> -
>  struct blendinfo {
>     Bool dst_alpha;
>     Bool src_alpha;
> @@ -1452,9 +1485,34 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
>     if (accel_state->vsync)
>        RADEONVlineHelperClear(pScrn);
>
> +    accel_state->composite_op = op;
> +    accel_state->dst_pic = pDstPicture;
> +    accel_state->src_pic = pSrcPicture;
> +    accel_state->dst_pix = pDst;
> +    accel_state->msk_pix = pMask;
> +    accel_state->src_pix = pSrc;
> +
>     return TRUE;
>  }
>
> +static void R600DoneComposite(PixmapPtr pDst)
> +{
> +    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)
> +       r600_cp_wait_vline_sync(pScrn, accel_state->ib, pDst,
> +                              accel_state->vline_crtc,
> +                              accel_state->vline_y1,
> +                              accel_state->vline_y2);
> +
> +    vtx_size = accel_state->msk_pic ? 24 : 16;
> +
> +    r600_finish_op(pScrn, vtx_size);
> +}
> +
>  static void R600Composite(PixmapPtr pDst,
>                          int srcX, int srcY,
>                          int maskX, int maskY,
> @@ -1469,6 +1527,20 @@ static void R600Composite(PixmapPtr pDst,
>     /* ErrorF("R600Composite (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n",
>        srcX, srcY, maskX, maskY,dstX, dstY, w, h); */
>
> +#ifdef XF86DRM_MODE
> +    if (info->cs && CS_FULL(info->cs)) {
> +       R600DoneComposite(info->accel_state->dst_pix);
> +       radeon_cs_flush_indirect(pScrn);
> +       R600PrepareComposite(info->accel_state->composite_op,
> +                            info->accel_state->src_pic,
> +                            info->accel_state->msk_pic,
> +                            info->accel_state->dst_pic,
> +                            info->accel_state->src_pix,
> +                            info->accel_state->msk_pix,
> +                            info->accel_state->dst_pix);
> +    }
> +#endif
> +
>     if (accel_state->vsync)
>        RADEONVlineHelperSet(pScrn, dstX, dstY, dstX + w, dstY + h);
>
> @@ -1524,24 +1596,6 @@ static void R600Composite(PixmapPtr pDst,
>
>  }
>
> -static void R600DoneComposite(PixmapPtr pDst)
> -{
> -    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)
> -       r600_cp_wait_vline_sync(pScrn, accel_state->ib, pDst,
> -                              accel_state->vline_crtc,
> -                              accel_state->vline_y1,
> -                              accel_state->vline_y2);
> -
> -    vtx_size = accel_state->msk_pic ? 24 : 16;
> -
> -    r600_finish_op(pScrn, vtx_size);
> -}
> -
>  Bool
>  R600CopyToVRAM(ScrnInfoPtr pScrn,
>               char *src, int src_pitch,
> diff --git a/src/radeon.h b/src/radeon.h
> index 50ce62f..73d6db1 100644
> --- a/src/radeon.h
> +++ b/src/radeon.h
> @@ -735,12 +735,13 @@ struct radeon_accel_state {
>     // UTS/DFS
>     drmBufPtr         scratch;
>
> -    // copy
> +    // solid/copy
>     ExaOffscreenArea  *copy_area;
>     struct radeon_bo  *copy_area_bo;
>     Bool              same_surface;
>     int               rop;
>     uint32_t          planemask;
> +    uint32_t          fg;
>
>     // composite
>     Bool              component_alpha;
> --
> 1.7.7.1
>
>
> _______________________________________________
> xorg-driver-ati mailing list
> xorg-driver-ati at lists.x.org
> http://lists.x.org/mailman/listinfo/xorg-driver-ati
>


More information about the xorg-driver-ati mailing list