From 3f7a3dd58c0ce2719af83ff1d89a26185d08c04c Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sat, 12 Apr 2008 21:52:46 -0400 Subject: Make shaders operate on a block of memory instead of arrays of vertex_header's --- src/gallium/auxiliary/draw/draw_context.c | 10 ++--- src/gallium/auxiliary/draw/draw_private.h | 15 ++++--- src/gallium/auxiliary/draw/draw_vertex_cache.c | 33 +++++++++------ src/gallium/auxiliary/draw/draw_vertex_shader.c | 7 ++-- src/gallium/auxiliary/draw/draw_vs_exec.c | 54 ++++++++++++------------ src/gallium/auxiliary/draw/draw_vs_llvm.c | 2 +- src/gallium/auxiliary/draw/draw_vs_sse.c | 56 +++++++++++++++---------- 7 files changed, 100 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index b3c65c90d6..cdca556fbd 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -86,14 +86,12 @@ struct draw_context *draw_create( void ) /* Statically allocate maximum sized vertices for the cache - could be cleverer... */ { - uint i; const unsigned size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; - char *tmp = align_malloc(Elements(draw->vs.queue) * size, 16); + char *tmp = align_malloc(VS_QUEUE_LENGTH * size, 16); if (!tmp) goto fail; - for (i = 0; i < Elements(draw->vs.queue); i++) - draw->vs.queue[i].vertex = (struct vertex_header *)(tmp + i * size); + draw->vs.vertex_cache = tmp; } draw->shader_queue_flush = draw_vertex_shader_queue_flush; @@ -156,8 +154,8 @@ void draw_destroy( struct draw_context *draw ) tgsi_exec_machine_free_data(&draw->machine); - if (draw->vs.queue[0].vertex) - align_free( draw->vs.queue[0].vertex ); /* Frees all the vertices. */ + if (draw->vs.vertex_cache) + align_free( draw->vs.vertex_cache ); /* Frees all the vertices. */ /* Not so fast -- we're just borrowing this at the moment. * diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 5c710667fc..1115166192 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -152,7 +152,7 @@ struct draw_vertex_shader { struct draw_context *draw, const unsigned *elts, unsigned count, - struct vertex_header *vOut[] ); + void *out ); void (*delete)( struct draw_vertex_shader * ); @@ -321,10 +321,8 @@ struct draw_context /* Vertex shader queue: */ struct { - struct { - unsigned elt; /**< index into the user's vertex arrays */ - struct vertex_header *vertex; - } queue[VS_QUEUE_LENGTH]; + unsigned elts[VS_QUEUE_LENGTH]; /**< index into the user's vertex arrays */ + char *vertex_cache; unsigned queue_nr; unsigned post_nr; } vs; @@ -450,4 +448,11 @@ dot4(const float *a, const float *b) return result; } +static INLINE struct vertex_header * +draw_header_from_block(char *block, int num) +{ + static const unsigned size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; + return (struct vertex_header*)(block + num * size); +} + #endif /* DRAW_PRIVATE_H */ diff --git a/src/gallium/auxiliary/draw/draw_vertex_cache.c b/src/gallium/auxiliary/draw/draw_vertex_cache.c index c0248979e2..9256dec4ea 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_cache.c +++ b/src/gallium/auxiliary/draw/draw_vertex_cache.c @@ -71,25 +71,27 @@ static struct vertex_header *get_vertex( struct draw_context *draw, /* Cache hit? */ if (draw->vcache.idx[slot].in == i) { -// _mesa_printf("HIT %d %d\n", slot, i); + /*debug_printf("HIT %d %d\n", slot, i);*/ assert(draw->vcache.idx[slot].out < draw->vs.queue_nr); - return draw->vs.queue[draw->vcache.idx[slot].out].vertex; + return draw_header_from_block(draw->vs.vertex_cache, + draw->vcache.idx[slot].out); } /* Otherwise a collision */ slot = VCACHE_SIZE + draw->vcache.overflow++; -// _mesa_printf("XXX %d --> %d\n", i, slot); + /*debug_printf("XXX %d --> %d\n", i, slot);*/ } /* Deal with the cache miss: */ { unsigned out; - + struct vertex_header *header; + assert(slot < Elements(draw->vcache.idx)); -// _mesa_printf("NEW %d %d\n", slot, i); + /*debug_printf("NEW %d %d\n", slot, i);*/ draw->vcache.idx[slot].in = i; draw->vcache.idx[slot].out = out = draw->vs.queue_nr++; draw->vcache.referenced |= (1 << slot); @@ -99,17 +101,19 @@ static struct vertex_header *get_vertex( struct draw_context *draw, */ assert(draw->vs.queue_nr < VS_QUEUE_LENGTH); - draw->vs.queue[out].elt = i; - draw->vs.queue[out].vertex->clipmask = 0; - draw->vs.queue[out].vertex->edgeflag = draw_get_edgeflag(draw, i); - draw->vs.queue[out].vertex->pad = 0; - draw->vs.queue[out].vertex->vertex_id = UNDEFINED_VERTEX_ID; + header = draw_header_from_block(draw->vs.vertex_cache, out); + draw->vs.elts[out] = i; + header->clipmask = 0; + header->edgeflag = draw_get_edgeflag(draw, i); + header->pad = 0; + header->vertex_id = UNDEFINED_VERTEX_ID; /* Need to set the vertex's edge flag here. If we're being called * by do_ef_triangle(), that function needs edge flag info! */ - return draw->vs.queue[draw->vcache.idx[slot].out].vertex; + return draw_header_from_block(draw->vs.vertex_cache, + draw->vcache.idx[slot].out); } } @@ -142,8 +146,11 @@ void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ) { unsigned i; - for (i = 0; i < draw->vs.post_nr; i++) - draw->vs.queue[i].vertex->vertex_id = UNDEFINED_VERTEX_ID; + for (i = 0; i < draw->vs.post_nr; i++) { + struct vertex_header * header = + draw_header_from_block(draw->vs.vertex_cache, i); + header->vertex_id = UNDEFINED_VERTEX_ID; + } } diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index 726921d77b..452d0175c3 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -57,18 +57,17 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) /* run vertex shader on vertex cache entries, four per invokation */ for (i = 0; i < draw->vs.queue_nr; i += MAX_SHADER_VERTICES) { - struct vertex_header *dests[MAX_SHADER_VERTICES]; unsigned elts[MAX_SHADER_VERTICES]; int j, n = MIN2(MAX_SHADER_VERTICES, draw->vs.queue_nr - i); + struct vertex_header *dests = + draw_header_from_block(draw->vs.vertex_cache, i); for (j = 0; j < n; j++) { - elts[j] = draw->vs.queue[i + j].elt; - dests[j] = draw->vs.queue[i + j].vertex; + elts[j] = draw->vs.elts[i + j]; } for ( ; j < MAX_SHADER_VERTICES; j++) { elts[j] = elts[0]; - dests[j] = draw->vs.queue[i + j].vertex; } assert(n > 0); diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 09e0d0eaab..6fe4e554d5 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -69,7 +69,7 @@ vs_exec_run( struct draw_vertex_shader *shader, struct draw_context *draw, const unsigned *elts, unsigned count, - struct vertex_header *vOut[] ) + void *vOut ) { struct tgsi_exec_machine *machine = &draw->machine; unsigned int i, j; @@ -106,6 +106,8 @@ vs_exec_run( struct draw_vertex_shader *shader, for (j = 0; j < max_vertices; j++) { unsigned slot; float x, y, z, w; + struct vertex_header *out = + draw_header_from_block(vOut, i + j); /* Handle attr[0] (position) specially: * @@ -113,15 +115,15 @@ vs_exec_run( struct draw_vertex_shader *shader, * program as a set of DP4 instructions appended to the * user-provided code. */ - x = vOut[i + j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = vOut[i + j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = vOut[i + j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = vOut[i + j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + x = out->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = out->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = out->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = out->clip[3] = machine->Outputs[0].xyzw[3].f[j]; if (!draw->rasterizer->bypass_clipping) { - vOut[i + j]->clipmask = compute_clipmask(vOut[i + j]->clip, draw->plane, - draw->nr_planes); - clipped += vOut[i + j]->clipmask; + out->clipmask = compute_clipmask(out->clip, draw->plane, + draw->nr_planes); + clipped += out->clipmask; /* divide by w */ w = 1.0f / w; @@ -130,42 +132,42 @@ vs_exec_run( struct draw_vertex_shader *shader, z *= w; } else { - vOut[i + j]->clipmask = 0; + out->clipmask = 0; } - vOut[i + j]->edgeflag = 1; + out->edgeflag = 1; if (!draw->identity_viewport) { /* Viewport mapping */ - vOut[i + j]->data[0][0] = x * scale[0] + trans[0]; - vOut[i + j]->data[0][1] = y * scale[1] + trans[1]; - vOut[i + j]->data[0][2] = z * scale[2] + trans[2]; - vOut[i + j]->data[0][3] = w; + out->data[0][0] = x * scale[0] + trans[0]; + out->data[0][1] = y * scale[1] + trans[1]; + out->data[0][2] = z * scale[2] + trans[2]; + out->data[0][3] = w; } else { - vOut[i + j]->data[0][0] = x; - vOut[i + j]->data[0][1] = y; - vOut[i + j]->data[0][2] = z; - vOut[i + j]->data[0][3] = w; + out->data[0][0] = x; + out->data[0][1] = y; + out->data[0][2] = z; + out->data[0][3] = w; } /* Remaining attributes are packed into sequential post-transform * vertex attrib slots. */ for (slot = 1; slot < draw->num_vs_outputs; slot++) { - vOut[i + j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - vOut[i + j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - vOut[i + j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - vOut[i + j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + out->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + out->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + out->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + out->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; } #if 0 /*DEBUG*/ printf("%d) Post xform vert:\n", i + j); for (slot = 0; slot < draw->num_vs_outputs; slot++) { printf("\t%d: %f %f %f %f\n", slot, - vOut[i + j]->data[slot][0], - vOut[i + j]->data[slot][1], - vOut[i + j]->data[slot][2], - vOut[i + j]->data[slot][3]); + out->data[slot][0], + out->data[slot][1], + out->data[slot][2], + out->data[slot][3]); } #endif } /* loop over vertices */ diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 6db1e65a2d..72317c67ae 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -72,7 +72,7 @@ vs_llvm_run( struct draw_vertex_shader *base, struct draw_context *draw, const unsigned *elts, unsigned count, - struct vertex_header *vOut[] ) + void *vOut ) { struct draw_llvm_vertex_shader *shader = (struct draw_llvm_vertex_shader *)base; diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 6e8d2021f5..c877f5ee3a 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -83,7 +83,7 @@ vs_sse_run( struct draw_vertex_shader *base, struct draw_context *draw, const unsigned *elts, unsigned count, - struct vertex_header *vOut[] ) + void *vOut ) { struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base; struct tgsi_exec_machine *machine = &draw->machine; @@ -135,16 +135,18 @@ vs_sse_run( struct draw_vertex_shader *base, for (j = 0; j < max_vertices; j++) { unsigned slot; float x, y, z, w; + struct vertex_header *out = + draw_header_from_block(vOut, i + j); - x = vOut[i + j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = vOut[i + j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = vOut[i + j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = vOut[i + j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + x = out->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = out->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = out->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = out->clip[3] = machine->Outputs[0].xyzw[3].f[j]; if (!draw->rasterizer->bypass_clipping) { - vOut[i + j]->clipmask = compute_clipmask(vOut[i + j]->clip, draw->plane, - draw->nr_planes); - clipped += vOut[i + j]->clipmask; + out->clipmask = compute_clipmask(out->clip, draw->plane, + draw->nr_planes); + clipped += out->clipmask; /* divide by w */ w = 1.0f / w; @@ -153,33 +155,43 @@ vs_sse_run( struct draw_vertex_shader *base, z *= w; } else { - vOut[i + j]->clipmask = 0; + out->clipmask = 0; } - vOut[j]->edgeflag = 1; + out->edgeflag = 1; if (!draw->identity_viewport) { /* Viewport mapping */ - vOut[i + j]->data[0][0] = x * scale[0] + trans[0]; - vOut[i + j]->data[0][1] = y * scale[1] + trans[1]; - vOut[i + j]->data[0][2] = z * scale[2] + trans[2]; - vOut[i + j]->data[0][3] = w; + out->data[0][0] = x * scale[0] + trans[0]; + out->data[0][1] = y * scale[1] + trans[1]; + out->data[0][2] = z * scale[2] + trans[2]; + out->data[0][3] = w; } else { - vOut[i + j]->data[0][0] = x; - vOut[i + j]->data[0][1] = y; - vOut[i + j]->data[0][2] = z; - vOut[i + j]->data[0][3] = w; + out->data[0][0] = x; + out->data[0][1] = y; + out->data[0][2] = z; + out->data[0][3] = w; } /* Remaining attributes are packed into sequential post-transform * vertex attrib slots. */ for (slot = 1; slot < draw->num_vs_outputs; slot++) { - vOut[i + j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - vOut[i + j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - vOut[i + j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - vOut[i + j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + out->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + out->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + out->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + out->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; } +#if 0 /*DEBUG*/ + printf("%d) Post xform vert:\n", i + j); + for (slot = 0; slot < draw->num_vs_outputs; slot++) { + printf("\t%d: %f %f %f %f\n", slot, + out->data[slot][0], + out->data[slot][1], + out->data[slot][2], + out->data[slot][3]); + } +#endif } } return clipped != 0; -- cgit v1.2.3