[Intel-gfx] [PATCH] Move i965 render vb setup to use time, and decouple state emit from it.

Eric Anholt eric at anholt.net
Tue Jan 20 06:12:14 CET 2009


The require_space had failed since it only checked for the space required
by the batch emits in the function itself, but not in the
i965_emit_composite_state() that it called (the state we were concerned about
having set up for that 12 * 4 dwords to follow!).  This is replaced by
intel_batch_start_atomic(), which will catch such mistakes in the future.
---
 src/i965_render.c |   89 ++++++++++++++++++++++++++++++++--------------------
 1 files changed, 55 insertions(+), 34 deletions(-)

diff --git a/src/i965_render.c b/src/i965_render.c
index d5eb683..a5e332a 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -519,6 +519,8 @@ struct gen4_render_state {
 
     int vb_offset;
     int vertex_size;
+
+    Bool needs_state_emit;
 };
 
 /**
@@ -963,12 +965,7 @@ i965_emit_composite_state(ScrnInfoPtr pScrn)
     uint32_t src_blend, dst_blend;
     dri_bo *binding_table_bo = composite_op->binding_table_bo;
 
-    if (render_state->vertex_buffer_bo == NULL) {
-	render_state->vertex_buffer_bo = dri_bo_alloc (pI830->bufmgr, "vb",
-						       sizeof (gen4_vertex_buffer),
-						       4096);
-	render_state->vb_offset = 0;
-    }
+    render_state->needs_state_emit = FALSE;
 
     IntelEmitInvarientState(pScrn);
     *pI830->last_3d = LAST_3D_RENDER;
@@ -1372,11 +1369,44 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
 	    I830FALLBACK("Couldn't fit render operation in aperture\n");
     }
 
-    i965_emit_composite_state(pScrn);
+    render_state->needs_state_emit = TRUE;
 
     return TRUE;
 }
 
+static drm_intel_bo *
+i965_get_vb_space(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    struct gen4_render_state *render_state = pI830->gen4_render_state;
+
+    /* If the vertex buffer is too full, then we free the old and a new one
+     * gets made.
+     */
+    if (render_state->vb_offset + VERTEX_FLOATS_PER_COMPOSITE >
+	VERTEX_BUFFER_SIZE) {
+	drm_intel_bo_unreference(render_state->vertex_buffer_bo);
+	render_state->vertex_buffer_bo = NULL;
+    }
+
+    /* Alloc a new vertex buffer if necessary. */
+    if (render_state->vertex_buffer_bo == NULL) {
+	render_state->vertex_buffer_bo = drm_intel_bo_alloc(pI830->bufmgr, "vb",
+							    sizeof(gen4_vertex_buffer),
+							    4096);
+	render_state->vb_offset = 0;
+    }
+
+    /* Map the vertex_buffer buffer object so we can write to it. */
+    if (drm_intel_bo_map(render_state->vertex_buffer_bo, 1) != 0) {
+	ErrorF("i965_get_vb_space(): couldn't map vb\n");
+	return NULL;
+    }
+
+    drm_intel_bo_reference(render_state->vertex_buffer_bo);
+    return render_state->vertex_buffer_bo;
+}
+
 void
 i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 	       int dstX, int dstY, int w, int h)
@@ -1388,6 +1418,7 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     Bool is_affine_src, is_affine_mask, is_affine;
     float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
     int i;
+    drm_intel_bo *vb_bo;
     float *vb;
 
     is_affine_src = i830_transform_is_affine (pI830->transform[0]);
@@ -1464,30 +1495,10 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 	}
     }
 
-    /* We're about to do a BEGIN_BATCH(12) for the vertex setup. And
-     * we first need to ensure that that's not going to cause a flush
-     * since we need to not flush between setting up our vertices in
-     * the VB and emitting them into the batch. */
-    intel_batch_require_space(pScrn, pI830, 12 * 4);
-
-    /* If the vertex buffer is too full, then we flush and re-emit all
-     * necessary state into the batch for the composite operation. */
-    if (render_state->vb_offset + VERTEX_FLOATS_PER_COMPOSITE > VERTEX_BUFFER_SIZE) {
-	dri_bo_unreference (render_state->vertex_buffer_bo);
-	render_state->vertex_buffer_bo = NULL;
-    }
-
-    if (!i965_composite_check_aperture(pScrn))
-	intel_batch_flush(pScrn, FALSE);
-    if (render_state->vertex_buffer_bo == NULL)
-	i965_emit_composite_state(pScrn);
-
-    /* Map the vertex_buffer buffer object so we can write to it. */
-    if (dri_bo_map (render_state->vertex_buffer_bo, 1) != 0)
-	return;		/* XXX what else to do here? */
-
-    vb = render_state->vertex_buffer_bo->virtual;
-
+    vb_bo = i965_get_vb_space(pScrn);
+    if (vb_bo == NULL)
+	return;
+    vb = vb_bo->virtual;
     i = render_state->vb_offset;
     /* rect (x2,y2) */
     vb[i++] = (float)(dstX + w);
@@ -1531,8 +1542,14 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 	    vb[i++] = mask_w[0];
     }
     assert (i <= VERTEX_BUFFER_SIZE);
+    drm_intel_bo_unmap(vb_bo);
 
-    dri_bo_unmap (render_state->vertex_buffer_bo);
+    if (!i965_composite_check_aperture(pScrn))
+	intel_batch_flush(pScrn, FALSE);
+
+    intel_batch_start_atomic(pScrn, 200);
+    if (render_state->needs_state_emit)
+	i965_emit_composite_state(pScrn);
 
     BEGIN_BATCH(12);
     OUT_BATCH(MI_FLUSH);
@@ -1541,8 +1558,7 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) |
 	      VB0_VERTEXDATA |
 	      (render_state->vertex_size << VB0_BUFFER_PITCH_SHIFT));
-    OUT_RELOC(render_state->vertex_buffer_bo, I915_GEM_DOMAIN_VERTEX, 0,
-	      render_state->vb_offset * 4);
+    OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0, render_state->vb_offset * 4);
     OUT_BATCH(3);
     OUT_BATCH(0); // ignore for VERTEXDATA, but still there
 
@@ -1559,6 +1575,9 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     ADVANCE_BATCH();
 
     render_state->vb_offset = i;
+    drm_intel_bo_unreference(vb_bo);
+
+    intel_batch_end_atomic(pScrn);
 
 #ifdef I830DEBUG
     ErrorF("sync after 3dprimitive\n");
@@ -1579,6 +1598,8 @@ i965_batch_flush_notify(ScrnInfoPtr pScrn)
 	dri_bo_unreference (render_state->vertex_buffer_bo);
 	render_state->vertex_buffer_bo = NULL;
     }
+
+    render_state->needs_state_emit = TRUE;
 }
 
 /**
-- 
1.5.6.5




More information about the Intel-gfx mailing list