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