panwrap-decoder.c 30.2 KB
Newer Older
1
/*
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
2
 * © Copyright 2017-2018 The Panfrost Community
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * A copy of the licence is included with the program, and can also be obtained
 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 *
 */

#include "panwrap.h"
#include <mali-ioctl.h>
#include <mali-job.h>
18
#include <stdio.h>
19
#include <memory.h>
20

21 22
#include "panwrap-shader.h"

23 24
#define MEMORY_PROP(obj, p) {\
	char *a = pointer_as_memory_reference(obj->p); \
25 26 27 28
	panwrap_prop("%s = %s", #p, a); \
	free(a); \
}

29 30 31 32 33
#define DYN_MEMORY_PROP(obj, no, p) { \
	if (obj->p) \
		panwrap_prop("%s = %s_%d_p", #p, #p, no); \
}

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
34 35
#define FLAG_INFO(flag) { MALI_GL_##flag, "MALI_GL_" #flag }
static const struct panwrap_flag_info gl_enable_flag_info[] = {
36 37
	FLAG_INFO(CULL_FACE_FRONT),
	FLAG_INFO(CULL_FACE_BACK),
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
38 39 40 41
	{}
};
#undef FLAG_INFO

42 43 44 45 46 47 48 49 50
#define FLAG_INFO(flag) { MALI_CLEAR_##flag, "MALI_CLEAR_" #flag }
static const struct panwrap_flag_info clear_flag_info[] = {
	FLAG_INFO(FAST),
	FLAG_INFO(SLOW),
	FLAG_INFO(SLOW_STENCIL),
	{}
};
#undef FLAG_INFO

51 52
#define FLAG_INFO(flag) { MALI_##flag, "MALI_" #flag }
static const struct panwrap_flag_info u3_flag_info[] = {
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
53
	FLAG_INFO(HAS_MSAA),
54 55
	FLAG_INFO(CAN_DISCARD),
	FLAG_INFO(HAS_BLEND_SHADER),
56 57 58
	FLAG_INFO(NO_DEPTH_TEST_A),
	FLAG_INFO(NO_DEPTH_TEST_B),
	FLAG_INFO(DEPTH_TEST),
59 60
	{}
};
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
61 62 63

static const struct panwrap_flag_info u4_flag_info[] = {
	FLAG_INFO(NO_MSAA),
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
64
	FLAG_INFO(STENCIL_TEST),
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
65 66
	{}
};
67
#undef FLAG_INFO
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
68

69 70 71 72 73 74 75
#define FLAG_INFO(flag) { MALI_FRAMEBUFFER_##flag, "MALI_FRAMEBUFFER_" #flag }
static const struct panwrap_flag_info u2_flag_info[] = {
	FLAG_INFO(MSAA_A),
	FLAG_INFO(MSAA_B),
	FLAG_INFO(MSAA_8),
	{}
};
76
#undef FLAG_INFO
77

78 79
extern char* replace_fragment;
extern char* replace_vertex;
80 81 82

static char *panwrap_job_type_name(enum mali_job_type type)
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
83
#define DEFINE_CASE(name) case JOB_TYPE_ ## name: return "JOB_TYPE_" #name
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
	switch (type) {
	DEFINE_CASE(NULL);
	DEFINE_CASE(SET_VALUE);
	DEFINE_CASE(CACHE_FLUSH);
	DEFINE_CASE(COMPUTE);
	DEFINE_CASE(VERTEX);
	DEFINE_CASE(TILER);
	DEFINE_CASE(FUSED);
	DEFINE_CASE(FRAGMENT);
	case JOB_NOT_STARTED:
		return "NOT_STARTED";
	default:
		panwrap_log("Warning! Unknown job type %x\n", type);
		return "!?!?!?";
	}
#undef DEFINE_CASE
}

static char *panwrap_gl_mode_name(enum mali_gl_mode mode)
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
104
#define DEFINE_CASE(name) case MALI_ ## name: return "MALI_" #name
105 106 107 108 109 110
	switch(mode) {
	DEFINE_CASE(GL_POINTS);
	DEFINE_CASE(GL_LINES);
	DEFINE_CASE(GL_TRIANGLES);
	DEFINE_CASE(GL_TRIANGLE_STRIP);
	DEFINE_CASE(GL_TRIANGLE_FAN);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
111 112
	DEFINE_CASE(GL_LINE_STRIP);
	DEFINE_CASE(GL_LINE_LOOP);
113 114 115 116 117
	default: return "MALI_GL_TRIANGLES /* XXX: Unknown GL mode, check dump */";
	}
#undef DEFINE_CASE
}

118 119
#define DEFINE_CASE(name) case MALI_FUNC_ ## name: return "MALI_FUNC_" #name
static char *panwrap_func_name(enum mali_func mode)
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
120 121 122 123 124 125 126 127 128 129
{
	switch(mode) {
	DEFINE_CASE(NEVER);
	DEFINE_CASE(LESS);
	DEFINE_CASE(EQUAL);
	DEFINE_CASE(LEQUAL);
	DEFINE_CASE(GREATER);
	DEFINE_CASE(NOTEQUAL);
	DEFINE_CASE(GEQUAL);
	DEFINE_CASE(ALWAYS);
130
	default: return "MALI_FUNC_NEVER /* XXX: Unknown function, check dump */";
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
131 132
	}
}
133
#undef DEFINE_CASE
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
134

135
#define DEFINE_CASE(name) case MALI_STENCIL_ ## name: return "MALI_STENCIL_" #name
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
static char *panwrap_stencil_op_name(enum mali_stencil_op op)
{
	switch(op) {
	DEFINE_CASE(KEEP);
	DEFINE_CASE(REPLACE);
	DEFINE_CASE(ZERO);
	DEFINE_CASE(INVERT);
	DEFINE_CASE(INCR_WRAP);
	DEFINE_CASE(DECR_WRAP);
	DEFINE_CASE(INCR);
	DEFINE_CASE(DECR);
	default: return "MALI_STENCIL_KEEP /* XXX: Unknown stencil op, check dump */";
	}
}

