s/Tungsten Graphics/VMware/
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_sanity.c
1 /**************************************************************************
2
3 Copyright 2002 ATI Technologies Inc., Ontario, Canada, and
4 VMware, Inc.
5
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
17 Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 ATI, VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Keith Whitwell <keithw@vmware.com>
32 *
33 */
34 #include <errno.h>
35
36 #include "main/glheader.h"
37
38 #include "radeon_context.h"
39 #include "radeon_sanity.h"
40
41 /* Set this '1' to get more verbiage.
42 */
43 #define MORE_VERBOSE 1
44
45 #if MORE_VERBOSE
46 #define VERBOSE (RADEON_DEBUG & RADEON_VERBOSE)
47 #define NORMAL (1)
48 #else
49 #define VERBOSE 0
50 #define NORMAL (RADEON_DEBUG & RADEON_VERBOSE)
51 #endif
52
53
54 /* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in
55 * 1.3 cmdbuffers allow all previous state to be updated as well as
56 * the tcl scalar and vector areas.
57 */
58 static struct {
59 int start;
60 int len;
61 const char *name;
62 } packet[RADEON_MAX_STATE_PACKETS] = {
63 { RADEON_PP_MISC,7,"RADEON_PP_MISC" },
64 { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" },
65 { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" },
66 { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" },
67 { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" },
68 { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" },
69 { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" },
70 { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" },
71 { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" },
72 { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" },
73 { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" },
74 { RADEON_RE_MISC,1,"RADEON_RE_MISC" },
75 { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" },
76 { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" },
77 { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" },
78 { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" },
79 { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" },
80 { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" },
81 { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" },
82 { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" },
83 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" },
84 { 0, 4, "R200_PP_TXCBLEND_0" },
85 { 0, 4, "R200_PP_TXCBLEND_1" },
86 { 0, 4, "R200_PP_TXCBLEND_2" },
87 { 0, 4, "R200_PP_TXCBLEND_3" },
88 { 0, 4, "R200_PP_TXCBLEND_4" },
89 { 0, 4, "R200_PP_TXCBLEND_5" },
90 { 0, 4, "R200_PP_TXCBLEND_6" },
91 { 0, 4, "R200_PP_TXCBLEND_7" },
92 { 0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" },
93 { 0, 6, "R200_PP_TFACTOR_0" },
94 { 0, 4, "R200_SE_VTX_FMT_0" },
95 { 0, 1, "R200_SE_VAP_CNTL" },
96 { 0, 5, "R200_SE_TCL_MATRIX_SEL_0" },
97 { 0, 5, "R200_SE_TCL_TEX_PROC_CTL_2" },
98 { 0, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" },
99 { 0, 6, "R200_PP_TXFILTER_0" },
100 { 0, 6, "R200_PP_TXFILTER_1" },
101 { 0, 6, "R200_PP_TXFILTER_2" },
102 { 0, 6, "R200_PP_TXFILTER_3" },
103 { 0, 6, "R200_PP_TXFILTER_4" },
104 { 0, 6, "R200_PP_TXFILTER_5" },
105 { 0, 1, "R200_PP_TXOFFSET_0" },
106 { 0, 1, "R200_PP_TXOFFSET_1" },
107 { 0, 1, "R200_PP_TXOFFSET_2" },
108 { 0, 1, "R200_PP_TXOFFSET_3" },
109 { 0, 1, "R200_PP_TXOFFSET_4" },
110 { 0, 1, "R200_PP_TXOFFSET_5" },
111 { 0, 1, "R200_SE_VTE_CNTL" },
112 { 0, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" },
113 { 0, 1, "R200_PP_TAM_DEBUG3" },
114 { 0, 1, "R200_PP_CNTL_X" },
115 { 0, 1, "R200_RB3D_DEPTHXY_OFFSET" },
116 { 0, 1, "R200_RE_AUX_SCISSOR_CNTL" },
117 { 0, 2, "R200_RE_SCISSOR_TL_0" },
118 { 0, 2, "R200_RE_SCISSOR_TL_1" },
119 { 0, 2, "R200_RE_SCISSOR_TL_2" },
120 { 0, 1, "R200_SE_VAP_CNTL_STATUS" },
121 { 0, 1, "R200_SE_VTX_STATE_CNTL" },
122 { 0, 1, "R200_RE_POINTSIZE" },
123 { 0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" },
124 { 0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */
125 { 0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */
126 { 0, 1, "R200_PP_CUBIC_FACES_1" },
127 { 0, 5, "R200_PP_CUBIC_OFFSET_F1_1" },
128 { 0, 1, "R200_PP_CUBIC_FACES_2" },
129 { 0, 5, "R200_PP_CUBIC_OFFSET_F1_2" },
130 { 0, 1, "R200_PP_CUBIC_FACES_3" },
131 { 0, 5, "R200_PP_CUBIC_OFFSET_F1_3" },
132 { 0, 1, "R200_PP_CUBIC_FACES_4" },
133 { 0, 5, "R200_PP_CUBIC_OFFSET_F1_4" },
134 { 0, 1, "R200_PP_CUBIC_FACES_5" },
135 { 0, 5, "R200_PP_CUBIC_OFFSET_F1_5" },
136 { RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0" },
137 { RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" },
138 { RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2" },
139 { 0, 3, "R200_RB3D_BLENDCOLOR" },
140 { 0, 1, "R200_SE_TCL_POINT_SPRITE_CNTL" },
141 { RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0" },
142 { RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0" },
143 { RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1" },
144 { RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0" },
145 { RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2" },
146 { RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0" },
147 { 0, 2, "R200_PP_TRI_PERF" },
148 { 0, 32, "R200_PP_AFS_0"}, /* 85 */
149 { 0, 32, "R200_PP_AFS_1"},
150 { 0, 8, "R200_ATF_TFACTOR"},
151 { 0, 8, "R200_PP_TXCTLALL_0"},
152 { 0, 8, "R200_PP_TXCTLALL_1"},
153 { 0, 8, "R200_PP_TXCTLALL_2"},
154 { 0, 8, "R200_PP_TXCTLALL_3"},
155 { 0, 8, "R200_PP_TXCTLALL_4"},
156 { 0, 8, "R200_PP_TXCTLALL_5"},
157 { 0, 2, "R200_VAP_PVS_CNTL"},
158 };
159
160 struct reg_names {
161 int idx;
162 const char *name;
163 };
164
165 static struct reg_names reg_names[] = {
166 { RADEON_PP_MISC, "RADEON_PP_MISC" },
167 { RADEON_PP_FOG_COLOR, "RADEON_PP_FOG_COLOR" },
168 { RADEON_RE_SOLID_COLOR, "RADEON_RE_SOLID_COLOR" },
169 { RADEON_RB3D_BLENDCNTL, "RADEON_RB3D_BLENDCNTL" },
170 { RADEON_RB3D_DEPTHOFFSET, "RADEON_RB3D_DEPTHOFFSET" },
171 { RADEON_RB3D_DEPTHPITCH, "RADEON_RB3D_DEPTHPITCH" },
172 { RADEON_RB3D_ZSTENCILCNTL, "RADEON_RB3D_ZSTENCILCNTL" },
173 { RADEON_PP_CNTL, "RADEON_PP_CNTL" },
174 { RADEON_RB3D_CNTL, "RADEON_RB3D_CNTL" },
175 { RADEON_RB3D_COLOROFFSET, "RADEON_RB3D_COLOROFFSET" },
176 { RADEON_RB3D_COLORPITCH, "RADEON_RB3D_COLORPITCH" },
177 { RADEON_SE_CNTL, "RADEON_SE_CNTL" },
178 { RADEON_SE_COORD_FMT, "RADEON_SE_COORDFMT" },
179 { RADEON_SE_CNTL_STATUS, "RADEON_SE_CNTL_STATUS" },
180 { RADEON_RE_LINE_PATTERN, "RADEON_RE_LINE_PATTERN" },
181 { RADEON_RE_LINE_STATE, "RADEON_RE_LINE_STATE" },
182 { RADEON_SE_LINE_WIDTH, "RADEON_SE_LINE_WIDTH" },
183 { RADEON_RB3D_STENCILREFMASK, "RADEON_RB3D_STENCILREFMASK" },
184 { RADEON_RB3D_ROPCNTL, "RADEON_RB3D_ROPCNTL" },
185 { RADEON_RB3D_PLANEMASK, "RADEON_RB3D_PLANEMASK" },
186 { RADEON_SE_VPORT_XSCALE, "RADEON_SE_VPORT_XSCALE" },
187 { RADEON_SE_VPORT_XOFFSET, "RADEON_SE_VPORT_XOFFSET" },
188 { RADEON_SE_VPORT_YSCALE, "RADEON_SE_VPORT_YSCALE" },
189 { RADEON_SE_VPORT_YOFFSET, "RADEON_SE_VPORT_YOFFSET" },
190 { RADEON_SE_VPORT_ZSCALE, "RADEON_SE_VPORT_ZSCALE" },
191 { RADEON_SE_VPORT_ZOFFSET, "RADEON_SE_VPORT_ZOFFSET" },
192 { RADEON_RE_MISC, "RADEON_RE_MISC" },
193 { RADEON_PP_TXFILTER_0, "RADEON_PP_TXFILTER_0" },
194 { RADEON_PP_TXFILTER_1, "RADEON_PP_TXFILTER_1" },
195 { RADEON_PP_TXFILTER_2, "RADEON_PP_TXFILTER_2" },
196 { RADEON_PP_TXFORMAT_0, "RADEON_PP_TXFORMAT_0" },
197 { RADEON_PP_TXFORMAT_1, "RADEON_PP_TXFORMAT_1" },
198 { RADEON_PP_TXFORMAT_2, "RADEON_PP_TXFORMAT_2" },
199 { RADEON_PP_TXOFFSET_0, "RADEON_PP_TXOFFSET_0" },
200 { RADEON_PP_TXOFFSET_1, "RADEON_PP_TXOFFSET_1" },
201 { RADEON_PP_TXOFFSET_2, "RADEON_PP_TXOFFSET_2" },
202 { RADEON_PP_TXCBLEND_0, "RADEON_PP_TXCBLEND_0" },
203 { RADEON_PP_TXCBLEND_1, "RADEON_PP_TXCBLEND_1" },
204 { RADEON_PP_TXCBLEND_2, "RADEON_PP_TXCBLEND_2" },
205 { RADEON_PP_TXABLEND_0, "RADEON_PP_TXABLEND_0" },
206 { RADEON_PP_TXABLEND_1, "RADEON_PP_TXABLEND_1" },
207 { RADEON_PP_TXABLEND_2, "RADEON_PP_TXABLEND_2" },
208 { RADEON_PP_TFACTOR_0, "RADEON_PP_TFACTOR_0" },
209 { RADEON_PP_TFACTOR_1, "RADEON_PP_TFACTOR_1" },
210 { RADEON_PP_TFACTOR_2, "RADEON_PP_TFACTOR_2" },
211 { RADEON_PP_BORDER_COLOR_0, "RADEON_PP_BORDER_COLOR_0" },
212 { RADEON_PP_BORDER_COLOR_1, "RADEON_PP_BORDER_COLOR_1" },
213 { RADEON_PP_BORDER_COLOR_2, "RADEON_PP_BORDER_COLOR_2" },
214 { RADEON_SE_ZBIAS_FACTOR, "RADEON_SE_ZBIAS_FACTOR" },
215 { RADEON_SE_ZBIAS_CONSTANT, "RADEON_SE_ZBIAS_CONSTANT" },
216 { RADEON_SE_TCL_OUTPUT_VTX_FMT, "RADEON_SE_TCL_OUTPUT_VTXFMT" },
217 { RADEON_SE_TCL_OUTPUT_VTX_SEL, "RADEON_SE_TCL_OUTPUT_VTXSEL" },
218 { RADEON_SE_TCL_MATRIX_SELECT_0, "RADEON_SE_TCL_MATRIX_SELECT_0" },
219 { RADEON_SE_TCL_MATRIX_SELECT_1, "RADEON_SE_TCL_MATRIX_SELECT_1" },
220 { RADEON_SE_TCL_UCP_VERT_BLEND_CTL, "RADEON_SE_TCL_UCP_VERT_BLEND_CTL" },
221 { RADEON_SE_TCL_TEXTURE_PROC_CTL, "RADEON_SE_TCL_TEXTURE_PROC_CTL" },
222 { RADEON_SE_TCL_LIGHT_MODEL_CTL, "RADEON_SE_TCL_LIGHT_MODEL_CTL" },
223 { RADEON_SE_TCL_PER_LIGHT_CTL_0, "RADEON_SE_TCL_PER_LIGHT_CTL_0" },
224 { RADEON_SE_TCL_PER_LIGHT_CTL_1, "RADEON_SE_TCL_PER_LIGHT_CTL_1" },
225 { RADEON_SE_TCL_PER_LIGHT_CTL_2, "RADEON_SE_TCL_PER_LIGHT_CTL_2" },
226 { RADEON_SE_TCL_PER_LIGHT_CTL_3, "RADEON_SE_TCL_PER_LIGHT_CTL_3" },
227 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, "RADEON_SE_TCL_EMMISSIVE_RED" },
228 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_GREEN, "RADEON_SE_TCL_EMMISSIVE_GREEN" },
229 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_BLUE, "RADEON_SE_TCL_EMMISSIVE_BLUE" },
230 { RADEON_SE_TCL_MATERIAL_EMMISSIVE_ALPHA, "RADEON_SE_TCL_EMMISSIVE_ALPHA" },
231 { RADEON_SE_TCL_MATERIAL_AMBIENT_RED, "RADEON_SE_TCL_AMBIENT_RED" },
232 { RADEON_SE_TCL_MATERIAL_AMBIENT_GREEN, "RADEON_SE_TCL_AMBIENT_GREEN" },
233 { RADEON_SE_TCL_MATERIAL_AMBIENT_BLUE, "RADEON_SE_TCL_AMBIENT_BLUE" },
234 { RADEON_SE_TCL_MATERIAL_AMBIENT_ALPHA, "RADEON_SE_TCL_AMBIENT_ALPHA" },
235 { RADEON_SE_TCL_MATERIAL_DIFFUSE_RED, "RADEON_SE_TCL_DIFFUSE_RED" },
236 { RADEON_SE_TCL_MATERIAL_DIFFUSE_GREEN, "RADEON_SE_TCL_DIFFUSE_GREEN" },
237 { RADEON_SE_TCL_MATERIAL_DIFFUSE_BLUE, "RADEON_SE_TCL_DIFFUSE_BLUE" },
238 { RADEON_SE_TCL_MATERIAL_DIFFUSE_ALPHA, "RADEON_SE_TCL_DIFFUSE_ALPHA" },
239 { RADEON_SE_TCL_MATERIAL_SPECULAR_RED, "RADEON_SE_TCL_SPECULAR_RED" },
240 { RADEON_SE_TCL_MATERIAL_SPECULAR_GREEN, "RADEON_SE_TCL_SPECULAR_GREEN" },
241 { RADEON_SE_TCL_MATERIAL_SPECULAR_BLUE, "RADEON_SE_TCL_SPECULAR_BLUE" },
242 { RADEON_SE_TCL_MATERIAL_SPECULAR_ALPHA, "RADEON_SE_TCL_SPECULAR_ALPHA" },
243 { RADEON_SE_TCL_SHININESS, "RADEON_SE_TCL_SHININESS" },
244 { RADEON_SE_COORD_FMT, "RADEON_SE_COORD_FMT" },
245 { RADEON_PP_TEX_SIZE_0, "RADEON_PP_TEX_SIZE_0" },
246 { RADEON_PP_TEX_SIZE_1, "RADEON_PP_TEX_SIZE_1" },
247 { RADEON_PP_TEX_SIZE_2, "RADEON_PP_TEX_SIZE_2" },
248 { RADEON_PP_TEX_SIZE_0+4, "RADEON_PP_TEX_PITCH_0" },
249 { RADEON_PP_TEX_SIZE_1+4, "RADEON_PP_TEX_PITCH_1" },
250 { RADEON_PP_TEX_SIZE_2+4, "RADEON_PP_TEX_PITCH_2" },
251 { RADEON_PP_CUBIC_FACES_0, "RADEON_PP_CUBIC_FACES_0" },
252 { RADEON_PP_CUBIC_FACES_1, "RADEON_PP_CUBIC_FACES_1" },
253 { RADEON_PP_CUBIC_FACES_2, "RADEON_PP_CUBIC_FACES_2" },
254 { RADEON_PP_CUBIC_OFFSET_T0_0, "RADEON_PP_CUBIC_OFFSET_T0_0" },
255 { RADEON_PP_CUBIC_OFFSET_T0_1, "RADEON_PP_CUBIC_OFFSET_T0_1" },
256 { RADEON_PP_CUBIC_OFFSET_T0_2, "RADEON_PP_CUBIC_OFFSET_T0_2" },
257 { RADEON_PP_CUBIC_OFFSET_T0_3, "RADEON_PP_CUBIC_OFFSET_T0_3" },
258 { RADEON_PP_CUBIC_OFFSET_T0_4, "RADEON_PP_CUBIC_OFFSET_T0_4" },
259 { RADEON_PP_CUBIC_OFFSET_T1_0, "RADEON_PP_CUBIC_OFFSET_T1_0" },
260 { RADEON_PP_CUBIC_OFFSET_T1_1, "RADEON_PP_CUBIC_OFFSET_T1_1" },
261 { RADEON_PP_CUBIC_OFFSET_T1_2, "RADEON_PP_CUBIC_OFFSET_T1_2" },
262 { RADEON_PP_CUBIC_OFFSET_T1_3, "RADEON_PP_CUBIC_OFFSET_T1_3" },
263 { RADEON_PP_CUBIC_OFFSET_T1_4, "RADEON_PP_CUBIC_OFFSET_T1_4" },
264 { RADEON_PP_CUBIC_OFFSET_T2_0, "RADEON_PP_CUBIC_OFFSET_T2_0" },
265 { RADEON_PP_CUBIC_OFFSET_T2_1, "RADEON_PP_CUBIC_OFFSET_T2_1" },
266 { RADEON_PP_CUBIC_OFFSET_T2_2, "RADEON_PP_CUBIC_OFFSET_T2_2" },
267 { RADEON_PP_CUBIC_OFFSET_T2_3, "RADEON_PP_CUBIC_OFFSET_T2_3" },
268 { RADEON_PP_CUBIC_OFFSET_T2_4, "RADEON_PP_CUBIC_OFFSET_T2_4" },
269 };
270
271 static struct reg_names scalar_names[] = {
272 { RADEON_SS_LIGHT_DCD_ADDR, "LIGHT_DCD" },
273 { RADEON_SS_LIGHT_SPOT_EXPONENT_ADDR, "LIGHT_SPOT_EXPONENT" },
274 { RADEON_SS_LIGHT_SPOT_CUTOFF_ADDR, "LIGHT_SPOT_CUTOFF" },
275 { RADEON_SS_LIGHT_SPECULAR_THRESH_ADDR, "LIGHT_SPECULAR_THRESH" },
276 { RADEON_SS_LIGHT_RANGE_CUTOFF_ADDR, "LIGHT_RANGE_CUTOFF" },
277 { RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR, "VERT_GUARD_CLIP" },
278 { RADEON_SS_VERT_GUARD_DISCARD_ADJ_ADDR, "VERT_GUARD_DISCARD" },
279 { RADEON_SS_HORZ_GUARD_CLIP_ADJ_ADDR, "HORZ_GUARD_CLIP" },
280 { RADEON_SS_HORZ_GUARD_DISCARD_ADJ_ADDR, "HORZ_GUARD_DISCARD" },
281 { RADEON_SS_SHININESS, "SHININESS" },
282 { 1000, "" },
283 };
284
285 /* Puff these out to make them look like normal (dword) registers.
286 */
287 static struct reg_names vector_names[] = {
288 { RADEON_VS_MATRIX_0_ADDR * 4, "MATRIX_0" },
289 { RADEON_VS_MATRIX_1_ADDR * 4, "MATRIX_1" },
290 { RADEON_VS_MATRIX_2_ADDR * 4, "MATRIX_2" },
291 { RADEON_VS_MATRIX_3_ADDR * 4, "MATRIX_3" },
292 { RADEON_VS_MATRIX_4_ADDR * 4, "MATRIX_4" },
293 { RADEON_VS_MATRIX_5_ADDR * 4, "MATRIX_5" },
294 { RADEON_VS_MATRIX_6_ADDR * 4, "MATRIX_6" },
295 { RADEON_VS_MATRIX_7_ADDR * 4, "MATRIX_7" },
296 { RADEON_VS_MATRIX_8_ADDR * 4, "MATRIX_8" },
297 { RADEON_VS_MATRIX_9_ADDR * 4, "MATRIX_9" },
298 { RADEON_VS_MATRIX_10_ADDR * 4, "MATRIX_10" },
299 { RADEON_VS_MATRIX_11_ADDR * 4, "MATRIX_11" },
300 { RADEON_VS_MATRIX_12_ADDR * 4, "MATRIX_12" },
301 { RADEON_VS_MATRIX_13_ADDR * 4, "MATRIX_13" },
302 { RADEON_VS_MATRIX_14_ADDR * 4, "MATRIX_14" },
303 { RADEON_VS_MATRIX_15_ADDR * 4, "MATRIX_15" },
304 { RADEON_VS_LIGHT_AMBIENT_ADDR * 4, "LIGHT_AMBIENT" },
305 { RADEON_VS_LIGHT_DIFFUSE_ADDR * 4, "LIGHT_DIFFUSE" },
306 { RADEON_VS_LIGHT_SPECULAR_ADDR * 4, "LIGHT_SPECULAR" },
307 { RADEON_VS_LIGHT_DIRPOS_ADDR * 4, "LIGHT_DIRPOS" },
308 { RADEON_VS_LIGHT_HWVSPOT_ADDR * 4, "LIGHT_HWVSPOT" },
309 { RADEON_VS_LIGHT_ATTENUATION_ADDR * 4, "LIGHT_ATTENUATION" },
310 { RADEON_VS_MATRIX_EYE2CLIP_ADDR * 4, "MATRIX_EYE2CLIP" },
311 { RADEON_VS_UCP_ADDR * 4, "UCP" },
312 { RADEON_VS_GLOBAL_AMBIENT_ADDR * 4, "GLOBAL_AMBIENT" },
313 { RADEON_VS_FOG_PARAM_ADDR * 4, "FOG_PARAM" },
314 { RADEON_VS_EYE_VECTOR_ADDR * 4, "EYE_VECTOR" },
315 { 1000, "" },
316 };
317
318 union fi { float f; int i; };
319
320 #define ISVEC 1
321 #define ISFLOAT 2
322 #define TOUCHED 4
323
324 struct reg {
325 int idx;
326 struct reg_names *closest;
327 int flags;
328 union fi current;
329 union fi *values;
330 int nvalues;
331 int nalloc;
332 float vmin, vmax;
333 };
334
335
336 static struct reg regs[Elements(reg_names)+1];
337 static struct reg scalars[512+1];
338 static struct reg vectors[512*4+1];
339
340 static int total, total_changed, bufs;
341
342 static void init_regs( void )
343 {
344 struct reg_names *tmp;
345 int i;
346
347 for (i = 0 ; i < Elements(regs)-1 ; i++) {
348 regs[i].idx = reg_names[i].idx;
349 regs[i].closest = &reg_names[i];
350 regs[i].flags = 0;
351 }
352
353 for (i = 0, tmp = scalar_names ; i < Elements(scalars) ; i++) {
354 if (tmp[1].idx == i) tmp++;
355 scalars[i].idx = i;
356 scalars[i].closest = tmp;
357 scalars[i].flags = ISFLOAT;
358 }
359
360 for (i = 0, tmp = vector_names ; i < Elements(vectors) ; i++) {
361 if (tmp[1].idx*4 == i) tmp++;
362 vectors[i].idx = i;
363 vectors[i].closest = tmp;
364 vectors[i].flags = ISFLOAT|ISVEC;
365 }
366
367 regs[Elements(regs)-1].idx = -1;
368 scalars[Elements(scalars)-1].idx = -1;
369 vectors[Elements(vectors)-1].idx = -1;
370 }
371
372 static int find_or_add_value( struct reg *reg, int val )
373 {
374 int j;
375
376 for ( j = 0 ; j < reg->nvalues ; j++)
377 if ( val == reg->values[j].i )
378 return 1;
379
380 if (j == reg->nalloc) {
381 reg->nalloc += 5;
382 reg->nalloc *= 2;
383 reg->values = realloc( reg->values, reg->nalloc * sizeof(union fi) );
384 }
385
386 reg->values[reg->nvalues++].i = val;
387 return 0;
388 }
389
390 static struct reg *lookup_reg( struct reg *tab, int reg )
391 {
392 int i;
393
394 for (i = 0 ; tab[i].idx != -1 ; i++) {
395 if (tab[i].idx == reg)
396 return &tab[i];
397 }
398
399 fprintf(stderr, "*** unknown reg 0x%x\n", reg);
400 return NULL;
401 }
402
403
404 static const char *get_reg_name( struct reg *reg )
405 {
406 static char tmp[80];
407
408 if (reg->idx == reg->closest->idx)
409 return reg->closest->name;
410
411
412 if (reg->flags & ISVEC) {
413 if (reg->idx/4 != reg->closest->idx)
414 sprintf(tmp, "%s+%d[%d]",
415 reg->closest->name,
416 (reg->idx/4) - reg->closest->idx,
417 reg->idx%4);
418 else
419 sprintf(tmp, "%s[%d]", reg->closest->name, reg->idx%4);
420 }
421 else {
422 if (reg->idx != reg->closest->idx)
423 sprintf(tmp, "%s+%d", reg->closest->name, reg->idx - reg->closest->idx);
424 else
425 sprintf(tmp, "%s", reg->closest->name);
426 }
427
428 return tmp;
429 }
430
431 static int print_int_reg_assignment( struct reg *reg, int data )
432 {
433 int changed = (reg->current.i != data);
434 int ever_seen = find_or_add_value( reg, data );
435
436 if (VERBOSE || (NORMAL && (changed || !ever_seen)))
437 fprintf(stderr, " %s <-- 0x%x", get_reg_name(reg), data);
438
439 if (NORMAL) {
440 if (!ever_seen)
441 fprintf(stderr, " *** BRAND NEW VALUE");
442 else if (changed)
443 fprintf(stderr, " *** CHANGED");
444 }
445
446 reg->current.i = data;
447
448 if (VERBOSE || (NORMAL && (changed || !ever_seen)))
449 fprintf(stderr, "\n");
450
451 return changed;
452 }
453
454
455 static int print_float_reg_assignment( struct reg *reg, float data )
456 {
457 int changed = (reg->current.f != data);
458 int newmin = (data < reg->vmin);
459 int newmax = (data > reg->vmax);
460
461 if (VERBOSE || (NORMAL && (newmin || newmax || changed)))
462 fprintf(stderr, " %s <-- %.3f", get_reg_name(reg), data);
463
464 if (NORMAL) {
465 if (newmin) {
466 fprintf(stderr, " *** NEW MIN (prev %.3f)", reg->vmin);
467 reg->vmin = data;
468 }
469 else if (newmax) {
470 fprintf(stderr, " *** NEW MAX (prev %.3f)", reg->vmax);
471 reg->vmax = data;
472 }
473 else if (changed) {
474 fprintf(stderr, " *** CHANGED");
475 }
476 }
477
478 reg->current.f = data;
479
480 if (VERBOSE || (NORMAL && (newmin || newmax || changed)))
481 fprintf(stderr, "\n");
482
483 return changed;
484 }
485
486 static int print_reg_assignment( struct reg *reg, int data )
487 {
488 float_ui32_type datau;
489 datau.ui32 = data;
490 reg->flags |= TOUCHED;
491 if (reg->flags & ISFLOAT)
492 return print_float_reg_assignment( reg, datau.f );
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( r100ContextPtr 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 }