From 84501e68f6294370d6f2f6aec4e7eab57bcc0e72 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 4 Apr 2008 17:02:20 +0100 Subject: [PATCH] gallium: Handle client-supplied edgeflags. Also, implement support in the draw module. We were hardwiring these to one for quite a long time... Currently using a draw_set_edgeflags() function, may be better to push the argument into the draw_arrays() function. TBD. --- src/gallium/auxiliary/draw/draw_context.c | 16 ++++++ src/gallium/auxiliary/draw/draw_context.h | 3 ++ src/gallium/auxiliary/draw/draw_private.h | 13 ++--- .../auxiliary/draw/draw_pt_fetch_pipeline.c | 49 +++++++++++++------ src/gallium/auxiliary/draw/draw_pt_pipeline.c | 8 +-- .../auxiliary/draw/draw_vertex_cache.c | 2 +- src/gallium/include/pipe/p_context.h | 8 +++ 7 files changed, 71 insertions(+), 28 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 470c1c571b4..b3c65c90d67 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -444,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 48545af9e2b..4d056f6dbaf 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -250,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) */ @@ -402,15 +404,6 @@ void draw_pt_run_pipeline( struct draw_context *draw, unsigned count ); -/* Prototype/hack (DEPRECATED) - */ -boolean -draw_passthrough_arrays(struct draw_context *draw, - unsigned prim, - unsigned start, - unsigned count); - - #define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */ #define DRAW_FLUSH_PRIM_QUEUE 0x2 #define DRAW_FLUSH_VERTEX_CACHE 0x4 @@ -420,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_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c index 0ddb400f7e9..ba95420b72a 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)( const unsigned *edgeflag, unsigned count, 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,8 +122,9 @@ static void emit_R32G32B32A32_FLOAT( const float *attrib, (*out) += 4; } -static void emit_header( const float *attrib, - float **out ) +static void header( const unsigned *edgeflag, + unsigned idx, + float **out ) { struct vertex_header *header = (struct vertex_header *) (*out); @@ -143,6 +140,26 @@ static void emit_header( const float *attrib, (*out) += 5; } + +static void header_ef( const unsigned *edgeflag, + unsigned idx, + float **out ) +{ + struct vertex_header *header = (struct vertex_header *) (*out); + + header->clipmask = 0; + header->edgeflag = (edgeflag[idx/32] & (1 << (idx%32))) != 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,12 +172,15 @@ fetch_store_general( struct fetch_pipeline_middle_end *fpme, const unsigned *fetch_elts, unsigned count ) { + const unsigned *edgeflag = fpme->draw->user.edgeflag; float *out = (float *)out_ptr; uint i, j; for (i = 0; i < count; i++) { unsigned elt = fetch_elts[i]; + fpme->header( edgeflag, i, &out ); + for (j = 0; j < fpme->nr_fetch; j++) { float attrib[4]; const ubyte *from = (fpme->fetch[j].ptr + @@ -200,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; } @@ -232,7 +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); + fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); } diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c index 6e46d3925f0..942df518eb2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_pipeline.c @@ -86,12 +86,14 @@ static void do_triangle( struct draw_context *draw, 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; + prim.reset_line_stipple = 1; + prim.edgeflags = ((prim.v[0]->edgeflag) | + (prim.v[1]->edgeflag << 1) | + (prim.v[2]->edgeflag << 2)); + prim.pad = 0; draw->pipeline.first->tri( draw->pipeline.first, &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; diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 324f70185af..f3a9c2cd8b2 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -57,6 +57,14 @@ struct pipe_context { void (*destroy)( struct pipe_context * ); + + /* Possible interface for setting edgeflags. These aren't really + * vertex elements, so don't fit there. + */ + void (*set_edgeflags)( struct pipe_context *, + const unsigned *bitfield ); + + /** * VBO drawing (return false on fallbacks (temporary??)) */ -- 2.30.2