1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_sanity.c,v 1.1 2002/10/30 12:51:55 alanh Exp $ */
2 /**************************************************************************
4 Copyright 2002 ATI Technologies Inc., Ontario, Canada, and
5 Tungsten Graphics Inc, Cedar Park, TX.
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the "Software"),
11 to deal in the Software without restriction, including without limitation
12 on the rights to use, copy, modify, merge, publish, distribute, sub
13 license, and/or sell copies of the Software, and to permit persons to whom
14 the Software is furnished to do so, subject to the following conditions:
16 The above copyright notice and this permission notice (including the next
17 paragraph) shall be included in all copies or substantial portions of the
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
23 ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
24 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
25 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
26 USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Keith Whitwell <keith@tungstengraphics.com>
39 #include "radeon_context.h"
40 #include "radeon_ioctl.h"
41 #include "radeon_sanity.h"
43 /* Set this '1' to get more verbiage.
45 #define MORE_VERBOSE 1
48 #define VERBOSE (RADEON_DEBUG & DEBUG_VERBOSE)
52 #define NORMAL (RADEON_DEBUG & DEBUG_VERBOSE)
56 /* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in
57 * 1.3 cmdbuffers allow all previous state to be updated as well as
58 * the tcl scalar and vector areas.
64 } packet
[RADEON_MAX_STATE_PACKETS
] = {
65 { RADEON_PP_MISC
,7,"RADEON_PP_MISC" },
66 { RADEON_PP_CNTL
,3,"RADEON_PP_CNTL" },
67 { RADEON_RB3D_COLORPITCH
,1,"RADEON_RB3D_COLORPITCH" },
68 { RADEON_RE_LINE_PATTERN
,2,"RADEON_RE_LINE_PATTERN" },
69 { RADEON_SE_LINE_WIDTH
,1,"RADEON_SE_LINE_WIDTH" },
70 { RADEON_PP_LUM_MATRIX
,1,"RADEON_PP_LUM_MATRIX" },
71 { RADEON_PP_ROT_MATRIX_0
,2,"RADEON_PP_ROT_MATRIX_0" },
72 { RADEON_RB3D_STENCILREFMASK
,3,"RADEON_RB3D_STENCILREFMASK" },
73 { RADEON_SE_VPORT_XSCALE
,6,"RADEON_SE_VPORT_XSCALE" },
74 { RADEON_SE_CNTL
,2,"RADEON_SE_CNTL" },
75 { RADEON_SE_CNTL_STATUS
,1,"RADEON_SE_CNTL_STATUS" },
76 { RADEON_RE_MISC
,1,"RADEON_RE_MISC" },
77 { RADEON_PP_TXFILTER_0
,6,"RADEON_PP_TXFILTER_0" },
78 { RADEON_PP_BORDER_COLOR_0
,1,"RADEON_PP_BORDER_COLOR_0" },
79 { RADEON_PP_TXFILTER_1
,6,"RADEON_PP_TXFILTER_1" },
80 { RADEON_PP_BORDER_COLOR_1
,1,"RADEON_PP_BORDER_COLOR_1" },
81 { RADEON_PP_TXFILTER_2
,6,"RADEON_PP_TXFILTER_2" },
82 { RADEON_PP_BORDER_COLOR_2
,1,"RADEON_PP_BORDER_COLOR_2" },
83 { RADEON_SE_ZBIAS_FACTOR
,2,"RADEON_SE_ZBIAS_FACTOR" },
84 { RADEON_SE_TCL_OUTPUT_VTX_FMT
,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" },
85 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED
,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" },
86 { 0, 4, "R200_PP_TXCBLEND_0" },
87 { 0, 4, "R200_PP_TXCBLEND_1" },
88 { 0, 4, "R200_PP_TXCBLEND_2" },
89 { 0, 4, "R200_PP_TXCBLEND_3" },
90 { 0, 4, "R200_PP_TXCBLEND_4" },
91 { 0, 4, "R200_PP_TXCBLEND_5" },
92 { 0, 4, "R200_PP_TXCBLEND_6" },
93 { 0, 4, "R200_PP_TXCBLEND_7" },
94 { 0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" },
95 { 0, 6, "R200_PP_TFACTOR_0" },
96 { 0, 4, "R200_SE_VTX_FMT_0" },
97 { 0, 1, "R200_SE_VAP_CNTL" },
98 { 0, 5, "R200_SE_TCL_MATRIX_SEL_0" },
99 { 0, 5, "R200_SE_TCL_TEX_PROC_CTL_2" },
100 { 0, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" },
101 { 0, 6, "R200_PP_TXFILTER_0" },
102 { 0, 6, "R200_PP_TXFILTER_1" },
103 { 0, 6, "R200_PP_TXFILTER_2" },
104 { 0, 6, "R200_PP_TXFILTER_3" },
105 { 0, 6, "R200_PP_TXFILTER_4" },
106 { 0, 6, "R200_PP_TXFILTER_5" },
107 { 0, 1, "R200_PP_TXOFFSET_0" },
108 { 0, 1, "R200_PP_TXOFFSET_1" },
109 { 0, 1, "R200_PP_TXOFFSET_2" },
110 { 0, 1, "R200_PP_TXOFFSET_3" },
111 { 0, 1, "R200_PP_TXOFFSET_4" },
112 { 0, 1, "R200_PP_TXOFFSET_5" },
113 { 0, 1, "R200_SE_VTE_CNTL" },
114 { 0, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" },
115 { 0, 1, "R200_PP_TAM_DEBUG3" },
116 { 0, 1, "R200_PP_CNTL_X" },
117 { 0, 1, "R200_RB3D_DEPTHXY_OFFSET" },
118 { 0, 1, "R200_RE_AUX_SCISSOR_CNTL" },
119 { 0, 2, "R200_RE_SCISSOR_TL_0" },
120 { 0, 2, "R200_RE_SCISSOR_TL_1" },
121 { 0, 2, "R200_RE_SCISSOR_TL_2" },
122 { 0, 1, "R200_SE_VAP_CNTL_STATUS" },
123 { 0, 1, "R200_SE_VTX_STATE_CNTL" },
124 { 0, 1, "R200_RE_POINTSIZE" },
125 { 0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" },
126 { 0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */
127 { 0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */
128 { 0, 1, "R200_PP_CUBIC_FACES_1" },
129 { 0, 5, "R200_PP_CUBIC_OFFSET_F1_1" },
130 { 0, 1, "R200_PP_CUBIC_FACES_2" },
131 { 0, 5, "R200_PP_CUBIC_OFFSET_F1_2" },
132 { 0, 1, "R200_PP_CUBIC_FACES_3" },
133 { 0, 5, "R200_PP_CUBIC_OFFSET_F1_3" },
134 { 0, 1, "R200_PP_CUBIC_FACES_4" },
135 { 0, 5, "R200_PP_CUBIC_OFFSET_F1_4" },
136 { 0, 1, "R200_PP_CUBIC_FACES_5" },
137 { 0, 5, "R200_PP_CUBIC_OFFSET_F1_5" },
138 { RADEON_PP_TEX_SIZE_0
, 2, "RADEON_PP_TEX_SIZE_0" },
139 { RADEON_PP_TEX_SIZE_1
, 2, "RADEON_PP_TEX_SIZE_1" },
140 { RADEON_PP_TEX_SIZE_2
, 2, "RADEON_PP_TEX_SIZE_2" },
141 { 0, 3, "R200_RB3D_BLENDCOLOR" },
142 { 0, 1, "R200_SE_TCL_POINT_SPRITE_CNTL" },
151 static struct reg_names reg_names
[] = {
152 { RADEON_PP_MISC
, "RADEON_PP_MISC" },
153 { RADEON_PP_FOG_COLOR
, "RADEON_PP_FOG_COLOR" },
154 { RADEON_RE_SOLID_COLOR
, "RADEON_RE_SOLID_COLOR" },
155 { RADEON_RB3D_BLENDCNTL
, "RADEON_RB3D_BLENDCNTL" },
156 { RADEON_RB3D_DEPTHOFFSET
, "RADEON_RB3D_DEPTHOFFSET" },
157 { RADEON_RB3D_DEPTHPITCH
, "RADEON_RB3D_DEPTHPITCH" },
158 { RADEON_RB3D_ZSTENCILCNTL
, "RADEON_RB3D_ZSTENCILCNTL" },
159 { RADEON_PP_CNTL
, "RADEON_PP_CNTL" },
160 { RADEON_RB3D_CNTL
, "RADEON_RB3D_CNTL" },
161 { RADEON_RB3D_COLOROFFSET
, "RADEON_RB3D_COLOROFFSET" },
162 { RADEON_RB3D_COLORPITCH
, "RADEON_RB3D_COLORPITCH" },
163 { RADEON_SE_CNTL
, "RADEON_SE_CNTL" },
164 { RADEON_SE_COORD_FMT
, "RADEON_SE_COORDFMT" },
165 { RADEON_SE_CNTL_STATUS
, "RADEON_SE_CNTL_STATUS" },
166 { RADEON_RE_LINE_PATTERN
, "RADEON_RE_LINE_PATTERN" },
167 { RADEON_RE_LINE_STATE
, "RADEON_RE_LINE_STATE" },
168 { RADEON_SE_LINE_WIDTH
, "RADEON_SE_LINE_WIDTH" },
169 { RADEON_RB3D_STENCILREFMASK
, "RADEON_RB3D_STENCILREFMASK" },
170 { RADEON_RB3D_ROPCNTL
, "RADEON_RB3D_ROPCNTL" },
171 { RADEON_RB3D_PLANEMASK
, "RADEON_RB3D_PLANEMASK" },
172 { RADEON_SE_VPORT_XSCALE
, "RADEON_SE_VPORT_XSCALE" },
173 { RADEON_SE_VPORT_XOFFSET
, "RADEON_SE_VPORT_XOFFSET" },
174 { RADEON_SE_VPORT_YSCALE
, "RADEON_SE_VPORT_YSCALE" },
175 { RADEON_SE_VPORT_YOFFSET
, "RADEON_SE_VPORT_YOFFSET" },
176 { RADEON_SE_VPORT_ZSCALE
, "RADEON_SE_VPORT_ZSCALE" },
177 { RADEON_SE_VPORT_ZOFFSET
, "RADEON_SE_VPORT_ZOFFSET" },
178 { RADEON_RE_MISC
, "RADEON_RE_MISC" },
179 { RADEON_PP_TXFILTER_0
, "RADEON_PP_TXFILTER_0" },
180 { RADEON_PP_TXFILTER_1
, "RADEON_PP_TXFILTER_1" },
181 { RADEON_PP_TXFILTER_2
, "RADEON_PP_TXFILTER_2" },
182 { RADEON_PP_TXFORMAT_0
, "RADEON_PP_TXFORMAT_0" },
183 { RADEON_PP_TXFORMAT_1
, "RADEON_PP_TXFORMAT_1" },
184 { RADEON_PP_TXFORMAT_2
, "RADEON_PP_TXFORMAT_2" },
185 { RADEON_PP_TXOFFSET_0
, "RADEON_PP_TXOFFSET_0" },
186 { RADEON_PP_TXOFFSET_1
, "RADEON_PP_TXOFFSET_1" },
187 { RADEON_PP_TXOFFSET_2
, "RADEON_PP_TXOFFSET_2" },
188 { RADEON_PP_TXCBLEND_0
, "RADEON_PP_TXCBLEND_0" },
189 { RADEON_PP_TXCBLEND_1
, "RADEON_PP_TXCBLEND_1" },
190 { RADEON_PP_TXCBLEND_2
, "RADEON_PP_TXCBLEND_2" },
191 { RADEON_PP_TXABLEND_0
, "RADEON_PP_TXABLEND_0" },
192 { RADEON_PP_TXABLEND_1
, "RADEON_PP_TXABLEND_1" },
193 { RADEON_PP_TXABLEND_2
, "RADEON_PP_TXABLEND_2" },
194 { RADEON_PP_TFACTOR_0
, "RADEON_PP_TFACTOR_0" },
195 { RADEON_PP_TFACTOR_1
, "RADEON_PP_TFACTOR_1" },
196 { RADEON_PP_TFACTOR_2
, "RADEON_PP_TFACTOR_2" },
197 { RADEON_PP_BORDER_COLOR_0
, "RADEON_PP_BORDER_COLOR_0" },
198 { RADEON_PP_BORDER_COLOR_1
, "RADEON_PP_BORDER_COLOR_1" },
199 { RADEON_PP_BORDER_COLOR_2
, "RADEON_PP_BORDER_COLOR_2" },
200 { RADEON_SE_ZBIAS_FACTOR
, "RADEON_SE_ZBIAS_FACTOR" },
201 { RADEON_SE_ZBIAS_CONSTANT
, "RADEON_SE_ZBIAS_CONSTANT" },
202 { RADEON_SE_TCL_OUTPUT_VTX_FMT
, "RADEON_SE_TCL_OUTPUT_VTXFMT" },
203 { RADEON_SE_TCL_OUTPUT_VTX_SEL
, "RADEON_SE_TCL_OUTPUT_VTXSEL" },
204 { RADEON_SE_TCL_MATRIX_SELECT_0
, "RADEON_SE_TCL_MATRIX_SELECT_0" },
205 { RADEON_SE_TCL_MATRIX_SELECT_1
, "RADEON_SE_TCL_MATRIX_SELECT_1" },
206 { RADEON_SE_TCL_UCP_VERT_BLEND_CTL
, "RADEON_SE_TCL_UCP_VERT_BLEND_CTL" },
207 { RADEON_SE_TCL_TEXTURE_PROC_CTL
, "RADEON_SE_TCL_TEXTURE_PROC_CTL" },
208 { RADEON_SE_TCL_LIGHT_MODEL_CTL
, "RADEON_SE_TCL_LIGHT_MODEL_CTL" },
209 { RADEON_SE_TCL_PER_LIGHT_CTL_0
, "RADEON_SE_TCL_PER_LIGHT_CTL_0" },
210 { RADEON_SE_TCL_PER_LIGHT_CTL_1
, "RADEON_SE_TCL_PER_LIGHT_CTL_1" },
211 { RADEON_SE_TCL_PER_LIGHT_CTL_2
, "RADEON_SE_TCL_PER_LIGHT_CTL_2" },
212 { RADEON_SE_TCL_PER_LIGHT_CTL_3
, "RADEON_SE_TCL_PER_LIGHT_CTL_3" },
213 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED
, "RADEON_SE_TCL_EMMISSIVE_RED" },
214 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_GREEN
, "RADEON_SE_TCL_EMMISSIVE_GREEN" },
215 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_BLUE
, "RADEON_SE_TCL_EMMISSIVE_BLUE" },
216 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_ALPHA
, "RADEON_SE_TCL_EMMISSIVE_ALPHA" },
217 { RADEON_SE_TCL_MATERIAL_AMBIENT_RED
, "RADEON_SE_TCL_AMBIENT_RED" },
218 { RADEON_SE_TCL_MATERIAL_AMBIENT_GREEN
, "RADEON_SE_TCL_AMBIENT_GREEN" },
219 { RADEON_SE_TCL_MATERIAL_AMBIENT_BLUE
, "RADEON_SE_TCL_AMBIENT_BLUE" },
220 { RADEON_SE_TCL_MATERIAL_AMBIENT_ALPHA
, "RADEON_SE_TCL_AMBIENT_ALPHA" },
221 { RADEON_SE_TCL_MATERIAL_DIFFUSE_RED
, "RADEON_SE_TCL_DIFFUSE_RED" },
222 { RADEON_SE_TCL_MATERIAL_DIFFUSE_GREEN
, "RADEON_SE_TCL_DIFFUSE_GREEN" },
223 { RADEON_SE_TCL_MATERIAL_DIFFUSE_BLUE
, "RADEON_SE_TCL_DIFFUSE_BLUE" },
224 { RADEON_SE_TCL_MATERIAL_DIFFUSE_ALPHA
, "RADEON_SE_TCL_DIFFUSE_ALPHA" },
225 { RADEON_SE_TCL_MATERIAL_SPECULAR_RED
, "RADEON_SE_TCL_SPECULAR_RED" },
226 { RADEON_SE_TCL_MATERIAL_SPECULAR_GREEN
, "RADEON_SE_TCL_SPECULAR_GREEN" },
227 { RADEON_SE_TCL_MATERIAL_SPECULAR_BLUE
, "RADEON_SE_TCL_SPECULAR_BLUE" },
228 { RADEON_SE_TCL_MATERIAL_SPECULAR_ALPHA
, "RADEON_SE_TCL_SPECULAR_ALPHA" },
229 { RADEON_SE_TCL_SHININESS
, "RADEON_SE_TCL_SHININESS" },
230 { RADEON_SE_COORD_FMT
, "RADEON_SE_COORD_FMT" },
231 { RADEON_PP_TEX_SIZE_0
, "RADEON_PP_TEX_SIZE_0" },
232 { RADEON_PP_TEX_SIZE_1
, "RADEON_PP_TEX_SIZE_1" },
233 { RADEON_PP_TEX_SIZE_2
, "RADEON_PP_TEX_SIZE_2" },
234 { RADEON_PP_TEX_SIZE_0
+4, "RADEON_PP_TEX_PITCH_0" },
235 { RADEON_PP_TEX_SIZE_1
+4, "RADEON_PP_TEX_PITCH_1" },
236 { RADEON_PP_TEX_SIZE_2
+4, "RADEON_PP_TEX_PITCH_2" },
239 static struct reg_names scalar_names
[] = {
240 { RADEON_SS_LIGHT_DCD_ADDR
, "LIGHT_DCD" },
241 { RADEON_SS_LIGHT_SPOT_EXPONENT_ADDR
, "LIGHT_SPOT_EXPONENT" },
242 { RADEON_SS_LIGHT_SPOT_CUTOFF_ADDR
, "LIGHT_SPOT_CUTOFF" },
243 { RADEON_SS_LIGHT_SPECULAR_THRESH_ADDR
, "LIGHT_SPECULAR_THRESH" },
244 { RADEON_SS_LIGHT_RANGE_CUTOFF_ADDR
, "LIGHT_RANGE_CUTOFF" },
245 { RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR
, "VERT_GUARD_CLIP" },
246 { RADEON_SS_VERT_GUARD_DISCARD_ADJ_ADDR
, "VERT_GUARD_DISCARD" },
247 { RADEON_SS_HORZ_GUARD_CLIP_ADJ_ADDR
, "HORZ_GUARD_CLIP" },
248 { RADEON_SS_HORZ_GUARD_DISCARD_ADJ_ADDR
, "HORZ_GUARD_DISCARD" },
249 { RADEON_SS_SHININESS
, "SHININESS" },
253 /* Puff these out to make them look like normal (dword) registers.
255 static struct reg_names vector_names
[] = {
256 { RADEON_VS_MATRIX_0_ADDR
* 4, "MATRIX_0" },
257 { RADEON_VS_MATRIX_1_ADDR
* 4, "MATRIX_1" },
258 { RADEON_VS_MATRIX_2_ADDR
* 4, "MATRIX_2" },
259 { RADEON_VS_MATRIX_3_ADDR
* 4, "MATRIX_3" },
260 { RADEON_VS_MATRIX_4_ADDR
* 4, "MATRIX_4" },
261 { RADEON_VS_MATRIX_5_ADDR
* 4, "MATRIX_5" },
262 { RADEON_VS_MATRIX_6_ADDR
* 4, "MATRIX_6" },
263 { RADEON_VS_MATRIX_7_ADDR
* 4, "MATRIX_7" },
264 { RADEON_VS_MATRIX_8_ADDR
* 4, "MATRIX_8" },
265 { RADEON_VS_MATRIX_9_ADDR
* 4, "MATRIX_9" },
266 { RADEON_VS_MATRIX_10_ADDR
* 4, "MATRIX_10" },
267 { RADEON_VS_MATRIX_11_ADDR
* 4, "MATRIX_11" },
268 { RADEON_VS_MATRIX_12_ADDR
* 4, "MATRIX_12" },
269 { RADEON_VS_MATRIX_13_ADDR
* 4, "MATRIX_13" },
270 { RADEON_VS_MATRIX_14_ADDR
* 4, "MATRIX_14" },
271 { RADEON_VS_MATRIX_15_ADDR
* 4, "MATRIX_15" },
272 { RADEON_VS_LIGHT_AMBIENT_ADDR
* 4, "LIGHT_AMBIENT" },
273 { RADEON_VS_LIGHT_DIFFUSE_ADDR
* 4, "LIGHT_DIFFUSE" },
274 { RADEON_VS_LIGHT_SPECULAR_ADDR
* 4, "LIGHT_SPECULAR" },
275 { RADEON_VS_LIGHT_DIRPOS_ADDR
* 4, "LIGHT_DIRPOS" },
276 { RADEON_VS_LIGHT_HWVSPOT_ADDR
* 4, "LIGHT_HWVSPOT" },
277 { RADEON_VS_LIGHT_ATTENUATION_ADDR
* 4, "LIGHT_ATTENUATION" },
278 { RADEON_VS_MATRIX_EYE2CLIP_ADDR
* 4, "MATRIX_EYE2CLIP" },
279 { RADEON_VS_UCP_ADDR
* 4, "UCP" },
280 { RADEON_VS_GLOBAL_AMBIENT_ADDR
* 4, "GLOBAL_AMBIENT" },
281 { RADEON_VS_FOG_PARAM_ADDR
* 4, "FOG_PARAM" },
282 { RADEON_VS_EYE_VECTOR_ADDR
* 4, "EYE_VECTOR" },
286 union fi
{ float f
; int i
; };
294 struct reg_names
*closest
;
304 static struct reg regs
[Elements(reg_names
)+1];
305 static struct reg scalars
[512+1];
306 static struct reg vectors
[512*4+1];
308 static int total
, total_changed
, bufs
;
310 static void init_regs( void )
312 struct reg_names
*tmp
;
315 for (i
= 0 ; i
< Elements(regs
) ; i
++) {
316 regs
[i
].idx
= reg_names
[i
].idx
;
317 regs
[i
].closest
= ®_names
[i
];
321 for (i
= 0, tmp
= scalar_names
; i
< Elements(scalars
) ; i
++) {
322 if (tmp
[1].idx
== i
) tmp
++;
324 scalars
[i
].closest
= tmp
;
325 scalars
[i
].flags
= ISFLOAT
;
328 for (i
= 0, tmp
= vector_names
; i
< Elements(vectors
) ; i
++) {
329 if (tmp
[1].idx
*4 == i
) tmp
++;
331 vectors
[i
].closest
= tmp
;
332 vectors
[i
].flags
= ISFLOAT
|ISVEC
;
335 regs
[Elements(regs
)-1].idx
= -1;
336 scalars
[Elements(scalars
)-1].idx
= -1;
337 vectors
[Elements(vectors
)-1].idx
= -1;
340 static int find_or_add_value( struct reg
*reg
, int val
)
344 for ( j
= 0 ; j
< reg
->nvalues
; j
++)
345 if ( val
== reg
->values
[j
].i
)
348 if (j
== reg
->nalloc
) {
351 reg
->values
= (union fi
*) realloc( reg
->values
,
352 reg
->nalloc
* sizeof(union fi
) );
355 reg
->values
[reg
->nvalues
++].i
= val
;
359 static struct reg
*lookup_reg( struct reg
*tab
, int reg
)
363 for (i
= 0 ; tab
[i
].idx
!= -1 ; i
++) {
364 if (tab
[i
].idx
== reg
)
368 fprintf(stderr
, "*** unknown reg 0x%x\n", reg
);
373 static const char *get_reg_name( struct reg
*reg
)
377 if (reg
->idx
== reg
->closest
->idx
)
378 return reg
->closest
->name
;
381 if (reg
->flags
& ISVEC
) {
382 if (reg
->idx
/4 != reg
->closest
->idx
)
383 sprintf(tmp
, "%s+%d[%d]",
385 (reg
->idx
/4) - reg
->closest
->idx
,
388 sprintf(tmp
, "%s[%d]", reg
->closest
->name
, reg
->idx
%4);
391 if (reg
->idx
!= reg
->closest
->idx
)
392 sprintf(tmp
, "%s+%d", reg
->closest
->name
, reg
->idx
- reg
->closest
->idx
);
394 sprintf(tmp
, "%s", reg
->closest
->name
);
400 static int print_int_reg_assignment( struct reg
*reg
, int data
)
402 int changed
= (reg
->current
.i
!= data
);
403 int ever_seen
= find_or_add_value( reg
, data
);
405 if (VERBOSE
|| (NORMAL
&& (changed
|| !ever_seen
)))
406 fprintf(stderr
, " %s <-- 0x%x", get_reg_name(reg
), data
);
410 fprintf(stderr
, " *** BRAND NEW VALUE");
412 fprintf(stderr
, " *** CHANGED");
415 reg
->current
.i
= data
;
417 if (VERBOSE
|| (NORMAL
&& (changed
|| !ever_seen
)))
418 fprintf(stderr
, "\n");
424 static int print_float_reg_assignment( struct reg
*reg
, float data
)
426 int changed
= (reg
->current
.f
!= data
);
427 int newmin
= (data
< reg
->vmin
);
428 int newmax
= (data
> reg
->vmax
);
430 if (VERBOSE
|| (NORMAL
&& (newmin
|| newmax
|| changed
)))
431 fprintf(stderr
, " %s <-- %.3f", get_reg_name(reg
), data
);
435 fprintf(stderr
, " *** NEW MIN (prev %.3f)", reg
->vmin
);
439 fprintf(stderr
, " *** NEW MAX (prev %.3f)", reg
->vmax
);
443 fprintf(stderr
, " *** CHANGED");
447 reg
->current
.f
= data
;
449 if (VERBOSE
|| (NORMAL
&& (newmin
|| newmax
|| changed
)))
450 fprintf(stderr
, "\n");
455 static int print_reg_assignment( struct reg
*reg
, int data
)
457 reg
->flags
|= TOUCHED
;
458 if (reg
->flags
& ISFLOAT
)
459 return print_float_reg_assignment( reg
, *(float *)&data
);
461 return print_int_reg_assignment( reg
, data
);
464 static void print_reg( struct reg
*reg
)
466 if (reg
->flags
& TOUCHED
) {
467 if (reg
->flags
& ISFLOAT
) {
468 fprintf(stderr
, " %s == %f\n", get_reg_name(reg
), reg
->current
.f
);
470 fprintf(stderr
, " %s == 0x%x\n", get_reg_name(reg
), reg
->current
.i
);
476 static void dump_state( void )
480 for (i
= 0 ; i
< Elements(regs
) ; i
++)
481 print_reg( ®s
[i
] );
483 for (i
= 0 ; i
< Elements(scalars
) ; i
++)
484 print_reg( &scalars
[i
] );
486 for (i
= 0 ; i
< Elements(vectors
) ; i
++)
487 print_reg( &vectors
[i
] );
492 static int radeon_emit_packets(
493 drm_radeon_cmd_header_t header
,
494 drm_radeon_cmd_buffer_t
*cmdbuf
)
496 int id
= (int)header
.packet
.packet_id
;
497 int sz
= packet
[id
].len
;
498 int *data
= (int *)cmdbuf
->buf
;
501 if (sz
* sizeof(int) > cmdbuf
->bufsz
) {
502 fprintf(stderr
, "Packet overflows cmdbuf\n");
506 if (!packet
[id
].name
) {
507 fprintf(stderr
, "*** Unknown packet 0 nr %d\n", id
);
513 fprintf(stderr
, "Packet 0 reg %s nr %d\n", packet
[id
].name
, sz
);
515 for ( i
= 0 ; i
< sz
; i
++) {
516 struct reg
*reg
= lookup_reg( regs
, packet
[id
].start
+ i
*4 );
517 if (print_reg_assignment( reg
, data
[i
] ))
522 cmdbuf
->buf
+= sz
* sizeof(int);
523 cmdbuf
->bufsz
-= sz
* sizeof(int);
528 static int radeon_emit_scalars(
529 drm_radeon_cmd_header_t header
,
530 drm_radeon_cmd_buffer_t
*cmdbuf
)
532 int sz
= header
.scalars
.count
;
533 int *data
= (int *)cmdbuf
->buf
;
534 int start
= header
.scalars
.offset
;
535 int stride
= header
.scalars
.stride
;
539 fprintf(stderr
, "emit scalars, start %d stride %d nr %d (end %d)\n",
540 start
, stride
, sz
, start
+ stride
* sz
);
543 for (i
= 0 ; i
< sz
; i
++, start
+= stride
) {
544 struct reg
*reg
= lookup_reg( scalars
, start
);
545 if (print_reg_assignment( reg
, data
[i
] ))
550 cmdbuf
->buf
+= sz
* sizeof(int);
551 cmdbuf
->bufsz
-= sz
* sizeof(int);
556 static int radeon_emit_scalars2(
557 drm_radeon_cmd_header_t header
,
558 drm_radeon_cmd_buffer_t
*cmdbuf
)
560 int sz
= header
.scalars
.count
;
561 int *data
= (int *)cmdbuf
->buf
;
562 int start
= header
.scalars
.offset
+ 0x100;
563 int stride
= header
.scalars
.stride
;
567 fprintf(stderr
, "emit scalars2, start %d stride %d nr %d (end %d)\n",
568 start
, stride
, sz
, start
+ stride
* sz
);
570 if (start
+ stride
* sz
> 257) {
571 fprintf(stderr
, "emit scalars OVERFLOW %d/%d/%d\n", start
, stride
, sz
);
575 for (i
= 0 ; i
< sz
; i
++, start
+= stride
) {
576 struct reg
*reg
= lookup_reg( scalars
, start
);
577 if (print_reg_assignment( reg
, data
[i
] ))
582 cmdbuf
->buf
+= sz
* sizeof(int);
583 cmdbuf
->bufsz
-= sz
* sizeof(int);
587 /* Check: inf/nan/extreme-size?
588 * Check: table start, end, nr, etc.
590 static int radeon_emit_vectors(
591 drm_radeon_cmd_header_t header
,
592 drm_radeon_cmd_buffer_t
*cmdbuf
)
594 int sz
= header
.vectors
.count
;
595 int *data
= (int *)cmdbuf
->buf
;
596 int start
= header
.vectors
.offset
;
597 int stride
= header
.vectors
.stride
;
601 fprintf(stderr
, "emit vectors, start %d stride %d nr %d (end %d) (0x%x)\n",
602 start
, stride
, sz
, start
+ stride
* sz
, header
.i
);
604 /* if (start + stride * (sz/4) > 128) { */
605 /* fprintf(stderr, "emit vectors OVERFLOW %d/%d/%d\n", start, stride, sz); */
609 for (i
= 0 ; i
< sz
; start
+= stride
) {
611 for (j
= 0 ; j
< 4 ; i
++,j
++) {
612 struct reg
*reg
= lookup_reg( vectors
, start
*4+j
);
613 if (print_reg_assignment( reg
, data
[i
] ))
622 cmdbuf
->buf
+= sz
* sizeof(int);
623 cmdbuf
->bufsz
-= sz
* sizeof(int);
628 static int print_vertex_format( int vfmt
)
631 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",
635 (vfmt
& RADEON_CP_VC_FRMT_Z
) ? "z," : "",
636 (vfmt
& RADEON_CP_VC_FRMT_W0
) ? "w0," : "",
637 (vfmt
& RADEON_CP_VC_FRMT_FPCOLOR
) ? "fpcolor," : "",
638 (vfmt
& RADEON_CP_VC_FRMT_FPALPHA
) ? "fpalpha," : "",
639 (vfmt
& RADEON_CP_VC_FRMT_PKCOLOR
) ? "pkcolor," : "",
640 (vfmt
& RADEON_CP_VC_FRMT_FPSPEC
) ? "fpspec," : "",
641 (vfmt
& RADEON_CP_VC_FRMT_FPFOG
) ? "fpfog," : "",
642 (vfmt
& RADEON_CP_VC_FRMT_PKSPEC
) ? "pkspec," : "",
643 (vfmt
& RADEON_CP_VC_FRMT_ST0
) ? "st0," : "",
644 (vfmt
& RADEON_CP_VC_FRMT_ST1
) ? "st1," : "",
645 (vfmt
& RADEON_CP_VC_FRMT_Q1
) ? "q1," : "",
646 (vfmt
& RADEON_CP_VC_FRMT_ST2
) ? "st2," : "",
647 (vfmt
& RADEON_CP_VC_FRMT_Q2
) ? "q2," : "",
648 (vfmt
& RADEON_CP_VC_FRMT_ST3
) ? "st3," : "",
649 (vfmt
& RADEON_CP_VC_FRMT_Q3
) ? "q3," : "",
650 (vfmt
& RADEON_CP_VC_FRMT_Q0
) ? "q0," : "",
651 (vfmt
& RADEON_CP_VC_FRMT_N0
) ? "n0," : "",
652 (vfmt
& RADEON_CP_VC_FRMT_XY1
) ? "xy1," : "",
653 (vfmt
& RADEON_CP_VC_FRMT_Z1
) ? "z1," : "",
654 (vfmt
& RADEON_CP_VC_FRMT_W1
) ? "w1," : "",
655 (vfmt
& RADEON_CP_VC_FRMT_N1
) ? "n1," : "");
658 /* if (!find_or_add_value( &others[V_VTXFMT], vfmt )) */
659 /* fprintf(stderr, " *** NEW VALUE"); */
661 fprintf(stderr
, "\n");
667 static char *primname
[0xf] = {
681 static int print_prim_and_flags( int prim
)
686 fprintf(stderr
, " %s(%x): %s%s%s%s%s%s%s\n",
689 ((prim
& 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_IND
) ? "IND," : "",
690 ((prim
& 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_LIST
) ? "LIST," : "",
691 ((prim
& 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_RING
) ? "RING," : "",
692 (prim
& RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA
) ? "RGBA," : "BGRA, ",
693 (prim
& RADEON_CP_VC_CNTL_MAOS_ENABLE
) ? "MAOS," : "",
694 (prim
& RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE
) ? "RADEON," : "",
695 (prim
& RADEON_CP_VC_CNTL_TCL_ENABLE
) ? "TCL," : "");
697 if ((prim
& 0xf) > RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST
) {
698 fprintf(stderr
, " *** Bad primitive: %x\n", prim
& 0xf);
705 fprintf(stderr
, " prim: %s numverts %d\n", primname
[prim
&0xf], numverts
);
707 switch (prim
& 0xf) {
708 case RADEON_CP_VC_CNTL_PRIM_TYPE_NONE
:
709 case RADEON_CP_VC_CNTL_PRIM_TYPE_POINT
:
711 fprintf(stderr
, "Bad nr verts for line %d\n", numverts
);
715 case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE
:
716 if ((numverts
& 1) || numverts
== 0) {
717 fprintf(stderr
, "Bad nr verts for line %d\n", numverts
);
721 case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP
:
723 fprintf(stderr
, "Bad nr verts for line_strip %d\n", numverts
);
727 case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST
:
728 case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST
:
729 case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST
:
730 case RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST
:
731 if (numverts
% 3 || numverts
== 0) {
732 fprintf(stderr
, "Bad nr verts for tri %d\n", numverts
);
736 case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN
:
737 case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP
:
739 fprintf(stderr
, "Bad nr verts for strip/fan %d\n", numverts
);
744 fprintf(stderr
, "Bad primitive\n");
750 /* build in knowledge about each packet type
752 static int radeon_emit_packet3( drm_radeon_cmd_buffer_t
*cmdbuf
)
755 int *cmd
= (int *)cmdbuf
->buf
;
757 int i
, stride
, size
, start
;
759 cmdsz
= 2 + ((cmd
[0] & RADEON_CP_PACKET_COUNT_MASK
) >> 16);
761 if ((cmd
[0] & RADEON_CP_PACKET_MASK
) != RADEON_CP_PACKET3
||
762 cmdsz
* 4 > cmdbuf
->bufsz
||
763 cmdsz
> RADEON_CP_PACKET_MAX_DWORDS
) {
764 fprintf(stderr
, "Bad packet\n");
768 switch( cmd
[0] & ~RADEON_CP_PACKET_COUNT_MASK
) {
769 case RADEON_CP_PACKET3_NOP
:
771 fprintf(stderr
, "PACKET3_NOP, %d dwords\n", cmdsz
);
773 case RADEON_CP_PACKET3_NEXT_CHAR
:
775 fprintf(stderr
, "PACKET3_NEXT_CHAR, %d dwords\n", cmdsz
);
777 case RADEON_CP_PACKET3_PLY_NEXTSCAN
:
779 fprintf(stderr
, "PACKET3_PLY_NEXTSCAN, %d dwords\n", cmdsz
);
781 case RADEON_CP_PACKET3_SET_SCISSORS
:
783 fprintf(stderr
, "PACKET3_SET_SCISSORS, %d dwords\n", cmdsz
);
785 case RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM
:
787 fprintf(stderr
, "PACKET3_3D_RNDR_GEN_INDX_PRIM, %d dwords\n",
790 case RADEON_CP_PACKET3_LOAD_MICROCODE
:
792 fprintf(stderr
, "PACKET3_LOAD_MICROCODE, %d dwords\n", cmdsz
);
794 case RADEON_CP_PACKET3_WAIT_FOR_IDLE
:
796 fprintf(stderr
, "PACKET3_WAIT_FOR_IDLE, %d dwords\n", cmdsz
);
799 case RADEON_CP_PACKET3_3D_DRAW_VBUF
:
801 fprintf(stderr
, "PACKET3_3D_DRAW_VBUF, %d dwords\n", cmdsz
);
802 print_vertex_format(cmd
[1]);
803 print_prim_and_flags(cmd
[2]);
806 case RADEON_CP_PACKET3_3D_DRAW_IMMD
:
808 fprintf(stderr
, "PACKET3_3D_DRAW_IMMD, %d dwords\n", cmdsz
);
810 case RADEON_CP_PACKET3_3D_DRAW_INDX
: {
813 fprintf(stderr
, "PACKET3_3D_DRAW_INDX, %d dwords\n", cmdsz
);
814 print_vertex_format(cmd
[1]);
815 print_prim_and_flags(cmd
[2]);
816 neltdwords
= cmd
[2]>>16;
817 neltdwords
+= neltdwords
& 1;
819 if (neltdwords
+ 3 != cmdsz
)
820 fprintf(stderr
, "Mismatch in DRAW_INDX, %d vs cmdsz %d\n",
824 case RADEON_CP_PACKET3_LOAD_PALETTE
:
826 fprintf(stderr
, "PACKET3_LOAD_PALETTE, %d dwords\n", cmdsz
);
828 case RADEON_CP_PACKET3_3D_LOAD_VBPNTR
:
830 fprintf(stderr
, "PACKET3_3D_LOAD_VBPNTR, %d dwords\n", cmdsz
);
831 fprintf(stderr
, " nr arrays: %d\n", cmd
[1]);
834 if (cmd
[1]/2 + cmd
[1]%2 != cmdsz
- 3) {
835 fprintf(stderr
, " ****** MISMATCH %d/%d *******\n",
836 cmd
[1]/2 + cmd
[1]%2 + 3, cmdsz
);
842 for (i
= 0 ; i
< cmd
[1] ; i
++) {
844 stride
= (tmp
[0]>>24) & 0xff;
845 size
= (tmp
[0]>>16) & 0xff;
850 stride
= (tmp
[0]>>8) & 0xff;
851 size
= (tmp
[0]) & 0xff;
854 fprintf(stderr
, " array %d: start 0x%x vsize %d vstride %d\n",
855 i
, start
, size
, stride
);
859 case RADEON_CP_PACKET3_CNTL_PAINT
:
861 fprintf(stderr
, "PACKET3_CNTL_PAINT, %d dwords\n", cmdsz
);
863 case RADEON_CP_PACKET3_CNTL_BITBLT
:
865 fprintf(stderr
, "PACKET3_CNTL_BITBLT, %d dwords\n", cmdsz
);
867 case RADEON_CP_PACKET3_CNTL_SMALLTEXT
:
869 fprintf(stderr
, "PACKET3_CNTL_SMALLTEXT, %d dwords\n", cmdsz
);
871 case RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT
:
873 fprintf(stderr
, "PACKET3_CNTL_HOSTDATA_BLT, %d dwords\n",
876 case RADEON_CP_PACKET3_CNTL_POLYLINE
:
878 fprintf(stderr
, "PACKET3_CNTL_POLYLINE, %d dwords\n", cmdsz
);
880 case RADEON_CP_PACKET3_CNTL_POLYSCANLINES
:
882 fprintf(stderr
, "PACKET3_CNTL_POLYSCANLINES, %d dwords\n",
885 case RADEON_CP_PACKET3_CNTL_PAINT_MULTI
:
887 fprintf(stderr
, "PACKET3_CNTL_PAINT_MULTI, %d dwords\n",
890 case RADEON_CP_PACKET3_CNTL_BITBLT_MULTI
:
892 fprintf(stderr
, "PACKET3_CNTL_BITBLT_MULTI, %d dwords\n",
895 case RADEON_CP_PACKET3_CNTL_TRANS_BITBLT
:
897 fprintf(stderr
, "PACKET3_CNTL_TRANS_BITBLT, %d dwords\n",
901 fprintf(stderr
, "UNKNOWN PACKET, %d dwords\n", cmdsz
);
905 cmdbuf
->buf
+= cmdsz
* 4;
906 cmdbuf
->bufsz
-= cmdsz
* 4;
911 /* Check cliprects for bounds, then pass on to above:
913 static int radeon_emit_packet3_cliprect( drm_radeon_cmd_buffer_t
*cmdbuf
)
915 drm_clip_rect_t
*boxes
= cmdbuf
->boxes
;
918 if (VERBOSE
&& total_changed
) {
922 else fprintf(stderr
, "total_changed zero\n");
926 if ( i
< cmdbuf
->nbox
) {
927 fprintf(stderr
, "Emit box %d/%d %d,%d %d,%d\n",
929 boxes
[i
].x1
, boxes
[i
].y1
, boxes
[i
].x2
, boxes
[i
].y2
);
931 } while ( ++i
< cmdbuf
->nbox
);
934 if (cmdbuf
->nbox
== 1)
937 return radeon_emit_packet3( cmdbuf
);
941 int radeonSanityCmdBuffer( radeonContextPtr rmesa
,
943 drm_clip_rect_t
*boxes
)
946 drm_radeon_cmd_buffer_t cmdbuf
;
947 drm_radeon_cmd_header_t header
;
948 static int inited
= 0;
955 cmdbuf
.buf
= rmesa
->store
.cmd_buf
;
956 cmdbuf
.bufsz
= rmesa
->store
.cmd_used
;
957 cmdbuf
.boxes
= boxes
;
960 while ( cmdbuf
.bufsz
>= sizeof(header
) ) {
962 header
.i
= *(int *)cmdbuf
.buf
;
963 cmdbuf
.buf
+= sizeof(header
);
964 cmdbuf
.bufsz
-= sizeof(header
);
966 switch (header
.header
.cmd_type
) {
967 case RADEON_CMD_PACKET
:
968 if (radeon_emit_packets( header
, &cmdbuf
)) {
969 fprintf(stderr
,"radeon_emit_packets failed\n");
974 case RADEON_CMD_SCALARS
:
975 if (radeon_emit_scalars( header
, &cmdbuf
)) {
976 fprintf(stderr
,"radeon_emit_scalars failed\n");
981 case RADEON_CMD_SCALARS2
:
982 if (radeon_emit_scalars2( header
, &cmdbuf
)) {
983 fprintf(stderr
,"radeon_emit_scalars failed\n");
988 case RADEON_CMD_VECTORS
:
989 if (radeon_emit_vectors( header
, &cmdbuf
)) {
990 fprintf(stderr
,"radeon_emit_vectors failed\n");
995 case RADEON_CMD_DMA_DISCARD
:
996 idx
= header
.dma
.buf_idx
;
998 fprintf(stderr
, "RADEON_CMD_DMA_DISCARD buf %d\n", idx
);
1002 case RADEON_CMD_PACKET3
:
1003 if (radeon_emit_packet3( &cmdbuf
)) {
1004 fprintf(stderr
,"radeon_emit_packet3 failed\n");
1009 case RADEON_CMD_PACKET3_CLIP
:
1010 if (radeon_emit_packet3_cliprect( &cmdbuf
)) {
1011 fprintf(stderr
,"radeon_emit_packet3_clip failed\n");
1016 case RADEON_CMD_WAIT
:
1020 fprintf(stderr
,"bad cmd_type %d at %p\n",
1021 header
.header
.cmd_type
,
1022 cmdbuf
.buf
- sizeof(header
));
1032 fprintf(stderr
, "Bufs %d Total emitted %d real changes %d (%.2f%%)\n",
1034 total
, total_changed
,
1035 ((float)total_changed
/(float)total
*100.0));
1036 fprintf(stderr
, "Total emitted per buf: %.2f\n",
1037 (float)total
/(float)bufs
);
1038 fprintf(stderr
, "Real changes per buf: %.2f\n",
1039 (float)total_changed
/(float)bufs
);
1041 bufs
= n
= total
= total_changed
= 0;