diff --git a/src/radeon.h b/src/radeon.h index 221d6e7..b1e5d67 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -1136,6 +1136,7 @@ extern Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen); # endif uint32_t radeonGetPixmapOffset(PixmapPtr pPix); #endif +int radeon_cs_space_remaining(ScrnInfoPtr pScrn); #ifdef USE_XAA /* radeon_accelfuncs.c */ diff --git a/src/radeon_accel.c b/src/radeon_accel.c index 0250d91..c3f3ff4 100644 --- a/src/radeon_accel.c +++ b/src/radeon_accel.c @@ -573,6 +573,18 @@ uint32_t radeonGetPixmapOffset(PixmapPtr pPix) return offset; } +int radeon_cs_space_remaining(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + +#ifdef XF86DRM_MODE + if (info->cs) + return (info->cs->ndw - info->cs->cdw); + else +#endif + return (info->cp->indirectBuffer->total - info->cp->indirectBuffer->used) / (int)sizeof(uint32_t); +} + #define ACCEL_MMIO #define ACCEL_PREAMBLE() unsigned char *RADEONMMIO = info->MMIO #define BEGIN_ACCEL(n) RADEONWaitForFifo(pScrn, (n)) diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c index f967331..cb1dcb9 100644 --- a/src/radeon_textured_videofuncs.c +++ b/src/radeon_textured_videofuncs.c @@ -99,6 +99,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv uint32_t colorpitch; Bool isplanar = FALSE; int dstxoff, dstyoff, pixel_shift, vtx_count; + int loops, nBox_loop, i; BoxPtr pBox = REGION_RECTS(&pPriv->clip); int nBox = REGION_NUM_RECTS(&pPriv->clip); ACCEL_PREAMBLE(); @@ -391,83 +392,94 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv * render as a quad. */ + if (radeon_cs_space_remaining(pScrn) > (nBox * 3 * vtx_count + 5)) { + loops = 1; + nBox_loop = nBox; + } else { + loops = nBox; + nBox_loop = 1; + } + + for (i = 0; i < loops; i++) { #ifdef ACCEL_CP - BEGIN_RING(nBox * 3 * vtx_count + 5); + BEGIN_RING(nBox_loop * 3 * vtx_count + 5); OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_3D_DRAW_IMMD, - nBox * 3 * vtx_count + 1)); + nBox_loop * 3 * vtx_count + 1)); if (isplanar) OUT_RING(RADEON_CP_VC_FRMT_XY | RADEON_CP_VC_FRMT_ST0 | RADEON_CP_VC_FRMT_ST1); else - OUT_RING(RADEON_CP_VC_FRMT_XY | - RADEON_CP_VC_FRMT_ST0); + OUT_RING(RADEON_CP_VC_FRMT_XY | + RADEON_CP_VC_FRMT_ST0); OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST | RADEON_CP_VC_CNTL_PRIM_WALK_RING | RADEON_CP_VC_CNTL_MAOS_ENABLE | RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | - ((nBox * 3) << RADEON_CP_VC_CNTL_NUM_SHIFT)); + ((nBox_loop * 3) << RADEON_CP_VC_CNTL_NUM_SHIFT)); #else /* ACCEL_CP */ - BEGIN_ACCEL(nBox * vtx_count * 3 + 2); + BEGIN_ACCEL(nBox_loop * vtx_count * 3 + 2); OUT_ACCEL_REG(RADEON_SE_VF_CNTL, (RADEON_VF_PRIM_TYPE_RECTANGLE_LIST | RADEON_VF_PRIM_WALK_DATA | RADEON_VF_RADEON_MODE | - ((nBox * 3) << RADEON_VF_NUM_VERTICES_SHIFT))); + ((nBox_loop * 3) << RADEON_VF_NUM_VERTICES_SHIFT))); #endif - while (nBox--) { - int srcX, srcY, srcw, srch; - int dstX, dstY, dstw, dsth; - dstX = pBox->x1 + dstxoff; - dstY = pBox->y1 + dstyoff; - dstw = pBox->x2 - pBox->x1; - dsth = pBox->y2 - pBox->y1; + while (nBox_loop--) { + int srcX, srcY, srcw, srch; + int dstX, dstY, dstw, dsth; + dstX = pBox->x1 + dstxoff; + dstY = pBox->y1 + dstyoff; + dstw = pBox->x2 - pBox->x1; + dsth = pBox->y2 - pBox->y1; - srcX = pPriv->src_x; - srcX += ((pBox->x1 - pPriv->drw_x) * - pPriv->src_w) / pPriv->dst_w; - srcY = pPriv->src_y; - srcY += ((pBox->y1 - pPriv->drw_y) * - pPriv->src_h) / pPriv->dst_h; + srcX = pPriv->src_x; + srcX += ((pBox->x1 - pPriv->drw_x) * + pPriv->src_w) / pPriv->dst_w; + srcY = pPriv->src_y; + srcY += ((pBox->y1 - pPriv->drw_y) * + pPriv->src_h) / pPriv->dst_h; - srcw = (pPriv->src_w * dstw) / pPriv->dst_w; - srch = (pPriv->src_h * dsth) / pPriv->dst_h; + srcw = (pPriv->src_w * dstw) / pPriv->dst_w; + srch = (pPriv->src_h * dsth) / pPriv->dst_h; - if (isplanar) { - /* - * Just render a rect (using three coords). - */ - VTX_OUT_6((float)dstX, (float)(dstY + dsth), - (float)srcX / pPriv->w, (float)(srcY + srch) / pPriv->h, - (float)srcX / pPriv->w, (float)(srcY + srch) / pPriv->h); - VTX_OUT_6((float)(dstX + dstw), (float)(dstY + dsth), - (float)(srcX + srcw) / pPriv->w, (float)(srcY + srch) / pPriv->h, - (float)(srcX + srcw) / pPriv->w, (float)(srcY + srch) / pPriv->h); - VTX_OUT_6((float)(dstX + dstw), (float)dstY, - (float)(srcX + srcw) / pPriv->w, (float)srcY / pPriv->h, - (float)(srcX + srcw) / pPriv->w, (float)srcY / pPriv->h); - } else { - /* - * Just render a rect (using three coords). - */ - VTX_OUT_4((float)dstX, (float)(dstY + dsth), - (float)srcX / pPriv->w, (float)(srcY + srch) / pPriv->h); - VTX_OUT_4((float)(dstX + dstw), (float)(dstY + dsth), - (float)(srcX + srcw) / pPriv->w, (float)(srcY + srch) / pPriv->h); - VTX_OUT_4((float)(dstX + dstw), (float)dstY, - (float)(srcX + srcw) / pPriv->w, (float)srcY / pPriv->h); - } + if (isplanar) { + /* + * Just render a rect (using three coords). + */ + VTX_OUT_6((float)dstX, (float)(dstY + dsth), + (float)srcX / pPriv->w, (float)(srcY + srch) / pPriv->h, + (float)srcX / pPriv->w, (float)(srcY + srch) / pPriv->h); + VTX_OUT_6((float)(dstX + dstw), (float)(dstY + dsth), + (float)(srcX + srcw) / pPriv->w, (float)(srcY + srch) / pPriv->h, + (float)(srcX + srcw) / pPriv->w, (float)(srcY + srch) / pPriv->h); + VTX_OUT_6((float)(dstX + dstw), (float)dstY, + (float)(srcX + srcw) / pPriv->w, (float)srcY / pPriv->h, + (float)(srcX + srcw) / pPriv->w, (float)srcY / pPriv->h); + } else { + /* + * Just render a rect (using three coords). + */ + VTX_OUT_4((float)dstX, (float)(dstY + dsth), + (float)srcX / pPriv->w, (float)(srcY + srch) / pPriv->h); + VTX_OUT_4((float)(dstX + dstw), (float)(dstY + dsth), + (float)(srcX + srcw) / pPriv->w, (float)(srcY + srch) / pPriv->h); + VTX_OUT_4((float)(dstX + dstw), (float)dstY, + (float)(srcX + srcw) / pPriv->w, (float)srcY / pPriv->h); + } - pBox++; - } + pBox++; + } + nBox_loop = 1; - OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); #ifdef ACCEL_CP ADVANCE_RING(); #else FINISH_ACCEL(); #endif /* !ACCEL_CP */ + } DamageDamageRegion(pPriv->pDraw, &pPriv->clip); } @@ -485,6 +497,7 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) uint32_t colorpitch; Bool isplanar = FALSE; int dstxoff, dstyoff, pixel_shift, vtx_count; + int loops, nBox_loop, i; BoxPtr pBox = REGION_RECTS(&pPriv->clip); int nBox = REGION_NUM_RECTS(&pPriv->clip); @@ -959,74 +972,85 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) * render as a quad. */ + if (radeon_cs_space_remaining(pScrn) > (nBox * 3 * vtx_count + 4)) { + loops = 1; + nBox_loop = nBox; + } else { + loops = nBox; + nBox_loop = 1; + } + + for (i = 0; i < loops; i++) { #ifdef ACCEL_CP - BEGIN_RING(nBox * 3 * vtx_count + 4); + BEGIN_RING(nBox_loop * 3 * vtx_count + 4); OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2, nBox * 3 * vtx_count)); OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST | RADEON_CP_VC_CNTL_PRIM_WALK_RING | - ((nBox * 3) << RADEON_CP_VC_CNTL_NUM_SHIFT)); + ((nBox_loop * 3) << RADEON_CP_VC_CNTL_NUM_SHIFT)); #else /* ACCEL_CP */ - BEGIN_ACCEL(nBox * 3 * vtx_count + 2); + BEGIN_ACCEL(nBox_loop * 3 * vtx_count + 2); OUT_ACCEL_REG(RADEON_SE_VF_CNTL, (RADEON_VF_PRIM_TYPE_RECTANGLE_LIST | RADEON_VF_PRIM_WALK_DATA | - ((nBox * 3) << RADEON_VF_NUM_VERTICES_SHIFT))); + ((nBox_loop * 3) << RADEON_VF_NUM_VERTICES_SHIFT))); #endif - while (nBox--) { - int srcX, srcY, srcw, srch; - int dstX, dstY, dstw, dsth; - dstX = pBox->x1 + dstxoff; - dstY = pBox->y1 + dstyoff; - dstw = pBox->x2 - pBox->x1; - dsth = pBox->y2 - pBox->y1; - - srcX = pPriv->src_x; - srcX += ((pBox->x1 - pPriv->drw_x) * - pPriv->src_w) / pPriv->dst_w; - srcY = pPriv->src_y; - srcY += ((pBox->y1 - pPriv->drw_y) * - pPriv->src_h) / pPriv->dst_h; - - srcw = (pPriv->src_w * dstw) / pPriv->dst_w; - srch = (pPriv->src_h * dsth) / pPriv->dst_h; + while (nBox_loop--) { + int srcX, srcY, srcw, srch; + int dstX, dstY, dstw, dsth; + dstX = pBox->x1 + dstxoff; + dstY = pBox->y1 + dstyoff; + dstw = pBox->x2 - pBox->x1; + dsth = pBox->y2 - pBox->y1; + + srcX = pPriv->src_x; + srcX += ((pBox->x1 - pPriv->drw_x) * + pPriv->src_w) / pPriv->dst_w; + srcY = pPriv->src_y; + srcY += ((pBox->y1 - pPriv->drw_y) * + pPriv->src_h) / pPriv->dst_h; + + srcw = (pPriv->src_w * dstw) / pPriv->dst_w; + srch = (pPriv->src_h * dsth) / pPriv->dst_h; + + if (isplanar) { + /* + * Just render a rect (using three coords). + */ + VTX_OUT_6((float)dstX, (float)(dstY + dsth), + (float)srcX / pPriv->w, (float)(srcY + srch) / pPriv->h, + (float)srcX / pPriv->w, (float)(srcY + srch) / pPriv->h); + VTX_OUT_6((float)(dstX + dstw), (float)(dstY + dsth), + (float)(srcX + srcw) / pPriv->w, (float)(srcY + srch) / pPriv->h, + (float)(srcX + srcw) / pPriv->w, (float)(srcY + srch) / pPriv->h); + VTX_OUT_6((float)(dstX + dstw), (float)dstY, + (float)(srcX + srcw) / pPriv->w, (float)srcY / pPriv->h, + (float)(srcX + srcw) / pPriv->w, (float)srcY / pPriv->h); + } else { + /* + * Just render a rect (using three coords). + */ + VTX_OUT_4((float)dstX, (float)(dstY + dsth), + (float)srcX / pPriv->w, (float)(srcY + srch) / pPriv->h); + VTX_OUT_4((float)(dstX + dstw), (float)(dstY + dsth), + (float)(srcX + srcw) / pPriv->w, (float)(srcY + srch) / pPriv->h); + VTX_OUT_4((float)(dstX + dstw), (float)dstY, + (float)(srcX + srcw) / pPriv->w, (float)srcY / pPriv->h); + } - if (isplanar) { - /* - * Just render a rect (using three coords). - */ - VTX_OUT_6((float)dstX, (float)(dstY + dsth), - (float)srcX / pPriv->w, (float)(srcY + srch) / pPriv->h, - (float)srcX / pPriv->w, (float)(srcY + srch) / pPriv->h); - VTX_OUT_6((float)(dstX + dstw), (float)(dstY + dsth), - (float)(srcX + srcw) / pPriv->w, (float)(srcY + srch) / pPriv->h, - (float)(srcX + srcw) / pPriv->w, (float)(srcY + srch) / pPriv->h); - VTX_OUT_6((float)(dstX + dstw), (float)dstY, - (float)(srcX + srcw) / pPriv->w, (float)srcY / pPriv->h, - (float)(srcX + srcw) / pPriv->w, (float)srcY / pPriv->h); - } else { - /* - * Just render a rect (using three coords). - */ - VTX_OUT_4((float)dstX, (float)(dstY + dsth), - (float)srcX / pPriv->w, (float)(srcY + srch) / pPriv->h); - VTX_OUT_4((float)(dstX + dstw), (float)(dstY + dsth), - (float)(srcX + srcw) / pPriv->w, (float)(srcY + srch) / pPriv->h); - VTX_OUT_4((float)(dstX + dstw), (float)dstY, - (float)(srcX + srcw) / pPriv->w, (float)srcY / pPriv->h); + pBox++; } + nBox_loop = 1; - pBox++; - } - - OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); #ifdef ACCEL_CP ADVANCE_RING(); #else FINISH_ACCEL(); #endif /* !ACCEL_CP */ + } DamageDamageRegion(pPriv->pDraw, &pPriv->clip); }