intel: use pwrite for batch
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 10 Feb 2011 20:25:51 +0000 (20:25 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Mon, 21 Feb 2011 12:59:35 +0000 (12:59 +0000)
It's faster. Not only is the memcpy more efficiently performed in the
kernel (making up for the system call overhead), but by not using mmap
we remove the greater overhead of tracking the vma of every batch.

And it means we can read back from the batch buffer without incurring
the cost of a uncached read through the GTT.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
27 files changed:
src/mesa/drivers/dri/i915/i830_vtbl.c
src/mesa/drivers/dri/i915/i915_vtbl.c
src/mesa/drivers/dri/i915/intel_render.c
src/mesa/drivers/dri/i915/intel_tris.c
src/mesa/drivers/dri/i965/brw_cc.c
src/mesa/drivers/dri/i965/brw_draw.c
src/mesa/drivers/dri/i965/brw_draw_upload.c
src/mesa/drivers/dri/i965/brw_misc_state.c
src/mesa/drivers/dri/i965/brw_queryobj.c
src/mesa/drivers/dri/i965/brw_state.h
src/mesa/drivers/dri/i965/brw_state_batch.c
src/mesa/drivers/dri/i965/brw_state_dump.c
src/mesa/drivers/dri/i965/brw_state_upload.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/intel/intel_batchbuffer.c
src/mesa/drivers/dri/intel/intel_batchbuffer.h
src/mesa/drivers/dri/intel/intel_blit.c
src/mesa/drivers/dri/intel/intel_buffer_objects.c
src/mesa/drivers/dri/intel/intel_context.c
src/mesa/drivers/dri/intel/intel_context.h
src/mesa/drivers/dri/intel/intel_fbo.c
src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
src/mesa/drivers/dri/intel/intel_pixel_read.c
src/mesa/drivers/dri/intel/intel_regions.c
src/mesa/drivers/dri/intel/intel_screen.c
src/mesa/drivers/dri/intel/intel_syncobj.c
src/mesa/drivers/dri/intel/intel_tex_image.c

index ebdefeac87447b1edcba855af8a81af4460c58bf..19f0807759941b3477226165f7fbba700fb2ff78 100644 (file)
@@ -364,7 +364,7 @@ i830_emit_invarient_state(struct intel_context *intel)
 
 
 #define emit( intel, state, size )                     \
-   intel_batchbuffer_data(intel->batch, state, size, false)
+   intel_batchbuffer_data(intel, state, size, false)
 
 static GLuint
 get_dirty(struct i830_hw_state *state)
@@ -428,7 +428,7 @@ i830_emit_state(struct intel_context *intel)
     * scheduling is allowed, rather than assume that it is whenever a
     * batchbuffer fills up.
     */
-   intel_batchbuffer_require_space(intel->batch,
+   intel_batchbuffer_require_space(intel,
                                   get_state_size(state) + INTEL_PRIM_EMIT_SIZE,
                                   false);
    count = 0;
@@ -436,7 +436,7 @@ i830_emit_state(struct intel_context *intel)
    aper_count = 0;
    dirty = get_dirty(state);
 
-   aper_array[aper_count++] = intel->batch->buf;
+   aper_array[aper_count++] = intel->batch.bo;
    if (dirty & I830_UPLOAD_BUFFERS) {
       aper_array[aper_count++] = state->draw_region->buffer;
       if (state->depth_region)
@@ -453,7 +453,7 @@ i830_emit_state(struct intel_context *intel)
    if (dri_bufmgr_check_aperture_space(aper_array, aper_count)) {
        if (count == 0) {
           count++;
-          intel_batchbuffer_flush(intel->batch);
+          intel_batchbuffer_flush(intel);
           goto again;
        } else {
           _mesa_error(ctx, GL_OUT_OF_MEMORY, "i830 emit state");
@@ -556,9 +556,7 @@ i830_emit_state(struct intel_context *intel)
       }
    }
 
-   intel->batch->dirty_state &= ~dirty;
    assert(get_dirty(state) == 0);
-   assert((intel->batch->dirty_state & (1<<1)) == 0);
 }
 
 static void
index a94b957127563295ea0308242278bec2a91107f1..394935c96cc1cc0a3d7ab4c7e36308d72fa8f348 100644 (file)
@@ -217,7 +217,7 @@ i915_emit_invarient_state(struct intel_context *intel)
 
 
 #define emit(intel, state, size )                   \
-   intel_batchbuffer_data(intel->batch, state, size, false)
+   intel_batchbuffer_data(intel, state, size, false)
 
 static GLuint
 get_dirty(struct i915_hw_state *state)
@@ -299,7 +299,7 @@ i915_emit_state(struct intel_context *intel)
     * scheduling is allowed, rather than assume that it is whenever a
     * batchbuffer fills up.
     */
-   intel_batchbuffer_require_space(intel->batch,
+   intel_batchbuffer_require_space(intel,
                                   get_state_size(state) + INTEL_PRIM_EMIT_SIZE,
                                   false);
    count = 0;
@@ -307,7 +307,7 @@ i915_emit_state(struct intel_context *intel)
    aper_count = 0;
    dirty = get_dirty(state);
 
-   aper_array[aper_count++] = intel->batch->buf;
+   aper_array[aper_count++] = intel->batch.bo;
    if (dirty & I915_UPLOAD_BUFFERS) {
       aper_array[aper_count++] = state->draw_region->buffer;
       if (state->depth_region)
@@ -327,7 +327,7 @@ i915_emit_state(struct intel_context *intel)
    if (dri_bufmgr_check_aperture_space(aper_array, aper_count)) {
        if (count == 0) {
           count++;
-          intel_batchbuffer_flush(intel->batch);
+          intel_batchbuffer_flush(intel);
           goto again;
        } else {
           _mesa_error(ctx, GL_OUT_OF_MEMORY, "i915 emit state");
@@ -476,9 +476,7 @@ i915_emit_state(struct intel_context *intel)
       }
    }
 
-   intel->batch->dirty_state &= ~dirty;
    assert(get_dirty(state) == 0);
-   assert((intel->batch->dirty_state & (1<<1)) == 0);
 }
 
 static void
index 0d8ab4b507e37888835380666d865dc7bd280d42..2d361ca0a9aa7f947b794b35b5d145a5f7042487 100644 (file)
@@ -124,7 +124,7 @@ static INLINE GLuint intel_get_vb_max(struct intel_context *intel)
    GLuint ret;
 
    if (intel->intelScreen->no_vbo)
-      ret = intel->batch->size - 1500;
+      ret = sizeof(intel->batch.map) - 1500;
    else
       ret = INTEL_VB_SIZE;
    ret /= (intel->vertex_size * 4);
index b9a8aeb12f29787e5c6e24c3e04e0c3d66ff0196..c6b5a01885fdcdd300e2cc2d632fff13040f2ab9 100644 (file)
@@ -62,22 +62,22 @@ static void intelRasterPrimitive(struct gl_context * ctx, GLenum rprim,
 static void
 intel_flush_inline_primitive(struct intel_context *intel)
 {
-   GLuint used = intel->batch->ptr - intel->prim.start_ptr;
+   GLuint used = intel->batch.used - intel->prim.start_ptr;
 
    assert(intel->prim.primitive != ~0);
 
 /*    printf("/\n"); */
 
-   if (used < 8)
+   if (used < 2)
       goto do_discard;
 
-   *(int *) intel->prim.start_ptr = (_3DPRIMITIVE |
-                                     intel->prim.primitive | (used / 4 - 2));
+   intel->batch.map[intel->prim.start_ptr] =
+      _3DPRIMITIVE | intel->prim.primitive | (used - 2);
 
    goto finished;
 
  do_discard:
-   intel->batch->ptr -= used;
+   intel->batch.used = intel->prim.start_ptr;
 
  finished:
    intel->prim.primitive = ~0;
@@ -100,9 +100,7 @@ static void intel_start_inline(struct intel_context *intel, uint32_t prim)
     */
    BEGIN_BATCH(1);
 
-   assert((intel->batch->dirty_state & (1<<1)) == 0);
-
-   intel->prim.start_ptr = intel->batch->ptr;
+   intel->prim.start_ptr = intel->batch.used;
    intel->prim.primitive = prim;
    intel->prim.flush = intel_flush_inline_primitive;
 
@@ -118,26 +116,25 @@ static void intel_wrap_inline(struct intel_context *intel)
    GLuint prim = intel->prim.primitive;
 
    intel_flush_inline_primitive(intel);
-   intel_batchbuffer_flush(intel->batch);
+   intel_batchbuffer_flush(intel);
    intel_start_inline(intel, prim);  /* ??? */
 }
 
 static GLuint *intel_extend_inline(struct intel_context *intel, GLuint dwords)
 {
-   GLuint sz = dwords * sizeof(GLuint);
    GLuint *ptr;
 
    assert(intel->prim.flush == intel_flush_inline_primitive);
 
-   if (intel_batchbuffer_space(intel->batch) < sz)
+   if (intel_batchbuffer_space(intel) < dwords * sizeof(GLuint))
       intel_wrap_inline(intel);
 
 /*    printf("."); */
 
    intel->vtbl.assert_not_dirty(intel);
 
-   ptr = (GLuint *) intel->batch->ptr;
-   intel->batch->ptr += sz;
+   ptr = intel->batch.map + intel->batch.used;
+   intel->batch.used += dwords;
 
    return ptr;
 }
@@ -223,10 +220,10 @@ void intel_flush_prim(struct intel_context *intel)
 
    intel->vtbl.emit_state(intel);
 
-   aper_array[0] = intel->batch->buf;
+   aper_array[0] = intel->batch.bo;
    aper_array[1] = vb_bo;
    if (dri_bufmgr_check_aperture_space(aper_array, 2)) {
-      intel_batchbuffer_flush(intel->batch);
+      intel_batchbuffer_flush(intel);
       intel->vtbl.emit_state(intel);
    }
 
@@ -236,11 +233,6 @@ void intel_flush_prim(struct intel_context *intel)
     */
    intel->no_batch_wrap = GL_TRUE;
 
-   /* Check that we actually emitted the state into this batch, using the
-    * UPLOAD_CTX bit as the signal.
-    */
-   assert((intel->batch->dirty_state & (1<<1)) == 0);
-
 #if 0
    printf("emitting %d..%d=%d vertices size %d\n", offset,
          intel->prim.current_offset, count,
index 408783a3e6a87b38766220f26103605de9a25dba..c37376ef0de6a91ea4fa1dd7d6a5fdfedc1f9582 100644 (file)
@@ -214,7 +214,7 @@ static void upload_cc_unit(struct brw_context *brw)
    brw->state.dirty.cache |= CACHE_NEW_CC_UNIT;
 
    /* Emit CC viewport relocation */
-   drm_intel_bo_emit_reloc(brw->intel.batch->buf,
+   drm_intel_bo_emit_reloc(brw->intel.batch.bo,
                           (brw->cc.state_offset +
                            offsetof(struct brw_cc_unit_state, cc4)),
                           brw->cc.vp_bo, 0,
index 57d1d7bbe076eac4f7a2a53af8168f1887b9b560..99c1b2b359c3891d1c0864a0434ac2b4352e8617 100644 (file)
@@ -155,14 +155,14 @@ static void brw_emit_prim(struct brw_context *brw,
     * the besides the draw code.
     */
    if (intel->always_flush_cache) {
-      intel_batchbuffer_emit_mi_flush(intel->batch);
+      intel_batchbuffer_emit_mi_flush(intel);
    }
    if (prim_packet.verts_per_instance) {
-      intel_batchbuffer_data( brw->intel.batch, &prim_packet,
+      intel_batchbuffer_data(&brw->intel, &prim_packet,
                              sizeof(prim_packet), false);
    }
    if (intel->always_flush_cache) {
-      intel_batchbuffer_emit_mi_flush(intel->batch);
+      intel_batchbuffer_emit_mi_flush(intel);
    }
 }
 
@@ -303,7 +303,6 @@ static GLboolean brw_try_draw_prims( struct gl_context *ctx,
    struct brw_context *brw = brw_context(ctx);
    GLboolean retval = GL_FALSE;
    GLboolean warn = GL_FALSE;
-   GLboolean first_time = GL_TRUE;
    GLuint i;
 
    if (ctx->NewState)
@@ -351,14 +350,10 @@ static GLboolean brw_try_draw_prims( struct gl_context *ctx,
        * an upper bound of how much we might emit in a single
        * brw_try_draw_prims().
        */
-      intel_batchbuffer_require_space(intel->batch, intel->batch->size / 4,
-                                     false);
+      intel_batchbuffer_require_space(intel, 1024, false);
 
       hw_prim = brw_set_prim(brw, &prim[i]);
-
-      if (first_time || (brw->state.dirty.brw & BRW_NEW_PRIMITIVE)) {
-        first_time = GL_FALSE;
-
+      if (brw->state.dirty.brw) {
         brw_validate_state(brw);
 
         /* Various fallback checks:  */
@@ -371,7 +366,7 @@ static GLboolean brw_try_draw_prims( struct gl_context *ctx,
         if (dri_bufmgr_check_aperture_space(brw->state.validated_bos,
                                             brw->state.validated_bo_count)) {
            static GLboolean warned;
-           intel_batchbuffer_flush(intel->batch);
+           intel_batchbuffer_flush(intel);
 
            /* Validate the state after we flushed the batch (which would have
             * changed the set of dirty state).  If we still fail to
@@ -400,7 +395,7 @@ static GLboolean brw_try_draw_prims( struct gl_context *ctx,
    }
 
    if (intel->always_flush_batch)
-      intel_batchbuffer_flush(intel->batch);
+      intel_batchbuffer_flush(intel);
  out:
 
    brw_state_cache_check_size(brw);
index fb31b2c2d4b52d928449a1650719fbd7773c8bc7..c257b9c517e45708556e0c5ed7165b3ea2143e66 100644 (file)
@@ -25,6 +25,7 @@
  * 
  **************************************************************************/
 
+#undef NDEBUG
 
 #include "main/glheader.h"
 #include "main/bufferobj.h"
@@ -298,6 +299,9 @@ static void brw_prepare_vertices(struct brw_context *brw)
       brw->vb.enabled[brw->vb.nr_enabled++] = input;
    }
 
+   if (brw->vb.nr_enabled == 0)
+      return;
+
    /* XXX: In the rare cases where this happens we fallback all
     * the way to software rasterization, although a tnl fallback
     * would be sufficient.  I don't know of *any* real world
@@ -481,6 +485,7 @@ static void brw_emit_vertices(struct brw_context *brw)
    }
    ADVANCE_BATCH();
 
+
    BEGIN_BATCH(1 + brw->vb.nr_enabled * 2);
    OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + brw->vb.nr_enabled * 2) - 2));
    for (i = 0; i < brw->vb.nr_enabled; i++) {
index fc4e18d9b2be2c0fa1160d3a571570c591f9cfba..c5c7409824636f2e29331cab3eebfdc270b4de60 100644 (file)
@@ -151,7 +151,7 @@ static void upload_pipelined_state_pointers(struct brw_context *brw )
    OUT_RELOC(brw->clip.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
    OUT_RELOC(brw->sf.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
    OUT_RELOC(brw->wm.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
-   OUT_RELOC(brw->intel.batch->buf, I915_GEM_DOMAIN_INSTRUCTION, 0,
+   OUT_RELOC(brw->intel.batch.bo, I915_GEM_DOMAIN_INSTRUCTION, 0,
             brw->cc.state_offset);
    ADVANCE_BATCH();
 
@@ -565,7 +565,7 @@ static void upload_state_base_address( struct brw_context *brw )
        BEGIN_BATCH(10);
        OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (10 - 2));
        OUT_BATCH(1); /* General state base address */
-       OUT_RELOC(intel->batch->buf, I915_GEM_DOMAIN_SAMPLER, 0,
+       OUT_RELOC(intel->batch.bo, I915_GEM_DOMAIN_SAMPLER, 0,
                 1); /* Surface state base address */
        OUT_BATCH(1); /* Dynamic state base address */
        OUT_BATCH(1); /* Indirect object base address */
@@ -579,7 +579,7 @@ static void upload_state_base_address( struct brw_context *brw )
        BEGIN_BATCH(8);
        OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (8 - 2));
        OUT_BATCH(1); /* General state base address */
-       OUT_RELOC(intel->batch->buf, I915_GEM_DOMAIN_SAMPLER, 0,
+       OUT_RELOC(intel->batch.bo, I915_GEM_DOMAIN_SAMPLER, 0,
                 1); /* Surface state base address */
        OUT_BATCH(1); /* Indirect object base address */
        OUT_BATCH(1); /* Instruction base address */
@@ -591,7 +591,7 @@ static void upload_state_base_address( struct brw_context *brw )
        BEGIN_BATCH(6);
        OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2));
        OUT_BATCH(1); /* General state base address */
-       OUT_RELOC(intel->batch->buf, I915_GEM_DOMAIN_SAMPLER, 0,
+       OUT_RELOC(intel->batch.bo, I915_GEM_DOMAIN_SAMPLER, 0,
                 1); /* Surface state base address */
        OUT_BATCH(1); /* Indirect object base address */
        OUT_BATCH(1); /* General state upper bound */
index 656aad630a19024d84ef99a4b5197b986c6ea683..b41d05dd438adb07f0350543d153b72f1d9cbacc 100644 (file)
@@ -177,7 +177,7 @@ brw_end_query(struct gl_context *ctx, struct gl_query_object *q)
          ADVANCE_BATCH();
       }
 
-      intel_batchbuffer_flush(intel->batch);
+      intel_batchbuffer_flush(intel);
    } else {
       /* Flush the batchbuffer in case it has writes to our query BO.
        * Have later queries write to a new query BO so that further rendering
@@ -185,7 +185,7 @@ brw_end_query(struct gl_context *ctx, struct gl_query_object *q)
        */
       if (query->bo) {
         brw_emit_query_end(brw);
-        intel_batchbuffer_flush(intel->batch);
+        intel_batchbuffer_flush(intel);
 
         drm_intel_bo_unreference(brw->query.bo);
         brw->query.bo = NULL;
index ece05540a406de44eb2567c8c807f463dd47a2d5..23d9e90c6e4f4fd67d44681b2f5ab029a174fb6f 100644 (file)
@@ -164,7 +164,7 @@ void brw_destroy_caches( struct brw_context *brw );
 /***********************************************************************
  * brw_state_batch.c
  */
-#define BRW_BATCH_STRUCT(brw, s) intel_batchbuffer_data(brw->intel.batch, (s), \
+#define BRW_BATCH_STRUCT(brw, s) intel_batchbuffer_data(&brw->intel, (s), \
                                                        sizeof(*(s)), false)
 #define BRW_CACHED_BATCH_STRUCT(brw, s) brw_cached_batch_struct( brw, (s), sizeof(*(s)) )
 
index 6d7b6a429dc223d1c4f5406457737c06ff1a36d4..f363a922c1d8d7bb76dd505cce166078e9e910d4 100644 (file)
@@ -48,7 +48,7 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw,
    struct header *newheader = (struct header *)data;
 
    if (brw->emit_state_always) {
-      intel_batchbuffer_data(brw->intel.batch, data, sz, false);
+      intel_batchbuffer_data(&brw->intel, data, sz, false);
       return GL_TRUE;
    }
 
@@ -75,7 +75,7 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw,
 
  emit:
    memcpy(item->header, newheader, sz);
-   intel_batchbuffer_data(brw->intel.batch, data, sz, false);
+   intel_batchbuffer_data(&brw->intel, data, sz, false);
    return GL_TRUE;
 }
 
@@ -118,10 +118,10 @@ brw_state_batch(struct brw_context *brw,
                int alignment,
                uint32_t *out_offset)
 {
-   struct intel_batchbuffer *batch = brw->intel.batch;
+   struct intel_batchbuffer *batch = &brw->intel.batch;
    uint32_t offset;
 
-   assert(size < batch->buf->size);
+   assert(size < batch->bo->size);
    offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment);
 
    /* If allocating from the top would wrap below the batchbuffer, or
@@ -129,13 +129,13 @@ brw_state_batch(struct brw_context *brw,
     * space, then flush and try again.
     */
    if (batch->state_batch_offset < size ||
-       offset < batch->ptr - batch->map + batch->reserved_space) {
-      intel_batchbuffer_flush(batch);
+       offset < 4*batch->used + batch->reserved_space) {
+      intel_batchbuffer_flush(&brw->intel);
       offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment);
    }
 
    batch->state_batch_offset = offset;
 
    *out_offset = offset;
-   return batch->map + offset;
+   return batch->map + (offset>>2);
 }
index 6c153319b82796e3e2cab144d80ef2a0da8fa25b..fdce79da2f4a0ba72bdbcc9fde44cfcc4980fc91 100644 (file)
@@ -104,7 +104,7 @@ static void dump_wm_surface_state(struct brw_context *brw)
    GLubyte *base;
    int i;
 
-   bo = brw->intel.batch->buf;
+   bo = brw->intel.batch.bo;
    drm_intel_bo_map(bo, GL_FALSE);
    base = bo->virtual;
 
@@ -285,7 +285,7 @@ static void dump_cc_state(struct brw_context *brw)
    const char *name = "CC";
    struct gen6_color_calc_state *cc;
    uint32_t cc_off;
-   dri_bo *bo = brw->intel.batch->buf;
+   dri_bo *bo = brw->intel.batch.bo;
 
    if (brw->cc.state_offset == 0)
        return;
@@ -376,7 +376,7 @@ void brw_debug_batch(struct intel_context *intel)
    struct brw_context *brw = brw_context(&intel->ctx);
 
    state_struct_out("WM bind",
-                   brw->intel.batch->buf,
+                   brw->intel.batch.bo,
                    brw->wm.bind_bo_offset,
                    4 * brw->wm.nr_surfaces);
    dump_wm_surface_state(brw);
index 9d120cf8425694d8ddd201c243690a817f47ee42..08b7ac907965ba551c3a8ec4db55932ad3b4b95b 100644 (file)
@@ -352,7 +352,7 @@ void brw_validate_state( struct brw_context *brw )
    state->mesa |= brw->intel.NewGLState;
    brw->intel.NewGLState = 0;
 
-   brw_add_validated_bo(brw, intel->batch->buf);
+   brw_add_validated_bo(brw, intel->batch.bo);
 
    if (intel->gen >= 6) {
       atoms = gen6_atoms;
index 82da6c4777eee58da81a977f8400db6632ea5ae2..1010d9f6f9c23781ef374554e00eee3d07d4a5d0 100644 (file)
@@ -224,7 +224,7 @@ brw_update_texture_surface( struct gl_context *ctx, GLuint unit )
    }
 
    /* Emit relocation to surface contents */
-   drm_intel_bo_emit_reloc(brw->intel.batch->buf,
+   drm_intel_bo_emit_reloc(brw->intel.batch.bo,
                           brw->wm.surf_offset[surf_index] +
                           offsetof(struct brw_surface_state, ss1),
                           intelObj->mt->region->buffer, 0,
@@ -268,7 +268,7 @@ brw_create_constant_surface(struct brw_context *brw,
     * bspec ("Data Cache") says that the data cache does not exist as
     * a separate cache and is just the sampler cache.
     */
-   drm_intel_bo_emit_reloc(brw->intel.batch->buf,
+   drm_intel_bo_emit_reloc(brw->intel.batch.bo,
                           (*out_offset +
                            offsetof(struct brw_surface_state, ss1)),
                           bo, 0,
@@ -491,7 +491,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
         surf->ss0.writedisable_alpha = !ctx->Color.ColorMask[unit][3];
    }
 
-   drm_intel_bo_emit_reloc(brw->intel.batch->buf,
+   drm_intel_bo_emit_reloc(brw->intel.batch.bo,
                           brw->wm.surf_offset[unit] +
                           offsetof(struct brw_surface_state, ss1),
                           region->buffer,
index 5564e3ea2c719c55e41ecad93d2d1e89f77524f7..7d224ae535cf30b79907d03915c8ef16ea664fec 100644 (file)
 #include "intel_buffers.h"
 
 void
-intel_batchbuffer_reset(struct intel_batchbuffer *batch)
+intel_batchbuffer_reset(struct intel_context *intel)
 {
-   struct intel_context *intel = batch->intel;
-
-   if (batch->buf != NULL) {
-      drm_intel_bo_unreference(batch->buf);
-      batch->buf = NULL;
+   if (intel->batch.bo != NULL) {
+      drm_intel_bo_unreference(intel->batch.bo);
+      intel->batch.bo = NULL;
    }
 
-   batch->buf = drm_intel_bo_alloc(intel->bufmgr, "batchbuffer",
-                                  intel->maxBatchSize, 4096);
-   drm_intel_gem_bo_map_gtt(batch->buf);
-   batch->map = batch->buf->virtual;
-
-   batch->size = intel->maxBatchSize;
-   batch->ptr = batch->map;
-   batch->reserved_space = BATCH_RESERVED;
-   batch->dirty_state = ~0;
-   batch->state_batch_offset = batch->size;
-}
-
-struct intel_batchbuffer *
-intel_batchbuffer_alloc(struct intel_context *intel)
-{
-   struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1);
-
-   batch->intel = intel;
-   intel_batchbuffer_reset(batch);
+   intel->batch.bo = drm_intel_bo_alloc(intel->bufmgr, "batchbuffer",
+                                       intel->maxBatchSize, 4096);
 
-   return batch;
+   intel->batch.reserved_space = BATCH_RESERVED;
+   intel->batch.state_batch_offset = intel->batch.bo->size;
+   intel->batch.used = 0;
 }
 
 void
-intel_batchbuffer_free(struct intel_batchbuffer *batch)
+intel_batchbuffer_free(struct intel_context *intel)
 {
-   if (batch->map) {
-      drm_intel_gem_bo_unmap_gtt(batch->buf);
-      batch->map = NULL;
-   }
-   dri_bo_unreference(batch->buf);
-   batch->buf = NULL;
-   free(batch);
+   drm_intel_bo_unreference(intel->batch.bo);
 }
 
 
-
 /* TODO: Push this whole function into bufmgr.
  */
 static void
-do_flush_locked(struct intel_batchbuffer *batch, GLuint used)
+do_flush_locked(struct intel_context *intel)
 {
-   struct intel_context *intel = batch->intel;
+   struct intel_batchbuffer *batch = &intel->batch;
    int ret = 0;
-   int x_off = 0, y_off = 0;
-
-   drm_intel_gem_bo_unmap_gtt(batch->buf);
-
-   batch->ptr = NULL;
 
    if (!intel->intelScreen->no_hw) {
       int ring;
 
-      if (intel->gen < 6 || !intel->batch->is_blit) {
+      if (intel->gen < 6 || !batch->is_blit) {
         ring = I915_EXEC_RENDER;
       } else {
         ring = I915_EXEC_BLT;
       }
 
-      drm_intel_bo_mrb_exec(batch->buf, used, NULL, 0,
-                           (x_off & 0xffff) | (y_off << 16), ring);
+      ret = drm_intel_bo_subdata(batch->bo, 0, 4*batch->used, batch->map);
+      if (ret == 0 && batch->state_batch_offset != batch->bo->size) {
+        ret = drm_intel_bo_subdata(batch->bo,
+                                   batch->state_batch_offset,
+                                   batch->bo->size - batch->state_batch_offset,
+                                   (char *)batch->map + batch->state_batch_offset);
+      }
+
+      if (ret == 0)
+        ret = drm_intel_bo_mrb_exec(batch->bo, 4*batch->used, NULL, 0, 0, ring);
    }
 
    if (unlikely(INTEL_DEBUG & DEBUG_BATCH)) {
-      drm_intel_bo_map(batch->buf, GL_FALSE);
-      intel_decode(batch->buf->virtual, used / 4, batch->buf->offset,
+      intel_decode(batch->map, batch->used,
+                  batch->bo->offset,
                   intel->intelScreen->deviceID, GL_TRUE);
-      drm_intel_bo_unmap(batch->buf);
 
       if (intel->vtbl.debug_batch != NULL)
         intel->vtbl.debug_batch(intel);
@@ -123,55 +101,33 @@ do_flush_locked(struct intel_batchbuffer *batch, GLuint used)
 }
 
 void
-_intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
-                        int line)
+_intel_batchbuffer_flush(struct intel_context *intel,
+                        const char *file, int line)
 {
-   struct intel_context *intel = batch->intel;
-   GLuint used = batch->ptr - batch->map;
+   if (intel->batch.used == 0)
+      return;
 
    if (intel->first_post_swapbuffers_batch == NULL) {
-      intel->first_post_swapbuffers_batch = intel->batch->buf;
+      intel->first_post_swapbuffers_batch = intel->batch.bo;
       drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
    }
 
-   if (used == 0)
-      return;
-
    if (unlikely(INTEL_DEBUG & DEBUG_BATCH))
       fprintf(stderr, "%s:%d: Batchbuffer flush with %db used\n", file, line,
-             used);
+             4*intel->batch.used);
 
-   batch->reserved_space = 0;
+   intel->batch.reserved_space = 0;
 
    if (intel->always_flush_cache) {
-      intel_batchbuffer_emit_mi_flush(batch);
-      used = batch->ptr - batch->map;
-   }
-
-   /* Round batchbuffer usage to 2 DWORDs. */
-
-   if ((used & 4) == 0) {
-      *(GLuint *) (batch->ptr) = 0; /* noop */
-      batch->ptr += 4;
-      used = batch->ptr - batch->map;
+      intel_batchbuffer_emit_mi_flush(intel);
    }
 
    /* Mark the end of the buffer. */
-   *(GLuint *) (batch->ptr) = MI_BATCH_BUFFER_END;
-   batch->ptr += 4;
-   used = batch->ptr - batch->map;
-   assert (used <= batch->buf->size);
-
-   /* Workaround for recursive batchbuffer flushing: If the window is
-    * moved, we can get into a case where we try to flush during a
-    * flush.  What happens is that when we try to grab the lock for
-    * the first flush, we detect that the window moved which then
-    * causes another flush (from the intel_draw_buffer() call in
-    * intelUpdatePageFlipping()).  To work around this we reset the
-    * batchbuffer tail pointer before trying to get the lock.  This
-    * prevent the nested buffer flush, but a better fix would be to
-    * avoid that in the first place. */
-   batch->ptr = batch->map;
+   intel_batchbuffer_emit_dword(intel, MI_BATCH_BUFFER_END);
+   if (intel->batch.used & 1) {
+      /* Round batchbuffer usage to 2 DWORDs. */
+      intel_batchbuffer_emit_dword(intel, MI_NOOP);
+   }
 
    if (intel->vtbl.finish_batch)
       intel->vtbl.finish_batch(intel);
@@ -181,24 +137,23 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
    /* Check that we didn't just wrap our batchbuffer at a bad time. */
    assert(!intel->no_batch_wrap);
 
-   do_flush_locked(batch, used);
+   do_flush_locked(intel);
 
    if (unlikely(INTEL_DEBUG & DEBUG_SYNC)) {
       fprintf(stderr, "waiting for idle\n");
-      drm_intel_bo_map(batch->buf, GL_TRUE);
-      drm_intel_bo_unmap(batch->buf);
+      drm_intel_bo_wait_rendering(intel->batch.bo);
    }
 
    /* Reset the buffer:
     */
-   intel_batchbuffer_reset(batch);
+   intel_batchbuffer_reset(intel);
 }
 
 
 /*  This is the only way buffers get added to the validate list.
  */
 GLboolean
-intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
+intel_batchbuffer_emit_reloc(struct intel_context *intel,
                              drm_intel_bo *buffer,
                              uint32_t read_domains, uint32_t write_domain,
                             uint32_t delta)
@@ -207,58 +162,55 @@ intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
 
    assert(delta < buffer->size);
 
-   if (batch->ptr - batch->map > batch->buf->size)
-    printf ("bad relocation ptr %p map %p offset %d size %lu\n",
-           batch->ptr, batch->map, batch->ptr - batch->map, batch->buf->size);
-   ret = drm_intel_bo_emit_reloc(batch->buf, batch->ptr - batch->map,
+   ret = drm_intel_bo_emit_reloc(intel->batch.bo, 4*intel->batch.used,
                                 buffer, delta,
                                 read_domains, write_domain);
+   assert (ret == 0);
 
    /*
     * Using the old buffer offset, write in what the right data would be, in case
     * the buffer doesn't move and we can short-circuit the relocation processing
     * in the kernel
     */
-   intel_batchbuffer_emit_dword (batch, buffer->offset + delta);
+   intel_batchbuffer_emit_dword(intel, buffer->offset + delta);
 
    return GL_TRUE;
 }
 
 GLboolean
-intel_batchbuffer_emit_reloc_fenced(struct intel_batchbuffer *batch,
+intel_batchbuffer_emit_reloc_fenced(struct intel_context *intel,
                                    drm_intel_bo *buffer,
-                                   uint32_t read_domains, uint32_t write_domain,
+                                   uint32_t read_domains,
+                                   uint32_t write_domain,
                                    uint32_t delta)
 {
    int ret;
 
    assert(delta < buffer->size);
 
-   if (batch->ptr - batch->map > batch->buf->size)
-    printf ("bad relocation ptr %p map %p offset %d size %lu\n",
-           batch->ptr, batch->map, batch->ptr - batch->map, batch->buf->size);
-   ret = drm_intel_bo_emit_reloc_fence(batch->buf, batch->ptr - batch->map,
+   ret = drm_intel_bo_emit_reloc_fence(intel->batch.bo, 4*intel->batch.used,
                                       buffer, delta,
                                       read_domains, write_domain);
+   assert (ret == 0);
 
    /*
     * Using the old buffer offset, write in what the right data would
     * be, in case the buffer doesn't move and we can short-circuit the
     * relocation processing in the kernel
     */
-   intel_batchbuffer_emit_dword (batch, buffer->offset + delta);
+   intel_batchbuffer_emit_dword(intel, buffer->offset + delta);
 
    return GL_TRUE;
 }
 
 void
-intel_batchbuffer_data(struct intel_batchbuffer *batch,
+intel_batchbuffer_data(struct intel_context *intel,
                        const void *data, GLuint bytes, bool is_blit)
 {
    assert((bytes & 3) == 0);
-   intel_batchbuffer_require_space(batch, bytes, is_blit);
-   __memcpy(batch->ptr, data, bytes);
-   batch->ptr += bytes;
+   intel_batchbuffer_require_space(intel, bytes, is_blit);
+   __memcpy(intel->batch.map + intel->batch.used, data, bytes);
+   intel->batch.used += bytes >> 2;
 }
 
 /* Emit a pipelined flush to either flush render and texture cache for
@@ -268,12 +220,10 @@ intel_batchbuffer_data(struct intel_batchbuffer *batch,
  * This is also used for the always_flush_cache driconf debug option.
  */
 void
-intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch)
+intel_batchbuffer_emit_mi_flush(struct intel_context *intel)
 {
-   struct intel_context *intel = batch->intel;
-
    if (intel->gen >= 6) {
-      if (intel->batch->is_blit) {
+      if (intel->batch.is_blit) {
         BEGIN_BATCH_BLT(4);
         OUT_BATCH(MI_FLUSH_DW);
         OUT_BATCH(0);
index 635708587a6af9f81ae9b699e9041498d2af88f3..7699715c0ea01b46281050f14490b751efad615e 100644 (file)
@@ -7,71 +7,37 @@
 #include "intel_bufmgr.h"
 #include "intel_reg.h"
 
-#define BATCH_SZ 16384
 #define BATCH_RESERVED 16
 
+void intel_batchbuffer_reset(struct intel_context *intel);
+void intel_batchbuffer_free(struct intel_context *intel);
 
-struct intel_batchbuffer
-{
-   struct intel_context *intel;
-
-   drm_intel_bo *buf;
-
-   GLubyte *map;
-   GLubyte *ptr;
-
-   GLuint size;
-   uint32_t state_batch_offset;
-
-#ifdef DEBUG
-   /** Tracking of BEGIN_BATCH()/OUT_BATCH()/ADVANCE_BATCH() debugging */
-   struct {
-      GLuint total;
-      GLubyte *start_ptr;
-   } emit;
-#endif
-
-   bool is_blit;
-   GLuint dirty_state;
-   GLuint reserved_space;
-};
-
-struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context
-                                                  *intel);
-
-void intel_batchbuffer_free(struct intel_batchbuffer *batch);
-
-
-void _intel_batchbuffer_flush(struct intel_batchbuffer *batch,
+void _intel_batchbuffer_flush(struct intel_context *intel,
                              const char *file, int line);
 
-#define intel_batchbuffer_flush(batch) \
-       _intel_batchbuffer_flush(batch, __FILE__, __LINE__)
+#define intel_batchbuffer_flush(intel) \
+       _intel_batchbuffer_flush(intel, __FILE__, __LINE__)
 
-void intel_batchbuffer_reset(struct intel_batchbuffer *batch);
 
 
 /* Unlike bmBufferData, this currently requires the buffer be mapped.
  * Consider it a convenience function wrapping multple
  * intel_buffer_dword() calls.
  */
-void intel_batchbuffer_data(struct intel_batchbuffer *batch,
+void intel_batchbuffer_data(struct intel_context *intel,
                             const void *data, GLuint bytes, bool is_blit);
 
-void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
-                                     GLuint bytes);
-
-GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
+GLboolean intel_batchbuffer_emit_reloc(struct intel_context *intel,
                                        drm_intel_bo *buffer,
                                       uint32_t read_domains,
                                       uint32_t write_domain,
                                       uint32_t offset);
-GLboolean intel_batchbuffer_emit_reloc_fenced(struct intel_batchbuffer *batch,
+GLboolean intel_batchbuffer_emit_reloc_fenced(struct intel_context *intel,
                                              drm_intel_bo *buffer,
                                              uint32_t read_domains,
                                              uint32_t write_domain,
                                              uint32_t offset);
-void intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch);
+void intel_batchbuffer_emit_mi_flush(struct intel_context *intel);
 
 static INLINE uint32_t float_as_int(float f)
 {
@@ -90,73 +56,70 @@ static INLINE uint32_t float_as_int(float f)
  * work...
  */
 static INLINE GLint
-intel_batchbuffer_space(struct intel_batchbuffer *batch)
+intel_batchbuffer_space(struct intel_context *intel)
 {
-   return (batch->state_batch_offset - batch->reserved_space) -
-      (batch->ptr - batch->map);
+   return (intel->batch.state_batch_offset - intel->batch.reserved_space) - intel->batch.used*4;
 }
 
 
 static INLINE void
-intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword)
+intel_batchbuffer_emit_dword(struct intel_context *intel, GLuint dword)
 {
 #ifdef DEBUG
-   assert(intel_batchbuffer_space(batch) >= 4);
+   assert(intel_batchbuffer_space(intel) >= 4);
 #endif
-   *(GLuint *) (batch->ptr) = dword;
-   batch->ptr += 4;
+   intel->batch.map[intel->batch.used++] = dword;
 }
 
 static INLINE void
-intel_batchbuffer_emit_float(struct intel_batchbuffer *batch, float f)
+intel_batchbuffer_emit_float(struct intel_context *intel, float f)
 {
-   intel_batchbuffer_emit_dword(batch, float_as_int(f));
+   intel_batchbuffer_emit_dword(intel, float_as_int(f));
 }
 
 static INLINE void
-intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
+intel_batchbuffer_require_space(struct intel_context *intel,
                                 GLuint sz, int is_blit)
 {
 
-   if (batch->intel->gen >= 6 && batch->is_blit != is_blit &&
-       batch->ptr != batch->map) {
-      intel_batchbuffer_flush(batch);
+   if (intel->gen >= 6 &&
+       intel->batch.is_blit != is_blit && intel->batch.used) {
+      intel_batchbuffer_flush(intel);
    }
 
-   batch->is_blit = is_blit;
+   intel->batch.is_blit = is_blit;
 
 #ifdef DEBUG
-   assert(sz < batch->size - 8);
+   assert(sz < sizeof(intel->batch.map) - BATCH_RESERVED);
 #endif
-   if (intel_batchbuffer_space(batch) < sz)
-      intel_batchbuffer_flush(batch);
+   if (intel_batchbuffer_space(intel) < sz)
+      intel_batchbuffer_flush(intel);
 }
 
 static INLINE void
-intel_batchbuffer_begin(struct intel_batchbuffer *batch, int n, bool is_blit)
+intel_batchbuffer_begin(struct intel_context *intel, int n, bool is_blit)
 {
-   intel_batchbuffer_require_space(batch, n * 4, is_blit);
+   intel_batchbuffer_require_space(intel, n * 4, is_blit);
 
 #ifdef DEBUG
-   assert(batch->map);
-   assert(batch->emit.start_ptr == NULL);
-   batch->emit.total = n * 4;
-   batch->emit.start_ptr = batch->ptr;
+   intel->batch.emit.total = n;
+   intel->batch.emit.start_ptr = intel->batch.used;
 #endif
 }
 
 static INLINE void
-intel_batchbuffer_advance(struct intel_batchbuffer *batch)
+intel_batchbuffer_advance(struct intel_context *intel)
 {
 #ifdef DEBUG
-   unsigned int _n = batch->ptr - batch->emit.start_ptr;
-   assert(batch->emit.start_ptr != NULL);
-   if (_n != batch->emit.total) {
+   struct intel_batchbuffer *batch = &intel->batch;
+   unsigned int _n = batch->used - batch->emit;
+   assert(batch->total != 0);
+   if (_n != batch->total) {
       fprintf(stderr, "ADVANCE_BATCH: %d of %d dwords emitted\n",
-             _n, batch->emit.total);
+             _n, batch->total);
       abort();
    }
-   batch->emit.start_ptr = NULL;
+   batch->total = 0;
 #endif
 }
 
@@ -164,19 +127,19 @@ intel_batchbuffer_advance(struct intel_batchbuffer *batch)
  */
 #define BATCH_LOCALS
 
-#define BEGIN_BATCH(n) intel_batchbuffer_begin(intel->batch, n, false)
-#define BEGIN_BATCH_BLT(n) intel_batchbuffer_begin(intel->batch, n, true)
-#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d)
-#define OUT_BATCH_F(f) intel_batchbuffer_emit_float(intel->batch,f)
+#define BEGIN_BATCH(n) intel_batchbuffer_begin(intel, n, false)
+#define BEGIN_BATCH_BLT(n) intel_batchbuffer_begin(intel, n, true)
+#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel, d)
+#define OUT_BATCH_F(f) intel_batchbuffer_emit_float(intel,f)
 #define OUT_RELOC(buf, read_domains, write_domain, delta) do {         \
-   intel_batchbuffer_emit_reloc(intel->batch, buf,                     \
+   intel_batchbuffer_emit_reloc(intel, buf,                    \
                                read_domains, write_domain, delta);     \
 } while (0)
 #define OUT_RELOC_FENCED(buf, read_domains, write_domain, delta) do {  \
-   intel_batchbuffer_emit_reloc_fenced(intel->batch, buf,              \
+   intel_batchbuffer_emit_reloc_fenced(intel, buf,             \
                                       read_domains, write_domain, delta); \
 } while (0)
 
-#define ADVANCE_BATCH() intel_batchbuffer_advance(intel->batch);
+#define ADVANCE_BATCH() intel_batchbuffer_advance(intel);
 
 #endif
index 6232e479cb6ef4ba86c38bd7d421ce4f2295714c..e1ab7f163718f0208cdaa463d0a370c519490c56 100644 (file)
@@ -123,12 +123,12 @@ intelEmitCopyBlit(struct intel_context *intel,
 
    /* do space check before going any further */
    do {
-       aper_array[0] = intel->batch->buf;
+       aper_array[0] = intel->batch.bo;
        aper_array[1] = dst_buffer;
        aper_array[2] = src_buffer;
 
        if (dri_bufmgr_check_aperture_space(aper_array, 3) != 0) {
-           intel_batchbuffer_flush(intel->batch);
+           intel_batchbuffer_flush(intel);
            pass++;
        } else
            break;
@@ -137,7 +137,7 @@ intelEmitCopyBlit(struct intel_context *intel,
    if (pass >= 2)
       return GL_FALSE;
 
-   intel_batchbuffer_require_space(intel->batch, 8 * 4, true);
+   intel_batchbuffer_require_space(intel, 8 * 4, true);
    DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
        __FUNCTION__,
        src_buffer, src_pitch, src_offset, src_x, src_y,
@@ -193,7 +193,7 @@ intelEmitCopyBlit(struct intel_context *intel,
                    src_offset);
    ADVANCE_BATCH();
 
-   intel_batchbuffer_emit_mi_flush(intel->batch);
+   intel_batchbuffer_emit_mi_flush(intel);
 
    return GL_TRUE;
 }
@@ -343,12 +343,12 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
       assert(y1 < y2);
 
       /* do space check before going any further */
-      aper_array[0] = intel->batch->buf;
+      aper_array[0] = intel->batch.bo;
       aper_array[1] = write_buffer;
 
       if (drm_intel_bufmgr_check_aperture_space(aper_array,
                                                ARRAY_SIZE(aper_array)) != 0) {
-        intel_batchbuffer_flush(intel->batch);
+        intel_batchbuffer_flush(intel);
       }
 
       BEGIN_BATCH_BLT(6);
@@ -363,7 +363,7 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
       ADVANCE_BATCH();
 
       if (intel->always_flush_cache)
-        intel_batchbuffer_emit_mi_flush(intel->batch);
+        intel_batchbuffer_emit_mi_flush(intel);
 
       if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL)
         mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
@@ -410,10 +410,10 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
        __FUNCTION__,
        dst_buffer, dst_pitch, dst_offset, x, y, w, h, src_size, dwords);
 
-   intel_batchbuffer_require_space( intel->batch,
-                                   (8 * 4) +
-                                   (3 * 4) +
-                                   dwords * 4, true);
+   intel_batchbuffer_require_space(intel,
+                                  (8 * 4) +
+                                  (3 * 4) +
+                                  dwords * 4, true);
 
    opcode = XY_SETUP_BLT_CMD;
    if (cpp == 4)
@@ -449,11 +449,9 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
    OUT_BATCH(((y + h) << 16) | (x + w));
    ADVANCE_BATCH();
 
-   intel_batchbuffer_data(intel->batch,
-                         src_bits,
-                         dwords * 4, true);
+   intel_batchbuffer_data(intel, src_bits, dwords * 4, true);
 
-   intel_batchbuffer_emit_mi_flush(intel->batch);
+   intel_batchbuffer_emit_mi_flush(intel);
 
    return GL_TRUE;
 }
@@ -543,10 +541,10 @@ intel_set_teximage_alpha_to_one(struct gl_context *ctx,
 
    DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
        __FUNCTION__,
-       intel_image->mt->region->buffer, (pitch * region->cpp),
+       intel_image->mt->region->buffer, (pitch * cpp),
        x1, y1, x2 - x1, y2 - y1);
 
-   BR13 = br13_for_cpp(region->cpp) | 0xf0 << 16;
+   BR13 = br13_for_cpp(cpp) | 0xf0 << 16;
    CMD = XY_COLOR_BLT_CMD;
    CMD |= XY_BLT_WRITE_ALPHA;
 
@@ -558,15 +556,15 @@ intel_set_teximage_alpha_to_one(struct gl_context *ctx,
       pitch /= 4;
    }
 #endif
-   BR13 |= (pitch * region->cpp);
+   BR13 |= (pitch * cpp);
 
    /* do space check before going any further */
-   aper_array[0] = intel->batch->buf;
+   aper_array[0] = intel->batch.bo;
    aper_array[1] = region->buffer;
 
    if (drm_intel_bufmgr_check_aperture_space(aper_array,
                                             ARRAY_SIZE(aper_array)) != 0) {
-      intel_batchbuffer_flush(intel->batch);
+      intel_batchbuffer_flush(intel);
    }
 
    BEGIN_BATCH_BLT(6);
@@ -580,5 +578,5 @@ intel_set_teximage_alpha_to_one(struct gl_context *ctx,
    OUT_BATCH(0xffffffff); /* white, but only alpha gets written */
    ADVANCE_BATCH();
 
-   intel_batchbuffer_emit_mi_flush(intel->batch);
+   intel_batchbuffer_emit_mi_flush(intel);
 }
index 19c73e6ab3a637be3329a343d85c8d496b3f9f51..4edf29ec7594c3425001ed0cde7cecc6b66ae27c 100644 (file)
@@ -225,7 +225,7 @@ intel_bufferobj_subdata(struct gl_context * ctx,
    } else {
       bool busy =
         drm_intel_bo_busy(intel_obj->buffer) ||
-        drm_intel_bo_references(intel->batch->buf, intel_obj->buffer);
+        drm_intel_bo_references(intel->batch.bo, intel_obj->buffer);
 
       /* replace the current busy bo with fresh data */
       if (busy && size == intel_obj->Base.Size) {
@@ -251,8 +251,8 @@ intel_bufferobj_subdata(struct gl_context * ctx,
         }
       } else {
         /* Can't use the blit to modify the buffer in the middle of batch. */
-        if (drm_intel_bo_references(intel->batch->buf, intel_obj->buffer)) {
-           intel_batchbuffer_flush(intel->batch);
+        if (drm_intel_bo_references(intel->batch.bo, intel_obj->buffer)) {
+           intel_batchbuffer_flush(intel);
         }
         drm_intel_bo_subdata(intel_obj->buffer, offset, size, data);
       }
@@ -309,7 +309,7 @@ intel_bufferobj_map(struct gl_context * ctx,
    }
 
    /* Flush any existing batchbuffer that might reference this data. */
-   if (drm_intel_bo_references(intel->batch->buf, intel_obj->buffer))
+   if (drm_intel_bo_references(intel->batch.bo, intel_obj->buffer))
       intel_flush(ctx);
 
    if (intel_obj->region)
@@ -386,7 +386,7 @@ intel_bufferobj_map_range(struct gl_context * ctx,
     * syncing.
     */
    if (!(access & GL_MAP_UNSYNCHRONIZED_BIT) &&
-       drm_intel_bo_references(intel->batch->buf, intel_obj->buffer))
+       drm_intel_bo_references(intel->batch.bo, intel_obj->buffer))
       intel_flush(ctx);
 
    if (intel_obj->buffer == NULL) {
@@ -499,7 +499,7 @@ intel_bufferobj_unmap(struct gl_context * ctx,
        * flush.  Once again, we wish for a domain tracker in libdrm to cover
        * usage inside of a batchbuffer.
        */
-      intel_batchbuffer_emit_mi_flush(intel->batch);
+      intel_batchbuffer_emit_mi_flush(intel);
       free(intel_obj->range_map_buffer);
       intel_obj->range_map_buffer = NULL;
    } else if (intel_obj->range_map_bo != NULL) {
@@ -519,7 +519,7 @@ intel_bufferobj_unmap(struct gl_context * ctx,
        * flush.  Once again, we wish for a domain tracker in libdrm to cover
        * usage inside of a batchbuffer.
        */
-      intel_batchbuffer_emit_mi_flush(intel->batch);
+      intel_batchbuffer_emit_mi_flush(intel);
 
       drm_intel_bo_unreference(intel_obj->range_map_bo);
       intel_obj->range_map_bo = NULL;
@@ -766,7 +766,7 @@ intel_bufferobj_copy_subdata(struct gl_context *ctx,
     * flush.  Once again, we wish for a domain tracker in libdrm to cover
     * usage inside of a batchbuffer.
     */
-   intel_batchbuffer_emit_mi_flush(intel->batch);
+   intel_batchbuffer_emit_mi_flush(intel);
 }
 
 #if FEATURE_APPLE_object_purgeable
index 65c4148e73eac257f8d3e5427f5863e0efeab528..c470febfb3a06eb476b13fabff224a08d5eac772 100644 (file)
@@ -554,8 +554,8 @@ intel_flush(struct gl_context *ctx)
    if (intel->gen < 4)
       INTEL_FIREVERTICES(intel);
 
-   if (intel->batch->map != intel->batch->ptr)
-      intel_batchbuffer_flush(intel->batch);
+   if (intel->batch.used)
+      intel_batchbuffer_flush(intel);
 }
 
 static void
@@ -751,7 +751,7 @@ intelInitContext(struct intel_context *intel,
    if (intelScreen->deviceID == PCI_CHIP_I865_G)
       intel->maxBatchSize = 4096;
    else
-      intel->maxBatchSize = BATCH_SZ;
+      intel->maxBatchSize = sizeof(intel->batch.map);
 
    intel->bufmgr = intelScreen->bufmgr;
 
@@ -863,7 +863,7 @@ intelInitContext(struct intel_context *intel,
    if (INTEL_DEBUG & DEBUG_BUFMGR)
       dri_bufmgr_set_debug(intel->bufmgr, GL_TRUE);
 
-   intel->batch = intel_batchbuffer_alloc(intel);
+   intel_batchbuffer_reset(intel);
 
    intel_fbo_init(intel);
 
@@ -920,8 +920,7 @@ intelDestroyContext(__DRIcontext * driContextPriv)
       _swrast_DestroyContext(&intel->ctx);
       intel->Fallback = 0x0;      /* don't call _swrast_Flush later */
 
-      intel_batchbuffer_free(intel->batch);
-      intel->batch = NULL;
+      intel_batchbuffer_free(intel);
 
       free(intel->prim.vb);
       intel->prim.vb = NULL;
index 0ea273837de0b313a6261f43c3793b4b263d6c1a..bf2a0b4ead824f4815d25c983a41088e7e5c07c9 100644 (file)
@@ -169,7 +169,27 @@ struct intel_context
 
    int urb_size;
 
-   struct intel_batchbuffer *batch;
+   struct intel_batchbuffer {
+      drm_intel_bo *bo;
+
+      uint16_t used;
+      uint16_t reserved_space;
+      uint32_t map[8192];
+#define BATCH_SZ (8192*sizeof(uint32_t))
+
+      uint32_t state_batch_offset;
+
+#ifdef DEBUG
+      /** Tracking of BEGIN_BATCH()/OUT_BATCH()/ADVANCE_BATCH() debugging */
+      struct {
+        uint16_t total;
+        uint16_t start_ptr;
+      } emit;
+#endif
+
+      bool is_blit;
+   } batch;
+
    drm_intel_bo *first_post_swapbuffers_batch;
    GLboolean need_throttle;
    GLboolean no_batch_wrap;
@@ -177,9 +197,9 @@ struct intel_context
    struct
    {
       GLuint id;
+      uint32_t start_ptr; /**< for i8xx */
       uint32_t primitive;      /**< Current hardware primitive type */
       void (*flush) (struct intel_context *);
-      GLubyte *start_ptr; /**< for i8xx */
       drm_intel_bo *vb_bo;
       uint8_t *vb;
       unsigned int start_offset; /**< Byte offset of primitive sequence */
index 0db5a491c8fa3cb493fb43f39ebee31165e03cd0..886b25c23b41e8d403d9a29a315ddc5311214d46 100644 (file)
@@ -580,7 +580,7 @@ intel_finish_render_texture(struct gl_context * ctx,
     * batch.  Once again, we wish for a domain tracker in libdrm to cover
     * usage inside of a batchbuffer like GEM does in the kernel.
     */
-   intel_batchbuffer_emit_mi_flush(intel->batch);
+   intel_batchbuffer_emit_mi_flush(intel);
 }
 
 /**
index e7356a6da0d325f41073020fa84e306c8fdfcc5f..d7561ee689dddc061126f8427c06757fcdbaa150 100644 (file)
@@ -285,7 +285,7 @@ do_blit_bitmap( struct gl_context *ctx,
 out:
 
    if (unlikely(INTEL_DEBUG & DEBUG_SYNC))
-      intel_batchbuffer_flush(intel->batch);
+      intel_batchbuffer_flush(intel);
 
    if (_mesa_is_bufferobj(unpack->BufferObj)) {
       /* done with PBO so unmap it now */
index 716b9cea40271791f60743c1c3234929e81db911..f90f8224c958627eb13ba40e0f07a83964dffcbd 100644 (file)
@@ -78,7 +78,6 @@ do_blit_readpixels(struct gl_context * ctx,
    GLuint dst_offset;
    GLuint rowLength;
    drm_intel_bo *dst_buffer;
-   GLuint offset;
    GLboolean all;
    GLint dst_x, dst_y;
 
@@ -148,7 +147,7 @@ do_blit_readpixels(struct gl_context * ctx,
    if (!intelEmitCopyBlit(intel,
                          src->cpp,
                          src->pitch, src->buffer, 0, src->tiling,
-                         rowLength, dst_buffer, dst_offset + offset, GL_FALSE,
+                         rowLength, dst_buffer, dst_offset, GL_FALSE,
                          x, y,
                          dst_x, dst_y,
                          width, height,
index e87e29462c38934794bad322af12160ceb4b5d60..0857fa8ad70f6d6706bf88cad3b24b8de2e8ce61 100644 (file)
@@ -491,7 +491,7 @@ intel_region_cow(struct intel_context *intel, struct intel_region *region)
 
    assert(region->cpp * region->pitch * region->height == pbo->Base.Size);
 
-   _DBG("%s %p (%d bytes)\n", __FUNCTION__, region, pbo->Base.Size);
+   _DBG("%s %p (%d bytes)\n", __FUNCTION__, region, (int)pbo->Base.Size);
 
    /* Now blit from the texture buffer to the new buffer: 
     */
index 2f35fe7f24076160780b5414596c5a5cc83470c1..356d5f72d89f1e56c53d5cd1c03303e1ec01a255 100644 (file)
@@ -111,8 +111,8 @@ intelDRI2Flush(__DRIdrawable *drawable)
 
    intel->need_throttle = GL_TRUE;
 
-   if (intel->batch->map != intel->batch->ptr)
-      intel_batchbuffer_flush(intel->batch);
+   if (intel->batch.used)
+      intel_batchbuffer_flush(intel);
 }
 
 static const struct __DRI2flushExtensionRec intelFlushExtension = {
index bbfac74b6054179838c08969b281a86c11f3788c..b303ea84dd8a25d277d57c64fa6fb88ca87e8396 100644 (file)
@@ -72,9 +72,9 @@ intel_fence_sync(struct gl_context *ctx, struct gl_sync_object *s,
    struct intel_sync_object *sync = (struct intel_sync_object *)s;
 
    assert(condition == GL_SYNC_GPU_COMMANDS_COMPLETE);
-   intel_batchbuffer_emit_mi_flush(intel->batch);
+   intel_batchbuffer_emit_mi_flush(intel);
 
-   sync->bo = intel->batch->buf;
+   sync->bo = intel->batch.bo;
    drm_intel_bo_reference(sync->bo);
 
    intel_flush(ctx);
index ddcb748c82858117caccf9cd491e1bcd33912d78..9dba529c58d0aba26fc6a57a47ff77b8d13512d1 100644 (file)
@@ -231,7 +231,7 @@ try_pbo_upload(struct intel_context *intel,
 
    dst_stride = intelImage->mt->region->pitch;
 
-   if (drm_intel_bo_references(intel->batch->buf, dst_buffer))
+   if (drm_intel_bo_references(intel->batch.bo, dst_buffer))
       intel_flush(&intel->ctx);
 
    {
@@ -431,7 +431,7 @@ intelTexImage(struct gl_context * ctx,
    if (intelImage->mt) {
       if (pixels != NULL) {
         /* Flush any queued rendering with the texture before mapping. */
-        if (drm_intel_bo_references(intel->batch->buf,
+        if (drm_intel_bo_references(intel->batch.bo,
                                     intelImage->mt->region->buffer)) {
            intel_flush(ctx);
         }