commit d0383d5fbde00867626eb5b5d430c94f58fcd73c Author: Michel Dänzer Date: Mon Jul 6 11:39:02 2009 +0200 KMS CS fixes, take two. diff --git a/src/r600_exa.c b/src/r600_exa.c index 18831f7..3673064 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c @@ -1166,7 +1166,7 @@ static Bool R600TextureSetup(PicturePtr pPict, PixmapPtr pPix, } if (unit == 0) { - if (!accel_state->has_mask) { + if (!accel_state->msk_pic) { if (PICT_FORMAT_RGB(pPict->format) == 0) { pix_r = SQ_SEL_0; pix_g = SQ_SEL_0; @@ -1397,7 +1397,7 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, /* return FALSE; */ if (pMask) { - accel_state->has_mask = TRUE; + accel_state->msk_pic = pMaskPicture; if (pMaskPicture->componentAlpha) { accel_state->component_alpha = TRUE; if (R600BlendOp[op].src_alpha) @@ -1409,7 +1409,7 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, accel_state->src_alpha = FALSE; } } else { - accel_state->has_mask = FALSE; + accel_state->msk_pic = NULL; accel_state->component_alpha = FALSE; accel_state->src_alpha = FALSE; } @@ -1598,7 +1598,7 @@ static void R600Composite(PixmapPtr pDst, srcBottomRight.x = IntToxFixed(srcX + w); srcBottomRight.y = IntToxFixed(srcY + h); - if (accel_state->has_mask) { + if (accel_state->msk_pic) { xPointFixed maskTopLeft, maskTopRight, maskBottomLeft, maskBottomRight; if (((accel_state->vb_index + 3) * 24) > (accel_state->ib->total / 2)) { @@ -1693,7 +1693,7 @@ static void R600DoneComposite(PixmapPtr pDst) /* Vertex buffer setup */ - if (accel_state->has_mask) { + if (accel_state->msk_pic) { accel_state->vb_size = accel_state->vb_index * 24; vtx_res.id = SQ_VTX_RESOURCE_vs; vtx_res.vtx_size_dw = 24 / 4; diff --git a/src/radeon.h b/src/radeon.h index c030034..917ca35 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -672,9 +672,15 @@ struct radeon_accel_state { #define EXA_ENGINEMODE_2D 1 #define EXA_ENGINEMODE_3D 2 + int composite_op; + PicturePtr dst_pic; + PicturePtr msk_pic; + PicturePtr src_pic; + PixmapPtr dst_pix; + PixmapPtr msk_pix; + PixmapPtr src_pix; Bool is_transform[2]; PictTransform *transform[2]; - Bool has_mask; /* Whether we are tiling horizontally and vertically */ Bool need_src_tile_x; Bool need_src_tile_y; @@ -1518,8 +1524,10 @@ do { \ uint32_t flush = 0; \ switch (info->accel_state->engineMode) { \ case EXA_ENGINEMODE_UNKNOWN: \ - case EXA_ENGINEMODE_3D: \ flush = 1; \ + break; \ + case EXA_ENGINEMODE_3D: \ + flush = TRUE && info->cs == NULL; \ case EXA_ENGINEMODE_2D: \ break; \ } \ @@ -1537,8 +1545,10 @@ do { \ uint32_t flush = 0; \ switch (info->accel_state->engineMode) { \ case EXA_ENGINEMODE_UNKNOWN: \ - case EXA_ENGINEMODE_2D: \ flush = 1; \ + break; \ + case EXA_ENGINEMODE_2D: \ + flush = 1 || info->cs == NULL || info->cs->cdw > 15 * 1024; \ case EXA_ENGINEMODE_3D: \ break; \ } \ @@ -1547,8 +1557,9 @@ do { \ radeon_cs_flush_indirect(pScrn); \ else if (info->directRenderingEnabled) \ RADEONCPFlushIndirect(pScrn, 1); \ - RADEONInit3DEngine(pScrn); \ } \ + if (!info->accel_state->XInited3D) \ + RADEONInit3DEngine(pScrn); \ info->accel_state->engineMode = EXA_ENGINEMODE_3D; \ } while (0); #else diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c index 460824d..11dde5a 100644 --- a/src/radeon_exa_funcs.c +++ b/src/radeon_exa_funcs.c @@ -131,6 +131,22 @@ static void FUNC_NAME(Emit2DState)(ScrnInfoPtr pScrn, int op) info->reemit_current2d = FUNC_NAME(Emit2DState); } +static void +FUNC_NAME(RADEONDone2D)(PixmapPtr pPix) +{ + RINFO_FROM_SCREEN(pPix->drawable.pScreen); + ACCEL_PREAMBLE(); + + TRACE; + + info->state_2d.op = 0; + BEGIN_ACCEL(2); + OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, + RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); + FINISH_ACCEL(); +} + static Bool FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) { @@ -185,6 +201,8 @@ FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) if (driver_priv) info->state_2d.dst_bo = driver_priv->bo; + info->accel_state->dst_pix = pPix; + FUNC_NAME(Emit2DState)(pScrn, RADEON_2D_EXA_SOLID); return TRUE; @@ -199,6 +217,14 @@ FUNC_NAME(RADEONSolid)(PixmapPtr pPix, int x1, int y1, int x2, int y2) TRACE; +#ifdef ACCEL_CP + if (info->cs && info->cs->cdw > 15 * 1024) { + FUNC_NAME(RADEONDone2D)(info->accel_state->dst_pix); + radeon_cs_flush_indirect(pScrn); + FUNC_NAME(Emit2DState)(pScrn, RADEON_2D_EXA_SOLID); + } +#endif + if (info->accel_state->vsync) FUNC_NAME(RADEONWaitForVLine)(pScrn, pPix, RADEONBiggerCrtcArea(pPix), y1, y2); @@ -208,22 +234,6 @@ FUNC_NAME(RADEONSolid)(PixmapPtr pPix, int x1, int y1, int x2, int y2) FINISH_ACCEL(); } -static void -FUNC_NAME(RADEONDone2D)(PixmapPtr pPix) -{ - RINFO_FROM_SCREEN(pPix->drawable.pScreen); - ACCEL_PREAMBLE(); - - TRACE; - - info->state_2d.op = 0; - BEGIN_ACCEL(2); - OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); - OUT_ACCEL_REG(RADEON_WAIT_UNTIL, - RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); - FINISH_ACCEL(); -} - void FUNC_NAME(RADEONDoPrepareCopy)(ScrnInfoPtr pScrn, uint32_t src_pitch_offset, uint32_t dst_pitch_offset, uint32_t datatype, int rop, @@ -288,6 +298,7 @@ FUNC_NAME(RADEONPrepareCopy)(PixmapPtr pSrc, PixmapPtr pDst, info->accel_state->xdir = xdir; info->accel_state->ydir = ydir; + info->accel_state->dst_pix = pDst; if (pDst->drawable.bitsPerPixel == 24) RADEON_FALLBACK(("24bpp unsupported")); @@ -315,6 +326,14 @@ FUNC_NAME(RADEONCopy)(PixmapPtr pDst, TRACE; +#ifdef ACCEL_CP + if (info->cs && info->cs->cdw > 15 * 1024) { + FUNC_NAME(RADEONDone2D)(info->accel_state->dst_pix); + radeon_cs_flush_indirect(pScrn); + FUNC_NAME(Emit2DState)(pScrn, RADEON_2D_EXA_COPY); + } +#endif + if (info->accel_state->xdir < 0) { srcX += w - 1; dstX += w - 1; diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c index 1e07408..10144a6 100644 --- a/src/radeon_exa_render.c +++ b/src/radeon_exa_render.c @@ -542,6 +542,45 @@ static Bool R100CheckComposite(int op, PicturePtr pSrcPicture, return TRUE; } + +static Bool +RADEONPrepareCompositeCS(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, + PixmapPtr pDst) +{ + RINFO_FROM_SCREEN(pDst->drawable.pScreen); + + info->accel_state->composite_op = op; + info->accel_state->dst_pic = pDstPicture; + info->accel_state->msk_pic = pMaskPicture; + info->accel_state->src_pic = pSrcPicture; + info->accel_state->dst_pix = pDst; + info->accel_state->msk_pix = pMask; + info->accel_state->src_pix = pSrc; + +#ifdef XF86DRM_MODE + if (info->cs) { + int ret; + + radeon_cs_space_reset_bos(info->cs); + + radeon_add_pixmap(info->cs, pSrc, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + + if (pMask) + radeon_add_pixmap(info->cs, pMask, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + + radeon_add_pixmap(info->cs, pDst, 0, RADEON_GEM_DOMAIN_VRAM); + + ret = radeon_cs_space_check(info->cs); + if (ret) + RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n")); + } +#endif + + return TRUE; +} + #endif /* ONLY_ONCE */ static Bool FUNC_NAME(R100PrepareComposite)(int op, @@ -557,7 +596,6 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op, uint32_t pp_cntl, blendcntl, cblend, ablend; int pixel_shift; struct radeon_exa_pixmap_priv *driver_priv; - int ret; ACCEL_PREAMBLE(); TRACE; @@ -568,11 +606,6 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op, if (pDstPicture->format == PICT_a8 && RadeonBlendOp[op].dst_alpha) RADEON_FALLBACK(("Can't dst alpha blend A8\n")); - if (pMask) - info->accel_state->has_mask = TRUE; - else - info->accel_state->has_mask = FALSE; - pixel_shift = pDst->drawable.bitsPerPixel >> 4; dst_pitch = exaGetPixmapPitch(pDst); @@ -585,28 +618,15 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op, if (((dst_pitch >> pixel_shift) & 0x7) != 0) RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); - /* switch to 3D before doing buffer space checks as it may flush */ - RADEON_SWITCH_TO_3D(); - - if (info->cs) { - radeon_cs_space_reset_bos(info->cs); - - radeon_add_pixmap(info->cs, pSrc, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); - - if (pMask) - radeon_add_pixmap(info->cs, pMask, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); - - radeon_add_pixmap(info->cs, pDst, 0, RADEON_GEM_DOMAIN_VRAM); - - ret = radeon_cs_space_check(info->cs); - if (ret) - RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n")); - } - if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE)) return FALSE; + RADEONPrepareCompositeCS(op, pSrcPicture, pMaskPicture, pDstPicture, + pSrc, pMask, pDst); + + /* switch to 3D after doing buffer space checks as the latter may flush */ + RADEON_SWITCH_TO_3D(); + if (!FUNC_NAME(R100TextureSetup)(pSrcPicture, pSrc, 0)) return FALSE; pp_cntl = RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE; @@ -905,7 +925,6 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture, uint32_t pp_cntl, blendcntl, cblend, ablend, colorpitch; int pixel_shift; struct radeon_exa_pixmap_priv *driver_priv; - int ret; ACCEL_PREAMBLE(); TRACE; @@ -916,11 +935,6 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture, if (pDstPicture->format == PICT_a8 && RadeonBlendOp[op].dst_alpha) RADEON_FALLBACK(("Can't dst alpha blend A8\n")); - if (pMask) - info->accel_state->has_mask = TRUE; - else - info->accel_state->has_mask = FALSE; - pixel_shift = pDst->drawable.bitsPerPixel >> 4; dst_pitch = exaGetPixmapPitch(pDst); @@ -933,26 +947,15 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture, if (((dst_pitch >> pixel_shift) & 0x7) != 0) RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); - /* switch to 3D before doing buffer space checks as it may flush */ - RADEON_SWITCH_TO_3D(); - - if (info->cs) { - radeon_cs_space_reset_bos(info->cs); - radeon_add_pixmap(info->cs, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); - - if (pMask) - radeon_add_pixmap(info->cs, pMask, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); - - radeon_add_pixmap(info->cs, pDst, 0, RADEON_GEM_DOMAIN_VRAM); - - ret = radeon_cs_space_check(info->cs); - if (ret) - RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n")); - } - if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE)) return FALSE; + RADEONPrepareCompositeCS(op, pSrcPicture, pMaskPicture, pDstPicture, + pSrc, pMask, pDst); + + /* switch to 3D after doing buffer space checks as it may flush */ + RADEON_SWITCH_TO_3D(); + if (!FUNC_NAME(R200TextureSetup)(pSrcPicture, pSrc, 0)) return FALSE; pp_cntl = RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE; @@ -1145,7 +1148,7 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix, txformat1 = R300TexFormats[i].card_fmt; if (IS_R300_3D) { - if ((unit == 0) && info->accel_state->has_mask) + if ((unit == 0) && info->accel_state->msk_pic) txformat1 |= R300_TX_FORMAT_CACHE_HALF_REGION_0; else if (unit == 1) txformat1 |= R300_TX_FORMAT_CACHE_HALF_REGION_1; @@ -1383,7 +1386,6 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, uint32_t src_color, src_alpha; uint32_t mask_color, mask_alpha; int pixel_shift; - int ret; struct radeon_exa_pixmap_priv *driver_priv; ACCEL_PREAMBLE(); TRACE; @@ -1391,11 +1393,6 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, if (!R300GetDestFormat(pDstPicture, &dst_format)) return FALSE; - if (pMask) - info->accel_state->has_mask = TRUE; - else - info->accel_state->has_mask = FALSE; - pixel_shift = pDst->drawable.bitsPerPixel >> 4; dst_pitch = exaGetPixmapPitch(pDst); @@ -1411,26 +1408,15 @@ 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)); - /* have to execute switch before doing buffer sizing check as it flushes */ - RADEON_SWITCH_TO_3D(); - - if (info->cs) { - radeon_cs_space_reset_bos(info->cs); - radeon_add_pixmap(info->cs, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); - - if (pMask) - radeon_add_pixmap(info->cs, pMask, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); - - radeon_add_pixmap(info->cs, pDst, 0, RADEON_GEM_DOMAIN_VRAM); - - ret = radeon_cs_space_check(info->cs); - if (ret) - RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n")); - } - if (!RADEONSetupSourceTile(pSrcPicture, pSrc, TRUE, FALSE)) return FALSE; + RADEONPrepareCompositeCS(op, pSrcPicture, pMaskPicture, pDstPicture, + pSrc, pMask, pDst); + + /* have to execute switch after doing buffer sizing check as the latter flushes */ + RADEON_SWITCH_TO_3D(); + if (!FUNC_NAME(R300TextureSetup)(pSrcPicture, pSrc, 0)) return FALSE; txenable = R300_TEX_0_ENABLE; @@ -2027,7 +2013,7 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, FINISH_ACCEL(); BEGIN_ACCEL(1); - if (info->accel_state->has_mask) + if (pMask) OUT_ACCEL_REG(R300_VAP_VTX_SIZE, 6); else OUT_ACCEL_REG(R300_VAP_VTX_SIZE, 4); @@ -2036,6 +2022,25 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, return TRUE; } +static void FUNC_NAME(RadeonDoneComposite)(PixmapPtr pDst) +{ + RINFO_FROM_SCREEN(pDst->drawable.pScreen); + ACCEL_PREAMBLE(); + + ENTER_DRAW(0); + + if (IS_R300_3D || IS_R500_3D) { + BEGIN_ACCEL(3); + OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xAAAA); + OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FLUSH_ALL); + } else + BEGIN_ACCEL(1); + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); + FINISH_ACCEL(); + + LEAVE_DRAW(0); +} + #ifdef ACCEL_CP @@ -2110,6 +2115,20 @@ static void FUNC_NAME(RadeonCompositeTile)(ScrnInfoPtr pScrn, /* ErrorF("RadeonComposite (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", srcX, srcY, maskX, maskY,dstX, dstY, w, h); */ +#ifdef ACCEL_CP + if (info->cs && info->cs->cdw > 15 * 1024) { + FUNC_NAME(RadeonDoneComposite)(info->accel_state->dst_pix); + radeon_cs_flush_indirect(pScrn); + info->accel_state->exa->PrepareComposite(info->accel_state->composite_op, + info->accel_state->dst_pic, + info->accel_state->msk_pic, + info->accel_state->src_pic, + info->accel_state->dst_pix, + info->accel_state->msk_pix, + info->accel_state->src_pix); + } +#endif + srcTopLeft.x = IntToxFixed(srcX); srcTopLeft.y = IntToxFixed(srcY); srcTopRight.x = IntToxFixed(srcX + w); @@ -2128,7 +2147,7 @@ static void FUNC_NAME(RadeonCompositeTile)(ScrnInfoPtr pScrn, } } - if (info->accel_state->has_mask) { + if (info->accel_state->msk_pic) { maskTopLeft.x = IntToxFixed(maskX); maskTopLeft.y = IntToxFixed(maskY); maskTopRight.x = IntToxFixed(maskX + w); @@ -2159,7 +2178,7 @@ static void FUNC_NAME(RadeonCompositeTile)(ScrnInfoPtr pScrn, BEGIN_RING(3 * vtx_count + 3); OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_3D_DRAW_IMMD, 3 * vtx_count + 1)); - if (info->accel_state->has_mask) + if (info->accel_state->msk_pic) OUT_RING(RADEON_CP_VC_FRMT_XY | RADEON_CP_VC_FRMT_ST0 | RADEON_CP_VC_FRMT_ST1); @@ -2209,7 +2228,7 @@ static void FUNC_NAME(RadeonCompositeTile)(ScrnInfoPtr pScrn, #endif - if (info->accel_state->has_mask) { + if (info->accel_state->msk_pic) { if (IS_R300_3D || IS_R500_3D) { VTX_OUT_MASK((float)dstX, (float)dstY, xFixedToFloat(srcTopLeft.x) / info->accel_state->texW[0], xFixedToFloat(srcTopLeft.y) / info->accel_state->texH[0], @@ -2317,24 +2336,5 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst, } } -static void FUNC_NAME(RadeonDoneComposite)(PixmapPtr pDst) -{ - RINFO_FROM_SCREEN(pDst->drawable.pScreen); - ACCEL_PREAMBLE(); - - ENTER_DRAW(0); - - if (IS_R300_3D || IS_R500_3D) { - BEGIN_ACCEL(3); - OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xAAAA); - OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FLUSH_ALL); - } else - BEGIN_ACCEL(1); - OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); - FINISH_ACCEL(); - - LEAVE_DRAW(0); -} - #undef ONLY_ONCE #undef FUNC_NAME