[Mesa-dev] [PATCH v2 09/11] intel: decoder: decouple decoding from memory pointers
Lionel Landwerlin
lionel.g.landwerlin at intel.com
Wed Nov 1 18:12:16 UTC 2017
We want to introduce a reader interface for accessing memory, so that
later on we can use different ways of storing the content of the GTT
address space that don't involve a pointer to a linear buffer.
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
---
src/intel/common/gen_decoder.c | 75 ++++++++++++++++++++-------
src/intel/common/gen_decoder.h | 24 +++++++--
src/intel/tools/aubinator.c | 7 ++-
src/intel/tools/aubinator_error_decode.c | 12 +++--
src/mesa/drivers/dri/i965/intel_batchbuffer.c | 26 +++++++---
5 files changed, 108 insertions(+), 36 deletions(-)
diff --git a/src/intel/common/gen_decoder.c b/src/intel/common/gen_decoder.c
index 7aebcef278c..c578824c186 100644
--- a/src/intel/common/gen_decoder.c
+++ b/src/intel/common/gen_decoder.c
@@ -799,12 +799,18 @@ iter_group_offset_bits(const struct gen_field_iterator *iter,
return iter->group->group_offset + (group_iter * iter->group->group_size);
}
+uint32_t gen_read_dword_from_pointer(void *user_data, uint32_t dword_offset)
+{
+ return ((uint32_t *) user_data)[dword_offset];
+}
+
static bool
iter_more_groups(const struct gen_field_iterator *iter)
{
if (iter->group->variable) {
return iter_group_offset_bits(iter, iter->group_iter + 1) <
- (gen_group_get_length(iter->group, iter->p[0]) * 32);
+ (gen_group_get_length(iter->group,
+ gen_read_dword(iter->reader, 0)) * 32);
} else {
return (iter->group_iter + 1) < iter->group->group_count ||
iter->group->next != NULL;
@@ -856,17 +862,20 @@ iter_advance_field(struct gen_field_iterator *iter)
static uint64_t
iter_decode_field_raw(struct gen_field *field,
- const uint32_t *p,
- const uint32_t *end)
+ uint32_t dword_offset,
+ uint32_t dword_end,
+ const struct gen_dword_reader *reader)
{
uint64_t qw = 0;
if ((field->end - field->start) > 32) {
- if ((p + 1) < end)
- qw = ((uint64_t) p[1]) << 32;
- qw |= p[0];
+ if ((dword_offset + 1) < dword_end) {
+ qw = gen_read_dword(reader, dword_offset + 1);
+ qw <<= 32;
+ }
+ qw |= gen_read_dword(reader, dword_offset);
} else
- qw = p[0];
+ qw = gen_read_dword(reader, dword_offset);
qw = field_value(qw, field->start, field->end);
@@ -895,8 +904,8 @@ iter_decode_field(struct gen_field_iterator *iter)
memset(&v, 0, sizeof(v));
- v.qw = iter_decode_field_raw(iter->field,
- &iter->p[iter->dword], iter->p_end);
+ v.qw = iter_decode_field_raw(iter->field, iter->dword,
+ iter->dword_end, iter->reader);
const char *enum_name = NULL;
@@ -966,7 +975,7 @@ iter_decode_field(struct gen_field_iterator *iter)
void
gen_field_iterator_init(struct gen_field_iterator *iter,
struct gen_group *group,
- const uint32_t *p,
+ const struct gen_dword_reader *reader,
bool print_colors)
{
memset(iter, 0, sizeof(*iter));
@@ -976,8 +985,9 @@ gen_field_iterator_init(struct gen_field_iterator *iter,
iter->field = group->fields;
else
iter->field = group->next->fields;
- iter->p = p;
- iter->p_end = &p[gen_group_get_length(iter->group, p[0])];
+ iter->reader = reader;
+ iter->dword_end = gen_group_get_length(iter->group,
+ gen_read_dword(reader, 0));
iter->print_colors = print_colors;
iter_decode_field(iter);
@@ -997,10 +1007,12 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
static void
print_dword_header(FILE *outfile,
struct gen_field_iterator *iter,
- uint64_t offset, uint32_t dword)
+ uint64_t offset,
+ uint32_t dword)
{
fprintf(outfile, "0x%08"PRIx64": 0x%08x : Dword %d\n",
- offset + 4 * dword, iter->p[dword], dword);
+ offset + 4 * dword,
+ gen_read_dword(iter->reader, dword), dword);
}
bool
@@ -1018,21 +1030,38 @@ gen_field_is_header(struct gen_field *field)
}
void gen_field_decode(struct gen_field *field,
- const uint32_t *p, const uint32_t *end,
+ const struct gen_dword_reader *reader,
union gen_field_value *value)
{
+ uint32_t length = gen_group_get_length(field->parent,
+ gen_read_dword(reader, 0));
uint32_t dword = field->start / 32;
- value->u64 = iter_decode_field_raw(field, &p[dword], end);
+ value->u64 = iter_decode_field_raw(field, dword, length, reader);
+}
+
+struct sub_struct_reader {
+ struct gen_dword_reader base;
+ const struct gen_dword_reader *reader;
+ uint32_t struct_offset;
+};
+
+static uint32_t
+read_struct_dword(void *user_data, uint32_t dword_offset)
+{
+ struct sub_struct_reader *reader = user_data;
+ return gen_read_dword(reader->reader, reader->struct_offset + dword_offset);
}
void
gen_print_group(FILE *outfile, struct gen_group *group,
- uint64_t offset, const uint32_t *p, bool color)
+ uint64_t offset,
+ const struct gen_dword_reader *reader,
+ bool color)
{
struct gen_field_iterator iter;
int last_dword = -1;
- gen_field_iterator_init(&iter, group, p, color);
+ gen_field_iterator_init(&iter, group, reader, color);
do {
if (last_dword != iter.dword) {
for (int i = last_dword + 1; i <= iter.dword; i++)
@@ -1043,8 +1072,16 @@ gen_print_group(FILE *outfile, struct gen_group *group,
fprintf(outfile, " %s: %s\n", iter.name, iter.value);
if (iter.struct_desc) {
uint64_t struct_offset = offset + 4 * iter.dword;
+ struct sub_struct_reader struct_reader = {
+ .base = {
+ .user_data = &struct_reader,
+ .read = read_struct_dword,
+ },
+ .reader = reader,
+ .struct_offset = 4 * iter.dword,
+ };
gen_print_group(outfile, iter.struct_desc, struct_offset,
- &p[iter.dword], color);
+ &struct_reader.base, color);
}
}
} while (gen_field_iterator_next(&iter));
diff --git a/src/intel/common/gen_decoder.h b/src/intel/common/gen_decoder.h
index d4a5984e578..bcc0da7a3d7 100644
--- a/src/intel/common/gen_decoder.h
+++ b/src/intel/common/gen_decoder.h
@@ -39,6 +39,19 @@ struct gen_group;
struct gen_field;
union gen_field_value;
+struct gen_dword_reader {
+ void *user_data;
+ uint32_t (*read)(void *user_data, uint32_t dword_offset);
+};
+
+uint32_t gen_read_dword_from_pointer(void *user_data, uint32_t dword_offset);
+
+static inline uint32_t
+gen_read_dword(const struct gen_dword_reader *reader, uint32_t dword_offset)
+{
+ return reader->read(reader->user_data, dword_offset);
+}
+
static inline uint32_t gen_make_gen(uint32_t major, uint32_t minor)
{
return (major << 8) | minor;
@@ -63,7 +76,7 @@ struct gen_field *gen_group_find_field(struct gen_group *group, const char *name
bool gen_field_is_header(struct gen_field *field);
void gen_field_decode(struct gen_field *field,
- const uint32_t *p, const uint32_t *end,
+ const struct gen_dword_reader *reader,
union gen_field_value *value);
struct gen_field_iterator {
@@ -71,11 +84,11 @@ struct gen_field_iterator {
char name[128];
char value[128];
struct gen_group *struct_desc;
- const uint32_t *p;
- const uint32_t *p_end;
+ const struct gen_dword_reader *reader;
int dword; /**< current field starts at &p[dword] */
int start; /**< current field starts at this bit number */
int end; /**< current field ends at this bit number */
+ int dword_end;
int group_iter;
@@ -176,14 +189,15 @@ struct gen_field {
void gen_field_iterator_init(struct gen_field_iterator *iter,
struct gen_group *group,
- const uint32_t *p,
+ const struct gen_dword_reader *reader,
bool print_colors);
bool gen_field_iterator_next(struct gen_field_iterator *iter);
void gen_print_group(FILE *out,
struct gen_group *group,
- uint64_t offset, const uint32_t *p,
+ uint64_t offset,
+ const struct gen_dword_reader *reader,
bool color);
#ifdef __cplusplus
diff --git a/src/intel/tools/aubinator.c b/src/intel/tools/aubinator.c
index bf9490e315f..b3b39e1d578 100644
--- a/src/intel/tools/aubinator.c
+++ b/src/intel/tools/aubinator.c
@@ -93,8 +93,13 @@ 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;
+ struct gen_dword_reader reader = {
+ .user_data = (void *) p,
+ .read = gen_read_dword_from_pointer,
+ };
- gen_print_group(outfile, strct, offset, p, option_color == COLOR_ALWAYS);
+ gen_print_group(outfile, strct, offset, &reader,
+ option_color == COLOR_ALWAYS);
}
static void
diff --git a/src/intel/tools/aubinator_error_decode.c b/src/intel/tools/aubinator_error_decode.c
index 0881a8ef502..d7d8163d70b 100644
--- a/src/intel/tools/aubinator_error_decode.c
+++ b/src/intel/tools/aubinator_error_decode.c
@@ -67,9 +67,10 @@ static void
print_register(struct gen_spec *spec, const char *name, uint32_t reg)
{
struct gen_group *reg_spec = gen_spec_find_register_by_name(spec, name);
+ struct gen_dword_reader reader = { ®, gen_read_dword_from_pointer };
if (reg_spec)
- gen_print_group(stdout, reg_spec, 0, ®, option_color == COLOR_ALWAYS);
+ gen_print_group(stdout, reg_spec, 0, &reader, option_color == COLOR_ALWAYS);
}
struct ring_register_mapping {
@@ -265,7 +266,8 @@ static void decode(struct gen_spec *spec,
printf("%s0x%08"PRIx64": 0x%08x: %-80s%s\n",
color, offset, p[0], gen_group_get_name(inst), reset_color);
- gen_print_group(stdout, inst, offset, p,
+ struct gen_dword_reader reader = { p, gen_read_dword_from_pointer };
+ gen_print_group(stdout, inst, offset, &reader,
option_color == COLOR_ALWAYS);
if (strcmp(inst->name, "MI_BATCH_BUFFER_END") == 0)
@@ -273,7 +275,7 @@ static void decode(struct gen_spec *spec,
if (strcmp(inst->name, "STATE_BASE_ADDRESS") == 0) {
struct gen_field_iterator iter;
- gen_field_iterator_init(&iter, inst, p, false);
+ gen_field_iterator_init(&iter, inst, &reader, false);
while (gen_field_iterator_next(&iter)) {
if (strcmp(iter.name, "Instruction Base Address") == 0) {
@@ -284,7 +286,7 @@ static void decode(struct gen_spec *spec,
strcmp(inst->name, "3DSTATE_PS") == 0 ||
strcmp(inst->name, "3DSTATE_WM") == 0) {
struct gen_field_iterator iter;
- gen_field_iterator_init(&iter, inst, p, false);
+ gen_field_iterator_init(&iter, inst, &reader, false);
uint64_t ksp[3] = {0, 0, 0};
bool enabled[3] = {false, false, false};
@@ -355,7 +357,7 @@ static void decode(struct gen_spec *spec,
strcmp(inst->name, "3DSTATE_GS") == 0 ||
strcmp(inst->name, "3DSTATE_VS") == 0) {
struct gen_field_iterator iter;
- gen_field_iterator_init(&iter, inst, p, false);
+ gen_field_iterator_init(&iter, inst, &reader, false);
uint64_t ksp = 0;
bool is_simd8 = false; /* vertex shaders on Gen8+ only */
bool is_enabled = true;
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
index 0f6759d55aa..065bc249732 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
@@ -405,8 +405,11 @@ decode_struct(struct brw_context *brw, struct gen_spec *spec,
return;
fprintf(stderr, "%s\n", struct_name);
- gen_print_group(stderr, group, gtt_offset + offset,
- &data[offset / 4], color);
+ struct gen_dword_reader reader = {
+ .read = gen_read_dword_from_pointer,
+ .user_data = &data[offset / 4],
+ };
+ gen_print_group(stderr, group, gtt_offset + offset, &reader, color);
}
static void
@@ -422,8 +425,11 @@ decode_structs(struct brw_context *brw, struct gen_spec *spec,
int entries = brw_state_batch_size(brw, offset) / struct_size;
for (int i = 0; i < entries; i++) {
fprintf(stderr, "%s %d\n", struct_name, i);
- gen_print_group(stderr, group, gtt_offset + offset,
- &data[(offset + i * struct_size) / 4], color);
+ struct gen_dword_reader reader = {
+ .read = gen_read_dword_from_pointer,
+ .user_data = &data[(offset + i * struct_size) / 4],
+ };
+ gen_print_group(stderr, group, gtt_offset + offset, &reader, color);
}
}
@@ -468,7 +474,11 @@ do_batch_dump(struct brw_context *brw)
fprintf(stderr, "%s0x%08"PRIx64": 0x%08x: %-80s%s\n", header_color,
offset, p[0], gen_group_get_name(inst), reset_color);
- gen_print_group(stderr, inst, offset, p, color);
+ struct gen_dword_reader reader = {
+ .read = gen_read_dword_from_pointer,
+ .user_data = p,
+ };
+ gen_print_group(stderr, inst, offset, &reader, color);
switch (gen_group_get_opcode(inst) >> 16) {
case _3DSTATE_PIPELINED_POINTERS:
@@ -509,8 +519,12 @@ do_batch_dump(struct brw_context *brw)
uint32_t *bt_pointers = &state[bt_offset / 4];
for (int i = 0; i < bt_entries; i++) {
fprintf(stderr, "SURFACE_STATE - BTI = %d\n", i);
+ struct gen_dword_reader reader = {
+ .read = gen_read_dword_from_pointer,
+ .user_data = &state[bt_pointers[i] / 4],
+ };
gen_print_group(stderr, group, state_gtt_offset + bt_pointers[i],
- &state[bt_pointers[i] / 4], color);
+ &reader, color);
}
break;
}
--
2.15.0
More information about the mesa-dev
mailing list