xf86-video-ati: Branch 'master' - 7 commits

Dave Airlie airlied at kemper.freedesktop.org
Tue Nov 24 19:03:14 PST 2009


 src/drmmode_display.c          |    7 +-
 src/r600_exa.c                 |  115 +++++++++++++++++++++--------------------
 src/r600_state.h               |    2 
 src/r600_textured_videofuncs.c |   23 ++++----
 src/r6xx_accel.c               |   27 +++++++++
 src/radeon.h                   |    5 +
 src/radeon_kms.c               |    9 ++-
 7 files changed, 117 insertions(+), 71 deletions(-)

New commits:
commit f0acb16fa19844453adc6db3399977fba7c8a0db
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Nov 25 12:04:47 2009 +1000

    r600/xv: drop inited 3d false in xv code

diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c
index 0318e60..bf0511e 100644
--- a/src/r600_textured_videofuncs.c
+++ b/src/r600_textured_videofuncs.c
@@ -264,10 +264,6 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
     r600_cp_start(pScrn);
 
     /* Init */
-#if defined(XF86DRM_MODE)
-    if (info->cs)
-	accel_state->XInited3D = FALSE;
-#endif
     start_3d(pScrn, accel_state->ib);
 
     set_default_state(pScrn, accel_state->ib);
commit 985a065518b1d33599de33f7fe082d3302db58a6
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Nov 25 11:54:08 2009 +1000

    r600: enable multiple operations in one CS
    
    This switches on multiple ops in a single CS under KMS/DRI2.
    
    It gets for on a Pentium D 3 + rv740 from 330,000 to 500,000
    with x11perf -aa10text.
    
    It also knocks a couple of seconds of gtkperf -a
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c
index 0ca44ad..ea3ef07 100644
--- a/src/r6xx_accel.c
+++ b/src/r6xx_accel.c
@@ -1240,5 +1240,6 @@ void r600_finish_op(ScrnInfoPtr pScrn)
     accel_state->vb_start_op = 0;
     accel_state->ib_reset_op = 0;
 
-    R600CPFlushIndirect(pScrn, accel_state->ib);
+    if (!info->cs)
+        R600CPFlushIndirect(pScrn, accel_state->ib);
 }
commit af816ac752820255f245793b53a7cca5a4a49cd4
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Nov 25 11:53:07 2009 +1000

    r600: fixup problems with EXA operation reset for multiple ops
    
    To put multiple ops into one CS, you can't just discard the whole
    IB. This add supports for reset the CS cdw to the correct place
    after an op discards.
    
    Still doesn't enable the final accel bits.

diff --git a/src/r600_exa.c b/src/r600_exa.c
index 3488070..1405db7 100644
--- a/src/r600_exa.c
+++ b/src/r600_exa.c
@@ -220,10 +220,6 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
     r600_cp_start(pScrn);
 
     /* Init */
-#if defined(XF86DRM_MODE)
-    if (info->cs)
-	accel_state->XInited3D = FALSE;
-#endif
     start_3d(pScrn, accel_state->ib);
 
     set_default_state(pScrn, accel_state->ib);
@@ -454,9 +450,7 @@ R600DoneSolid(PixmapPtr pPix)
 			accel_state->dst_size, accel_state->dst_mc_addr,
 			accel_state->dst_bo, RADEON_GEM_DOMAIN_VRAM, 0);
 
-    accel_state->vb_start_op = 0;
-
-    R600CPFlushIndirect(pScrn, accel_state->ib);
+    r600_finish_op(pScrn);
 }
 
 static void
@@ -500,10 +494,6 @@ R600DoPrepareCopy(ScrnInfoPtr pScrn,
     r600_cp_start(pScrn);
 
     /* Init */
-#if defined(XF86DRM_MODE)
-    if (info->cs)
-	accel_state->XInited3D = FALSE;
-#endif
     start_3d(pScrn, accel_state->ib);
 
     set_default_state(pScrn, accel_state->ib);
@@ -720,8 +710,7 @@ R600DoCopy(ScrnInfoPtr pScrn)
 			accel_state->dst_size, accel_state->dst_mc_addr,
 			accel_state->dst_bo, RADEON_GEM_DOMAIN_VRAM, 0);
 
