[Mesa-dev] [PATCH 01/16] tgsi/scan: add tgsi_scan_arrays

Marek Olšák maraeo at gmail.com
Thu Aug 11 23:22:22 UTC 2016


This patch:

Reviewed-by: Marek Olšák <marek.olsak at amd.com>

Marek

On Wed, Aug 10, 2016 at 9:23 PM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> ---
>  src/gallium/auxiliary/tgsi/tgsi_scan.c | 76 ++++++++++++++++++++++++++++++++++
>  src/gallium/auxiliary/tgsi/tgsi_scan.h | 17 ++++++++
>  2 files changed, 93 insertions(+)
>
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c
> index 98d86fc..0167e22 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
> @@ -628,20 +628,96 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
>        info->file_max[TGSI_FILE_INPUT] =
>              MAX2(info->file_max[TGSI_FILE_INPUT], num_verts - 1);
>        for (j = 0; j < num_verts; ++j) {
>           info->file_mask[TGSI_FILE_INPUT] |= (1 << j);
>        }
>     }
>
>     tgsi_parse_free(&parse);
>  }
>
> +/**
> + * Collect information about the arrays of a given register file.
> + *
> + * @param tokens TGSI shader
> + * @param file the register file to scan through
> + * @param max_array_id number of entries in @p arrays; should be equal to the
> + *                     highest array id, i.e. tgsi_shader_info::array_max[file].
> + * @param arrays info for array of each ID will be written to arrays[ID - 1].
> + */
> +void
> +tgsi_scan_arrays(const struct tgsi_token *tokens,
> +                 unsigned file,
> +                 unsigned max_array_id,
> +                 struct tgsi_array_info *arrays)
> +{
> +   struct tgsi_parse_context parse;
> +
> +   if (tgsi_parse_init(&parse, tokens) != TGSI_PARSE_OK) {
> +      debug_printf("tgsi_parse_init() failed in tgsi_scan_arrays()!\n");
> +      return;
> +   }
> +
> +   memset(arrays, 0, sizeof(arrays[0]) * max_array_id);
> +
> +   while (!tgsi_parse_end_of_tokens(&parse)) {
> +      struct tgsi_full_instruction *inst;
> +
> +      tgsi_parse_token(&parse);
> +
> +      if (parse.FullToken.Token.Type == TGSI_TOKEN_TYPE_DECLARATION) {
> +         struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration;
> +
> +         if (decl->Declaration.Array && decl->Declaration.File == file &&
> +             decl->Array.ArrayID > 0 && decl->Array.ArrayID <= max_array_id) {
> +            struct tgsi_array_info *array = &arrays[decl->Array.ArrayID - 1];
> +            assert(!array->declared);
> +            array->declared = true;
> +            array->range = decl->Range;
> +         }
> +      }
> +
> +      if (parse.FullToken.Token.Type != TGSI_TOKEN_TYPE_INSTRUCTION)
> +         continue;
> +
> +      inst = &parse.FullToken.FullInstruction;
> +      for (unsigned i = 0; i < inst->Instruction.NumDstRegs; i++) {
> +         const struct tgsi_full_dst_register *dst = &inst->Dst[i];
> +         if (dst->Register.File != file)
> +            continue;
> +
> +         if (dst->Register.Indirect) {
> +            if (dst->Indirect.ArrayID > 0 &&
> +                dst->Indirect.ArrayID <= max_array_id) {
> +               arrays[dst->Indirect.ArrayID - 1].writemask |= dst->Register.WriteMask;
> +            } else {
> +               /* Indirect writes without an ArrayID can write anywhere. */
> +               for (unsigned j = 0; j < max_array_id; ++j)
> +                  arrays[j].writemask |= dst->Register.WriteMask;
> +            }
> +         } else {
> +            /* Check whether the write falls into any of the arrays anyway. */
> +            for (unsigned j = 0; j < max_array_id; ++j) {
> +               struct tgsi_array_info *array = &arrays[j];
> +               if (array->declared &&
> +                   dst->Register.Index >= array->range.First &&
> +                   dst->Register.Index <= array->range.Last)
> +                  array->writemask |= dst->Register.WriteMask;
> +            }
> +         }
> +      }
> +   }
> +
> +   tgsi_parse_free(&parse);
> +
> +   return;
> +}
>
>
>  /**
>   * Check if the given shader is a "passthrough" shader consisting of only
>   * MOV instructions of the form:  MOV OUT[n], IN[n]
>   *
>   */
>  boolean
>  tgsi_is_passthrough_shader(const struct tgsi_token *tokens)
>  {
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h
> index f7eefa4..30d0146 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_scan.h
> +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h
> @@ -142,23 +142,40 @@ struct tgsi_shader_info
>     unsigned indirect_files_written;
>
>     unsigned properties[TGSI_PROPERTY_COUNT]; /* index with TGSI_PROPERTY_ */
>
>     /**
>      * Max nesting limit of loops/if's
>      */
>     unsigned max_depth;
>  };
>
> +struct tgsi_array_info
> +{
> +   /** Whether an array with this ID was declared. */
> +   bool declared;
> +
> +   /** The OR of all writemasks used to write to this array. */
> +   ubyte writemask;
> +
> +   /** The range with which the array was declared. */
> +   struct tgsi_declaration_range range;
> +};
> +
>  extern void
>  tgsi_scan_shader(const struct tgsi_token *tokens,
>                   struct tgsi_shader_info *info);
>
> +void
> +tgsi_scan_arrays(const struct tgsi_token *tokens,
> +                 unsigned file,
> +                 unsigned max_array_id,
> +                 struct tgsi_array_info *arrays);
>
>  extern boolean
>  tgsi_is_passthrough_shader(const struct tgsi_token *tokens);
>
>  #ifdef __cplusplus
>  } // extern "C"
>  #endif
>
>  #endif /* TGSI_SCAN_H */
> --
> 2.7.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list