panwrap-decoder.c 31.3 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

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
51 52 53 54 55 56 57 58 59 60
#define FLAG_INFO(flag) { MALI_MASK_##flag, "MALI_MASK_" #flag }
static const struct panwrap_flag_info mask_flag_info[] = {
	FLAG_INFO(R),
	FLAG_INFO(G),
	FLAG_INFO(B),
	FLAG_INFO(A),
	{}
};
#undef FLAG_INFO

61 62
#define FLAG_INFO(flag) { MALI_##flag, "MALI_" #flag }
static const struct panwrap_flag_info u3_flag_info[] = {
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
63
	FLAG_INFO(HAS_MSAA),
64 65
	FLAG_INFO(CAN_DISCARD),
	FLAG_INFO(HAS_BLEND_SHADER),
66
	FLAG_INFO(DEPTH_TEST),
67 68
	{}
};
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
69 70 71

static const struct panwrap_flag_info u4_flag_info[] = {
	FLAG_INFO(NO_MSAA),
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
72
	FLAG_INFO(NO_DITHER),
73 74
	FLAG_INFO(DEPTH_RANGE_A),
	FLAG_INFO(DEPTH_RANGE_B),
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
75
	FLAG_INFO(STENCIL_TEST),
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
76 77
	{}
};
78
#undef FLAG_INFO
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
79

80 81 82 83 84 85 86
#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),
	{}
};
87
#undef FLAG_INFO
88

89 90
extern char* replace_fragment;
extern char* replace_vertex;
91 92 93

static char *panwrap_job_type_name(enum mali_job_type type)
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
94
#define DEFINE_CASE(name) case JOB_TYPE_ ## name: return "JOB_TYPE_" #name
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
	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
115
#define DEFINE_CASE(name) case MALI_ ## name: return "MALI_" #name
116 117 118 119 120 121
	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
122 123
	DEFINE_CASE(GL_LINE_STRIP);
	DEFINE_CASE(GL_LINE_LOOP);
124 125 126 127 128
	default: return "MALI_GL_TRIANGLES /* XXX: Unknown GL mode, check dump */";
	}
#undef DEFINE_CASE
}

129 130
#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
131 132 133 134 135 136 137 138 139 140
{
	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);
141
	default: return "MALI_FUNC_NEVER /* XXX: Unknown function, check dump */";
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
142 143
	}
}
144
#undef DEFINE_CASE
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
145

146
#define DEFINE_CASE(name) case MALI_STENCIL_ ## name: return "MALI_STENCIL_" #name
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
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
164 165 166 167 168 169 170 171 172 173
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");
}

174 175 176 177 178 179 180
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!?";
}

181 182 183 184 185 186 187 188 189 190 191 192 193 194
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
195
{
196
	struct panwrap_mapped_memory *mem = panwrap_find_mapped_gpu_mem_containing(gpu_va);
197
	const struct mali_single_framebuffer *PANWRAP_PTR_VAR(s, mem, (mali_ptr) gpu_va);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
198

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

202
	panwrap_log("struct mali_single_framebuffer framebuffer_%d = {\n", job_no);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
203 204 205 206 207
	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);
208 209 210 211

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

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
213 214
	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
215 216 217

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

