summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2010-06-23 18:06:52 +0100
committerKeith Whitwell <keithw@vmware.com>2010-06-23 18:10:20 +0100
commit64682da8ab7aff7b4ce651db99a32ed1fd8b178c (patch)
treea216f21f6caa1628c7b25defd5a19a777226725c
parent292eecca8c4284cbb343d954b76586fcaa26de2a (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.
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c12
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c9
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c8
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c13
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c8
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_varray.c8
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache.c16
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 );
}