summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/intel/common/gen_decoder.c35
-rw-r--r--src/intel/common/gen_decoder.h6
-rw-r--r--src/intel/tools/aubinator.c19
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++) {