From: Alyssa Rosenzweig Date: Tue, 10 Mar 2020 20:06:30 +0000 (-0400) Subject: panfrost: Move Midgard sysval code to common Panfrost X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e610267510199532fe22b3c62c0ec68c12918ad4;p=mesa.git panfrost: Move Midgard sysval code to common Panfrost We'll use this all as-is in Bifrost. Signed-off-by: Alyssa Rosenzweig Part-of: --- diff --git a/src/panfrost/midgard/compiler.h b/src/panfrost/midgard/compiler.h index cbe045b09a9..fee1ba9d504 100644 --- a/src/panfrost/midgard/compiler.h +++ b/src/panfrost/midgard/compiler.h @@ -234,13 +234,6 @@ enum midgard_rt_id { MIDGARD_NUM_RTS, }; -struct panfrost_sysvals { - /* The mapping of sysvals to uniforms, the count, and the off-by-one inverse */ - unsigned sysvals[MAX_SYSVAL_COUNT]; - unsigned sysval_count; - struct hash_table_u64 *sysval_to_id; -}; - typedef struct compiler_context { nir_shader *nir; gl_shader_stage stage; diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index f2a69ebdfca..0bc17dc719b 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -295,120 +295,6 @@ midgard_nir_lower_fdot2_body(nir_builder *b, nir_alu_instr *alu) nir_ssa_def_rewrite_uses(&alu->dest.dest.ssa, nir_src_for_ssa(sum)); } -/* TODO: ssbo_size */ -static int -midgard_sysval_for_ssbo(nir_intrinsic_instr *instr) -{ - nir_src index = instr->src[0]; - assert(nir_src_is_const(index)); - uint32_t uindex = nir_src_as_uint(index); - - return PAN_SYSVAL(SSBO, uindex); -} - -static int -midgard_sysval_for_sampler(nir_intrinsic_instr *instr) -{ - /* TODO: indirect samplers !!! */ - nir_src index = instr->src[0]; - assert(nir_src_is_const(index)); - uint32_t uindex = nir_src_as_uint(index); - - return PAN_SYSVAL(SAMPLER, uindex); -} - -static unsigned -midgard_nir_sysval_for_intrinsic(nir_intrinsic_instr *instr) -{ - switch (instr->intrinsic) { - case nir_intrinsic_load_viewport_scale: - return PAN_SYSVAL_VIEWPORT_SCALE; - case nir_intrinsic_load_viewport_offset: - return PAN_SYSVAL_VIEWPORT_OFFSET; - case nir_intrinsic_load_num_work_groups: - return PAN_SYSVAL_NUM_WORK_GROUPS; - case nir_intrinsic_load_ssbo_address: - case nir_intrinsic_get_buffer_size: - return midgard_sysval_for_ssbo(instr); - case nir_intrinsic_load_sampler_lod_parameters_pan: - return midgard_sysval_for_sampler(instr); - default: - return ~0; - } -} - -static int -sysval_for_instr(nir_instr *instr, nir_dest *dest) -{ - nir_intrinsic_instr *intr; - nir_dest *dst = NULL; - nir_tex_instr *tex; - unsigned sysval = ~0; - - switch (instr->type) { - case nir_instr_type_intrinsic: - intr = nir_instr_as_intrinsic(instr); - sysval = midgard_nir_sysval_for_intrinsic(intr); - dst = &intr->dest; - break; - case nir_instr_type_tex: - tex = nir_instr_as_tex(instr); - if (tex->op != nir_texop_txs) - break; - - sysval = PAN_SYSVAL(TEXTURE_SIZE, - PAN_TXS_SYSVAL_ID(tex->texture_index, - nir_tex_instr_dest_size(tex) - - (tex->is_array ? 1 : 0), - tex->is_array)); - dst = &tex->dest; - break; - default: - break; - } - - if (dest && dst) - *dest = *dst; - - return sysval; -} - -static void -midgard_nir_assign_sysval_body(struct panfrost_sysvals *ctx, nir_instr *instr) -{ - int sysval = sysval_for_instr(instr, NULL); - if (sysval < 0) - return; - - /* We have a sysval load; check if it's already been assigned */ - - if (_mesa_hash_table_u64_search(ctx->sysval_to_id, sysval)) - return; - - /* It hasn't -- so assign it now! */ - - unsigned id = ctx->sysval_count++; - _mesa_hash_table_u64_insert(ctx->sysval_to_id, sysval, (void *) ((uintptr_t) id + 1)); - ctx->sysvals[id] = sysval; -} - -static void -midgard_nir_assign_sysvals(struct panfrost_sysvals *ctx, nir_shader *shader) -{ - ctx->sysval_count = 0; - ctx->sysval_to_id = _mesa_hash_table_u64_create(NULL); - - nir_foreach_function(function, shader) { - if (!function->impl) continue; - - nir_foreach_block(block, function->impl) { - nir_foreach_instr_safe(instr, block) { - midgard_nir_assign_sysval_body(ctx, instr); - } - } - } -} - static bool midgard_nir_lower_fdot2(nir_shader *shader) { @@ -1373,7 +1259,7 @@ emit_sysval_read(compiler_context *ctx, nir_instr *instr, nir_dest nir_dest; /* Figure out which uniform this is */ - int sysval = sysval_for_instr(instr, &nir_dest); + int sysval = panfrost_sysval_for_instr(instr, &nir_dest); void *val = _mesa_hash_table_u64_search(ctx->sysvals.sysval_to_id, sysval); unsigned dest = nir_dest_index(&nir_dest); @@ -2826,7 +2712,7 @@ midgard_compile_shader_nir(nir_shader *nir, panfrost_program *program, bool is_b /* Assign sysvals and counts, now that we're sure * (post-optimisation) */ - midgard_nir_assign_sysvals(&ctx->sysvals, nir); + panfrost_nir_assign_sysvals(&ctx->sysvals, nir); program->uniform_count = nir->num_uniforms; program->sysval_count = ctx->sysvals.sysval_count; diff --git a/src/panfrost/util/meson.build b/src/panfrost/util/meson.build index 0b7e426c03f..cf8577041dd 100644 --- a/src/panfrost/util/meson.build +++ b/src/panfrost/util/meson.build @@ -22,12 +22,14 @@ libpanfrost_util_files = files( 'pan_ir.c', 'pan_ir.h', + 'pan_sysval.c', ) libpanfrost_util = static_library( 'panfrost_util', [libpanfrost_util_files], include_directories : [inc_common, inc_panfrost_hw], + dependencies: [idep_nir], c_args : [c_vis_args, no_override_init_args], cpp_args : [cpp_vis_args], build_by_default : false, diff --git a/src/panfrost/util/pan_ir.h b/src/panfrost/util/pan_ir.h index 774ce26e88e..425c5246c1c 100644 --- a/src/panfrost/util/pan_ir.h +++ b/src/panfrost/util/pan_ir.h @@ -26,7 +26,9 @@ #include #include "panfrost-job.h" +#include "compiler/nir/nir.h" #include "util/u_dynarray.h" +#include "util/hash_table.h" /* Define the general compiler entry point */ @@ -67,6 +69,19 @@ enum { PAN_MAX_ATTRIBUTE }; +struct panfrost_sysvals { + /* The mapping of sysvals to uniforms, the count, and the off-by-one inverse */ + unsigned sysvals[MAX_SYSVAL_COUNT]; + unsigned sysval_count; + struct hash_table_u64 *sysval_to_id; +}; + +void +panfrost_nir_assign_sysvals(struct panfrost_sysvals *ctx, nir_shader *shader); + +int +panfrost_sysval_for_instr(nir_instr *instr, nir_dest *dest); + typedef struct { int work_register_count; int uniform_count; diff --git a/src/panfrost/util/pan_sysval.c b/src/panfrost/util/pan_sysval.c new file mode 100644 index 00000000000..5f67e71f68c --- /dev/null +++ b/src/panfrost/util/pan_sysval.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2020 Collabora Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors (Collabora): + * Alyssa Rosenzweig + */ + +#include "pan_ir.h" + +/* TODO: ssbo_size */ +static int +panfrost_sysval_for_ssbo(nir_intrinsic_instr *instr) +{ + nir_src index = instr->src[0]; + assert(nir_src_is_const(index)); + uint32_t uindex = nir_src_as_uint(index); + + return PAN_SYSVAL(SSBO, uindex); +} + +static int +panfrost_sysval_for_sampler(nir_intrinsic_instr *instr) +{ + /* TODO: indirect samplers !!! */ + nir_src index = instr->src[0]; + assert(nir_src_is_const(index)); + uint32_t uindex = nir_src_as_uint(index); + + return PAN_SYSVAL(SAMPLER, uindex); +} + +static unsigned +panfrost_nir_sysval_for_intrinsic(nir_intrinsic_instr *instr) +{ + switch (instr->intrinsic) { + case nir_intrinsic_load_viewport_scale: + return PAN_SYSVAL_VIEWPORT_SCALE; + case nir_intrinsic_load_viewport_offset: + return PAN_SYSVAL_VIEWPORT_OFFSET; + case nir_intrinsic_load_num_work_groups: + return PAN_SYSVAL_NUM_WORK_GROUPS; + case nir_intrinsic_load_ssbo_address: + case nir_intrinsic_get_buffer_size: + return panfrost_sysval_for_ssbo(instr); + case nir_intrinsic_load_sampler_lod_parameters_pan: + return panfrost_sysval_for_sampler(instr); + default: + return ~0; + } +} + +int +panfrost_sysval_for_instr(nir_instr *instr, nir_dest *dest) +{ + nir_intrinsic_instr *intr; + nir_dest *dst = NULL; + nir_tex_instr *tex; + unsigned sysval = ~0; + + switch (instr->type) { + case nir_instr_type_intrinsic: + intr = nir_instr_as_intrinsic(instr); + sysval = panfrost_nir_sysval_for_intrinsic(intr); + dst = &intr->dest; + break; + case nir_instr_type_tex: + tex = nir_instr_as_tex(instr); + if (tex->op != nir_texop_txs) + break; + + sysval = PAN_SYSVAL(TEXTURE_SIZE, + PAN_TXS_SYSVAL_ID(tex->texture_index, + nir_tex_instr_dest_size(tex) - + (tex->is_array ? 1 : 0), + tex->is_array)); + dst = &tex->dest; + break; + default: + break; + } + + if (dest && dst) + *dest = *dst; + + return sysval; +} + +static void +panfrost_nir_assign_sysval_body(struct panfrost_sysvals *ctx, nir_instr *instr) +{ + int sysval = panfrost_sysval_for_instr(instr, NULL); + if (sysval < 0) + return; + + /* We have a sysval load; check if it's already been assigned */ + + if (_mesa_hash_table_u64_search(ctx->sysval_to_id, sysval)) + return; + + /* It hasn't -- so assign it now! */ + + unsigned id = ctx->sysval_count++; + _mesa_hash_table_u64_insert(ctx->sysval_to_id, sysval, (void *) ((uintptr_t) id + 1)); + ctx->sysvals[id] = sysval; +} + +void +panfrost_nir_assign_sysvals(struct panfrost_sysvals *ctx, nir_shader *shader) +{ + ctx->sysval_count = 0; + ctx->sysval_to_id = _mesa_hash_table_u64_create(NULL); + + nir_foreach_function(function, shader) { + if (!function->impl) continue; + + nir_foreach_block(block, function->impl) { + nir_foreach_instr_safe(instr, block) { + panfrost_nir_assign_sysval_body(ctx, instr); + } + } + } +}