diff --git a/src/imagination/common/pvr_dump.c b/src/imagination/common/pvr_dump.c index 2ccc71e2bda..bb684ad8db2 100644 --- a/src/imagination/common/pvr_dump.c +++ b/src/imagination/common/pvr_dump.c @@ -23,10 +23,12 @@ #include #include +#include #include #include "pvr_dump.h" #include "pvr_util.h" +#include "util/u_math.h" const struct pvr_dump_ctx __pvr_dump_ctx_invalid = { .active_child = &__pvr_dump_ctx_invalid, @@ -37,56 +39,51 @@ const struct pvr_dump_ctx __pvr_dump_ctx_invalid = { *****************************************************************************/ #define HEX_WORD_SIZE ((unsigned)sizeof(uint32_t)) -#define HEX_WORD_FMT "%08" PRIx32 +#define HEX_BYTE_FMT "%02" PRIx8 /* This must be even, and should probably always be a power of 2. */ -#define HEX_LINE_SIZE UINT32_C(8) +#define HEX_LINE_SIZE (HEX_WORD_SIZE * 8) struct pvr_dump_hex_ctx { struct pvr_dump_ctx base; - const uint32_t *start_ptr; - const uint32_t *end_ptr; - - uint64_t nr_words; + const uint8_t *start_ptr; + const uint8_t *end_ptr; + uint64_t nr_bytes; uint32_t offset_digits; /* User-modifiable values */ - const uint32_t *line_ptr; + const uint8_t *line_ptr; - uint32_t prev_non_zero_trailing_zero_words; + uint32_t prev_non_zero_trailing_zero_bytes; uint64_t prev_non_zero_leading_zero_lines; - const uint32_t *prev_non_zero_line; + const uint8_t *prev_non_zero_line; uint64_t zero_lines; }; static bool pvr_dump_hex_ctx_push(struct pvr_dump_hex_ctx *const ctx, struct pvr_dump_buffer_ctx *const parent_ctx, - const uint64_t nr_words) + const uint64_t nr_bytes) { - const uint64_t real_nr_words = - nr_words ? nr_words : parent_ctx->remaining_size / HEX_WORD_SIZE; - const uint64_t nr_bytes = real_nr_words * HEX_WORD_SIZE; + const uint64_t real_nr_bytes = nr_bytes ? nr_bytes + : parent_ctx->remaining_size; bool ret; - if (parent_ctx->remaining_size < nr_bytes || - (!nr_words && nr_bytes != parent_ctx->remaining_size) || - !ptr_is_aligned(parent_ctx->ptr, HEX_WORD_SIZE)) { + if (parent_ctx->remaining_size < nr_bytes) return false; - } ret = pvr_dump_ctx_push(&ctx->base, &parent_ctx->base); if (!ret) return false; ctx->start_ptr = parent_ctx->ptr; - ctx->end_ptr = ctx->start_ptr + real_nr_words; - ctx->nr_words = real_nr_words; - ctx->offset_digits = u64_hex_digits(nr_bytes); + ctx->end_ptr = ctx->start_ptr + real_nr_bytes; + ctx->nr_bytes = real_nr_bytes; + ctx->offset_digits = u64_hex_digits(real_nr_bytes); ctx->line_ptr = ctx->start_ptr; - ctx->prev_non_zero_trailing_zero_words = 0; + ctx->prev_non_zero_trailing_zero_bytes = 0; ctx->prev_non_zero_leading_zero_lines = 0; ctx->prev_non_zero_line = NULL; ctx->zero_lines = 0; @@ -111,7 +108,7 @@ pvr_dump_hex_ctx_pop(struct pvr_dump_hex_ctx *const ctx) parent = container_of(parent_base, struct pvr_dump_buffer_ctx, base); - pvr_dump_buffer_advance(parent, ctx->nr_words * HEX_WORD_SIZE); + pvr_dump_buffer_advance(parent, ctx->nr_bytes); return parent; } @@ -122,7 +119,7 @@ static inline void pvr_dump_hex_print_prefix(const struct pvr_dump_hex_ctx *ctx, pvr_dump_printf(&ctx->base, PVR_DUMP_OFFSET_PREFIX, ctx->offset_digits, - offset * HEX_WORD_SIZE); + offset); } #define pvr_dump_hex_println(ctx, offset, format, args...) \ @@ -130,31 +127,62 @@ static inline void pvr_dump_hex_print_prefix(const struct pvr_dump_hex_ctx *ctx, PVR_DUMP_OFFSET_PREFIX format, \ (ctx)->offset_digits, \ offset, \ - ##args); + ##args) #define pvr_dump_hex_println_no_prefix(ctx, format, args...) \ pvr_dump_println(&(ctx)->base, \ "%*c" format, \ (ctx)->offset_digits + 3, \ ' ', \ - ##args); + ##args) + +static void pvr_dump_hex_print_line(const struct pvr_dump_hex_ctx *ctx, + const uint8_t *const line_ptr, + const uint32_t truncate) +{ + const uint32_t nr_bytes = + MIN2(HEX_LINE_SIZE - truncate, ctx->end_ptr - line_ptr); + + pvr_dump_hex_print_prefix(ctx, line_ptr - ctx->start_ptr); + + for (uint32_t i = 0; i < nr_bytes; i++) { + if (i == HEX_LINE_SIZE / 2) + pvr_dump_printf_cont(&ctx->base, " "); + + if (i % HEX_WORD_SIZE == 0) + pvr_dump_printf_cont(&ctx->base, " "); + + if (line_ptr[i]) + pvr_dump_printf_cont(&ctx->base, HEX_BYTE_FMT, line_ptr[i]); + else + pvr_dump_printf_cont(&ctx->base, ".."); + } + + pvr_dump_print_eol(&ctx->base); +} static void pvr_dump_hex_print_zero_lines(const struct pvr_dump_hex_ctx *const ctx, const uint64_t zero_lines) { - const uint64_t zero_words = zero_lines * HEX_LINE_SIZE; - const uint64_t zero_bytes = zero_words * HEX_WORD_SIZE; + const uint64_t zero_bytes = zero_lines * HEX_LINE_SIZE; - if (zero_lines == 0) + if (!zero_lines) return; + /* If we've only buffered a single zero line, print it normally. We don't + * save any space by folding it, and it's more readable this way. + */ + if (zero_lines == 1) { + pvr_dump_hex_print_line(ctx, ctx->prev_non_zero_line + HEX_LINE_SIZE, 0); + return; + } + pvr_dump_hex_println_no_prefix(ctx, " + %" PRIu64 " zero line%s (%" PRIu64 - " words; %" PRIu64 "/0x%" PRIx64 " bytes)", + "/0x%" PRIx64 " bytes)", zero_lines, zero_lines == 1 ? "" : "s", - zero_words, zero_bytes, zero_bytes); } @@ -162,11 +190,10 @@ pvr_dump_hex_print_zero_lines(const struct pvr_dump_hex_ctx *const ctx, static void pvr_dump_hex_print_trailing_zeroes(const struct pvr_dump_hex_ctx *const ctx) { - const uint64_t zero_words = - ctx->zero_lines * HEX_LINE_SIZE + ctx->prev_non_zero_trailing_zero_words; - const uint64_t zero_bytes = zero_words * HEX_WORD_SIZE; + const uint64_t zero_bytes = + ctx->zero_lines * HEX_LINE_SIZE + ctx->prev_non_zero_trailing_zero_bytes; - if (!ctx->prev_non_zero_trailing_zero_words) + if (!ctx->prev_non_zero_trailing_zero_bytes) return pvr_dump_hex_print_zero_lines(ctx, ctx->zero_lines); if (!ctx->zero_lines) @@ -174,46 +201,29 @@ pvr_dump_hex_print_trailing_zeroes(const struct pvr_dump_hex_ctx *const ctx) pvr_dump_hex_println_no_prefix(ctx, " + %" PRIu64 "+%" PRIu32 - " zero lines (%" PRIu64 " words; %" PRIu64 - "/0x%" PRIx64 " bytes)", + " zero lines (%" PRIu64 "/0x%" PRIx64 + " bytes)", ctx->zero_lines, - ctx->prev_non_zero_trailing_zero_words, - zero_words, + ctx->prev_non_zero_trailing_zero_bytes, zero_bytes, zero_bytes); } -static void pvr_dump_hex_print_line(struct pvr_dump_hex_ctx *ctx, - const uint32_t *const line_ptr, - const uint32_t truncate) +static void pvr_dump_hex_process_line(struct pvr_dump_hex_ctx *const ctx, + uint32_t truncate) { - const uint32_t nr_words = - MIN2(HEX_LINE_SIZE - truncate, ctx->end_ptr - line_ptr); + const uint32_t max_bytes = HEX_LINE_SIZE - truncate; - pvr_dump_hex_print_prefix(ctx, line_ptr - ctx->start_ptr); + uint32_t trailing_zero_bytes = max_bytes; - for (uint32_t i = 0; i < nr_words; i++) { - if (i == HEX_LINE_SIZE / 2) - pvr_dump_printf_cont(&ctx->base, " "); - - pvr_dump_printf_cont(&ctx->base, " " HEX_WORD_FMT, line_ptr[i]); - } - - pvr_dump_print_eol(&ctx->base); -} - -static void pvr_dump_hex_process_line(struct pvr_dump_hex_ctx *const ctx) -{ - uint32_t trailing_zero_words = HEX_LINE_SIZE; - - for (uint32_t i = HEX_LINE_SIZE; i > 0; i--) { + for (uint32_t i = max_bytes; i > 0; i--) { if (ctx->line_ptr[i - 1]) { - trailing_zero_words = HEX_LINE_SIZE - i; + trailing_zero_bytes = HEX_LINE_SIZE - i; break; } } - if (trailing_zero_words == HEX_LINE_SIZE) { + if (trailing_zero_bytes == max_bytes) { /* No non-zero words were found in this line; mark it and move on. */ ctx->zero_lines++; return; @@ -225,7 +235,7 @@ static void pvr_dump_hex_process_line(struct pvr_dump_hex_ctx *const ctx) */ if (ctx->prev_non_zero_line) { pvr_dump_hex_print_zero_lines(ctx, ctx->prev_non_zero_leading_zero_lines); - pvr_dump_hex_print_line(ctx, ctx->prev_non_zero_line, 0); + pvr_dump_hex_print_line(ctx, ctx->prev_non_zero_line, truncate); } /* Now we store the current non-zero line for printing later. This way we @@ -233,25 +243,38 @@ static void pvr_dump_hex_process_line(struct pvr_dump_hex_ctx *const ctx) */ ctx->prev_non_zero_line = ctx->line_ptr; ctx->prev_non_zero_leading_zero_lines = ctx->zero_lines; - ctx->prev_non_zero_trailing_zero_words = trailing_zero_words; + ctx->prev_non_zero_trailing_zero_bytes = trailing_zero_bytes; ctx->zero_lines = 0; } static void pvr_dump_hex(struct pvr_dump_hex_ctx *const ctx) { - while (ctx->end_ptr - ctx->line_ptr > 0) { - pvr_dump_hex_process_line(ctx); + while (ctx->line_ptr < (ctx->end_ptr - HEX_LINE_SIZE)) { + pvr_dump_hex_process_line(ctx, 0); ctx->line_ptr += HEX_LINE_SIZE; } - if (ctx->prev_non_zero_line) { - pvr_dump_hex_print_zero_lines(ctx, ctx->prev_non_zero_leading_zero_lines); - pvr_dump_hex_print_line(ctx, - ctx->prev_non_zero_line, - ctx->prev_non_zero_trailing_zero_words); + pvr_dump_hex_process_line(ctx, + HEX_LINE_SIZE - (ctx->end_ptr - ctx->line_ptr)); + ctx->line_ptr = ctx->end_ptr; - /* Collapse and print any trailing zeroes. */ - pvr_dump_hex_print_trailing_zeroes(ctx); + if (ctx->prev_non_zero_line) { + /* If we don't have any zero lines to collapse, print the trailing zeroes + * on the last line. + */ + if (!ctx->zero_lines) { + pvr_dump_hex_print_line(ctx, ctx->prev_non_zero_line, 0); + } else { + pvr_dump_hex_print_zero_lines(ctx, + ctx->prev_non_zero_leading_zero_lines); + + pvr_dump_hex_print_line(ctx, + ctx->prev_non_zero_line, + ctx->prev_non_zero_trailing_zero_bytes); + + /* Collapse and print any trailing zeroes. */ + pvr_dump_hex_print_trailing_zeroes(ctx); + } } else { /* We made it to the end of the buffer without ever encountering a * non-zero word. Make this known. @@ -259,15 +282,15 @@ static void pvr_dump_hex(struct pvr_dump_hex_ctx *const ctx) pvr_dump_hex_println(ctx, UINT64_C(0), " "); } - pvr_dump_hex_println(ctx, ctx->nr_words, " "); + pvr_dump_hex_println(ctx, ctx->nr_bytes, " "); } bool pvr_dump_buffer_hex(struct pvr_dump_buffer_ctx *const ctx, - const uint64_t nr_words) + const uint64_t nr_bytes) { struct pvr_dump_hex_ctx hex_ctx; - if (!pvr_dump_hex_ctx_push(&hex_ctx, ctx, nr_words)) + if (!pvr_dump_hex_ctx_push(&hex_ctx, ctx, nr_bytes)) return false; pvr_dump_hex(&hex_ctx); diff --git a/src/imagination/common/pvr_dump.h b/src/imagination/common/pvr_dump.h index dcd704344df..de2f68a74d9 100644 --- a/src/imagination/common/pvr_dump.h +++ b/src/imagination/common/pvr_dump.h @@ -287,7 +287,7 @@ pvr_dump_buffer_ctx_pop(struct pvr_dump_buffer_ctx *const ctx) return pvr_dump_ctx_pop(&ctx->base); } -bool pvr_dump_buffer_hex(struct pvr_dump_buffer_ctx *ctx, uint64_t nr_words); +bool pvr_dump_buffer_hex(struct pvr_dump_buffer_ctx *ctx, uint64_t nr_bytes); static inline void __pvr_dump_buffer_advance(struct pvr_dump_buffer_ctx *ctx, const uint64_t nr_bytes) diff --git a/src/imagination/vulkan/pvr_dump_csb.c b/src/imagination/vulkan/pvr_dump_csb.c index 5527a95c4ea..f45eb3f6827 100644 --- a/src/imagination/vulkan/pvr_dump_csb.c +++ b/src/imagination/vulkan/pvr_dump_csb.c @@ -452,7 +452,7 @@ print_block_vdmctrl_ppp_state_update(struct pvr_dump_csb_ctx *const csb_ctx, device, BUFFER_TYPE_PPP, ppp_addr, - ppp_size, + ppp_size * PVR_DUMP_CSB_WORD_SIZE, "word_count"); end_pop_ctx: @@ -1882,28 +1882,23 @@ static bool print_sub_buffer(struct pvr_dump_ctx *const ctx, if (!expected_size) { pvr_dump_field(base_ctx, "", - "%" PRIu64 " words (%" PRIu64 " bytes) mapped", - real_size, - real_size * PVR_DUMP_CSB_WORD_SIZE); + "%" PRIu64 " bytes mapped", + real_size); } else if (expected_size > real_size) { pvr_dump_field(base_ctx, "", - "%" PRIu64 " (%" PRIu64 " bytes) mapped, expected %" PRIu64 - " (%" PRIu64 " bytes) from %s", + "%" PRIu64 " bytes mapped, expected %" PRIu64 + " bytes (from %s)", real_size, - real_size * PVR_DUMP_CSB_WORD_SIZE, expected_size, - expected_size * PVR_DUMP_CSB_WORD_SIZE, size_src); } else { pvr_dump_field(base_ctx, "", - "%" PRIu64 " (%" PRIu64 " bytes; from %s)", + "%" PRIu64 " bytes (from %s)", expected_size, - expected_size * PVR_DUMP_CSB_WORD_SIZE, size_src); - pvr_dump_buffer_truncate(&sub_ctx.base, - expected_size * PVR_DUMP_CSB_WORD_SIZE); + pvr_dump_buffer_truncate(&sub_ctx.base, expected_size); } if (sub_ctx.bo_mapped_in_ctx)