diff options
-rw-r--r-- | src/intel/common/gen_decoder.c | 35 | ||||
-rw-r--r-- | src/intel/common/gen_decoder.h | 6 | ||||
-rw-r--r-- | 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 e3327d38542..15bba3274ed 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 870bd7f7841..4f4295ff95a 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 f1bedd271e1..53b2a27fa90 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++) { |