-    accel_state->vb_start_op = 0;
-    R600CPFlushIndirect(pScrn, accel_state->ib);
+    r600_finish_op(pScrn);
 }
 
 static void
@@ -858,7 +847,6 @@ R600PrepareCopy(PixmapPtr pSrc,   PixmapPtr pDst,
 						       RADEON_GEM_DOMAIN_VRAM,
 						       0);
 	    if (accel_state->copy_area_bo == NULL) {
-		R600IBDiscard(pScrn, accel_state->ib);
 		return FALSE;
 	    }
 	    radeon_cs_space_add_persistent_bo(info->cs, accel_state->copy_area_bo,
@@ -866,7 +854,6 @@ R600PrepareCopy(PixmapPtr pSrc,   PixmapPtr pDst,
 	    if (radeon_cs_space_check(info->cs)) {
 		radeon_bo_unref(accel_state->copy_area_bo);
 		accel_state->copy_area_bo = NULL;
-		R600IBDiscard(pScrn, accel_state->ib);
 		return FALSE;
 	    }
 	    accel_state->copy_area = (void*)accel_state->copy_area_bo;
@@ -1733,10 +1720,6 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
     r600_cp_start(pScrn);
 
     /* Init */
-#if defined(XF86DRM_MODE)
-    if (info->cs)
-	accel_state->XInited3D = FALSE;
-#endif
     start_3d(pScrn, accel_state->ib);
 
     set_default_state(pScrn, accel_state->ib);
@@ -2049,8 +2032,7 @@ static void R600DoneComposite(PixmapPtr pDst)
 			accel_state->dst_size, accel_state->dst_mc_addr,
 			accel_state->dst_bo, RADEON_GEM_DOMAIN_VRAM, 0);
 
-    accel_state->vb_start_op = 0;
-    R600CPFlushIndirect(pScrn, accel_state->ib);
+    r600_finish_op(pScrn);
 }
 
 Bool
diff --git a/src/r600_state.h b/src/r600_state.h
index 46c18f9..b2d2433 100644
--- a/src/r600_state.h
+++ b/src/r600_state.h
@@ -326,6 +326,8 @@ void
 r600_vb_discard(ScrnInfoPtr pScrn);
 int
 r600_cp_start(ScrnInfoPtr pScrn);
+void
+r600_finish_op(ScrnInfoPtr pScrn);
 
 extern Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index);
 extern void RADEONFinishAccess_CS(PixmapPtr pPix, int index);
diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c
index c740e06..0318e60 100644
--- a/src/r600_textured_videofuncs.c
+++ b/src/r600_textured_videofuncs.c
@@ -112,8 +112,7 @@ R600DoneTexturedVideo(ScrnInfoPtr pScrn)
 			accel_state->dst_size, accel_state->dst_mc_addr,
 			accel_state->dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
 
-    accel_state->vb_start_op = 0;
-    R600CPFlushIndirect(pScrn, accel_state->ib);
+    r600_finish_op(pScrn);
 }
 
 void
diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c
index 50afaed..0ca44ad 100644
--- a/src/r6xx_accel.c
+++ b/src/r6xx_accel.c
@@ -83,6 +83,12 @@ void R600IBDiscard(ScrnInfoPtr pScrn, drmBufPtr ib)
     int ret;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     if (info->cs) {
+	if (info->accel_state->ib_reset_op) {
+	    /* if we have data just reset the CS and ignore the operation */
+	    info->cs->cdw = info->accel_state->ib_reset_op;
+	    info->accel_state->ib_reset_op = 0;
+	    return;
+	}
 	if (info->accel_state->vb_ptr) {
 	    radeon_bo_unmap(info->accel_state->vb_bo);
 	    info->accel_state->vb_ptr = NULL;
@@ -1203,6 +1209,10 @@ r600_cp_start(ScrnInfoPtr pScrn)
 
 #if defined(XF86DRM_MODE)
     if (info->cs) {
+
+	if (CS_FULL(info->cs)) {
+	    radeon_cs_flush_indirect(pScrn);
+	}
 	if (!r600_vb_get(pScrn))
 	    return -1;
 	if (accel_state->vb_bo)
@@ -1210,6 +1220,7 @@ r600_cp_start(ScrnInfoPtr pScrn)
 					    RADEON_GEM_DOMAIN_GTT, 0);
 
 	radeon_cs_space_check(info->cs);
+	accel_state->ib_reset_op = info->cs->cdw;
     } else
 #endif
     {
@@ -1220,3 +1231,14 @@ r600_cp_start(ScrnInfoPtr pScrn)
     }
     return 0;
 }