#undef DEFINE_CASE

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
153 154 155 156 157 158 159 160 161 162
static void panwrap_property_u32_list(const char *name, const u32 *lst, size_t c)
{
	panwrap_log(".%s = { ", name);
	panwrap_indent++;
	for (int i = 0; i < c; ++i)
		panwrap_log_cont("0x%" PRIx32 ", ", lst[i]);
	panwrap_indent--;
	panwrap_log_cont("},\n");
}

163 164 165 166 167 168 169
static inline char *panwrap_decode_fbd_type(enum mali_fbd_type type)
{
	if (type == MALI_SFBD)      return "SFBD";
	else if (type == MALI_MFBD) return "MFBD";
	else return "WTF!?";
}

170 171 172 173 174 175 176 177 178 179 180 181 182 183
static bool
panwrap_deduplicate(struct panwrap_mapped_memory *mem, uint64_t gpu_va, const char *name, int number)
{
	if (mem->touched[(gpu_va - mem->gpu_va) / sizeof(uint32_t)]) {
		/* XXX: Is this correct? */
		panwrap_log("mali_ptr %s_%d_p = %s_%d_p;\n", name, number, name, number - 1);
		return true;
	}

	return false;
}

static void
panwrap_replay_sfbd(uint64_t gpu_va, int job_no)
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
184
{
185
	struct panwrap_mapped_memory *mem = panwrap_find_mapped_gpu_mem_containing(gpu_va);
186
	const struct mali_single_framebuffer *PANWRAP_PTR_VAR(s, mem, (mali_ptr) gpu_va);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
187

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
188
	/* FBDs are frequently duplicated, so watch for this */
189
	if (panwrap_deduplicate(mem, gpu_va, "framebuffer", job_no)) return;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
190

191
	panwrap_log("struct mali_single_framebuffer framebuffer_%d = {\n", job_no);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
192 193 194 195 196
	panwrap_indent++;

	panwrap_prop("unknown1 = 0x%" PRIx32, s->unknown1);
	panwrap_prop("flags = 0x%" PRIx32, s->flags);
	panwrap_prop("heap_free_address = 0x%" PRIx64, s->heap_free_address);
197 198 199 200

	panwrap_log(".unknown2 = ");
	panwrap_log_decoded_flags(u2_flag_info, s->unknown2);
	panwrap_log_cont(",\n");
201

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
202 203
	panwrap_prop("width = MALI_POSITIVE(%" PRId16 ")", s->width + 1);
	panwrap_prop("height = MALI_POSITIVE(%" PRId16 ")", s->height + 1);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
204 205 206

	panwrap_property_u32_list("weights", s->weights, MALI_FBD_HIERARCHY_WEIGHTS);

207 208 209 210 211 212 213
	/* Earlier in the actual commandstream -- right before width -- but we
	 * delay to flow nicer */

	panwrap_log(".clear_flags = ");
	panwrap_log_decoded_flags(clear_flag_info, s->clear_flags);
	panwrap_log_cont(",\n");

214 215 216 217
	if (s->depth_buffer | s->depth_buffer_enable) {
		panwrap_prop("depth_buffer = " MALI_PTR_FMT, s->depth_buffer);
		panwrap_prop("depth_buffer_enable = %s", DS_ENABLE(s->depth_buffer_enable));
	}
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
218

219 220 221 222
	if (s->stencil_buffer | s->stencil_buffer_enable) {
		panwrap_prop("stencil_buffer = " MALI_PTR_FMT, s->depth_buffer);
		panwrap_prop("stencil_buffer_enable = %s", DS_ENABLE(s->stencil_buffer_enable));
	}
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
223

224 225 226 227 228 229
	if (s->clear_color_1 | s->clear_color_2 | s->clear_color_3 | s->clear_color_4) {
		panwrap_prop("clear_color_1 = 0x%" PRIx32, s->clear_color_1);
		panwrap_prop("clear_color_2 = 0x%" PRIx32, s->clear_color_2);
		panwrap_prop("clear_color_3 = 0x%" PRIx32, s->clear_color_3);
		panwrap_prop("clear_color_4 = 0x%" PRIx32, s->clear_color_4);
	}
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
230

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
231
	if (s->clear_depth_1 != 0 || s->clear_depth_2 != 0 || s->clear_depth_3 != 0 || s->clear_depth_4 != 0) {
232 233 234 235 236
		panwrap_prop("clear_depth_1 = %f", s->clear_depth_1);
		panwrap_prop("clear_depth_2 = %f", s->clear_depth_2);
		panwrap_prop("clear_depth_3 = %f", s->clear_depth_3);
		panwrap_prop("clear_depth_4 = %f", s->clear_depth_4);
	}
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
237

238 239 240
	if (s->clear_stencil) {
		panwrap_prop("clear_stencil = 0x%x", s->clear_stencil);
	}
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
241

242 243 244
	MEMORY_PROP(s, unknown_address_0);
	MEMORY_PROP(s, unknown_address_1);
	MEMORY_PROP(s, unknown_address_2);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
245 246 247 248

	panwrap_prop("unknown8 = 0x%" PRIx32, s->unknown8);
	panwrap_prop("unknown9 = 0x%" PRIx32, s->unknown9);

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
249
	panwrap_prop("tiler_jc_list = 0x%" PRIx64, s->tiler_jc_list);
250 251

	MEMORY_PROP(s, unknown_address_4);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
252 253 254 255 256 257 258 259 260 261 262 263 264

	panwrap_indent--;
	panwrap_log("};\n");

	int zero_sum_pun = 0;
	zero_sum_pun += s->zero1;
	zero_sum_pun += s->zero2;
	for (int i = 0; i < sizeof(s->zero3)/sizeof(s->zero3[0]); ++i) zero_sum_pun += s->zero3[i];
	for (int i = 0; i < sizeof(s->zero6)/sizeof(s->zero6[0]); ++i) zero_sum_pun += s->zero6[i];

	if (zero_sum_pun)
		panwrap_msg("Zero sum tripped (%d), replay may be wrong\n", zero_sum_pun);

265
	TOUCH(mem, (mali_ptr) gpu_va, *s, "framebuffer", job_no, true);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
266 267
}

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
268
void panwrap_replay_attributes(const struct panwrap_mapped_memory *mem,
269
			       mali_ptr addr, int job_no, int count, bool varying)
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
270
{
271
	char *prefix = varying ? "varyings" : "attributes";
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
272

273 274
	/* Varyings in particular get duplicated between parts of the job */
	if (panwrap_deduplicate(mem, addr, prefix, job_no)) return;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
275

276
	struct mali_attr *attr = panwrap_fetch_gpu_mem(mem, addr, sizeof(struct mali_attr) * count); 
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
277

278 279
	char base[128];
	snprintf(base, sizeof(base), "%s_data_%d", prefix, job_no);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
280

281 282
	for (int i = 0; i < count; ++i) {
		mali_ptr raw_elements = attr[i].elements & ~3;
283

284 285
		size_t vertex_count;
		size_t component_count;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
286

287 288 289
		if (!varying) {
			/* TODO: Attributes are not necessarily float32 vectors in general;
			 * decoding like this without snarfing types from the shader is unsafe all things considered */
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
290

291
			float *buffer = panwrap_fetch_gpu_mem(mem, raw_elements, attr[i].size);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
292

293 294
			vertex_count = attr[i].size / attr[i].stride;
			component_count = attr[i].stride / sizeof(float);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
295

296
			panwrap_log("float %s_%d[] = {\n", base, i);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
297

298 299 300
			panwrap_indent++;
			for (int row = 0; row < vertex_count; row++) {
				panwrap_log_empty();
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
301

302 303
				for (int i = 0; i < component_count; i++)
					panwrap_log_cont("%ff, ", buffer[i]);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
304

305 306 307 308 309 310
				panwrap_log_cont("\n");

				buffer += component_count;
			}
			panwrap_indent--;
			panwrap_log("};\n");
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
311

312
			TOUCH_LEN(mem, raw_elements, attr[i].size, base, i, true);
313 314 315 316 317 318 319
		} else {
			/* TODO: Allocate space for varyings dynamically? */

			char *a = pointer_as_memory_reference(raw_elements);
			panwrap_log("mali_ptr %s_%d_p = %s;\n", base, i, a);
			free(a);
		}
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
320
	}
321

322
	panwrap_log("struct mali_attr %s_%d[] = {\n", prefix, job_no);
323 324
	panwrap_indent++;

325 326 327 328 329 330 331 332 333 334 335
	for (int i = 0; i < count; ++i) {
		panwrap_log("{\n");
		panwrap_indent++;

		int flags = attr[i].elements & 3;
		panwrap_prop("elements = (%s_%d_p) | %d", base, i, attr[i].elements & 3);

		panwrap_prop("stride = 0x%" PRIx32, attr[i].stride);
		panwrap_prop("size = 0x%" PRIx32, attr[i].size);
		panwrap_indent--;
		panwrap_log("}, \n");
336 337 338 339 340
	}

	panwrap_indent--;
	panwrap_log("};\n");

341
	TOUCH_LEN(mem, addr, sizeof(*attr) * count, prefix, job_no, true);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
342 343
}

