[Mesa-dev] [PATCH v2 20/73] radeonsi: scan NIR shaders to obtain required info

Marek Olšák maraeo at gmail.com
Fri Jul 28 05:10:58 UTC 2017


On Wed, Jul 5, 2017 at 12:48 PM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> ---
>  src/gallium/drivers/radeonsi/Makefile.sources   |   1 +
>  src/gallium/drivers/radeonsi/si_shader.c        |   1 +
>  src/gallium/drivers/radeonsi/si_shader.h        |   4 +
>  src/gallium/drivers/radeonsi/si_shader_nir.c    | 312 ++++++++++++++++++++++++
>  src/gallium/drivers/radeonsi/si_state_shaders.c |  23 +-
>  5 files changed, 335 insertions(+), 6 deletions(-)
>  create mode 100644 src/gallium/drivers/radeonsi/si_shader_nir.c
>
> diff --git a/src/gallium/drivers/radeonsi/Makefile.sources b/src/gallium/drivers/radeonsi/Makefile.sources
> index 626fe6f..1587d64 100644
> --- a/src/gallium/drivers/radeonsi/Makefile.sources
> +++ b/src/gallium/drivers/radeonsi/Makefile.sources
> @@ -10,18 +10,19 @@ C_SOURCES := \
>         si_hw_context.c \
>         si_pipe.c \
>         si_pipe.h \
>         si_pm4.c \
>         si_pm4.h \
>         si_perfcounter.c \
>         si_public.h \
>         si_shader.c \
>         si_shader.h \
>         si_shader_internal.h \
> +       si_shader_nir.c \
>         si_shader_tgsi_alu.c \
>         si_shader_tgsi_mem.c \
>         si_shader_tgsi_setup.c \
>         si_state.c \
>         si_state_draw.c \
>         si_state_shaders.c \
>         si_state.h \
>         si_uvd.c
> diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
> index d8bacdb..5ff16f5 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.c
> +++ b/src/gallium/drivers/radeonsi/si_shader.c
> @@ -5518,20 +5518,21 @@ static void si_init_exec_from_input(struct si_shader_context *ctx,
>                            ctx->voidt, args, 2, LP_FUNC_ATTR_CONVERGENT);
>  }
>
>  static bool si_compile_tgsi_main(struct si_shader_context *ctx,
>                                  bool is_monolithic)
>  {
>         struct si_shader *shader = ctx->shader;
>         struct si_shader_selector *sel = shader->selector;
>         struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
>
> +       // TODO clean all this up!
>         switch (ctx->type) {
>         case PIPE_SHADER_VERTEX:
>                 ctx->load_input = declare_input_vs;
>                 if (shader->key.as_ls)
>                         bld_base->emit_epilogue = si_llvm_emit_ls_epilogue;
>                 else if (shader->key.as_es)
>                         bld_base->emit_epilogue = si_llvm_emit_es_epilogue;
>                 else
>                         bld_base->emit_epilogue = si_llvm_emit_vs_epilogue;
>                 break;
> diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
> index 6de7b69..339e156 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.h
> +++ b/src/gallium/drivers/radeonsi/si_shader.h
> @@ -625,20 +625,24 @@ void si_multiwave_lds_size_workaround(struct si_screen *sscreen,
>                                       unsigned *lds_size);
>  void si_shader_apply_scratch_relocs(struct si_shader *shader,
>                                     uint64_t scratch_va);
>  void si_shader_binary_read_config(struct ac_shader_binary *binary,
>                                   struct si_shader_config *conf,
>                                   unsigned symbol_offset);
>  unsigned si_get_spi_shader_z_format(bool writes_z, bool writes_stencil,
>                                     bool writes_samplemask);
>  const char *si_get_shader_name(const struct si_shader *shader, unsigned processor);
>
> +/* si_shader_nir.c */
> +void si_nir_scan_shader(const struct nir_shader *nir,
> +                       struct tgsi_shader_info *info);
> +
>  /* Inline helpers. */
>
>  /* Return the pointer to the main shader part's pointer. */
>  static inline struct si_shader **
>  si_get_main_shader_part(struct si_shader_selector *sel,
>                         struct si_shader_key *key)
>  {
>         if (key->as_ls)
>                 return &sel->main_shader_part_ls;
>         if (key->as_es)
> diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c
> new file mode 100644
> index 0000000..2278c62
> --- /dev/null
> +++ b/src/gallium/drivers/radeonsi/si_shader_nir.c
> @@ -0,0 +1,312 @@
> +/*
> + * Copyright 2017 Advanced Micro Devices, Inc.
> + *
> + * 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
> + * on the rights to use, copy, modify, merge, publish, distribute, sub
> + * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS 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.
> + */
> +
> +#include "si_shader.h"
> +
> +#include "tgsi/tgsi_from_mesa.h"
> +
> +#include "compiler/nir/nir.h"
> +#include "compiler/nir_types.h"
> +
> +
> +static void scan_instruction(struct tgsi_shader_info *info,
> +                            nir_instr *instr)
> +{
> +       if (instr->type == nir_instr_type_alu) {
> +               nir_alu_instr *alu = nir_instr_as_alu(instr);
> +
> +               switch (alu->op) {
> +               case nir_op_fddx:
> +               case nir_op_fddy:
> +               case nir_op_fddx_fine:
> +               case nir_op_fddy_fine:
> +               case nir_op_fddx_coarse:
> +               case nir_op_fddy_coarse:
> +                       info->uses_derivatives = true;
> +                       break;
> +               default:
> +                       break;
> +               }
> +       } else if (instr->type == nir_instr_type_tex) {
> +               nir_tex_instr *tex = nir_instr_as_tex(instr);
> +
> +               switch (tex->op) {
> +               case nir_texop_tex:
> +               case nir_texop_txb:
> +               case nir_texop_lod:
> +                       info->uses_derivatives = true;
> +                       break;
> +               default:
> +                       break;
> +               }
> +       } else if (instr->type == nir_instr_type_intrinsic) {
> +               nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
> +
> +               switch (intr->intrinsic) {
> +               case nir_intrinsic_load_front_face:
> +                       info->uses_frontface = 1;
> +                       break;
> +               case nir_intrinsic_load_instance_id:
> +                       info->uses_instanceid = 1;
> +                       break;
> +               case nir_intrinsic_load_vertex_id:
> +                       info->uses_vertexid = 1;
> +                       break;
> +               case nir_intrinsic_load_vertex_id_zero_base:
> +                       info->uses_vertexid_nobase = 1;
> +                       break;
> +               case nir_intrinsic_load_base_vertex:
> +                       info->uses_basevertex = 1;
> +                       break;
> +               case nir_intrinsic_load_primitive_id:
> +                       info->uses_primid = 1;
> +                       break;
> +               case nir_intrinsic_image_store:
> +               case nir_intrinsic_image_atomic_add:
> +               case nir_intrinsic_image_atomic_min:
> +               case nir_intrinsic_image_atomic_max:
> +               case nir_intrinsic_image_atomic_and:
> +               case nir_intrinsic_image_atomic_or:
> +               case nir_intrinsic_image_atomic_xor:
> +               case nir_intrinsic_image_atomic_exchange:
> +               case nir_intrinsic_image_atomic_comp_swap:
> +               case nir_intrinsic_store_ssbo:
> +               case nir_intrinsic_ssbo_atomic_add:
> +               case nir_intrinsic_ssbo_atomic_imin:
> +               case nir_intrinsic_ssbo_atomic_umin:
> +               case nir_intrinsic_ssbo_atomic_imax:
> +               case nir_intrinsic_ssbo_atomic_umax:
> +               case nir_intrinsic_ssbo_atomic_and:
> +               case nir_intrinsic_ssbo_atomic_or:
> +               case nir_intrinsic_ssbo_atomic_xor:
> +               case nir_intrinsic_ssbo_atomic_exchange:
> +               case nir_intrinsic_ssbo_atomic_comp_swap:
> +                       info->writes_memory = true;
> +                       break;
> +               default:
> +                       break;
> +               }
> +       }
> +}
> +
> +void si_nir_scan_shader(const struct nir_shader *nir,
> +                       struct tgsi_shader_info *info)
> +{
> +       nir_function *func;
> +       unsigned i;
> +
> +       assert(nir->stage == MESA_SHADER_VERTEX ||
> +              nir->stage == MESA_SHADER_FRAGMENT);
> +
> +       info->processor = pipe_shader_type_from_mesa(nir->stage);
> +       info->num_tokens = 1; /* indicate that the shader is non-empty */
> +       info->num_instructions = 1;

This should be 2. 1 means there is only END.

Marek


More information about the mesa-dev mailing list