[Mesa-dev] [PATCH 6/7] i965: Kill software primitive counting entirely.

Kenneth Graunke kenneth at whitecape.org
Mon May 20 15:54:36 PDT 2013


Now that we have hardware contexts, we don't need to continually
reprogram the GS_SVBI_INDEX registers.  They're automatically saved and
restored with the context, so they can just increment over time.  We
only need to reset them when starting transform feedback.

There's also no reason to delay until the next drawing operation; we can
just emit the packet immediately.  However, this means we must drop the
initialization in brw_invariant_state, as BeginTransformFeedback may
occur before the first drawing in a context.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
Cc: Eric Anholt <eric at anholt.net>
Cc: Paul Berry <stereotype441 at gmail.com>
---
 src/mesa/drivers/dri/i965/brw_context.h      |  7 ----
 src/mesa/drivers/dri/i965/brw_draw.c         | 54 ----------------------------
 src/mesa/drivers/dri/i965/brw_misc_state.c   | 13 -------
 src/mesa/drivers/dri/i965/brw_state.h        |  1 -
 src/mesa/drivers/dri/i965/brw_state_upload.c |  2 --
 src/mesa/drivers/dri/i965/gen6_sol.c         | 53 ++++++++++++---------------
 6 files changed, 22 insertions(+), 108 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 97caccd..be49078 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -148,7 +148,6 @@ enum brw_state_id {
    BRW_STATE_VS_CONSTBUF,
    BRW_STATE_PROGRAM_CACHE,
    BRW_STATE_STATE_BASE_ADDRESS,
-   BRW_STATE_SOL_INDICES,
    BRW_STATE_VUE_MAP_GEOM_OUT,
    BRW_STATE_TRANSFORM_FEEDBACK,
    BRW_STATE_RASTERIZER_DISCARD,
@@ -181,7 +180,6 @@ enum brw_state_id {
 #define BRW_NEW_VS_CONSTBUF            (1 << BRW_STATE_VS_CONSTBUF)
 #define BRW_NEW_PROGRAM_CACHE		(1 << BRW_STATE_PROGRAM_CACHE)
 #define BRW_NEW_STATE_BASE_ADDRESS	(1 << BRW_STATE_STATE_BASE_ADDRESS)
-#define BRW_NEW_SOL_INDICES		(1 << BRW_STATE_SOL_INDICES)
 #define BRW_NEW_VUE_MAP_GEOM_OUT	(1 << BRW_STATE_VUE_MAP_GEOM_OUT)
 #define BRW_NEW_TRANSFORM_FEEDBACK	(1 << BRW_STATE_TRANSFORM_FEEDBACK)
 #define BRW_NEW_RASTERIZER_DISCARD	(1 << BRW_STATE_RASTERIZER_DISCARD)
@@ -1085,11 +1083,6 @@ struct brw_context
    } *state_batch_list;
    int state_batch_count;
 
-   struct brw_sol_state {
-      uint32_t svbi_0_starting_index;
-      uint32_t svbi_0_max_index;
-   } sol;
-
    uint32_t render_target_format[MESA_FORMAT_COUNT];
    bool format_supported_as_render_target[MESA_FORMAT_COUNT];
 
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 4dd185e..657d6ee 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -351,57 +351,6 @@ static void brw_postdraw_set_buffers_need_resolve(struct brw_context *brw)
       intel_renderbuffer_set_needs_depth_resolve(depth_irb);
 }
 
-static int
-verts_per_prim(GLenum mode)
-{
-   switch (mode) {
-   case GL_POINTS:
-      return 1;
-   case GL_LINE_STRIP:
-   case GL_LINE_LOOP:
-   case GL_LINES:
-      return 2;
-   case GL_TRIANGLE_STRIP:
-   case GL_TRIANGLE_FAN:
-   case GL_POLYGON:
-   case GL_TRIANGLES:
-   case GL_QUADS:
-   case GL_QUAD_STRIP:
-      return 3;
-   default:
-      _mesa_problem(NULL,
-		    "unknown prim type in transform feedback primitive count");
-      return 0;
-   }
-}
-
-/**
- * Update internal counters based on the the drawing operation described in
- * prim.
- */
-static void
-brw_update_primitive_count(struct brw_context *brw,
-                           const struct _mesa_prim *prim)
-{
-   uint32_t count
-      = vbo_count_tessellated_primitives(prim->mode, prim->count,
-                                         prim->num_instances);
-   if (_mesa_is_xfb_active_and_unpaused(&brw->intel.ctx)) {
-      /* Update brw->sol.svbi_0_max_index to reflect the amount by which the
-       * hardware is going to increment SVBI 0 when this drawing operation
-       * occurs.  This is necessary because the kernel does not (yet) save and
-       * restore GPU registers when context switching, so we'll need to be
-       * able to reload SVBI 0 with the correct value in case we have to start
-       * a new batch buffer.
-       */
-      unsigned verts = verts_per_prim(prim->mode);
-      uint32_t space_avail =
-         (brw->sol.svbi_0_max_index - brw->sol.svbi_0_starting_index) / verts;
-      uint32_t primitives_written = MIN2 (space_avail, count);
-      brw->sol.svbi_0_starting_index += verts * primitives_written;
-   }
-}
-
 /* May fail if out of video memory for texture or vbo upload, or on
  * fallback conditions.
  */
@@ -524,9 +473,6 @@ retry:
 	    }
 	 }
       }
-
-      if (!_mesa_meta_in_progress(ctx))
-         brw_update_primitive_count(brw, &prim[i]);
    }
 
    if (intel->always_flush_batch)
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 6b61929..8162eeb 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -999,19 +999,6 @@ static void upload_invariant_state( struct brw_context *brw )
       ADVANCE_BATCH();
    }
 
