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