Home | History | Annotate | Download | only in i915
      1 /**************************************************************************
      2  *
      3  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 #include "main/imports.h"
     29 
     30 #include "i915_reg.h"
     31 #include "i915_context.h"
     32 #include "i915_debug.h"
     33 
     34 static bool
     35 debug(struct debug_stream *stream, const char *name, GLuint len)
     36 {
     37    GLuint i;
     38    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
     39 
     40    if (len == 0) {
     41       printf("Error - zero length packet (0x%08x)\n", stream->ptr[0]);
     42       assert(0);
     43       return false;
     44    }
     45 
     46    if (stream->print_addresses)
     47       printf("%08x:  ", stream->offset);
     48 
     49 
     50    printf("%s (%d dwords):\n", name, len);
     51    for (i = 0; i < len; i++)
     52       printf("\t0x%08x\n",  ptr[i]);
     53    printf("\n");
     54 
     55    stream->offset += len * sizeof(GLuint);
     56 
     57    return true;
     58 }
     59 
     60 
     61 static const char *get_prim_name( GLuint val )
     62 {
     63    switch (val & PRIM3D_MASK) {
     64    case PRIM3D_TRILIST: return "TRILIST"; break;
     65    case PRIM3D_TRISTRIP: return "TRISTRIP"; break;
     66    case PRIM3D_TRISTRIP_RVRSE: return "TRISTRIP_RVRSE"; break;
     67    case PRIM3D_TRIFAN: return "TRIFAN"; break;
     68    case PRIM3D_POLY: return "POLY"; break;
     69    case PRIM3D_LINELIST: return "LINELIST"; break;
     70    case PRIM3D_LINESTRIP: return "LINESTRIP"; break;
     71    case PRIM3D_RECTLIST: return "RECTLIST"; break;
     72    case PRIM3D_POINTLIST: return "POINTLIST"; break;
     73    case PRIM3D_DIB: return "DIB"; break;
     74    case PRIM3D_CLEAR_RECT: return "CLEAR_RECT"; break;
     75    case PRIM3D_ZONE_INIT: return "ZONE_INIT"; break;
     76    default: return "????"; break;
     77    }
     78 }
     79 
     80 static bool
     81 debug_prim(struct debug_stream *stream, const char *name,
     82 	   bool dump_floats, GLuint len)
     83 {
     84    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
     85    const char *prim = get_prim_name( ptr[0] );
     86    GLuint i;
     87 
     88 
     89 
     90    printf("%s %s (%d dwords):\n", name, prim, len);
     91    printf("\t0x%08x\n",  ptr[0]);
     92    for (i = 1; i < len; i++) {
     93       if (dump_floats)
     94 	 printf("\t0x%08x // %f\n",  ptr[i], *(GLfloat *)&ptr[i]);
     95       else
     96 	 printf("\t0x%08x\n",  ptr[i]);
     97    }
     98 
     99 
    100    printf("\n");
    101 
    102    stream->offset += len * sizeof(GLuint);
    103 
    104    return true;
    105 }
    106 
    107 
    108 
    109 
    110 static bool
    111 debug_program(struct debug_stream *stream, const char *name, GLuint len)
    112 {
    113    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
    114 
    115    if (len == 0) {
    116       printf("Error - zero length packet (0x%08x)\n", stream->ptr[0]);
    117       assert(0);
    118       return false;
    119    }
    120 
    121    if (stream->print_addresses)
    122       printf("%08x:  ", stream->offset);
    123 
    124    printf("%s (%d dwords):\n", name, len);
    125    i915_disassemble_program( ptr, len );
    126 
    127    stream->offset += len * sizeof(GLuint);
    128    return true;
    129 }
    130 
    131 
    132 static bool
    133 debug_chain(struct debug_stream *stream, const char *name, GLuint len)
    134 {
    135    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
    136    GLuint old_offset = stream->offset + len * sizeof(GLuint);
    137    GLuint i;
    138 
    139    printf("%s (%d dwords):\n", name, len);
    140    for (i = 0; i < len; i++)
    141       printf("\t0x%08x\n",  ptr[i]);
    142 
    143    stream->offset = ptr[1] & ~0x3;
    144 
    145    if (stream->offset < old_offset)
    146       printf("\n... skipping backwards from 0x%x --> 0x%x ...\n\n",
    147 		   old_offset, stream->offset );
    148    else
    149       printf("\n... skipping from 0x%x --> 0x%x ...\n\n",
    150 		   old_offset, stream->offset );
    151 
    152 
    153    return true;
    154 }
    155 
    156 
    157 static bool
    158 debug_variable_length_prim(struct debug_stream *stream)
    159 {
    160    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
    161    const char *prim = get_prim_name( ptr[0] );
    162    GLuint i, len;
    163 
    164    GLushort *idx = (GLushort *)(ptr+1);
    165    for (i = 0; idx[i] != 0xffff; i++)
    166       ;
    167 
    168    len = 1+(i+2)/2;
    169 
    170    printf("3DPRIM, %s variable length %d indicies (%d dwords):\n", prim, i, len);
    171    for (i = 0; i < len; i++)
    172       printf("\t0x%08x\n",  ptr[i]);
    173    printf("\n");
    174 
    175    stream->offset += len * sizeof(GLuint);
    176    return true;
    177 }
    178 
    179 
    180 #define BITS( dw, hi, lo, ... )				\
    181 do {							\
    182    unsigned himask = 0xffffffffU >> (31 - (hi));		\
    183    printf("\t\t ");				\
    184    printf(__VA_ARGS__);			\
    185    printf(": 0x%x\n", ((dw) & himask) >> (lo));	\
    186 } while (0)
    187 
    188 #define MBZ( dw, hi, lo) do {							\
    189    unsigned x = (dw) >> (lo);				\
    190    unsigned lomask = (1 << (lo)) - 1;			\
    191    unsigned himask;					\
    192    himask = (1UL << (hi)) - 1;				\
    193    assert ((x & himask & ~lomask) == 0);	\
    194 } while (0)
    195 
    196 #define FLAG( dw, bit, ... )			\
    197 do {							\
    198    if (((dw) >> (bit)) & 1) {				\
    199       printf("\t\t ");				\
    200       printf(__VA_ARGS__);			\
    201       printf("\n");				\
    202    }							\
    203 } while (0)
    204 
    205 static bool
    206 debug_load_immediate(struct debug_stream *stream, const char *name, GLuint len)
    207 {
    208    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
    209    GLuint bits = (ptr[0] >> 4) & 0xff;
    210    GLuint j = 0;
    211 
    212    printf("%s (%d dwords, flags: %x):\n", name, len, bits);
    213    printf("\t0x%08x\n",  ptr[j++]);
    214 
    215    if (bits & (1<<0)) {
    216       printf("\t  LIS0: 0x%08x\n", ptr[j]);
    217       printf("\t vb address: 0x%08x\n", (ptr[j] & ~0x3));
    218       BITS(ptr[j], 0, 0, "vb invalidate disable");
    219       j++;
    220    }
    221    if (bits & (1<<1)) {
    222       printf("\t  LIS1: 0x%08x\n", ptr[j]);
    223       BITS(ptr[j], 29, 24, "vb dword width");
    224       BITS(ptr[j], 21, 16, "vb dword pitch");
    225       BITS(ptr[j], 15, 0, "vb max index");
    226       j++;
    227    }
    228    if (bits & (1<<2)) {
    229       int i;
    230       printf("\t  LIS2: 0x%08x\n", ptr[j]);
    231       for (i = 0; i < 8; i++) {
    232 	 unsigned tc = (ptr[j] >> (i * 4)) & 0xf;
    233 	 if (tc != 0xf)
    234 	    BITS(tc, 3, 0, "tex coord %d", i);
    235       }
    236       j++;
    237    }
    238    if (bits & (1<<3)) {
    239       printf("\t  LIS3: 0x%08x\n", ptr[j]);
    240       j++;
    241    }
    242    if (bits & (1<<4)) {
    243       printf("\t  LIS4: 0x%08x\n", ptr[j]);
    244       BITS(ptr[j], 31, 23, "point width");
    245       BITS(ptr[j], 22, 19, "line width");
    246       FLAG(ptr[j], 18, "alpha flatshade");
    247       FLAG(ptr[j], 17, "fog flatshade");
    248       FLAG(ptr[j], 16, "spec flatshade");
    249       FLAG(ptr[j], 15, "rgb flatshade");
    250       BITS(ptr[j], 14, 13, "cull mode");
    251       FLAG(ptr[j], 12, "vfmt: point width");
    252       FLAG(ptr[j], 11, "vfmt: specular/fog");
    253       FLAG(ptr[j], 10, "vfmt: rgba");
    254       FLAG(ptr[j], 9, "vfmt: depth offset");
    255       BITS(ptr[j], 8, 6, "vfmt: position (2==xyzw)");
    256       FLAG(ptr[j], 5, "force dflt diffuse");
    257       FLAG(ptr[j], 4, "force dflt specular");
    258       FLAG(ptr[j], 3, "local depth offset enable");
    259       FLAG(ptr[j], 2, "vfmt: fp32 fog coord");
    260       FLAG(ptr[j], 1, "sprite point");
    261       FLAG(ptr[j], 0, "antialiasing");
    262       j++;
    263    }
    264    if (bits & (1<<5)) {
    265       printf("\t  LIS5: 0x%08x\n", ptr[j]);
    266       BITS(ptr[j], 31, 28, "rgba write disables");
    267       FLAG(ptr[j], 27,     "force dflt point width");
    268       FLAG(ptr[j], 26,     "last pixel enable");
    269       FLAG(ptr[j], 25,     "global z offset enable");
    270       FLAG(ptr[j], 24,     "fog enable");
    271       BITS(ptr[j], 23, 16, "stencil ref");
    272       BITS(ptr[j], 15, 13, "stencil test");
    273       BITS(ptr[j], 12, 10, "stencil fail op");
    274       BITS(ptr[j], 9, 7,   "stencil pass z fail op");
    275       BITS(ptr[j], 6, 4,   "stencil pass z pass op");
    276       FLAG(ptr[j], 3,      "stencil write enable");
    277       FLAG(ptr[j], 2,      "stencil test enable");
    278       FLAG(ptr[j], 1,      "color dither enable");
    279       FLAG(ptr[j], 0,      "logiop enable");
    280       j++;
    281    }
    282    if (bits & (1<<6)) {
    283       printf("\t  LIS6: 0x%08x\n", ptr[j]);
    284       FLAG(ptr[j], 31,      "alpha test enable");
    285       BITS(ptr[j], 30, 28,  "alpha func");
    286       BITS(ptr[j], 27, 20,  "alpha ref");
    287       FLAG(ptr[j], 19,      "depth test enable");
    288       BITS(ptr[j], 18, 16,  "depth func");
    289       FLAG(ptr[j], 15,      "blend enable");
    290       BITS(ptr[j], 14, 12,  "blend func");
    291       BITS(ptr[j], 11, 8,   "blend src factor");
    292       BITS(ptr[j], 7,  4,   "blend dst factor");
    293       FLAG(ptr[j], 3,       "depth write enable");
    294       FLAG(ptr[j], 2,       "color write enable");
    295       BITS(ptr[j], 1,  0,   "provoking vertex");
    296       j++;
    297    }
    298 
    299 
    300    printf("\n");
    301 
    302    assert(j == len);
    303 
    304    stream->offset += len * sizeof(GLuint);
    305 
    306    return true;
    307 }
    308 
    309 
    310 
    311 static bool
    312 debug_load_indirect(struct debug_stream *stream, const char *name, GLuint len)
    313 {
    314    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
    315    GLuint bits = (ptr[0] >> 8) & 0x3f;
    316    GLuint i, j = 0;
    317 
    318    printf("%s (%d dwords):\n", name, len);
    319    printf("\t0x%08x\n",  ptr[j++]);
    320 
    321    for (i = 0; i < 6; i++) {
    322       if (bits & (1<<i)) {
    323 	 switch (1<<(8+i)) {
    324 	 case LI0_STATE_STATIC_INDIRECT:
    325 	    printf("        STATIC: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++;
    326 	    printf("                0x%08x\n", ptr[j++]);
    327 	    break;
    328 	 case LI0_STATE_DYNAMIC_INDIRECT:
    329 	    printf("       DYNAMIC: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++;
    330 	    break;
    331 	 case LI0_STATE_SAMPLER:
    332 	    printf("       SAMPLER: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++;
    333 	    printf("                0x%08x\n", ptr[j++]);
    334 	    break;
    335 	 case LI0_STATE_MAP:
    336 	    printf("           MAP: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++;
    337 	    printf("                0x%08x\n", ptr[j++]);
    338 	    break;
    339 	 case LI0_STATE_PROGRAM:
    340 	    printf("       PROGRAM: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++;
    341 	    printf("                0x%08x\n", ptr[j++]);
    342 	    break;
    343 	 case LI0_STATE_CONSTANTS:
    344 	    printf("     CONSTANTS: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++;
    345 	    printf("                0x%08x\n", ptr[j++]);
    346 	    break;
    347 	 default:
    348 	    assert(0);
    349 	    break;
    350 	 }
    351       }
    352    }
    353 
    354    if (bits == 0) {
    355       printf("\t  DUMMY: 0x%08x\n", ptr[j++]);
    356    }
    357 
    358    printf("\n");
    359 
    360 
    361    assert(j == len);
    362 
    363    stream->offset += len * sizeof(GLuint);
    364 
    365    return true;
    366 }
    367 
    368 static void BR13( struct debug_stream *stream,
    369 		  GLuint val )
    370 {
    371    printf("\t0x%08x\n",  val);
    372    FLAG(val, 30, "clipping enable");
    373    BITS(val, 25, 24, "color depth (3==32bpp)");
    374    BITS(val, 23, 16, "raster op");
    375    BITS(val, 15, 0,  "dest pitch");
    376 }
    377 
    378 
    379 static void BR2223( struct debug_stream *stream,
    380 		    GLuint val22, GLuint val23 )
    381 {
    382    union { GLuint val; short field[2]; } BR22, BR23;
    383 
    384    BR22.val = val22;
    385    BR23.val = val23;
    386 
    387    printf("\t0x%08x\n",  val22);
    388    BITS(val22, 31, 16, "dest y1");
    389    BITS(val22, 15, 0,  "dest x1");
    390 
    391    printf("\t0x%08x\n",  val23);
    392    BITS(val23, 31, 16, "dest y2");
    393    BITS(val23, 15, 0,  "dest x2");
    394 
    395    /* The blit engine may produce unexpected results when these aren't met */
    396    assert(BR22.field[0] < BR23.field[0]);
    397    assert(BR22.field[1] < BR23.field[1]);
    398 }
    399 
    400 static void BR09( struct debug_stream *stream,
    401 		  GLuint val )
    402 {
    403    printf("\t0x%08x -- dest address\n",  val);
    404 }
    405 
    406 static void BR26( struct debug_stream *stream,
    407 		  GLuint val )
    408 {
    409    printf("\t0x%08x\n",  val);
    410    BITS(val, 31, 16, "src y1");
    411    BITS(val, 15, 0,  "src x1");
    412 }
    413 
    414 static void BR11( struct debug_stream *stream,
    415 		  GLuint val )
    416 {
    417    printf("\t0x%08x\n",  val);
    418    BITS(val, 15, 0,  "src pitch");
    419 }
    420 
    421 static void BR12( struct debug_stream *stream,
    422 		  GLuint val )
    423 {
    424    printf("\t0x%08x -- src address\n",  val);
    425 }
    426 
    427 static void BR16( struct debug_stream *stream,
    428 		  GLuint val )
    429 {
    430    printf("\t0x%08x -- color\n",  val);
    431 }
    432 
    433 static bool
    434 debug_copy_blit(struct debug_stream *stream, const char *name, GLuint len)
    435 {
    436    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
    437    int j = 0;
    438 
    439    printf("%s (%d dwords):\n", name, len);
    440    printf("\t0x%08x\n",  ptr[j++]);
    441 
    442    BR13(stream, ptr[j++]);
    443    BR2223(stream, ptr[j], ptr[j+1]);
    444    j += 2;
    445    BR09(stream, ptr[j++]);
    446    BR26(stream, ptr[j++]);
    447    BR11(stream, ptr[j++]);
    448    BR12(stream, ptr[j++]);
    449 
    450    stream->offset += len * sizeof(GLuint);
    451    assert(j == len);
    452    return true;
    453 }
    454 
    455 static bool
    456 debug_color_blit(struct debug_stream *stream, const char *name, GLuint len)
    457 {
    458    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
    459    int j = 0;
    460 
    461    printf("%s (%d dwords):\n", name, len);
    462    printf("\t0x%08x\n",  ptr[j++]);
    463 
    464    BR13(stream, ptr[j++]);
    465    BR2223(stream, ptr[j], ptr[j+1]);
    466    j += 2;
    467    BR09(stream, ptr[j++]);
    468    BR16(stream, ptr[j++]);
    469 
    470    stream->offset += len * sizeof(GLuint);
    471    assert(j == len);
    472    return true;
    473 }
    474 
    475 static bool
    476 debug_modes4(struct debug_stream *stream, const char *name, GLuint len)
    477 {
    478    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
    479    int j = 0;
    480 
    481    printf("%s (%d dwords):\n", name, len);
    482    printf("\t0x%08x\n",  ptr[j]);
    483    BITS(ptr[j], 21, 18, "logicop func");
    484    FLAG(ptr[j], 17, "stencil test mask modify-enable");
    485    FLAG(ptr[j], 16, "stencil write mask modify-enable");
    486    BITS(ptr[j], 15, 8, "stencil test mask");
    487    BITS(ptr[j], 7, 0,  "stencil write mask");
    488    j++;
    489 
    490    stream->offset += len * sizeof(GLuint);
    491    assert(j == len);
    492    return true;
    493 }
    494 
    495 static bool
    496 debug_map_state(struct debug_stream *stream, const char *name, GLuint len)
    497 {
    498    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
    499    int j = 0;
    500 
    501    printf("%s (%d dwords):\n", name, len);
    502    printf("\t0x%08x\n",  ptr[j++]);
    503 
    504    {
    505       printf("\t0x%08x\n",  ptr[j]);
    506       BITS(ptr[j], 15, 0,   "map mask");
    507       j++;
    508    }
    509 
    510    while (j < len) {
    511       {
    512 	 printf("\t  TMn.0: 0x%08x\n", ptr[j]);
    513 	 printf("\t map address: 0x%08x\n", (ptr[j] & ~0x3));
    514 	 FLAG(ptr[j], 1, "vertical line stride");
    515 	 FLAG(ptr[j], 0, "vertical line stride offset");
    516 	 j++;
    517       }
    518 
    519       {
    520 	 printf("\t  TMn.1: 0x%08x\n", ptr[j]);
    521 	 BITS(ptr[j], 31, 21, "height");
    522 	 BITS(ptr[j], 20, 10, "width");
    523 	 BITS(ptr[j], 9, 7, "surface format");
    524 	 BITS(ptr[j], 6, 3, "texel format");
    525 	 FLAG(ptr[j], 2, "use fence regs");
    526 	 FLAG(ptr[j], 1, "tiled surface");
    527 	 FLAG(ptr[j], 0, "tile walk ymajor");
    528 	 j++;
    529       }
    530       {
    531 	 printf("\t  TMn.2: 0x%08x\n", ptr[j]);
    532 	 BITS(ptr[j], 31, 21, "dword pitch");
    533 	 BITS(ptr[j], 20, 15, "cube face enables");
    534 	 BITS(ptr[j], 14, 9, "max lod");
    535 	 FLAG(ptr[j], 8,     "mip layout right");
    536 	 BITS(ptr[j], 7, 0, "depth");
    537 	 j++;
    538       }
    539    }
    540 
    541    stream->offset += len * sizeof(GLuint);
    542    assert(j == len);
    543    return true;
    544 }
    545 
    546 static bool
    547 debug_sampler_state(struct debug_stream *stream, const char *name, GLuint len)
    548 {
    549    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
    550    int j = 0;
    551 
    552    printf("%s (%d dwords):\n", name, len);
    553    printf("\t0x%08x\n",  ptr[j++]);
    554 
    555    {
    556       printf("\t0x%08x\n",  ptr[j]);
    557       BITS(ptr[j], 15, 0,   "sampler mask");
    558       j++;
    559    }
    560 
    561    while (j < len) {
    562       {
    563 	 printf("\t  TSn.0: 0x%08x\n", ptr[j]);
    564 	 FLAG(ptr[j], 31, "reverse gamma");
    565 	 FLAG(ptr[j], 30, "planar to packed");
    566 	 FLAG(ptr[j], 29, "yuv->rgb");
    567 	 BITS(ptr[j], 28, 27, "chromakey index");
    568 	 BITS(ptr[j], 26, 22, "base mip level");
    569 	 BITS(ptr[j], 21, 20, "mip mode filter");
    570 	 BITS(ptr[j], 19, 17, "mag mode filter");
    571 	 BITS(ptr[j], 16, 14, "min mode filter");
    572 	 BITS(ptr[j], 13, 5,  "lod bias (s4.4)");
    573 	 FLAG(ptr[j], 4,      "shadow enable");
    574 	 FLAG(ptr[j], 3,      "max-aniso-4");
    575 	 BITS(ptr[j], 2, 0,   "shadow func");
    576 	 j++;
    577       }
    578 
    579       {
    580 	 printf("\t  TSn.1: 0x%08x\n", ptr[j]);
    581 	 BITS(ptr[j], 31, 24, "min lod");
    582 	 MBZ( ptr[j], 23, 18 );
    583 	 FLAG(ptr[j], 17,     "kill pixel enable");
    584 	 FLAG(ptr[j], 16,     "keyed tex filter mode");
    585 	 FLAG(ptr[j], 15,     "chromakey enable");
    586 	 BITS(ptr[j], 14, 12, "tcx wrap mode");
    587 	 BITS(ptr[j], 11, 9,  "tcy wrap mode");
    588 	 BITS(ptr[j], 8,  6,  "tcz wrap mode");
    589 	 FLAG(ptr[j], 5,      "normalized coords");
    590 	 BITS(ptr[j], 4,  1,  "map (surface) index");
    591 	 FLAG(ptr[j], 0,      "EAST deinterlacer enable");
    592 	 j++;
    593       }
    594       {
    595 	 printf("\t  TSn.2: 0x%08x  (default color)\n", ptr[j]);
    596 	 j++;
    597       }
    598    }
    599 
    600    stream->offset += len * sizeof(GLuint);
    601    assert(j == len);
    602    return true;
    603 }
    604 
    605 static bool
    606 debug_dest_vars(struct debug_stream *stream, const char *name, GLuint len)
    607 {
    608    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
    609    int j = 0;
    610 
    611    printf("%s (%d dwords):\n", name, len);
    612    printf("\t0x%08x\n",  ptr[j++]);
    613 
    614    {
    615       printf("\t0x%08x\n",  ptr[j]);
    616       FLAG(ptr[j], 31,     "early classic ztest");
    617       FLAG(ptr[j], 30,     "opengl tex default color");
    618       FLAG(ptr[j], 29,     "bypass iz");
    619       FLAG(ptr[j], 28,     "lod preclamp");
    620       BITS(ptr[j], 27, 26, "dither pattern");
    621       FLAG(ptr[j], 25,     "linear gamma blend");
    622       FLAG(ptr[j], 24,     "debug dither");
    623       BITS(ptr[j], 23, 20, "dstorg x");
    624       BITS(ptr[j], 19, 16, "dstorg y");
    625       MBZ (ptr[j], 15, 15 );
    626       BITS(ptr[j], 14, 12, "422 write select");
    627       BITS(ptr[j], 11, 8,  "cbuf format");
    628       BITS(ptr[j], 3, 2,   "zbuf format");
    629       FLAG(ptr[j], 1,      "vert line stride");
    630       FLAG(ptr[j], 1,      "vert line stride offset");
    631       j++;
    632    }
    633 
    634    stream->offset += len * sizeof(GLuint);
    635    assert(j == len);
    636    return true;
    637 }
    638 
    639 static bool
    640 debug_buf_info(struct debug_stream *stream, const char *name, GLuint len)
    641 {
    642    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
    643    int j = 0;
    644 
    645    printf("%s (%d dwords):\n", name, len);
    646    printf("\t0x%08x\n",  ptr[j++]);
    647 
    648    {
    649       printf("\t0x%08x\n",  ptr[j]);
    650       BITS(ptr[j], 28, 28, "aux buffer id");
    651       BITS(ptr[j], 27, 24, "buffer id (7=depth, 3=back)");
    652       FLAG(ptr[j], 23,     "use fence regs");
    653       FLAG(ptr[j], 22,     "tiled surface");
    654       FLAG(ptr[j], 21,     "tile walk ymajor");
    655       MBZ (ptr[j], 20, 14);
    656       BITS(ptr[j], 13, 2,  "dword pitch");
    657       MBZ (ptr[j], 2,  0);
    658       j++;
    659    }
    660 
    661    printf("\t0x%08x -- buffer base address\n",  ptr[j++]);
    662 
    663    stream->offset += len * sizeof(GLuint);
    664    assert(j == len);
    665    return true;
    666 }
    667 
    668 static bool
    669 i915_debug_packet(struct debug_stream *stream)
    670 {
    671    GLuint *ptr = (GLuint *)(stream->ptr + stream->offset);
    672    GLuint cmd = *ptr;
    673 
    674    switch (((cmd >> 29) & 0x7)) {
    675    case 0x0:
    676       switch ((cmd >> 23) & 0x3f) {
    677       case 0x0:
    678 	 return debug(stream, "MI_NOOP", 1);
    679       case 0x3:
    680 	 return debug(stream, "MI_WAIT_FOR_EVENT", 1);
    681       case 0x4:
    682 	 return debug(stream, "MI_FLUSH", 1);
    683       case 0xA:
    684 	 debug(stream, "MI_BATCH_BUFFER_END", 1);
    685 	 return false;
    686       case 0x22:
    687 	 return debug(stream, "MI_LOAD_REGISTER_IMM", 3);
    688       case 0x31:
    689 	 return debug_chain(stream, "MI_BATCH_BUFFER_START", 2);
    690       default:
    691 	 break;
    692       }
    693       break;
    694    case 0x1:
    695       break;
    696    case 0x2:
    697       switch ((cmd >> 22) & 0xff) {
    698       case 0x50:
    699 	 return debug_color_blit(stream, "XY_COLOR_BLT", (cmd & 0xff) + 2);
    700       case 0x53:
    701 	 return debug_copy_blit(stream, "XY_SRC_COPY_BLT", (cmd & 0xff) + 2);
    702       default:
    703 	 return debug(stream, "blit command", (cmd & 0xff) + 2);
    704       }
    705       break;
    706    case 0x3:
    707       switch ((cmd >> 24) & 0x1f) {
    708       case 0x6:
    709 	 return debug(stream, "3DSTATE_ANTI_ALIASING", 1);
    710       case 0x7:
    711 	 return debug(stream, "3DSTATE_RASTERIZATION_RULES", 1);
    712       case 0x8:
    713 	 return debug(stream, "3DSTATE_BACKFACE_STENCIL_OPS", 2);
    714       case 0x9:
    715 	 return debug(stream, "3DSTATE_BACKFACE_STENCIL_MASKS", 1);
    716       case 0xb:
    717 	 return debug(stream, "3DSTATE_INDEPENDENT_ALPHA_BLEND", 1);
    718       case 0xc:
    719 	 return debug(stream, "3DSTATE_MODES5", 1);
    720       case 0xd:
    721 	 return debug_modes4(stream, "3DSTATE_MODES4", 1);
    722       case 0x15:
    723 	 return debug(stream, "3DSTATE_FOG_COLOR", 1);
    724       case 0x16:
    725 	 return debug(stream, "3DSTATE_COORD_SET_BINDINGS", 1);
    726       case 0x1c:
    727 	 /* 3DState16NP */
    728 	 switch((cmd >> 19) & 0x1f) {
    729 	 case 0x10:
    730 	    return debug(stream, "3DSTATE_SCISSOR_ENABLE", 1);
    731 	 case 0x11:
    732 	    return debug(stream, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE", 1);
    733 	 default:
    734 	    break;
    735 	 }
    736 	 break;
    737       case 0x1d:
    738 	 /* 3DStateMW */
    739 	 switch ((cmd >> 16) & 0xff) {
    740 	 case 0x0:
    741 	    return debug_map_state(stream, "3DSTATE_MAP_STATE", (cmd & 0x1f) + 2);
    742 	 case 0x1:
    743 	    return debug_sampler_state(stream, "3DSTATE_SAMPLER_STATE", (cmd & 0x1f) + 2);
    744 	 case 0x4:
    745 	    return debug_load_immediate(stream, "3DSTATE_LOAD_STATE_IMMEDIATE", (cmd & 0xf) + 2);
    746 	 case 0x5:
    747 	    return debug_program(stream, "3DSTATE_PIXEL_SHADER_PROGRAM", (cmd & 0x1ff) + 2);
    748 	 case 0x6:
    749 	    return debug(stream, "3DSTATE_PIXEL_SHADER_CONSTANTS", (cmd & 0xff) + 2);
    750 	 case 0x7:
    751 	    return debug_load_indirect(stream, "3DSTATE_LOAD_INDIRECT", (cmd & 0xff) + 2);
    752 	 case 0x80:
    753 	    return debug(stream, "3DSTATE_DRAWING_RECTANGLE", (cmd & 0xffff) + 2);
    754 	 case 0x81:
    755 	    return debug(stream, "3DSTATE_SCISSOR_RECTANGLE", (cmd & 0xffff) + 2);
    756 	 case 0x83:
    757 	    return debug(stream, "3DSTATE_SPAN_STIPPLE", (cmd & 0xffff) + 2);
    758 	 case 0x85:
    759 	    return debug_dest_vars(stream, "3DSTATE_DEST_BUFFER_VARS", (cmd & 0xffff) + 2);
    760 	 case 0x88:
    761 	    return debug(stream, "3DSTATE_CONSTANT_BLEND_COLOR", (cmd & 0xffff) + 2);
    762 	 case 0x89:
    763 	    return debug(stream, "3DSTATE_FOG_MODE", (cmd & 0xffff) + 2);
    764 	 case 0x8e:
    765 	    return debug_buf_info(stream, "3DSTATE_BUFFER_INFO", (cmd & 0xffff) + 2);
    766 	 case 0x97:
    767 	    return debug(stream, "3DSTATE_DEPTH_OFFSET_SCALE", (cmd & 0xffff) + 2);
    768 	 case 0x98:
    769 	    return debug(stream, "3DSTATE_DEFAULT_Z", (cmd & 0xffff) + 2);
    770 	 case 0x99:
    771 	    return debug(stream, "3DSTATE_DEFAULT_DIFFUSE", (cmd & 0xffff) + 2);
    772 	 case 0x9a:
    773 	    return debug(stream, "3DSTATE_DEFAULT_SPECULAR", (cmd & 0xffff) + 2);
    774 	 case 0x9c:
    775 	    return debug(stream, "3DSTATE_CLEAR_PARAMETERS", (cmd & 0xffff) + 2);
    776 	 default:
    777 	    assert(0);
    778 	    return 0;
    779 	 }
    780 	 break;
    781       case 0x1e:
    782 	 if (cmd & (1 << 23))
    783 	    return debug(stream, "???", (cmd & 0xffff) + 1);
    784 	 else
    785 	    return debug(stream, "", 1);
    786 	 break;
    787       case 0x1f:
    788 	 if ((cmd & (1 << 23)) == 0)
    789 	    return debug_prim(stream, "3DPRIM (inline)", 1, (cmd & 0x1ffff) + 2);
    790 	 else if (cmd & (1 << 17))
    791 	 {
    792 	    if ((cmd & 0xffff) == 0)
    793 	       return debug_variable_length_prim(stream);
    794 	    else
    795 	       return debug_prim(stream, "3DPRIM (indexed)", 0, (((cmd & 0xffff) + 1) / 2) + 1);
    796 	 }
    797 	 else
    798 	    return debug_prim(stream, "3DPRIM  (indirect sequential)", 0, 2);
    799 	 break;
    800       default:
    801 	 return debug(stream, "", 0);
    802       }
    803       break;
    804    default:
    805       assert(0);
    806       return 0;
    807    }
    808 
    809    assert(0);
    810    return 0;
    811 }
    812 
    813 
    814 
    815 void
    816 i915_dump_batchbuffer( GLuint *start,
    817 		       GLuint *end )
    818 {
    819    struct debug_stream stream;
    820    GLuint bytes = (end - start) * 4;
    821    bool done = false;
    822 
    823    printf("\n\nBATCH: (%d)\n", bytes / 4);
    824 
    825    stream.offset = 0;
    826    stream.ptr = (char *)start;
    827    stream.print_addresses = 0;
    828 
    829    while (!done &&
    830 	  stream.offset < bytes &&
    831 	  stream.offset >= 0)
    832    {
    833       if (!i915_debug_packet( &stream ))
    834 	 break;
    835 
    836       assert(stream.offset <= bytes &&
    837 	     stream.offset >= 0);
    838    }
    839 
    840    printf("END-BATCH\n\n\n");
    841 }
    842 
    843 
    844