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