+
+void r600_finish_op(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    struct radeon_accel_state *accel_state = info->accel_state;
+    
+    accel_state->vb_start_op = 0;
+    accel_state->ib_reset_op = 0;
+
+    R600CPFlushIndirect(pScrn, accel_state->ib);
+}
diff --git a/src/radeon.h b/src/radeon.h
index 745ee8e..4ee37b5 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -710,6 +710,8 @@ struct radeon_accel_state {
     uint32_t          vb_size;
     struct radeon_bo  *vb_bo;
     uint32_t          vb_start_op;
+    /* where to discard IB from if we cancel operation */
+    uint32_t          ib_reset_op;
 
     // shader storage
     ExaOffscreenArea  *shaders;
commit 3d8dcbc29323a3c644100bec13aa93f024653bd3
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Nov 25 11:43:57 2009 +1000

    kms: flush cs on close screen.
    
    this is needed for server recycle.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index b9228c1..68a6345 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -543,6 +543,9 @@ static Bool RADEONCloseScreen_KMS(int scrnIndex, ScreenPtr pScreen)
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONCloseScreen\n");
 
+    if (info->cs)
+      radeon_cs_flush_indirect(pScrn);
+
     if (info->accel_state->exa) {
 	exaDriverFini(pScreen);
 	xfree(info->accel_state->exa);
commit 19f1a357944f9d8f4567a2691a68067ec033ccb7
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Nov 25 11:41:52 2009 +1000

    radeon: fix check for no work in operation

diff --git a/src/r600_exa.c b/src/r600_exa.c
index 331711c..3488070 100644
--- a/src/r600_exa.c
+++ b/src/r600_exa.c
@@ -406,7 +406,7 @@ R600DoneSolid(PixmapPtr pPix)
     CLEAR (draw_conf);
     CLEAR (vtx_res);
 
-    if (accel_state->vb_offset == 0) {
+    if (accel_state->vb_offset == accel_state->vb_start_op) {
         R600IBDiscard(pScrn, accel_state->ib);
         r600_vb_discard(pScrn);
         return;
@@ -672,7 +672,7 @@ R600DoCopy(ScrnInfoPtr pScrn)
     CLEAR (draw_conf);
     CLEAR (vtx_res);
 
-    if (accel_state->vb_offset == 0) {
+    if (accel_state->vb_offset == accel_state->vb_start_op) {
         R600IBDiscard(pScrn, accel_state->ib);
         r600_vb_discard(pScrn);
         return;
@@ -1994,7 +1994,7 @@ static void R600DoneComposite(PixmapPtr pDst)
     CLEAR (draw_conf);
     CLEAR (vtx_res);
 
-    if (accel_state->vb_offset == 0) {
+    if (accel_state->vb_offset == accel_state->vb_start_op) {
         R600IBDiscard(pScrn, accel_state->ib);
         r600_vb_discard(pScrn);
         return;
diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c
index 7d0cfa7..c740e06 100644
--- a/src/r600_textured_videofuncs.c
+++ b/src/r600_textured_videofuncs.c
@@ -65,7 +65,7 @@ R600DoneTexturedVideo(ScrnInfoPtr pScrn)
     CLEAR (draw_conf);
     CLEAR (vtx_res);
 
-    if (accel_state->vb_offset == 0) {
+    if (accel_state->vb_offset == accel_state->vb_start_op) {
         R600IBDiscard(pScrn, accel_state->ib);
         r600_vb_discard(pScrn);
         return;
commit 3a460a14b9603159f10d89da27b559c36a184e27
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Nov 25 10:33:17 2009 +1000

    r600: refactor code to help future acceleration speedups.
    
    This changes the vertex buffer index to be an offset, and
    records the start of the vb for each operation and uses
    that to set the operations up.
    
    This still flushes after each operation to make sure we have
    no regressions in non-kms/kms cases.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/r600_exa.c b/src/r600_exa.c
index 4c63378..331711c 100644
--- a/src/r600_exa.c
+++ b/src/r600_exa.c
@@ -359,6 +359,7 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
     ErrorF("PM: 0x%08x\n", pm);
 #endif
 
+    accel_state->vb_start_op = accel_state->vb_offset;
     return TRUE;
 }
 
@@ -371,12 +372,14 @@ R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
     struct radeon_accel_state *accel_state = info->accel_state;
     float *vb;
 
-    if (((accel_state->vb_index + 3) * 8) > accel_state->vb_total) {
+    if ((accel_state->vb_offset + (3 * 8)) > accel_state->vb_total) {
         R600DoneSolid(pPix);
+	if (info->cs)
+	    radeon_cs_flush_indirect(pScrn);
 	r600_cp_start(pScrn);
     }
 
-    vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*8);
+    vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_offset);
 
     vb[0] = (float)x1;
     vb[1] = (float)y1;
@@ -387,7 +390,7 @@ R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
     vb[4] = (float)x2;
     vb[5] = (float)y2;
 
-    accel_state->vb_index += 3;
+    accel_state->vb_offset += (3*8);
 
 }
 
@@ -403,13 +406,13 @@ R600DoneSolid(PixmapPtr pPix)
     CLEAR (draw_conf);
     CLEAR (vtx_res);
 
-    if (accel_state->vb_index == 0) {
+    if (accel_state->vb_offset == 0) {
         R600IBDiscard(pScrn, accel_state->ib);
         r600_vb_discard(pScrn);
         return;
     }
 
-    accel_state->vb_size = accel_state->vb_index * 8;
+    accel_state->vb_size = accel_state->vb_offset;
 
     /* flush vertex cache */
     if ((info->ChipFamily == CHIP_FAMILY_RV610) ||
@@ -426,11 +429,12 @@ R600DoneSolid(PixmapPtr pPix)
 			    accel_state->vb_bo, RADEON_GEM_DOMAIN_GTT, 0);
 
     /* Vertex buffer setup */
+    accel_state->vb_size -= accel_state->vb_start_op;
     vtx_res.id              = SQ_VTX_RESOURCE_vs;
     vtx_res.vtx_size_dw     = 8 / 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;
+    vtx_res.vb_addr         = accel_state->vb_mc_addr + accel_state->vb_start_op;
     vtx_res.bo              = accel_state->vb_bo;
     set_vtx_resource        (pScrn, accel_state->ib, &vtx_res);
 
@@ -450,6 +454,8 @@ R600DoneSolid(PixmapPtr pPix)
 			accel_state->dst_size, accel_state->dst_mc_addr,
 			accel_state->dst_bo, RADEON_GEM_DOMAIN_VRAM, 0);
 
+    accel_state->vb_start_op = 0;
+
     R600CPFlushIndirect(pScrn, accel_state->ib);
 }
 
@@ -651,6 +657,8 @@ R600DoPrepareCopy(ScrnInfoPtr pScrn,
 								SEL_CENTROID_bit));
     EREG(accel_state->ib, SPI_INTERP_CONTROL_0,                0);
     END_BATCH();
+
+    accel_state->vb_start_op = accel_state->vb_offset;
 }
 
 static void
@@ -664,13 +672,13 @@ R600DoCopy(ScrnInfoPtr pScrn)
     CLEAR (draw_conf);
     CLEAR (vtx_res);
 
-    if (accel_state->vb_index == 0) {
+    if (accel_state->vb_offset == 0) {
         R600IBDiscard(pScrn, accel_state->ib);
         r600_vb_discard(pScrn);
         return;
     }
 
-    accel_state->vb_size = accel_state->vb_index * 16;
+    accel_state->vb_size = accel_state->vb_offset;
 
     /* flush vertex cache */
     if ((info->ChipFamily == CHIP_FAMILY_RV610) ||
@@ -687,11 +695,13 @@ R600DoCopy(ScrnInfoPtr pScrn)
 			    accel_state->vb_bo, RADEON_GEM_DOMAIN_GTT, 0);
 
     /* Vertex buffer setup */
+    accel_state->vb_size -= accel_state->vb_start_op;
+
     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;
+    vtx_res.vb_addr         = accel_state->vb_mc_addr + accel_state->vb_start_op;
     vtx_res.bo              = accel_state->vb_bo;
     set_vtx_resource        (pScrn, accel_state->ib, &vtx_res);
 
@@ -710,6 +720,7 @@ R600DoCopy(ScrnInfoPtr pScrn)
 			accel_state->dst_size, accel_state->dst_mc_addr,
 			accel_state->dst_bo, RADEON_GEM_DOMAIN_VRAM, 0);
 
+    accel_state->vb_start_op = 0;
     R600CPFlushIndirect(pScrn, accel_state->ib);
 }
 
@@ -723,12 +734,14 @@ R600AppendCopyVertex(ScrnInfoPtr pScrn,
     struct radeon_accel_state *accel_state = info->accel_state;
     float *vb;
 
-    if (((accel_state->vb_index + 3) * 16) > accel_state->vb_total) {
+    if ((accel_state->vb_offset + (3 * 16)) > accel_state->vb_total) {
         R600DoCopy(pScrn);
+	if (info->cs)
+	    radeon_cs_flush_indirect(pScrn);
 	r600_cp_start(pScrn);
     }
 
-    vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*16);
+    vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_offset);
 
     vb[0] = (float)dstX;
     vb[1] = (float)dstY;
@@ -745,7 +758,7 @@ R600AppendCopyVertex(ScrnInfoPtr pScrn,
     vb[10] = (float)(srcX + w);
     vb[11] = (float)(srcY + h);
 
-    accel_state->vb_index += 3;
+    accel_state->vb_offset += (3 * 16);
 }
 
 static Bool
@@ -1888,6 +1901,8 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
     EREG(accel_state->ib, SPI_INTERP_CONTROL_0,                0);
     END_BATCH();
 
+    accel_state->vb_start_op = accel_state->vb_offset;
+
     return TRUE;
 }
 
@@ -1906,12 +1921,14 @@ static void R600Composite(PixmapPtr pDst,
        srcX, srcY, maskX, maskY,dstX, dstY, w, h); */
 
     if (accel_state->msk_pic) {
-        if (((accel_state->vb_index + 3) * 24) > accel_state->vb_total) {
+        if ((accel_state->vb_offset + (3 * 24)) > accel_state->vb_total) {
             R600DoneComposite(pDst);
+	     if (info->cs)
+	         radeon_cs_flush_indirect(pScrn);
 	    r600_cp_start(pScrn);
         }
 
-        vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*24);
+        vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_offset);
 
 	vb[0] = (float)dstX;
 	vb[1] = (float)dstY;
@@ -1934,13 +1951,16 @@ static void R600Composite(PixmapPtr pDst,
 	vb[16] = (float)(maskX + w);
 	vb[17] = (float)(maskY + h);
 
+	accel_state->vb_offset += 3 * 24;
     } else {
-        if (((accel_state->vb_index + 3) * 16) > accel_state->vb_total) {
+        if ((accel_state->vb_offset + (3 * 16)) > accel_state->vb_total) {
             R600DoneComposite(pDst);
+	    if (info->cs)
+	        radeon_cs_flush_indirect(pScrn);
 	    r600_cp_start(pScrn);
         }
 
-        vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*16);
+        vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_offset);
 
 	vb[0] = (float)dstX;
 	vb[1] = (float)dstY;
@@ -1956,9 +1976,10 @@ static void R600Composite(PixmapPtr pDst,
 	vb[9] = (float)(dstY + h);
 	vb[10] = (float)(srcX + w);
 	vb[11] = (float)(srcY + h);
+	accel_state->vb_offset += 3 * 16;
+
     }
 
-    accel_state->vb_index += 3;
 
 }
 
@@ -1973,30 +1994,13 @@ static void R600DoneComposite(PixmapPtr pDst)
     CLEAR (draw_conf);
     CLEAR (vtx_res);
 
-    if (accel_state->vb_index == 0) {
+    if (accel_state->vb_offset == 0) {
         R600IBDiscard(pScrn, accel_state->ib);
         r600_vb_discard(pScrn);
         return;
     }
 
-    /* Vertex buffer setup */
-    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;
-	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;
-	vtx_res.bo              = accel_state->vb_bo;
-    } else {
-	accel_state->vb_size = accel_state->vb_index * 16;
-	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;
-	vtx_res.bo              = accel_state->vb_bo;
-    }
+    accel_state->vb_size = accel_state->vb_offset;
     /* flush vertex cache */
     if ((info->ChipFamily == CHIP_FAMILY_RV610) ||
 	(info->ChipFamily == CHIP_FAMILY_RV620) ||
@@ -2011,6 +2015,24 @@ static void R600DoneComposite(PixmapPtr pDst)
 			    accel_state->vb_size, accel_state->vb_mc_addr,
 			    accel_state->vb_bo, RADEON_GEM_DOMAIN_GTT, 0);
 
+    accel_state->vb_size -= accel_state->vb_start_op;
+
+    /* Vertex buffer setup */
+    if (accel_state->msk_pic) {
+	vtx_res.id              = SQ_VTX_RESOURCE_vs;
+	vtx_res.vtx_size_dw     = 24 / 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 + accel_state->vb_start_op;
+	vtx_res.bo              = accel_state->vb_bo;
+    } else {
+	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 + accel_state->vb_start_op;
+	vtx_res.bo              = accel_state->vb_bo;
+    }
     set_vtx_resource(pScrn, accel_state->ib, &vtx_res);
 
     draw_conf.prim_type          = DI_PT_RECTLIST;
@@ -2027,8 +2049,8 @@ static void R600DoneComposite(PixmapPtr pDst)
 			accel_state->dst_size, accel_state->dst_mc_addr,
 			accel_state->dst_bo, RADEON_GEM_DOMAIN_VRAM, 0);
 