344 345 346 347 348 349 350 351 352 353 354 355 356
static mali_ptr
panwrap_replay_shader_address(const char *name, mali_ptr ptr)
{
	/* TODO: Decode flags */
	mali_ptr shader_ptr = ptr & ~15;

	char *a = pointer_as_memory_reference(shader_ptr);
	panwrap_prop("%s = (%s) | %d", name, a, (int) (ptr & 15));
	free(a);

	return shader_ptr;
}

357
static void
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
358
panwrap_replay_stencil(const char *name, const u32 *raw)
359
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
360
	const struct mali_stencil_test *stencil = (struct mali_stencil_test *) raw;
361

362
	const char *func = panwrap_func_name(stencil->func);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
363 364 365
	const char *sfail = panwrap_stencil_op_name(stencil->sfail);
	const char *dpfail = panwrap_stencil_op_name(stencil->dpfail);
	const char *dppass = panwrap_stencil_op_name(stencil->dppass);
366

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
367 368
	if (stencil->zero)
		panwrap_msg("Stencil zero tripped: %X\n", stencil->zero);
369

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
370 371 372 373 374 375 376 377 378 379
	panwrap_log(".stencil_%s = {\n", name);
	panwrap_indent++;
	panwrap_prop("ref = %d", stencil->ref);
	panwrap_prop("mask = 0x%02X", stencil->mask);
	panwrap_prop("func = %s", func);
	panwrap_prop("sfail = %s", sfail);
	panwrap_prop("dpfail = %s", dpfail);
	panwrap_prop("dppass = %s", dppass);
	panwrap_indent--;
	panwrap_log("},\n");
380 381
}

