diff --git a/docs/envvars.rst b/docs/envvars.rst index 39e3c1be2aa..d69cd71cb34 100644 --- a/docs/envvars.rst +++ b/docs/envvars.rst @@ -2168,6 +2168,8 @@ PowerVR driver environment variables Print verbose IR. ``ra`` Print register alloc info. + ``stats`` + Print shader stats. .. envvar:: PCO_COLOR diff --git a/src/imagination/pco/pco.c b/src/imagination/pco/pco.c index d39453cf48a..42c76bd9db3 100644 --- a/src/imagination/pco/pco.c +++ b/src/imagination/pco/pco.c @@ -19,6 +19,7 @@ #include "util/list.h" #include "util/macros.h" #include "util/ralloc.h" +#include "util/shader_stats.h" #include #include @@ -316,3 +317,64 @@ pco_precomp_data pco_get_precomp_data(pco_shader *shader) .size_dwords = size_dwords, }; } + +/** + * \brief Returns statistics for a shader. + * + * \param[in] shader PCO shader. + * \return The shader statistics. + */ +struct pvr_stats pco_get_pvr_stats(pco_shader *shader) +{ + assert(shader->is_grouped); + + unsigned shader_size = pco_shader_binary_size(shader); + assert(shader_size > 0); + + unsigned loop_count = 0; + unsigned igrp_count = 0; + + unsigned main_count = 0; + unsigned bitwise_count = 0; + unsigned control_count = 0; + + pco_foreach_func_in_shader (func, shader) { + pco_foreach_loop_in_func (loop, func) { + loop_count++; + } + pco_foreach_igrp_in_func (igrp, func) { + igrp_count++; + switch (igrp->hdr.alutype) { + case PCO_ALUTYPE_MAIN: + main_count++; + break; + + case PCO_ALUTYPE_BITWISE: + bitwise_count++; + break; + + case PCO_ALUTYPE_CONTROL: + control_count++; + break; + + default: + UNREACHABLE("Invalid pco_alutype"); + } + } + } + + return (struct pvr_stats){ + .isa = PVR_STAT_ROGUE, + .rogue = (struct rogue_stats) { + .code_size = shader_size, + .scratch_size = shader->data.common.scratch, + .spill_count = shader->data.common.spilled_temps, + .temp_count = shader->data.common.temps, + .loop_count = loop_count, + .inst_group_count = igrp_count, + .main_inst_group_count = main_count, + .bitwise_inst_group_count = bitwise_count, + .control_inst_group_count = control_count, + }, + }; +} diff --git a/src/imagination/pco/pco.h b/src/imagination/pco/pco.h index 03e4b02103f..4b528e1b121 100644 --- a/src/imagination/pco/pco.h +++ b/src/imagination/pco/pco.h @@ -55,6 +55,7 @@ const void *pco_shader_binary_data(pco_shader *shader); void pco_validate_shader(pco_shader *shader, const char *when); +void pco_print_shader_stats(pco_shader *shader, FILE *fp); void pco_print_shader(pco_shader *shader, FILE *fp, const char *when); void pco_print_binary(pco_shader *shader, FILE *fp, const char *when); diff --git a/src/imagination/pco/pco_binary.c b/src/imagination/pco/pco_binary.c index ce78465cf0b..7c9aaf0fb35 100644 --- a/src/imagination/pco/pco_binary.c +++ b/src/imagination/pco/pco_binary.c @@ -127,6 +127,9 @@ void pco_encode_ir(pco_ctx *ctx, pco_shader *shader) if (pco_should_print_binary(shader)) pco_print_binary(shader, stdout, "after encoding"); + + if (pco_should_print_stats(shader)) + pco_print_shader_stats(shader, stdout); } /** diff --git a/src/imagination/pco/pco_data.h b/src/imagination/pco/pco_data.h index 4231e1e2e45..36c166f036e 100644 --- a/src/imagination/pco/pco_data.h +++ b/src/imagination/pco/pco_data.h @@ -256,4 +256,6 @@ typedef struct PACKED _pco_precomp_data { static_assert(sizeof(pco_precomp_data) == 8, "sizeof(pco_precomp_data) != 8"); pco_precomp_data pco_get_precomp_data(pco_shader *shader); + +struct pvr_stats pco_get_pvr_stats(pco_shader *shader); #endif /* PCO_DATA_H */ diff --git a/src/imagination/pco/pco_debug.c b/src/imagination/pco/pco_debug.c index 881ed0c60b5..54f5c254e35 100644 --- a/src/imagination/pco/pco_debug.c +++ b/src/imagination/pco/pco_debug.c @@ -42,6 +42,7 @@ static const struct debug_named_value pco_debug_print_options[] = { { "binary", PCO_DEBUG_PRINT_BINARY, "Print the resulting binary." }, { "verbose", PCO_DEBUG_PRINT_VERBOSE, "Print verbose IR." }, { "ra", PCO_DEBUG_PRINT_RA, "Print register alloc info." }, + { "stats", PCO_DEBUG_PRINT_STATS, "Print shader stats." }, DEBUG_NAMED_VALUE_END, }; diff --git a/src/imagination/pco/pco_internal.h b/src/imagination/pco/pco_internal.h index 50d42566e49..fb900c3bb14 100644 --- a/src/imagination/pco/pco_internal.h +++ b/src/imagination/pco/pco_internal.h @@ -75,6 +75,7 @@ enum pco_debug_print { PCO_DEBUG_PRINT_BINARY = BITFIELD64_BIT(6), PCO_DEBUG_PRINT_VERBOSE = BITFIELD64_BIT(7), PCO_DEBUG_PRINT_RA = BITFIELD64_BIT(8), + PCO_DEBUG_PRINT_STATS = BITFIELD64_BIT(9), }; extern uint64_t pco_debug_print; @@ -1727,6 +1728,24 @@ static inline bool pco_should_print_binary(pco_shader *shader) return true; } +static inline bool pco_should_print_stats(pco_shader *shader) +{ + if (!PCO_DEBUG_PRINT(STATS)) + return false; + + if (shader->is_internal && !PCO_DEBUG_PRINT(INTERNAL)) + return false; + + if (shader->stage == MESA_SHADER_VERTEX && !PCO_DEBUG_PRINT(VS)) + return false; + else if (shader->stage == MESA_SHADER_FRAGMENT && !PCO_DEBUG_PRINT(FS)) + return false; + else if (shader->stage == MESA_SHADER_COMPUTE && !PCO_DEBUG_PRINT(CS)) + return false; + + return true; +} + /* Interface with NIR. */ typedef union PACKED _pco_smp_flags { struct PACKED { diff --git a/src/imagination/pco/pco_print.c b/src/imagination/pco/pco_print.c index 3d17fcb0bf2..17ad1996f88 100644 --- a/src/imagination/pco/pco_print.c +++ b/src/imagination/pco/pco_print.c @@ -17,6 +17,7 @@ #include "util/bitscan.h" #include "util/list.h" #include "util/macros.h" +#include "util/shader_stats.h" #include "util/u_hexdump.h" #include @@ -1239,7 +1240,30 @@ static void _pco_print_shader_info(pco_print_state *state, pco_shader *shader) pco_printfi(state, "name: \"%s\"\n", shader->name); pco_printfi(state, "stage: %s\n", mesa_shader_stage_name(shader->stage)); pco_printfi(state, "internal: %s\n", true_false_str(shader->is_internal)); - /* TODO: more info/stats, e.g. temps/other regs used, etc.? */ +} + +/** + * \brief Print PCO shader stats. + * + * \param[in] shader PCO state. + * \param[in] fp Print target file pointer. + */ +void pco_print_shader_stats(pco_shader *shader, FILE *fp) +{ + pco_print_state state = { + .fp = fp, + .shader = shader, + .indent = 0, + .is_grouped = shader->is_grouped, + .verbose = PCO_DEBUG_PRINT(VERBOSE), + }; + + _pco_print_shader_info(&state, shader); + + struct pvr_stats stats = pco_get_pvr_stats(shader); + pvr_stats_fprintf(fp, + _mesa_shader_stage_to_abbrev(shader->nir->info.stage), + &stats); } /** diff --git a/src/util/shader_stats.xml b/src/util/shader_stats.xml index 7628275bded..7c764520a69 100644 --- a/src/util/shader_stats.xml +++ b/src/util/shader_stats.xml @@ -187,4 +187,18 @@ + + + + Binary size in bytes + Scratch size per instance in bytes + Number of spilled registers per instance + Number of allocated temp registers + Number of not unrolled loops in the shader + Total number of instruction groups + Number of main instruction groups + Number of bitwise instruction groups + Number of control instruction groups + +