+    accel_state->vb_start_op = 0;
     R600CPFlushIndirect(pScrn, accel_state->ib);
-
 }
 
 Bool
@@ -2336,6 +2358,9 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
 		      3, 0xffffffff);
     R600AppendCopyVertex(pScrn, x, y, 0, 0, w, h);
     R600DoCopy(pScrn);
+    
+    if (info->cs)
+	radeon_cs_flush_indirect(pScrn);
 
     r = radeon_bo_map(scratch, 0);
     if (r) {
diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c
index 7598429..7d0cfa7 100644
--- a/src/r600_textured_videofuncs.c
+++ b/src/r600_textured_videofuncs.c
@@ -65,13 +65,13 @@ R600DoneTexturedVideo(ScrnInfoPtr pScrn)
     CLEAR (draw_conf);
     CLEAR (vtx_res);
 
-    if (accel_state->vb_index == 0) {
+    if (accel_state->vb_offset == 0) {
         R600IBDiscard(pScrn, accel_state->ib);
         r600_vb_discard(pScrn);
         return;
     }
 
-    accel_state->vb_size = accel_state->vb_index * 16;
+    accel_state->vb_size = accel_state->vb_offset;
 
     /* flush vertex cache */
     if ((info->ChipFamily == CHIP_FAMILY_RV610) ||
@@ -88,11 +88,12 @@ R600DoneTexturedVideo(ScrnInfoPtr pScrn)
 			    accel_state->vb_bo, RADEON_GEM_DOMAIN_GTT, 0);
 
     /* Vertex buffer setup */
+    accel_state->vb_size -= accel_state->vb_start_op;
     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;
+    vtx_res.vb_addr         = accel_state->vb_mc_addr + accel_state->vb_start_op;
     vtx_res.bo              = accel_state->vb_bo;
     set_vtx_resource        (pScrn, accel_state->ib, &vtx_res);
 
@@ -111,6 +112,7 @@ R600DoneTexturedVideo(ScrnInfoPtr pScrn)
 			accel_state->dst_size, accel_state->dst_mc_addr,
 			accel_state->dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
 
+    accel_state->vb_start_op = 0;
     R600CPFlushIndirect(pScrn, accel_state->ib);
 }
 
@@ -564,6 +566,8 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
     EREG(accel_state->ib, SPI_INTERP_CONTROL_0,                0);
     END_BATCH();
 
+    accel_state->vb_start_op = accel_state->vb_offset;
+
     vs_alu_consts[0] = 1.0 / pPriv->w;
     vs_alu_consts[1] = 1.0 / pPriv->h;
     vs_alu_consts[2] = 0.0;
@@ -595,12 +599,14 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
 	int dstX, dstY, dstw, dsth;
 	float *vb;
 
-        if (((accel_state->vb_index + 3) * 16) > accel_state->vb_total) {
+        if ((accel_state->vb_offset + (3 * 16)) > accel_state->vb_total) {
             R600DoneTexturedVideo(pScrn);
+	    if (info->cs)
+	        radeon_cs_flush_indirect(pScrn);
 	    r600_cp_start(pScrn);
         }
 
-        vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*16);
+        vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_offset);
 
 	dstX = pBox->x1 + dstxoff;
 	dstY = pBox->y1 + dstyoff;
