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