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