218 219 220 221 222 223 224
	/* 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");

225 226 227 228
	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
229

230 231 232 233
	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
234

235 236 237 238 239 240
	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
241

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
242
	if (s->clear_depth_1 != 0 || s->clear_depth_2 != 0 || s->clear_depth_3 != 0 || s->clear_depth_4 != 0) {
243 244 245 246 247
		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
248

249 250 251
	if (s->clear_stencil) {
		panwrap_prop("clear_stencil = 0x%x", s->clear_stencil);
	}
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
252

253 254 255
	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
256 257 258 259

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

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
260
	panwrap_prop("tiler_jc_list = 0x%" PRIx64, s->tiler_jc_list);
261 262

	MEMORY_PROP(s, unknown_address_4);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
263 264 265 266 267 268 269 270 271 272 273 274 275

	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);

276
	TOUCH(mem, (mali_ptr) gpu_va, *s, "framebuffer", job_no, true);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
277 278
}

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
279
void panwrap_replay_attributes(const struct panwrap_mapped_memory *mem,
280
			       mali_ptr addr, int job_no, int count, bool varying)
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
281
{
282
	char *prefix = varying ? "varyings" : "attributes";
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
283

284 285
	/* 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
286

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

289 290
	char base[128];
	snprintf(base, sizeof(base), "%s_data_%d", prefix, job_no);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
291

292 293
	for (int i = 0; i < count; ++i) {
		mali_ptr raw_elements = attr[i].elements & ~3;
294

295 296
		size_t vertex_count;
		size_t component_count;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
297

298 299 300
		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
301

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

304 305
			vertex_count = attr[i].size / attr[i].stride;
			component_count = attr[i].stride / sizeof(float);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
306

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

309 310 311
			panwrap_indent++;
			for (int row = 0; row < vertex_count; row++) {
				panwrap_log_empty();
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
312

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

316 317 318 319 320 321
				panwrap_log_cont("\n");

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

323
			TOUCH_LEN(mem, raw_elements, attr[i].size, base, i, true);
324 325 326 327 328 329 330
		} 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
331
	}
332

333
	panwrap_log("struct mali_attr %s_%d[] = {\n", prefix, job_no);
334 335
	panwrap_indent++;

336 337 338 339 340 341 342 343 344 345 346
	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");
347 348 349 350 351
	}

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

352
	TOUCH_LEN(mem, addr, sizeof(*attr) * count, prefix, job_no, true);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
353 354
}

355 356 357 358 359 360 361 362 363 364 365 366 367
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;
}

368
static void
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
369
panwrap_replay_stencil(const char *name, const u32 *raw)
370
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
371
	const struct mali_stencil_test *stencil = (struct mali_stencil_test *) raw;
372

373
	const char *func = panwrap_func_name(stencil->func);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
374 375 376
	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);
377

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

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
381 382 383 384 385 386 387 388 389 390
	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");
391 392
}

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
static void
panwrap_replay_blend_equation(const u32 *raw)
{
	const struct mali_blend_equation *blend = (struct mali_blend_equation *) raw;

	if (blend->zero)
		panwrap_msg("Blend zero tripped: %X\n", blend->zero);

	panwrap_log(".blend_equation = {\n");
	panwrap_indent++;

	panwrap_prop("unknown = 0x%X", blend->unknown);

	panwrap_log(".color_mask = ");
	panwrap_log_decoded_flags(mask_flag_info, blend->color_mask);
	panwrap_log_cont(",\n");

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

414 415
static int
panwrap_replay_vertex_or_tiler_job(const struct mali_job_descriptor_header *h,
416 417 418 419 420 421
					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
422
	mali_ptr shader_meta_ptr = (u64) (uintptr_t) (v->_shader_upper << 4);
423

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

427
	int varying_count, attribute_count, uniform_count;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
428

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
429 430 431 432 433 434 435
	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++;

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

438 439
		if (s->zero1)
			panwrap_msg("XXX shader zero tripped\n");
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
440

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
441
		panwrap_prop("attribute_count = %" PRId16, s->attribute_count);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
442
		panwrap_prop("varying_count = %" PRId16, s->varying_count);
443 444 445 446
		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
447

448 449
		/* Save for dumps */
		attribute_count = s->attribute_count;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
450
		varying_count = s->varying_count;
451
		uniform_count = s->uniform_count; 
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
452

453 454 455
		/* 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
456

457 458 459 460
		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);
		}
461 462

		panwrap_log(".unknown2_3 = ");
463 464

		int unknown2_3 = s->unknown2_3;
465
		int unknown2_4 = s->unknown2_4;
466 467 468 469 470 471 472 473 474 475 476 477
		
		/* 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);
478
		panwrap_log_cont(",\n");
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
479

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
480
		panwrap_log(".unknown2_4 = ");
481 482 483 484 485 486 487 488 489 490

		/* TODO: Make less ugly */

		panwrap_log_cont("MALI_STENCIL_MASK_FRONT(0x%02X) | MALI_STENCIL_MASK_BACK(0x%02X) | ",
				MALI_GET_STENCIL_MASK_FRONT(unknown2_4),
				MALI_GET_STENCIL_MASK_BACK(unknown2_4));

		unknown2_4 &= ~MALI_STENCIL_MASK_MASK;

		panwrap_log_decoded_flags(u4_flag_info, unknown2_4);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
