Merge branch 'mesa_7_7_branch'
[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->AttribPtr[_TNL_ATTRIB_TEX0 + tmu0_source]->data;
66 tc0_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu0_source]->stride;
67 u0scale = fxMesa->s0scale;
68 v0scale = fxMesa->t0scale;
69 if (IND & SETUP_PTEX)
70 tc0_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu0_source]->size;
71 }
72
73 if (IND & SETUP_TMU1) {
74 tc1 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu1_source]->data;
75 tc1_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + 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->AttribPtr[_TNL_ATTRIB_TEX0 + tmu1_source]->size;
80 }
81
82 if (IND & SETUP_RGBA) {
83 col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
84 col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
85 col_size = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size;
86 }
87
88 if (IND & SETUP_SPEC) {
89 spec = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->data;
90 spec_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->stride;
91 }
92
93 if (IND & SETUP_FOGC) {
94 fog = VB->AttribPtr[_TNL_ATTRIB_FOG]->data;
95 fog_stride = VB->AttribPtr[_TNL_ATTRIB_FOG]->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
128 if (IND & SETUP_SNAP) {
129 #if defined(USE_IEEE)
130 const float snapper = (3L << 18);
131 v->x += snapper;
132 v->x -= snapper;
133 v->y += snapper;
134 v->y -= snapper;
135 #else
136 v->x = ((int) (v->x * 16.0f)) * (1.0f / 16.0f);
137 v->y = ((int) (v->y * 16.0f)) * (1.0f / 16.0f);
138 #endif
139 }
140 } else {
141 /* clipped */
142 v->oow = 1.0;
143 }
144
145 proj = (GLfloat (*)[4])((GLubyte *)proj + proj_stride);
146 }
147 if (IND & SETUP_RGBA) {
148 #if FX_PACKEDCOLOR
149 UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[2], col[0][0]);
150 UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[1], col[0][1]);
151 UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[0], col[0][2]);
152 if (col_size == 4) {
153 UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[3], col[0][3]);
154 } else {
155 v->pargb[3] = 255;
156 }
157 #else /* !FX_PACKEDCOLOR */
158 CNORM(v->r, col[0][0]);
159 CNORM(v->g, col[0][1]);
160 CNORM(v->b, col[0][2]);
161 if (col_size == 4) {
162 CNORM(v->a, col[0][3]);
163 } else {
164 v->a = 255.0f;
165 }
166 #endif /* !FX_PACKEDCOLOR */
167 STRIDE_4F(col, col_stride);
168 }
169 if (IND & SETUP_SPEC) {
170 #if FX_PACKEDCOLOR
171 UNCLAMPED_FLOAT_TO_UBYTE(v->pspec[2], spec[0][0]);
172 UNCLAMPED_FLOAT_TO_UBYTE(v->pspec[1], spec[0][1]);
173 UNCLAMPED_FLOAT_TO_UBYTE(v->pspec[0], spec[0][2]);
174 #else /* !FX_PACKEDCOLOR */
175 CNORM(v->r1, spec[0][0]);
176 CNORM(v->g1, spec[0][1]);
177 CNORM(v->b1, spec[0][2]);
178 #endif /* !FX_PACKEDCOLOR */
179 STRIDE_4F(spec, spec_stride);
180 }
181 if (IND & SETUP_FOGC) {
182 v->fog = CLAMP(fog[0][0], 0.0f, 1.0f);
183 fog = (GLfloat (*)[4])((GLubyte *)fog + fog_stride);
184 }
185 if (IND & SETUP_TMU0) {
186 GLfloat w = v->oow;
187 v->tmuvtx[0].sow = tc0[0][0] * u0scale * w;
188 v->tmuvtx[0].tow = tc0[0][1] * v0scale * w;
189 if (IND & SETUP_PTEX) {
190 v->tmuvtx[0].oow = w;
191 if (tc0_size == 4)
192 v->tmuvtx[0].oow *= tc0[0][3];
193 }
194 tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride);
195 }
196 if (IND & SETUP_TMU1) {
197 GLfloat w = v->oow;
198 v->tmuvtx[1].sow = tc1[0][0] * u1scale * w;
199 v->tmuvtx[1].tow = tc1[0][1] * v1scale * w;
200 if (IND & SETUP_PTEX) {
201 v->tmuvtx[1].oow = w;
202 if (tc1_size == 4)
203 v->tmuvtx[1].oow *= tc1[0][3];
204 }
205 tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + tc1_stride);
206 }
207 }
208 }
209
210 #if (IND & SETUP_XYZW) && (IND & SETUP_RGBA)
211
212 static GLboolean TAG(check_tex_sizes)( GLcontext *ctx )
213 {
214 /* fprintf(stderr, "%s\n", __FUNCTION__); */
215
216 if (IND & SETUP_PTEX)
217 return GL_TRUE;
218
219 if (IND & SETUP_TMU0) {
220 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
221
222 if (IND & SETUP_TMU1) {
223 if (VB->AttribPtr[_TNL_ATTRIB_TEX0] == 0)
224 VB->AttribPtr[_TNL_ATTRIB_TEX0] = VB->AttribPtr[_TNL_ATTRIB_TEX1];
225
226 if (VB->AttribPtr[_TNL_ATTRIB_TEX1]->size == 4)
227 return GL_FALSE;
228 }
229
230 if (VB->AttribPtr[_TNL_ATTRIB_TEX0] &&
231 VB->AttribPtr[_TNL_ATTRIB_TEX0]->size == 4)
232 return GL_FALSE;
233 }
234
235 return GL_TRUE;
236 }
237
238 static void TAG(interp)( GLcontext *ctx,
239 GLfloat t,
240 GLuint edst, GLuint eout, GLuint ein,
241 GLboolean force_boundary )
242 {
243 fxMesaContext fxMesa = FX_CONTEXT( ctx );
244 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
245 const GLfloat *dstclip = VB->ClipPtr->data[edst];
246 const GLfloat oow = (dstclip[3] == 0.0F) ? 1.0F : (1.0F / dstclip[3]);
247 const GLfloat *const s = ctx->Viewport._WindowMap.m;
248 GrVertex *fxverts = fxMesa->verts;
249 GrVertex *dst = (GrVertex *) (fxverts + edst);
250 const GrVertex *out = (const GrVertex *) (fxverts + eout);
251 const GrVertex *in = (const GrVertex *) (fxverts + ein);
252 const GLfloat wout = oow / out->oow;
253 const GLfloat win = oow / in->oow;
254
255 VIEWPORT_X(dst->x, dstclip[0] * oow);
256 VIEWPORT_Y(dst->y, dstclip[1] * oow);
257 VIEWPORT_Z(dst->ooz, dstclip[2] * oow);
258 dst->oow = oow;
259
260 if (IND & SETUP_SNAP) {
261 #if defined(USE_IEEE)
262 const float snapper = (3L << 18);
263 dst->x += snapper;
264 dst->x -= snapper;
265 dst->y += snapper;
266 dst->y -= snapper;
267 #else
268 dst->x = ((int) (dst->x * 16.0f)) * (1.0f / 16.0f);
269 dst->y = ((int) (dst->y * 16.0f)) * (1.0f / 16.0f);
270 #endif
271 }
272
273
274 #if FX_PACKEDCOLOR
275 INTERP_UB( t, dst->pargb[0], out->pargb[0], in->pargb[0] );
276 INTERP_UB( t, dst->pargb[1], out->pargb[1], in->pargb[1] );
277 INTERP_UB( t, dst->pargb[2], out->pargb[2], in->pargb[2] );
278 INTERP_UB( t, dst->pargb[3], out->pargb[3], in->pargb[3] );
279 #else /* !FX_PACKEDCOLOR */
280 INTERP_F( t, dst->r, out->r, in->r );
281 INTERP_F( t, dst->g, out->g, in->g );
282 INTERP_F( t, dst->b, out->b, in->b );
283 INTERP_F( t, dst->a, out->a, in->a );
284 #endif /* !FX_PACKEDCOLOR */
285
286 if (IND & SETUP_SPEC) {
287 #if FX_PACKEDCOLOR
288 INTERP_UB( t, dst->pspec[0], out->pspec[0], in->pspec[0] );
289 INTERP_UB( t, dst->pspec[1], out->pspec[1], in->pspec[1] );
290 INTERP_UB( t, dst->pspec[2], out->pspec[2], in->pspec[2] );
291 #else /* !FX_PACKEDCOLOR */
292 INTERP_F( t, dst->r1, out->r1, in->r1 );
293 INTERP_F( t, dst->g1, out->g1, in->g1 );
294 INTERP_F( t, dst->b1, out->b1, in->b1 );
295 #endif /* !FX_PACKEDCOLOR */
296 }
297
298 if (IND & SETUP_FOGC) {
299 INTERP_F( t, dst->fog, out->fog, in->fog );
300 }
301
302 if (IND & SETUP_TMU0) {
303 INTERP_F( t,
304 dst->tmuvtx[0].sow,
305 out->tmuvtx[0].sow * wout,
306 in->tmuvtx[0].sow * win );
307 INTERP_F( t,
308 dst->tmuvtx[0].tow,
309 out->tmuvtx[0].tow * wout,
310 in->tmuvtx[0].tow * win );
311 if (IND & SETUP_PTEX) {
312 INTERP_F( t,
313 dst->tmuvtx[0].oow,
314 out->tmuvtx[0].oow * wout,
315 in->tmuvtx[0].oow * win );
316 }
317 }
318
319 if (IND & SETUP_TMU1) {
320 INTERP_F( t,
321 dst->tmuvtx[1].sow,
322 out->tmuvtx[1].sow * wout,
323 in->tmuvtx[1].sow * win );
324 INTERP_F( t,
325 dst->tmuvtx[1].tow,
326 out->tmuvtx[1].tow * wout,
327 in->tmuvtx[1].tow * win );
328 if (IND & SETUP_PTEX) {
329 INTERP_F( t,
330 dst->tmuvtx[1].oow,
331 out->tmuvtx[1].oow * wout,
332 in->tmuvtx[1].oow * win );
333 }
334 }
335 }
336 #endif
337
338
339 static void TAG(init)( void )
340 {
341 setup_tab[IND].emit = TAG(emit);
342
343 if (IND & SETUP_SPEC) {
344 setup_tab[IND].copy_pv = copy_pv2;
345 } else {
346 setup_tab[IND].copy_pv = copy_pv;
347 }
348
349 #if ((IND & SETUP_XYZW) && (IND & SETUP_RGBA))
350 setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes);
351 setup_tab[IND].interp = TAG(interp);
352
353 setup_tab[IND].vertex_format = 0;
354 if (IND & SETUP_PTEX) {
355 setup_tab[IND].vertex_format |= GR_STWHINT_W_DIFF_TMU0;
356 }
357
358 #if (IND & SETUP_TMU1)
359 setup_tab[IND].vertex_format |= GR_STWHINT_ST_DIFF_TMU1;
360 if (IND & SETUP_PTEX) {
361 setup_tab[IND].vertex_format |= GR_STWHINT_W_DIFF_TMU1;
362 }
363 #endif
364
365 #endif
366 }
367
368
369 #undef IND
370 #undef TAG