radeonsi: skip redundant INDEX_TYPE writes
authorMarek Olšák <marek.olsak@amd.com>
Mon, 5 Sep 2016 22:35:12 +0000 (00:35 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 7 Sep 2016 09:13:13 +0000 (11:13 +0200)
Ported from Vulkan.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@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 a03b3275d047178e5587edaaab6d61ef96ddfcd8..24b036048905faea6a5746b4d9c64f205f552486 100644 (file)
@@ -225,6 +225,7 @@ void si_begin_new_cs(struct si_context *ctx)
        /* Invalidate various draw states so that they are emitted before
         * the first draw call. */
        si_invalidate_draw_sh_constants(ctx);
+       ctx->last_index_size = -1;
        ctx->last_primitive_restart_en = -1;
        ctx->last_restart_index = SI_RESTART_INDEX_UNKNOWN;
        ctx->last_gs_out_prim = -1;
index 5c041ce88b632333f390b4e08f2df87c6d62ea8d..a648d868225401ce9271bfc67856c9402a5e5b31 100644 (file)
@@ -307,6 +307,7 @@ struct si_context {
        bool                    occlusion_queries_disabled;
 
        /* Emitted draw state. */
+       int                     last_index_size;
        int                     last_base_vertex;
        int                     last_start_instance;
        int                     last_drawid;
index d4447a975fe02dc1e8897c7ab70a1ded225c225e..d7325ff37d2c7ef6247b891bff273feb9450b6d4 100644 (file)
@@ -553,26 +553,30 @@ static void si_emit_draw_packets(struct si_context *sctx,
 
        /* draw packet */
        if (info->indexed) {
-               radeon_emit(cs, PKT3(PKT3_INDEX_TYPE, 0, 0));
-
-               /* index type */
-               switch (ib->index_size) {
-               case 1:
-                       radeon_emit(cs, V_028A7C_VGT_INDEX_8);
-                       break;
-               case 2:
-                       radeon_emit(cs, V_028A7C_VGT_INDEX_16 |
-                                   (SI_BIG_ENDIAN && sctx->b.chip_class <= CIK ?
-                                            V_028A7C_VGT_DMA_SWAP_16_BIT : 0));
-                       break;
-               case 4:
-                       radeon_emit(cs, V_028A7C_VGT_INDEX_32 |
-                                   (SI_BIG_ENDIAN && sctx->b.chip_class <= CIK ?
-                                            V_028A7C_VGT_DMA_SWAP_32_BIT : 0));
-                       break;
-               default:
-                       assert(!"unreachable");
-                       return;
+               if (ib->index_size != sctx->last_index_size) {
+                       radeon_emit(cs, PKT3(PKT3_INDEX_TYPE, 0, 0));
+
+                       /* index type */
+                       switch (ib->index_size) {
+                       case 1:
+                               radeon_emit(cs, V_028A7C_VGT_INDEX_8);
+                               break;
+                       case 2:
+                               radeon_emit(cs, V_028A7C_VGT_INDEX_16 |
+                                           (SI_BIG_ENDIAN && sctx->b.chip_class <= CIK ?
+                                                    V_028A7C_VGT_DMA_SWAP_16_BIT : 0));
+                               break;
+                       case 4:
+                               radeon_emit(cs, V_028A7C_VGT_INDEX_32 |
+                                           (SI_BIG_ENDIAN && sctx->b.chip_class <= CIK ?
+                                                    V_028A7C_VGT_DMA_SWAP_32_BIT : 0));
+                               break;
+                       default:
+                               assert(!"unreachable");
+                               return;
+                       }
+
+                       sctx->last_index_size = ib->index_size;
                }
 
                index_max_size = (ib->buffer->width0 - ib->offset) /
@@ -582,6 +586,12 @@ static void si_emit_draw_packets(struct si_context *sctx,
                radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
                                      (struct r600_resource *)ib->buffer,
                                      RADEON_USAGE_READ, RADEON_PRIO_INDEX_BUFFER);
+       } else {
+               /* On CI and later, non-indexed draws overwrite VGT_INDEX_TYPE,
+                * so the state must be re-emitted before the next indexed draw.
+                */
+               if (sctx->b.chip_class >= CIK)
+                       sctx->last_index_size = -1;
        }
 
        if (!info->indirect) {