xf86-video-ati: Branch 'r6xx-r7xx-support'

Alex Deucher agd5f at kemper.freedesktop.org
Wed Feb 18 17:06:09 PST 2009


 src/r600_exa.c                 |   69 +++++++++---------------
 src/r600_textured_videofuncs.c |  116 ++++++++++++++++++++---------------------
 src/r6xx_accel.c               |    2 
 3 files changed, 87 insertions(+), 100 deletions(-)

New commits:
commit adff8906c9899dde7711382577a63f4a726437ca
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Feb 18 20:01:57 2009 -0500

    R6xx/R7xx EXA/Xv: properly deal with running out of vertex buffer space
    
    As noted by mhopf, if VGT_MAX/MIN_INDX, etc. regs change, you need to re-emit
    CB blocks to avoid a hang.  So, just set the VGT_MAX_INDX to a reasonably large value
    in the default state and don't touch them when drawing.  When we run out of VB space,
    just draw the current buffer, grab a new one, and continue.

diff --git a/src/r600_exa.c b/src/r600_exa.c
index 5b17dcb..a252fb6 100644
--- a/src/r600_exa.c
+++ b/src/r600_exa.c
@@ -79,6 +79,13 @@ uint32_t RADEON_ROP[16] = {
     RADEON_ROP3_ONE,  /* GXset          */
 };
 
