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