summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/draw
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r--src/gallium/auxiliary/draw/Makefile1
-rw-r--r--src/gallium/auxiliary/draw/SConscript1
-rw-r--r--src/gallium/auxiliary/draw/draw_clip.c15
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c19
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h3
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h27
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h10
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c163
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_pipeline.c168
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache.c396
-rw-r--r--src/gallium/auxiliary/draw/draw_vertex_cache.c2
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;