382 383
static int
panwrap_replay_vertex_or_tiler_job(const struct mali_job_descriptor_header *h,
384 385 386 387 388 389
					const struct panwrap_mapped_memory *mem,
					mali_ptr payload, int job_no)
{
	struct mali_payload_vertex_tiler *PANWRAP_PTR_VAR(v, mem, payload);
	struct mali_shader_meta *meta;
	struct panwrap_mapped_memory *attr_mem;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
390
	mali_ptr shader_meta_ptr = (u64) (uintptr_t) (v->_shader_upper << 4);
391

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
392
	/* TODO: Isn't this an -M-FBD? What's the difference? */
393
	panwrap_replay_sfbd((u64) (uintptr_t) v->framebuffer, job_no);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
394

395
	int varying_count, attribute_count, uniform_count;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
396

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
397 398 399 400 401 402 403
	if (shader_meta_ptr) {
		struct panwrap_mapped_memory *smem = panwrap_find_mapped_gpu_mem_containing(shader_meta_ptr);
		struct mali_shader_meta *PANWRAP_PTR_VAR(s, smem, shader_meta_ptr);

		panwrap_log("struct mali_shader_meta shader_meta_%d = {\n", job_no);
		panwrap_indent++;

404
		mali_ptr shader_ptr = panwrap_replay_shader_address("shader", s->shader);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
405

406 407
		if (s->zero1)
			panwrap_msg("XXX shader zero tripped\n");
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
408

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
409
		panwrap_prop("attribute_count = %" PRId16, s->attribute_count);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
410
		panwrap_prop("varying_count = %" PRId16, s->varying_count);
411 412 413 414
		panwrap_prop("uniform_count = %" PRId16, s->uniform_count);
		panwrap_prop("work_count = %" PRId16, s->work_count);
		panwrap_prop("unknown1 = 0x%" PRIx32, s->unknown1);
		panwrap_prop("unknown2 = 0x%" PRIx32, s->unknown2);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
415

416 417
		/* Save for dumps */
		attribute_count = s->attribute_count;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
418
		varying_count = s->varying_count;
419
		uniform_count = s->uniform_count; 
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
420

421 422 423
		/* WTF? All zero for vertex shaders; block of assorted, largely
		 * unknown fields for fragment shaders. Let's figure it out,
		 * girls :) */
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
424

425 426 427 428
		if (s->depth_units || s->depth_factor) {
			panwrap_prop("depth_units = MALI_NEGATIVE(%f)", s->depth_units - 1.0f);
			panwrap_prop("depth_factor = %f", s->depth_factor);
		}
429 430

		panwrap_log(".unknown2_3 = ");
431 432 433 434 435 436 437 438 439 440 441 442 443 444

		int unknown2_3 = s->unknown2_3;
		
		/* We're not quite sure what these flags mean without the depth test, if anything */

		if (unknown2_3 & (MALI_DEPTH_TEST | MALI_DEPTH_FUNC_MASK)) {
			const char *func = panwrap_func_name(MALI_GET_DEPTH_FUNC(unknown2_3));
			unknown2_3 &= ~MALI_DEPTH_FUNC_MASK;

			panwrap_log_cont("MALI_DEPTH_FUNC(%s) | ", func);
		}


		panwrap_log_decoded_flags(u3_flag_info, unknown2_3);
445
		panwrap_log_cont(",\n");
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
446

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
447 448 449 450
		panwrap_log(".unknown2_4 = ");
		panwrap_log_decoded_flags(u4_flag_info, s->unknown2_4);
		panwrap_log_cont(",\n");

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
451 452
		panwrap_replay_stencil("front", &s->stencil_front);
		panwrap_replay_stencil("back", &s->stencil_back);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
453

454 455
		panwrap_prop("unknown2_7 = 0x%" PRIx32, s->unknown2_7);
		panwrap_prop("unknown2_8 = 0x%" PRIx32, s->unknown2_8);
456 457 458 459

		if (s->unknown2_3 & MALI_HAS_BLEND_SHADER) {
			panwrap_replay_shader_address("blend_shader", s->blend_shader);
		} else {
460
			panwrap_prop("blend_equation = 0x%" PRIx64, s->blend_equation);
461
		}
462

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
463 464
		panwrap_indent--;
		panwrap_log("};\n");
465
		TOUCH(smem, shader_meta_ptr, *meta, "shader_meta", job_no, false);
466

467
		panwrap_shader_disassemble(shader_ptr, job_no, h->job_type);
468

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
469 470
	} else
		panwrap_msg("<no shader>\n");
471
	
472 473 474
	if (v->viewport) {
		struct panwrap_mapped_memory *fmem = panwrap_find_mapped_gpu_mem_containing(v->viewport);
		struct mali_viewport *PANWRAP_PTR_VAR(f, fmem, v->viewport);
475

476
		panwrap_log("struct mali_viewport viewport_%d = {\n", job_no);
477
		panwrap_indent++;
478
		panwrap_log(".floats = {\n");
479 480 481 482 483 484
		panwrap_indent++;

		for (int i = 0; i < sizeof(f->floats) / sizeof(f->floats[0]); i += 2)
			panwrap_log("%ff, %ff,\n", f->floats[i], f->floats[i + 1]);

		panwrap_indent--;
485
		panwrap_log("},\n");
486 487 488 489 490 491 492 493 494

		/* Only the higher coordinates are MALI_POSITIVE scaled */

		panwrap_prop("viewport0 = { %d, %d }",
				f->viewport0[0], f->viewport0[1]);

		panwrap_prop("viewport1 = { MALI_POSITIVE(%d), MALI_POSITIVE(%d) }",
				f->viewport1[0] + 1, f->viewport1[1] + 1);

495 496 497
		panwrap_indent--;
		panwrap_log("};\n");

498
		TOUCH(fmem, v->viewport, *f, "viewport", job_no, true);
499
	}
500 501

	if (v->attribute_meta) {
502
		panwrap_log("struct mali_attr_meta attribute_meta_%d[] = {\n", job_no);
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
		panwrap_indent++;

		size_t count = 0;

		struct mali_attr_meta *attr_meta;
		mali_ptr p;

		attr_mem = panwrap_find_mapped_gpu_mem_containing(v->attribute_meta);

		for (p = v->attribute_meta;
		     *PANWRAP_PTR(attr_mem, p, u64) != 0;
		     p += sizeof(struct mali_attr_meta), count++) {
			attr_meta = panwrap_fetch_gpu_mem(attr_mem, p,
							  sizeof(*attr_mem));

			panwrap_log("{ .index = %d, .flags = 0x%" PRIx64 "},\n",
519
					attr_meta->index, (u64) attr_meta->flags);
520 521 522 523 524
		}

		panwrap_indent--;
		panwrap_log("};\n");

525
		TOUCH_LEN(attr_mem, v->attribute_meta, sizeof(struct mali_attr_meta) * count, "attribute_meta", job_no, true);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
526 527 528

		attr_mem = panwrap_find_mapped_gpu_mem_containing(v->attributes);

529
		panwrap_replay_attributes( attr_mem, v->attributes, job_no, attribute_count, false);
530
	}
531

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
532 533 534 535 536 537
	/* Varyings are encoded like attributes but not actually sent; we just
	 * pass a zero buffer with the right stride/size set, (or whatever)
	 * since the GPU will write to it itself */

	if (v->varyings) {
		attr_mem = panwrap_find_mapped_gpu_mem_containing(v->varyings);
538

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
539 540
		/* Number of descriptors depends on whether there are
		 * non-internal varyings */
541

542
		panwrap_replay_attributes(attr_mem, v->varyings, job_no, varying_count > 1 ? 2 : 1, true);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
543 544
	}

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
545 546 547
	/* XXX: This entire block is such a hack... where are uniforms configured exactly? */

	if (v->uniforms) {
548
		int rows = uniform_count, width = 4;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
549 550 551 552 553 554 555 556 557 558
		size_t sz = rows * width * sizeof(float);

		struct panwrap_mapped_memory *uniform_mem = panwrap_find_mapped_gpu_mem_containing(v->uniforms);
		panwrap_fetch_gpu_mem(uniform_mem, v->uniforms, sz);
		float *PANWRAP_PTR_VAR(uniforms, uniform_mem, v->uniforms);

		panwrap_log("float uniforms_%d[] = {\n", job_no);

		panwrap_indent++;
		for (int row = 0; row < rows; row++) {
559
			panwrap_log_empty();
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
560 561 562 563 564 565 566 567 568 569 570

			for (int i = 0; i < width; i++)
				panwrap_log_cont("%ff, ", uniforms[i]);

			panwrap_log_cont("\n");

			uniforms += width;
		}
		panwrap_indent--;
		panwrap_log("};\n");

571
		TOUCH_LEN(mem, v->uniforms, sz, "uniforms", job_no, true);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
572 573
	}

574 575 576 577 578 579 580 581 582
	if (v->unknown1) {
		struct panwrap_mapped_memory *umem = panwrap_find_mapped_gpu_mem_containing(v->unknown1);

		if (umem) {
			u64 *PANWRAP_PTR_VAR(u, umem, v->unknown1);

			mali_ptr ptr = *u >> 8;
			uint8_t flags = *u & 0xFF;

583 584 585 586 587
			/* Points to... a buffer of zeroes in the same region?
			 * *shrug* Deliberate 0 length so we don't memset
			 * anything out */
			
			panwrap_log("u32 inner_unknown1_%d = 0; /* XXX */\n", job_no);
588
			TOUCH_LEN(umem, ptr, 0, "inner_unknown1", job_no, true);
589 590

			panwrap_log("u64 unknown1_%d = ((inner_unknown1_%d_p) << 8) | %d;\n", job_no, job_no, flags);
591
			TOUCH(umem, v->unknown1, u64, "unknown1", job_no, true);
592 593
		}
	}
594 595 596 597 598

	if (v->unknown6) {
		struct panwrap_mapped_memory *umem = panwrap_find_mapped_gpu_mem_containing(v->unknown6);

		if (umem) {
599
			struct mali_unknown6 *PANWRAP_PTR_VAR(u, umem, v->unknown6 & ~0xF);
600 601 602 603 604 605 606 607 608 609 610

			panwrap_log("struct mali_unknown6 unknown6_%d = {\n", job_no);
			panwrap_indent++;

			panwrap_prop("unknown0 = 0x%" PRIx64, u->unknown0);
			panwrap_prop("unknown1 = 0x%" PRIx64, u->unknown1);


			panwrap_indent--;
			panwrap_log("};\n");

611
			TOUCH(umem, v->unknown6 & ~0xF, *u, "unknown6", job_no, true);
612 613
		}
	}
614

615 616
	/* Just a pointer to... another pointer >_< */

617 618
	if (v->texture_trampoline) {
		struct panwrap_mapped_memory *mmem = panwrap_find_mapped_gpu_mem_containing(v->texture_trampoline);
619 620

		if (mmem) {
621
			mali_ptr *PANWRAP_PTR_VAR(u, mmem, v->texture_trampoline);
622 623

			char *a = pointer_as_memory_reference(*u);
624
			panwrap_log("uint64_t texture_trampoline_%d = %s;", job_no, a);
625 626
			free(a);

627
			TOUCH(mmem, v->texture_trampoline, *u, "texture_trampoline", job_no, true);
628 629 630 631 632 633 634 635 636 637

			/* Now, finally, descend down into the texture descriptor */
			struct panwrap_mapped_memory *tmem = panwrap_find_mapped_gpu_mem_containing(*u);

			if (tmem) {
				struct mali_texture_descriptor *PANWRAP_PTR_VAR(t, tmem, *u);

				panwrap_log("struct mali_texture_descriptor texture_descriptor_%d = {\n", job_no);
				panwrap_indent++;

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
638 639
				panwrap_prop("width = MALI_POSITIVE(%" PRId16 ")", t->width + 1);
				panwrap_prop("height = MALI_POSITIVE(%" PRId16 ")", t->height + 1);
640

641
				panwrap_prop("unknown1 = 0x%" PRIx32, t->unknown1);
642
				
643 644 645
				/* TODO: I don't understand how these work at all yet */
				panwrap_prop("format1 = 0x%" PRIx32, t->format1);
				panwrap_prop("format2 = 0x%" PRIx32, t->format2);
646

647
				panwrap_prop("unknown3 = 0x%" PRIx32, t->unknown3);
648

649 650 651
				panwrap_prop("unknown5 = 0x%" PRIx32, t->unknown5);
				panwrap_prop("unknown6 = 0x%" PRIx32, t->unknown6);
				panwrap_prop("unknown7 = 0x%" PRIx32, t->unknown7);
652 653 654

				MEMORY_PROP(t, swizzled_bitmap_0);
				MEMORY_PROP(t, swizzled_bitmap_1);
655 656 657 658

				panwrap_indent--;
				panwrap_log("};\n");

659
				TOUCH(tmem, *u, *t, "texture_descriptor", job_no, false);
660
			}
661 662 663
		}
	}

664 665 666 667 668 669 670 671 672
	if (v->sampler_descriptor) {
		struct panwrap_mapped_memory *smem = panwrap_find_mapped_gpu_mem_containing(v->sampler_descriptor);

		if (smem) {
			struct mali_sampler_descriptor *PANWRAP_PTR_VAR(s, smem, v->sampler_descriptor);

			panwrap_log("struct mali_sampler_descriptor sampler_descriptor_%d = {\n", job_no);
			panwrap_indent++;

673
			/* Only the lower two bits are understood right now; the rest we display as hex */
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
674
			panwrap_log(".filter_mode = MALI_GL_TEX_MIN(%s) | MALI_GL_TEX_MAG(%s) | 0x%" PRIx32",\n",
675 676 677
				       	MALI_FILTER_NAME(s->filter_mode & MALI_GL_TEX_MIN_MASK),
				       	MALI_FILTER_NAME(s->filter_mode & MALI_GL_TEX_MAG_MASK),
					s->filter_mode & ~3);
678 679 680 681 682 683 684

			panwrap_prop("unknown1 = 0x%" PRIx32, s->unknown1);
			panwrap_prop("unknown2 = 0x%" PRIx32, s->unknown2);

			panwrap_indent--;
			panwrap_log("};\n");

685
			TOUCH(smem, v->sampler_descriptor, *s, "sampler_descriptor", job_no, false);
686 687
		}
	}
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708

	if (v->indices) {
		struct panwrap_mapped_memory *imem = panwrap_find_mapped_gpu_mem_containing(v->indices);

		if (imem) {
			/* Indices are literally just a u32 array :) */

			uint32_t *PANWRAP_PTR_VAR(indices, imem, v->indices);

			panwrap_log("uint32_t indices_%d[] = {\n", job_no);
			panwrap_indent++;

			for(int i = 0; i < (v->index_count + 1); i += 3)
				panwrap_log("%d, %d, %d,\n",
						indices[i],
						indices[i + 1],
						indices[i + 2]);

			panwrap_indent--;
			panwrap_log("};\n");

709
			TOUCH_LEN(imem, v->indices, sizeof(uint32_t) * (v->index_count + 1), "indices", job_no, false);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
710 711
		}
	}
712 713


714
	panwrap_log("struct mali_payload_vertex_tiler payload_%d = {\n", job_no);
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759
	panwrap_indent++;

	panwrap_prop("line_width = %ff", v->line_width);
	panwrap_prop("vertex_count = MALI_POSITIVE(%" PRId32 ")", v->vertex_count + 1);
	panwrap_prop("unk1 = 0x%" PRIx32, v->unk1);

	if (h->job_type == JOB_TYPE_TILER) {
		panwrap_prop("draw_mode = 0x%" PRIx32 " | %s", v->draw_mode & ~(0xF), panwrap_gl_mode_name(v->draw_mode & 0xF));
	} else {
		panwrap_prop("draw_mode = 0x%" PRIx32, v->draw_mode);
	}

	/* Index count only exists for tiler jobs anyway */ 

	if (v->index_count)
		panwrap_prop("index_count = MALI_POSITIVE(%" PRId32 ")", v->index_count + 1);

	uint32_t remaining_gl_enables = v->gl_enables;

	panwrap_log(".gl_enables = ");
	
	if (h->job_type == JOB_TYPE_TILER) {
		panwrap_log_cont("MALI_GL_FRONT_FACE(MALI_GL_%s) | ",
		    v->gl_enables & MALI_GL_FRONT_FACE(MALI_GL_CW) ? "CW" : "CCW");

		remaining_gl_enables &= ~(MALI_GL_FRONT_FACE(1));
	}

	panwrap_log_decoded_flags(gl_enable_flag_info, remaining_gl_enables);

	panwrap_log_cont(",\n");

	if (h->job_type == JOB_TYPE_VERTEX && v->index_count)
		panwrap_msg("Warning: index count set in vertex job\n");

	if (v->zero0 | v->zero1 | v->zero3 | v->zero4 | v->zero5 | v->zero6) {
		panwrap_msg("Zero tripped, replay may be wrong\n");
		panwrap_prop("zero0 = 0x%" PRIx32, v->zero0);
		panwrap_prop("zero1 = 0x%" PRIx32, v->zero1);
		panwrap_prop("zero3 = 0x%" PRIx32, v->zero3);
		panwrap_prop("zero4 = 0x%" PRIx32, v->zero4);
		panwrap_prop("zero5 = 0x%" PRIx32, v->zero5);
		panwrap_prop("zero6 = 0x%" PRIx32, v->zero6);
	}

760
	DYN_MEMORY_PROP(v, job_no, indices);
761
	//DYN_MEMORY_PROP(v, job_no, unknown0);
762
	DYN_MEMORY_PROP(v, job_no, unknown1); 
763
	DYN_MEMORY_PROP(v, job_no, texture_trampoline);
764
	DYN_MEMORY_PROP(v, job_no, sampler_descriptor);
765 766 767 768
	DYN_MEMORY_PROP(v, job_no, uniforms);
	DYN_MEMORY_PROP(v, job_no, attributes); 
	DYN_MEMORY_PROP(v, job_no, attribute_meta); 
	DYN_MEMORY_PROP(v, job_no, varyings); 
769
	//DYN_MEMORY_PROP(v, job_no, unknown6);
770
	DYN_MEMORY_PROP(v, job_no, viewport);
771
	DYN_MEMORY_PROP(v, job_no, framebuffer);
772

773
	MEMORY_PROP(v, unknown0);
774

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
775
	panwrap_prop("_shader_upper = (shader_meta_%d_p) >> 4", job_no);
776 777
	panwrap_prop("flags = %d", v->flags); 

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
778 779
	if (v->unknown6)
		panwrap_prop("unknown6 = (unknown6_%d_p) | 0x%X", job_no, v->unknown6 & 0xF);
780

781 782 783
	panwrap_indent--;
	panwrap_log("};\n");

784
	return sizeof(*v);
785 786
}

