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