[Mesa-dev] [PATCH 2/2] i965: Implement rasterizer discard via SOL unless required for queries.

Kenneth Graunke kenneth at whitecape.org
Wed Jun 22 23:26:35 UTC 2016


We currently use CL_INVOCATION_COUNT for the GL_PRIMITIVES_GENERATED
query, which involves passing all primitives to the clipper.  When
rasterizer discard is enabled, we program the clipper in REJECT_ALL
mode, rather than using the SOL stage's "Rendering Disable" feature.

See commit f09b91f78247409f54c975f56cb10d5f350fe64e for an explanation
of why we implement GL_PRIMITIVES_GENERATED this way.

Apparently the SOL stage's "Rendering Disable" feature is a lot faster
than having the clipper reject all primitives.  It's safe to use when
no GL_PRIMITIVES_GENERATED query is active, as we don't care about
CL_INVOCATION_COUNT incrementing.

This patch makes us use SO_RENDERING_DISABLE when no query is active,
but continues falling back to the clipper in REJECT_ALL mode when the
queries are enabled.  It brings back the perf_debug for the clipper
case (which I removed in commit 1f9445ff57b, thinking it wasn't useful).

Improves performance in Gl32GSCloth by 84.8303% +/- 2.07132% (n = 10)
on my Broadwell GT2 laptop.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/drivers/dri/i965/gen6_queryobj.c  |  4 ++++
 src/mesa/drivers/dri/i965/gen7_sol_state.c | 17 +++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/gen6_queryobj.c b/src/mesa/drivers/dri/i965/gen6_queryobj.c
index f36f095..96db5e9 100644
--- a/src/mesa/drivers/dri/i965/gen6_queryobj.c
+++ b/src/mesa/drivers/dri/i965/gen6_queryobj.c
@@ -307,6 +307,8 @@ gen6_begin_query(struct gl_context *ctx, struct gl_query_object *q)
 
    case GL_PRIMITIVES_GENERATED:
       write_primitives_generated(brw, query->bo, query->Base.Stream, 0);
+      if (query->Base.Stream == 0)
+         ctx->NewDriverState |= BRW_NEW_RASTERIZER_DISCARD;
       break;
 
    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
@@ -359,6 +361,8 @@ gen6_end_query(struct gl_context *ctx, struct gl_query_object *q)
 
    case GL_PRIMITIVES_GENERATED:
       write_primitives_generated(brw, query->bo, query->Base.Stream, 1);
+      if (query->Base.Stream == 0)
+         ctx->NewDriverState |= BRW_NEW_RASTERIZER_DISCARD;
       break;
 
    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
diff --git a/src/mesa/drivers/dri/i965/gen7_sol_state.c b/src/mesa/drivers/dri/i965/gen7_sol_state.c
index 8fcc591..6c747fa 100644
--- a/src/mesa/drivers/dri/i965/gen7_sol_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_sol_state.c
@@ -214,6 +214,12 @@ gen7_upload_3dstate_so_decl_list(struct brw_context *brw,
    ADVANCE_BATCH();
 }
 
+static bool
+query_active(struct gl_query_object *q)
+{
+   return q && q->Active;
+}
+
 static void
 upload_3dstate_streamout(struct brw_context *brw, bool active,
 			 const struct brw_vue_map *vue_map)
@@ -235,6 +241,16 @@ upload_3dstate_streamout(struct brw_context *brw, bool active,
       dw1 |= SO_FUNCTION_ENABLE;
       dw1 |= SO_STATISTICS_ENABLE;
 
+      /* BRW_NEW_RASTERIZER_DISCARD */
+      if (ctx->RasterDiscard) {
+         if (!query_active(ctx->Query.PrimitivesGenerated[0])) {
+            dw1 |= SO_RENDERING_DISABLE;
+         } else {
+            perf_debug("Rasterizer discard with a GL_PRIMITIVES_GENERATED "
+                       "query active relies on the clipper.");
+         }
+      }
+
       /* _NEW_LIGHT */
       if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION)
 	 dw1 |= SO_REORDER_TRAILING;
@@ -317,6 +333,7 @@ const struct brw_tracked_state gen7_sol_state = {
       .mesa  = _NEW_LIGHT,
       .brw   = BRW_NEW_BATCH |
                BRW_NEW_BLORP |
+               BRW_NEW_RASTERIZER_DISCARD |
                BRW_NEW_VUE_MAP_GEOM_OUT |
                BRW_NEW_TRANSFORM_FEEDBACK,
    },
-- 
2.9.0



More information about the mesa-dev mailing list