787
static int panwrap_replay_fragment_job(const struct panwrap_mapped_memory *mem,
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
788 789 790 791
					mali_ptr payload, int job_no)
{
	const struct mali_payload_fragment *PANWRAP_PTR_VAR(s, mem, payload);

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
792 793
	bool fbd_dumped = false;

794
	if ((s->framebuffer & FBD_TYPE) == MALI_SFBD) {
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
795 796 797 798 799 800 801 802
		/* Only SFBDs are understood, not MFBDs. We're speculating,
		 * based on the versioning, kernel code, etc, that the
		 * difference is between Single FrameBuffer Descriptor and
		 * Multiple FrmaeBuffer Descriptor; the change apparently lines
		 * up with multi-framebuffer support being added (T7xx onwards,
		 * including Gxx). In any event, there's some field shuffling
		 * that we haven't looked into yet. */

803
		panwrap_replay_sfbd(s->framebuffer & FBD_MASK, job_no);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
804 805 806
		fbd_dumped = true;
	}

807
	uintptr_t p = (uintptr_t) s->framebuffer & FBD_MASK;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
808

809
	panwrap_log("struct mali_payload_fragment payload_%d = {\n", job_no);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
810
	panwrap_indent++;
811

812 813 814
	if (s->zero)
		panwrap_msg("ZT\n");

815 816 817
	/* See the comments by the macro definitions for mathematical context
	 * on why this is so weird */

818 819 820 821 822 823 824 825 826
	panwrap_prop("min_tile_coord = MALI_COORDINATE_TO_TILE_MIN(%d, %d, %d)",
			MALI_TILE_COORD_X(s->min_tile_coord) << MALI_TILE_SHIFT,
			MALI_TILE_COORD_Y(s->min_tile_coord) << MALI_TILE_SHIFT,
			MALI_TILE_COORD_FLAGS(s->min_tile_coord));

	panwrap_prop("max_tile_coord = MALI_COORDINATE_TO_TILE_MAX(%d, %d, %d)",
			(MALI_TILE_COORD_X(s->max_tile_coord) + 1) << MALI_TILE_SHIFT,
			(MALI_TILE_COORD_Y(s->max_tile_coord) + 1) << MALI_TILE_SHIFT,
			MALI_TILE_COORD_FLAGS(s->max_tile_coord));
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
827

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
828 829 830
	/* If the FBD was just decoded, we can refer to it by pointer. If not,
	 * we have to fallback on offsets. */

831
	const char *fbd_type = s->framebuffer & MALI_MFBD ? "MALI_MFBD" : "MALI_SFBD";
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
832 833

	if (fbd_dumped)
834
		panwrap_prop("framebuffer = framebuffer_%d_p | %s", job_no, fbd_type);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
835
	else
836
		panwrap_prop("framebuffer = %s | %s", pointer_as_memory_reference(p), fbd_type);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
837

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
838 839
	panwrap_indent--;
	panwrap_log("};\n");
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
840

841
	return sizeof(*s);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
842 843
}

