1/* 2 * Copyright (c) 2019 Andreas Baierl <ichgeh@imkreisrum.de> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sub license, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the 12 * next paragraph) shall be included in all copies or substantial portions 13 * of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 */ 24 25#include "util/u_math.h" 26 27#include <stdio.h> 28#include <stdint.h> 29#include <string.h> 30 31#include "lima_context.h" 32#include "lima_parser.h" 33#include "lima_texture.h" 34 35#include "lima/ir/gp/codegen.h" 36#include "lima/ir/pp/codegen.h" 37 38typedef struct { 39 char *info; 40} render_state_info; 41 42static render_state_info render_state_infos[] = { 43 { .info = "BLEND_COLOR_BG", }, 44 { .info = "BLEND_COLOR_RA", }, 45 { .info = "ALPHA_BLEND", }, 46 { .info = "DEPTH_TEST", }, 47 { .info = "DEPTH_RANGE", }, 48 { .info = "STENCIL_FRONT", }, 49 { .info = "STENCIL_BACK", }, 50 { .info = "STENCIL_TEST", }, 51 { .info = "MULTI_SAMPLE", }, 52 { .info = "SHADER_ADDRESS (FS)", }, 53 { .info = "VARYING_TYPES", }, 54 { .info = "UNIFORMS_ADDRESS (PP)", }, 55 { .info = "TEXTURES_ADDRESS", }, 56 { .info = "AUX0", }, 57 { .info = "AUX1", }, 58 { .info = "VARYINGS_ADDRESS", }, 59}; 60 61/* VS CMD stream parser functions */ 62 63static void 64parse_vs_draw(FILE *fp, uint32_t *value1, uint32_t *value2) 65{ 66 if ((*value1 == 0x00000000) && (*value2 == 0x00000000)) 67 fprintf(fp, "\t/* ---EMPTY CMD */\n"); 68 else 69 fprintf(fp, "\t/* DRAW: num: %d, index_draw: %s */\n", 70 (*value1 & 0xff000000) >> 24 | (*value2 & 0x000000ff) << 8, 71 (*value1 & 0x00000001) ? "true" : "false"); 72} 73 74static void 75parse_vs_shader_info(FILE *fp, uint32_t *value1, uint32_t *value2) 76{ 77 fprintf(fp, "\t/* SHADER_INFO: prefetch: %d, size: %d */\n", 78 (*value1 & 0xfff00000) >> 20, 79 (((*value1 & 0x000fffff) >> 10) + 1) << 4); 80} 81 82static void 83parse_vs_unknown1(FILE *fp, uint32_t *value1, uint32_t *value2) 84{ 85 fprintf(fp, "\t/* UNKNOWN_1 */\n"); 86} 87 88static void 89parse_vs_varying_attribute_count(FILE *fp, uint32_t *value1, uint32_t *value2) 90{ 91 fprintf(fp, "\t/* VARYING_ATTRIBUTE_COUNT: nr_vary: %d, nr_attr: %d */\n", 92 ((*value1 & 0x00ffffff) >> 8) + 1, (*value1 >> 24) + 1); 93} 94 95static void 96parse_vs_attributes_address(FILE *fp, uint32_t *value1, uint32_t *value2) 97{ 98 fprintf(fp, "\t/* ATTRIBUTES_ADDRESS: address: 0x%08x, size: %d */\n", 99 *value1, (*value2 & 0x0fffffff) >> 17); 100} 101 102static void 103parse_vs_varyings_address(FILE *fp, uint32_t *value1, uint32_t *value2) 104{ 105 fprintf(fp, "\t/* VARYINGS_ADDRESS: varying info @ 0x%08x, size: %d */\n", 106 *value1, (*value2 & 0x0fffffff) >> 17); 107} 108 109static void 110parse_vs_uniforms_address(FILE *fp, uint32_t *value1, uint32_t *value2) 111{ 112 fprintf(fp, "\t/* UNIFORMS_ADDRESS (GP): address: 0x%08x, size: %d */\n", 113 *value1, (*value2 & 0x0fffffff) >> 12); 114} 115 116static void 117parse_vs_shader_address(FILE *fp, uint32_t *value1, uint32_t *value2) 118{ 119 fprintf(fp, "\t/* SHADER_ADDRESS (VS): address: 0x%08x, size: %d */\n", 120 *value1, (*value2 & 0x0fffffff) >> 12); 121} 122 123static void 124parse_vs_semaphore(FILE *fp, uint32_t *value1, uint32_t *value2) 125{ 126 if (*value1 == 0x00028000) 127 fprintf(fp, "\t/* SEMAPHORE_BEGIN_1 */\n"); 128 else if (*value1 == 0x00000001) 129 fprintf(fp, "\t/* SEMAPHORE_BEGIN_2 */\n"); 130 else if (*value1 == 0x00000000) 131 fprintf(fp, "\t/* SEMAPHORE_END: index_draw disabled */\n"); 132 else if (*value1 == 0x00018000) 133 fprintf(fp, "\t/* SEMAPHORE_END: index_draw enabled */\n"); 134 else 135 fprintf(fp, "\t/* SEMAPHORE - cmd unknown! */\n"); 136} 137 138static void 139parse_vs_unknown2(FILE *fp, uint32_t *value1, uint32_t *value2) 140{ 141 fprintf(fp, "\t/* UNKNOWN_2 */\n"); 142} 143 144static void 145parse_vs_continue(FILE *fp, uint32_t *value1, uint32_t *value2) 146{ 147 fprintf(fp, "\t/* CONTINUE: at 0x%08x */\n", *value1); 148} 149 150void 151lima_parse_vs(FILE *fp, uint32_t *data, int size, uint32_t start) 152{ 153 uint32_t *value1; 154 uint32_t *value2; 155 156 fprintf(fp, "\n"); 157 fprintf(fp, "/* ============ VS CMD STREAM BEGIN ============= */\n"); 158 for (int i = 0; i * 4 < size; i += 2) { 159 value1 = &data[i]; 160 value2 = &data[i + 1]; 161 fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x 0x%08x", 162 start + i * 4, i * 4, *value1, *value2); 163 164 if ((*value2 & 0xffff0000) == 0x00000000) 165 parse_vs_draw(fp, value1, value2); 166 else if ((*value2 & 0xff0000ff) == 0x10000040) 167 parse_vs_shader_info(fp, value1, value2); 168 else if ((*value2 & 0xff0000ff) == 0x10000041) 169 parse_vs_unknown1(fp, value1, value2); 170 else if ((*value2 & 0xff0000ff) == 0x10000042) 171 parse_vs_varying_attribute_count(fp, value1, value2); 172 else if ((*value2 & 0xff0000ff) == 0x20000000) 173 parse_vs_attributes_address(fp, value1, value2); 174 else if ((*value2 & 0xff0000ff) == 0x20000008) 175 parse_vs_varyings_address(fp, value1, value2); 176 else if ((*value2 & 0xff000000) == 0x30000000) 177 parse_vs_uniforms_address(fp, value1, value2); 178 else if ((*value2 & 0xff000000) == 0x40000000) 179 parse_vs_shader_address(fp, value1, value2); 180 else if ((*value2 & 0xff000000)== 0x50000000) 181 parse_vs_semaphore(fp, value1, value2); 182 else if ((*value2 & 0xff000000) == 0x60000000) 183 parse_vs_unknown2(fp, value1, value2); 184 else if ((*value2 & 0xff000000) == 0xf0000000) 185 parse_vs_continue(fp, value1, value2); 186 else 187 fprintf(fp, "\t/* --- unknown cmd --- */\n"); 188 } 189 fprintf(fp, "/* ============ VS CMD STREAM END =============== */\n"); 190 fprintf(fp, "\n"); 191} 192 193/* PLBU CMD stream parser functions */ 194 195static void 196parse_plbu_block_step(FILE *fp, uint32_t *value1, uint32_t *value2) 197{ 198 fprintf(fp, "\t/* BLOCK_STEP: shift_min: %d, shift_h: %d, shift_w: %d */\n", 199 (*value1 & 0xf0000000) >> 28, 200 (*value1 & 0x0fff0000) >> 16, 201 *value1 & 0x0000ffff); 202} 203 204static void 205parse_plbu_tiled_dimensions(FILE *fp, uint32_t *value1, uint32_t *value2) 206{ 207 fprintf(fp, "\t/* TILED_DIMENSIONS: tiled_w: %d, tiled_h: %d */\n", 208 ((*value1 & 0xff000000) >> 24) + 1, 209 ((*value1 & 0x00ffff00) >> 8) + 1); 210} 211 212static void 213parse_plbu_block_stride(FILE *fp, uint32_t *value1, uint32_t *value2) 214{ 215 fprintf(fp, "\t/* BLOCK_STRIDE: block_w: %d */\n", *value1 & 0x000000ff); 216} 217 218static void 219parse_plbu_array_address(FILE *fp, uint32_t *value1, uint32_t *value2) 220{ 221 fprintf(fp, "\t/* ARRAY_ADDRESS: gp_stream: 0x%08x, block_num (block_w * block_h): %d */\n", 222 *value1, (*value2 & 0x00ffffff) + 1); 223} 224 225static void 226parse_plbu_viewport_left(FILE *fp, float *value1, uint32_t *value2) 227{ 228 fprintf(fp, "\t/* VIEWPORT_LEFT: viewport_left: %f */\n", *value1); 229} 230 231static void 232parse_plbu_viewport_right(FILE *fp, float *value1, uint32_t *value2) 233{ 234 fprintf(fp, "\t/* VIEWPORT_RIGHT: viewport_right: %f */\n", *value1); 235} 236 237static void 238parse_plbu_viewport_bottom(FILE *fp, float *value1, uint32_t *value2) 239{ 240 fprintf(fp, "\t/* VIEWPORT_BOTTOM: viewport_bottom: %f */\n", *value1); 241} 242 243static void 244parse_plbu_viewport_top(FILE *fp, float *value1, uint32_t *value2) 245{ 246 fprintf(fp, "\t/* VIEWPORT_TOP: viewport_top: %f */\n", *value1); 247} 248 249static void 250parse_plbu_semaphore(FILE *fp, uint32_t *value1, uint32_t *value2) 251{ 252 if (*value1 == 0x00010002) 253 fprintf(fp, "\t/* ARRAYS_SEMAPHORE_BEGIN */\n"); 254 else if (*value1 == 0x00010001) 255 fprintf(fp, "\t/* ARRAYS_SEMAPHORE_END */\n"); 256 else 257 fprintf(fp, "\t/* SEMAPHORE - cmd unknown! */\n"); 258} 259 260static void 261parse_plbu_primitive_setup(FILE *fp, uint32_t *value1, uint32_t *value2) 262{ 263 if (*value1 == 0x00000200) 264 fprintf(fp, "\t/* UNKNOWN_2 (PRIMITIVE_SETUP INIT?) */\n"); 265 else 266 fprintf(fp, "\t/* PRIMITIVE_SETUP: %scull: %d (0x%x), index_size: %d */\n", 267 (*value1 & 0x1000) ? "force point size, " : "", 268 (*value1 & 0x000f0000) >> 16, (*value1 & 0x000f0000) >> 16, 269 (*value1 & 0x00000e00) >> 9); 270} 271 272static void 273parse_plbu_rsw_vertex_array(FILE *fp, uint32_t *value1, uint32_t *value2) 274{ 275 fprintf(fp, "\t/* RSW_VERTEX_ARRAY: rsw: 0x%08x, gl_pos: 0x%08x */\n", 276 *value1, 277 (*value2 & 0x0fffffff) << 4); 278} 279 280static void 281parse_plbu_scissors(FILE *fp, uint32_t *value1, uint32_t *value2) 282{ 283 float minx = (*value1 & 0xc0000000) >> 30 | (*value2 & 0x00001fff) << 2; 284 float maxx = ((*value2 & 0x0fffe000) >> 13) + 1; 285 float miny = *value1 & 0x00003fff; 286 float maxy = ((*value1 & 0x3fff8000) >> 15) + 1; 287 288 fprintf(fp, "\t/* SCISSORS: minx: %f, maxx: %f, miny: %f, maxy: %f */\n", 289 minx, maxx, miny, maxy); 290} 291 292static void 293parse_plbu_unknown_1(FILE *fp, uint32_t *value1, uint32_t *value2) 294{ 295 fprintf(fp, "\t/* UNKNOWN_1 */\n"); 296} 297 298static void 299parse_plbu_low_prim_size(FILE *fp, float *value1, uint32_t *value2) 300{ 301 fprintf(fp, "\t/* LOW_PRIM_SIZE: size: %f */\n", *value1); 302} 303 304static void 305parse_plbu_depth_range_near(FILE *fp, float *value1, uint32_t *value2) 306{ 307 fprintf(fp, "\t/* DEPTH_RANG_NEAR: depth_range: %f */\n", *value1); 308} 309 310static void 311parse_plbu_depth_range_far(FILE *fp, float *value1, uint32_t *value2) 312{ 313 fprintf(fp, "\t/* DEPTH_RANGE_FAR: depth_range: %f */\n", *value1); 314} 315 316static void 317parse_plbu_indexed_dest(FILE *fp, uint32_t *value1, uint32_t *value2) 318{ 319 fprintf(fp, "\t/* INDEXED_DEST: gl_pos: 0x%08x */\n", *value1); 320} 321 322static void 323parse_plbu_indexed_pt_size(FILE *fp, uint32_t *value1, uint32_t *value2) 324{ 325 fprintf(fp, "\t/* INDEXED_PT_SIZE: pt_size: 0x%08x */\n", *value1); 326} 327 328static void 329parse_plbu_indices(FILE *fp, uint32_t *value1, uint32_t *value2) 330{ 331 fprintf(fp, "\t/* INDICES: indices: 0x%08x */\n", *value1); 332} 333 334static void 335parse_plbu_draw_arrays(FILE *fp, uint32_t *value1, uint32_t *value2) 336{ 337 if ((*value1 == 0x00000000) && (*value2 == 0x00000000)) { 338 fprintf(fp, "\t/* ---EMPTY CMD */\n"); 339 return; 340 } 341 342 uint32_t count = (*value1 & 0xff000000) >> 24 | (*value2 & 0x000000ff) << 8; 343 uint32_t start = *value1 & 0x00ffffff; 344 uint32_t mode = (*value2 & 0x001f0000) >> 16; 345 346 fprintf(fp, "\t/* DRAW_ARRAYS: count: %d, start: %d, mode: %d (0x%x) */\n", 347 count, start, mode, mode); 348} 349 350static void 351parse_plbu_draw_elements(FILE *fp, uint32_t *value1, uint32_t *value2) 352{ 353 uint32_t count = (*value1 & 0xff000000) >> 24 | (*value2 & 0x000000ff) << 8; 354 uint32_t start = *value1 & 0x00ffffff; 355 uint32_t mode = (*value2 & 0x001f0000) >> 16; 356 357 fprintf(fp, "\t/* DRAW_ELEMENTS: count: %d, start: %d, mode: %d (0x%x) */\n", 358 count, start, mode, mode); 359} 360 361static void 362parse_plbu_continue(FILE *fp, uint32_t *value1, uint32_t *value2) 363{ 364 fprintf(fp, "\t/* CONTINUE: continue at 0x%08x */\n", *value1); 365} 366 367static void 368parse_plbu_end(FILE *fp, uint32_t *value1, uint32_t *value2) 369{ 370 fprintf(fp, "\t/* END (FINISH/FLUSH) */\n"); 371} 372 373void 374lima_parse_plbu(FILE *fp, uint32_t *data, int size, uint32_t start) 375{ 376 uint32_t *value1; 377 uint32_t *value2; 378 379 fprintf(fp, "/* ============ PLBU CMD STREAM BEGIN ============= */\n"); 380 for (int i = 0; i * 4 < size; i += 2) { 381 value1 = &data[i]; 382 value2 = &data[i + 1]; 383 fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x 0x%08x", 384 start + i * 4, i * 4, *value1, *value2); 385 386 if ((*value2 & 0xffe00000) == 0x00000000) 387 parse_plbu_draw_arrays(fp, value1, value2); 388 else if ((*value2 & 0xffe00000) == 0x00200000) 389 parse_plbu_draw_elements(fp, value1, value2); 390 else if ((*value2 & 0xff000fff) == 0x10000100) 391 parse_plbu_indexed_dest(fp, value1, value2); 392 else if ((*value2 & 0xff000fff) == 0x10000101) 393 parse_plbu_indices(fp, value1, value2); 394 else if ((*value2 & 0xff000fff) == 0x10000102) 395 parse_plbu_indexed_pt_size(fp, value1, value2); 396 else if ((*value2 & 0xff000fff) == 0x10000105) 397 parse_plbu_viewport_bottom(fp, (float *)value1, value2); 398 else if ((*value2 & 0xff000fff) == 0x10000106) 399 parse_plbu_viewport_top(fp, (float *)value1, value2); 400 else if ((*value2 & 0xff000fff) == 0x10000107) 401 parse_plbu_viewport_left(fp, (float *)value1, value2); 402 else if ((*value2 & 0xff000fff) == 0x10000108) 403 parse_plbu_viewport_right(fp, (float *)value1, value2); 404 else if ((*value2 & 0xff000fff) == 0x10000109) 405 parse_plbu_tiled_dimensions(fp, value1, value2); 406 else if ((*value2 & 0xff000fff) == 0x1000010a) 407 parse_plbu_unknown_1(fp, value1, value2); 408 else if ((*value2 & 0xff000fff) == 0x1000010b) /* also unknown_2 */ 409 parse_plbu_primitive_setup(fp, value1, value2); 410 else if ((*value2 & 0xff000fff) == 0x1000010c) 411 parse_plbu_block_step(fp, value1, value2); 412 else if ((*value2 & 0xff000fff) == 0x1000010d) 413 parse_plbu_low_prim_size(fp, (float *)value1, value2); 414 else if ((*value2 & 0xff000fff) == 0x1000010e) 415 parse_plbu_depth_range_near(fp, (float *)value1, value2); 416 else if ((*value2 & 0xff000fff) == 0x1000010f) 417 parse_plbu_depth_range_far(fp, (float *)value1, value2); 418 else if ((*value2 & 0xff000000) == 0x28000000) 419 parse_plbu_array_address(fp, value1, value2); 420 else if ((*value2 & 0xf0000000) == 0x30000000) 421 parse_plbu_block_stride(fp, value1, value2); 422 else if (*value2 == 0x50000000) 423 parse_plbu_end(fp, value1, value2); 424 else if ((*value2 & 0xf0000000)== 0x60000000) 425 parse_plbu_semaphore(fp, value1, value2); 426 else if ((*value2 & 0xf0000000)== 0x70000000) 427 parse_plbu_scissors(fp, value1, value2); 428 else if ((*value2 & 0xf0000000)== 0x80000000) 429 parse_plbu_rsw_vertex_array(fp, value1, value2); 430 else if ((*value2 & 0xf0000000)== 0xf0000000) 431 parse_plbu_continue(fp, value1, value2); 432 else 433 fprintf(fp, "\t/* --- unknown cmd --- */\n"); 434 } 435 fprintf(fp, "/* ============ PLBU CMD STREAM END =============== */\n"); 436 fprintf(fp, "\n"); 437} 438 439void 440lima_parse_shader(FILE *fp, uint32_t *data, int size, bool is_frag) 441{ 442 uint32_t *value = &data[0]; 443 444 if (is_frag) { 445 uint32_t *bin = value; 446 uint32_t offt = 0; 447 uint32_t next_instr_length = 0; 448 449 fprintf(fp, "/* ============ FS DISASSEMBLY BEGIN ============== */\n"); 450 451 do { 452 ppir_codegen_ctrl *ctrl = (ppir_codegen_ctrl *)bin; 453 fprintf(fp, "@%6d: ", offt); 454 ppir_disassemble_instr(bin, offt, fp); 455 bin += ctrl->count; 456 offt += ctrl->count; 457 next_instr_length = ctrl->next_count; 458 } while (next_instr_length); 459 460 fprintf(fp, "/* ============ FS DISASSEMBLY END ================= */\n"); 461 } else { 462 fprintf(fp, "/* ============ VS DISASSEMBLY BEGIN ============== */\n"); 463 gpir_disassemble_program((gpir_codegen_instr *)value, size / sizeof(gpir_codegen_instr), fp); 464 fprintf(fp, "/* ============ VS DISASSEMBLY END ================= */\n"); 465 } 466} 467 468static void 469parse_rsw(FILE *fp, uint32_t *value, int i, uint32_t *helper) 470{ 471 fprintf(fp, "\t/* %s", render_state_infos[i].info); 472 473 switch (i) { 474 case 0: /* BLEND COLOR BG */ 475 fprintf(fp, ": blend_color.color[1] = %f, blend_color.color[2] = %f */\n", 476 (float)(ubyte_to_float((*value & 0xffff0000) >> 16)), 477 (float)(ubyte_to_float(*value & 0x0000ffff))); 478 break; 479 case 1: /* BLEND COLOR RA */ 480 fprintf(fp, ": blend_color.color[3] = %f, blend_color.color[0] = %f */\n", 481 (float)(ubyte_to_float((*value & 0xffff0000) >> 16)), 482 (float)(ubyte_to_float(*value & 0x0000ffff))); 483 break; 484 case 2: /* ALPHA BLEND */ 485 fprintf(fp, "(1): colormask 0x%02x, rgb_func %d (%s), alpha_func %d (%s) */\n", 486 (*value & 0xf0000000) >> 28, /* colormask */ 487 (*value & 0x00000007), 488 lima_get_blend_func_string((*value & 0x00000007)), /* rgb_func */ 489 (*value & 0x00000038) >> 3, 490 lima_get_blend_func_string((*value & 0x00000038) >> 3)); /* alpha_func */ 491 /* add a few tabs for alignment */ 492 fprintf(fp, "\t\t\t\t\t\t/* %s(2)", render_state_infos[i].info); 493 fprintf(fp, ": rgb_src_factor %d (%s), rbg_dst_factor %d (%s) */\n", 494 (*value & 0x000007c0) >> 6, 495 lima_get_blendfactor_string((*value & 0x000007c0) >> 6), /* rgb_src_factor */ 496 (*value & 0x0000f800) >> 11, 497 lima_get_blendfactor_string((*value & 0x0000f800) >> 11)); /* rgb_dst_factor */ 498 fprintf(fp, "\t\t\t\t\t\t/* %s(3)", render_state_infos[i].info); 499 fprintf(fp, ": alpha_src_factor %d (%s), alpha_dst_factor %d (%s), bits 24-27 0x%02x */\n", 500 (*value & 0x000f0000) >> 16, 501 lima_get_blendfactor_string((*value & 0x000f0000) >> 16), /* alpha_src_factor */ 502 (*value & 0x00f00000) >> 20, 503 lima_get_blendfactor_string((*value & 0x00f00000) >> 20), /* alpha_dst_factor */ 504 (*value & 0x0f000000) >> 24); /* bits 24-27 */ 505 break; 506 case 3: /* DEPTH TEST */ 507 if ((*value & 0x00000001) == 0x00000001) 508 fprintf(fp, "(1): depth test enabled && writes allowed"); 509 else 510 fprintf(fp, "(1): depth test disabled || writes not allowed"); 511 512 fprintf(fp, "\n\t\t\t\t\t\t/* %s(2)", render_state_infos[i].info); 513 fprintf(fp, ": depth_func %d (%s)", ((*value & 0x0000000e) >> 1), 514 lima_get_compare_func_string((*value & 0x0000000e) >> 1)); 515 fprintf(fp, ", offset_scale: %d", (*value & 0x00ff0000) >> 16); 516 fprintf(fp, ", offset_units: %d", (*value & 0xff000000) >> 24); 517 if (*value & 0x400) 518 fprintf(fp, ", shader writes depth or stencil"); 519 if (*value & 0x800) 520 fprintf(fp, ", shader writes depth"); 521 if (*value & 0x1000) 522 fprintf(fp, ", shader writes stencil"); 523 fprintf(fp, " */\n\t\t\t\t\t\t/* %s(3)", render_state_infos[i].info); 524 if ((*value & 0x00000010) == 0x00000010) 525 fprintf(fp, ": ignore depth clip near"); 526 if ((*value & 0x00000020) == 0x00000020) 527 fprintf(fp, ", ignore depth clip far"); 528 fprintf(fp, ", register for gl_FragDepth: $%d", (*value & 0x000003c0) >> 6); 529 fprintf(fp, ", unknown bits 13-15: 0x%08x */\n", *value & 0x00000e000); 530 break; 531 case 4: /* DEPTH RANGE */ 532 fprintf(fp, ": viewport.far = %f, viewport.near = %f */\n", 533 (float)(ushort_to_float((*value & 0xffff0000) >> 16)), 534 (float)(ushort_to_float(*value & 0x0000ffff))); 535 break; 536 case 5: /* STENCIL FRONT */ 537 fprintf(fp, "(1): valuemask 0x%02x, ref value %d (0x%02x), stencil_func %d (%s)*/\n", 538 (*value & 0xff000000) >> 24, /* valuemask */ 539 (*value & 0x00ff0000) >> 16, (*value & 0x00ff0000) >> 16, /* ref value */ 540 (*value & 0x00000007), 541 lima_get_compare_func_string((*value & 0x00000007))); /* stencil_func */ 542 /* add a few tabs for alignment */ 543 fprintf(fp, "\t\t\t\t\t\t/* %s(2)", render_state_infos[i].info); 544 fprintf(fp, ": fail_op %d (%s), zfail_op %d (%s), zpass_op %d (%s), unknown (12-15) 0x%02x */\n", 545 (*value & 0x00000038) >> 3, 546 lima_get_stencil_op_string((*value & 0x00000038) >> 3), /* fail_op */ 547 (*value & 0x000001c0) >> 6, 548 lima_get_stencil_op_string((*value & 0x000001c0) >> 6), /* zfail_op */ 549 (*value & 0x00000e00) >> 9, 550 lima_get_stencil_op_string((*value & 0x00000e00) >> 9), /* zpass_op */ 551 (*value & 0x0000f000) >> 12); /* unknown */ 552 break; 553 case 6: /* STENCIL BACK */ 554 fprintf(fp, "(1): valuemask 0x%02x, ref value %d (0x%02x), stencil_func %d (%s)*/\n", 555 (*value & 0xff000000) >> 24, /* valuemask */ 556 (*value & 0x00ff0000) >> 16, (*value & 0x00ff0000) >> 16, /* ref value */ 557 (*value & 0x00000007), 558 lima_get_compare_func_string((*value & 0x00000007))); /* stencil_func */ 559 /* add a few tabs for alignment */ 560 fprintf(fp, "\t\t\t\t\t\t/* %s(2)", render_state_infos[i].info); 561 fprintf(fp, ": fail_op %d (%s), zfail_op %d (%s), zpass_op %d (%s), unknown (12-15) 0x%02x */\n", 562 (*value & 0x00000038) >> 3, 563 lima_get_stencil_op_string((*value & 0x00000038) >> 3), /* fail_op */ 564 (*value & 0x000001c0) >> 6, 565 lima_get_stencil_op_string((*value & 0x000001c0) >> 6), /* zfail_op */ 566 (*value & 0x00000e00) >> 9, 567 lima_get_stencil_op_string((*value & 0x00000e00) >> 9), /* zpass_op */ 568 (*value & 0x0000f000) >> 12); /* unknown */ 569 break; 570 case 7: /* STENCIL TEST */ 571 fprintf(fp, "(1): stencil_front writemask 0x%02x, stencil_back writemask 0x%02x */\n", 572 (*value & 0x000000ff), /* front writemask */ 573 (*value & 0x0000ff00) >> 8); /* back writemask */ 574 /* add a few tabs for alignment */ 575 fprintf(fp, "\t\t\t\t\t\t/* %s(2)", render_state_infos[i].info); 576 fprintf(fp, ": alpha_ref_value: 0x%02x */\n", (*value & 0x00ff0000) >> 16); 577 fprintf(fp, "\t\t\t\t\t\t/* %s(3)", render_state_infos[i].info); 578 fprintf(fp, ": unknown (bits 24-31) 0x%02x */\n", 579 (*value & 0xff000000) >> 24); /* unknown */ 580 break; 581 case 8: /* MULTI SAMPLE */ 582 if ((*value & 0x00000f00) == 0x00000000) 583 fprintf(fp, ": points"); 584 else if ((*value & 0x00000f00) == 0x00000400) 585 fprintf(fp, ": lines"); 586 else if ((*value & 0x00000f00) == 0x00000800) 587 fprintf(fp, ": triangles"); 588 else 589 fprintf(fp, ": unknown"); 590 591 if ((*value & 0x00000078) == 0x00000068) 592 fprintf(fp, ", msaa */\n"); 593 else if ((*value & 0x00000078) == 0x00000000) 594 fprintf(fp, " */\n"); 595 else 596 fprintf(fp, ", UNKNOWN */\n"); 597 598 fprintf(fp, "\t\t\t\t\t\t/* %s(3)", render_state_infos[i].info); 599 fprintf(fp, ": sample_mask: 0x%.x", ((*value & 0xf000) >> 12)); 600 if ((*value & (1 << 7))) 601 fprintf(fp, ", alpha_to_coverage"); 602 if ((*value & (1 << 8))) 603 fprintf(fp, ", alpha_to_one"); 604 fprintf(fp, " */\n"); 605 606 fprintf(fp, "\t\t\t\t\t\t/* %s(4)", render_state_infos[i].info); 607 fprintf(fp, ", register for gl_FragColor: $%d $%d $%d $%d */\n", 608 (*value & 0xf0000000) >> 28, 609 (*value & 0x0f000000) >> 24, 610 (*value & 0x00f00000) >> 20, 611 (*value & 0x000f0000) >> 16); 612 fprintf(fp, "\t\t\t\t\t\t/* %s(3)", render_state_infos[i].info); 613 fprintf(fp, ": alpha_test_func: %d (%s) */\n", 614 (*value & 0x00000007), 615 lima_get_compare_func_string((*value & 0x00000007))); /* alpha_test_func */ 616 break; 617 case 9: /* SHADER ADDRESS */ 618 fprintf(fp, ": fs shader @ 0x%08x, first instr length %d */\n", 619 *value & 0xffffffe0, *value & 0x0000001f); 620 break; 621 case 10: /* VARYING TYPES */ 622 fprintf(fp, "(1): "); 623 int val, j; 624 /* 0 - 5 */ 625 for (j = 0; j < 6; j++) { 626 val = (*value >> (j * 3)) & 0x07; 627 fprintf(fp, "val %d-%d, ", j, val); 628 } 629 /* 6 - 9 */ 630 /* add a few tabs for alignment */ 631 fprintf(fp, "\n\t\t\t\t\t\t/* %s(2): ", render_state_infos[i].info); 632 for (j = 6; j < 10; j++) { 633 val = (*value >> (j * 3)) & 0x07; 634 fprintf(fp, "val %d-%d, ", j, val); 635 } 636 /* 10 */ 637 val = ((*value & 0xc0000000) >> 30) | ((*helper & 0x00000001) << 2); 638 fprintf(fp, "val %d-%d, ", j, val); 639 j++; 640 /* 11 */ 641 val = (*helper & 0x0000000e) >> 1; 642 fprintf(fp, "val %d-%d */\n", j, val); 643 break; 644 case 11: /* UNIFORMS ADDRESS */ 645 fprintf(fp, ": pp uniform info @ 0x%08x, bits: 0x%01x */\n", 646 *value & 0xfffffff0, *value & 0x0000000f); 647 break; 648 case 12: /* TEXTURES ADDRESS */ 649 fprintf(fp, ": address: 0x%08x */\n", *value); 650 break; 651 case 13: /* AUX0 */ 652 fprintf(fp, "(1): varying_stride: %d", /* bits 0 - 4 varying stride, 8 aligned */ 653 (*value & 0x0000001f) << 3); 654 if ((*value & 0x00000020) == 0x00000020) /* bit 5 has num_samplers */ 655 fprintf(fp, ", num_samplers %d", 656 (*value & 0xffffc000) >> 14); /* bits 14 - 31 num_samplers */ 657 658 if ((*value & 0x00000080) == 0x00000080) /* bit 7 has_fs_uniforms */ 659 fprintf(fp, ", has_fs_uniforms */"); 660 else 661 fprintf(fp, " */"); 662 663 fprintf(fp, "\n\t\t\t\t\t\t/* %s(2):", render_state_infos[i].info); 664 if ((*value & 0x00000200) == 0x00000200) /* bit 9 early-z */ 665 fprintf(fp, " early-z enabled"); 666 else 667 fprintf(fp, " early-z disabled"); 668 669 if ((*value & 0x00001000) == 0x00001000) /* bit 12 pixel-kill */ 670 fprintf(fp, ", pixel kill enabled"); 671 else 672 fprintf(fp, ", pixel kill disabled"); 673 674 if ((*value & 0x00000040) == 0x00000040) /* bit 6 unknown */ 675 fprintf(fp, ", bit 6 set"); 676 677 if ((*value & 0x00000100) == 0x00000100) /* bit 8 unknown */ 678 fprintf(fp, ", bit 8 set"); 679 680 if (((*value & 0x00000c00) >> 10) > 0) /* bit 10 - 11 unknown */ 681 fprintf(fp, ", bit 10 - 11: %d", ((*value & 0x00000c00) >> 10)); 682 683 if ((*value & 0x00002000) == 0x00002000) /* bit 13 unknown */ 684 fprintf(fp, ", bit 13 set"); 685 686 fprintf(fp, " */\n"); 687 fprintf(fp, "\n\t\t\t\t\t\t/* %s(3):", render_state_infos[i].info); 688 fprintf(fp, " register for gl_SecondaryFragColor: $%d", 689 (*value & 0xf0000000) >> 28); 690 fprintf(fp, " */\n"); 691 break; 692 case 14: /* AUX1 */ 693 fprintf(fp, ": "); 694 if ((*value & 0x00002000) == 0x00002000) 695 fprintf(fp, "blend->base.dither true, "); 696 697 if ((*value & 0x00001000) == 0x00001000) 698 fprintf(fp, "glFrontFace(GL_CCW), "); 699 else 700 fprintf(fp, "glFrontFace(GL_CW), "); 701 702 if ((*value & 0x00010000) == 0x00010000) 703 fprintf(fp, "ctx->const_buffer[PIPE_SHADER_FRAGMENT].buffer true "); 704 fprintf(fp, "*/\n"); 705 break; 706 case 15: /* VARYINGS ADDRESS */ 707 fprintf(fp, ": varyings @ 0x%08x */\n", *value & 0xfffffff0); 708 break; 709 default: /* should never be executed! */ 710 fprintf(fp, ": something went wrong!!! */\n"); 711 break; 712 } 713} 714 715void 716lima_parse_render_state(FILE *fp, uint32_t *data, int size, uint32_t start) 717{ 718 uint32_t *value; 719 720 fprintf(fp, "/* ============ RSW BEGIN ========================= */\n"); 721 for (int i = 0; i * 4 < size; i++) { 722 value = &data[i]; 723 fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x", 724 start + i * 4, i * 4, *value); 725 if (i == 10) 726 parse_rsw(fp, value, i, &data[15]); 727 else 728 parse_rsw(fp, value, i, NULL); 729 } 730 fprintf(fp, "/* ============ RSW END =========================== */\n"); 731} 732 733static void 734parse_texture(FILE *fp, uint32_t *data, uint32_t start, uint32_t offset) 735{ 736 uint32_t i = 0; 737 offset /= 4; 738 lima_tex_desc *desc = (lima_tex_desc *)&data[offset]; 739 740 /* Word 0 */ 741 fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x\n", 742 start + i * 4, i * 4, *(&data[i + offset])); 743 i++; 744 fprintf(fp, "\t format: 0x%x (%d)\n", desc->format, desc->format); 745 fprintf(fp, "\t flag1: 0x%x (%d)\n", desc->flag1, desc->flag1); 746 fprintf(fp, "\t swap_r_b: 0x%x (%d)\n", desc->swap_r_b, desc->swap_r_b); 747 fprintf(fp, "\t unknown_0_1: 0x%x (%d)\n", desc->unknown_0_1, desc->unknown_0_1); 748 fprintf(fp, "\t stride: 0x%x (%d)\n", desc->stride, desc->stride); 749 fprintf(fp, "\t unknown_0_2: 0x%x (%d)\n", desc->unknown_0_2, desc->unknown_0_2); 750 751 /* Word 1 - 5 */ 752 fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", 753 start + i * 4, i * 4, *(&data[i + offset]), *(&data[i + 1 + offset]), 754 *(&data[i + 2 + offset]), *(&data[i + 3 + offset]), *(&data[i + 4 + offset])); 755 i += 5; 756 fprintf(fp, "\t unknown_1_1: 0x%x (%d)\n", desc->unknown_1_1, desc->unknown_1_1); 757 fprintf(fp, "\t unnorm_coords: 0x%x (%d)\n", desc->unnorm_coords, desc->unnorm_coords); 758 fprintf(fp, "\t unknown_1_2: 0x%x (%d)\n", desc->unknown_1_2, desc->unknown_1_2); 759 fprintf(fp, "\t cube_map: 0x%x (%d)\n", desc->cube_map, desc->cube_map); 760 fprintf(fp, "\t sampler_dim: 0x%x (%d)\n", desc->sampler_dim, desc->sampler_dim); 761 fprintf(fp, "\t min_lod: 0x%x (%d) (%f)\n", desc->min_lod, desc->min_lod, lima_fixed8_to_float(desc->min_lod)); 762 fprintf(fp, "\t max_lod: 0x%x (%d) (%f)\n", desc->max_lod, desc->max_lod, lima_fixed8_to_float(desc->max_lod)); 763 fprintf(fp, "\t lod_bias: 0x%x (%d) (%f)\n", desc->lod_bias, desc->lod_bias, lima_fixed8_to_float(desc->lod_bias)); 764 fprintf(fp, "\t unknown_2_1: 0x%x (%d)\n", desc->unknown_2_1, desc->unknown_2_1); 765 fprintf(fp, "\t has_stride: 0x%x (%d)\n", desc->has_stride, desc->has_stride); 766 fprintf(fp, "\t min_mipfilter_2: 0x%x (%d)\n", desc->min_mipfilter_2, desc->min_mipfilter_2); 767 fprintf(fp, "\t min_img_filter_nearest: 0x%x (%d)\n", desc->min_img_filter_nearest, desc->min_img_filter_nearest); 768 fprintf(fp, "\t mag_img_filter_nearest: 0x%x (%d)\n", desc->mag_img_filter_nearest, desc->mag_img_filter_nearest); 769 fprintf(fp, "\t wrap_s: %d (%s)\n", desc->wrap_s, 770 lima_get_wrap_mode_string(desc->wrap_s)); 771 fprintf(fp, "\t wrap_t: %d (%s)\n", desc->wrap_t, 772 lima_get_wrap_mode_string(desc->wrap_t)); 773 fprintf(fp, "\t wrap_r: %d (%s)\n", desc->wrap_r, 774 lima_get_wrap_mode_string(desc->wrap_r)); 775 fprintf(fp, "\t width: 0x%x (%d)\n", desc->width, desc->width); 776 fprintf(fp, "\t height: 0x%x (%d)\n", desc->height, desc->height); 777 fprintf(fp, "\t depth: 0x%x (%d)\n", desc->depth, desc->depth); 778 fprintf(fp, "\t border_red: 0x%x (%d)\n", desc->border_red, desc->border_red); 779 fprintf(fp, "\t border_green: 0x%x (%d)\n", desc->border_green, desc->border_green); 780 fprintf(fp, "\t border_blue: 0x%x (%d)\n", desc->border_blue, desc->border_blue); 781 fprintf(fp, "\t border_alpha: 0x%x (%d)\n", desc->border_alpha, desc->border_alpha); 782 fprintf(fp, "\t unknown_5_1: 0x%x (%d)\n", desc->unknown_5_1, desc->unknown_5_1); 783 784 /* Word 6 - */ 785 fprintf(fp, "/* 0x%08x (0x%08x) */", 786 start + i * 4, i * 4); 787 fprintf(fp, "\t"); 788 789 int miplevels = (int)lima_fixed8_to_float(desc->max_lod); 790 for (int k = 0; k < ((((miplevels + 1) * 26) + 64) / 32); k++) 791 fprintf(fp, "0x%08x ", *(&data[i + offset + k])); 792 fprintf(fp, "\n"); 793 794 i++; 795 fprintf(fp, "\t unknown_6_1: 0x%x (%d)\n", desc->va_s.unknown_6_1, desc->va_s.unknown_6_1); 796 fprintf(fp, "\t layout: 0x%x (%d)\n", desc->va_s.layout, desc->va_s.layout); 797 fprintf(fp, "\t unknown_6_2: 0x%x (%d)\n", desc->va_s.unknown_6_2, desc->va_s.unknown_6_2); 798 fprintf(fp, "\t unknown_6_3: 0x%x (%d)\n", desc->va_s.unknown_6_3, desc->va_s.unknown_6_3); 799 800 /* first level */ 801 fprintf(fp, "\t va_0: 0x%x \n", desc->va_s.va_0 << 6); 802 803 /* second level up to desc->miplevels */ 804 int j; 805 unsigned va_bit_idx; 806 unsigned va_idx; 807 uint32_t va; 808 uint32_t va_1; 809 uint32_t va_2; 810 for (j = 1; j <= miplevels; j++) { 811 va = 0; 812 va_1 = 0; 813 va_2 = 0; 814 815 va_bit_idx = VA_BIT_OFFSET + (VA_BIT_SIZE * j); 816 va_idx = va_bit_idx / 32; 817 va_bit_idx %= 32; 818 819 /* the first (32 - va_bit_idx) bits */ 820 va_1 |= (*(&data[i + offset + va_idx - 1]) >> va_bit_idx); 821 822 /* do we need some bits from the following word? */ 823 if (va_bit_idx > 6) { 824 /* shift left and right again to erase the unneeded bits, keep space for va1 */ 825 va_2 |= (*(&data[i + offset + va_idx]) << (2 * 32 - VA_BIT_SIZE - va_bit_idx)); 826 va_2 >>= ((2 * 32 - VA_BIT_SIZE - va_bit_idx) - (32 - va_bit_idx)); 827 va |= va_2; 828 } 829 va |= va_1; 830 va <<= 6; 831 fprintf(fp, "\t va_%d: 0x%x \n", j, va); 832 } 833} 834 835void 836lima_parse_texture_descriptor(FILE *fp, uint32_t *data, int size, uint32_t start, uint32_t offset) 837{ 838 fprintf(fp, "/* ============ TEXTURE BEGIN ===================== */\n"); 839 parse_texture(fp, data, start, offset); 840 fprintf(fp, "/* ============ TEXTURE END ======================= */\n"); 841} 842