491 492
		panwrap_log_cont(",\n");

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
493 494
		panwrap_replay_stencil("front", &s->stencil_front);
		panwrap_replay_stencil("back", &s->stencil_back);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
495

496 497
		panwrap_prop("unknown2_7 = 0x%" PRIx32, s->unknown2_7);
		panwrap_prop("unknown2_8 = 0x%" PRIx32, s->unknown2_8);
498 499 500 501

		if (s->unknown2_3 & MALI_HAS_BLEND_SHADER) {
			panwrap_replay_shader_address("blend_shader", s->blend_shader);
		} else {
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
502
			panwrap_replay_blend_equation(&s->blend_equation);
503
		}
504

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
505 506
		panwrap_indent--;
		panwrap_log("};\n");
507
		TOUCH(smem, shader_meta_ptr, *meta, "shader_meta", job_no, false);
508

509
		panwrap_shader_disassemble(shader_ptr, job_no, h->job_type);
510

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
511 512
	} else
		panwrap_msg("<no shader>\n");
513
	
514 515 516
	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);
517

518
		panwrap_log("struct mali_viewport viewport_%d = {\n", job_no);
519
		panwrap_indent++;
520
		panwrap_log(".floats = {\n");
521 522 523 524 525 526
		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--;
527
		panwrap_log("},\n");
528

529 530 531
		panwrap_prop("depth_range_n = %f", f->depth_range_n);
		panwrap_prop("depth_range_f = %f", f->depth_range_f);

532 533 534 535 536 537 538 539
		/* 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);

540 541 542
		panwrap_indent--;
		panwrap_log("};\n");

543
		TOUCH(fmem, v->viewport, *f, "viewport", job_no, true);
544
	}
545 546

	if (v->attribute_meta) {
547
		panwrap_log("struct mali_attr_meta attribute_meta_%d[] = {\n", job_no);
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
		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",
564
					attr_meta->index, (u64) attr_meta->flags);
565 566 567 568 569
		}

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

570
		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
571 572 573

		attr_mem = panwrap_find_mapped_gpu_mem_containing(v->attributes);

574
		panwrap_replay_attributes( attr_mem, v->attributes, job_no, attribute_count, false);
575
	}
576

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
577 578 579 580 581 582
	/* 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);
583

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
584 585
		/* Number of descriptors depends on whether there are
		 * non-internal varyings */
586

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

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

	if (v->uniforms) {
593
		int rows = uniform_count, width = 4;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
594 595 596 597 598 599 600 601 602 603
		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++) {
604
			panwrap_log_empty();
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
605 606 607 608 609 610 611 612 613 614 615

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

			panwrap_log_cont("\n");

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

616
		TOUCH_LEN(mem, v->uniforms, sz, "uniforms", job_no, true);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
617 618
	}

619 620 621 622 623 624 625 626 627
	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;

628 629 630 631 632
			/* 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);
633
			TOUCH_LEN(umem, ptr, 0, "inner_unknown1", job_no, true);
634 635

			panwrap_log("u64 unknown1_%d = ((inner_unknown1_%d_p) << 8) | %d;\n", job_no, job_no, flags);
636
			TOUCH(umem, v->unknown1, u64, "unknown1", job_no, true);
637 638
		}
	}
639 640 641 642 643

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

		if (umem) {
644
			struct mali_unknown6 *PANWRAP_PTR_VAR(u, umem, v->unknown6 & ~0xF);
645 646 647 648 649 650 651 652 653 654 655

			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");

656
			TOUCH(umem, v->unknown6 & ~0xF, *u, "unknown6", job_no, true);
657 658
		}
	}
659

660 661
	/* Just a pointer to... another pointer >_< */

