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