radeonsi: don't set DrawID and StartInstance if they are unused

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7721>
This commit is contained in:
Marek Olšák
2020-11-25 03:28:10 -05:00
parent c4ddf67ee1
commit c7470c1760
6 changed files with 66 additions and 12 deletions
+6
View File
@@ -45,6 +45,8 @@
* one which will mean "unknown" for the purpose of state tracking and
* the number shouldn't be a commonly-used one. */
#define SI_BASE_VERTEX_UNKNOWN INT_MIN
#define SI_START_INSTANCE_UNKNOWN INT_MIN
#define SI_DRAW_ID_UNKNOWN INT_MIN
#define SI_RESTART_INDEX_UNKNOWN INT_MIN
#define SI_INSTANCE_COUNT_UNKNOWN INT_MIN
#define SI_NUM_SMOOTH_AA_SAMPLES 8
@@ -1045,6 +1047,8 @@ struct si_context {
bool do_update_shaders;
bool compute_shaderbuf_sgprs_dirty;
bool compute_image_sgprs_dirty;
bool vs_uses_base_instance;
bool vs_uses_draw_id;
/* shader descriptors */
struct si_descriptors descriptors[SI_NUM_DESCS];
@@ -1634,6 +1638,8 @@ static inline void si_context_add_resource_size(struct si_context *sctx, struct
static inline void si_invalidate_draw_sh_constants(struct si_context *sctx)
{
sctx->last_base_vertex = SI_BASE_VERTEX_UNKNOWN;
sctx->last_start_instance = SI_START_INSTANCE_UNKNOWN;
sctx->last_drawid = SI_DRAW_ID_UNKNOWN;
}
static inline void si_invalidate_draw_constants(struct si_context *sctx)
+16
View File
@@ -2630,6 +2630,22 @@ bool si_create_shader_variant(struct si_screen *sscreen, struct ac_llvm_compiler
sel->info.stage == MESA_SHADER_VERTEX &&
sel->so.num_outputs;
if (sel->info.stage == MESA_SHADER_VERTEX) {
shader->uses_base_instance = sel->info.uses_base_instance ||
shader->key.part.vs.prolog.instance_divisor_is_one ||
shader->key.part.vs.prolog.instance_divisor_is_fetched;
} else if (sel->info.stage == MESA_SHADER_TESS_CTRL) {
shader->uses_base_instance = shader->previous_stage_sel &&
(shader->previous_stage_sel->info.uses_base_instance ||
shader->key.part.tcs.ls_prolog.instance_divisor_is_one ||
shader->key.part.tcs.ls_prolog.instance_divisor_is_fetched);
} else if (sel->info.stage == MESA_SHADER_GEOMETRY) {
shader->uses_base_instance = shader->previous_stage_sel &&
(shader->previous_stage_sel->info.uses_base_instance ||
shader->key.part.gs.vs_prolog.instance_divisor_is_one ||
shader->key.part.gs.vs_prolog.instance_divisor_is_fetched);
}
si_fix_resource_usage(sscreen, shader);
si_shader_dump(sscreen, shader, debug, stderr, true);
+3
View File
@@ -368,6 +368,7 @@ struct si_shader_info {
bool uses_interp_at_sample;
bool uses_instanceid;
bool uses_base_vertex;
bool uses_base_instance;
bool uses_drawid;
bool uses_primid;
bool uses_frontface;
@@ -752,6 +753,8 @@ struct si_shader {
bool uses_vs_state_provoking_vertex;
bool uses_vs_state_outprim;
bool uses_base_instance;
struct {
uint16_t ngg_emit_size; /* in dwords */
uint16_t hw_max_esverts;
@@ -346,6 +346,7 @@ void si_nir_scan_shader(const struct nir_shader *nir, struct si_shader_info *inf
info->uses_frontface = nir->info.system_values_read & BITFIELD64_BIT(SYSTEM_VALUE_FRONT_FACE);
info->uses_instanceid = nir->info.system_values_read & BITFIELD64_BIT(SYSTEM_VALUE_INSTANCE_ID);
info->uses_base_vertex = nir->info.system_values_read & BITFIELD64_BIT(SYSTEM_VALUE_BASE_VERTEX);
info->uses_base_instance = nir->info.system_values_read & BITFIELD64_BIT(SYSTEM_VALUE_BASE_INSTANCE);
info->uses_invocationid = nir->info.system_values_read & BITFIELD64_BIT(SYSTEM_VALUE_INVOCATION_ID);
info->uses_grid_size = nir->info.system_values_read & BITFIELD64_BIT(SYSTEM_VALUE_NUM_WORK_GROUPS);
info->uses_subgroup_info = nir->info.system_values_read & BITFIELD64_BIT(SYSTEM_VALUE_LOCAL_INVOCATION_INDEX) ||
+34 -12
View File
@@ -973,6 +973,9 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
/* Base vertex and start instance. */
base_vertex = original_index_size ? info->index_bias : draws[0].start;
bool set_draw_id = sctx->vs_uses_draw_id;
bool set_base_instance = sctx->vs_uses_base_instance;
if (sctx->num_vs_blit_sgprs) {
/* Re-emit draw constants after we leave u_blitter. */
si_invalidate_draw_sh_constants(sctx);
@@ -982,19 +985,38 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
radeon_emit_array(cs, sctx->vs_blit_sh_data, sctx->num_vs_blit_sgprs);
} else if (base_vertex != sctx->last_base_vertex ||
sctx->last_base_vertex == SI_BASE_VERTEX_UNKNOWN ||
info->start_instance != sctx->last_start_instance ||
info->drawid != sctx->last_drawid || sh_base_reg != sctx->last_sh_base_reg) {
radeon_set_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 3);
radeon_emit(cs, base_vertex);
radeon_emit(cs, info->drawid);
radeon_emit(cs, info->start_instance);
(set_base_instance &&
(info->start_instance != sctx->last_start_instance ||
sctx->last_start_instance == SI_START_INSTANCE_UNKNOWN)) ||
(set_draw_id &&
(info->drawid != sctx->last_drawid ||
sctx->last_drawid == SI_DRAW_ID_UNKNOWN)) ||
sh_base_reg != sctx->last_sh_base_reg) {
if (set_base_instance) {
radeon_set_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 3);
radeon_emit(cs, base_vertex);
radeon_emit(cs, info->drawid);
radeon_emit(cs, info->start_instance);
sctx->last_start_instance = info->start_instance;
sctx->last_drawid = info->drawid;
} else if (set_draw_id) {
radeon_set_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 2);
radeon_emit(cs, base_vertex);
radeon_emit(cs, info->drawid);
sctx->last_drawid = info->drawid;
} else {
radeon_set_sh_reg(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, base_vertex);
}
sctx->last_base_vertex = base_vertex;
sctx->last_start_instance = info->start_instance;
sctx->last_drawid = info->drawid;
sctx->last_sh_base_reg = sh_base_reg;
}
/* Don't update draw_id in the following code if it doesn't increment. */
set_draw_id &= info->increment_draw_id;
if (index_size) {
if (dispatch_prim_discard_cs) {
for (unsigned i = 0; i < num_draws; i++) {
@@ -1010,7 +1032,7 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
for (unsigned i = 0; i < num_draws; i++) {
uint64_t va = index_va + draws[i].start * index_size;
if (i > 0 && info->increment_draw_id) {
if (i > 0 && set_draw_id) {
unsigned draw_id = info->drawid + i;
radeon_set_sh_reg(cs, sh_base_reg + SI_SGPR_DRAWID * 4, draw_id);
@@ -1028,7 +1050,7 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
* NOT_EOP doesn't work on gfx9 and older.
*/
S_0287F0_NOT_EOP(sctx->chip_class >= GFX10 &&
!info->increment_draw_id &&
!set_draw_id &&
i < num_draws - 1 &&
!(sctx->ngg_culling & SI_NGG_CULL_GS_FAST_LAUNCH_ALL)));
}
@@ -1049,7 +1071,7 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
radeon_emit(cs, index_va >> 32);
if (i > 0) {
if (info->increment_draw_id) {
if (set_draw_id) {
unsigned draw_id = info->drawid + i;
radeon_set_sh_reg(cs, sh_base_reg + SI_SGPR_DRAWID * 4, draw_id);
@@ -1067,7 +1089,7 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
for (unsigned i = 0; i < num_draws; i++) {
if (i > 0) {
if (info->increment_draw_id) {
if (set_draw_id) {
unsigned draw_id = info->drawid + i;
radeon_set_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 2);
@@ -3005,6 +3005,7 @@ static void si_bind_vs_shader(struct pipe_context *ctx, void *state)
sctx->vs_shader.cso = sel;
sctx->vs_shader.current = sel ? sel->first_variant : NULL;
sctx->num_vs_blit_sgprs = sel ? sel->info.base.vs.blit_sgprs_amd : 0;
sctx->vs_uses_draw_id = sel ? sel->info.uses_drawid : false;
if (si_update_ngg(sctx))
si_shader_change_notify(sctx);
@@ -4038,6 +4039,11 @@ bool si_update_shaders(struct si_context *sctx)
key.u.ngg_gs_fast_launch = !!(vs->key.opt.ngg_culling & SI_NGG_CULL_GS_FAST_LAUNCH_ALL);
}
sctx->vs_uses_base_instance =
sctx->vs_shader.current ? sctx->vs_shader.current->uses_base_instance :
sctx->queued.named.hs ? sctx->queued.named.hs->shader->uses_base_instance :
sctx->gs_shader.current->uses_base_instance;
si_update_vgt_shader_config(sctx, key);
if (old_kill_clip_distances != si_get_vs_state(sctx)->key.opt.kill_clip_distances)