diff --git a/src/imagination/pco/meson.build b/src/imagination/pco/meson.build index 7db2e010dc4..c0ea6812893 100644 --- a/src/imagination/pco/meson.build +++ b/src/imagination/pco/meson.build @@ -93,9 +93,20 @@ idep_pco_pygen = declare_dependency( pco_pygen_c_files = [pco_info_c] +pco_nir_algebraic_c = custom_target( + 'pco_nir_algebraic.c', + input : 'pco_nir_algebraic.py', + output : 'pco_nir_algebraic.c', + command : [ + prog_python, '@INPUT@', '-p', dir_compiler_nir, + ], + capture : true, + depend_files : nir_algebraic_depends, +) + libpowervr_compiler = static_library( 'powervr_compiler', - [libpowervr_compiler_files, pco_pygen_c_files], + [libpowervr_compiler_files, pco_pygen_c_files, pco_nir_algebraic_c], include_directories : [ inc_imagination, inc_powervr_compiler, diff --git a/src/imagination/pco/pco_internal.h b/src/imagination/pco/pco_internal.h index d6fca168a5b..bd9f01da4c0 100644 --- a/src/imagination/pco/pco_internal.h +++ b/src/imagination/pco/pco_internal.h @@ -1206,8 +1206,10 @@ bool pco_end(pco_shader *shader); bool pco_group_instrs(pco_shader *shader); bool pco_index(pco_shader *shader, bool skip_ssa); bool pco_legalize(pco_shader *shader); -bool pco_nir_pfo(nir_shader *nir, pco_fs_data *fs); -bool pco_nir_pvi(nir_shader *nir, pco_vs_data *vs); +bool pco_nir_lower_algebraic(nir_shader *shader); +bool pco_nir_lower_algebraic_late(nir_shader *shader); +bool pco_nir_pfo(nir_shader *shader, pco_fs_data *fs); +bool pco_nir_pvi(nir_shader *shader, pco_vs_data *vs); bool pco_opt(pco_shader *shader); bool pco_ra(pco_shader *shader); bool pco_schedule(pco_shader *shader); diff --git a/src/imagination/pco/pco_nir.c b/src/imagination/pco/pco_nir.c index 5cd4888f501..403d395e597 100644 --- a/src/imagination/pco/pco_nir.c +++ b/src/imagination/pco/pco_nir.c @@ -212,15 +212,17 @@ void pco_lower_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data) NIR_PASS(_, nir, nir_lower_alu); NIR_PASS(_, nir, nir_lower_pack); NIR_PASS(_, nir, nir_opt_algebraic); + NIR_PASS(_, nir, pco_nir_lower_algebraic); do { progress = false; NIR_PASS(progress, nir, nir_opt_algebraic_late); - NIR_PASS(_, nir, nir_opt_constant_folding); - NIR_PASS(_, nir, nir_lower_load_const_to_scalar); - NIR_PASS(_, nir, nir_copy_prop); - NIR_PASS(_, nir, nir_opt_dce); - NIR_PASS(_, nir, nir_opt_cse); + NIR_PASS(progress, nir, pco_nir_lower_algebraic_late); + NIR_PASS(progress, nir, nir_opt_constant_folding); + NIR_PASS(progress, nir, nir_lower_load_const_to_scalar); + NIR_PASS(progress, nir, nir_copy_prop); + NIR_PASS(progress, nir, nir_opt_dce); + NIR_PASS(progress, nir, nir_opt_cse); } while (progress); nir_variable_mode vec_modes = nir_var_shader_in; diff --git a/src/imagination/pco/pco_nir_algebraic.py b/src/imagination/pco/pco_nir_algebraic.py new file mode 100644 index 00000000000..3510a8960a4 --- /dev/null +++ b/src/imagination/pco/pco_nir_algebraic.py @@ -0,0 +1,47 @@ +# Copyright © 2025 Imagination Technologies Ltd. +# SPDX-License-Identifier: MIT + +import argparse +import sys +import math + +a = 'a' +b = 'b' + +lower_algebraic = [] +lower_algebraic_late = [] + +lower_scmp = [ + # Float comparisons + bool conversions. + (('b2f32', ('flt', a, b)), ('slt', a, 'b@32'), '!options->lower_scmp'), + (('b2f32', ('fge', a, b)), ('sge', a, 'b@32'), '!options->lower_scmp'), + (('b2f32', ('feq', a, b)), ('seq', a, 'b@32'), '!options->lower_scmp'), + (('b2f32', ('fneu', a, b)), ('sne', a, 'b@32'), '!options->lower_scmp'), + + # Float comparisons + bool conversions via bcsel. + (('bcsel@32', ('flt', a, b), 1.0, 0.0), ('slt', a, 'b@32'), '!options->lower_scmp'), + (('bcsel@32', ('fge', a, b), 1.0, 0.0), ('sge', a, 'b@32'), '!options->lower_scmp'), + (('bcsel@32', ('feq', a, b), 1.0, 0.0), ('seq', a, 'b@32'), '!options->lower_scmp'), + (('bcsel@32', ('fneu', a, b), 1.0, 0.0), ('sne', a, 'b@32'), '!options->lower_scmp'), +] + +lower_algebraic_late.extend(lower_scmp) + +# TODO: core-specific info. +params=[] + +def run(): + import nir_algebraic # pylint: disable=import-error + print('#include "pco_internal.h"') + print(nir_algebraic.AlgebraicPass('pco_nir_lower_algebraic', lower_algebraic, params=params).render()) + print(nir_algebraic.AlgebraicPass('pco_nir_lower_algebraic_late', lower_algebraic_late, params=params).render()) + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('-p', '--import-path', required=True) + args = parser.parse_args() + sys.path.insert(0, args.import_path) + run() + +if __name__ == '__main__': + main() diff --git a/src/imagination/pco/pco_nir_pvfio.c b/src/imagination/pco/pco_nir_pvfio.c index 606fad72278..c793521edb5 100644 --- a/src/imagination/pco/pco_nir_pvfio.c +++ b/src/imagination/pco/pco_nir_pvfio.c @@ -177,19 +177,21 @@ static bool lower_pfo(nir_builder *b, nir_instr *instr, void *cb_data) /** * \brief Per-fragment output pass. * - * \param[in,out] nir NIR shader. + * \param[in,out] shader NIR shader. * \param[in,out] fs Fragment shader-specific data. * \return True if the pass made progress. */ -bool pco_nir_pfo(nir_shader *nir, pco_fs_data *fs) +bool pco_nir_pfo(nir_shader *shader, pco_fs_data *fs) { - assert(nir->info.stage == MESA_SHADER_FRAGMENT); + assert(shader->info.stage == MESA_SHADER_FRAGMENT); struct pfo_state state = { .fs = fs }; util_dynarray_init(&state.stores, NULL); - bool progress = - nir_shader_instructions_pass(nir, lower_pfo, nir_metadata_none, &state); + bool progress = nir_shader_instructions_pass(shader, + lower_pfo, + nir_metadata_none, + &state); util_dynarray_fini(&state.stores); @@ -199,13 +201,13 @@ bool pco_nir_pfo(nir_shader *nir, pco_fs_data *fs) /** * \brief Per-vertex input pass. * - * \param[in,out] nir NIR shader. + * \param[in,out] shader NIR shader. * \param[in,out] vs Vertex shader-specific data. * \return True if the pass made progress. */ -bool pco_nir_pvi(nir_shader *nir, pco_vs_data *vs) +bool pco_nir_pvi(nir_shader *shader, pco_vs_data *vs) { - assert(nir->info.stage == MESA_SHADER_VERTEX); + assert(shader->info.stage == MESA_SHADER_VERTEX); puts("finishme: pco_nir_pvi");