* larger FBD */
static void
-pandecode_midgard_tiler_descriptor(const struct midgard_tiler_descriptor *t)
+pandecode_midgard_tiler_descriptor(
+ const struct midgard_tiler_descriptor *t,
+ unsigned width,
+ unsigned height)
{
pandecode_log(".tiler = {\n");
pandecode_indent++;
pandecode_prop("hierarchy_mask = 0x%" PRIx16, t->hierarchy_mask);
pandecode_prop("flags = 0x%" PRIx16, t->flags);
- pandecode_prop("polygon_list_size = 0x%x", t->polygon_list_size);
MEMORY_PROP(t, polygon_list);
- MEMORY_PROP(t, polygon_list_body);
- MEMORY_PROP(t, heap_start);
+ /* The body is offset from the base of the polygon list */
+ assert(t->polygon_list_body > t->polygon_list);
+ unsigned body_offset = t->polygon_list_body - t->polygon_list;
- if (t->heap_start == t->heap_end) {
- /* Print identically to show symmetry for empty tiler heaps */
- MEMORY_PROP(t, heap_end);
- } else {
- /* Points to the end of a buffer */
- char *a = pointer_as_memory_reference(t->heap_end - 1);
- pandecode_prop("heap_end = %s + 1", a);
- free(a);
+ /* It needs to fit inside the reported size */
+ assert(t->polygon_list_size >= body_offset);
+
+ /* Check that we fit */
+ struct pandecode_mapped_memory *plist =
+ pandecode_find_mapped_gpu_mem_containing(t->polygon_list);
+
+ assert(t->polygon_list_size <= plist->length);
+
+ /* Now that we've sanity checked, we'll try to calculate the sizes
+ * ourselves for comparison */
+
+ unsigned ref_header = panfrost_tiler_header_size(width, height, t->hierarchy_mask);
+ unsigned ref_body = panfrost_tiler_body_size(width, height, t->hierarchy_mask);
+ unsigned ref_size = ref_header + ref_body;
+
+ if (!((ref_header == body_offset) && (ref_size == t->polygon_list_size))) {
+ pandecode_msg("XXX: bad polygon list size (expected %d / 0x%x)\n",
+ ref_header, ref_size);
+ pandecode_prop("polygon_list_size = 0x%x", t->polygon_list_size);
+ pandecode_msg("body offset %d\n", body_offset);
}
+ /* The tiler heap has a start and end specified, so check that
+ * everything fits in a contiguous BO (otherwise, we risk out-of-bounds
+ * reads) */
+
+ MEMORY_PROP(t, heap_start);
+ assert(t->heap_end >= t->heap_start);
+
+ struct pandecode_mapped_memory *heap =
+ pandecode_find_mapped_gpu_mem_containing(t->heap_start);
+
+ unsigned heap_size = t->heap_end - t->heap_start;
+ assert(heap_size <= heap->length);
+
+ pandecode_msg("heap size %d\n", heap_size);
+
bool nonzero_weights = false;
for (unsigned w = 0; w < ARRAY_SIZE(t->weights); ++w) {
MEMORY_PROP(s, unknown_address_0);
const struct midgard_tiler_descriptor t = s->tiler;
- pandecode_midgard_tiler_descriptor(&t);
+ pandecode_midgard_tiler_descriptor(&t, s->width + 1, s->height + 1);
pandecode_indent--;
pandecode_log("};\n");
pandecode_prop("unknown2 = 0x%x", fb->unknown2);
MEMORY_PROP(fb, scratchpad);
const struct midgard_tiler_descriptor t = fb->tiler;
- pandecode_midgard_tiler_descriptor(&t);
+ pandecode_midgard_tiler_descriptor(&t, fb->width1 + 1, fb->height1 + 1);
if (fb->zero3 || fb->zero4) {
pandecode_msg("framebuffer zeros tripped\n");
(p->size_z_shift == ref.size_z_shift) &&
(p->workgroups_x_shift == ref.workgroups_x_shift) &&
(p->workgroups_y_shift == ref.workgroups_y_shift) &&
- (p->workgroups_z_shift == ref.workgroups_z_shift);
+ (p->workgroups_z_shift == ref.workgroups_z_shift) &&
+ (p->workgroups_x_shift_2 == ref.workgroups_x_shift_2);
if (!canonical) {
pandecode_msg("XXX: non-canonical workgroups packing\n");
ref.size_z_shift,
ref.workgroups_x_shift,
ref.workgroups_y_shift,
- ref.workgroups_z_shift);
+ ref.workgroups_z_shift,
+ ref.workgroups_x_shift_2);
pandecode_prop("invocation_count = 0x%" PRIx32, p->invocation_count);
pandecode_prop("size_y_shift = %d", p->size_y_shift);
pandecode_prop("workgroups_x_shift = %d", p->workgroups_x_shift);
pandecode_prop("workgroups_y_shift = %d", p->workgroups_y_shift);
pandecode_prop("workgroups_z_shift = %d", p->workgroups_z_shift);
+ pandecode_prop("workgroups_x_shift_2 = %d", p->workgroups_x_shift_2);
}
/* Regardless, print the decode */
if (p->unknown_draw)
pandecode_prop("unknown_draw = 0x%" PRIx32, p->unknown_draw);
- pandecode_prop("workgroups_x_shift_2 = 0x%" PRIx32, p->workgroups_x_shift_2);
pandecode_prop("workgroups_x_shift_3 = 0x%" PRIx32, p->workgroups_x_shift_3);
if (p->draw_mode != MALI_DRAW_NONE)
if (h->job_descriptor_size)
pandecode_prop("job_descriptor_size = %d", h->job_descriptor_size);
- if (h->exception_status != 0x1)
+ if (h->exception_status && h->exception_status != 0x1)
pandecode_prop("exception_status = %x (source ID: 0x%x access: %s exception: 0x%x)",
h->exception_status,
(h->exception_status >> 16) & 0xFFFF,