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.
This commit is contained in:
Keith Whitwell 2008-04-04 17:02:20 +01:00
parent 1d6877b326
commit 84501e68f6
7 changed files with 71 additions and 28 deletions

View file

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

View file

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

View file

@ -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 );
/**

View file

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

View file

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

View file

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

View file

@ -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??))
*/