1 /************************************************************************** 2 3 Copyright 2002 ATI Technologies Inc., Ontario, Canada, and 4 Tungsten Graphics Inc, Cedar Park, TX. 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, TUNGSTEN GRAPHICS 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 <keith (at) tungstengraphics.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 union fi { float f; int i; }; 319 320 #define ISVEC 1 321 #define ISFLOAT 2 322 #define TOUCHED 4 323 324 struct reg { 325 int idx; 326 struct reg_names *closest; 327 int flags; 328 union fi current; 329 union fi *values; 330 int nvalues; 331 int nalloc; 332 float vmin, vmax; 333 }; 334 335 336 static struct reg regs[Elements(reg_names)+1]; 337 static struct reg scalars[512+1]; 338 static struct reg vectors[512*4+1]; 339 340 static int total, total_changed, bufs; 341 342 static void init_regs( void ) 343 { 344 struct reg_names *tmp; 345 int i; 346 347 for (i = 0 ; i < Elements(regs)-1 ; i++) { 348 regs[i].idx = reg_names[i].idx; 349 regs[i].closest = ®_names[i]; 350 regs[i].flags = 0; 351 } 352 353 for (i = 0, tmp = scalar_names ; i < Elements(scalars) ; i++) { 354 if (tmp[1].idx == i) tmp++; 355 scalars[i].idx = i; 356 scalars[i].closest = tmp; 357 scalars[i].flags = ISFLOAT; 358 } 359 360 for (i = 0, tmp = vector_names ; i < Elements(vectors) ; i++) { 361 if (tmp[1].idx*4 == i) tmp++; 362 vectors[i].idx = i; 363 vectors[i].closest = tmp; 364 vectors[i].flags = ISFLOAT|ISVEC; 365 } 366 367 regs[Elements(regs)-1].idx = -1; 368 scalars[Elements(scalars)-1].idx = -1; 369 vectors[Elements(vectors)-1].idx = -1; 370 } 371 372 static int find_or_add_value( struct reg *reg, int val ) 373 { 374 int j; 375 376 for ( j = 0 ; j < reg->nvalues ; j++) 377 if ( val == reg->values[j].i ) 378 return 1; 379 380 if (j == reg->nalloc) { 381 reg->nalloc += 5; 382 reg->nalloc *= 2; 383 reg->values = (union fi *) realloc( reg->values, 384 reg->nalloc * sizeof(union fi) ); 385 } 386 387 reg->values[reg->nvalues++].i = val; 388 return 0; 389 } 390 391 static struct reg *lookup_reg( struct reg *tab, int reg ) 392 { 393 int i; 394 395 for (i = 0 ; tab[i].idx != -1 ; i++) { 396 if (tab[i].idx == reg) 397 return &tab[i]; 398 } 399 400 fprintf(stderr, "*** unknown reg 0x%x\n", reg); 401 return NULL; 402 } 403 404 405 static const char *get_reg_name( struct reg *reg ) 406 { 407 static char tmp[80]; 408 409 if (reg->idx == reg->closest->idx) 410 return reg->closest->name; 411 412 413 if (reg->flags & ISVEC) { 414 if (reg->idx/4 != reg->closest->idx) 415 sprintf(tmp, "%s+%d[%d]", 416 reg->closest->name, 417 (reg->idx/4) - reg->closest->idx, 418 reg->idx%4); 419 else 420 sprintf(tmp, "%s[%d]", reg->closest->name, reg->idx%4); 421 } 422 else { 423 if (reg->idx != reg->closest->idx) 424 sprintf(tmp, "%s+%d", reg->closest->name, reg->idx - reg->closest->idx); 425 else 426 sprintf(tmp, "%s", reg->closest->name); 427 } 428 429 return tmp; 430 } 431 432 static int print_int_reg_assignment( struct reg *reg, int data ) 433 { 434 int changed = (reg->current.i != data); 435 int ever_seen = find_or_add_value( reg, data ); 436 437 if (VERBOSE || (NORMAL && (changed || !ever_seen))) 438 fprintf(stderr, " %s <-- 0x%x", get_reg_name(reg), data); 439 440 if (NORMAL) { 441 if (!ever_seen) 442 fprintf(stderr, " *** BRAND NEW VALUE"); 443 else if (changed) 444 fprintf(stderr, " *** CHANGED"); 445 } 446 447 reg->current.i = data; 448 449 if (VERBOSE || (NORMAL && (changed || !ever_seen))) 450 fprintf(stderr, "\n"); 451 452 return changed; 453 } 454 455 456 static int print_float_reg_assignment( struct reg *reg, float data ) 457 { 458 int changed = (reg->current.f != data); 459 int newmin = (data < reg->vmin); 460 int newmax = (data > reg->vmax); 461 462 if (VERBOSE || (NORMAL && (newmin || newmax || changed))) 463 fprintf(stderr, " %s <-- %.3f", get_reg_name(reg), data); 464 465 if (NORMAL) { 466 if (newmin) { 467 fprintf(stderr, " *** NEW MIN (prev %.3f)", reg->vmin); 468 reg->vmin = data; 469 } 470 else if (newmax) { 471 fprintf(stderr, " *** NEW MAX (prev %.3f)", reg->vmax); 472 reg->vmax = data; 473 } 474 else if (changed) { 475 fprintf(stderr, " *** CHANGED"); 476 } 477 } 478 479 reg->current.f = data; 480 481 if (VERBOSE || (NORMAL && (newmin || newmax || changed))) 482 fprintf(stderr, "\n"); 483 484 return changed; 485 } 486 487 static int print_reg_assignment( struct reg *reg, int data ) 488 { 489 float_ui32_type datau; 490 datau.ui32 = data; 491 reg->flags |= TOUCHED; 492 if (reg->flags & ISFLOAT) 493 return print_float_reg_assignment( reg, datau.f ); 494 else 495 return print_int_reg_assignment( reg, data ); 496 } 497 498 static void print_reg( struct reg *reg ) 499 { 500 if (reg->flags & TOUCHED) { 501 if (reg->flags & ISFLOAT) { 502 fprintf(stderr, " %s == %f\n", get_reg_name(reg), reg->current.f); 503 } else { 504 fprintf(stderr, " %s == 0x%x\n", get_reg_name(reg), reg->current.i); 505 } 506 } 507 } 508 509 510 static void dump_state( void ) 511 { 512 int i; 513 514 for (i = 0 ; i < Elements(regs) ; i++) 515 print_reg( ®s[i] ); 516 517 for (i = 0 ; i < Elements(scalars) ; i++) 518 print_reg( &scalars[i] ); 519 520 for (i = 0 ; i < Elements(vectors) ; i++) 521 print_reg( &vectors[i] ); 522 } 523 524 525 526 static int radeon_emit_packets( 527 drm_radeon_cmd_header_t header, 528 drm_radeon_cmd_buffer_t *cmdbuf ) 529 { 530 int id = (int)header.packet.packet_id; 531 int sz = packet[id].len; 532 int *data = (int *)cmdbuf->buf; 533 int i; 534 535 if (sz * sizeof(int) > cmdbuf->bufsz) { 536 fprintf(stderr, "Packet overflows cmdbuf\n"); 537 return -EINVAL; 538 } 539 540 if (!packet[id].name) { 541 fprintf(stderr, "*** Unknown packet 0 nr %d\n", id ); 542 return -EINVAL; 543 } 544 545 546 if (VERBOSE) 547 fprintf(stderr, "Packet 0 reg %s nr %d\n", packet[id].name, sz ); 548 549 for ( i = 0 ; i < sz ; i++) { 550 struct reg *reg = lookup_reg( regs, packet[id].start + i*4 ); 551 if (print_reg_assignment( reg, data[i] )) 552 total_changed++; 553 total++; 554 } 555 556 cmdbuf->buf += sz * sizeof(int); 557 cmdbuf->bufsz -= sz * sizeof(int); 558 return 0; 559 } 560 561 562 static int radeon_emit_scalars( 563 drm_radeon_cmd_header_t header, 564 drm_radeon_cmd_buffer_t *cmdbuf ) 565 { 566 int sz = header.scalars.count; 567 int *data = (int *)cmdbuf->buf; 568 int start = header.scalars.offset; 569 int stride = header.scalars.stride; 570 int i; 571 572 if (VERBOSE) 573 fprintf(stderr, "emit scalars, start %d stride %d nr %d (end %d)\n", 574 start, stride, sz, start + stride * sz); 575 576 577 for (i = 0 ; i < sz ; i++, start += stride) { 578 struct reg *reg = lookup_reg( scalars, start ); 579 if (print_reg_assignment( reg, data[i] )) 580 total_changed++; 581 total++; 582 } 583 584 cmdbuf->buf += sz * sizeof(int); 585 cmdbuf->bufsz -= sz * sizeof(int); 586 return 0; 587 } 588 589 590 static int radeon_emit_scalars2( 591 drm_radeon_cmd_header_t header, 592 drm_radeon_cmd_buffer_t *cmdbuf ) 593 { 594 int sz = header.scalars.count; 595 int *data = (int *)cmdbuf->buf; 596 int start = header.scalars.offset + 0x100; 597 int stride = header.scalars.stride; 598 int i; 599 600 if (VERBOSE) 601 fprintf(stderr, "emit scalars2, start %d stride %d nr %d (end %d)\n", 602 start, stride, sz, start + stride * sz); 603 604 if (start + stride * sz > 257) { 605 fprintf(stderr, "emit scalars OVERFLOW %d/%d/%d\n", start, stride, sz); 606 return -1; 607 } 608 609 for (i = 0 ; i < sz ; i++, start += stride) { 610 struct reg *reg = lookup_reg( scalars, start ); 611 if (print_reg_assignment( reg, data[i] )) 612 total_changed++; 613 total++; 614 } 615 616 cmdbuf->buf += sz * sizeof(int); 617 cmdbuf->bufsz -= sz * sizeof(int); 618 return 0; 619 } 620 621 /* Check: inf/nan/extreme-size? 622 * Check: table start, end, nr, etc. 623 */ 624 static int radeon_emit_vectors( 625 drm_radeon_cmd_header_t header, 626 drm_radeon_cmd_buffer_t *cmdbuf ) 627 { 628 int sz = header.vectors.count; 629 int *data = (int *)cmdbuf->buf; 630 int start = header.vectors.offset; 631 int stride = header.vectors.stride; 632 int i,j; 633 634 if (VERBOSE) 635 fprintf(stderr, "emit vectors, start %d stride %d nr %d (end %d) (0x%x)\n", 636 start, stride, sz, start + stride * sz, header.i); 637 638 /* if (start + stride * (sz/4) > 128) { */ 639 /* fprintf(stderr, "emit vectors OVERFLOW %d/%d/%d\n", start, stride, sz); */ 640 /* return -1; */ 641 /* } */ 642 643 for (i = 0 ; i < sz ; start += stride) { 644 int changed = 0; 645 for (j = 0 ; j < 4 ; i++,j++) { 646 struct reg *reg = lookup_reg( vectors, start*4+j ); 647 if (print_reg_assignment( reg, data[i] )) 648 changed = 1; 649 } 650 if (changed) 651 total_changed += 4; 652 total += 4; 653 } 654 655 656 cmdbuf->buf += sz * sizeof(int); 657 cmdbuf->bufsz -= sz * sizeof(int); 658 return 0; 659 } 660 661 662 static int print_vertex_format( int vfmt ) 663 { 664 if (NORMAL) { 665 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", 666 "vertex format", 667 vfmt, 668 "xy,", 669 (vfmt & RADEON_CP_VC_FRMT_Z) ? "z," : "", 670 (vfmt & RADEON_CP_VC_FRMT_W0) ? "w0," : "", 671 (vfmt & RADEON_CP_VC_FRMT_FPCOLOR) ? "fpcolor," : "", 672 (vfmt & RADEON_CP_VC_FRMT_FPALPHA) ? "fpalpha," : "", 673 (vfmt & RADEON_CP_VC_FRMT_PKCOLOR) ? "pkcolor," : "", 674 (vfmt & RADEON_CP_VC_FRMT_FPSPEC) ? "fpspec," : "", 675 (vfmt & RADEON_CP_VC_FRMT_FPFOG) ? "fpfog," : "", 676 (vfmt & RADEON_CP_VC_FRMT_PKSPEC) ? "pkspec," : "", 677 (vfmt & RADEON_CP_VC_FRMT_ST0) ? "st0," : "", 678 (vfmt & RADEON_CP_VC_FRMT_ST1) ? "st1," : "", 679 (vfmt & RADEON_CP_VC_FRMT_Q1) ? "q1," : "", 680 (vfmt & RADEON_CP_VC_FRMT_ST2) ? "st2," : "", 681 (vfmt & RADEON_CP_VC_FRMT_Q2) ? "q2," : "", 682 (vfmt & RADEON_CP_VC_FRMT_ST3) ? "st3," : "", 683 (vfmt & RADEON_CP_VC_FRMT_Q3) ? "q3," : "", 684 (vfmt & RADEON_CP_VC_FRMT_Q0) ? "q0," : "", 685 (vfmt & RADEON_CP_VC_FRMT_N0) ? "n0," : "", 686 (vfmt & RADEON_CP_VC_FRMT_XY1) ? "xy1," : "", 687 (vfmt & RADEON_CP_VC_FRMT_Z1) ? "z1," : "", 688 (vfmt & RADEON_CP_VC_FRMT_W1) ? "w1," : "", 689 (vfmt & RADEON_CP_VC_FRMT_N1) ? "n1," : ""); 690 691 692 /* if (!find_or_add_value( &others[V_VTXFMT], vfmt )) */ 693 /* fprintf(stderr, " *** NEW VALUE"); */ 694 695 fprintf(stderr, "\n"); 696 } 697 698 return 0; 699 } 700 701 static char *primname[0xf] = { 702 "NONE", 703 "POINTS", 704 "LINES", 705 "LINE_STRIP", 706 "TRIANGLES", 707 "TRIANGLE_FAN", 708 "TRIANGLE_STRIP", 709 "TRI_TYPE_2", 710 "RECT_LIST", 711 "3VRT_POINTS", 712 "3VRT_LINES", 713 }; 714 715 static int print_prim_and_flags( int prim ) 716 { 717 int numverts; 718 719 if (NORMAL) 720 fprintf(stderr, " %s(%x): %s%s%s%s%s%s%s\n", 721 "prim flags", 722 prim, 723 ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_IND) ? "IND," : "", 724 ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_LIST) ? "LIST," : "", 725 ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_RING) ? "RING," : "", 726 (prim & RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA) ? "RGBA," : "BGRA, ", 727 (prim & RADEON_CP_VC_CNTL_MAOS_ENABLE) ? "MAOS," : "", 728 (prim & RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE) ? "RADEON," : "", 729 (prim & RADEON_CP_VC_CNTL_TCL_ENABLE) ? "TCL," : ""); 730 731 if ((prim & 0xf) > RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST) { 732 fprintf(stderr, " *** Bad primitive: %x\n", prim & 0xf); 733 return -1; 734 } 735 736 numverts = prim>>16; 737 738 if (NORMAL) 739 fprintf(stderr, " prim: %s numverts %d\n", primname[prim&0xf], numverts); 740 741 switch (prim & 0xf) { 742 case RADEON_CP_VC_CNTL_PRIM_TYPE_NONE: 743 case RADEON_CP_VC_CNTL_PRIM_TYPE_POINT: 744 if (numverts < 1) { 745 fprintf(stderr, "Bad nr verts for line %d\n", numverts); 746 return -1; 747 } 748 break; 749 case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE: 750 if ((numverts & 1) || numverts == 0) { 751 fprintf(stderr, "Bad nr verts for line %d\n", numverts); 752 return -1; 753 } 754 break; 755 case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP: 756 if (numverts < 2) { 757 fprintf(stderr, "Bad nr verts for line_strip %d\n", numverts); 758 return -1; 759 } 760 break; 761 case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST: 762 case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST: 763 case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST: 764 case RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST: 765 if (numverts % 3 || numverts == 0) { 766 fprintf(stderr, "Bad nr verts for tri %d\n", numverts); 767 return -1; 768 } 769 break; 770 case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN: 771 case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP: 772 if (numverts < 3) { 773 fprintf(stderr, "Bad nr verts for strip/fan %d\n", numverts); 774 return -1; 775 } 776 break; 777 default: 778 fprintf(stderr, "Bad primitive\n"); 779 return -1; 780 } 781 return 0; 782 } 783 784 /* build in knowledge about each packet type 785 */ 786 static int radeon_emit_packet3( drm_radeon_cmd_buffer_t *cmdbuf ) 787 { 788 int cmdsz; 789 int *cmd = (int *)cmdbuf->buf; 790 int *tmp; 791 int i, stride, size, start; 792 793 cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16); 794 795 if ((cmd[0] & RADEON_CP_PACKET_MASK) != RADEON_CP_PACKET3 || 796 cmdsz * 4 > cmdbuf->bufsz || 797 cmdsz > RADEON_CP_PACKET_MAX_DWORDS) { 798 fprintf(stderr, "Bad packet\n"); 799 return -EINVAL; 800 } 801 802 switch( cmd[0] & ~RADEON_CP_PACKET_COUNT_MASK ) { 803 case RADEON_CP_PACKET3_NOP: 804 if (NORMAL) 805 fprintf(stderr, "PACKET3_NOP, %d dwords\n", cmdsz); 806 break; 807 case RADEON_CP_PACKET3_NEXT_CHAR: 808 if (NORMAL) 809 fprintf(stderr, "PACKET3_NEXT_CHAR, %d dwords\n", cmdsz); 810 break; 811 case RADEON_CP_PACKET3_PLY_NEXTSCAN: 812 if (NORMAL) 813 fprintf(stderr, "PACKET3_PLY_NEXTSCAN, %d dwords\n", cmdsz); 814 break; 815 case RADEON_CP_PACKET3_SET_SCISSORS: 816 if (NORMAL) 817 fprintf(stderr, "PACKET3_SET_SCISSORS, %d dwords\n", cmdsz); 818 break; 819 case RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM: 820 if (NORMAL) 821 fprintf(stderr, "PACKET3_3D_RNDR_GEN_INDX_PRIM, %d dwords\n", 822 cmdsz); 823 break; 824 case RADEON_CP_PACKET3_LOAD_MICROCODE: 825 if (NORMAL) 826 fprintf(stderr, "PACKET3_LOAD_MICROCODE, %d dwords\n", cmdsz); 827 break; 828 case RADEON_CP_PACKET3_WAIT_FOR_IDLE: 829 if (NORMAL) 830 fprintf(stderr, "PACKET3_WAIT_FOR_IDLE, %d dwords\n", cmdsz); 831 break; 832 833 case RADEON_CP_PACKET3_3D_DRAW_VBUF: 834 if (NORMAL) 835 fprintf(stderr, "PACKET3_3D_DRAW_VBUF, %d dwords\n", cmdsz); 836 print_vertex_format(cmd[1]); 837 print_prim_and_flags(cmd[2]); 838 break; 839 840 case RADEON_CP_PACKET3_3D_DRAW_IMMD: 841 if (NORMAL) 842 fprintf(stderr, "PACKET3_3D_DRAW_IMMD, %d dwords\n", cmdsz); 843 break; 844 case RADEON_CP_PACKET3_3D_DRAW_INDX: { 845 int neltdwords; 846 if (NORMAL) 847 fprintf(stderr, "PACKET3_3D_DRAW_INDX, %d dwords\n", cmdsz); 848 print_vertex_format(cmd[1]); 849 print_prim_and_flags(cmd[2]); 850 neltdwords = cmd[2]>>16; 851 neltdwords += neltdwords & 1; 852 neltdwords /= 2; 853 if (neltdwords + 3 != cmdsz) 854 fprintf(stderr, "Mismatch in DRAW_INDX, %d vs cmdsz %d\n", 855 neltdwords, cmdsz); 856 break; 857 } 858 case RADEON_CP_PACKET3_LOAD_PALETTE: 859 if (NORMAL) 860 fprintf(stderr, "PACKET3_LOAD_PALETTE, %d dwords\n", cmdsz); 861 break; 862 case RADEON_CP_PACKET3_3D_LOAD_VBPNTR: 863 if (NORMAL) { 864 fprintf(stderr, "PACKET3_3D_LOAD_VBPNTR, %d dwords\n", cmdsz); 865 fprintf(stderr, " nr arrays: %d\n", cmd[1]); 866 } 867 868 if (cmd[1]/2 + cmd[1]%2 != cmdsz - 3) { 869 fprintf(stderr, " ****** MISMATCH %d/%d *******\n", 870 cmd[1]/2 + cmd[1]%2 + 3, cmdsz); 871 return -EINVAL; 872 } 873 874 if (NORMAL) { 875 tmp = cmd+2; 876 for (i = 0 ; i < cmd[1] ; i++) { 877 if (i & 1) { 878 stride = (tmp[0]>>24) & 0xff; 879 size = (tmp[0]>>16) & 0xff; 880 start = tmp[2]; 881 tmp += 3; 882 } 883 else { 884 stride = (tmp[0]>>8) & 0xff; 885 size = (tmp[0]) & 0xff; 886 start = tmp[1]; 887 } 888 fprintf(stderr, " array %d: start 0x%x vsize %d vstride %d\n", 889 i, start, size, stride ); 890 } 891 } 892 break; 893 case RADEON_CP_PACKET3_CNTL_PAINT: 894 if (NORMAL) 895 fprintf(stderr, "PACKET3_CNTL_PAINT, %d dwords\n", cmdsz); 896 break; 897 case RADEON_CP_PACKET3_CNTL_BITBLT: 898 if (NORMAL) 899 fprintf(stderr, "PACKET3_CNTL_BITBLT, %d dwords\n", cmdsz); 900 break; 901 case RADEON_CP_PACKET3_CNTL_SMALLTEXT: 902 if (NORMAL) 903 fprintf(stderr, "PACKET3_CNTL_SMALLTEXT, %d dwords\n", cmdsz); 904 break; 905 case RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT: 906 if (NORMAL) 907 fprintf(stderr, "PACKET3_CNTL_HOSTDATA_BLT, %d dwords\n", 908 cmdsz); 909 break; 910 case RADEON_CP_PACKET3_CNTL_POLYLINE: 911 if (NORMAL) 912 fprintf(stderr, "PACKET3_CNTL_POLYLINE, %d dwords\n", cmdsz); 913 break; 914 case RADEON_CP_PACKET3_CNTL_POLYSCANLINES: 915 if (NORMAL) 916 fprintf(stderr, "PACKET3_CNTL_POLYSCANLINES, %d dwords\n", 917 cmdsz); 918 break; 919 case RADEON_CP_PACKET3_CNTL_PAINT_MULTI: 920 if (NORMAL) 921 fprintf(stderr, "PACKET3_CNTL_PAINT_MULTI, %d dwords\n", 922 cmdsz); 923 break; 924 case RADEON_CP_PACKET3_CNTL_BITBLT_MULTI: 925 if (NORMAL) 926 fprintf(stderr, "PACKET3_CNTL_BITBLT_MULTI, %d dwords\n", 927 cmdsz); 928 break; 929 case RADEON_CP_PACKET3_CNTL_TRANS_BITBLT: 930 if (NORMAL) 931 fprintf(stderr, "PACKET3_CNTL_TRANS_BITBLT, %d dwords\n", 932 cmdsz); 933 break; 934 default: 935 fprintf(stderr, "UNKNOWN PACKET, %d dwords\n", cmdsz); 936 break; 937 } 938 939 cmdbuf->buf += cmdsz * 4; 940 cmdbuf->bufsz -= cmdsz * 4; 941 return 0; 942 } 943 944 945 /* Check cliprects for bounds, then pass on to above: 946 */ 947 static int radeon_emit_packet3_cliprect( drm_radeon_cmd_buffer_t *cmdbuf ) 948 { 949 drm_clip_rect_t *boxes = cmdbuf->boxes; 950 int i = 0; 951 952 if (VERBOSE && total_changed) { 953 dump_state(); 954 total_changed = 0; 955 } 956 else fprintf(stderr, "total_changed zero\n"); 957 958 if (NORMAL) { 959 do { 960 if ( i < cmdbuf->nbox ) { 961 fprintf(stderr, "Emit box %d/%d %d,%d %d,%d\n", 962 i, cmdbuf->nbox, 963 boxes[i].x1, boxes[i].y1, boxes[i].x2, boxes[i].y2); 964 } 965 } while ( ++i < cmdbuf->nbox ); 966 } 967 968 if (cmdbuf->nbox == 1) 969 cmdbuf->nbox = 0; 970 971 return radeon_emit_packet3( cmdbuf ); 972 } 973 974 975 int radeonSanityCmdBuffer( r100ContextPtr rmesa, 976 int nbox, 977 drm_clip_rect_t *boxes ) 978 { 979 int idx; 980 drm_radeon_cmd_buffer_t cmdbuf; 981 drm_radeon_cmd_header_t header; 982 static int inited = 0; 983 984 if (!inited) { 985 init_regs(); 986 inited = 1; 987 } 988 989 cmdbuf.buf = rmesa->store.cmd_buf; 990 cmdbuf.bufsz = rmesa->store.cmd_used; 991 cmdbuf.boxes = boxes; 992 cmdbuf.nbox = nbox; 993 994 while ( cmdbuf.bufsz >= sizeof(header) ) { 995 996 header.i = *(int *)cmdbuf.buf; 997 cmdbuf.buf += sizeof(header); 998 cmdbuf.bufsz -= sizeof(header); 999 1000 switch (header.header.cmd_type) { 1001 case RADEON_CMD_PACKET: 1002 if (radeon_emit_packets( header, &cmdbuf )) { 1003 fprintf(stderr,"radeon_emit_packets failed\n"); 1004 return -EINVAL; 1005 } 1006 break; 1007 1008 case RADEON_CMD_SCALARS: 1009 if (radeon_emit_scalars( header, &cmdbuf )) { 1010 fprintf(stderr,"radeon_emit_scalars failed\n"); 1011 return -EINVAL; 1012 } 1013 break; 1014 1015 case RADEON_CMD_SCALARS2: 1016 if (radeon_emit_scalars2( header, &cmdbuf )) { 1017 fprintf(stderr,"radeon_emit_scalars failed\n"); 1018 return -EINVAL; 1019 } 1020 break; 1021 1022 case RADEON_CMD_VECTORS: 1023 if (radeon_emit_vectors( header, &cmdbuf )) { 1024 fprintf(stderr,"radeon_emit_vectors failed\n"); 1025 return -EINVAL; 1026 } 1027 break; 1028 1029 case RADEON_CMD_DMA_DISCARD: 1030 idx = header.dma.buf_idx; 1031 if (NORMAL) 1032 fprintf(stderr, "RADEON_CMD_DMA_DISCARD buf %d\n", idx); 1033 bufs++; 1034 break; 1035 1036 case RADEON_CMD_PACKET3: 1037 if (radeon_emit_packet3( &cmdbuf )) { 1038 fprintf(stderr,"radeon_emit_packet3 failed\n"); 1039 return -EINVAL; 1040 } 1041 break; 1042 1043 case RADEON_CMD_PACKET3_CLIP: 1044 if (radeon_emit_packet3_cliprect( &cmdbuf )) { 1045 fprintf(stderr,"radeon_emit_packet3_clip failed\n"); 1046 return -EINVAL; 1047 } 1048 break; 1049 1050 case RADEON_CMD_WAIT: 1051 break; 1052 1053 default: 1054 fprintf(stderr,"bad cmd_type %d at %p\n", 1055 header.header.cmd_type, 1056 cmdbuf.buf - sizeof(header)); 1057 return -EINVAL; 1058 } 1059 } 1060 1061 if (0) 1062 { 1063 static int n = 0; 1064 n++; 1065 if (n == 10) { 1066 fprintf(stderr, "Bufs %d Total emitted %d real changes %d (%.2f%%)\n", 1067 bufs, 1068 total, total_changed, 1069 ((float)total_changed/(float)total*100.0)); 1070 fprintf(stderr, "Total emitted per buf: %.2f\n", 1071 (float)total/(float)bufs); 1072 fprintf(stderr, "Real changes per buf: %.2f\n", 1073 (float)total_changed/(float)bufs); 1074 1075 bufs = n = total = total_changed = 0; 1076 } 1077 } 1078 1079 return 0; 1080 } 1081