mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 04:30:10 +01:00
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.
This commit is contained in:
parent
292eecca8c
commit
64682da8ab
8 changed files with 46 additions and 34 deletions
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue