panfrost: Add some debug utility methods for resources

Add a method to dump a specific superblock given its index (header
and few first bytes from the body) and a method to dump a resource
to a ppm file.

Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25012>
This commit is contained in:
Louis-Francis Ratté-Boulianne 2023-09-01 13:34:28 -04:00 committed by Marge Bot
parent 33b48a5585
commit 888d7c8ee6
2 changed files with 118 additions and 0 deletions

View file

@ -37,6 +37,7 @@
#include "frontend/winsys_handle.h"
#include "util/format/u_format.h"
#include "util/u_debug_image.h"
#include "util/u_drm.h"
#include "util/u_gen_mipmap.h"
#include "util/u_memory.h"
@ -920,6 +921,121 @@ panfrost_load_tiled_images(struct panfrost_transfer *transfer,
}
}
#ifdef DEBUG
static unsigned
get_superblock_size(uint32_t *hdr, unsigned uncompressed_size)
{
/* AFBC superblock layout 0 */
unsigned body_base_ptr_len = 32;
unsigned nr_subblocks = 16;
unsigned sz_len = 6; /* bits */
unsigned mask = (1 << sz_len) - 1;
unsigned size = 0;
/* Sum up all of the subblock sizes */
for (int i = 0; i < nr_subblocks; i++) {
unsigned bitoffset = body_base_ptr_len + (i * sz_len);
unsigned start = bitoffset / 32;
unsigned end = (bitoffset + (sz_len - 1)) / 32;
unsigned offset = bitoffset % 32;
unsigned subblock_size;
if (start != end)
subblock_size = (hdr[start] >> offset) | (hdr[end] << (32 - offset));
else
subblock_size = hdr[start] >> offset;
subblock_size = (subblock_size == 1) ? uncompressed_size : subblock_size;
size += subblock_size & mask;
if (i == 0 && size == 0)
return 0;
}
return size;
}
static void
dump_block(struct panfrost_resource *rsrc, uint32_t idx)
{
panfrost_bo_wait(rsrc->image.data.bo, INT64_MAX, false);
uint8_t *ptr = rsrc->image.data.bo->ptr.cpu;
uint32_t *header = (uint32_t *)(ptr + (idx * AFBC_HEADER_BYTES_PER_TILE));
uint32_t body_base_ptr = header[0];
uint32_t *body = (uint32_t *)(ptr + body_base_ptr);
struct pan_block_size block_sz =
panfrost_afbc_subblock_size(rsrc->image.layout.modifier);
unsigned pixel_sz = util_format_get_blocksize(rsrc->base.format);
unsigned uncompressed_size = pixel_sz * block_sz.width * block_sz.height;
unsigned size = get_superblock_size(header, uncompressed_size);
fprintf(stderr, " Header: %08x %08x %08x %08x (size: %u bytes)\n",
header[0], header[1], header[2], header[3], size);
if (size > 0) {
fprintf(stderr, " Body: %08x %08x %08x %08x\n", body[0], body[1],
body[2], body[3]);
} else {
uint8_t *comp = (uint8_t *)(header + 2);
fprintf(stderr, " Color: 0x%02x%02x%02x%02x\n", comp[0], comp[1],
comp[2], comp[3]);
}
fprintf(stderr, "\n");
}
void
pan_dump_resource(struct panfrost_context *ctx, struct panfrost_resource *rsc)
{
struct pipe_context *pctx = &ctx->base;
struct pipe_resource tmpl = rsc->base;
struct pipe_resource *plinear = NULL;
struct panfrost_resource *linear = rsc;
struct pipe_blit_info blit = {0};
struct pipe_box box;
char buffer[1024];
if (rsc->image.layout.modifier != DRM_FORMAT_MOD_LINEAR) {
tmpl.bind |= PIPE_BIND_LINEAR;
tmpl.bind &= ~PAN_BIND_SHARED_MASK;
plinear = pctx->screen->resource_create(pctx->screen, &tmpl);
u_box_2d(0, 0, rsc->base.width0, rsc->base.height0, &box);
blit.src.resource = &rsc->base;
blit.src.format = rsc->base.format;
blit.src.level = 0;
blit.src.box = box;
blit.dst.resource = plinear;
blit.dst.format = rsc->base.format;
blit.dst.level = 0;
blit.dst.box = box;
blit.mask = util_format_get_mask(blit.dst.format);
blit.filter = PIPE_TEX_FILTER_NEAREST;
panfrost_blit(pctx, &blit);
linear = pan_resource(plinear);
}
panfrost_flush_writer(ctx, linear, "dump image");
panfrost_bo_wait(linear->image.data.bo, INT64_MAX, false);
panfrost_bo_mmap(linear->image.data.bo);
static unsigned frame_count = 0;
frame_count++;
snprintf(buffer, sizeof(buffer), "dump_image.%04d", frame_count);
debug_dump_image(buffer, rsc->base.format, 0 /* UNUSED */, rsc->base.width0,
rsc->base.height0,
linear->image.layout.slices[0].row_stride,
linear->image.data.bo->ptr.cpu);
if (plinear)
pipe_resource_reference(&plinear, NULL);
}
#endif
/* Get scan-order index from (x, y) position when blocks are
* arranged in z-order in 8x8 tiles */
static unsigned

View file

@ -194,5 +194,7 @@ void pan_resource_modifier_convert(struct panfrost_context *ctx,
void pan_legalize_afbc_format(struct panfrost_context *ctx,
struct panfrost_resource *rsrc,
enum pipe_format format, bool write);
void pan_dump_resource(struct panfrost_context *ctx,
struct panfrost_resource *rsc);
#endif /* PAN_RESOURCE_H */