Fixed off by one errors in clipping.
[mesa.git] / src / mesa / drivers / dri / unichrome / via_dd_vbtmp.h
1 /*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25
26 /* Unlike the other templates here, this assumes quite a bit about the
27 * underlying hardware. Specifically it assumes a d3d-like vertex
28 * format, with a layout more or less constrained to look like the
29 * following:
30 *
31 * union {
32 * struct {
33 * float x, y, z, w;
34 * struct { char r, g, b, a; } color;
35 * struct { char r, g, b, fog; } spec;
36 * float u0, v0;
37 * float u1, v1;
38 * float u2, v2;
39 * float u3, v3;
40 * } v;
41 * struct {
42 * float x, y, z, w;
43 * struct { char r, g, b, a; } color;
44 * struct { char r, g, b, fog; } spec;
45 * float u0, v0, q0;
46 * float u1, v1, q1;
47 * float u2, v2, q2;
48 * float u3, v3, q3;
49 * } pv;
50 * struct {
51 * float x, y, z;
52 * struct { char r, g, b, a; } color;
53 * } tv;
54 * float f[16];
55 * unsigned int ui[16];
56 * unsigned char ub4[4][16];
57 * }
58 *
59
60 * DO_XYZW: Emit xyz and maybe w coordinates.
61 * DO_RGBA: Emit color.
62 * DO_SPEC: Emit specular color.
63 * DO_FOG: Emit fog coordinate in specular alpha.
64 * DO_TEX0: Emit tex0 u,v coordinates.
65 * DO_TEX1: Emit tex1 u,v coordinates.
66 * DO_TEX2: Emit tex2 u,v coordinates.
67 * DO_TEX3: Emit tex3 u,v coordinates.
68 * DO_PTEX: Emit tex0,1,2,3 q coordinates where possible.
69 *
70 * HAVE_RGBA_COLOR: Hardware takes color in rgba order (else bgra).
71 *
72 * HAVE_HW_VIEWPORT: Hardware performs viewport transform.
73 * HAVE_HW_DIVIDE: Hardware performs perspective divide.
74 *
75 * HAVE_TINY_VERTICES: Hardware understands v.tv format.
76 * HAVE_PTEX_VERTICES: Hardware understands v.pv format.
77 * HAVE_NOTEX_VERTICES: Hardware understands v.v format with texcount 0.
78 *
79 * Additionally, this template assumes it is emitting *transformed*
80 * vertices; the modifications to emit untransformed vertices (ie. to
81 * t&l hardware) are probably too great to cooexist with the code
82 * already in this file.
83 *
84 * NOTE: The PTEX vertex format always includes TEX0 and TEX1, even if
85 * only TEX0 is enabled, in order to maintain a vertex size which is
86 * an exact number of quadwords.
87 */
88
89 #if (HAVE_HW_VIEWPORT)
90 #define VIEWPORT_X(dst, x) dst = x
91 #define VIEWPORT_Y(dst, y) dst = y
92 #define VIEWPORT_Z(dst, z) dst = z
93 #else
94 #define VIEWPORT_X(dst, x) dst = s[0] * x + s[12]
95 #define VIEWPORT_Y(dst, y) dst = s[5] * y + s[13]
96 #define VIEWPORT_Z(dst, z) dst = s[10] * z + s[14]
97 #endif
98
99 #if (HAVE_HW_DIVIDE && !HAVE_PTEX_VERTICES)
100 #error "can't cope with this combination"
101 #endif
102
103 #ifndef LOCALVARS
104 #define LOCALVARS
105 #endif
106
107 #ifndef CHECK_HW_DIVIDE
108 #define CHECK_HW_DIVIDE 1
109 #endif
110
111 #if (HAVE_HW_DIVIDE || DO_SPEC || DO_TEX0 || DO_FOG || !HAVE_TINY_VERTICES)
112
113 static void TAG(emit)(GLcontext *ctx,
114 GLuint start, GLuint end,
115 void *dest,
116 GLuint stride)
117 {
118 LOCALVARS
119 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
120 GLfloat (*tc0)[4], (*tc1)[4], (*fog)[4];
121 GLfloat (*tc2)[4], (*tc3)[4];
122 GLfloat (*col)[4], (*spec)[4];
123 GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride;
124 GLuint tc2_stride, tc3_stride;
125 GLuint tc0_size, tc1_size;
126 GLuint tc2_size, tc3_size;
127 GLfloat (*coord)[4];
128 GLuint coord_stride;
129 VERTEX *v = (VERTEX *)dest;
130 const GLfloat *s = GET_VIEWPORT_MAT();
131 const GLubyte *mask = VB->ClipMask;
132 int i;
133
134 #ifdef DEBUG
135 if (VIA_DEBUG) fprintf(stderr, "TAG-emit for HAVE_HW_DIVIDE || DO_SPEC || DO_TEX0 || DO_FOG || !HAVE_TINY_VERTICE\n");
136 #endif
137
138 if (HAVE_HW_VIEWPORT && HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
139 (void) s;
140 coord = VB->ClipPtr->data;
141 coord_stride = VB->ClipPtr->stride;
142 }
143 else {
144 coord = VB->NdcPtr->data;
145 coord_stride = VB->NdcPtr->stride;
146 }
147
148 if (DO_TEX3) {
149 const GLuint t3 = GET_TEXSOURCE(3);
150 tc3 = VB->TexCoordPtr[t3]->data;
151 tc3_stride = VB->TexCoordPtr[t3]->stride;
152 if (DO_PTEX)
153 tc3_size = VB->TexCoordPtr[t3]->size;
154 }
155
156 if (DO_TEX2) {
157 const GLuint t2 = GET_TEXSOURCE(2);
158 tc2 = VB->TexCoordPtr[t2]->data;
159 tc2_stride = VB->TexCoordPtr[t2]->stride;
160 if (DO_PTEX)
161 tc2_size = VB->TexCoordPtr[t2]->size;
162 }
163
164 if (DO_TEX1) {
165 const GLuint t1 = GET_TEXSOURCE(1);
166 tc1 = VB->TexCoordPtr[t1]->data;
167 tc1_stride = VB->TexCoordPtr[t1]->stride;
168 if (DO_PTEX)
169 tc1_size = VB->TexCoordPtr[t1]->size;
170 }
171
172 if (DO_TEX0) {
173 const GLuint t0 = GET_TEXSOURCE(0);
174 /* test */
175 tc0_stride = VB->TexCoordPtr[t0]->stride;
176 tc0 = VB->TexCoordPtr[t0]->data;
177 if (DO_PTEX)
178 tc0_size = VB->TexCoordPtr[t0]->size;
179 }
180
181 if (DO_RGBA) {
182 col = VB->ColorPtr[0]->data;
183 col_stride = VB->ColorPtr[0]->stride;
184 }
185
186 if (DO_SPEC) {
187 spec = VB->SecondaryColorPtr[0]->data;
188 spec_stride = VB->SecondaryColorPtr[0]->stride;
189 }
190
191 if (DO_FOG) {
192 if (VB->FogCoordPtr) {
193 fog = VB->FogCoordPtr->data;
194 fog_stride = VB->FogCoordPtr->stride;
195 }
196 else {
197 static GLfloat tmp[4] = { 0, 0, 0, 0 };
198 fog = &tmp;
199 fog_stride = 0;
200 }
201 }
202
203 /* May have nonstandard strides:
204 */
205 if (start) {
206 STRIDE_4F(coord, start * coord_stride);
207 if (DO_TEX0)
208 STRIDE_4F(tc0, start * tc0_stride);
209 if (DO_TEX1)
210 STRIDE_4F(tc1, start * tc1_stride);
211 if (DO_TEX2)
212 STRIDE_4F(tc2, start * tc2_stride);
213 if (DO_TEX3)
214 STRIDE_4F(tc3, start * tc3_stride);
215 if (DO_RGBA)
216 STRIDE_4F(col, start * col_stride);
217 if (DO_SPEC)
218 STRIDE_4F(spec, start * spec_stride);
219 if (DO_FOG)
220 STRIDE_4F(fog, start * fog_stride);
221 }
222
223 for (i = start; i < end; i++, v = (VERTEX *)((GLubyte *)v + stride)) {
224 if (DO_XYZW) {
225 if (HAVE_HW_VIEWPORT || mask[i] == 0) {
226 VIEWPORT_X(v->v.x, coord[0][0]);
227 VIEWPORT_Y(v->v.y, coord[0][1]);
228 VIEWPORT_Z(v->v.z, coord[0][2]);
229 }
230 v->v.w = coord[0][3];
231 STRIDE_4F(coord, coord_stride);
232 }
233 if (DO_RGBA) {
234 UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.red, col[0][0]);
235 UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.green, col[0][1]);
236 UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.blue, col[0][2]);
237 UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.alpha, col[0][3]);
238 STRIDE_4F(col, col_stride);
239 }
240
241 if (DO_SPEC) {
242 UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.red, spec[0][0]);
243 UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.green, spec[0][1]);
244 UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.blue, spec[0][2]);
245 STRIDE_4F(spec, spec_stride);
246 }
247 else {
248 v->v.specular.red = 0;
249 v->v.specular.green = 0;
250 v->v.specular.blue = 0;
251 }
252
253 if (DO_FOG) {
254 UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.alpha, fog[0][0]);
255 /*=* [DBG] exy : fix lighting on + fog off error *=*/
256 STRIDE_4F(fog, fog_stride);
257 }
258 else {
259 v->v.specular.alpha = 0;
260 }
261
262 if (DO_TEX0) {
263 v->v.u0 = tc0[0][0];
264 v->v.v0 = tc0[0][1];
265 if (DO_PTEX) {
266 if (HAVE_PTEX_VERTICES) {
267 if (tc0_size == 4)
268 v->pv.q0 = tc0[0][3];
269 else
270 v->pv.q0 = 1.0;
271 }
272 else if (tc0_size == 4) {
273 float rhw = 1.0 / tc0[0][3];
274 v->v.w *= tc0[0][3];
275 v->v.u0 *= rhw;
276 v->v.v0 *= rhw;
277 }
278 }
279 STRIDE_4F(tc0, tc0_stride);
280 }
281 if (DO_TEX1) {
282 if (DO_PTEX && HAVE_PTEX_VERTICES) {
283 v->pv.u1 = tc1[0][0];
284 v->pv.v1 = tc1[0][1];
285 if (tc1_size == 4)
286 v->pv.q1 = tc1[0][3];
287 else
288 v->pv.q1 = 1.0;
289 }
290 else {
291 v->v.u1 = tc1[0][0];
292 v->v.v1 = tc1[0][1];
293 }
294 STRIDE_4F(tc1, tc1_stride);
295 }
296 else if (DO_PTEX) {
297 *(GLuint *)&v->pv.q1 = 0;
298 }
299 if (DO_TEX2) {
300 if (DO_PTEX) {
301 v->pv.u2 = tc2[0][0];
302 v->pv.v2 = tc2[0][1];
303 if (tc2_size == 4)
304 v->pv.q2 = tc2[0][3];
305 else
306 v->pv.q2 = 1.0;
307 }
308 else {
309 v->v.u2 = tc2[0][0];
310 v->v.v2 = tc2[0][1];
311 }
312 STRIDE_4F(tc2, tc2_stride);
313 }
314 if (DO_TEX3) {
315 if (DO_PTEX) {
316 v->pv.u3 = tc3[0][0];
317 v->pv.v3 = tc3[0][1];
318 if (tc3_size == 4)
319 v->pv.q3 = tc3[0][3];
320 else
321 v->pv.q3 = 1.0;
322 }
323 else {
324 v->v.u3 = tc3[0][0];
325 v->v.v3 = tc3[0][1];
326 }
327 STRIDE_4F(tc3, tc3_stride);
328 }
329 }
330 }
331 #else
332 #if DO_XYZW
333
334 #if HAVE_HW_DIVIDE
335 #error "cannot use tiny vertices with hw perspective divide"
336 #endif
337
338 static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
339 void *dest, GLuint stride)
340 {
341 LOCALVARS
342 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
343 GLfloat (*col)[4];
344 GLuint col_stride;
345 GLfloat (*coord)[4] = VB->NdcPtr->data;
346 GLuint coord_stride = VB->NdcPtr->stride;
347 GLfloat *v = (GLfloat *)dest;
348 const GLubyte *mask = VB->ClipMask;
349 const GLfloat *s = GET_VIEWPORT_MAT();
350 int i;
351
352 (void) s;
353
354 /*ASSERT(stride == 4);*/
355 #ifdef DEBUG
356 if (VIA_DEBUG) {
357 fprintf(stderr, "TAG-emit for DO_XYZW\n");
358 fprintf(stderr, "%s\n", __FUNCTION__);
359 }
360 #endif
361
362 col = VB->ColorPtr[0]->data;
363 col_stride = VB->ColorPtr[0]->stride;
364
365 if (start) {
366 STRIDE_4F(coord, start * coord_stride);
367 STRIDE_4F(col, start * col_stride);
368 }
369
370 for (i = start; i < end; i++, v += 4) {
371 if (DO_XYZW) {
372 if (HAVE_HW_VIEWPORT || mask[i] == 0) {
373 VIEWPORT_X(v[0], coord[0][0]);
374 VIEWPORT_Y(v[1], coord[0][1]);
375 VIEWPORT_Z(v[2], coord[0][2]);
376 }
377 STRIDE_4F(coord, coord_stride);
378 }
379 if (DO_RGBA) {
380 VERTEX_COLOR *c = (VERTEX_COLOR *)&v[3];
381 UNCLAMPED_FLOAT_TO_UBYTE(c->red, col[0][0]);
382 UNCLAMPED_FLOAT_TO_UBYTE(c->green, col[0][1]);
383 UNCLAMPED_FLOAT_TO_UBYTE(c->blue, col[0][2]);
384 UNCLAMPED_FLOAT_TO_UBYTE(c->alpha, col[0][3]);
385 STRIDE_4F( col, col_stride );
386 }
387 }
388 }
389 #else
390 static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
391 void *dest, GLuint stride)
392 {
393 LOCALVARS
394 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
395 GLubyte (*col)[4];
396 GLuint col_stride;
397 GLfloat *v = (GLfloat *)dest;
398 int i;
399 #ifdef DEBUG
400 if (VIA_DEBUG) {
401 fprintf(stderr, "TAG-emit for No DO_XYZW\n");
402 fprintf(stderr, "%s\n", __FUNCTION__);
403 }
404 #endif
405
406 if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE)
407 IMPORT_FLOAT_COLORS( ctx );
408
409 col = VB->ColorPtr[0]->Ptr;
410 col_stride = VB->ColorPtr[0]->StrideB;
411
412 if (start)
413 STRIDE_4UB(col, col_stride * start);
414
415 /* Need to figure out where color is:
416 */
417 if (GET_VERTEX_FORMAT() == TINY_VERTEX_FORMAT)
418 v += 3;
419 else
420 v += 4;
421
422 for (i = start; i < end; i++, STRIDE_F(v, stride)) {
423 if (HAVE_RGBA_COLOR) {
424 *(GLuint *)v = *(GLuint *)col[0];
425 }
426 else {
427 GLubyte *b = (GLubyte *)v;
428 b[0] = col[0][2];
429 b[1] = col[0][1];
430 b[2] = col[0][0];
431 b[3] = col[0][3];
432 }
433 STRIDE_4UB(col, col_stride);
434 }
435 }
436 #endif /* emit */
437 #endif /* emit */
438
439 #if (DO_XYZW) && (DO_RGBA)
440
441 #if (HAVE_PTEX_VERTICES)
442 static GLboolean TAG(check_tex_sizes)(GLcontext *ctx)
443 {
444 LOCALVARS
445 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
446
447 /* Force 'missing' texcoords to something valid.
448 */
449 #ifdef DEBUG
450 fprintf(stderr, "%s - in\n", __FUNCTION__);
451 #endif
452 if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
453 VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
454
455 if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
456 VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
457
458 if (DO_TEX1 && VB->TexCoordPtr[0] == 0)
459 VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
460
461 if (DO_PTEX)
462 return GL_TRUE;
463
464 if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
465 (DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
466 (DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4) ||
467 (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4))
468 return GL_FALSE;
469 #ifdef DEBUG
470 fprintf(stderr, "%s - out\n", __FUNCTION__);
471 #endif
472 return GL_TRUE;
473 }
474 #else
475 static GLboolean TAG(check_tex_sizes)(GLcontext *ctx)
476 {
477 LOCALVARS
478 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
479
480 /* Force 'missing' texcoords to something valid.
481 */
482 if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
483 VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
484
485 if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
486 VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
487
488 if (DO_TEX1 && VB->TexCoordPtr[0] == 0) {
489 VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
490 }
491
492 if (DO_PTEX)
493 return GL_TRUE;
494
495 if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
496 (DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
497 (DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4)) {
498 /*PTEX_FALLBACK();*/
499 return GL_FALSE;
500 }
501
502 if (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4) {
503 if (DO_TEX1 || DO_TEX2 || DO_TEX3) {
504 /*PTEX_FALLBACK();*/
505 }
506 return GL_FALSE;
507 }
508 return GL_TRUE;
509 }
510 #endif /* ptex */
511
512
513 static void TAG(interp)(GLcontext *ctx,
514 GLfloat t,
515 GLuint edst, GLuint eout, GLuint ein,
516 GLboolean force_boundary)
517 {
518 LOCALVARS
519 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
520 GLubyte *ddverts = GET_VERTEX_STORE();
521 GLuint shift = GET_VERTEX_STRIDE_SHIFT();
522 const GLfloat *dstclip = VB->ClipPtr->data[edst];
523 GLfloat w;
524 const GLfloat *s = GET_VIEWPORT_MAT();
525
526 VERTEX *dst = (VERTEX *)(ddverts + (edst << shift));
527 VERTEX *in = (VERTEX *)(ddverts + (ein << shift));
528 VERTEX *out = (VERTEX *)(ddverts + (eout << shift));
529
530 (void)s;
531 #ifdef DEBUG
532 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
533 #endif
534 if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
535 VIEWPORT_X(dst->v.x, dstclip[0]);
536 VIEWPORT_Y(dst->v.y, dstclip[1]);
537 VIEWPORT_Z(dst->v.z, dstclip[2]);
538 w = dstclip[3];
539 }
540 else {
541 w = 1.0 / dstclip[3];
542 VIEWPORT_X(dst->v.x, dstclip[0] * w);
543 VIEWPORT_Y(dst->v.y, dstclip[1] * w);
544 VIEWPORT_Z(dst->v.z, dstclip[2] * w);
545 }
546
547 if ((HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) ||
548 DO_FOG || DO_SPEC || DO_TEX0 || DO_TEX1 ||
549 DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES) {
550
551 dst->v.w = w;
552
553 INTERP_UB(t, dst->ub4[4][0], out->ub4[4][0], in->ub4[4][0]);
554 INTERP_UB(t, dst->ub4[4][1], out->ub4[4][1], in->ub4[4][1]);
555 INTERP_UB(t, dst->ub4[4][2], out->ub4[4][2], in->ub4[4][2]);
556 INTERP_UB(t, dst->ub4[4][3], out->ub4[4][3], in->ub4[4][3]);
557
558 if (DO_SPEC) {
559 INTERP_UB(t, dst->ub4[5][0], out->ub4[5][0], in->ub4[5][0]);
560 INTERP_UB(t, dst->ub4[5][1], out->ub4[5][1], in->ub4[5][1]);
561 INTERP_UB(t, dst->ub4[5][2], out->ub4[5][2], in->ub4[5][2]);
562 }
563 if (DO_FOG) {
564 INTERP_UB(t, dst->ub4[5][3], out->ub4[5][3], in->ub4[5][3]);
565 }
566 if (DO_TEX0) {
567 if (DO_PTEX) {
568 if (HAVE_PTEX_VERTICES) {
569 INTERP_F(t, dst->pv.u0, out->pv.u0, in->pv.u0);
570 INTERP_F(t, dst->pv.v0, out->pv.v0, in->pv.v0);
571 INTERP_F(t, dst->pv.q0, out->pv.q0, in->pv.q0);
572 }
573 else {
574 INTERP_F(t, dst->v.u0, out->v.u0, in->v.u0);
575 INTERP_F(t, dst->v.v0, out->v.v0, in->v.v0);
576 }
577 }
578 else {
579 INTERP_F(t, dst->v.u0, out->v.u0, in->v.u0);
580 INTERP_F(t, dst->v.v0, out->v.v0, in->v.v0);
581 }
582 }
583 if (DO_TEX1) {
584 if (DO_PTEX) {
585 if (HAVE_PTEX_VERTICES) {
586 INTERP_F(t, dst->pv.u1, out->pv.u1, in->pv.u1);
587 INTERP_F(t, dst->pv.v1, out->pv.v1, in->pv.v1);
588 INTERP_F(t, dst->pv.q1, out->pv.q1, in->pv.q1);
589 }
590 else {
591 INTERP_F(t, dst->v.u1, out->v.u1, in->v.u1);
592 INTERP_F(t, dst->v.v1, out->v.v1, in->v.v1);
593 }
594 }
595 else {
596 INTERP_F(t, dst->v.u1, out->v.u1, in->v.u1);
597 INTERP_F(t, dst->v.v1, out->v.v1, in->v.v1);
598 }
599 }
600 else if (DO_PTEX) {
601 dst->pv.q0 = 0.0; /* must be a valid float on radeon */
602 }
603 if (DO_TEX2) {
604 if (DO_PTEX) {
605 INTERP_F(t, dst->pv.u2, out->pv.u2, in->pv.u2);
606 INTERP_F(t, dst->pv.v2, out->pv.v2, in->pv.v2);
607 INTERP_F(t, dst->pv.q2, out->pv.q2, in->pv.q2);
608 }
609 else {
610 INTERP_F(t, dst->v.u2, out->v.u2, in->v.u2);
611 INTERP_F(t, dst->v.v2, out->v.v2, in->v.v2);
612 }
613 }
614 if (DO_TEX3) {
615 if (DO_PTEX) {
616 INTERP_F(t, dst->pv.u3, out->pv.u3, in->pv.u3);
617 INTERP_F(t, dst->pv.v3, out->pv.v3, in->pv.v3);
618 INTERP_F(t, dst->pv.q3, out->pv.q3, in->pv.q3);
619 }
620 else {
621 INTERP_F(t, dst->v.u3, out->v.u3, in->v.u3);
622 INTERP_F(t, dst->v.v3, out->v.v3, in->v.v3);
623 }
624 }
625 }
626 else {
627 /* 4-dword vertex. Color is in v[3] and there is no oow coordinate.
628 */
629 INTERP_UB(t, dst->ub4[3][0], out->ub4[3][0], in->ub4[3][0]);
630 INTERP_UB(t, dst->ub4[3][1], out->ub4[3][1], in->ub4[3][1]);
631 INTERP_UB(t, dst->ub4[3][2], out->ub4[3][2], in->ub4[3][2]);
632 INTERP_UB(t, dst->ub4[3][3], out->ub4[3][3], in->ub4[3][3]);
633 }
634 #ifdef DEBUG
635 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
636 #endif
637 }
638
639 #endif /* rgba && xyzw */
640
641 static void TAG(init)(void)
642 {
643 setup_tab[IND].emit = TAG(emit);
644
645 #if (DO_XYZW && DO_RGBA)
646 setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes);
647 setup_tab[IND].interp = TAG(interp);
648 #endif
649
650 if (DO_SPEC)
651 setup_tab[IND].copyPv = copy_pv_rgba4_spec5;
652 else if (HAVE_HW_DIVIDE || DO_SPEC || DO_FOG || DO_TEX0 || DO_TEX1 ||
653 DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES)
654 setup_tab[IND].copyPv = copy_pv_rgba4;
655 else
656 setup_tab[IND].copyPv = copy_pv_rgba3;
657
658 if (DO_TEX3) {
659 if (DO_PTEX && HAVE_PTEX_VERTICES) {
660 ASSERT(HAVE_PTEX_VERTICES);
661 setup_tab[IND].vertexFormat = PROJ_TEX3_VERTEX_FORMAT;
662 setup_tab[IND].vertexSize = 18;
663 setup_tab[IND].vertexStrideShift = 7;
664 }
665 else {
666 setup_tab[IND].vertexFormat = TEX3_VERTEX_FORMAT;
667 setup_tab[IND].vertexSize = 14;
668 setup_tab[IND].vertexStrideShift = 6;
669 }
670 }
671 else if (DO_TEX2) {
672 if (DO_PTEX && HAVE_PTEX_VERTICES) {
673 ASSERT(HAVE_PTEX_VERTICES);
674 setup_tab[IND].vertexFormat = PROJ_TEX3_VERTEX_FORMAT;
675 setup_tab[IND].vertexSize = 18;
676 setup_tab[IND].vertexStrideShift = 7;
677 }
678 else {
679 setup_tab[IND].vertexFormat = TEX2_VERTEX_FORMAT;
680 setup_tab[IND].vertexSize = 12;
681 setup_tab[IND].vertexStrideShift = 6;
682 }
683 }
684 else if (DO_TEX1) {
685 if (DO_PTEX && HAVE_PTEX_VERTICES) {
686 ASSERT(HAVE_PTEX_VERTICES);
687 setup_tab[IND].vertexFormat = PROJ_TEX1_VERTEX_FORMAT;
688 setup_tab[IND].vertexSize = 12;
689 setup_tab[IND].vertexStrideShift = 6;
690 }
691 else {
692 setup_tab[IND].vertexFormat = TEX1_VERTEX_FORMAT;
693 setup_tab[IND].vertexSize = 10;
694 setup_tab[IND].vertexStrideShift = 6;
695 }
696 }
697 else if (DO_TEX0) {
698 if (DO_PTEX && HAVE_PTEX_VERTICES) {
699 setup_tab[IND].vertexFormat = PROJ_TEX1_VERTEX_FORMAT;
700 setup_tab[IND].vertexSize = 12;
701 setup_tab[IND].vertexStrideShift = 6;
702 }
703 else {
704 setup_tab[IND].vertexFormat = TEX0_VERTEX_FORMAT;
705 setup_tab[IND].vertexSize = 8;
706 setup_tab[IND].vertexStrideShift = 5;
707 }
708 }
709 else if (!HAVE_HW_DIVIDE && !DO_SPEC && !DO_FOG && HAVE_TINY_VERTICES) {
710 setup_tab[IND].vertexFormat = TINY_VERTEX_FORMAT;
711 setup_tab[IND].vertexSize = 4;
712 setup_tab[IND].vertexStrideShift = 4;
713 }
714 else if (HAVE_NOTEX_VERTICES) {
715 setup_tab[IND].vertexFormat = NOTEX_VERTEX_FORMAT;
716 setup_tab[IND].vertexSize = 6;
717 setup_tab[IND].vertexStrideShift = 5;
718 }
719 else {
720 setup_tab[IND].vertexFormat = TEX0_VERTEX_FORMAT;
721 setup_tab[IND].vertexSize = 8;
722 setup_tab[IND].vertexStrideShift = 5;
723 }
724
725 assert(setup_tab[IND].vertexSize * 4 <=
726 1 << setup_tab[IND].vertexStrideShift);
727 }
728
729 #undef IND
730 #undef TAG