1 
2 /*
3  * Mesa 3-D graphics library
4  * Version:  3.5
5  *
6  * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included
16  * in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  * Authors:
26  *    Keith Whitwell <keith@tungstengraphics.com>
27  */
28 #include "math/m_translate.h"
29 
30 #if (HAVE_HW_VIEWPORT)
31 #define UNVIEWPORT_VARS
32 #define UNVIEWPORT_X(x) x
33 #define UNVIEWPORT_Y(x) x
34 #define UNVIEWPORT_Z(x) x
35 #endif
36 
37 #ifndef LOCALVARS
38 #define LOCALVARS
39 #endif
40 
41 #ifndef CHECK_HW_DIVIDE
42 #define CHECK_HW_DIVIDE 1
43 #endif
44 
45 /* These don't need to be duplicated, but there's currently nowhere
46  * really convenient to put them.  Need to build some actual .o files in
47  * this directory?
48  */
copy_pv_rgba4_spec5(struct gl_context * ctx,GLuint edst,GLuint esrc)49 static void copy_pv_rgba4_spec5( struct gl_context *ctx, GLuint edst, GLuint esrc )
50 {
51    LOCALVARS
52    GLubyte *verts = GET_VERTEX_STORE();
53    GLuint size = GET_VERTEX_SIZE();
54    GLuint *dst = (GLuint *)(verts + (edst * size));
55    GLuint *src = (GLuint *)(verts + (esrc * size));
56    dst[4] = src[4];
57    dst[5] = src[5];
58 }
59 
copy_pv_rgba4(struct gl_context * ctx,GLuint edst,GLuint esrc)60 static void copy_pv_rgba4( struct gl_context *ctx, GLuint edst, GLuint esrc )
61 {
62    LOCALVARS
63    GLubyte *verts = GET_VERTEX_STORE();
64    GLuint size = GET_VERTEX_SIZE();
65    GLuint *dst = (GLuint *)(verts + (edst * size));
66    GLuint *src = (GLuint *)(verts + (esrc * size));
67    dst[4] = src[4];
68 }
69 
copy_pv_rgba3(struct gl_context * ctx,GLuint edst,GLuint esrc)70 static void copy_pv_rgba3( struct gl_context *ctx, GLuint edst, GLuint esrc )
71 {
72    LOCALVARS
73    GLubyte *verts = GET_VERTEX_STORE();
74    GLuint size = GET_VERTEX_SIZE();
75    GLuint *dst = (GLuint *)(verts + (edst * size));
76    GLuint *src = (GLuint *)(verts + (esrc * size));
77    dst[3] = src[3];
78 }
79 
80 
TAG(translate_vertex)81 void TAG(translate_vertex)(struct gl_context *ctx,
82 			   const VERTEX *src,
83 			   SWvertex *dst)
84 {
85    LOCALVARS
86    GLuint format = GET_VERTEX_FORMAT();
87    GLfloat *s = ctx->Viewport._WindowMap.m;
88    UNVIEWPORT_VARS;
89 
90    if (format == TINY_VERTEX_FORMAT) {
91       if (HAVE_HW_VIEWPORT) {
92 	 dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0]  * src->v.x + s[12];
93 	 dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5]  * src->v.y + s[13];
94 	 dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z + s[14];
95 	 dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
96       } else {
97 	 dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( src->v.x );
98 	 dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( src->v.y );
99 	 dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( src->v.z );
100 	 dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
101       }
102 
103       dst->color[0] = src->tv.color.red;
104       dst->color[1] = src->tv.color.green;
105       dst->color[2] = src->tv.color.blue;
106       dst->color[3] = src->tv.color.alpha;
107    }
108    else {
109       if (HAVE_HW_VIEWPORT) {
110 	 if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
111 	    GLfloat oow = 1.0 / src->v.w;
112 	    dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0]  * src->v.x * oow + s[12];
113 	    dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5]  * src->v.y * oow + s[13];
114 	    dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z * oow + s[14];
115 	    dst->attrib[FRAG_ATTRIB_WPOS][3] = oow;
116 	 } else {
117 	    dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0]  * src->v.x + s[12];
118 	    dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5]  * src->v.y + s[13];
119 	    dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z + s[14];
120 	    dst->attrib[FRAG_ATTRIB_WPOS][3] = src->v.w;
121 	 }
122       } else {
123 	 dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( src->v.x );
124 	 dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( src->v.y );
125 	 dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( src->v.z );
126 	 dst->attrib[FRAG_ATTRIB_WPOS][3] = src->v.w;
127       }
128 
129       dst->color[0] = src->v.color.red;
130       dst->color[1] = src->v.color.green;
131       dst->color[2] = src->v.color.blue;
132       dst->color[3] = src->v.color.alpha;
133 
134       dst->attrib[FRAG_ATTRIB_COL1][0] = UBYTE_TO_FLOAT(src->v.specular.red);
135       dst->attrib[FRAG_ATTRIB_COL1][1] = UBYTE_TO_FLOAT(src->v.specular.green);
136       dst->attrib[FRAG_ATTRIB_COL1][2] = UBYTE_TO_FLOAT(src->v.specular.blue);
137 
138       dst->attrib[FRAG_ATTRIB_FOGC][0] = UBYTE_TO_FLOAT(src->v.specular.alpha);
139 
140       if (HAVE_PTEX_VERTICES &&
141 	  ((HAVE_TEX2_VERTICES && format == PROJ_TEX3_VERTEX_FORMAT) ||
142 	   (format == PROJ_TEX1_VERTEX_FORMAT))) {
143 
144 	 dst->attrib[FRAG_ATTRIB_TEX0][0] = src->pv.u0;
145 	 dst->attrib[FRAG_ATTRIB_TEX0][1] = src->pv.v0;
146 	 dst->attrib[FRAG_ATTRIB_TEX0][3] = src->pv.q0;
147 
148 	 dst->attrib[FRAG_ATTRIB_TEX1][0] = src->pv.u1;
149 	 dst->attrib[FRAG_ATTRIB_TEX1][1] = src->pv.v1;
150 	 dst->attrib[FRAG_ATTRIB_TEX1][3] = src->pv.q1;
151 
152 	 if (HAVE_TEX2_VERTICES) {
153 	    dst->attrib[FRAG_ATTRIB_TEX2][0] = src->pv.u2;
154 	    dst->attrib[FRAG_ATTRIB_TEX2][1] = src->pv.v2;
155 	    dst->attrib[FRAG_ATTRIB_TEX2][3] = src->pv.q2;
156 	 }
157 
158 	 if (HAVE_TEX3_VERTICES) {
159 	    dst->attrib[FRAG_ATTRIB_TEX3][0] = src->pv.u3;
160 	    dst->attrib[FRAG_ATTRIB_TEX3][1] = src->pv.v3;
161 	    dst->attrib[FRAG_ATTRIB_TEX3][3] = src->pv.q3;
162 	 }
163       }
164       else {
165 	 dst->attrib[FRAG_ATTRIB_TEX0][0] = src->v.u0;
166 	 dst->attrib[FRAG_ATTRIB_TEX0][1] = src->v.v0;
167 	 dst->attrib[FRAG_ATTRIB_TEX0][3] = 1.0;
168 
169 	 dst->attrib[FRAG_ATTRIB_TEX1][0] = src->v.u1;
170 	 dst->attrib[FRAG_ATTRIB_TEX1][1] = src->v.v1;
171 	 dst->attrib[FRAG_ATTRIB_TEX1][3] = 1.0;
172 
173 	 if (HAVE_TEX2_VERTICES) {
174 	    dst->attrib[FRAG_ATTRIB_TEX2][0] = src->v.u2;
175 	    dst->attrib[FRAG_ATTRIB_TEX2][1] = src->v.v2;
176 	    dst->attrib[FRAG_ATTRIB_TEX2][3] = 1.0;
177 	 }
178 
179 	 if (HAVE_TEX3_VERTICES) {
180 	    dst->attrib[FRAG_ATTRIB_TEX3][0] = src->v.u3;
181 	    dst->attrib[FRAG_ATTRIB_TEX3][1] = src->v.v3;
182 	    dst->attrib[FRAG_ATTRIB_TEX3][3] = 1.0;
183 	 }
184       }
185    }
186 
187    dst->pointSize = ctx->Point.Size;
188 }
189 
190 
191 /* prototype to silence warning */
192 void TAG(print_vertex)( struct gl_context *ctx, const VERTEX *v );
193 
194 
TAG(print_vertex)195 void TAG(print_vertex)( struct gl_context *ctx, const VERTEX *v )
196 {
197    LOCALVARS
198    GLuint format = GET_VERTEX_FORMAT();
199 
200    fprintf(stderr, "(%x) ", format);
201 
202    switch (format) {
203 #if HAVE_TINY_VERTICES
204    case TINY_VERTEX_FORMAT:
205       fprintf(stderr, "xyz %.4f,%.4f,%.4f rgba %x:%x:%x:%x\n",
206 	      v->v.x, v->v.y, v->v.z,
207 	      v->tv.color.red,
208 	      v->tv.color.green,
209 	      v->tv.color.blue,
210 	      v->tv.color.alpha);
211       break;
212 #endif
213 #if HAVE_NOTEX_VERTICES
214    case NOTEX_VERTEX_FORMAT:
215       fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x spec %x:%x:%x:%x\n",
216 	      v->v.x, v->v.y, v->v.z, v->v.w,
217 	      v->v.color.red,
218 	      v->v.color.green,
219 	      v->v.color.blue,
220 	      v->v.color.alpha,
221 	      v->v.specular.red,
222 	      v->v.specular.green,
223 	      v->v.specular.blue,
224 	      v->v.specular.alpha);
225       break;
226 #endif
227 #if HAVE_TEX0_VERTICES
228    case TEX0_VERTEX_FORMAT:
229       fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f\n",
230 	      v->v.x, v->v.y, v->v.z, v->v.w,
231 	      v->v.color.red,
232 	      v->v.color.green,
233 	      v->v.color.blue,
234 	      v->v.color.alpha,
235 	      v->v.u0,
236 	      v->v.v0);
237       break;
238 #endif
239 #if HAVE_TEX1_VERTICES
240    case TEX1_VERTEX_FORMAT:
241       fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f st %.4f,%.4f\n",
242 	      v->v.x, v->v.y, v->v.z, v->v.w,
243 	      v->v.color.red,
244 	      v->v.color.green,
245 	      v->v.color.blue,
246 	      v->v.color.alpha,
247 	      v->v.u0,
248 	      v->v.v0,
249 	      v->v.u1,
250 	      v->v.u2);
251       break;
252 #endif
253 #if HAVE_PTEX_VERTICES
254    case PROJ_TEX1_VERTEX_FORMAT:
255       fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x stq %.4f,%.4f,%.4f stq %.4f,%.4f,%.4f\n",
256 	      v->v.x, v->v.y, v->v.z, v->v.w,
257 	      v->v.color.red,
258 	      v->v.color.green,
259 	      v->v.color.blue,
260 	      v->v.color.alpha,
261 	      v->pv.u0,
262 	      v->pv.v0,
263 	      v->pv.q0,
264 	      v->pv.u1,
265 	      v->pv.v1,
266 	      v->pv.q1);
267       break;
268 #endif
269    default:
270       fprintf(stderr, "???\n");
271       break;
272    }
273 
274    fprintf(stderr, "\n");
275 }
276 
277 
278 
279 /* Interpolate the elements of the VB not included in typical hardware
280  * vertices.
281  *
282  * NOTE: All these arrays are guarenteed by tnl to be writeable and
283  * have good stride.
284  */
285 #ifndef INTERP_QUALIFIER
286 #define INTERP_QUALIFIER static
287 #endif
288 
289 #define GET_COLOR(ptr, idx) ((ptr)->data[idx])
290 
291 
TAG(interp_extras)292 INTERP_QUALIFIER void TAG(interp_extras)( struct gl_context *ctx,
293 					  GLfloat t,
294 					  GLuint dst, GLuint out, GLuint in,
295 					  GLboolean force_boundary )
296 {
297    LOCALVARS
298    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
299 
300    if (VB->BackfaceColorPtr) {
301       assert(VB->BackfaceColorPtr->stride == 4 * sizeof(GLfloat));
302 
303       INTERP_4F( t,
304 		    GET_COLOR(VB->BackfaceColorPtr, dst),
305 		    GET_COLOR(VB->BackfaceColorPtr, out),
306 		    GET_COLOR(VB->BackfaceColorPtr, in) );
307 
308       if (VB->BackfaceSecondaryColorPtr) {
309 	 INTERP_3F( t,
310 		       GET_COLOR(VB->BackfaceSecondaryColorPtr, dst),
311 		       GET_COLOR(VB->BackfaceSecondaryColorPtr, out),
312 		       GET_COLOR(VB->BackfaceSecondaryColorPtr, in) );
313       }
314    }
315 
316    if (VB->EdgeFlag) {
317       VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
318    }
319 
320    INTERP_VERTEX(ctx, t, dst, out, in, force_boundary);
321 }
322 
TAG(copy_pv_extras)323 INTERP_QUALIFIER void TAG(copy_pv_extras)( struct gl_context *ctx,
324 					   GLuint dst, GLuint src )
325 {
326    LOCALVARS
327       struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
328 
329    if (VB->BackfaceColorPtr) {
330       COPY_4FV( GET_COLOR(VB->BackfaceColorPtr, dst),
331 		GET_COLOR(VB->BackfaceColorPtr, src) );
332 
333       if (VB->BackfaceSecondaryColorPtr) {
334 	 COPY_4FV( GET_COLOR(VB->BackfaceSecondaryColorPtr, dst),
335 		   GET_COLOR(VB->BackfaceSecondaryColorPtr, src) );
336       }
337    }
338 
339    COPY_PV_VERTEX(ctx, dst, src);
340 }
341 
342 
343 #undef INTERP_QUALIFIER
344 #undef GET_COLOR
345 
346 #undef IND
347 #undef TAG
348