some changes for SOLO build
[mesa.git] / src / mesa / drivers / dri / ffb / ffb_vtxfmt.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_vtxfmt.c,v 1.1 2002/02/22 21:32:59 dawes Exp $
2 *
3 * GLX Hardware Device Driver for Sun Creator/Creator3D
4 * Copyright (C) 2001 David S. Miller
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * DAVID MILLER, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 *
25 * David S. Miller <davem@redhat.com>
26 */
27
28 #include "glheader.h"
29 #include "api_noop.h"
30 #include "context.h"
31 #include "light.h"
32 #include "macros.h"
33 #include "imports.h"
34 #include "mtypes.h"
35 #include "simple_list.h"
36 #include "vtxfmt.h"
37 #include "ffb_xmesa.h"
38 #include "ffb_context.h"
39 #include "ffb_vb.h"
40 #include "tnl/tnl.h"
41 #include "tnl/t_context.h"
42
43 #include "ffb_vtxfmt.h"
44
45 #ifndef __GNUC__
46 #define __inline /**/
47 #endif
48
49 #define TNL_VERTEX ffbTnlVertex
50
51 #define INTERP_RGBA(t, out, a, b) \
52 do { \
53 GLint i; \
54 for ( i = 0 ; i < 4 ; i++ ) { \
55 GLfloat fa = a[i]; \
56 GLfloat fb = b[i]; \
57 out[i] = LINTERP( t, fa, fb ); \
58 } \
59 } while (0)
60
61 /* Color functions: */
62
63 static __inline void ffb_recalc_base_color(GLcontext *ctx)
64 {
65 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
66 struct gl_light *light;
67
68 COPY_3V(fmesa->vtx_state.light.base_color, ctx->Light._BaseColor[0]);
69 foreach (light, &ctx->Light.EnabledList) {
70 ACC_3V(fmesa->vtx_state.light.base_color,
71 light->_MatAmbient[0]);
72 }
73
74 fmesa->vtx_state.light.base_alpha = ctx->Light._BaseAlpha[0];
75 }
76
77 #define GET_CURRENT \
78 GET_CURRENT_CONTEXT(ctx); \
79 ffbContextPtr fmesa = FFB_CONTEXT(ctx)
80
81 #define CURRENT_COLOR(COMP) fmesa->vtx_state.current.color[COMP]
82 #define CURRENT_SPECULAR(COMP) fmesa->vtx_state.current.specular[COMP]
83 #define COLOR_IS_FLOAT
84 #define RECALC_BASE_COLOR(ctx) ffb_recalc_base_color(ctx)
85
86 #define TAG(x) ffb_##x
87 #include "tnl_dd/t_dd_imm_capi.h"
88
89 /* Normal functions: */
90
91 struct ffb_norm_tab {
92 void (*normal3f_multi)(GLfloat x, GLfloat y, GLfloat z);
93 void (*normal3fv_multi)(const GLfloat *v);
94 void (*normal3f_single)(GLfloat x, GLfloat y, GLfloat z);
95 void (*normal3fv_single)(const GLfloat *v);
96 };
97
98 static struct ffb_norm_tab norm_tab[0x4];
99
100 #define HAVE_HW_LIGHTING 0
101 #define GET_CURRENT_VERTEX \
102 GET_CURRENT_CONTEXT(ctx); \
103 ffbContextPtr fmesa = FFB_CONTEXT(ctx); \
104 ffbTnlVertexPtr v = fmesa->imm.v0
105
106 #define CURRENT_NORMAL fmesa->vtx_state.current.normal
107 #define BASE_COLOR fmesa->vtx_state.light.base_color
108 #define BASE_ALPHA fmesa->vtx_state.light.base_alpha
109 #define VERT_COLOR( COMP ) v->color[COMP]
110 #define VERT_COLOR_IS_FLOAT
111
112 #define IND (0)
113 #define TAG(x) ffb_##x
114 #define PRESERVE_NORMAL_DEFS
115 #include "tnl_dd/t_dd_imm_napi.h"
116
117 #define IND (NORM_RESCALE)
118 #define TAG(x) ffb_##x##_rescale
119 #define PRESERVE_NORMAL_DEFS
120 #include "tnl_dd/t_dd_imm_napi.h"
121
122 #define IND (NORM_NORMALIZE)
123 #define TAG(x) ffb_##x##_normalize
124 #include "tnl_dd/t_dd_imm_napi.h"
125
126 static void ffb_init_norm_funcs(void)
127 {
128 ffb_init_norm();
129 ffb_init_norm_rescale();
130 ffb_init_norm_normalize();
131 }
132
133 static void choose_normals(void)
134 {
135 GET_CURRENT_CONTEXT(ctx);
136 GLuint index;
137
138 if (ctx->Light.Enabled) {
139 if (ctx->Transform.Normalize) {
140 index = NORM_NORMALIZE;
141 } else if (!ctx->Transform.RescaleNormals &&
142 ctx->_ModelViewInvScale != 1.0) {
143 index = NORM_RESCALE;
144 } else {
145 index = 0;
146 }
147
148 if (ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev) {
149 ctx->Exec->Normal3f = norm_tab[index].normal3f_single;
150 ctx->Exec->Normal3fv = norm_tab[index].normal3fv_single;
151 } else {
152 ctx->Exec->Normal3f = norm_tab[index].normal3f_multi;
153 ctx->Exec->Normal3fv = norm_tab[index].normal3fv_multi;
154 }
155 } else {
156 ctx->Exec->Normal3f = _mesa_noop_Normal3f;
157 ctx->Exec->Normal3fv = _mesa_noop_Normal3fv;
158 }
159 }
160
161 static void ffb_choose_Normal3f(GLfloat x, GLfloat y, GLfloat z)
162 {
163 choose_normals();
164 glNormal3f(x, y, z);
165 }
166
167 static void ffb_choose_Normal3fv(const GLfloat *v)
168 {
169 choose_normals();
170 glNormal3fv(v);
171 }
172
173 /* Vertex functions: */
174
175 #define GET_CURRENT_VERTEX \
176 GET_CURRENT_CONTEXT(ctx); \
177 ffbContextPtr fmesa = FFB_CONTEXT(ctx); \
178 ffbTnlVertexPtr v = fmesa->imm.v0
179
180 #define CURRENT_VERTEX v->obj
181 #define SAVE_VERTEX fmesa->imm.save_vertex(ctx, v)
182
183 #define TAG(x) ffb_##x
184 #include "tnl_dd/t_dd_imm_vapi.h"
185
186 struct ffb_vert_tab {
187 void (*save_vertex)(GLcontext *ctx, ffbTnlVertexPtr v);
188 void (*interpolate_vertex)(GLfloat t,
189 ffbTnlVertex *O,
190 const ffbTnlVertex *I,
191 const ffbTnlVertex *J);
192 };
193
194 static struct ffb_vert_tab vert_tab[0xf];
195
196 #define VTX_NORMAL 0x0
197 #define VTX_RGBA 0x1
198
199 #define LOCAL_VARS \
200 ffbContextPtr fmesa = FFB_CONTEXT(ctx)
201
202 #define CURRENT_COLOR fmesa->vtx_state.current.color
203 #define COLOR_IS_FLOAT
204 #define FLUSH_VERTEX fmesa->imm.flush_vertex( ctx, v );
205
206 #define IND (VTX_NORMAL)
207 #define TAG(x) ffb_##x##_NORMAL
208 #define PRESERVE_VERTEX_DEFS
209 #include "tnl_dd/t_dd_imm_vertex.h"
210
211 #define IND (VTX_RGBA)
212 #define TAG(x) ffb_##x##_RGBA
213 #include "tnl_dd/t_dd_imm_vertex.h"
214
215 static void ffb_init_vert_funcs( void )
216 {
217 ffb_init_vert_NORMAL();
218 ffb_init_vert_RGBA();
219 }
220
221 #define LOCAL_VARS \
222 ffbContextPtr fmesa = FFB_CONTEXT(ctx)
223
224 #define GET_INTERP_FUNC \
225 ffb_interp_func interp = fmesa->imm.interp
226
227 #define FLUSH_VERTEX fmesa->imm.flush_vertex
228 #define IMM_VERTEX( V ) fmesa->imm.V
229 #define IMM_VERTICES( n ) fmesa->imm.vertices[n]
230
231 #define EMIT_VERTEX_USES_HWREGS
232
233 /* XXX Implement me XXX */
234 #define EMIT_VERTEX_TRI(VTX0, VTX1, VTX2) \
235 do { } while (0)
236 #define EMIT_VERTEX_LINE(VTX0, VTX1) \
237 do { } while (0)
238 #define EMIT_VERTEX_POINT(VTX0) \
239 do { } while (0)
240
241 #define TAG(x) ffb_##x
242 #include "tnl_dd/t_dd_imm_primtmp.h"
243
244 /* Bzzt: Material changes are lost on fallback. */
245 static void ffb_Materialfv(GLenum face, GLenum pname,
246 const GLfloat *params)
247 {
248 GET_CURRENT_CONTEXT(ctx);
249
250 _mesa_noop_Materialfv( face, pname, params );
251 ffb_recalc_base_color( ctx );
252 }
253
254 /* Fallback functions: */
255
256 static void ffb_do_fallback(GLcontext *ctx)
257 {
258 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
259 struct ffb_current_state *current = &fmesa->vtx_state.current;
260
261 /* Tell tnl to restore its exec vtxfmt, rehook its driver callbacks
262 * and revive internal state that depended on those callbacks:
263 */
264 _tnl_wakeup_exec(ctx);
265
266 /* Replay enough vertices that the current primitive is continued
267 * correctly:
268 */
269 if (fmesa->imm.prim != PRIM_OUTSIDE_BEGIN_END )
270 glBegin(fmesa->imm.prim);
271
272 if (ctx->Light.Enabled) {
273 glColor4fv(ctx->Current.Color); /* Catch ColorMaterial */
274 glNormal3fv(current->normal);
275 } else {
276 glColor4fv(current->color);
277 }
278 }
279
280 #define PRE_LOOPBACK( FUNC ) do { \
281 GET_CURRENT_CONTEXT(ctx); \
282 ffb_do_fallback( ctx ); \
283 } while (0)
284
285 #define TAG(x) ffb_fallback_##x
286 #include "vtxfmt_tmp.h"
287
288 static void ffb_Begin(GLenum prim)
289 {
290 GET_CURRENT_CONTEXT(ctx);
291 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
292
293 if (prim > GL_POLYGON) {
294 _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" );
295 return;
296 }
297
298 if (fmesa->imm.prim != PRIM_OUTSIDE_BEGIN_END) {
299 _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
300 return;
301 }
302
303 ctx->Driver.NeedFlush |= (FLUSH_STORED_VERTICES |
304 FLUSH_UPDATE_CURRENT);
305
306 fmesa->imm.prim = prim;
307 fmesa->imm.v0 = &fmesa->imm.vertices[0];
308 fmesa->imm.save_vertex = ffb_save_vertex_RGBA;
309 fmesa->imm.flush_vertex = ffb_flush_tab[prim];
310
311 /* XXX Lock hardware, update FBC, PPC, DRAWOP, etc. XXX */
312 }
313
314 static void ffb_End(void)
315 {
316 GET_CURRENT_CONTEXT(ctx);
317 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
318
319 if (fmesa->imm.prim == PRIM_OUTSIDE_BEGIN_END) {
320 _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
321 return;
322 }
323
324 fmesa->imm.prim = PRIM_OUTSIDE_BEGIN_END;
325
326 ctx->Driver.NeedFlush &= ~(FLUSH_STORED_VERTICES |
327 FLUSH_UPDATE_CURRENT);
328
329 /* XXX Unlock hardware, etc. */
330 }
331
332 void ffbInitTnlModule(GLcontext *ctx)
333 {
334 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
335 GLvertexformat *vfmt = &(fmesa->imm.vtxfmt);
336
337 /* Work in progress... */
338 return;
339
340 ffb_init_norm_funcs();
341 ffb_init_vert_funcs();
342
343 MEMSET(vfmt, 0, sizeof(GLvertexformat));
344
345 /* Handled fully in supported states: */
346 vfmt->ArrayElement = NULL; /* FIXME: ... */
347 vfmt->Color3f = ffb_choose_Color3f;
348 vfmt->Color3fv = ffb_choose_Color3fv;
349 vfmt->Color3ub = ffb_choose_Color3ub;
350 vfmt->Color3ubv = ffb_choose_Color3ubv;
351 vfmt->Color4f = ffb_choose_Color4f;
352 vfmt->Color4fv = ffb_choose_Color4fv;
353 vfmt->Color4ub = ffb_choose_Color4ub;
354 vfmt->Color4ubv = ffb_choose_Color4ubv;
355 vfmt->FogCoordfvEXT = ffb_FogCoordfvEXT;
356 vfmt->FogCoordfEXT = ffb_FogCoordfEXT;
357 vfmt->Materialfv = ffb_Materialfv;
358 vfmt->MultiTexCoord1fARB = ffb_fallback_MultiTexCoord1fARB;
359 vfmt->MultiTexCoord1fvARB = ffb_fallback_MultiTexCoord1fvARB;
360 vfmt->MultiTexCoord2fARB = ffb_fallback_MultiTexCoord2fARB;
361 vfmt->MultiTexCoord2fvARB = ffb_fallback_MultiTexCoord2fvARB;
362 vfmt->MultiTexCoord3fARB = ffb_fallback_MultiTexCoord3fARB;
363 vfmt->MultiTexCoord3fvARB = ffb_fallback_MultiTexCoord3fvARB;
364 vfmt->MultiTexCoord4fARB = ffb_fallback_MultiTexCoord4fARB;
365 vfmt->MultiTexCoord4fvARB = ffb_fallback_MultiTexCoord4fvARB;
366 vfmt->Normal3f = ffb_choose_Normal3f;
367 vfmt->Normal3fv = ffb_choose_Normal3fv;
368 vfmt->SecondaryColor3ubEXT = ffb_SecondaryColor3ubEXT;
369 vfmt->SecondaryColor3ubvEXT = ffb_SecondaryColor3ubvEXT;
370 vfmt->SecondaryColor3fEXT = ffb_SecondaryColor3fEXT;
371 vfmt->SecondaryColor3fvEXT = ffb_SecondaryColor3fvEXT;
372 vfmt->TexCoord1f = ffb_fallback_TexCoord1f;
373 vfmt->TexCoord1fv = ffb_fallback_TexCoord1fv;
374 vfmt->TexCoord2f = ffb_fallback_TexCoord2f;
375 vfmt->TexCoord2fv = ffb_fallback_TexCoord2fv;
376 vfmt->TexCoord3f = ffb_fallback_TexCoord3f;
377 vfmt->TexCoord3fv = ffb_fallback_TexCoord3fv;
378 vfmt->TexCoord4f = ffb_fallback_TexCoord4f;
379 vfmt->TexCoord4fv = ffb_fallback_TexCoord4fv;
380
381 vfmt->Vertex2f = ffb_Vertex2f;
382 vfmt->Vertex2fv = ffb_Vertex2fv;
383 vfmt->Vertex3f = ffb_Vertex3f;
384 vfmt->Vertex3fv = ffb_Vertex3fv;
385 vfmt->Vertex4f = ffb_Vertex4f;
386 vfmt->Vertex4fv = ffb_Vertex4fv;
387
388 vfmt->Begin = ffb_Begin;
389 vfmt->End = ffb_End;
390
391 vfmt->Rectf = _mesa_noop_Rectf; /* generic helper */
392
393 vfmt->DrawArrays = NULL;
394 vfmt->DrawElements = NULL;
395 vfmt->DrawRangeElements = _mesa_noop_DrawRangeElements; /* discard range */
396
397
398 /* Not active in supported states; just keep ctx->Current uptodate: */
399 vfmt->EdgeFlag = _mesa_noop_EdgeFlag;
400 vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv;
401 vfmt->Indexi = _mesa_noop_Indexi;
402 vfmt->Indexiv = _mesa_noop_Indexiv;
403
404 /* Active but unsupported -- fallback if we receive these:
405 *
406 * All of these fallbacks can be fixed with additional code, except
407 * CallList, unless we build a play_immediate_noop() command which
408 * turns an immediate back into glBegin/glEnd commands...
409 */
410 vfmt->CallList = ffb_fallback_CallList;
411 vfmt->EvalCoord1f = ffb_fallback_EvalCoord1f;
412 vfmt->EvalCoord1fv = ffb_fallback_EvalCoord1fv;
413 vfmt->EvalCoord2f = ffb_fallback_EvalCoord2f;
414 vfmt->EvalCoord2fv = ffb_fallback_EvalCoord2fv;
415 vfmt->EvalMesh1 = ffb_fallback_EvalMesh1;
416 vfmt->EvalMesh2 = ffb_fallback_EvalMesh2;
417 vfmt->EvalPoint1 = ffb_fallback_EvalPoint1;
418 vfmt->EvalPoint2 = ffb_fallback_EvalPoint2;
419
420 vfmt->prefer_float_colors = GL_TRUE;
421
422 fmesa->imm.prim = PRIM_OUTSIDE_BEGIN_END;
423
424 /* THIS IS A HACK! */
425 _mesa_install_exec_vtxfmt( ctx, vfmt );
426 }