radeonsi/gfx10: fix GL_LINE polygon mode for decomposed primitives
authorMarek Olšák <marek.olsak@amd.com>
Thu, 30 May 2019 00:06:16 +0000 (20:06 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 3 Jul 2019 19:51:13 +0000 (15:51 -0400)
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 <bas@basnieuwenhuizen.nl>
src/gallium/drivers/radeonsi/si_gfx_cs.c
src/gallium/drivers/radeonsi/si_shader.h
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state.h
src/gallium/drivers/radeonsi/si_state_shaders.c

index 3c323fbafdf751152f0c886299a8b51ab4f884a0..f32e64ea5707fa150086971dc3cf40be97b04d3c 100644 (file)
@@ -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;
index 9dbf08fa95f081c273bf239078154ef866cf5d33..b545bf1bc235dc46fdb81076a609420960328710 100644 (file)
@@ -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;
 
index d4b7aabd5cee8cd7d17b4cdce6890a273d0569ac..40de130a34f45f5fa669dda21a8afe76f6e8b0e0 100644 (file)
@@ -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) {
index 757dd1bf5cd5e092f5af57d9f9f2d4d3cc0172f9..4493969037c9bfb7f6bd0a9427eadd1e35a562ce 100644 (file)
@@ -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,
 
index aa98a209cecc5300ce6b2e0d439989dd59a22b2d..5e1a166f391bb316ed8eb5853d541f29c85ce4b5 100644 (file)
@@ -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) |