summaryrefslogtreecommitdiffstats
path: root/src/intel/common
diff options
context:
space:
mode:
authorRafael Antognolli <[email protected]>2017-04-18 09:41:40 -0700
committerKenneth Graunke <[email protected]>2017-04-24 15:13:51 -0700
commit1ea41163eb0657e7c6cd46c45bdbc3fd4e8e72f8 (patch)
tree90a04709966e49edf6d5d4569aac84749dba3e73 /src/intel/common
parent50134cede1eee1222c1a28022b42b2177f7379c2 (diff)
intel/aubinator: Correctly read variable length structs.
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 <[email protected]> Tested-by: Jason Ekstrand <[email protected]> Acked-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/intel/common')
-rw-r--r--src/intel/common/gen_decoder.c35
-rw-r--r--src/intel/common/gen_decoder.h6
2 files changed, 35 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;