From 7ade08e2a83d5cf1d9dbdb767130f19e9d885864 Mon Sep 17 00:00:00 2001 From: Constantine Kharlamov Date: Sun, 2 Apr 2017 20:33:05 +0300 Subject: [PATCH] r600g: extract a code into a r600_emit_rasterizer_prim_state() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Marek Olšák Tested-by: Dieter Nützel --- 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 4663d99c0b6..4511ce0c01e 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 a05d543f0d1..86634b8681f 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 d1251469079..e4d16609339 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.30.2