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