diff options
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r-- | src/gallium/auxiliary/draw/Makefile | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/SConscript | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_clip.c | 15 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.c | 19 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.h | 3 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_private.h | 27 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt.h | 10 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c | 163 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_pipeline.c | 168 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_vcache.c | 396 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_vertex_cache.c | 2 |
12 files changed, 516 insertions, 291 deletions
diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index b28e516396e..28262a92c60 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -19,6 +19,7 @@ C_SOURCES = \ draw_pt_vcache.c \ draw_pt_fetch_emit.c \ draw_pt_fetch_pipeline.c \ + draw_pt_pipeline.c \ draw_pt_elts.c \ draw_prim.c \ draw_pstipple.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 9ca41974412..52107912f5e 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -18,6 +18,7 @@ draw = env.ConvenienceLibrary( 'draw_pt_vcache.c', 'draw_pt_fetch_emit.c', 'draw_pt_fetch_pipeline.c', + 'draw_pt_pipeline.c', 'draw_pt_elts.c', 'draw_prim.c', 'draw_pstipple.c', diff --git a/src/gallium/auxiliary/draw/draw_clip.c b/src/gallium/auxiliary/draw/draw_clip.c index 200152ecab9..e24c5d80322 100644 --- a/src/gallium/auxiliary/draw/draw_clip.c +++ b/src/gallium/auxiliary/draw/draw_clip.c @@ -181,6 +181,21 @@ static void emit_poly( struct draw_stage *stage, (header.v[1]->edgeflag << 1) | (header.v[2]->edgeflag << 2)); + if (0) { + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + uint j, k; + debug_printf("Clipped tri:\n"); + for (j = 0; j < 3; j++) { + for (k = 0; k < vs->info.num_outputs; k++) { + debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k, + header.v[j]->data[k][0], + header.v[j]->data[k][1], + header.v[j]->data[k][2], + header.v[j]->data[k][3]); + } + } + } + stage->next->tri( stage->next, &header ); header.v[1]->edgeflag = tmp1; diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index d0d5f66b376..b3c65c90d67 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -434,7 +434,8 @@ void draw_reset_vertex_ids(struct draw_context *draw) stage = stage->next; } - draw_vertex_cache_reset_vertex_ids(draw); + draw_vertex_cache_reset_vertex_ids(draw); /* going away soon */ + draw_pt_reset_vertex_ids(draw); } @@ -443,3 +444,19 @@ void draw_set_render( struct draw_context *draw, { draw->render = render; } + +void draw_set_edgeflags( struct draw_context *draw, + const unsigned *edgeflag ) +{ + draw->user.edgeflag = edgeflag; +} + + +boolean draw_get_edgeflag( struct draw_context *draw, + unsigned idx ) +{ + if (draw->user.edgeflag) + return (draw->user.edgeflag[idx/32] & (1 << (idx%32))) != 0; + else + return 1; +} diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 84bae3bd78d..c7ac32b4522 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -155,6 +155,9 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw, void draw_set_mapped_constant_buffer(struct draw_context *draw, const void *buffer); +void draw_set_edgeflags( struct draw_context *draw, + const unsigned *edgeflag ); + /*********************************************************************** * draw_prim.c diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 0c9f9c2e036..4d056f6dbaf 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -227,6 +227,12 @@ struct draw_context struct draw_pt_front_end *vcache; } front; + struct { + char *verts; + unsigned vertex_stride; + unsigned vertex_count; + } pipeline; + } pt; boolean flushing; @@ -244,6 +250,8 @@ struct draw_context /* user-space vertex data, buffers */ struct { + const unsigned *edgeflag; + /** vertex element/index buffer (ex: glDrawElements) */ const void *elts; /** bytes per index (0, 1, 2 or 4) */ @@ -386,15 +394,14 @@ boolean draw_pt_arrays( struct draw_context *draw, unsigned start, unsigned count ); - - -/* Prototype/hack (DEPRECATED) - */ -boolean -draw_passthrough_arrays(struct draw_context *draw, - unsigned prim, - unsigned start, - unsigned count); +void draw_pt_reset_vertex_ids( struct draw_context *draw ); +void draw_pt_run_pipeline( struct draw_context *draw, + unsigned prim, + char *verts, + unsigned vertex_stride, + unsigned vertex_count, + const ushort *elts, + unsigned count ); #define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */ @@ -406,6 +413,8 @@ draw_passthrough_arrays(struct draw_context *draw, void draw_do_flush( struct draw_context *draw, unsigned flags ); +boolean draw_get_edgeflag( struct draw_context *draw, + unsigned idx ); /** diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 800072c5115..590823fd330 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -40,6 +40,16 @@ typedef unsigned (*pt_elt_func)( const void *elts, unsigned idx ); struct draw_pt_middle_end; struct draw_context; +/* We use the top couple of bits in the vertex fetch index to convey a + * little API information. This limits the number of vertices we can + * address to only 1 billion -- if that becomes a problem, these could + * be moved out & passed separately. + */ +#define DRAW_PT_EDGEFLAG (1<<30) +#define DRAW_PT_RESET_STIPPLE (1<<31) +#define DRAW_PT_FLAG_MASK (3<<30) + + /* The "front end" - prepare sets of fetch, draw elements for the * middle end. * diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 39f0b40838f..0806076956d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -149,7 +149,7 @@ fetch_store_general( struct fetch_emit_middle_end *feme, uint i, j; for (i = 0; i < count; i++) { - unsigned elt = fetch_elts[i]; + unsigned elt = fetch_elts[i] & ~DRAW_PT_FLAG_MASK; for (j = 0; j < feme->nr_fetch; j++) { float attrib[4]; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c index 94e7d01be4b..4c2a281b295 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -72,6 +72,8 @@ struct fetch_pipeline_middle_end { struct draw_pt_middle_end base; struct draw_context *draw; + void (*header)( unsigned idx, float **out); + struct { const ubyte *ptr; unsigned pitch; @@ -85,12 +87,6 @@ struct fetch_pipeline_middle_end { }; -static void fetch_NULL( const void *from, - float *attrib ) -{ -} - - static void emit_R32_FLOAT( const float *attrib, float **out ) @@ -126,10 +122,16 @@ static void emit_R32G32B32A32_FLOAT( const float *attrib, (*out) += 4; } -static void emit_header( const float *attrib, - float **out ) +static void header( unsigned idx, + float **out ) { - (*out)[0] = 0; + struct vertex_header *header = (struct vertex_header *) (*out); + + header->clipmask = 0; + header->edgeflag = 1; + header->pad = 0; + header->vertex_id = UNDEFINED_VERTEX_ID; + (*out)[1] = 0; (*out)[2] = 0; (*out)[3] = 0; @@ -137,6 +139,27 @@ static void emit_header( const float *attrib, (*out) += 5; } + +static void header_ef( unsigned idx, + float **out ) +{ + struct vertex_header *header = (struct vertex_header *) (*out); + + /* XXX: need a reset_stipple flag in the vertex header too? + */ + header->clipmask = 0; + header->edgeflag = (idx & DRAW_PT_EDGEFLAG) != 0; + header->pad = 0; + header->vertex_id = UNDEFINED_VERTEX_ID; + + (*out)[1] = 0; + (*out)[2] = 0; + (*out)[3] = 0; + (*out)[3] = 1; + (*out) += 5; +} + + /** * General-purpose fetch from user's vertex arrays, emit to driver's * vertex buffer. @@ -155,6 +178,9 @@ fetch_store_general( struct fetch_pipeline_middle_end *fpme, for (i = 0; i < count; i++) { unsigned elt = fetch_elts[i]; + fpme->header( elt, &out ); + elt &= ~DRAW_PT_FLAG_MASK; + for (j = 0; j < fpme->nr_fetch; j++) { float attrib[4]; const ubyte *from = (fpme->fetch[j].ptr + @@ -194,12 +220,11 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, /* Emit the vertex header and empty clipspace coord field: */ - { - fpme->fetch[nr].ptr = NULL; - fpme->fetch[nr].pitch = 0; - fpme->fetch[nr].fetch = fetch_NULL; - fpme->fetch[nr].emit = emit_header; - nr++; + if (draw->user.edgeflag) { + fpme->header = header_ef; + } + else { + fpme->header = header; } @@ -226,100 +251,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, } fpme->nr_fetch = nr; - fpme->pipeline_vertex_size = (5 + (nr-1) * 4) * sizeof(float); -} - - - -/** - * Add a point to the primitive queue. - * \param i0 index into user's vertex arrays - */ -static void do_point( struct draw_context *draw, - const char *v0 ) -{ - struct prim_header prim; - - prim.reset_line_stipple = 0; - prim.edgeflags = 1; - prim.pad = 0; - prim.v[0] = (struct vertex_header *)v0; - - draw->pipeline.first->point( draw->pipeline.first, &prim ); -} - - -/** - * Add a line to the primitive queue. - * \param i0 index into user's vertex arrays - * \param i1 index into user's vertex arrays - */ -static void do_line( struct draw_context *draw, - const char *v0, - const char *v1 ) -{ - struct prim_header prim; - - prim.reset_line_stipple = 1; /* fixme */ - prim.edgeflags = 1; - prim.pad = 0; - prim.v[0] = (struct vertex_header *)v0; - prim.v[1] = (struct vertex_header *)v1; - - draw->pipeline.first->line( draw->pipeline.first, &prim ); -} - -/** - * Add a triangle to the primitive queue. - */ -static void do_triangle( struct draw_context *draw, - char *v0, - char *v1, - char *v2 ) -{ - struct prim_header prim; - -// _mesa_printf("tri %d %d %d\n", i0, i1, i2); - prim.reset_line_stipple = 1; - prim.edgeflags = ~0; - prim.pad = 0; - prim.v[0] = (struct vertex_header *)v0; - prim.v[1] = (struct vertex_header *)v1; - prim.v[2] = (struct vertex_header *)v2; - - draw->pipeline.first->tri( draw->pipeline.first, &prim ); -} - - -static void run_pipeline( struct fetch_pipeline_middle_end *fpme, - char *verts, - const ushort *elts, - unsigned count ) -{ - struct draw_context *draw = fpme->draw; - unsigned stride = fpme->pipeline_vertex_size; - unsigned i; - - switch (fpme->prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i++) - do_point( draw, - verts + stride * elts[i] ); - break; - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) - do_line( draw, - verts + stride * elts[i+0], - verts + stride * elts[i+1]); - break; - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) - do_triangle( draw, - verts + stride * elts[i+0], - verts + stride * elts[i+1], - verts + stride * elts[i+2]); - break; - } + fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); } @@ -351,10 +283,15 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, fetch_count ); - run_pipeline( fpme, - pipeline_verts, - draw_elts, - draw_count ); + /* Run the pipeline + */ + draw_pt_run_pipeline( fpme->draw, + fpme->prim, + pipeline_verts, + fpme->pipeline_vertex_size, + fetch_count, + draw_elts, + draw_count ); /* Done -- that was easy, wasn't it: diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c new file mode 100644 index 00000000000..e70e63d08fb --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_pipeline.c @@ -0,0 +1,168 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell <[email protected]> + */ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" + + +/** + * Add a point to the primitive queue. + * \param i0 index into user's vertex arrays + */ +static void do_point( struct draw_context *draw, + const char *v0 ) +{ + struct prim_header prim; + + prim.reset_line_stipple = 0; + prim.edgeflags = 1; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + + draw->pipeline.first->point( draw->pipeline.first, &prim ); +} + + +/** + * Add a line to the primitive queue. + * \param i0 index into user's vertex arrays + * \param i1 index into user's vertex arrays + */ +static void do_line( struct draw_context *draw, + const char *v0, + const char *v1 ) +{ + struct prim_header prim; + + prim.reset_line_stipple = 1; /* fixme */ + prim.edgeflags = 1; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + prim.v[1] = (struct vertex_header *)v1; + + draw->pipeline.first->line( draw->pipeline.first, &prim ); +} + +/** + * Add a triangle to the primitive queue. + */ +static void do_triangle( struct draw_context *draw, + char *v0, + char *v1, + char *v2 ) +{ + struct prim_header prim; + + prim.v[0] = (struct vertex_header *)v0; + prim.v[1] = (struct vertex_header *)v1; + prim.v[2] = (struct vertex_header *)v2; + prim.reset_line_stipple = 1; + prim.edgeflags = ((prim.v[0]->edgeflag) | + (prim.v[1]->edgeflag << 1) | + (prim.v[2]->edgeflag << 2)); + prim.pad = 0; + + if (0) debug_printf("tri ef: %d %d %d\n", + prim.v[0]->edgeflag, + prim.v[1]->edgeflag, + prim.v[2]->edgeflag); + + draw->pipeline.first->tri( draw->pipeline.first, &prim ); +} + + + +void draw_pt_reset_vertex_ids( struct draw_context *draw ) +{ + unsigned i; + char *verts = draw->pt.pipeline.verts; + unsigned stride = draw->pt.pipeline.vertex_stride; + + for (i = 0; i < draw->pt.pipeline.vertex_count; i++) { + ((struct vertex_header *)verts)->vertex_id = UNDEFINED_VERTEX_ID; + verts += stride; + } +} + + +/* Code to run the pipeline on a fairly arbitary collection of vertices. + * + * Vertex headers must be pre-initialized with the + * UNDEFINED_VERTEX_ID, this code will cause that id to become + * overwritten, so it may have to be reset if there is the intention + * to reuse the vertices. + * + * This code provides a callback to reset the vertex id's which the + * draw_vbuf.c code uses when it has to perform a flush. + */ +void draw_pt_run_pipeline( struct draw_context *draw, + unsigned prim, + char *verts, + unsigned stride, + unsigned vertex_count, + const ushort *elts, + unsigned count ) +{ + unsigned i; + + draw->pt.pipeline.verts = verts; + draw->pt.pipeline.vertex_stride = stride; + draw->pt.pipeline.vertex_count = vertex_count; + + switch (prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i++) + do_point( draw, + verts + stride * elts[i] ); + break; + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) + do_line( draw, + verts + stride * elts[i+0], + verts + stride * elts[i+1]); + break; + case PIPE_PRIM_TRIANGLES: + for (i = 0; i+2 < count; i += 3) + do_triangle( draw, + verts + stride * elts[i+0], + verts + stride * elts[i+1], + verts + stride * elts[i+2]); + break; + } + + draw->pt.pipeline.verts = NULL; + draw->pt.pipeline.vertex_count = 0; +} + diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 5a068761df9..107dcfc269c 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -55,9 +55,6 @@ struct vcache_frontend { unsigned draw_count; unsigned fetch_count; - pt_elt_func elt_func; - const void *elt_ptr; - struct draw_pt_middle_end *middle; unsigned input_prim; @@ -66,17 +63,6 @@ struct vcache_frontend { static void vcache_flush( struct vcache_frontend *vcache ) { -#if 0 - /* Should always be true if output_prim == input_prim, otherwise - * not so much... - */ - unsigned i; - for (i = 0; i < vcache->draw_count; i++) { - assert( vcache->fetch_elts[vcache->draw_elts[i]] == - vcache->elt_func(vcache->elt_ptr, i) ); - } -#endif - if (vcache->draw_count) { vcache->middle->run( vcache->middle, vcache->fetch_elts, @@ -115,26 +101,73 @@ static void vcache_elt( struct vcache_frontend *vcache, vcache->draw_elts[vcache->draw_count++] = vcache->out[idx]; } + +static unsigned add_edgeflag( struct vcache_frontend *vcache, + unsigned idx, + unsigned mask ) +{ + if (mask && draw_get_edgeflag(vcache->draw, idx)) + return idx | DRAW_PT_EDGEFLAG; + else + return idx; +} + + +static unsigned add_reset_stipple( unsigned idx, + unsigned reset ) +{ + if (reset) + return idx | DRAW_PT_RESET_STIPPLE; + else + return idx; +} + static void vcache_triangle( struct vcache_frontend *vcache, unsigned i0, unsigned i1, unsigned i2 ) { - /* TODO: encode edgeflags in draw_elts */ + vcache_elt(vcache, i0 | DRAW_PT_EDGEFLAG | DRAW_PT_RESET_STIPPLE); + vcache_elt(vcache, i1 | DRAW_PT_EDGEFLAG); + vcache_elt(vcache, i2 | DRAW_PT_EDGEFLAG); + vcache_check_flush(vcache); +} + + +static void vcache_ef_triangle( struct vcache_frontend *vcache, + boolean reset_stipple, + unsigned ef_mask, + unsigned i0, + unsigned i1, + unsigned i2 ) +{ + i0 = add_edgeflag( vcache, i0, (ef_mask >> 0) & 1 ); + i1 = add_edgeflag( vcache, i1, (ef_mask >> 1) & 1 ); + i2 = add_edgeflag( vcache, i2, (ef_mask >> 2) & 1 ); + + i0 = add_reset_stipple( i0, reset_stipple ); + vcache_elt(vcache, i0); vcache_elt(vcache, i1); vcache_elt(vcache, i2); vcache_check_flush(vcache); + + if (0) debug_printf("emit tri ef: %d %d %d\n", + !!(i0 & DRAW_PT_EDGEFLAG), + !!(i1 & DRAW_PT_EDGEFLAG), + !!(i2 & DRAW_PT_EDGEFLAG)); + } + static void vcache_line( struct vcache_frontend *vcache, - boolean reset, + boolean reset_stipple, unsigned i0, unsigned i1 ) { - /* TODO: encode reset-line-stipple in draw_elts */ - (void) reset; + i0 = add_reset_stipple( i0, reset_stipple ); + vcache_elt(vcache, i0); vcache_elt(vcache, i1); vcache_check_flush(vcache); @@ -158,39 +191,43 @@ static void vcache_quad( struct vcache_frontend *vcache, vcache_triangle( vcache, i1, i2, i3 ); } +static void vcache_ef_quad( struct vcache_frontend *vcache, + unsigned i0, + unsigned i1, + unsigned i2, + unsigned i3 ) +{ + const unsigned omitEdge2 = ~(1 << 1); + const unsigned omitEdge3 = ~(1 << 2); + vcache_ef_triangle( vcache, 1, omitEdge2, i0, i1, i3 ); + vcache_ef_triangle( vcache, 0, omitEdge3, i1, i2, i3 ); +} + -static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { - PIPE_PRIM_POINTS, - PIPE_PRIM_LINES, - PIPE_PRIM_LINES, - PIPE_PRIM_LINES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES -}; -static void vcache_run_pv2( struct draw_pt_front_end *frontend, - pt_elt_func get_elt, - const void *elts, - unsigned count ) +static void vcache_run( struct draw_pt_front_end *frontend, + pt_elt_func get_elt, + const void *elts, + unsigned count ) { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; + struct draw_context *draw = vcache->draw; + + boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL); + + boolean flatfirst = (draw->rasterizer->flatshade && + draw->rasterizer->flatshade_first); unsigned i; - - /* These are for validation only: - */ - vcache->elt_func = get_elt; - vcache->elt_ptr = elts; + +// debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count ); switch (vcache->input_prim) { case PIPE_PRIM_POINTS: for (i = 0; i < count; i ++) { - vcache_point( vcache, - get_elt(elts, i) ); + vcache_point( vcache, + get_elt(elts, i + 0) ); } break; @@ -205,17 +242,17 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend, case PIPE_PRIM_LINE_LOOP: if (count >= 2) { - for (i = 1; i < count; i++) { - vcache_line( vcache, + for (i = 1; i < count; i++) { + vcache_line( vcache, i == 1, /* XXX: only if vb not split */ get_elt(elts, i - 1), - get_elt(elts, i) ); - } + get_elt(elts, i )); + } - vcache_line( vcache, + vcache_line( vcache, 0, get_elt(elts, count - 1), - get_elt(elts, 0) ); + get_elt(elts, 0 )); } break; @@ -224,72 +261,163 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend, vcache_line( vcache, i == 1, get_elt(elts, i - 1), - get_elt(elts, i) ); + get_elt(elts, i )); } break; case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2) ); + if (unfilled) { + for (i = 0; i+2 < count; i += 3) { + vcache_ef_triangle( vcache, + 1, + ~0, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2 )); + } + } + else { + for (i = 0; i+2 < count; i += 3) { + vcache_triangle( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2 )); + } } break; case PIPE_PRIM_TRIANGLE_STRIP: - for (i = 0; i+2 < count; i++) { - if (i & 1) { - vcache_triangle( vcache, - get_elt(elts, i + 1), - get_elt(elts, i + 0), - get_elt(elts, i + 2) ); + if (flatfirst) { + for (i = 0; i+2 < count; i++) { + if (i & 1) { + vcache_triangle( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 2), + get_elt(elts, i + 1 )); + } + else { + vcache_triangle( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2 )); + } } - else { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2) ); + } + else { + for (i = 0; i+2 < count; i++) { + if (i & 1) { + vcache_triangle( vcache, + get_elt(elts, i + 1), + get_elt(elts, i + 0), + get_elt(elts, i + 2 )); + } + else { + vcache_triangle( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2 )); + } } } break; case PIPE_PRIM_TRIANGLE_FAN: - for (i = 0; i+2 < count; i++) { - vcache_triangle( vcache, - get_elt(elts, 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2) ); + if (count >= 3) { + if (flatfirst) { + for (i = 0; i+2 < count; i++) { + vcache_triangle( vcache, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0 )); + } + } + else { + for (i = 0; i+2 < count; i++) { + vcache_triangle( vcache, + get_elt(elts, 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2 )); + } + } } break; case PIPE_PRIM_QUADS: - for (i = 0; i+3 < count; i += 4) { - vcache_quad( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, i + 3)); + if (unfilled) { + for (i = 0; i+3 < count; i += 4) { + vcache_ef_quad( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, i + 3)); + } + } + else { + for (i = 0; i+3 < count; i += 4) { + vcache_quad( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, i + 3)); + } } break; case PIPE_PRIM_QUAD_STRIP: - for (i = 0; i+3 < count; i += 2) { - vcache_quad( vcache, - get_elt(elts, i + 2), - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 3)); + if (unfilled) { + for (i = 0; i+3 < count; i += 2) { + vcache_ef_quad( vcache, + get_elt(elts, i + 2), + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 3)); + } + } + else { + for (i = 0; i+3 < count; i += 2) { + vcache_quad( vcache, + get_elt(elts, i + 2), + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 3)); + } } break; case PIPE_PRIM_POLYGON: - for (i = 0; i+2 < count; i++) { - vcache_triangle( vcache, - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, 0)); + if (unfilled) { + /* These bitflags look a little odd because we submit the + * vertices as (1,2,0) to satisfy flatshade requirements. + */ + const unsigned edge_first = (1<<2); + const unsigned edge_middle = (1<<0); + const unsigned edge_last = (1<<1); + + for (i = 0; i+2 < count; i++) { + unsigned ef_mask = edge_middle; + + if (i == 0) + ef_mask |= edge_first; + + if (i + 3 == count) + ef_mask |= edge_last; + + vcache_ef_triangle( vcache, + i == 0, + ef_mask, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0)); + } + } + else { + for (i = 0; i+2 < count; i++) { + vcache_triangle( vcache, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0)); + } } break; @@ -302,88 +430,21 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend, } -static void vcache_run_pv0( struct draw_pt_front_end *frontend, - pt_elt_func get_elt, - const void *elts, - unsigned count ) -{ - struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; - unsigned i; - - /* These are for validation only: - */ - vcache->elt_func = get_elt; - vcache->elt_ptr = elts; - - switch (vcache->input_prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i ++) { - vcache_point( vcache, - get_elt(elts, i) ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - vcache_line( vcache, - TRUE, - get_elt(elts, i + 0), - get_elt(elts, i + 1)); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < count; i++) { - vcache_line( vcache, - i == 1, - get_elt(elts, i - 1), - get_elt(elts, i) ); - } - break; - - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2) ); - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - for (i = 0; i+2 < count; i++) { - if (i & 1) { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 2), - get_elt(elts, i + 1) ); - } - else { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2) ); - } - } - break; - case PIPE_PRIM_TRIANGLE_FAN: - for (i = 0; i+2 < count; i++) { - vcache_triangle( vcache, - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, 0) ); - } - break; +static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { + PIPE_PRIM_POINTS, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES +}; - default: - assert(0); - break; - } - - vcache_flush( vcache ); -} static void vcache_prepare( struct draw_pt_front_end *frontend, unsigned prim, @@ -391,11 +452,14 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; +/* if (vcache->draw->rasterizer->flatshade_first) vcache->base.run = vcache_run_pv0; else vcache->base.run = vcache_run_pv2; - +*/ + + vcache->base.run = vcache_run; vcache->input_prim = prim; vcache->output_prim = reduced_prim[prim]; diff --git a/src/gallium/auxiliary/draw/draw_vertex_cache.c b/src/gallium/auxiliary/draw/draw_vertex_cache.c index 161b247d4e9..c0248979e26 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_cache.c +++ b/src/gallium/auxiliary/draw/draw_vertex_cache.c @@ -101,7 +101,7 @@ static struct vertex_header *get_vertex( struct draw_context *draw, draw->vs.queue[out].elt = i; draw->vs.queue[out].vertex->clipmask = 0; - draw->vs.queue[out].vertex->edgeflag = 1; /*XXX use user's edge flag! */ + 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; |