[Mesa-dev] [PATCH 2/3] draw/clip: don't emit so many empty triangles

Jose Fonseca jfonseca at vmware.com
Fri Sep 20 05:06:44 PDT 2013



----- Original Message -----
> Am 19.09.2013 20:43, schrieb Zack Rusin:
> > Compress empty triangles (don't emit more than one in a row) and
> > never emit empty triangles if we already generated a triangle
> > covering a non-null area. We can't skip all null-triangles
> > because c_primitives expects ones that were generated from vertices
> > exactly at the clipping-plane, to be emitted.
> > 
> > Signed-off-by: Zack Rusin <zackr at vmware.com>
> > ---
> >  src/gallium/auxiliary/draw/draw_pipe_clip.c | 39
> >  +++++++++++++++++++++++++++++
> >  1 file changed, 39 insertions(+)
> > 
> > diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c
> > b/src/gallium/auxiliary/draw/draw_pipe_clip.c
> > index 0f90bfd..2d6df81 100644
> > --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
> > +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
> > @@ -209,6 +209,29 @@ static void interp( const struct clip_stage *clip,
> >     }
> >  }
> >  
> > +/**
> > + * Checks whether the specifed triangle is empty and if it is returns
> specified
> 
> > + * true, otherwise returns false.
> > + * Triangle is considered null/empty if it's area is qual to zero.
> equal
> 
> 
> 
> > + */
> > +static INLINE boolean
> > +is_tri_null(struct draw_context *draw, const struct prim_header *header)
> > +{
> > +   const unsigned pos_attr = draw_current_shader_position_output(draw);
> > +   float x1 = header->v[1]->data[pos_attr][0] -
> > header->v[0]->data[pos_attr][0];
> > +   float y1 = header->v[1]->data[pos_attr][1] -
> > header->v[0]->data[pos_attr][1];
> > +   float z1 = header->v[1]->data[pos_attr][2] -
> > header->v[0]->data[pos_attr][2];
> > +
> > +   float x2 = header->v[2]->data[pos_attr][0] -
> > header->v[0]->data[pos_attr][0];
> > +   float y2 = header->v[2]->data[pos_attr][1] -
> > header->v[0]->data[pos_attr][1];
> > +   float z2 = header->v[2]->data[pos_attr][2] -
> > header->v[0]->data[pos_attr][2];
> > +
> > +   float vx = y1 * z2 - z1 * y2;
> > +   float vy = x1 * z2 - z1 * x2;
> > +   float vz = x1 * y2 - y1 * x2;
> > +


> > +   return (vx*vx  + vy*vy + vz*vz) == 0.f;

You can simplify this with

  return vz == 0.0f && vy == 0.0f && vz == 0.0f

> > +}
> 
> Hmm I think the usual calculation for area would be:
> 
>    dx01 = x[0] - x[1];
>    dy01 = y[0] - y[1];
> 
>    dx20 = x[2] - x[0];
>    dy20 = y[2] - y[0];
> 
>    area = dx01 * dy20 - dx20 * dy01;

This is the projection of the aera in the xy plane, ie, the same a `vz` in Zack's patch.
> 
> Do you really need to factor in z for figuring out if the area is null
> here? In other words I'm wondering if the ordinary face culling stage
> wouldn't just do the job if enabled (as even without face culling it
> will calculate this area and toss out the prim in case it's zero).
> I guess though the problem is that cull stage is _after_ clip.

It's a matter of convention, so it really depends on what the tests expect to see in the statistics.

Otherwise series looks good to me.

Jose


More information about the mesa-dev mailing list