radeon_maos_verts.c revision bd13e6e5e2403ada2098e3a07c0af4b4ba989ab7
1/**************************************************************************
2
3Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4                     Tungsten Graphics Inc., Austin, Texas.
5
6All Rights Reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining
9a copy of this software and associated documentation files (the
10"Software"), to deal in the Software without restriction, including
11without limitation the rights to use, copy, modify, merge, publish,
12distribute, sublicense, and/or sell copies of the Software, and to
13permit persons to whom the Software is furnished to do so, subject to
14the following conditions:
15
16The above copyright notice and this permission notice (including the
17next paragraph) shall be included in all copies or substantial
18portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28**************************************************************************/
29
30/*
31 * Authors:
32 *   Keith Whitwell <keith@tungstengraphics.com>
33 */
34
35#include "main/glheader.h"
36#include "main/imports.h"
37#include "main/mtypes.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 "math/m_translate.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
52
53#define RADEON_TCL_MAX_SETUP 19
54
55union emit_union { float f; GLuint ui; radeon_color_t rgba; };
56
57static struct {
58   void   (*emit)( GLcontext *, 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		 (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR))
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)
71#define DO_TEX1 (IND & RADEON_CP_VC_FRMT_ST1)
72#define DO_TEX2 (IND & RADEON_CP_VC_FRMT_ST2)
73#define DO_PTEX (IND & RADEON_CP_VC_FRMT_Q0)
74#define DO_NORM (IND & RADEON_CP_VC_FRMT_N0)
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
287static 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
311void radeonEmitArrays( GLcontext *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]._ReallyEnabled & (TEXTURE_CUBE_BIT)) == 0)) {
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      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->AttribPtr[_TNL_ATTRIB_POS] = &rmesa->tcl.ObjClean;
420   }
421
422
423   radeon_bo_map(rmesa->radeon.tcl.aos[0].bo, 1);
424   setup_tab[i].emit( ctx, 0, VB->Count,
425		      rmesa->radeon.tcl.aos[0].bo->ptr + rmesa->radeon.tcl.aos[0].offset);
426   radeon_bo_unmap(rmesa->radeon.tcl.aos[0].bo);
427   //   rmesa->radeon.tcl.aos[0].size = setup_tab[i].vertex_size;
428   rmesa->radeon.tcl.aos[0].stride = setup_tab[i].vertex_size;
429   rmesa->tcl.vertex_format = setup_tab[i].vertex_format;
430   rmesa->radeon.tcl.aos_count = 1;
431}
432
433
434