[Mesa-dev] [PATCH 01/35] intel/aubinator: Correctly read variable length structs.

Jason Ekstrand jason at jlekstrand.net
Thu Apr 20 00:03:13 UTC 2017


Tested-by: Jason Ekstrand <jason at jlekstrand.net>

On Wed, Apr 19, 2017 at 4:55 PM, Rafael Antognolli <
rafael.antognolli at intel.com> wrote:

> Before this commit, when a group with count="0" is found, only one field
> is added to the struct representing the instruction. This causes only
> one entry to be printed by aubinator, for variable length groups.
>
> With this commit we "detect" that there's a variable length group
> (count="0") and store the offset of the last entry added to the struct
> when reading the xml. When finally reading the aubdump file, we check
> the size of the group and whether we have variable number of elements,
> and in that case, reuse the last field to add the remaining elements.
>
> Signed-off-by: Rafael Antognolli <rafael.antognolli at intel.com>
> ---
>  src/intel/common/gen_decoder.c | 35 +++++++++++++++++++++++++++++------
>  src/intel/common/gen_decoder.h |  6 ++++++-
>  src/intel/tools/aubinator.c    | 19 +++++++++++++++++++-
>  3 files changed, 54 insertions(+), 6 deletions(-)
>
> diff --git a/src/intel/common/gen_decoder.c b/src/intel/common/gen_
> decoder.c
> index e3327d3..15bba32 100644
> --- a/src/intel/common/gen_decoder.c
> +++ b/src/intel/common/gen_decoder.c
> @@ -190,6 +190,8 @@ create_group(struct parser_context *ctx, const char
> *name, const char **atts)
>     group->spec = ctx->spec;
>     group->group_offset = 0;
>     group->group_count = 0;
> +   group->variable_offset = 0;
> +   group->variable = false;
>
>     return group;
>  }
> @@ -210,16 +212,22 @@ create_enum(struct parser_context *ctx, const char
> *name, const char **atts)
>
>  static void
>  get_group_offset_count(struct parser_context *ctx, const char *name,
> -                       const char **atts, uint32_t *offset, uint32_t
> *count)
> +                       const char **atts, uint32_t *offset, uint32_t
> *count,
> +                       uint32_t *elem_size, bool *variable)
>  {
>     char *p;
>     int i;
>
>     for (i = 0; atts[i]; i += 2) {
> -      if (strcmp(atts[i], "count") == 0)
> +      if (strcmp(atts[i], "count") == 0) {
>           *count = strtoul(atts[i + 1], &p, 0);
> -      else if (strcmp(atts[i], "start") == 0)
> +         if (*count == 0)
> +            *variable = true;
> +      } else if (strcmp(atts[i], "start") == 0) {
>           *offset = strtoul(atts[i + 1], &p, 0);
> +      } else if (strcmp(atts[i], "size") == 0) {
> +         *elem_size = strtoul(atts[i + 1], &p, 0);
> +      }
>     }
>     return;
>  }
> @@ -331,8 +339,11 @@ create_field(struct parser_context *ctx, const char
> **atts)
>           field->start = ctx->group->group_offset+strtoul(atts[i + 1],
> &p, 0);
>        else if (strcmp(atts[i], "end") == 0) {
>           field->end = ctx->group->group_offset+strtoul(atts[i + 1], &p,
> 0);
> -         if (ctx->group->group_offset)
> +         if (ctx->group->group_offset) {
>              ctx->group->group_offset = field->end+1;
> +            if (ctx->group->variable)
> +               ctx->group->variable_offset = ctx->group->group_offset;
> +         }
>        } else if (strcmp(atts[i], "type") == 0)
>           field->type = string_to_type(ctx, atts[i + 1]);
>        else if (strcmp(atts[i], "default") == 0 &&
> @@ -400,7 +411,8 @@ start_element(void *data, const char *element_name,
> const char **atts)
>        get_register_offset(atts, &ctx->group->register_offset);
>     } else if (strcmp(element_name, "group") == 0) {
>        get_group_offset_count(ctx, name, atts, &ctx->group->group_offset,
> -                             &ctx->group->group_count);
> +                             &ctx->group->group_count,
> &ctx->group->elem_size,
> +                             &ctx->group->variable);
>     } else if (strcmp(element_name, "field") == 0) {
>        do {
>           ctx->fields[ctx->nfields++] = create_field(ctx, atts);
> @@ -734,6 +746,8 @@ gen_field_iterator_init(struct gen_field_iterator
> *iter,
>     iter->p = p;
>     iter->i = 0;
>     iter->print_colors = print_colors;
> +   iter->repeat = false;
> +   iter->addr_inc = 0;
>  }
>
>  static const char *
> @@ -755,8 +769,17 @@ gen_field_iterator_next(struct gen_field_iterator
> *iter)
>        float f;
>     } v;
>
> -   if (iter->i == iter->group->nfields)
> +   if (iter->i == iter->group->nfields) {
> +      if (iter->group->group_size > 0) {
> +         int iter_length = iter->group->elem_size;
> +
> +         iter->group->group_size -= iter_length / 32;
> +         iter->addr_inc += iter_length;
> +         iter->dword = (iter->field->start + iter->addr_inc) / 32;
> +         return true;
> +      }
>        return false;
> +   }
>
>     iter->field = iter->group->fields[iter->i++];
>     iter->name = iter->field->name;
> diff --git a/src/intel/common/gen_decoder.h b/src/intel/common/gen_
> decoder.h
> index 870bd7f..4f4295f 100644
> --- a/src/intel/common/gen_decoder.h
> +++ b/src/intel/common/gen_decoder.h
> @@ -61,6 +61,8 @@ struct gen_field_iterator {
>     int i;
>     struct gen_field *field;
>     bool print_colors;
> +   bool repeat;
> +   uint32_t addr_inc;
>  };
>
>  struct gen_group {
> @@ -69,6 +71,10 @@ struct gen_group {
>     int nfields;
>     struct gen_field **fields;
>     uint32_t group_offset, group_count;
> +   uint32_t elem_size;
> +   uint32_t variable_offset;
> +   bool variable;
> +   uint32_t group_size;
>
>     uint32_t opcode_mask;
>     uint32_t opcode;
> diff --git a/src/intel/tools/aubinator.c b/src/intel/tools/aubinator.c
> index f1bedd2..53b2a27 100644
> --- a/src/intel/tools/aubinator.c
> +++ b/src/intel/tools/aubinator.c
> @@ -95,10 +95,28 @@ valid_offset(uint32_t offset)
>     return offset < gtt_end;
>  }
>
> +/**
> + * Set group variable size for groups with count="0".
> + *
> + * By default the group size is fixed and not needed because the struct
> + * describing a group knows the number of elements. However, for groups
> with
> + * count="0" we have a variable number of elements, and the struct
> describing
> + * the group only includes one of them. So we calculate the remaining
> size of
> + * the group based on the size we get here, and the offset after the last
> + * element added to the group.
> + */
> +static void
> +group_set_size(struct gen_group *strct, uint32_t size)
> +{
> +   if (strct->variable && strct->elem_size)
> +      strct->group_size = size - (strct->variable_offset / 32);
> +}
> +
>  static void
>  decode_group(struct gen_group *strct, const uint32_t *p, int
> starting_dword)
>  {
>     uint64_t offset = option_print_offsets ? (void *) p - gtt : 0;
> +
>     gen_print_group(outfile, strct, offset, p, option_color ==
> COLOR_ALWAYS);
>  }
>
> @@ -722,6 +740,7 @@ parse_commands(struct gen_spec *spec, uint32_t *cmds,
> int size, int engine)
>                gen_group_get_name(inst), reset_color);
>
>        if (option_full_decode) {
> +         group_set_size(inst, length);
>           decode_group(inst, p, 0);
>
>           for (i = 0; i < ARRAY_LENGTH(custom_handlers); i++) {
> --
> git-series 0.9.1
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170419/1b8683a5/attachment.html>


More information about the mesa-dev mailing list