Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 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 
32
 *
33
 */
34
#include 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 */
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
 
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
 
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
 */
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
 */
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
 
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
}