radv: add support for push constants inlining when possible
This removes some scalar loads from shaders, but it increases the number of SET_SH_REG packets. This is currently basic but it could be improved if needed. Inlining dynamic offsets might also help. Original idea from Dave Airlie. 29077 shaders in 15096 tests Totals: SGPRS: 1321325 -> 1357101 (2.71 %) VGPRS: 936000 -> 932576 (-0.37 %) Spilled SGPRs: 24804 -> 24791 (-0.05 %) Code Size: 49827960 -> 49642232 (-0.37 %) bytes Max Waves: 242007 -> 242700 (0.29 %) Totals from affected shaders: SGPRS: 290989 -> 326765 (12.29 %) VGPRS: 244680 -> 241256 (-1.40 %) Spilled SGPRs: 1442 -> 1429 (-0.90 %) Code Size: 8126688 -> 7940960 (-2.29 %) bytes Max Waves: 80952 -> 81645 (0.86 %) Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:
@@ -627,6 +627,50 @@ count_vs_user_sgprs(struct radv_shader_context *ctx)
|
||||
return count;
|
||||
}
|
||||
|
||||
static void allocate_inline_push_consts(struct radv_shader_context *ctx,
|
||||
struct user_sgpr_info *user_sgpr_info)
|
||||
{
|
||||
uint8_t remaining_sgprs = user_sgpr_info->remaining_sgprs;
|
||||
|
||||
/* Only supported if shaders use push constants. */
|
||||
if (ctx->shader_info->info.min_push_constant_used == UINT8_MAX)
|
||||
return;
|
||||
|
||||
/* Only supported if shaders don't have indirect push constants. */
|
||||
if (ctx->shader_info->info.has_indirect_push_constants)
|
||||
return;
|
||||
|
||||
/* Only supported for 32-bit push constants. */
|
||||
if (!ctx->shader_info->info.has_only_32bit_push_constants)
|
||||
return;
|
||||
|
||||
uint8_t num_push_consts =
|
||||
(ctx->shader_info->info.max_push_constant_used -
|
||||
ctx->shader_info->info.min_push_constant_used) / 4;
|
||||
|
||||
/* Check if the number of user SGPRs is large enough. */
|
||||
if (num_push_consts < remaining_sgprs) {
|
||||
ctx->shader_info->info.num_inline_push_consts = num_push_consts;
|
||||
} else {
|
||||
ctx->shader_info->info.num_inline_push_consts = remaining_sgprs;
|
||||
}
|
||||
|
||||
/* Clamp to the maximum number of allowed inlined push constants. */
|
||||
if (ctx->shader_info->info.num_inline_push_consts > AC_MAX_INLINE_PUSH_CONSTS)
|
||||
ctx->shader_info->info.num_inline_push_consts = AC_MAX_INLINE_PUSH_CONSTS;
|
||||
|
||||
if (ctx->shader_info->info.num_inline_push_consts == num_push_consts &&
|
||||
!ctx->shader_info->info.loads_dynamic_offsets) {
|
||||
/* Disable the default push constants path if all constants are
|
||||
* inlined and if shaders don't use dynamic descriptors.
|
||||
*/
|
||||
ctx->shader_info->info.loads_push_constants = false;
|
||||
}
|
||||
|
||||
ctx->shader_info->info.base_inline_push_consts =
|
||||
ctx->shader_info->info.min_push_constant_used / 4;
|
||||
}
|
||||
|
||||
static void allocate_user_sgprs(struct radv_shader_context *ctx,
|
||||
gl_shader_stage stage,
|
||||
bool has_previous_stage,
|
||||
@@ -706,6 +750,8 @@ static void allocate_user_sgprs(struct radv_shader_context *ctx,
|
||||
} else {
|
||||
user_sgpr_info->remaining_sgprs = remaining_sgprs - num_desc_set;
|
||||
}
|
||||
|
||||
allocate_inline_push_consts(ctx, user_sgpr_info);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -735,6 +781,13 @@ declare_global_input_sgprs(struct radv_shader_context *ctx,
|
||||
add_arg(args, ARG_SGPR, type, &ctx->abi.push_constants);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < ctx->shader_info->info.num_inline_push_consts; i++) {
|
||||
add_arg(args, ARG_SGPR, ctx->ac.i32,
|
||||
&ctx->abi.inline_push_consts[i]);
|
||||
}
|
||||
ctx->abi.num_inline_push_consts = ctx->shader_info->info.num_inline_push_consts;
|
||||
ctx->abi.base_inline_push_consts = ctx->shader_info->info.base_inline_push_consts;
|
||||
|
||||
if (ctx->shader_info->info.so.num_outputs) {
|
||||
add_arg(args, ARG_SGPR,
|
||||
ac_array_in_const32_addr_space(ctx->ac.v4i32),
|
||||
@@ -853,6 +906,11 @@ set_global_input_locs(struct radv_shader_context *ctx,
|
||||
set_loc_shader_ptr(ctx, AC_UD_PUSH_CONSTANTS, user_sgpr_idx);
|
||||
}
|
||||
|
||||
if (ctx->shader_info->info.num_inline_push_consts) {
|
||||
set_loc_shader(ctx, AC_UD_INLINE_PUSH_CONSTANTS, user_sgpr_idx,
|
||||
ctx->shader_info->info.num_inline_push_consts);
|
||||
}
|
||||
|
||||
if (ctx->streamout_buffers) {
|
||||
set_loc_shader_ptr(ctx, AC_UD_STREAMOUT_BUFFERS,
|
||||
user_sgpr_idx);
|
||||
|
Reference in New Issue
Block a user