mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
radeonsi: set GS_STATE_OUTPRIM and PROVOKING_VTX_INDEX only when they change
This moves setting those registers from an unconditional place in draw_vbo into si_set_rasterized_prim (for draw_vbo), si_update_rasterized_prim (for bind_xx_shader), and si_bind_rs_state. It's a little more complicated than expected. Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18195>
This commit is contained in:
parent
a070a09d00
commit
dcd80d31cf
4 changed files with 50 additions and 21 deletions
|
|
@ -2105,9 +2105,34 @@ void si_check_dirty_buffers_textures(struct si_context *sctx)
|
|||
}
|
||||
}
|
||||
|
||||
/* Set the primitive type seen by the rasterizer. GS and tessellation affect this. */
|
||||
/* Update these two GS_STATE fields. They depend on whatever the last shader before PS is
|
||||
* and the rasterizer state.
|
||||
*
|
||||
* It's expected that hw_vs and ngg are inline constants in draw_vbo after optimizations.
|
||||
*/
|
||||
static inline void
|
||||
si_set_rasterized_prim(struct si_context *sctx, enum pipe_prim_type rast_prim)
|
||||
si_update_ngg_prim_state_sgpr(struct si_context *sctx, struct si_shader *hw_vs, bool ngg)
|
||||
{
|
||||
if (!ngg || !hw_vs)
|
||||
return;
|
||||
|
||||
if (hw_vs->uses_vs_state_provoking_vertex) {
|
||||
unsigned vtx_index = sctx->queued.named.rasterizer->flatshade_first ? 0 : sctx->gs_out_prim;
|
||||
|
||||
SET_FIELD(sctx->current_gs_state, GS_STATE_PROVOKING_VTX_INDEX, vtx_index);
|
||||
}
|
||||
|
||||
if (hw_vs->uses_gs_state_outprim) {
|
||||
SET_FIELD(sctx->current_gs_state, GS_STATE_OUTPRIM, sctx->gs_out_prim);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the primitive type seen by the rasterizer. GS and tessellation affect this.
|
||||
* It's expected that hw_vs and ngg are inline constants in draw_vbo after optimizations.
|
||||
*/
|
||||
static inline void
|
||||
si_set_rasterized_prim(struct si_context *sctx, enum pipe_prim_type rast_prim,
|
||||
struct si_shader *hw_vs, bool ngg)
|
||||
{
|
||||
if (rast_prim != sctx->current_rast_prim) {
|
||||
bool is_rect = rast_prim == SI_PRIM_RECTANGLE_LIST;
|
||||
|
|
@ -2123,6 +2148,7 @@ si_set_rasterized_prim(struct si_context *sctx, enum pipe_prim_type rast_prim)
|
|||
is_lines ? V_028A6C_LINESTRIP :
|
||||
is_rect ? V_028A6C_RECTLIST : V_028A6C_POINTLIST;
|
||||
sctx->do_update_shaders = true;
|
||||
si_update_ngg_prim_state_sgpr(sctx, hw_vs, ngg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1215,6 +1215,9 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
|
|||
old_rs->poly_stipple_enable != rs->poly_stipple_enable ||
|
||||
old_rs->flatshade != rs->flatshade)
|
||||
si_update_vrs_flat_shading(sctx);
|
||||
|
||||
if (old_rs->flatshade_first != rs->flatshade_first)
|
||||
si_update_ngg_prim_state_sgpr(sctx, si_get_vs(sctx)->current, sctx->ngg);
|
||||
}
|
||||
|
||||
static void si_delete_rs_state(struct pipe_context *ctx, void *state)
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ static bool si_update_shaders(struct si_context *sctx)
|
|||
struct pipe_context *ctx = (struct pipe_context *)sctx;
|
||||
struct si_shader *old_vs = si_get_vs_inline(sctx, HAS_TESS, HAS_GS)->current;
|
||||
unsigned old_pa_cl_vs_out_cntl = old_vs ? old_vs->pa_cl_vs_out_cntl : 0;
|
||||
bool old_uses_vs_state_provoking_vertex = old_vs ? old_vs->uses_vs_state_provoking_vertex : false;
|
||||
bool old_uses_gs_state_outprim = old_vs ? old_vs->uses_gs_state_outprim : false;
|
||||
struct si_shader *old_ps = sctx->shader.ps.current;
|
||||
unsigned old_spi_shader_col_format =
|
||||
old_ps ? old_ps->key.ps.part.epilog.spi_shader_col_format : 0;
|
||||
|
|
@ -247,10 +249,16 @@ static bool si_update_shaders(struct si_context *sctx)
|
|||
*pm4 = si_build_vgt_shader_config(sctx->screen, key);
|
||||
si_pm4_bind_state(sctx, vgt_shader_config, *pm4);
|
||||
|
||||
if (old_pa_cl_vs_out_cntl !=
|
||||
si_get_vs_inline(sctx, HAS_TESS, HAS_GS)->current->pa_cl_vs_out_cntl)
|
||||
struct si_shader *hw_vs = si_get_vs_inline(sctx, HAS_TESS, HAS_GS)->current;
|
||||
|
||||
if (old_pa_cl_vs_out_cntl != hw_vs->pa_cl_vs_out_cntl)
|
||||
si_mark_atom_dirty(sctx, &sctx->atoms.s.clip_regs);
|
||||
|
||||
/* If we start to use any of these, we need to update the SGPR. */
|
||||
if ((hw_vs->uses_vs_state_provoking_vertex && !old_uses_vs_state_provoking_vertex) ||
|
||||
(hw_vs->uses_gs_state_outprim && !old_uses_gs_state_outprim))
|
||||
si_update_ngg_prim_state_sgpr(sctx, hw_vs, NGG);
|
||||
|
||||
r = si_shader_select(ctx, &sctx->shader.ps);
|
||||
if (r)
|
||||
return false;
|
||||
|
|
@ -1157,20 +1165,6 @@ static void si_emit_rasterizer_prim_state(struct si_context *sctx)
|
|||
radeon_end_update_context_roll(sctx);
|
||||
else
|
||||
radeon_end();
|
||||
|
||||
if (NGG) {
|
||||
struct si_shader *hw_vs = si_get_vs_inline(sctx, HAS_TESS, HAS_GS)->current;
|
||||
|
||||
if (hw_vs->uses_vs_state_provoking_vertex) {
|
||||
unsigned vtx_index = rs->flatshade_first ? 0 : gs_out_prim;
|
||||
|
||||
SET_FIELD(sctx->current_gs_state, GS_STATE_PROVOKING_VTX_INDEX, vtx_index);
|
||||
}
|
||||
|
||||
if (hw_vs->uses_gs_state_outprim) {
|
||||
SET_FIELD(sctx->current_gs_state, GS_STATE_OUTPRIM, gs_out_prim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <amd_gfx_level GFX_VERSION, si_has_tess HAS_TESS, si_has_gs HAS_GS, si_has_ngg NGG,
|
||||
|
|
@ -2333,7 +2327,8 @@ static void si_draw(struct pipe_context *ctx,
|
|||
rast_prim = prim;
|
||||
}
|
||||
|
||||
si_set_rasterized_prim(sctx, rast_prim);
|
||||
si_set_rasterized_prim(sctx, rast_prim, si_get_vs_inline(sctx, HAS_TESS, HAS_GS)->current,
|
||||
NGG);
|
||||
}
|
||||
|
||||
if (IS_DRAW_VERTEX_STATE) {
|
||||
|
|
|
|||
|
|
@ -3313,15 +3313,20 @@ static void si_update_clip_regs(struct si_context *sctx, struct si_shader_select
|
|||
|
||||
static void si_update_rasterized_prim(struct si_context *sctx)
|
||||
{
|
||||
struct si_shader *hw_vs = si_get_vs(sctx)->current;
|
||||
|
||||
if (sctx->shader.gs.cso) {
|
||||
/* Only possibilities: POINTS, LINE_STRIP, TRIANGLES */
|
||||
si_set_rasterized_prim(sctx, sctx->shader.gs.cso->rast_prim);
|
||||
si_set_rasterized_prim(sctx, sctx->shader.gs.cso->rast_prim, hw_vs, sctx->ngg);
|
||||
} else if (sctx->shader.tes.cso) {
|
||||
/* Only possibilities: POINTS, LINE_STRIP, TRIANGLES */
|
||||
si_set_rasterized_prim(sctx, sctx->shader.tes.cso->rast_prim);
|
||||
si_set_rasterized_prim(sctx, sctx->shader.tes.cso->rast_prim, hw_vs, sctx->ngg);
|
||||
} else {
|
||||
/* The rasterized prim is determined by draw calls. */
|
||||
}
|
||||
|
||||
/* This must be done unconditionally because it also depends on si_shader fields. */
|
||||
si_update_ngg_prim_state_sgpr(sctx, hw_vs, sctx->ngg);
|
||||
}
|
||||
|
||||
static void si_update_common_shader_state(struct si_context *sctx, struct si_shader_selector *sel,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue