diff options
author | Jason Ekstrand <[email protected]> | 2017-12-13 09:19:57 -0800 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2017-12-14 13:27:13 -0800 |
commit | d4081fb778e2bb0e6189d828962e28adeeb4bf46 (patch) | |
tree | e91c0145805163e1a6490765940b68f455d7b53d | |
parent | e27ec208ed282998390496034f923d45750ff012 (diff) |
intel/batch-decoder: Decode vertex and index buffers
Reviewed-by: Lionel Landwerlin <[email protected]>
-rw-r--r-- | src/intel/common/gen_decoder.h | 2 | ||||
-rw-r--r-- | src/intel/tools/gen_batch_decoder.c | 159 |
2 files changed, 161 insertions, 0 deletions
diff --git a/src/intel/common/gen_decoder.h b/src/intel/common/gen_decoder.h index b188787a76f..ff388700287 100644 --- a/src/intel/common/gen_decoder.h +++ b/src/intel/common/gen_decoder.h @@ -191,6 +191,8 @@ enum gen_batch_decode_flags { GEN_BATCH_DECODE_FULL = (1 << 1), /** Print offsets along with the batch */ GEN_BATCH_DECODE_OFFSETS = (1 << 2), + /** Guess when a value is a float and print it as such */ + GEN_BATCH_DECODE_FLOATS = (1 << 3), }; struct gen_batch_decode_bo { diff --git a/src/intel/tools/gen_batch_decoder.c b/src/intel/tools/gen_batch_decoder.c index f7a30b9f560..eb7d90c91f2 100644 --- a/src/intel/tools/gen_batch_decoder.c +++ b/src/intel/tools/gen_batch_decoder.c @@ -115,6 +115,57 @@ ctx_disassemble_program(struct gen_batch_decode_ctx *ctx, ctx->fp); } +/* Heuristic to determine whether a uint32_t is probably actually a float + * (http://stackoverflow.com/a/2953466) + */ + +static bool +probably_float(uint32_t bits) +{ + int exp = ((bits & 0x7f800000U) >> 23) - 127; + uint32_t mant = bits & 0x007fffff; + + /* +- 0.0 */ + if (exp == -127 && mant == 0) + return true; + + /* +- 1 billionth to 1 billion */ + if (-30 <= exp && exp <= 30) + return true; + + /* some value with only a few binary digits */ + if ((mant & 0x0000ffff) == 0) + return true; + + return false; +} + +static void +ctx_print_buffer(struct gen_batch_decode_ctx *ctx, + struct gen_batch_decode_bo bo, + uint32_t read_length, + uint32_t pitch) +{ + const uint32_t *dw_end = bo.map + MIN2(bo.size, read_length); + + unsigned line_count = 0; + for (const uint32_t *dw = bo.map; dw < dw_end; dw++) { + if (line_count * 4 == pitch || line_count == 8) { + fprintf(ctx->fp, "\n"); + line_count = 0; + } + fprintf(ctx->fp, line_count == 0 ? " " : " "); + + if ((ctx->flags & GEN_BATCH_DECODE_FLOATS) && probably_float(*dw)) + fprintf(ctx->fp, " %8.2f", *(float *) dw); + else + fprintf(ctx->fp, " 0x%08x", *dw); + + line_count++; + } + fprintf(ctx->fp, "\n"); +} + static void handle_state_base_address(struct gen_batch_decode_ctx *ctx, const uint32_t *p) { @@ -265,12 +316,120 @@ handle_media_interface_descriptor_load(struct gen_batch_decode_ctx *ctx, } } +static void +handle_3dstate_vertex_buffers(struct gen_batch_decode_ctx *ctx, + const uint32_t *p) +{ + struct gen_group *inst = gen_spec_find_instruction(ctx->spec, p); + + struct gen_batch_decode_bo vb = {}; + uint32_t vb_size = 0; + int index = -1; + int pitch = -1; + bool ready = false; + + struct gen_field_iterator iter; + gen_field_iterator_init(&iter, inst, p, 0, false); + do { + if (strcmp(iter.name, "Vertex Buffer Index") == 0) { + index = iter.raw_value; + } else if (strcmp(iter.name, "Buffer Pitch") == 0) { + pitch = iter.raw_value; + } else if (strcmp(iter.name, "Buffer Starting Address") == 0) { + vb = ctx_get_bo(ctx, iter.raw_value); + } else if (strcmp(iter.name, "Buffer Size") == 0) { + vb_size = iter.raw_value; + ready = true; + } else if (strcmp(iter.name, "End Address") == 0) { + if (vb.map && iter.raw_value >= vb.addr) + vb_size = iter.raw_value - vb.addr; + else + vb_size = 0; + ready = true; + } + + if (!ready) + continue; + + fprintf(ctx->fp, "vertex buffer %d, size %d\n", index, vb_size); + + if (vb.map == NULL) { + fprintf(ctx->fp, " buffer contents unavailable\n"); + continue; + } + + if (vb.map == 0 || vb_size == 0) + continue; + + ctx_print_buffer(ctx, vb, vb_size, pitch); + + vb.map = NULL; + vb_size = 0; + index = -1; + pitch = -1; + ready = false; + } while (gen_field_iterator_next(&iter)); +} + +static void +handle_3dstate_index_buffer(struct gen_batch_decode_ctx *ctx, + const uint32_t *p) +{ + struct gen_group *inst = gen_spec_find_instruction(ctx->spec, p); + + struct gen_batch_decode_bo ib = {}; + uint32_t ib_size = 0; + uint32_t format = 0; + + struct gen_field_iterator iter; + gen_field_iterator_init(&iter, inst, p, 0, false); + do { + if (strcmp(iter.name, "Index Format") == 0) { + format = iter.raw_value; + } else if (strcmp(iter.name, "Buffer Starting Address") == 0) { + ib = ctx_get_bo(ctx, iter.raw_value); + } else if (strcmp(iter.name, "Buffer Size") == 0) { + ib_size = iter.raw_value; + } + } while (gen_field_iterator_next(&iter)); + + if (ib.map == NULL) { + fprintf(ctx->fp, " buffer contents unavailable\n"); + return; + } + + const void *m = ib.map; + const void *ib_end = ib.map + MIN2(ib.size, ib_size); + for (int i = 0; m < ib_end && i < 10; i++) { + switch (format) { + case 0: + fprintf(ctx->fp, "%3d ", *(uint8_t *)m); + m += 1; + break; + case 1: + fprintf(ctx->fp, "%3d ", *(uint16_t *)m); + m += 2; + break; + case 2: + fprintf(ctx->fp, "%3d ", *(uint32_t *)m); + m += 4; + break; + } + } + + if (m < ib_end) + fprintf(ctx->fp, "..."); + fprintf(ctx->fp, "\n"); +} + struct custom_decoder { const char *cmd_name; void (*decode)(struct gen_batch_decode_ctx *ctx, const uint32_t *p); } custom_decoders[] = { { "STATE_BASE_ADDRESS", handle_state_base_address }, { "MEDIA_INTERFACE_DESCRIPTOR_LOAD", handle_media_interface_descriptor_load }, + { "3DSTATE_VERTEX_BUFFERS", handle_3dstate_vertex_buffers }, + { "3DSTATE_INDEX_BUFFER", handle_3dstate_index_buffer }, }; static inline uint64_t |