mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 08:50:13 +01:00
pan/decode: handle more than one panfrost_device
Before this commit, if an application tried to create more than one panfrost_device, such as piglit's "ext_image_dma_buf_import" tests, it would result in a crash when running with PAN_MESA_DEBUG=sync or PAN_MESA_DEBUG=trace. This commit fixes that by introducing a pandecode_context, which encapsulates all the information that is being tracked, and thus avoiding memory conflicts. Signed-off-by: Italo Nicola <italonicola@collabora.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24144>
This commit is contained in:
parent
cea0cc5b16
commit
56be9a55be
14 changed files with 732 additions and 630 deletions
|
|
@ -114,7 +114,7 @@ panfrost_flush(struct pipe_context *pipe, struct pipe_fence_handle **fence,
|
|||
}
|
||||
|
||||
if (dev->debug & PAN_DBG_TRACE)
|
||||
pandecode_next_frame();
|
||||
pandecode_next_frame(dev->decode_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -685,14 +685,14 @@ panfrost_batch_submit_ioctl(struct panfrost_batch *batch,
|
|||
drmSyncobjWait(dev->fd, &out_sync, 1, INT64_MAX, 0, NULL);
|
||||
|
||||
if (dev->debug & PAN_DBG_TRACE)
|
||||
pandecode_jc(submit.jc, dev->gpu_id);
|
||||
pandecode_jc(dev->decode_ctx, submit.jc, dev->gpu_id);
|
||||
|
||||
if (dev->debug & PAN_DBG_DUMP)
|
||||
pandecode_dump_mappings();
|
||||
pandecode_dump_mappings(dev->decode_ctx);
|
||||
|
||||
/* Jobs won't be complete if blackhole rendering, that's ok */
|
||||
if (!ctx->is_noop && dev->debug & PAN_DBG_SYNC)
|
||||
pandecode_abort_on_fault(submit.jc, dev->gpu_id);
|
||||
pandecode_abort_on_fault(dev->decode_ctx, submit.jc, dev->gpu_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1004,7 +1004,8 @@ panfrost_ptr_map(struct pipe_context *pctx, struct pipe_resource *resource,
|
|||
panfrost_bo_mmap(bo);
|
||||
|
||||
if (dev->debug & (PAN_DBG_TRACE | PAN_DBG_SYNC))
|
||||
pandecode_inject_mmap(bo->ptr.gpu, bo->ptr.cpu, bo->size, NULL);
|
||||
pandecode_inject_mmap(dev->decode_ctx, bo->ptr.gpu, bo->ptr.cpu, bo->size,
|
||||
NULL);
|
||||
|
||||
/* Upgrade writes to uninitialized ranges to UNSYNCHRONIZED */
|
||||
if ((usage & PIPE_MAP_WRITE) && resource->target == PIPE_BUFFER &&
|
||||
|
|
|
|||
|
|
@ -45,11 +45,12 @@
|
|||
* larger FBD */
|
||||
|
||||
static void
|
||||
pandecode_midgard_tiler_descriptor(const struct mali_tiler_context_packed *tp,
|
||||
pandecode_midgard_tiler_descriptor(struct pandecode_context *ctx,
|
||||
const struct mali_tiler_context_packed *tp,
|
||||
const struct mali_tiler_weights_packed *wp)
|
||||
{
|
||||
pan_unpack(tp, TILER_CONTEXT, t);
|
||||
DUMP_UNPACKED(TILER_CONTEXT, t, "Tiler:\n");
|
||||
DUMP_UNPACKED(ctx, TILER_CONTEXT, t, "Tiler:\n");
|
||||
|
||||
/* We've never seen weights used in practice, but they exist */
|
||||
pan_unpack(wp, TILER_WEIGHTS, w);
|
||||
|
|
@ -65,55 +66,58 @@ pandecode_midgard_tiler_descriptor(const struct mali_tiler_context_packed *tp,
|
|||
nonzero_weights |= w.weight7 != 0x0;
|
||||
|
||||
if (nonzero_weights)
|
||||
DUMP_UNPACKED(TILER_WEIGHTS, w, "Tiler Weights:\n");
|
||||
DUMP_UNPACKED(ctx, TILER_WEIGHTS, w, "Tiler Weights:\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PAN_ARCH >= 5
|
||||
static void
|
||||
pandecode_render_target(uint64_t gpu_va, unsigned gpu_id,
|
||||
pandecode_render_target(struct pandecode_context *ctx, uint64_t gpu_va,
|
||||
unsigned gpu_id,
|
||||
const struct MALI_FRAMEBUFFER_PARAMETERS *fb)
|
||||
{
|
||||
pandecode_log("Color Render Targets @%" PRIx64 ":\n", gpu_va);
|
||||
pandecode_indent++;
|
||||
pandecode_log(ctx, "Color Render Targets @%" PRIx64 ":\n", gpu_va);
|
||||
ctx->indent++;
|
||||
|
||||
for (int i = 0; i < (fb->render_target_count); i++) {
|
||||
mali_ptr rt_va = gpu_va + i * pan_size(RENDER_TARGET);
|
||||
const struct mali_render_target_packed *PANDECODE_PTR_VAR(
|
||||
rtp, (mali_ptr)rt_va);
|
||||
DUMP_CL(RENDER_TARGET, rtp, "Color Render Target %d:\n", i);
|
||||
ctx, rtp, (mali_ptr)rt_va);
|
||||
DUMP_CL(ctx, RENDER_TARGET, rtp, "Color Render Target %d:\n", i);
|
||||
}
|
||||
|
||||
pandecode_indent--;
|
||||
pandecode_log("\n");
|
||||
ctx->indent--;
|
||||
pandecode_log(ctx, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PAN_ARCH >= 6
|
||||
static void
|
||||
pandecode_sample_locations(const void *fb)
|
||||
pandecode_sample_locations(struct pandecode_context *ctx, const void *fb)
|
||||
{
|
||||
pan_section_unpack(fb, FRAMEBUFFER, PARAMETERS, params);
|
||||
|
||||
const u16 *PANDECODE_PTR_VAR(samples, params.sample_locations);
|
||||
const u16 *PANDECODE_PTR_VAR(ctx, samples, params.sample_locations);
|
||||
|
||||
pandecode_log("Sample locations @%" PRIx64 ":\n", params.sample_locations);
|
||||
pandecode_log(ctx, "Sample locations @%" PRIx64 ":\n",
|
||||
params.sample_locations);
|
||||
for (int i = 0; i < 33; i++) {
|
||||
pandecode_log(" (%d, %d),\n", samples[2 * i] - 128,
|
||||
pandecode_log(ctx, " (%d, %d),\n", samples[2 * i] - 128,
|
||||
samples[2 * i + 1] - 128);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct pandecode_fbd
|
||||
GENX(pandecode_fbd)(uint64_t gpu_va, bool is_fragment, unsigned gpu_id)
|
||||
GENX(pandecode_fbd)(struct pandecode_context *ctx, uint64_t gpu_va,
|
||||
bool is_fragment, unsigned gpu_id)
|
||||
{
|
||||
const void *PANDECODE_PTR_VAR(fb, (mali_ptr)gpu_va);
|
||||
const void *PANDECODE_PTR_VAR(ctx, fb, (mali_ptr)gpu_va);
|
||||
pan_section_unpack(fb, FRAMEBUFFER, PARAMETERS, params);
|
||||
DUMP_UNPACKED(FRAMEBUFFER_PARAMETERS, params, "Parameters:\n");
|
||||
DUMP_UNPACKED(ctx, FRAMEBUFFER_PARAMETERS, params, "Parameters:\n");
|
||||
|
||||
#if PAN_ARCH >= 6
|
||||
pandecode_sample_locations(fb);
|
||||
pandecode_sample_locations(ctx, fb);
|
||||
|
||||
unsigned dcd_size = pan_size(DRAW);
|
||||
unsigned job_type_param = 0;
|
||||
|
|
@ -123,64 +127,64 @@ GENX(pandecode_fbd)(uint64_t gpu_va, bool is_fragment, unsigned gpu_id)
|
|||
#endif
|
||||
|
||||
if (params.pre_frame_0 != MALI_PRE_POST_FRAME_SHADER_MODE_NEVER) {
|
||||
const void *PANDECODE_PTR_VAR(dcd,
|
||||
const void *PANDECODE_PTR_VAR(ctx, dcd,
|
||||
params.frame_shader_dcds + (0 * dcd_size));
|
||||
pan_unpack(dcd, DRAW, draw);
|
||||
pandecode_log("Pre frame 0 @%" PRIx64 " (mode=%d):\n",
|
||||
pandecode_log(ctx, "Pre frame 0 @%" PRIx64 " (mode=%d):\n",
|
||||
params.frame_shader_dcds, params.pre_frame_0);
|
||||
GENX(pandecode_dcd)(&draw, job_type_param, gpu_id);
|
||||
GENX(pandecode_dcd)(ctx, &draw, job_type_param, gpu_id);
|
||||
}
|
||||
|
||||
if (params.pre_frame_1 != MALI_PRE_POST_FRAME_SHADER_MODE_NEVER) {
|
||||
const void *PANDECODE_PTR_VAR(dcd,
|
||||
const void *PANDECODE_PTR_VAR(ctx, dcd,
|
||||
params.frame_shader_dcds + (1 * dcd_size));
|
||||
pan_unpack(dcd, DRAW, draw);
|
||||
pandecode_log("Pre frame 1 @%" PRIx64 ":\n",
|
||||
pandecode_log(ctx, "Pre frame 1 @%" PRIx64 ":\n",
|
||||
params.frame_shader_dcds + (1 * dcd_size));
|
||||
GENX(pandecode_dcd)(&draw, job_type_param, gpu_id);
|
||||
GENX(pandecode_dcd)(ctx, &draw, job_type_param, gpu_id);
|
||||
}
|
||||
|
||||
if (params.post_frame != MALI_PRE_POST_FRAME_SHADER_MODE_NEVER) {
|
||||
const void *PANDECODE_PTR_VAR(dcd,
|
||||
const void *PANDECODE_PTR_VAR(ctx, dcd,
|
||||
params.frame_shader_dcds + (2 * dcd_size));
|
||||
pan_unpack(dcd, DRAW, draw);
|
||||
pandecode_log("Post frame:\n");
|
||||
GENX(pandecode_dcd)(&draw, job_type_param, gpu_id);
|
||||
pandecode_log(ctx, "Post frame:\n");
|
||||
GENX(pandecode_dcd)(ctx, &draw, job_type_param, gpu_id);
|
||||
}
|
||||
#else
|
||||
DUMP_SECTION(FRAMEBUFFER, LOCAL_STORAGE, fb, "Local Storage:\n");
|
||||
DUMP_SECTION(ctx, FRAMEBUFFER, LOCAL_STORAGE, fb, "Local Storage:\n");
|
||||
|
||||
const void *t = pan_section_ptr(fb, FRAMEBUFFER, TILER);
|
||||
const void *w = pan_section_ptr(fb, FRAMEBUFFER, TILER_WEIGHTS);
|
||||
pandecode_midgard_tiler_descriptor(t, w);
|
||||
pandecode_midgard_tiler_descriptor(ctx, t, w);
|
||||
#endif
|
||||
|
||||
pandecode_log("Framebuffer @%" PRIx64 ":\n", gpu_va);
|
||||
pandecode_indent++;
|
||||
pandecode_log(ctx, "Framebuffer @%" PRIx64 ":\n", gpu_va);
|
||||
ctx->indent++;
|
||||
|
||||
DUMP_UNPACKED(FRAMEBUFFER_PARAMETERS, params, "Parameters:\n");
|
||||
DUMP_UNPACKED(ctx, FRAMEBUFFER_PARAMETERS, params, "Parameters:\n");
|
||||
#if PAN_ARCH >= 6
|
||||
if (params.tiler)
|
||||
GENX(pandecode_tiler)(params.tiler, gpu_id);
|
||||
GENX(pandecode_tiler)(ctx, params.tiler, gpu_id);
|
||||
#endif
|
||||
|
||||
pandecode_indent--;
|
||||
pandecode_log("\n");
|
||||
ctx->indent--;
|
||||
pandecode_log(ctx, "\n");
|
||||
|
||||
#if PAN_ARCH >= 5
|
||||
gpu_va += pan_size(FRAMEBUFFER);
|
||||
|
||||
if (params.has_zs_crc_extension) {
|
||||
const struct mali_zs_crc_extension_packed *PANDECODE_PTR_VAR(
|
||||
zs_crc, (mali_ptr)gpu_va);
|
||||
DUMP_CL(ZS_CRC_EXTENSION, zs_crc, "ZS CRC Extension:\n");
|
||||
pandecode_log("\n");
|
||||
ctx, zs_crc, (mali_ptr)gpu_va);
|
||||
DUMP_CL(ctx, ZS_CRC_EXTENSION, zs_crc, "ZS CRC Extension:\n");
|
||||
pandecode_log(ctx, "\n");
|
||||
|
||||
gpu_va += pan_size(ZS_CRC_EXTENSION);
|
||||
}
|
||||
|
||||
if (is_fragment)
|
||||
pandecode_render_target(gpu_va, gpu_id, ¶ms);
|
||||
pandecode_render_target(ctx, gpu_va, gpu_id, ¶ms);
|
||||
|
||||
return (struct pandecode_fbd){
|
||||
.rt_count = params.render_target_count,
|
||||
|
|
@ -201,10 +205,11 @@ GENX(pandecode_fbd)(uint64_t gpu_va, bool is_fragment, unsigned gpu_id)
|
|||
|
||||
#if PAN_ARCH >= 5
|
||||
mali_ptr
|
||||
GENX(pandecode_blend)(void *descs, int rt_no, mali_ptr frag_shader)
|
||||
GENX(pandecode_blend)(struct pandecode_context *ctx, void *descs, int rt_no,
|
||||
mali_ptr frag_shader)
|
||||
{
|
||||
pan_unpack(descs + (rt_no * pan_size(BLEND)), BLEND, b);
|
||||
DUMP_UNPACKED(BLEND, b, "Blend RT %d:\n", rt_no);
|
||||
DUMP_UNPACKED(ctx, BLEND, b, "Blend RT %d:\n", rt_no);
|
||||
#if PAN_ARCH >= 6
|
||||
if (b.internal.mode != MALI_BLEND_MODE_SHADER)
|
||||
return 0;
|
||||
|
|
@ -231,7 +236,8 @@ panfrost_is_yuv_format(uint32_t packed)
|
|||
}
|
||||
|
||||
static void
|
||||
pandecode_texture_payload(mali_ptr payload, const struct MALI_TEXTURE *tex)
|
||||
pandecode_texture_payload(struct pandecode_context *ctx, mali_ptr payload,
|
||||
const struct MALI_TEXTURE *tex)
|
||||
{
|
||||
unsigned nr_samples =
|
||||
tex->dimension == MALI_TEXTURE_DIMENSION_3D ? 1 : tex->sample_count;
|
||||
|
|
@ -257,8 +263,8 @@ pandecode_texture_payload(mali_ptr payload, const struct MALI_TEXTURE *tex)
|
|||
#define PANDECODE_EMIT_TEX_PAYLOAD_DESC(T, msg) \
|
||||
for (int i = 0; i < bitmap_count; ++i) { \
|
||||
uint64_t addr = payload + pan_size(T) * i; \
|
||||
pan_unpack(PANDECODE_PTR(addr, void), T, s); \
|
||||
DUMP_UNPACKED(T, s, msg " @%" PRIx64 ":\n", addr) \
|
||||
pan_unpack(PANDECODE_PTR(ctx, addr, void), T, s); \
|
||||
DUMP_UNPACKED(ctx, T, s, msg " @%" PRIx64 ":\n", addr) \
|
||||
}
|
||||
|
||||
#if PAN_ARCH <= 5
|
||||
|
|
@ -277,7 +283,7 @@ pandecode_texture_payload(mali_ptr payload, const struct MALI_TEXTURE *tex)
|
|||
"Surface With Stride");
|
||||
break;
|
||||
default:
|
||||
fprintf(pandecode_dump_stream, "Unknown surface descriptor type %X\n",
|
||||
fprintf(ctx->dump_stream, "Unknown surface descriptor type %X\n",
|
||||
tex->surface_type);
|
||||
break;
|
||||
}
|
||||
|
|
@ -299,25 +305,26 @@ pandecode_texture_payload(mali_ptr payload, const struct MALI_TEXTURE *tex)
|
|||
|
||||
#if PAN_ARCH <= 5
|
||||
void
|
||||
GENX(pandecode_texture)(mali_ptr u, unsigned tex)
|
||||
GENX(pandecode_texture)(struct pandecode_context *ctx, mali_ptr u, unsigned tex)
|
||||
{
|
||||
const uint8_t *cl = pandecode_fetch_gpu_mem(u, pan_size(TEXTURE));
|
||||
const uint8_t *cl = pandecode_fetch_gpu_mem(ctx, u, pan_size(TEXTURE));
|
||||
|
||||
pan_unpack(cl, TEXTURE, temp);
|
||||
DUMP_UNPACKED(TEXTURE, temp, "Texture:\n")
|
||||
DUMP_UNPACKED(ctx, TEXTURE, temp, "Texture:\n")
|
||||
|
||||
pandecode_indent++;
|
||||
pandecode_texture_payload(u + pan_size(TEXTURE), &temp);
|
||||
pandecode_indent--;
|
||||
ctx->indent++;
|
||||
pandecode_texture_payload(ctx, u + pan_size(TEXTURE), &temp);
|
||||
ctx->indent--;
|
||||
}
|
||||
#else
|
||||
void
|
||||
GENX(pandecode_texture)(const void *cl, unsigned tex)
|
||||
GENX(pandecode_texture)(struct pandecode_context *ctx, const void *cl,
|
||||
unsigned tex)
|
||||
{
|
||||
pan_unpack(cl, TEXTURE, temp);
|
||||
DUMP_UNPACKED(TEXTURE, temp, "Texture:\n")
|
||||
DUMP_UNPACKED(ctx, TEXTURE, temp, "Texture:\n")
|
||||
|
||||
pandecode_indent++;
|
||||
ctx->indent++;
|
||||
|
||||
#if PAN_ARCH >= 9
|
||||
int plane_count = temp.levels * temp.array_size;
|
||||
|
|
@ -327,66 +334,70 @@ GENX(pandecode_texture)(const void *cl, unsigned tex)
|
|||
plane_count *= 6;
|
||||
|
||||
for (unsigned i = 0; i < plane_count; ++i)
|
||||
DUMP_ADDR(PLANE, temp.surfaces + i * pan_size(PLANE), "Plane %u:\n", i);
|
||||
DUMP_ADDR(ctx, PLANE, temp.surfaces + i * pan_size(PLANE), "Plane %u:\n",
|
||||
i);
|
||||
#else
|
||||
pandecode_texture_payload(temp.surfaces, &temp);
|
||||
pandecode_texture_payload(ctx, temp.surfaces, &temp);
|
||||
#endif
|
||||
pandecode_indent--;
|
||||
ctx->indent--;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PAN_ARCH >= 6
|
||||
void
|
||||
GENX(pandecode_tiler)(mali_ptr gpu_va, unsigned gpu_id)
|
||||
GENX(pandecode_tiler)(struct pandecode_context *ctx, mali_ptr gpu_va,
|
||||
unsigned gpu_id)
|
||||
{
|
||||
pan_unpack(PANDECODE_PTR(gpu_va, void), TILER_CONTEXT, t);
|
||||
pan_unpack(PANDECODE_PTR(ctx, gpu_va, void), TILER_CONTEXT, t);
|
||||
|
||||
if (t.heap) {
|
||||
pan_unpack(PANDECODE_PTR(t.heap, void), TILER_HEAP, h);
|
||||
DUMP_UNPACKED(TILER_HEAP, h, "Tiler Heap:\n");
|
||||
pan_unpack(PANDECODE_PTR(ctx, t.heap, void), TILER_HEAP, h);
|
||||
DUMP_UNPACKED(ctx, TILER_HEAP, h, "Tiler Heap:\n");
|
||||
}
|
||||
|
||||
DUMP_UNPACKED(TILER_CONTEXT, t, "Tiler Context @%" PRIx64 ":\n", gpu_va);
|
||||
DUMP_UNPACKED(ctx, TILER_CONTEXT, t, "Tiler Context @%" PRIx64 ":\n",
|
||||
gpu_va);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PAN_ARCH >= 9
|
||||
void
|
||||
GENX(pandecode_fau)(mali_ptr addr, unsigned count, const char *name)
|
||||
GENX(pandecode_fau)(struct pandecode_context *ctx, mali_ptr addr,
|
||||
unsigned count, const char *name)
|
||||
{
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
const uint32_t *PANDECODE_PTR_VAR(raw, addr);
|
||||
const uint32_t *PANDECODE_PTR_VAR(ctx, raw, addr);
|
||||
|
||||
pandecode_validate_buffer(addr, count * 8);
|
||||
pandecode_validate_buffer(ctx, addr, count * 8);
|
||||
|
||||
fprintf(pandecode_dump_stream, "%s @%" PRIx64 ":\n", name, addr);
|
||||
fprintf(ctx->dump_stream, "%s @%" PRIx64 ":\n", name, addr);
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
fprintf(pandecode_dump_stream, " %08X %08X\n", raw[2 * i],
|
||||
raw[2 * i + 1]);
|
||||
fprintf(ctx->dump_stream, " %08X %08X\n", raw[2 * i], raw[2 * i + 1]);
|
||||
}
|
||||
fprintf(pandecode_dump_stream, "\n");
|
||||
fprintf(ctx->dump_stream, "\n");
|
||||
}
|
||||
|
||||
mali_ptr
|
||||
GENX(pandecode_shader)(mali_ptr addr, const char *label, unsigned gpu_id)
|
||||
GENX(pandecode_shader)(struct pandecode_context *ctx, mali_ptr addr,
|
||||
const char *label, unsigned gpu_id)
|
||||
{
|
||||
MAP_ADDR(SHADER_PROGRAM, addr, cl);
|
||||
MAP_ADDR(ctx, SHADER_PROGRAM, addr, cl);
|
||||
pan_unpack(cl, SHADER_PROGRAM, desc);
|
||||
|
||||
assert(desc.type == 8);
|
||||
|
||||
DUMP_UNPACKED(SHADER_PROGRAM, desc, "%s Shader @%" PRIx64 ":\n", label,
|
||||
DUMP_UNPACKED(ctx, SHADER_PROGRAM, desc, "%s Shader @%" PRIx64 ":\n", label,
|
||||
addr);
|
||||
pandecode_shader_disassemble(desc.binary, gpu_id);
|
||||
pandecode_shader_disassemble(ctx, desc.binary, gpu_id);
|
||||
return desc.binary;
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_resources(mali_ptr addr, unsigned size)
|
||||
pandecode_resources(struct pandecode_context *ctx, mali_ptr addr, unsigned size)
|
||||
{
|
||||
const uint8_t *cl = pandecode_fetch_gpu_mem(addr, size);
|
||||
const uint8_t *cl = pandecode_fetch_gpu_mem(ctx, addr, size);
|
||||
assert((size % 0x20) == 0);
|
||||
|
||||
for (unsigned i = 0; i < size; i += 0x20) {
|
||||
|
|
@ -394,96 +405,101 @@ pandecode_resources(mali_ptr addr, unsigned size)
|
|||
|
||||
switch (type) {
|
||||
case MALI_DESCRIPTOR_TYPE_SAMPLER:
|
||||
DUMP_CL(SAMPLER, cl + i, "Sampler @%" PRIx64 ":\n", addr + i);
|
||||
DUMP_CL(ctx, SAMPLER, cl + i, "Sampler @%" PRIx64 ":\n", addr + i);
|
||||
break;
|
||||
case MALI_DESCRIPTOR_TYPE_TEXTURE:
|
||||
pandecode_log("Texture @%" PRIx64 "\n", addr + i);
|
||||
GENX(pandecode_texture)(cl + i, i);
|
||||
pandecode_log(ctx, "Texture @%" PRIx64 "\n", addr + i);
|
||||
GENX(pandecode_texture)(ctx, cl + i, i);
|
||||
break;
|
||||
case MALI_DESCRIPTOR_TYPE_ATTRIBUTE:
|
||||
DUMP_CL(ATTRIBUTE, cl + i, "Attribute @%" PRIx64 ":\n", addr + i);
|
||||
DUMP_CL(ctx, ATTRIBUTE, cl + i, "Attribute @%" PRIx64 ":\n", addr + i);
|
||||
break;
|
||||
case MALI_DESCRIPTOR_TYPE_BUFFER:
|
||||
DUMP_CL(BUFFER, cl + i, "Buffer @%" PRIx64 ":\n", addr + i);
|
||||
DUMP_CL(ctx, BUFFER, cl + i, "Buffer @%" PRIx64 ":\n", addr + i);
|
||||
break;
|
||||
default:
|
||||
fprintf(pandecode_dump_stream, "Unknown descriptor type %X\n", type);
|
||||
fprintf(ctx->dump_stream, "Unknown descriptor type %X\n", type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GENX(pandecode_resource_tables)(mali_ptr addr, const char *label)
|
||||
GENX(pandecode_resource_tables)(struct pandecode_context *ctx, mali_ptr addr,
|
||||
const char *label)
|
||||
{
|
||||
unsigned count = addr & 0x3F;
|
||||
addr = addr & ~0x3F;
|
||||
|
||||
const uint8_t *cl =
|
||||
pandecode_fetch_gpu_mem(addr, MALI_RESOURCE_LENGTH * count);
|
||||
pandecode_fetch_gpu_mem(ctx, addr, MALI_RESOURCE_LENGTH * count);
|
||||
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
pan_unpack(cl + i * MALI_RESOURCE_LENGTH, RESOURCE, entry);
|
||||
DUMP_UNPACKED(RESOURCE, entry, "Entry %u @%" PRIx64 ":\n", i,
|
||||
DUMP_UNPACKED(ctx, RESOURCE, entry, "Entry %u @%" PRIx64 ":\n", i,
|
||||
addr + i * MALI_RESOURCE_LENGTH);
|
||||
|
||||
pandecode_indent += 2;
|
||||
ctx->indent += 2;
|
||||
if (entry.address)
|
||||
pandecode_resources(entry.address, entry.size);
|
||||
pandecode_indent -= 2;
|
||||
pandecode_resources(ctx, entry.address, entry.size);
|
||||
ctx->indent -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GENX(pandecode_depth_stencil)(mali_ptr addr)
|
||||
GENX(pandecode_depth_stencil)(struct pandecode_context *ctx, mali_ptr addr)
|
||||
{
|
||||
MAP_ADDR(DEPTH_STENCIL, addr, cl);
|
||||
MAP_ADDR(ctx, DEPTH_STENCIL, addr, cl);
|
||||
pan_unpack(cl, DEPTH_STENCIL, desc);
|
||||
DUMP_UNPACKED(DEPTH_STENCIL, desc, "Depth/stencil");
|
||||
DUMP_UNPACKED(ctx, DEPTH_STENCIL, desc, "Depth/stencil");
|
||||
}
|
||||
|
||||
void
|
||||
GENX(pandecode_shader_environment)(const struct MALI_SHADER_ENVIRONMENT *p,
|
||||
GENX(pandecode_shader_environment)(struct pandecode_context *ctx,
|
||||
const struct MALI_SHADER_ENVIRONMENT *p,
|
||||
unsigned gpu_id)
|
||||
{
|
||||
if (p->shader)
|
||||
GENX(pandecode_shader)(p->shader, "Shader", gpu_id);
|
||||
GENX(pandecode_shader)(ctx, p->shader, "Shader", gpu_id);
|
||||
|
||||
if (p->resources)
|
||||
GENX(pandecode_resource_tables)(p->resources, "Resources");
|
||||
GENX(pandecode_resource_tables)(ctx, p->resources, "Resources");
|
||||
|
||||
if (p->thread_storage)
|
||||
DUMP_ADDR(LOCAL_STORAGE, p->thread_storage, "Local Storage:\n");
|
||||
DUMP_ADDR(ctx, LOCAL_STORAGE, p->thread_storage, "Local Storage:\n");
|
||||
|
||||
if (p->fau)
|
||||
GENX(pandecode_fau)(p->fau, p->fau_count, "FAU");
|
||||
GENX(pandecode_fau)(ctx, p->fau, p->fau_count, "FAU");
|
||||
}
|
||||
|
||||
void
|
||||
GENX(pandecode_blend_descs)(mali_ptr blend, unsigned count,
|
||||
mali_ptr frag_shader, unsigned gpu_id)
|
||||
GENX(pandecode_blend_descs)(struct pandecode_context *ctx, mali_ptr blend,
|
||||
unsigned count, mali_ptr frag_shader,
|
||||
unsigned gpu_id)
|
||||
{
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
struct mali_blend_packed *PANDECODE_PTR_VAR(blend_descs, blend);
|
||||
struct mali_blend_packed *PANDECODE_PTR_VAR(ctx, blend_descs, blend);
|
||||
|
||||
mali_ptr blend_shader =
|
||||
GENX(pandecode_blend)(blend_descs, i, frag_shader);
|
||||
GENX(pandecode_blend)(ctx, blend_descs, i, frag_shader);
|
||||
if (blend_shader) {
|
||||
fprintf(pandecode_dump_stream, "Blend shader %u @%" PRIx64 "", i,
|
||||
fprintf(ctx->dump_stream, "Blend shader %u @%" PRIx64 "", i,
|
||||
blend_shader);
|
||||
pandecode_shader_disassemble(blend_shader, gpu_id);
|
||||
pandecode_shader_disassemble(ctx, blend_shader, gpu_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GENX(pandecode_dcd)(const struct MALI_DRAW *p, unsigned unused, unsigned gpu_id)
|
||||
GENX(pandecode_dcd)(struct pandecode_context *ctx, const struct MALI_DRAW *p,
|
||||
unsigned unused, unsigned gpu_id)
|
||||
{
|
||||
mali_ptr frag_shader = 0;
|
||||
|
||||
GENX(pandecode_depth_stencil)(p->depth_stencil);
|
||||
GENX(pandecode_blend_descs)(p->blend, p->blend_count, frag_shader, gpu_id);
|
||||
GENX(pandecode_shader_environment)(&p->shader, gpu_id);
|
||||
DUMP_UNPACKED(DRAW, *p, "Draw:\n");
|
||||
GENX(pandecode_depth_stencil)(ctx, p->depth_stencil);
|
||||
GENX(pandecode_blend_descs)
|
||||
(ctx, p->blend, p->blend_count, frag_shader, gpu_id);
|
||||
GENX(pandecode_shader_environment)(ctx, &p->shader, gpu_id);
|
||||
DUMP_UNPACKED(ctx, DRAW, *p, "Draw:\n");
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,13 +28,22 @@
|
|||
|
||||
#include "genxml/gen_macros.h"
|
||||
#include "util/rb_tree.h"
|
||||
#include "util/simple_mtx.h"
|
||||
#include "util/u_dynarray.h"
|
||||
|
||||
#include "wrap.h"
|
||||
|
||||
extern FILE *pandecode_dump_stream;
|
||||
extern unsigned pandecode_indent;
|
||||
struct pandecode_context {
|
||||
int id; /* only used for the filename */
|
||||
FILE *dump_stream;
|
||||
unsigned indent;
|
||||
struct rb_tree mmap_tree;
|
||||
struct util_dynarray ro_mappings;
|
||||
int dump_frame_count;
|
||||
simple_mtx_t lock;
|
||||
};
|
||||
|
||||
void pandecode_dump_file_open(void);
|
||||
void pandecode_dump_file_open(struct pandecode_context *ctx);
|
||||
|
||||
struct pandecode_mapped_memory {
|
||||
struct rb_node node;
|
||||
|
|
@ -45,21 +54,22 @@ struct pandecode_mapped_memory {
|
|||
char name[32];
|
||||
};
|
||||
|
||||
char *pointer_as_memory_reference(uint64_t ptr);
|
||||
char *pointer_as_memory_reference(struct pandecode_context *ctx, uint64_t ptr);
|
||||
|
||||
struct pandecode_mapped_memory *
|
||||
pandecode_find_mapped_gpu_mem_containing(uint64_t addr);
|
||||
pandecode_find_mapped_gpu_mem_containing(struct pandecode_context *ctx,
|
||||
uint64_t addr);
|
||||
|
||||
void pandecode_map_read_write(void);
|
||||
void pandecode_map_read_write(struct pandecode_context *ctx);
|
||||
|
||||
void pandecode_dump_mappings(void);
|
||||
void pandecode_dump_mappings(struct pandecode_context *ctx);
|
||||
|
||||
static inline void *
|
||||
__pandecode_fetch_gpu_mem(uint64_t gpu_va, size_t size, int line,
|
||||
const char *filename)
|
||||
__pandecode_fetch_gpu_mem(struct pandecode_context *ctx, uint64_t gpu_va,
|
||||
size_t size, int line, const char *filename)
|
||||
{
|
||||
const struct pandecode_mapped_memory *mem =
|
||||
pandecode_find_mapped_gpu_mem_containing(gpu_va);
|
||||
pandecode_find_mapped_gpu_mem_containing(ctx, gpu_va);
|
||||
|
||||
if (!mem) {
|
||||
fprintf(stderr, "Access to unknown memory %" PRIx64 " in %s:%d\n", gpu_va,
|
||||
|
|
@ -72,97 +82,110 @@ __pandecode_fetch_gpu_mem(uint64_t gpu_va, size_t size, int line,
|
|||
return mem->addr + gpu_va - mem->gpu_va;
|
||||
}
|
||||
|
||||
#define pandecode_fetch_gpu_mem(gpu_va, size) \
|
||||
__pandecode_fetch_gpu_mem(gpu_va, size, __LINE__, __FILE__)
|
||||
#define pandecode_fetch_gpu_mem(ctx, gpu_va, size) \
|
||||
__pandecode_fetch_gpu_mem(ctx, gpu_va, size, __LINE__, __FILE__)
|
||||
|
||||
/* Returns a validated pointer to mapped GPU memory with the given pointer type,
|
||||
* size automatically determined from the pointer type
|
||||
*/
|
||||
#define PANDECODE_PTR(gpu_va, type) \
|
||||
((type *)(__pandecode_fetch_gpu_mem(gpu_va, sizeof(type), __LINE__, \
|
||||
#define PANDECODE_PTR(ctx, gpu_va, type) \
|
||||
((type *)(__pandecode_fetch_gpu_mem(ctx, gpu_va, sizeof(type), __LINE__, \
|
||||
__FILE__)))
|
||||
|
||||
/* Usage: <variable type> PANDECODE_PTR_VAR(name, gpu_va) */
|
||||
#define PANDECODE_PTR_VAR(name, gpu_va) \
|
||||
name = __pandecode_fetch_gpu_mem(gpu_va, sizeof(*name), __LINE__, __FILE__)
|
||||
#define PANDECODE_PTR_VAR(ctx, name, gpu_va) \
|
||||
name = __pandecode_fetch_gpu_mem(ctx, gpu_va, sizeof(*name), __LINE__, \
|
||||
__FILE__)
|
||||
|
||||
void pandecode_validate_buffer(mali_ptr addr, size_t sz);
|
||||
void pandecode_validate_buffer(struct pandecode_context *ctx, mali_ptr addr,
|
||||
size_t sz);
|
||||
|
||||
/* Forward declare for all supported gens to permit thunking */
|
||||
void pandecode_jc_v4(mali_ptr jc_gpu_va, unsigned gpu_id);
|
||||
void pandecode_jc_v5(mali_ptr jc_gpu_va, unsigned gpu_id);
|
||||
void pandecode_jc_v6(mali_ptr jc_gpu_va, unsigned gpu_id);
|
||||
void pandecode_jc_v7(mali_ptr jc_gpu_va, unsigned gpu_id);
|
||||
void pandecode_jc_v9(mali_ptr jc_gpu_va, unsigned gpu_id);
|
||||
void pandecode_jc_v4(struct pandecode_context *ctx, mali_ptr jc_gpu_va,
|
||||
unsigned gpu_id);
|
||||
void pandecode_jc_v5(struct pandecode_context *ctx, mali_ptr jc_gpu_va,
|
||||
unsigned gpu_id);
|
||||
void pandecode_jc_v6(struct pandecode_context *ctx, mali_ptr jc_gpu_va,
|
||||
unsigned gpu_id);
|
||||
void pandecode_jc_v7(struct pandecode_context *ctx, mali_ptr jc_gpu_va,
|
||||
unsigned gpu_id);
|
||||
void pandecode_jc_v9(struct pandecode_context *ctx, mali_ptr jc_gpu_va,
|
||||
unsigned gpu_id);
|
||||
|
||||
void pandecode_abort_on_fault_v4(mali_ptr jc_gpu_va);
|
||||
void pandecode_abort_on_fault_v5(mali_ptr jc_gpu_va);
|
||||
void pandecode_abort_on_fault_v6(mali_ptr jc_gpu_va);
|
||||
void pandecode_abort_on_fault_v7(mali_ptr jc_gpu_va);
|
||||
void pandecode_abort_on_fault_v9(mali_ptr jc_gpu_va);
|
||||
void pandecode_abort_on_fault_v4(struct pandecode_context *ctx,
|
||||
mali_ptr jc_gpu_va);
|
||||
void pandecode_abort_on_fault_v5(struct pandecode_context *ctx,
|
||||
mali_ptr jc_gpu_va);
|
||||
void pandecode_abort_on_fault_v6(struct pandecode_context *ctx,
|
||||
mali_ptr jc_gpu_va);
|
||||
void pandecode_abort_on_fault_v7(struct pandecode_context *ctx,
|
||||
mali_ptr jc_gpu_va);
|
||||
void pandecode_abort_on_fault_v9(struct pandecode_context *ctx,
|
||||
mali_ptr jc_gpu_va);
|
||||
|
||||
void pandecode_cs_v10(mali_ptr queue, uint32_t size, unsigned gpu_id,
|
||||
uint32_t *regs);
|
||||
void pandecode_cs_v10(struct pandecode_context *ctx, mali_ptr queue,
|
||||
uint32_t size, unsigned gpu_id, uint32_t *regs);
|
||||
|
||||
/* Logging infrastructure */
|
||||
static void
|
||||
pandecode_make_indent(void)
|
||||
pandecode_make_indent(struct pandecode_context *ctx)
|
||||
{
|
||||
for (unsigned i = 0; i < pandecode_indent; ++i)
|
||||
fprintf(pandecode_dump_stream, " ");
|
||||
for (unsigned i = 0; i < ctx->indent; ++i)
|
||||
fprintf(ctx->dump_stream, " ");
|
||||
}
|
||||
|
||||
static inline void PRINTFLIKE(1, 2) pandecode_log(const char *format, ...)
|
||||
static inline void PRINTFLIKE(2, 3)
|
||||
pandecode_log(struct pandecode_context *ctx, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
pandecode_make_indent();
|
||||
pandecode_make_indent(ctx);
|
||||
va_start(ap, format);
|
||||
vfprintf(pandecode_dump_stream, format, ap);
|
||||
vfprintf(ctx->dump_stream, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static inline void
|
||||
pandecode_log_cont(const char *format, ...)
|
||||
pandecode_log_cont(struct pandecode_context *ctx, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vfprintf(pandecode_dump_stream, format, ap);
|
||||
vfprintf(ctx->dump_stream, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* Convenience methods */
|
||||
#define DUMP_UNPACKED(T, var, ...) \
|
||||
#define DUMP_UNPACKED(ctx, T, var, ...) \
|
||||
{ \
|
||||
pandecode_log(__VA_ARGS__); \
|
||||
pan_print(pandecode_dump_stream, T, var, (pandecode_indent + 1) * 2); \
|
||||
pandecode_log(ctx, __VA_ARGS__); \
|
||||
pan_print(ctx->dump_stream, T, var, (ctx->indent + 1) * 2); \
|
||||
}
|
||||
|
||||
#define DUMP_CL(T, cl, ...) \
|
||||
#define DUMP_CL(ctx, T, cl, ...) \
|
||||
{ \
|
||||
pan_unpack(cl, T, temp); \
|
||||
DUMP_UNPACKED(T, temp, __VA_ARGS__); \
|
||||
DUMP_UNPACKED(ctx, T, temp, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define DUMP_SECTION(A, S, cl, ...) \
|
||||
#define DUMP_SECTION(ctx, A, S, cl, ...) \
|
||||
{ \
|
||||
pan_section_unpack(cl, A, S, temp); \
|
||||
pandecode_log(__VA_ARGS__); \
|
||||
pan_section_print(pandecode_dump_stream, A, S, temp, \
|
||||
(pandecode_indent + 1) * 2); \
|
||||
pandecode_log(ctx, __VA_ARGS__); \
|
||||
pan_section_print(ctx->dump_stream, A, S, temp, (ctx->indent + 1) * 2); \
|
||||
}
|
||||
|
||||
#define MAP_ADDR(T, addr, cl) \
|
||||
const uint8_t *cl = pandecode_fetch_gpu_mem(addr, pan_size(T));
|
||||
#define MAP_ADDR(ctx, T, addr, cl) \
|
||||
const uint8_t *cl = pandecode_fetch_gpu_mem(ctx, addr, pan_size(T));
|
||||
|
||||
#define DUMP_ADDR(T, addr, ...) \
|
||||
#define DUMP_ADDR(ctx, T, addr, ...) \
|
||||
{ \
|
||||
MAP_ADDR(T, addr, cl) \
|
||||
DUMP_CL(T, cl, __VA_ARGS__); \
|
||||
MAP_ADDR(ctx, T, addr, cl) \
|
||||
DUMP_CL(ctx, T, cl, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
void pandecode_shader_disassemble(mali_ptr shader_ptr, unsigned gpu_id);
|
||||
void pandecode_shader_disassemble(struct pandecode_context *ctx,
|
||||
mali_ptr shader_ptr, unsigned gpu_id);
|
||||
|
||||
#ifdef PAN_ARCH
|
||||
|
||||
|
|
@ -172,46 +195,58 @@ struct pandecode_fbd {
|
|||
bool has_extra;
|
||||
};
|
||||
|
||||
struct pandecode_fbd GENX(pandecode_fbd)(uint64_t gpu_va, bool is_fragment,
|
||||
struct pandecode_fbd GENX(pandecode_fbd)(struct pandecode_context *ctx,
|
||||
uint64_t gpu_va, bool is_fragment,
|
||||
unsigned gpu_id);
|
||||
|
||||
#if PAN_ARCH >= 9
|
||||
void GENX(pandecode_dcd)(const struct MALI_DRAW *p, unsigned unused,
|
||||
void GENX(pandecode_dcd)(struct pandecode_context *ctx,
|
||||
const struct MALI_DRAW *p, unsigned unused,
|
||||
unsigned gpu_id);
|
||||
#else
|
||||
void GENX(pandecode_dcd)(const struct MALI_DRAW *p, enum mali_job_type job_type,
|
||||
void GENX(pandecode_dcd)(struct pandecode_context *ctx,
|
||||
const struct MALI_DRAW *p, enum mali_job_type job_type,
|
||||
unsigned gpu_id);
|
||||
#endif
|
||||
|
||||
#if PAN_ARCH <= 5
|
||||
void GENX(pandecode_texture)(mali_ptr u, unsigned tex);
|
||||
void GENX(pandecode_texture)(struct pandecode_context *ctx, mali_ptr u,
|
||||
unsigned tex);
|
||||
#else
|
||||
void GENX(pandecode_texture)(const void *cl, unsigned tex);
|
||||
void GENX(pandecode_texture)(struct pandecode_context *ctx, const void *cl,
|
||||
unsigned tex);
|
||||
#endif
|
||||
|
||||
#if PAN_ARCH >= 5
|
||||
mali_ptr GENX(pandecode_blend)(void *descs, int rt_no, mali_ptr frag_shader);
|
||||
mali_ptr GENX(pandecode_blend)(struct pandecode_context *ctx, void *descs,
|
||||
int rt_no, mali_ptr frag_shader);
|
||||
#endif
|
||||
|
||||
#if PAN_ARCH >= 6
|
||||
void GENX(pandecode_tiler)(mali_ptr gpu_va, unsigned gpu_id);
|
||||
void GENX(pandecode_tiler)(struct pandecode_context *ctx, mali_ptr gpu_va,
|
||||
unsigned gpu_id);
|
||||
#endif
|
||||
|
||||
#if PAN_ARCH >= 9
|
||||
void GENX(pandecode_shader_environment)(const struct MALI_SHADER_ENVIRONMENT *p,
|
||||
void GENX(pandecode_shader_environment)(struct pandecode_context *ctx,
|
||||
const struct MALI_SHADER_ENVIRONMENT *p,
|
||||
unsigned gpu_id);
|
||||
|
||||
void GENX(pandecode_resource_tables)(mali_ptr addr, const char *label);
|
||||
void GENX(pandecode_resource_tables)(struct pandecode_context *ctx,
|
||||
mali_ptr addr, const char *label);
|
||||
|
||||
void GENX(pandecode_fau)(mali_ptr addr, unsigned count, const char *name);
|
||||
void GENX(pandecode_fau)(struct pandecode_context *ctx, mali_ptr addr,
|
||||
unsigned count, const char *name);
|
||||
|
||||
mali_ptr GENX(pandecode_shader)(mali_ptr addr, const char *label,
|
||||
unsigned gpu_id);
|
||||
mali_ptr GENX(pandecode_shader)(struct pandecode_context *ctx, mali_ptr addr,
|
||||
const char *label, unsigned gpu_id);
|
||||
|
||||
void GENX(pandecode_blend_descs)(mali_ptr blend, unsigned count,
|
||||
mali_ptr frag_shader, unsigned gpu_id);
|
||||
void GENX(pandecode_blend_descs)(struct pandecode_context *ctx, mali_ptr blend,
|
||||
unsigned count, mali_ptr frag_shader,
|
||||
unsigned gpu_id);
|
||||
|
||||
void GENX(pandecode_depth_stencil)(mali_ptr addr);
|
||||
void GENX(pandecode_depth_stencil)(struct pandecode_context *ctx,
|
||||
mali_ptr addr);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,9 +31,7 @@
|
|||
#include <sys/mman.h>
|
||||
|
||||
#include "util/macros.h"
|
||||
#include "util/simple_mtx.h"
|
||||
#include "util/u_debug.h"
|
||||
#include "util/u_dynarray.h"
|
||||
#include "util/u_hexdump.h"
|
||||
#include "decode.h"
|
||||
|
||||
|
|
@ -41,17 +39,9 @@
|
|||
#include "compiler/valhall/disassemble.h"
|
||||
#include "midgard/disassemble.h"
|
||||
|
||||
FILE *pandecode_dump_stream;
|
||||
|
||||
unsigned pandecode_indent;
|
||||
|
||||
/* Memory handling */
|
||||
|
||||
static struct rb_tree mmap_tree;
|
||||
|
||||
static struct util_dynarray ro_mappings;
|
||||
|
||||
static simple_mtx_t pandecode_lock = SIMPLE_MTX_INITIALIZER;
|
||||
/* Used to distiguish dumped files, otherwise we would have to print the ctx
|
||||
* pointer, which is annoying for the user since it changes with every run */
|
||||
static int num_ctxs = 0;
|
||||
|
||||
#define to_mapped_memory(x) \
|
||||
rb_node_data(struct pandecode_mapped_memory, x, node)
|
||||
|
|
@ -80,27 +70,31 @@ pandecode_cmp(const struct rb_node *lhs, const struct rb_node *rhs)
|
|||
}
|
||||
|
||||
static struct pandecode_mapped_memory *
|
||||
pandecode_find_mapped_gpu_mem_containing_rw(uint64_t addr)
|
||||
pandecode_find_mapped_gpu_mem_containing_rw(struct pandecode_context *ctx,
|
||||
uint64_t addr)
|
||||
{
|
||||
simple_mtx_assert_locked(&pandecode_lock);
|
||||
simple_mtx_assert_locked(&ctx->lock);
|
||||
|
||||
struct rb_node *node = rb_tree_search(&mmap_tree, &addr, pandecode_cmp_key);
|
||||
struct rb_node *node =
|
||||
rb_tree_search(&ctx->mmap_tree, &addr, pandecode_cmp_key);
|
||||
|
||||
return to_mapped_memory(node);
|
||||
}
|
||||
|
||||
struct pandecode_mapped_memory *
|
||||
pandecode_find_mapped_gpu_mem_containing(uint64_t addr)
|
||||
pandecode_find_mapped_gpu_mem_containing(struct pandecode_context *ctx,
|
||||
uint64_t addr)
|
||||
{
|
||||
simple_mtx_assert_locked(&pandecode_lock);
|
||||
simple_mtx_assert_locked(&ctx->lock);
|
||||
|
||||
struct pandecode_mapped_memory *mem =
|
||||
pandecode_find_mapped_gpu_mem_containing_rw(addr);
|
||||
pandecode_find_mapped_gpu_mem_containing_rw(ctx, addr);
|
||||
|
||||
if (mem && mem->addr && !mem->ro) {
|
||||
mprotect(mem->addr, mem->length, PROT_READ);
|
||||
mem->ro = true;
|
||||
util_dynarray_append(&ro_mappings, struct pandecode_mapped_memory *, mem);
|
||||
util_dynarray_append(&ctx->ro_mappings, struct pandecode_mapped_memory *,
|
||||
mem);
|
||||
}
|
||||
|
||||
return mem;
|
||||
|
|
@ -112,20 +106,21 @@ pandecode_find_mapped_gpu_mem_containing(uint64_t addr)
|
|||
* detect GPU-side memory bugs by validating pointers.
|
||||
*/
|
||||
void
|
||||
pandecode_validate_buffer(mali_ptr addr, size_t sz)
|
||||
pandecode_validate_buffer(struct pandecode_context *ctx, mali_ptr addr,
|
||||
size_t sz)
|
||||
{
|
||||
if (!addr) {
|
||||
pandecode_log("// XXX: null pointer deref\n");
|
||||
pandecode_log(ctx, "// XXX: null pointer deref\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find a BO */
|
||||
|
||||
struct pandecode_mapped_memory *bo =
|
||||
pandecode_find_mapped_gpu_mem_containing(addr);
|
||||
pandecode_find_mapped_gpu_mem_containing(ctx, addr);
|
||||
|
||||
if (!bo) {
|
||||
pandecode_log("// XXX: invalid memory dereference\n");
|
||||
pandecode_log(ctx, "// XXX: invalid memory dereference\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +130,8 @@ pandecode_validate_buffer(mali_ptr addr, size_t sz)
|
|||
unsigned total = offset + sz;
|
||||
|
||||
if (total > bo->length) {
|
||||
pandecode_log("// XXX: buffer overrun. "
|
||||
pandecode_log(ctx,
|
||||
"// XXX: buffer overrun. "
|
||||
"Chunk of size %zu at offset %d in buffer of size %zu. "
|
||||
"Overrun by %zu bytes. \n",
|
||||
sz, offset, bo->length, total - bo->length);
|
||||
|
|
@ -144,22 +140,24 @@ pandecode_validate_buffer(mali_ptr addr, size_t sz)
|
|||
}
|
||||
|
||||
void
|
||||
pandecode_map_read_write(void)
|
||||
pandecode_map_read_write(struct pandecode_context *ctx)
|
||||
{
|
||||
simple_mtx_assert_locked(&pandecode_lock);
|
||||
simple_mtx_assert_locked(&ctx->lock);
|
||||
|
||||
util_dynarray_foreach(&ro_mappings, struct pandecode_mapped_memory *, mem) {
|
||||
util_dynarray_foreach(&ctx->ro_mappings, struct pandecode_mapped_memory *,
|
||||
mem) {
|
||||
(*mem)->ro = false;
|
||||
mprotect((*mem)->addr, (*mem)->length, PROT_READ | PROT_WRITE);
|
||||
}
|
||||
util_dynarray_clear(&ro_mappings);
|
||||
util_dynarray_clear(&ctx->ro_mappings);
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_add_name(struct pandecode_mapped_memory *mem, uint64_t gpu_va,
|
||||
pandecode_add_name(struct pandecode_context *ctx,
|
||||
struct pandecode_mapped_memory *mem, uint64_t gpu_va,
|
||||
const char *name)
|
||||
{
|
||||
simple_mtx_assert_locked(&pandecode_lock);
|
||||
simple_mtx_assert_locked(&ctx->lock);
|
||||
|
||||
if (!name) {
|
||||
/* If we don't have a name, assign one */
|
||||
|
|
@ -172,19 +170,20 @@ pandecode_add_name(struct pandecode_mapped_memory *mem, uint64_t gpu_va,
|
|||
}
|
||||
|
||||
void
|
||||
pandecode_inject_mmap(uint64_t gpu_va, void *cpu, unsigned sz, const char *name)
|
||||
pandecode_inject_mmap(struct pandecode_context *ctx, uint64_t gpu_va, void *cpu,
|
||||
unsigned sz, const char *name)
|
||||
{
|
||||
simple_mtx_lock(&pandecode_lock);
|
||||
simple_mtx_lock(&ctx->lock);
|
||||
|
||||
/* First, search if we already mapped this and are just updating an address */
|
||||
|
||||
struct pandecode_mapped_memory *existing =
|
||||
pandecode_find_mapped_gpu_mem_containing_rw(gpu_va);
|
||||
pandecode_find_mapped_gpu_mem_containing_rw(ctx, gpu_va);
|
||||
|
||||
if (existing && existing->gpu_va == gpu_va) {
|
||||
existing->length = sz;
|
||||
existing->addr = cpu;
|
||||
pandecode_add_name(existing, gpu_va, name);
|
||||
pandecode_add_name(ctx, existing, gpu_va, name);
|
||||
} else {
|
||||
/* Otherwise, add a fresh mapping */
|
||||
struct pandecode_mapped_memory *mapped_mem = NULL;
|
||||
|
|
@ -193,45 +192,46 @@ pandecode_inject_mmap(uint64_t gpu_va, void *cpu, unsigned sz, const char *name)
|
|||
mapped_mem->gpu_va = gpu_va;
|
||||
mapped_mem->length = sz;
|
||||
mapped_mem->addr = cpu;
|
||||
pandecode_add_name(mapped_mem, gpu_va, name);
|
||||
pandecode_add_name(ctx, mapped_mem, gpu_va, name);
|
||||
|
||||
/* Add it to the tree */
|
||||
rb_tree_insert(&mmap_tree, &mapped_mem->node, pandecode_cmp);
|
||||
rb_tree_insert(&ctx->mmap_tree, &mapped_mem->node, pandecode_cmp);
|
||||
}
|
||||
|
||||
simple_mtx_unlock(&pandecode_lock);
|
||||
simple_mtx_unlock(&ctx->lock);
|
||||
}
|
||||
|
||||
void
|
||||
pandecode_inject_free(uint64_t gpu_va, unsigned sz)
|
||||
pandecode_inject_free(struct pandecode_context *ctx, uint64_t gpu_va,
|
||||
unsigned sz)
|
||||
{
|
||||
simple_mtx_lock(&pandecode_lock);
|
||||
simple_mtx_lock(&ctx->lock);
|
||||
|
||||
struct pandecode_mapped_memory *mem =
|
||||
pandecode_find_mapped_gpu_mem_containing_rw(gpu_va);
|
||||
pandecode_find_mapped_gpu_mem_containing_rw(ctx, gpu_va);
|
||||
|
||||
if (mem) {
|
||||
assert(mem->gpu_va == gpu_va);
|
||||
assert(mem->length == sz);
|
||||
|
||||
rb_tree_remove(&mmap_tree, &mem->node);
|
||||
rb_tree_remove(&ctx->mmap_tree, &mem->node);
|
||||
free(mem);
|
||||
}
|
||||
|
||||
simple_mtx_unlock(&pandecode_lock);
|
||||
simple_mtx_unlock(&ctx->lock);
|
||||
}
|
||||
|
||||
char *
|
||||
pointer_as_memory_reference(uint64_t ptr)
|
||||
pointer_as_memory_reference(struct pandecode_context *ctx, uint64_t ptr)
|
||||
{
|
||||
simple_mtx_assert_locked(&pandecode_lock);
|
||||
simple_mtx_assert_locked(&ctx->lock);
|
||||
|
||||
struct pandecode_mapped_memory *mapped;
|
||||
char *out = malloc(128);
|
||||
|
||||
/* Try to find the corresponding mapped zone */
|
||||
|
||||
mapped = pandecode_find_mapped_gpu_mem_containing_rw(ptr);
|
||||
mapped = pandecode_find_mapped_gpu_mem_containing_rw(ctx, ptr);
|
||||
|
||||
if (mapped) {
|
||||
snprintf(out, 128, "%s + %d", mapped->name, (int)(ptr - mapped->gpu_va));
|
||||
|
|
@ -244,32 +244,25 @@ pointer_as_memory_reference(uint64_t ptr)
|
|||
return out;
|
||||
}
|
||||
|
||||
static int pandecode_dump_frame_count = 0;
|
||||
|
||||
static bool force_stderr = false;
|
||||
|
||||
void
|
||||
pandecode_dump_file_open(void)
|
||||
pandecode_dump_file_open(struct pandecode_context *ctx)
|
||||
{
|
||||
simple_mtx_assert_locked(&pandecode_lock);
|
||||
|
||||
if (pandecode_dump_stream)
|
||||
return;
|
||||
simple_mtx_assert_locked(&ctx->lock);
|
||||
|
||||
/* This does a getenv every frame, so it is possible to use
|
||||
* setenv to change the base at runtime.
|
||||
*/
|
||||
const char *dump_file_base =
|
||||
debug_get_option("PANDECODE_DUMP_FILE", "pandecode.dump");
|
||||
if (force_stderr || !strcmp(dump_file_base, "stderr"))
|
||||
pandecode_dump_stream = stdout; // stderr;
|
||||
else {
|
||||
if (!strcmp(dump_file_base, "stderr"))
|
||||
ctx->dump_stream = stderr;
|
||||
else if (!ctx->dump_stream) {
|
||||
char buffer[1024];
|
||||
snprintf(buffer, sizeof(buffer), "%s.%04d", dump_file_base,
|
||||
pandecode_dump_frame_count);
|
||||
snprintf(buffer, sizeof(buffer), "%s.ctx-%d.%04d", dump_file_base,
|
||||
ctx->id, ctx->dump_frame_count);
|
||||
printf("pandecode: dump command stream to file %s\n", buffer);
|
||||
pandecode_dump_stream = fopen(buffer, "w");
|
||||
if (!pandecode_dump_stream)
|
||||
ctx->dump_stream = fopen(buffer, "w");
|
||||
if (!ctx->dump_stream)
|
||||
fprintf(stderr,
|
||||
"pandecode: failed to open command stream log file %s\n",
|
||||
buffer);
|
||||
|
|
@ -277,171 +270,191 @@ pandecode_dump_file_open(void)
|
|||
}
|
||||
|
||||
static void
|
||||
pandecode_dump_file_close(void)
|
||||
pandecode_dump_file_close(struct pandecode_context *ctx)
|
||||
{
|
||||
simple_mtx_assert_locked(&pandecode_lock);
|
||||
simple_mtx_assert_locked(&ctx->lock);
|
||||
|
||||
if (pandecode_dump_stream && pandecode_dump_stream != stderr) {
|
||||
if (fclose(pandecode_dump_stream))
|
||||
if (ctx->dump_stream && ctx->dump_stream != stderr) {
|
||||
if (fclose(ctx->dump_stream))
|
||||
perror("pandecode: dump file");
|
||||
|
||||
pandecode_dump_stream = NULL;
|
||||
ctx->dump_stream = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pandecode_initialize(bool to_stderr)
|
||||
struct pandecode_context *
|
||||
pandecode_create_context(bool to_stderr)
|
||||
{
|
||||
force_stderr = to_stderr;
|
||||
rb_tree_init(&mmap_tree);
|
||||
util_dynarray_init(&ro_mappings, NULL);
|
||||
struct pandecode_context *ctx = calloc(1, sizeof(*ctx));
|
||||
|
||||
/* Not thread safe, but we shouldn't ever hit this, and even if we do, the
|
||||
* worst that could happen is having the files dumped with their filenames
|
||||
* in a different order. */
|
||||
ctx->id = num_ctxs++;
|
||||
|
||||
/* This will be initialized later and can be changed at run time through
|
||||
* the PANDECODE_DUMP_FILE environment variable.
|
||||
*/
|
||||
ctx->dump_stream = to_stderr ? stderr : NULL;
|
||||
|
||||
rb_tree_init(&ctx->mmap_tree);
|
||||
util_dynarray_init(&ctx->ro_mappings, NULL);
|
||||
|
||||
simple_mtx_t mtx_init = SIMPLE_MTX_INITIALIZER;
|
||||
memcpy(&ctx->lock, &mtx_init, sizeof(simple_mtx_t));
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void
|
||||
pandecode_next_frame(void)
|
||||
pandecode_next_frame(struct pandecode_context *ctx)
|
||||
{
|
||||
simple_mtx_lock(&pandecode_lock);
|
||||
simple_mtx_lock(&ctx->lock);
|
||||
|
||||
pandecode_dump_file_close();
|
||||
pandecode_dump_frame_count++;
|
||||
pandecode_dump_file_close(ctx);
|
||||
ctx->dump_frame_count++;
|
||||
|
||||
simple_mtx_unlock(&pandecode_lock);
|
||||
simple_mtx_unlock(&ctx->lock);
|
||||
}
|
||||
|
||||
void
|
||||
pandecode_close(void)
|
||||
pandecode_destroy_context(struct pandecode_context *ctx)
|
||||
{
|
||||
simple_mtx_lock(&pandecode_lock);
|
||||
simple_mtx_lock(&ctx->lock);
|
||||
|
||||
rb_tree_foreach_safe(struct pandecode_mapped_memory, it, &mmap_tree, node) {
|
||||
rb_tree_remove(&mmap_tree, &it->node);
|
||||
rb_tree_foreach_safe(struct pandecode_mapped_memory, it, &ctx->mmap_tree,
|
||||
node) {
|
||||
rb_tree_remove(&ctx->mmap_tree, &it->node);
|
||||
free(it);
|
||||
}
|
||||
|
||||
util_dynarray_fini(&ro_mappings);
|
||||
pandecode_dump_file_close();
|
||||
util_dynarray_fini(&ctx->ro_mappings);
|
||||
pandecode_dump_file_close(ctx);
|
||||
|
||||
simple_mtx_unlock(&pandecode_lock);
|
||||
simple_mtx_unlock(&ctx->lock);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
pandecode_dump_mappings(void)
|
||||
pandecode_dump_mappings(struct pandecode_context *ctx)
|
||||
{
|
||||
simple_mtx_lock(&pandecode_lock);
|
||||
simple_mtx_lock(&ctx->lock);
|
||||
|
||||
pandecode_dump_file_open();
|
||||
pandecode_dump_file_open(ctx);
|
||||
|
||||
rb_tree_foreach(struct pandecode_mapped_memory, it, &mmap_tree, node) {
|
||||
rb_tree_foreach(struct pandecode_mapped_memory, it, &ctx->mmap_tree, node) {
|
||||
if (!it->addr || !it->length)
|
||||
continue;
|
||||
|
||||
fprintf(pandecode_dump_stream, "Buffer: %s gpu %" PRIx64 "\n\n", it->name,
|
||||
fprintf(ctx->dump_stream, "Buffer: %s gpu %" PRIx64 "\n\n", it->name,
|
||||
it->gpu_va);
|
||||
|
||||
u_hexdump(pandecode_dump_stream, it->addr, it->length, false);
|
||||
fprintf(pandecode_dump_stream, "\n");
|
||||
u_hexdump(ctx->dump_stream, it->addr, it->length, false);
|
||||
fprintf(ctx->dump_stream, "\n");
|
||||
}
|
||||
|
||||
fflush(pandecode_dump_stream);
|
||||
simple_mtx_unlock(&pandecode_lock);
|
||||
fflush(ctx->dump_stream);
|
||||
simple_mtx_unlock(&ctx->lock);
|
||||
}
|
||||
|
||||
void
|
||||
pandecode_abort_on_fault(mali_ptr jc_gpu_va, unsigned gpu_id)
|
||||
pandecode_abort_on_fault(struct pandecode_context *ctx, mali_ptr jc_gpu_va,
|
||||
unsigned gpu_id)
|
||||
{
|
||||
simple_mtx_lock(&pandecode_lock);
|
||||
simple_mtx_lock(&ctx->lock);
|
||||
|
||||
switch (pan_arch(gpu_id)) {
|
||||
case 4:
|
||||
pandecode_abort_on_fault_v4(jc_gpu_va);
|
||||
pandecode_abort_on_fault_v4(ctx, jc_gpu_va);
|
||||
break;
|
||||
case 5:
|
||||
pandecode_abort_on_fault_v5(jc_gpu_va);
|
||||
pandecode_abort_on_fault_v5(ctx, jc_gpu_va);
|
||||
break;
|
||||
case 6:
|
||||
pandecode_abort_on_fault_v6(jc_gpu_va);
|
||||
pandecode_abort_on_fault_v6(ctx, jc_gpu_va);
|
||||
break;
|
||||
case 7:
|
||||
pandecode_abort_on_fault_v7(jc_gpu_va);
|
||||
pandecode_abort_on_fault_v7(ctx, jc_gpu_va);
|
||||
break;
|
||||
case 9:
|
||||
pandecode_abort_on_fault_v9(jc_gpu_va);
|
||||
pandecode_abort_on_fault_v9(ctx, jc_gpu_va);
|
||||
break;
|
||||
default:
|
||||
unreachable("Unsupported architecture");
|
||||
}
|
||||
|
||||
simple_mtx_unlock(&pandecode_lock);
|
||||
simple_mtx_unlock(&ctx->lock);
|
||||
}
|
||||
|
||||
void
|
||||
pandecode_jc(mali_ptr jc_gpu_va, unsigned gpu_id)
|
||||
pandecode_jc(struct pandecode_context *ctx, mali_ptr jc_gpu_va, unsigned gpu_id)
|
||||
{
|
||||
simple_mtx_lock(&pandecode_lock);
|
||||
simple_mtx_lock(&ctx->lock);
|
||||
|
||||
switch (pan_arch(gpu_id)) {
|
||||
case 4:
|
||||
pandecode_jc_v4(jc_gpu_va, gpu_id);
|
||||
pandecode_jc_v4(ctx, jc_gpu_va, gpu_id);
|
||||
break;
|
||||
case 5:
|
||||
pandecode_jc_v5(jc_gpu_va, gpu_id);
|
||||
pandecode_jc_v5(ctx, jc_gpu_va, gpu_id);
|
||||
break;
|
||||
case 6:
|
||||
pandecode_jc_v6(jc_gpu_va, gpu_id);
|
||||
pandecode_jc_v6(ctx, jc_gpu_va, gpu_id);
|
||||
break;
|
||||
case 7:
|
||||
pandecode_jc_v7(jc_gpu_va, gpu_id);
|
||||
pandecode_jc_v7(ctx, jc_gpu_va, gpu_id);
|
||||
break;
|
||||
case 9:
|
||||
pandecode_jc_v9(jc_gpu_va, gpu_id);
|
||||
pandecode_jc_v9(ctx, jc_gpu_va, gpu_id);
|
||||
break;
|
||||
default:
|
||||
unreachable("Unsupported architecture");
|
||||
}
|
||||
|
||||
simple_mtx_unlock(&pandecode_lock);
|
||||
simple_mtx_unlock(&ctx->lock);
|
||||
}
|
||||
|
||||
void
|
||||
pandecode_cs(mali_ptr queue_gpu_va, uint32_t size, unsigned gpu_id,
|
||||
uint32_t *regs)
|
||||
pandecode_cs(struct pandecode_context *ctx, mali_ptr queue_gpu_va,
|
||||
uint32_t size, unsigned gpu_id, uint32_t *regs)
|
||||
{
|
||||
simple_mtx_lock(&pandecode_lock);
|
||||
simple_mtx_lock(&ctx->lock);
|
||||
|
||||
switch (pan_arch(gpu_id)) {
|
||||
case 10:
|
||||
pandecode_cs_v10(queue_gpu_va, size, gpu_id, regs);
|
||||
pandecode_cs_v10(ctx, queue_gpu_va, size, gpu_id, regs);
|
||||
break;
|
||||
default:
|
||||
unreachable("Unsupported architecture");
|
||||
}
|
||||
|
||||
simple_mtx_unlock(&pandecode_lock);
|
||||
simple_mtx_unlock(&ctx->lock);
|
||||
}
|
||||
|
||||
void
|
||||
pandecode_shader_disassemble(mali_ptr shader_ptr, unsigned gpu_id)
|
||||
pandecode_shader_disassemble(struct pandecode_context *ctx, mali_ptr shader_ptr,
|
||||
unsigned gpu_id)
|
||||
{
|
||||
uint8_t *PANDECODE_PTR_VAR(code, shader_ptr);
|
||||
uint8_t *PANDECODE_PTR_VAR(ctx, code, shader_ptr);
|
||||
|
||||
/* Compute maximum possible size */
|
||||
struct pandecode_mapped_memory *mem =
|
||||
pandecode_find_mapped_gpu_mem_containing(shader_ptr);
|
||||
pandecode_find_mapped_gpu_mem_containing(ctx, shader_ptr);
|
||||
size_t sz = mem->length - (shader_ptr - mem->gpu_va);
|
||||
|
||||
/* Print some boilerplate to clearly denote the assembly (which doesn't
|
||||
* obey indentation rules), and actually do the disassembly! */
|
||||
|
||||
pandecode_log_cont("\nShader %p (GPU VA %" PRIx64 ") sz %" PRId64 "\n", code,
|
||||
shader_ptr, sz);
|
||||
pandecode_log_cont(ctx, "\nShader %p (GPU VA %" PRIx64 ") sz %" PRId64 "\n",
|
||||
code, shader_ptr, sz);
|
||||
|
||||
if (pan_arch(gpu_id) >= 9) {
|
||||
disassemble_valhall(pandecode_dump_stream, (const uint64_t *)code, sz,
|
||||
true);
|
||||
disassemble_valhall(ctx->dump_stream, (const uint64_t *)code, sz, true);
|
||||
} else if (pan_arch(gpu_id) >= 6)
|
||||
disassemble_bifrost(pandecode_dump_stream, code, sz, false);
|
||||
disassemble_bifrost(ctx->dump_stream, code, sz, false);
|
||||
else
|
||||
disassemble_midgard(pandecode_dump_stream, code, sz, gpu_id, true);
|
||||
disassemble_midgard(ctx->dump_stream, code, sz, gpu_id, true);
|
||||
|
||||
pandecode_log_cont("\n\n");
|
||||
pandecode_log_cont(ctx, "\n\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,21 +55,21 @@ struct queue_ctx {
|
|||
};
|
||||
|
||||
static uint32_t
|
||||
cs_get_u32(struct queue_ctx *ctx, uint8_t reg)
|
||||
cs_get_u32(struct queue_ctx *qctx, uint8_t reg)
|
||||
{
|
||||
assert(reg < ctx->nr_regs);
|
||||
return ctx->regs[reg];
|
||||
assert(reg < qctx->nr_regs);
|
||||
return qctx->regs[reg];
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
cs_get_u64(struct queue_ctx *ctx, uint8_t reg)
|
||||
cs_get_u64(struct queue_ctx *qctx, uint8_t reg)
|
||||
{
|
||||
return (((uint64_t)cs_get_u32(ctx, reg + 1)) << 32) | cs_get_u32(ctx, reg);
|
||||
return (((uint64_t)cs_get_u32(qctx, reg + 1)) << 32) | cs_get_u32(qctx, reg);
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_run_compute(FILE *fp, struct queue_ctx *ctx,
|
||||
struct MALI_CEU_RUN_COMPUTE *I)
|
||||
pandecode_run_compute(struct pandecode_context *ctx, FILE *fp,
|
||||
struct queue_ctx *qctx, struct MALI_CEU_RUN_COMPUTE *I)
|
||||
{
|
||||
const char *axes[4] = {"x_axis", "y_axis", "z_axis"};
|
||||
|
||||
|
|
@ -78,39 +78,41 @@ pandecode_run_compute(FILE *fp, struct queue_ctx *ctx,
|
|||
*/
|
||||
fprintf(fp, "RUN_COMPUTE.%s #%u\n", axes[I->task_axis], I->task_increment);
|
||||
|
||||
pandecode_indent++;
|
||||
ctx->indent++;
|
||||
|
||||
unsigned reg_srt = 0 + (I->srt_select * 2);
|
||||
unsigned reg_fau = 8 + (I->fau_select * 2);
|
||||
unsigned reg_spd = 16 + (I->spd_select * 2);
|
||||
unsigned reg_tsd = 24 + (I->tsd_select * 2);
|
||||
|
||||
GENX(pandecode_resource_tables)(cs_get_u64(ctx, reg_srt), "Resources");
|
||||
GENX(pandecode_resource_tables)(ctx, cs_get_u64(qctx, reg_srt), "Resources");
|
||||
|
||||
mali_ptr fau = cs_get_u64(ctx, reg_fau);
|
||||
mali_ptr fau = cs_get_u64(qctx, reg_fau);
|
||||
|
||||
if (fau)
|
||||
GENX(pandecode_fau)(fau & BITFIELD64_MASK(48), fau >> 56, "FAU");
|
||||
GENX(pandecode_fau)(ctx, fau & BITFIELD64_MASK(48), fau >> 56, "FAU");
|
||||
|
||||
GENX(pandecode_shader)(cs_get_u64(ctx, reg_spd), "Shader", ctx->gpu_id);
|
||||
GENX(pandecode_shader)
|
||||
(ctx, cs_get_u64(qctx, reg_spd), "Shader", qctx->gpu_id);
|
||||
|
||||
DUMP_ADDR(LOCAL_STORAGE, cs_get_u64(ctx, reg_tsd),
|
||||
"Local Storage @%" PRIx64 ":\n", cs_get_u64(ctx, reg_tsd));
|
||||
DUMP_ADDR(ctx, LOCAL_STORAGE, cs_get_u64(qctx, reg_tsd),
|
||||
"Local Storage @%" PRIx64 ":\n", cs_get_u64(qctx, reg_tsd));
|
||||
|
||||
pandecode_log("Global attribute offset: %u\n", cs_get_u32(ctx, 32));
|
||||
DUMP_CL(COMPUTE_SIZE_WORKGROUP, &ctx->regs[33], "Workgroup size\n");
|
||||
pandecode_log("Job offset X: %u\n", cs_get_u32(ctx, 34));
|
||||
pandecode_log("Job offset Y: %u\n", cs_get_u32(ctx, 35));
|
||||
pandecode_log("Job offset Z: %u\n", cs_get_u32(ctx, 36));
|
||||
pandecode_log("Job size X: %u\n", cs_get_u32(ctx, 37));
|
||||
pandecode_log("Job size Y: %u\n", cs_get_u32(ctx, 38));
|
||||
pandecode_log("Job size Z: %u\n", cs_get_u32(ctx, 39));
|
||||
pandecode_log(ctx, "Global attribute offset: %u\n", cs_get_u32(qctx, 32));
|
||||
DUMP_CL(ctx, COMPUTE_SIZE_WORKGROUP, &qctx->regs[33], "Workgroup size\n");
|
||||
pandecode_log(ctx, "Job offset X: %u\n", cs_get_u32(qctx, 34));
|
||||
pandecode_log(ctx, "Job offset Y: %u\n", cs_get_u32(qctx, 35));
|
||||
pandecode_log(ctx, "Job offset Z: %u\n", cs_get_u32(qctx, 36));
|
||||
pandecode_log(ctx, "Job size X: %u\n", cs_get_u32(qctx, 37));
|
||||
pandecode_log(ctx, "Job size Y: %u\n", cs_get_u32(qctx, 38));
|
||||
pandecode_log(ctx, "Job size Z: %u\n", cs_get_u32(qctx, 39));
|
||||
|
||||
pandecode_indent--;
|
||||
ctx->indent--;
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_run_idvs(FILE *fp, struct queue_ctx *ctx, struct MALI_CEU_RUN_IDVS *I)
|
||||
pandecode_run_idvs(struct pandecode_context *ctx, FILE *fp,
|
||||
struct queue_ctx *qctx, struct MALI_CEU_RUN_IDVS *I)
|
||||
{
|
||||
/* Print the instruction. Ignore the selects and the flags override
|
||||
* since we'll print them implicitly later.
|
||||
|
|
@ -122,10 +124,10 @@ pandecode_run_idvs(FILE *fp, struct queue_ctx *ctx, struct MALI_CEU_RUN_IDVS *I)
|
|||
|
||||
fprintf(fp, "\n");
|
||||
|
||||
pandecode_indent++;
|
||||
ctx->indent++;
|
||||
|
||||
/* Merge flag overrides with the register flags */
|
||||
uint32_t tiler_flags_raw = cs_get_u64(ctx, 56);
|
||||
uint32_t tiler_flags_raw = cs_get_u64(qctx, 56);
|
||||
tiler_flags_raw |= I->flags_override;
|
||||
pan_unpack(&tiler_flags_raw, PRIMITIVE_FLAGS, tiler_flags);
|
||||
|
||||
|
|
@ -141,110 +143,113 @@ pandecode_run_idvs(FILE *fp, struct queue_ctx *ctx, struct MALI_CEU_RUN_IDVS *I)
|
|||
unsigned reg_frag_fau = 12;
|
||||
unsigned reg_frag_tsd = I->fragment_tsd_select ? 28 : 24;
|
||||
|
||||
uint64_t position_srt = cs_get_u64(ctx, reg_position_srt);
|
||||
uint64_t vary_srt = cs_get_u64(ctx, reg_vary_srt);
|
||||
uint64_t frag_srt = cs_get_u64(ctx, reg_frag_srt);
|
||||
uint64_t position_srt = cs_get_u64(qctx, reg_position_srt);
|
||||
uint64_t vary_srt = cs_get_u64(qctx, reg_vary_srt);
|
||||
uint64_t frag_srt = cs_get_u64(qctx, reg_frag_srt);
|
||||
|
||||
GENX(pandecode_resource_tables)(position_srt, "Position resources");
|
||||
GENX(pandecode_resource_tables)(vary_srt, "Varying resources");
|
||||
GENX(pandecode_resource_tables)(frag_srt, "Fragment resources");
|
||||
GENX(pandecode_resource_tables)(ctx, position_srt, "Position resources");
|
||||
GENX(pandecode_resource_tables)(ctx, vary_srt, "Varying resources");
|
||||
GENX(pandecode_resource_tables)(ctx, frag_srt, "Fragment resources");
|
||||
|
||||
mali_ptr position_fau = cs_get_u64(ctx, reg_position_fau);
|
||||
mali_ptr vary_fau = cs_get_u64(ctx, reg_vary_fau);
|
||||
mali_ptr fragment_fau = cs_get_u64(ctx, reg_frag_fau);
|
||||
mali_ptr position_fau = cs_get_u64(qctx, reg_position_fau);
|
||||
mali_ptr vary_fau = cs_get_u64(qctx, reg_vary_fau);
|
||||
mali_ptr fragment_fau = cs_get_u64(qctx, reg_frag_fau);
|
||||
|
||||
if (position_fau) {
|
||||
uint64_t lo = position_fau & BITFIELD64_MASK(48);
|
||||
uint64_t hi = position_fau >> 56;
|
||||
|
||||
GENX(pandecode_fau)(lo, hi, "Position FAU");
|
||||
GENX(pandecode_fau)(ctx, lo, hi, "Position FAU");
|
||||
}
|
||||
|
||||
if (vary_fau) {
|
||||
uint64_t lo = vary_fau & BITFIELD64_MASK(48);
|
||||
uint64_t hi = vary_fau >> 56;
|
||||
|
||||
GENX(pandecode_fau)(lo, hi, "Varying FAU");
|
||||
GENX(pandecode_fau)(ctx, lo, hi, "Varying FAU");
|
||||
}
|
||||
|
||||
if (fragment_fau) {
|
||||
uint64_t lo = fragment_fau & BITFIELD64_MASK(48);
|
||||
uint64_t hi = fragment_fau >> 56;
|
||||
|
||||
GENX(pandecode_fau)(lo, hi, "Fragment FAU");
|
||||
GENX(pandecode_fau)(ctx, lo, hi, "Fragment FAU");
|
||||
}
|
||||
|
||||
GENX(pandecode_shader)(cs_get_u64(ctx, 16), "Position shader", ctx->gpu_id);
|
||||
GENX(pandecode_shader)
|
||||
(ctx, cs_get_u64(qctx, 16), "Position shader", qctx->gpu_id);
|
||||
|
||||
if (tiler_flags.secondary_shader) {
|
||||
uint64_t ptr = cs_get_u64(ctx, 18);
|
||||
uint64_t ptr = cs_get_u64(qctx, 18);
|
||||
|
||||
GENX(pandecode_shader)(ptr, "Varying shader", ctx->gpu_id);
|
||||
GENX(pandecode_shader)(ctx, ptr, "Varying shader", qctx->gpu_id);
|
||||
}
|
||||
|
||||
GENX(pandecode_shader)(cs_get_u64(ctx, 20), "Fragment shader", ctx->gpu_id);
|
||||
GENX(pandecode_shader)
|
||||
(ctx, cs_get_u64(qctx, 20), "Fragment shader", qctx->gpu_id);
|
||||
|
||||
DUMP_ADDR(LOCAL_STORAGE, cs_get_u64(ctx, 24),
|
||||
DUMP_ADDR(ctx, LOCAL_STORAGE, cs_get_u64(qctx, 24),
|
||||
"Position Local Storage @%" PRIx64 ":\n",
|
||||
cs_get_u64(ctx, reg_position_tsd));
|
||||
DUMP_ADDR(LOCAL_STORAGE, cs_get_u64(ctx, 24),
|
||||
cs_get_u64(qctx, reg_position_tsd));
|
||||
DUMP_ADDR(ctx, LOCAL_STORAGE, cs_get_u64(qctx, 24),
|
||||
"Varying Local Storage @%" PRIx64 ":\n",
|
||||
cs_get_u64(ctx, reg_vary_tsd));
|
||||
DUMP_ADDR(LOCAL_STORAGE, cs_get_u64(ctx, 30),
|
||||
cs_get_u64(qctx, reg_vary_tsd));
|
||||
DUMP_ADDR(ctx, LOCAL_STORAGE, cs_get_u64(qctx, 30),
|
||||
"Fragment Local Storage @%" PRIx64 ":\n",
|
||||
cs_get_u64(ctx, reg_frag_tsd));
|
||||
cs_get_u64(qctx, reg_frag_tsd));
|
||||
|
||||
pandecode_log("Global attribute offset: %u\n", cs_get_u32(ctx, 32));
|
||||
pandecode_log("Index count: %u\n", cs_get_u32(ctx, 33));
|
||||
pandecode_log("Instance count: %u\n", cs_get_u32(ctx, 34));
|
||||
pandecode_log(ctx, "Global attribute offset: %u\n", cs_get_u32(qctx, 32));
|
||||
pandecode_log(ctx, "Index count: %u\n", cs_get_u32(qctx, 33));
|
||||
pandecode_log(ctx, "Instance count: %u\n", cs_get_u32(qctx, 34));
|
||||
|
||||
if (tiler_flags.index_type)
|
||||
pandecode_log("Index offset: %u\n", cs_get_u32(ctx, 35));
|
||||
pandecode_log(ctx, "Index offset: %u\n", cs_get_u32(qctx, 35));
|
||||
|
||||
pandecode_log("Vertex offset: %d\n", cs_get_u32(ctx, 36));
|
||||
pandecode_log("Instance offset: %u\n", cs_get_u32(ctx, 37));
|
||||
pandecode_log("Tiler DCD flags2: %X\n", cs_get_u32(ctx, 38));
|
||||
pandecode_log(ctx, "Vertex offset: %d\n", cs_get_u32(qctx, 36));
|
||||
pandecode_log(ctx, "Instance offset: %u\n", cs_get_u32(qctx, 37));
|
||||
pandecode_log(ctx, "Tiler DCD flags2: %X\n", cs_get_u32(qctx, 38));
|
||||
|
||||
if (tiler_flags.index_type)
|
||||
pandecode_log("Index array size: %u\n", cs_get_u32(ctx, 39));
|
||||
pandecode_log(ctx, "Index array size: %u\n", cs_get_u32(qctx, 39));
|
||||
|
||||
GENX(pandecode_tiler)(cs_get_u64(ctx, 40), ctx->gpu_id);
|
||||
GENX(pandecode_tiler)(ctx, cs_get_u64(qctx, 40), qctx->gpu_id);
|
||||
|
||||
DUMP_CL(SCISSOR, &ctx->regs[42], "Scissor\n");
|
||||
pandecode_log("Low depth clamp: %f\n", uif(cs_get_u32(ctx, 44)));
|
||||
pandecode_log("High depth clamp: %f\n", uif(cs_get_u32(ctx, 45)));
|
||||
pandecode_log("Occlusion: %" PRIx64 "\n", cs_get_u64(ctx, 46));
|
||||
DUMP_CL(ctx, SCISSOR, &qctx->regs[42], "Scissor\n");
|
||||
pandecode_log(ctx, "Low depth clamp: %f\n", uif(cs_get_u32(qctx, 44)));
|
||||
pandecode_log(ctx, "High depth clamp: %f\n", uif(cs_get_u32(qctx, 45)));
|
||||
pandecode_log(ctx, "Occlusion: %" PRIx64 "\n", cs_get_u64(qctx, 46));
|
||||
|
||||
if (tiler_flags.secondary_shader)
|
||||
pandecode_log("Varying allocation: %u\n", cs_get_u32(ctx, 48));
|
||||
pandecode_log(ctx, "Varying allocation: %u\n", cs_get_u32(qctx, 48));
|
||||
|
||||
mali_ptr blend = cs_get_u64(ctx, 50);
|
||||
GENX(pandecode_blend_descs)(blend & ~7, blend & 7, 0, ctx->gpu_id);
|
||||
mali_ptr blend = cs_get_u64(qctx, 50);
|
||||
GENX(pandecode_blend_descs)(ctx, blend & ~7, blend & 7, 0, qctx->gpu_id);
|
||||
|
||||
DUMP_ADDR(DEPTH_STENCIL, cs_get_u64(ctx, 52), "Depth/stencil");
|
||||
DUMP_ADDR(ctx, DEPTH_STENCIL, cs_get_u64(qctx, 52), "Depth/stencil");
|
||||
|
||||
if (tiler_flags.index_type)
|
||||
pandecode_log("Indices: %" PRIx64 "\n", cs_get_u64(ctx, 54));
|
||||
pandecode_log(ctx, "Indices: %" PRIx64 "\n", cs_get_u64(qctx, 54));
|
||||
|
||||
DUMP_UNPACKED(PRIMITIVE_FLAGS, tiler_flags, "Primitive flags\n");
|
||||
DUMP_CL(DCD_FLAGS_0, &ctx->regs[57], "DCD Flags 0\n");
|
||||
DUMP_CL(DCD_FLAGS_1, &ctx->regs[58], "DCD Flags 1\n");
|
||||
DUMP_CL(PRIMITIVE_SIZE, &ctx->regs[60], "Primitive size\n");
|
||||
DUMP_UNPACKED(ctx, PRIMITIVE_FLAGS, tiler_flags, "Primitive flags\n");
|
||||
DUMP_CL(ctx, DCD_FLAGS_0, &qctx->regs[57], "DCD Flags 0\n");
|
||||
DUMP_CL(ctx, DCD_FLAGS_1, &qctx->regs[58], "DCD Flags 1\n");
|
||||
DUMP_CL(ctx, PRIMITIVE_SIZE, &qctx->regs[60], "Primitive size\n");
|
||||
|
||||
pandecode_indent--;
|
||||
ctx->indent--;
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_run_fragment(struct queue_ctx *ctx, struct MALI_CEU_RUN_FRAGMENT *I)
|
||||
pandecode_run_fragment(struct pandecode_context *ctx, struct queue_ctx *qctx,
|
||||
struct MALI_CEU_RUN_FRAGMENT *I)
|
||||
{
|
||||
pandecode_indent++;
|
||||
ctx->indent++;
|
||||
|
||||
DUMP_CL(SCISSOR, &ctx->regs[42], "Scissor\n");
|
||||
DUMP_CL(ctx, SCISSOR, &qctx->regs[42], "Scissor\n");
|
||||
|
||||
/* TODO: Tile enable map */
|
||||
GENX(pandecode_fbd)(cs_get_u64(ctx, 40), true, ctx->gpu_id);
|
||||
GENX(pandecode_fbd)(ctx, cs_get_u64(qctx, 40), true, qctx->gpu_id);
|
||||
|
||||
pandecode_indent--;
|
||||
ctx->indent--;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -271,8 +276,9 @@ print_reg_tuple(unsigned base, uint16_t mask, FILE *fp)
|
|||
}
|
||||
|
||||
static void
|
||||
disassemble_ceu_instr(uint64_t dword, unsigned indent, bool verbose, FILE *fp,
|
||||
struct queue_ctx *ctx)
|
||||
disassemble_ceu_instr(struct pandecode_context *ctx, uint64_t dword,
|
||||
unsigned indent, bool verbose, FILE *fp,
|
||||
struct queue_ctx *qctx)
|
||||
{
|
||||
if (verbose) {
|
||||
fprintf(fp, " ");
|
||||
|
|
@ -327,13 +333,13 @@ disassemble_ceu_instr(uint64_t dword, unsigned indent, bool verbose, FILE *fp,
|
|||
|
||||
case MALI_CEU_OPCODE_RUN_COMPUTE: {
|
||||
pan_unpack(bytes, CEU_RUN_COMPUTE, I);
|
||||
pandecode_run_compute(fp, ctx, &I);
|
||||
pandecode_run_compute(ctx, fp, qctx, &I);
|
||||
break;
|
||||
}
|
||||
|
||||
case MALI_CEU_OPCODE_RUN_IDVS: {
|
||||
pan_unpack(bytes, CEU_RUN_IDVS, I);
|
||||
pandecode_run_idvs(fp, ctx, &I);
|
||||
pandecode_run_idvs(ctx, fp, qctx, &I);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -341,7 +347,7 @@ disassemble_ceu_instr(uint64_t dword, unsigned indent, bool verbose, FILE *fp,
|
|||
pan_unpack(bytes, CEU_RUN_FRAGMENT, I);
|
||||
fprintf(fp, "RUN_FRAGMENT%s\n",
|
||||
I.enable_tem ? ".tile_enable_map_enable" : "");
|
||||
pandecode_run_fragment(ctx, &I);
|
||||
pandecode_run_fragment(ctx, qctx, &I);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -593,12 +599,12 @@ disassemble_ceu_instr(uint64_t dword, unsigned indent, bool verbose, FILE *fp,
|
|||
}
|
||||
|
||||
static bool
|
||||
interpret_ceu_jump(struct queue_ctx *ctx, uint64_t reg_address,
|
||||
uint32_t reg_length)
|
||||
interpret_ceu_jump(struct pandecode_context *ctx, struct queue_ctx *qctx,
|
||||
uint64_t reg_address, uint32_t reg_length)
|
||||
{
|
||||
uint32_t address_lo = ctx->regs[reg_address];
|
||||
uint32_t address_hi = ctx->regs[reg_address + 1];
|
||||
uint32_t length = ctx->regs[reg_length];
|
||||
uint32_t address_lo = qctx->regs[reg_address];
|
||||
uint32_t address_hi = qctx->regs[reg_address + 1];
|
||||
uint32_t length = qctx->regs[reg_length];
|
||||
|
||||
if (length % 8) {
|
||||
fprintf(stderr, "CS call alignment error\n");
|
||||
|
|
@ -607,10 +613,10 @@ interpret_ceu_jump(struct queue_ctx *ctx, uint64_t reg_address,
|
|||
|
||||
/* Map the entire subqueue now */
|
||||
uint64_t address = ((uint64_t)address_hi << 32) | address_lo;
|
||||
uint64_t *cs = pandecode_fetch_gpu_mem(address, length);
|
||||
uint64_t *cs = pandecode_fetch_gpu_mem(ctx, address, length);
|
||||
|
||||
ctx->ip = cs;
|
||||
ctx->end = cs + (length / 8);
|
||||
qctx->ip = cs;
|
||||
qctx->end = cs + (length / 8);
|
||||
|
||||
/* Skip the usual IP update */
|
||||
return true;
|
||||
|
|
@ -624,34 +630,34 @@ interpret_ceu_jump(struct queue_ctx *ctx, uint64_t reg_address,
|
|||
* Returns true if execution should continue.
|
||||
*/
|
||||
static bool
|
||||
interpret_ceu_instr(struct queue_ctx *ctx)
|
||||
interpret_ceu_instr(struct pandecode_context *ctx, struct queue_ctx *qctx)
|
||||
{
|
||||
/* Unpack the base so we get the opcode */
|
||||
uint8_t *bytes = (uint8_t *)ctx->ip;
|
||||
uint8_t *bytes = (uint8_t *)qctx->ip;
|
||||
pan_unpack(bytes, CEU_BASE, base);
|
||||
|
||||
assert(ctx->ip < ctx->end);
|
||||
assert(qctx->ip < qctx->end);
|
||||
|
||||
switch (base.opcode) {
|
||||
case MALI_CEU_OPCODE_MOVE: {
|
||||
pan_unpack(bytes, CEU_MOVE, I);
|
||||
|
||||
ctx->regs[I.destination + 0] = (uint32_t)I.immediate;
|
||||
ctx->regs[I.destination + 1] = (uint32_t)(I.immediate >> 32);
|
||||
qctx->regs[I.destination + 0] = (uint32_t)I.immediate;
|
||||
qctx->regs[I.destination + 1] = (uint32_t)(I.immediate >> 32);
|
||||
break;
|
||||
}
|
||||
|
||||
case MALI_CEU_OPCODE_MOVE32: {
|
||||
pan_unpack(bytes, CEU_MOVE32, I);
|
||||
|
||||
ctx->regs[I.destination] = I.immediate;
|
||||
qctx->regs[I.destination] = I.immediate;
|
||||
break;
|
||||
}
|
||||
|
||||
case MALI_CEU_OPCODE_ADD_IMMEDIATE32: {
|
||||
pan_unpack(bytes, CEU_ADD_IMMEDIATE32, I);
|
||||
|
||||
ctx->regs[I.destination] = ctx->regs[I.source] + I.immediate;
|
||||
qctx->regs[I.destination] = qctx->regs[I.source] + I.immediate;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -659,46 +665,46 @@ interpret_ceu_instr(struct queue_ctx *ctx)
|
|||
pan_unpack(bytes, CEU_ADD_IMMEDIATE64, I);
|
||||
|
||||
int64_t value =
|
||||
(ctx->regs[I.source] | ((int64_t)ctx->regs[I.source + 1] << 32)) +
|
||||
(qctx->regs[I.source] | ((int64_t)qctx->regs[I.source + 1] << 32)) +
|
||||
I.immediate;
|
||||
|
||||
ctx->regs[I.destination] = value;
|
||||
ctx->regs[I.destination + 1] = value >> 32;
|
||||
qctx->regs[I.destination] = value;
|
||||
qctx->regs[I.destination + 1] = value >> 32;
|
||||
break;
|
||||
}
|
||||
|
||||
case MALI_CEU_OPCODE_CALL: {
|
||||
pan_unpack(bytes, CEU_CALL, I);
|
||||
|
||||
if (ctx->call_stack_depth == MAX_CALL_STACK_DEPTH) {
|
||||
if (qctx->call_stack_depth == MAX_CALL_STACK_DEPTH) {
|
||||
fprintf(stderr, "CS call stack overflow\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(ctx->call_stack_depth < MAX_CALL_STACK_DEPTH);
|
||||
assert(qctx->call_stack_depth < MAX_CALL_STACK_DEPTH);
|
||||
|
||||
ctx->ip++;
|
||||
qctx->ip++;
|
||||
|
||||
/* Note: tail calls are not optimized in the hardware. */
|
||||
assert(ctx->ip <= ctx->end);
|
||||
assert(qctx->ip <= qctx->end);
|
||||
|
||||
unsigned depth = ctx->call_stack_depth++;
|
||||
unsigned depth = qctx->call_stack_depth++;
|
||||
|
||||
ctx->call_stack[depth].lr = ctx->ip;
|
||||
ctx->call_stack[depth].end = ctx->end;
|
||||
qctx->call_stack[depth].lr = qctx->ip;
|
||||
qctx->call_stack[depth].end = qctx->end;
|
||||
|
||||
return interpret_ceu_jump(ctx, I.address, I.length);
|
||||
return interpret_ceu_jump(ctx, qctx, I.address, I.length);
|
||||
}
|
||||
|
||||
case MALI_CEU_OPCODE_JUMP: {
|
||||
pan_unpack(bytes, CEU_CALL, I);
|
||||
|
||||
if (ctx->call_stack_depth == 0) {
|
||||
if (qctx->call_stack_depth == 0) {
|
||||
fprintf(stderr, "Cannot jump from the entrypoint\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return interpret_ceu_jump(ctx, I.address, I.length);
|
||||
return interpret_ceu_jump(ctx, qctx, I.address, I.length);
|
||||
}
|
||||
|
||||
default:
|
||||
|
|
@ -708,35 +714,35 @@ interpret_ceu_instr(struct queue_ctx *ctx)
|
|||
/* Update IP first to point to the next instruction, so call doesn't
|
||||
* require special handling (even for tail calls).
|
||||
*/
|
||||
ctx->ip++;
|
||||
qctx->ip++;
|
||||
|
||||
while (ctx->ip == ctx->end) {
|
||||
while (qctx->ip == qctx->end) {
|
||||
/* Graceful termination */
|
||||
if (ctx->call_stack_depth == 0)
|
||||
if (qctx->call_stack_depth == 0)
|
||||
return false;
|
||||
|
||||
/* Pop off the call stack */
|
||||
unsigned old_depth = --ctx->call_stack_depth;
|
||||
unsigned old_depth = --qctx->call_stack_depth;
|
||||
|
||||
ctx->ip = ctx->call_stack[old_depth].lr;
|
||||
ctx->end = ctx->call_stack[old_depth].end;
|
||||
qctx->ip = qctx->call_stack[old_depth].lr;
|
||||
qctx->end = qctx->call_stack[old_depth].end;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GENX(pandecode_cs)(mali_ptr queue, uint32_t size, unsigned gpu_id,
|
||||
uint32_t *regs)
|
||||
GENX(pandecode_cs)(struct pandecode_context *ctx, mali_ptr queue, uint32_t size,
|
||||
unsigned gpu_id, uint32_t *regs)
|
||||
{
|
||||
pandecode_dump_file_open();
|
||||
pandecode_dump_file_open(ctx);
|
||||
|
||||
uint64_t *cs = pandecode_fetch_gpu_mem(queue, size);
|
||||
uint64_t *cs = pandecode_fetch_gpu_mem(ctx, queue, size);
|
||||
|
||||
/* Mali-G610 has 96 registers. Other devices not yet supported, we can make
|
||||
* this configurable later when we encounter new Malis.
|
||||
*/
|
||||
struct queue_ctx ctx = {
|
||||
struct queue_ctx qctx = {
|
||||
.nr_regs = 96,
|
||||
.regs = regs,
|
||||
.ip = cs,
|
||||
|
|
@ -746,12 +752,12 @@ GENX(pandecode_cs)(mali_ptr queue, uint32_t size, unsigned gpu_id,
|
|||
|
||||
if (size) {
|
||||
do {
|
||||
disassemble_ceu_instr(*(ctx.ip), 1 + ctx.call_stack_depth, true,
|
||||
pandecode_dump_stream, &ctx);
|
||||
} while (interpret_ceu_instr(&ctx));
|
||||
disassemble_ceu_instr(ctx, *(qctx.ip), 1 + qctx.call_stack_depth, true,
|
||||
ctx->dump_stream, &qctx);
|
||||
} while (interpret_ceu_instr(ctx, &qctx));
|
||||
}
|
||||
|
||||
fflush(pandecode_dump_stream);
|
||||
pandecode_map_read_write();
|
||||
fflush(ctx->dump_stream);
|
||||
pandecode_map_read_write(ctx);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@
|
|||
#if PAN_ARCH <= 9
|
||||
|
||||
static void
|
||||
pandecode_primitive(const void *p)
|
||||
pandecode_primitive(struct pandecode_context *ctx, const void *p)
|
||||
{
|
||||
pan_unpack(p, PRIMITIVE, primitive);
|
||||
DUMP_UNPACKED(PRIMITIVE, primitive, "Primitive:\n");
|
||||
DUMP_UNPACKED(ctx, PRIMITIVE, primitive, "Primitive:\n");
|
||||
|
||||
#if PAN_ARCH <= 7
|
||||
/* Validate an index buffer is present if we need one. TODO: verify
|
||||
|
|
@ -50,41 +50,41 @@ pandecode_primitive(const void *p)
|
|||
* size */
|
||||
|
||||
if (!size)
|
||||
pandecode_log("// XXX: index size missing\n");
|
||||
pandecode_log(ctx, "// XXX: index size missing\n");
|
||||
else
|
||||
pandecode_validate_buffer(primitive.indices,
|
||||
pandecode_validate_buffer(ctx, primitive.indices,
|
||||
primitive.index_count * size);
|
||||
} else if (primitive.index_type)
|
||||
pandecode_log("// XXX: unexpected index size\n");
|
||||
pandecode_log(ctx, "// XXX: unexpected index size\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PAN_ARCH <= 7
|
||||
static void
|
||||
pandecode_attributes(mali_ptr addr, int count, bool varying,
|
||||
enum mali_job_type job_type)
|
||||
pandecode_attributes(struct pandecode_context *ctx, mali_ptr addr, int count,
|
||||
bool varying, enum mali_job_type job_type)
|
||||
{
|
||||
char *prefix = varying ? "Varying" : "Attribute";
|
||||
assert(addr);
|
||||
|
||||
if (!count) {
|
||||
pandecode_log("// warn: No %s records\n", prefix);
|
||||
pandecode_log(ctx, "// warn: No %s records\n", prefix);
|
||||
return;
|
||||
}
|
||||
|
||||
MAP_ADDR(ATTRIBUTE_BUFFER, addr, cl);
|
||||
MAP_ADDR(ctx, ATTRIBUTE_BUFFER, addr, cl);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
pan_unpack(cl + i * pan_size(ATTRIBUTE_BUFFER), ATTRIBUTE_BUFFER, temp);
|
||||
DUMP_UNPACKED(ATTRIBUTE_BUFFER, temp, "%s:\n", prefix);
|
||||
DUMP_UNPACKED(ctx, ATTRIBUTE_BUFFER, temp, "%s:\n", prefix);
|
||||
|
||||
switch (temp.type) {
|
||||
case MALI_ATTRIBUTE_TYPE_1D_NPOT_DIVISOR_WRITE_REDUCTION:
|
||||
case MALI_ATTRIBUTE_TYPE_1D_NPOT_DIVISOR: {
|
||||
pan_unpack(cl + (i + 1) * pan_size(ATTRIBUTE_BUFFER),
|
||||
ATTRIBUTE_BUFFER_CONTINUATION_NPOT, temp2);
|
||||
pan_print(pandecode_dump_stream, ATTRIBUTE_BUFFER_CONTINUATION_NPOT,
|
||||
temp2, (pandecode_indent + 1) * 2);
|
||||
pan_print(ctx->dump_stream, ATTRIBUTE_BUFFER_CONTINUATION_NPOT, temp2,
|
||||
(ctx->indent + 1) * 2);
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
|
|
@ -92,8 +92,8 @@ pandecode_attributes(mali_ptr addr, int count, bool varying,
|
|||
case MALI_ATTRIBUTE_TYPE_3D_INTERLEAVED: {
|
||||
pan_unpack(cl + (i + 1) * pan_size(ATTRIBUTE_BUFFER_CONTINUATION_3D),
|
||||
ATTRIBUTE_BUFFER_CONTINUATION_3D, temp2);
|
||||
pan_print(pandecode_dump_stream, ATTRIBUTE_BUFFER_CONTINUATION_3D,
|
||||
temp2, (pandecode_indent + 1) * 2);
|
||||
pan_print(ctx->dump_stream, ATTRIBUTE_BUFFER_CONTINUATION_3D, temp2,
|
||||
(ctx->indent + 1) * 2);
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
|
|
@ -101,22 +101,24 @@ pandecode_attributes(mali_ptr addr, int count, bool varying,
|
|||
break;
|
||||
}
|
||||
}
|
||||
pandecode_log("\n");
|
||||
pandecode_log(ctx, "\n");
|
||||
}
|
||||
|
||||
static unsigned
|
||||
pandecode_attribute_meta(int count, mali_ptr attribute, bool varying)
|
||||
pandecode_attribute_meta(struct pandecode_context *ctx, int count,
|
||||
mali_ptr attribute, bool varying)
|
||||
{
|
||||
unsigned max = 0;
|
||||
|
||||
for (int i = 0; i < count; ++i, attribute += pan_size(ATTRIBUTE)) {
|
||||
MAP_ADDR(ATTRIBUTE, attribute, cl);
|
||||
MAP_ADDR(ctx, ATTRIBUTE, attribute, cl);
|
||||
pan_unpack(cl, ATTRIBUTE, a);
|
||||
DUMP_UNPACKED(ATTRIBUTE, a, "%s:\n", varying ? "Varying" : "Attribute");
|
||||
DUMP_UNPACKED(ctx, ATTRIBUTE, a, "%s:\n",
|
||||
varying ? "Varying" : "Attribute");
|
||||
max = MAX2(max, a.buffer_index);
|
||||
}
|
||||
|
||||
pandecode_log("\n");
|
||||
pandecode_log(ctx, "\n");
|
||||
return MIN2(max + 1, 256);
|
||||
}
|
||||
|
||||
|
|
@ -134,7 +136,7 @@ bits(u32 word, u32 lo, u32 hi)
|
|||
}
|
||||
|
||||
static void
|
||||
pandecode_invocation(const void *i)
|
||||
pandecode_invocation(struct pandecode_context *ctx, const void *i)
|
||||
{
|
||||
/* Decode invocation_count. See the comment before the definition of
|
||||
* invocation_count for an explanation.
|
||||
|
|
@ -161,94 +163,98 @@ pandecode_invocation(const void *i)
|
|||
unsigned groups_z =
|
||||
bits(invocation.invocations, invocation.workgroups_z_shift, 32) + 1;
|
||||
|
||||
pandecode_log("Invocation (%d, %d, %d) x (%d, %d, %d)\n", size_x, size_y,
|
||||
size_z, groups_x, groups_y, groups_z);
|
||||
pandecode_log(ctx, "Invocation (%d, %d, %d) x (%d, %d, %d)\n", size_x,
|
||||
size_y, size_z, groups_x, groups_y, groups_z);
|
||||
|
||||
DUMP_UNPACKED(INVOCATION, invocation, "Invocation:\n")
|
||||
DUMP_UNPACKED(ctx, INVOCATION, invocation, "Invocation:\n")
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_textures(mali_ptr textures, unsigned texture_count)
|
||||
pandecode_textures(struct pandecode_context *ctx, mali_ptr textures,
|
||||
unsigned texture_count)
|
||||
{
|
||||
if (!textures)
|
||||
return;
|
||||
|
||||
pandecode_log("Textures %" PRIx64 ":\n", textures);
|
||||
pandecode_indent++;
|
||||
pandecode_log(ctx, "Textures %" PRIx64 ":\n", textures);
|
||||
ctx->indent++;
|
||||
|
||||
#if PAN_ARCH >= 6
|
||||
const void *cl =
|
||||
pandecode_fetch_gpu_mem(textures, pan_size(TEXTURE) * texture_count);
|
||||
pandecode_fetch_gpu_mem(ctx, textures, pan_size(TEXTURE) * texture_count);
|
||||
|
||||
for (unsigned tex = 0; tex < texture_count; ++tex)
|
||||
GENX(pandecode_texture)(cl + pan_size(TEXTURE) * tex, tex);
|
||||
GENX(pandecode_texture)(ctx, cl + pan_size(TEXTURE) * tex, tex);
|
||||
#else
|
||||
mali_ptr *PANDECODE_PTR_VAR(u, textures);
|
||||
mali_ptr *PANDECODE_PTR_VAR(ctx, u, textures);
|
||||
|
||||
for (int tex = 0; tex < texture_count; ++tex) {
|
||||
mali_ptr *PANDECODE_PTR_VAR(u, textures + tex * sizeof(mali_ptr));
|
||||
char *a = pointer_as_memory_reference(*u);
|
||||
pandecode_log("%s,\n", a);
|
||||
mali_ptr *PANDECODE_PTR_VAR(ctx, u, textures + tex * sizeof(mali_ptr));
|
||||
char *a = pointer_as_memory_reference(ctx, *u);
|
||||
pandecode_log(ctx, "%s,\n", a);
|
||||
free(a);
|
||||
}
|
||||
|
||||
/* Now, finally, descend down into the texture descriptor */
|
||||
for (unsigned tex = 0; tex < texture_count; ++tex) {
|
||||
mali_ptr *PANDECODE_PTR_VAR(u, textures + tex * sizeof(mali_ptr));
|
||||
GENX(pandecode_texture)(*u, tex);
|
||||
mali_ptr *PANDECODE_PTR_VAR(ctx, u, textures + tex * sizeof(mali_ptr));
|
||||
GENX(pandecode_texture)(ctx, *u, tex);
|
||||
}
|
||||
#endif
|
||||
pandecode_indent--;
|
||||
pandecode_log("\n");
|
||||
ctx->indent--;
|
||||
pandecode_log(ctx, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_samplers(mali_ptr samplers, unsigned sampler_count)
|
||||
pandecode_samplers(struct pandecode_context *ctx, mali_ptr samplers,
|
||||
unsigned sampler_count)
|
||||
{
|
||||
pandecode_log("Samplers %" PRIx64 ":\n", samplers);
|
||||
pandecode_indent++;
|
||||
pandecode_log(ctx, "Samplers %" PRIx64 ":\n", samplers);
|
||||
ctx->indent++;
|
||||
|
||||
for (int i = 0; i < sampler_count; ++i)
|
||||
DUMP_ADDR(SAMPLER, samplers + (pan_size(SAMPLER) * i), "Sampler %d:\n",
|
||||
i);
|
||||
DUMP_ADDR(ctx, SAMPLER, samplers + (pan_size(SAMPLER) * i),
|
||||
"Sampler %d:\n", i);
|
||||
|
||||
pandecode_indent--;
|
||||
pandecode_log("\n");
|
||||
ctx->indent--;
|
||||
pandecode_log(ctx, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_uniform_buffers(mali_ptr pubufs, int ubufs_count)
|
||||
pandecode_uniform_buffers(struct pandecode_context *ctx, mali_ptr pubufs,
|
||||
int ubufs_count)
|
||||
{
|
||||
uint64_t *PANDECODE_PTR_VAR(ubufs, pubufs);
|
||||
uint64_t *PANDECODE_PTR_VAR(ctx, ubufs, pubufs);
|
||||
|
||||
for (int i = 0; i < ubufs_count; i++) {
|
||||
mali_ptr addr = (ubufs[i] >> 10) << 2;
|
||||
unsigned size = addr ? (((ubufs[i] & ((1 << 10) - 1)) + 1) * 16) : 0;
|
||||
|
||||
pandecode_validate_buffer(addr, size);
|
||||
pandecode_validate_buffer(ctx, addr, size);
|
||||
|
||||
char *ptr = pointer_as_memory_reference(addr);
|
||||
pandecode_log("ubuf_%d[%u] = %s;\n", i, size, ptr);
|
||||
char *ptr = pointer_as_memory_reference(ctx, addr);
|
||||
pandecode_log(ctx, "ubuf_%d[%u] = %s;\n", i, size, ptr);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
pandecode_log("\n");
|
||||
pandecode_log(ctx, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_uniforms(mali_ptr uniforms, unsigned uniform_count)
|
||||
pandecode_uniforms(struct pandecode_context *ctx, mali_ptr uniforms,
|
||||
unsigned uniform_count)
|
||||
{
|
||||
pandecode_validate_buffer(uniforms, uniform_count * 16);
|
||||
pandecode_validate_buffer(ctx, uniforms, uniform_count * 16);
|
||||
|
||||
char *ptr = pointer_as_memory_reference(uniforms);
|
||||
pandecode_log("vec4 uniforms[%u] = %s;\n", uniform_count, ptr);
|
||||
char *ptr = pointer_as_memory_reference(ctx, uniforms);
|
||||
pandecode_log(ctx, "vec4 uniforms[%u] = %s;\n", uniform_count, ptr);
|
||||
free(ptr);
|
||||
pandecode_log("\n");
|
||||
pandecode_log(ctx, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
GENX(pandecode_dcd)(const struct MALI_DRAW *p, enum mali_job_type job_type,
|
||||
unsigned gpu_id)
|
||||
GENX(pandecode_dcd)(struct pandecode_context *ctx, const struct MALI_DRAW *p,
|
||||
enum mali_job_type job_type, unsigned gpu_id)
|
||||
{
|
||||
#if PAN_ARCH >= 5
|
||||
struct pandecode_fbd fbd_info = {.rt_count = 1};
|
||||
|
|
@ -256,7 +262,7 @@ GENX(pandecode_dcd)(const struct MALI_DRAW *p, enum mali_job_type job_type,
|
|||
|
||||
if (PAN_ARCH >= 6 || (PAN_ARCH == 5 && job_type != MALI_JOB_TYPE_TILER)) {
|
||||
#if PAN_ARCH >= 5
|
||||
DUMP_ADDR(LOCAL_STORAGE, p->thread_storage & ~1, "Local Storage:\n");
|
||||
DUMP_ADDR(ctx, LOCAL_STORAGE, p->thread_storage & ~1, "Local Storage:\n");
|
||||
#endif
|
||||
} else {
|
||||
#if PAN_ARCH == 5
|
||||
|
|
@ -268,13 +274,12 @@ GENX(pandecode_dcd)(const struct MALI_DRAW *p, enum mali_job_type job_type,
|
|||
if (!ptr.type || ptr.zs_crc_extension_present ||
|
||||
ptr.render_target_count != 1) {
|
||||
|
||||
fprintf(pandecode_dump_stream,
|
||||
"Unexpected framebuffer pointer settings");
|
||||
fprintf(ctx->dump_stream, "Unexpected framebuffer pointer settings");
|
||||
}
|
||||
|
||||
GENX(pandecode_fbd)(ptr.pointer, false, gpu_id);
|
||||
GENX(pandecode_fbd)(ctx, ptr.pointer, false, gpu_id);
|
||||
#elif PAN_ARCH == 4
|
||||
GENX(pandecode_fbd)(p->fbd, false, gpu_id);
|
||||
GENX(pandecode_fbd)(ctx, p->fbd, false, gpu_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -284,21 +289,21 @@ GENX(pandecode_dcd)(const struct MALI_DRAW *p, enum mali_job_type job_type,
|
|||
|
||||
if (p->state) {
|
||||
uint32_t *cl =
|
||||
pandecode_fetch_gpu_mem(p->state, pan_size(RENDERER_STATE));
|
||||
pandecode_fetch_gpu_mem(ctx, p->state, pan_size(RENDERER_STATE));
|
||||
|
||||
pan_unpack(cl, RENDERER_STATE, state);
|
||||
|
||||
if (state.shader.shader & ~0xF)
|
||||
pandecode_shader_disassemble(state.shader.shader & ~0xF, gpu_id);
|
||||
pandecode_shader_disassemble(ctx, state.shader.shader & ~0xF, gpu_id);
|
||||
|
||||
#if PAN_ARCH >= 6
|
||||
bool idvs = (job_type == MALI_JOB_TYPE_INDEXED_VERTEX);
|
||||
|
||||
if (idvs && state.secondary_shader)
|
||||
pandecode_shader_disassemble(state.secondary_shader, gpu_id);
|
||||
pandecode_shader_disassemble(ctx, state.secondary_shader, gpu_id);
|
||||
#endif
|
||||
DUMP_UNPACKED(RENDERER_STATE, state, "State:\n");
|
||||
pandecode_indent++;
|
||||
DUMP_UNPACKED(ctx, RENDERER_STATE, state, "State:\n");
|
||||
ctx->indent++;
|
||||
|
||||
/* Save for dumps */
|
||||
attribute_count = state.shader.attribute_count;
|
||||
|
|
@ -316,10 +321,10 @@ GENX(pandecode_dcd)(const struct MALI_DRAW *p, enum mali_job_type job_type,
|
|||
#if PAN_ARCH == 4
|
||||
mali_ptr shader = state.blend_shader & ~0xF;
|
||||
if (state.multisample_misc.blend_shader && shader)
|
||||
pandecode_shader_disassemble(shader, gpu_id);
|
||||
pandecode_shader_disassemble(ctx, shader, gpu_id);
|
||||
#endif
|
||||
pandecode_indent--;
|
||||
pandecode_log("\n");
|
||||
ctx->indent--;
|
||||
pandecode_log(ctx, "\n");
|
||||
|
||||
/* MRT blend fields are used on v5+. Technically, they are optional on v5
|
||||
* for backwards compatibility but we don't care about that.
|
||||
|
|
@ -332,141 +337,146 @@ GENX(pandecode_dcd)(const struct MALI_DRAW *p, enum mali_job_type job_type,
|
|||
|
||||
for (unsigned i = 0; i < fbd_info.rt_count; i++) {
|
||||
mali_ptr shader =
|
||||
GENX(pandecode_blend)(blend_base, i, state.shader.shader);
|
||||
GENX(pandecode_blend)(ctx, blend_base, i, state.shader.shader);
|
||||
if (shader & ~0xF)
|
||||
pandecode_shader_disassemble(shader, gpu_id);
|
||||
pandecode_shader_disassemble(ctx, shader, gpu_id);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
pandecode_log("// XXX: missing shader descriptor\n");
|
||||
pandecode_log(ctx, "// XXX: missing shader descriptor\n");
|
||||
|
||||
if (p->viewport) {
|
||||
DUMP_ADDR(VIEWPORT, p->viewport, "Viewport:\n");
|
||||
pandecode_log("\n");
|
||||
DUMP_ADDR(ctx, VIEWPORT, p->viewport, "Viewport:\n");
|
||||
pandecode_log(ctx, "\n");
|
||||
}
|
||||
|
||||
unsigned max_attr_index = 0;
|
||||
|
||||
if (p->attributes)
|
||||
max_attr_index =
|
||||
pandecode_attribute_meta(attribute_count, p->attributes, false);
|
||||
pandecode_attribute_meta(ctx, attribute_count, p->attributes, false);
|
||||
|
||||
if (p->attribute_buffers)
|
||||
pandecode_attributes(p->attribute_buffers, max_attr_index, false,
|
||||
pandecode_attributes(ctx, p->attribute_buffers, max_attr_index, false,
|
||||
job_type);
|
||||
|
||||
if (p->varyings) {
|
||||
varying_count =
|
||||
pandecode_attribute_meta(varying_count, p->varyings, true);
|
||||
pandecode_attribute_meta(ctx, varying_count, p->varyings, true);
|
||||
}
|
||||
|
||||
if (p->varying_buffers)
|
||||
pandecode_attributes(p->varying_buffers, varying_count, true, job_type);
|
||||
pandecode_attributes(ctx, p->varying_buffers, varying_count, true,
|
||||
job_type);
|
||||
|
||||
if (p->uniform_buffers) {
|
||||
if (uniform_buffer_count)
|
||||
pandecode_uniform_buffers(p->uniform_buffers, uniform_buffer_count);
|
||||
pandecode_uniform_buffers(ctx, p->uniform_buffers,
|
||||
uniform_buffer_count);
|
||||
else
|
||||
pandecode_log("// warn: UBOs specified but not referenced\n");
|
||||
pandecode_log(ctx, "// warn: UBOs specified but not referenced\n");
|
||||
} else if (uniform_buffer_count)
|
||||
pandecode_log("// XXX: UBOs referenced but not specified\n");
|
||||
pandecode_log(ctx, "// XXX: UBOs referenced but not specified\n");
|
||||
|
||||
/* We don't want to actually dump uniforms, but we do need to validate
|
||||
* that the counts we were given are sane */
|
||||
|
||||
if (p->push_uniforms) {
|
||||
if (uniform_count)
|
||||
pandecode_uniforms(p->push_uniforms, uniform_count);
|
||||
pandecode_uniforms(ctx, p->push_uniforms, uniform_count);
|
||||
else
|
||||
pandecode_log("// warn: Uniforms specified but not referenced\n");
|
||||
pandecode_log(ctx, "// warn: Uniforms specified but not referenced\n");
|
||||
} else if (uniform_count)
|
||||
pandecode_log("// XXX: Uniforms referenced but not specified\n");
|
||||
pandecode_log(ctx, "// XXX: Uniforms referenced but not specified\n");
|
||||
|
||||
if (p->textures)
|
||||
pandecode_textures(p->textures, texture_count);
|
||||
pandecode_textures(ctx, p->textures, texture_count);
|
||||
|
||||
if (p->samplers)
|
||||
pandecode_samplers(p->samplers, sampler_count);
|
||||
pandecode_samplers(ctx, p->samplers, sampler_count);
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_vertex_compute_geometry_job(const struct MALI_JOB_HEADER *h,
|
||||
pandecode_vertex_compute_geometry_job(struct pandecode_context *ctx,
|
||||
const struct MALI_JOB_HEADER *h,
|
||||
mali_ptr job, unsigned gpu_id)
|
||||
{
|
||||
struct mali_compute_job_packed *PANDECODE_PTR_VAR(p, job);
|
||||
struct mali_compute_job_packed *PANDECODE_PTR_VAR(ctx, p, job);
|
||||
pan_section_unpack(p, COMPUTE_JOB, DRAW, draw);
|
||||
GENX(pandecode_dcd)(&draw, h->type, gpu_id);
|
||||
GENX(pandecode_dcd)(ctx, &draw, h->type, gpu_id);
|
||||
|
||||
pandecode_log("Vertex Job Payload:\n");
|
||||
pandecode_indent++;
|
||||
pandecode_invocation(pan_section_ptr(p, COMPUTE_JOB, INVOCATION));
|
||||
DUMP_SECTION(COMPUTE_JOB, PARAMETERS, p, "Vertex Job Parameters:\n");
|
||||
DUMP_UNPACKED(DRAW, draw, "Draw:\n");
|
||||
pandecode_indent--;
|
||||
pandecode_log("\n");
|
||||
pandecode_log(ctx, "Vertex Job Payload:\n");
|
||||
ctx->indent++;
|
||||
pandecode_invocation(ctx, pan_section_ptr(p, COMPUTE_JOB, INVOCATION));
|
||||
DUMP_SECTION(ctx, COMPUTE_JOB, PARAMETERS, p, "Vertex Job Parameters:\n");
|
||||
DUMP_UNPACKED(ctx, DRAW, draw, "Draw:\n");
|
||||
ctx->indent--;
|
||||
pandecode_log(ctx, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
pandecode_write_value_job(mali_ptr job)
|
||||
pandecode_write_value_job(struct pandecode_context *ctx, mali_ptr job)
|
||||
{
|
||||
struct mali_write_value_job_packed *PANDECODE_PTR_VAR(p, job);
|
||||
struct mali_write_value_job_packed *PANDECODE_PTR_VAR(ctx, p, job);
|
||||
pan_section_unpack(p, WRITE_VALUE_JOB, PAYLOAD, u);
|
||||
DUMP_SECTION(WRITE_VALUE_JOB, PAYLOAD, p, "Write Value Payload:\n");
|
||||
pandecode_log("\n");
|
||||
DUMP_SECTION(ctx, WRITE_VALUE_JOB, PAYLOAD, p, "Write Value Payload:\n");
|
||||
pandecode_log(ctx, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_cache_flush_job(mali_ptr job)
|
||||
pandecode_cache_flush_job(struct pandecode_context *ctx, mali_ptr job)
|
||||
{
|
||||
struct mali_cache_flush_job_packed *PANDECODE_PTR_VAR(p, job);
|
||||
struct mali_cache_flush_job_packed *PANDECODE_PTR_VAR(ctx, p, job);
|
||||
pan_section_unpack(p, CACHE_FLUSH_JOB, PAYLOAD, u);
|
||||
DUMP_SECTION(CACHE_FLUSH_JOB, PAYLOAD, p, "Cache Flush Payload:\n");
|
||||
pandecode_log("\n");
|
||||
DUMP_SECTION(ctx, CACHE_FLUSH_JOB, PAYLOAD, p, "Cache Flush Payload:\n");
|
||||
pandecode_log(ctx, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_tiler_job(const struct MALI_JOB_HEADER *h, mali_ptr job,
|
||||
pandecode_tiler_job(struct pandecode_context *ctx,
|
||||
const struct MALI_JOB_HEADER *h, mali_ptr job,
|
||||
unsigned gpu_id)
|
||||
{
|
||||
struct mali_tiler_job_packed *PANDECODE_PTR_VAR(p, job);
|
||||
struct mali_tiler_job_packed *PANDECODE_PTR_VAR(ctx, p, job);
|
||||
pan_section_unpack(p, TILER_JOB, DRAW, draw);
|
||||
GENX(pandecode_dcd)(&draw, h->type, gpu_id);
|
||||
pandecode_log("Tiler Job Payload:\n");
|
||||
pandecode_indent++;
|
||||
GENX(pandecode_dcd)(ctx, &draw, h->type, gpu_id);
|
||||
pandecode_log(ctx, "Tiler Job Payload:\n");
|
||||
ctx->indent++;
|
||||
|
||||
#if PAN_ARCH <= 7
|
||||
pandecode_invocation(pan_section_ptr(p, TILER_JOB, INVOCATION));
|
||||
pandecode_invocation(ctx, pan_section_ptr(p, TILER_JOB, INVOCATION));
|
||||
#endif
|
||||
|
||||
pandecode_primitive(pan_section_ptr(p, TILER_JOB, PRIMITIVE));
|
||||
DUMP_UNPACKED(DRAW, draw, "Draw:\n");
|
||||
pandecode_primitive(ctx, pan_section_ptr(p, TILER_JOB, PRIMITIVE));
|
||||
DUMP_UNPACKED(ctx, DRAW, draw, "Draw:\n");
|
||||
|
||||
DUMP_SECTION(TILER_JOB, PRIMITIVE_SIZE, p, "Primitive Size:\n");
|
||||
DUMP_SECTION(ctx, TILER_JOB, PRIMITIVE_SIZE, p, "Primitive Size:\n");
|
||||
|
||||
#if PAN_ARCH >= 6
|
||||
pan_section_unpack(p, TILER_JOB, TILER, tiler_ptr);
|
||||
GENX(pandecode_tiler)(tiler_ptr.address, gpu_id);
|
||||
GENX(pandecode_tiler)(ctx, tiler_ptr.address, gpu_id);
|
||||
|
||||
#if PAN_ARCH >= 9
|
||||
DUMP_SECTION(TILER_JOB, INSTANCE_COUNT, p, "Instance count:\n");
|
||||
DUMP_SECTION(TILER_JOB, VERTEX_COUNT, p, "Vertex count:\n");
|
||||
DUMP_SECTION(TILER_JOB, SCISSOR, p, "Scissor:\n");
|
||||
DUMP_SECTION(TILER_JOB, INDICES, p, "Indices:\n");
|
||||
DUMP_SECTION(ctx, TILER_JOB, INSTANCE_COUNT, p, "Instance count:\n");
|
||||
DUMP_SECTION(ctx, TILER_JOB, VERTEX_COUNT, p, "Vertex count:\n");
|
||||
DUMP_SECTION(ctx, TILER_JOB, SCISSOR, p, "Scissor:\n");
|
||||
DUMP_SECTION(ctx, TILER_JOB, INDICES, p, "Indices:\n");
|
||||
#else
|
||||
pan_section_unpack(p, TILER_JOB, PADDING, padding);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
pandecode_indent--;
|
||||
pandecode_log("\n");
|
||||
ctx->indent--;
|
||||
pandecode_log(ctx, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_fragment_job(mali_ptr job, unsigned gpu_id)
|
||||
pandecode_fragment_job(struct pandecode_context *ctx, mali_ptr job,
|
||||
unsigned gpu_id)
|
||||
{
|
||||
struct mali_fragment_job_packed *PANDECODE_PTR_VAR(p, job);
|
||||
struct mali_fragment_job_packed *PANDECODE_PTR_VAR(ctx, p, job);
|
||||
pan_section_unpack(p, FRAGMENT_JOB, PAYLOAD, s);
|
||||
|
||||
uint64_t fbd_pointer;
|
||||
|
|
@ -483,47 +493,50 @@ pandecode_fragment_job(mali_ptr job, unsigned gpu_id)
|
|||
#endif
|
||||
|
||||
UNUSED struct pandecode_fbd info =
|
||||
GENX(pandecode_fbd)(fbd_pointer, true, gpu_id);
|
||||
GENX(pandecode_fbd)(ctx, fbd_pointer, true, gpu_id);
|
||||
|
||||
#if PAN_ARCH >= 5
|
||||
if (!ptr.type || ptr.zs_crc_extension_present != info.has_extra ||
|
||||
ptr.render_target_count != info.rt_count) {
|
||||
pandecode_log("invalid FBD tag\n");
|
||||
pandecode_log(ctx, "invalid FBD tag\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
DUMP_UNPACKED(FRAGMENT_JOB_PAYLOAD, s, "Fragment Job Payload:\n");
|
||||
DUMP_UNPACKED(ctx, FRAGMENT_JOB_PAYLOAD, s, "Fragment Job Payload:\n");
|
||||
|
||||
pandecode_log("\n");
|
||||
pandecode_log(ctx, "\n");
|
||||
}
|
||||
|
||||
#if PAN_ARCH == 6 || PAN_ARCH == 7
|
||||
static void
|
||||
pandecode_indexed_vertex_job(const struct MALI_JOB_HEADER *h, mali_ptr job,
|
||||
pandecode_indexed_vertex_job(struct pandecode_context *ctx,
|
||||
const struct MALI_JOB_HEADER *h, mali_ptr job,
|
||||
unsigned gpu_id)
|
||||
{
|
||||
struct mali_indexed_vertex_job_packed *PANDECODE_PTR_VAR(p, job);
|
||||
struct mali_indexed_vertex_job_packed *PANDECODE_PTR_VAR(ctx, p, job);
|
||||
|
||||
pandecode_log("Vertex:\n");
|
||||
pandecode_log(ctx, "Vertex:\n");
|
||||
pan_section_unpack(p, INDEXED_VERTEX_JOB, VERTEX_DRAW, vert_draw);
|
||||
GENX(pandecode_dcd)(&vert_draw, h->type, gpu_id);
|
||||
DUMP_UNPACKED(DRAW, vert_draw, "Vertex Draw:\n");
|
||||
GENX(pandecode_dcd)(ctx, &vert_draw, h->type, gpu_id);
|
||||
DUMP_UNPACKED(ctx, DRAW, vert_draw, "Vertex Draw:\n");
|
||||
|
||||
pandecode_log("Fragment:\n");
|
||||
pandecode_log(ctx, "Fragment:\n");
|
||||
pan_section_unpack(p, INDEXED_VERTEX_JOB, FRAGMENT_DRAW, frag_draw);
|
||||
GENX(pandecode_dcd)(&frag_draw, MALI_JOB_TYPE_FRAGMENT, gpu_id);
|
||||
DUMP_UNPACKED(DRAW, frag_draw, "Fragment Draw:\n");
|
||||
GENX(pandecode_dcd)(ctx, &frag_draw, MALI_JOB_TYPE_FRAGMENT, gpu_id);
|
||||
DUMP_UNPACKED(ctx, DRAW, frag_draw, "Fragment Draw:\n");
|
||||
|
||||
pan_section_unpack(p, INDEXED_VERTEX_JOB, TILER, tiler_ptr);
|
||||
pandecode_log("Tiler Job Payload:\n");
|
||||
pandecode_indent++;
|
||||
GENX(pandecode_tiler)(tiler_ptr.address, gpu_id);
|
||||
pandecode_indent--;
|
||||
pandecode_log(ctx, "Tiler Job Payload:\n");
|
||||
ctx->indent++;
|
||||
GENX(pandecode_tiler)(ctx, tiler_ptr.address, gpu_id);
|
||||
ctx->indent--;
|
||||
|
||||
pandecode_invocation(pan_section_ptr(p, INDEXED_VERTEX_JOB, INVOCATION));
|
||||
pandecode_primitive(pan_section_ptr(p, INDEXED_VERTEX_JOB, PRIMITIVE));
|
||||
pandecode_invocation(ctx,
|
||||
pan_section_ptr(p, INDEXED_VERTEX_JOB, INVOCATION));
|
||||
pandecode_primitive(ctx, pan_section_ptr(p, INDEXED_VERTEX_JOB, PRIMITIVE));
|
||||
|
||||
DUMP_SECTION(INDEXED_VERTEX_JOB, PRIMITIVE_SIZE, p, "Primitive Size:\n");
|
||||
DUMP_SECTION(ctx, INDEXED_VERTEX_JOB, PRIMITIVE_SIZE, p,
|
||||
"Primitive Size:\n");
|
||||
|
||||
pan_section_unpack(p, INDEXED_VERTEX_JOB, PADDING, padding);
|
||||
}
|
||||
|
|
@ -531,45 +544,47 @@ pandecode_indexed_vertex_job(const struct MALI_JOB_HEADER *h, mali_ptr job,
|
|||
|
||||
#if PAN_ARCH == 9
|
||||
static void
|
||||
pandecode_malloc_vertex_job(mali_ptr job, unsigned gpu_id)
|
||||
pandecode_malloc_vertex_job(struct pandecode_context *ctx, mali_ptr job,
|
||||
unsigned gpu_id)
|
||||
{
|
||||
struct mali_malloc_vertex_job_packed *PANDECODE_PTR_VAR(p, job);
|
||||
struct mali_malloc_vertex_job_packed *PANDECODE_PTR_VAR(ctx, p, job);
|
||||
|
||||
DUMP_SECTION(MALLOC_VERTEX_JOB, PRIMITIVE, p, "Primitive:\n");
|
||||
DUMP_SECTION(MALLOC_VERTEX_JOB, INSTANCE_COUNT, p, "Instance count:\n");
|
||||
DUMP_SECTION(MALLOC_VERTEX_JOB, ALLOCATION, p, "Allocation:\n");
|
||||
DUMP_SECTION(MALLOC_VERTEX_JOB, TILER, p, "Tiler:\n");
|
||||
DUMP_SECTION(MALLOC_VERTEX_JOB, SCISSOR, p, "Scissor:\n");
|
||||
DUMP_SECTION(MALLOC_VERTEX_JOB, PRIMITIVE_SIZE, p, "Primitive Size:\n");
|
||||
DUMP_SECTION(MALLOC_VERTEX_JOB, INDICES, p, "Indices:\n");
|
||||
DUMP_SECTION(ctx, MALLOC_VERTEX_JOB, PRIMITIVE, p, "Primitive:\n");
|
||||
DUMP_SECTION(ctx, MALLOC_VERTEX_JOB, INSTANCE_COUNT, p, "Instance count:\n");
|
||||
DUMP_SECTION(ctx, MALLOC_VERTEX_JOB, ALLOCATION, p, "Allocation:\n");
|
||||
DUMP_SECTION(ctx, MALLOC_VERTEX_JOB, TILER, p, "Tiler:\n");
|
||||
DUMP_SECTION(ctx, MALLOC_VERTEX_JOB, SCISSOR, p, "Scissor:\n");
|
||||
DUMP_SECTION(ctx, MALLOC_VERTEX_JOB, PRIMITIVE_SIZE, p, "Primitive Size:\n");
|
||||
DUMP_SECTION(ctx, MALLOC_VERTEX_JOB, INDICES, p, "Indices:\n");
|
||||
|
||||
pan_section_unpack(p, MALLOC_VERTEX_JOB, DRAW, dcd);
|
||||
|
||||
pan_section_unpack(p, MALLOC_VERTEX_JOB, TILER, tiler_ptr);
|
||||
pandecode_log("Tiler Job Payload:\n");
|
||||
pandecode_indent++;
|
||||
pandecode_log(ctx, "Tiler Job Payload:\n");
|
||||
ctx->indent++;
|
||||
if (tiler_ptr.address)
|
||||
GENX(pandecode_tiler)(tiler_ptr.address, gpu_id);
|
||||
GENX(pandecode_tiler)(ctx, tiler_ptr.address, gpu_id);
|
||||
else
|
||||
pandecode_log("<omitted>\n");
|
||||
pandecode_indent--;
|
||||
pandecode_log(ctx, "<omitted>\n");
|
||||
ctx->indent--;
|
||||
|
||||
GENX(pandecode_dcd)(&dcd, 0, gpu_id);
|
||||
GENX(pandecode_dcd)(ctx, &dcd, 0, gpu_id);
|
||||
|
||||
pan_section_unpack(p, MALLOC_VERTEX_JOB, POSITION, position);
|
||||
pan_section_unpack(p, MALLOC_VERTEX_JOB, VARYING, varying);
|
||||
GENX(pandecode_shader_environment)(&position, gpu_id);
|
||||
GENX(pandecode_shader_environment)(&varying, gpu_id);
|
||||
GENX(pandecode_shader_environment)(ctx, &position, gpu_id);
|
||||
GENX(pandecode_shader_environment)(ctx, &varying, gpu_id);
|
||||
}
|
||||
|
||||
static void
|
||||
pandecode_compute_job(mali_ptr job, unsigned gpu_id)
|
||||
pandecode_compute_job(struct pandecode_context *ctx, mali_ptr job,
|
||||
unsigned gpu_id)
|
||||
{
|
||||
struct mali_compute_job_packed *PANDECODE_PTR_VAR(p, job);
|
||||
struct mali_compute_job_packed *PANDECODE_PTR_VAR(ctx, p, job);
|
||||
pan_section_unpack(p, COMPUTE_JOB, PAYLOAD, payload);
|
||||
|
||||
GENX(pandecode_shader_environment)(&payload.compute, gpu_id);
|
||||
DUMP_SECTION(COMPUTE_JOB, PAYLOAD, p, "Compute");
|
||||
GENX(pandecode_shader_environment)(ctx, &payload.compute, gpu_id);
|
||||
DUMP_SECTION(ctx, COMPUTE_JOB, PAYLOAD, p, "Compute");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -578,9 +593,10 @@ pandecode_compute_job(mali_ptr job, unsigned gpu_id)
|
|||
* GPU using the job manager.
|
||||
*/
|
||||
void
|
||||
GENX(pandecode_jc)(mali_ptr jc_gpu_va, unsigned gpu_id)
|
||||
GENX(pandecode_jc)(struct pandecode_context *ctx, mali_ptr jc_gpu_va,
|
||||
unsigned gpu_id)
|
||||
{
|
||||
pandecode_dump_file_open();
|
||||
pandecode_dump_file_open(ctx);
|
||||
|
||||
struct set *va_set = _mesa_pointer_set_create(NULL);
|
||||
struct set_entry *entry = NULL;
|
||||
|
|
@ -589,7 +605,7 @@ GENX(pandecode_jc)(mali_ptr jc_gpu_va, unsigned gpu_id)
|
|||
|
||||
do {
|
||||
struct mali_job_header_packed *hdr =
|
||||
PANDECODE_PTR(jc_gpu_va, struct mali_job_header_packed);
|
||||
PANDECODE_PTR(ctx, jc_gpu_va, struct mali_job_header_packed);
|
||||
|
||||
entry = _mesa_set_search(va_set, hdr);
|
||||
if (entry != NULL) {
|
||||
|
|
@ -600,45 +616,46 @@ GENX(pandecode_jc)(mali_ptr jc_gpu_va, unsigned gpu_id)
|
|||
pan_unpack(hdr, JOB_HEADER, h);
|
||||
next_job = h.next;
|
||||
|
||||
DUMP_UNPACKED(JOB_HEADER, h, "Job Header (%" PRIx64 "):\n", jc_gpu_va);
|
||||
pandecode_log("\n");
|
||||
DUMP_UNPACKED(ctx, JOB_HEADER, h, "Job Header (%" PRIx64 "):\n",
|
||||
jc_gpu_va);
|
||||
pandecode_log(ctx, "\n");
|
||||
|
||||
switch (h.type) {
|
||||
case MALI_JOB_TYPE_WRITE_VALUE:
|
||||
pandecode_write_value_job(jc_gpu_va);
|
||||
pandecode_write_value_job(ctx, jc_gpu_va);
|
||||
break;
|
||||
|
||||
case MALI_JOB_TYPE_CACHE_FLUSH:
|
||||
pandecode_cache_flush_job(jc_gpu_va);
|
||||
pandecode_cache_flush_job(ctx, jc_gpu_va);
|
||||
break;
|
||||
|
||||
case MALI_JOB_TYPE_TILER:
|
||||
pandecode_tiler_job(&h, jc_gpu_va, gpu_id);
|
||||
pandecode_tiler_job(ctx, &h, jc_gpu_va, gpu_id);
|
||||
break;
|
||||
|
||||
#if PAN_ARCH <= 7
|
||||
case MALI_JOB_TYPE_VERTEX:
|
||||
case MALI_JOB_TYPE_COMPUTE:
|
||||
pandecode_vertex_compute_geometry_job(&h, jc_gpu_va, gpu_id);
|
||||
pandecode_vertex_compute_geometry_job(ctx, &h, jc_gpu_va, gpu_id);
|
||||
break;
|
||||
|
||||
#if PAN_ARCH >= 6
|
||||
case MALI_JOB_TYPE_INDEXED_VERTEX:
|
||||
pandecode_indexed_vertex_job(&h, jc_gpu_va, gpu_id);
|
||||
pandecode_indexed_vertex_job(ctx, &h, jc_gpu_va, gpu_id);
|
||||
break;
|
||||
#endif
|
||||
#else
|
||||
case MALI_JOB_TYPE_COMPUTE:
|
||||
pandecode_compute_job(jc_gpu_va, gpu_id);
|
||||
pandecode_compute_job(ctx, jc_gpu_va, gpu_id);
|
||||
break;
|
||||
|
||||
case MALI_JOB_TYPE_MALLOC_VERTEX:
|
||||
pandecode_malloc_vertex_job(jc_gpu_va, gpu_id);
|
||||
pandecode_malloc_vertex_job(ctx, jc_gpu_va, gpu_id);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case MALI_JOB_TYPE_FRAGMENT:
|
||||
pandecode_fragment_job(jc_gpu_va, gpu_id);
|
||||
pandecode_fragment_job(ctx, jc_gpu_va, gpu_id);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -651,17 +668,18 @@ GENX(pandecode_jc)(mali_ptr jc_gpu_va, unsigned gpu_id)
|
|||
|
||||
_mesa_set_destroy(va_set, NULL);
|
||||
|
||||
fflush(pandecode_dump_stream);
|
||||
pandecode_map_read_write();
|
||||
fflush(ctx->dump_stream);
|
||||
pandecode_map_read_write(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
GENX(pandecode_abort_on_fault)(mali_ptr jc_gpu_va)
|
||||
GENX(pandecode_abort_on_fault)(struct pandecode_context *ctx,
|
||||
mali_ptr jc_gpu_va)
|
||||
{
|
||||
mali_ptr next_job = 0;
|
||||
|
||||
do {
|
||||
pan_unpack(PANDECODE_PTR(jc_gpu_va, struct mali_job_header_packed),
|
||||
pan_unpack(PANDECODE_PTR(ctx, jc_gpu_va, struct mali_job_header_packed),
|
||||
JOB_HEADER, h);
|
||||
next_job = h.next;
|
||||
|
||||
|
|
@ -673,7 +691,7 @@ GENX(pandecode_abort_on_fault)(mali_ptr jc_gpu_va)
|
|||
}
|
||||
} while ((jc_gpu_va = next_job));
|
||||
|
||||
pandecode_map_read_write();
|
||||
pandecode_map_read_write(ctx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -405,9 +405,11 @@ panfrost_bo_create(struct panfrost_device *dev, size_t size, uint32_t flags,
|
|||
|
||||
if (dev->debug & (PAN_DBG_TRACE | PAN_DBG_SYNC)) {
|
||||
if (flags & PAN_BO_INVISIBLE)
|
||||
pandecode_inject_mmap(bo->ptr.gpu, NULL, bo->size, NULL);
|
||||
pandecode_inject_mmap(dev->decode_ctx, bo->ptr.gpu, NULL, bo->size,
|
||||
NULL);
|
||||
else if (!(flags & PAN_BO_DELAY_MMAP))
|
||||
pandecode_inject_mmap(bo->ptr.gpu, bo->ptr.cpu, bo->size, NULL);
|
||||
pandecode_inject_mmap(dev->decode_ctx, bo->ptr.gpu, bo->ptr.cpu,
|
||||
bo->size, NULL);
|
||||
}
|
||||
|
||||
return bo;
|
||||
|
|
@ -444,7 +446,7 @@ panfrost_bo_unreference(struct panfrost_bo *bo)
|
|||
panfrost_bo_munmap(bo);
|
||||
|
||||
if (dev->debug & (PAN_DBG_TRACE | PAN_DBG_SYNC))
|
||||
pandecode_inject_free(bo->ptr.gpu, bo->size);
|
||||
pandecode_inject_free(dev->decode_ctx, bo->ptr.gpu, bo->size);
|
||||
|
||||
/* Rather than freeing the BO now, we'll cache the BO for later
|
||||
* allocations if we're allowed to.
|
||||
|
|
|
|||
|
|
@ -130,6 +130,9 @@ struct panfrost_device {
|
|||
|
||||
int fd;
|
||||
|
||||
/* For pandecode */
|
||||
struct pandecode_context *decode_ctx;
|
||||
|
||||
/* Properties of the GPU in use */
|
||||
unsigned arch;
|
||||
unsigned gpu_id;
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ panfrost_open_device(void *memctx, int fd, struct panfrost_device *dev)
|
|||
|
||||
/* Initialize pandecode before we start allocating */
|
||||
if (dev->debug & (PAN_DBG_TRACE | PAN_DBG_SYNC))
|
||||
pandecode_initialize(!(dev->debug & PAN_DBG_TRACE));
|
||||
dev->decode_ctx = pandecode_create_context(!(dev->debug & PAN_DBG_TRACE));
|
||||
|
||||
/* Tiler heap is internally required by the tiler, which can only be
|
||||
* active for a single job chain at once, so a single heap can be
|
||||
|
|
|
|||
|
|
@ -42,22 +42,29 @@
|
|||
* included in-tree.
|
||||
*/
|
||||
|
||||
void pandecode_initialize(bool to_stderr);
|
||||
// TODO: update panwrap
|
||||
|
||||
void pandecode_next_frame(void);
|
||||
struct pandecode_context;
|
||||
|
||||
void pandecode_close(void);
|
||||
struct pandecode_context *pandecode_create_context(bool to_stderr);
|
||||
|
||||
void pandecode_inject_mmap(uint64_t gpu_va, void *cpu, unsigned sz,
|
||||
const char *name);
|
||||
void pandecode_next_frame(struct pandecode_context *ctx);
|
||||
|
||||
void pandecode_inject_free(uint64_t gpu_va, unsigned sz);
|
||||
void pandecode_destroy_context(struct pandecode_context *ctx);
|
||||
|
||||
void pandecode_jc(uint64_t jc_gpu_va, unsigned gpu_id);
|
||||
void pandecode_inject_mmap(struct pandecode_context *ctx, uint64_t gpu_va,
|
||||
void *cpu, unsigned sz, const char *name);
|
||||
|
||||
void pandecode_cs(mali_ptr queue_gpu_va, uint32_t size, unsigned gpu_id,
|
||||
uint32_t *regs);
|
||||
void pandecode_inject_free(struct pandecode_context *ctx, uint64_t gpu_va,
|
||||
unsigned sz);
|
||||
|
||||
void pandecode_abort_on_fault(uint64_t jc_gpu_va, unsigned gpu_id);
|
||||
void pandecode_jc(struct pandecode_context *ctx, uint64_t jc_gpu_va,
|
||||
unsigned gpu_id);
|
||||
|
||||
void pandecode_cs(struct pandecode_context *ctx, mali_ptr queue_gpu_va,
|
||||
uint32_t size, unsigned gpu_id, uint32_t *regs);
|
||||
|
||||
void pandecode_abort_on_fault(struct pandecode_context *ctx, uint64_t jc_gpu_va,
|
||||
unsigned gpu_id);
|
||||
|
||||
#endif /* __MMAP_TRACE_H__ */
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ main(int argc, char *argv[])
|
|||
i = j = k = 0;
|
||||
|
||||
atexit(cleanup);
|
||||
pandecode_initialize(false);
|
||||
struct pandecode_context *ctx = pandecode_create_context(false);
|
||||
|
||||
hdr_fp = fopen(argv[optind], "r");
|
||||
if (!hdr_fp) {
|
||||
|
|
@ -374,7 +374,7 @@ main(int argc, char *argv[])
|
|||
|
||||
fclose(bodump);
|
||||
|
||||
pandecode_inject_mmap(doh.bomap.iova, bos[j], doh.file_size,
|
||||
pandecode_inject_mmap(ctx, doh.bomap.iova, bos[j], doh.file_size,
|
||||
NULL);
|
||||
|
||||
} else {
|
||||
|
|
@ -397,8 +397,8 @@ main(int argc, char *argv[])
|
|||
if (doh.type != PANFROSTDUMP_BUF_TRAILER)
|
||||
fprintf(stderr, "Trailing header isn't right\n");
|
||||
|
||||
pandecode_jc(jc, gpu_id);
|
||||
pandecode_close();
|
||||
pandecode_jc(ctx, jc, gpu_id);
|
||||
pandecode_destroy_context(ctx);
|
||||
|
||||
fclose(data_fp);
|
||||
fclose(hdr_fp);
|
||||
|
|
|
|||
|
|
@ -77,10 +77,11 @@ panvk_queue_submit_batch(struct panvk_queue *queue, struct panvk_batch *batch,
|
|||
}
|
||||
|
||||
if (debug & PANVK_DEBUG_TRACE)
|
||||
pandecode_jc(batch->scoreboard.first_job, pdev->gpu_id);
|
||||
pandecode_jc(pdev->decode_ctx, batch->scoreboard.first_job,
|
||||
pdev->gpu_id);
|
||||
|
||||
if (debug & PANVK_DEBUG_DUMP)
|
||||
pandecode_dump_mappings();
|
||||
pandecode_dump_mappings(pdev->decode_ctx);
|
||||
}
|
||||
|
||||
if (batch->fragment_job) {
|
||||
|
|
@ -109,14 +110,14 @@ panvk_queue_submit_batch(struct panvk_queue *queue, struct panvk_batch *batch,
|
|||
}
|
||||
|
||||
if (debug & PANVK_DEBUG_TRACE)
|
||||
pandecode_jc(batch->fragment_job, pdev->gpu_id);
|
||||
pandecode_jc(pdev->decode_ctx, batch->fragment_job, pdev->gpu_id);
|
||||
|
||||
if (debug & PANVK_DEBUG_DUMP)
|
||||
pandecode_dump_mappings();
|
||||
pandecode_dump_mappings(pdev->decode_ctx);
|
||||
}
|
||||
|
||||
if (debug & PANVK_DEBUG_TRACE)
|
||||
pandecode_next_frame();
|
||||
pandecode_next_frame(0);
|
||||
|
||||
batch->issued = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue