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