radeonsi: emit base vertex and start instance only if they change
authorMarek Olšák <marek.olsak@amd.com>
Sun, 7 Dec 2014 19:04:40 +0000 (20:04 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 10 Dec 2014 20:59:37 +0000 (21:59 +0100)
v2: added a helper function for invalidation of the sh constants

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
src/gallium/drivers/radeonsi/si_hw_context.c
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_state_draw.c

index f597218cf678a3756f26596c17445f6ce99695db..6c2734eac29548ba2f08ca5567f0a0c2e7e00b0c 100644 (file)
@@ -155,4 +155,5 @@ void si_begin_new_cs(struct si_context *ctx)
        r600_postflush_resume_features(&ctx->b);
 
        ctx->b.initial_gfx_cs_size = ctx->b.rings.gfx.cs->cdw;
+       si_invalidate_draw_sh_constants(ctx);
 }
index 15ca9a559e54731161b20c2cc74fe4cb64c5579e..e3cc09a0b85bd820f658d6b932ae1d3af95c7a65 100644 (file)
 #define SI_BIG_ENDIAN 0
 #endif
 
+/* The base vertex can be any number, but we must pick one which
+ * will mean "unknown" for the purpose of state tracking and the number
+ * shouldn't be a commonly-used one. */
+#define SI_BASE_VERTEX_UNKNOWN INT_MIN
+
 #define SI_TRACE_CS 0
 #define SI_TRACE_CS_DWORDS             6
 
@@ -169,6 +174,11 @@ struct si_context {
        bool                    db_depth_clear;
        bool                    db_depth_disable_expclear;
        unsigned                ps_db_shader_control;
+
+       /* Draw state. */
+       int                     last_base_vertex;
+       int                     last_start_instance;
+       int                     last_sh_base_reg;
 };
 
 /* si_blit.c */
@@ -227,4 +237,12 @@ si_resource_create_custom(struct pipe_screen *screen,
                PIPE_BIND_CUSTOM, usage, size));
 }
 
+static INLINE void
+si_invalidate_draw_sh_constants(struct si_context *sctx)
+{
+       sctx->last_base_vertex = SI_BASE_VERTEX_UNKNOWN;
+       sctx->last_start_instance = -1; /* reset to an unknown value */
+       sctx->last_sh_base_reg = -1; /* reset to an unknown value */
+}
+
 #endif
index a69d59625033557e8ba4aa3fe6913bc6b48ee533..f9ff0e34c1744dc828fc17b8fd8f3e64feed5b9c 100644 (file)
@@ -242,13 +242,29 @@ static void si_emit_draw_packets(struct si_context *sctx,
        }
 
        if (!info->indirect) {
+               int base_vertex;
+
                radeon_emit(cs, PKT3(PKT3_NUM_INSTANCES, 0, 0));
                radeon_emit(cs, info->instance_count);
 
-               si_write_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 2);
-               radeon_emit(cs, info->indexed ? info->index_bias : info->start);
-               radeon_emit(cs, info->start_instance);
+               /* Base vertex and start instance. */
+               base_vertex = info->indexed ? info->index_bias : info->start;
+
+               if (base_vertex != sctx->last_base_vertex ||
+                   sctx->last_base_vertex == SI_BASE_VERTEX_UNKNOWN ||
+                   info->start_instance != sctx->last_start_instance ||
+                   sh_base_reg != sctx->last_sh_base_reg) {
+                       si_write_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 2);
+                       radeon_emit(cs, base_vertex);
+                       radeon_emit(cs, info->start_instance);
+
+                       sctx->last_base_vertex = base_vertex;
+                       sctx->last_start_instance = info->start_instance;
+                       sctx->last_sh_base_reg = sh_base_reg;
+               }
        } else {
+               si_invalidate_draw_sh_constants(sctx);
+
                r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
                                      (struct r600_resource *)info->indirect,
                                      RADEON_USAGE_READ, RADEON_PRIO_MIN);