From 6920f09f4ba6a889bf4ef804cf65be7b5ecd0e43 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 29 May 2019 20:06:16 -0400 Subject: [PATCH] radeonsi/gfx10: fix GL_LINE polygon mode for decomposed primitives We need to tell PA to accept edge flags generated by the input assembler, because decomposed primitives shouldn't draw inner edges. Acked-by: Bas Nieuwenhuizen --- src/gallium/drivers/radeonsi/si_gfx_cs.c | 1 + src/gallium/drivers/radeonsi/si_shader.h | 1 + src/gallium/drivers/radeonsi/si_state.c | 1 - src/gallium/drivers/radeonsi/si_state.h | 1 + .../drivers/radeonsi/si_state_shaders.c | 23 +++++++++++++++++-- 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_gfx_cs.c b/src/gallium/drivers/radeonsi/si_gfx_cs.c index 3c323fbafdf..f32e64ea570 100644 --- a/src/gallium/drivers/radeonsi/si_gfx_cs.c +++ b/src/gallium/drivers/radeonsi/si_gfx_cs.c @@ -508,6 +508,7 @@ void si_begin_new_gfx_cs(struct si_context *ctx) ctx->tracked_regs.reg_value[SI_TRACKED_SPI_VS_OUT_CONFIG] = 0x00000000; ctx->tracked_regs.reg_value[SI_TRACKED_SPI_SHADER_POS_FORMAT] = 0x00000000; ctx->tracked_regs.reg_value[SI_TRACKED_PA_CL_VTE_CNTL] = 0x00000000; + ctx->tracked_regs.reg_value[SI_TRACKED_PA_CL_NGG_CNTL] = 0x00000000; ctx->tracked_regs.reg_value[SI_TRACKED_SPI_PS_INPUT_ENA] = 0x00000000; ctx->tracked_regs.reg_value[SI_TRACKED_SPI_PS_INPUT_ADDR] = 0x00000000; ctx->tracked_regs.reg_value[SI_TRACKED_SPI_BARYC_CNTL] = 0x00000000; diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 9dbf08fa95f..b545bf1bc23 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -692,6 +692,7 @@ struct si_shader { unsigned spi_shader_idx_format; unsigned spi_shader_pos_format; unsigned pa_cl_vte_cntl; + unsigned pa_cl_ngg_cntl; unsigned vgt_gs_max_vert_out; /* for API GS */ } ngg; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index d4b7aabd5ce..40de130a34f 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -5563,7 +5563,6 @@ static void si_init_config(struct si_context *sctx) */ si_pm4_set_reg(pm4, R_028C50_PA_SC_NGG_MODE_CNTL, S_028C50_MAX_DEALLOCS_IN_WAVE(512)); - si_pm4_set_reg(pm4, R_028838_PA_CL_NGG_CNTL, 0); /* TODO edge flags? */ } if (sctx->chip_class >= GFX8) { diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index 757dd1bf5cd..4493969037c 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -319,6 +319,7 @@ enum si_tracked_reg { SI_TRACKED_VGT_REUSE_OFF, SI_TRACKED_SPI_VS_OUT_CONFIG, SI_TRACKED_PA_CL_VTE_CNTL, + SI_TRACKED_PA_CL_NGG_CNTL, SI_TRACKED_GE_MAX_OUTPUT_PER_SUBGROUP, SI_TRACKED_GE_NGG_SUBGRP_CNTL, diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index aa98a209cec..5e1a166f391 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -981,6 +981,9 @@ static void gfx10_emit_shader_ngg_tail(struct si_context *sctx, radeon_opt_set_context_reg(sctx, R_028818_PA_CL_VTE_CNTL, SI_TRACKED_PA_CL_VTE_CNTL, shader->ctx_reg.ngg.pa_cl_vte_cntl); + radeon_opt_set_context_reg(sctx, R_028838_PA_CL_NGG_CNTL, + SI_TRACKED_PA_CL_NGG_CNTL, + shader->ctx_reg.ngg.pa_cl_ngg_cntl); if (initial_cdw != sctx->gfx_cs->current.cdw) sctx->context_roll = true; @@ -1111,9 +1114,13 @@ static void gfx10_shader_ngg(struct si_screen *sscreen, struct si_shader *shader /* If offsets 4, 5 are used, GS_VGPR_COMP_CNT is ignored and * VGPR[0:4] are always loaded. + * + * Vertex shaders always need to load VGPR3, because they need to + * pass edge flags for decomposed primitives (such as quads) to the PA + * for the GL_LINE polygon mode to skip rendering lines on inner edges. */ - if (gs_info->uses_invocationid) - gs_vgpr_comp_cnt = 3; /* VGPR3 contains InvocationID. */ + if (gs_info->uses_invocationid || gs_type == PIPE_SHADER_VERTEX) + gs_vgpr_comp_cnt = 3; /* VGPR3 contains InvocationID, edge flags. */ else if (gs_info->uses_primid) gs_vgpr_comp_cnt = 2; /* VGPR2 contains PrimitiveID. */ else if (input_prim >= PIPE_PRIM_TRIANGLES) @@ -1185,6 +1192,18 @@ static void gfx10_shader_ngg(struct si_screen *sscreen, struct si_shader *shader S_028B90_EN_MAX_VERT_OUT_PER_GS_INSTANCE( shader->ngg.max_vert_out_per_gs_instance); + /* User edge flags are set by the pos exports. If user edge flags are + * not used, we must use hw-generated edge flags and pass them via + * the prim export to prevent drawing lines on internal edges of + * decomposed primitives (such as quads) with polygon mode = lines. + * + * TODO: We should combine hw-generated edge flags with user edge + * flags in the shader. + */ + shader->ctx_reg.ngg.pa_cl_ngg_cntl = + S_028838_INDEX_BUF_EDGE_FLAG_ENA(gs_type == PIPE_SHADER_VERTEX && + !gs_info->writes_edgeflag); + shader->ge_cntl = S_03096C_PRIM_GRP_SIZE(shader->ngg.max_gsprims) | S_03096C_VERT_GRP_SIZE(shader->ngg.hw_max_esverts) | -- 2.30.2