662 663
	if (v->texture_trampoline) {
		struct panwrap_mapped_memory *mmem = panwrap_find_mapped_gpu_mem_containing(v->texture_trampoline);
664 665

		if (mmem) {
666
			mali_ptr *PANWRAP_PTR_VAR(u, mmem, v->texture_trampoline);
667 668

			char *a = pointer_as_memory_reference(*u);
669
			panwrap_log("uint64_t texture_trampoline_%d = %s;", job_no, a);
670 671
			free(a);

672
			TOUCH(mmem, v->texture_trampoline, *u, "texture_trampoline", job_no, true);
673 674 675 676 677 678 679 680 681 682

			/* 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
683 684
				panwrap_prop("width = MALI_POSITIVE(%" PRId16 ")", t->width + 1);
				panwrap_prop("height = MALI_POSITIVE(%" PRId16 ")", t->height + 1);
685

686
				panwrap_prop("unknown1 = 0x%" PRIx32, t->unknown1);
687
				
688 689 690
				/* 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);
691

692
				panwrap_prop("unknown3 = 0x%" PRIx32, t->unknown3);
693

694 695 696
				panwrap_prop("unknown5 = 0x%" PRIx32, t->unknown5);
				panwrap_prop("unknown6 = 0x%" PRIx32, t->unknown6);
				panwrap_prop("unknown7 = 0x%" PRIx32, t->unknown7);
697 698 699

				MEMORY_PROP(t, swizzled_bitmap_0);
				MEMORY_PROP(t, swizzled_bitmap_1);
700 701 702 703

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

704
				TOUCH(tmem, *u, *t, "texture_descriptor", job_no, false);
705
			}
706 707 708
		}
	}

709 710 711 712 713 714 715 716 717
	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++;

718
			/* Only the lower two bits are understood right now; the rest we display as hex */
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
719
			panwrap_log(".filter_mode = MALI_GL_TEX_MIN(%s) | MALI_GL_TEX_MAG(%s) | 0x%" PRIx32",\n",
720 721 722
				       	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);
723 724 725 726 727 728 729

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

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

730
			TOUCH(smem, v->sampler_descriptor, *s, "sampler_descriptor", job_no, false);
731 732
		}
	}
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753

	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");

754
			TOUCH_LEN(imem, v->indices, sizeof(uint32_t) * (v->index_count + 1), "indices", job_no, false);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
755 756
		}
	}
757 758


759
	panwrap_log("struct mali_payload_vertex_tiler payload_%d = {\n", job_no);
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
	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);
	}

805
	DYN_MEMORY_PROP(v, job_no, indices);
806
	//DYN_MEMORY_PROP(v, job_no, unknown0);
807
	DYN_MEMORY_PROP(v, job_no, unknown1); 
808
	DYN_MEMORY_PROP(v, job_no, texture_trampoline);
809
	DYN_MEMORY_PROP(v, job_no, sampler_descriptor);
810 811 812 813
	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); 
814
	//DYN_MEMORY_PROP(v, job_no, unknown6);
815
	DYN_MEMORY_PROP(v, job_no, viewport);
816
	DYN_MEMORY_PROP(v, job_no, framebuffer);
817

818
	MEMORY_PROP(v, unknown0);
819

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

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

826 827 828
	panwrap_indent--;
	panwrap_log("};\n");

829
	return sizeof(*v);
830 831
}

832
static int panwrap_replay_fragment_job(const struct panwrap_mapped_memory *mem,
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
833 834 835 836
					mali_ptr payload, int job_no)
{
	const struct mali_payload_fragment *PANWRAP_PTR_VAR(s, mem, payload);

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
837 838
	bool fbd_dumped = false;

839
	if ((s->framebuffer & FBD_TYPE) == MALI_SFBD) {
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
840 841 842 843 844 845 846 847
		/* 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. */

848
		panwrap_replay_sfbd(s->framebuffer & FBD_MASK, job_no);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
849 850 851
		fbd_dumped = true;
	}

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

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

857 858 859
	if (s->zero)
		panwrap_msg("ZT\n");

860 861 862
	/* See the comments by the macro definitions for mathematical context
	 * on why this is so weird */

863 864 865 866 867 868 869 870 871
	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
872

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

876
	const char *fbd_type = s->framebuffer & MALI_MFBD ? "MALI_MFBD" : "MALI_SFBD";
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
877 878

	if (fbd_dumped)
879
		panwrap_prop("framebuffer = framebuffer_%d_p | %s", job_no, fbd_type);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
880
	else
881
		panwrap_prop("framebuffer = %s | %s", pointer_as_memory_reference(p), fbd_type);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
882

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
883 884
	panwrap_indent--;
	panwrap_log("};\n");
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
885

886
	return sizeof(*s);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
887 888
}

889 890
static int job_descriptor_number = 0;

