Home | History | Annotate | Download | only in radeon
      1 /**************************************************************************
      2 
      3 Copyright 2002 ATI Technologies Inc., Ontario, Canada, and
      4                      VMware, Inc.
      5 
      6 All Rights Reserved.
      7 
      8 Permission is hereby granted, free of charge, to any person obtaining a
      9 copy of this software and associated documentation files (the "Software"),
     10 to deal in the Software without restriction, including without limitation
     11 on the rights to use, copy, modify, merge, publish, distribute, sub
     12 license, and/or sell copies of the Software, and to permit persons to whom
     13 the Software is furnished to do so, subject to the following conditions:
     14 
     15 The above copyright notice and this permission notice (including the next
     16 paragraph) shall be included in all copies or substantial portions of the
     17 Software.
     18 
     19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     22 ATI, VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
     23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     25 USE OR OTHER DEALINGS IN THE SOFTWARE.
     26 
     27 **************************************************************************/
     28 
     29 /*
     30  * Authors:
     31  *   Keith Whitwell <keithw (at) vmware.com>
     32  *
     33  */
     34 #include <errno.h>
     35 
     36 #include "main/glheader.h"
     37 
     38 #include "radeon_context.h"
     39 #include "radeon_sanity.h"
     40 
     41 /* Set this '1' to get more verbiage.
     42  */
     43 #define MORE_VERBOSE 1
     44 
     45 #if MORE_VERBOSE
     46 #define VERBOSE (RADEON_DEBUG & RADEON_VERBOSE)
     47 #define NORMAL  (1)
     48 #else
     49 #define VERBOSE 0
     50 #define NORMAL  (RADEON_DEBUG & RADEON_VERBOSE)
     51 #endif
     52 
     53 
     54 /* New (1.3) state mechanism.  3 commands (packet, scalar, vector) in
     55  * 1.3 cmdbuffers allow all previous state to be updated as well as
     56  * the tcl scalar and vector areas.
     57  */
     58 static struct {
     59    int start;
     60    int len;
     61    const char *name;
     62 } packet[RADEON_MAX_STATE_PACKETS] = {
     63    { RADEON_PP_MISC,7,"RADEON_PP_MISC" },
     64    { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" },
     65    { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" },
     66    { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" },
     67    { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" },
     68    { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" },
     69    { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" },
     70    { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" },
     71    { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" },
     72    { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" },
     73    { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" },
     74    { RADEON_RE_MISC,1,"RADEON_RE_MISC" },
     75    { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" },
     76    { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" },
     77    { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" },
     78    { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" },
     79    { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" },
     80    { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" },
     81    { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" },
     82    { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" },
     83    { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" },
     84 	{ 0, 4, "R200_PP_TXCBLEND_0" },
     85 	{ 0, 4, "R200_PP_TXCBLEND_1" },
     86 	{ 0, 4, "R200_PP_TXCBLEND_2" },
     87 	{ 0, 4, "R200_PP_TXCBLEND_3" },
     88 	{ 0, 4, "R200_PP_TXCBLEND_4" },
     89 	{ 0, 4, "R200_PP_TXCBLEND_5" },
     90 	{ 0, 4, "R200_PP_TXCBLEND_6" },
     91 	{ 0, 4, "R200_PP_TXCBLEND_7" },
     92 	{ 0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" },
     93 	{ 0, 6, "R200_PP_TFACTOR_0" },
     94 	{ 0, 4, "R200_SE_VTX_FMT_0" },
     95 	{ 0, 1, "R200_SE_VAP_CNTL" },
     96 	{ 0, 5, "R200_SE_TCL_MATRIX_SEL_0" },
     97 	{ 0, 5, "R200_SE_TCL_TEX_PROC_CTL_2" },
     98 	{ 0, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" },
     99 	{ 0, 6, "R200_PP_TXFILTER_0" },
    100 	{ 0, 6, "R200_PP_TXFILTER_1" },
    101 	{ 0, 6, "R200_PP_TXFILTER_2" },
    102 	{ 0, 6, "R200_PP_TXFILTER_3" },
    103 	{ 0, 6, "R200_PP_TXFILTER_4" },
    104 	{ 0, 6, "R200_PP_TXFILTER_5" },
    105 	{ 0, 1, "R200_PP_TXOFFSET_0" },
    106 	{ 0, 1, "R200_PP_TXOFFSET_1" },
    107 	{ 0, 1, "R200_PP_TXOFFSET_2" },
    108 	{ 0, 1, "R200_PP_TXOFFSET_3" },
    109 	{ 0, 1, "R200_PP_TXOFFSET_4" },
    110 	{ 0, 1, "R200_PP_TXOFFSET_5" },
    111 	{ 0, 1, "R200_SE_VTE_CNTL" },
    112 	{ 0, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" },
    113 	{ 0, 1, "R200_PP_TAM_DEBUG3" },
    114 	{ 0, 1, "R200_PP_CNTL_X" },
    115 	{ 0, 1, "R200_RB3D_DEPTHXY_OFFSET" },
    116 	{ 0, 1, "R200_RE_AUX_SCISSOR_CNTL" },
    117 	{ 0, 2, "R200_RE_SCISSOR_TL_0" },
    118 	{ 0, 2, "R200_RE_SCISSOR_TL_1" },
    119 	{ 0, 2, "R200_RE_SCISSOR_TL_2" },
    120 	{ 0, 1, "R200_SE_VAP_CNTL_STATUS" },
    121 	{ 0, 1, "R200_SE_VTX_STATE_CNTL" },
    122 	{ 0, 1, "R200_RE_POINTSIZE" },
    123 	{ 0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" },
    124 	{ 0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */
    125 	{ 0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */
    126 	{ 0, 1, "R200_PP_CUBIC_FACES_1" },
    127 	{ 0, 5, "R200_PP_CUBIC_OFFSET_F1_1" },
    128 	{ 0, 1, "R200_PP_CUBIC_FACES_2" },
    129 	{ 0, 5, "R200_PP_CUBIC_OFFSET_F1_2" },
    130 	{ 0, 1, "R200_PP_CUBIC_FACES_3" },
    131 	{ 0, 5, "R200_PP_CUBIC_OFFSET_F1_3" },
    132 	{ 0, 1, "R200_PP_CUBIC_FACES_4" },
    133 	{ 0, 5, "R200_PP_CUBIC_OFFSET_F1_4" },
    134 	{ 0, 1, "R200_PP_CUBIC_FACES_5" },
    135 	{ 0, 5, "R200_PP_CUBIC_OFFSET_F1_5" },
    136    { RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0" },
    137    { RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" },
    138    { RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2" },
    139 	{ 0, 3, "R200_RB3D_BLENDCOLOR" },
    140 	{ 0, 1, "R200_SE_TCL_POINT_SPRITE_CNTL" },
    141    { RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0" },
    142    { RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0" },
    143    { RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1" },
    144    { RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0" },
    145    { RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2" },
    146    { RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0" },
    147    { 0, 2, "R200_PP_TRI_PERF" },
    148    { 0, 32, "R200_PP_AFS_0"},   /* 85 */
    149    { 0, 32, "R200_PP_AFS_1"},
    150    { 0, 8, "R200_ATF_TFACTOR"},
    151    { 0, 8, "R200_PP_TXCTLALL_0"},
    152    { 0, 8, "R200_PP_TXCTLALL_1"},
    153    { 0, 8, "R200_PP_TXCTLALL_2"},
    154    { 0, 8, "R200_PP_TXCTLALL_3"},
    155    { 0, 8, "R200_PP_TXCTLALL_4"},
    156    { 0, 8, "R200_PP_TXCTLALL_5"},
    157    { 0, 2, "R200_VAP_PVS_CNTL"},
    158 };
    159 
    160 struct reg_names {
    161    int idx;
    162    const char *name;
    163 };
    164 
    165 static struct reg_names reg_names[] = {
    166    { RADEON_PP_MISC, "RADEON_PP_MISC" },
    167    { RADEON_PP_FOG_COLOR, "RADEON_PP_FOG_COLOR" },
    168    { RADEON_RE_SOLID_COLOR, "RADEON_RE_SOLID_COLOR" },
    169    { RADEON_RB3D_BLENDCNTL, "RADEON_RB3D_BLENDCNTL" },
    170    { RADEON_RB3D_DEPTHOFFSET, "RADEON_RB3D_DEPTHOFFSET" },
    171    { RADEON_RB3D_DEPTHPITCH, "RADEON_RB3D_DEPTHPITCH" },
    172    { RADEON_RB3D_ZSTENCILCNTL, "RADEON_RB3D_ZSTENCILCNTL" },
    173    { RADEON_PP_CNTL, "RADEON_PP_CNTL" },
    174    { RADEON_RB3D_CNTL, "RADEON_RB3D_CNTL" },
    175    { RADEON_RB3D_COLOROFFSET, "RADEON_RB3D_COLOROFFSET" },
    176    { RADEON_RB3D_COLORPITCH, "RADEON_RB3D_COLORPITCH" },
    177    { RADEON_SE_CNTL, "RADEON_SE_CNTL" },
    178    { RADEON_SE_COORD_FMT, "RADEON_SE_COORDFMT" },
    179    { RADEON_SE_CNTL_STATUS, "RADEON_SE_CNTL_STATUS" },
    180    { RADEON_RE_LINE_PATTERN, "RADEON_RE_LINE_PATTERN" },
    181    { RADEON_RE_LINE_STATE, "RADEON_RE_LINE_STATE" },
    182    { RADEON_SE_LINE_WIDTH, "RADEON_SE_LINE_WIDTH" },
    183    { RADEON_RB3D_STENCILREFMASK, "RADEON_RB3D_STENCILREFMASK" },
    184    { RADEON_RB3D_ROPCNTL, "RADEON_RB3D_ROPCNTL" },
    185    { RADEON_RB3D_PLANEMASK, "RADEON_RB3D_PLANEMASK" },
    186    { RADEON_SE_VPORT_XSCALE, "RADEON_SE_VPORT_XSCALE" },
    187    { RADEON_SE_VPORT_XOFFSET, "RADEON_SE_VPORT_XOFFSET" },
    188    { RADEON_SE_VPORT_YSCALE, "RADEON_SE_VPORT_YSCALE" },
    189    { RADEON_SE_VPORT_YOFFSET, "RADEON_SE_VPORT_YOFFSET" },
    190    { RADEON_SE_VPORT_ZSCALE, "RADEON_SE_VPORT_ZSCALE" },
    191    { RADEON_SE_VPORT_ZOFFSET, "RADEON_SE_VPORT_ZOFFSET" },
    192    { RADEON_RE_MISC, "RADEON_RE_MISC" },
    193    { RADEON_PP_TXFILTER_0, "RADEON_PP_TXFILTER_0" },
    194    { RADEON_PP_TXFILTER_1, "RADEON_PP_TXFILTER_1" },
    195    { RADEON_PP_TXFILTER_2, "RADEON_PP_TXFILTER_2" },
    196    { RADEON_PP_TXFORMAT_0, "RADEON_PP_TXFORMAT_0" },
    197    { RADEON_PP_TXFORMAT_1, "RADEON_PP_TXFORMAT_1" },
    198    { RADEON_PP_TXFORMAT_2, "RADEON_PP_TXFORMAT_2" },
    199    { RADEON_PP_TXOFFSET_0, "RADEON_PP_TXOFFSET_0" },
    200    { RADEON_PP_TXOFFSET_1, "RADEON_PP_TXOFFSET_1" },
    201    { RADEON_PP_TXOFFSET_2, "RADEON_PP_TXOFFSET_2" },
    202    { RADEON_PP_TXCBLEND_0, "RADEON_PP_TXCBLEND_0" },
    203    { RADEON_PP_TXCBLEND_1, "RADEON_PP_TXCBLEND_1" },
    204    { RADEON_PP_TXCBLEND_2, "RADEON_PP_TXCBLEND_2" },
    205    { RADEON_PP_TXABLEND_0, "RADEON_PP_TXABLEND_0" },
    206    { RADEON_PP_TXABLEND_1, "RADEON_PP_TXABLEND_1" },
    207    { RADEON_PP_TXABLEND_2, "RADEON_PP_TXABLEND_2" },
    208    { RADEON_PP_TFACTOR_0, "RADEON_PP_TFACTOR_0" },
    209    { RADEON_PP_TFACTOR_1, "RADEON_PP_TFACTOR_1" },
    210    { RADEON_PP_TFACTOR_2, "RADEON_PP_TFACTOR_2" },
    211    { RADEON_PP_BORDER_COLOR_0, "RADEON_PP_BORDER_COLOR_0" },
    212    { RADEON_PP_BORDER_COLOR_1, "RADEON_PP_BORDER_COLOR_1" },
    213    { RADEON_PP_BORDER_COLOR_2, "RADEON_PP_BORDER_COLOR_2" },
    214    { RADEON_SE_ZBIAS_FACTOR, "RADEON_SE_ZBIAS_FACTOR" },
    215    { RADEON_SE_ZBIAS_CONSTANT, "RADEON_SE_ZBIAS_CONSTANT" },
    216    { RADEON_SE_TCL_OUTPUT_VTX_FMT, "RADEON_SE_TCL_OUTPUT_VTXFMT" },
    217    { RADEON_SE_TCL_OUTPUT_VTX_SEL, "RADEON_SE_TCL_OUTPUT_VTXSEL" },
    218    { RADEON_SE_TCL_MATRIX_SELECT_0, "RADEON_SE_TCL_MATRIX_SELECT_0" },
    219    { RADEON_SE_TCL_MATRIX_SELECT_1, "RADEON_SE_TCL_MATRIX_SELECT_1" },
    220    { RADEON_SE_TCL_UCP_VERT_BLEND_CTL, "RADEON_SE_TCL_UCP_VERT_BLEND_CTL" },
    221    { RADEON_SE_TCL_TEXTURE_PROC_CTL, "RADEON_SE_TCL_TEXTURE_PROC_CTL" },
    222    { RADEON_SE_TCL_LIGHT_MODEL_CTL, "RADEON_SE_TCL_LIGHT_MODEL_CTL" },
    223    { RADEON_SE_TCL_PER_LIGHT_CTL_0, "RADEON_SE_TCL_PER_LIGHT_CTL_0" },
    224    { RADEON_SE_TCL_PER_LIGHT_CTL_1, "RADEON_SE_TCL_PER_LIGHT_CTL_1" },
    225    { RADEON_SE_TCL_PER_LIGHT_CTL_2, "RADEON_SE_TCL_PER_LIGHT_CTL_2" },
    226    { RADEON_SE_TCL_PER_LIGHT_CTL_3, "RADEON_SE_TCL_PER_LIGHT_CTL_3" },
    227    { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, "RADEON_SE_TCL_EMMISSIVE_RED" },
    228    { RADEON_SE_TCL_MATERIAL_EMMISSIVE_GREEN, "RADEON_SE_TCL_EMMISSIVE_GREEN" },
    229    { RADEON_SE_TCL_MATERIAL_EMMISSIVE_BLUE, "RADEON_SE_TCL_EMMISSIVE_BLUE" },
    230    { RADEON_SE_TCL_MATERIAL_EMMISSIVE_ALPHA, "RADEON_SE_TCL_EMMISSIVE_ALPHA" },
    231    { RADEON_SE_TCL_MATERIAL_AMBIENT_RED, "RADEON_SE_TCL_AMBIENT_RED" },
    232    { RADEON_SE_TCL_MATERIAL_AMBIENT_GREEN, "RADEON_SE_TCL_AMBIENT_GREEN" },
    233    { RADEON_SE_TCL_MATERIAL_AMBIENT_BLUE, "RADEON_SE_TCL_AMBIENT_BLUE" },
    234    { RADEON_SE_TCL_MATERIAL_AMBIENT_ALPHA, "RADEON_SE_TCL_AMBIENT_ALPHA" },
    235    { RADEON_SE_TCL_MATERIAL_DIFFUSE_RED, "RADEON_SE_TCL_DIFFUSE_RED" },
    236    { RADEON_SE_TCL_MATERIAL_DIFFUSE_GREEN, "RADEON_SE_TCL_DIFFUSE_GREEN" },
    237    { RADEON_SE_TCL_MATERIAL_DIFFUSE_BLUE, "RADEON_SE_TCL_DIFFUSE_BLUE" },
    238    { RADEON_SE_TCL_MATERIAL_DIFFUSE_ALPHA, "RADEON_SE_TCL_DIFFUSE_ALPHA" },
    239    { RADEON_SE_TCL_MATERIAL_SPECULAR_RED, "RADEON_SE_TCL_SPECULAR_RED" },
    240    { RADEON_SE_TCL_MATERIAL_SPECULAR_GREEN, "RADEON_SE_TCL_SPECULAR_GREEN" },
    241    { RADEON_SE_TCL_MATERIAL_SPECULAR_BLUE, "RADEON_SE_TCL_SPECULAR_BLUE" },
    242    { RADEON_SE_TCL_MATERIAL_SPECULAR_ALPHA, "RADEON_SE_TCL_SPECULAR_ALPHA" },
    243    { RADEON_SE_TCL_SHININESS, "RADEON_SE_TCL_SHININESS" },
    244    { RADEON_SE_COORD_FMT, "RADEON_SE_COORD_FMT" },
    245    { RADEON_PP_TEX_SIZE_0, "RADEON_PP_TEX_SIZE_0" },
    246    { RADEON_PP_TEX_SIZE_1, "RADEON_PP_TEX_SIZE_1" },
    247    { RADEON_PP_TEX_SIZE_2, "RADEON_PP_TEX_SIZE_2" },
    248    { RADEON_PP_TEX_SIZE_0+4, "RADEON_PP_TEX_PITCH_0" },
    249    { RADEON_PP_TEX_SIZE_1+4, "RADEON_PP_TEX_PITCH_1" },
    250    { RADEON_PP_TEX_SIZE_2+4, "RADEON_PP_TEX_PITCH_2" },
    251    { RADEON_PP_CUBIC_FACES_0, "RADEON_PP_CUBIC_FACES_0" },
    252    { RADEON_PP_CUBIC_FACES_1, "RADEON_PP_CUBIC_FACES_1" },
    253    { RADEON_PP_CUBIC_FACES_2, "RADEON_PP_CUBIC_FACES_2" },
    254    { RADEON_PP_CUBIC_OFFSET_T0_0, "RADEON_PP_CUBIC_OFFSET_T0_0" },
    255    { RADEON_PP_CUBIC_OFFSET_T0_1, "RADEON_PP_CUBIC_OFFSET_T0_1" },
    256    { RADEON_PP_CUBIC_OFFSET_T0_2, "RADEON_PP_CUBIC_OFFSET_T0_2" },
    257    { RADEON_PP_CUBIC_OFFSET_T0_3, "RADEON_PP_CUBIC_OFFSET_T0_3" },
    258    { RADEON_PP_CUBIC_OFFSET_T0_4, "RADEON_PP_CUBIC_OFFSET_T0_4" },
    259    { RADEON_PP_CUBIC_OFFSET_T1_0, "RADEON_PP_CUBIC_OFFSET_T1_0" },
    260    { RADEON_PP_CUBIC_OFFSET_T1_1, "RADEON_PP_CUBIC_OFFSET_T1_1" },
    261    { RADEON_PP_CUBIC_OFFSET_T1_2, "RADEON_PP_CUBIC_OFFSET_T1_2" },
    262    { RADEON_PP_CUBIC_OFFSET_T1_3, "RADEON_PP_CUBIC_OFFSET_T1_3" },
    263    { RADEON_PP_CUBIC_OFFSET_T1_4, "RADEON_PP_CUBIC_OFFSET_T1_4" },
    264    { RADEON_PP_CUBIC_OFFSET_T2_0, "RADEON_PP_CUBIC_OFFSET_T2_0" },
    265    { RADEON_PP_CUBIC_OFFSET_T2_1, "RADEON_PP_CUBIC_OFFSET_T2_1" },
    266    { RADEON_PP_CUBIC_OFFSET_T2_2, "RADEON_PP_CUBIC_OFFSET_T2_2" },
    267    { RADEON_PP_CUBIC_OFFSET_T2_3, "RADEON_PP_CUBIC_OFFSET_T2_3" },
    268    { RADEON_PP_CUBIC_OFFSET_T2_4, "RADEON_PP_CUBIC_OFFSET_T2_4" },
    269 };
    270 
    271 static struct reg_names scalar_names[] = {
    272    { RADEON_SS_LIGHT_DCD_ADDR, "LIGHT_DCD" },
    273    { RADEON_SS_LIGHT_SPOT_EXPONENT_ADDR, "LIGHT_SPOT_EXPONENT" },
    274    { RADEON_SS_LIGHT_SPOT_CUTOFF_ADDR, "LIGHT_SPOT_CUTOFF" },
    275    { RADEON_SS_LIGHT_SPECULAR_THRESH_ADDR, "LIGHT_SPECULAR_THRESH" },
    276    { RADEON_SS_LIGHT_RANGE_CUTOFF_ADDR, "LIGHT_RANGE_CUTOFF" },
    277    { RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR, "VERT_GUARD_CLIP" },
    278    { RADEON_SS_VERT_GUARD_DISCARD_ADJ_ADDR, "VERT_GUARD_DISCARD" },
    279    { RADEON_SS_HORZ_GUARD_CLIP_ADJ_ADDR, "HORZ_GUARD_CLIP" },
    280    { RADEON_SS_HORZ_GUARD_DISCARD_ADJ_ADDR, "HORZ_GUARD_DISCARD" },
    281    { RADEON_SS_SHININESS, "SHININESS" },
    282    { 1000, "" },
    283 };
    284 
    285 /* Puff these out to make them look like normal (dword) registers.
    286  */
    287 static struct reg_names vector_names[] = {
    288    { RADEON_VS_MATRIX_0_ADDR * 4, "MATRIX_0" },
    289    { RADEON_VS_MATRIX_1_ADDR * 4, "MATRIX_1" },
    290    { RADEON_VS_MATRIX_2_ADDR * 4, "MATRIX_2" },
    291    { RADEON_VS_MATRIX_3_ADDR * 4, "MATRIX_3" },
    292    { RADEON_VS_MATRIX_4_ADDR * 4, "MATRIX_4" },
    293    { RADEON_VS_MATRIX_5_ADDR * 4, "MATRIX_5" },
    294    { RADEON_VS_MATRIX_6_ADDR * 4, "MATRIX_6" },
    295    { RADEON_VS_MATRIX_7_ADDR * 4, "MATRIX_7" },
    296    { RADEON_VS_MATRIX_8_ADDR * 4, "MATRIX_8" },
    297    { RADEON_VS_MATRIX_9_ADDR * 4, "MATRIX_9" },
    298    { RADEON_VS_MATRIX_10_ADDR * 4, "MATRIX_10" },
    299    { RADEON_VS_MATRIX_11_ADDR * 4, "MATRIX_11" },
    300    { RADEON_VS_MATRIX_12_ADDR * 4, "MATRIX_12" },
    301    { RADEON_VS_MATRIX_13_ADDR * 4, "MATRIX_13" },
    302    { RADEON_VS_MATRIX_14_ADDR * 4, "MATRIX_14" },
    303    { RADEON_VS_MATRIX_15_ADDR * 4, "MATRIX_15" },
    304    { RADEON_VS_LIGHT_AMBIENT_ADDR * 4, "LIGHT_AMBIENT" },
    305    { RADEON_VS_LIGHT_DIFFUSE_ADDR * 4, "LIGHT_DIFFUSE" },
    306    { RADEON_VS_LIGHT_SPECULAR_ADDR * 4, "LIGHT_SPECULAR" },
    307    { RADEON_VS_LIGHT_DIRPOS_ADDR * 4, "LIGHT_DIRPOS" },
    308    { RADEON_VS_LIGHT_HWVSPOT_ADDR * 4, "LIGHT_HWVSPOT" },
    309    { RADEON_VS_LIGHT_ATTENUATION_ADDR * 4, "LIGHT_ATTENUATION" },
    310    { RADEON_VS_MATRIX_EYE2CLIP_ADDR * 4, "MATRIX_EYE2CLIP" },
    311    { RADEON_VS_UCP_ADDR * 4, "UCP" },
    312    { RADEON_VS_GLOBAL_AMBIENT_ADDR * 4, "GLOBAL_AMBIENT" },
    313    { RADEON_VS_FOG_PARAM_ADDR * 4, "FOG_PARAM" },
    314    { RADEON_VS_EYE_VECTOR_ADDR * 4, "EYE_VECTOR" },
    315    { 1000, "" },
    316 };
    317 
    318 #define ISVEC   1
    319 #define ISFLOAT 2
    320 #define TOUCHED 4
    321 
    322 struct reg {
    323    int idx;
    324    struct reg_names *closest;
    325    int flags;
    326    union fi current;
    327    union fi *values;
    328    int nvalues;
    329    int nalloc;
    330    float vmin, vmax;
    331 };
    332 
    333 
    334 static struct reg regs[ARRAY_SIZE(reg_names)+1];
    335 static struct reg scalars[512+1];
    336 static struct reg vectors[512*4+1];
    337 
    338 static int total, total_changed, bufs;
    339 
    340 static void init_regs( void )
    341 {
    342    struct reg_names *tmp;
    343    int i;
    344 
    345    for (i = 0 ; i < ARRAY_SIZE(regs)-1 ; i++) {
    346       regs[i].idx = reg_names[i].idx;
    347       regs[i].closest = &reg_names[i];
    348       regs[i].flags = 0;
    349    }
    350 
    351    for (i = 0, tmp = scalar_names ; i < ARRAY_SIZE(scalars) ; i++) {
    352       if (tmp[1].idx == i) tmp++;
    353       scalars[i].idx = i;
    354       scalars[i].closest = tmp;
    355       scalars[i].flags = ISFLOAT;
    356    }
    357 
    358    for (i = 0, tmp = vector_names ; i < ARRAY_SIZE(vectors) ; i++) {
    359       if (tmp[1].idx*4 == i) tmp++;
    360       vectors[i].idx = i;
    361       vectors[i].closest = tmp;
    362       vectors[i].flags = ISFLOAT|ISVEC;
    363    }
    364 
    365    regs[ARRAY_SIZE(regs)-1].idx = -1;
    366    scalars[ARRAY_SIZE(scalars)-1].idx = -1;
    367    vectors[ARRAY_SIZE(vectors)-1].idx = -1;
    368 }
    369 
    370 static int find_or_add_value( struct reg *reg, int val )
    371 {
    372    int j;
    373 
    374    for ( j = 0 ; j < reg->nvalues ; j++)
    375       if ( val == reg->values[j].i )
    376 	 return 1;
    377 
    378    if (j == reg->nalloc) {
    379       reg->nalloc += 5;
    380       reg->nalloc *= 2;
    381       reg->values = realloc( reg->values, reg->nalloc * sizeof(union fi) );
    382    }
    383 
    384    reg->values[reg->nvalues++].i = val;
    385    return 0;
    386 }
    387 
    388 static struct reg *lookup_reg( struct reg *tab, int reg )
    389 {
    390    int i;
    391 
    392    for (i = 0 ; tab[i].idx != -1 ; i++) {
    393       if (tab[i].idx == reg)
    394 	 return &tab[i];
    395    }
    396 
    397    fprintf(stderr, "*** unknown reg 0x%x\n", reg);
    398    return NULL;
    399 }
    400 
    401 
    402 static const char *get_reg_name( struct reg *reg )
    403 {
    404    static char tmp[80];
    405 
    406    if (reg->idx == reg->closest->idx)
    407       return reg->closest->name;
    408 
    409 
    410    if (reg->flags & ISVEC) {
    411       if (reg->idx/4 != reg->closest->idx)
    412 	 sprintf(tmp, "%s+%d[%d]",
    413 		 reg->closest->name,
    414 		 (reg->idx/4) - reg->closest->idx,
    415 		 reg->idx%4);
    416       else
    417 	 sprintf(tmp, "%s[%d]", reg->closest->name, reg->idx%4);
    418    }
    419    else {
    420       if (reg->idx != reg->closest->idx)
    421 	 sprintf(tmp, "%s+%d", reg->closest->name, reg->idx - reg->closest->idx);
    422       else
    423 	 sprintf(tmp, "%s", reg->closest->name);
    424    }
    425 
    426    return tmp;
    427 }
    428 
    429 static int print_int_reg_assignment( struct reg *reg, int data )
    430 {
    431    int changed = (reg->current.i != data);
    432    int ever_seen = find_or_add_value( reg, data );
    433 
    434    if (VERBOSE || (NORMAL && (changed || !ever_seen)))
    435        fprintf(stderr, "   %s <-- 0x%x", get_reg_name(reg), data);
    436 
    437    if (NORMAL) {
    438       if (!ever_seen)
    439 	 fprintf(stderr, " *** BRAND NEW VALUE");
    440       else if (changed)
    441 	 fprintf(stderr, " *** CHANGED");
    442    }
    443 
    444    reg->current.i = data;
    445 
    446    if (VERBOSE || (NORMAL && (changed || !ever_seen)))
    447       fprintf(stderr, "\n");
    448 
    449    return changed;
    450 }
    451 
    452 
    453 static int print_float_reg_assignment( struct reg *reg, float data )
    454 {
    455    int changed = (reg->current.f != data);
    456    int newmin = (data < reg->vmin);
    457    int newmax = (data > reg->vmax);
    458 
    459    if (VERBOSE || (NORMAL && (newmin || newmax || changed)))
    460       fprintf(stderr, "   %s <-- %.3f", get_reg_name(reg), data);
    461 
    462    if (NORMAL) {
    463       if (newmin) {
    464 	 fprintf(stderr, " *** NEW MIN (prev %.3f)", reg->vmin);
    465 	 reg->vmin = data;
    466       }
    467       else if (newmax) {
    468 	 fprintf(stderr, " *** NEW MAX (prev %.3f)", reg->vmax);
    469 	 reg->vmax = data;
    470       }
    471       else if (changed) {
    472 	 fprintf(stderr, " *** CHANGED");
    473       }
    474    }
    475 
    476    reg->current.f = data;
    477 
    478    if (VERBOSE || (NORMAL && (newmin || newmax || changed)))
    479       fprintf(stderr, "\n");
    480 
    481    return changed;
    482 }
    483 
    484 static int print_reg_assignment( struct reg *reg, int data )
    485 {
    486    float_ui32_type datau;
    487    datau.ui32 = data;
    488    reg->flags |= TOUCHED;
    489    if (reg->flags & ISFLOAT)
    490       return print_float_reg_assignment( reg, datau.f );
    491    else
    492       return print_int_reg_assignment( reg, data );
    493 }
    494 
    495 static void print_reg( struct reg *reg )
    496 {
    497    if (reg->flags & TOUCHED) {
    498       if (reg->flags & ISFLOAT) {
    499 	 fprintf(stderr, "   %s == %f\n", get_reg_name(reg), reg->current.f);
    500       } else {
    501 	 fprintf(stderr, "   %s == 0x%x\n", get_reg_name(reg), reg->current.i);
    502       }
    503    }
    504 }
    505 
    506 
    507 static void dump_state( void )
    508 {
    509    int i;
    510 
    511    for (i = 0 ; i < ARRAY_SIZE(regs) ; i++)
    512       print_reg( &regs[i] );
    513 
    514    for (i = 0 ; i < ARRAY_SIZE(scalars) ; i++)
    515       print_reg( &scalars[i] );
    516 
    517    for (i = 0 ; i < ARRAY_SIZE(vectors) ; i++)
    518       print_reg( &vectors[i] );
    519 }
    520 
    521 
    522 
    523 static int radeon_emit_packets(
    524    drm_radeon_cmd_header_t header,
    525    drm_radeon_cmd_buffer_t *cmdbuf )
    526 {
    527    int id = (int)header.packet.packet_id;
    528    int sz = packet[id].len;
    529    int *data = (int *)cmdbuf->buf;
    530    int i;
    531 
    532    if (sz * sizeof(int) > cmdbuf->bufsz) {
    533       fprintf(stderr, "Packet overflows cmdbuf\n");
    534       return -EINVAL;
    535    }
    536 
    537    if (!packet[id].name) {
    538       fprintf(stderr, "*** Unknown packet 0 nr %d\n", id );
    539       return -EINVAL;
    540    }
    541 
    542 
    543    if (VERBOSE)
    544       fprintf(stderr, "Packet 0 reg %s nr %d\n", packet[id].name, sz );
    545 
    546    for ( i = 0 ; i < sz ; i++) {
    547       struct reg *reg = lookup_reg( regs, packet[id].start + i*4 );
    548       if (print_reg_assignment( reg, data[i] ))
    549 	 total_changed++;
    550       total++;
    551    }
    552 
    553    cmdbuf->buf += sz * sizeof(int);
    554    cmdbuf->bufsz -= sz * sizeof(int);
    555    return 0;
    556 }
    557 
    558 
    559 static int radeon_emit_scalars(
    560    drm_radeon_cmd_header_t header,
    561    drm_radeon_cmd_buffer_t *cmdbuf )
    562 {
    563    int sz = header.scalars.count;
    564    int *data = (int *)cmdbuf->buf;
    565    int start = header.scalars.offset;
    566    int stride = header.scalars.stride;
    567    int i;
    568 
    569    if (VERBOSE)
    570       fprintf(stderr, "emit scalars, start %d stride %d nr %d (end %d)\n",
    571 	      start, stride, sz, start + stride * sz);
    572 
    573 
    574    for (i = 0 ; i < sz ; i++, start += stride) {
    575       struct reg *reg = lookup_reg( scalars, start );
    576       if (print_reg_assignment( reg, data[i] ))
    577 	 total_changed++;
    578       total++;
    579    }
    580 
    581    cmdbuf->buf += sz * sizeof(int);
    582    cmdbuf->bufsz -= sz * sizeof(int);
    583    return 0;
    584 }
    585 
    586 
    587 static int radeon_emit_scalars2(
    588    drm_radeon_cmd_header_t header,
    589    drm_radeon_cmd_buffer_t *cmdbuf )
    590 {
    591    int sz = header.scalars.count;
    592    int *data = (int *)cmdbuf->buf;
    593    int start = header.scalars.offset + 0x100;
    594    int stride = header.scalars.stride;
    595    int i;
    596 
    597    if (VERBOSE)
    598       fprintf(stderr, "emit scalars2, start %d stride %d nr %d (end %d)\n",
    599 	      start, stride, sz, start + stride * sz);
    600 
    601    if (start + stride * sz > 257) {
    602       fprintf(stderr, "emit scalars OVERFLOW %d/%d/%d\n", start, stride, sz);
    603       return -1;
    604    }
    605 
    606    for (i = 0 ; i < sz ; i++, start += stride) {
    607       struct reg *reg = lookup_reg( scalars, start );
    608       if (print_reg_assignment( reg, data[i] ))
    609 	 total_changed++;
    610       total++;
    611    }
    612 
    613    cmdbuf->buf += sz * sizeof(int);
    614    cmdbuf->bufsz -= sz * sizeof(int);
    615    return 0;
    616 }
    617 
    618 /* Check: inf/nan/extreme-size?
    619  * Check: table start, end, nr, etc.
    620  */
    621 static int radeon_emit_vectors(
    622    drm_radeon_cmd_header_t header,
    623    drm_radeon_cmd_buffer_t *cmdbuf )
    624 {
    625    int sz = header.vectors.count;
    626    int *data = (int *)cmdbuf->buf;
    627    int start = header.vectors.offset;
    628    int stride = header.vectors.stride;
    629    int i,j;
    630 
    631    if (VERBOSE)
    632       fprintf(stderr, "emit vectors, start %d stride %d nr %d (end %d) (0x%x)\n",
    633 	      start, stride, sz, start + stride * sz, header.i);
    634 
    635 /*    if (start + stride * (sz/4) > 128) { */
    636 /*       fprintf(stderr, "emit vectors OVERFLOW %d/%d/%d\n", start, stride, sz); */
    637 /*       return -1; */
    638 /*    } */
    639 
    640    for (i = 0 ; i < sz ;  start += stride) {
    641       int changed = 0;
    642       for (j = 0 ; j < 4 ; i++,j++) {
    643 	 struct reg *reg = lookup_reg( vectors, start*4+j );
    644 	 if (print_reg_assignment( reg, data[i] ))
    645 	    changed = 1;
    646       }
    647       if (changed)
    648 	 total_changed += 4;
    649       total += 4;
    650    }
    651 
    652 
    653    cmdbuf->buf += sz * sizeof(int);
    654    cmdbuf->bufsz -= sz * sizeof(int);
    655    return 0;
    656 }
    657 
    658 
    659 static int print_vertex_format( int vfmt )
    660 {
    661    if (NORMAL) {
    662       fprintf(stderr, "   %s(%x): %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
    663 	      "vertex format",
    664 	      vfmt,
    665 	      "xy,",
    666 	      (vfmt & RADEON_CP_VC_FRMT_Z) ? "z," : "",
    667 	      (vfmt & RADEON_CP_VC_FRMT_W0) ? "w0," : "",
    668 	      (vfmt & RADEON_CP_VC_FRMT_FPCOLOR) ? "fpcolor," : "",
    669 	      (vfmt & RADEON_CP_VC_FRMT_FPALPHA) ? "fpalpha," : "",
    670 	      (vfmt & RADEON_CP_VC_FRMT_PKCOLOR) ? "pkcolor," : "",
    671 	      (vfmt & RADEON_CP_VC_FRMT_FPSPEC) ? "fpspec," : "",
    672 	      (vfmt & RADEON_CP_VC_FRMT_FPFOG) ? "fpfog," : "",
    673 	      (vfmt & RADEON_CP_VC_FRMT_PKSPEC) ? "pkspec," : "",
    674 	      (vfmt & RADEON_CP_VC_FRMT_ST0) ? "st0," : "",
    675 	      (vfmt & RADEON_CP_VC_FRMT_ST1) ? "st1," : "",
    676 	      (vfmt & RADEON_CP_VC_FRMT_Q1) ? "q1," : "",
    677 	      (vfmt & RADEON_CP_VC_FRMT_ST2) ? "st2," : "",
    678 	      (vfmt & RADEON_CP_VC_FRMT_Q2) ? "q2," : "",
    679 	      (vfmt & RADEON_CP_VC_FRMT_ST3) ? "st3," : "",
    680 	      (vfmt & RADEON_CP_VC_FRMT_Q3) ? "q3," : "",
    681 	      (vfmt & RADEON_CP_VC_FRMT_Q0) ? "q0," : "",
    682 	      (vfmt & RADEON_CP_VC_FRMT_N0) ? "n0," : "",
    683 	      (vfmt & RADEON_CP_VC_FRMT_XY1) ? "xy1," : "",
    684 	      (vfmt & RADEON_CP_VC_FRMT_Z1) ? "z1," : "",
    685 	      (vfmt & RADEON_CP_VC_FRMT_W1) ? "w1," : "",
    686 	      (vfmt & RADEON_CP_VC_FRMT_N1) ? "n1," : "");
    687 
    688 
    689 /*       if (!find_or_add_value( &others[V_VTXFMT], vfmt )) */
    690 /* 	 fprintf(stderr, " *** NEW VALUE"); */
    691 
    692       fprintf(stderr, "\n");
    693    }
    694 
    695    return 0;
    696 }
    697 
    698 static char *primname[0xf] = {
    699    "NONE",
    700    "POINTS",
    701    "LINES",
    702    "LINE_STRIP",
    703    "TRIANGLES",
    704    "TRIANGLE_FAN",
    705    "TRIANGLE_STRIP",
    706    "TRI_TYPE_2",
    707    "RECT_LIST",
    708    "3VRT_POINTS",
    709    "3VRT_LINES",
    710 };
    711 
    712 static int print_prim_and_flags( int prim )
    713 {
    714    int numverts;
    715 
    716    if (NORMAL)
    717       fprintf(stderr, "   %s(%x): %s%s%s%s%s%s%s\n",
    718 	      "prim flags",
    719 	      prim,
    720 	      ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_IND) ? "IND," : "",
    721 	      ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_LIST) ? "LIST," : "",
    722 	      ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_RING) ? "RING," : "",
    723 	      (prim & RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA) ? "RGBA," : "BGRA, ",
    724 	      (prim & RADEON_CP_VC_CNTL_MAOS_ENABLE) ? "MAOS," : "",
    725 	      (prim & RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE) ? "RADEON," : "",
    726 	      (prim & RADEON_CP_VC_CNTL_TCL_ENABLE) ? "TCL," : "");
    727 
    728    if ((prim & 0xf) > RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST) {
    729       fprintf(stderr, "   *** Bad primitive: %x\n", prim & 0xf);
    730       return -1;
    731    }
    732 
    733    numverts = prim>>16;
    734 
    735    if (NORMAL)
    736       fprintf(stderr, "   prim: %s numverts %d\n", primname[prim&0xf], numverts);
    737 
    738    switch (prim & 0xf) {
    739    case RADEON_CP_VC_CNTL_PRIM_TYPE_NONE:
    740    case RADEON_CP_VC_CNTL_PRIM_TYPE_POINT:
    741       if (numverts < 1) {
    742 	 fprintf(stderr, "Bad nr verts for line %d\n", numverts);
    743 	 return -1;
    744       }
    745       break;
    746    case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE:
    747       if ((numverts & 1) || numverts == 0) {
    748 	 fprintf(stderr, "Bad nr verts for line %d\n", numverts);
    749 	 return -1;
    750       }
    751       break;
    752    case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP:
    753       if (numverts < 2) {
    754 	 fprintf(stderr, "Bad nr verts for line_strip %d\n", numverts);
    755 	 return -1;
    756       }
    757       break;
    758    case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST:
    759    case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST:
    760    case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST:
    761    case RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST:
    762       if (numverts % 3 || numverts == 0) {
    763 	 fprintf(stderr, "Bad nr verts for tri %d\n", numverts);
    764 	 return -1;
    765       }
    766       break;
    767    case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN:
    768    case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP:
    769       if (numverts < 3) {
    770 	 fprintf(stderr, "Bad nr verts for strip/fan %d\n", numverts);
    771 	 return -1;
    772       }
    773       break;
    774    default:
    775       fprintf(stderr, "Bad primitive\n");
    776       return -1;
    777    }
    778    return 0;
    779 }
    780 
    781 /* build in knowledge about each packet type
    782  */
    783 static int radeon_emit_packet3( drm_radeon_cmd_buffer_t *cmdbuf )
    784 {
    785    int cmdsz;
    786    int *cmd = (int *)cmdbuf->buf;
    787    int *tmp;
    788    int i, stride, size, start;
    789 
    790    cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);
    791 
    792    if ((cmd[0] & RADEON_CP_PACKET_MASK) != RADEON_CP_PACKET3 ||
    793        cmdsz * 4 > cmdbuf->bufsz ||
    794        cmdsz > RADEON_CP_PACKET_MAX_DWORDS) {
    795       fprintf(stderr, "Bad packet\n");
    796       return -EINVAL;
    797    }
    798 
    799    switch( cmd[0] & ~RADEON_CP_PACKET_COUNT_MASK ) {
    800    case RADEON_CP_PACKET3_NOP:
    801       if (NORMAL)
    802 	 fprintf(stderr, "PACKET3_NOP, %d dwords\n", cmdsz);
    803       break;
    804    case RADEON_CP_PACKET3_NEXT_CHAR:
    805       if (NORMAL)
    806 	 fprintf(stderr, "PACKET3_NEXT_CHAR, %d dwords\n", cmdsz);
    807       break;
    808    case RADEON_CP_PACKET3_PLY_NEXTSCAN:
    809       if (NORMAL)
    810 	 fprintf(stderr, "PACKET3_PLY_NEXTSCAN, %d dwords\n", cmdsz);
    811       break;
    812    case RADEON_CP_PACKET3_SET_SCISSORS:
    813       if (NORMAL)
    814 	 fprintf(stderr, "PACKET3_SET_SCISSORS, %d dwords\n", cmdsz);
    815       break;
    816    case RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM:
    817       if (NORMAL)
    818 	 fprintf(stderr, "PACKET3_3D_RNDR_GEN_INDX_PRIM, %d dwords\n",
    819 	      cmdsz);
    820       break;
    821    case RADEON_CP_PACKET3_LOAD_MICROCODE:
    822       if (NORMAL)
    823 	 fprintf(stderr, "PACKET3_LOAD_MICROCODE, %d dwords\n", cmdsz);
    824       break;
    825    case RADEON_CP_PACKET3_WAIT_FOR_IDLE:
    826       if (NORMAL)
    827 	 fprintf(stderr, "PACKET3_WAIT_FOR_IDLE, %d dwords\n", cmdsz);
    828       break;
    829 
    830    case RADEON_CP_PACKET3_3D_DRAW_VBUF:
    831       if (NORMAL)
    832 	 fprintf(stderr, "PACKET3_3D_DRAW_VBUF, %d dwords\n", cmdsz);
    833       print_vertex_format(cmd[1]);
    834       print_prim_and_flags(cmd[2]);
    835       break;
    836 
    837    case RADEON_CP_PACKET3_3D_DRAW_IMMD:
    838       if (NORMAL)
    839 	 fprintf(stderr, "PACKET3_3D_DRAW_IMMD, %d dwords\n", cmdsz);
    840       break;
    841    case RADEON_CP_PACKET3_3D_DRAW_INDX: {
    842       int neltdwords;
    843       if (NORMAL)
    844 	 fprintf(stderr, "PACKET3_3D_DRAW_INDX, %d dwords\n", cmdsz);
    845       print_vertex_format(cmd[1]);
    846       print_prim_and_flags(cmd[2]);
    847       neltdwords = cmd[2]>>16;
    848       neltdwords += neltdwords & 1;
    849       neltdwords /= 2;
    850       if (neltdwords + 3 != cmdsz)
    851 	 fprintf(stderr, "Mismatch in DRAW_INDX, %d vs cmdsz %d\n",
    852 		 neltdwords, cmdsz);
    853       break;
    854    }
    855    case RADEON_CP_PACKET3_LOAD_PALETTE:
    856       if (NORMAL)
    857 	 fprintf(stderr, "PACKET3_LOAD_PALETTE, %d dwords\n", cmdsz);
    858       break;
    859    case RADEON_CP_PACKET3_3D_LOAD_VBPNTR:
    860       if (NORMAL) {
    861 	 fprintf(stderr, "PACKET3_3D_LOAD_VBPNTR, %d dwords\n", cmdsz);
    862 	 fprintf(stderr, "   nr arrays: %d\n", cmd[1]);
    863       }
    864 
    865       if (cmd[1]/2 + cmd[1]%2 != cmdsz - 3) {
    866 	 fprintf(stderr, "  ****** MISMATCH %d/%d *******\n",
    867 		 cmd[1]/2 + cmd[1]%2 + 3, cmdsz);
    868 	 return -EINVAL;
    869       }
    870 
    871       if (NORMAL) {
    872 	 tmp = cmd+2;
    873 	 for (i = 0 ; i < cmd[1] ; i++) {
    874 	    if (i & 1) {
    875 	       stride = (tmp[0]>>24) & 0xff;
    876 	       size = (tmp[0]>>16) & 0xff;
    877 	       start = tmp[2];
    878 	       tmp += 3;
    879 	    }
    880 	    else {
    881 	       stride = (tmp[0]>>8) & 0xff;
    882 	       size = (tmp[0]) & 0xff;
    883 	       start = tmp[1];
    884 	    }
    885 	    fprintf(stderr, "   array %d: start 0x%x vsize %d vstride %d\n",
    886 		    i, start, size, stride );
    887 	 }
    888       }
    889       break;
    890    case RADEON_CP_PACKET3_CNTL_PAINT:
    891       if (NORMAL)
    892 	 fprintf(stderr, "PACKET3_CNTL_PAINT, %d dwords\n", cmdsz);
    893       break;
    894    case RADEON_CP_PACKET3_CNTL_BITBLT:
    895       if (NORMAL)
    896 	 fprintf(stderr, "PACKET3_CNTL_BITBLT, %d dwords\n", cmdsz);
    897       break;
    898    case RADEON_CP_PACKET3_CNTL_SMALLTEXT:
    899       if (NORMAL)
    900 	 fprintf(stderr, "PACKET3_CNTL_SMALLTEXT, %d dwords\n", cmdsz);
    901       break;
    902    case RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT:
    903       if (NORMAL)
    904 	 fprintf(stderr, "PACKET3_CNTL_HOSTDATA_BLT, %d dwords\n",
    905 	      cmdsz);
    906       break;
    907    case RADEON_CP_PACKET3_CNTL_POLYLINE:
    908       if (NORMAL)
    909 	 fprintf(stderr, "PACKET3_CNTL_POLYLINE, %d dwords\n", cmdsz);
    910       break;
    911    case RADEON_CP_PACKET3_CNTL_POLYSCANLINES:
    912       if (NORMAL)
    913 	 fprintf(stderr, "PACKET3_CNTL_POLYSCANLINES, %d dwords\n",
    914 	      cmdsz);
    915       break;
    916    case RADEON_CP_PACKET3_CNTL_PAINT_MULTI:
    917       if (NORMAL)
    918 	 fprintf(stderr, "PACKET3_CNTL_PAINT_MULTI, %d dwords\n",
    919 	      cmdsz);
    920       break;
    921    case RADEON_CP_PACKET3_CNTL_BITBLT_MULTI:
    922       if (NORMAL)
    923 	 fprintf(stderr, "PACKET3_CNTL_BITBLT_MULTI, %d dwords\n",
    924 	      cmdsz);
    925       break;
    926    case RADEON_CP_PACKET3_CNTL_TRANS_BITBLT:
    927       if (NORMAL)
    928 	 fprintf(stderr, "PACKET3_CNTL_TRANS_BITBLT, %d dwords\n",
    929 	      cmdsz);
    930       break;
    931    default:
    932       fprintf(stderr, "UNKNOWN PACKET, %d dwords\n", cmdsz);
    933       break;
    934    }
    935 
    936    cmdbuf->buf += cmdsz * 4;
    937    cmdbuf->bufsz -= cmdsz * 4;
    938    return 0;
    939 }
    940 
    941 
    942 /* Check cliprects for bounds, then pass on to above:
    943  */
    944 static int radeon_emit_packet3_cliprect( drm_radeon_cmd_buffer_t *cmdbuf )
    945 {
    946    drm_clip_rect_t *boxes = cmdbuf->boxes;
    947    int i = 0;
    948 
    949    if (VERBOSE && total_changed) {
    950       dump_state();
    951       total_changed = 0;
    952    }
    953    else fprintf(stderr, "total_changed zero\n");
    954 
    955    if (NORMAL) {
    956       do {
    957 	 if ( i < cmdbuf->nbox ) {
    958 	    fprintf(stderr, "Emit box %d/%d %d,%d %d,%d\n",
    959 		    i, cmdbuf->nbox,
    960 		    boxes[i].x1, boxes[i].y1, boxes[i].x2, boxes[i].y2);
    961 	 }
    962       } while ( ++i < cmdbuf->nbox );
    963    }
    964 
    965    if (cmdbuf->nbox == 1)
    966       cmdbuf->nbox = 0;
    967 
    968    return radeon_emit_packet3( cmdbuf );
    969 }
    970 
    971 
    972 int radeonSanityCmdBuffer( r100ContextPtr rmesa,
    973 			   int nbox,
    974 			   drm_clip_rect_t *boxes )
    975 {
    976    int idx;
    977    drm_radeon_cmd_buffer_t cmdbuf;
    978    drm_radeon_cmd_header_t header;
    979    static int inited = 0;
    980 
    981    if (!inited) {
    982       init_regs();
    983       inited = 1;
    984    }
    985 
    986    cmdbuf.buf = rmesa->store.cmd_buf;
    987    cmdbuf.bufsz = rmesa->store.cmd_used;
    988    cmdbuf.boxes = boxes;
    989    cmdbuf.nbox = nbox;
    990 
    991    while ( cmdbuf.bufsz >= sizeof(header) ) {
    992 
    993       header.i = *(int *)cmdbuf.buf;
    994       cmdbuf.buf += sizeof(header);
    995       cmdbuf.bufsz -= sizeof(header);
    996 
    997       switch (header.header.cmd_type) {
    998       case RADEON_CMD_PACKET:
    999 	 if (radeon_emit_packets( header, &cmdbuf )) {
   1000 	    fprintf(stderr,"radeon_emit_packets failed\n");
   1001 	    return -EINVAL;
   1002 	 }
   1003 	 break;
   1004 
   1005       case RADEON_CMD_SCALARS:
   1006 	 if (radeon_emit_scalars( header, &cmdbuf )) {
   1007 	    fprintf(stderr,"radeon_emit_scalars failed\n");
   1008 	    return -EINVAL;
   1009 	 }
   1010 	 break;
   1011 
   1012       case RADEON_CMD_SCALARS2:
   1013 	 if (radeon_emit_scalars2( header, &cmdbuf )) {
   1014 	    fprintf(stderr,"radeon_emit_scalars failed\n");
   1015 	    return -EINVAL;
   1016 	 }
   1017 	 break;
   1018 
   1019       case RADEON_CMD_VECTORS:
   1020 	 if (radeon_emit_vectors( header, &cmdbuf )) {
   1021 	    fprintf(stderr,"radeon_emit_vectors failed\n");
   1022 	    return -EINVAL;
   1023 	 }
   1024 	 break;
   1025 
   1026       case RADEON_CMD_DMA_DISCARD:
   1027 	 idx = header.dma.buf_idx;
   1028 	 if (NORMAL)
   1029 	    fprintf(stderr, "RADEON_CMD_DMA_DISCARD buf %d\n", idx);
   1030 	 bufs++;
   1031 	 break;
   1032 
   1033       case RADEON_CMD_PACKET3:
   1034 	 if (radeon_emit_packet3( &cmdbuf )) {
   1035 	    fprintf(stderr,"radeon_emit_packet3 failed\n");
   1036 	    return -EINVAL;
   1037 	 }
   1038 	 break;
   1039 
   1040       case RADEON_CMD_PACKET3_CLIP:
   1041 	 if (radeon_emit_packet3_cliprect( &cmdbuf )) {
   1042 	    fprintf(stderr,"radeon_emit_packet3_clip failed\n");
   1043 	    return -EINVAL;
   1044 	 }
   1045 	 break;
   1046 
   1047       case RADEON_CMD_WAIT:
   1048 	 break;
   1049 
   1050       default:
   1051 	 fprintf(stderr,"bad cmd_type %d at %p\n",
   1052 		   header.header.cmd_type,
   1053 		   cmdbuf.buf - sizeof(header));
   1054 	 return -EINVAL;
   1055       }
   1056    }
   1057 
   1058    if (0)
   1059    {
   1060       static int n = 0;
   1061       n++;
   1062       if (n == 10) {
   1063 	 fprintf(stderr, "Bufs %d Total emitted %d real changes %d (%.2f%%)\n",
   1064 		 bufs,
   1065 		 total, total_changed,
   1066 		 ((float)total_changed/(float)total*100.0));
   1067 	 fprintf(stderr, "Total emitted per buf: %.2f\n",
   1068 		 (float)total/(float)bufs);
   1069 	 fprintf(stderr, "Real changes per buf: %.2f\n",
   1070 		 (float)total_changed/(float)bufs);
   1071 
   1072 	 bufs = n = total = total_changed = 0;
   1073       }
   1074    }
   1075 
   1076    return 0;
   1077 }
   1078