Browse Source

intel: extend current vertex buffers

If the next vertex arrays are a (discontiguous) continuation of the
current arrays, such that the new vertices are simply offset from the
start of the current vertex buffer definitions we can reuse those
defintions and avoid the overhead of relocations and invalidations.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
tags/android-x86-2.2-r2
Chris Wilson 14 years ago
parent
commit
c625aa19cb

+ 12
- 2
src/mesa/drivers/dri/i965/brw_context.h View File

@@ -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


+ 5
- 0
src/mesa/drivers/dri/i965/brw_draw.c View File

@@ -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

+ 53
- 18
src/mesa/drivers/dri/i965/brw_draw_upload.c View File

@@ -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();


+ 2
- 0
src/mesa/drivers/dri/i965/brw_vtbl.c View File

@@ -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 )

+ 1
- 3
src/mesa/drivers/dri/intel/intel_buffer_objects.c View File

@@ -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);
}


Loading…
Cancel
Save