diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-04-16 20:40:56 -0400 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2010-04-16 20:40:56 -0400 |
commit | 57577d5cd0641b7cad02242478699bcfece59227 (patch) | |
tree | 102e881fc09ae78540b529c32e56987cee938000 | |
parent | 31a888e78fa403f2bddacee098a29f36eaa969cb (diff) |
r1xx texvid: deal with large numbers of verts
should fix fdo bug 25884
-rw-r--r-- | src/radeon.h | 1 | ||||
-rw-r--r-- | src/radeon_accel.c | 12 | ||||
-rw-r--r-- | src/radeon_textured_videofuncs.c | 121 |
3 files changed, 104 insertions, 30 deletions
diff --git a/src/radeon.h b/src/radeon.h index 961c59e0..859224c3 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -1138,6 +1138,7 @@ extern Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen); # endif uint32_t radeonGetPixmapOffset(PixmapPtr pPix); #endif +extern 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 0250d912..823f91d6 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 0bf7a108..270d0dc6 100644 --- a/src/radeon_textured_videofuncs.c +++ b/src/radeon_textured_videofuncs.c @@ -342,6 +342,23 @@ FUNC_NAME(RADEONPrepareTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv (scissor_h << RADEON_RE_HEIGHT_SHIFT))); FINISH_ACCEL(); + if (pPriv->vsync) { + xf86CrtcPtr crtc; + if (pPriv->desired_crtc) + crtc = pPriv->desired_crtc; + else + crtc = radeon_pick_best_crtc(pScrn, + pPriv->drw_x, + pPriv->drw_x + pPriv->dst_w, + pPriv->drw_y, + pPriv->drw_y + pPriv->dst_h); + if (crtc) + FUNC_NAME(RADEONWaitForVLine)(pScrn, pPixmap, + crtc, + pPriv->drw_y - crtc->y, + (pPriv->drw_y - crtc->y) + pPriv->dst_h); + } + return TRUE; } @@ -366,22 +383,6 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv if (!FUNC_NAME(RADEONPrepareTexturedVideo)(pScrn, pPriv)) return; - if (pPriv->vsync) { - xf86CrtcPtr crtc; - if (pPriv->desired_crtc) - crtc = pPriv->desired_crtc; - else - crtc = radeon_pick_best_crtc(pScrn, - pPriv->drw_x, - pPriv->drw_x + pPriv->dst_w, - pPriv->drw_y, - pPriv->drw_y + pPriv->dst_h); - if (crtc) - FUNC_NAME(RADEONWaitForVLine)(pScrn, pPixmap, - crtc, - pPriv->drw_y - crtc->y, - (pPriv->drw_y - crtc->y) + pPriv->dst_h); - } /* * Rendering of the actual polygon is done in two different * ways depending on chip generation: @@ -401,11 +402,25 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv * the single triangle up to 2560/4021 pixels; above that we * render as a quad. */ - #ifdef ACCEL_CP - BEGIN_RING(nBox * 3 * pPriv->vtx_count + 5); + while (nBox) { + int draw_size = 3 * pPriv->vtx_count + 5; + int loop_boxes; + + if (draw_size > radeon_cs_space_remaining(pScrn)) { + if (info->cs) + radeon_cs_flush_indirect(pScrn); + else + RADEONCPFlushIndirect(pScrn, 1); + if (!FUNC_NAME(RADEONPrepareTexturedVideo)(pScrn, pPriv)) + return; + } + loop_boxes = MIN(radeon_cs_space_remaining(pScrn) / draw_size, nBox); + nBox -= loop_boxes; + + BEGIN_RING(loop_boxes * 3 * pPriv->vtx_count + 5); OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_3D_DRAW_IMMD, - nBox * 3 * pPriv->vtx_count + 1)); + loop_boxes * 3 * pPriv->vtx_count + 1)); if (pPriv->is_planar) OUT_RING(RADEON_CP_VC_FRMT_XY | RADEON_CP_VC_FRMT_ST0 | @@ -417,15 +432,64 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv 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)); -#else /* ACCEL_CP */ - BEGIN_ACCEL(nBox * pPriv->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))); -#endif + ((loop_boxes * 3) << RADEON_CP_VC_CNTL_NUM_SHIFT)); + + while (loop_boxes--) { + 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 (pPriv->is_planar) { + /* + * 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++; + } + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); + ADVANCE_RING(); + } +#else /* ACCEL_CP */ + BEGIN_ACCEL(nBox * pPriv->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))); while (nBox--) { int srcX, srcY, srcw, srch; int dstX, dstY, dstw, dsth; @@ -474,9 +538,6 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv } OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); -#ifdef ACCEL_CP - ADVANCE_RING(); -#else FINISH_ACCEL(); #endif /* !ACCEL_CP */ |