1 /* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_vtxfmt.c,v 1.1 2002/02/22 21:32:59 dawes Exp $
3 * GLX Hardware Device Driver for Sun Creator/Creator3D
4 * Copyright (C) 2001 David S. Miller
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
25 * David S. Miller <davem@redhat.com>
35 #include "simple_list.h"
37 #include "ffb_xmesa.h"
38 #include "ffb_context.h"
41 #include "tnl/t_context.h"
43 #include "ffb_vtxfmt.h"
49 #define TNL_VERTEX ffbTnlVertex
51 #define INTERP_RGBA(t, out, a, b) \
54 for ( i = 0 ; i < 4 ; i++ ) { \
57 out[i] = LINTERP( t, fa, fb ); \
61 /* Color functions: */
63 static __inline
void ffb_recalc_base_color(GLcontext
*ctx
)
65 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
66 struct gl_light
*light
;
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]);
74 fmesa
->vtx_state
.light
.base_alpha
= ctx
->Light
._BaseAlpha
[0];
78 GET_CURRENT_CONTEXT(ctx); \
79 ffbContextPtr fmesa = FFB_CONTEXT(ctx)
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)
86 #define TAG(x) ffb_##x
87 #include "tnl_dd/t_dd_imm_capi.h"
89 /* Normal functions: */
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
);
98 static struct ffb_norm_tab norm_tab
[0x4];
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
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
113 #define TAG(x) ffb_##x
114 #define PRESERVE_NORMAL_DEFS
115 #include "tnl_dd/t_dd_imm_napi.h"
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"
122 #define IND (NORM_NORMALIZE)
123 #define TAG(x) ffb_##x##_normalize
124 #include "tnl_dd/t_dd_imm_napi.h"
126 static void ffb_init_norm_funcs(void)
129 ffb_init_norm_rescale();
130 ffb_init_norm_normalize();
133 static void choose_normals(void)
135 GET_CURRENT_CONTEXT(ctx
);
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
;
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
;
152 ctx
->Exec
->Normal3f
= norm_tab
[index
].normal3f_multi
;
153 ctx
->Exec
->Normal3fv
= norm_tab
[index
].normal3fv_multi
;
156 ctx
->Exec
->Normal3f
= _mesa_noop_Normal3f
;
157 ctx
->Exec
->Normal3fv
= _mesa_noop_Normal3fv
;
161 static void ffb_choose_Normal3f(GLfloat x
, GLfloat y
, GLfloat z
)
164 GL_CALL(Normal3f
)(x
, y
, z
);
167 static void ffb_choose_Normal3fv(const GLfloat
*v
)
170 GL_CALL(Normal3fv
)(v
);
173 /* Vertex functions: */
175 #define GET_CURRENT_VERTEX \
176 GET_CURRENT_CONTEXT(ctx); \
177 ffbContextPtr fmesa = FFB_CONTEXT(ctx); \
178 ffbTnlVertexPtr v = fmesa->imm.v0
180 #define CURRENT_VERTEX v->obj
181 #define SAVE_VERTEX fmesa->imm.save_vertex(ctx, v)
183 #define TAG(x) ffb_##x
184 #include "tnl_dd/t_dd_imm_vapi.h"
186 struct ffb_vert_tab
{
187 void (*save_vertex
)(GLcontext
*ctx
, ffbTnlVertexPtr v
);
188 void (*interpolate_vertex
)(GLfloat t
,
190 const ffbTnlVertex
*I
,
191 const ffbTnlVertex
*J
);
194 static struct ffb_vert_tab vert_tab
[0xf];
196 #define VTX_NORMAL 0x0
200 ffbContextPtr fmesa = FFB_CONTEXT(ctx)
202 #define CURRENT_COLOR fmesa->vtx_state.current.color
203 #define COLOR_IS_FLOAT
204 #define FLUSH_VERTEX fmesa->imm.flush_vertex( ctx, v );
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"
211 #define IND (VTX_RGBA)
212 #define TAG(x) ffb_##x##_RGBA
213 #include "tnl_dd/t_dd_imm_vertex.h"
215 static void ffb_init_vert_funcs( void )
217 ffb_init_vert_NORMAL();
218 ffb_init_vert_RGBA();
222 ffbContextPtr fmesa = FFB_CONTEXT(ctx)
224 #define GET_INTERP_FUNC \
225 ffb_interp_func interp = fmesa->imm.interp
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]
231 #define EMIT_VERTEX_USES_HWREGS
233 /* XXX Implement me XXX */
234 #define EMIT_VERTEX_TRI(VTX0, VTX1, VTX2) \
236 #define EMIT_VERTEX_LINE(VTX0, VTX1) \
238 #define EMIT_VERTEX_POINT(VTX0) \
241 #define TAG(x) ffb_##x
242 #include "tnl_dd/t_dd_imm_primtmp.h"
244 /* Bzzt: Material changes are lost on fallback. */
245 static void ffb_Materialfv(GLenum face
, GLenum pname
,
246 const GLfloat
*params
)
248 GET_CURRENT_CONTEXT(ctx
);
250 _mesa_noop_Materialfv( face
, pname
, params
);
251 ffb_recalc_base_color( ctx
);
254 /* Fallback functions: */
256 static void ffb_do_fallback(GLcontext
*ctx
)
258 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
259 struct ffb_current_state
*current
= &fmesa
->vtx_state
.current
;
261 /* Tell tnl to restore its exec vtxfmt, rehook its driver callbacks
262 * and revive internal state that depended on those callbacks:
264 _tnl_wakeup_exec(ctx
);
266 /* Replay enough vertices that the current primitive is continued
269 if (fmesa
->imm
.prim
!= PRIM_OUTSIDE_BEGIN_END
)
270 GL_CALL(Begin
)(fmesa
->imm
.prim
);
272 if (ctx
->Light
.Enabled
) {
273 GL_CALL(Color4fv
)(ctx
->Current
.Color
); /* Catch ColorMaterial */
274 GL_CALL(Normal3fv
)(current
->normal
);
276 GL_CALL(Color4fv
)(current
->color
);
280 #define PRE_LOOPBACK( FUNC ) do { \
281 GET_CURRENT_CONTEXT(ctx); \
282 ffb_do_fallback( ctx ); \
285 #define TAG(x) ffb_fallback_##x
286 #include "vtxfmt_tmp.h"
288 static void ffb_Begin(GLenum prim
)
290 GET_CURRENT_CONTEXT(ctx
);
291 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
293 if (prim
> GL_POLYGON
) {
294 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBegin" );
298 if (fmesa
->imm
.prim
!= PRIM_OUTSIDE_BEGIN_END
) {
299 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glBegin" );
303 ctx
->Driver
.NeedFlush
|= (FLUSH_STORED_VERTICES
|
304 FLUSH_UPDATE_CURRENT
);
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
];
311 /* XXX Lock hardware, update FBC, PPC, DRAWOP, etc. XXX */
314 static void ffb_End(void)
316 GET_CURRENT_CONTEXT(ctx
);
317 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
319 if (fmesa
->imm
.prim
== PRIM_OUTSIDE_BEGIN_END
) {
320 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glEnd" );
324 fmesa
->imm
.prim
= PRIM_OUTSIDE_BEGIN_END
;
326 ctx
->Driver
.NeedFlush
&= ~(FLUSH_STORED_VERTICES
|
327 FLUSH_UPDATE_CURRENT
);
329 /* XXX Unlock hardware, etc. */
332 void ffbInitTnlModule(GLcontext
*ctx
)
334 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
335 GLvertexformat
*vfmt
= &(fmesa
->imm
.vtxfmt
);
337 /* Work in progress... */
340 ffb_init_norm_funcs();
341 ffb_init_vert_funcs();
343 MEMSET(vfmt
, 0, sizeof(GLvertexformat
));
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
;
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
;
388 vfmt
->Begin
= ffb_Begin
;
391 vfmt
->Rectf
= _mesa_noop_Rectf
; /* generic helper */
393 vfmt
->DrawArrays
= NULL
;
394 vfmt
->DrawElements
= NULL
;
395 vfmt
->DrawRangeElements
= _mesa_noop_DrawRangeElements
; /* discard range */
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
;
404 /* Active but unsupported -- fallback if we receive these:
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...
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
;
420 vfmt
->prefer_float_colors
= GL_TRUE
;
422 fmesa
->imm
.prim
= PRIM_OUTSIDE_BEGIN_END
;
424 /* THIS IS A HACK! */
425 _mesa_install_exec_vtxfmt( ctx
, vfmt
);