Merge branch 'master' of git+ssh://michal@git.freedesktop.org/git/mesa/mesa into...
[mesa.git] / src / mesa / tnl_dd / t_dd_vb.c
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 */
49 static void copy_pv_rgba4_spec5( GLcontext *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
60 static void copy_pv_rgba4( GLcontext *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
70 static void copy_pv_rgba3( GLcontext *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
81 void TAG(translate_vertex)(GLcontext *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
192 void TAG(print_vertex)( GLcontext *ctx, const VERTEX *v )
193 {
194 LOCALVARS
195 GLuint format = GET_VERTEX_FORMAT();
196
197 fprintf(stderr, "(%x) ", format);
198
199 switch (format) {
200 #if HAVE_TINY_VERTICES
201 case TINY_VERTEX_FORMAT:
202 fprintf(stderr, "xyz %.4f,%.4f,%.4f rgba %x:%x:%x:%x\n",
203 v->v.x, v->v.y, v->v.z,
204 v->tv.color.red,
205 v->tv.color.green,
206 v->tv.color.blue,
207 v->tv.color.alpha);
208 break;
209 #endif
210 #if HAVE_NOTEX_VERTICES
211 case NOTEX_VERTEX_FORMAT:
212 fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x spec %x:%x:%x:%x\n",
213 v->v.x, v->v.y, v->v.z, v->v.w,
214 v->v.color.red,
215 v->v.color.green,
216 v->v.color.blue,
217 v->v.color.alpha,
218 v->v.specular.red,
219 v->v.specular.green,
220 v->v.specular.blue,
221 v->v.specular.alpha);
222 break;
223 #endif
224 #if HAVE_TEX0_VERTICES
225 case TEX0_VERTEX_FORMAT:
226 fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f\n",
227 v->v.x, v->v.y, v->v.z, v->v.w,
228 v->v.color.red,
229 v->v.color.green,
230 v->v.color.blue,
231 v->v.color.alpha,
232 v->v.u0,
233 v->v.v0);
234 break;
235 #endif
236 #if HAVE_TEX1_VERTICES
237 case TEX1_VERTEX_FORMAT:
238 fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f st %.4f,%.4f\n",
239 v->v.x, v->v.y, v->v.z, v->v.w,
240 v->v.color.red,
241 v->v.color.green,
242 v->v.color.blue,
243 v->v.color.alpha,
244 v->v.u0,
245 v->v.v0,
246 v->v.u1,
247 v->v.u2);
248 break;
249 #endif
250 #if HAVE_PTEX_VERTICES
251 case PROJ_TEX1_VERTEX_FORMAT:
252 fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x stq %.4f,%.4f,%.4f stq %.4f,%.4f,%.4f\n",
253 v->v.x, v->v.y, v->v.z, v->v.w,
254 v->v.color.red,
255 v->v.color.green,
256 v->v.color.blue,
257 v->v.color.alpha,
258 v->pv.u0,
259 v->pv.v0,
260 v->pv.q0,
261 v->pv.u1,
262 v->pv.v1,
263 v->pv.q1);
264 break;
265 #endif
266 default:
267 fprintf(stderr, "???\n");
268 break;
269 }
270
271 fprintf(stderr, "\n");
272 }
273
274
275
276 /* Interpolate the elements of the VB not included in typical hardware
277 * vertices.
278 *
279 * NOTE: All these arrays are guarenteed by tnl to be writeable and
280 * have good stride.
281 */
282 #ifndef INTERP_QUALIFIER
283 #define INTERP_QUALIFIER static
284 #endif
285
286 #define GET_COLOR(ptr, idx) ((ptr)->data[idx])
287
288
289 INTERP_QUALIFIER void TAG(interp_extras)( GLcontext *ctx,
290 GLfloat t,
291 GLuint dst, GLuint out, GLuint in,
292 GLboolean force_boundary )
293 {
294 LOCALVARS
295 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
296
297 if (VB->ColorPtr[1]) {
298 assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat));
299
300 INTERP_4F( t,
301 GET_COLOR(VB->ColorPtr[1], dst),
302 GET_COLOR(VB->ColorPtr[1], out),
303 GET_COLOR(VB->ColorPtr[1], in) );
304
305 if (VB->SecondaryColorPtr[1]) {
306 INTERP_3F( t,
307 GET_COLOR(VB->SecondaryColorPtr[1], dst),
308 GET_COLOR(VB->SecondaryColorPtr[1], out),
309 GET_COLOR(VB->SecondaryColorPtr[1], in) );
310 }
311 }
312
313 if (VB->EdgeFlag) {
314 VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
315 }
316
317 INTERP_VERTEX(ctx, t, dst, out, in, force_boundary);
318 }
319
320 INTERP_QUALIFIER void TAG(copy_pv_extras)( GLcontext *ctx,
321 GLuint dst, GLuint src )
322 {
323 LOCALVARS
324 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
325
326 if (VB->ColorPtr[1]) {
327 COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst),
328 GET_COLOR(VB->ColorPtr[1], src) );
329
330 if (VB->SecondaryColorPtr[1]) {
331 COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst),
332 GET_COLOR(VB->SecondaryColorPtr[1], src) );
333 }
334 }
335
336 COPY_PV_VERTEX(ctx, dst, src);
337 }
338
339
340 #undef INTERP_QUALIFIER
341 #undef GET_COLOR
342
343 #undef IND
344 #undef TAG