aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/ffb/ffb_vtxfmt.c
diff options
context:
space:
mode:
authorAlan Hourihane <[email protected]>2003-12-04 13:38:06 +0000
committerAlan Hourihane <[email protected]>2003-12-04 13:38:06 +0000
commit13e6a4849c6800eac454fd1010cb2320874f2ed6 (patch)
treec311173244771131a63ba18318be645b4534521c /src/mesa/drivers/dri/ffb/ffb_vtxfmt.c
parent15af25aca0ed6a2390fe9e0d91055cfc01134ce2 (diff)
add SPARC ffb DRI driver
Diffstat (limited to 'src/mesa/drivers/dri/ffb/ffb_vtxfmt.c')
-rw-r--r--src/mesa/drivers/dri/ffb/ffb_vtxfmt.c429
1 files changed, 429 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/ffb/ffb_vtxfmt.c b/src/mesa/drivers/dri/ffb/ffb_vtxfmt.c
new file mode 100644
index 00000000000..5f6d5c902dd
--- /dev/null
+++ b/src/mesa/drivers/dri/ffb/ffb_vtxfmt.c
@@ -0,0 +1,429 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_vtxfmt.c,v 1.1 2002/02/22 21:32:59 dawes Exp $
+ *
+ * GLX Hardware Device Driver for Sun Creator/Creator3D
+ * Copyright (C) 2001 David S. Miller
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID MILLER, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * David S. Miller <[email protected]>
+ */
+
+#include "glheader.h"
+#include "api_noop.h"
+#include "context.h"
+#include "light.h"
+#include "macros.h"
+#include "imports.h"
+#include "mmath.h"
+#include "mtypes.h"
+#include "simple_list.h"
+#include "vtxfmt.h"
+#include "ffb_xmesa.h"
+#include "ffb_context.h"
+#include "ffb_vb.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+
+#include "ffb_vtxfmt.h"
+
+#ifndef __GNUC__
+#define __inline /**/
+#endif
+
+#define TNL_VERTEX ffbTnlVertex
+
+#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A)))
+
+#define INTERP_RGBA(t, out, a, b) \
+do { \
+ GLint i; \
+ for ( i = 0 ; i < 4 ; i++ ) { \
+ GLfloat fa = a[i]; \
+ GLfloat fb = b[i]; \
+ out[i] = LINTERP( t, fa, fb ); \
+ } \
+} while (0)
+
+/* Color functions: */
+
+static __inline void ffb_recalc_base_color(GLcontext *ctx)
+{
+ ffbContextPtr fmesa = FFB_CONTEXT(ctx);
+ struct gl_light *light;
+
+ COPY_3V(fmesa->vtx_state.light.base_color, ctx->Light._BaseColor[0]);
+ foreach (light, &ctx->Light.EnabledList) {
+ ACC_3V(fmesa->vtx_state.light.base_color,
+ light->_MatAmbient[0]);
+ }
+
+ fmesa->vtx_state.light.base_alpha = ctx->Light._BaseAlpha[0];
+}
+
+#define GET_CURRENT \
+ GET_CURRENT_CONTEXT(ctx); \
+ ffbContextPtr fmesa = FFB_CONTEXT(ctx)
+
+#define CURRENT_COLOR(COMP) fmesa->vtx_state.current.color[COMP]
+#define CURRENT_SPECULAR(COMP) fmesa->vtx_state.current.specular[COMP]
+#define COLOR_IS_FLOAT
+#define RECALC_BASE_COLOR(ctx) ffb_recalc_base_color(ctx)
+
+#define TAG(x) ffb_##x
+#include "tnl_dd/t_dd_imm_capi.h"
+
+/* Normal functions: */
+
+struct ffb_norm_tab {
+ void (*normal3f_multi)(GLfloat x, GLfloat y, GLfloat z);
+ void (*normal3fv_multi)(const GLfloat *v);
+ void (*normal3f_single)(GLfloat x, GLfloat y, GLfloat z);
+ void (*normal3fv_single)(const GLfloat *v);
+};
+
+static struct ffb_norm_tab norm_tab[0x4];
+
+#define HAVE_HW_LIGHTING 0
+#define GET_CURRENT_VERTEX \
+ GET_CURRENT_CONTEXT(ctx); \
+ ffbContextPtr fmesa = FFB_CONTEXT(ctx); \
+ ffbTnlVertexPtr v = fmesa->imm.v0
+
+#define CURRENT_NORMAL fmesa->vtx_state.current.normal
+#define BASE_COLOR fmesa->vtx_state.light.base_color
+#define BASE_ALPHA fmesa->vtx_state.light.base_alpha
+#define VERT_COLOR( COMP ) v->color[COMP]
+#define VERT_COLOR_IS_FLOAT
+
+#define IND (0)
+#define TAG(x) ffb_##x
+#define PRESERVE_NORMAL_DEFS
+#include "tnl_dd/t_dd_imm_napi.h"
+
+#define IND (NORM_RESCALE)
+#define TAG(x) ffb_##x##_rescale
+#define PRESERVE_NORMAL_DEFS
+#include "tnl_dd/t_dd_imm_napi.h"
+
+#define IND (NORM_NORMALIZE)
+#define TAG(x) ffb_##x##_normalize
+#include "tnl_dd/t_dd_imm_napi.h"
+
+static void ffb_init_norm_funcs(void)
+{
+ ffb_init_norm();
+ ffb_init_norm_rescale();
+ ffb_init_norm_normalize();
+}
+
+static void choose_normals(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint index;
+
+ if (ctx->Light.Enabled) {
+ if (ctx->Transform.Normalize) {
+ index = NORM_NORMALIZE;
+ } else if (!ctx->Transform.RescaleNormals &&
+ ctx->_ModelViewInvScale != 1.0) {
+ index = NORM_RESCALE;
+ } else {
+ index = 0;
+ }
+
+ if (ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev) {
+ ctx->Exec->Normal3f = norm_tab[index].normal3f_single;
+ ctx->Exec->Normal3fv = norm_tab[index].normal3fv_single;
+ } else {
+ ctx->Exec->Normal3f = norm_tab[index].normal3f_multi;
+ ctx->Exec->Normal3fv = norm_tab[index].normal3fv_multi;
+ }
+ } else {
+ ctx->Exec->Normal3f = _mesa_noop_Normal3f;
+ ctx->Exec->Normal3fv = _mesa_noop_Normal3fv;
+ }
+}
+
+static void ffb_choose_Normal3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ choose_normals();
+ glNormal3f(x, y, z);
+}
+
+static void ffb_choose_Normal3fv(const GLfloat *v)
+{
+ choose_normals();
+ glNormal3fv(v);
+}
+
+/* Vertex functions: */
+
+#define GET_CURRENT_VERTEX \
+ GET_CURRENT_CONTEXT(ctx); \
+ ffbContextPtr fmesa = FFB_CONTEXT(ctx); \
+ ffbTnlVertexPtr v = fmesa->imm.v0
+
+#define CURRENT_VERTEX v->obj
+#define SAVE_VERTEX fmesa->imm.save_vertex(ctx, v)
+
+#define TAG(x) ffb_##x
+#include "tnl_dd/t_dd_imm_vapi.h"
+
+struct ffb_vert_tab {
+ void (*save_vertex)(GLcontext *ctx, ffbTnlVertexPtr v);
+ void (*interpolate_vertex)(GLfloat t,
+ ffbTnlVertex *O,
+ const ffbTnlVertex *I,
+ const ffbTnlVertex *J);
+};
+
+static struct ffb_vert_tab vert_tab[0xf];
+
+#define VTX_NORMAL 0x0
+#define VTX_RGBA 0x1
+
+#define LOCAL_VARS \
+ ffbContextPtr fmesa = FFB_CONTEXT(ctx)
+
+#define CURRENT_COLOR fmesa->vtx_state.current.color
+#define COLOR_IS_FLOAT
+#define FLUSH_VERTEX fmesa->imm.flush_vertex( ctx, v );
+
+#define IND (VTX_NORMAL)
+#define TAG(x) ffb_##x##_NORMAL
+#define PRESERVE_VERTEX_DEFS
+#include "tnl_dd/t_dd_imm_vertex.h"
+
+#define IND (VTX_RGBA)
+#define TAG(x) ffb_##x##_RGBA
+#include "tnl_dd/t_dd_imm_vertex.h"
+
+static void ffb_init_vert_funcs( void )
+{
+ ffb_init_vert_NORMAL();
+ ffb_init_vert_RGBA();
+}
+
+#define LOCAL_VARS \
+ ffbContextPtr fmesa = FFB_CONTEXT(ctx)
+
+#define GET_INTERP_FUNC \
+ ffb_interp_func interp = fmesa->imm.interp
+
+#define FLUSH_VERTEX fmesa->imm.flush_vertex
+#define IMM_VERTEX( V ) fmesa->imm.V
+#define IMM_VERTICES( n ) fmesa->imm.vertices[n]
+
+#define EMIT_VERTEX_USES_HWREGS
+
+/* XXX Implement me XXX */
+#define EMIT_VERTEX_TRI(VTX0, VTX1, VTX2) \
+ do { } while (0)
+#define EMIT_VERTEX_LINE(VTX0, VTX1) \
+ do { } while (0)
+#define EMIT_VERTEX_POINT(VTX0) \
+ do { } while (0)
+
+#define TAG(x) ffb_##x
+#include "tnl_dd/t_dd_imm_primtmp.h"
+
+/* Bzzt: Material changes are lost on fallback. */
+static void ffb_Materialfv(GLenum face, GLenum pname,
+ const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ _mesa_noop_Materialfv( face, pname, params );
+ ffb_recalc_base_color( ctx );
+}
+
+/* Fallback functions: */
+
+static void ffb_do_fallback(GLcontext *ctx)
+{
+ ffbContextPtr fmesa = FFB_CONTEXT(ctx);
+ struct ffb_current_state *current = &fmesa->vtx_state.current;
+
+ /* Tell tnl to restore its exec vtxfmt, rehook its driver callbacks
+ * and revive internal state that depended on those callbacks:
+ */
+ _tnl_wakeup_exec(ctx);
+
+ /* Replay enough vertices that the current primitive is continued
+ * correctly:
+ */
+ if (fmesa->imm.prim != PRIM_OUTSIDE_BEGIN_END )
+ glBegin(fmesa->imm.prim);
+
+ if (ctx->Light.Enabled) {
+ glColor4fv(ctx->Current.Color); /* Catch ColorMaterial */
+ glNormal3fv(current->normal);
+ } else {
+ glColor4fv(current->color);
+ }
+}
+
+#define PRE_LOOPBACK( FUNC ) do { \
+ GET_CURRENT_CONTEXT(ctx); \
+ ffb_do_fallback( ctx ); \
+} while (0)
+
+#define TAG(x) ffb_fallback_##x
+#include "vtxfmt_tmp.h"
+
+static void ffb_Begin(GLenum prim)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ffbContextPtr fmesa = FFB_CONTEXT(ctx);
+
+ if (prim > GL_POLYGON) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" );
+ return;
+ }
+
+ if (fmesa->imm.prim != PRIM_OUTSIDE_BEGIN_END) {
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
+ return;
+ }
+
+ ctx->Driver.NeedFlush |= (FLUSH_STORED_VERTICES |
+ FLUSH_UPDATE_CURRENT);
+
+ fmesa->imm.prim = prim;
+ fmesa->imm.v0 = &fmesa->imm.vertices[0];
+ fmesa->imm.save_vertex = ffb_save_vertex_RGBA;
+ fmesa->imm.flush_vertex = ffb_flush_tab[prim];
+
+ /* XXX Lock hardware, update FBC, PPC, DRAWOP, etc. XXX */
+}
+
+static void ffb_End(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ffbContextPtr fmesa = FFB_CONTEXT(ctx);
+
+ if (fmesa->imm.prim == PRIM_OUTSIDE_BEGIN_END) {
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
+ return;
+ }
+
+ fmesa->imm.prim = PRIM_OUTSIDE_BEGIN_END;
+
+ ctx->Driver.NeedFlush &= ~(FLUSH_STORED_VERTICES |
+ FLUSH_UPDATE_CURRENT);
+
+ /* XXX Unlock hardware, etc. */
+}
+
+void ffbInitTnlModule(GLcontext *ctx)
+{
+ ffbContextPtr fmesa = FFB_CONTEXT(ctx);
+ GLvertexformat *vfmt = &(fmesa->imm.vtxfmt);
+
+ /* Work in progress... */
+ return;
+
+ ffb_init_norm_funcs();
+ ffb_init_vert_funcs();
+
+ MEMSET(vfmt, 0, sizeof(GLvertexformat));
+
+ /* Handled fully in supported states: */
+ vfmt->ArrayElement = NULL; /* FIXME: ... */
+ vfmt->Color3f = ffb_choose_Color3f;
+ vfmt->Color3fv = ffb_choose_Color3fv;
+ vfmt->Color3ub = ffb_choose_Color3ub;
+ vfmt->Color3ubv = ffb_choose_Color3ubv;
+ vfmt->Color4f = ffb_choose_Color4f;
+ vfmt->Color4fv = ffb_choose_Color4fv;
+ vfmt->Color4ub = ffb_choose_Color4ub;
+ vfmt->Color4ubv = ffb_choose_Color4ubv;
+ vfmt->FogCoordfvEXT = ffb_FogCoordfvEXT;
+ vfmt->FogCoordfEXT = ffb_FogCoordfEXT;
+ vfmt->Materialfv = ffb_Materialfv;
+ vfmt->MultiTexCoord1fARB = ffb_fallback_MultiTexCoord1fARB;
+ vfmt->MultiTexCoord1fvARB = ffb_fallback_MultiTexCoord1fvARB;
+ vfmt->MultiTexCoord2fARB = ffb_fallback_MultiTexCoord2fARB;
+ vfmt->MultiTexCoord2fvARB = ffb_fallback_MultiTexCoord2fvARB;
+ vfmt->MultiTexCoord3fARB = ffb_fallback_MultiTexCoord3fARB;
+ vfmt->MultiTexCoord3fvARB = ffb_fallback_MultiTexCoord3fvARB;
+ vfmt->MultiTexCoord4fARB = ffb_fallback_MultiTexCoord4fARB;
+ vfmt->MultiTexCoord4fvARB = ffb_fallback_MultiTexCoord4fvARB;
+ vfmt->Normal3f = ffb_choose_Normal3f;
+ vfmt->Normal3fv = ffb_choose_Normal3fv;
+ vfmt->SecondaryColor3ubEXT = ffb_SecondaryColor3ubEXT;
+ vfmt->SecondaryColor3ubvEXT = ffb_SecondaryColor3ubvEXT;
+ vfmt->SecondaryColor3fEXT = ffb_SecondaryColor3fEXT;
+ vfmt->SecondaryColor3fvEXT = ffb_SecondaryColor3fvEXT;
+ vfmt->TexCoord1f = ffb_fallback_TexCoord1f;
+ vfmt->TexCoord1fv = ffb_fallback_TexCoord1fv;
+ vfmt->TexCoord2f = ffb_fallback_TexCoord2f;
+ vfmt->TexCoord2fv = ffb_fallback_TexCoord2fv;
+ vfmt->TexCoord3f = ffb_fallback_TexCoord3f;
+ vfmt->TexCoord3fv = ffb_fallback_TexCoord3fv;
+ vfmt->TexCoord4f = ffb_fallback_TexCoord4f;
+ vfmt->TexCoord4fv = ffb_fallback_TexCoord4fv;
+
+ vfmt->Vertex2f = ffb_Vertex2f;
+ vfmt->Vertex2fv = ffb_Vertex2fv;
+ vfmt->Vertex3f = ffb_Vertex3f;
+ vfmt->Vertex3fv = ffb_Vertex3fv;
+ vfmt->Vertex4f = ffb_Vertex4f;
+ vfmt->Vertex4fv = ffb_Vertex4fv;
+
+ vfmt->Begin = ffb_Begin;
+ vfmt->End = ffb_End;
+
+ vfmt->Rectf = _mesa_noop_Rectf; /* generic helper */
+
+ vfmt->DrawArrays = NULL;
+ vfmt->DrawElements = NULL;
+ vfmt->DrawRangeElements = _mesa_noop_DrawRangeElements; /* discard range */
+
+
+ /* Not active in supported states; just keep ctx->Current uptodate: */
+ vfmt->EdgeFlag = _mesa_noop_EdgeFlag;
+ vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv;
+ vfmt->Indexi = _mesa_noop_Indexi;
+ vfmt->Indexiv = _mesa_noop_Indexiv;
+
+ /* Active but unsupported -- fallback if we receive these:
+ *
+ * All of these fallbacks can be fixed with additional code, except
+ * CallList, unless we build a play_immediate_noop() command which
+ * turns an immediate back into glBegin/glEnd commands...
+ */
+ vfmt->CallList = ffb_fallback_CallList;
+ vfmt->EvalCoord1f = ffb_fallback_EvalCoord1f;
+ vfmt->EvalCoord1fv = ffb_fallback_EvalCoord1fv;
+ vfmt->EvalCoord2f = ffb_fallback_EvalCoord2f;
+ vfmt->EvalCoord2fv = ffb_fallback_EvalCoord2fv;
+ vfmt->EvalMesh1 = ffb_fallback_EvalMesh1;
+ vfmt->EvalMesh2 = ffb_fallback_EvalMesh2;
+ vfmt->EvalPoint1 = ffb_fallback_EvalPoint1;
+ vfmt->EvalPoint2 = ffb_fallback_EvalPoint2;
+
+ vfmt->prefer_float_colors = GL_TRUE;
+
+ fmesa->imm.prim = PRIM_OUTSIDE_BEGIN_END;
+
+ /* THIS IS A HACK! */
+ _mesa_install_exec_vtxfmt( ctx, vfmt );
+}