summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
authorZack Rusin <zack@tungstengraphics.com>2008-05-06 18:59:45 -0400
committerZack Rusin <zack@tungstengraphics.com>2008-05-08 15:26:26 -0400
commitfe586f8612dd517b9a1f0d87fbaf3a75e3caf588 (patch)
tree3a19e7cf2fc4699b211de7091e82ddcbff37ac8c /src/gallium
parente897fd6cd35c6b9e398e1903d2e79678fe85708a (diff)
redo the linear paths
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe.c39
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c18
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c36
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_varray.c27
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_varray_tmp.h5
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h198
8 files changed, 279 insertions, 56 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c
index 46afb0f41f..cb97f955b2 100644
--- a/src/gallium/auxiliary/draw/draw_pipe.c
+++ b/src/gallium/auxiliary/draw/draw_pipe.c
@@ -212,6 +212,45 @@ void draw_pipeline_run( struct draw_context *draw,
draw->pipeline.vertex_count = 0;
}
+void draw_pipeline_run_linear( struct draw_context *draw,
+ unsigned prim,
+ struct vertex_header *vertices,
+ unsigned count,
+ unsigned stride )
+{
+ char *verts = (char *)vertices;
+ unsigned i;
+
+ draw->pipeline.verts = verts;
+ draw->pipeline.vertex_stride = stride;
+ draw->pipeline.vertex_count = count;
+
+ switch (prim) {
+ case PIPE_PRIM_POINTS:
+ for (i = 0; i < count; i++)
+ do_point( draw,
+ verts + stride * i );
+ break;
+ case PIPE_PRIM_LINES:
+ for (i = 0; i+1 < count; i += 2)
+ do_line( draw,
+ i+0, /* flags */
+ verts + stride * ((i+0) & ~DRAW_PIPE_FLAG_MASK),
+ verts + stride * (i+1));
+ break;
+ case PIPE_PRIM_TRIANGLES:
+ for (i = 0; i+2 < count; i += 3)
+ do_triangle( draw,
+ (i+0), /* flags */
+ verts + stride * ((i+0) & ~DRAW_PIPE_FLAG_MASK),
+ verts + stride * (i+1),
+ verts + stride * (i+2));
+ break;
+ }
+
+ draw->pipeline.verts = NULL;
+ draw->pipeline.vertex_count = 0;
+}
void draw_pipeline_flush( struct draw_context *draw,
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index cee58bbf73..e036d498b8 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -247,6 +247,12 @@ void draw_pipeline_run( struct draw_context *draw,
const ushort *elts,
unsigned count );
+void draw_pipeline_run_linear( struct draw_context *draw,
+ unsigned prim,
+ struct vertex_header *vertices,
+ unsigned count,
+ unsigned stride );
+
void draw_pipeline_flush( struct draw_context *draw,
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index 2f96ceaf00..312fdbe4f4 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -93,10 +93,8 @@ struct draw_pt_middle_end {
unsigned draw_count );
void (*run_linear)(struct draw_pt_middle_end *,
- unsigned fetch_start,
- unsigned fetch_count,
- const ushort *draw_elts,
- unsigned draw_count);
+ unsigned start,
+ unsigned count);
void (*finish)( struct draw_pt_middle_end * );
void (*destroy)( struct draw_pt_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 6d5a54cf0e..8df4241b82 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -258,10 +258,8 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,
static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
- unsigned fetch_start,
- unsigned fetch_count,
- const ushort *draw_elts,
- unsigned draw_count )
+ unsigned start,
+ unsigned count )
{
struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
struct draw_context *draw = feme->draw;
@@ -273,7 +271,7 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
hw_verts = draw->render->allocate_vertices( draw->render,
(ushort)feme->translate->key.output_stride,
- (ushort)fetch_count );
+ (ushort)count );
if (!hw_verts) {
assert(0);
return;
@@ -282,13 +280,13 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
/* Single routine to fetch vertices and emit HW verts.
*/
feme->translate->run( feme->translate,
- fetch_start,
- fetch_count,
+ start,
+ count,
hw_verts );
if (0) {
unsigned i;
- for (i = 0; i < fetch_count; i++) {
+ for (i = 0; i < count; i++) {
debug_printf("\n\nvertex %d:\n", i);
draw_dump_emitted_vertex( feme->vinfo,
(const uint8_t *)hw_verts + feme->vinfo->size * 4 * i );
@@ -300,14 +298,14 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
*/
draw->render->draw_arrays( draw->render,
0, /*start*/
- draw_count );
+ count );
/* Done -- that was easy, wasn't it:
*/
draw->render->release_vertices( draw->render,
hw_verts,
feme->translate->key.output_stride,
- fetch_count );
+ count );
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index b1e08a8f40..dad54690a5 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -178,18 +178,16 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
- unsigned fetch_start,
- unsigned fetch_count,
- const ushort *draw_elts,
- unsigned draw_count )
+ unsigned start,
+ unsigned count)
{
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
struct draw_context *draw = fpme->draw;
struct draw_vertex_shader *shader = draw->vertex_shader;
unsigned opt = fpme->opt;
- unsigned alloc_count = align_int( fetch_count, 4 );
+ unsigned alloc_count = align_int( count, 4 );
- struct vertex_header *pipeline_verts =
+ struct vertex_header *pipeline_verts =
(struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count);
if (!pipeline_verts) {
@@ -202,8 +200,8 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
/* Fetch into our vertex buffer
*/
draw_pt_fetch_run_linear( fpme->fetch,
- fetch_start,
- fetch_count,
+ start,
+ count,
(char *)pipeline_verts );
/* Run the shader, note that this overwrites the data[] parts of
@@ -213,18 +211,18 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
*/
if (opt & PT_SHADE)
{
- shader->run_linear(shader,
+ shader->run_linear(shader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
(const float (*)[4])draw->pt.user.constants,
- fetch_count,
+ count,
fpme->vertex_size,
fpme->vertex_size);
}
if (draw_pt_post_vs_run( fpme->post_vs,
pipeline_verts,
- fetch_count,
+ count,
fpme->vertex_size ))
{
opt |= PT_PIPELINE;
@@ -233,21 +231,19 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
/* Do we need to run the pipeline?
*/
if (opt & PT_PIPELINE) {
- draw_pipeline_run( fpme->draw,
- fpme->prim,
- pipeline_verts,
- fetch_count,
- fpme->vertex_size,
- draw_elts,
- draw_count );
+ draw_pipeline_run_linear( fpme->draw,
+ fpme->prim,
+ pipeline_verts,
+ count,
+ fpme->vertex_size);
}
else {
draw_pt_emit_linear( fpme->emit,
(const float (*)[4])pipeline_verts->data,
- fetch_count,
+ count,
fpme->vertex_size,
0, /*start*/
- draw_count );
+ count );
}
FREE(pipeline_verts);
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c
index e7e21e4bf6..59a9569270 100644
--- a/src/gallium/auxiliary/draw/draw_pt_varray.c
+++ b/src/gallium/auxiliary/draw/draw_pt_varray.c
@@ -75,29 +75,18 @@ static void varray_flush(struct varray_frontend *varray)
varray->draw_count = 0;
}
-static void varray_flush_linear(struct varray_frontend *varray)
+static void varray_flush_linear(struct varray_frontend *varray,
+ unsigned start, unsigned count)
{
- if (varray->draw_count) {
+ if (count) {
#if 0
- debug_printf("FLUSH LINEAR fc = %d, dc = %d\n",
- varray->fetch_count,
- varray->draw_count);
- debug_printf("\telt0 = %d, eltx = %d, draw0 = %d, drawx = %d\n",
- varray->fetch_elts[0],
- varray->fetch_elts[varray->fetch_count-1],
- varray->draw_elts[0],
- varray->draw_elts[varray->draw_count-1]);
+ debug_printf("FLUSH LINEAR start = %d, count = %d\n",
+ start,
+ count);
#endif
assert(varray->middle->run_linear);
- varray->middle->run_linear(varray->middle,
- varray->fetch_start,
- varray->fetch_count,
- varray->draw_elts,
- varray->draw_count);
+ varray->middle->run_linear(varray->middle, start, count);
}
-
- varray->fetch_count = 0;
- varray->draw_count = 0;
}
static INLINE void fetch_init(struct varray_frontend *varray,
@@ -261,7 +250,7 @@ static INLINE void varray_ef_quad( struct varray_frontend *varray,
#define LINE(vc,flags,i0,i1) varray_line(vc,i0,i1)
#define POINT(vc,i0) varray_point(vc,i0)
#define FUNC varray_run
-#include "draw_pt_varray_tmp.h"
+#include "draw_pt_varray_tmp_linear.h"
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h
index 10ac08ea30..335c4c89ca 100644
--- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h
@@ -92,9 +92,8 @@ static void FUNC(struct draw_pt_front_end *frontend,
i + 0, i + 1, i + 2);
}
i = end;
- varray->fetch_count = end;
- varray_flush_linear(varray);
- varray->fetch_start += end;
+ fetch_init(varray, end);
+ varray_flush(varray);
}
break;
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
new file mode 100644
index 0000000000..dfa4338407
--- /dev/null
+++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
@@ -0,0 +1,198 @@
+
+static void FUNC(struct draw_pt_front_end *frontend,
+ pt_elt_func get_elt,
+ const void *elts,
+ unsigned count)
+{
+ struct varray_frontend *varray = (struct varray_frontend *)frontend;
+ struct draw_context *draw = varray->draw;
+ unsigned start = (unsigned)elts;
+
+ boolean flatfirst = (draw->rasterizer->flatshade &&
+ draw->rasterizer->flatshade_first);
+ unsigned i, j, flags;
+ unsigned first, incr;
+
+ varray->fetch_start = start;
+
+ split_prim_inplace(varray->input_prim, &first, &incr);
+
+#if 0
+ debug_printf("%s (%d) %d/%d\n", __FUNCTION__,
+ varray->input_prim,
+ start, count);
+#endif
+
+ switch (varray->input_prim) {
+ case PIPE_PRIM_POINTS:
+ case PIPE_PRIM_LINES:
+ case PIPE_PRIM_TRIANGLES:
+ j = 0;
+ while (j + first <= count) {
+ unsigned end = MIN2(FETCH_MAX, count - j);
+ end -= (end % incr);
+ varray_flush_linear(varray, start + j, end);
+ j += end;
+ }
+ break;
+
+ case PIPE_PRIM_LINE_LOOP:
+ if (count >= 2) {
+ flags = DRAW_PIPE_RESET_STIPPLE;
+
+ for (j = 0; j + first <= count; j += i) {
+ unsigned end = MIN2(FETCH_MAX, count - j);
+ end -= (end % incr);
+ for (i = 1; i < end; i++, flags = 0) {
+ LINE(varray, flags, i - 1, i);
+ }
+ LINE(varray, flags, i - 1, 0);
+ i = end;
+ fetch_init(varray, end);
+ varray_flush(varray);
+ }
+ }
+ break;
+
+ case PIPE_PRIM_LINE_STRIP:
+ flags = DRAW_PIPE_RESET_STIPPLE;
+ for (j = 0; j + first <= count; j += i) {
+ unsigned end = MIN2(FETCH_MAX, count - j);
+ end -= (end % incr);
+ for (i = 1; i < end; i++, flags = 0) {
+ LINE(varray, flags, i - 1, i);
+ }
+ i = end;
+ fetch_init(varray, end);
+ varray_flush(varray);
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ if (flatfirst) {
+ for (j = 0; j + first <= count; j += i) {
+ unsigned end = MIN2(FETCH_MAX, count - j);
+ end -= (end % incr);
+ for (i = 0; i+2 < end; i++) {
+ TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
+ i + 0, i + 1 + (i&1), i + 2 - (i&1));
+ }
+ i = end;
+ fetch_init(varray, end);
+ varray_flush(varray);
+ }
+ }
+ else {
+ for (j = 0; j + first <= count;) {
+ unsigned end = MIN2(FETCH_MAX, count - j);
+ //end -= (end % incr);
+ for (i = 0; i+2 < end; i++) {
+ TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
+ i + 0 + (i&1), i + 1 - (i&1), i + 2);
+ }
+ fetch_init(varray, end);
+ varray_flush(varray);
+ j += end;
+ if (j <= count)
+ j -= incr;
+ }
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLE_FAN:
+ if (count >= 3) {
+ if (flatfirst) {
+ flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
+ for (j = 0; j + first <= count; j += i) {
+ unsigned end = MIN2(FETCH_MAX, count - j);
+ end -= (end % incr);
+ for (i = 0; i+2 < end; i++) {
+ TRIANGLE(varray, flags, i + 1, i + 2, 0);
+ }
+ i = end;
+ fetch_init(varray, end);
+ varray_flush(varray);
+ }
+ }
+ else {
+ flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
+ for (j = 0; j + first <= count; j += i) {
+ unsigned end = MIN2(FETCH_MAX, count - j);
+ end -= (end % incr);
+ for (i = 0; i+2 < end; i++) {
+ TRIANGLE(varray, flags, 0, i + 1, i + 2);
+ }
+ i = end;
+ fetch_init(varray, end);
+ varray_flush(varray);
+ }
+ }
+ }
+ break;
+
+ case PIPE_PRIM_QUADS:
+ for (j = 0; j + first <= count; j += i) {
+ unsigned end = MIN2(FETCH_MAX, count - j);
+ end -= (end % incr);
+ for (i = 0; i+3 < end; i += 4) {
+ QUAD(varray, i + 0, i + 1, i + 2, i + 3);
+ }
+ i = end;
+ fetch_init(varray, end);
+ varray_flush(varray);
+ }
+ break;
+
+ case PIPE_PRIM_QUAD_STRIP:
+ for (j = 0; j + first <= count; j += i) {
+ unsigned end = MIN2(FETCH_MAX, count - j);
+ end -= (end % incr);
+ for (i = 0; i+3 < end; i += 2) {
+ QUAD(varray, i + 2, i + 0, i + 1, i + 3);
+ }
+ i = end;
+ fetch_init(varray, end);
+ varray_flush(varray);
+ }
+ break;
+
+ case PIPE_PRIM_POLYGON:
+ {
+ /* These bitflags look a little odd because we submit the
+ * vertices as (1,2,0) to satisfy flatshade requirements.
+ */
+ const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2;
+ const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0;
+ const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1;
+
+ flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
+ for (j = 0; j + first <= count; j += i) {
+ unsigned end = MIN2(FETCH_MAX, count - j);
+ end -= (end % incr);
+ for (i = 0; i+2 < end; i++, flags = edge_middle) {
+
+ if (i + 3 == count)
+ flags |= edge_last;
+
+ TRIANGLE(varray, flags, i + 1, i + 2, 0);
+ }
+ i = end;
+ fetch_init(varray, end);
+ varray_flush(varray);
+ }
+ }
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ varray_flush(varray);
+}
+
+#undef TRIANGLE
+#undef QUAD
+#undef POINT
+#undef LINE
+#undef FUNC