1 /**************************************************************************
2
3 Copyright 2000, 2001 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
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 **************************************************************************/
29
30 /*
31 * Authors:
32 * Keith Whitwell <keithw@vmware.com>
33 */
34
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/mtypes.h"
38 #include "main/state.h"
39
40 #include "vbo/vbo.h"
41 #include "math/m_translate.h"
42 #include "tnl/tnl.h"
43 #include "tnl/t_pipeline.h"
44 #include "radeon_context.h"
45 #include "radeon_state.h"
46 #include "radeon_ioctl.h"
47 #include "radeon_tex.h"
48 #include "radeon_tcl.h"
49 #include "radeon_swtcl.h"
50 #include "radeon_maos.h"
51 #include "radeon_fog.h"
52
53 #define RADEON_TCL_MAX_SETUP 19
54
55 union emit_union { float f; GLuint ui; radeon_color_t rgba; };
56
57 static struct {
58 void (*emit)( struct gl_context *, GLuint, GLuint, void * );
59 GLuint vertex_size;
60 GLuint vertex_format;
61 } setup_tab[RADEON_TCL_MAX_SETUP];
62
63 #define DO_W (IND & RADEON_CP_VC_FRMT_W0)
64 #define DO_RGBA (IND & RADEON_CP_VC_FRMT_PKCOLOR)
65 #define DO_SPEC_OR_FOG (IND & RADEON_CP_VC_FRMT_PKSPEC)
66 #define DO_SPEC ((IND & RADEON_CP_VC_FRMT_PKSPEC) && \
67 _mesa_need_secondary_color(ctx))
68 #define DO_FOG ((IND & RADEON_CP_VC_FRMT_PKSPEC) && ctx->Fog.Enabled && \
69 (ctx->Fog.FogCoordinateSource == GL_FOG_COORD))
70 #define DO_TEX0 ((IND & RADEON_CP_VC_FRMT_ST0) != 0)
71 #define DO_TEX1 ((IND & RADEON_CP_VC_FRMT_ST1) != 0)
72 #define DO_TEX2 ((IND & RADEON_CP_VC_FRMT_ST2) != 0)
73 #define DO_PTEX ((IND & RADEON_CP_VC_FRMT_Q0) != 0)
74 #define DO_NORM ((IND & RADEON_CP_VC_FRMT_N0) != 0)
75
76 #define DO_TEX3 0
77
78 #define GET_TEXSOURCE(n) n
79
80 /***********************************************************************
81 * Generate vertex emit functions *
82 ***********************************************************************/
83
84
85 /* Defined in order of increasing vertex size:
86 */
87 #define IDX 0
88 #define IND (RADEON_CP_VC_FRMT_XY| \
89 RADEON_CP_VC_FRMT_Z| \
90 RADEON_CP_VC_FRMT_PKCOLOR)
91 #define TAG(x) x##_rgba
92 #include "radeon_maos_vbtmp.h"
93
94 #define IDX 1
95 #define IND (RADEON_CP_VC_FRMT_XY| \
96 RADEON_CP_VC_FRMT_Z| \
97 RADEON_CP_VC_FRMT_N0)
98 #define TAG(x) x##_n
99 #include "radeon_maos_vbtmp.h"
100
101 #define IDX 2
102 #define IND (RADEON_CP_VC_FRMT_XY| \
103 RADEON_CP_VC_FRMT_Z| \
104 RADEON_CP_VC_FRMT_PKCOLOR| \
105 RADEON_CP_VC_FRMT_ST0)
106 #define TAG(x) x##_rgba_st
107 #include "radeon_maos_vbtmp.h"
108
109 #define IDX 3
110 #define IND (RADEON_CP_VC_FRMT_XY| \
111 RADEON_CP_VC_FRMT_Z| \
112 RADEON_CP_VC_FRMT_PKCOLOR| \
113 RADEON_CP_VC_FRMT_N0)
114 #define TAG(x) x##_rgba_n
115 #include "radeon_maos_vbtmp.h"
116
117 #define IDX 4
118 #define IND (RADEON_CP_VC_FRMT_XY| \
119 RADEON_CP_VC_FRMT_Z| \
120 RADEON_CP_VC_FRMT_ST0| \
121 RADEON_CP_VC_FRMT_N0)
122 #define TAG(x) x##_st_n
123 #include "radeon_maos_vbtmp.h"
124
125 #define IDX 5
126 #define IND (RADEON_CP_VC_FRMT_XY| \
127 RADEON_CP_VC_FRMT_Z| \
128 RADEON_CP_VC_FRMT_PKCOLOR| \
129 RADEON_CP_VC_FRMT_ST0| \
130 RADEON_CP_VC_FRMT_ST1)
131 #define TAG(x) x##_rgba_st_st
132 #include "radeon_maos_vbtmp.h"
133
134 #define IDX 6
135 #define IND (RADEON_CP_VC_FRMT_XY| \
136 RADEON_CP_VC_FRMT_Z| \
137 RADEON_CP_VC_FRMT_PKCOLOR| \
138 RADEON_CP_VC_FRMT_ST0| \
139 RADEON_CP_VC_FRMT_N0)
140 #define TAG(x) x##_rgba_st_n
141 #include "radeon_maos_vbtmp.h"
142
143 #define IDX 7
144 #define IND (RADEON_CP_VC_FRMT_XY| \
145 RADEON_CP_VC_FRMT_Z| \
146 RADEON_CP_VC_FRMT_PKCOLOR| \
147 RADEON_CP_VC_FRMT_PKSPEC| \
148 RADEON_CP_VC_FRMT_ST0| \
149 RADEON_CP_VC_FRMT_ST1)
150 #define TAG(x) x##_rgba_spec_st_st
151 #include "radeon_maos_vbtmp.h"
152
153 #define IDX 8
154 #define IND (RADEON_CP_VC_FRMT_XY| \
155 RADEON_CP_VC_FRMT_Z| \
156 RADEON_CP_VC_FRMT_ST0| \
157 RADEON_CP_VC_FRMT_ST1| \
158 RADEON_CP_VC_FRMT_N0)
159 #define TAG(x) x##_st_st_n
160 #include "radeon_maos_vbtmp.h"
161
162 #define IDX 9
163 #define IND (RADEON_CP_VC_FRMT_XY| \
164 RADEON_CP_VC_FRMT_Z| \
165 RADEON_CP_VC_FRMT_PKCOLOR| \
166 RADEON_CP_VC_FRMT_PKSPEC| \
167 RADEON_CP_VC_FRMT_ST0| \
168 RADEON_CP_VC_FRMT_ST1| \
169 RADEON_CP_VC_FRMT_N0)
170 #define TAG(x) x##_rgba_spec_st_st_n
171 #include "radeon_maos_vbtmp.h"
172
173 #define IDX 10
174 #define IND (RADEON_CP_VC_FRMT_XY| \
175 RADEON_CP_VC_FRMT_Z| \
176 RADEON_CP_VC_FRMT_PKCOLOR| \
177 RADEON_CP_VC_FRMT_ST0| \
178 RADEON_CP_VC_FRMT_Q0)
179 #define TAG(x) x##_rgba_stq
180 #include "radeon_maos_vbtmp.h"
181
182 #define IDX 11
183 #define IND (RADEON_CP_VC_FRMT_XY| \
184 RADEON_CP_VC_FRMT_Z| \
185 RADEON_CP_VC_FRMT_PKCOLOR| \
186 RADEON_CP_VC_FRMT_ST1| \
187 RADEON_CP_VC_FRMT_Q1| \
188 RADEON_CP_VC_FRMT_ST0| \
189 RADEON_CP_VC_FRMT_Q0)
190 #define TAG(x) x##_rgba_stq_stq
191 #include "radeon_maos_vbtmp.h"
192
193 #define IDX 12
194 #define IND (RADEON_CP_VC_FRMT_XY| \
195 RADEON_CP_VC_FRMT_Z| \
196 RADEON_CP_VC_FRMT_W0| \
197 RADEON_CP_VC_FRMT_PKCOLOR| \
198 RADEON_CP_VC_FRMT_PKSPEC| \
199 RADEON_CP_VC_FRMT_ST0| \
200 RADEON_CP_VC_FRMT_Q0| \
201 RADEON_CP_VC_FRMT_ST1| \
202 RADEON_CP_VC_FRMT_Q1| \
203 RADEON_CP_VC_FRMT_N0)
204 #define TAG(x) x##_w_rgba_spec_stq_stq_n
205 #include "radeon_maos_vbtmp.h"
206
207 #define IDX 13
208 #define IND (RADEON_CP_VC_FRMT_XY| \
209 RADEON_CP_VC_FRMT_Z| \
210 RADEON_CP_VC_FRMT_PKCOLOR| \
211 RADEON_CP_VC_FRMT_ST0| \
212 RADEON_CP_VC_FRMT_ST1| \
213 RADEON_CP_VC_FRMT_ST2)
214 #define TAG(x) x##_rgba_st_st_st
215 #include "radeon_maos_vbtmp.h"
216
217 #define IDX 14
218 #define IND (RADEON_CP_VC_FRMT_XY| \
219 RADEON_CP_VC_FRMT_Z| \
220 RADEON_CP_VC_FRMT_PKCOLOR| \
221 RADEON_CP_VC_FRMT_PKSPEC| \
222 RADEON_CP_VC_FRMT_ST0| \
223 RADEON_CP_VC_FRMT_ST1| \
224 RADEON_CP_VC_FRMT_ST2)
225 #define TAG(x) x##_rgba_spec_st_st_st
226 #include "radeon_maos_vbtmp.h"
227
228 #define IDX 15
229 #define IND (RADEON_CP_VC_FRMT_XY| \
230 RADEON_CP_VC_FRMT_Z| \
231 RADEON_CP_VC_FRMT_ST0| \
232 RADEON_CP_VC_FRMT_ST1| \
233 RADEON_CP_VC_FRMT_ST2| \
234 RADEON_CP_VC_FRMT_N0)
235 #define TAG(x) x##_st_st_st_n
236 #include "radeon_maos_vbtmp.h"
237
238 #define IDX 16
239 #define IND (RADEON_CP_VC_FRMT_XY| \
240 RADEON_CP_VC_FRMT_Z| \
241 RADEON_CP_VC_FRMT_PKCOLOR| \
242 RADEON_CP_VC_FRMT_PKSPEC| \
243 RADEON_CP_VC_FRMT_ST0| \
244 RADEON_CP_VC_FRMT_ST1| \
245 RADEON_CP_VC_FRMT_ST2| \
246 RADEON_CP_VC_FRMT_N0)
247 #define TAG(x) x##_rgba_spec_st_st_st_n
248 #include "radeon_maos_vbtmp.h"
249
250 #define IDX 17
251 #define IND (RADEON_CP_VC_FRMT_XY| \
252 RADEON_CP_VC_FRMT_Z| \
253 RADEON_CP_VC_FRMT_PKCOLOR| \
254 RADEON_CP_VC_FRMT_ST0| \
255 RADEON_CP_VC_FRMT_Q0| \
256 RADEON_CP_VC_FRMT_ST1| \
257 RADEON_CP_VC_FRMT_Q1| \
258 RADEON_CP_VC_FRMT_ST2| \
259 RADEON_CP_VC_FRMT_Q2)
260 #define TAG(x) x##_rgba_stq_stq_stq
261 #include "radeon_maos_vbtmp.h"
262
263 #define IDX 18
264 #define IND (RADEON_CP_VC_FRMT_XY| \
265 RADEON_CP_VC_FRMT_Z| \
266 RADEON_CP_VC_FRMT_W0| \
267 RADEON_CP_VC_FRMT_PKCOLOR| \
268 RADEON_CP_VC_FRMT_PKSPEC| \
269 RADEON_CP_VC_FRMT_ST0| \
270 RADEON_CP_VC_FRMT_Q0| \
271 RADEON_CP_VC_FRMT_ST1| \
272 RADEON_CP_VC_FRMT_Q1| \
273 RADEON_CP_VC_FRMT_ST2| \
274 RADEON_CP_VC_FRMT_Q2| \
275 RADEON_CP_VC_FRMT_N0)
276 #define TAG(x) x##_w_rgba_spec_stq_stq_stq_n
277 #include "radeon_maos_vbtmp.h"
278
279
280
281
282 /***********************************************************************
283 * Initialization
284 ***********************************************************************/
285
286
init_tcl_verts(void)287 static void init_tcl_verts( void )
288 {
289 init_rgba();
290 init_n();
291 init_rgba_n();
292 init_rgba_st();
293 init_st_n();
294 init_rgba_st_st();
295 init_rgba_st_n();
296 init_rgba_spec_st_st();
297 init_st_st_n();
298 init_rgba_spec_st_st_n();
299 init_rgba_stq();
300 init_rgba_stq_stq();
301 init_w_rgba_spec_stq_stq_n();
302 init_rgba_st_st_st();
303 init_rgba_spec_st_st_st();
304 init_st_st_st_n();
305 init_rgba_spec_st_st_st_n();
306 init_rgba_stq_stq_stq();
307 init_w_rgba_spec_stq_stq_stq_n();
308 }
309
310
radeonEmitArrays(struct gl_context * ctx,GLuint inputs)311 void radeonEmitArrays( struct gl_context *ctx, GLuint inputs )
312 {
313 r100ContextPtr rmesa = R100_CONTEXT(ctx);
314 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
315 GLuint req = 0;
316 GLuint unit;
317 GLuint vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &
318 ~(RADEON_TCL_VTX_Q0|RADEON_TCL_VTX_Q1|RADEON_TCL_VTX_Q2));
319 int i;
320 static int firsttime = 1;
321
322 if (firsttime) {
323 init_tcl_verts();
324 firsttime = 0;
325 }
326
327 if (1) {
328 req |= RADEON_CP_VC_FRMT_Z;
329 if (VB->AttribPtr[_TNL_ATTRIB_POS]->size == 4) {
330 req |= RADEON_CP_VC_FRMT_W0;
331 }
332 }
333
334 if (inputs & VERT_BIT_NORMAL) {
335 req |= RADEON_CP_VC_FRMT_N0;
336 }
337
338 if (inputs & VERT_BIT_COLOR0) {
339 req |= RADEON_CP_VC_FRMT_PKCOLOR;
340 }
341
342 if (inputs & (VERT_BIT_COLOR1|VERT_BIT_FOG)) {
343 req |= RADEON_CP_VC_FRMT_PKSPEC;
344 }
345
346 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
347 if (inputs & VERT_BIT_TEX(unit)) {
348 req |= RADEON_ST_BIT(unit);
349 /* assume we need the 3rd coord if texgen is active for r/q OR at least
350 3 coords are submitted. This may not be 100% correct */
351 if (VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size >= 3) {
352 req |= RADEON_Q_BIT(unit);
353 vtx |= RADEON_Q_BIT(unit);
354 }
355 if ( (ctx->Texture.Unit[unit].TexGenEnabled & (R_BIT | Q_BIT)) )
356 vtx |= RADEON_Q_BIT(unit);
357 else if ((VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size >= 3) &&
358 (!ctx->Texture.Unit[unit]._Current ||
359 ctx->Texture.Unit[unit]._Current->Target != GL_TEXTURE_CUBE_MAP)) {
360 GLuint swaptexmatcol = (VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size - 3);
361 if (((rmesa->NeedTexMatrix >> unit) & 1) &&
362 (swaptexmatcol != ((rmesa->TexMatColSwap >> unit) & 1)))
363 radeonUploadTexMatrix( rmesa, unit, swaptexmatcol ) ;
364 }
365 }
366 }
367
368 if (vtx != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT]) {
369 RADEON_STATECHANGE( rmesa, tcl );
370 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = vtx;
371 }
372
373 for (i = 0 ; i < RADEON_TCL_MAX_SETUP ; i++)
374 if ((setup_tab[i].vertex_format & req) == req)
375 break;
376
377 if (rmesa->tcl.vertex_format == setup_tab[i].vertex_format &&
378 rmesa->radeon.tcl.aos[0].bo)
379 return;
380
381 if (rmesa->radeon.tcl.aos[0].bo)
382 radeonReleaseArrays( ctx, ~0 );
383
384 radeonAllocDmaRegion( &rmesa->radeon,
385 &rmesa->radeon.tcl.aos[0].bo,
386 &rmesa->radeon.tcl.aos[0].offset,
387 VB->Count * setup_tab[i].vertex_size * 4,
388 4);
389
390 /* The vertex code expects Obj to be clean to element 3. To fix
391 * this, add more vertex code (for obj-2, obj-3) or preferably move
392 * to maos.
393 */
394 if (VB->AttribPtr[_TNL_ATTRIB_POS]->size < 3 ||
395 (VB->AttribPtr[_TNL_ATTRIB_POS]->size == 3 &&
396 (setup_tab[i].vertex_format & RADEON_CP_VC_FRMT_W0))) {
397
398 _math_trans_4f( rmesa->tcl.ObjClean.data,
399 VB->AttribPtr[_TNL_ATTRIB_POS]->data,
400 VB->AttribPtr[_TNL_ATTRIB_POS]->stride,
401 GL_FLOAT,
402 VB->AttribPtr[_TNL_ATTRIB_POS]->size,
403 0,
404 VB->Count );
405
406 switch (VB->AttribPtr[_TNL_ATTRIB_POS]->size) {
407 case 1:
408 _mesa_vector4f_clean_elem(&rmesa->tcl.ObjClean, VB->Count, 1);
409 case 2:
410 _mesa_vector4f_clean_elem(&rmesa->tcl.ObjClean, VB->Count, 2);
411 case 3:
412 if (setup_tab[i].vertex_format & RADEON_CP_VC_FRMT_W0) {
413 _mesa_vector4f_clean_elem(&rmesa->tcl.ObjClean, VB->Count, 3);
414 }
415 case 4:
416 default:
417 break;
418 }
419
420 VB->AttribPtr[_TNL_ATTRIB_POS] = &rmesa->tcl.ObjClean;
421 }
422
423
424 radeon_bo_map(rmesa->radeon.tcl.aos[0].bo, 1);
425 setup_tab[i].emit( ctx, 0, VB->Count,
426 rmesa->radeon.tcl.aos[0].bo->ptr + rmesa->radeon.tcl.aos[0].offset);
427 radeon_bo_unmap(rmesa->radeon.tcl.aos[0].bo);
428 // rmesa->radeon.tcl.aos[0].size = setup_tab[i].vertex_size;
429 rmesa->radeon.tcl.aos[0].stride = setup_tab[i].vertex_size;
430 rmesa->tcl.vertex_format = setup_tab[i].vertex_format;
431 rmesa->radeon.tcl.aos_count = 1;
432 }
433
434
435