Also change gs_output_prim type: unsigned → pipe_prim_type. The idea of
the code is mostly taken from radeonsi. The new code operating on
prev/curr rast_primitives saves ≈15 reloads of PA_SC_LINE_STIPPLE per
frame in Kane&Lynch2

Signed-off-by: Constantine Kharlamov <hi-an...@yandex.ru>
---
 src/gallium/drivers/r600/r600_hw_context.c   |  2 ++
 src/gallium/drivers/r600/r600_pipe.h         |  8 +++---
 src/gallium/drivers/r600/r600_state_common.c | 37 +++++++++++++++++++---------
 3 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_hw_context.c 
b/src/gallium/drivers/r600/r600_hw_context.c
index 4663d99c0b..4511ce0c01 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -369,6 +369,8 @@ void r600_begin_new_cs(struct r600_context *ctx)
        /* Re-emit the draw state. */
        ctx->last_primitive_type = -1;
        ctx->last_start_instance = -1;
+       ctx->last_rast_prim      = -1;
+       ctx->current_rast_prim   = -1;
 
        assert(!ctx->b.gfx.cs->prev_dw);
        ctx->b.initial_gfx_cs_size = ctx->b.gfx.cs->current.cdw;
diff --git a/src/gallium/drivers/r600/r600_pipe.h 
b/src/gallium/drivers/r600/r600_pipe.h
index a05d543f0d..86634b8681 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -322,9 +322,9 @@ struct r600_pipe_shader_selector {
        enum pipe_shader_type   type;
 
        /* geometry shader properties */
-       unsigned        gs_output_prim;
-       unsigned        gs_max_out_vertices;
-       unsigned        gs_num_invocations;
+       enum pipe_prim_type     gs_output_prim;
+       unsigned                gs_max_out_vertices;
+       unsigned                gs_num_invocations;
 
        /* TCS/VS */
        uint64_t        lds_patch_outputs_written_mask;
@@ -512,6 +512,8 @@ struct r600_context {
 
        /* Last draw state (-1 = unset). */
        enum pipe_prim_type             last_primitive_type; /* Last primitive 
type used in draw_vbo. */
+       enum pipe_prim_type             current_rast_prim; /* primitive type 
after TES, GS */
+       enum pipe_prim_type             last_rast_prim;
        unsigned                        last_start_instance;
 
        void                            *sb_context;
diff --git a/src/gallium/drivers/r600/r600_state_common.c 
b/src/gallium/drivers/r600/r600_state_common.c
index d125146907..e4d1660933 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -1666,6 +1666,27 @@ void r600_emit_clip_misc_state(struct r600_context 
*rctx, struct r600_atom *atom
                                       
S_028AB4_REUSE_OFF(state->vs_out_viewport));
 }
 
+/* rast_prim is the primitive type after GS. */
+static inline void r600_emit_rasterizer_prim_state(struct r600_context *rctx)
+{
+       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       unsigned ls_mask = 0;
+       enum pipe_prim_type rast_prim = rctx->current_rast_prim;
+       if (rast_prim == rctx->last_rast_prim)
+               return;
+
+       if (rast_prim == PIPE_PRIM_LINES)
+               ls_mask = 1;
+       else if (rast_prim == PIPE_PRIM_LINE_STRIP ||
+                rast_prim == PIPE_PRIM_LINE_LOOP)
+               ls_mask = 2;
+
+       radeon_set_context_reg(cs, R_028A0C_PA_SC_LINE_STIPPLE,
+                              S_028A0C_AUTO_RESET_CNTL(ls_mask) |
+                              (rctx->rasterizer ? 
rctx->rasterizer->pa_sc_line_stipple : 0));
+       rctx->last_rast_prim = rast_prim;
+}
+
 static void r600_draw_vbo(struct pipe_context *ctx, const struct 
pipe_draw_info *info)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
@@ -1704,6 +1725,10 @@ static void r600_draw_vbo(struct pipe_context *ctx, 
const struct pipe_draw_info
                return;
        }
 
+       rctx->current_rast_prim = (rctx->gs_shader)? 
rctx->gs_shader->gs_output_prim
+               : (rctx->tes_shader)? 
rctx->tes_shader->info.properties[TGSI_PROPERTY_TES_PRIM_MODE]
+               : info->mode;
+
        if (info->indexed) {
                /* Initialize the index buffer struct. */
                pipe_resource_reference(&ib.buffer, rctx->index_buffer.buffer);
@@ -1863,17 +1888,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, 
const struct pipe_draw_info
 
        /* Update the primitive type. */
        if (rctx->last_primitive_type != info->mode) {
-               unsigned ls_mask = 0;
-
-               if (info->mode == PIPE_PRIM_LINES)
-                       ls_mask = 1;
-               else if (info->mode == PIPE_PRIM_LINE_STRIP ||
-                        info->mode == PIPE_PRIM_LINE_LOOP)
-                       ls_mask = 2;
-
-               radeon_set_context_reg(cs, R_028A0C_PA_SC_LINE_STIPPLE,
-                                      S_028A0C_AUTO_RESET_CNTL(ls_mask) |
-                                      (rctx->rasterizer ? 
rctx->rasterizer->pa_sc_line_stipple : 0));
+               r600_emit_rasterizer_prim_state(rctx);
                radeon_set_config_reg(cs, R_008958_VGT_PRIMITIVE_TYPE,
                                      r600_conv_pipe_prim(info->mode));
 
-- 
2.12.0

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to