diff options
author | Keith Whitwell <keith@tungstengraphics.com> | 2006-10-23 08:43:26 +0000 |
---|---|---|
committer | Keith Whitwell <keith@tungstengraphics.com> | 2006-10-23 08:43:26 +0000 |
commit | 759facb4d87843f6368fad9c5f20a5b1b3d95055 (patch) | |
tree | 434ca5e820db551267789c3de8c9a3a155c9e021 /src/mesa/drivers/dri/i965/brw_draw.c | |
parent | b9786cfaae3bd58d8e487846cfa9c251e1246abd (diff) |
Emit cliprects in the userspace driver as required, rather than
passing them to the kernel. This works because all drawing commands
in the 965 driver are emitted with the lock held and the batchbuffer
is always flushed prior to releasing the lock. This allows multiple
cliprects to be dealt with, without replaying entire batchbuffers and
redundantly re-emitting state.
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_draw.c')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_draw.c | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index e476b18cea..5c0c5da7ea 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -123,6 +123,23 @@ static GLuint trim(GLenum prim, GLuint length) } +static void brw_emit_cliprect( struct brw_context *brw, + const drm_clip_rect_t *rect ) +{ + struct brw_drawrect bdr; + + bdr.header.opcode = CMD_DRAW_RECT; + bdr.header.length = sizeof(bdr)/4 - 2; + bdr.xmin = rect->x1; + bdr.xmax = rect->x2 - 1; + bdr.ymin = rect->y1; + bdr.ymax = rect->y2 - 1; + bdr.xorg = brw->intel.drawX; + bdr.yorg = brw->intel.drawY; + + intel_batchbuffer_data( brw->intel.batch, &bdr, sizeof(bdr), + INTEL_BATCH_NO_CLIPRECTS); +} static void brw_emit_prim( struct brw_context *brw, @@ -149,7 +166,7 @@ static void brw_emit_prim( struct brw_context *brw, if (prim_packet.verts_per_instance) { intel_batchbuffer_data( brw->intel.batch, &prim_packet, sizeof(prim_packet), - INTEL_BATCH_CLIPRECTS); + INTEL_BATCH_NO_CLIPRECTS); } } @@ -277,7 +294,7 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, struct intel_context *intel = intel_context(ctx); struct brw_context *brw = brw_context(ctx); GLboolean retval = GL_FALSE; - GLuint i; + GLuint i, j; if (ctx->NewState) _mesa_update_state( ctx ); @@ -294,8 +311,17 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, */ LOCK_HARDWARE(intel); + + if (brw->intel.numClipRects == 0) { + assert(intel->batch->ptr == intel->batch->map + intel->batch->offset); + UNLOCK_HARDWARE(intel); + return GL_TRUE; + } + { assert(intel->locked); + + /* Set the first primitive early, ahead of validate_state: */ @@ -322,10 +348,25 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, goto out; } - /* Emit prims to batchbuffer: + /* For single cliprect, state is already emitted: */ - for (i = 0; i < nr_prims; i++) { - brw_emit_prim(brw, &prim[i]); + if (brw->intel.numClipRects == 1) { + for (i = 0; i < nr_prims; i++) { + brw_emit_prim(brw, &prim[i]); + } + } + else { + /* Otherwise, explicitly do the cliprects at this point: + */ + for (j = 0; j < brw->intel.numClipRects; j++) { + brw_emit_cliprect(brw, &brw->intel.pClipRects[j]); + + /* Emit prims to batchbuffer: + */ + for (i = 0; i < nr_prims; i++) { + brw_emit_prim(brw, &prim[i]); + } + } } intel->need_flush = GL_TRUE; |