diff options
-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 */ + + 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; } - - 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.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); } |