summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i965/brw_gs.c
diff options
context:
space:
mode:
authorPaul Berry <stereotype441@gmail.com>2011-11-29 14:51:03 -0800
committerPaul Berry <stereotype441@gmail.com>2011-12-07 16:38:01 -0800
commitd4976158c7f32705b48c773c3abd1b22bebe9c16 (patch)
tree0995446df96766d034e8f41112f919c00882232e /src/mesa/drivers/dri/i965/brw_gs.c
parent2252e5e3f1e8caece5c73df82f3ddf306baa2c91 (diff)
i965 gen6: Implement pass-through GS for transform feedback.
In Gen6, transform feedback is accomplished by having the geometry shader send vertex data to the data port using "Streamed Vertex Buffer Write" messages, while simultaneously passing vertices through to the rest of the graphics pipeline (if rendering is enabled). This patch adds a geometry shader program that simply passes vertices through to the rest of the graphics pipeline. The rest of transform feedback functionality will be added in future patches. To make the new geometry shader easier to test, I've added an environment variable "INTEL_FORCE_GS". If this environment variable is enabled, then the pass-through geometry shader will always be used, regardless of whether transform feedback is in effect. On my Sandy Bridge laptop, I'm able to enable INTEL_FORCE_GS with no Piglit regressions. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Acked-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_gs.c')
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs.c106
1 files changed, 76 insertions, 30 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c
index e72ff5e5a8f..69ffa19c40c 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_gs.c
@@ -53,12 +53,6 @@ static void compile_gs_prog( struct brw_context *brw,
void *mem_ctx;
GLuint program_size;
- /* Gen6: VF has already converted into polygon, and LINELOOP is
- * converted to LINESTRIP at the beginning of the 3D pipeline.
- */
- if (intel->gen >= 6)
- return;
-
memset(&c, 0, sizeof(c));
c.key = *key;
@@ -80,24 +74,60 @@ static void compile_gs_prog( struct brw_context *brw,
*/
brw_set_mask_control(&c.func, BRW_MASK_DISABLE);
-
- /* Note that primitives which don't require a GS program have
- * already been weeded out by this stage:
- */
-
- switch (key->primitive) {
- case _3DPRIM_QUADLIST:
- brw_gs_quads( &c, key );
- break;
- case _3DPRIM_QUADSTRIP:
- brw_gs_quad_strip( &c, key );
- break;
- case _3DPRIM_LINELOOP:
- brw_gs_lines( &c );
- break;
- default:
- ralloc_free(mem_ctx);
- return;
+ if (intel->gen >= 6) {
+ unsigned num_verts;
+ bool check_edge_flag;
+ /* On Sandybridge, we use the GS for implementing transform feedback
+ * (called "Stream Out" in the PRM).
+ */
+ switch (key->primitive) {
+ case _3DPRIM_POINTLIST:
+ num_verts = 1;
+ check_edge_flag = false;
+ break;
+ case _3DPRIM_LINELIST:
+ case _3DPRIM_LINESTRIP:
+ case _3DPRIM_LINELOOP:
+ num_verts = 2;
+ check_edge_flag = false;
+ break;
+ case _3DPRIM_TRILIST:
+ case _3DPRIM_TRIFAN:
+ case _3DPRIM_TRISTRIP:
+ case _3DPRIM_RECTLIST:
+ num_verts = 3;
+ check_edge_flag = false;
+ break;
+ case _3DPRIM_QUADLIST:
+ case _3DPRIM_QUADSTRIP:
+ case _3DPRIM_POLYGON:
+ num_verts = 3;
+ check_edge_flag = true;
+ break;
+ default:
+ assert(!"Unexpected primitive type in Gen6 SOL program.");
+ return;
+ }
+ gen6_sol_program(&c, key, num_verts, check_edge_flag);
+ } else {
+ /* On Gen4-5, we use the GS to decompose certain types of primitives.
+ * Note that primitives which don't require a GS program have already
+ * been weeded out by now.
+ */
+ switch (key->primitive) {
+ case _3DPRIM_QUADLIST:
+ brw_gs_quads( &c, key );
+ break;
+ case _3DPRIM_QUADSTRIP:
+ brw_gs_quad_strip( &c, key );
+ break;
+ case _3DPRIM_LINELOOP:
+ brw_gs_lines( &c );
+ break;
+ default:
+ ralloc_free(mem_ctx);
+ return;
+ }
}
/* get the program
@@ -148,11 +178,26 @@ static void populate_key( struct brw_context *brw,
/* _NEW_TRANSFORM */
key->userclip_active = (ctx->Transform.ClipPlanesEnabled != 0);
- key->need_gs_prog = (intel->gen >= 6)
- ? 0
- : (brw->primitive == _3DPRIM_QUADLIST ||
- brw->primitive == _3DPRIM_QUADSTRIP ||
- brw->primitive == _3DPRIM_LINELOOP);
+ if (intel->gen >= 7) {
+ /* On Gen7 and later, we don't use GS (yet). */
+ key->need_gs_prog = false;
+ } else if (intel->gen == 6) {
+ /* On Gen6, GS is used for transform feedback. */
+ /* _NEW_TRANSFORM_FEEDBACK */
+ key->need_gs_prog = ctx->TransformFeedback.CurrentObject->Active;
+ } else {
+ /* Pre-gen6, GS is used to transform QUADLIST, QUADSTRIP, and LINELOOP
+ * into simpler primitives.
+ */
+ key->need_gs_prog = (brw->primitive == _3DPRIM_QUADLIST ||
+ brw->primitive == _3DPRIM_QUADSTRIP ||
+ brw->primitive == _3DPRIM_LINELOOP);
+ }
+ /* For testing, the environment variable INTEL_FORCE_GS can be used to
+ * force a GS program to be used, even if it's not necessary.
+ */
+ if (getenv("INTEL_FORCE_GS"))
+ key->need_gs_prog = true;
}
/* Calculate interpolants for triangle and line rasterization.
@@ -183,7 +228,8 @@ brw_upload_gs_prog(struct brw_context *brw)
const struct brw_tracked_state brw_gs_prog = {
.dirty = {
.mesa = (_NEW_LIGHT |
- _NEW_TRANSFORM),
+ _NEW_TRANSFORM |
+ _NEW_TRANSFORM_FEEDBACK),
.brw = BRW_NEW_PRIMITIVE,
.cache = CACHE_NEW_VS_PROG
},