diff options
| author | Eric Anholt <eric@anholt.net> | 2009-08-11 14:48:03 -0700 | 
|---|---|---|
| committer | Eric Anholt <eric@anholt.net> | 2009-08-12 12:43:42 -0700 | 
| commit | 255e5be265133280293bbfd8b2f9b74b2dec50bb (patch) | |
| tree | 4658e135973b453cccffdb410fec62c555495b09 /src/mesa | |
| parent | a245c05dd3a1ca48204dd84252e6964aba91d4df (diff) | |
i965: Avoid re-uploading the index buffer when we don't need to.
No performance difference proven at 95% confidence with my GLSL demo (n=10).
Diffstat (limited to 'src/mesa')
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_context.h | 8 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_draw.c | 2 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_draw_upload.c | 58 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_state.h | 1 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_state_upload.c | 2 | 
5 files changed, 55 insertions, 16 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 00d5980dd0..847c44ed83 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -143,6 +143,7 @@ struct brw_context;  #define BRW_NEW_DEPTH_BUFFER		0x20000  #define BRW_NEW_NR_WM_SURFACES		0x40000  #define BRW_NEW_NR_VS_SURFACES		0x80000 +#define BRW_NEW_INDEX_BUFFER		0x100000  struct brw_state_flags {     /** State update flags signalled by mesa internals */ @@ -505,8 +506,15 @@ struct brw_context         */        const struct _mesa_index_buffer *ib; +      /* Updates to these fields are signaled by BRW_NEW_INDEX_BUFFER. */        dri_bo *bo;        unsigned int offset; +      unsigned int size; +      /* Offset to index buffer index to use in CMD_3D_PRIM so that we can +       * avoid re-uploading the IB packet over and over if we're actually +       * referencing the same index buffer. +       */ +      unsigned int start_vertex_offset;     } ib;     /* Active vertex program:  diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 8c94c904c1..682094ff13 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -141,6 +141,8 @@ static void brw_emit_prim(struct brw_context *brw,     prim_packet.verts_per_instance = trim(prim->mode, prim->count);     prim_packet.start_vert_location = prim->start; +   if (prim->indexed) +      prim_packet.start_vert_location += brw->ib.start_vertex_offset;     prim_packet.instance_count = 1;     prim_packet.start_instance_location = 0;     prim_packet.base_vert_location = 0; diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 4bdb37349b..ab6b62812f 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -612,17 +612,20 @@ static void brw_prepare_indices(struct brw_context *brw)     dri_bo *bo = NULL;     struct gl_buffer_object *bufferobj;     GLuint offset; +   GLuint ib_type_size;     if (index_buffer == NULL)        return; -   ib_size = get_size(index_buffer->type) * index_buffer->count; +   ib_type_size = get_size(index_buffer->type); +   ib_size = ib_type_size * index_buffer->count;     bufferobj = index_buffer->obj;;     /* Turn into a proper VBO:      */     if (!bufferobj->Name) { -      +      brw->ib.start_vertex_offset = 0; +        /* Get new bufferobj, offset:         */        get_space(brw, ib_size, &bo, &offset); @@ -638,6 +641,7 @@ static void brw_prepare_indices(struct brw_context *brw)        }     } else {        offset = (GLuint) (unsigned long) index_buffer->ptr; +      brw->ib.start_vertex_offset = 0;        /* If the index buffer isn't aligned to its element size, we have to         * rebase it into a temporary. @@ -658,39 +662,62 @@ static void brw_prepare_indices(struct brw_context *brw)  	  bo = intel_bufferobj_buffer(intel, intel_buffer_object(bufferobj),  				      INTEL_READ);  	  dri_bo_reference(bo); + +	  /* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading +	   * the index buffer state when we're just moving the start index +	   * of our drawing. +	   */ +	  brw->ib.start_vertex_offset = offset / ib_type_size; +	  offset = 0; +	  ib_size = bo->size;         }     } -   dri_bo_unreference(brw->ib.bo); -   brw->ib.bo = bo; -   brw->ib.offset = offset; +   if (brw->ib.bo != bo || +       brw->ib.offset != offset || +       brw->ib.size != ib_size) +   { +      drm_intel_bo_unreference(brw->ib.bo); +      brw->ib.bo = bo; +      brw->ib.offset = offset; +      brw->ib.size = ib_size; + +      brw->state.dirty.brw |= BRW_NEW_INDEX_BUFFER; +   } else { +      drm_intel_bo_unreference(bo); +   }     brw_add_validated_bo(brw, brw->ib.bo);  } -static void brw_emit_indices(struct brw_context *brw) +const struct brw_tracked_state brw_indices = { +   .dirty = { +      .mesa = 0, +      .brw = BRW_NEW_INDICES, +      .cache = 0, +   }, +   .prepare = brw_prepare_indices, +}; + +static void brw_emit_index_buffer(struct brw_context *brw)  {     struct intel_context *intel = &brw->intel;     const struct _mesa_index_buffer *index_buffer = brw->ib.ib; -   GLuint ib_size;     if (index_buffer == NULL)        return; -   ib_size = get_size(index_buffer->type) * index_buffer->count - 1; -     /* Emit the indexbuffer packet:      */     {        struct brw_indexbuffer ib;        memset(&ib, 0, sizeof(ib)); -    +        ib.header.bits.opcode = CMD_INDEX_BUFFER;        ib.header.bits.length = sizeof(ib)/4 - 2;        ib.header.bits.index_format = get_index_type(index_buffer->type);        ib.header.bits.cut_index_enable = 0; -           BEGIN_BATCH(4, IGNORE_CLIPRECTS);        OUT_BATCH( ib.header.dword ); @@ -699,18 +726,17 @@ static void brw_emit_indices(struct brw_context *brw)  		brw->ib.offset);        OUT_RELOC(brw->ib.bo,  		I915_GEM_DOMAIN_VERTEX, 0, -		brw->ib.offset + ib_size); +		brw->ib.offset + brw->ib.size);        OUT_BATCH( 0 );        ADVANCE_BATCH();     }  } -const struct brw_tracked_state brw_indices = { +const struct brw_tracked_state brw_index_buffer = {     .dirty = {        .mesa = 0, -      .brw = BRW_NEW_BATCH | BRW_NEW_INDICES, +      .brw = BRW_NEW_BATCH | BRW_NEW_INDEX_BUFFER,        .cache = 0,     }, -   .prepare = brw_prepare_indices, -   .emit = brw_emit_indices, +   .emit = brw_emit_index_buffer,  }; diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index bf9f6cae55..78572356a3 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -92,6 +92,7 @@ const struct brw_tracked_state brw_clear_batch_cache;  const struct brw_tracked_state brw_drawing_rect;  const struct brw_tracked_state brw_indices;  const struct brw_tracked_state brw_vertices; +const struct brw_tracked_state brw_index_buffer;  /**   * Use same key for WM and VS surfaces. diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 38d9dd8991..95d42d2dcc 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -94,6 +94,7 @@ const struct brw_tracked_state *atoms[] =     &brw_drawing_rect,     &brw_indices, +   &brw_index_buffer,     &brw_vertices,     &brw_constant_buffer @@ -208,6 +209,7 @@ static struct dirty_bit_map brw_bits[] = {     DEFINE_BIT(BRW_NEW_PSP),     DEFINE_BIT(BRW_NEW_FENCE),     DEFINE_BIT(BRW_NEW_INDICES), +   DEFINE_BIT(BRW_NEW_INDEX_BUFFER),     DEFINE_BIT(BRW_NEW_VERTICES),     DEFINE_BIT(BRW_NEW_BATCH),     DEFINE_BIT(BRW_NEW_DEPTH_BUFFER),  | 
