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 /**************************************************************************
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 Tungsten Graphics Inc., Austin, Texas.
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:
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.
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.
29 **************************************************************************/
33 * Keith Whitwell <keith@tungstengraphics.com>
40 #include "array_cache/acache.h"
41 #include "math/m_translate.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"
54 #define RADEON_TCL_MAX_SETUP 19
56 union emit_union
{ float f
; GLuint ui
; radeon_color_t rgba
; };
59 void (*emit
)( GLcontext
*, GLuint
, GLuint
, void * );
62 } setup_tab
[RADEON_TCL_MAX_SETUP
];
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)
79 #define GET_TEXSOURCE(n) n
81 /***********************************************************************
82 * Generate vertex emit functions *
83 ***********************************************************************/
86 /* Defined in order of increasing vertex size:
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"
96 #define IND (RADEON_CP_VC_FRMT_XY| \
97 RADEON_CP_VC_FRMT_Z| \
100 #include "radeon_maos_vbtmp.h"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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"
283 /***********************************************************************
285 ***********************************************************************/
288 static void init_tcl_verts( void )
297 init_rgba_spec_st_st();
299 init_rgba_spec_st_st_n();
302 init_w_rgba_spec_stq_stq_n();
303 init_rgba_st_st_st();
304 init_rgba_spec_st_st_st();
306 init_rgba_spec_st_st_st_n();
307 init_rgba_stq_stq_stq();
308 init_w_rgba_spec_stq_stq_stq_n();
312 void radeonEmitArrays( GLcontext
*ctx
, GLuint inputs
)
314 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
315 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
318 GLuint vtx
= (rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] &
319 ~(RADEON_TCL_VTX_Q0
|RADEON_TCL_VTX_Q1
|RADEON_TCL_VTX_Q2
));
321 static int firsttime
= 1;
329 req
|= RADEON_CP_VC_FRMT_Z
;
330 if (VB
->ObjPtr
->size
== 4) {
331 req
|= RADEON_CP_VC_FRMT_W0
;
335 if (inputs
& VERT_BIT_NORMAL
) {
336 req
|= RADEON_CP_VC_FRMT_N0
;
339 if (inputs
& VERT_BIT_COLOR0
) {
340 req
|= RADEON_CP_VC_FRMT_PKCOLOR
;
343 if (inputs
& (VERT_BIT_COLOR1
|VERT_BIT_FOG
)) {
344 req
|= RADEON_CP_VC_FRMT_PKSPEC
;
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
);
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
) ;
368 if (vtx
!= rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
]) {
369 RADEON_STATECHANGE( rmesa
, tcl
);
370 rmesa
->hw
.tcl
.cmd
[TCL_OUTPUT_VTXFMT
] = vtx
;
373 for (i
= 0 ; i
< RADEON_TCL_MAX_SETUP
; i
++)
374 if ((setup_tab
[i
].vertex_format
& req
) == req
)
377 if (rmesa
->tcl
.vertex_format
== setup_tab
[i
].vertex_format
&&
378 rmesa
->tcl
.indexed_verts
.buf
)
381 if (rmesa
->tcl
.indexed_verts
.buf
)
382 radeonReleaseArrays( ctx
, ~0 );
384 radeonAllocDmaRegion( rmesa
,
385 &rmesa
->tcl
.indexed_verts
,
386 VB
->Count
* setup_tab
[i
].vertex_size
* 4,
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
393 if (VB
->ObjPtr
->size
< 3 ||
394 (VB
->ObjPtr
->size
== 3 &&
395 (setup_tab
[i
].vertex_format
& RADEON_CP_VC_FRMT_W0
))) {
397 _math_trans_4f( rmesa
->tcl
.ObjClean
.data
,
405 switch (VB
->ObjPtr
->size
) {
407 _mesa_vector4f_clean_elem(&rmesa
->tcl
.ObjClean
, VB
->Count
, 1);
409 _mesa_vector4f_clean_elem(&rmesa
->tcl
.ObjClean
, VB
->Count
, 2);
411 if (setup_tab
[i
].vertex_format
& RADEON_CP_VC_FRMT_W0
) {
412 _mesa_vector4f_clean_elem(&rmesa
->tcl
.ObjClean
, VB
->Count
, 3);
419 VB
->ObjPtr
= &rmesa
->tcl
.ObjClean
;
424 setup_tab
[i
].emit( ctx
, 0, VB
->Count
,
425 rmesa
->tcl
.indexed_verts
.address
+
426 rmesa
->tcl
.indexed_verts
.start
);
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
;
433 rmesa
->tcl
.aos_components
[0] = &rmesa
->tcl
.indexed_verts
;
434 rmesa
->tcl
.nr_aos_components
= 1;
439 void radeonReleaseArrays( GLcontext
*ctx
, GLuint newinputs
)
441 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
444 if (RADEON_DEBUG
& DEBUG_VERTS
)
445 _tnl_print_vert_flags( __FUNCTION__
, newinputs
);
449 radeonReleaseDmaRegion( rmesa
, &rmesa
->tcl
.indexed_verts
, __FUNCTION__
);