844 845
static int job_descriptor_number = 0;

846
int panwrap_replay_jc(mali_ptr jc_gpu_va)
847 848 849
{
	struct mali_job_descriptor_header *h;

850 851
	int start_number;

852
	bool first = true;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
853
	bool last_size;
854

855
	do {
856 857 858
		struct panwrap_mapped_memory *mem =
			panwrap_find_mapped_gpu_mem_containing(jc_gpu_va);

859 860 861
		void *payload;

		h = PANWRAP_PTR(mem, jc_gpu_va, typeof(*h));
862 863 864 865

		int offset = h->job_descriptor_size == MALI_JOB_32 ? 4 : 0;
		mali_ptr payload_ptr = jc_gpu_va + sizeof(*h) - offset;

866 867 868
		payload = panwrap_fetch_gpu_mem(mem, payload_ptr,
						MALI_PAYLOAD_SIZE);

869 870
		int job_no = job_descriptor_number++;

871 872 873
		if (first)
			start_number = job_no;

874 875 876
		panwrap_log("struct mali_job_descriptor_header job_%d = {\n", job_no);
		panwrap_indent++;

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
877
		panwrap_prop("job_type = %s", panwrap_job_type_name(h->job_type));
878

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
879 880 881
		/* Save for next job fixing */
		last_size = h->job_descriptor_size;

882 883 884
		if (h->job_descriptor_size)
			panwrap_prop("job_descriptor_size = %d", h->job_descriptor_size);

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
885 886 887 888 889 890 891 892 893 894 895 896
		if (h->exception_status)
			panwrap_prop("exception_status = %d", h->exception_status);

		if (h->first_incomplete_task)
			panwrap_prop("first_incomplete_task = %d", h->first_incomplete_task);

		if (h->fault_pointer)
			panwrap_prop("fault_pointer = 0x%" PRIx64, h->fault_pointer);

		if (h->job_barrier)
			panwrap_prop("job_barrier = %d", h->job_barrier);

897 898
		panwrap_prop("job_index = %d", h->job_index);

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
899 900 901
		if (h->unknown_flags)
			panwrap_prop("unknown_flags = %d", h->unknown_flags);

902
		if (h->job_dependency_index_1)
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
903
			panwrap_prop("job_dependency_index_1 = %d", h->job_dependency_index_1);
904

905 906
		if (h->job_dependency_index_2)
			panwrap_prop("job_dependency_index_2 = %d", h->job_dependency_index_2);
907

908 909 910
		panwrap_indent--;
		panwrap_log("};\n");

911 912 913 914 915
		/* Do not touch the field yet -- decode the payload first, and
		 * don't touch that either. This is essential for the uploads
		 * to occur in sequence and therefore be dynamically allocated
		 * correctly. Do note the size, however, for that related
		 * reason. */
916

917
		int payload_size = 0;
918

919 920 921 922 923
		switch (h->job_type) {
		case JOB_TYPE_SET_VALUE:
			{
				struct mali_payload_set_value *s = payload;

924
				panwrap_log("struct mali_payload_set_value payload_%d = {\n", job_no);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
925
				panwrap_indent++;
926
				MEMORY_PROP(s, out);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
927 928 929
				panwrap_prop("unknown = 0x%" PRIX64, s->unknown);
				panwrap_indent--;
				panwrap_log("};\n");
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
930

931
				payload_size = sizeof(*s);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
932

933 934 935 936
				break;
			}
		case JOB_TYPE_TILER:
		case JOB_TYPE_VERTEX:
937 938
			payload_size = panwrap_replay_vertex_or_tiler_job(h, mem, payload_ptr, job_no);

939 940
			break;
		case JOB_TYPE_FRAGMENT:
941
			payload_size = panwrap_replay_fragment_job(mem, payload_ptr, job_no);
942 943 944 945
			break;
		default:
			break;
		}
946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966

		/* Touch the job descriptor fields, careful about 32/64-bit */
		TOUCH_JOB_HEADER(mem, jc_gpu_va, sizeof(*h), offset, job_no);

		/* Touch the payload immediately after, sequentially */
		TOUCH_SEQUENTIAL(mem, payload_ptr, payload_size, "payload", job_no);

		/* Handle linkage */

		if (!first) {
			panwrap_log("((struct mali_job_descriptor_header *) (uintptr_t) job_%d_p)->", job_no - 1);

			if (last_size)
				panwrap_log_cont("next_job_64 = job_%d_p;\n\n", job_no);
			else
				panwrap_log_cont("next_job_32 = (u32) (uintptr_t) job_%d_p;\n\n", job_no);
		}

		first = false;


Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
967
	} while ((jc_gpu_va = h->job_descriptor_size ? h->next_job_64 : h->next_job_32));
968 969

	return start_number;
970
}
971

