3e64be83edd58af95e3c35597d435598966c3cdc
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_sanity.c
1 /**************************************************************************
2
3 Copyright 2002 ATI Technologies Inc., Ontario, Canada, and
4 Tungsten Graphics Inc, Cedar Park, TX.
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, TUNGSTEN GRAPHICS 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 <keith@tungstengraphics.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 = (union fi *) realloc( reg->values,
384 reg->nalloc * sizeof(union fi) );
385 }
386
387 reg->values[reg->nvalues++].i = val;
388 return 0;
389 }
390
391 static struct reg *lookup_reg( struct reg *tab, int reg )
392 {
393 int i;
394
395 for (i = 0 ; tab[i].idx != -1 ; i++) {
396 if (tab[i].idx == reg)
397 return &tab[i];
398 }
399
400 fprintf(stderr, "*** unknown reg 0x%x\n", reg);
401 return NULL;
402 }
403
404
405 static const char *get_reg_name( struct reg *reg )
406 {
407 static char tmp[80];
408
409 if (reg->idx == reg->closest->idx)
410 return reg->closest->name;
411
412
413 if (reg->flags & ISVEC) {
414 if (reg->idx/4 != reg->closest->idx)
415 sprintf(tmp, "%s+%d[%d]",
416 reg->closest->name,
417 (reg->idx/4) - reg->closest->idx,
418 reg->idx%4);
419 else
420 sprintf(tmp, "%s[%d]", reg->closest->name, reg->idx%4);
421 }
422 else {
423 if (reg->idx != reg->closest->idx)
424 sprintf(tmp, "%s+%d", reg->closest->name, reg->idx - reg->closest->idx);
425 else
426 sprintf(tmp, "%s", reg->closest->name);
427 }
428
429 return tmp;
430 }
431
432 static int print_int_reg_assignment( struct reg *reg, int data )
433 {
434 int changed = (reg->current.i != data);
435 int ever_seen = find_or_add_value( reg, data );
436
437 if (VERBOSE || (NORMAL && (changed || !ever_seen)))
438 fprintf(stderr, " %s <-- 0x%x", get_reg_name(reg), data);
439
440 if (NORMAL) {
441 if (!ever_seen)
442 fprintf(stderr, " *** BRAND NEW VALUE");
443 else if (changed)
444 fprintf(stderr, " *** CHANGED");
445 }
446
447 reg->current.i = data;
448
449 if (VERBOSE || (NORMAL && (changed || !ever_seen)))
450 fprintf(stderr, "\n");
451
452 return changed;
453 }
454
455
456 static int print_float_reg_assignment( struct reg *reg, float data )
457 {
458 int changed = (reg->current.f != data);
459 int newmin = (data < reg->vmin);
460 int newmax = (data > reg->vmax);
461
462 if (VERBOSE || (NORMAL && (newmin || newmax || changed)))
463 fprintf(stderr, " %s <-- %.3f", get_reg_name(reg), data);
464
465 if (NORMAL) {
466 if (newmin) {
467 fprintf(stderr, " *** NEW MIN (prev %.3f)", reg->vmin);
468 reg->vmin = data;
469 }
470 else if (newmax) {
471 fprintf(stderr, " *** NEW MAX (prev %.3f)", reg->vmax);
472 reg->vmax = data;
473 }
474 else if (changed) {
475 fprintf(stderr, " *** CHANGED");
476 }
477 }
478
479 reg->current.f = data;
480
481 if (VERBOSE || (NORMAL && (newmin || newmax || changed)))
482 fprintf(stderr, "\n");
483
484 return changed;
485 }
486
487 static int print_reg_assignment( struct reg *reg, int data )
488 {
489 float_ui32_type datau;
490 datau.ui32 = data;
491 reg->flags |= TOUCHED;
492 if (reg->flags & ISFLOAT)
493 return print_float_reg_assignment( reg, datau.f );
494 else
495 return print_int_reg_assignment( reg, data );
496 }
497
498 static void print_reg( struct reg *reg )
499 {
500 if (reg->flags & TOUCHED) {
501 if (reg->flags & ISFLOAT) {
502 fprintf(stderr, " %s == %f\n", get_reg_name(reg), reg->current.f);
503 } else {
504 fprintf(stderr, " %s == 0x%x\n", get_reg_name(reg), reg->current.i);
505 }
506 }
507 }
508
509
510 static void dump_state( void )
511 {
512 int i;
513
514 for (i = 0 ; i < Elements(regs) ; i++)
515 print_reg( &regs[i] );
516
517 for (i = 0 ; i < Elements(scalars) ; i++)
518 print_reg( &scalars[i] );
519
520 for (i = 0 ; i < Elements(vectors) ; i++)
521 print_reg( &vectors[i] );
522 }
523
524
525
526 static int radeon_emit_packets(
527 drm_radeon_cmd_header_t header,
528 drm_radeon_cmd_buffer_t *cmdbuf )
529 {
530 int id = (int)header.packet.packet_id;
531 int sz = packet[id].len;
532 int *data = (int *)cmdbuf->buf;
533 int i;
534
535 if (sz * sizeof(int) > cmdbuf->bufsz) {
536 fprintf(stderr, "Packet overflows cmdbuf\n");
537 return -EINVAL;
538 }
539
540 if (!packet[id].name) {
541 fprintf(stderr, "*** Unknown packet 0 nr %d\n", id );
542 return -EINVAL;
543 }
544
545
546 if (VERBOSE)
547 fprintf(stderr, "Packet 0 reg %s nr %d\n", packet[id].name, sz );
548
549 for ( i = 0 ; i < sz ; i++) {
550 struct reg *reg = lookup_reg( regs, packet[id].start + i*4 );
551 if (print_reg_assignment( reg, data[i] ))
552 total_changed++;
553 total++;
554 }
555
556 cmdbuf->buf += sz * sizeof(int);
557 cmdbuf->bufsz -= sz * sizeof(int);
558 return 0;
559 }
560
561
562 static int radeon_emit_scalars(
563 drm_radeon_cmd_header_t header,
564 drm_radeon_cmd_buffer_t *cmdbuf )
565 {
566 int sz = header.scalars.count;
567 int *data = (int *)cmdbuf->buf;
568 int start = header.scalars.offset;
569 int stride = header.scalars.stride;
570 int i;
571
572 if (VERBOSE)
573 fprintf(stderr, "emit scalars, start %d stride %d nr %d (end %d)\n",
574 start, stride, sz, start + stride * sz);
575
576
577 for (i = 0 ; i < sz ; i++, start += stride) {
578 struct reg *reg = lookup_reg( scalars, start );
579 if (print_reg_assignment( reg, data[i] ))
580 total_changed++;
581 total++;
582 }
583
584 cmdbuf->buf += sz * sizeof(int);
585 cmdbuf->bufsz -= sz * sizeof(int);
586 return 0;
587 }
588
589
590 static int radeon_emit_scalars2(
591 drm_radeon_cmd_header_t header,
592 drm_radeon_cmd_buffer_t *cmdbuf )
593 {
594 int sz = header.scalars.count;
595 int *data = (int *)cmdbuf->buf;
596 int start = header.scalars.offset + 0x100;
597 int stride = header.scalars.stride;
598 int i;
599
600 if (VERBOSE)
601 fprintf(stderr, "emit scalars2, start %d stride %d nr %d (end %d)\n",
602 start, stride, sz, start + stride * sz);
603
604 if (start + stride * sz > 257) {
605 fprintf(stderr, "emit scalars OVERFLOW %d/%d/%d\n", start, stride, sz);
606 return -1;
607 }
608
609 for (i = 0 ; i < sz ; i++, start += stride) {
610 struct reg *reg = lookup_reg( scalars, start );
611 if (print_reg_assignment( reg, data[i] ))
612 total_changed++;
613 total++;
614 }
615
616 cmdbuf->buf += sz * sizeof(int);
617 cmdbuf->bufsz -= sz * sizeof(int);
618 return 0;
619 }
620
621 /* Check: inf/nan/extreme-size?
622 * Check: table start, end, nr, etc.
623 */
624 static int radeon_emit_vectors(
625 drm_radeon_cmd_header_t header,
626 drm_radeon_cmd_buffer_t *cmdbuf )
627 {
628 int sz = header.vectors.count;
629 int *data = (int *)cmdbuf->buf;
630 int start = header.vectors.offset;
631 int stride = header.vectors.stride;
632 int i,j;
633
634 if (VERBOSE)
635 fprintf(stderr, "emit vectors, start %d stride %d nr %d (end %d) (0x%x)\n",
636 start, stride, sz, start + stride * sz, header.i);
637
638 /* if (start + stride * (sz/4) > 128) { */
639 /* fprintf(stderr, "emit vectors OVERFLOW %d/%d/%d\n", start, stride, sz); */
640 /* return -1; */
641 /* } */
642
643 for (i = 0 ; i < sz ; start += stride) {
644 int changed = 0;
645 for (j = 0 ; j < 4 ; i++,j++) {
646 struct reg *reg = lookup_reg( vectors, start*4+j );
647 if (print_reg_assignment( reg, data[i] ))
648 changed = 1;
649 }
650 if (changed)
651 total_changed += 4;
652 total += 4;
653 }
654
655
656 cmdbuf->buf += sz * sizeof(int);
657 cmdbuf->bufsz -= sz * sizeof(int);
658 return 0;
659 }
660
661
662 static int print_vertex_format( int vfmt )
663 {
664 if (NORMAL) {
665 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",
666 "vertex format",
667 vfmt,
668 "xy,",
669 (vfmt & RADEON_CP_VC_FRMT_Z) ? "z," : "",
670 (vfmt & RADEON_CP_VC_FRMT_W0) ? "w0," : "",
671 (vfmt & RADEON_CP_VC_FRMT_FPCOLOR) ? "fpcolor," : "",
672 (vfmt & RADEON_CP_VC_FRMT_FPALPHA) ? "fpalpha," : "",
673 (vfmt & RADEON_CP_VC_FRMT_PKCOLOR) ? "pkcolor," : "",
674 (vfmt & RADEON_CP_VC_FRMT_FPSPEC) ? "fpspec," : "",
675 (vfmt & RADEON_CP_VC_FRMT_FPFOG) ? "fpfog," : "",
676 (vfmt & RADEON_CP_VC_FRMT_PKSPEC) ? "pkspec," : "",
677 (vfmt & RADEON_CP_VC_FRMT_ST0) ? "st0," : "",
678 (vfmt & RADEON_CP_VC_FRMT_ST1) ? "st1," : "",
679 (vfmt & RADEON_CP_VC_FRMT_Q1) ? "q1," : "",
680 (vfmt & RADEON_CP_VC_FRMT_ST2) ? "st2," : "",
681 (vfmt & RADEON_CP_VC_FRMT_Q2) ? "q2," : "",
682 (vfmt & RADEON_CP_VC_FRMT_ST3) ? "st3," : "",
683 (vfmt & RADEON_CP_VC_FRMT_Q3) ? "q3," : "",
684 (vfmt & RADEON_CP_VC_FRMT_Q0) ? "q0," : "",
685 (vfmt & RADEON_CP_VC_FRMT_N0) ? "n0," : "",
686 (vfmt & RADEON_CP_VC_FRMT_XY1) ? "xy1," : "",
687 (vfmt & RADEON_CP_VC_FRMT_Z1) ? "z1," : "",
688 (vfmt & RADEON_CP_VC_FRMT_W1) ? "w1," : "",
689 (vfmt & RADEON_CP_VC_FRMT_N1) ? "n1," : "");
690
691
692 /* if (!find_or_add_value( &others[V_VTXFMT], vfmt )) */
693 /* fprintf(stderr, " *** NEW VALUE"); */
694
695 fprintf(stderr, "\n");
696 }
697
698 return 0;
699 }
700
701 static char *primname[0xf] = {
702 "NONE",
703 "POINTS",
704 "LINES",
705 "LINE_STRIP",
706 "TRIANGLES",
707 "TRIANGLE_FAN",
708 "TRIANGLE_STRIP",
709 "TRI_TYPE_2",
710 "RECT_LIST",
711 "3VRT_POINTS",
712 "3VRT_LINES",
713 };
714
715 static int print_prim_and_flags( int prim )
716 {
717 int numverts;
718
719 if (NORMAL)
720 fprintf(stderr, " %s(%x): %s%s%s%s%s%s%s\n",
721 "prim flags",
722 prim,
723 ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_IND) ? "IND," : "",
724 ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_LIST) ? "LIST," : "",
725 ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_RING) ? "RING," : "",
726 (prim & RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA) ? "RGBA," : "BGRA, ",
727 (prim & RADEON_CP_VC_CNTL_MAOS_ENABLE) ? "MAOS," : "",
728 (prim & RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE) ? "RADEON," : "",
729 (prim & RADEON_CP_VC_CNTL_TCL_ENABLE) ? "TCL," : "");
730
731 if ((prim & 0xf) > RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST) {
732 fprintf(stderr, " *** Bad primitive: %x\n", prim & 0xf);
733 return -1;
734 }
735
736 numverts = prim>>16;
737
738 if (NORMAL)
739 fprintf(stderr, " prim: %s numverts %d\n", primname[prim&0xf], numverts);
740
741 switch (prim & 0xf) {
742 case RADEON_CP_VC_CNTL_PRIM_TYPE_NONE:
743 case RADEON_CP_VC_CNTL_PRIM_TYPE_POINT:
744 if (numverts < 1) {
745 fprintf(stderr, "Bad nr verts for line %d\n", numverts);
746 return -1;
747 }
748 break;
749 case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE:
750 if ((numverts & 1) || numverts == 0) {
751 fprintf(stderr, "Bad nr verts for line %d\n", numverts);
752 return -1;
753 }
754 break;
755 case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP:
756 if (numverts < 2) {
757 fprintf(stderr, "Bad nr verts for line_strip %d\n", numverts);
758 return -1;
759 }
760 break;
761 case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST:
762 case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST:
763 case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST:
764 case RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST:
765 if (numverts % 3 || numverts == 0) {
766 fprintf(stderr, "Bad nr verts for tri %d\n", numverts);
767 return -1;
768 }
769 break;
770 case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN:
771 case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP:
772 if (numverts < 3) {
773 fprintf(stderr, "Bad nr verts for strip/fan %d\n", numverts);
774 return -1;
775 }
776 break;
777 default:
778 fprintf(stderr, "Bad primitive\n");
779 return -1;
780 }
781 return 0;
782 }
783
784 /* build in knowledge about each packet type
785 */
786 static int radeon_emit_packet3( drm_radeon_cmd_buffer_t *cmdbuf )
787 {
788 int cmdsz;
789 int *cmd = (int *)cmdbuf->buf;
790 int *tmp;
791 int i, stride, size, start;
792
793 cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);
794
795 if ((cmd[0] & RADEON_CP_PACKET_MASK) != RADEON_CP_PACKET3 ||
796 cmdsz * 4 > cmdbuf->bufsz ||
797 cmdsz > RADEON_CP_PACKET_MAX_DWORDS) {
798 fprintf(stderr, "Bad packet\n");
799 return -EINVAL;
800 }
801
802 switch( cmd[0] & ~RADEON_CP_PACKET_COUNT_MASK ) {
803 case RADEON_CP_PACKET3_NOP:
804 if (NORMAL)
805 fprintf(stderr, "PACKET3_NOP, %d dwords\n", cmdsz);
806 break;
807 case RADEON_CP_PACKET3_NEXT_CHAR:
808 if (NORMAL)
809 fprintf(stderr, "PACKET3_NEXT_CHAR, %d dwords\n", cmdsz);
810 break;
811 case RADEON_CP_PACKET3_PLY_NEXTSCAN:
812 if (NORMAL)
813 fprintf(stderr, "PACKET3_PLY_NEXTSCAN, %d dwords\n", cmdsz);
814 break;
815 case RADEON_CP_PACKET3_SET_SCISSORS:
816 if (NORMAL)
817 fprintf(stderr, "PACKET3_SET_SCISSORS, %d dwords\n", cmdsz);
818 break;
819 case RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM:
820 if (NORMAL)
821 fprintf(stderr, "PACKET3_3D_RNDR_GEN_INDX_PRIM, %d dwords\n",
822 cmdsz);
823 break;
824 case RADEON_CP_PACKET3_LOAD_MICROCODE:
825 if (NORMAL)
826 fprintf(stderr, "PACKET3_LOAD_MICROCODE, %d dwords\n", cmdsz);
827 break;
828 case RADEON_CP_PACKET3_WAIT_FOR_IDLE:
829 if (NORMAL)
830 fprintf(stderr, "PACKET3_WAIT_FOR_IDLE, %d dwords\n", cmdsz);
831 break;
832
833 case RADEON_CP_PACKET3_3D_DRAW_VBUF:
834 if (NORMAL)
835 fprintf(stderr, "PACKET3_3D_DRAW_VBUF, %d dwords\n", cmdsz);
836 print_vertex_format(cmd[1]);
837 print_prim_and_flags(cmd[2]);
838 break;
839
840 case RADEON_CP_PACKET3_3D_DRAW_IMMD:
841 if (NORMAL)
842 fprintf(stderr, "PACKET3_3D_DRAW_IMMD, %d dwords\n", cmdsz);
843 break;
844 case RADEON_CP_PACKET3_3D_DRAW_INDX: {
845 int neltdwords;
846 if (NORMAL)
847 fprintf(stderr, "PACKET3_3D_DRAW_INDX, %d dwords\n", cmdsz);
848 print_vertex_format(cmd[1]);
849 print_prim_and_flags(cmd[2]);
850 neltdwords = cmd[2]>>16;
851 neltdwords += neltdwords & 1;
852 neltdwords /= 2;
853 if (neltdwords + 3 != cmdsz)
854 fprintf(stderr, "Mismatch in DRAW_INDX, %d vs cmdsz %d\n",
855 neltdwords, cmdsz);
856 break;
857 }
858 case RADEON_CP_PACKET3_LOAD_PALETTE:
859 if (NORMAL)
860 fprintf(stderr, "PACKET3_LOAD_PALETTE, %d dwords\n", cmdsz);
861 break;
862 case RADEON_CP_PACKET3_3D_LOAD_VBPNTR:
863 if (NORMAL) {
864 fprintf(stderr, "PACKET3_3D_LOAD_VBPNTR, %d dwords\n", cmdsz);
865 fprintf(stderr, " nr arrays: %d\n", cmd[1]);
866 }
867
868 if (cmd[1]/2 + cmd[1]%2 != cmdsz - 3) {
869 fprintf(stderr, " ****** MISMATCH %d/%d *******\n",
870 cmd[1]/2 + cmd[1]%2 + 3, cmdsz);
871 return -EINVAL;
872 }
873
874 if (NORMAL) {
875 tmp = cmd+2;
876 for (i = 0 ; i < cmd[1] ; i++) {
877 if (i & 1) {
878 stride = (tmp[0]>>24) & 0xff;
879 size = (tmp[0]>>16) & 0xff;
880 start = tmp[2];
881 tmp += 3;
882 }
883 else {
884 stride = (tmp[0]>>8) & 0xff;
885 size = (tmp[0]) & 0xff;
886 start = tmp[1];
887 }
888 fprintf(stderr, " array %d: start 0x%x vsize %d vstride %d\n",
889 i, start, size, stride );
890 }
891 }
892 break;
893 case RADEON_CP_PACKET3_CNTL_PAINT:
894 if (NORMAL)
895 fprintf(stderr, "PACKET3_CNTL_PAINT, %d dwords\n", cmdsz);
896 break;
897 case RADEON_CP_PACKET3_CNTL_BITBLT:
898 if (NORMAL)
899 fprintf(stderr, "PACKET3_CNTL_BITBLT, %d dwords\n", cmdsz);
900 break;
901 case RADEON_CP_PACKET3_CNTL_SMALLTEXT:
902 if (NORMAL)
903 fprintf(stderr, "PACKET3_CNTL_SMALLTEXT, %d dwords\n", cmdsz);
904 break;
905 case RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT:
906 if (NORMAL)
907 fprintf(stderr, "PACKET3_CNTL_HOSTDATA_BLT, %d dwords\n",
908 cmdsz);
909 break;
910 case RADEON_CP_PACKET3_CNTL_POLYLINE:
911 if (NORMAL)
912 fprintf(stderr, "PACKET3_CNTL_POLYLINE, %d dwords\n", cmdsz);
913 break;
914 case RADEON_CP_PACKET3_CNTL_POLYSCANLINES:
915 if (NORMAL)
916 fprintf(stderr, "PACKET3_CNTL_POLYSCANLINES, %d dwords\n",
917 cmdsz);
918 break;
919 case RADEON_CP_PACKET3_CNTL_PAINT_MULTI:
920 if (NORMAL)
921 fprintf(stderr, "PACKET3_CNTL_PAINT_MULTI, %d dwords\n",
922 cmdsz);
923 break;
924 case RADEON_CP_PACKET3_CNTL_BITBLT_MULTI:
925 if (NORMAL)
926 fprintf(stderr, "PACKET3_CNTL_BITBLT_MULTI, %d dwords\n",
927 cmdsz);
928 break;
929 case RADEON_CP_PACKET3_CNTL_TRANS_BITBLT:
930 if (NORMAL)
931 fprintf(stderr, "PACKET3_CNTL_TRANS_BITBLT, %d dwords\n",
932 cmdsz);
933 break;
934 default:
935 fprintf(stderr, "UNKNOWN PACKET, %d dwords\n", cmdsz);
936 break;
937 }
938
939 cmdbuf->buf += cmdsz * 4;
940 cmdbuf->bufsz -= cmdsz * 4;
941 return 0;
942 }
943
944
945 /* Check cliprects for bounds, then pass on to above:
946 */
947 static int radeon_emit_packet3_cliprect( drm_radeon_cmd_buffer_t *cmdbuf )
948 {
949 drm_clip_rect_t *boxes = cmdbuf->boxes;
950 int i = 0;
951
952 if (VERBOSE && total_changed) {
953 dump_state();
954 total_changed = 0;
955 }
956 else fprintf(stderr, "total_changed zero\n");
957
958 if (NORMAL) {
959 do {
960 if ( i < cmdbuf->nbox ) {
961 fprintf(stderr, "Emit box %d/%d %d,%d %d,%d\n",
962 i, cmdbuf->nbox,
963 boxes[i].x1, boxes[i].y1, boxes[i].x2, boxes[i].y2);
964 }
965 } while ( ++i < cmdbuf->nbox );
966 }
967
968 if (cmdbuf->nbox == 1)
969 cmdbuf->nbox = 0;
970
971 return radeon_emit_packet3( cmdbuf );
972 }
973
974
975 int radeonSanityCmdBuffer( r100ContextPtr rmesa,
976 int nbox,
977 drm_clip_rect_t *boxes )
978 {
979 int idx;
980 drm_radeon_cmd_buffer_t cmdbuf;
981 drm_radeon_cmd_header_t header;
982 static int inited = 0;
983
984 if (!inited) {
985 init_regs();
986 inited = 1;
987 }
988
989 cmdbuf.buf = rmesa->store.cmd_buf;
990 cmdbuf.bufsz = rmesa->store.cmd_used;
991 cmdbuf.boxes = boxes;
992 cmdbuf.nbox = nbox;
993
994 while ( cmdbuf.bufsz >= sizeof(header) ) {
995
996 header.i = *(int *)cmdbuf.buf;
997 cmdbuf.buf += sizeof(header);
998 cmdbuf.bufsz -= sizeof(header);
999
1000 switch (header.header.cmd_type) {
1001 case RADEON_CMD_PACKET:
1002 if (radeon_emit_packets( header, &cmdbuf )) {
1003 fprintf(stderr,"radeon_emit_packets failed\n");
1004 return -EINVAL;
1005 }
1006 break;
1007
1008 case RADEON_CMD_SCALARS:
1009 if (radeon_emit_scalars( header, &cmdbuf )) {
1010 fprintf(stderr,"radeon_emit_scalars failed\n");
1011 return -EINVAL;
1012 }
1013 break;
1014
1015 case RADEON_CMD_SCALARS2:
1016 if (radeon_emit_scalars2( header, &cmdbuf )) {
1017 fprintf(stderr,"radeon_emit_scalars failed\n");
1018 return -EINVAL;
1019 }
1020 break;
1021
1022 case RADEON_CMD_VECTORS:
1023 if (radeon_emit_vectors( header, &cmdbuf )) {
1024 fprintf(stderr,"radeon_emit_vectors failed\n");
1025 return -EINVAL;
1026 }
1027 break;
1028
1029 case RADEON_CMD_DMA_DISCARD:
1030 idx = header.dma.buf_idx;
1031 if (NORMAL)
1032 fprintf(stderr, "RADEON_CMD_DMA_DISCARD buf %d\n", idx);
1033 bufs++;
1034 break;
1035
1036 case RADEON_CMD_PACKET3:
1037 if (radeon_emit_packet3( &cmdbuf )) {
1038 fprintf(stderr,"radeon_emit_packet3 failed\n");
1039 return -EINVAL;
1040 }
1041 break;
1042
1043 case RADEON_CMD_PACKET3_CLIP:
1044 if (radeon_emit_packet3_cliprect( &cmdbuf )) {
1045 fprintf(stderr,"radeon_emit_packet3_clip failed\n");
1046 return -EINVAL;
1047 }
1048 break;
1049
1050 case RADEON_CMD_WAIT:
1051 break;
1052
1053 default:
1054 fprintf(stderr,"bad cmd_type %d at %p\n",
1055 header.header.cmd_type,
1056 cmdbuf.buf - sizeof(header));
1057 return -EINVAL;
1058 }
1059 }
1060
1061 if (0)
1062 {
1063 static int n = 0;
1064 n++;
1065 if (n == 10) {
1066 fprintf(stderr, "Bufs %d Total emitted %d real changes %d (%.2f%%)\n",
1067 bufs,
1068 total, total_changed,
1069 ((float)total_changed/(float)total*100.0));
1070 fprintf(stderr, "Total emitted per buf: %.2f\n",
1071 (float)total/(float)bufs);
1072 fprintf(stderr, "Real changes per buf: %.2f\n",
1073 (float)total_changed/(float)bufs);
1074
1075 bufs = n = total = total_changed = 0;
1076 }
1077 }
1078
1079 return 0;
1080 }