diff options
author | Keith Whitwell <[email protected]> | 2010-06-23 18:06:52 +0100 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2010-06-23 18:10:20 +0100 |
commit | 64682da8ab7aff7b4ce651db99a32ed1fd8b178c (patch) | |
tree | a216f21f6caa1628c7b25defd5a19a777226725c /src/gallium/auxiliary/draw | |
parent | 292eecca8c4284cbb343d954b76586fcaa26de2a (diff) |
draw: don't try to precalculate the pipeline output primitive
We were previously calculating a value which was either the geometry
shader output primitive or the application's input primitive, and
passing that to the various front/middle/back components for use as
the ultimate rendering primtive.
Unfortunately, this was not correct -- if the vcache decomposition
path is active and geometry shaders are *not* active, we can end up
with a third primitive -- specifically the decomposed version of the
input primitive.
Rather than trying to precalculate this, just let the individual
components inform their successors about which primitive type they are
recieving.
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt.c | 12 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt.h | 6 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 9 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c | 8 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 13 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c | 8 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_varray.c | 8 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_vcache.c | 16 |
8 files changed, 46 insertions, 34 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 02c97fec817..6234272d6ce 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -69,7 +69,6 @@ draw_pt_arrays(struct draw_context *draw, struct draw_pt_front_end *frontend = NULL; struct draw_pt_middle_end *middle = NULL; unsigned opt = 0; - unsigned out_prim = prim; /* Sanitize primitive length: */ @@ -80,18 +79,19 @@ draw_pt_arrays(struct draw_context *draw, if (count < first) return TRUE; } - if (draw->gs.geometry_shader) { - out_prim = draw->gs.geometry_shader->output_primitive; - } if (!draw->force_passthrough) { + unsigned gs_out_prim = (draw->gs.geometry_shader ? + draw->gs.geometry_shader->output_primitive : + prim); + if (!draw->render) { opt |= PT_PIPELINE; } if (draw_need_pipeline(draw, draw->rasterizer, - out_prim)) { + gs_out_prim)) { opt |= PT_PIPELINE; } @@ -122,7 +122,7 @@ draw_pt_arrays(struct draw_context *draw, frontend = draw->pt.front.varray; } - frontend->prepare( frontend, prim, out_prim, middle, opt ); + frontend->prepare( frontend, prim, middle, opt ); frontend->run(frontend, draw_pt_elt_func(draw), diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index b6741ca83ce..44356fba4c5 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -62,8 +62,7 @@ struct draw_vertex_info; */ struct draw_pt_front_end { void (*prepare)( struct draw_pt_front_end *, - unsigned input_prim, - unsigned output_prim, + unsigned prim, struct draw_pt_middle_end *, unsigned opt ); @@ -87,8 +86,7 @@ struct draw_pt_front_end { */ struct draw_pt_middle_end { void (*prepare)( struct draw_pt_middle_end *, - unsigned input_prim, - unsigned output_prim, + unsigned prim, unsigned opt, unsigned *max_vertices ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index c629d555636..5c8af17c8e3 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -36,6 +36,7 @@ #include "draw/draw_vbuf.h" #include "draw/draw_vertex.h" #include "draw/draw_pt.h" +#include "draw/draw_gs.h" #include "translate/translate.h" #include "translate/translate_cache.h" @@ -90,7 +91,6 @@ struct fetch_emit_middle_end { static void fetch_emit_prepare( struct draw_pt_middle_end *middle, unsigned prim, - unsigned out_prim, unsigned opt, unsigned *max_vertices ) { @@ -101,9 +101,14 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, boolean ok; struct translate_key key; + unsigned gs_out_prim = (draw->gs.geometry_shader ? + draw->gs.geometry_shader->output_primitive : + prim); + + ok = draw->render->set_primitive( draw->render, - out_prim ); + gs_out_prim ); if (!ok) { assert(0); return; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 5483a25f1dc..b8270280b64 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -68,8 +68,7 @@ struct fetch_shade_emit { static void fse_prepare( struct draw_pt_middle_end *middle, - unsigned in_prim, - unsigned out_prim, + unsigned prim, unsigned opt, unsigned *max_vertices ) { @@ -80,9 +79,12 @@ static void fse_prepare( struct draw_pt_middle_end *middle, unsigned i; unsigned nr_vbs = 0; + /* Can't support geometry shader on this path. + */ + assert(!draw->gs.geometry_shader); if (!draw->render->set_primitive( draw->render, - out_prim )) { + prim )) { assert(0); return; } 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 43b08a030cf..047e192d4d1 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -48,13 +48,11 @@ struct fetch_pipeline_middle_end { unsigned vertex_data_offset; unsigned vertex_size; unsigned input_prim; - unsigned output_prim; unsigned opt; }; static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, - unsigned in_prim, - unsigned out_prim, + unsigned prim, unsigned opt, unsigned *max_vertices ) { @@ -64,6 +62,10 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, unsigned i; unsigned instance_id_index = ~0; + unsigned gs_out_prim = (draw->gs.geometry_shader ? + draw->gs.geometry_shader->output_primitive : + prim); + /* Add one to num_outputs because the pipeline occasionally tags on * an additional texcoord, eg for AA lines. */ @@ -79,8 +81,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, } } - fpme->input_prim = in_prim; - fpme->output_prim = out_prim; + fpme->input_prim = prim; fpme->opt = opt; /* Always leave room for the vertex header whether we need it or @@ -108,7 +109,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, if (!(opt & PT_PIPELINE)) { draw_pt_emit_prepare( fpme->emit, - out_prim, + gs_out_prim, max_vertices ); *max_vertices = MAX2( *max_vertices, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index 7d2de58e733..774fb7bf7a2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -49,7 +49,6 @@ struct llvm_middle_end { unsigned vertex_data_offset; unsigned vertex_size; unsigned input_prim; - unsigned output_prim; unsigned opt; struct draw_llvm *llvm; @@ -62,7 +61,6 @@ struct llvm_middle_end { static void llvm_middle_end_prepare( struct draw_pt_middle_end *middle, unsigned in_prim, - unsigned out_prim, unsigned opt, unsigned *max_vertices ) { @@ -74,6 +72,11 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle, unsigned i; unsigned instance_id_index = ~0; + + unsigned out_prim = (draw->gs.geometry_shader ? + draw->gs.geometry_shader->output_primitive : + in_prim); + /* Add one to num_outputs because the pipeline occasionally tags on * an additional texcoord, eg for AA lines. */ @@ -90,7 +93,6 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle, } fpme->input_prim = in_prim; - fpme->output_prim = out_prim; fpme->opt = opt; /* Always leave room for the vertex header whether we need it or diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index 5ea833032f3..d89d5cd20f4 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -137,7 +137,6 @@ static unsigned decompose_prim[PIPE_PRIM_POLYGON + 1] = { static void varray_prepare(struct draw_pt_front_end *frontend, unsigned in_prim, - unsigned out_prim, struct draw_pt_middle_end *middle, unsigned opt) { @@ -146,11 +145,12 @@ static void varray_prepare(struct draw_pt_front_end *frontend, varray->base.run = varray_run; varray->input_prim = in_prim; - varray->output_prim = decompose_prim[out_prim]; + varray->output_prim = decompose_prim[in_prim]; varray->middle = middle; - middle->prepare(middle, varray->input_prim, - varray->output_prim, opt, &varray->driver_fetch_max ); + middle->prepare(middle, + varray->output_prim, + opt, &varray->driver_fetch_max ); /* check that the max is even */ assert((varray->driver_fetch_max & 1) == 0); diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 914c87a9dc4..b7e0da7d44e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -70,7 +70,6 @@ vcache_flush( struct vcache_frontend *vcache ) if (vcache->middle_prim != vcache->output_prim) { vcache->middle_prim = vcache->output_prim; vcache->middle->prepare( vcache->middle, - vcache->input_prim, vcache->middle_prim, vcache->opt, &vcache->fetch_max ); @@ -368,7 +367,6 @@ vcache_check_run( struct draw_pt_front_end *frontend, if (vcache->middle_prim != vcache->input_prim) { vcache->middle_prim = vcache->input_prim; vcache->middle->prepare( vcache->middle, - vcache->input_prim, vcache->middle_prim, vcache->opt, &vcache->fetch_max ); @@ -472,7 +470,6 @@ vcache_check_run( struct draw_pt_front_end *frontend, static void vcache_prepare( struct draw_pt_front_end *frontend, unsigned in_prim, - unsigned out_prim, struct draw_pt_middle_end *middle, unsigned opt ) { @@ -487,8 +484,14 @@ vcache_prepare( struct draw_pt_front_end *frontend, vcache->base.run = vcache_check_run; } + /* VCache will always emit the reduced version of its input + * primitive, ie STRIP/FANS become TRIS, etc. + * + * This is not to be confused with what the GS might be up to, + * which is a separate issue. + */ vcache->input_prim = in_prim; - vcache->output_prim = u_reduced_prim(out_prim); + vcache->output_prim = u_reduced_prim(in_prim); vcache->middle = middle; vcache->opt = opt; @@ -497,8 +500,9 @@ vcache_prepare( struct draw_pt_front_end *frontend, * doing so: */ vcache->middle_prim = (opt & PT_PIPELINE) ? vcache->output_prim : vcache->input_prim; - middle->prepare( middle, vcache->input_prim, - vcache->middle_prim, opt, &vcache->fetch_max ); + middle->prepare( middle, + vcache->middle_prim, + opt, &vcache->fetch_max ); } |