Emit cliprects in the userspace driver as required, rather than
authorKeith Whitwell <keith@tungstengraphics.com>
Mon, 23 Oct 2006 08:43:26 +0000 (08:43 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Mon, 23 Oct 2006 08:43:26 +0000 (08:43 +0000)
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.

src/mesa/drivers/dri/i965/brw_aub_playback.c
src/mesa/drivers/dri/i965/brw_draw.c
src/mesa/drivers/dri/i965/brw_misc_state.c
src/mesa/drivers/dri/i965/bufmgr_fake.c
src/mesa/drivers/dri/i965/intel_batchbuffer.c
src/mesa/drivers/dri/i965/intel_buffers.c
src/mesa/drivers/dri/i965/intel_context.c
src/mesa/drivers/dri/i965/intel_ioctl.c
src/mesa/drivers/dri/i965/intel_ioctl.h
src/mesa/drivers/dri/i965/intel_screen.c

index 49cc967716e1535fb63e75f93bf9b952d127f3c6..2433d50c1163439bf06dc1bdc44b7844715b9428 100644 (file)
@@ -39,7 +39,7 @@ static void flush_and_fence( struct aub_state *s )
    buf[0] = intel->vtbl.flush_cmd();
    buf[1] = 0;
 
-   intel_cmd_ioctl(intel, (char *)&buf, sizeof(buf), GL_TRUE);
+   intel_cmd_ioctl(intel, (char *)&buf, sizeof(buf));
       
    intelWaitIrq( intel, intelEmitIrqLocked( intel ));
 }
@@ -64,7 +64,7 @@ static void flush_cmds( struct aub_state *s,
     * This differs slightly from how the stream was executed
     * initially as this would have been a batchbuffer.
     */
-   intel_cmd_ioctl(s->intel, (void *)data, len, GL_TRUE);
+   intel_cmd_ioctl(s->intel, (void *)data, len);
 
    if (1)
       flush_and_fence(s);
@@ -345,7 +345,7 @@ static int parse_block_header( struct aub_state *s )
       }
       case BH_COMMAND_WRITE:
 #if 0
-        intel_cmd_ioctl(s->intel, (void *)data, len, GL_TRUE);
+        intel_cmd_ioctl(s->intel, (void *)data, len);
 #else
         if (parse_commands(s, data, len) != 0)
            _mesa_printf("parse_commands failed\n");