+static void
+R600DoneSolid(PixmapPtr pPix);
+
+static void
+R600DoneComposite(PixmapPtr pDst);
+
+
 static Bool
 R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
 {
@@ -260,13 +267,16 @@ R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
     RADEONInfoPtr info = RADEONPTR(pScrn);
     struct radeon_accel_state *accel_state = info->accel_state;
     struct r6xx_solid_vertex vertex[3];
-    struct r6xx_solid_vertex *solid_vb = (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
+    struct r6xx_solid_vertex *solid_vb;
 
     if (((accel_state->vb_index + 3) * 8) > (accel_state->ib->total / 2)) {
-	ErrorF("Solid: Ran out of VB space!\n");
-	return;
+	R600DoneSolid(pPix);
+	accel_state->vb_index = 0;
+	accel_state->ib = RADEONCPGetBuffer(pScrn);
     }
 
+    solid_vb = (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
+
     vertex[0].x = (float)x1;
     vertex[0].y = (float)y1;
 
@@ -335,13 +345,6 @@ R600DoneSolid(PixmapPtr pPix)
     draw_conf.num_indices        = vtx_res.vtx_num_entries / vtx_res.vtx_size_dw;
     draw_conf.index_type         = DI_INDEX_SIZE_16_BIT;
 
-    ereg  (accel_state->ib, VGT_INSTANCE_STEP_RATE_0,            0);	/* ? */
-    ereg  (accel_state->ib, VGT_INSTANCE_STEP_RATE_1,            0);
-
-    ereg  (accel_state->ib, VGT_MAX_VTX_INDX,                    draw_conf.num_indices);
-    ereg  (accel_state->ib, VGT_MIN_VTX_INDX,                    0);
-    ereg  (accel_state->ib, VGT_INDX_OFFSET,                     0);
-
     draw_auto(pScrn, accel_state->ib, &draw_conf);
 
     wait_3d_idle_clean(pScrn, accel_state->ib);
@@ -581,13 +584,6 @@ R600DoCopy(ScrnInfoPtr pScrn)
     draw_conf.num_indices        = vtx_res.vtx_num_entries / vtx_res.vtx_size_dw;
     draw_conf.index_type         = DI_INDEX_SIZE_16_BIT;
 
-    ereg  (accel_state->ib, VGT_INSTANCE_STEP_RATE_0,            0);	/* ? */
-    ereg  (accel_state->ib, VGT_INSTANCE_STEP_RATE_1,            0);
-
-    ereg  (accel_state->ib, VGT_MAX_VTX_INDX,                    draw_conf.num_indices);
-    ereg  (accel_state->ib, VGT_MIN_VTX_INDX,                    0);
-    ereg  (accel_state->ib, VGT_INDX_OFFSET,                     0);
-
     draw_auto(pScrn, accel_state->ib, &draw_conf);
 
     wait_3d_idle_clean(pScrn, accel_state->ib);
@@ -611,17 +607,9 @@ R600AppendCopyVertex(ScrnInfoPtr pScrn,
     struct r6xx_copy_vertex vertex[3];
 
     if (((accel_state->vb_index + 3) * 16) > (accel_state->ib->total / 2)) {
-	//ErrorF("Copy: Ran out of VB space!\n");
-	// emit the old VB
 	R600DoCopy(pScrn);
-	// start a new one
-	R600DoPrepareCopy(pScrn,
-			  accel_state->src_pitch[0], accel_state->src_width[0], accel_state->src_height[0],
-			  accel_state->src_mc_addr[0], accel_state->src_bpp[0],
-			  accel_state->dst_pitch, accel_state->dst_height,
-			  accel_state->dst_mc_addr, accel_state->dst_bpp,
-			  accel_state->rop, accel_state->planemask);
-
+	accel_state->vb_index = 0;
+	accel_state->ib = RADEONCPGetBuffer(pScrn);
     }
 
     copy_vb = (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
@@ -1950,16 +1938,18 @@ static void R600Composite(PixmapPtr pDst,
     }
 
     if (accel_state->has_mask) {
-	struct r6xx_comp_mask_vertex *comp_vb =
-	    (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
+	struct r6xx_comp_mask_vertex *comp_vb;
 	struct r6xx_comp_mask_vertex vertex[3];
 	xPointFixed maskTopLeft, maskTopRight, maskBottomLeft, maskBottomRight;
 
 	if (((accel_state->vb_index + 3) * 24) > (accel_state->ib->total / 2)) {
-	    ErrorF("Composite: Ran out of VB space!\n");
-	    return;
+	    R600DoneComposite(pDst);
+	    accel_state->vb_index = 0;
+	    accel_state->ib = RADEONCPGetBuffer(pScrn);
 	}
 
+	comp_vb = (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
+
 	maskTopLeft.x     = IntToxFixed(maskX);
 	maskTopLeft.y     = IntToxFixed(maskY);
 	maskTopRight.x    = IntToxFixed(maskX + w);
@@ -2012,15 +2002,17 @@ static void R600Composite(PixmapPtr pDst,
 	comp_vb[accel_state->vb_index++] = vertex[2];
 
     } else {
-	struct r6xx_comp_vertex *comp_vb =
-	    (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
+	struct r6xx_comp_vertex *comp_vb;
 	struct r6xx_comp_vertex vertex[3];
 
 	if (((accel_state->vb_index + 3) * 16) > (accel_state->ib->total / 2)) {
-	    ErrorF("Composite: Ran out of VB space!\n");
-	    return;
+	    R600DoneComposite(pDst);
+	    accel_state->vb_index = 0;
+	    accel_state->ib = RADEONCPGetBuffer(pScrn);
 	}
 
+	comp_vb = (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
+
 	vertex[0].x = (float)dstX;
 	vertex[0].y = (float)dstY;
 	vertex[0].src_s = xFixedToFloat(srcTopLeft.x) / accel_state->texW[0];
@@ -2106,13 +2098,6 @@ static void R600DoneComposite(PixmapPtr pDst)
     draw_conf.num_indices        = vtx_res.vtx_num_entries / vtx_res.vtx_size_dw;
     draw_conf.index_type         = DI_INDEX_SIZE_16_BIT;
 
-    ereg  (accel_state->ib, VGT_INSTANCE_STEP_RATE_0,            0);	/* ? */
-    ereg  (accel_state->ib, VGT_INSTANCE_STEP_RATE_1,            0);
-
-    ereg  (accel_state->ib, VGT_MAX_VTX_INDX,                    draw_conf.num_indices);
-    ereg  (accel_state->ib, VGT_MIN_VTX_INDX,                    0);
-    ereg  (accel_state->ib, VGT_INDX_OFFSET,                     0);
-
     draw_auto(pScrn, accel_state->ib, &draw_conf);
 
     wait_3d_idle_clean(pScrn, accel_state->ib);
diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c
index aca6412..c2b0e75 100644
--- a/src/r600_textured_videofuncs.c
+++ b/src/r600_textured_videofuncs.c
@@ -44,6 +44,61 @@
 
 #include "damage.h"
 
+void
+R600DoneTexturedVideo(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    struct radeon_accel_state *accel_state = info->accel_state;
+    draw_config_t   draw_conf;
+    vtx_resource_t  vtx_res;
+
+    CLEAR (draw_conf);
+    CLEAR (vtx_res);
+
+    if (accel_state->vb_index == 0) {
+	R600IBDiscard(pScrn, accel_state->ib);
+	return;
+    }
+
+    accel_state->vb_mc_addr = info->gartLocation + info->dri->bufStart +
+	(accel_state->ib->idx * accel_state->ib->total) + (accel_state->ib->total / 2);
+    accel_state->vb_size = accel_state->vb_index * 16;
+
+    /* flush vertex cache */
+    if ((info->ChipFamily == CHIP_FAMILY_RV610) ||
+	(info->ChipFamily == CHIP_FAMILY_RV620) ||
+	(info->ChipFamily == CHIP_FAMILY_RS780) ||
+	(info->ChipFamily == CHIP_FAMILY_RV710))
+	cp_set_surface_sync(pScrn, accel_state->ib, TC_ACTION_ENA_bit,
+			    accel_state->vb_size, accel_state->vb_mc_addr);
+    else
+	cp_set_surface_sync(pScrn, accel_state->ib, VC_ACTION_ENA_bit,
+			    accel_state->vb_size, accel_state->vb_mc_addr);
+
+    /* Vertex buffer setup */
+    vtx_res.id              = SQ_VTX_RESOURCE_vs;
+    vtx_res.vtx_size_dw     = 16 / 4;
+    vtx_res.vtx_num_entries = accel_state->vb_size / 4;
+    vtx_res.mem_req_size    = 1;
+    vtx_res.vb_addr         = accel_state->vb_mc_addr;
+    set_vtx_resource        (pScrn, accel_state->ib, &vtx_res);
+
+    draw_conf.prim_type          = DI_PT_RECTLIST;
+    draw_conf.vgt_draw_initiator = DI_SRC_SEL_AUTO_INDEX;
+    draw_conf.num_instances      = 1;
+    draw_conf.num_indices        = vtx_res.vtx_num_entries / vtx_res.vtx_size_dw;
+    draw_conf.index_type         = DI_INDEX_SIZE_16_BIT;
+
+    draw_auto(pScrn, accel_state->ib, &draw_conf);
+
+    wait_3d_idle_clean(pScrn, accel_state->ib);
+
+    /* sync destination surface */
+    cp_set_surface_sync(pScrn, accel_state->ib, (CB_ACTION_ENA_bit | CB0_DEST_BASE_ENA_bit),
+			accel_state->dst_size, accel_state->dst_mc_addr);
+
+    R600CPFlushIndirect(pScrn, accel_state->ib);
+}
 
 void
 R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
@@ -58,8 +113,6 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
     tex_resource_t  tex_res;
     tex_sampler_t   tex_samp;
     shader_config_t vs_conf, ps_conf;
-    draw_config_t   draw_conf;
-    vtx_resource_t  vtx_res;
     int uv_offset;
 
     static float ps_alu_consts[] = {
@@ -80,8 +133,6 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
     CLEAR (tex_samp);
     CLEAR (vs_conf);
     CLEAR (ps_conf);
-    CLEAR (draw_conf);
-    CLEAR (vtx_res);
 
     accel_state->dst_pitch = exaGetPixmapPitch(pPixmap) / (pPixmap->drawable.bitsPerPixel / 8);
     accel_state->src_pitch[0] = pPriv->src_pitch;
@@ -415,8 +466,9 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
 	struct r6xx_copy_vertex vertex[3];
 
 	if (((accel_state->vb_index + 3) * 16) > (accel_state->ib->total / 2)) {
-	    ErrorF("Xv: Ran out of VB space!\n");
-	    break;
+	    R600DoneTexturedVideo(pScrn);
+	    accel_state->vb_index = 0;
+	    accel_state->ib = RADEONCPGetBuffer(pScrn);
 	}
 
 	dstX = pBox->x1 + dstxoff;
@@ -461,57 +513,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
 	pBox++;
     }
 
-    if (accel_state->vb_index == 0) {
-	R600IBDiscard(pScrn, accel_state->ib);
-	DamageDamageRegion(pPriv->pDraw, &pPriv->clip);
-	return;
-    }
-
-    accel_state->vb_mc_addr = info->gartLocation + info->dri->bufStart +
-	(accel_state->ib->idx * accel_state->ib->total) + (accel_state->ib->total / 2);
-    accel_state->vb_size = accel_state->vb_index * 16;
-
-    /* flush vertex cache */
-    if ((info->ChipFamily == CHIP_FAMILY_RV610) ||
-	(info->ChipFamily == CHIP_FAMILY_RV620) ||
-	(info->ChipFamily == CHIP_FAMILY_RS780) ||
-	(info->ChipFamily == CHIP_FAMILY_RV710))
-	cp_set_surface_sync(pScrn, accel_state->ib, TC_ACTION_ENA_bit,
-			    accel_state->vb_size, accel_state->vb_mc_addr);
-    else
-	cp_set_surface_sync(pScrn, accel_state->ib, VC_ACTION_ENA_bit,
-			    accel_state->vb_size, accel_state->vb_mc_addr);
-
-    /* Vertex buffer setup */
-    vtx_res.id              = SQ_VTX_RESOURCE_vs;
-    vtx_res.vtx_size_dw     = 16 / 4;
-    vtx_res.vtx_num_entries = accel_state->vb_size / 4;
-    vtx_res.mem_req_size    = 1;
-    vtx_res.vb_addr         = accel_state->vb_mc_addr;
-    set_vtx_resource        (pScrn, accel_state->ib, &vtx_res);
-
-    draw_conf.prim_type          = DI_PT_RECTLIST;
-    draw_conf.vgt_draw_initiator = DI_SRC_SEL_AUTO_INDEX;
-    draw_conf.num_instances      = 1;
-    draw_conf.num_indices        = vtx_res.vtx_num_entries / vtx_res.vtx_size_dw;
-    draw_conf.index_type         = DI_INDEX_SIZE_16_BIT;
-
-    ereg  (accel_state->ib, VGT_INSTANCE_STEP_RATE_0,            0);	/* ? */
-    ereg  (accel_state->ib, VGT_INSTANCE_STEP_RATE_1,            0);
-
-    ereg  (accel_state->ib, VGT_MAX_VTX_INDX,                    draw_conf.num_indices);
-    ereg  (accel_state->ib, VGT_MIN_VTX_INDX,                    0);
-    ereg  (accel_state->ib, VGT_INDX_OFFSET,                     0);
-
-    draw_auto(pScrn, accel_state->ib, &draw_conf);
-
-    wait_3d_idle_clean(pScrn, accel_state->ib);
-
-    /* sync destination surface */
-    cp_set_surface_sync(pScrn, accel_state->ib, (CB_ACTION_ENA_bit | CB0_DEST_BASE_ENA_bit),
-			accel_state->dst_size, accel_state->dst_mc_addr);
-
-    R600CPFlushIndirect(pScrn, accel_state->ib);
+    R600DoneTexturedVideo(pScrn);
 
     DamageDamageRegion(pPriv->pDraw, &pPriv->clip);
 }
diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c
index bebab88..267a7b0 100644
--- a/src/r6xx_accel.c
+++ b/src/r6xx_accel.c
@@ -1058,7 +1058,7 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib)
     fs_setup(pScrn, ib, &fs_conf);
 
     // VGT
-    ereg  (ib, VGT_MAX_VTX_INDX,                    0);
+    ereg  (ib, VGT_MAX_VTX_INDX,                    2048); /* XXX set to a reasonably large number of indices */
     ereg  (ib, VGT_MIN_VTX_INDX,                    0);
     ereg  (ib, VGT_INDX_OFFSET,                     0);
     ereg  (ib, VGT_INSTANCE_STEP_RATE_0,            0);


More information about the xorg-commit mailing list