891
int panwrap_replay_jc(mali_ptr jc_gpu_va)
892 893 894
{
	struct mali_job_descriptor_header *h;

895 896
	int start_number;

897
	bool first = true;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
898
	bool last_size;
899

900
	do {
901 902 903
		struct panwrap_mapped_memory *mem =
			panwrap_find_mapped_gpu_mem_containing(jc_gpu_va);

904 905 906
		void *payload;

		h = PANWRAP_PTR(mem, jc_gpu_va, typeof(*h));
907 908 909 910

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

911 912 913
		payload = panwrap_fetch_gpu_mem(mem, payload_ptr,
						MALI_PAYLOAD_SIZE);

914 915
		int job_no = job_descriptor_number++;

916 917 918
		if (first)
			start_number = job_no;

919 920 921
		panwrap_log("struct mali_job_descriptor_header job_%d = {\n", job_no);
		panwrap_indent++;

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

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
924 925 926
		/* Save for next job fixing */
		last_size = h->job_descriptor_size;

927 928 929
		if (h->job_descriptor_size)
			panwrap_prop("job_descriptor_size = %d", h->job_descriptor_size);

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
930 931 932 933 934 935 936 937 938 939 940 941
		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);

942 943
		panwrap_prop("job_index = %d", h->job_index);

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
944 945 946
		if (h->unknown_flags)
			panwrap_prop("unknown_flags = %d", h->unknown_flags);

947
		if (h->job_dependency_index_1)
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
948
			panwrap_prop("job_dependency_index_1 = %d", h->job_dependency_index_1);
949

950 951
		if (h->job_dependency_index_2)
			panwrap_prop("job_dependency_index_2 = %d", h->job_dependency_index_2);
952

953 954 955
		panwrap_indent--;
		panwrap_log("};\n");

956 957 958 959 960
		/* 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. */
961

962
		int payload_size = 0;
963

964 965 966 967 968
		switch (h->job_type) {
		case JOB_TYPE_SET_VALUE:
			{
				struct mali_payload_set_value *s = payload;

969
				panwrap_log("struct mali_payload_set_value payload_%d = {\n", job_no);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
970
				panwrap_indent++;
971
				MEMORY_PROP(s, out);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
972 973 974
				panwrap_prop("unknown = 0x%" PRIX64, s->unknown);
				panwrap_indent--;
				panwrap_log("};\n");
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
975

976
				payload_size = sizeof(*s);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
977

978 979 980 981
				break;
			}
		case JOB_TYPE_TILER:
		case JOB_TYPE_VERTEX:
982 983
			payload_size = panwrap_replay_vertex_or_tiler_job(h, mem, payload_ptr, job_no);

984 985
			break;
		case JOB_TYPE_FRAGMENT:
986
			payload_size = panwrap_replay_fragment_job(mem, payload_ptr, job_no);
987 988 989 990
			break;
		default:
			break;
		}
991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011

		/* 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
1012
	} while ((jc_gpu_va = h->job_descriptor_size ? h->next_job_64 : h->next_job_32));
1013 1014

	return start_number;
1015
}
1016

1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028
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++;

1029 1030 1031
	MEMORY_PROP(v, tiler_jc_list);
	MEMORY_PROP(v, fragment_jc);
	MEMORY_PROP(v, tiler_heap_free);
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053

	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");

1054
	TOUCH(mem, jc_gpu_va, *v, "soft_replay_payload", job_no, false);
1055 1056
}

1057
int panwrap_replay_soft_replay(mali_ptr jc_gpu_va)
1058 1059
{
	struct mali_jd_replay_jc *v;
1060 1061
	int start_no;
	bool first = true;
1062 1063 1064 1065 1066 1067 1068 1069

	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++;
1070 1071 1072 1073 1074 1075 1076

		if (first)
			start_no = job_no;

		first = false;

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

1079 1080
		MEMORY_PROP(v, next);
		MEMORY_PROP(v, jc);
1081 1082 1083 1084

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

1085 1086
		panwrap_replay_soft_replay_payload(jc_gpu_va + sizeof(struct mali_jd_replay_jc), job_no);

1087
		TOUCH(mem, jc_gpu_va, *v, "job", job_no, false);
1088
	} while ((jc_gpu_va = v->next));
1089 1090

	return start_no;
1091
}