1/* 2 * Copyright © 2007-2011 Intel Corporation 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, sublicense, 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 next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * 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 NONINFRINGEMENT. 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 FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Eric Anholt <eric@anholt.net> 25 * Chris Wilson <chris@chris-wilson.co.uk> 26 * 27 */ 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#include <sys/mman.h> 34#include <assert.h> 35 36#include "sna.h" 37#include "sna_reg.h" 38 39#include "gen3_render.h" 40 41#include "kgem_debug.h" 42 43enum type { 44 T_FLOAT32, 45 T_FLOAT16, 46}; 47 48static struct state { 49 struct vertex_buffer { 50 int handle; 51 void *base; 52 const char *ptr; 53 int pitch; 54 55 struct kgem_bo *current; 56 } vb; 57 struct vertex_elements { 58 int offset; 59 bool valid; 60 enum type type; 61 int size; 62 uint8_t swizzle[4]; 63 } ve[33]; 64 int num_ve; 65} state; 66 67static float int_as_float(int i) 68{ 69 union { 70 float f; 71 int i; 72 } x; 73 x.i = i; 74 return x.f; 75} 76 77static void gen3_update_vertex_buffer_addr(struct kgem *kgem, 78 uint32_t offset) 79{ 80 uint32_t handle; 81 struct kgem_bo *bo = NULL; 82 void *base, *ptr; 83 int i; 84 85 offset *= sizeof(uint32_t); 86 87 for (i = 0; i < kgem->nreloc; i++) 88 if (kgem->reloc[i].offset == offset) 89 break; 90 assert(i < kgem->nreloc); 91 handle = kgem->reloc[i].target_handle; 92 93 if (handle == 0) { 94 base = kgem->batch; 95 } else { 96 list_for_each_entry(bo, &kgem->next_request->buffers, request) 97 if (bo->handle == handle) 98 break; 99 assert(&bo->request != &kgem->next_request->buffers); 100 base = kgem_bo_map__debug(kgem, bo); 101 } 102 ptr = (char *)base + kgem->reloc[i].delta; 103 104 state.vb.current = bo; 105 state.vb.base = base; 106 state.vb.ptr = ptr; 107} 108 109static void gen3_update_vertex_buffer_pitch(struct kgem *kgem, 110 uint32_t offset) 111{ 112 state.vb.pitch = kgem->batch[offset] >> 16 & 0x3f; 113 state.vb.pitch *= sizeof(uint32_t); 114} 115 116static void gen3_update_vertex_elements(struct kgem *kgem, uint32_t data) 117{ 118 state.ve[1].valid = 1; 119 120 switch ((data >> 6) & 7) { 121 case 1: 122 state.ve[1].type = T_FLOAT32; 123 state.ve[1].size = 3; 124 state.ve[1].swizzle[0] = 1; 125 state.ve[1].swizzle[1] = 1; 126 state.ve[1].swizzle[2] = 1; 127 state.ve[1].swizzle[3] = 3; 128 break; 129 case 2: 130 state.ve[1].type = T_FLOAT32; 131 state.ve[1].size = 4; 132 state.ve[1].swizzle[0] = 1; 133 state.ve[1].swizzle[1] = 1; 134 state.ve[1].swizzle[2] = 1; 135 state.ve[1].swizzle[3] = 1; 136 break; 137 case 3: 138 state.ve[1].type = T_FLOAT32; 139 state.ve[1].size = 2; 140 state.ve[1].swizzle[0] = 1; 141 state.ve[1].swizzle[1] = 1; 142 state.ve[1].swizzle[2] = 2; 143 state.ve[1].swizzle[3] = 3; 144 break; 145 case 4: 146 state.ve[1].type = T_FLOAT32; 147 state.ve[1].size = 3; 148 state.ve[1].swizzle[0] = 1; 149 state.ve[1].swizzle[1] = 1; 150 state.ve[1].swizzle[2] = 3; 151 state.ve[1].swizzle[3] = 1; 152 break; 153 } 154 155 state.ve[2].valid = 0; 156 state.ve[3].valid = 0; 157} 158 159static void gen3_update_vertex_texcoords(struct kgem *kgem, uint32_t data) 160{ 161 int id; 162 for (id = 0; id < 8; id++) { 163 uint32_t fmt = (data >> (id*4)) & 0xf; 164 int width; 165 166 state.ve[id+4].valid = fmt != 0xf; 167 168 width = 0; 169 switch (fmt) { 170 case 0: 171 state.ve[id+4].type = T_FLOAT32; 172 width = state.ve[id+4].size = 2; 173 break; 174 case 1: 175 state.ve[id+4].type = T_FLOAT32; 176 width = state.ve[id+4].size = 3; 177 break; 178 case 2: 179 state.ve[id+4].type = T_FLOAT32; 180 width = state.ve[id+4].size = 4; 181 break; 182 case 3: 183 state.ve[id+4].type = T_FLOAT32; 184 width = state.ve[id+4].size = 1; 185 break; 186 case 4: 187 state.ve[id+4].type = T_FLOAT16; 188 width = state.ve[id+4].size = 2; 189 break; 190 case 5: 191 state.ve[id+4].type = T_FLOAT16; 192 width = state.ve[id+4].size = 4; 193 break; 194 } 195 196 state.ve[id+4].swizzle[0] = width > 0 ? 1 : 2; 197 state.ve[id+4].swizzle[1] = width > 1 ? 1 : 2; 198 state.ve[id+4].swizzle[2] = width > 2 ? 1 : 2; 199 state.ve[id+4].swizzle[3] = width > 3 ? 1 : 2; 200 } 201} 202 203static void gen3_update_vertex_elements_offsets(struct kgem *kgem) 204{ 205 int i, offset; 206 207 for (i = offset = 0; i < ARRAY_SIZE(state.ve); i++) { 208 if (!state.ve[i].valid) 209 continue; 210 211 state.ve[i].offset = offset; 212 offset += 4 * state.ve[i].size; 213 state.num_ve = i; 214 } 215} 216 217static void vertices_float32_out(const struct vertex_elements *ve, const float *f, int max) 218{ 219 int c; 220 221 ErrorF("("); 222 for (c = 0; c < max; c++) { 223 switch (ve->swizzle[c]) { 224 case 0: ErrorF("#"); break; 225 case 1: ErrorF("%f", f[c]); break; 226 case 2: ErrorF("0.0"); break; 227 case 3: ErrorF("1.0"); break; 228 case 4: ErrorF("0x1"); break; 229 case 5: break; 230 default: ErrorF("?"); 231 } 232 if (c < max-1) 233 ErrorF(", "); 234 } 235 ErrorF(")"); 236} 237 238static void ve_out(const struct vertex_elements *ve, const void *ptr) 239{ 240 switch (ve->type) { 241 case T_FLOAT32: 242 vertices_float32_out(ve, ptr, ve->size); 243 break; 244 case T_FLOAT16: 245 //vertices_float16_out(ve, ptr, ve->size); 246 break; 247 } 248} 249 250static void indirect_vertex_out(struct kgem *kgem, uint32_t v) 251{ 252 const struct vertex_buffer *vb = &state.vb; 253 int i = 1; 254 255 do { 256 const struct vertex_elements *ve = &state.ve[i]; 257 const void *ptr = vb->ptr + v * vb->pitch + ve->offset; 258 259 if (!ve->valid) 260 continue; 261 262 ve_out(ve, ptr); 263 264 while (++i <= state.num_ve && !state.ve[i].valid) 265 ; 266 267 if (i <= state.num_ve) 268 ErrorF(", "); 269 } while (i <= state.num_ve); 270} 271 272static int inline_vertex_out(struct kgem *kgem, void *base) 273{ 274 const struct vertex_buffer *vb = &state.vb; 275 int i = 1; 276 277 do { 278 const struct vertex_elements *ve = &state.ve[i]; 279 const void *ptr = (char *)base + ve->offset; 280 281 if (!ve->valid) 282 continue; 283 284 ve_out(ve, ptr); 285 286 while (++i <= state.num_ve && !state.ve[i].valid) 287 ; 288 289 if (i <= state.num_ve) 290 ErrorF(", "); 291 } while (i <= state.num_ve); 292 293 return vb->pitch; 294} 295 296static int 297gen3_decode_3d_1c(struct kgem *kgem, uint32_t offset) 298{ 299 uint32_t *data = kgem->batch + offset; 300 uint32_t opcode; 301 302 opcode = (data[0] & 0x00f80000) >> 19; 303 304 switch (opcode) { 305 case 0x11: 306 kgem_debug_print(data, offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE\n"); 307 return 1; 308 case 0x10: 309 kgem_debug_print(data, offset, 0, "3DSTATE_SCISSOR_ENABLE %s\n", 310 data[0]&1?"enabled":"disabled"); 311 return 1; 312 case 0x01: 313 kgem_debug_print(data, offset, 0, "3DSTATE_MAP_COORD_SET_I830\n"); 314 return 1; 315 case 0x0a: 316 kgem_debug_print(data, offset, 0, "3DSTATE_MAP_CUBE_I830\n"); 317 return 1; 318 case 0x05: 319 kgem_debug_print(data, offset, 0, "3DSTATE_MAP_TEX_STREAM_I830\n"); 320 return 1; 321 } 322 323 kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d_1c opcode = 0x%x\n", 324 opcode); 325 assert(0); 326 return 1; 327} 328 329/** Sets the string dstname to describe the destination of the PS instruction */ 330static void 331gen3_get_instruction_dst(uint32_t *data, int i, char *dstname, int do_mask) 332{ 333 uint32_t a0 = data[i]; 334 int dst_nr = (a0 >> 14) & 0xf; 335 char dstmask[8]; 336 const char *sat; 337 338 if (do_mask) { 339 if (((a0 >> 10) & 0xf) == 0xf) { 340 dstmask[0] = 0; 341 } else { 342 int dstmask_index = 0; 343 344 dstmask[dstmask_index++] = '.'; 345 if (a0 & (1 << 10)) 346 dstmask[dstmask_index++] = 'x'; 347 if (a0 & (1 << 11)) 348 dstmask[dstmask_index++] = 'y'; 349 if (a0 & (1 << 12)) 350 dstmask[dstmask_index++] = 'z'; 351 if (a0 & (1 << 13)) 352 dstmask[dstmask_index++] = 'w'; 353 dstmask[dstmask_index++] = 0; 354 } 355 356 if (a0 & (1 << 22)) 357 sat = ".sat"; 358 else 359 sat = ""; 360 } else { 361 dstmask[0] = 0; 362 sat = ""; 363 } 364 365 switch ((a0 >> 19) & 0x7) { 366 case 0: 367 assert(dst_nr <= 15); 368 sprintf(dstname, "R%d%s%s", dst_nr, dstmask, sat); 369 break; 370 case 4: 371 assert(dst_nr == 0); 372 sprintf(dstname, "oC%s%s", dstmask, sat); 373 break; 374 case 5: 375 assert(dst_nr == 0); 376 sprintf(dstname, "oD%s%s", dstmask, sat); 377 break; 378 case 6: 379 assert(dst_nr <= 3); 380 sprintf(dstname, "U%d%s%s", dst_nr, dstmask, sat); 381 break; 382 default: 383 sprintf(dstname, "RESERVED"); 384 break; 385 } 386} 387 388static const char * 389gen3_get_channel_swizzle(uint32_t select) 390{ 391 switch (select & 0x7) { 392 case 0: 393 return (select & 8) ? "-x" : "x"; 394 case 1: 395 return (select & 8) ? "-y" : "y"; 396 case 2: 397 return (select & 8) ? "-z" : "z"; 398 case 3: 399 return (select & 8) ? "-w" : "w"; 400 case 4: 401 return (select & 8) ? "-0" : "0"; 402 case 5: 403 return (select & 8) ? "-1" : "1"; 404 default: 405 return (select & 8) ? "-bad" : "bad"; 406 } 407} 408 409static void 410gen3_get_instruction_src_name(uint32_t src_type, uint32_t src_nr, char *name) 411{ 412 switch (src_type) { 413 case 0: 414 sprintf(name, "R%d", src_nr); 415 assert(src_nr <= 15); 416 break; 417 case 1: 418 if (src_nr < 8) 419 sprintf(name, "T%d", src_nr); 420 else if (src_nr == 8) 421 sprintf(name, "DIFFUSE"); 422 else if (src_nr == 9) 423 sprintf(name, "SPECULAR"); 424 else if (src_nr == 10) 425 sprintf(name, "FOG"); 426 else { 427 assert(0); 428 sprintf(name, "RESERVED"); 429 } 430 break; 431 case 2: 432 sprintf(name, "C%d", src_nr); 433 assert(src_nr <= 31); 434 break; 435 case 4: 436 sprintf(name, "oC"); 437 assert(src_nr == 0); 438 break; 439 case 5: 440 sprintf(name, "oD"); 441 assert(src_nr == 0); 442 break; 443 case 6: 444 sprintf(name, "U%d", src_nr); 445 assert(src_nr <= 3); 446 break; 447 default: 448 sprintf(name, "RESERVED"); 449 assert(0); 450 break; 451 } 452} 453 454static void 455gen3_get_instruction_src0(uint32_t *data, int i, char *srcname) 456{ 457 uint32_t a0 = data[i]; 458 uint32_t a1 = data[i + 1]; 459 int src_nr = (a0 >> 2) & 0x1f; 460 const char *swizzle_x = gen3_get_channel_swizzle((a1 >> 28) & 0xf); 461 const char *swizzle_y = gen3_get_channel_swizzle((a1 >> 24) & 0xf); 462 const char *swizzle_z = gen3_get_channel_swizzle((a1 >> 20) & 0xf); 463 const char *swizzle_w = gen3_get_channel_swizzle((a1 >> 16) & 0xf); 464 char swizzle[100]; 465 466 gen3_get_instruction_src_name((a0 >> 7) & 0x7, src_nr, srcname); 467 sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); 468 if (strcmp(swizzle, ".xyzw") != 0) 469 strcat(srcname, swizzle); 470} 471 472static void 473gen3_get_instruction_src1(uint32_t *data, int i, char *srcname) 474{ 475 uint32_t a1 = data[i + 1]; 476 uint32_t a2 = data[i + 2]; 477 int src_nr = (a1 >> 8) & 0x1f; 478 const char *swizzle_x = gen3_get_channel_swizzle((a1 >> 4) & 0xf); 479 const char *swizzle_y = gen3_get_channel_swizzle((a1 >> 0) & 0xf); 480 const char *swizzle_z = gen3_get_channel_swizzle((a2 >> 28) & 0xf); 481 const char *swizzle_w = gen3_get_channel_swizzle((a2 >> 24) & 0xf); 482 char swizzle[100]; 483 484 gen3_get_instruction_src_name((a1 >> 13) & 0x7, src_nr, srcname); 485 sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); 486 if (strcmp(swizzle, ".xyzw") != 0) 487 strcat(srcname, swizzle); 488} 489 490static void 491gen3_get_instruction_src2(uint32_t *data, int i, char *srcname) 492{ 493 uint32_t a2 = data[i + 2]; 494 int src_nr = (a2 >> 16) & 0x1f; 495 const char *swizzle_x = gen3_get_channel_swizzle((a2 >> 12) & 0xf); 496 const char *swizzle_y = gen3_get_channel_swizzle((a2 >> 8) & 0xf); 497 const char *swizzle_z = gen3_get_channel_swizzle((a2 >> 4) & 0xf); 498 const char *swizzle_w = gen3_get_channel_swizzle((a2 >> 0) & 0xf); 499 char swizzle[100]; 500 501 gen3_get_instruction_src_name((a2 >> 21) & 0x7, src_nr, srcname); 502 sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); 503 if (strcmp(swizzle, ".xyzw") != 0) 504 strcat(srcname, swizzle); 505} 506 507static void 508gen3_get_instruction_addr(uint32_t src_type, uint32_t src_nr, char *name) 509{ 510 switch (src_type) { 511 case 0: 512 sprintf(name, "R%d", src_nr); 513 assert(src_nr <= 15); 514 break; 515 case 1: 516 if (src_nr < 8) 517 sprintf(name, "T%d", src_nr); 518 else if (src_nr == 8) 519 sprintf(name, "DIFFUSE"); 520 else if (src_nr == 9) 521 sprintf(name, "SPECULAR"); 522 else if (src_nr == 10) 523 sprintf(name, "FOG"); 524 else { 525 assert(0); 526 sprintf(name, "RESERVED"); 527 } 528 break; 529 case 4: 530 sprintf(name, "oC"); 531 assert(src_nr == 0); 532 break; 533 case 5: 534 sprintf(name, "oD"); 535 assert(src_nr == 0); 536 break; 537 default: 538 assert(0); 539 sprintf(name, "RESERVED"); 540 break; 541 } 542} 543 544static void 545gen3_decode_alu1(uint32_t *data, uint32_t offset, 546 int i, char *instr_prefix, const char *op_name) 547{ 548 char dst[100], src0[100]; 549 550 gen3_get_instruction_dst(data, i, dst, 1); 551 gen3_get_instruction_src0(data, i, src0); 552 553 kgem_debug_print(data, offset, i++, "%s: %s %s, %s\n", instr_prefix, 554 op_name, dst, src0); 555 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 556 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 557} 558 559static void 560gen3_decode_alu2(uint32_t *data, uint32_t offset, 561 int i, char *instr_prefix, const char *op_name) 562{ 563 char dst[100], src0[100], src1[100]; 564 565 gen3_get_instruction_dst(data, i, dst, 1); 566 gen3_get_instruction_src0(data, i, src0); 567 gen3_get_instruction_src1(data, i, src1); 568 569 kgem_debug_print(data, offset, i++, "%s: %s %s, %s, %s\n", instr_prefix, 570 op_name, dst, src0, src1); 571 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 572 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 573} 574 575static void 576gen3_decode_alu3(uint32_t *data, uint32_t offset, 577 int i, char *instr_prefix, const char *op_name) 578{ 579 char dst[100], src0[100], src1[100], src2[100]; 580 581 gen3_get_instruction_dst(data, i, dst, 1); 582 gen3_get_instruction_src0(data, i, src0); 583 gen3_get_instruction_src1(data, i, src1); 584 gen3_get_instruction_src2(data, i, src2); 585 586 kgem_debug_print(data, offset, i++, "%s: %s %s, %s, %s, %s\n", instr_prefix, 587 op_name, dst, src0, src1, src2); 588 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 589 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 590} 591 592static void 593gen3_decode_tex(uint32_t *data, uint32_t offset, int i, char *instr_prefix, 594 const char *tex_name) 595{ 596 uint32_t t0 = data[i]; 597 uint32_t t1 = data[i + 1]; 598 char dst_name[100]; 599 char addr_name[100]; 600 int sampler_nr; 601 602 gen3_get_instruction_dst(data, i, dst_name, 0); 603 gen3_get_instruction_addr((t1 >> 24) & 0x7, 604 (t1 >> 17) & 0xf, 605 addr_name); 606 sampler_nr = t0 & 0xf; 607 608 kgem_debug_print(data, offset, i++, "%s: %s %s, S%d, %s\n", instr_prefix, 609 tex_name, dst_name, sampler_nr, addr_name); 610 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 611 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 612} 613 614static void 615gen3_decode_dcl(uint32_t *data, uint32_t offset, int i, char *instr_prefix) 616{ 617 uint32_t d0 = data[i]; 618 const char *sampletype; 619 int dcl_nr = (d0 >> 14) & 0xf; 620 const char *dcl_x = d0 & (1 << 10) ? "x" : ""; 621 const char *dcl_y = d0 & (1 << 11) ? "y" : ""; 622 const char *dcl_z = d0 & (1 << 12) ? "z" : ""; 623 const char *dcl_w = d0 & (1 << 13) ? "w" : ""; 624 char dcl_mask[10]; 625 626 switch ((d0 >> 19) & 0x3) { 627 case 1: 628 sprintf(dcl_mask, ".%s%s%s%s", dcl_x, dcl_y, dcl_z, dcl_w); 629 assert (strcmp(dcl_mask, ".")); 630 631 assert(dcl_nr <= 10); 632 if (dcl_nr < 8) { 633 if (strcmp(dcl_mask, ".x") != 0 && 634 strcmp(dcl_mask, ".xy") != 0 && 635 strcmp(dcl_mask, ".xz") != 0 && 636 strcmp(dcl_mask, ".w") != 0 && 637 strcmp(dcl_mask, ".xyzw") != 0) { 638 assert(0); 639 } 640 kgem_debug_print(data, offset, i++, "%s: DCL T%d%s\n", instr_prefix, 641 dcl_nr, dcl_mask); 642 } else { 643 if (strcmp(dcl_mask, ".xz") == 0) 644 assert(0); 645 else if (strcmp(dcl_mask, ".xw") == 0) 646 assert(0); 647 else if (strcmp(dcl_mask, ".xzw") == 0) 648 assert(0); 649 650 if (dcl_nr == 8) { 651 kgem_debug_print(data, offset, i++, "%s: DCL DIFFUSE%s\n", instr_prefix, 652 dcl_mask); 653 } else if (dcl_nr == 9) { 654 kgem_debug_print(data, offset, i++, "%s: DCL SPECULAR%s\n", instr_prefix, 655 dcl_mask); 656 } else if (dcl_nr == 10) { 657 kgem_debug_print(data, offset, i++, "%s: DCL FOG%s\n", instr_prefix, 658 dcl_mask); 659 } 660 } 661 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 662 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 663 break; 664 case 3: 665 switch ((d0 >> 22) & 0x3) { 666 case 0: 667 sampletype = "2D"; 668 break; 669 case 1: 670 sampletype = "CUBE"; 671 break; 672 case 2: 673 sampletype = "3D"; 674 break; 675 default: 676 sampletype = "RESERVED"; 677 break; 678 } 679 assert(dcl_nr <= 15); 680 kgem_debug_print(data, offset, i++, "%s: DCL S%d %s\n", instr_prefix, 681 dcl_nr, sampletype); 682 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 683 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 684 break; 685 default: 686 kgem_debug_print(data, offset, i++, "%s: DCL RESERVED%d\n", instr_prefix, dcl_nr); 687 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 688 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 689 } 690} 691 692static void 693gen3_decode_instruction(uint32_t *data, uint32_t offset, 694 int i, char *instr_prefix) 695{ 696 switch ((data[i] >> 24) & 0x1f) { 697 case 0x0: 698 kgem_debug_print(data, offset, i++, "%s: NOP\n", instr_prefix); 699 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 700 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 701 break; 702 case 0x01: 703 gen3_decode_alu2(data, offset, i, instr_prefix, "ADD"); 704 break; 705 case 0x02: 706 gen3_decode_alu1(data, offset, i, instr_prefix, "MOV"); 707 break; 708 case 0x03: 709 gen3_decode_alu2(data, offset, i, instr_prefix, "MUL"); 710 break; 711 case 0x04: 712 gen3_decode_alu3(data, offset, i, instr_prefix, "MAD"); 713 break; 714 case 0x05: 715 gen3_decode_alu3(data, offset, i, instr_prefix, "DP2ADD"); 716 break; 717 case 0x06: 718 gen3_decode_alu2(data, offset, i, instr_prefix, "DP3"); 719 break; 720 case 0x07: 721 gen3_decode_alu2(data, offset, i, instr_prefix, "DP4"); 722 break; 723 case 0x08: 724 gen3_decode_alu1(data, offset, i, instr_prefix, "FRC"); 725 break; 726 case 0x09: 727 gen3_decode_alu1(data, offset, i, instr_prefix, "RCP"); 728 break; 729 case 0x0a: 730 gen3_decode_alu1(data, offset, i, instr_prefix, "RSQ"); 731 break; 732 case 0x0b: 733 gen3_decode_alu1(data, offset, i, instr_prefix, "EXP"); 734 break; 735 case 0x0c: 736 gen3_decode_alu1(data, offset, i, instr_prefix, "LOG"); 737 break; 738 case 0x0d: 739 gen3_decode_alu2(data, offset, i, instr_prefix, "CMP"); 740 break; 741 case 0x0e: 742 gen3_decode_alu2(data, offset, i, instr_prefix, "MIN"); 743 break; 744 case 0x0f: 745 gen3_decode_alu2(data, offset, i, instr_prefix, "MAX"); 746 break; 747 case 0x10: 748 gen3_decode_alu1(data, offset, i, instr_prefix, "FLR"); 749 break; 750 case 0x11: 751 gen3_decode_alu1(data, offset, i, instr_prefix, "MOD"); 752 break; 753 case 0x12: 754 gen3_decode_alu1(data, offset, i, instr_prefix, "TRC"); 755 break; 756 case 0x13: 757 gen3_decode_alu2(data, offset, i, instr_prefix, "SGE"); 758 break; 759 case 0x14: 760 gen3_decode_alu2(data, offset, i, instr_prefix, "SLT"); 761 break; 762 case 0x15: 763 gen3_decode_tex(data, offset, i, instr_prefix, "TEXLD"); 764 break; 765 case 0x16: 766 gen3_decode_tex(data, offset, i, instr_prefix, "TEXLDP"); 767 break; 768 case 0x17: 769 gen3_decode_tex(data, offset, i, instr_prefix, "TEXLDB"); 770 break; 771 case 0x19: 772 gen3_decode_dcl(data, offset, i, instr_prefix); 773 break; 774 default: 775 kgem_debug_print(data, offset, i++, "%s: unknown\n", instr_prefix); 776 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 777 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); 778 break; 779 } 780} 781 782static const char * 783gen3_decode_compare_func(uint32_t op) 784{ 785 switch (op&0x7) { 786 case 0: return "always"; 787 case 1: return "never"; 788 case 2: return "less"; 789 case 3: return "equal"; 790 case 4: return "lequal"; 791 case 5: return "greater"; 792 case 6: return "notequal"; 793 case 7: return "gequal"; 794 } 795 return ""; 796} 797 798static const char * 799gen3_decode_stencil_op(uint32_t op) 800{ 801 switch (op&0x7) { 802 case 0: return "keep"; 803 case 1: return "zero"; 804 case 2: return "replace"; 805 case 3: return "incr_sat"; 806 case 4: return "decr_sat"; 807 case 5: return "greater"; 808 case 6: return "incr"; 809 case 7: return "decr"; 810 } 811 return ""; 812} 813 814#if 0 815/* part of MODES_4 */ 816static const char * 817gen3_decode_logic_op(uint32_t op) 818{ 819 switch (op&0xf) { 820 case 0: return "clear"; 821 case 1: return "nor"; 822 case 2: return "and_inv"; 823 case 3: return "copy_inv"; 824 case 4: return "and_rvrse"; 825 case 5: return "inv"; 826 case 6: return "xor"; 827 case 7: return "nand"; 828 case 8: return "and"; 829 case 9: return "equiv"; 830 case 10: return "noop"; 831 case 11: return "or_inv"; 832 case 12: return "copy"; 833 case 13: return "or_rvrse"; 834 case 14: return "or"; 835 case 15: return "set"; 836 } 837 return ""; 838} 839#endif 840 841static const char * 842gen3_decode_blend_fact(uint32_t op) 843{ 844 switch (op&0xf) { 845 case 1: return "zero"; 846 case 2: return "one"; 847 case 3: return "src_colr"; 848 case 4: return "inv_src_colr"; 849 case 5: return "src_alpha"; 850 case 6: return "inv_src_alpha"; 851 case 7: return "dst_alpha"; 852 case 8: return "inv_dst_alpha"; 853 case 9: return "dst_colr"; 854 case 10: return "inv_dst_colr"; 855 case 11: return "src_alpha_sat"; 856 case 12: return "cnst_colr"; 857 case 13: return "inv_cnst_colr"; 858 case 14: return "cnst_alpha"; 859 case 15: return "inv_const_alpha"; 860 } 861 return ""; 862} 863 864static const char * 865decode_tex_coord_mode(uint32_t mode) 866{ 867 switch (mode&0x7) { 868 case 0: return "wrap"; 869 case 1: return "mirror"; 870 case 2: return "clamp_edge"; 871 case 3: return "cube"; 872 case 4: return "clamp_border"; 873 case 5: return "mirror_once"; 874 } 875 return ""; 876} 877 878static const char * 879gen3_decode_sample_filter(uint32_t mode) 880{ 881 switch (mode&0x7) { 882 case 0: return "nearest"; 883 case 1: return "linear"; 884 case 2: return "anisotropic"; 885 case 3: return "4x4_1"; 886 case 4: return "4x4_2"; 887 case 5: return "4x4_flat"; 888 case 6: return "6x5_mono"; 889 } 890 return ""; 891} 892 893static int 894gen3_decode_load_state_immediate_1(struct kgem *kgem, uint32_t offset) 895{ 896 const uint32_t *data = kgem->batch + offset; 897 int len, i, word; 898 899 kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); 900 len = (data[0] & 0x0000000f) + 2; 901 i = 1; 902 for (word = 0; word <= 8; word++) { 903 if (data[0] & (1 << (4 + word))) { 904 switch (word) { 905 case 0: 906 kgem_debug_print(data, offset, i, "S0: vbo offset: 0x%08x%s\n", 907 data[i]&(~1),data[i]&1?", auto cache invalidate disabled":""); 908 gen3_update_vertex_buffer_addr(kgem, offset + i); 909 break; 910 case 1: 911 kgem_debug_print(data, offset, i, "S1: vertex width: %i, vertex pitch: %i\n", 912 (data[i]>>24)&0x3f,(data[i]>>16)&0x3f); 913 gen3_update_vertex_buffer_pitch(kgem, offset + i); 914 break; 915 case 2: 916 { 917 char buf[200]; 918 int len = 0; 919 int tex_num; 920 for (tex_num = 0; tex_num < 8; tex_num++) { 921 switch((data[i]>>tex_num*4)&0xf) { 922 case 0: len += sprintf(buf + len, "%i=2D ", tex_num); break; 923 case 1: len += sprintf(buf + len, "%i=3D ", tex_num); break; 924 case 2: len += sprintf(buf + len, "%i=4D ", tex_num); break; 925 case 3: len += sprintf(buf + len, "%i=1D ", tex_num); break; 926 case 4: len += sprintf(buf + len, "%i=2D_16 ", tex_num); break; 927 case 5: len += sprintf(buf + len, "%i=4D_16 ", tex_num); break; 928 case 0xf: len += sprintf(buf + len, "%i=NP ", tex_num); break; 929 } 930 } 931 kgem_debug_print(data, offset, i, "S2: texcoord formats: %s\n", buf); 932 gen3_update_vertex_texcoords(kgem, data[i]); 933 } 934 935 break; 936 case 3: 937 kgem_debug_print(data, offset, i, "S3: not documented\n"); 938 break; 939 case 4: 940 { 941 const char *cullmode = ""; 942 const char *vfmt_xyzw = ""; 943 switch((data[i]>>13)&0x3) { 944 case 0: cullmode = "both"; break; 945 case 1: cullmode = "none"; break; 946 case 2: cullmode = "cw"; break; 947 case 3: cullmode = "ccw"; break; 948 } 949 switch(data[i] & (7<<6 | 1<<2)) { 950 case 1<<6: vfmt_xyzw = "XYZ,"; break; 951 case 2<<6: vfmt_xyzw = "XYZW,"; break; 952 case 3<<6: vfmt_xyzw = "XY,"; break; 953 case 4<<6: vfmt_xyzw = "XYW,"; break; 954 case 1<<6 | 1<<2: vfmt_xyzw = "XYZF,"; break; 955 case 2<<6 | 1<<2: vfmt_xyzw = "XYZWF,"; break; 956 case 3<<6 | 1<<2: vfmt_xyzw = "XYF,"; break; 957 case 4<<6 | 1<<2: vfmt_xyzw = "XYWF,"; break; 958 } 959 kgem_debug_print(data, offset, i, "S4: point_width=%i, line_width=%.1f," 960 "%s%s%s%s%s cullmode=%s, vfmt=%s%s%s%s%s%s%s%s " 961 "%s%s%s\n", 962 (data[i]>>23)&0x1ff, 963 ((data[i]>>19)&0xf) / 2.0, 964 data[i]&(0xf<<15)?" flatshade=":"", 965 data[i]&(1<<18)?"Alpha,":"", 966 data[i]&(1<<17)?"Fog,":"", 967 data[i]&(1<<16)?"Specular,":"", 968 data[i]&(1<<15)?"Color,":"", 969 cullmode, 970 data[i]&(1<<12)?"PointWidth,":"", 971 data[i]&(1<<11)?"SpecFog,":"", 972 data[i]&(1<<10)?"Color,":"", 973 data[i]&(1<<9)?"DepthOfs,":"", 974 vfmt_xyzw, 975 data[i]&(1<<9)?"FogParam,":"", 976 data[i]&(1<<5)?"force default diffuse, ":"", 977 data[i]&(1<<4)?"force default specular, ":"", 978 data[i]&(1<<3)?"local depth ofs enable, ":"", 979 data[i]&(1<<1)?"point sprite enable, ":"", 980 data[i]&(1<<0)?"line AA enable, ":""); 981 gen3_update_vertex_elements(kgem, data[i]); 982 break; 983 } 984 case 5: 985 { 986 kgem_debug_print(data, offset, i, "S5:%s%s%s%s%s" 987 "%s%s%s%s stencil_ref=0x%x, stencil_test=%s, " 988 "stencil_fail=%s, stencil_pass_z_fail=%s, " 989 "stencil_pass_z_pass=%s, %s%s%s%s\n", 990 data[i]&(0xf<<28)?" write_disable=":"", 991 data[i]&(1<<31)?"Alpha,":"", 992 data[i]&(1<<30)?"Red,":"", 993 data[i]&(1<<29)?"Green,":"", 994 data[i]&(1<<28)?"Blue,":"", 995 data[i]&(1<<27)?" force default point size,":"", 996 data[i]&(1<<26)?" last pixel enable,":"", 997 data[i]&(1<<25)?" global depth ofs enable,":"", 998 data[i]&(1<<24)?" fog enable,":"", 999 (data[i]>>16)&0xff, 1000 gen3_decode_compare_func(data[i]>>13), 1001 gen3_decode_stencil_op(data[i]>>10), 1002 gen3_decode_stencil_op(data[i]>>7), 1003 gen3_decode_stencil_op(data[i]>>4), 1004 data[i]&(1<<3)?"stencil write enable, ":"", 1005 data[i]&(1<<2)?"stencil test enable, ":"", 1006 data[i]&(1<<1)?"color dither enable, ":"", 1007 data[i]&(1<<0)?"logicop enable, ":""); 1008 } 1009 break; 1010 case 6: 1011 kgem_debug_print(data, offset, i, "S6: %salpha_test=%s, alpha_ref=0x%x, " 1012 "depth_test=%s, %ssrc_blnd_fct=%s, dst_blnd_fct=%s, " 1013 "%s%stristrip_provoking_vertex=%i\n", 1014 data[i]&(1<<31)?"alpha test enable, ":"", 1015 gen3_decode_compare_func(data[i]>>28), 1016 data[i]&(0xff<<20), 1017 gen3_decode_compare_func(data[i]>>16), 1018 data[i]&(1<<15)?"cbuf blend enable, ":"", 1019 gen3_decode_blend_fact(data[i]>>8), 1020 gen3_decode_blend_fact(data[i]>>4), 1021 data[i]&(1<<3)?"depth write enable, ":"", 1022 data[i]&(1<<2)?"cbuf write enable, ":"", 1023 data[i]&(0x3)); 1024 break; 1025 case 7: 1026 kgem_debug_print(data, offset, i, "S7: depth offset constant: 0x%08x\n", data[i]); 1027 break; 1028 } 1029 i++; 1030 } 1031 } 1032 1033 assert(len == i); 1034 return len; 1035} 1036 1037static int 1038gen3_decode_3d_1d(struct kgem *kgem, uint32_t offset) 1039{ 1040 uint32_t *data = kgem->batch + offset; 1041 unsigned int len, i, c, idx, word, map, sampler, instr; 1042 const char *format, *zformat, *type; 1043 uint32_t opcode; 1044 static const struct { 1045 uint32_t opcode; 1046 int min_len; 1047 int max_len; 1048 const char *name; 1049 } opcodes_3d_1d[] = { 1050 { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" }, 1051 { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, 1052 { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, 1053 { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, 1054 { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" }, 1055 { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, 1056 { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, 1057 { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" }, 1058 { 0x89, 4, 4, "3DSTATE_FOG_MODE" }, 1059 { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, 1060 { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" }, 1061 }, *opcode_3d_1d; 1062 1063 opcode = (data[0] & 0x00ff0000) >> 16; 1064 1065 switch (opcode) { 1066 case 0x07: 1067 /* This instruction is unusual. A 0 length means just 1 DWORD instead of 1068 * 2. The 0 length is specified in one place to be unsupported, but 1069 * stated to be required in another, and 0 length LOAD_INDIRECTs appear 1070 * to cause no harm at least. 1071 */ 1072 kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_INDIRECT\n"); 1073 len = (data[0] & 0x000000ff) + 1; 1074 i = 1; 1075 if (data[0] & (0x01 << 8)) { 1076 kgem_debug_print(data, offset, i++, "SIS.0\n"); 1077 kgem_debug_print(data, offset, i++, "SIS.1\n"); 1078 } 1079 if (data[0] & (0x02 << 8)) { 1080 kgem_debug_print(data, offset, i++, "DIS.0\n"); 1081 } 1082 if (data[0] & (0x04 << 8)) { 1083 kgem_debug_print(data, offset, i++, "SSB.0\n"); 1084 kgem_debug_print(data, offset, i++, "SSB.1\n"); 1085 } 1086 if (data[0] & (0x08 << 8)) { 1087 kgem_debug_print(data, offset, i++, "MSB.0\n"); 1088 kgem_debug_print(data, offset, i++, "MSB.1\n"); 1089 } 1090 if (data[0] & (0x10 << 8)) { 1091 kgem_debug_print(data, offset, i++, "PSP.0\n"); 1092 kgem_debug_print(data, offset, i++, "PSP.1\n"); 1093 } 1094 if (data[0] & (0x20 << 8)) { 1095 kgem_debug_print(data, offset, i++, "PSC.0\n"); 1096 kgem_debug_print(data, offset, i++, "PSC.1\n"); 1097 } 1098 assert(len == i); 1099 return len; 1100 case 0x04: 1101 return gen3_decode_load_state_immediate_1(kgem, offset); 1102 case 0x03: 1103 kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_2\n"); 1104 len = (data[0] & 0x0000000f) + 2; 1105 i = 1; 1106 for (word = 6; word <= 14; word++) { 1107 if (data[0] & (1 << word)) { 1108 if (word == 6) 1109 kgem_debug_print(data, offset, i++, "TBCF\n"); 1110 else if (word >= 7 && word <= 10) { 1111 kgem_debug_print(data, offset, i++, "TB%dC\n", word - 7); 1112 kgem_debug_print(data, offset, i++, "TB%dA\n", word - 7); 1113 } else if (word >= 11 && word <= 14) { 1114 kgem_debug_print(data, offset, i, "TM%dS0: offset=0x%08x, %s\n", 1115 word - 11, 1116 data[i]&0xfffffffe, 1117 data[i]&1?"use fence":""); 1118 i++; 1119 kgem_debug_print(data, offset, i, "TM%dS1: height=%i, width=%i, %s\n", 1120 word - 11, 1121 data[i]>>21, (data[i]>>10)&0x3ff, 1122 data[i]&2?(data[i]&1?"y-tiled":"x-tiled"):""); 1123 i++; 1124 kgem_debug_print(data, offset, i, "TM%dS2: pitch=%i, \n", 1125 word - 11, 1126 ((data[i]>>21) + 1)*4); 1127 i++; 1128 kgem_debug_print(data, offset, i++, "TM%dS3\n", word - 11); 1129 kgem_debug_print(data, offset, i++, "TM%dS4: dflt color\n", word - 11); 1130 } 1131 } 1132 } 1133 assert(len == i); 1134 return len; 1135 case 0x00: 1136 kgem_debug_print(data, offset, 0, "3DSTATE_MAP_STATE\n"); 1137 len = (data[0] & 0x0000003f) + 2; 1138 kgem_debug_print(data, offset, 1, "mask\n"); 1139 1140 i = 2; 1141 for (map = 0; map <= 15; map++) { 1142 if (data[1] & (1 << map)) { 1143 int width, height, pitch, dword; 1144 struct drm_i915_gem_relocation_entry *reloc; 1145 const char *tiling; 1146 1147 reloc = kgem_debug_get_reloc_entry(kgem, &data[i] - kgem->batch); 1148 assert(reloc->target_handle); 1149 1150 dword = data[i]; 1151 kgem_debug_print(data, offset, i++, "map %d MS2 %s%s%s, handle=%d\n", map, 1152 dword&(1<<31)?"untrusted surface, ":"", 1153 dword&(1<<1)?"vertical line stride enable, ":"", 1154 dword&(1<<0)?"vertical ofs enable, ":"", 1155 reloc->target_handle); 1156 1157 dword = data[i]; 1158 width = ((dword >> 10) & ((1 << 11) - 1))+1; 1159 height = ((dword >> 21) & ((1 << 11) - 1))+1; 1160 1161 tiling = "none"; 1162 if (dword & (1 << 2)) 1163 tiling = "fenced"; 1164 else if (dword & (1 << 1)) 1165 tiling = dword & (1 << 0) ? "Y" : "X"; 1166 type = " BAD"; 1167 format = " (invalid)"; 1168 switch ((dword>>7) & 0x7) { 1169 case 1: 1170 type = "8"; 1171 switch ((dword>>3) & 0xf) { 1172 case 0: format = "I"; break; 1173 case 1: format = "L"; break; 1174 case 4: format = "A"; break; 1175 case 5: format = " mono"; break; 1176 } 1177 break; 1178 case 2: 1179 type = "16"; 1180 switch ((dword>>3) & 0xf) { 1181 case 0: format = " rgb565"; break; 1182 case 1: format = " argb1555"; break; 1183 case 2: format = " argb4444"; break; 1184 case 3: format = " ay88"; break; 1185 case 5: format = " 88dvdu"; break; 1186 case 6: format = " bump655"; break; 1187 case 7: format = "I"; break; 1188 case 8: format = "L"; break; 1189 case 9: format = "A"; break; 1190 } 1191 break; 1192 case 3: 1193 type = "32"; 1194 switch ((dword>>3) & 0xf) { 1195 case 0: format = " argb8888"; break; 1196 case 1: format = " abgr8888"; break; 1197 case 2: format = " xrgb8888"; break; 1198 case 3: format = " xbgr8888"; break; 1199 case 4: format = " qwvu8888"; break; 1200 case 5: format = " axvu8888"; break; 1201 case 6: format = " lxvu8888"; break; 1202 case 7: format = " xlvu8888"; break; 1203 case 8: format = " argb2101010"; break; 1204 case 9: format = " abgr2101010"; break; 1205 case 10: format = " awvu2101010"; break; 1206 case 11: format = " gr1616"; break; 1207 case 12: format = " vu1616"; break; 1208 case 13: format = " xI824"; break; 1209 case 14: format = " xA824"; break; 1210 case 15: format = " xL824"; break; 1211 } 1212 break; 1213 case 5: 1214 type = "422"; 1215 switch ((dword>>3) & 0xf) { 1216 case 0: format = " yuv_swapy"; break; 1217 case 1: format = " yuv"; break; 1218 case 2: format = " yuv_swapuv"; break; 1219 case 3: format = " yuv_swapuvy"; break; 1220 } 1221 break; 1222 case 6: 1223 type = "compressed"; 1224 switch ((dword>>3) & 0x7) { 1225 case 0: format = " dxt1"; break; 1226 case 1: format = " dxt2_3"; break; 1227 case 2: format = " dxt4_5"; break; 1228 case 3: format = " fxt1"; break; 1229 case 4: format = " dxt1_rb"; break; 1230 } 1231 break; 1232 case 7: 1233 type = "4b indexed"; 1234 switch ((dword>>3) & 0xf) { 1235 case 7: format = " argb8888"; break; 1236 } 1237 break; 1238 default: 1239 format = "BAD"; 1240 break; 1241 } 1242 dword = data[i]; 1243 kgem_debug_print(data, offset, i++, "map %d MS3 [width=%d, height=%d, format=%s%s, tiling=%s%s]\n", 1244 map, width, height, type, format, tiling, 1245 dword&(1<<9)?" palette select":""); 1246 1247 dword = data[i]; 1248 pitch = 4*(((dword >> 21) & ((1 << 11) - 1))+1); 1249 kgem_debug_print(data, offset, i++, "map %d MS4 [pitch=%d, max_lod=%i, vol_depth=%i, cube_face_ena=%x, %s]\n", 1250 map, pitch, 1251 (dword>>9)&0x3f, dword&0xff, (dword>>15)&0x3f, 1252 dword&(1<<8)?"miplayout legacy":"miplayout right"); 1253 } 1254 } 1255 assert(len == i); 1256 return len; 1257 case 0x06: 1258 kgem_debug_print(data, offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); 1259 len = (data[0] & 0x000000ff) + 2; 1260 1261 i = 2; 1262 for (c = 0; c <= 31; c++) { 1263 if (data[1] & (1 << c)) { 1264 kgem_debug_print(data, offset, i, "C%d.X = %f\n", 1265 c, int_as_float(data[i])); 1266 i++; 1267 kgem_debug_print(data, offset, i, "C%d.Y = %f\n", 1268 c, int_as_float(data[i])); 1269 i++; 1270 kgem_debug_print(data, offset, i, "C%d.Z = %f\n", 1271 c, int_as_float(data[i])); 1272 i++; 1273 kgem_debug_print(data, offset, i, "C%d.W = %f\n", 1274 c, int_as_float(data[i])); 1275 i++; 1276 } 1277 } 1278 assert(len == i); 1279 return len; 1280 case 0x05: 1281 kgem_debug_print(data, offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n"); 1282 len = (data[0] & 0x000000ff) + 2; 1283 assert(((len-1) % 3) == 0); 1284 assert(len <= 370); 1285 i = 1; 1286 for (instr = 0; instr < (len - 1) / 3; instr++) { 1287 char instr_prefix[10]; 1288 1289 sprintf(instr_prefix, "PS%03d", instr); 1290 gen3_decode_instruction(data, offset, i, instr_prefix); 1291 i += 3; 1292 } 1293 return len; 1294 case 0x01: 1295 kgem_debug_print(data, offset, 0, "3DSTATE_SAMPLER_STATE\n"); 1296 kgem_debug_print(data, offset, 1, "mask\n"); 1297 len = (data[0] & 0x0000003f) + 2; 1298 i = 2; 1299 for (sampler = 0; sampler <= 15; sampler++) { 1300 if (data[1] & (1 << sampler)) { 1301 uint32_t dword; 1302 const char *mip_filter = ""; 1303 dword = data[i]; 1304 switch ((dword>>20)&0x3) { 1305 case 0: mip_filter = "none"; break; 1306 case 1: mip_filter = "nearest"; break; 1307 case 3: mip_filter = "linear"; break; 1308 } 1309 kgem_debug_print(data, offset, i++, "sampler %d SS2:%s%s%s " 1310 "base_mip_level=%i, mip_filter=%s, mag_filter=%s, min_filter=%s " 1311 "lod_bias=%.2f,%s max_aniso=%i, shadow_func=%s\n", sampler, 1312 dword&(1<<31)?" reverse gamma,":"", 1313 dword&(1<<30)?" packed2planar,":"", 1314 dword&(1<<29)?" colorspace conversion,":"", 1315 (dword>>22)&0x1f, 1316 mip_filter, 1317 gen3_decode_sample_filter(dword>>17), 1318 gen3_decode_sample_filter(dword>>14), 1319 ((dword>>5)&0x1ff)/(0x10*1.0), 1320 dword&(1<<4)?" shadow,":"", 1321 dword&(1<<3)?4:2, 1322 gen3_decode_compare_func(dword)); 1323 dword = data[i]; 1324 kgem_debug_print(data, offset, i++, "sampler %d SS3: min_lod=%.2f,%s " 1325 "tcmode_x=%s, tcmode_y=%s, tcmode_z=%s,%s texmap_idx=%i,%s\n", 1326 sampler, ((dword>>24)&0xff)/(0x10*1.0), 1327 dword&(1<<17)?" kill pixel enable,":"", 1328 decode_tex_coord_mode(dword>>12), 1329 decode_tex_coord_mode(dword>>9), 1330 decode_tex_coord_mode(dword>>6), 1331 dword&(1<<5)?" normalized coords,":"", 1332 (dword>>1)&0xf, 1333 dword&(1<<0)?" deinterlacer,":""); 1334 kgem_debug_print(data, offset, i++, "sampler %d SS4: border color\n", 1335 sampler); 1336 } 1337 } 1338 assert(len == i); 1339 return len; 1340 case 0x85: 1341 len = (data[0] & 0x0000000f) + 2; 1342 assert(len == 2); 1343 1344 kgem_debug_print(data, offset, 0, 1345 "3DSTATE_DEST_BUFFER_VARIABLES\n"); 1346 1347 switch ((data[1] >> 8) & 0xf) { 1348 case 0x0: format = "g8"; break; 1349 case 0x1: format = "x1r5g5b5"; break; 1350 case 0x2: format = "r5g6b5"; break; 1351 case 0x3: format = "a8r8g8b8"; break; 1352 case 0x4: format = "ycrcb_swapy"; break; 1353 case 0x5: format = "ycrcb_normal"; break; 1354 case 0x6: format = "ycrcb_swapuv"; break; 1355 case 0x7: format = "ycrcb_swapuvy"; break; 1356 case 0x8: format = "a4r4g4b4"; break; 1357 case 0x9: format = "a1r5g5b5"; break; 1358 case 0xa: format = "a2r10g10b10"; break; 1359 default: format = "BAD"; break; 1360 } 1361 switch ((data[1] >> 2) & 0x3) { 1362 case 0x0: zformat = "u16"; break; 1363 case 0x1: zformat = "f16"; break; 1364 case 0x2: zformat = "u24x8"; break; 1365 default: zformat = "BAD"; break; 1366 } 1367 kgem_debug_print(data, offset, 1, "%s format, %s depth format, early Z %sabled\n", 1368 format, zformat, 1369 (data[1] & (1 << 31)) ? "en" : "dis"); 1370 return len; 1371 1372 case 0x8e: 1373 { 1374 const char *name, *tiling; 1375 1376 len = (data[0] & 0x0000000f) + 2; 1377 assert(len == 3); 1378 1379 switch((data[1] >> 24) & 0x7) { 1380 case 0x3: name = "color"; break; 1381 case 0x7: name = "depth"; break; 1382 default: name = "unknown"; break; 1383 } 1384 1385 tiling = "none"; 1386 if (data[1] & (1 << 23)) 1387 tiling = "fenced"; 1388 else if (data[1] & (1 << 22)) 1389 tiling = data[1] & (1 << 21) ? "Y" : "X"; 1390 1391 kgem_debug_print(data, offset, 0, "3DSTATE_BUFFER_INFO\n"); 1392 kgem_debug_print(data, offset, 1, "%s, tiling = %s, pitch=%d\n", name, tiling, data[1]&0xffff); 1393 1394 kgem_debug_print(data, offset, 2, "address\n"); 1395 return len; 1396 } 1397 case 0x81: 1398 len = (data[0] & 0x0000000f) + 2; 1399 assert(len == 3); 1400 1401 kgem_debug_print(data, offset, 0, 1402 "3DSTATE_SCISSOR_RECTANGLE\n"); 1403 kgem_debug_print(data, offset, 1, "(%d,%d)\n", 1404 data[1] & 0xffff, data[1] >> 16); 1405 kgem_debug_print(data, offset, 2, "(%d,%d)\n", 1406 data[2] & 0xffff, data[2] >> 16); 1407 1408 return len; 1409 case 0x80: 1410 len = (data[0] & 0x0000000f) + 2; 1411 assert(len == 5); 1412 1413 kgem_debug_print(data, offset, 0, 1414 "3DSTATE_DRAWING_RECTANGLE\n"); 1415 kgem_debug_print(data, offset, 1, "%s\n", 1416 data[1]&(1<<30)?"depth ofs disabled ":""); 1417 kgem_debug_print(data, offset, 2, "(%d,%d)\n", 1418 data[2] & 0xffff, data[2] >> 16); 1419 kgem_debug_print(data, offset, 3, "(%d,%d)\n", 1420 data[3] & 0xffff, data[3] >> 16); 1421 kgem_debug_print(data, offset, 4, "(%d,%d)\n", 1422 (int16_t)(data[4] & 0xffff), 1423 (int16_t)(data[4] >> 16)); 1424 1425 return len; 1426 case 0x9c: 1427 len = (data[0] & 0x0000000f) + 2; 1428 assert(len == 7); 1429 1430 kgem_debug_print(data, offset, 0, 1431 "3DSTATE_CLEAR_PARAMETERS\n"); 1432 kgem_debug_print(data, offset, 1, "prim_type=%s, clear=%s%s%s\n", 1433 data[1]&(1<<16)?"CLEAR_RECT":"ZONE_INIT", 1434 data[1]&(1<<2)?"color,":"", 1435 data[1]&(1<<1)?"depth,":"", 1436 data[1]&(1<<0)?"stencil,":""); 1437 kgem_debug_print(data, offset, 2, "clear color\n"); 1438 kgem_debug_print(data, offset, 3, "clear depth/stencil\n"); 1439 kgem_debug_print(data, offset, 4, "color value (rgba8888)\n"); 1440 kgem_debug_print(data, offset, 5, "depth value %f\n", 1441 int_as_float(data[5])); 1442 kgem_debug_print(data, offset, 6, "clear stencil\n"); 1443 return len; 1444 } 1445 1446 for (idx = 0; idx < ARRAY_SIZE(opcodes_3d_1d); idx++) { 1447 opcode_3d_1d = &opcodes_3d_1d[idx]; 1448 if (((data[0] & 0x00ff0000) >> 16) == opcode_3d_1d->opcode) { 1449 len = (data[0] & 0xf) + 2; 1450 kgem_debug_print(data, offset, 0, "%s\n", opcode_3d_1d->name); 1451 for (i = 1; i < len; i++) 1452 kgem_debug_print(data, offset, i, "dword %d\n", i); 1453 1454 return len; 1455 } 1456 } 1457 1458 kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d_1d opcode = 0x%x\n", opcode); 1459 assert(0); 1460 return 1; 1461} 1462 1463#define VERTEX_OUT(fmt, ...) do { \ 1464 kgem_debug_print(data, offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ 1465 i++; \ 1466} while (0) 1467 1468static int 1469gen3_decode_3d_primitive(struct kgem *kgem, uint32_t offset) 1470{ 1471 uint32_t *data = kgem->batch + offset; 1472 char immediate = (data[0] & (1 << 23)) == 0; 1473 unsigned int len, i, ret; 1474 const char *primtype; 1475 unsigned int vertex = 0; 1476 1477 switch ((data[0] >> 18) & 0xf) { 1478 case 0x0: primtype = "TRILIST"; break; 1479 case 0x1: primtype = "TRISTRIP"; break; 1480 case 0x2: primtype = "TRISTRIP_REVERSE"; break; 1481 case 0x3: primtype = "TRIFAN"; break; 1482 case 0x4: primtype = "POLYGON"; break; 1483 case 0x5: primtype = "LINELIST"; break; 1484 case 0x6: primtype = "LINESTRIP"; break; 1485 case 0x7: primtype = "RECTLIST"; break; 1486 case 0x8: primtype = "POINTLIST"; break; 1487 case 0x9: primtype = "DIB"; break; 1488 case 0xa: primtype = "CLEAR_RECT"; assert(0); break; 1489 default: primtype = "unknown"; break; 1490 } 1491 1492 gen3_update_vertex_elements_offsets(kgem); 1493 1494 /* XXX: 3DPRIM_DIB not supported */ 1495 if (immediate) { 1496 len = (data[0] & 0x0003ffff) + 2; 1497 kgem_debug_print(data, offset, 0, "3DPRIMITIVE inline %s\n", primtype); 1498 for (i = 1; i < len; ) { 1499 ErrorF(" [%d]: ", vertex); 1500 i += inline_vertex_out(kgem, data + i) / sizeof(uint32_t); 1501 ErrorF("\n"); 1502 vertex++; 1503 } 1504 1505 ret = len; 1506 } else { 1507 /* indirect vertices */ 1508 len = data[0] & 0x0000ffff; /* index count */ 1509 if (data[0] & (1 << 17)) { 1510 /* random vertex access */ 1511 kgem_debug_print(data, offset, 0, 1512 "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); 1513 assert(0); 1514 if (len == 0) { 1515 /* vertex indices continue until 0xffff is found */ 1516 } else { 1517 /* fixed size vertex index buffer */ 1518 } 1519 ret = (len + 1) / 2 + 1; 1520 goto out; 1521 } else { 1522 /* sequential vertex access */ 1523 vertex = data[1] & 0xffff; 1524 kgem_debug_print(data, offset, 0, 1525 "3DPRIMITIVE sequential indirect %s, %d starting from " 1526 "%d\n", primtype, len, vertex); 1527 kgem_debug_print(data, offset, 1, " start\n"); 1528 for (i = 0; i < len; i++) { 1529 ErrorF(" [%d]: ", vertex); 1530 indirect_vertex_out(kgem, vertex++); 1531 ErrorF("\n"); 1532 } 1533 ret = 2; 1534 goto out; 1535 } 1536 } 1537 1538out: 1539 return ret; 1540} 1541 1542int kgem_gen3_decode_3d(struct kgem *kgem, uint32_t offset) 1543{ 1544 static const struct { 1545 uint32_t opcode; 1546 int min_len; 1547 int max_len; 1548 const char *name; 1549 } opcodes[] = { 1550 { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" }, 1551 { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" }, 1552 { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" }, 1553 { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" }, 1554 { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, 1555 { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" }, 1556 { 0x0d, 1, 1, "3DSTATE_MODES_4" }, 1557 { 0x0c, 1, 1, "3DSTATE_MODES_5" }, 1558 { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, 1559 }; 1560 uint32_t *data = kgem->batch + offset; 1561 uint32_t opcode; 1562 unsigned int idx; 1563 1564 opcode = (data[0] & 0x1f000000) >> 24; 1565 1566 switch (opcode) { 1567 case 0x1f: 1568 return gen3_decode_3d_primitive(kgem, offset); 1569 case 0x1d: 1570 return gen3_decode_3d_1d(kgem, offset); 1571 case 0x1c: 1572 return gen3_decode_3d_1c(kgem, offset); 1573 } 1574 1575 for (idx = 0; idx < ARRAY_SIZE(opcodes); idx++) { 1576 if (opcode == opcodes[idx].opcode) { 1577 unsigned int len = 1, i; 1578 1579 kgem_debug_print(data, offset, 0, "%s\n", opcodes[idx].name); 1580 if (opcodes[idx].max_len > 1) { 1581 len = (data[0] & 0xff) + 2; 1582 assert(len >= opcodes[idx].min_len || 1583 len <= opcodes[idx].max_len); 1584 } 1585 1586 for (i = 1; i < len; i++) 1587 kgem_debug_print(data, offset, i, "dword %d\n", i); 1588 return len; 1589 } 1590 } 1591 1592 kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d opcode = 0x%x\n", opcode); 1593 return 1; 1594} 1595 1596 1597void kgem_gen3_finish_state(struct kgem *kgem) 1598{ 1599 memset(&state, 0, sizeof(state)); 1600} 1601