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 = ®_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( ®s[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