index e476b18ceae1671aace1e6c94427a6d064757761..5c0c5da7eaae6169c09095e26cd55f21530fe486 100644 (file)
@@ -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;
index 29296c17e9eea869baada9e9cadc553e9f927578..6a6c4503c7449e39b468357da1919813cc5df726 100644 (file)
@@ -74,7 +74,6 @@ const struct brw_tracked_state brw_blend_constant_color = {
 /***********************************************************************
  * Drawing rectangle -- Need for AUB file only.
  */
-
 static void upload_drawing_rect(struct brw_context *brw)
 {
    struct intel_context *intel = &brw->intel;
@@ -83,13 +82,12 @@ static void upload_drawing_rect(struct brw_context *brw)
    int x1, y1;
    int x2, y2;
 
-   if (!brw->intel.aub_file) 
+   /* If there is a single cliprect, set it here.  Otherwise iterate
+    * over them in brw_draw_prim().
+    */
+   if (brw->intel.numClipRects > 1) 
       return; 
  
-   /* Basically calculate a single cliprect for the whole window.
-    * Don't bother iterating over cliprects at the moment.
-    */
-
    x1 = dPriv->x;
    y1 = dPriv->y;      
    x2 = dPriv->x + dPriv->w;
@@ -110,7 +108,10 @@ static void upload_drawing_rect(struct brw_context *brw)
    bdr.xorg = dPriv->x;
    bdr.yorg = dPriv->y;
 
-   BRW_CACHED_BATCH_STRUCT(brw, &bdr);
+   /* Can't use BRW_CACHED_BATCH_STRUCT because this is also emitted
+    * uncached in brw_draw.c:
+    */
+   BRW_BATCH_STRUCT(brw, &bdr);
 }
 
 const struct brw_tracked_state brw_drawing_rect = {
index 30a235a2e53621b9a45f915981754c89e81860b1..ed88ab3797af3757d0bb88a6e6f7c4d81ce6bd18 100644 (file)
@@ -1307,7 +1307,7 @@ unsigned bmSetFence( struct intel_context *intel )
       GLuint dword[2];
       dword[0] = intel->vtbl.flush_cmd();
       dword[1] = 0;
-      intel_cmd_ioctl(intel, (char *)&dword, sizeof(dword), GL_TRUE);
+      intel_cmd_ioctl(intel, (char *)&dword, sizeof(dword));
       
       intel->bm->last_fence = intelEmitIrqLocked( intel );
       
index 598ce08735dedaf071d3025f64204c8ec92090b0..64885ed9b4b73ff0fd8195c06919a6dc38408914 100644 (file)
@@ -128,7 +128,6 @@ GLboolean intel_batchbuffer_flush( struct intel_batchbuffer *batch )
    struct intel_context *intel = batch->intel;
    GLuint used = batch->ptr - (batch->map + batch->offset);
    GLuint offset;
-   GLboolean ignore_cliprects = (batch->flags & INTEL_BATCH_CLIPRECTS) ? GL_FALSE : GL_TRUE;
    GLint retval = GL_TRUE;
 
    assert(intel->locked);
@@ -138,22 +137,6 @@ GLboolean intel_batchbuffer_flush( struct intel_batchbuffer *batch )
       return GL_TRUE;
    }
 
-   /* Throw away non-effective packets.  
-    */
-   if (intel->numClipRects == 0 && !ignore_cliprects) {
-      batch->ptr = batch->map + batch->offset;
-      bmReleaseBuffers( batch->intel );
-      intel->vtbl.lost_hardware(intel);
-      batch->flags = 0;
-
-      UNLOCK_HARDWARE(intel);
-      sched_yield();
-      LOCK_HARDWARE(intel);
-
-      return GL_TRUE;
-   }
-
-
    /* Add the MI_BATCH_BUFFER_END.  Always add an MI_FLUSH - this is a
     * performance drain that we would like to avoid.
     */
@@ -204,8 +187,7 @@ GLboolean intel_batchbuffer_flush( struct intel_batchbuffer *batch )
     */
    intel_batch_ioctl(batch->intel, 
                     offset + batch->offset,
-                    used,
-                    ignore_cliprects);
+                    used);
 
    if (intel->aub_file && 
        intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT)
index 9c985715ab4aca5a5bc165d5786b52183536cd71..dc5b9c0bc42e4a5906900d5e470635270eb7506a 100644 (file)
@@ -210,6 +210,12 @@ void intelWindowMoved( struct intel_context *intel )
 
       intel->NewGLState |= _NEW_SCISSOR;
    }
+
+   /* This works because the lock is always grabbed before emitting
+    * commands and commands are always flushed prior to releasing
+    * the lock.
+    */
+   intel->NewGLState |= _NEW_WINDOW_POS; 
 }
 
 
index 8be954d51d11a3333a41a43a03c83ead18e3bad2..36edd7db7f581e5ff2286f22d7ff4ab7987958e1 100644 (file)
@@ -577,12 +577,6 @@ static void intelContendedLock( struct intel_context *intel, GLuint flags )
    if (dPriv && intel->lastStamp != dPriv->lastStamp) {
       intelWindowMoved( intel );
       intel->lastStamp = dPriv->lastStamp;
-
-      /* This works because the lock is always grabbed before emitting
-       * commands and commands are always flushed prior to releasing
-       * the lock.
-       */
-      intel->NewGLState |= _NEW_WINDOW_POS; 
    }
 }
 
