summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-04-16 20:40:56 -0400
committerAlex Deucher <alexdeucher@gmail.com>2010-04-16 20:40:56 -0400
commit57577d5cd0641b7cad02242478699bcfece59227 (patch)
tree102e881fc09ae78540b529c32e56987cee938000
parent31a888e78fa403f2bddacee098a29f36eaa969cb (diff)
r1xx texvid: deal with large numbers of verts
should fix fdo bug 25884
-rw-r--r--src/radeon.h1
-rw-r--r--src/radeon_accel.c12
-rw-r--r--src/radeon_textured_videofuncs.c121
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 */