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