disable W1 when single-texturing
[mesa.git] / src / mesa / drivers / glide / fxvbtmp.h
1 /*
2 * Mesa 3-D graphics library
3 * Version: 4.1
4 *
5 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /* Authors:
26 * Keith Whitwell <keith@tungstengraphics.com>
27 * Daniel Borca <dborca@users.sourceforge.net>
28 */
29
30
31 #define VIEWPORT_X(dst,x) dst = s[0] * x + s[12]
32 #define VIEWPORT_Y(dst,y) dst = s[5] * y + s[13]
33 #define VIEWPORT_Z(dst,z) dst = s[10] * z + s[14]
34
35 static void TAG(emit)( GLcontext *ctx,
36 GLuint start, GLuint end,
37 void *dest )
38 {
39 fxMesaContext fxMesa = FX_CONTEXT(ctx);
40 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
41 GLuint tmu0_source = fxMesa->tmu_source[0];
42 GLuint tmu1_source = fxMesa->tmu_source[1];
43 GLfloat (*tc0)[4], (*tc1)[4];
44 GLfloat (*col)[4], (*spec)[4];
45 GLuint tc0_stride, tc1_stride, col_stride, spec_stride;
46 GLuint tc0_size, tc1_size, col_size;
47 GLfloat (*proj)[4] = VB->NdcPtr->data;
48 GLuint proj_stride = VB->NdcPtr->stride;
49 GLfloat (*psize)[4];
50 GLuint psize_stride;
51 GLfloat (*fog)[4];
52 GLuint fog_stride;
53 GrVertex *v = (GrVertex *)dest;
54 GLfloat u0scale,v0scale,u1scale,v1scale;
55 const GLubyte *mask = VB->ClipMask;
56 const GLfloat *const s = ctx->Viewport._WindowMap.m;
57 int i;
58
59 if (IND & SETUP_PSIZ) {
60 psize = VB->PointSizePtr->data;
61 psize_stride = VB->PointSizePtr->stride;
62 }
63
64 if (IND & SETUP_TMU0) {
65 tc0 = VB->TexCoordPtr[tmu0_source]->data;
66 tc0_stride = VB->TexCoordPtr[tmu0_source]->stride;
67 u0scale = fxMesa->s0scale;
68 v0scale = fxMesa->t0scale;
69 if (IND & SETUP_PTEX)
70 tc0_size = VB->TexCoordPtr[tmu0_source]->size;
71 }
72
73 if (IND & SETUP_TMU1) {
74 tc1 = VB->TexCoordPtr[tmu1_source]->data;
75 tc1_stride = VB->TexCoordPtr[tmu1_source]->stride;
76 u1scale = fxMesa->s1scale; /* wrong if tmu1_source == 0, possible? */
77 v1scale = fxMesa->t1scale;
78 if (IND & SETUP_PTEX)
79 tc1_size = VB->TexCoordPtr[tmu1_source]->size;
80 }
81
82 if (IND & SETUP_RGBA) {
83 col = VB->ColorPtr[0]->data;
84 col_stride = VB->ColorPtr[0]->stride;
85 col_size = VB->ColorPtr[0]->size;
86 }
87
88 if (IND & SETUP_SPEC) {
89 spec = VB->SecondaryColorPtr[0]->data;
90 spec_stride = VB->SecondaryColorPtr[0]->stride;
91 }
92
93 if (IND & SETUP_FOGC) {
94 fog = VB->FogCoordPtr->data;
95 fog_stride = VB->FogCoordPtr->stride;
96 }
97
98 if (start) {
99 proj = (GLfloat (*)[4])((GLubyte *)proj + start * proj_stride);
100 if (IND & SETUP_PSIZ)
101 psize = (GLfloat (*)[4])((GLubyte *)psize + start * psize_stride);
102 if (IND & SETUP_TMU0)
103 tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + start * tc0_stride);
104 if (IND & SETUP_TMU1)
105 tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + start * tc1_stride);
106 if (IND & SETUP_RGBA)
107 STRIDE_4F(col, start * col_stride);
108 if (IND & SETUP_SPEC)
109 STRIDE_4F(spec, start * spec_stride);
110 if (IND & SETUP_FOGC)
111 fog = (GLfloat (*)[4])((GLubyte *)fog + start * fog_stride);
112 }
113
114 for (i=start; i < end; i++, v++) {
115 if (IND & SETUP_PSIZ) {
116 v->psize = psize[0][0];
117 psize = (GLfloat (*)[4])((GLubyte *)psize + psize_stride);
118 }
119
120 if (IND & SETUP_XYZW) {
121 if (mask[i] == 0) {
122 /* unclipped */
123 VIEWPORT_X(v->x, proj[0][0]);
124 VIEWPORT_Y(v->y, proj[0][1]);
125 VIEWPORT_Z(v->ooz, proj[0][2]);
126 v->oow = proj[0][3];
127 } else {
128 /* clipped */
129 v->oow = 1.0;
130 }
131
132 if (IND & SETUP_SNAP) {
133 #if defined(USE_IEEE)
134 const float snapper = (3L << 18);
135 v->x += snapper;
136 v->x -= snapper;
137 v->y += snapper;
138 v->y -= snapper;
139 #else
140 v->x = ((int) (v->x * 16.0f)) * (1.0f / 16.0f);
141 v->y = ((int) (v->y * 16.0f)) * (1.0f / 16.0f);
142 #endif
143 }
144
145 proj = (GLfloat (*)[4])((GLubyte *)proj + proj_stride);
146 }
147 if (IND & SETUP_RGBA) {
148 UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[2], col[0][0]);
149 UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[1], col[0][1]);
150 UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[0], col[0][2]);
151 if (col_size == 4) {
152 UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[3], col[0][3]);
153 } else {
154 v->pargb[3] = 255;
155 }
156 STRIDE_4F(col, col_stride);
157 }
158 if (IND & SETUP_SPEC) {
159 UNCLAMPED_FLOAT_TO_UBYTE(v->pspec[2], spec[0][0]);
160 UNCLAMPED_FLOAT_TO_UBYTE(v->pspec[1], spec[0][1]);
161 UNCLAMPED_FLOAT_TO_UBYTE(v->pspec[0], spec[0][2]);
162 STRIDE_4F(spec, spec_stride);
163 }
164 if (IND & SETUP_FOGC) {
165 v->fog = CLAMP(fog[0][0], 0.0f, 1.0f);
166 fog = (GLfloat (*)[4])((GLubyte *)fog + fog_stride);
167 }
168 if (IND & SETUP_TMU0) {
169 GLfloat w = v->oow;
170 v->tmuvtx[0].sow = tc0[0][0] * u0scale * w;
171 v->tmuvtx[0].tow = tc0[0][1] * v0scale * w;
172 if (IND & SETUP_PTEX) {
173 v->tmuvtx[0].oow = w;
174 if (tc0_size == 4)
175 v->tmuvtx[0].oow *= tc0[0][3];
176 }
177 tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride);
178 }
179 if (IND & SETUP_TMU1) {
180 GLfloat w = v->oow;
181 v->tmuvtx[1].sow = tc1[0][0] * u1scale * w;
182 v->tmuvtx[1].tow = tc1[0][1] * v1scale * w;
183 if (IND & SETUP_PTEX) {
184 v->tmuvtx[1].oow = w;
185 if (tc1_size == 4)
186 v->tmuvtx[1].oow *= tc1[0][3];
187 }
188 tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + tc1_stride);
189 }
190 }
191 }
192
193 #if (IND & SETUP_XYZW) && (IND & SETUP_RGBA)
194
195 static GLboolean TAG(check_tex_sizes)( GLcontext *ctx )
196 {
197 /* fprintf(stderr, "%s\n", __FUNCTION__); */
198
199 if (IND & SETUP_PTEX)
200 return GL_TRUE;
201
202 if (IND & SETUP_TMU0) {
203 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
204
205 if (IND & SETUP_TMU1) {
206 if (VB->TexCoordPtr[0] == 0)
207 VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
208
209 if (VB->TexCoordPtr[1]->size == 4)
210 return GL_FALSE;
211 }
212
213 if (VB->TexCoordPtr[0] && VB->TexCoordPtr[0]->size == 4)
214 return GL_FALSE;
215 }
216
217 return GL_TRUE;
218 }
219
220 static void TAG(interp)( GLcontext *ctx,
221 GLfloat t,
222 GLuint edst, GLuint eout, GLuint ein,
223 GLboolean force_boundary )
224 {
225 fxMesaContext fxMesa = FX_CONTEXT( ctx );
226 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
227 const GLfloat *dstclip = VB->ClipPtr->data[edst];
228 const GLfloat oow = (dstclip[3] == 0.0F) ? 1.0F : (1.0F / dstclip[3]);
229 const GLfloat *const s = ctx->Viewport._WindowMap.m;
230 GrVertex *fxverts = fxMesa->verts;
231 GrVertex *dst = (GrVertex *) (fxverts + edst);
232 const GrVertex *out = (const GrVertex *) (fxverts + eout);
233 const GrVertex *in = (const GrVertex *) (fxverts + ein);
234 const GLfloat wout = oow / out->oow;
235 const GLfloat win = oow / in->oow;
236
237 VIEWPORT_X(dst->x, dstclip[0] * oow);
238 VIEWPORT_Y(dst->y, dstclip[1] * oow);
239 VIEWPORT_Z(dst->ooz, dstclip[2] * oow);
240 dst->oow = oow;
241
242 if (IND & SETUP_SNAP) {
243 #if defined(USE_IEEE)
244 const float snapper = (3L << 18);
245 dst->x += snapper;
246 dst->x -= snapper;
247 dst->y += snapper;
248 dst->y -= snapper;
249 #else
250 dst->x = ((int) (dst->x * 16.0f)) * (1.0f / 16.0f);
251 dst->y = ((int) (dst->y * 16.0f)) * (1.0f / 16.0f);
252 #endif
253 }
254
255
256 INTERP_UB( t, dst->pargb[0], out->pargb[0], in->pargb[0] );
257 INTERP_UB( t, dst->pargb[1], out->pargb[1], in->pargb[1] );
258 INTERP_UB( t, dst->pargb[2], out->pargb[2], in->pargb[2] );
259 INTERP_UB( t, dst->pargb[3], out->pargb[3], in->pargb[3] );
260
261 if (IND & SETUP_SPEC) {
262 INTERP_UB( t, dst->pspec[0], out->pspec[0], in->pspec[0] );
263 INTERP_UB( t, dst->pspec[1], out->pspec[1], in->pspec[1] );
264 INTERP_UB( t, dst->pspec[2], out->pspec[2], in->pspec[2] );
265 }
266
267 if (IND & SETUP_FOGC) {
268 INTERP_F( t, dst->fog, out->fog, in->fog );
269 }
270
271 if (IND & SETUP_TMU0) {
272 INTERP_F( t,
273 dst->tmuvtx[0].sow,
274 out->tmuvtx[0].sow * wout,
275 in->tmuvtx[0].sow * win );
276 INTERP_F( t,
277 dst->tmuvtx[0].tow,
278 out->tmuvtx[0].tow * wout,
279 in->tmuvtx[0].tow * win );
280 if (IND & SETUP_PTEX) {
281 INTERP_F( t,
282 dst->tmuvtx[0].oow,
283 out->tmuvtx[0].oow * wout,
284 in->tmuvtx[0].oow * win );
285 }
286 }
287
288 if (IND & SETUP_TMU1) {
289 INTERP_F( t,
290 dst->tmuvtx[1].sow,
291 out->tmuvtx[1].sow * wout,
292 in->tmuvtx[1].sow * win );
293 INTERP_F( t,
294 dst->tmuvtx[1].tow,
295 out->tmuvtx[1].tow * wout,
296 in->tmuvtx[1].tow * win );
297 if (IND & SETUP_PTEX) {
298 INTERP_F( t,
299 dst->tmuvtx[1].oow,
300 out->tmuvtx[1].oow * wout,
301 in->tmuvtx[1].oow * win );
302 }
303 }
304 }
305 #endif
306
307
308 static void TAG(init)( void )
309 {
310 setup_tab[IND].emit = TAG(emit);
311
312 if (IND & SETUP_SPEC) {
313 setup_tab[IND].copy_pv = copy_pv2;
314 } else {
315 setup_tab[IND].copy_pv = copy_pv;
316 }
317
318 #if ((IND & SETUP_XYZW) && (IND & SETUP_RGBA))
319 setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes);
320 setup_tab[IND].interp = TAG(interp);
321
322 setup_tab[IND].vertex_format = 0;
323 if (IND & SETUP_PTEX) {
324 setup_tab[IND].vertex_format |= GR_STWHINT_W_DIFF_TMU0;
325 }
326
327 #if (IND & SETUP_TMU1)
328 setup_tab[IND].vertex_format |= GR_STWHINT_ST_DIFF_TMU1;
329 if (IND & SETUP_PTEX) {
330 setup_tab[IND].vertex_format |= GR_STWHINT_W_DIFF_TMU1;
331 }
332 #endif
333
334 #endif
335 }
336
337
338 #undef IND
339 #undef TAG