1 
2 /*
3  * Copyright 2003 Tungsten Graphics, inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * on the rights to use, copy, modify, merge, publish, distribute, sub
10  * license, and/or sell copies of the Software, and to permit persons to whom
11  * the Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
20  * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23  * USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  * Authors:
26  *    Keith Whitwell <keithw@tungstengraphics.com>
27  */
28 
29 #include "main/glheader.h"
30 #include "main/context.h"
31 #include "main/colormac.h"
32 #include "main/simple_list.h"
33 #include "swrast/s_chan.h"
34 #include "t_context.h"
35 #include "t_vertex.h"
36 
37 
38 #if 0
39 #define DEBUG_INSERT printf("%s\n", __FUNCTION__)
40 #else
41 #define DEBUG_INSERT
42 #endif
43 
44 
45 /*
46  * These functions take the NDC coordinates pointed to by 'in', apply the
47  * NDC->Viewport mapping and store the results at 'v'.
48  */
49 
insert_4f_viewport_4(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)50 static inline void insert_4f_viewport_4( const struct tnl_clipspace_attr *a, GLubyte *v,
51                       const GLfloat *in )
52 {
53    GLfloat *out = (GLfloat *)v;
54    const GLfloat * const vp = a->vp;
55    DEBUG_INSERT;
56    out[0] = vp[0] * in[0] + vp[12];
57    out[1] = vp[5] * in[1] + vp[13];
58    out[2] = vp[10] * in[2] + vp[14];
59    out[3] = in[3];
60 }
61 
insert_4f_viewport_3(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)62 static inline void insert_4f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
63 				const GLfloat *in )
64 {
65    GLfloat *out = (GLfloat *)v;
66    const GLfloat * const vp = a->vp;
67    DEBUG_INSERT;
68    out[0] = vp[0] * in[0] + vp[12];
69    out[1] = vp[5] * in[1] + vp[13];
70    out[2] = vp[10] * in[2] + vp[14];
71    out[3] = 1;
72 }
73 
insert_4f_viewport_2(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)74 static inline void insert_4f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
75 				const GLfloat *in )
76 {
77    GLfloat *out = (GLfloat *)v;
78    const GLfloat * const vp = a->vp;
79    DEBUG_INSERT;
80    out[0] = vp[0] * in[0] + vp[12];
81    out[1] = vp[5] * in[1] + vp[13];
82    out[2] = vp[14];
83    out[3] = 1;
84 }
85 
insert_4f_viewport_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)86 static inline void insert_4f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
87 				const GLfloat *in )
88 {
89    GLfloat *out = (GLfloat *)v;
90    const GLfloat * const vp = a->vp;
91    DEBUG_INSERT;
92    out[0] = vp[0] * in[0] + vp[12];
93    out[1] = vp[13];
94    out[2] = vp[14];
95    out[3] = 1;
96 }
97 
insert_3f_viewport_3(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)98 static inline void insert_3f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
99 				const GLfloat *in )
100 {
101    GLfloat *out = (GLfloat *)v;
102    const GLfloat * const vp = a->vp;
103    DEBUG_INSERT;
104    out[0] = vp[0] * in[0] + vp[12];
105    out[1] = vp[5] * in[1] + vp[13];
106    out[2] = vp[10] * in[2] + vp[14];
107 }
108 
insert_3f_viewport_2(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)109 static inline void insert_3f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
110 				const GLfloat *in )
111 {
112    GLfloat *out = (GLfloat *)v;
113    const GLfloat * const vp = a->vp;
114    DEBUG_INSERT;
115    out[0] = vp[0] * in[0] + vp[12];
116    out[1] = vp[5] * in[1] + vp[13];
117    out[2] = vp[14];
118 }
119 
insert_3f_viewport_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)120 static inline void insert_3f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
121 				const GLfloat *in )
122 {
123    GLfloat *out = (GLfloat *)v;
124    const GLfloat * const vp = a->vp;
125    DEBUG_INSERT;
126    out[0] = vp[0] * in[0] + vp[12];
127    out[1] = vp[13];
128    out[2] = vp[14];
129 }
130 
insert_2f_viewport_2(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)131 static inline void insert_2f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
132 				const GLfloat *in )
133 {
134    GLfloat *out = (GLfloat *)v;
135    const GLfloat * const vp = a->vp;
136    DEBUG_INSERT;
137    out[0] = vp[0] * in[0] + vp[12];
138    out[1] = vp[5] * in[1] + vp[13];
139 }
140 
insert_2f_viewport_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)141 static inline void insert_2f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
142 				const GLfloat *in )
143 {
144    GLfloat *out = (GLfloat *)v;
145    const GLfloat * const vp = a->vp;
146    DEBUG_INSERT;
147    out[0] = vp[0] * in[0] + vp[12];
148    out[1] = vp[13];
149 }
150 
151 
152 /*
153  * These functions do the same as above, except for the viewport mapping.
154  */
155 
insert_4f_4(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)156 static inline void insert_4f_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
157 {
158    GLfloat *out = (GLfloat *)(v);
159    (void) a;
160    DEBUG_INSERT;
161    out[0] = in[0];
162    out[1] = in[1];
163    out[2] = in[2];
164    out[3] = in[3];
165 }
166 
insert_4f_3(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)167 static inline void insert_4f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
168 {
169    GLfloat *out = (GLfloat *)(v);
170    (void) a;
171    DEBUG_INSERT;
172    out[0] = in[0];
173    out[1] = in[1];
174    out[2] = in[2];
175    out[3] = 1;
176 }
177 
insert_4f_2(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)178 static inline void insert_4f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
179 {
180    GLfloat *out = (GLfloat *)(v);
181    (void) a;
182    DEBUG_INSERT;
183    out[0] = in[0];
184    out[1] = in[1];
185    out[2] = 0;
186    out[3] = 1;
187 }
188 
insert_4f_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)189 static inline void insert_4f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
190 {
191    GLfloat *out = (GLfloat *)(v);
192    (void) a;
193    DEBUG_INSERT;
194    out[0] = in[0];
195    out[1] = 0;
196    out[2] = 0;
197    out[3] = 1;
198 }
199 
insert_3f_xyw_4(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)200 static inline void insert_3f_xyw_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
201 {
202    GLfloat *out = (GLfloat *)(v);
203    (void) a;
204    DEBUG_INSERT;
205    out[0] = in[0];
206    out[1] = in[1];
207    out[2] = in[3];
208 }
209 
insert_3f_xyw_err(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)210 static inline void insert_3f_xyw_err( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
211 {
212    (void) a; (void) v; (void) in;
213    DEBUG_INSERT;
214    exit(1);
215 }
216 
insert_3f_3(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)217 static inline void insert_3f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
218 {
219    GLfloat *out = (GLfloat *)(v);
220    (void) a;
221    DEBUG_INSERT;
222    out[0] = in[0];
223    out[1] = in[1];
224    out[2] = in[2];
225 }
226 
insert_3f_2(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)227 static inline void insert_3f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
228 {
229    GLfloat *out = (GLfloat *)(v);
230    (void) a;
231    DEBUG_INSERT;
232    out[0] = in[0];
233    out[1] = in[1];
234    out[2] = 0;
235 }
236 
insert_3f_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)237 static inline void insert_3f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
238 {
239    GLfloat *out = (GLfloat *)(v);
240    (void) a;
241    DEBUG_INSERT;
242    out[0] = in[0];
243    out[1] = 0;
244    out[2] = 0;
245 }
246 
247 
insert_2f_2(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)248 static inline void insert_2f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
249 {
250    GLfloat *out = (GLfloat *)(v);
251    (void) a;
252    DEBUG_INSERT;
253    out[0] = in[0];
254    out[1] = in[1];
255 }
256 
insert_2f_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)257 static inline void insert_2f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
258 {
259    GLfloat *out = (GLfloat *)(v);
260    (void) a;
261    DEBUG_INSERT;
262    out[0] = in[0];
263    out[1] = 0;
264 }
265 
insert_1f_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)266 static inline void insert_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
267 {
268    GLfloat *out = (GLfloat *)(v);
269    (void) a;
270    DEBUG_INSERT;
271    out[0] = in[0];
272 }
273 
insert_null(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)274 static inline void insert_null( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
275 {
276    DEBUG_INSERT;
277    (void) a; (void) v; (void) in;
278 }
279 
insert_4chan_4f_rgba_4(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)280 static inline void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v,
281 				  const GLfloat *in )
282 {
283    GLchan *c = (GLchan *)v;
284    DEBUG_INSERT;
285    (void) a;
286    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
287    UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
288    UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]);
289    UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]);
290 }
291 
insert_4chan_4f_rgba_3(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)292 static inline void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v,
293 				  const GLfloat *in )
294 {
295    GLchan *c = (GLchan *)v;
296    DEBUG_INSERT;
297    (void) a;
298    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
299    UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
300    UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]);
301    c[3] = CHAN_MAX;
302 }
303 
insert_4chan_4f_rgba_2(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)304 static inline void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v,
305 				  const GLfloat *in )
306 {
307    GLchan *c = (GLchan *)v;
308    DEBUG_INSERT;
309    (void) a;
310    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
311    UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
312    c[2] = 0;
313    c[3] = CHAN_MAX;
314 }
315 
insert_4chan_4f_rgba_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)316 static inline void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v,
317 				  const GLfloat *in )
318 {
319    GLchan *c = (GLchan *)v;
320    DEBUG_INSERT;
321    (void) a;
322    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
323    c[1] = 0;
324    c[2] = 0;
325    c[3] = CHAN_MAX;
326 }
327 
insert_4ub_4f_rgba_4(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)328 static inline void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v,
329 				const GLfloat *in )
330 {
331    DEBUG_INSERT;
332    (void) a;
333    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
334    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
335    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
336    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
337 }
338 
insert_4ub_4f_rgba_3(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)339 static inline void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v,
340 				const GLfloat *in )
341 {
342    DEBUG_INSERT;
343    (void) a;
344    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
345    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
346    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
347    v[3] = 0xff;
348 }
349 
insert_4ub_4f_rgba_2(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)350 static inline void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v,
351 				const GLfloat *in )
352 {
353    DEBUG_INSERT;
354    (void) a;
355    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
356    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
357    v[2] = 0;
358    v[3] = 0xff;
359 }
360 
insert_4ub_4f_rgba_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)361 static inline void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v,
362 				const GLfloat *in )
363 {
364    DEBUG_INSERT;
365    (void) a;
366    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
367    v[1] = 0;
368    v[2] = 0;
369    v[3] = 0xff;
370 }
371 
insert_4ub_4f_bgra_4(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)372 static inline void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr *a, GLubyte *v,
373 				const GLfloat *in )
374 {
375    DEBUG_INSERT;
376    (void) a;
377    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
378    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
379    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
380    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
381 }
382 
insert_4ub_4f_bgra_3(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)383 static inline void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr *a, GLubyte *v,
384 				const GLfloat *in )
385 {
386    DEBUG_INSERT;
387    (void) a;
388    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
389    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
390    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
391    v[3] = 0xff;
392 }
393 
insert_4ub_4f_bgra_2(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)394 static inline void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr *a, GLubyte *v,
395 				const GLfloat *in )
396 {
397    DEBUG_INSERT;
398    (void) a;
399    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
400    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
401    v[0] = 0;
402    v[3] = 0xff;
403 }
404 
insert_4ub_4f_bgra_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)405 static inline void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr *a, GLubyte *v,
406 				const GLfloat *in )
407 {
408    DEBUG_INSERT;
409    (void) a;
410    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
411    v[1] = 0;
412    v[0] = 0;
413    v[3] = 0xff;
414 }
415 
insert_4ub_4f_argb_4(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)416 static inline void insert_4ub_4f_argb_4( const struct tnl_clipspace_attr *a, GLubyte *v,
417 				const GLfloat *in )
418 {
419    DEBUG_INSERT;
420    (void) a;
421    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
422    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
423    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]);
424    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]);
425 }
426 
insert_4ub_4f_argb_3(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)427 static inline void insert_4ub_4f_argb_3( const struct tnl_clipspace_attr *a, GLubyte *v,
428 				const GLfloat *in )
429 {
430    DEBUG_INSERT;
431    (void) a;
432    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
433    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
434    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]);
435    v[0] = 0xff;
436 }
437 
insert_4ub_4f_argb_2(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)438 static inline void insert_4ub_4f_argb_2( const struct tnl_clipspace_attr *a, GLubyte *v,
439 				const GLfloat *in )
440 {
441    DEBUG_INSERT;
442    (void) a;
443    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
444    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
445    v[3] = 0x00;
446    v[0] = 0xff;
447 }
448 
insert_4ub_4f_argb_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)449 static inline void insert_4ub_4f_argb_1( const struct tnl_clipspace_attr *a, GLubyte *v,
450 				const GLfloat *in )
451 {
452    DEBUG_INSERT;
453    (void) a;
454    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
455    v[2] = 0x00;
456    v[3] = 0x00;
457    v[0] = 0xff;
458 }
459 
insert_4ub_4f_abgr_4(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)460 static inline void insert_4ub_4f_abgr_4( const struct tnl_clipspace_attr *a, GLubyte *v,
461 				const GLfloat *in )
462 {
463    DEBUG_INSERT;
464    (void) a;
465    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
466    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
467    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]);
468    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]);
469 }
470 
insert_4ub_4f_abgr_3(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)471 static inline void insert_4ub_4f_abgr_3( const struct tnl_clipspace_attr *a, GLubyte *v,
472 				const GLfloat *in )
473 {
474    DEBUG_INSERT;
475    (void) a;
476    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
477    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
478    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]);
479    v[0] = 0xff;
480 }
481 
insert_4ub_4f_abgr_2(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)482 static inline void insert_4ub_4f_abgr_2( const struct tnl_clipspace_attr *a, GLubyte *v,
483 				const GLfloat *in )
484 {
485    DEBUG_INSERT;
486    (void) a;
487    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
488    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
489    v[1] = 0x00;
490    v[0] = 0xff;
491 }
492 
insert_4ub_4f_abgr_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)493 static inline void insert_4ub_4f_abgr_1( const struct tnl_clipspace_attr *a, GLubyte *v,
494 				const GLfloat *in )
495 {
496    DEBUG_INSERT;
497    (void) a;
498    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
499    v[2] = 0x00;
500    v[1] = 0x00;
501    v[0] = 0xff;
502 }
503 
insert_3ub_3f_rgb_3(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)504 static inline void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr *a, GLubyte *v,
505 			       const GLfloat *in )
506 {
507    DEBUG_INSERT;
508    (void) a;
509    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
510    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
511    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
512 }
513 
insert_3ub_3f_rgb_2(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)514 static inline void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr *a, GLubyte *v,
515 			       const GLfloat *in )
516 {
517    DEBUG_INSERT;
518    (void) a;
519    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
520    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
521    v[2] = 0;
522 }
523 
insert_3ub_3f_rgb_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)524 static inline void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr *a, GLubyte *v,
525 			       const GLfloat *in )
526 {
527    DEBUG_INSERT;
528    (void) a;
529    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
530    v[1] = 0;
531    v[2] = 0;
532 }
533 
insert_3ub_3f_bgr_3(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)534 static inline void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr *a, GLubyte *v,
535 				 const GLfloat *in )
536 {
537    DEBUG_INSERT;
538    (void) a;
539    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
540    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
541    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
542 }
543 
insert_3ub_3f_bgr_2(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)544 static inline void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr *a, GLubyte *v,
545 				 const GLfloat *in )
546 {
547    DEBUG_INSERT;
548    (void) a;
549    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
550    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
551    v[0] = 0;
552 }
553 
insert_3ub_3f_bgr_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)554 static inline void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr *a, GLubyte *v,
555 				 const GLfloat *in )
556 {
557    DEBUG_INSERT;
558    (void) a;
559    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
560    v[1] = 0;
561    v[0] = 0;
562 }
563 
564 
insert_1ub_1f_1(const struct tnl_clipspace_attr * a,GLubyte * v,const GLfloat * in)565 static inline void insert_1ub_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v,
566 			   const GLfloat *in )
567 {
568    DEBUG_INSERT;
569    (void) a;
570    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
571 }
572 
573 
574 /***********************************************************************
575  * Functions to perform the reverse operations to the above, for
576  * swrast translation and clip-interpolation.
577  *
578  * Currently always extracts a full 4 floats.
579  */
580 
extract_4f_viewport(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)581 static void extract_4f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
582 				 const GLubyte *v )
583 {
584    const GLfloat *in = (const GLfloat *)v;
585    const GLfloat * const vp = a->vp;
586 
587    /* Although included for completeness, the position coordinate is
588     * usually handled differently during clipping.
589     */
590    DEBUG_INSERT;
591    out[0] = (in[0] - vp[12]) / vp[0];
592    out[1] = (in[1] - vp[13]) / vp[5];
593    out[2] = (in[2] - vp[14]) / vp[10];
594    out[3] = in[3];
595 }
596 
extract_3f_viewport(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)597 static void extract_3f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
598 				 const GLubyte *v )
599 {
600    const GLfloat *in = (const GLfloat *)v;
601    const GLfloat * const vp = a->vp;
602    DEBUG_INSERT;
603    out[0] = (in[0] - vp[12]) / vp[0];
604    out[1] = (in[1] - vp[13]) / vp[5];
605    out[2] = (in[2] - vp[14]) / vp[10];
606    out[3] = 1;
607 }
608 
609 
extract_2f_viewport(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)610 static void extract_2f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
611 				 const GLubyte *v )
612 {
613    const GLfloat *in = (const GLfloat *)v;
614    const GLfloat * const vp = a->vp;
615    DEBUG_INSERT;
616    out[0] = (in[0] - vp[12]) / vp[0];
617    out[1] = (in[1] - vp[13]) / vp[5];
618    out[2] = 0;
619    out[3] = 1;
620 }
621 
622 
extract_4f(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)623 static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v  )
624 {
625    const GLfloat *in = (const GLfloat *)v;
626    (void) a;
627 
628    out[0] = in[0];
629    out[1] = in[1];
630    out[2] = in[2];
631    out[3] = in[3];
632 }
633 
extract_3f_xyw(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)634 static void extract_3f_xyw( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
635 {
636    const GLfloat *in = (const GLfloat *)v;
637    (void) a;
638 
639    out[0] = in[0];
640    out[1] = in[1];
641    out[2] = 0;
642    out[3] = in[2];
643 }
644 
645 
extract_3f(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)646 static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
647 {
648    const GLfloat *in = (const GLfloat *)v;
649    (void) a;
650 
651    out[0] = in[0];
652    out[1] = in[1];
653    out[2] = in[2];
654    out[3] = 1;
655 }
656 
657 
extract_2f(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)658 static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
659 {
660    const GLfloat *in = (const GLfloat *)v;
661    (void) a;
662 
663    out[0] = in[0];
664    out[1] = in[1];
665    out[2] = 0;
666    out[3] = 1;
667 }
668 
extract_1f(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)669 static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
670 {
671    const GLfloat *in = (const GLfloat *)v;
672    (void) a;
673 
674    out[0] = in[0];
675    out[1] = 0;
676    out[2] = 0;
677    out[3] = 1;
678 }
679 
extract_4chan_4f_rgba(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)680 static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out,
681 				 const GLubyte *v )
682 {
683    GLchan *c = (GLchan *)v;
684    (void) a;
685 
686    out[0] = CHAN_TO_FLOAT(c[0]);
687    out[1] = CHAN_TO_FLOAT(c[1]);
688    out[2] = CHAN_TO_FLOAT(c[2]);
689    out[3] = CHAN_TO_FLOAT(c[3]);
690 }
691 
extract_4ub_4f_rgba(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)692 static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out,
693 				 const GLubyte *v )
694 {
695    (void) a;
696    out[0] = UBYTE_TO_FLOAT(v[0]);
697    out[1] = UBYTE_TO_FLOAT(v[1]);
698    out[2] = UBYTE_TO_FLOAT(v[2]);
699    out[3] = UBYTE_TO_FLOAT(v[3]);
700 }
701 
extract_4ub_4f_bgra(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)702 static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr *a, GLfloat *out,
703 				 const GLubyte *v )
704 {
705    (void) a;
706    out[2] = UBYTE_TO_FLOAT(v[0]);
707    out[1] = UBYTE_TO_FLOAT(v[1]);
708    out[0] = UBYTE_TO_FLOAT(v[2]);
709    out[3] = UBYTE_TO_FLOAT(v[3]);
710 }
711 
extract_4ub_4f_argb(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)712 static void extract_4ub_4f_argb( const struct tnl_clipspace_attr *a, GLfloat *out,
713 				 const GLubyte *v )
714 {
715    (void) a;
716    out[3] = UBYTE_TO_FLOAT(v[0]);
717    out[0] = UBYTE_TO_FLOAT(v[1]);
718    out[1] = UBYTE_TO_FLOAT(v[2]);
719    out[2] = UBYTE_TO_FLOAT(v[3]);
720 }
721 
extract_4ub_4f_abgr(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)722 static void extract_4ub_4f_abgr( const struct tnl_clipspace_attr *a, GLfloat *out,
723 				 const GLubyte *v )
724 {
725    (void) a;
726    out[3] = UBYTE_TO_FLOAT(v[0]);
727    out[2] = UBYTE_TO_FLOAT(v[1]);
728    out[1] = UBYTE_TO_FLOAT(v[2]);
729    out[0] = UBYTE_TO_FLOAT(v[3]);
730 }
731 
extract_3ub_3f_rgb(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)732 static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr *a, GLfloat *out,
733 				const GLubyte *v )
734 {
735    (void) a;
736    out[0] = UBYTE_TO_FLOAT(v[0]);
737    out[1] = UBYTE_TO_FLOAT(v[1]);
738    out[2] = UBYTE_TO_FLOAT(v[2]);
739    out[3] = 1;
740 }
741 
extract_3ub_3f_bgr(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)742 static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr *a, GLfloat *out,
743 				const GLubyte *v )
744 {
745    (void) a;
746    out[2] = UBYTE_TO_FLOAT(v[0]);
747    out[1] = UBYTE_TO_FLOAT(v[1]);
748    out[0] = UBYTE_TO_FLOAT(v[2]);
749    out[3] = 1;
750 }
751 
extract_1ub_1f(const struct tnl_clipspace_attr * a,GLfloat * out,const GLubyte * v)752 static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
753 {
754    (void) a;
755    out[0] = UBYTE_TO_FLOAT(v[0]);
756    out[1] = 0;
757    out[2] = 0;
758    out[3] = 1;
759 }
760 
761 
762 const struct tnl_format_info _tnl_format_info[EMIT_MAX] =
763 {
764    { "1f",
765      extract_1f,
766      { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 },
767      sizeof(GLfloat) },
768 
769    { "2f",
770      extract_2f,
771      { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 },
772      2 * sizeof(GLfloat) },
773 
774    { "3f",
775      extract_3f,
776      { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 },
777      3 * sizeof(GLfloat) },
778 
779    { "4f",
780      extract_4f,
781      { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 },
782      4 * sizeof(GLfloat) },
783 
784    { "2f_viewport",
785      extract_2f_viewport,
786      { insert_2f_viewport_1, insert_2f_viewport_2, insert_2f_viewport_2,
787        insert_2f_viewport_2 },
788      2 * sizeof(GLfloat) },
789 
790    { "3f_viewport",
791      extract_3f_viewport,
792      { insert_3f_viewport_1, insert_3f_viewport_2, insert_3f_viewport_3,
793        insert_3f_viewport_3 },
794      3 * sizeof(GLfloat) },
795 
796    { "4f_viewport",
797      extract_4f_viewport,
798      { insert_4f_viewport_1, insert_4f_viewport_2, insert_4f_viewport_3,
799        insert_4f_viewport_4 },
800      4 * sizeof(GLfloat) },
801 
802    { "3f_xyw",
803      extract_3f_xyw,
804      { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err,
805        insert_3f_xyw_4 },
806      3 * sizeof(GLfloat) },
807 
808    { "1ub_1f",
809      extract_1ub_1f,
810      { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 },
811      sizeof(GLubyte) },
812 
813    { "3ub_3f_rgb",
814      extract_3ub_3f_rgb,
815      { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3,
816        insert_3ub_3f_rgb_3 },
817      3 * sizeof(GLubyte) },
818 
819    { "3ub_3f_bgr",
820      extract_3ub_3f_bgr,
821      { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3,
822        insert_3ub_3f_bgr_3 },
823      3 * sizeof(GLubyte) },
824 
825    { "4ub_4f_rgba",
826      extract_4ub_4f_rgba,
827      { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3,
828        insert_4ub_4f_rgba_4 },
829      4 * sizeof(GLubyte) },
830 
831    { "4ub_4f_bgra",
832      extract_4ub_4f_bgra,
833      { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3,
834        insert_4ub_4f_bgra_4 },
835      4 * sizeof(GLubyte) },
836 
837    { "4ub_4f_argb",
838      extract_4ub_4f_argb,
839      { insert_4ub_4f_argb_1, insert_4ub_4f_argb_2, insert_4ub_4f_argb_3,
840        insert_4ub_4f_argb_4 },
841      4 * sizeof(GLubyte) },
842 
843    { "4ub_4f_abgr",
844      extract_4ub_4f_abgr,
845      { insert_4ub_4f_abgr_1, insert_4ub_4f_abgr_2, insert_4ub_4f_abgr_3,
846        insert_4ub_4f_abgr_4 },
847      4 * sizeof(GLubyte) },
848 
849    { "4chan_4f_rgba",
850      extract_4chan_4f_rgba,
851      { insert_4chan_4f_rgba_1, insert_4chan_4f_rgba_2, insert_4chan_4f_rgba_3,
852        insert_4chan_4f_rgba_4 },
853      4 * sizeof(GLchan) },
854 
855    { "pad",
856      NULL,
857      { NULL, NULL, NULL, NULL },
858      0 }
859 
860 };
861 
862 
863 
864 
865 /***********************************************************************
866  * Hardwired fastpaths for emitting whole vertices or groups of
867  * vertices
868  */
869 #define EMIT5(NR, F0, F1, F2, F3, F4, NAME)				\
870 static void NAME( struct gl_context *ctx,					\
871 		  GLuint count,						\
872 		  GLubyte *v )						\
873 {									\
874    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);			\
875    struct tnl_clipspace_attr *a = vtx->attr;				\
876    GLuint i;								\
877 									\
878    for (i = 0 ; i < count ; i++, v += vtx->vertex_size) {		\
879       if (NR > 0) {							\
880 	 F0( &a[0], v + a[0].vertoffset, (GLfloat *)a[0].inputptr );	\
881 	 a[0].inputptr += a[0].inputstride;				\
882       }									\
883       									\
884       if (NR > 1) {							\
885 	 F1( &a[1], v + a[1].vertoffset, (GLfloat *)a[1].inputptr );	\
886 	 a[1].inputptr += a[1].inputstride;				\
887       }									\
888       									\
889       if (NR > 2) {							\
890 	 F2( &a[2], v + a[2].vertoffset, (GLfloat *)a[2].inputptr );	\
891 	 a[2].inputptr += a[2].inputstride;				\
892       }									\
893       									\
894       if (NR > 3) {							\
895 	 F3( &a[3], v + a[3].vertoffset, (GLfloat *)a[3].inputptr );	\
896 	 a[3].inputptr += a[3].inputstride;				\
897       }									\
898 									\
899       if (NR > 4) {							\
900 	 F4( &a[4], v + a[4].vertoffset, (GLfloat *)a[4].inputptr );	\
901 	 a[4].inputptr += a[4].inputstride;				\
902       }									\
903    }									\
904 }
905 
906 
907 #define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \
908 				  insert_null, insert_null, NAME)
909 
910 #define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \
911 				      insert_null, NAME)
912 
913 #define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \
914 				          insert_null, NAME)
915 
916 
EMIT2(insert_3f_viewport_3,insert_4ub_4f_rgba_4,emit_viewport3_rgba4)917 EMIT2(insert_3f_viewport_3, insert_4ub_4f_rgba_4, emit_viewport3_rgba4)
918 EMIT2(insert_3f_viewport_3, insert_4ub_4f_bgra_4, emit_viewport3_bgra4)
919 EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4)
920 
921 EMIT3(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_viewport4_rgba4_st2)
922 EMIT3(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2,  emit_viewport4_bgra4_st2)
923 EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2)
924 
925 EMIT4(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_viewport4_rgba4_st2_st2)
926 EMIT4(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2, insert_2f_2,  emit_viewport4_bgra4_st2_st2)
927 EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2)
928 
929 
930 /* Use the codegen paths to select one of a number of hardwired
931  * fastpaths.
932  */
933 void _tnl_generate_hardwired_emit( struct gl_context *ctx )
934 {
935    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
936    tnl_emit_func func = NULL;
937 
938    /* Does it fit a hardwired fastpath?  Help! this is growing out of
939     * control!
940     */
941    switch (vtx->attr_count) {
942    case 2:
943       if (vtx->attr[0].emit == insert_3f_viewport_3) {
944 	 if (vtx->attr[1].emit == insert_4ub_4f_bgra_4)
945 	    func = emit_viewport3_bgra4;
946 	 else if (vtx->attr[1].emit == insert_4ub_4f_rgba_4)
947 	    func = emit_viewport3_rgba4;
948       }
949       else if (vtx->attr[0].emit == insert_3f_3 &&
950 	       vtx->attr[1].emit == insert_4ub_4f_rgba_4) {
951  	 func = emit_xyz3_rgba4;
952       }
953       break;
954    case 3:
955       if (vtx->attr[2].emit == insert_2f_2) {
956 	 if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) {
957 	    if (vtx->attr[0].emit == insert_4f_viewport_4)
958 	       func = emit_viewport4_rgba4_st2;
959 	    else if (vtx->attr[0].emit == insert_4f_4)
960 	       func = emit_xyzw4_rgba4_st2;
961 	 }
962 	 else if (vtx->attr[1].emit == insert_4ub_4f_bgra_4 &&
963 		  vtx->attr[0].emit == insert_4f_viewport_4)
964 	    func = emit_viewport4_bgra4_st2;
965       }
966       break;
967    case 4:
968       if (vtx->attr[2].emit == insert_2f_2 &&
969 	  vtx->attr[3].emit == insert_2f_2) {
970 	 if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) {
971 	    if (vtx->attr[0].emit == insert_4f_viewport_4)
972 	       func = emit_viewport4_rgba4_st2_st2;
973 	    else if (vtx->attr[0].emit == insert_4f_4)
974 	       func = emit_xyzw4_rgba4_st2_st2;
975 	 }
976 	 else if (vtx->attr[1].emit == insert_4ub_4f_bgra_4 &&
977 		  vtx->attr[0].emit == insert_4f_viewport_4)
978 	    func = emit_viewport4_bgra4_st2_st2;
979       }
980       break;
981    }
982 
983    vtx->emit = func;
984 }
985 
986 /***********************************************************************
987  * Generic (non-codegen) functions for whole vertices or groups of
988  * vertices
989  */
990 
_tnl_generic_emit(struct gl_context * ctx,GLuint count,GLubyte * v)991 void _tnl_generic_emit( struct gl_context *ctx,
992 			GLuint count,
993 			GLubyte *v )
994 {
995    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
996    struct tnl_clipspace_attr *a = vtx->attr;
997    const GLuint attr_count = vtx->attr_count;
998    const GLuint stride = vtx->vertex_size;
999    GLuint i, j;
1000 
1001    for (i = 0 ; i < count ; i++, v += stride) {
1002       for (j = 0; j < attr_count; j++) {
1003 	 GLfloat *in = (GLfloat *)a[j].inputptr;
1004 	 a[j].inputptr += a[j].inputstride;
1005 	 a[j].emit( &a[j], v + a[j].vertoffset, in );
1006       }
1007    }
1008 }
1009 
1010 
_tnl_generic_interp(struct gl_context * ctx,GLfloat t,GLuint edst,GLuint eout,GLuint ein,GLboolean force_boundary)1011 void _tnl_generic_interp( struct gl_context *ctx,
1012 			    GLfloat t,
1013 			    GLuint edst, GLuint eout, GLuint ein,
1014 			    GLboolean force_boundary )
1015 {
1016    TNLcontext *tnl = TNL_CONTEXT(ctx);
1017    struct vertex_buffer *VB = &tnl->vb;
1018    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1019    const GLubyte *vin  = vtx->vertex_buf + ein  * vtx->vertex_size;
1020    const GLubyte *vout = vtx->vertex_buf + eout * vtx->vertex_size;
1021    GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
1022    const struct tnl_clipspace_attr *a = vtx->attr;
1023    const GLuint attr_count = vtx->attr_count;
1024    GLuint j;
1025    (void) force_boundary;
1026 
1027    if (tnl->NeedNdcCoords) {
1028       const GLfloat *dstclip = VB->ClipPtr->data[edst];
1029       if (dstclip[3] != 0.0) {
1030 	 const GLfloat w = 1.0f / dstclip[3];
1031 	 GLfloat pos[4];
1032 
1033 	 pos[0] = dstclip[0] * w;
1034 	 pos[1] = dstclip[1] * w;
1035 	 pos[2] = dstclip[2] * w;
1036 	 pos[3] = w;
1037 
1038 	 a[0].insert[4-1]( &a[0], vdst, pos );
1039       }
1040    }
1041    else {
1042       a[0].insert[4-1]( &a[0], vdst, VB->ClipPtr->data[edst] );
1043    }
1044 
1045 
1046    for (j = 1; j < attr_count; j++) {
1047       GLfloat fin[4], fout[4], fdst[4];
1048 
1049       a[j].extract( &a[j], fin, vin + a[j].vertoffset );
1050       a[j].extract( &a[j], fout, vout + a[j].vertoffset );
1051 
1052       INTERP_4F(t, fdst, fout, fin);
1053 
1054       a[j].insert[4-1]( &a[j], vdst + a[j].vertoffset, fdst );
1055    }
1056 }
1057 
1058 
1059 /* Extract color attributes from one vertex and insert them into
1060  * another.  (Shortcircuit extract/insert with memcpy).
1061  */
_tnl_generic_copy_pv(struct gl_context * ctx,GLuint edst,GLuint esrc)1062 void _tnl_generic_copy_pv( struct gl_context *ctx, GLuint edst, GLuint esrc )
1063 {
1064    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1065    GLubyte *vsrc = vtx->vertex_buf + esrc * vtx->vertex_size;
1066    GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
1067    const struct tnl_clipspace_attr *a = vtx->attr;
1068    const GLuint attr_count = vtx->attr_count;
1069    GLuint j;
1070 
1071    for (j = 0; j < attr_count; j++) {
1072       if (a[j].attrib == VERT_ATTRIB_COLOR0 ||
1073 	  a[j].attrib == VERT_ATTRIB_COLOR1) {
1074 
1075 	 memcpy( vdst + a[j].vertoffset,
1076                  vsrc + a[j].vertoffset,
1077                  a[j].vertattrsize );
1078       }
1079    }
1080 }
1081 
1082 
1083 /* Helper functions for hardware which doesn't put back colors and/or
1084  * edgeflags into vertices.
1085  */
_tnl_generic_interp_extras(struct gl_context * ctx,GLfloat t,GLuint dst,GLuint out,GLuint in,GLboolean force_boundary)1086 void _tnl_generic_interp_extras( struct gl_context *ctx,
1087 				   GLfloat t,
1088 				   GLuint dst, GLuint out, GLuint in,
1089 				   GLboolean force_boundary )
1090 {
1091    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
1092 
1093    /* If stride is zero, BackfaceColorPtr is constant across the VB, so
1094     * there is no point interpolating between two values as they will
1095     * be identical.  In all other cases, this value is generated by
1096     * t_vb_lighttmp.h and has a stride of 4 dwords.
1097     */
1098    if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) {
1099       assert(VB->BackfaceColorPtr->stride == 4 * sizeof(GLfloat));
1100 
1101       INTERP_4F( t,
1102 		 VB->BackfaceColorPtr->data[dst],
1103 		 VB->BackfaceColorPtr->data[out],
1104 		 VB->BackfaceColorPtr->data[in] );
1105    }
1106 
1107    if (VB->BackfaceSecondaryColorPtr) {
1108       assert(VB->BackfaceSecondaryColorPtr->stride == 4 * sizeof(GLfloat));
1109 
1110       INTERP_3F( t,
1111 		 VB->BackfaceSecondaryColorPtr->data[dst],
1112 		 VB->BackfaceSecondaryColorPtr->data[out],
1113 		 VB->BackfaceSecondaryColorPtr->data[in] );
1114    }
1115 
1116    if (VB->BackfaceIndexPtr) {
1117       VB->BackfaceIndexPtr->data[dst][0] = LINTERP( t,
1118 					       VB->BackfaceIndexPtr->data[out][0],
1119 					       VB->BackfaceIndexPtr->data[in][0] );
1120    }
1121 
1122    if (VB->EdgeFlag) {
1123       VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
1124    }
1125 
1126    _tnl_generic_interp(ctx, t, dst, out, in, force_boundary);
1127 }
1128 
_tnl_generic_copy_pv_extras(struct gl_context * ctx,GLuint dst,GLuint src)1129 void _tnl_generic_copy_pv_extras( struct gl_context *ctx,
1130 				  GLuint dst, GLuint src )
1131 {
1132    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
1133 
1134    /* See above comment:
1135     */
1136    if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) {
1137       COPY_4FV( VB->BackfaceColorPtr->data[dst],
1138 		VB->BackfaceColorPtr->data[src] );
1139    }
1140 
1141    if (VB->BackfaceSecondaryColorPtr) {
1142       COPY_4FV( VB->BackfaceSecondaryColorPtr->data[dst],
1143 		VB->BackfaceSecondaryColorPtr->data[src] );
1144    }
1145 
1146    if (VB->BackfaceIndexPtr) {
1147       VB->BackfaceIndexPtr->data[dst][0] = VB->BackfaceIndexPtr->data[src][0];
1148    }
1149 
1150    _tnl_generic_copy_pv(ctx, dst, src);
1151 }
1152 
1153 
1154