diff --git a/src/gallium/drivers/radeonsi/si_gfx_cs.c b/src/gallium/drivers/radeonsi/si_gfx_cs.c index c715785c20f..a7441e26a53 100644 --- a/src/gallium/drivers/radeonsi/si_gfx_cs.c +++ b/src/gallium/drivers/radeonsi/si_gfx_cs.c @@ -515,7 +515,8 @@ void si_begin_new_gfx_cs(struct si_context *ctx, bool first_cs) * the first draw call. */ si_invalidate_draw_constants(ctx); ctx->last_index_size = -1; - ctx->last_primitive_restart_en = -1; + /* Primitive restart is set to false by the gfx preamble on GFX11+. */ + ctx->last_primitive_restart_en = ctx->gfx_level >= GFX11 ? false : -1; ctx->last_restart_index = SI_RESTART_INDEX_UNKNOWN; ctx->last_prim = -1; ctx->last_multi_vgt_param = -1; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 19d4f794144..9b2dcbd827c 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -6003,6 +6003,12 @@ void si_init_cs_preamble_state(struct si_context *sctx, bool uses_reg_shadowing) si_pm4_set_reg(pm4, R_028620_PA_RATE_CNTL, S_028620_VERTEX_RATE(2) | S_028620_PRIM_RATE(1)); + /* This is changed by draws for indexed draws, but we need to set DISABLE_FOR_AUTO_INDEX + * here, which disables primitive restart for all non-indexed draws, so that those draws + * won't have to set this state. + */ + si_pm4_set_reg(pm4, R_03092C_GE_MULTI_PRIM_IB_RESET_EN, S_03092C_DISABLE_FOR_AUTO_INDEX(1)); + uint64_t rb_mask = BITFIELD64_MASK(sctx->screen->info.max_render_backends); si_pm4_cmd_add(pm4, PKT3(PKT3_EVENT_WRITE, 2, 0)); diff --git a/src/gallium/drivers/radeonsi/si_state_draw.cpp b/src/gallium/drivers/radeonsi/si_state_draw.cpp index 9343f7a5229..bd09a8e8547 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.cpp +++ b/src/gallium/drivers/radeonsi/si_state_draw.cpp @@ -1322,7 +1322,7 @@ template ALWAYS_INLINE static void si_emit_draw_registers(struct si_context *sctx, const struct pipe_draw_indirect_info *indirect, - enum pipe_prim_type prim, + enum pipe_prim_type prim, unsigned index_size, unsigned instance_count, bool primitive_restart, unsigned restart_index, unsigned min_vertex_count) { @@ -1352,20 +1352,39 @@ static void si_emit_draw_registers(struct si_context *sctx, } /* Primitive restart. */ - if (primitive_restart != sctx->last_primitive_restart_en) { - if (GFX_VERSION >= GFX11) - radeon_set_uconfig_reg(R_03092C_GE_MULTI_PRIM_IB_RESET_EN, primitive_restart); - else if (GFX_VERSION >= GFX9) - radeon_set_uconfig_reg(R_03092C_VGT_MULTI_PRIM_IB_RESET_EN, primitive_restart); - else - radeon_set_context_reg(R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, primitive_restart); - sctx->last_primitive_restart_en = primitive_restart; - } - if (si_prim_restart_index_changed(sctx, primitive_restart, restart_index)) { - radeon_set_context_reg(R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, restart_index); - sctx->last_restart_index = restart_index; - if (GFX_VERSION == GFX9) - sctx->context_roll = true; + if (GFX_VERSION >= GFX11) { + /* GFX11+ can ignore primitive restart for non-indexed draws because it has no effect. + * (it's disabled for non-indexed draws by setting DISABLE_FOR_AUTO_INDEX in the preamble) + */ + if (index_size) { + if (primitive_restart != sctx->last_primitive_restart_en) { + radeon_set_uconfig_reg(R_03092C_GE_MULTI_PRIM_IB_RESET_EN, + S_03092C_RESET_EN(primitive_restart) | + /* This disables primitive restart for non-indexed draws. + * By keeping this set, we don't have to unset RESET_EN + * for non-indexed draws. */ + S_03092C_DISABLE_FOR_AUTO_INDEX(1)); + sctx->last_primitive_restart_en = primitive_restart; + } + if (si_prim_restart_index_changed(sctx, primitive_restart, restart_index)) { + radeon_set_context_reg(R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, restart_index); + sctx->last_restart_index = restart_index; + } + } + } else { + if (primitive_restart != sctx->last_primitive_restart_en) { + if (GFX_VERSION >= GFX9) + radeon_set_uconfig_reg(R_03092C_VGT_MULTI_PRIM_IB_RESET_EN, primitive_restart); + else + radeon_set_context_reg(R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, primitive_restart); + sctx->last_primitive_restart_en = primitive_restart; + } + if (si_prim_restart_index_changed(sctx, primitive_restart, restart_index)) { + radeon_set_context_reg(R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, restart_index); + sctx->last_restart_index = restart_index; + if (GFX_VERSION == GFX9) + sctx->context_roll = true; + } } radeon_end(); } @@ -2406,7 +2425,7 @@ static void si_draw(struct pipe_context *ctx, /* Emit draw states. */ si_emit_vs_state(sctx, index_size); si_emit_draw_registers - (sctx, indirect, prim, instance_count, primitive_restart, + (sctx, indirect, prim, index_size, instance_count, primitive_restart, info->restart_index, min_direct_count); if (sctx->flags)