diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_context.h | 14 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_draw.c | 5 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_draw_upload.c | 71 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_vtbl.c | 2 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/intel/intel_buffer_objects.c | 4 | 
5 files changed, 73 insertions, 23 deletions
| diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 03cce5154c..957acd26a2 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -489,16 +489,26 @@ struct brw_context     struct {        struct brw_vertex_element inputs[VERT_ATTRIB_MAX];        struct brw_vertex_buffer buffers[VERT_ATTRIB_MAX]; +      struct { +	      uint32_t handle; +	      uint32_t offset; +	      uint32_t stride; +      } current_buffers[VERT_ATTRIB_MAX];        struct brw_vertex_element *enabled[VERT_ATTRIB_MAX];        GLuint nr_enabled; -      GLuint nr_buffers; +      GLuint nr_buffers, nr_current_buffers;        /* Summary of size and varying of active arrays, so we can check         * for changes to this state:         */        struct brw_vertex_info info;        unsigned int min_index, max_index; + +      /* Offset from start of vertex buffer so we can avoid redefining +       * the same VB packed over and over again. +       */ +      unsigned int start_vertex_bias;     } vb;     struct { @@ -512,6 +522,7 @@ struct brw_context        /* Updates to these fields are signaled by BRW_NEW_INDEX_BUFFER. */        drm_intel_bo *bo;        unsigned int offset; +        /* 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. @@ -832,4 +843,3 @@ float convert_param(enum param_conversion conversion, float param)  GLboolean brw_do_cubemap_normalize(struct exec_list *instructions);  #endif - diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 3431d29b05..f5abe021c4 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -145,9 +145,14 @@ static void brw_emit_prim(struct brw_context *brw,     prim_packet.start_vert_location = prim->start;     if (prim->indexed)        prim_packet.start_vert_location += brw->ib.start_vertex_offset; +   else +      prim_packet.start_vert_location += brw->vb.start_vertex_bias;     prim_packet.instance_count = 1;     prim_packet.start_instance_location = 0;     prim_packet.base_vert_location = prim->basevertex; +   if (prim->indexed) +      prim_packet.base_vert_location += brw->vb.start_vertex_bias; +     /* If we're set to always flush, do it before and after the primitive emit.      * We want to catch both missed flushes that hurt instruction/state cache diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index d4841226bf..09d7a5ee14 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -271,11 +271,11 @@ static void brw_prepare_vertices(struct brw_context *brw)     struct gl_context *ctx = &brw->intel.ctx;     struct intel_context *intel = intel_context(ctx);     GLbitfield vs_inputs = brw->vs.prog_data->inputs_read;  -   GLuint i, j;     const unsigned char *ptr = NULL;     GLuint interleaved = 0, total_size = 0;     unsigned int min_index = brw->vb.min_index;     unsigned int max_index = brw->vb.max_index; +   int i, j;     struct brw_vertex_element *upload[VERT_ATTRIB_MAX];     GLuint nr_uploads = 0; @@ -455,6 +455,33 @@ static void brw_prepare_vertices(struct brw_context *brw)  			      upload[i]->element_size);        upload[i]->buffer = j++;     } + +   /* can we simply extend the current vb? */ +   brw->vb.start_vertex_bias = 0; +   if (j == brw->vb.nr_current_buffers) { +      int delta = 0; +      for (i = 0; i < j; i++) { +	 int d; + +	 if (brw->vb.current_buffers[i].handle != brw->vb.buffers[i].bo->handle || +	     brw->vb.current_buffers[i].stride != brw->vb.buffers[i].stride) +	    break; + +	 d = brw->vb.buffers[i].offset - brw->vb.current_buffers[i].offset; +	 if (delta == 0) +	    delta = d / brw->vb.current_buffers[i].stride; +	 else if (delta * brw->vb.current_buffers[i].stride != d) +	    break; +      } + +      if (i == j) { +	 brw->vb.start_vertex_bias = delta; +	 while (--j >= 0) +	    drm_intel_bo_unreference(brw->vb.buffers[j].bo); +	 j = 0; +      } +   } +     brw->vb.nr_buffers = j;  validate: @@ -504,25 +531,33 @@ static void brw_emit_vertices(struct brw_context *brw)     /* Now emit VB and VEP state packets.      */ -   BEGIN_BATCH(1 + 4*brw->vb.nr_buffers); -   OUT_BATCH((CMD_VERTEX_BUFFER << 16) | (4*brw->vb.nr_buffers - 1)); -   for (i = 0; i < brw->vb.nr_buffers; i++) { -      struct brw_vertex_buffer *buffer = &brw->vb.buffers[i]; -      uint32_t dw0; +   if (brw->vb.nr_buffers) { +      BEGIN_BATCH(1 + 4*brw->vb.nr_buffers); +      OUT_BATCH((CMD_VERTEX_BUFFER << 16) | (4*brw->vb.nr_buffers - 1)); +      for (i = 0; i < brw->vb.nr_buffers; i++) { +	 struct brw_vertex_buffer *buffer = &brw->vb.buffers[i]; +	 uint32_t dw0; -      if (intel->gen >= 6) { -	 dw0 = GEN6_VB0_ACCESS_VERTEXDATA | (i << GEN6_VB0_INDEX_SHIFT); -      } else { -	 dw0 = BRW_VB0_ACCESS_VERTEXDATA | (i << BRW_VB0_INDEX_SHIFT); -      } +	 if (intel->gen >= 6) { +	    dw0 = GEN6_VB0_ACCESS_VERTEXDATA | (i << GEN6_VB0_INDEX_SHIFT); +	 } else { +	    dw0 = BRW_VB0_ACCESS_VERTEXDATA | (i << BRW_VB0_INDEX_SHIFT); +	 } + +	 OUT_BATCH(dw0 | (buffer->stride << BRW_VB0_PITCH_SHIFT)); +	 OUT_RELOC(buffer->bo, I915_GEM_DOMAIN_VERTEX, 0, buffer->offset); +	 if (intel->gen >= 5) { +	    OUT_RELOC(buffer->bo, I915_GEM_DOMAIN_VERTEX, 0, buffer->bo->size - 1); +	 } else +	    OUT_BATCH(0); +	 OUT_BATCH(0); /* Instance data step rate */ -      OUT_BATCH(dw0 | (buffer->stride << BRW_VB0_PITCH_SHIFT)); -      OUT_RELOC(buffer->bo, I915_GEM_DOMAIN_VERTEX, 0, buffer->offset); -      if (intel->gen >= 5) { -	 OUT_RELOC(buffer->bo, I915_GEM_DOMAIN_VERTEX, 0, buffer->bo->size - 1); -      } else -          OUT_BATCH(0); -      OUT_BATCH(0); /* Instance data step rate */ +	 brw->vb.current_buffers[i].handle = buffer->bo->handle; +	 brw->vb.current_buffers[i].offset = buffer->offset; +	 brw->vb.current_buffers[i].stride = buffer->stride; +      } +      brw->vb.nr_current_buffers = i; +      ADVANCE_BATCH();     }     ADVANCE_BATCH(); diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index 9a53516046..152ee14156 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -158,6 +158,8 @@ static void brw_new_batch( struct intel_context *intel )     brw->state.dirty.mesa |= ~0;     brw->state.dirty.brw |= ~0;     brw->state.dirty.cache |= ~0; + +   brw->vb.nr_current_buffers = 0;  }  static void brw_invalidate_state( struct intel_context *intel, GLuint new_state ) diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c index 81afe170c1..bc57803c84 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c @@ -120,10 +120,8 @@ intel_bufferobj_free(struct gl_context * ctx, struct gl_buffer_object *obj)     if (intel_obj->region) {        intel_bufferobj_release_region(intel, intel_obj);     } -   else if (intel_obj->buffer) { -      drm_intel_bo_unreference(intel_obj->buffer); -   } +   drm_intel_bo_unreference(intel_obj->buffer);     free(intel_obj);  } | 