@@ -632,7 +638,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
 	vb[10] = (float)(srcX + srcw);
 	vb[11] = (float)(srcY + srch);
 
-	accel_state->vb_index += 3;
+	accel_state->vb_offset += 3 * 16;
 
 	pBox++;
     }
diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c
index a89bfb3..50afaed 100644
--- a/src/r6xx_accel.c
+++ b/src/r6xx_accel.c
@@ -86,6 +86,8 @@ void R600IBDiscard(ScrnInfoPtr pScrn, drmBufPtr ib)
 	if (info->accel_state->vb_ptr) {
 	    radeon_bo_unmap(info->accel_state->vb_bo);
 	    info->accel_state->vb_ptr = NULL;
+	    info->accel_state->vb_offset = 0;
+	    info->accel_state->vb_start_op = 0;
         }
 	if (CS_FULL(info->cs)) {
 	    radeon_cs_flush_indirect(pScrn);
@@ -1183,8 +1185,8 @@ r600_vb_get(ScrnInfoPtr pScrn)
 	accel_state->vb_total = (accel_state->ib->total / 2);
 	accel_state->vb_ptr = (pointer)((char*)accel_state->ib->address +
 					(accel_state->ib->total / 2));
+	accel_state->vb_offset = 0;
     }
-    accel_state->vb_index = 0;
     return TRUE;
 }
 
