summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2008-05-03 22:32:17 -0400
committerZack Rusin <[email protected]>2008-05-08 15:26:08 -0400
commitabb08e9335b5d7cb004dc9e6cec390ab6968abe5 (patch)
tree56a15f6fc8a3e663fc179df61ac789a67b4c4eef
parent90a46ed277cc887d49c8d8c627174c3bd693ecf7 (diff)
implement linear emition and fetching and plug it in the varray paths
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h18
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_emit.c45
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch.c36
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c88
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_varray.c26
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_varray_tmp.h4
6 files changed, 208 insertions, 9 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index 2dec376ceee..2f96ceaf00d 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -92,6 +92,12 @@ struct draw_pt_middle_end {
const ushort *draw_elts,
unsigned draw_count );
+ void (*run_linear)(struct draw_pt_middle_end *,
+ unsigned fetch_start,
+ unsigned fetch_count,
+ const ushort *draw_elts,
+ unsigned draw_count);
+
void (*finish)( struct draw_pt_middle_end * );
void (*destroy)( struct draw_pt_middle_end * );
};
@@ -152,6 +158,13 @@ void draw_pt_emit( struct pt_emit *emit,
const ushort *elts,
unsigned count );
+void draw_pt_emit_linear( struct pt_emit *emit,
+ const float (*vertex_data)[4],
+ unsigned vertex_count,
+ unsigned stride,
+ unsigned start,
+ unsigned count );
+
void draw_pt_emit_destroy( struct pt_emit *emit );
struct pt_emit *draw_pt_emit_create( struct draw_context *draw );
@@ -170,6 +183,11 @@ void draw_pt_fetch_run( struct pt_fetch *fetch,
unsigned count,
char *verts );
+void draw_pt_fetch_run_linear( struct pt_fetch *fetch,
+ unsigned start,
+ unsigned count,
+ char *verts );
+
void draw_pt_fetch_destroy( struct pt_fetch *fetch );
struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw );
diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c
index f9ac16786ef..2a961b7088d 100644
--- a/src/gallium/auxiliary/draw/draw_pt_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_emit.c
@@ -179,6 +179,51 @@ void draw_pt_emit( struct pt_emit *emit,
}
+void draw_pt_emit_linear(struct pt_emit *emit,
+ const float (*vertex_data)[4],
+ unsigned vertex_count,
+ unsigned stride,
+ unsigned start,
+ unsigned count)
+{
+ struct draw_context *draw = emit->draw;
+ struct translate *translate = emit->translate;
+ struct vbuf_render *render = draw->render;
+ void *hw_verts;
+
+ debug_printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n");
+ /* XXX: need to flush to get prim_vbuf.c to release its allocation??
+ */
+ draw_do_flush( draw, DRAW_FLUSH_BACKEND );
+
+ hw_verts = render->allocate_vertices(render,
+ (ushort)translate->key.output_stride,
+ (ushort)count);
+ if (!hw_verts) {
+ assert(0);
+ return;
+ }
+
+ translate->set_buffer(translate, 0,
+ vertex_data, stride);
+
+ translate->set_buffer(translate, 1,
+ &draw->rasterizer->point_size,
+ 0);
+
+ translate->run(translate,
+ 0,
+ vertex_count,
+ hw_verts);
+
+ render->draw_arrays(render, start, count);
+
+ render->release_vertices(render,
+ hw_verts,
+ translate->key.output_stride,
+ vertex_count);
+}
+
struct pt_emit *draw_pt_emit_create( struct draw_context *draw )
{
struct pt_emit *emit = CALLOC_STRUCT(pt_emit);
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c
index 1f765b73adf..d7cc1807d77 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -167,6 +167,42 @@ void draw_pt_fetch_run( struct pt_fetch *fetch,
}
+void draw_pt_fetch_run_linear( struct pt_fetch *fetch,
+ unsigned start,
+ unsigned count,
+ char *verts )
+{
+ struct draw_context *draw = fetch->draw;
+ struct translate *translate = fetch->translate;
+ unsigned i;
+
+ for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
+ translate->set_buffer(translate,
+ i,
+ ((char *)draw->pt.user.vbuffer[i] +
+ draw->pt.vertex_buffer[i].buffer_offset),
+ draw->pt.vertex_buffer[i].pitch );
+ }
+
+ translate->run( translate,
+ start,
+ count,
+ verts );
+
+ /* Edgeflags are hard to fit into a translate program, populate
+ * them separately if required. In the setup above they are
+ * defaulted to one, so only need this if there is reason to change
+ * that default:
+ */
+ if (fetch->need_edgeflags) {
+ for (i = 0; i < count; i++) {
+ struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size);
+ vh->edgeflag = draw_pt_get_edgeflag( draw, start + i );
+ }
+ }
+}
+
+
struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw )
{
struct pt_fetch *fetch = CALLOC_STRUCT(pt_fetch);
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 4ec20493c4c..b1e08a8f402 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -162,7 +162,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
fpme->vertex_size,
draw_elts,
draw_count );
- }
+ }
else {
draw_pt_emit( fpme->emit,
(const float (*)[4])pipeline_verts->data,
@@ -177,6 +177,83 @@ 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 )
+{
+ 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 );
+
+ struct vertex_header *pipeline_verts =
+ (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count);
+
+ if (!pipeline_verts) {
+ /* Not much we can do here - just skip the rendering.
+ */
+ assert(0);
+ return;
+ }
+
+ /* Fetch into our vertex buffer
+ */
+ draw_pt_fetch_run_linear( fpme->fetch,
+ fetch_start,
+ fetch_count,
+ (char *)pipeline_verts );
+
+ /* Run the shader, note that this overwrites the data[] parts of
+ * the pipeline verts. If there is no shader, ie a bypass shader,
+ * then the inputs == outputs, and are already in the correct
+ * place.
+ */
+ if (opt & PT_SHADE)
+ {
+ shader->run_linear(shader,
+ (const float (*)[4])pipeline_verts->data,
+ ( float (*)[4])pipeline_verts->data,
+ (const float (*)[4])draw->pt.user.constants,
+ fetch_count,
+ fpme->vertex_size,
+ fpme->vertex_size);
+ }
+
+ if (draw_pt_post_vs_run( fpme->post_vs,
+ pipeline_verts,
+ fetch_count,
+ fpme->vertex_size ))
+ {
+ opt |= PT_PIPELINE;
+ }
+
+ /* 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 );
+ }
+ else {
+ draw_pt_emit_linear( fpme->emit,
+ (const float (*)[4])pipeline_verts->data,
+ fetch_count,
+ fpme->vertex_size,
+ 0, /*start*/
+ draw_count );
+ }
+
+ FREE(pipeline_verts);
+}
+
+
static void fetch_pipeline_finish( struct draw_pt_middle_end *middle )
{
@@ -206,10 +283,11 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context *
if (!fpme)
goto fail;
- fpme->base.prepare = fetch_pipeline_prepare;
- fpme->base.run = fetch_pipeline_run;
- fpme->base.finish = fetch_pipeline_finish;
- fpme->base.destroy = fetch_pipeline_destroy;
+ fpme->base.prepare = fetch_pipeline_prepare;
+ fpme->base.run = fetch_pipeline_run;
+ fpme->base.run_linear = fetch_pipeline_linear_run;
+ fpme->base.finish = fetch_pipeline_finish;
+ fpme->base.destroy = fetch_pipeline_destroy;
fpme->draw = draw;
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c
index c9843bded0d..916373acc88 100644
--- a/src/gallium/auxiliary/draw/draw_pt_varray.c
+++ b/src/gallium/auxiliary/draw/draw_pt_varray.c
@@ -75,6 +75,28 @@ static void varray_flush(struct varray_frontend *varray)
varray->draw_count = 0;
}
+static void varray_flush_linear(struct varray_frontend *varray)
+{
+ if (varray->draw_count) {
+ 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]);
+ varray->middle->run_linear(varray->middle,
+ varray->fetch_elts[0],
+ varray->fetch_count,
+ varray->draw_elts,
+ varray->draw_count);
+ }
+
+ varray->fetch_count = 0;
+ varray->draw_count = 0;
+}
+
static INLINE void fetch_init(struct varray_frontend *varray,
unsigned count)
{
@@ -265,8 +287,8 @@ static void varray_prepare(struct draw_pt_front_end *frontend,
if (opt & PT_PIPELINE)
{
varray->base.run = varray_run_extras;
- }
- else
+ }
+ else
{
varray->base.run = varray_run;
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h
index 073c1aadbf4..67baafa3be4 100644
--- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h
@@ -17,7 +17,7 @@ static void FUNC(struct draw_pt_front_end *frontend,
split_prim_inplace(varray->input_prim, &first, &incr);
-#if 1
+#if 0
debug_printf("%s (%d) %d/%d\n", __FUNCTION__,
varray->input_prim,
start, count);
@@ -88,7 +88,7 @@ static void FUNC(struct draw_pt_front_end *frontend,
i + 0, i + 1, i + 2);
}
fetch_init(varray, end);
- varray_flush(varray);
+ varray_flush_linear(varray);
}
break;