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