-   if (intel->gen == 6) {
-      int i;
-
-      for (i = 0; i < 4; i++) {
-         BEGIN_BATCH(4);
-         OUT_BATCH(_3DSTATE_GS_SVB_INDEX << 16 | (4 - 2));
-         OUT_BATCH(i << SVB_INDEX_SHIFT);
-         OUT_BATCH(0);
-         OUT_BATCH(0xffffffff);
-         ADVANCE_BATCH();
-      }
-   }
-
    BEGIN_BATCH(2);
    OUT_BATCH(CMD_STATE_SIP << 16 | (2 - 2));
    OUT_BATCH(0);
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 9c956f8..8d886be 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -101,7 +101,6 @@ extern const struct brw_tracked_state gen6_multisample_state;
 extern const struct brw_tracked_state gen6_renderbuffer_surfaces;
 extern const struct brw_tracked_state gen6_sampler_state;
 extern const struct brw_tracked_state gen6_scissor_state;
-extern const struct brw_tracked_state gen6_sol_indices;
 extern const struct brw_tracked_state gen6_sol_surface;
 extern const struct brw_tracked_state gen6_sf_state;
 extern const struct brw_tracked_state gen6_sf_vp;
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 5549f59..63659be 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -165,7 +165,6 @@ static const struct brw_tracked_state *gen6_atoms[] =
 
    &brw_drawing_rect,
 
-   &gen6_sol_indices,
    &brw_indices,
    &brw_index_buffer,
    &brw_vertices,
@@ -368,7 +367,6 @@ static struct dirty_bit_map brw_bits[] = {
    DEFINE_BIT(BRW_NEW_VS_CONSTBUF),
    DEFINE_BIT(BRW_NEW_PROGRAM_CACHE),
    DEFINE_BIT(BRW_NEW_STATE_BASE_ADDRESS),
-   DEFINE_BIT(BRW_NEW_SOL_INDICES),
    DEFINE_BIT(BRW_NEW_VUE_MAP_GEOM_OUT),
    DEFINE_BIT(BRW_NEW_TRANSFORM_FEEDBACK),
    DEFINE_BIT(BRW_NEW_RASTERIZER_DISCARD),
diff --git a/src/mesa/drivers/dri/i965/gen6_sol.c b/src/mesa/drivers/dri/i965/gen6_sol.c
index 668a99e..cdd6e74 100644
--- a/src/mesa/drivers/dri/i965/gen6_sol.c
+++ b/src/mesa/drivers/dri/i965/gen6_sol.c
@@ -132,29 +132,6 @@ const struct brw_tracked_state gen6_gs_binding_table = {
    .emit = brw_gs_upload_binding_table,
 };
 
-static void
-gen6_update_sol_indices(struct brw_context *brw)
-{
-   struct intel_context *intel = &brw->intel;
-
-   BEGIN_BATCH(4);
-   OUT_BATCH(_3DSTATE_GS_SVB_INDEX << 16 | (4 - 2));
-   OUT_BATCH(0);
-   OUT_BATCH(brw->sol.svbi_0_starting_index); /* BRW_NEW_SOL_INDICES */
-   OUT_BATCH(brw->sol.svbi_0_max_index); /* BRW_NEW_SOL_INDICES */
-   ADVANCE_BATCH();
-}
-
-const struct brw_tracked_state gen6_sol_indices = {
-   .dirty = {
-      .mesa = 0,
-      .brw = (BRW_NEW_CONTEXT |
-              BRW_NEW_SOL_INDICES),
-      .cache = 0
-   },
-   .emit = gen6_update_sol_indices,
-};
-
 void
 brw_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
 			     struct gl_transform_feedback_object *obj)
@@ -175,14 +152,28 @@ brw_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
       = _mesa_compute_max_transform_feedback_vertices(xfb_obj,
                                                       linked_xfb_info);
 
-   /* Initialize the SVBI 0 register to zero and set the maximum index.
-    * These values will be sent to the hardware on the next draw.
-    */
-   brw->state.dirty.brw |= BRW_NEW_SOL_INDICES;
-   brw->sol.svbi_0_starting_index = 0;
-   brw->sol.svbi_0_max_index = max_index;
-
-   if (intel->gen >= 7) {
+   if (intel->gen == 6) {
+      /* Initialize the SVBI 0 register to zero and set the maximum index. */
+      BEGIN_BATCH(4);
+      OUT_BATCH(_3DSTATE_GS_SVB_INDEX << 16 | (4 - 2));
+      OUT_BATCH(0); /* SVBI 0 */
+      OUT_BATCH(0); /* starting index */
+      OUT_BATCH(max_index);
+      ADVANCE_BATCH();
+
+      /* Initialize the rest of the unused streams to sane values.  Otherwise,
+       * they may indicate that there is no room to write data and prevent
+       * anything from happening at all.
+       */
+      for (int i = 1; i < 4; i++) {
+         BEGIN_BATCH(4);
+         OUT_BATCH(_3DSTATE_GS_SVB_INDEX << 16 | (4 - 2));
+         OUT_BATCH(i << SVB_INDEX_SHIFT);
+         OUT_BATCH(0); /* starting index */
+         OUT_BATCH(0xffffffff);
+         ADVANCE_BATCH();
+      }
+   } else if (intel->gen >= 7) {
       /* Reset the SOL buffer offset register. */
       for (int i = 0; i < 4; i++) {
          BEGIN_BATCH(3);
-- 
1.8.2.3



More information about the mesa-dev mailing list