kgem_debug_gen2.c revision 03b705cf
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 "gen2_render.h" 40 41#include "kgem_debug.h" 42 43static struct state { 44 int vertex_format; 45} state; 46 47static inline float int_as_float(uint32_t dw) 48{ 49 union { 50 float f; 51 uint32_t dw; 52 } u; 53 u.dw = dw; 54 return u.f; 55} 56 57static int 58decode_3d_primitive(struct kgem *kgem, uint32_t offset) 59{ 60 uint32_t *data = kgem->batch + offset; 61 char immediate = (data[0] & (1 << 23)) == 0; 62 unsigned int len; 63 const char *primtype; 64 65 switch ((data[0] >> 18) & 0xf) { 66 case 0x0: primtype = "TRILIST"; break; 67 case 0x1: primtype = "TRISTRIP"; break; 68 case 0x2: primtype = "TRISTRIP_REVERSE"; break; 69 case 0x3: primtype = "TRIFAN"; break; 70 case 0x4: primtype = "POLYGON"; break; 71 case 0x5: primtype = "LINELIST"; break; 72 case 0x6: primtype = "LINESTRIP"; break; 73 case 0x7: primtype = "RECTLIST"; break; 74 case 0x8: primtype = "POINTLIST"; break; 75 case 0x9: primtype = "DIB"; break; 76 case 0xa: primtype = "CLEAR_RECT"; break; 77 default: primtype = "unknown"; break; 78 } 79 80 /* XXX: 3DPRIM_DIB not supported */ 81 if (immediate) { 82 len = (data[0] & 0x0003ffff) + 2; 83 kgem_debug_print(data, offset, 0, "3DPRIMITIVE inline %s\n", primtype); 84#if 0 85 if (!saved_s2_set || !saved_s4_set) { 86 fprintf(out, "unknown vertex format\n"); 87 for (i = 1; i < len; i++) { 88 kgem_debug_print(data, offset, i, 89 " vertex data (%f float)\n", 90 int_as_float(data[i])); 91 } 92 } else { 93 unsigned int vertex = 0; 94 for (i = 1; i < len;) { 95 unsigned int tc; 96 97#define VERTEX_OUT(fmt, ...) do { \ 98 if (i < len) \ 99 kgem_debug_print(data, offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ 100 else \ 101 fprintf(out, " missing data in V%d\n", vertex); \ 102 i++; \ 103} while (0) 104 105 VERTEX_OUT("X = %f", int_as_float(data[i])); 106 VERTEX_OUT("Y = %f", int_as_float(data[i])); 107 switch (saved_s4 >> 6 & 0x7) { 108 case 0x1: 109 VERTEX_OUT("Z = %f", int_as_float(data[i])); 110 break; 111 case 0x2: 112 VERTEX_OUT("Z = %f", int_as_float(data[i])); 113 VERTEX_OUT("W = %f", int_as_float(data[i])); 114 break; 115 case 0x3: 116 break; 117 case 0x4: 118 VERTEX_OUT("W = %f", int_as_float(data[i])); 119 break; 120 default: 121 fprintf(out, "bad S4 position mask\n"); 122 } 123 124 if (saved_s4 & (1 << 10)) { 125 VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, " 126 "B=0x%02x)", 127 data[i] >> 24, 128 (data[i] >> 16) & 0xff, 129 (data[i] >> 8) & 0xff, 130 data[i] & 0xff); 131 } 132 if (saved_s4 & (1 << 11)) { 133 VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, " 134 "B=0x%02x)", 135 data[i] >> 24, 136 (data[i] >> 16) & 0xff, 137 (data[i] >> 8) & 0xff, 138 data[i] & 0xff); 139 } 140 if (saved_s4 & (1 << 12)) 141 VERTEX_OUT("width = 0x%08x)", data[i]); 142 143 for (tc = 0; tc <= 7; tc++) { 144 switch ((saved_s2 >> (tc * 4)) & 0xf) { 145 case 0x0: 146 VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); 147 VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); 148 break; 149 case 0x1: 150 VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); 151 VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); 152 VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); 153 break; 154 case 0x2: 155 VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); 156 VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); 157 VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); 158 VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i])); 159 break; 160 case 0x3: 161 VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); 162 break; 163 case 0x4: 164 VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); 165 break; 166 case 0x5: 167 VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); 168 VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]); 169 break; 170 case 0xf: 171 break; 172 default: 173 fprintf(out, "bad S2.T%d format\n", tc); 174 } 175 } 176 vertex++; 177 } 178 } 179#endif 180 } else { 181 /* indirect vertices */ 182 len = data[0] & 0x0000ffff; /* index count */ 183#if 0 184 if (data[0] & (1 << 17)) { 185 /* random vertex access */ 186 kgem_debug_print(data, offset, 0, 187 "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); 188 if (len == 0) { 189 /* vertex indices continue until 0xffff is found */ 190 for (i = 1; i < count; i++) { 191 if ((data[i] & 0xffff) == 0xffff) { 192 kgem_debug_print(data, offset, i, 193 " indices: (terminator)\n"); 194 ret = i; 195 goto out; 196 } else if ((data[i] >> 16) == 0xffff) { 197 kgem_debug_print(data, offset, i, 198 " indices: 0x%04x, (terminator)\n", 199 data[i] & 0xffff); 200 ret = i; 201 goto out; 202 } else { 203 kgem_debug_print(data, offset, i, 204 " indices: 0x%04x, 0x%04x\n", 205 data[i] & 0xffff, data[i] >> 16); 206 } 207 } 208 fprintf(out, 209 "3DPRIMITIVE: no terminator found in index buffer\n"); 210 ret = count; 211 goto out; 212 } else { 213 /* fixed size vertex index buffer */ 214 for (j = 1, i = 0; i < len; i += 2, j++) { 215 if (i * 2 == len - 1) { 216 kgem_debug_print(data, offset, j, 217 " indices: 0x%04x\n", 218 data[j] & 0xffff); 219 } else { 220 kgem_debug_print(data, offset, j, 221 " indices: 0x%04x, 0x%04x\n", 222 data[j] & 0xffff, data[j] >> 16); 223 } 224 } 225 } 226 ret = (len + 1) / 2 + 1; 227 goto out; 228 } else { 229 /* sequential vertex access */ 230 kgem_debug_print(data, offset, 0, 231 "3DPRIMITIVE sequential indirect %s, %d starting from " 232 "%d\n", primtype, len, data[1] & 0xffff); 233 kgem_debug_print(data, offset, 1, " start\n"); 234 ret = 2; 235 goto out; 236 } 237#endif 238 } 239 240 return len; 241} 242 243static int 244decode_3d_1d(struct kgem *kgem, uint32_t offset) 245{ 246 uint32_t *data = kgem->batch + offset; 247 unsigned int len, i, idx, word, map; 248 const char *format, *zformat, *type; 249 uint32_t opcode; 250 251 static const struct { 252 uint32_t opcode; 253 int min_len; 254 int max_len; 255 const char *name; 256 } opcodes_3d_1d[] = { 257 { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" }, 258 { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, 259 { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, 260 { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, 261 { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" }, 262 { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, 263 { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, 264 { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" }, 265 { 0x89, 4, 4, "3DSTATE_FOG_MODE" }, 266 { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, 267 { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" }, 268 { 0x8c, 2, 2, "3DSTATE_MAP_COORD_TRANSFORM" }, 269 { 0x8b, 2, 2, "3DSTATE_MAP_VERTEX_TRANSFORM" }, 270 { 0x8d, 3, 3, "3DSTATE_W_STATE" }, 271 { 0x01, 2, 2, "3DSTATE_COLOR_FACTOR" }, 272 { 0x02, 2, 2, "3DSTATE_MAP_COORD_SETBIND" }, 273 }, *opcode_3d_1d; 274 275 opcode = (data[0] & 0x00ff0000) >> 16; 276 277 switch (opcode) { 278 case 0x07: 279 /* This instruction is unusual. A 0 length means just 1 DWORD instead of 280 * 2. The 0 length is specified in one place to be unsupported, but 281 * stated to be required in another, and 0 length LOAD_INDIRECTs appear 282 * to cause no harm at least. 283 */ 284 kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_INDIRECT\n"); 285 len = (data[0] & 0x000000ff) + 1; 286 i = 1; 287 if (data[0] & (0x01 << 8)) { 288 kgem_debug_print(data, offset, i++, "SIS.0\n"); 289 kgem_debug_print(data, offset, i++, "SIS.1\n"); 290 } 291 if (data[0] & (0x02 << 8)) { 292 kgem_debug_print(data, offset, i++, "DIS.0\n"); 293 } 294 if (data[0] & (0x04 << 8)) { 295 kgem_debug_print(data, offset, i++, "SSB.0\n"); 296 kgem_debug_print(data, offset, i++, "SSB.1\n"); 297 } 298 if (data[0] & (0x08 << 8)) { 299 kgem_debug_print(data, offset, i++, "MSB.0\n"); 300 kgem_debug_print(data, offset, i++, "MSB.1\n"); 301 } 302 if (data[0] & (0x10 << 8)) { 303 kgem_debug_print(data, offset, i++, "PSP.0\n"); 304 kgem_debug_print(data, offset, i++, "PSP.1\n"); 305 } 306 if (data[0] & (0x20 << 8)) { 307 kgem_debug_print(data, offset, i++, "PSC.0\n"); 308 kgem_debug_print(data, offset, i++, "PSC.1\n"); 309 } 310 assert(len == i); 311 return len; 312 case 0x04: 313 kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); 314 len = (data[0] & 0x0000000f) + 2; 315 i = 1; 316 for (word = 0; word <= 8; word++) { 317 if (data[0] & (1 << (4 + word))) { 318 kgem_debug_print(data, offset, i, "S%d: 0x%08x\n", i, data[i]); 319 i++; 320 } 321 } 322 assert (len ==i); 323 return len; 324 case 0x03: 325 kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_2\n"); 326 len = (data[0] & 0x0000000f) + 2; 327 i = 1; 328 for (word = 6; word <= 14; word++) { 329 if (data[0] & (1 << word)) { 330 if (word == 6) 331 kgem_debug_print(data, offset, i++, "TBCF\n"); 332 else if (word >= 7 && word <= 10) { 333 kgem_debug_print(data, offset, i++, "TB%dC\n", word - 7); 334 kgem_debug_print(data, offset, i++, "TB%dA\n", word - 7); 335 } else if (word >= 11 && word <= 14) { 336 kgem_debug_print(data, offset, i, "TM%dS0: offset=0x%08x, %s\n", 337 word - 11, 338 data[i]&0xfffffffe, 339 data[i]&1?"use fence":""); 340 i++; 341 kgem_debug_print(data, offset, i, "TM%dS1: height=%i, width=%i, %s\n", 342 word - 11, 343 data[i]>>21, (data[i]>>10)&0x3ff, 344 data[i]&2?(data[i]&1?"y-tiled":"x-tiled"):""); 345 i++; 346 kgem_debug_print(data, offset, i, "TM%dS2: pitch=%i, \n", 347 word - 11, 348 ((data[i]>>21) + 1)*4); 349 i++; 350 kgem_debug_print(data, offset, i++, "TM%dS3\n", word - 11); 351 kgem_debug_print(data, offset, i++, "TM%dS4: dflt color\n", word - 11); 352 } 353 } 354 } 355 assert (len == i); 356 return len; 357 case 0x00: 358 kgem_debug_print(data, offset, 0, "3DSTATE_MAP_STATE\n"); 359 len = (data[0] & 0x0000003f) + 2; 360 kgem_debug_print(data, offset, 1, "mask\n"); 361 362 i = 2; 363 for (map = 0; map <= 15; map++) { 364 if (data[1] & (1 << map)) { 365 int width, height, pitch, dword; 366 const char *tiling; 367 368 dword = data[i]; 369 kgem_debug_print(data, offset, i++, "map %d MS2 %s%s%s\n", map, 370 dword&(1<<31)?"untrusted surface, ":"", 371 dword&(1<<1)?"vertical line stride enable, ":"", 372 dword&(1<<0)?"vertical ofs enable, ":""); 373 374 dword = data[i]; 375 width = ((dword >> 10) & ((1 << 11) - 1))+1; 376 height = ((dword >> 21) & ((1 << 11) - 1))+1; 377 378 tiling = "none"; 379 if (dword & (1 << 2)) 380 tiling = "fenced"; 381 else if (dword & (1 << 1)) 382 tiling = dword & (1 << 0) ? "Y" : "X"; 383 type = " BAD"; 384 format = "BAD"; 385 switch ((dword>>7) & 0x7) { 386 case 1: 387 type = "8b"; 388 switch ((dword>>3) & 0xf) { 389 case 0: format = "I"; break; 390 case 1: format = "L"; break; 391 case 2: format = "A"; break; 392 case 3: format = " mono"; break; } 393 break; 394 case 2: 395 type = "16b"; 396 switch ((dword>>3) & 0xf) { 397 case 0: format = " rgb565"; break; 398 case 1: format = " argb1555"; break; 399 case 2: format = " argb4444"; break; 400 case 5: format = " ay88"; break; 401 case 6: format = " bump655"; break; 402 case 7: format = "I"; break; 403 case 8: format = "L"; break; 404 case 9: format = "A"; break; } 405 break; 406 case 3: 407 type = "32b"; 408 switch ((dword>>3) & 0xf) { 409 case 0: format = " argb8888"; break; 410 case 1: format = " abgr8888"; break; 411 case 2: format = " xrgb8888"; break; 412 case 3: format = " xbgr8888"; break; 413 case 4: format = " qwvu8888"; break; 414 case 5: format = " axvu8888"; break; 415 case 6: format = " lxvu8888"; break; 416 case 7: format = " xlvu8888"; break; 417 case 8: format = " argb2101010"; break; 418 case 9: format = " abgr2101010"; break; 419 case 10: format = " awvu2101010"; break; 420 case 11: format = " gr1616"; break; 421 case 12: format = " vu1616"; break; 422 case 13: format = " xI824"; break; 423 case 14: format = " xA824"; break; 424 case 15: format = " xL824"; break; } 425 break; 426 case 5: 427 type = "422"; 428 switch ((dword>>3) & 0xf) { 429 case 0: format = " yuv_swapy"; break; 430 case 1: format = " yuv"; break; 431 case 2: format = " yuv_swapuv"; break; 432 case 3: format = " yuv_swapuvy"; break; } 433 break; 434 case 6: 435 type = "compressed"; 436 switch ((dword>>3) & 0x7) { 437 case 0: format = " dxt1"; break; 438 case 1: format = " dxt2_3"; break; 439 case 2: format = " dxt4_5"; break; 440 case 3: format = " fxt1"; break; 441 case 4: format = " dxt1_rb"; break; } 442 break; 443 case 7: 444 type = "4b indexed"; 445 switch ((dword>>3) & 0xf) { 446 case 7: format = " argb8888"; break; } 447 break; 448 } 449 dword = data[i]; 450 kgem_debug_print(data, offset, i++, "map %d MS3 [width=%d, height=%d, format=%s%s, tiling=%s%s]\n", 451 map, width, height, type, format, tiling, 452 dword&(1<<9)?" palette select":""); 453 454 dword = data[i]; 455 pitch = 4*(((dword >> 21) & ((1 << 11) - 1))+1); 456 kgem_debug_print(data, offset, i++, "map %d MS4 [pitch=%d, max_lod=%i, vol_depth=%i, cube_face_ena=%x, %s]\n", 457 map, pitch, 458 (dword>>9)&0x3f, dword&0xff, (dword>>15)&0x3f, 459 dword&(1<<8)?"miplayout legacy":"miplayout right"); 460 } 461 } 462 assert (len == i); 463 return len; 464 case 0x85: 465 len = (data[0] & 0x0000000f) + 2; 466 assert (len == 2); 467 kgem_debug_print(data, offset, 0, 468 "3DSTATE_DEST_BUFFER_VARIABLES\n"); 469 470 switch ((data[1] >> 8) & 0xf) { 471 case 0x0: format = "g8"; break; 472 case 0x1: format = "x1r5g5b5"; break; 473 case 0x2: format = "r5g6b5"; break; 474 case 0x3: format = "a8r8g8b8"; break; 475 case 0x4: format = "ycrcb_swapy"; break; 476 case 0x5: format = "ycrcb_normal"; break; 477 case 0x6: format = "ycrcb_swapuv"; break; 478 case 0x7: format = "ycrcb_swapuvy"; break; 479 case 0x8: format = "a4r4g4b4"; break; 480 case 0x9: format = "a1r5g5b5"; break; 481 case 0xa: format = "a2r10g10b10"; break; 482 default: format = "BAD"; break; 483 } 484 switch ((data[1] >> 2) & 0x3) { 485 case 0x0: zformat = "u16"; break; 486 case 0x1: zformat = "f16"; break; 487 case 0x2: zformat = "u24x8"; break; 488 default: zformat = "BAD"; break; 489 } 490 kgem_debug_print(data, offset, 1, "%s format, %s depth format, early Z %sabled\n", 491 format, zformat, 492 (data[1] & (1 << 31)) ? "en" : "dis"); 493 return len; 494 495 case 0x8e: 496 { 497 const char *name, *tiling; 498 499 len = (data[0] & 0x0000000f) + 2; 500 assert (len == 3); 501 502 switch((data[1] >> 24) & 0x7) { 503 case 0x3: name = "color"; break; 504 case 0x7: name = "depth"; break; 505 default: name = "unknown"; break; 506 } 507 508 tiling = "none"; 509 if (data[1] & (1 << 23)) 510 tiling = "fenced"; 511 else if (data[1] & (1 << 22)) 512 tiling = data[1] & (1 << 21) ? "Y" : "X"; 513 514 kgem_debug_print(data, offset, 0, "3DSTATE_BUFFER_INFO\n"); 515 kgem_debug_print(data, offset, 1, "%s, tiling = %s, pitch=%d\n", name, tiling, data[1]&0xffff); 516 517 kgem_debug_print(data, offset, 2, "address\n"); 518 return len; 519 } 520 521 case 0x81: 522 len = (data[0] & 0x0000000f) + 2; 523 assert (len == 3); 524 525 kgem_debug_print(data, offset, 0, 526 "3DSTATE_SCISSOR_RECTANGLE\n"); 527 kgem_debug_print(data, offset, 1, "(%d,%d)\n", 528 data[1] & 0xffff, data[1] >> 16); 529 kgem_debug_print(data, offset, 2, "(%d,%d)\n", 530 data[2] & 0xffff, data[2] >> 16); 531 return len; 532 533 case 0x80: 534 len = (data[0] & 0x0000000f) + 2; 535 assert (len == 5); 536 537 kgem_debug_print(data, offset, 0, 538 "3DSTATE_DRAWING_RECTANGLE\n"); 539 kgem_debug_print(data, offset, 1, "%s\n", 540 data[1]&(1<<30)?"depth ofs disabled ":""); 541 kgem_debug_print(data, offset, 2, "(%d,%d)\n", 542 data[2] & 0xffff, data[2] >> 16); 543 kgem_debug_print(data, offset, 3, "(%d,%d)\n", 544 data[3] & 0xffff, data[3] >> 16); 545 kgem_debug_print(data, offset, 4, "(%d,%d)\n", 546 data[4] & 0xffff, data[4] >> 16); 547 return len; 548 549 case 0x9c: 550 len = (data[0] & 0x0000000f) + 2; 551 assert (len == 7); 552 553 kgem_debug_print(data, offset, 0, 554 "3DSTATE_CLEAR_PARAMETERS\n"); 555 kgem_debug_print(data, offset, 1, "prim_type=%s, clear=%s%s%s\n", 556 data[1]&(1<<16)?"CLEAR_RECT":"ZONE_INIT", 557 data[1]&(1<<2)?"color,":"", 558 data[1]&(1<<1)?"depth,":"", 559 data[1]&(1<<0)?"stencil,":""); 560 kgem_debug_print(data, offset, 2, "clear color\n"); 561 kgem_debug_print(data, offset, 3, "clear depth/stencil\n"); 562 kgem_debug_print(data, offset, 4, "color value (rgba8888)\n"); 563 kgem_debug_print(data, offset, 5, "depth value %f\n", 564 int_as_float(data[5])); 565 kgem_debug_print(data, offset, 6, "clear stencil\n"); 566 return len; 567 } 568 569 for (idx = 0; idx < ARRAY_SIZE(opcodes_3d_1d); idx++) { 570 opcode_3d_1d = &opcodes_3d_1d[idx]; 571 if (((data[0] & 0x00ff0000) >> 16) == opcode_3d_1d->opcode) { 572 len = 1; 573 574 kgem_debug_print(data, offset, 0, "%s\n", opcode_3d_1d->name); 575 if (opcode_3d_1d->max_len > 1) { 576 len = (data[0] & 0x0000ffff) + 2; 577 assert (len >= opcode_3d_1d->min_len && 578 len <= opcode_3d_1d->max_len); 579 } 580 581 for (i = 1; i < len; i++) 582 kgem_debug_print(data, offset, i, "dword %d\n", i); 583 584 return len; 585 } 586 } 587 588 kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d_1d opcode = 0x%x\n", opcode); 589 return 1; 590} 591 592static int 593decode_3d_1c(struct kgem *kgem, uint32_t offset) 594{ 595 uint32_t *data = kgem->batch + offset; 596 uint32_t opcode; 597 598 opcode = (data[0] & 0x00f80000) >> 19; 599 600 switch (opcode) { 601 case 0x11: 602 kgem_debug_print(data, offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE\n"); 603 return 1; 604 case 0x10: 605 kgem_debug_print(data, offset, 0, "3DSTATE_SCISSOR_ENABLE %s\n", 606 data[0]&1?"enabled":"disabled"); 607 return 1; 608 case 0x01: 609 kgem_debug_print(data, offset, 0, "3DSTATE_MAP_COORD_SET_I830\n"); 610 return 1; 611 case 0x0a: 612 kgem_debug_print(data, offset, 0, "3DSTATE_MAP_CUBE_I830\n"); 613 return 1; 614 case 0x05: 615 kgem_debug_print(data, offset, 0, "3DSTATE_MAP_TEX_STREAM_I830\n"); 616 return 1; 617 } 618 619 kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d_1c opcode = 0x%x\n", 620 opcode); 621 return 1; 622} 623 624int kgem_gen2_decode_3d(struct kgem *kgem, uint32_t offset) 625{ 626 const static struct { 627 uint32_t opcode; 628 int min_len; 629 int max_len; 630 const char *name; 631 } opcodes[] = { 632 { 0x02, 1, 1, "3DSTATE_MODES_3" }, 633 { 0x03, 1, 1, "3DSTATE_ENABLES_1"}, 634 { 0x04, 1, 1, "3DSTATE_ENABLES_2"}, 635 { 0x05, 1, 1, "3DSTATE_VFT0"}, 636 { 0x06, 1, 1, "3DSTATE_AA"}, 637 { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, 638 { 0x08, 1, 1, "3DSTATE_MODES_1" }, 639 { 0x09, 1, 1, "3DSTATE_STENCIL_TEST" }, 640 { 0x0a, 1, 1, "3DSTATE_VFT1"}, 641 { 0x0b, 1, 1, "3DSTATE_INDPT_ALPHA_BLEND" }, 642 { 0x0c, 1, 1, "3DSTATE_MODES_5" }, 643 { 0x0d, 1, 1, "3DSTATE_MAP_BLEND_OP" }, 644 { 0x0e, 1, 1, "3DSTATE_MAP_BLEND_ARG" }, 645 { 0x0f, 1, 1, "3DSTATE_MODES_2" }, 646 { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, 647 { 0x16, 1, 1, "3DSTATE_MODES_4" }, 648 }; 649 uint32_t *data = kgem->batch + offset; 650 uint32_t opcode = (data[0] & 0x1f000000) >> 24; 651 uint32_t idx; 652 653 switch (opcode) { 654 case 0x1f: 655 return decode_3d_primitive(kgem, offset); 656 case 0x1d: 657 return decode_3d_1d(kgem, offset); 658 case 0x1c: 659 return decode_3d_1c(kgem, offset); 660 } 661 662 /* Catch the known instructions */ 663 for (idx = 0; idx < ARRAY_SIZE(opcodes); idx++) { 664 if (opcode == opcodes[idx].opcode) { 665 unsigned int len = 1, i; 666 667 kgem_debug_print(data, offset, 0, "%s\n", opcodes[idx].name); 668 if (opcodes[idx].max_len > 1) { 669 len = (data[0] & 0xf) + 2; 670 assert(len >= opcodes[idx].min_len && 671 len <= opcodes[idx].max_len); 672 } 673 674 for (i = 1; i < len; i++) 675 kgem_debug_print(data, offset, i, "dword %d\n", i); 676 return len; 677 } 678 } 679 680 kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d opcode = 0x%x\n", opcode); 681 return 1; 682} 683 684void kgem_gen2_finish_state(struct kgem *kgem) 685{ 686 memset(&state, 0, sizeof(state)); 687} 688