i965/gs: implement EndPrimitive() functionality in the visitor.
authorPaul Berry <stereotype441@gmail.com>
Sun, 21 Apr 2013 15:51:33 +0000 (08:51 -0700)
committerPaul Berry <stereotype441@gmail.com>
Wed, 11 Sep 2013 18:17:54 +0000 (11:17 -0700)
commitebcdaa7bbc3a10fe59447ae77b508ee85eaa582f
treed607350ec2c1e39884997265805c16d26f32ac43
parent564a900a4539996b139b8d7618a40b22bbad1290
i965/gs: implement EndPrimitive() functionality in the visitor.

According to GLSL, the shader may call EndPrimitive() at any point
during its execution, causing the line or triangle strip currently
being output to be terminated and a new strip to be begun.

This is implemented in gen7 hardware by using one control data bit per
vertex, to indicate whether EndPrimitive() was called after that
vertex was emitted.

In order to make this work without sacrificing too much efficiency, we
accumulate 32 control data bits at a time in a GRF.  When we have
accumulated 32 bits (or when the shader terminates), we output them to
the appropriate DWORD in the control data header and reset the
accumulator to 0.

We have to take special care to make sure that EndPrimitive() calls
that occur prior to the first vertex have no effect.

Since geometry shaders that output a large number of vertices are
likely to be rare, an optimization kicks in if max_vertices <= 32.  In
this case, we know that we can wait until the end of shader execution
before any control data bits need to be output.

I've tried to write the code in such a way that in the future, we can
easily adapt it to output stream ID bits (which are two bits/vertex
instead of one).

Fixes piglit tests "spec/glsl-1.50/glsl-1.50-geometry-end-primitive *".

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h