• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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