diff --git a/src/radeon.h b/src/radeon.h
index 0dbaa52..745ee8e 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -703,12 +703,13 @@ struct radeon_accel_state {
     Bool              vsync;
 
     drmBufPtr         ib;
-    int               vb_index;
+    int               vb_offset;
     uint64_t          vb_mc_addr;
     int               vb_total;
     void              *vb_ptr;
     uint32_t          vb_size;
     struct radeon_bo  *vb_bo;
+    uint32_t          vb_start_op;
 
     // shader storage
     ExaOffscreenArea  *shaders;
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index cafc329..b9228c1 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -80,8 +80,10 @@ void radeon_cs_flush_indirect(ScrnInfoPtr pScrn)
 	return;
 
     if (info->accel_state->vb_ptr) {
-	radeon_bo_unmap(info->accel_state->vb_bo);
-	info->accel_state->vb_ptr = NULL;
+      radeon_bo_unmap(info->accel_state->vb_bo);
+      info->accel_state->vb_ptr = NULL;
+      info->accel_state->vb_start_op = 0;
+      info->accel_state->vb_offset = 0;
     }
 
     radeon_cs_emit(info->cs);
commit 797a3f0c71c94477eec565ea2c95553c6f66d9fd
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Nov 25 10:07:59 2009 +1000

    kms: allow prepare copy to fail without dying

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 3147981..6e54c8a 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -204,6 +204,7 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 	int crtc_id = 0;
 	int i;
 	int pitch = pScrn->displayWidth * info->CurrentLayout.pixel_bytes;
+	Bool ret;
 
 	if (info->accelOn == FALSE)
 		return;
@@ -228,8 +229,10 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 	if (!dst)
 		goto out_free_src;
 
-	info->accel_state->exa->PrepareCopy (src, dst,
-					     -1, -1, GXcopy, FB_ALLONES);
+	ret = info->accel_state->exa->PrepareCopy (src, dst,
+						   -1, -1, GXcopy, FB_ALLONES);
+	if (!ret)
+	  goto out_free_src;
 	info->accel_state->exa->Copy (dst, 0, 0, 0, 0,
 				      pScrn->virtualX, pScrn->virtualY);
 	info->accel_state->exa->DoneCopy (dst);


More information about the xorg-commit mailing list