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