index 9297543f82b108b05c8aa573b1f6b8c4461b88b2..d1f2e3f27ca6e30f5a842c397d3fee077a43e022 100644 (file)
@@ -105,8 +105,7 @@ void intelWaitIrq( struct intel_context *intel, int seq )
 
 void intel_batch_ioctl( struct intel_context *intel, 
                        GLuint start_offset,
-                       GLuint used,
-                       GLboolean ignore_cliprects)
+                       GLuint used)
 {
    drmI830BatchBuffer batch;
 
@@ -114,27 +113,24 @@ void intel_batch_ioctl( struct intel_context *intel,
    assert(used);
 
    if (0)
-      fprintf(stderr, "%s used %d offset %x..%x ignore_cliprects %d\n",
+      fprintf(stderr, "%s used %d offset %x..%x\n",
              __FUNCTION__, 
              used, 
              start_offset,
-             start_offset + used,
-             ignore_cliprects);
+             start_offset + used);
 
    batch.start = start_offset;
    batch.used = used;
-   batch.cliprects = intel->pClipRects;
-   batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
+   batch.cliprects = NULL;
+   batch.num_cliprects = 0;
    batch.DR1 = 0;
-   batch.DR4 = ((((GLuint)intel->drawX) & 0xffff) | 
-               (((GLuint)intel->drawY) << 16));
+   batch.DR4 = 0;
       
    if (INTEL_DEBUG & DEBUG_DMA)
-      fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n",
+      fprintf(stderr, "%s: 0x%x..0x%x\n",
              __FUNCTION__, 
              batch.start, 
-             batch.start + batch.used * 4,
-             batch.DR4, batch.num_cliprects);
+             batch.start + batch.used * 4);
 
    if (!intel->no_hw) {
       if (drmCommandWrite (intel->driFd, DRM_I830_BATCHBUFFER, &batch, 
@@ -148,8 +144,7 @@ void intel_batch_ioctl( struct intel_context *intel,
 
 void intel_cmd_ioctl( struct intel_context *intel, 
                      char *buf,
-                     GLuint used,
-                     GLboolean ignore_cliprects)
+                     GLuint used)
 {
    drmI830CmdBuffer cmd;
 
@@ -159,17 +154,15 @@ void intel_cmd_ioctl( struct intel_context *intel,
    cmd.buf = buf;
    cmd.sz = used;
    cmd.cliprects = intel->pClipRects;
-   cmd.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
+   cmd.num_cliprects = 0;
    cmd.DR1 = 0;
-   cmd.DR4 = ((((GLuint)intel->drawX) & 0xffff) | 
-             (((GLuint)intel->drawY) << 16));
+   cmd.DR4 = 0;
       
    if (INTEL_DEBUG & DEBUG_DMA)
-      fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n",
+      fprintf(stderr, "%s: 0x%x..0x%x\n",
              __FUNCTION__, 
              0, 
-             0 + cmd.sz,
-             cmd.DR4, cmd.num_cliprects);
+             0 + cmd.sz);
 
    if (!intel->no_hw) {
       if (drmCommandWrite (intel->driFd, DRM_I830_CMDBUFFER, &cmd, 
index dcebcb06d1dfed98667487ef79eda20e9779517d..df2765936266f5b9a5da7d475a58e16e1d612244 100644 (file)
@@ -35,12 +35,10 @@ int intelEmitIrqLocked( struct intel_context *intel );
 
 void intel_batch_ioctl( struct intel_context *intel, 
                        GLuint start_offset,
-                       GLuint used,
-                       GLboolean ignore_cliprects);
+                       GLuint used);
 
 void intel_cmd_ioctl( struct intel_context *intel, 
                      char *buf,
-                     GLuint used,
-                     GLboolean ignore_cliprects);
+                     GLuint used);
 
 #endif
index 4bc5bedc529ed53f48fc63e749ba8bcf392978cd..56e6a792fa25e75993268fa2e66d21edfe915dc5 100644 (file)
@@ -272,7 +272,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
    volatile drmI830Sarea *sarea;
 
    if (sPriv->devPrivSize != sizeof(I830DRIRec)) {
-      fprintf(stderr,"\nERROR!  sizeof(I830DRIRec) (%ld) does not match passed size from device driver (%d)\n", sizeof(I830DRIRec), sPriv->devPrivSize);
+      fprintf(stderr,"\nERROR!  sizeof(I830DRIRec) (%ld) does not match passed size from device driver (%d)\n", (unsigned long)sizeof(I830DRIRec), sPriv->devPrivSize);
       return GL_FALSE;
    }