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" },
149 static struct reg_names reg_names
[] = {
150 { RADEON_PP_MISC
, "RADEON_PP_MISC" },
151 { RADEON_PP_FOG_COLOR
, "RADEON_PP_FOG_COLOR" },
152 { RADEON_RE_SOLID_COLOR
, "RADEON_RE_SOLID_COLOR" },
153 { RADEON_RB3D_BLENDCNTL
, "RADEON_RB3D_BLENDCNTL" },
154 { RADEON_RB3D_DEPTHOFFSET
, "RADEON_RB3D_DEPTHOFFSET" },
155 { RADEON_RB3D_DEPTHPITCH
, "RADEON_RB3D_DEPTHPITCH" },
156 { RADEON_RB3D_ZSTENCILCNTL
, "RADEON_RB3D_ZSTENCILCNTL" },
157 { RADEON_PP_CNTL
, "RADEON_PP_CNTL" },
158 { RADEON_RB3D_CNTL
, "RADEON_RB3D_CNTL" },
159 { RADEON_RB3D_COLOROFFSET
, "RADEON_RB3D_COLOROFFSET" },
160 { RADEON_RB3D_COLORPITCH
, "RADEON_RB3D_COLORPITCH" },
161 { RADEON_SE_CNTL
, "RADEON_SE_CNTL" },
162 { RADEON_SE_COORD_FMT
, "RADEON_SE_COORDFMT" },
163 { RADEON_SE_CNTL_STATUS
, "RADEON_SE_CNTL_STATUS" },
164 { RADEON_RE_LINE_PATTERN
, "RADEON_RE_LINE_PATTERN" },
165 { RADEON_RE_LINE_STATE
, "RADEON_RE_LINE_STATE" },
166 { RADEON_SE_LINE_WIDTH
, "RADEON_SE_LINE_WIDTH" },
167 { RADEON_RB3D_STENCILREFMASK
, "RADEON_RB3D_STENCILREFMASK" },
168 { RADEON_RB3D_ROPCNTL
, "RADEON_RB3D_ROPCNTL" },
169 { RADEON_RB3D_PLANEMASK
, "RADEON_RB3D_PLANEMASK" },
170 { RADEON_SE_VPORT_XSCALE
, "RADEON_SE_VPORT_XSCALE" },
171 { RADEON_SE_VPORT_XOFFSET
, "RADEON_SE_VPORT_XOFFSET" },
172 { RADEON_SE_VPORT_YSCALE
, "RADEON_SE_VPORT_YSCALE" },
173 { RADEON_SE_VPORT_YOFFSET
, "RADEON_SE_VPORT_YOFFSET" },
174 { RADEON_SE_VPORT_ZSCALE
, "RADEON_SE_VPORT_ZSCALE" },
175 { RADEON_SE_VPORT_ZOFFSET
, "RADEON_SE_VPORT_ZOFFSET" },
176 { RADEON_RE_MISC
, "RADEON_RE_MISC" },
177 { RADEON_PP_TXFILTER_0
, "RADEON_PP_TXFILTER_0" },
178 { RADEON_PP_TXFILTER_1
, "RADEON_PP_TXFILTER_1" },
179 { RADEON_PP_TXFILTER_2
, "RADEON_PP_TXFILTER_2" },
180 { RADEON_PP_TXFORMAT_0
, "RADEON_PP_TXFORMAT_0" },
181 { RADEON_PP_TXFORMAT_1
, "RADEON_PP_TXFORMAT_1" },
182 { RADEON_PP_TXFORMAT_2
, "RADEON_PP_TXFORMAT_2" },
183 { RADEON_PP_TXOFFSET_0
, "RADEON_PP_TXOFFSET_0" },
184 { RADEON_PP_TXOFFSET_1
, "RADEON_PP_TXOFFSET_1" },
185 { RADEON_PP_TXOFFSET_2
, "RADEON_PP_TXOFFSET_2" },
186 { RADEON_PP_TXCBLEND_0
, "RADEON_PP_TXCBLEND_0" },
187 { RADEON_PP_TXCBLEND_1
, "RADEON_PP_TXCBLEND_1" },
188 { RADEON_PP_TXCBLEND_2
, "RADEON_PP_TXCBLEND_2" },
189 { RADEON_PP_TXABLEND_0
, "RADEON_PP_TXABLEND_0" },
190 { RADEON_PP_TXABLEND_1
, "RADEON_PP_TXABLEND_1" },
191 { RADEON_PP_TXABLEND_2
, "RADEON_PP_TXABLEND_2" },
192 { RADEON_PP_TFACTOR_0
, "RADEON_PP_TFACTOR_0" },
193 { RADEON_PP_TFACTOR_1
, "RADEON_PP_TFACTOR_1" },
194 { RADEON_PP_TFACTOR_2
, "RADEON_PP_TFACTOR_2" },
195 { RADEON_PP_BORDER_COLOR_0
, "RADEON_PP_BORDER_COLOR_0" },
196 { RADEON_PP_BORDER_COLOR_1
, "RADEON_PP_BORDER_COLOR_1" },
197 { RADEON_PP_BORDER_COLOR_2
, "RADEON_PP_BORDER_COLOR_2" },
198 { RADEON_SE_ZBIAS_FACTOR
, "RADEON_SE_ZBIAS_FACTOR" },
199 { RADEON_SE_ZBIAS_CONSTANT
, "RADEON_SE_ZBIAS_CONSTANT" },
200 { RADEON_SE_TCL_OUTPUT_VTX_FMT
, "RADEON_SE_TCL_OUTPUT_VTXFMT" },
201 { RADEON_SE_TCL_OUTPUT_VTX_SEL
, "RADEON_SE_TCL_OUTPUT_VTXSEL" },
202 { RADEON_SE_TCL_MATRIX_SELECT_0
, "RADEON_SE_TCL_MATRIX_SELECT_0" },
203 { RADEON_SE_TCL_MATRIX_SELECT_1
, "RADEON_SE_TCL_MATRIX_SELECT_1" },
204 { RADEON_SE_TCL_UCP_VERT_BLEND_CTL
, "RADEON_SE_TCL_UCP_VERT_BLEND_CTL" },
205 { RADEON_SE_TCL_TEXTURE_PROC_CTL
, "RADEON_SE_TCL_TEXTURE_PROC_CTL" },
206 { RADEON_SE_TCL_LIGHT_MODEL_CTL
, "RADEON_SE_TCL_LIGHT_MODEL_CTL" },
207 { RADEON_SE_TCL_PER_LIGHT_CTL_0
, "RADEON_SE_TCL_PER_LIGHT_CTL_0" },
208 { RADEON_SE_TCL_PER_LIGHT_CTL_1
, "RADEON_SE_TCL_PER_LIGHT_CTL_1" },
209 { RADEON_SE_TCL_PER_LIGHT_CTL_2
, "RADEON_SE_TCL_PER_LIGHT_CTL_2" },
210 { RADEON_SE_TCL_PER_LIGHT_CTL_3
, "RADEON_SE_TCL_PER_LIGHT_CTL_3" },
211 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED
, "RADEON_SE_TCL_EMMISSIVE_RED" },
212 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_GREEN
, "RADEON_SE_TCL_EMMISSIVE_GREEN" },
213 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_BLUE
, "RADEON_SE_TCL_EMMISSIVE_BLUE" },
214 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_ALPHA
, "RADEON_SE_TCL_EMMISSIVE_ALPHA" },
215 { RADEON_SE_TCL_MATERIAL_AMBIENT_RED
, "RADEON_SE_TCL_AMBIENT_RED" },
216 { RADEON_SE_TCL_MATERIAL_AMBIENT_GREEN
, "RADEON_SE_TCL_AMBIENT_GREEN" },
217 { RADEON_SE_TCL_MATERIAL_AMBIENT_BLUE
, "RADEON_SE_TCL_AMBIENT_BLUE" },
218 { RADEON_SE_TCL_MATERIAL_AMBIENT_ALPHA
, "RADEON_SE_TCL_AMBIENT_ALPHA" },
219 { RADEON_SE_TCL_MATERIAL_DIFFUSE_RED
, "RADEON_SE_TCL_DIFFUSE_RED" },
220 { RADEON_SE_TCL_MATERIAL_DIFFUSE_GREEN
, "RADEON_SE_TCL_DIFFUSE_GREEN" },
221 { RADEON_SE_TCL_MATERIAL_DIFFUSE_BLUE
, "RADEON_SE_TCL_DIFFUSE_BLUE" },
222 { RADEON_SE_TCL_MATERIAL_DIFFUSE_ALPHA
, "RADEON_SE_TCL_DIFFUSE_ALPHA" },
223 { RADEON_SE_TCL_MATERIAL_SPECULAR_RED
, "RADEON_SE_TCL_SPECULAR_RED" },
224 { RADEON_SE_TCL_MATERIAL_SPECULAR_GREEN
, "RADEON_SE_TCL_SPECULAR_GREEN" },
225 { RADEON_SE_TCL_MATERIAL_SPECULAR_BLUE
, "RADEON_SE_TCL_SPECULAR_BLUE" },
226 { RADEON_SE_TCL_MATERIAL_SPECULAR_ALPHA
, "RADEON_SE_TCL_SPECULAR_ALPHA" },
227 { RADEON_SE_TCL_SHININESS
, "RADEON_SE_TCL_SHININESS" },
228 { RADEON_SE_COORD_FMT
, "RADEON_SE_COORD_FMT" },
229 { RADEON_PP_TEX_SIZE_0
, "RADEON_PP_TEX_SIZE_0" },
230 { RADEON_PP_TEX_SIZE_1
, "RADEON_PP_TEX_SIZE_1" },
231 { RADEON_PP_TEX_SIZE_2
, "RADEON_PP_TEX_SIZE_2" },
232 { RADEON_PP_TEX_SIZE_0
+4, "RADEON_PP_TEX_PITCH_0" },
233 { RADEON_PP_TEX_SIZE_1
+4, "RADEON_PP_TEX_PITCH_1" },
234 { RADEON_PP_TEX_SIZE_2
+4, "RADEON_PP_TEX_PITCH_2" },
237 static struct reg_names scalar_names
[] = {
238 { RADEON_SS_LIGHT_DCD_ADDR
, "LIGHT_DCD" },
239 { RADEON_SS_LIGHT_SPOT_EXPONENT_ADDR
, "LIGHT_SPOT_EXPONENT" },
240 { RADEON_SS_LIGHT_SPOT_CUTOFF_ADDR
, "LIGHT_SPOT_CUTOFF" },
241 { RADEON_SS_LIGHT_SPECULAR_THRESH_ADDR
, "LIGHT_SPECULAR_THRESH" },
242 { RADEON_SS_LIGHT_RANGE_CUTOFF_ADDR
, "LIGHT_RANGE_CUTOFF" },
243 { RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR
, "VERT_GUARD_CLIP" },
244 { RADEON_SS_VERT_GUARD_DISCARD_ADJ_ADDR
, "VERT_GUARD_DISCARD" },
245 { RADEON_SS_HORZ_GUARD_CLIP_ADJ_ADDR
, "HORZ_GUARD_CLIP" },
246 { RADEON_SS_HORZ_GUARD_DISCARD_ADJ_ADDR
, "HORZ_GUARD_DISCARD" },
247 { RADEON_SS_SHININESS
, "SHININESS" },
251 /* Puff these out to make them look like normal (dword) registers.
253 static struct reg_names vector_names
[] = {
254 { RADEON_VS_MATRIX_0_ADDR
* 4, "MATRIX_0" },
255 { RADEON_VS_MATRIX_1_ADDR
* 4, "MATRIX_1" },
256 { RADEON_VS_MATRIX_2_ADDR
* 4, "MATRIX_2" },
257 { RADEON_VS_MATRIX_3_ADDR
* 4, "MATRIX_3" },
258 { RADEON_VS_MATRIX_4_ADDR
* 4, "MATRIX_4" },
259 { RADEON_VS_MATRIX_5_ADDR
* 4, "MATRIX_5" },
260 { RADEON_VS_MATRIX_6_ADDR
* 4, "MATRIX_6" },
261 { RADEON_VS_MATRIX_7_ADDR
* 4, "MATRIX_7" },
262 { RADEON_VS_MATRIX_8_ADDR
* 4, "MATRIX_8" },
263 { RADEON_VS_MATRIX_9_ADDR
* 4, "MATRIX_9" },
264 { RADEON_VS_MATRIX_10_ADDR
* 4, "MATRIX_10" },
265 { RADEON_VS_MATRIX_11_ADDR
* 4, "MATRIX_11" },
266 { RADEON_VS_MATRIX_12_ADDR
* 4, "MATRIX_12" },
267 { RADEON_VS_MATRIX_13_ADDR
* 4, "MATRIX_13" },
268 { RADEON_VS_MATRIX_14_ADDR
* 4, "MATRIX_14" },
269 { RADEON_VS_MATRIX_15_ADDR
* 4, "MATRIX_15" },
270 { RADEON_VS_LIGHT_AMBIENT_ADDR
* 4, "LIGHT_AMBIENT" },
271 { RADEON_VS_LIGHT_DIFFUSE_ADDR
* 4, "LIGHT_DIFFUSE" },
272 { RADEON_VS_LIGHT_SPECULAR_ADDR
* 4, "LIGHT_SPECULAR" },
273 { RADEON_VS_LIGHT_DIRPOS_ADDR
* 4, "LIGHT_DIRPOS" },
274 { RADEON_VS_LIGHT_HWVSPOT_ADDR
* 4, "LIGHT_HWVSPOT" },
275 { RADEON_VS_LIGHT_ATTENUATION_ADDR
* 4, "LIGHT_ATTENUATION" },
276 { RADEON_VS_MATRIX_EYE2CLIP_ADDR
* 4, "MATRIX_EYE2CLIP" },
277 { RADEON_VS_UCP_ADDR
* 4, "UCP" },
278 { RADEON_VS_GLOBAL_AMBIENT_ADDR
* 4, "GLOBAL_AMBIENT" },
279 { RADEON_VS_FOG_PARAM_ADDR
* 4, "FOG_PARAM" },
280 { RADEON_VS_EYE_VECTOR_ADDR
* 4, "EYE_VECTOR" },
284 union fi
{ float f
; int i
; };
292 struct reg_names
*closest
;
302 static struct reg regs
[Elements(reg_names
)+1];
303 static struct reg scalars
[512+1];
304 static struct reg vectors
[512*4+1];
306 static int total
, total_changed
, bufs
;
308 static void init_regs( void )
310 struct reg_names
*tmp
;
313 for (i
= 0 ; i
< Elements(regs
) ; i
++) {
314 regs
[i
].idx
= reg_names
[i
].idx
;
315 regs
[i
].closest
= ®_names
[i
];
319 for (i
= 0, tmp
= scalar_names
; i
< Elements(scalars
) ; i
++) {
320 if (tmp
[1].idx
== i
) tmp
++;
322 scalars
[i
].closest
= tmp
;
323 scalars
[i
].flags
= ISFLOAT
;
326 for (i
= 0, tmp
= vector_names
; i
< Elements(vectors
) ; i
++) {
327 if (tmp
[1].idx
*4 == i
) tmp
++;
329 vectors
[i
].closest
= tmp
;
330 vectors
[i
].flags
= ISFLOAT
|ISVEC
;
333 regs
[Elements(regs
)-1].idx
= -1;
334 scalars
[Elements(scalars
)-1].idx
= -1;
335 vectors
[Elements(vectors
)-1].idx
= -1;
338 static int find_or_add_value( struct reg
*reg
, int val
)
342 for ( j
= 0 ; j
< reg
->nvalues
; j
++)
343 if ( val
== reg
->values
[j
].i
)
346 if (j
== reg
->nalloc
) {
349 reg
->values
= (union fi
*) realloc( reg
->values
,
350 reg
->nalloc
* sizeof(union fi
) );
353 reg
->values
[reg
->nvalues
++].i
= val
;
357 static struct reg
*lookup_reg( struct reg
*tab
, int reg
)
361 for (i
= 0 ; tab
[i
].idx
!= -1 ; i
++) {
362 if (tab
[i
].idx
== reg
)
366 fprintf(stderr
, "*** unknown reg 0x%x\n", reg
);
371 static const char *get_reg_name( struct reg
*reg
)
375 if (reg
->idx
== reg
->closest
->idx
)
376 return reg
->closest
->name
;
379 if (reg
->flags
& ISVEC
) {
380 if (reg
->idx
/4 != reg
->closest
->idx
)
381 sprintf(tmp
, "%s+%d[%d]",
383 (reg
->idx
/4) - reg
->closest
->idx
,
386 sprintf(tmp
, "%s[%d]", reg
->closest
->name
, reg
->idx
%4);
389 if (reg
->idx
!= reg
->closest
->idx
)
390 sprintf(tmp
, "%s+%d", reg
->closest
->name
, reg
->idx
- reg
->closest
->idx
);
392 sprintf(tmp
, "%s", reg
->closest
->name
);
398 static int print_int_reg_assignment( struct reg
*reg
, int data
)
400 int changed
= (reg
->current
.i
!= data
);
401 int ever_seen
= find_or_add_value( reg
, data
);
403 if (VERBOSE
|| (NORMAL
&& (changed
|| !ever_seen
)))
404 fprintf(stderr
, " %s <-- 0x%x", get_reg_name(reg
), data
);
408 fprintf(stderr
, " *** BRAND NEW VALUE");
410 fprintf(stderr
, " *** CHANGED");
413 reg
->current
.i
= data
;
415 if (VERBOSE
|| (NORMAL
&& (changed
|| !ever_seen
)))
416 fprintf(stderr
, "\n");
422 static int print_float_reg_assignment( struct reg
*reg
, float data
)
424 int changed
= (reg
->current
.f
!= data
);
425 int newmin
= (data
< reg
->vmin
);
426 int newmax
= (data
> reg
->vmax
);
428 if (VERBOSE
|| (NORMAL
&& (newmin
|| newmax
|| changed
)))
429 fprintf(stderr
, " %s <-- %.3f", get_reg_name(reg
), data
);
433 fprintf(stderr
, " *** NEW MIN (prev %.3f)", reg
->vmin
);
437 fprintf(stderr
, " *** NEW MAX (prev %.3f)", reg
->vmax
);
441 fprintf(stderr
, " *** CHANGED");
445 reg
->current
.f
= data
;
447 if (VERBOSE
|| (NORMAL
&& (newmin
|| newmax
|| changed
)))
448 fprintf(stderr
, "\n");
453 static int print_reg_assignment( struct reg
*reg
, int data
)
455 reg
->flags
|= TOUCHED
;
456 if (reg
->flags
& ISFLOAT
)
457 return print_float_reg_assignment( reg
, *(float *)&data
);
459 return print_int_reg_assignment( reg
, data
);
462 static void print_reg( struct reg
*reg
)
464 if (reg
->flags
& TOUCHED
) {
465 if (reg
->flags
& ISFLOAT
) {
466 fprintf(stderr
, " %s == %f\n", get_reg_name(reg
), reg
->current
.f
);
468 fprintf(stderr
, " %s == 0x%x\n", get_reg_name(reg
), reg
->current
.i
);
474 static void dump_state( void )
478 for (i
= 0 ; i
< Elements(regs
) ; i
++)
479 print_reg( ®s
[i
] );
481 for (i
= 0 ; i
< Elements(scalars
) ; i
++)
482 print_reg( &scalars
[i
] );
484 for (i
= 0 ; i
< Elements(vectors
) ; i
++)
485 print_reg( &vectors
[i
] );
490 static int radeon_emit_packets(
491 drm_radeon_cmd_header_t header
,
492 drm_radeon_cmd_buffer_t
*cmdbuf
)
494 int id
= (int)header
.packet
.packet_id
;
495 int sz
= packet
[id
].len
;
496 int *data
= (int *)cmdbuf
->buf
;
499 if (sz
* sizeof(int) > cmdbuf
->bufsz
) {
500 fprintf(stderr
, "Packet overflows cmdbuf\n");
504 if (!packet
[id
].name
) {
505 fprintf(stderr
, "*** Unknown packet 0 nr %d\n", id
);
511 fprintf(stderr
, "Packet 0 reg %s nr %d\n", packet
[id
].name
, sz
);
513 for ( i
= 0 ; i
< sz
; i
++) {
514 struct reg
*reg
= lookup_reg( regs
, packet
[id
].start
+ i
*4 );
515 if (print_reg_assignment( reg
, data
[i
] ))
520 cmdbuf
->buf
+= sz
* sizeof(int);
521 cmdbuf
->bufsz
-= sz
* sizeof(int);
526 static int radeon_emit_scalars(
527 drm_radeon_cmd_header_t header
,
528 drm_radeon_cmd_buffer_t
*cmdbuf
)
530 int sz
= header
.scalars
.count
;
531 int *data
= (int *)cmdbuf
->buf
;
532 int start
= header
.scalars
.offset
;
533 int stride
= header
.scalars
.stride
;
537 fprintf(stderr
, "emit scalars, start %d stride %d nr %d (end %d)\n",
538 start
, stride
, sz
, start
+ stride
* sz
);
541 for (i
= 0 ; i
< sz
; i
++, start
+= stride
) {
542 struct reg
*reg
= lookup_reg( scalars
, start
);
543 if (print_reg_assignment( reg
, data
[i
] ))
548 cmdbuf
->buf
+= sz
* sizeof(int);
549 cmdbuf
->bufsz
-= sz
* sizeof(int);
554 static int radeon_emit_scalars2(
555 drm_radeon_cmd_header_t header
,
556 drm_radeon_cmd_buffer_t
*cmdbuf
)
558 int sz
= header
.scalars
.count
;
559 int *data
= (int *)cmdbuf
->buf
;
560 int start
= header
.scalars
.offset
+ 0x100;
561 int stride
= header
.scalars
.stride
;
565 fprintf(stderr
, "emit scalars2, start %d stride %d nr %d (end %d)\n",
566 start
, stride
, sz
, start
+ stride
* sz
);
568 if (start
+ stride
* sz
> 257) {
569 fprintf(stderr
, "emit scalars OVERFLOW %d/%d/%d\n", start
, stride
, sz
);
573 for (i
= 0 ; i
< sz
; i
++, start
+= stride
) {
574 struct reg
*reg
= lookup_reg( scalars
, start
);
575 if (print_reg_assignment( reg
, data
[i
] ))
580 cmdbuf
->buf
+= sz
* sizeof(int);
581 cmdbuf
->bufsz
-= sz
* sizeof(int);
585 /* Check: inf/nan/extreme-size?
586 * Check: table start, end, nr, etc.
588 static int radeon_emit_vectors(
589 drm_radeon_cmd_header_t header
,
590 drm_radeon_cmd_buffer_t
*cmdbuf
)
592 int sz
= header
.vectors
.count
;
593 int *data
= (int *)cmdbuf
->buf
;
594 int start
= header
.vectors
.offset
;
595 int stride
= header
.vectors
.stride
;
599 fprintf(stderr
, "emit vectors, start %d stride %d nr %d (end %d) (0x%x)\n",
600 start
, stride
, sz
, start
+ stride
* sz
, header
.i
);
602 /* if (start + stride * (sz/4) > 128) { */
603 /* fprintf(stderr, "emit vectors OVERFLOW %d/%d/%d\n", start, stride, sz); */
607 for (i
= 0 ; i
< sz
; start
+= stride
) {
609 for (j
= 0 ; j
< 4 ; i
++,j
++) {
610 struct reg
*reg
= lookup_reg( vectors
, start
*4+j
);
611 if (print_reg_assignment( reg
, data
[i
] ))
620 cmdbuf
->buf
+= sz
* sizeof(int);
621 cmdbuf
->bufsz
-= sz
* sizeof(int);
626 static int print_vertex_format( int vfmt
)
629 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",
633 (vfmt
& RADEON_CP_VC_FRMT_Z
) ? "z," : "",
634 (vfmt
& RADEON_CP_VC_FRMT_W0
) ? "w0," : "",
635 (vfmt
& RADEON_CP_VC_FRMT_FPCOLOR
) ? "fpcolor," : "",
636 (vfmt
& RADEON_CP_VC_FRMT_FPALPHA
) ? "fpalpha," : "",
637 (vfmt
& RADEON_CP_VC_FRMT_PKCOLOR
) ? "pkcolor," : "",
638 (vfmt
& RADEON_CP_VC_FRMT_FPSPEC
) ? "fpspec," : "",
639 (vfmt
& RADEON_CP_VC_FRMT_FPFOG
) ? "fpfog," : "",
640 (vfmt
& RADEON_CP_VC_FRMT_PKSPEC
) ? "pkspec," : "",
641 (vfmt
& RADEON_CP_VC_FRMT_ST0
) ? "st0," : "",
642 (vfmt
& RADEON_CP_VC_FRMT_ST1
) ? "st1," : "",
643 (vfmt
& RADEON_CP_VC_FRMT_Q1
) ? "q1," : "",
644 (vfmt
& RADEON_CP_VC_FRMT_ST2
) ? "st2," : "",
645 (vfmt
& RADEON_CP_VC_FRMT_Q2
) ? "q2," : "",
646 (vfmt
& RADEON_CP_VC_FRMT_ST3
) ? "st3," : "",
647 (vfmt
& RADEON_CP_VC_FRMT_Q3
) ? "q3," : "",
648 (vfmt
& RADEON_CP_VC_FRMT_Q0
) ? "q0," : "",
649 (vfmt
& RADEON_CP_VC_FRMT_N0
) ? "n0," : "",
650 (vfmt
& RADEON_CP_VC_FRMT_XY1
) ? "xy1," : "",
651 (vfmt
& RADEON_CP_VC_FRMT_Z1
) ? "z1," : "",
652 (vfmt
& RADEON_CP_VC_FRMT_W1
) ? "w1," : "",
653 (vfmt
& RADEON_CP_VC_FRMT_N1
) ? "n1," : "");
656 /* if (!find_or_add_value( &others[V_VTXFMT], vfmt )) */
657 /* fprintf(stderr, " *** NEW VALUE"); */
659 fprintf(stderr
, "\n");
665 static char *primname
[0xf] = {
679 static int print_prim_and_flags( int prim
)
684 fprintf(stderr
, " %s(%x): %s%s%s%s%s%s%s\n",
687 ((prim
& 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_IND
) ? "IND," : "",
688 ((prim
& 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_LIST
) ? "LIST," : "",
689 ((prim
& 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_RING
) ? "RING," : "",
690 (prim
& RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA
) ? "RGBA," : "BGRA, ",
691 (prim
& RADEON_CP_VC_CNTL_MAOS_ENABLE
) ? "MAOS," : "",
692 (prim
& RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE
) ? "RADEON," : "",
693 (prim
& RADEON_CP_VC_CNTL_TCL_ENABLE
) ? "TCL," : "");
695 if ((prim
& 0xf) > RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST
) {
696 fprintf(stderr
, " *** Bad primitive: %x\n", prim
& 0xf);
703 fprintf(stderr
, " prim: %s numverts %d\n", primname
[prim
&0xf], numverts
);
705 switch (prim
& 0xf) {
706 case RADEON_CP_VC_CNTL_PRIM_TYPE_NONE
:
707 case RADEON_CP_VC_CNTL_PRIM_TYPE_POINT
:
709 fprintf(stderr
, "Bad nr verts for line %d\n", numverts
);
713 case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE
:
714 if ((numverts
& 1) || numverts
== 0) {
715 fprintf(stderr
, "Bad nr verts for line %d\n", numverts
);
719 case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP
:
721 fprintf(stderr
, "Bad nr verts for line_strip %d\n", numverts
);
725 case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST
:
726 case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST
:
727 case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST
:
728 case RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST
:
729 if (numverts
% 3 || numverts
== 0) {
730 fprintf(stderr
, "Bad nr verts for tri %d\n", numverts
);
734 case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN
:
735 case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP
:
737 fprintf(stderr
, "Bad nr verts for strip/fan %d\n", numverts
);
742 fprintf(stderr
, "Bad primitive\n");
748 /* build in knowledge about each packet type
750 static int radeon_emit_packet3( drm_radeon_cmd_buffer_t
*cmdbuf
)
753 int *cmd
= (int *)cmdbuf
->buf
;
755 int i
, stride
, size
, start
;
757 cmdsz
= 2 + ((cmd
[0] & RADEON_CP_PACKET_COUNT_MASK
) >> 16);
759 if ((cmd
[0] & RADEON_CP_PACKET_MASK
) != RADEON_CP_PACKET3
||
760 cmdsz
* 4 > cmdbuf
->bufsz
||
761 cmdsz
> RADEON_CP_PACKET_MAX_DWORDS
) {
762 fprintf(stderr
, "Bad packet\n");
766 switch( cmd
[0] & ~RADEON_CP_PACKET_COUNT_MASK
) {
767 case RADEON_CP_PACKET3_NOP
:
769 fprintf(stderr
, "PACKET3_NOP, %d dwords\n", cmdsz
);
771 case RADEON_CP_PACKET3_NEXT_CHAR
:
773 fprintf(stderr
, "PACKET3_NEXT_CHAR, %d dwords\n", cmdsz
);
775 case RADEON_CP_PACKET3_PLY_NEXTSCAN
:
777 fprintf(stderr
, "PACKET3_PLY_NEXTSCAN, %d dwords\n", cmdsz
);
779 case RADEON_CP_PACKET3_SET_SCISSORS
:
781 fprintf(stderr
, "PACKET3_SET_SCISSORS, %d dwords\n", cmdsz
);
783 case RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM
:
785 fprintf(stderr
, "PACKET3_3D_RNDR_GEN_INDX_PRIM, %d dwords\n",
788 case RADEON_CP_PACKET3_LOAD_MICROCODE
:
790 fprintf(stderr
, "PACKET3_LOAD_MICROCODE, %d dwords\n", cmdsz
);
792 case RADEON_CP_PACKET3_WAIT_FOR_IDLE
:
794 fprintf(stderr
, "PACKET3_WAIT_FOR_IDLE, %d dwords\n", cmdsz
);
797 case RADEON_CP_PACKET3_3D_DRAW_VBUF
:
799 fprintf(stderr
, "PACKET3_3D_DRAW_VBUF, %d dwords\n", cmdsz
);
800 print_vertex_format(cmd
[1]);
801 print_prim_and_flags(cmd
[2]);
804 case RADEON_CP_PACKET3_3D_DRAW_IMMD
:
806 fprintf(stderr
, "PACKET3_3D_DRAW_IMMD, %d dwords\n", cmdsz
);
808 case RADEON_CP_PACKET3_3D_DRAW_INDX
: {
811 fprintf(stderr
, "PACKET3_3D_DRAW_INDX, %d dwords\n", cmdsz
);
812 print_vertex_format(cmd
[1]);
813 print_prim_and_flags(cmd
[2]);
814 neltdwords
= cmd
[2]>>16;
815 neltdwords
+= neltdwords
& 1;
817 if (neltdwords
+ 3 != cmdsz
)
818 fprintf(stderr
, "Mismatch in DRAW_INDX, %d vs cmdsz %d\n",
822 case RADEON_CP_PACKET3_LOAD_PALETTE
:
824 fprintf(stderr
, "PACKET3_LOAD_PALETTE, %d dwords\n", cmdsz
);
826 case RADEON_CP_PACKET3_3D_LOAD_VBPNTR
:
828 fprintf(stderr
, "PACKET3_3D_LOAD_VBPNTR, %d dwords\n", cmdsz
);
829 fprintf(stderr
, " nr arrays: %d\n", cmd
[1]);
832 if (cmd
[1]/2 + cmd
[1]%2 != cmdsz
- 3) {
833 fprintf(stderr
, " ****** MISMATCH %d/%d *******\n",
834 cmd
[1]/2 + cmd
[1]%2 + 3, cmdsz
);
840 for (i
= 0 ; i
< cmd
[1] ; i
++) {
842 stride
= (tmp
[0]>>24) & 0xff;
843 size
= (tmp
[0]>>16) & 0xff;
848 stride
= (tmp
[0]>>8) & 0xff;
849 size
= (tmp
[0]) & 0xff;
852 fprintf(stderr
, " array %d: start 0x%x vsize %d vstride %d\n",
853 i
, start
, size
, stride
);
857 case RADEON_CP_PACKET3_CNTL_PAINT
:
859 fprintf(stderr
, "PACKET3_CNTL_PAINT, %d dwords\n", cmdsz
);
861 case RADEON_CP_PACKET3_CNTL_BITBLT
:
863 fprintf(stderr
, "PACKET3_CNTL_BITBLT, %d dwords\n", cmdsz
);
865 case RADEON_CP_PACKET3_CNTL_SMALLTEXT
:
867 fprintf(stderr
, "PACKET3_CNTL_SMALLTEXT, %d dwords\n", cmdsz
);
869 case RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT
:
871 fprintf(stderr
, "PACKET3_CNTL_HOSTDATA_BLT, %d dwords\n",
874 case RADEON_CP_PACKET3_CNTL_POLYLINE
:
876 fprintf(stderr
, "PACKET3_CNTL_POLYLINE, %d dwords\n", cmdsz
);
878 case RADEON_CP_PACKET3_CNTL_POLYSCANLINES
:
880 fprintf(stderr
, "PACKET3_CNTL_POLYSCANLINES, %d dwords\n",
883 case RADEON_CP_PACKET3_CNTL_PAINT_MULTI
:
885 fprintf(stderr
, "PACKET3_CNTL_PAINT_MULTI, %d dwords\n",
888 case RADEON_CP_PACKET3_CNTL_BITBLT_MULTI
:
890 fprintf(stderr
, "PACKET3_CNTL_BITBLT_MULTI, %d dwords\n",
893 case RADEON_CP_PACKET3_CNTL_TRANS_BITBLT
:
895 fprintf(stderr
, "PACKET3_CNTL_TRANS_BITBLT, %d dwords\n",
899 fprintf(stderr
, "UNKNOWN PACKET, %d dwords\n", cmdsz
);
903 cmdbuf
->buf
+= cmdsz
* 4;
904 cmdbuf
->bufsz
-= cmdsz
* 4;
909 /* Check cliprects for bounds, then pass on to above:
911 static int radeon_emit_packet3_cliprect( drm_radeon_cmd_buffer_t
*cmdbuf
)
913 drm_clip_rect_t
*boxes
= cmdbuf
->boxes
;
916 if (VERBOSE
&& total_changed
) {
920 else fprintf(stderr
, "total_changed zero\n");
924 if ( i
< cmdbuf
->nbox
) {
925 fprintf(stderr
, "Emit box %d/%d %d,%d %d,%d\n",
927 boxes
[i
].x1
, boxes
[i
].y1
, boxes
[i
].x2
, boxes
[i
].y2
);
929 } while ( ++i
< cmdbuf
->nbox
);
932 if (cmdbuf
->nbox
== 1)
935 return radeon_emit_packet3( cmdbuf
);
939 int radeonSanityCmdBuffer( radeonContextPtr rmesa
,
941 drm_clip_rect_t
*boxes
)
944 drm_radeon_cmd_buffer_t cmdbuf
;
945 drm_radeon_cmd_header_t header
;
946 static int inited
= 0;
953 cmdbuf
.buf
= rmesa
->store
.cmd_buf
;
954 cmdbuf
.bufsz
= rmesa
->store
.cmd_used
;
955 cmdbuf
.boxes
= boxes
;
958 while ( cmdbuf
.bufsz
>= sizeof(header
) ) {
960 header
.i
= *(int *)cmdbuf
.buf
;
961 cmdbuf
.buf
+= sizeof(header
);
962 cmdbuf
.bufsz
-= sizeof(header
);
964 switch (header
.header
.cmd_type
) {
965 case RADEON_CMD_PACKET
:
966 if (radeon_emit_packets( header
, &cmdbuf
)) {
967 fprintf(stderr
,"radeon_emit_packets failed\n");
972 case RADEON_CMD_SCALARS
:
973 if (radeon_emit_scalars( header
, &cmdbuf
)) {
974 fprintf(stderr
,"radeon_emit_scalars failed\n");
979 case RADEON_CMD_SCALARS2
:
980 if (radeon_emit_scalars2( header
, &cmdbuf
)) {
981 fprintf(stderr
,"radeon_emit_scalars failed\n");
986 case RADEON_CMD_VECTORS
:
987 if (radeon_emit_vectors( header
, &cmdbuf
)) {
988 fprintf(stderr
,"radeon_emit_vectors failed\n");
993 case RADEON_CMD_DMA_DISCARD
:
994 idx
= header
.dma
.buf_idx
;
996 fprintf(stderr
, "RADEON_CMD_DMA_DISCARD buf %d\n", idx
);
1000 case RADEON_CMD_PACKET3
:
1001 if (radeon_emit_packet3( &cmdbuf
)) {
1002 fprintf(stderr
,"radeon_emit_packet3 failed\n");
1007 case RADEON_CMD_PACKET3_CLIP
:
1008 if (radeon_emit_packet3_cliprect( &cmdbuf
)) {
1009 fprintf(stderr
,"radeon_emit_packet3_clip failed\n");
1014 case RADEON_CMD_WAIT
:
1018 fprintf(stderr
,"bad cmd_type %d at %p\n",
1019 header
.header
.cmd_type
,
1020 cmdbuf
.buf
- sizeof(header
));
1030 fprintf(stderr
, "Bufs %d Total emitted %d real changes %d (%.2f%%)\n",
1032 total
, total_changed
,
1033 ((float)total_changed
/(float)total
*100.0));
1034 fprintf(stderr
, "Total emitted per buf: %.2f\n",
1035 (float)total
/(float)bufs
);
1036 fprintf(stderr
, "Real changes per buf: %.2f\n",
1037 (float)total_changed
/(float)bufs
);
1039 bufs
= n
= total
= total_changed
= 0;