972 973 974 975 976 977 978 979 980 981 982 983
void panwrap_replay_soft_replay_payload(mali_ptr jc_gpu_va, int job_no)
{
	struct mali_jd_replay_payload *v;

	struct panwrap_mapped_memory *mem =
		panwrap_find_mapped_gpu_mem_containing(jc_gpu_va);

	v = PANWRAP_PTR(mem, jc_gpu_va, typeof(*v));

	panwrap_log("struct mali_jd_replay_payload soft_replay_payload_%d = {\n", job_no);
	panwrap_indent++;

984 985 986
	MEMORY_PROP(v, tiler_jc_list);
	MEMORY_PROP(v, fragment_jc);
	MEMORY_PROP(v, tiler_heap_free);
987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008

	panwrap_prop("fragment_hierarchy_mask = 0x%" PRIx32, v->fragment_hierarchy_mask);
	panwrap_prop("tiler_hierarchy_mask = 0x%" PRIx32, v->tiler_hierarchy_mask);
	panwrap_prop("hierarchy_default_weight = 0x%" PRIx32, v->hierarchy_default_weight);

	panwrap_log(".tiler_core_req = ");
	if (v->tiler_core_req)
		ioctl_log_decoded_jd_core_req(v->tiler_core_req);
	else
		panwrap_log_cont("0");
	panwrap_log_cont(",\n");

	panwrap_log(".fragment_core_req = ");
	if (v->fragment_core_req)
		ioctl_log_decoded_jd_core_req(v->fragment_core_req);
	else
		panwrap_log_cont("0");
	panwrap_log_cont(",\n");

	panwrap_indent--;
	panwrap_log("};\n");

1009
	TOUCH(mem, jc_gpu_va, *v, "soft_replay_payload", job_no, false);
1010 1011
}

