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