1012
int panwrap_replay_soft_replay(mali_ptr jc_gpu_va)
1013 1014
{
	struct mali_jd_replay_jc *v;
1015 1016
	int start_no;
	bool first = true;
1017 1018 1019 1020 1021 1022 1023 1024

	do {
		struct panwrap_mapped_memory *mem =
			panwrap_find_mapped_gpu_mem_containing(jc_gpu_va);

		v = PANWRAP_PTR(mem, jc_gpu_va, typeof(*v));

		int job_no = job_descriptor_number++;
1025 1026 1027 1028 1029 1030 1031

		if (first)
			start_no = job_no;

		first = false;

		panwrap_log("struct mali_jd_replay_jc job_%d = {\n", job_no);
1032 1033
		panwrap_indent++;

1034 1035
		MEMORY_PROP(v, next);
		MEMORY_PROP(v, jc);
1036 1037 1038 1039

		panwrap_indent--;
		panwrap_log("};\n");

1040 1041
		panwrap_replay_soft_replay_payload(jc_gpu_va + sizeof(struct mali_jd_replay_jc), job_no);

1042
		TOUCH(mem, jc_gpu_va, *v, "job", job_no, false);
1043
	} while ((jc_gpu_va = v->next));
1044 1045

	return start_no;
1046
}