OSDN Git Service

Import s3virge and trident drivers. Not functional yet; no Makefile, no DRI-aware...
authorAdam Jackson <ajax@freedesktop.org>
Thu, 16 Dec 2004 19:26:23 +0000 (19:26 +0000)
committerAdam Jackson <ajax@freedesktop.org>
Thu, 16 Dec 2004 19:26:23 +0000 (19:26 +0000)
30 files changed:
src/mesa/drivers/dri/s3v/s3v_context.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_context.h [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_dd.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_inithw.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_lock.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_lock.h [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_macros.h [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_regs.h [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_render.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_screen.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_screen.h [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_span.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_state.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_tex.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_tex.h [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_texmem.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_texstate.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_tris.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_tris.h [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_tritmp.h [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_vb.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_vb.h [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3v_xmesa.c [new file with mode: 0644]
src/mesa/drivers/dri/s3v/s3virgetri.h [new file with mode: 0644]
src/mesa/drivers/dri/trident/trident_context.c [new file with mode: 0644]
src/mesa/drivers/dri/trident/trident_context.h [new file with mode: 0644]
src/mesa/drivers/dri/trident/trident_dd.c [new file with mode: 0644]
src/mesa/drivers/dri/trident/trident_state.c [new file with mode: 0644]
src/mesa/drivers/dri/trident/trident_tris.c [new file with mode: 0644]
src/mesa/drivers/dri/trident/trident_vb.c [new file with mode: 0644]

diff --git a/src/mesa/drivers/dri/s3v/s3v_context.c b/src/mesa/drivers/dri/s3v/s3v_context.c
new file mode 100644 (file)
index 0000000..4e199a6
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include "s3v_context.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "array_cache/acache.h"
+
+#include "tnl/tnl.h"
+#include "tnl/t_pipeline.h"
+
+#include "context.h"
+#include "simple_list.h"
+#include "mem.h"
+#include "matrix.h"
+#include "extensions.h"
+#if defined(USE_X86_ASM)
+#include "X86/common_x86_asm.h"
+#endif
+#include "simple_list.h"
+#include "mem.h"
+#include "mm.h"
+
+
+#include "s3v_vb.h"
+#include "s3v_tris.h"
+
+#if 0
+extern const struct gl_pipeline_stage _s3v_render_stage;
+
+static const struct gl_pipeline_stage *s3v_pipeline[] = {
+   &_tnl_vertex_transform_stage,
+   &_tnl_normal_transform_stage,
+   &_tnl_lighting_stage,
+   &_tnl_fog_coordinate_stage,
+   &_tnl_texgen_stage,
+   &_tnl_texture_transform_stage,
+                               /* REMOVE: point attenuation stage */
+#if 1
+   &_s3v_render_stage, /* ADD: unclipped rastersetup-to-dma */
+#endif
+   &_tnl_render_stage,
+   0,
+};
+#endif
+
+GLboolean s3vCreateContext( Display *dpy, const __GLcontextModes *glVisual,
+                            __DRIcontextPrivate *driContextPriv,
+                            void *sharedContextPrivate)
+{
+       GLcontext *ctx, *shareCtx;
+       __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+       s3vContextPtr vmesa;
+       s3vScreenPtr s3vScrn;
+       S3VSAREAPtr saPriv=(S3VSAREAPtr)(((char*)sPriv->pSAREA)+
+                                                sizeof(XF86DRISAREARec));
+
+       DEBUG_WHERE(("*** s3vCreateContext ***\n"));
+
+       vmesa = (s3vContextPtr) CALLOC( sizeof(*vmesa) );
+       if ( !vmesa ) return GL_FALSE;
+
+       /* Allocate the Mesa context */
+       if (sharedContextPrivate)
+               shareCtx = ((s3vContextPtr) sharedContextPrivate)->glCtx;
+       else
+               shareCtx = NULL;
+
+       vmesa->glCtx = _mesa_create_context(glVisual, shareCtx, vmesa, GL_TRUE);
+       if (!vmesa->glCtx) {
+               FREE(vmesa);
+               return GL_FALSE;
+       }
+
+       vmesa->display = dpy;
+
+       vmesa->driContext = driContextPriv;
+       vmesa->driScreen = sPriv;
+       vmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */
+
+       vmesa->hHWContext = driContextPriv->hHWContext;
+       vmesa->driHwLock = &sPriv->pSAREA->lock;
+       vmesa->driFd = sPriv->fd;
+       vmesa->sarea = saPriv;
+
+       s3vScrn = vmesa->s3vScreen = (s3vScreenPtr)(sPriv->private);
+
+       ctx = vmesa->glCtx;
+
+       ctx->Const.MaxTextureLevels = 11;  /* it is (11-1) -> 1024 * 1024 FIXME */
+
+       ctx->Const.MaxTextureUnits = 1; /* FIXME: or 2 ? */
+
+       /* No wide points.
+        */
+       ctx->Const.MinPointSize = 1.0;
+       ctx->Const.MinPointSizeAA = 1.0;
+       ctx->Const.MaxPointSize = 1.0;
+       ctx->Const.MaxPointSizeAA = 1.0;
+
+       /* No wide lines.
+        */
+       ctx->Const.MinLineWidth = 1.0;
+       ctx->Const.MinLineWidthAA = 1.0;
+       ctx->Const.MaxLineWidth = 1.0;
+       ctx->Const.MaxLineWidthAA = 1.0;
+       ctx->Const.LineWidthGranularity = 1.0;
+
+       vmesa->texHeap = mmInit( 0, vmesa->s3vScreen->textureSize );
+       DEBUG(("vmesa->s3vScreen->textureSize = 0x%x\n",
+               vmesa->s3vScreen->textureSize));
+       
+       /* NOTE */
+       /* mmInit(offset, size); */
+
+       /* allocates a structure like this:
+
+       struct mem_block_t {
+               struct mem_block_t *next;
+               struct mem_block_t *heap;
+               int ofs,size;
+               int align;
+               int free:1;
+               int reserved:1;
+       };
+
+       */
+
+       make_empty_list(&vmesa->TexObjList);
+       make_empty_list(&vmesa->SwappedOut);
+
+       vmesa->CurrentTexObj[0] = 0;
+       vmesa->CurrentTexObj[1] = 0; /* FIXME */
+
+       vmesa->RenderIndex = ~0;
+
+       /* Initialize the software rasterizer and helper modules.
+        */
+       _swrast_CreateContext( ctx );
+       _ac_CreateContext( ctx );
+       _tnl_CreateContext( ctx );
+       _swsetup_CreateContext( ctx );
+
+       /* Install the customized pipeline:
+        */
+#if 0
+       _tnl_destroy_pipeline( ctx );
+       _tnl_install_pipeline( ctx, s3v_pipeline );
+#endif
+       /* Configure swrast to match hardware characteristics:
+        */
+#if 0
+       _swrast_allow_pixel_fog( ctx, GL_FALSE );
+       _swrast_allow_vertex_fog( ctx, GL_TRUE );
+#endif
+       vmesa->_3d_mode = 0;
+
+       /* 3D lines / gouraud tris */
+       vmesa->CMD = ( AUTO_EXEC_ON | HW_CLIP_ON | DEST_COL_1555
+                       | FOG_OFF | ALPHA_OFF | Z_OFF | Z_UPDATE_OFF
+                       | Z_LESS | TEX_WRAP_ON | TEX_MODULATE | LINEAR
+                       | TEX_COL_ARGB1555 | CMD_3D );
+
+       vmesa->_alpha[0] = vmesa->_alpha[1] = ALPHA_OFF;
+       vmesa->alpha_cmd = vmesa->_alpha[0];
+       vmesa->_tri[0] = DO_GOURAUD_TRI;
+       vmesa->_tri[1] = DO_TEX_LIT_TRI;
+       vmesa->prim_cmd = vmesa->_tri[0];
+
+       /* printf("first vmesa->CMD = 0x%x\n", vmesa->CMD); */
+
+       vmesa->TexOffset = vmesa->s3vScreen->texOffset;
+
+       s3vInitVB( ctx );
+       s3vInitExtensions( ctx );
+       s3vInitDriverFuncs( ctx );
+       s3vInitStateFuncs( ctx );
+       s3vInitSpanFuncs( ctx );
+       s3vInitTextureFuncs( ctx );
+       s3vInitTriFuncs( ctx );
+       s3vInitState( vmesa );
+
+       driContextPriv->driverPrivate = (void *)vmesa;
+
+       /* HACK */
+       vmesa->bufSize = S3V_DMA_BUF_SZ;
+
+       DEBUG(("vmesa->bufSize = %i\n", vmesa->bufSize));
+       DEBUG(("vmesa->bufCount = %i\n", vmesa->bufCount));
+
+
+       /* dma init */
+       DEBUG_BUFS(("GET_FIRST_DMA\n"));
+       
+       vmesa->_bufNum = 0;
+
+       GET_FIRST_DMA(vmesa->driFd, vmesa->hHWContext,
+       1, &(vmesa->bufIndex[0]), &(vmesa->bufSize),
+       &vmesa->_buf[0], &vmesa->bufCount, s3vScrn);
+
+       GET_FIRST_DMA(vmesa->driFd, vmesa->hHWContext,
+    1, &(vmesa->bufIndex[1]), &(vmesa->bufSize),
+    &vmesa->_buf[1], &vmesa->bufCount, s3vScrn);
+
+       vmesa->buf = vmesa->_buf[vmesa->_bufNum];
+       
+/*
+       vmesa->CMD = (AUTO_EXEC_ON | HW_CLIP_ON | DEST_COL_1555
+       | FOG_OFF | ALPHA_OFF | Z_OFF | Z_UPDATE_OFF
+       | DO_GOURAUD_TRI | CMD_3D);
+
+       vmesa->TexOffset = vmesa->s3vScreen->texOffset;
+*/
+
+/* ... but we should support only 15 bit in virge (out of 8/15/24)... */
+
+       DEBUG(("glVisual->depthBits = %i\n", glVisual->depthBits));
+
+       switch (glVisual->depthBits) {
+       case 8:
+               break;
+       
+       case 15:
+       case 16:
+               vmesa->depth_scale = 1.0f / 0xffff; 
+               break;
+       case 24:
+               vmesa->depth_scale = 1.0f / 0xffffff;
+               break;
+       default:
+               break;
+       }
+
+       vmesa->cull_zero = 0.0f;
+
+       vmesa->DepthSize = glVisual->depthBits;
+       vmesa->Flags  = S3V_FRONT_BUFFER;
+       vmesa->Flags |= (glVisual->doubleBufferMode ? S3V_BACK_BUFFER : 0);
+       vmesa->Flags |= (vmesa->DepthSize > 0 ? S3V_DEPTH_BUFFER : 0);
+
+       vmesa->EnabledFlags = S3V_FRONT_BUFFER;
+       vmesa->EnabledFlags |= (glVisual->doubleBufferMode ? S3V_BACK_BUFFER : 0);
+
+
+       if (vmesa->Flags & S3V_BACK_BUFFER) {
+               vmesa->readOffset = vmesa->drawOffset = vmesa->s3vScreen->backOffset;
+       } else {
+               vmesa->readOffset = vmesa->drawOffset = 0;
+       }
+
+       s3vInitHW( vmesa );
+
+       driContextPriv->driverPrivate = (void *)vmesa;
+
+       return GL_TRUE;
+}
diff --git a/src/mesa/drivers/dri/s3v/s3v_context.h b/src/mesa/drivers/dri/s3v/s3v_context.h
new file mode 100644 (file)
index 0000000..79cd6fe
--- /dev/null
@@ -0,0 +1,443 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#ifndef _S3V_CONTEXT_H_
+#define _S3V_CONTEXT_H_
+
+#include "dri_util.h"
+
+#include "s3v_dri.h"
+#include "s3v_regs.h"
+#include "s3v_macros.h"
+#include "s3v_screen.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "drm.h"
+#include "mm.h"
+
+/* Flags for context */
+#define S3V_FRONT_BUFFER    0x00000001
+#define S3V_BACK_BUFFER     0x00000002
+#define S3V_DEPTH_BUFFER    0x00000004
+
+       /* FIXME: check */
+#define S3V_MAX_TEXTURE_SIZE    2048
+
+/* These are the minimum requirements and should probably be increased */
+#define MAX_MODELVIEW_STACK    16
+#define MAX_PROJECTION_STACK    2
+#define MAX_TEXTURE_STACK       2
+
+extern void            s3vDDUpdateHWState(GLcontext *ctx);
+extern s3vScreenPtr    s3vCreateScreen(__DRIscreenPrivate *sPriv);
+extern void            s3vDestroyScreen(__DRIscreenPrivate *sPriv);
+extern GLboolean       s3vCreateContext( Display *dpy,
+                                     const __GLcontextModes *glVisual,
+                                     __DRIcontextPrivate *driContextPriv,
+                                     void *sharedContextPrivate);
+
+#define S3V_UPLOAD_ALL                 0xffffffff
+/* #define S3V_UPLOAD_CLIPRECTS                0x00000002 */
+#define S3V_UPLOAD_ALPHA               0x00000004
+#define S3V_UPLOAD_BLEND               0x00000008
+#define S3V_UPLOAD_DEPTH               0x00000010
+#define S3V_UPLOAD_VIEWPORT            0x00000020
+#define S3V_UPLOAD_SHADE               0x00000040
+#define S3V_UPLOAD_CLIP                        0x00000080
+#define S3V_UPLOAD_MASKS               0x00000100
+#define S3V_UPLOAD_WINDOW              0x00000200 /* defunct */
+#define S3V_UPLOAD_GEOMETRY            0x00000400
+#define S3V_UPLOAD_POLYGON             0x00000800
+#define S3V_UPLOAD_DITHER              0x00001000
+#define S3V_UPLOAD_LOGICOP             0x00002000
+#define S3V_UPLOAD_FOG                 0x00004000
+#define S3V_UPLOAD_LIGHT               0x00008000
+#define S3V_UPLOAD_CONTEXT             0x00010000
+#define S3V_UPLOAD_TEX0                        0x00020000
+#define S3V_UPLOAD_STIPPLE             0x00040000
+#define S3V_UPLOAD_TRANSFORM           0x00080000
+#define S3V_UPLOAD_LINEMODE            0x00100000
+#define S3V_UPLOAD_POINTMODE           0x00200000
+#define S3V_UPLOAD_TRIMODE             0x00400000
+
+#define S3V_NEW_CLIP                   0x00000001
+#define S3V_NEW_WINDOW                 0x00000002
+#define S3V_NEW_CONTEXT                        0x00000004
+#define S3V_NEW_TEXTURE                        0x00000008 /* defunct */
+#define S3V_NEW_ALPHA                  0x00000010
+#define S3V_NEW_DEPTH                  0x00000020
+#define S3V_NEW_MASKS                  0x00000040
+#define S3V_NEW_POLYGON                        0x00000080
+#define S3V_NEW_CULL                   0x00000100
+#define S3V_NEW_LOGICOP                        0x00000200
+#define S3V_NEW_FOG                    0x00000400
+#define S3V_NEW_LIGHT                  0x00000800
+#define S3V_NEW_STIPPLE                        0x00001000
+#define S3V_NEW_ALL                    0xffffffff
+
+#define S3V_FALLBACK_TRI               0x00000001
+#define S3V_FALLBACK_TEXTURE           0x00000002
+
+struct s3v_context;
+typedef struct s3v_context s3vContextRec;
+typedef struct s3v_context *s3vContextPtr;
+typedef struct s3v_texture_object_t *s3vTextureObjectPtr;
+
+#define VALID_S3V_TEXTURE_OBJECT(tobj)  (tobj) 
+
+#define S3V_TEX_MAXLEVELS 12
+
+/* For shared texture space managment, these texture objects may also
+ * be used as proxies for regions of texture memory containing other
+ * client's textures.  Such proxy textures (not to be confused with GL
+ * proxy textures) are subject to the same LRU aging we use for our
+ * own private textures, and thus we have a mechanism where we can
+ * fairly decide between kicking out our own textures and those of
+ * other clients.
+ *
+ * Non-local texture objects have a valid MemBlock to describe the
+ * region managed by the other client, and can be identified by
+ * 't->globj == 0' 
+ */
+struct s3v_texture_object_t {
+       struct s3v_texture_object_t *next, *prev;
+
+       GLuint age;   
+       struct gl_texture_object *globj;
+     
+       int Pitch;
+       int Height;
+       int WidthLog2;
+       int texelBytes;
+       int totalSize;
+       int bound;
+
+       PMemBlock MemBlock;   
+       GLuint BufAddr;
+   
+       GLuint min_level;
+       GLuint max_level;
+       GLuint dirty_images;
+
+       GLint firstLevel, lastLevel;  /* upload tObj->Image[first .. lastLevel] */
+
+       struct { 
+               const struct gl_texture_image *image;
+               int offset;             /* into BufAddr */
+               int height;
+               int internalFormat;
+       } image[S3V_TEX_MAXLEVELS];
+
+       CARD32 TextureCMD;
+
+       CARD32 TextureColorMode;
+       CARD32 TextureFilterMode;
+       CARD32 TextureBorderColor;
+       CARD32 TextureWrap;
+       CARD32 TextureMipSize;
+
+       CARD32 TextureBaseAddr[S3V_TEX_MAXLEVELS];
+       CARD32 TextureFormat;
+       CARD32 TextureReadMode;
+};             
+
+#define S3V_NO_PALETTE        0x0
+#define S3V_USE_PALETTE       0x1
+#define S3V_UPDATE_PALETTE    0x2
+#define S3V_FALLBACK_PALETTE  0x4
+
+void s3vUpdateTextureState( GLcontext *ctx );
+
+void s3vDestroyTexObj( s3vContextPtr vmesa, s3vTextureObjectPtr t);
+void s3vUploadTexImages( s3vContextPtr vmesa, s3vTextureObjectPtr t );
+
+void s3vResetGlobalLRU( s3vContextPtr vmesa );
+void s3vTexturesGone( s3vContextPtr vmesa, 
+                      GLuint start, GLuint end, 
+                      GLuint in_use ); 
+
+void s3vEmitHwState( s3vContextPtr vmesa );
+void s3vGetLock( s3vContextPtr vmesa, GLuint flags );
+void s3vInitExtensions( GLcontext *ctx );
+void s3vInitDriverFuncs( GLcontext *ctx );
+void s3vInitSpanFuncs( GLcontext *ctx );
+void s3vInitState( s3vContextPtr vmesa );
+void s3vInitHW( s3vContextPtr vmesa );
+void s3vInitStateFuncs( GLcontext *ctx );
+void s3vInitTextureFuncs( GLcontext *ctx );
+void s3vInitTriFuncs( GLcontext *ctx );
+
+void s3vUpdateWindow( GLcontext *ctx );
+void s3vUpdateViewportOffset( GLcontext *ctx );
+
+void s3vPrintLocalLRU( s3vContextPtr vmesa );
+void s3vPrintGlobalLRU( s3vContextPtr vmesa );
+
+extern void s3vFallback( s3vContextPtr vmesa, GLuint bit, GLboolean mode );
+#define FALLBACK( imesa, bit, mode ) s3vFallback( imesa, bit, mode )
+
+/* Use the templated vertex formats.  Only one of these is used in s3v.
+ */
+#define TAG(x) s3v##x
+#include "tnl_dd/t_dd_vertex.h"
+#undef TAG
+
+typedef void (*s3v_quad_func)( s3vContextPtr, 
+                               const s3vVertex *, 
+                               const s3vVertex *,
+                               const s3vVertex *,
+                               const s3vVertex * );
+typedef void (*s3v_tri_func)( s3vContextPtr, 
+                               const s3vVertex *, 
+                               const s3vVertex *,
+                               const s3vVertex * );
+typedef void (*s3v_line_func)( s3vContextPtr, 
+                               const s3vVertex *, 
+                               const s3vVertex * );
+typedef void (*s3v_point_func)( s3vContextPtr, 
+                                const s3vVertex * );
+
+
+/* static void s3v_lines_emit(GLcontext *ctx, GLuint start, GLuint end); */
+typedef void (*emit_func)( GLcontext *, GLuint, GLuint);
+
+struct s3v_context {
+       GLcontext               *glCtx;         /* Mesa context */
+
+       __DRIcontextPrivate     *driContext;
+       __DRIscreenPrivate      *driScreen;
+       __DRIdrawablePrivate    *driDrawable;
+
+       GLuint new_gl_state;
+       GLuint new_state;
+       GLuint dirty;
+
+       S3VSAREAPtr     sarea; 
+
+       /* Temporaries for translating away float colors
+        */
+       struct gl_client_array UbyteColor;
+       struct gl_client_array UbyteSecondaryColor;
+
+       /* Mirrors of some DRI state
+        */
+       Display *display;               /* X server display */
+
+       drmContext hHWContext;
+       drmLock *driHwLock;
+       int driFd;
+
+       GLuint numClipRects;            /* Cliprects for the draw buffer */
+       XF86DRIClipRectPtr pClipRects;
+
+       CARD32* buf;                    /* FIXME */
+       CARD32* _buf[2];
+       int             _bufNum;
+       int             bufIndex[2];
+       int             bufSize;
+       int             bufCount;
+
+       s3vScreenPtr    s3vScreen;              /* Screen private DRI data */
+
+       int             drawOffset;
+       int             readOffset;
+
+       s3v_point_func  draw_point;
+       s3v_line_func   draw_line;
+       s3v_tri_func    draw_tri;
+       s3v_quad_func   draw_quad;
+
+       GLuint Fallback;
+       GLuint RenderIndex;
+       GLuint SetupNewInputs;
+       GLuint SetupIndex;
+
+       GLuint vertex_format;
+       GLuint vertex_size;
+       GLuint vertex_stride_shift;
+       char *verts;
+
+       GLfloat hw_viewport[16];
+       GLuint hw_primitive;
+       GLenum render_primitive;
+
+       GLfloat depth_scale;
+
+       s3vTextureObjectPtr CurrentTexObj[2];
+       struct s3v_texture_object_t TexObjList;
+       struct s3v_texture_object_t SwappedOut; 
+       GLenum TexEnvImageFmt[2];
+
+       memHeap_t *texHeap;
+
+       int lastSwap;
+       int texAge;
+       int ctxAge;
+       int dirtyAge;
+       int lastStamp;
+
+       /* max was here: don't touch */
+   
+       unsigned int S3V_REG[S3V_REGS_NUM];
+
+       CARD32 texMode;
+       CARD32 alphaMode;
+       CARD32 lightMode;
+
+       CARD32 SrcBase;
+       CARD32 DestBase;
+       CARD32 DestBlit;
+       CARD32 ScissorLR;
+       CARD32 ScissorTB;
+       CARD32 ScissorWH; /* SubScissorWH */ /* RectWH */
+       CARD32 FrontStride;
+       CARD32 BackStride;
+       CARD32 SrcStride;
+       CARD32 DestStride;
+       CARD32 SrcXY;
+       CARD32 DestXY;
+
+       CARD32 ClearColor;
+       CARD32 Color;
+       CARD32 DitherMode;
+       CARD32 ClearDepth;
+
+       CARD32 TextureBorderColor;
+       CARD32 TexOffset;
+       CARD32 TexStride;
+
+       CARD32 CMD;
+       CARD32 prim_cmd;
+       CARD32 _tri[2]; /* 0 = gouraud; 1 = tex (lit or unlit) */
+       CARD32 alpha_cmd; /* actual alpha cmd */
+       CARD32 _alpha[2];
+       CARD32 _alpha_tex; /* tex alpha type */
+       /* (3d_mode) 0 = 3d line/gourad tri; 1 = 3d tex tri */
+       CARD32 _3d_mode;
+       
+       GLfloat backface_sign;
+       GLfloat cull_zero;
+
+       int restore_primitive;
+
+/* *** 2check *** */
+
+       CARD32          FogMode;
+       CARD32          AreaStippleMode;
+       CARD32          LBReadFormat;
+       CARD32          LBWriteFormat;
+       CARD32          LineMode;
+       CARD32          PointMode;
+       CARD32          TriangleMode;
+       CARD32          AntialiasMode;
+       GLfloat         ViewportScaleX;
+       GLfloat         ViewportScaleY;
+       GLfloat         ViewportScaleZ;
+       GLfloat         ViewportOffsetX;
+       GLfloat         ViewportOffsetY;
+       GLfloat         ViewportOffsetZ;
+       int             MatrixMode;
+       int             DepthMode;
+       int             TransformMode;
+       int             LBReadMode;
+       int             FBReadMode;
+       int             FBWindowBase;
+       int             LBWindowBase;
+       int             ColorDDAMode;
+       int             GeometryMode;
+       int             AlphaTestMode;
+       int             AlphaBlendMode;
+       int             AB_FBReadMode;
+       int             AB_FBReadMode_Save;
+       int             DeltaMode;
+       int             ColorMaterialMode;
+       int             FBHardwareWriteMask;
+       int             MaterialMode;
+       int             NormalizeMode;
+       int             LightingMode;
+       int             Light0Mode;
+       int             Light1Mode;
+       int             Light2Mode;
+       int             Light3Mode;
+       int             Light4Mode;
+       int             Light5Mode;
+       int             Light6Mode;
+       int             Light7Mode;
+       int             Light8Mode;
+       int             Light9Mode;
+       int             Light10Mode;
+       int             Light11Mode;
+       int             Light12Mode;
+       int             Light13Mode;
+       int             Light14Mode;
+       int             Light15Mode;
+       int             LogicalOpMode;
+       int             ScissorMode;
+       int             ScissorMaxXY;
+       int             ScissorMinXY;
+       int             Window; /* GID part probably should be in draw priv */
+       int             WindowOrigin;
+       int             x, y, w, h; /* Probably should be in drawable priv */
+       int             FrameCount; /* Probably should be in drawable priv */
+       int             NotClipped; /* Probably should be in drawable priv */
+       int             WindowChanged; /* Probably should be in drawabl... */
+       int             Flags;
+       int             EnabledFlags;
+       int             DepthSize;
+       int             Begin;
+       GLenum          ErrorValue;
+       int             Texture1DEnabled;
+       int             Texture2DEnabled;
+
+       float           ModelView[16];
+       float           Proj[16];
+       float           ModelViewProj[16];
+       float           Texture[16];
+
+       float           ModelViewStack[(MAX_MODELVIEW_STACK-1)*16];
+       int             ModelViewCount;
+       float           ProjStack[(MAX_PROJECTION_STACK-1)*16];
+       int             ProjCount;
+       float           TextureStack[(MAX_TEXTURE_STACK-1)*16];
+       int             TextureCount;
+};
+
+#define S3VIRGEPACKCOLOR555( r, g, b, a ) \
+    ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
+     ((a) ? 0x8000 : 0))
+
+#define S3VIRGEPACKCOLOR565( r, g, b ) \
+    ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+
+#define S3VIRGEPACKCOLOR888( r, g, b ) \
+    (((r) << 16) | ((g) << 8) | (b))
+
+#define S3VIRGEPACKCOLOR8888( r, g, b, a ) \
+    (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+
+#define S3VIRGEPACKCOLOR4444( r, g, b, a ) \
+    ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
+
+static __inline GLuint s3vPackColor( GLuint cpp,
+                                       GLubyte r, GLubyte g,
+                                       GLubyte b, GLubyte a )
+{
+       unsigned int ret;
+       DEBUG(("cpp = %i, r=0x%x, g=0x%x, b=0x%x, a=0x%x\n", cpp, r, g, b, a));
+
+       switch ( cpp ) {
+       case 2:
+               ret = S3VIRGEPACKCOLOR555( r, g, b, a );
+               DEBUG(("ret = 0x%x\n", ret));
+               return ret;
+       case 4:
+               return PACK_COLOR_8888( a, r, g, b );
+       default:
+       return 0;
+       }
+}
+
+#define S3V_CONTEXT(ctx)       ((s3vContextPtr)(ctx->DriverCtx))
+
+#endif /* _S3V_CONTEXT_H_ */
diff --git a/src/mesa/drivers/dri/s3v/s3v_dd.c b/src/mesa/drivers/dri/s3v/s3v_dd.c
new file mode 100644 (file)
index 0000000..683ae34
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include "s3v_context.h"
+#include "s3v_vb.h"
+#include "s3v_lock.h"
+#if defined(USE_X86_ASM)
+#include "X86/common_x86_asm.h"
+#endif
+
+#include "context.h"
+#include "swrast/swrast.h"
+
+#define S3V_DATE "20020207"
+
+
+/* Return the width and height of the current color buffer.
+ */
+static void s3vDDGetBufferSize( GLframebuffer *buffer,
+                                GLuint *width, GLuint *height )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+/* S3VHW_LOCK( vmesa ); */
+   *width  = vmesa->driDrawable->w;
+   *height = vmesa->driDrawable->h;
+/* S3VHW_UNLOCK( vmesa ); */
+}
+
+
+/* Return various strings for glGetString().
+ */
+static const GLubyte *s3vDDGetString( GLcontext *ctx, GLenum name )
+{
+   static char buffer[128];
+
+   switch ( name ) {
+   case GL_VENDOR:
+      return (GLubyte *)"Max Lingua (ladybug)";
+
+   case GL_RENDERER:
+      sprintf( buffer, "Mesa DRI S3 Virge " S3V_DATE );
+
+      /* Append any CPU-specific information.
+       */
+#ifdef USE_X86_ASM
+      if ( _mesa_x86_cpu_features ) {
+        strncat( buffer, " x86", 4 );
+      
+}
+#ifdef USE_MMX_ASM
+      if ( cpu_has_mmx ) {
+        strncat( buffer, "/MMX", 4 );
+      }
+#endif
+#ifdef USE_3DNOW_ASM
+      if ( cpu_has_3dnow ) {
+        strncat( buffer, "/3DNow!", 7 );
+      }
+#endif
+#ifdef USE_SSE_ASM
+      if ( cpu_has_xmm ) {
+        strncat( buffer, "/SSE", 4 );
+      }
+#endif
+#endif
+      return (GLubyte *)buffer;
+
+   default:
+      return NULL;
+   }
+}
+
+/* Enable the extensions supported by this driver.
+ */
+void s3vInitExtensions( GLcontext *ctx )
+{
+   /* None... */
+}
+
+/* Initialize the driver's misc functions.
+ */
+void s3vInitDriverFuncs( GLcontext *ctx )
+{
+   ctx->Driver.GetBufferSize   = s3vDDGetBufferSize;
+   ctx->Driver.GetString               = s3vDDGetString;
+
+   ctx->Driver.Error                   = NULL;
+
+   /* Pixel path fallbacks
+    */
+   ctx->Driver.Accum                    = _swrast_Accum;
+   ctx->Driver.Bitmap                   = _swrast_Bitmap;
+   ctx->Driver.CopyPixels               = _swrast_CopyPixels;
+   ctx->Driver.DrawPixels               = _swrast_DrawPixels;
+   ctx->Driver.ReadPixels               = _swrast_ReadPixels;
+   ctx->Driver.ResizeBuffers            = _swrast_alloc_buffers;
+
+   /* Swrast hooks for imaging extensions:
+    */
+   ctx->Driver.CopyColorTable                  = _swrast_CopyColorTable;
+   ctx->Driver.CopyColorSubTable               = _swrast_CopyColorSubTable;
+   ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+   ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+}
diff --git a/src/mesa/drivers/dri/s3v/s3v_inithw.c b/src/mesa/drivers/dri/s3v/s3v_inithw.c
new file mode 100644 (file)
index 0000000..bdc9eff
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include <sys/ioctl.h>
+
+#include "s3v_context.h"
+
+void s3vInitHW( s3vContextPtr vmesa )
+{
+       int i;
+       static short _reset = 1;
+
+       DEBUG(("vmesa->driDrawable = %p\n", vmesa->driDrawable));
+       DEBUG(("stride = %i\n",
+               vmesa->driScreen->fbWidth*vmesa->s3vScreen->cpp));
+       DEBUG(("frontOffset = 0x%x\n", vmesa->s3vScreen->frontOffset));
+       DEBUG(("backOffset = 0x%x\n", vmesa->s3vScreen->backOffset));
+       DEBUG(("depthOffset = 0x%x\n", vmesa->s3vScreen->depthOffset));
+       DEBUG(("textureOffset = 0x%x\n", vmesa->s3vScreen->texOffset));
+
+/*     if (_reset) { */
+/*     ioctl(vmesa->driFd, 0x4a); */
+               ioctl(vmesa->driFd, 0x41); /* reset */
+               _reset = 0;
+/*     ioctl(vmesa->driFd, 0x4c); */
+/*     } */
+
+       /* FIXME */
+       switch (vmesa->s3vScreen->cpp) {
+               case 2:
+                       break;
+               case 4:
+                       break;
+       }
+
+       /* FIXME for stencil, gid, etc */
+       switch (vmesa->DepthSize) {
+               case 15:
+               case 16:
+                       break;
+               case 24:
+                       break;
+               case 32:
+                       break;
+       }
+
+       vmesa->FogMode = 1;
+       vmesa->ClearDepth = 0xffff;
+       vmesa->x = 0;
+       vmesa->y = 0;
+       vmesa->w = 0;
+       vmesa->h = 0;
+       vmesa->FrameCount = 0;
+       vmesa->MatrixMode = GL_MODELVIEW;
+       vmesa->ModelViewCount = 0;
+       vmesa->ProjCount = 0;
+       vmesa->TextureCount = 0;
+
+
+       /* FIXME: do we need the following? */
+
+       for (i = 0; i < 16; i++)
+               if (i % 5 == 0)
+                       vmesa->ModelView[i] =
+                       vmesa->Proj[i] =
+                       vmesa->ModelViewProj[i] =
+                       vmesa->Texture[i] = 1.0;
+               else
+                       vmesa->ModelView[i] =
+                       vmesa->Proj[i] =
+                       vmesa->ModelViewProj[i] =
+                       vmesa->Texture[i] = 0.0;
+
+       vmesa->LBWindowBase = vmesa->driScreen->fbWidth *
+                               (vmesa->driScreen->fbHeight - 1);
+       vmesa->FBWindowBase = vmesa->driScreen->fbWidth * 
+                               (vmesa->driScreen->fbHeight - 1);
+}
diff --git a/src/mesa/drivers/dri/s3v/s3v_lock.c b/src/mesa/drivers/dri/s3v/s3v_lock.c
new file mode 100644 (file)
index 0000000..52bb87e
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include "s3v_context.h"
+
+#if DEBUG_LOCKING
+char *prevLockFile = NULL;
+int prevLockLine = 0;
+#endif
+
+
+/* Update the hardware state.  This is called if another context has
+ * grabbed the hardware lock, which includes the X server.  This
+ * function also updates the driver's window state after the X server
+ * moves, resizes or restacks a window -- the change will be reflected
+ * in the drawable position and clip rects.  Since the X server grabs
+ * the hardware lock when it changes the window state, this routine will
+ * automatically be called after such a change.
+ */
+void s3vGetLock( s3vContextPtr vmesa, GLuint flags )
+{
+   __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+/*   __DRIscreenPrivate *sPriv = vmesa->driScreen; */
+
+   printf("s3vGetLock <- ***\n");
+
+   drmGetLock( vmesa->driFd, vmesa->hHWContext, flags );
+
+   /* The window might have moved, so we might need to get new clip
+    * rects.
+    *
+    * NOTE: This releases and regrabs the hw lock to allow the X server
+    * to respond to the DRI protocol request for new drawable info.
+    * Since the hardware state depends on having the latest drawable
+    * clip rects, all state checking must be done _after_ this call.
+    */
+   /* DRI_VALIDATE_DRAWABLE_INFO( vmesa->display, sPriv, dPriv ); */
+
+   if ( vmesa->lastStamp != dPriv->lastStamp ) {
+      vmesa->lastStamp = dPriv->lastStamp;
+      vmesa->new_state |= S3V_NEW_WINDOW | S3V_NEW_CLIP;
+   }
+
+   vmesa->numClipRects = dPriv->numClipRects;
+   vmesa->pClipRects = dPriv->pClipRects;
+
+#if 0
+   vmesa->dirty = ~0;
+
+   if ( sarea->ctxOwner != vmesa->hHWContext ) {
+      sarea->ctxOwner = vmesa->hHWContext;
+      vmesa->dirty = S3V_UPLOAD_ALL;
+   }
+
+   for ( i = 0 ; i < vmesa->lastTexHeap ; i++ ) {
+      if ( sarea->texAge[i] != vmesa->lastTexAge[i] ) {
+        s3vAgeTextures( vmesa, i );
+      }
+   }
+#endif
+}
diff --git a/src/mesa/drivers/dri/s3v/s3v_lock.h b/src/mesa/drivers/dri/s3v/s3v_lock.h
new file mode 100644 (file)
index 0000000..f1bb2a9
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#ifndef __S3V_LOCK_H__
+#define __S3V_LOCK_H__
+
+#include <sys/ioctl.h>
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void s3vGetLock( s3vContextPtr vmesa, GLuint flags );
+
+/* Turn DEBUG_LOCKING on to find locking conflicts.
+ */
+#define DEBUG_LOCKING  0
+
+#if DEBUG_LOCKING
+extern char *prevLockFile;
+extern int prevLockLine;
+
+#define DEBUG_LOCK() \
+   do {        \
+      prevLockFile = (__FILE__); \
+      prevLockLine = (__LINE__); \
+   } while (0)
+
+#define DEBUG_RESET() \
+   do {        \
+      prevLockFile = 0;        \
+      prevLockLine = 0;        \
+   } while (0)
+
+#define DEBUG_CHECK_LOCK() \
+   do {        \
+      if ( prevLockFile ) { \
+        fprintf( stderr, \
+                 "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \
+                 prevLockFile, prevLockLine, __FILE__, __LINE__ );     \
+        exit(1); \
+      }        \
+   } while (0)
+
+#else
+
+#define DEBUG_LOCK()
+#define DEBUG_RESET()
+#define DEBUG_CHECK_LOCK()
+
+#endif
+
+/*
+ * !!! We may want to separate locks from locks with validation.  This
+ * could be used to improve performance for those things commands that
+ * do not do any drawing !!!
+ */
+
+/* Lock the hardware and validate our state.
+ */
+#define LOCK_HARDWARE( vmesa ) \
+   do {        \
+      char __ret = 0; \
+      DEBUG_CHECK_LOCK(); \
+      DRM_CAS( vmesa->driHwLock, vmesa->hHWContext, \
+              (DRM_LOCK_HELD | vmesa->hHWContext), __ret ); \
+      if ( __ret ) \
+         s3vGetLock( vmesa, 0 ); \
+      DEBUG_LOCK(); \
+   } while (0)
+
+/* Unlock the hardware.
+ */
+#define UNLOCK_HARDWARE( vmesa ) \
+   do { \
+      DRM_UNLOCK( vmesa->driFd, \
+                 vmesa->driHwLock, \
+                 vmesa->hHWContext ); \
+      DEBUG_RESET(); \
+   } while (0)
+
+#endif
+
+#define S3VHW_LOCK( vmesa )    \
+   DRM_UNLOCK(vmesa->driFd, vmesa->driHwLock, vmesa->hHWContext); \
+   DRM_SPINLOCK(&vmesa->driScreen->pSAREA->drawable_lock, \
+                vmesa->driScreen->drawLockID); \
+   /* VALIDATE_DRAWABLE_INFO_NO_LOCK(vmesa); */
+
+#define S3VHW_UNLOCK( vmesa ) \
+    DRM_SPINUNLOCK(&vmesa->driScreen->pSAREA->drawable_lock, \
+                  vmesa->driScreen->drawLockID); \
+    /* VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(vmesa); */
+
+#define S3V_SIMPLE_LOCK( vmesa ) \
+       ioctl(vmesa->driFd, 0x4a) 
+
+#define S3V_SIMPLE_FLUSH_LOCK( vmesa ) \
+       ioctl(vmesa->driFd, 0x4b) 
+
+#define S3V_SIMPLE_UNLOCK( vmesa ) \
+       ioctl(vmesa->driFd, 0x4c) 
+
+#endif /* __S3V_LOCK_H__ */
diff --git a/src/mesa/drivers/dri/s3v/s3v_macros.h b/src/mesa/drivers/dri/s3v/s3v_macros.h
new file mode 100644 (file)
index 0000000..b54d506
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#ifndef _S3V_MACROS_H_
+#define _S3V_MACROS_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+/**************/
+/* DRI macros */
+/**************/
+
+#define GENERIC_DEBUG 0
+#define FLOW_DEBUG    0
+#define DMABUFS_DEBUG 0
+
+/* Note: The argument to DEBUG*() _must_ be enclosed in parenthesis */
+
+#if (GENERIC_DEBUG || FLOW_DEBUG || DMABUFS_DEBUG)
+       #include <stdio.h>
+#endif
+
+#if GENERIC_DEBUG
+       #define DEBUG(str) printf str
+#else
+       #define DEBUG(str)
+#endif
+
+#if FLOW_DEBUG
+       #define DEBUG_WHERE(str) printf str
+#else
+       #define DEBUG_WHERE(str)
+#endif
+
+#if DMABUFS_DEBUG
+       #define DEBUG_BUFS(str) printf str
+#else
+       #define DEBUG_BUFS(str)
+#endif
+
+
+#if 0
+#define S3V_DMA_SEND_FLAGS    DRM_DMA_PRIORITY
+#define S3V_DMA_SEND_FLAGS    DRM_DMA_BLOCK
+#else
+#define S3V_DMA_SEND_FLAGS    0
+#endif
+
+#if 0
+#define S3V_DMA_GET_FLAGS     \
+    (DRM_DMA_SMALLER_OK | DRM_DMA_LARGER_OK | DRM_DMA_WAIT)
+#else
+#define S3V_DMA_GET_FLAGS     DRM_DMA_WAIT
+#endif
+
+
+#define DMAOUT_CHECK(reg,len) \
+do { \
+       DEBUG(("DMAOUT_CHECK: reg = 0x%x\n", S3V_##reg##_REG)); \
+       DEBUG_BUFS(("DMAOUT_CHECK (was): ")); \
+       DEBUG_BUFS(("vmesa->bufCount=%i of vmesa->bufSize=%i\n", \
+               vmesa->bufCount, vmesa->bufSize)); \
+       /* FIXME: > or >= */ \
+       if (vmesa->bufCount+(len+1) >= vmesa->bufSize) \
+               DMAFLUSH(); \
+\
+       vmesa->bufCount += (len+1); \
+       DEBUG_BUFS(("DMAOUT_CHECK (is): vmesa->bufCount=%i len=%i, reg=%x\n", \
+               vmesa->bufCount, len, S3V_##reg##_REG)); \
+       DMAOUT( ((len & 0xffff) | ((S3V_##reg##_REG & 0xfffc) << 14)) );  \
+} while (0)
+
+#define DMAOUT(val) \
+do { \
+       *(vmesa->buf++)=val; \
+       DEBUG_BUFS(("DMAOUT: val=0x%x\n", (unsigned int)val)); \
+} while(0)
+
+#define DMAFINISH()    \
+do { \
+       /* NOTE: it does nothing - it just prints some summary infos */ \
+       DEBUG(("DMAFINISH: vmesa->bufCount=%i\n", vmesa->bufCount)); \
+       DEBUG(("buf: index=%i; addr=%p\n", vmesa->bufIndex[vmesa->_bufNum], \
+       vmesa->s3vScreen->bufs->list[vmesa->bufIndex[vmesa->_bufNum]].address)); \
+} while(0)
+
+#define DMAFLUSH() \
+do { \
+       if (vmesa->bufCount) { \
+               SEND_DMA(vmesa->driFd, vmesa->hHWContext, 1, \
+                       &vmesa->bufIndex[vmesa->_bufNum], &vmesa->bufCount); \
+/*
+               GET_DMA(vmesa->driFd, vmesa->hHWContext, 1, \
+                       &vmesa->bufIndex, &vmesa->bufSize); \
+*/ \
+               vmesa->_bufNum = !(vmesa->_bufNum); \
+               vmesa->buf = vmesa->_buf[vmesa->_bufNum]; \
+/* 
+               vmesa->buf = \
+                       vmesa->s3vScreen->bufs->list[vmesa->bufIndex].address; \
+*/ \
+               vmesa->bufCount = 0; \
+       } \
+} while (0)
+
+#define CMDCHANGE() \
+do { \
+       DMAOUT_CHECK(3DTRI_CMDSET, 1); /* FIXME: TRI/LINE */ \
+               DMAOUT(vmesa->CMD); \
+       DMAFINISH(); \
+} while (0)
+
+#ifdef DONT_SEND_DMA
+#define GET_DMA(fd, hHWCtx, n, idx, size)
+#define SEND_DMA(fd, hHWCtx,n, idx, cnt)
+#else
+#define GET_DMA(fd, hHWCtx, n, idx, size) \
+do { \
+       drmDMAReq dma; \
+       int retcode, i; \
+\
+       DEBUG(("GET_DMA: ")); \
+       DEBUG(("req_count=%i; req_list[#0]=%i; req_size[#0]=%i\n", \
+               n, (idx)[n-1], (size)[n-1])); \
+\
+       dma.context       = (hHWCtx); \
+       dma.send_count    = 0; \
+       dma.send_list     = NULL; \
+       dma.send_sizes    = NULL; \
+       dma.flags         = S3V_DMA_GET_FLAGS; \
+       dma.request_count = (n); \
+       dma.request_size  = S3V_DMA_BUF_SZ; \
+       dma.request_list  = (idx); \
+       dma.request_sizes = (size); \
+\
+       do { \
+               if ((retcode = drmDMA((fd), &dma))) { \
+               DEBUG_BUFS(("drmDMA (get) returned %d\n", retcode)); \
+       } \
+} while (!(dma).granted_count); \
+\
+       for (i = 0; i < (n); i++) { \
+               DEBUG(("Got buffer %i (index #%i)\n", (idx)[i], i)); \
+               DEBUG(("of %i bytes (%i words) size\n", \
+                       (size)[i], (size)[i] >>2)); \
+               /* Convert from bytes to words */ \
+               (size)[i] >>= 2; \
+       } \
+} while (0)
+
+#define SEND_DMA(fd, hHWCtx, n, idx, cnt) \
+do { \
+       drmDMAReq dma; \
+       int retcode, i; \
+\
+       DEBUG(("SEND_DMA: ")); \
+       DEBUG(("send_count=%i; send_list[#0]=%i; send_sizes[#0]=%i\n", \
+               n, (idx)[n-1], (cnt)[n-1])); \
+\
+       for (i = 0; i < (n); i++) { \
+               /* Convert from words to bytes */ \
+               (cnt)[i] <<= 2; \
+       } \
+\
+       dma.context       = (hHWCtx); \
+       dma.send_count    = (n); \
+       dma.send_list     = (idx); \
+       dma.send_sizes    = (cnt); \
+       dma.flags         = S3V_DMA_SEND_FLAGS; \
+       dma.request_count = 0; \
+       dma.request_size  = 0; \
+       dma.request_list  = NULL; \
+       dma.request_sizes = NULL; \
+\
+       if ((retcode = drmDMA((fd), &dma))) { \
+               DEBUG_BUFS(("drmDMA (send) returned %d\n", retcode)); \
+       } \
+\
+       for (i = 0; i < (n); i++) { \
+               DEBUG(("Sent buffer %i (index #%i)\n", (idx)[i], i)); \
+               DEBUG(("of %i bytes (%i words) size\n", \
+                       (cnt)[i], (cnt)[i] >>2)); \
+               (cnt)[i] = 0; \
+       } \
+} while (0)
+#endif /* DONT_SEND_DMA */
+
+#define GET_FIRST_DMA(fd, hHWCtx, n, idx, size, buf, cnt, vPriv) \
+do { \
+       int i; \
+       DEBUG_BUFS(("GET_FIRST_DMA\n")); \
+       DEBUG_BUFS(("n=%i idx=%i size=%i\n", n, *idx, *size)); \
+       DEBUG_BUFS(("going to GET_DMA\n")); \
+       GET_DMA(fd, hHWCtx, n, idx, size); \
+       DEBUG_BUFS(("coming from GET_DMA\n")); \
+       DEBUG_BUFS(("n=%i idx=%i size=%i\n", n, (idx)[0], (size)[0])); \
+       for (i = 0; i < (n); i++) { \
+               DEBUG_BUFS(("buf #%i @%p\n", \
+                       i, (vPriv)->bufs->list[(idx)[i]].address)); \
+               (buf)[i] = (vPriv)->bufs->list[(idx)[i]].address; \
+               (cnt)[i] = 0; \
+       } \
+       DEBUG(("GOING HOME\n")); \
+} while (0)
+
+#endif
+
+/**************************/
+/* generic, global macros */
+/**************************/
+
+#define CALC_LOG2(l2,s) \
+do { \
+       int __s = s; \
+       l2 = 0; \
+       while (__s > 1) { ++l2; __s >>= 1; } \
+} while (0)
+
+#define PrimType_Null               0x00000000
+#define PrimType_Points             0x10000000
+#define PrimType_Lines              0x20000000
+#define PrimType_LineLoop           0x30000000
+#define PrimType_LineStrip          0x40000000
+#define PrimType_Triangles          0x50000000
+#define PrimType_TriangleStrip      0x60000000
+#define PrimType_TriangleFan        0x70000000
+#define PrimType_Quads              0x80000000
+#define PrimType_QuadStrip          0x90000000
+#define PrimType_Polygon            0xa0000000
+#define PrimType_Mask               0xf0000000
+
+#endif /* _S3V_MACROS_H_ */
diff --git a/src/mesa/drivers/dri/s3v/s3v_regs.h b/src/mesa/drivers/dri/s3v/s3v_regs.h
new file mode 100644 (file)
index 0000000..26a7c54
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#ifndef _S3V_REG_H
+#define _S3V_REG_H
+
+#define S3V_REGS_NUM 256
+
+/************
+ * DMA REGS *
+ ************/
+
+#define S3V_DMA_ID                             0
+#define S3V_DMA_REG                            0x8590
+#define S3V_DMA_WRITEP_ID                      1
+#define S3V_DMA_WRITEP_REG                     0x8594
+#define S3V_DMA_READP_ID                       2
+#define S3V_DMA_READP_REG                      0x8598
+#define S3V_DMA_ENABLE_ID                      3
+#define S3V_DMA_ENABLE_REG                     0x859C
+#define S3V_DMA_UPDATE_ID                      4
+#define S3V_DMA_UPDATE_REG                     0x10000
+
+/***************
+ * STATUS REGS *
+ ***************/
+
+#define S3V_STAT_ID                            10
+#define S3V_STAT_REG                           0x8504
+#define S3V_STAT_VSYNC_ID                      11
+#define S3V_STAT_VSYNC_REG                     0x8505
+#define S3V_STAT_3D_DONE_ID                    12
+#define S3V_STAT_3D_DONE_REG                   0x8506
+#define S3V_STAT_FIFO_OVER_ID                  13
+#define S3V_STAT_FIFO_OVER_REG                 0x8508
+#define S3V_STAT_FIFO_EMPTY_ID                 14
+#define S3V_STAT_FIFO_EMPTY_REG                        0x850C
+#define S3V_STAT_HDMA_DONE_ID                  15
+#define S3V_STAT_HDMA_DONE_REG                 0x8514
+#define S3V_STAT_CDMA_DONE_ID                  16
+#define S3V_STAT_CDMA_DONE_REG                 0x8524
+#define S3V_STAT_3D_FIFO_EMPTY_ID              17
+#define S3V_STAT_3D_FIFO_EMPTY_REG             0x8544
+#define S3V_STAT_LPB_ID                                18
+#define S3V_STAT_LPB_REG                       0x8584
+#define S3V_STAT_3D_BUSY_ID                    19
+#define S3V_STAT_3D_BUSY_REG                   0x8704
+
+/***********
+ * 2D REGS *
+ ***********/
+
+#define S3V_BITBLT_ID                          30
+#define S3V_BITBLT_REG                         0xA400
+#define S3V_BITBLT_SRC_BASE_ID                 31
+#define S3V_BITBLT_SRC_BASE_REG                        0xA4D4
+#define S3V_BITBLT_DEST_BASE_ID                        32
+#define S3V_BITBLT_DEST_BASE_REG               0xA4D8
+#define S3V_BITBLT_CLIP_L_R_ID                 33
+#define S3V_BITBLT_CLIP_L_R_REG                        0xA4DC
+#define S3V_BITBLT_CLIP_T_B_ID                 34
+#define S3V_BITBLT_CLIP_T_B_REG                        0xA4E0
+#define S3V_BITBLT_DEST_SRC_STRIDE_ID          35
+#define S3V_BITBLT_DEST_SRC_STRIDE_REG         0xA4E4
+#define S3V_BITBLT_MONO_PAT0_ID                        36
+#define S3V_BITBLT_MONO_PAT0_REG               0xA4E8
+#define S3V_BITBLT_MONO_PAT1_ID                        37
+#define S3V_BITBLT_MONO_PAT1_REG               0xA4EC
+#define S3V_BITBLT_PAT_BG_COLOR_ID             38
+#define S3V_BITBLT_PAT_BG_COLOR_REG            0xA4F0
+#define S3V_BITBLT_PAT_FG_COLOR_ID             39
+#define S3V_BITBLT_PAT_FG_COLOR_REG            0xA4F4
+#define S3V_BITBLT_CMDSET_ID                   40
+#define S3V_BITBLT_CMDSET_REG                  0xA500
+#define S3V_BITBLT_WIDTH_HEIGHT_ID             41
+#define S3V_BITBLT_WIDTH_HEIGHT_REG            0xA504
+#define S3V_BITBLT_SRC_X_Y_ID                  42
+#define S3V_BITBLT_SRC_X_Y_REG                 0xA508
+#define S3V_BITBLT_DEST_X_Y_ID                 43
+#define S3V_BITBLT_DEST_X_Y_REG                        0xA50C
+#define S3V_2DLINE_ID                          44
+#define S3V_2DLINE_REG                         0xA800
+#define S3V_2DPOLY_ID                          45
+#define S3V_2DPOLY_REG                         0xAC00
+
+/***************
+ * 3DLINE REGS *
+ ***************/
+/* base regs */
+#define S3V_3DLINE_ID                                  50
+#define S3V_3DLINE_REG                         0xB000
+#define S3V_3DLINE_Z_BASE_ID                           51
+#define S3V_3DLINE_Z_BASE_REG                  0xB0D4
+#define S3V_3DLINE_SRC_BASE_ID                         52   /* it is the same reg */
+#define S3V_3DLINE_SRC_BASE_REG                        0xB0D4
+#define S3V_3DLINE_DEST_BASE_ID                        53
+#define S3V_3DLINE_DEST_BASE_REG               0xB0D8
+#define S3V_3DLINE_CLIP_L_R_ID                         54
+#define S3V_3DLINE_CLIP_L_R_REG                        0xB0DC
+#define S3V_3DLINE_CLIP_T_B_ID                 55
+#define S3V_3DLINE_CLIP_T_B_REG                0xB0E0
+#define S3V_3DLINE_DEST_SRC_STRIDE_ID          56
+#define S3V_3DLINE_DEST_SRC_STRIDE_REG         0xB0E4
+#define S3V_3DLINE_Z_STRIDE_ID                 57
+#define S3V_3DLINE_Z_STRIDE_REG                0xB0E8
+#define S3V_3DLINE_TEX_BASE_ID                 58
+#define S3V_3DLINE_TEX_BASE_REG                0xB0EC
+#define S3V_3DLINE_TEX_B_COLOR_ID              59
+#define S3V_3DLINE_TEX_B_COLOR_REG             0xB0F0
+#define S3V_3DLINE_FOG_COLOR_ID                60
+#define S3V_3DLINE_FOG_COLOR_REG               0xB0F4
+#define S3V_3DLINE_COLOR0_ID                           61
+#define S3V_3DLINE_COLOR0_REG                  0xB0F8
+#define S3V_3DLINE_COLOR1_ID                   62
+#define S3V_3DLINE_COLOR1_REG                  0xB0FC
+#define S3V_3DLINE_CMDSET_ID                   63
+#define S3V_3DLINE_CMDSET_REG                  0xB100 /* special */
+/* tex regs */
+/* FIXME: shouldn't it be a 1D tex for lines? */
+#define S3V_3DLINE_BASEV_ID                    64
+#define S3V_3DLINE_BASEV_REG                   0xB104 
+#define S3V_3DLINE_BASEU_ID                    65
+#define S3V_3DLINE_BASEU_REG                   0xB108
+#define S3V_3DLINE_WXD_ID                      66
+#define S3V_3DLINE_WXD_REG                             0xB10C
+#define S3V_3DLINE_WYD_ID                      67
+#define S3V_3DLINE_WYD_REG                     0xB110
+#define S3V_3DLINE_WSTART_ID                   68
+#define S3V_3DLINE_WSTART_REG                          0xB114
+#define S3V_3DLINE_DXD_ID                      69
+#define S3V_3DLINE_DXD_REG                     0xB118
+#define S3V_3DLINE_VXD_ID                      70
+#define S3V_3DLINE_VXD_REG                     0xB11C
+#define S3V_3DLINE_UXD_ID                      71
+#define S3V_3DLINE_UXD_REG                     0xB120
+#define S3V_3DLINE_DYD_ID                      72
+#define S3V_3DLINE_DYD_REG                     0xB124
+#define S3V_3DLINE_VYD_ID                      73
+#define S3V_3DLINE_VYD_REG                     0xB128
+#define S3V_3DLINE_UYD_ID                      74
+#define S3V_3DLINE_UYD_REG                     0xB12C
+#define S3V_3DLINE_DSTART_ID                   75
+#define S3V_3DLINE_DSTART_REG                  0xB130
+#define S3V_3DLINE_VSTART_ID                   76
+#define S3V_3DLINE_VSTART_REG                  0xB134
+#define S3V_3DLINE_USTART_ID                   77
+#define S3V_3DLINE_USTART_REG                  0xB138
+/* gourad regs */
+#define S3V_3DLINE_GBD_ID                      78
+#define S3V_3DLINE_GBD_REG                     0xB144
+#define S3V_3DLINE_ARD_ID                      79
+#define S3V_3DLINE_ARD_REG                             0xB148
+#define S3V_3DLINE_GS_BS_ID                    80
+#define S3V_3DLINE_GS_BS_REG                   0xB14C
+#define S3V_3DLINE_AS_RS_ID                    81
+#define S3V_3DLINE_AS_RS_REG                   0xB150
+/* vertex regs */
+#define S3V_3DLINE_DZ_ID                       82
+#define S3V_3DLINE_DZ_REG                      0xB158
+#define S3V_3DLINE_ZSTART_ID                   83
+#define S3V_3DLINE_ZSTART_REG                  0xB15C
+#define S3V_3DLINE_XEND0_END1_ID               84
+#define S3V_3DLINE_XEND0_END1_REG              0xB16C
+#define S3V_3DLINE_DX_ID                       85
+#define S3V_3DLINE_DX_REG                      0xB170
+#define S3V_3DLINE_XSTART_ID                   86
+#define S3V_3DLINE_XSTART_REG                  0xB174
+#define S3V_3DLINE_YSTART_ID                   87
+#define S3V_3DLINE_YSTART_REG                          0xB178
+#define S3V_3DLINE_YCNT_ID                     88
+#define S3V_3DLINE_YCNT_REG                    0xB17C
+
+/**************
+ * 3DTRI REGS *
+ **************/
+/* base regs */
+#define S3V_3DTRI_ID                                   100
+#define S3V_3DTRI_REG                          0xB400
+#define S3V_3DTRI_Z_BASE_ID                    101
+#define S3V_3DTRI_Z_BASE_REG                   0xB4D4
+#define S3V_3DTRI_SRC_BASE_ID                          102 /* it is the same reg */
+#define S3V_3DTRI_SRC_BASE_REG                 0xB4D4
+#define S3V_3DTRI_DEST_BASE_ID                         103
+#define S3V_3DTRI_DEST_BASE_REG                        0xB4D8
+#define S3V_3DTRI_CLIP_L_R_ID                          104
+#define S3V_3DTRI_CLIP_L_R_REG                         0xB4DC
+#define S3V_3DTRI_CLIP_T_B_ID                          105
+#define S3V_3DTRI_CLIP_T_B_REG                 0xB4E0
+#define S3V_3DTRI_DEST_SRC_STRIDE_ID                   106
+#define S3V_3DTRI_DEST_SRC_STRIDE_REG          0xB4E4
+#define S3V_3DTRI_Z_STRIDE_ID                          107
+#define S3V_3DTRI_Z_STRIDE_REG                 0xB4E8
+#define S3V_3DTRI_TEX_BASE_ID                          108
+#define S3V_3DTRI_TEX_BASE_REG                 0xB4EC
+#define S3V_3DTRI_TEX_B_COLOR_ID                       109
+#define S3V_3DTRI_TEX_B_COLOR_REG              0xB4F0
+#define S3V_3DTRI_FOG_COLOR_ID                         110
+#define S3V_3DTRI_FOG_COLOR_REG                        0xB4F4
+#define S3V_3DTRI_COLOR0_ID                            111
+#define S3V_3DTRI_COLOR0_REG                   0xB4F8
+#define S3V_3DTRI_COLOR1_ID                            112
+#define S3V_3DTRI_COLOR1_REG                   0xB4FC
+#define S3V_3DTRI_CMDSET_ID                            113  /* special */
+#define S3V_3DTRI_CMDSET_REG                   0xB500
+/* tex regs */
+#define S3V_3DTRI_BASEV_ID                             114
+#define S3V_3DTRI_BASEV_REG                    0xB504
+#define S3V_3DTRI_BASEU_ID                             115
+#define S3V_3DTRI_BASEU_REG                    0xB508
+#define S3V_3DTRI_WXD_ID                               116
+#define S3V_3DTRI_WXD_REG                      0xB50C
+#define S3V_3DTRI_WYD_ID                               117
+#define S3V_3DTRI_WYD_REG                      0xB510
+#define S3V_3DTRI_WSTART_ID                            118
+#define S3V_3DTRI_WSTART_REG                   0xB514
+#define S3V_3DTRI_DXD_ID                               119
+#define S3V_3DTRI_DXD_REG                      0xB518
+#define S3V_3DTRI_VXD_ID                               120
+#define S3V_3DTRI_VXD_REG                      0xB51C
+#define S3V_3DTRI_UXD_ID                       121
+#define S3V_3DTRI_UXD_REG                      0xB520
+#define S3V_3DTRI_DYD_ID                       122
+#define S3V_3DTRI_DYD_REG                      0xB524
+#define S3V_3DTRI_VYD_ID                       123
+#define S3V_3DTRI_VYD_REG                      0xB528
+#define S3V_3DTRI_UYD_ID                       124
+#define S3V_3DTRI_UYD_REG                      0xB52C
+#define S3V_3DTRI_DSTART_ID                    125
+#define S3V_3DTRI_DSTART_REG                   0xB530
+#define S3V_3DTRI_VSTART_ID                    126
+#define S3V_3DTRI_VSTART_REG                   0xB534
+#define S3V_3DTRI_USTART_ID                    127
+#define S3V_3DTRI_USTART_REG                   0xB538
+/* gourad regs */
+#define S3V_3DTRI_GBX_ID                               128
+#define S3V_3DTRI_GBX_REG                      0xB53C
+#define S3V_3DTRI_ARX_ID                               129
+#define S3V_3DTRI_ARX_REG                      0xB540
+#define S3V_3DTRI_GBY_ID                       130
+#define S3V_3DTRI_GBY_REG                      0xB544
+#define S3V_3DTRI_ARY_ID                       131
+#define S3V_3DTRI_ARY_REG                      0xB548
+#define S3V_3DTRI_GS_BS_ID                     132
+#define S3V_3DTRI_GS_BS_REG                    0xB54C
+#define S3V_3DTRI_AS_RS_ID                     133
+#define S3V_3DTRI_AS_RS_REG                    0xB550
+/* vertex regs */
+#define S3V_3DTRI_ZXD_ID                               134
+#define S3V_3DTRI_ZXD_REG                      0xB554
+#define S3V_3DTRI_ZYD_ID                               135
+#define S3V_3DTRI_ZYD_REG                      0xB558
+#define S3V_3DTRI_ZSTART_ID                            136
+#define S3V_3DTRI_ZSTART_REG                   0xB55C
+#define S3V_3DTRI_TXDELTA12_ID                         137
+#define S3V_3DTRI_TXDELTA12_REG                        0xB560
+#define S3V_3DTRI_TXEND12_ID                           138
+#define S3V_3DTRI_TXEND12_REG                  0xB564
+#define S3V_3DTRI_TXDELTA01_ID                         139
+#define S3V_3DTRI_TXDELTA01_REG                        0xB568
+#define S3V_3DTRI_TXEND01_ID                           140
+#define S3V_3DTRI_TXEND01_REG                  0xB56C
+#define S3V_3DTRI_TXDELTA02_ID                         141
+#define S3V_3DTRI_TXDELTA02_REG                        0xB570
+#define S3V_3DTRI_TXSTART02_ID                         142
+#define S3V_3DTRI_TXSTART02_REG                        0xB574
+#define S3V_3DTRI_TYS_ID                               143
+#define S3V_3DTRI_TYS_REG                      0xB578
+#define S3V_3DTRI_TY01_Y12_ID                          144
+#define S3V_3DTRI_TY01_Y12_REG                 0xB57C
+
+/* COMMANDS (to 0xB100 [lines] or 0xB500 [tris]) */
+
+/* Auto execute */
+#define AUTO_EXEC_MASK         0x00000001
+#define AUTO_EXEC_OFF          (0x0)
+#define AUTO_EXEC_ON           (0x1)
+/* HW clipping */
+#define HW_CLIP_MASK           0x00000002
+#define HW_CLIP_OFF            (0x0 << 1)
+#define HW_CLIP_ON             (0x1 << 1)
+/* Destination color */
+#define DEST_COL_MASK          0x0000001c
+#define DEST_COL_PAL           (0x0 << 2)      /* 8 bpp - palettized */
+#define DEST_COL_1555          (0x1 << 2)      /* 16 bpp - ZRGB */
+#define DEST_COL_888           (0x2 << 2)      /* 24 bpp - RGB */
+/* Texture color */
+#define TEX_COL_MASK           0x000000e0
+#define TEX_COL_ARGB8888       (0x0 << 5)      /* 32 bpp - ARGB */
+#define TEX_COL_ARGB4444       (0x1 << 5)      /* 16 bpp - ARGB */
+#define TEX_COL_ARGB1555       (0x2 << 5)      /* 16 bpp - ARGB */
+#define TEX_COL_ALPHA4         (0x3 << 5)      /* 8 bpp - ALPHA4 */
+#define TEX_COL_BLEND4_LOW     (0x4 << 5)      /* 4 bpp - BLEND4 low nibble */
+#define TEX_COL_BLEND4_HIGH    (0x5 << 5)      /* 4 bpp - BLEND4 high nibble */
+#define TEX_COL_PAL            (0x6 << 5)      /* 8 bpp - palettized */
+#define TEX_COL_YUV            (0x7 << 5)      /* 16 bpp - YUV */
+/* Mipmap level */
+#define MIP_MASK               0x00000f00
+#define MIPMAP_LEVEL(s)                (s << 8)        /* 8 -> 11 bits */
+/* Texture filtering */
+#define TEX_FILTER_MASK                0x00007000
+#define MIP_NEAREST            (0x0 << 12)
+#define LINEAR_MIP_NEAREST     (0x1 << 12)
+#define MIP_LINEAR             (0x2 << 12)
+#define LINEAR_MIP_LINEAR      (0x3 << 12)
+#define NEAREST                        (0x4 << 12)
+#define FAST_BILINEAR          (0x5 << 12)
+#define LINEAR                 (0x6 << 12)
+/* Texture blending */
+#define TEX_BLEND_MAKS         0x00018000
+#define TEX_REFLECT            (0x0 << 15)
+#define TEX_MODULATE           (0x1 << 15)
+#define TEX_DECAL              (0x2 << 15)
+/* Fog */
+#define FOG_MASK               0x00020000
+#define FOG_OFF                        (0x0 << 17)
+#define FOG_ON                 (0x1 << 17)
+/* Alpha blending */
+#define ALPHA_BLEND_MASK       0x000c0000
+#define ALPHA_OFF              (0x0 << 18) | (0x0 << 19)
+#define ALPHA_TEX              (0x2 << 18)
+#define ALPHA_SRC              (0x3 << 18)
+/* Depth compare mode */
+#define Z_MODE_MASK            0x00700000
+#define Z_NEVER                (0x0 << 20)
+#define Z_GREATER              (0x1 << 20)
+#define Z_EQUAL                (0x2 << 20)
+#define Z_GEQUAL               (0x3 << 20)
+#define Z_LESS                 (0x4 << 20)
+#define Z_NOTEQUAL             (0x5 << 20)
+#define Z_LEQUAL               (0x6 << 20) 
+#define Z_ALWAYS               (0x7 << 20)
+/* Depth update */
+#define Z_UPDATE_MASK          0x00800000
+#define Z_UPDATE_OFF           (0x0 << 23)     /* disable z update */
+#define Z_UPDATE_ON            (0x1 << 23)
+/* Depth buffering mode */
+#define Z_BUFFER_MASK          0x03000000
+#define Z_BUFFER               (0x0 << 24) | (0x0 << 25)
+#define Z_MUX_BUF              (0x1 << 24) | (0x0 << 25)
+#define Z_MUX_DRAW             (0x2 << 24)
+#define Z_OFF                  (0x3 << 24) /* no z buffering */
+/* Texture wrapping */
+#define TEX_WRAP_MASK          0x04000000
+#define TEX_WRAP_OFF           (0x0 << 26)
+#define TEX_WRAP_ON            (0x1 << 26)
+/* 3d command */
+#define DO_MASK                        0x78000000
+#define DO_GOURAUD_TRI         (0x0 << 27)
+#define DO_TEX_LIT_TRI_OLD     (0x1 << 27) 
+#define DO_TEX_UNLIT_TRI_OLD   (0x2 << 27)
+#define DO_TEX_LIT_TRI         (0x5 << 27)
+#define DO_TEX_UNLIT_TRI       (0x6 << 27)
+#define DO_3D_LINE             (0x8 << 27)
+#define        DO_NOP                  (0xf << 27) /* turn on autoexec */
+/* status */
+#define CMD_MASK               0x80000000
+#define CMD_2D                 (0x0 << 31) /* execute a 2d cmd */
+#define CMD_3D                 (0x1 << 31) /* execute a 3d cmd */
+
+/* global masks */
+#define TEX_MASK               ( TEX_COL_MASK | TEX_WRAP_MASK | MIP_MASK \
+                               | TEX_FILTER_MASK | TEX_BLEND_MAKS \
+                               | TEX_WRAP_MASK )
+#define Z_MASK                 ( Z_MODE_MASK | Z_UPDATE_MASK | Z_BUFFER_MASK )
+
+#endif /* _S3V_REG_H */
diff --git a/src/mesa/drivers/dri/s3v/s3v_render.c b/src/mesa/drivers/dri/s3v/s3v_render.c
new file mode 100644 (file)
index 0000000..3da9f76
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "mem.h"
+#include "mtypes.h"
+#include "mmath.h"
+
+#include "tnl/t_context.h"
+
+#include "s3v_context.h"
+#include "s3v_tris.h"
+#include "s3v_vb.h"
+
+
+#define HAVE_POINTS      0
+#define HAVE_LINES       0
+#define HAVE_LINE_STRIPS 0
+#define HAVE_TRIANGLES   0
+#define HAVE_TRI_STRIPS  0
+#define HAVE_TRI_STRIP_1 0
+#define HAVE_TRI_FANS    0
+#define HAVE_QUADS       0
+#define HAVE_QUAD_STRIPS 0
+#define HAVE_POLYGONS    0
+
+#define HAVE_ELTS        0
+
+static void VERT_FALLBACK( GLcontext *ctx,
+                          GLuint start,
+                          GLuint count,
+                          GLuint flags )
+{
+       TNLcontext *tnl = TNL_CONTEXT(ctx);
+/*     s3vContextPtr vmesa = S3V_CONTEXT(ctx); */
+       int _flags;
+   
+       DEBUG(("VERT_FALLBACK: flags & PRIM_MODE_MASK = %i\n",
+               flags & PRIM_MODE_MASK));
+       DEBUG(("VERT_FALLBACK: flags=%i PRIM_MODE_MASK=%i\n",
+               flags, PRIM_MODE_MASK));
+#if 0
+       tnl->Driver.Render.PrimitiveNotify( ctx, flags & PRIM_MODE_MASK );
+#endif
+       tnl->Driver.Render.BuildVertices( ctx, start, count, ~0 );
+
+       _flags = flags & PRIM_MODE_MASK;
+
+       tnl->Driver.Render.PrimTabVerts[_flags]( ctx, start, count, flags );
+       S3V_CONTEXT(ctx)->SetupNewInputs = VERT_CLIP;
+}
+
+static const GLuint hw_prim[GL_POLYGON+1] = {
+       PrimType_Points,
+       PrimType_Lines,
+       PrimType_LineLoop,
+       PrimType_LineStrip,
+       PrimType_Triangles,
+       PrimType_TriangleStrip,
+       PrimType_TriangleFan,
+       PrimType_Quads,
+       PrimType_QuadStrip,
+       PrimType_Polygon
+};
+
+static __inline void s3vStartPrimitive( s3vContextPtr vmesa, GLenum prim )
+{
+       __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+
+       int _hw_prim = hw_prim[prim];
+
+       DEBUG(("s3vStartPrimitive (new #%i) ", prim));
+
+       if (_hw_prim != vmesa->restore_primitive) {
+
+               if (prim == 4) { /* TRI */
+                       DEBUG(("switching to tri\n"));
+                       vmesa->prim_cmd = vmesa->_tri[vmesa->_3d_mode];
+                       vmesa->alpha_cmd = vmesa->_alpha[vmesa->_3d_mode];
+                       DMAOUT_CHECK(3DTRI_Z_BASE, 12);
+               } else if (prim == 1) { /* LINE */
+                       DEBUG(("switching to line\n"));
+                       vmesa->prim_cmd = DO_3D_LINE;
+                       vmesa->alpha_cmd = vmesa->_alpha[0];
+                       DMAOUT_CHECK(3DLINE_Z_BASE, 12);
+               } else {
+                       DEBUG(("Never mind the bollocks!\n"));
+               }
+
+               DMAOUT(vmesa->s3vScreen->depthOffset & 0x003FFFF8);
+               DMAOUT(vmesa->DestBase);
+               /* DMAOUT(vmesa->ScissorLR); */
+               /* DMAOUT(vmesa->ScissorTB); */
+               DMAOUT( (0 << 16) | (dPriv->w-1) );
+               DMAOUT( (0 << 16) | (dPriv->h-1) );
+               DMAOUT( (vmesa->SrcStride << 16) | vmesa->TexStride );
+               DMAOUT(vmesa->SrcStride);
+               DMAOUT(vmesa->TexOffset);
+               DMAOUT(vmesa->TextureBorderColor);
+               DMAOUT(0); /* FOG */
+               DMAOUT(0);
+               DMAOUT(0);
+               DMAOUT(vmesa->CMD | vmesa->prim_cmd | vmesa->alpha_cmd);
+               DMAFINISH();
+       }
+
+       vmesa->restore_primitive = _hw_prim;
+}
+
+static __inline void s3vEndPrimitive( s3vContextPtr vmesa )
+{
+/*     GLcontext *ctx = vmesa->glCtx; */
+       DEBUG(("s3vEndPrimitive\n"));
+}
+
+#define LOCAL_VARS s3vContextPtr vmesa = S3V_CONTEXT(ctx)
+#define INIT( prim ) s3vStartPrimitive( vmesa, prim )
+#define FINISH s3vEndPrimitive( vmesa )
+#define NEW_PRIMITIVE() (void) vmesa
+#define NEW_BUFFER() (void) vmesa
+#define FIRE_VERTICES() (void) vmesa
+#define GET_CURRENT_VB_MAX_VERTS() \
+       (vmesa->bufSize - vmesa->bufCount) / 2
+#define GET_SUBSEQUENT_VB_MAX_VERTS() \
+       S3V_DMA_BUF_SZ / 2
+#define EMIT_VERTS( ctx, j, nr ) \
+do { \
+       printf("Alas, emit...\n"); \
+       /* s3v_emit(ctx, j, (j)+(nr)) */ \
+       /* we don't need emit on s3v */ \
+} while (0)
+
+#define TAG(x) s3v_##x
+
+#include "tnl_dd/t_dd_dmatmp.h"
+
+/**********************************************************************/
+/*                          Render pipeline stage                     */
+/**********************************************************************/
+
+
+static GLboolean s3v_run_render( GLcontext *ctx,
+                                 struct gl_pipeline_stage *stage )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       TNLcontext *tnl = TNL_CONTEXT(ctx);
+       struct vertex_buffer *VB = &tnl->vb;
+       GLuint i, length, flags = 0;
+       render_func *tab;
+
+       DEBUG(("s3v_run_render\n"));
+       
+       /* FIXME: hw clip */
+       if (VB->ClipOrMask || vmesa->RenderIndex != 0) {
+               DEBUG(("*** CLIPPED in render ***\n"));
+#if 1
+               return GL_TRUE; /* don't handle clipping here */
+#endif
+       }
+
+
+       /* We don't do elts */
+       if (VB->Elts)
+               return GL_TRUE;
+
+       tab = TAG(render_tab_verts);
+
+       tnl->Driver.Render.Start( ctx );
+
+       for (i = 0 ; !(flags & PRIM_LAST) ; i += length)
+       {
+               flags = VB->Primitive[i];
+               length = VB->PrimitiveLength[i];
+
+               DEBUG(("s3v_run_render (loop=%i) (lenght=%i)\n", i, length));
+
+               if (length) {
+                       tnl->Driver.Render.BuildVertices( ctx, i, i+length,
+                       ~0 /*stage->inputs*/);
+                       tnl->Driver.Render.PrimTabVerts[flags & PRIM_MODE_MASK]
+                               ( ctx, i, i + length, flags );
+                       vmesa->SetupNewInputs = VERT_CLIP;
+               }
+       }
+       
+       tnl->Driver.Render.Finish( ctx );
+
+       return GL_FALSE; /* finished the pipe */
+}
+
+
+static void s3v_check_render( GLcontext *ctx,
+                                struct gl_pipeline_stage *stage )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       GLuint inputs = VERT_CLIP | VERT_RGBA;
+
+       DEBUG(("s3v_check_render\n"));
+
+       if (ctx->RenderMode == GL_RENDER) {
+       
+               if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
+                       DEBUG(("DD_SEPARATE_SPECULAR\n"));
+                       inputs |= VERT_SPEC_RGB;
+               }
+               
+               if (ctx->Texture.Unit[0]._ReallyEnabled) {
+                       DEBUG(("ctx->Texture.Unit[0]._ReallyEnabled\n"));
+                       inputs |= VERT_TEX(0);
+               }
+
+               if (ctx->Texture.Unit[1]._ReallyEnabled) {
+                       DEBUG(("ctx->Texture.Unit[1]._ReallyEnabled\n"));
+                       inputs |= VERT_TEX(1);
+               }
+
+               if (ctx->Fog.Enabled) {
+                       DEBUG(("ctx->Fog.Enabled\n"));
+                       inputs |= VERT_FOG_COORD;
+               }
+       }
+
+       stage->inputs = inputs;
+       vmesa->SetupNewInputs = inputs;
+}
+
+
+static void dtr( struct gl_pipeline_stage *stage )
+{
+       (void)stage;
+}
+
+
+const struct gl_pipeline_stage _s3v_render_stage =
+{
+       "s3v render",
+       (_DD_NEW_SEPARATE_SPECULAR |
+        _NEW_TEXTURE|
+        _NEW_FOG|
+        _NEW_RENDERMODE),      /* re-check (new inputs) */
+        0,                     /* re-run (always runs) */
+        GL_TRUE,               /* active */
+        0, 0,                  /* inputs (set in check_render), outputs */
+        0, 0,                  /* changed_inputs, private */
+        dtr,                   /* destructor */
+        s3v_check_render,      /* check - initially set to alloc data */
+        s3v_run_render         /* run */
+};
diff --git a/src/mesa/drivers/dri/s3v/s3v_screen.c b/src/mesa/drivers/dri/s3v/s3v_screen.c
new file mode 100644 (file)
index 0000000..e558d5b
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include "s3v_context.h"
+#include "s3v_vb.h"
+#include "s3v_dri.h" 
+
+#include "mem.h"
+
+s3vScreenPtr s3vCreateScreen( __DRIscreenPrivate *sPriv )
+{
+   s3vScreenPtr s3vScreen;
+   S3VDRIPtr vDRIPriv = (S3VDRIPtr)sPriv->pDevPriv;
+
+/*   int i; */
+
+   DEBUG(("s3vCreateScreen\n"));
+   DEBUG(("sPriv->pDevPriv at %p\n", sPriv->pDevPriv));
+   DEBUG(("size = %i\n", sizeof(*vDRIPriv)));
+
+   /* Allocate the private area */
+   s3vScreen = (s3vScreenPtr) CALLOC( sizeof(*s3vScreen) );
+   if ( !s3vScreen ) return NULL;
+
+   s3vScreen->regionCount  = 4;        /* Magic number.  Can we fix this? */
+    
+   s3vScreen->regions = Xmalloc(s3vScreen->regionCount * 
+                                                       sizeof(s3vRegion));
+   DEBUG(("sPriv->fd = %i\nvDRIPriv->dmaBufHandle = %x\n",
+      sPriv->fd, vDRIPriv->dmaBufHandle));
+
+   DEBUG(("vDRIPriv->dmaBufSize=%i\nvDRIPriv->dmaBuf=%p\n",
+      vDRIPriv->dmaBufSize, vDRIPriv->dmaBuf));
+
+
+   /* Get the list of dma buffers */
+   s3vScreen->bufs = drmMapBufs(sPriv->fd);
+
+   if (!s3vScreen->bufs) {
+      DEBUG(("Helter/skelter with drmMapBufs\n"));
+      return GL_FALSE; 
+   }
+
+   s3vScreen->textureSize                  = vDRIPriv->texSize;
+   s3vScreen->logTextureGranularity = vDRIPriv->logTextureGranularity;
+   s3vScreen->cpp                                      = vDRIPriv->cpp;
+   s3vScreen->frontOffset                      = vDRIPriv->frontOffset;
+   s3vScreen->frontPitch                       = vDRIPriv->frontPitch;
+   s3vScreen->backOffset                       = vDRIPriv->backOffset;
+   s3vScreen->backPitch                                = vDRIPriv->frontPitch; /* FIXME: check */
+   s3vScreen->depthOffset                      = vDRIPriv->depthOffset;
+   s3vScreen->depthPitch                       = vDRIPriv->frontPitch;
+   s3vScreen->texOffset                                = vDRIPriv->texOffset;
+
+   s3vScreen->driScreen = sPriv;
+
+   DEBUG(("vDRIPriv->width =%i; vDRIPriv->deviceID =%x\n", vDRIPriv->width,
+                 vDRIPriv->deviceID));
+   DEBUG(("vDRIPriv->mem =%i\n", vDRIPriv->mem));
+   DEBUG(("vDRIPriv->fbOffset =%i\n", vDRIPriv->fbOffset));
+   DEBUG((" ps3vDRI->fbStride =%i\n", vDRIPriv->fbStride));
+   DEBUG(("s3vScreen->cpp = %i\n", s3vScreen->cpp));
+   DEBUG(("s3vScreen->backOffset = %x\n", s3vScreen->backOffset));
+   DEBUG(("s3vScreen->depthOffset = %x\n", s3vScreen->depthOffset));
+   DEBUG(("s3vScreen->texOffset = %x\n", s3vScreen->texOffset));
+   DEBUG(("I will return from s3vCreateScreen now\n"));
+   
+   DEBUG(("s3vScreen->bufs = 0x%x\n", s3vScreen->bufs));
+   return s3vScreen;
+}
+
+/* Destroy the device specific screen private data struct.
+ */
+void s3vDestroyScreen( __DRIscreenPrivate *sPriv )
+{
+    s3vScreenPtr s3vScreen = (s3vScreenPtr)sPriv->private;
+
+    DEBUG(("s3vDestroyScreen\n"));
+
+    /* First, unmap the dma buffers */
+/*
+    drmUnmapBufs( s3vScreen->bufs );
+*/
+    /* Next, unmap all the regions */
+/*    while (s3vScreen->regionCount > 0) { 
+
+       (void)drmUnmap(s3vScreen->regions[s3vScreen->regionCount].map,
+                      s3vScreen->regions[s3vScreen->regionCount].size);
+       s3vScreen->regionCount--;
+
+    }
+    FREE(s3vScreen->regions); */
+       if (s3vScreen)
+           FREE(s3vScreen);
+}
diff --git a/src/mesa/drivers/dri/s3v/s3v_screen.h b/src/mesa/drivers/dri/s3v/s3v_screen.h
new file mode 100644 (file)
index 0000000..6bba29a
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+typedef struct _s3vRegion {
+    drmHandle  handle;
+    drmSize    size;
+    drmAddress map;
+} s3vRegion, *s3vRegionPtr;
+
+typedef struct {
+
+    int          regionCount;             /* Count of register regions */
+    s3vRegion           *regions;         /* Vector of mapped region info */
+
+    drmBufMapPtr bufs;             /* Map of DMA buffers */
+
+    __DRIscreenPrivate *driScreen; /* Back pointer to DRI screen */
+
+    int                cpp;
+    int                frontPitch;
+    int                frontOffset;
+
+    int                backPitch;
+    int                backOffset;
+    int                backX;
+    int                backY;
+
+    int                depthOffset;
+    int                depthPitch;
+
+    int                texOffset;
+    int                textureOffset;
+    int                textureSize;
+    int                logTextureGranularity;
+} s3vScreenRec, *s3vScreenPtr;
diff --git a/src/mesa/drivers/dri/s3v/s3v_span.c b/src/mesa/drivers/dri/s3v/s3v_span.c
new file mode 100644 (file)
index 0000000..d8210f6
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include "s3v_context.h"
+#include "s3v_lock.h"
+
+#include "swrast/swrast.h"
+
+#define _SPANLOCK 1
+#define DBG 0
+
+#define LOCAL_VARS \
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
+       s3vScreenPtr s3vscrn = vmesa->s3vScreen; \
+       __DRIscreenPrivate *sPriv = vmesa->driScreen; \
+       __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
+       GLuint pitch = ( (vmesa->Flags & S3V_BACK_BUFFER) ? \
+                       ((dPriv->w+31)&~31) * s3vscrn->cpp \
+                       : sPriv->fbWidth * s3vscrn->cpp); \
+       GLuint height = dPriv->h; \
+       char *buf = ( (vmesa->Flags & S3V_BACK_BUFFER) ? \
+                       (char *)(sPriv->pFB + vmesa->drawOffset) \
+                       : (char *)(sPriv->pFB + vmesa->drawOffset \
+                         + dPriv->x * s3vscrn->cpp + dPriv->y * pitch) ); \
+       char *read_buf = ( (vmesa->Flags & S3V_BACK_BUFFER) ? \
+                       (char *)(sPriv->pFB + vmesa->drawOffset) \
+                       : (char *)(sPriv->pFB + vmesa->drawOffset \
+                         + dPriv->x * s3vscrn->cpp + dPriv->y * pitch) ); \
+       GLuint p; \
+       (void) read_buf; (void) buf; (void) p; (void) pitch
+
+/* FIXME! Depth/Stencil read/writes don't work ! */
+#define LOCAL_DEPTH_VARS \
+       s3vScreenPtr s3vscrn = vmesa->s3vScreen; \
+       __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
+       __DRIscreenPrivate *sPriv = vmesa->driScreen; \
+       GLuint pitch = s3vscrn->depthPitch; \
+       GLuint height = dPriv->h; \
+       char *buf = (char *)(sPriv->pFB + \
+                       s3vscrn->depthOffset); /* + \   
+                       dPriv->x * s3vscrn->cpp + \
+                       dPriv->y * pitch)*/ \
+       (void) pitch
+
+#define LOCAL_STENCIL_VARS     LOCAL_DEPTH_VARS
+
+
+#define CLIPPIXEL( _x, _y ) \
+       ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy))
+
+
+#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
+       if ( _y < miny || _y >= maxy ) { \
+               _n1 = 0, _x1 = x; \
+       } else { \
+               _n1 = _n; \
+               _x1 = _x; \
+               if ( _x1 < minx ) \
+                       _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
+               if ( _x1 + _n1 >= maxx ) \
+                       n1 -= (_x1 + n1 - maxx); \
+       }
+
+#define Y_FLIP( _y )   (height - _y - 1)
+
+#if _SPANLOCK  /* OK, we lock */
+
+#define HW_LOCK() \
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
+       (void) vmesa; \
+       DMAFLUSH(); \
+       S3V_SIMPLE_FLUSH_LOCK(vmesa);
+#define HW_UNLOCK() S3V_SIMPLE_UNLOCK(vmesa);
+
+#else                  /* plz, don't lock */
+
+#define HW_LOCK() \
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
+    (void) vmesa; \
+       DMAFLUSH(); 
+#define HW_UNLOCK()
+
+#endif
+
+#define HW_CLIPLOOP()                                                  \
+   do {                                                                        \
+      __DRIdrawablePrivate *dPriv = vmesa->driDrawable;                        \
+      int _nc = dPriv->numClipRects;                                   \
+                                                                       \
+      while ( _nc-- ) {                                                        \
+        int minx = dPriv->pClipRects[_nc].x1 - dPriv->x;               \
+        int miny = dPriv->pClipRects[_nc].y1 - dPriv->y;               \
+        int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x;               \
+        int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
+
+#define HW_ENDCLIPLOOP()                                               \
+      }                                                                        \
+   } while (0)
+
+
+/* ================================================================
+ * Color buffer
+ */
+
+/* 16 bit, RGB565 color spanline and pixel functions
+ */
+#define INIT_MONO_PIXEL(p, color) \
+  p = S3VIRGEPACKCOLOR555( color[0], color[1], color[2], color[3] )
+
+#define WRITE_RGBA( _x, _y, r, g, b, a ) \
+do { \
+   *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 7) | \
+                                          (((int)g & 0xf8) << 2) | \
+                                          (((int)b & 0xf8) >> 3)); \
+   DEBUG(("buf=0x%x drawOffset=0x%x dPriv->x=%i s3vscrn->cpp=%i dPriv->y=%i pitch=%i\n", \
+       sPriv->pFB, vmesa->drawOffset, dPriv->x, s3vscrn->cpp, dPriv->y, pitch)); \
+   DEBUG(("dPriv->w = %i\n", dPriv->w)); \
+} while(0)
+
+#define WRITE_PIXEL( _x, _y, p ) \
+   *(GLushort *)(buf + _x*2 + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y ) \
+   do { \
+      GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
+      rgba[0] = (p >> 7) & 0xf8; \
+      rgba[1] = (p >> 2) & 0xf8; \
+      rgba[2] = (p << 3) & 0xf8; \
+      rgba[3] = 0xff; /*
+      if ( rgba[0] & 0x08 ) rgba[0] |= 0x07; \ 
+      if ( rgba[1] & 0x04 ) rgba[1] |= 0x03; \
+      if ( rgba[2] & 0x08 ) rgba[2] |= 0x07; */ \
+   } while (0)
+
+#define TAG(x) s3v##x##_RGB555
+#include "spantmp.h"
+
+
+/* 32 bit, ARGB8888 color spanline and pixel functions
+ */
+
+#undef INIT_MONO_PIXEL
+#define INIT_MONO_PIXEL(p, color) \
+  p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] )
+
+#define WRITE_RGBA( _x, _y, r, g, b, a ) \
+   *(GLuint *)(buf + _x*4 + _y*pitch) = ((b <<  0) | \
+                                        (g <<  8) | \
+                                        (r << 16) | \
+                                        (a << 24) )
+
+#define WRITE_PIXEL( _x, _y, p ) \
+   *(GLuint *)(buf + _x*4 + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y ) \
+do { \
+   GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
+   rgba[0] = (p >> 16) & 0xff; \
+   rgba[1] = (p >>  8) & 0xff; \
+   rgba[2] = (p >>  0) & 0xff; \
+   rgba[3] = (p >> 24) & 0xff; \
+} while (0)
+
+#define TAG(x) s3v##x##_ARGB8888
+#include "spantmp.h"
+
+
+/* 16 bit depthbuffer functions.
+ */
+#define WRITE_DEPTH( _x, _y, d ) \
+   *(GLushort *)(buf + _x*2 + _y*dPriv->w*2) = d
+
+#define READ_DEPTH( d, _x, _y ) \
+   d = *(GLushort *)(buf + _x*2 + _y*dPriv->w*2);
+
+#define TAG(x) s3v##x##_16
+#include "depthtmp.h"
+
+
+
+
+/* 32 bit depthbuffer functions.
+ */
+#if 0
+#define WRITE_DEPTH( _x, _y, d )       \
+   *(GLuint *)(buf + _x*4 + _y*pitch) = d;
+
+#define READ_DEPTH( d, _x, _y )                \
+   d = *(GLuint *)(buf + _x*4 + _y*pitch);     
+
+#define TAG(x) s3v##x##_32
+#include "depthtmp.h"
+#endif
+
+
+/* 24/8 bit interleaved depth/stencil functions
+ */
+#if 0
+#define WRITE_DEPTH( _x, _y, d ) { \
+   GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch);    \
+   tmp &= 0xff; \
+   tmp |= (d) & 0xffffff00; \
+   *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
+}
+
+#define READ_DEPTH( d, _x, _y ) \
+   d = *(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff      
+
+
+#define TAG(x) s3v##x##_24_8
+#include "depthtmp.h"
+
+#define WRITE_STENCIL( _x, _y, d ) { \
+   GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch);    \
+   tmp &= 0xffffff00; \
+   tmp |= d & 0xff; \
+   *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
+}
+
+#define READ_STENCIL( d, _x, _y ) \
+   d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff       
+
+#define TAG(x) s3v##x##_24_8
+#include "stenciltmp.h"
+
+#endif
+
+static void s3vSetReadBuffer( GLcontext *ctx,
+                                GLframebuffer *colorBuffer,
+                                GLenum mode )
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+   switch ( mode ) {
+   case GL_FRONT_LEFT:
+      vmesa->readOffset = 0;
+      break;
+   case GL_BACK_LEFT:
+      vmesa->readOffset = vmesa->driScreen->fbHeight * vmesa->driScreen->fbWidth * vmesa->s3vScreen->cpp; 
+      break;
+   }
+}
+
+
+void s3vInitSpanFuncs( GLcontext *ctx )
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+   struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
+
+   swdd->SetReadBuffer = s3vSetReadBuffer;
+
+   switch ( vmesa->s3vScreen->cpp ) {
+   case 2:
+      swdd->WriteRGBASpan      = s3vWriteRGBASpan_RGB555;
+      swdd->WriteRGBSpan       = s3vWriteRGBSpan_RGB555;
+      swdd->WriteMonoRGBASpan  = s3vWriteMonoRGBASpan_RGB555;
+      swdd->WriteRGBAPixels    = s3vWriteRGBAPixels_RGB555;
+      swdd->WriteMonoRGBAPixels        = s3vWriteMonoRGBAPixels_RGB555;
+      swdd->ReadRGBASpan       = s3vReadRGBASpan_RGB555;
+      swdd->ReadRGBAPixels      = s3vReadRGBAPixels_RGB555;
+      break;
+
+   case 4:
+      swdd->WriteRGBASpan      = s3vWriteRGBASpan_ARGB8888;
+      swdd->WriteRGBSpan       = s3vWriteRGBSpan_ARGB8888;
+      swdd->WriteMonoRGBASpan   = s3vWriteMonoRGBASpan_ARGB8888;
+      swdd->WriteRGBAPixels     = s3vWriteRGBAPixels_ARGB8888;
+      swdd->WriteMonoRGBAPixels = s3vWriteMonoRGBAPixels_ARGB8888;
+#if 1
+      swdd->ReadRGBASpan    = s3vReadRGBASpan_ARGB8888;
+#else
+      swdd->ReadRGBASpan    = s3vReadRGBASpan8888;
+#endif
+      swdd->ReadRGBAPixels  = s3vReadRGBAPixels_ARGB8888;
+      break;
+
+   default:
+      break;
+   }
+
+   switch ( vmesa->glCtx->Visual.depthBits ) {
+   case 15:
+   case 16:
+      swdd->ReadDepthSpan      = s3vReadDepthSpan_16;
+      swdd->WriteDepthSpan     = s3vWriteDepthSpan_16;
+      swdd->ReadDepthPixels    = s3vReadDepthPixels_16;
+      swdd->WriteDepthPixels   = s3vWriteDepthPixels_16;
+      break;
+
+#if 0
+   case 24:
+      swdd->ReadDepthSpan      = s3vReadDepthSpan_24_8;
+      swdd->WriteDepthSpan     = s3vWriteDepthSpan_24_8;
+      swdd->ReadDepthPixels    = s3vReadDepthPixels_24_8;
+      swdd->WriteDepthPixels   = s3vWriteDepthPixels_24_8;
+
+      swdd->ReadStencilSpan    = s3vReadStencilSpan_24_8;
+      swdd->WriteStencilSpan   = s3vWriteStencilSpan_24_8;
+      swdd->ReadStencilPixels  = s3vReadStencilPixels_24_8;
+      swdd->WriteStencilPixels = s3vWriteStencilPixels_24_8;
+      break;
+#endif
+
+   default:
+      break;
+   }
+}
diff --git a/src/mesa/drivers/dri/s3v/s3v_state.c b/src/mesa/drivers/dri/s3v/s3v_state.c
new file mode 100644 (file)
index 0000000..66f15db
--- /dev/null
@@ -0,0 +1,885 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include <X11/Xlibint.h>
+#include "s3v_context.h"
+#include "s3v_macros.h"
+#include "macros.h"
+#include "s3v_dri.h"
+#include "colormac.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "array_cache/acache.h"
+#include "tnl/tnl.h"
+
+/* #define DEBUG(str) printf str */
+#define ENABLELIGHTING 0
+
+
+/* =============================================================
+ * Alpha blending
+ */
+
+static void s3vUpdateAlphaMode( GLcontext *ctx )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       CARD32 cmd = vmesa->CMD;
+       cmd &= ~ALPHA_BLEND_MASK;
+
+       if ( ctx->Color.BlendEnabled ) {
+               DEBUG(("ctx->Color.AlphaEnabled = 1"));
+               vmesa->_alpha[0] = ALPHA_SRC;
+               vmesa->_alpha[1] = vmesa->_alpha_tex; /* FIXME: not all tex modes
+                                                        support alpha */
+       } else {
+               DEBUG(("ctx->Color.AlphaEnabled = 0"));
+               vmesa->_alpha[0] = vmesa->_alpha[1] = ALPHA_OFF;
+       }
+#if 1
+       if ((cmd & DO_MASK) & DO_3D_LINE) {     /* we are drawing 3d lines */
+                                               /* which don't support tex */
+               cmd |= vmesa->_alpha[0];
+       } else {
+               cmd |= vmesa->_alpha[vmesa->_3d_mode];
+       }
+
+       vmesa->CMD = cmd; /* FIXME: enough? */
+#else
+       vmesa->restore_primitive = -1;
+#endif
+       
+}
+
+static void s3vDDAlphaFunc( GLcontext *ctx, GLenum func, GLchan ref )
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+   DEBUG(("s3vDDAlphaFunc\n"));
+
+   vmesa->new_state |= S3V_NEW_ALPHA;
+}
+
+static void s3vDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor )
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+   DEBUG(("s3vDDBlendFunc\n"));
+
+   vmesa->new_state |= S3V_NEW_ALPHA;
+}
+
+/* ================================================================
+ * Buffer clear
+ */
+
+static void s3vDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+                              GLint cx, GLint cy, GLint cw, GLint ch )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       unsigned int _stride;
+
+       vmesa->restore_primitive = -1;
+
+       /* Update and emit any new state.  We need to do this here to catch
+        * changes to the masks.
+        * FIXME: Just update the masks?
+        */
+
+       if ( vmesa->new_state )
+               s3vDDUpdateHWState( ctx );
+
+/*     s3vUpdateMasks( ctx ); */
+/*     s3vUpdateClipping( ctx ); */
+/*     s3vEmitHwState( vmesa ); */
+       
+
+#if 1 /* soft (0)/hw (1)*/
+
+       DEBUG(("*** s3vDDClear ***\n"));
+
+       DMAOUT_CHECK(BITBLT_SRC_BASE, 15);
+               DMAOUT(vmesa->SrcBase);
+               DMAOUT(vmesa->DestBlit);
+               DMAOUT( vmesa->ScissorLR );
+               DMAOUT( vmesa->ScissorTB );
+               DMAOUT( (vmesa->SrcStride << 16) | vmesa->SrcStride );  /* FIXME: unify */
+               DMAOUT( (~(0)) ); /* masks */
+               DMAOUT( (~(0)) );
+               DMAOUT(0);
+               DMAOUT(vmesa->ClearColor);
+               DMAOUT(0);
+               DMAOUT(0);
+               /* FIXME */
+               DMAOUT(0x16000122 | 0x5 | (0xF0 << 17));    /* black magic to me */
+               DMAOUT(vmesa->ScissorWH);
+               DMAOUT(vmesa->SrcXY);
+               DMAOUT(vmesa->DestXY);
+       DMAFINISH();
+
+       if (mask & DD_DEPTH_BIT) { /* depth */
+               DEBUG(("DD_DEPTH_BIT\n"));
+               
+               _stride = ((cw+31)&~31) * 2;
+
+               DMAOUT_CHECK(BITBLT_SRC_BASE, 15);
+                       DMAOUT(0);
+                       DMAOUT(vmesa->s3vScreen->depthOffset);
+                       DMAOUT( (0 << 16) | cw );
+                       DMAOUT( (0 << 16) | ch );
+                       DMAOUT( (vmesa->SrcStride << 16) | vmesa->DestStride );
+                       DMAOUT( (~(0)) ); /* masks */
+                       DMAOUT( (~(0)) );
+                       DMAOUT(0);
+                       DMAOUT(vmesa->ClearDepth); /* 0x7FFF */
+                       /* FIXME */
+                       DMAOUT(0);
+                       DMAOUT(0);
+                       DMAOUT(0x16000122 | 0x5 | (0xF0 << 17));
+                       DMAOUT( ((cw-1) << 16) | (ch-1) );
+                       DMAOUT(0);
+                       DMAOUT( (0 << 16) | 0 );
+               DMAFINISH();            
+
+               DEBUG(("vmesa->ClearDepth = 0x%x\n", vmesa->ClearDepth));
+               mask &= ~DD_DEPTH_BIT;
+       }
+
+       if (!vmesa->NotClipped) {
+               DEBUG(("vmesa->NotClipped\n")); /* yes */
+       }
+
+       if (!(vmesa->EnabledFlags & S3V_BACK_BUFFER)) {
+               DEBUG(("!S3V_BACK_BUFFER -> flush\n"));
+               DMAFLUSH();
+       }
+/*
+       if ( mask )
+               DEBUG(("still masked ;3(\n")); */ /* yes */
+#else
+      _swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
+#endif
+}
+
+/* =============================================================
+ * Depth testing
+ */
+
+static void s3vUpdateZMode( GLcontext *ctx )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       CARD32 cmd = vmesa->CMD;
+
+       DEBUG(("Depth.Test = %i\n", ctx->Depth.Test));
+       DEBUG(("CMD was = 0x%x ", cmd));
+
+/*     printf("depth --- CMD was = 0x%x \n", cmd); */
+
+       cmd &= ~Z_MASK; /*  0xfc0fffff; */
+       /* Z_BUFFER */ /* 000 mode */ /* Z_UPDATE_OFF */
+
+       if (!ctx->Depth.Test)
+               cmd |= Z_OFF;
+
+       if ( ctx->Depth.Mask )
+               cmd |= Z_UPDATE_ON;
+                       
+       switch ( ctx->Depth.Func ) {
+               case GL_NEVER:
+                       cmd |= Z_NEVER;
+                       break;
+               case GL_ALWAYS:
+                       cmd |= Z_ALWAYS;
+                       break;
+               case GL_LESS:
+                       cmd |= Z_LESS;
+                       break;
+               case GL_LEQUAL:
+                       cmd |= Z_LEQUAL;
+                       break;
+               case GL_EQUAL:
+                       cmd |= Z_EQUAL;
+                       break;
+               case GL_GEQUAL:
+                       cmd |= Z_GEQUAL;
+                       break;
+               case GL_GREATER:
+                       cmd |= Z_GREATER;
+                       break;
+               case GL_NOTEQUAL:
+                       cmd |= Z_NOTEQUAL;
+                       break;
+       }
+
+       DEBUG(("CMD is 0x%x\n", cmd));
+
+       vmesa->dirty |= S3V_UPLOAD_DEPTH;
+       vmesa->CMD = cmd;
+}
+
+static void s3vDDDepthFunc( GLcontext *ctx, GLenum func )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+/*     FLUSH_BATCH( vmesa ); */
+       DEBUG(("s3vDDDepthFunc\n"));
+       vmesa->new_state |= S3V_NEW_DEPTH;
+}
+
+static void s3vDDDepthMask( GLcontext *ctx, GLboolean flag )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+       /* FLUSH_BATCH( vmesa ); */
+       DEBUG(("s3vDDDepthMask\n"));
+       vmesa->new_state |= S3V_NEW_DEPTH;
+}
+
+static void s3vDDClearDepth( GLcontext *ctx, GLclampd d )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+       switch ( vmesa->DepthSize ) {
+       case 15:
+       case 16:
+               vmesa->ClearDepth = d * 0x0000ffff;     /* 65536 */
+               DEBUG(("GLclampd d = %f\n", d));
+               DEBUG(("ctx->Depth.Clear = %f\n", ctx->Depth.Clear));
+               DEBUG(("(They should be the same)\n"));
+               break;
+       case 24:
+               vmesa->ClearDepth = d * 0x00ffffff;
+               break;
+       case 32:
+               vmesa->ClearDepth = d * 0xffffffff;
+               break;
+   }
+}
+
+static void s3vDDFinish( GLcontext *ctx )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       DMAFLUSH(); 
+}
+
+static void s3vDDFlush( GLcontext *ctx )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       DMAFLUSH();
+}
+
+/* =============================================================
+ * Fog
+ */
+
+static void s3vUpdateFogAttrib( GLcontext *ctx )
+{
+/*     s3vContextPtr vmesa = S3V_CONTEXT(ctx); */
+
+       if (ctx->Fog.Enabled) {
+       } else {
+       }
+
+       switch (ctx->Fog.Mode) {
+               case GL_LINEAR:
+                       break;
+               case GL_EXP:
+                       break;
+               case GL_EXP2:
+                       break;
+       }
+}
+
+static void s3vDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+   vmesa->new_state |= S3V_NEW_FOG;
+}
+
+/* =============================================================
+ * Lines
+ */
+static void s3vDDLineWidth( GLcontext *ctx, GLfloat width )
+{
+       /* FIXME: on virge you only have one size of 3d lines    *
+        * if we wanted more, we should start using tris instead *
+        * but virge has problem with some tris when all of the  *
+        * vertices stay on a line */
+}
+
+/* =============================================================
+ * Points
+ */
+static void s3vDDPointSize( GLcontext *ctx, GLfloat size )
+{
+       /* FIXME: we use 3d line to fake points. So same limitations
+        * as above apply */
+}
+
+/* =============================================================
+ * Polygon 
+ */
+
+static void s3vUpdatePolygon( GLcontext *ctx )
+{
+       /* FIXME: I don't think we could do much here */
+
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       vmesa->dirty |= S3V_UPLOAD_POLYGON;
+}
+
+/* =============================================================
+ * Clipping
+ */
+
+static void s3vUpdateClipping( GLcontext *ctx )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+
+       int x0,y0,x1,y1;
+
+       DEBUG((">>> s3vUpdateClipping <<<\n"));
+/*
+       if ( vmesa->driDrawable ) {
+               DEBUG(("s3vUpdateClipping\n"));
+*/
+       if (vmesa->EnabledFlags & S3V_BACK_BUFFER) {
+               DEBUG(("S3V_BACK_BUFFER\n"));
+
+               x0 = 0;
+               y0 = 0;
+               x1 = dPriv->w - 1;
+               y1 = dPriv->h - 1;
+
+               vmesa->SrcBase = 0;
+               vmesa->DestBase =  vmesa->s3vScreen->backOffset;
+               vmesa->DestBlit = vmesa->DestBase;
+               vmesa->ScissorLR = ( (0 << 16) | (dPriv->w-1) );
+               vmesa->ScissorTB = ( (0 << 16) | (dPriv->h-1) );
+/*
+               vmesa->ScissorLR = ( (x0 << 16) | x1 );
+               vmesa->ScissorTB = ( (y0 << 16) | y1 );
+*/
+               vmesa->SrcStride = ( ((dPriv->w+31)&~31) * vmesa->s3vScreen->cpp );
+               vmesa->DestStride = vmesa->driScreen->fbWidth*vmesa->s3vScreen->cpp;
+               vmesa->ScissorWH = ( (dPriv->w << 16) | dPriv->h );
+               vmesa->SrcXY = 0;
+/*             vmesa->DestXY = ( (dPriv->x << 16) | dPriv->y );  */
+               vmesa->DestXY = ( (0 << 16) | 0 );
+       } else {
+               DEBUG(("S3V_FRONT_BUFFER\n"));
+
+               x0 = dPriv->x;
+               y0 = dPriv->y;
+               x1 = x0 + dPriv->w - 1;
+               y1 = y0 + dPriv->h - 1;
+
+               vmesa->SrcBase = 0;
+               vmesa->DestBase = 0;
+               vmesa->ScissorLR = ( (x0 << 16) | x1 );
+               vmesa->ScissorTB = ( (y0 << 16) | y1 );
+               vmesa->DestStride = vmesa->driScreen->fbWidth*vmesa->s3vScreen->cpp;
+               vmesa->SrcStride = vmesa->DestStride;
+               vmesa->DestBase = (y0 * vmesa->DestStride)
+                               + x0*vmesa->s3vScreen->cpp;
+               vmesa->DestBlit = 0;
+               vmesa->ScissorWH = ( (x1 << 16) | y1 );
+               vmesa->SrcXY = 0;
+               vmesa->DestXY = ( (0 << 16) | 0 );
+/*             vmesa->DestXY = ( (dPriv->x << 16) | dPriv->y ); */
+       }
+
+       DEBUG(("x0=%i y0=%i x1=%i y1=%i\n", x0, y0, x1, y1));
+       DEBUG(("stride=%i rectWH=0x%x\n\n", vmesa->DestStride, vmesa->ScissorWH));
+
+       /* FIXME: how could we use the following info? */
+       /* if (ctx->Scissor.Enabled) {} */
+
+       vmesa->dirty |= S3V_UPLOAD_CLIP; 
+/*     }  */
+}
+
+static void s3vDDScissor( GLcontext *ctx,
+                          GLint x, GLint y, GLsizei w, GLsizei h )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+       DEBUG((">>> s3vDDScissor <<<"));
+       /* FLUSH_BATCH( vmesa ); */
+       vmesa->new_state |= S3V_NEW_CLIP;
+}
+
+/* =============================================================
+ * Culling
+ */
+
+static void s3vUpdateCull( GLcontext *ctx )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       GLfloat backface_sign = 1;
+
+       DEBUG(("s3vUpdateCull\n"));
+       /* FIXME: GL_FRONT_AND_BACK */
+
+       switch ( ctx->Polygon.CullFaceMode ) {
+       case GL_BACK:
+               if (ctx->Polygon.FrontFace == GL_CCW)
+                       backface_sign = -1;
+               break;
+
+       case GL_FRONT:
+               if (ctx->Polygon.FrontFace != GL_CCW)
+                       backface_sign = -1;
+               break;
+
+       default:
+               break;
+       }
+
+       vmesa->backface_sign = backface_sign;
+       vmesa->dirty |= S3V_UPLOAD_GEOMETRY;
+}
+
+
+static void s3vDDCullFace( GLcontext *ctx, GLenum mode )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       /* FLUSH_BATCH( vmesa ); */
+       vmesa->new_state |= S3V_NEW_CULL;
+}
+
+static void s3vDDFrontFace( GLcontext *ctx, GLenum mode )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       /* FLUSH_BATCH( vmesa ); */
+       vmesa->new_state |= S3V_NEW_CULL;
+}
+
+/* =============================================================
+ * Masks
+ */
+
+static void s3vUpdateMasks( GLcontext *ctx )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+       GLuint mask = s3vPackColor( vmesa->s3vScreen->cpp,
+                               ctx->Color.ColorMask[RCOMP],
+                               ctx->Color.ColorMask[GCOMP],
+                               ctx->Color.ColorMask[BCOMP],
+                               ctx->Color.ColorMask[ACOMP] );
+
+       if (vmesa->s3vScreen->cpp == 2) mask |= mask << 16;
+
+       /* FIXME: can we do something in virge? */
+}
+/*
+static void s3vDDColorMask( GLcontext *ctx, GLboolean r, GLboolean g,
+                             GLboolean b, GLboolean a)
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+   FLUSH_BATCH( vmesa );
+   vmesa->new_state |= S3V_NEW_MASKS;
+}
+*/
+/* =============================================================
+ * Rendering attributes
+ */
+
+/* =============================================================
+ * Miscellaneous
+ */
+
+static void s3vDDClearColor( GLcontext *ctx, const GLchan color[4])
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+   DEBUG(("*** s3vDDClearColor\n"));
+
+   vmesa->ClearColor = s3vPackColor( 2, /* vmesa->s3vScreen->cpp, */
+                                     color[0], color[1], color[2], color[3] );
+
+#if 0
+   if (vmesa->s3vScreen->cpp == 2) vmesa->ClearColor |= vmesa->ClearColor<<16;
+#endif
+}
+
+static void s3vDDSetDrawBuffer( GLcontext *ctx, GLenum mode )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       int found = GL_TRUE;
+
+       DEBUG(("*** s3vDDSetDrawBuffer ***\n"));
+
+       /* FLUSH_BATCH( vmesa ); */
+
+       switch ( mode ) {
+               case GL_FRONT_LEFT:
+                       vmesa->drawOffset = vmesa->s3vScreen->frontOffset;
+                       break;
+               case GL_BACK_LEFT:
+                       vmesa->drawOffset = vmesa->s3vScreen->backOffset;
+                       /* vmesa->driScreen->fbHeight *
+                        * vmesa->driScreen->fbWidth *
+                        * vmesa->s3vScreen->cpp; */
+                       break;
+               default:
+                       found = GL_FALSE;
+                       break;
+       }
+
+       DEBUG(("vmesa->drawOffset = 0x%x\n", vmesa->drawOffset));
+/*     return GL_TRUE; */
+}
+
+/* =============================================================
+ * Window position and viewport transformation
+ */
+
+void s3vUpdateWindow( GLcontext *ctx )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+       GLfloat xoffset = (GLfloat)dPriv->x;
+       GLfloat yoffset =
+               vmesa->driScreen->fbHeight - (GLfloat)dPriv->y - dPriv->h;
+       const GLfloat *v = ctx->Viewport._WindowMap.m;
+
+       GLfloat sx = v[MAT_SX];
+       GLfloat tx = v[MAT_TX] + xoffset;
+       GLfloat sy = v[MAT_SY];
+       GLfloat ty = v[MAT_TY] + yoffset;
+       GLfloat sz = v[MAT_SZ] * vmesa->depth_scale;
+       GLfloat tz = v[MAT_TZ] * vmesa->depth_scale;
+
+       vmesa->dirty |= S3V_UPLOAD_VIEWPORT;
+
+       vmesa->ViewportScaleX = sx;
+       vmesa->ViewportScaleY = sy;
+       vmesa->ViewportScaleZ = sz;
+       vmesa->ViewportOffsetX = tx;
+       vmesa->ViewportOffsetY = ty;
+       vmesa->ViewportOffsetZ = tz;
+}
+
+
+/*
+static void s3vDDViewport( GLcontext *ctx, GLint x, GLint y,
+                           GLsizei width, GLsizei height )
+{
+       s3vUpdateWindow( ctx );
+}
+
+static void s3vDDDepthRange( GLcontext *ctx, GLclampd nearval,
+                             GLclampd farval )
+{
+       s3vUpdateWindow( ctx );
+}
+*/
+void s3vUpdateViewportOffset( GLcontext *ctx )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+       GLfloat xoffset = (GLfloat)dPriv->x;
+       GLfloat yoffset =
+               vmesa->driScreen->fbHeight - (GLfloat)dPriv->y - dPriv->h;
+       const GLfloat *v = ctx->Viewport._WindowMap.m;
+
+       GLfloat tx = v[MAT_TX] + xoffset;
+       GLfloat ty = v[MAT_TY] + yoffset;
+
+       DEBUG(("*** s3vUpdateViewportOffset ***\n"));
+
+       if ( vmesa->ViewportOffsetX != tx ||
+               vmesa->ViewportOffsetY != ty )
+       {
+               vmesa->ViewportOffsetX = tx;
+               vmesa->ViewportOffsetY = ty;
+
+               vmesa->new_state |= S3V_NEW_WINDOW;
+       }
+
+/*     vmesa->new_state |= S3V_NEW_CLIP; */
+}
+
+/* =============================================================
+ * State enable/disable
+ */
+
+static void s3vDDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+       switch ( cap ) {
+       case GL_ALPHA_TEST:
+       case GL_BLEND:
+               vmesa->new_state |= S3V_NEW_ALPHA;
+               DEBUG(("s3vDDEnable: GL_BLEND\n"));
+       break;
+
+       case GL_CULL_FACE:
+               vmesa->new_state |= S3V_NEW_CULL;
+               DEBUG(("s3vDDEnable: GL_CULL_FACE\n"));
+       break;
+
+       case GL_DEPTH_TEST:
+               vmesa->new_state |= S3V_NEW_DEPTH;
+               DEBUG(("s3vDDEnable: GL_DEPTH\n"));
+       break;
+#if 0
+       case GL_FOG:
+               vmesa->new_state |= S3V_NEW_FOG;
+       break;
+#endif
+
+       case GL_SCISSOR_TEST:
+               vmesa->new_state |= S3V_NEW_CLIP;
+       break;
+
+       case GL_TEXTURE_2D:
+               DEBUG(("*** GL_TEXTURE_2D: %i\n", state));
+               vmesa->_3d_mode = state;
+               vmesa->restore_primitive = -1;
+       break;
+       
+       default:
+               return;
+       }
+}
+
+/* =============================================================
+ * State initialization, management
+ */
+
+
+/*
+ * Load the current context's state into the hardware.
+ *
+ * NOTE: Be VERY careful about ensuring the context state is marked for
+ * upload, the only place it shouldn't be uploaded is when the setup
+ * state has changed in ReducedPrimitiveChange as this comes right after
+ * a state update.
+ *
+ * Blits of any type should always upload the context and masks after
+ * they are done.
+ */
+void s3vEmitHwState( s3vContextPtr vmesa )
+{
+    if (!vmesa->driDrawable) return;
+    if (!vmesa->dirty) return; 
+
+       DEBUG(("**********************\n"));
+       DEBUG(("*** s3vEmitHwState ***\n"));
+       DEBUG(("**********************\n"));
+
+    if (vmesa->dirty & S3V_UPLOAD_VIEWPORT) {
+       vmesa->dirty &= ~S3V_UPLOAD_VIEWPORT;
+       DEBUG(("S3V_UPLOAD_VIEWPORT\n"));
+    }
+   
+    if ( (vmesa->dirty & S3V_UPLOAD_POINTMODE) ||
+        (vmesa->dirty & S3V_UPLOAD_LINEMODE) ||
+        (vmesa->dirty & S3V_UPLOAD_TRIMODE) ) {
+
+    }
+    
+    if (vmesa->dirty & S3V_UPLOAD_POINTMODE) {
+       vmesa->dirty &= ~S3V_UPLOAD_POINTMODE;
+    }
+
+    if (vmesa->dirty & S3V_UPLOAD_LINEMODE) {
+       vmesa->dirty &= ~S3V_UPLOAD_LINEMODE;
+    }
+    
+    if (vmesa->dirty & S3V_UPLOAD_TRIMODE) {
+       vmesa->dirty &= ~S3V_UPLOAD_TRIMODE;
+    }
+
+    if (vmesa->dirty & S3V_UPLOAD_FOG) {
+       GLchan c[3], col;
+       UNCLAMPED_FLOAT_TO_RGB_CHAN( c, vmesa->glCtx->Fog.Color );
+       DEBUG(("uploading ** FOG **\n"));
+       col = s3vPackColor(2, c[0], c[1], c[2], 0);
+       vmesa->dirty &= ~S3V_UPLOAD_FOG;
+    }
+    
+    if (vmesa->dirty & S3V_UPLOAD_DITHER) {
+       vmesa->dirty &= ~S3V_UPLOAD_DITHER;
+    }
+    
+    if (vmesa->dirty & S3V_UPLOAD_LOGICOP) {
+       vmesa->dirty &= ~S3V_UPLOAD_LOGICOP;
+    }
+    
+    if (vmesa->dirty & S3V_UPLOAD_CLIP) {
+       vmesa->dirty &= ~S3V_UPLOAD_CLIP;
+       DEBUG(("S3V_UPLOAD_CLIP\n"));
+       DEBUG(("vmesa->ScissorLR: %i\n",  vmesa->ScissorLR));
+       DEBUG(("vmesa->ScissorTB: %i\n",  vmesa->ScissorTB));
+    }
+
+    if (vmesa->dirty & S3V_UPLOAD_MASKS) {
+       vmesa->dirty &= ~S3V_UPLOAD_MASKS;
+       DEBUG(("S3V_UPLOAD_BLEND\n"));
+    }
+    
+    if (vmesa->dirty & S3V_UPLOAD_ALPHA) {
+       vmesa->dirty &= ~S3V_UPLOAD_ALPHA;
+       DEBUG(("S3V_UPLOAD_ALPHA\n"));
+    }
+    
+    if (vmesa->dirty & S3V_UPLOAD_SHADE) {
+       vmesa->dirty &= ~S3V_UPLOAD_SHADE;
+    }
+    
+    if (vmesa->dirty & S3V_UPLOAD_POLYGON) {
+       vmesa->dirty &= ~S3V_UPLOAD_POLYGON;
+    }
+    
+    if (vmesa->dirty & S3V_UPLOAD_DEPTH) {
+       vmesa->dirty &= ~S3V_UPLOAD_DEPTH;
+       DEBUG(("S3V_UPLOAD_DEPTH: DepthMode = 0x%x08\n", vmesa->DepthMode));
+    }
+    
+    if (vmesa->dirty & S3V_UPLOAD_GEOMETRY) {
+       vmesa->dirty &= ~S3V_UPLOAD_GEOMETRY;
+    }
+
+    if (vmesa->dirty & S3V_UPLOAD_TRANSFORM) {
+       vmesa->dirty &= ~S3V_UPLOAD_TRANSFORM;
+    }
+    
+    if (vmesa->dirty & S3V_UPLOAD_TEX0) {
+       s3vTextureObjectPtr curTex = vmesa->CurrentTexObj[0];
+       vmesa->dirty &= ~S3V_UPLOAD_TEX0;
+       DEBUG(("S3V_UPLOAD_TEX0\n"));
+       if (curTex) {
+               DEBUG(("S3V_UPLOAD_TEX0: curTex\n"));
+       } else {
+               DEBUG(("S3V_UPLOAD_TEX0: !curTex\n"));
+       }
+    }
+}
+
+void s3vDDUpdateHWState( GLcontext *ctx )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+       int new_state = vmesa->new_state;
+
+       /* s3vUpdateClipping( ctx ); */
+
+       if ( new_state )
+       {
+
+               vmesa->new_state = 0;
+
+               /* Update the various parts of the context's state.
+                */
+               if ( new_state & S3V_NEW_ALPHA )
+                       s3vUpdateAlphaMode( ctx );
+
+               if ( new_state & S3V_NEW_DEPTH )
+                       s3vUpdateZMode( ctx );
+
+               if ( new_state & S3V_NEW_FOG )
+                       s3vUpdateFogAttrib( ctx );
+
+               if ( new_state & S3V_NEW_CLIP )
+               {
+                       DEBUG(("---> going to s3vUpdateClipping\n"));
+                       s3vUpdateClipping( ctx );
+               }
+
+               if ( new_state & S3V_NEW_POLYGON )
+                       s3vUpdatePolygon( ctx );
+
+               if ( new_state & S3V_NEW_CULL )
+                       s3vUpdateCull( ctx );
+
+               if ( new_state & S3V_NEW_MASKS )
+                       s3vUpdateMasks( ctx );
+
+               if ( new_state & S3V_NEW_WINDOW )
+                       s3vUpdateWindow( ctx );
+/*
+               if ( new_state & S3_NEW_TEXTURE )
+                       s3vUpdateTextureState( ctx );           
+*/
+               CMDCHANGE();
+       }
+
+       /* HACK ! */
+       s3vEmitHwState( vmesa );
+}
+
+
+static void s3vDDUpdateState( GLcontext *ctx, GLuint new_state )
+{
+       _swrast_InvalidateState( ctx, new_state );
+       _swsetup_InvalidateState( ctx, new_state );
+       _ac_InvalidateState( ctx, new_state );
+       _tnl_InvalidateState( ctx, new_state );
+       S3V_CONTEXT(ctx)->new_gl_state |= new_state;
+}
+
+
+/* Initialize the context's hardware state.
+ */
+void s3vInitState( s3vContextPtr vmesa )
+{
+       vmesa->new_state = 0;
+}
+
+/* Initialize the driver's state functions.
+ */
+void s3vInitStateFuncs( GLcontext *ctx )
+{
+   ctx->Driver.UpdateState             = s3vDDUpdateState;
+
+   ctx->Driver.Clear                   = s3vDDClear;
+   ctx->Driver.ClearIndex              = NULL;
+   ctx->Driver.ClearColor              = s3vDDClearColor;
+   ctx->Driver.SetDrawBuffer           = s3vDDSetDrawBuffer; 
+
+   ctx->Driver.IndexMask               = NULL;
+   ctx->Driver.ColorMask               = NULL; /* s3vDDColorMask; */ /* FIXME */
+
+   ctx->Driver.AlphaFunc               = s3vDDAlphaFunc; /* FIXME */
+   ctx->Driver.BlendEquation           = NULL; /* s3vDDBlendEquation; */
+   ctx->Driver.BlendFunc               = s3vDDBlendFunc; /* FIXME */
+   ctx->Driver.BlendFuncSeparate       = NULL; /* s3vDDBlendFuncSeparate; */
+   ctx->Driver.ClearDepth              = s3vDDClearDepth;
+   ctx->Driver.CullFace                        = s3vDDCullFace; 
+   ctx->Driver.FrontFace               = s3vDDFrontFace;
+   ctx->Driver.DepthFunc               = s3vDDDepthFunc;       /* FIXME */
+   ctx->Driver.DepthMask               = s3vDDDepthMask;       /* FIXME */
+   ctx->Driver.DepthRange              = NULL; /* s3vDDDepthRange; */
+   ctx->Driver.Enable                  = s3vDDEnable;          /* FIXME */
+   ctx->Driver.Finish                  = s3vDDFinish;
+   ctx->Driver.Flush                   = s3vDDFlush;
+#if 1
+   ctx->Driver.Fogfv                   = NULL; /* s3vDDFogfv; */
+#endif
+   ctx->Driver.Hint                    = NULL;
+   ctx->Driver.LineWidth               = NULL; /* s3vDDLineWidth; */
+   ctx->Driver.LineStipple             = NULL; /* s3vDDLineStipple; */
+#if ENABLELIGHTING
+   ctx->Driver.Lightfv                 = NULL; /* s3vDDLightfv; */
+
+   ctx->Driver.LightModelfv            = NULL; /* s3vDDLightModelfv; */
+#endif
+   ctx->Driver.LogicOpcode             = NULL; /* s3vDDLogicalOpcode; */
+   ctx->Driver.PointSize               = NULL; /* s3vDDPointSize; */
+   ctx->Driver.PolygonMode             = NULL; /* s3vDDPolygonMode; */
+   ctx->Driver.PolygonStipple          = NULL; /* s3vDDPolygonStipple; */
+   ctx->Driver.Scissor                 = s3vDDScissor; /* ScissorLR / ScissorTB */
+   ctx->Driver.ShadeModel              = NULL; /* s3vDDShadeModel; */
+   ctx->Driver.ClearStencil            = NULL;
+   ctx->Driver.StencilFunc             = NULL;
+   ctx->Driver.StencilMask             = NULL;
+   ctx->Driver.StencilOp               = NULL;
+   ctx->Driver.Viewport                        = NULL; /* s3vDDViewport; */
+}
diff --git a/src/mesa/drivers/dri/s3v/s3v_tex.c b/src/mesa/drivers/dri/s3v/s3v_tex.c
new file mode 100644 (file)
index 0000000..8056410
--- /dev/null
@@ -0,0 +1,560 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "mem.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "texstore.h"
+#include "texformat.h"
+#include "swrast/swrast.h"
+
+#include "mm.h"
+#include "mmath.h"
+#include "s3v_context.h"
+#include "s3v_tex.h"
+
+
+extern void s3vSwapOutTexObj(s3vContextPtr vmesa, s3vTextureObjectPtr t);
+extern void s3vDestroyTexObj(s3vContextPtr vmesa, s3vTextureObjectPtr t);
+
+/*
+static GLuint s3vComputeLodBias(GLfloat bias)
+{
+#if TEX_DEBUG_ON
+       DEBUG_TEX(("*** s3vComputeLodBias ***\n"));
+#endif
+       return bias;
+}
+*/
+
+static void s3vSetTexWrapping(s3vContextPtr vmesa,
+                               s3vTextureObjectPtr t, 
+                              GLenum wraps, GLenum wrapt)
+{
+       CARD32 t0 = t->TextureCMD;
+       CARD32 cmd = vmesa->CMD;
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vSetTexWrapping: #%i ***\n", ++times));
+#endif
+
+
+       t0 &= ~TEX_WRAP_MASK;
+       cmd &= ~TEX_WRAP_MASK;
+
+       if ((wraps != GL_CLAMP) || (wrapt != GL_CLAMP)) {
+               DEBUG(("TEX_WRAP_ON\n"));
+               t0 |= TEX_WRAP_ON;
+               cmd |= TEX_WRAP_ON; 
+       }
+
+       cmd |= TEX_WRAP_ON; /* FIXME: broken if off */
+       t->TextureCMD = t0;
+       vmesa->CMD = cmd;
+}
+
+
+static void s3vSetTexFilter(s3vContextPtr vmesa, 
+                            s3vTextureObjectPtr t, 
+                            GLenum minf, GLenum magf)
+{
+       CARD32 t0 = t->TextureCMD;
+       CARD32 cmd = vmesa->CMD;
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vSetTexFilter: #%i ***\n", ++times));
+#endif
+
+       t0 &= ~TEX_FILTER_MASK;
+       cmd &= ~TEX_FILTER_MASK;
+
+       switch (minf) {
+               case GL_NEAREST:
+                       DEBUG(("GL_NEAREST\n"));
+                       t0 |= NEAREST;
+                       cmd |= NEAREST;
+                       break;
+               case GL_LINEAR:
+                       DEBUG(("GL_LINEAR\n"));
+                       t0 |= LINEAR;
+                       cmd |= LINEAR;
+                       break;
+               case GL_NEAREST_MIPMAP_NEAREST:
+                       DEBUG(("GL_MIPMAP_NEAREST\n"));
+                       t0 |= MIP_NEAREST;
+                       cmd |= MIP_NEAREST;
+                       break;
+               case GL_LINEAR_MIPMAP_NEAREST:
+                       DEBUG(("GL_LINEAR_MIPMAP_NEAREST\n"));
+                       t0 |= LINEAR_MIP_NEAREST;
+                       cmd |= LINEAR_MIP_NEAREST;
+                       break;
+               case GL_NEAREST_MIPMAP_LINEAR:
+                       DEBUG(("GL_NEAREST_MIPMAP_LINEAR\n"));
+                       t0 |= MIP_LINEAR;
+                       cmd |= MIP_LINEAR;
+                       break;
+               case GL_LINEAR_MIPMAP_LINEAR:
+                       DEBUG(("GL_LINEAR_MIPMAP_LINEAR\n"));
+                       t0 |= LINEAR_MIP_LINEAR;
+                       cmd |= LINEAR_MIP_LINEAR;
+                       break;
+               default:
+                       break;
+       }
+       /* FIXME: bilinear? */
+
+#if 0
+       switch (magf) {
+               case GL_NEAREST:
+                       break;
+               case GL_LINEAR:
+                       break;
+               default:
+                       break;
+       }  
+#endif
+
+       t->TextureCMD = t0;
+
+       DEBUG(("CMD was = 0x%x\n", vmesa->CMD));
+       DEBUG(("CMD is = 0x%x\n", cmd));
+
+       vmesa->CMD = cmd; 
+       /* CMDCHANGE(); */
+}
+
+
+static void s3vSetTexBorderColor(s3vContextPtr vmesa,
+                                 s3vTextureObjectPtr t, 
+                                 GLubyte color[4])
+{
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vSetTexBorderColor: #%i ***\n", ++times));
+#endif
+
+       /*FIXME: it should depend on tex col format */
+       /* switch(t0 ... t->TextureColorMode) */
+
+       /* case TEX_COL_ARGB1555: */
+       t->TextureBorderColor =
+               S3VIRGEPACKCOLOR555(color[0], color[1], color[2], color[3]);
+
+       DEBUG(("TextureBorderColor = 0x%x\n", t->TextureBorderColor));
+
+       vmesa->TextureBorderColor = t->TextureBorderColor;
+}
+
+static void s3vTexParameter( GLcontext *ctx, GLenum target,
+                             struct gl_texture_object *tObj,
+                             GLenum pname, const GLfloat *params )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vTexParameter: #%i ***\n", ++times));
+#endif
+   
+       if (!t) return;
+
+       /* Can't do the update now as we don't know whether to flush
+        * vertices or not.  Setting vmesa->new_state means that
+        * s3vUpdateTextureState() will be called before any triangles are
+        * rendered.  If a statechange has occurred, it will be detected at
+        * that point, and buffered vertices flushed.  
+       */
+       switch (pname) {
+       case GL_TEXTURE_MIN_FILTER:
+       case GL_TEXTURE_MAG_FILTER:
+               s3vSetTexFilter( vmesa, t, tObj->MinFilter, tObj->MagFilter );
+               break;
+
+       case GL_TEXTURE_WRAP_S:
+       case GL_TEXTURE_WRAP_T:
+               s3vSetTexWrapping( vmesa, t, tObj->WrapS, tObj->WrapT );
+               break;
+  
+       case GL_TEXTURE_BORDER_COLOR:
+               s3vSetTexBorderColor( vmesa, t, tObj->BorderColor );
+               break;
+
+       case GL_TEXTURE_BASE_LEVEL:
+       case GL_TEXTURE_MAX_LEVEL:
+       case GL_TEXTURE_MIN_LOD:
+       case GL_TEXTURE_MAX_LOD:
+       /* This isn't the most efficient solution but there doesn't appear to
+        * be a nice alternative for Virge.  Since there's no LOD clamping,
+        * we just have to rely on loading the right subset of mipmap levels
+        * to simulate a clamped LOD.
+        */
+               s3vSwapOutTexObj( vmesa, t ); 
+               break;
+
+       default:
+               return;
+       }
+
+       if (t == vmesa->CurrentTexObj[0])
+               vmesa->dirty |= S3V_UPLOAD_TEX0;
+
+#if 0
+       if (t == vmesa->CurrentTexObj[1]) {
+               vmesa->dirty |= S3V_UPLOAD_TEX1;
+       }
+#endif
+}
+
+
+static void s3vTexEnv( GLcontext *ctx, GLenum target, 
+                       GLenum pname, const GLfloat *param )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+       GLuint unit = ctx->Texture.CurrentUnit;
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vTexEnv: #%i ***\n", ++times));
+#endif
+
+       /* Only one env color.  Need a fallback if env colors are different
+        * and texture setup references env color in both units.  
+        */
+       switch (pname) {
+       case GL_TEXTURE_ENV_COLOR: {
+               struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+               GLfloat *fc = texUnit->EnvColor;
+               GLuint r, g, b, a, col;
+               CLAMPED_FLOAT_TO_UBYTE(r, fc[0]);
+               CLAMPED_FLOAT_TO_UBYTE(g, fc[1]);
+               CLAMPED_FLOAT_TO_UBYTE(b, fc[2]);
+               CLAMPED_FLOAT_TO_UBYTE(a, fc[3]);
+
+               col =  ((a << 24) | 
+                       (r << 16) | 
+                       (g <<  8) | 
+                       (b <<  0));
+
+               break;
+       }
+       case GL_TEXTURE_ENV_MODE:
+               vmesa->TexEnvImageFmt[unit] = 0; /* force recalc of env state */
+               break;
+       case GL_TEXTURE_LOD_BIAS_EXT: {
+/*
+               struct gl_texture_object *tObj =
+                       ctx->Texture.Unit[unit]._Current;
+
+               s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
+*/
+               break;
+       }
+       default:
+               break;
+       }
+} 
+
+static void s3vTexImage1D( GLcontext *ctx, GLenum target, GLint level,
+                           GLint internalFormat,
+                           GLint width, GLint border,
+                           GLenum format, GLenum type, 
+                           const GLvoid *pixels,
+                           const struct gl_pixelstore_attrib *pack,
+                           struct gl_texture_object *texObj,
+                           struct gl_texture_image *texImage )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+       s3vTextureObjectPtr t = (s3vTextureObjectPtr) texObj->DriverData;
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vTexImage1D: #%i ***\n", ++times));
+#endif
+
+#if 1 
+       if (t) {
+#if _TEXFLUSH
+               DMAFLUSH();
+#endif
+               s3vSwapOutTexObj( vmesa, t );
+/*
+               s3vDestroyTexObj( vmesa, t );
+               texObj->DriverData = 0;
+*/
+       }
+#endif
+       _mesa_store_teximage1d( ctx, target, level, internalFormat,
+                               width, border, format, type,
+                               pixels, pack, texObj, texImage );
+}
+
+static void s3vTexSubImage1D( GLcontext *ctx, 
+                              GLenum target,
+                              GLint level,     
+                              GLint xoffset,
+                              GLsizei width,
+                              GLenum format, GLenum type,
+                              const GLvoid *pixels,
+                              const struct gl_pixelstore_attrib *pack,
+                              struct gl_texture_object *texObj,
+                              struct gl_texture_image *texImage )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+       s3vTextureObjectPtr t = (s3vTextureObjectPtr) texObj->DriverData;
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vTexSubImage1D: #%i ***\n", ++times));
+#endif
+
+#if 1
+       if (t) {
+#if _TEXFLUSH
+               DMAFLUSH();
+#endif
+               s3vSwapOutTexObj( vmesa, t );
+/*
+               s3vDestroyTexObj( vmesa, t );
+               texObj->DriverData = 0;
+*/
+       }
+#endif
+       _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, 
+                               format, type, pixels, pack, texObj,
+                               texImage);
+}
+
+static void s3vTexImage2D( GLcontext *ctx, GLenum target, GLint level,
+                           GLint internalFormat,
+                           GLint width, GLint height, GLint border,
+                           GLenum format, GLenum type, const GLvoid *pixels,
+                           const struct gl_pixelstore_attrib *packing,
+                           struct gl_texture_object *texObj,
+                           struct gl_texture_image *texImage )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+       s3vTextureObjectPtr t = (s3vTextureObjectPtr) texObj->DriverData;
+
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vTexImage2D: #%i ***\n", ++times));
+#endif
+
+#if 1 
+       if (t) {
+#if _TEXFLUSH
+               DMAFLUSH();
+#endif
+               s3vSwapOutTexObj( vmesa, t ); 
+/*
+               s3vDestroyTexObj( vmesa, t );
+               texObj->DriverData = 0;
+*/
+       }
+#endif
+       _mesa_store_teximage2d( ctx, target, level, internalFormat,
+                               width, height, border, format, type,
+                               pixels, packing, texObj, texImage );
+}
+
+static void s3vTexSubImage2D( GLcontext *ctx, 
+                              GLenum target,
+                              GLint level,     
+                              GLint xoffset, GLint yoffset,
+                              GLsizei width, GLsizei height,
+                              GLenum format, GLenum type,
+                              const GLvoid *pixels,
+                              const struct gl_pixelstore_attrib *packing,
+                              struct gl_texture_object *texObj,
+                              struct gl_texture_image *texImage )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+       s3vTextureObjectPtr t = (s3vTextureObjectPtr) texObj->DriverData;
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vTexSubImage2D: #%i ***\n", ++times));
+#endif
+
+#if 1
+       if (t) {
+#if _TEXFLUSH
+               DMAFLUSH();
+#endif
+               s3vSwapOutTexObj( vmesa, t );
+/* 
+               s3vDestroyTexObj( vmesa, t );
+               texObj->DriverData = 0;
+*/
+       }
+#endif
+       _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, 
+                               height, format, type, pixels, packing, texObj,
+                               texImage);
+}
+
+
+static void s3vBindTexture( GLcontext *ctx, GLenum target,
+                            struct gl_texture_object *tObj )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+       s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
+       CARD32 cmd = vmesa->CMD;
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vBindTexture: #%i ***\n", ++times));
+#endif
+
+       if (!t) {
+/*
+               GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias;
+*/
+               t = CALLOC_STRUCT(s3v_texture_object_t);
+
+               /* Initialize non-image-dependent parts of the state:
+                */
+               t->globj = tObj;
+#if 0
+               if (target == GL_TEXTURE_2D) {
+               } else
+               if (target == GL_TEXTURE_1D) {
+               }
+
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+               t->TextureFormat = (TF_LittleEndian |
+#else
+               t->TextureFormat = (TF_BigEndian |
+#endif
+#endif
+               t->dirty_images = ~0;
+
+               tObj->DriverData = t;
+               make_empty_list( t );
+#if 0
+               s3vSetTexWrapping( vmesa, t, tObj->WrapS, tObj->WrapT );
+               s3vSetTexFilter( vmesa, t, tObj->MinFilter, tObj->MagFilter );
+               s3vSetTexBorderColor( vmesa, t, tObj->BorderColor );
+#endif
+       }
+
+       if (!ctx->Texture._ReallyEnabled) {
+               DEBUG_TEX(("!ctx->Texture._ReallyEnabled\n"));
+               return; 
+       }
+
+       cmd = vmesa->CMD & ~MIP_MASK;
+    vmesa->dirty |= S3V_UPLOAD_TEX0;
+    vmesa->TexOffset = t->TextureBaseAddr[tObj->BaseLevel];
+    vmesa->TexStride = t->Pitch;
+    cmd |= MIPMAP_LEVEL(t->WidthLog2);
+       vmesa->CMD = cmd;
+       vmesa->restore_primitive = -1;
+#if 0
+       printf("t->TextureBaseAddr[0] = 0x%x\n", t->TextureBaseAddr[0]);
+       printf("t->TextureBaseAddr[1] = 0x%x\n", t->TextureBaseAddr[1]);
+       printf("t->TextureBaseAddr[2] = 0x%x\n", t->TextureBaseAddr[2]);
+#endif
+}
+
+
+static void s3vDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
+{
+       s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vDeleteTexture: #%i ***\n", ++times));
+#endif
+
+       if (t) {
+               s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+
+#if _TEXFLUSH
+               if (vmesa) {
+                       DMAFLUSH();
+               }
+#endif
+
+               s3vDestroyTexObj( vmesa, t );
+               tObj->DriverData = 0;
+
+       }
+}
+
+static GLboolean s3vIsTextureResident( GLcontext *ctx, 
+                                       struct gl_texture_object *tObj )
+{
+       s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vIsTextureResident: #%i ***\n", ++times));
+#endif
+   
+       return (t && t->MemBlock);
+}
+
+static void s3vInitTextureObjects( GLcontext *ctx )
+{
+       /* s3vContextPtr vmesa = S3V_CONTEXT(ctx); */
+       struct gl_texture_object *texObj;
+       GLuint tmp = ctx->Texture.CurrentUnit;
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vInitTextureObjects: #%i ***\n", ++times));
+#endif
+
+#if 1
+       ctx->Texture.CurrentUnit = 0;
+
+       texObj = ctx->Texture.Unit[0].Current1D;
+       s3vBindTexture( ctx, GL_TEXTURE_1D, texObj );
+
+       texObj = ctx->Texture.Unit[0].Current2D;
+       s3vBindTexture( ctx, GL_TEXTURE_2D, texObj );
+#endif
+
+#if 0
+       ctx->Texture.CurrentUnit = 1;
+
+       texObj = ctx->Texture.Unit[1].Current1D;
+       s3vBindTexture( ctx, GL_TEXTURE_1D, texObj );
+
+       texObj = ctx->Texture.Unit[1].Current2D;
+       s3vBindTexture( ctx, GL_TEXTURE_2D, texObj );
+#endif
+
+       ctx->Texture.CurrentUnit = tmp;
+}
+
+
+void s3vInitTextureFuncs( GLcontext *ctx )
+{
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       DEBUG_TEX(("*** s3vInitTextureFuncs: #%i ***\n", ++times));
+#endif
+
+       ctx->Driver.TexEnv = s3vTexEnv;
+       ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
+       ctx->Driver.TexImage1D = _mesa_store_teximage1d;
+       ctx->Driver.TexImage2D = s3vTexImage2D;
+       ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+       ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
+       ctx->Driver.TexSubImage2D = s3vTexSubImage2D;
+       ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+       ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
+       ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
+       ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
+       ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+       ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+       ctx->Driver.BindTexture = s3vBindTexture;
+       ctx->Driver.DeleteTexture = s3vDeleteTexture;
+       ctx->Driver.TexParameter = s3vTexParameter;
+       ctx->Driver.UpdateTexturePalette = 0;
+       ctx->Driver.IsTextureResident = s3vIsTextureResident;
+       ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
+
+       s3vInitTextureObjects( ctx );
+}
diff --git a/src/mesa/drivers/dri/s3v/s3v_tex.h b/src/mesa/drivers/dri/s3v/s3v_tex.h
new file mode 100644 (file)
index 0000000..0bbe267
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#ifndef _S3V_TEX_H
+#define _S3V_TEX_H
+
+#define TEX_DEBUG_ON 0
+
+#if TEX_DEBUG_ON
+        #define DEBUG_TEX(str) printf str
+#else
+        #define DEBUG_TEX(str) /* str */
+#endif
+
+#define _TEXFLUSH 1 /* flush before uploading */
+#define _TEXLOCK  1 /* lock before writing new texures to card mem */
+                                       /*      if you turn it on you will gain stability and image
+                                               quality, but you will loose performance (~10%) */
+#define _TEXFALLBACK 0 /* fallback to software for -big- textures (slow) */
+                                       /* turning this off, you will lose some tex (e.g. mountains
+                                          on tuxracer) but you will increase average playability */
+
+#define _TEXALIGN 0x00000007
+
+#endif
diff --git a/src/mesa/drivers/dri/s3v/s3v_texmem.c b/src/mesa/drivers/dri/s3v/s3v_texmem.c
new file mode 100644 (file)
index 0000000..ab2e67d
--- /dev/null
@@ -0,0 +1,583 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "simple_list.h"
+#include "enums.h"
+
+#include "mm.h"
+#include "mem.h"
+#include "s3v_context.h"
+#include "s3v_lock.h"
+#include "s3v_tex.h"
+
+void s3vSwapOutTexObj(s3vContextPtr vmesa, s3vTextureObjectPtr t);
+void s3vUpdateTexLRU( s3vContextPtr vmesa, s3vTextureObjectPtr t );
+
+
+void s3vDestroyTexObj(s3vContextPtr vmesa, s3vTextureObjectPtr t)
+{
+#if TEX_DEBUG_ON
+   static unsigned int times=0;
+   DEBUG_TEX(("*** s3vDestroyTexObj: #%i ***\n", ++times));
+#endif
+
+   if (!t) return;
+
+/* FIXME: useful? */
+#if _TEXFLUSH
+       if (vmesa)
+               DMAFLUSH();
+#endif
+
+   /* This is sad - need to sync *in case* we upload a texture
+    * to this newly free memory...
+    */
+   if (t->MemBlock) {
+      mmFreeMem(t->MemBlock);
+      t->MemBlock = 0;
+
+      if (vmesa && t->age > vmesa->dirtyAge)
+            vmesa->dirtyAge = t->age;
+   }
+
+   if (t->globj)
+      t->globj->DriverData = NULL;
+
+   if (vmesa) {
+      if (vmesa->CurrentTexObj[0] == t) {
+               vmesa->CurrentTexObj[0] = 0;
+               vmesa->dirty &= ~S3V_UPLOAD_TEX0;
+      }
+
+#if 0
+      if (vmesa->CurrentTexObj[1] == t) {
+         vmesa->CurrentTexObj[1] = 0;
+         vmesa->dirty &= ~S3V_UPLOAD_TEX1;
+      }
+#endif
+   }
+
+   remove_from_list(t);
+   FREE(t);
+}
+
+
+void s3vSwapOutTexObj(s3vContextPtr vmesa, s3vTextureObjectPtr t)
+{
+/*   int i; */
+#if TEX_DEBUG_ON
+   static unsigned int times=0;
+   DEBUG_TEX(("*** s3vSwapOutTexObj: #%i ***\n", ++times));
+#endif
+
+   if (t->MemBlock) {
+
+      mmFreeMem(t->MemBlock);
+      t->MemBlock = 0;
+
+      if (t->age > vmesa->dirtyAge)
+         vmesa->dirtyAge = t->age;
+   
+      t->dirty_images = ~0; 
+      move_to_tail(&(vmesa->SwappedOut), t);
+   }
+}
+
+
+/* Upload an image from mesa's internal copy.
+ */
+
+static void s3vUploadTexLevel( s3vContextPtr vmesa, s3vTextureObjectPtr t,
+                               int level )
+{
+       __DRIscreenPrivate *sPriv = vmesa->driScreen;
+       const struct gl_texture_image *image = t->image[level].image;
+       int i,j;
+       int l2d;
+       /* int offset = 0; */
+       int words;
+       CARD32* dest;
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+#endif
+       if ( !image ) return;
+       if (image->Data == 0) return;
+
+       DEBUG_TEX(("*** s3vUploadTexLevel: #%i ***\n", ++times));
+       DEBUG_TEX(("level = %i\n", level));
+
+       l2d = 5; /* 32bits per texel == 1<<5 */
+/*
+       if (level == 0) 
+               ;
+*/
+       DEBUG_TEX(("t->image[%i].offset = 0x%x\n",
+               level, t->image[level].offset));
+               
+       t->TextureBaseAddr[level] = (CARD32)(t->BufAddr + t->image[level].offset
+               + _TEXALIGN) & (CARD32)(~_TEXALIGN);
+       dest = (CARD32*)(sPriv->pFB + t->TextureBaseAddr[level]); 
+
+       DEBUG_TEX(("sPriv->pFB = 0x%x\n", sPriv->pFB));
+       DEBUG_TEX(("dest = 0x%x\n", dest));
+       DEBUG_TEX(("dest - sPriv->pFB = 0x%x\n", ((int)dest - (int)sPriv->pFB)));
+
+       /* NOTE: we implicitly suppose t->texelBytes == 2 */
+
+       words = (image->Width * image->Height) >> 1;
+
+       DEBUG_TEX(("\n\n"));
+
+       switch (t->image[level].internalFormat) {
+       case GL_RGB:
+       case 3:
+       {
+               GLubyte *src = (GLubyte *)image->Data;
+
+               DEBUG_TEX(("GL_RGB:\n"));
+/*
+               if (level == 0)
+                       ;
+*/
+               /* The UGLY way, and SLOW : use DMA FIXME ! */
+
+               for (i = 0; i < words; i++) {
+               unsigned int data;
+               /* data = PACK_COLOR_565(src[0],src[1],src[2]); */
+               data = S3VIRGEPACKCOLOR555(src[0],src[1],src[2],255)
+                       |(S3VIRGEPACKCOLOR555(src[3],src[4],src[5],255)<<16);
+
+               *dest++ = data;
+               /* src += 3; */
+               src +=6;
+       }
+       }
+       break;
+
+       case GL_RGBA:
+       case 4:
+       {
+               GLubyte *src = (GLubyte *)image->Data;
+
+               DEBUG_TEX(("GL_RGBA:\n"));
+/*
+               if (level == 0)
+                       ;
+*/
+               for (i = 0; i < words; i++) {           
+               unsigned int data;
+               
+               /* data = PACK_COLOR_8888(src[0],src[1],src[2],src[3]); */
+               data = S3VIRGEPACKCOLOR4444(src[0], src[1],src[2], src[3])
+               | (S3VIRGEPACKCOLOR4444(src[4], src[5], src[6], src[7]) << 16);
+               
+               *dest++ = data;
+               /* src += 4; */
+               src += 8;
+               }
+       }
+       break;
+
+       case GL_LUMINANCE:
+       {
+               GLubyte *src = (GLubyte *)image->Data;
+
+               DEBUG_TEX(("GL_LUMINANCE:\n"));
+/*
+               if (level == 0)
+                       ;
+*/
+               for (i = 0; i < words; i++) {
+               unsigned int data;
+               
+               /* data = PACK_COLOR_888(src[0],src[0],src[0]); */
+               data = S3VIRGEPACKCOLOR4444(src[0],src[0],src[0],src[0])
+               | (S3VIRGEPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16);
+                
+               *dest++ = data;
+               /* src ++; */
+               src +=2;
+               }
+       }
+       break;
+
+       case GL_INTENSITY:
+       {
+               GLubyte *src = (GLubyte *)image->Data;
+
+               DEBUG_TEX(("GL_INTENSITY:\n"));
+/*     
+               if (level == 0)
+                       ;
+*/
+               for (i = 0; i < words; i++) {
+               unsigned int data;
+               
+               /* data = PACK_COLOR_8888(src[0],src[0],src[0],src[0]); */
+               data = S3VIRGEPACKCOLOR4444(src[0],src[0],src[0],src[0])
+               | (S3VIRGEPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16);
+
+               *dest++ = data; 
+               /* src ++; */
+               src += 2;
+               }
+       }
+       break;
+
+       case GL_LUMINANCE_ALPHA:
+       {
+               GLubyte *src = (GLubyte *)image->Data;
+
+               DEBUG_TEX(("GL_LUMINANCE_ALPHA:\n"));
+/*
+               if (level == 0)
+                       ;
+*/
+               for (i = 0; i < words; i++) {
+               unsigned int data;
+               
+               /* data = PACK_COLOR_8888(src[0],src[0],src[0],src[1]); */
+               data = S3VIRGEPACKCOLOR4444(src[0],src[0],src[0],src[1])
+               | (S3VIRGEPACKCOLOR4444(src[2],src[2],src[2],src[3]) << 16);
+               
+               *dest++ = data;
+               /* src += 2; */
+               src += 4;
+               }
+       }
+       break;
+
+       case GL_ALPHA:
+       {
+               GLubyte *src = (GLubyte *)image->Data;
+
+               DEBUG_TEX(("GL_ALPHA:\n"));
+/*
+               if (level == 0)
+                       ;
+*/
+               for (i = 0; i < words; i++) {
+               unsigned int data;
+               
+               /* data = PACK_COLOR_8888(255,255,255,src[0]); */
+               data = S3VIRGEPACKCOLOR4444(255,255,255,src[0])
+               | (S3VIRGEPACKCOLOR4444(255,255,255,src[1]) << 16);
+               
+               *dest++ = data;
+               /* src += 1; */
+               src += 2;
+               }
+       }
+       break;
+
+       /* TODO: Translate color indices *now*:
+        */
+       case GL_COLOR_INDEX:
+       {
+       
+               GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[level].offset);
+               GLubyte *src = (GLubyte *)image->Data;
+
+               DEBUG_TEX(("GL_COLOR_INDEX:\n"));
+
+               for (j = 0 ; j < image->Height ; j++, dst += t->Pitch) {
+                       for (i = 0 ; i < image->Width ; i++) {
+                               dst[i] = src[0];
+                               src += 1;
+                       }
+               }
+       }
+       break;
+
+       default:
+               fprintf(stderr, "Not supported texture format %s\n",
+                       _mesa_lookup_enum_by_nr(image->Format));
+       }
+
+       DEBUG_TEX(("words = %i\n\n", words));
+}
+
+void s3vPrintLocalLRU( s3vContextPtr vmesa )
+{
+   s3vTextureObjectPtr t;
+   int sz = 1 << (vmesa->s3vScreen->logTextureGranularity);
+
+#if TEX_DEBUG_ON
+   static unsigned int times=0;
+   DEBUG_TEX(("*** s3vPrintLocalLRU: #%i ***\n", ++times));
+#endif
+
+   foreach( t, &vmesa->TexObjList ) {
+      if (!t->globj)
+         fprintf(stderr, "Placeholder %d at %x sz %x\n",
+                   t->MemBlock->ofs / sz,
+                   t->MemBlock->ofs,
+                   t->MemBlock->size);
+      else
+         fprintf(stderr, "Texture at %x sz %x\n",
+                   t->MemBlock->ofs,
+                   t->MemBlock->size);
+
+   }
+}
+
+void s3vPrintGlobalLRU( s3vContextPtr vmesa )
+{
+   int i, j;
+   S3VTexRegionPtr list = vmesa->sarea->texList;
+#if TEX_DEBUG_ON
+   static unsigned int times=0;
+   DEBUG_TEX(("*** s3vPrintGlobalLRU: #%i ***\n", ++times));
+#endif
+
+   for (i = 0, j = S3V_NR_TEX_REGIONS ; i < S3V_NR_TEX_REGIONS ; i++) {
+      fprintf(stderr, "list[%d] age %d next %d prev %d\n",
+             j, list[j].age, list[j].next, list[j].prev);
+      j = list[j].next;
+      if (j == S3V_NR_TEX_REGIONS) break;
+   }
+
+   if (j != S3V_NR_TEX_REGIONS)
+      fprintf(stderr, "Loop detected in global LRU\n");
+}
+
+
+void s3vResetGlobalLRU( s3vContextPtr vmesa )
+{
+   S3VTexRegionPtr list = vmesa->sarea->texList;
+   int sz = 1 << vmesa->s3vScreen->logTextureGranularity;
+   int i;
+
+#if TEX_DEBUG_ON
+   static unsigned int times=0;
+   DEBUG_TEX(("*** s3vResetGlobalLRU: #%i ***\n", ++times));
+#endif
+
+   /* (Re)initialize the global circular LRU list.  The last element
+    * in the array (S3V_NR_TEX_REGIONS) is the sentinal.  Keeping it
+    * at the end of the array allows it to be addressed rationally
+    * when looking up objects at a particular location in texture
+    * memory.
+    */
+   for (i = 0 ; (i+1) * sz <= vmesa->s3vScreen->textureSize ; i++) {
+      list[i].prev = i-1;
+      list[i].next = i+1;
+      list[i].age = 0;
+   }
+
+   i--;
+   list[0].prev = S3V_NR_TEX_REGIONS;
+   list[i].prev = i-1;
+   list[i].next = S3V_NR_TEX_REGIONS;
+   list[S3V_NR_TEX_REGIONS].prev = i;
+   list[S3V_NR_TEX_REGIONS].next = 0;
+   vmesa->sarea->texAge = 0;
+}
+
+
+void s3vUpdateTexLRU( s3vContextPtr vmesa, s3vTextureObjectPtr t )
+{
+/*
+   int i;
+   int logsz = vmesa->s3vScreen->logTextureGranularity;
+   int start = t->MemBlock->ofs >> logsz;
+   int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz;
+   S3VTexRegionPtr list = vmesa->sarea->texList;
+*/
+
+#if TEX_DEBUG_ON
+   static unsigned int times=0;
+   DEBUG_TEX(("*** s3vUpdateTexLRU: #%i ***\n", ++times));
+#endif
+
+   vmesa->texAge = ++vmesa->sarea->texAge;
+
+   /* Update our local LRU
+    */
+   move_to_head( &(vmesa->TexObjList), t );
+
+   /* Update the global LRU
+    */
+#if 0
+   for (i = start ; i <= end ; i++) {
+
+      list[i].in_use = 1;
+      list[i].age = vmesa->texAge;
+
+      /* remove_from_list(i)
+       */
+      list[(unsigned)list[i].next].prev = list[i].prev;
+      list[(unsigned)list[i].prev].next = list[i].next;
+
+      /* insert_at_head(list, i)
+       */
+      list[i].prev = S3V_NR_TEX_REGIONS;
+      list[i].next = list[S3V_NR_TEX_REGIONS].next;
+      list[(unsigned)list[S3V_NR_TEX_REGIONS].next].prev = i;
+      list[S3V_NR_TEX_REGIONS].next = i;
+   }
+#endif
+}
+
+
+/* Called for every shared texture region which has increased in age
+ * since we last held the lock.
+ *
+ * Figures out which of our textures have been ejected by other clients,
+ * and pushes a placeholder texture onto the LRU list to represent
+ * the other client's textures.
+ */
+void s3vTexturesGone( s3vContextPtr vmesa,
+                      GLuint offset,
+                      GLuint size,
+                      GLuint in_use )
+{
+   s3vTextureObjectPtr t, tmp;
+#if TEX_DEBUG_ON
+   static unsigned int times=0;
+   DEBUG_TEX(("*** s3vTexturesGone: #%i ***\n", ++times));
+#endif
+
+   foreach_s ( t, tmp, &vmesa->TexObjList ) {
+
+      if (t->MemBlock->ofs >= offset + size ||
+         t->MemBlock->ofs + t->MemBlock->size <= offset)
+         continue;
+
+      /* It overlaps - kick it off.  Need to hold onto the currently bound
+       * objects, however.
+       */
+         s3vSwapOutTexObj( vmesa, t );
+   }
+
+   if (in_use) {
+                  t = (s3vTextureObjectPtr) calloc(1,sizeof(*t));
+                  if (!t) return;
+
+                  t->MemBlock = mmAllocMem( vmesa->texHeap, size, 0, offset);
+                  insert_at_head( &vmesa->TexObjList, t );
+   }
+
+   /* Reload any lost textures referenced by current vertex buffer.
+       */
+#if 0
+   if (vmesa->vertex_buffer) {
+                  int i, j;
+
+                  fprintf(stderr, "\n\nreload tex\n");
+
+                  for (i = 0 ; i < vmesa->statenr ; i++) {
+                                  for (j = 0 ; j < 2 ; j++) {
+                                                  s3vTextureObjectPtr t = vmesa->state_tex[j][i];
+                                                  if (t) {
+                                                                  if (t->MemBlock == 0)
+                                                                                  s3vUploadTexImages( vmesa, t );
+                                                  }
+                                  }
+                  }
+
+                  /* Hard to do this with the lock held:
+                       */
+                  /*        S3V_FIREVERTICES( vmesa ); */
+   }
+#endif
+}
+
+
+/* This is called with the lock held.  May have to eject our own and/or
+ * other client's texture objects to make room for the upload.
+ */
+void s3vUploadTexImages( s3vContextPtr vmesa, s3vTextureObjectPtr t )
+{
+       int i;
+       int ofs;
+       int numLevels;
+#if TEX_DEBUG_ON
+       static unsigned int times=0;
+       static unsigned int try=0;
+
+       DEBUG_TEX(("*** s3vUploadTexImages: #%i ***\n", ++times));
+       DEBUG_TEX(("vmesa->texHeap = 0x%x; t->totalSize = %i\n",
+               (unsigned int)vmesa->texHeap, t->totalSize));
+#endif
+
+       /* Do we need to eject LRU texture objects?
+        */
+       if (!t->MemBlock) {
+
+               while (1)
+               {
+                       /* int try = 0; */
+                       DEBUG_TEX(("trying to alloc mem for tex (try %i)\n", ++try));
+
+                       t->MemBlock = mmAllocMem( vmesa->texHeap, t->totalSize, 12, 0 );
+
+                       if (t->MemBlock)
+                               break;
+
+                       if (vmesa->TexObjList.prev == vmesa->CurrentTexObj[0]) {
+/*                         || vmesa->TexObjList.prev == vmesa->CurrentTexObj[1]) {
+                               fprintf(stderr, "Hit bound texture in upload\n");
+                               s3vPrintLocalLRU( vmesa ); */
+                               return;
+                       }
+
+                       if (vmesa->TexObjList.prev == &(vmesa->TexObjList)) {
+/*                             fprintf(stderr, "Failed to upload texture, sz %d\n",
+                                       t->totalSize);
+                               mmDumpMemInfo( vmesa->texHeap ); */
+                               return;
+                       }
+
+                       DEBUG_TEX(("swapping out: %p\n", vmesa->TexObjList.prev));
+                       s3vSwapOutTexObj( vmesa, vmesa->TexObjList.prev );
+               }
+
+       ofs = t->MemBlock->ofs;
+
+       t->BufAddr = vmesa->s3vScreen->texOffset + ofs;
+
+       DEBUG_TEX(("ofs = 0x%x\n", ofs));
+       DEBUG_TEX(("t->BufAddr = 0x%x\n", t->BufAddr));
+
+/* FIXME: check if we need it */
+#if 0
+       if (t == vmesa->CurrentTexObj[0]) {
+               vmesa->dirty |= S3V_UPLOAD_TEX0; 
+               vmesa->restore_primitive = -1; 
+       }
+#endif
+
+#if 0
+       if (t == vmesa->CurrentTexObj[1])
+               vmesa->dirty |= S3V_UPLOAD_TEX1;
+#endif
+
+       s3vUpdateTexLRU( vmesa, t );
+       }
+
+#if 0
+       if (vmesa->dirtyAge >= GET_DISPATCH_AGE(vmesa))
+               s3vWaitAgeLocked( vmesa, vmesa->dirtyAge );
+#endif
+
+#if _TEXLOCK
+       S3V_SIMPLE_FLUSH_LOCK(vmesa);
+#endif
+       numLevels = t->lastLevel - t->firstLevel + 1;
+       for (i = 0 ; i < numLevels ; i++)
+               if (t->dirty_images & (1<<i))
+                       s3vUploadTexLevel( vmesa, t, i );
+
+       t->dirty_images = 0;
+#if _TEXLOCK
+       S3V_SIMPLE_UNLOCK(vmesa);
+#endif
+}
diff --git a/src/mesa/drivers/dri/s3v/s3v_texstate.c b/src/mesa/drivers/dri/s3v/s3v_texstate.c
new file mode 100644 (file)
index 0000000..7141e39
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "simple_list.h"
+#include "enums.h"
+
+#include "mm.h"
+#include "s3v_context.h"
+#include "s3v_tex.h"
+
+
+static void s3vSetTexImages( s3vContextPtr vmesa, 
+                             struct gl_texture_object *tObj )
+{
+   GLuint height, width, pitch, i, /*textureFormat,*/ log_pitch;
+   s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
+   const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel];
+   GLint firstLevel, lastLevel, numLevels;
+   GLint log2Width, log2Height;
+#if TEX_DEBUG_ON
+   static unsigned int times=0;
+   DEBUG_TEX(("*** s3vSetTexImages: #%i ***\n", ++times));
+#endif
+
+   t->texelBytes = 2; /* FIXME: always 2 ? */
+
+   /* Compute which mipmap levels we really want to send to the hardware.
+    * This depends on the base image size, GL_TEXTURE_MIN_LOD,
+    * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
+    * Yes, this looks overly complicated, but it's all needed.
+    */
+   if (tObj->MinFilter == GL_LINEAR || tObj->MinFilter == GL_NEAREST) {
+      firstLevel = lastLevel = tObj->BaseLevel;
+   }
+   else {
+      firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
+      firstLevel = MAX2(firstLevel, tObj->BaseLevel);
+      lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
+         lastLevel = MAX2(lastLevel, tObj->BaseLevel);
+      lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
+      lastLevel = MIN2(lastLevel, tObj->MaxLevel);
+      lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
+   }
+
+   /* save these values */
+   t->firstLevel = firstLevel;
+   t->lastLevel = lastLevel;
+
+   numLevels = lastLevel - firstLevel + 1;
+
+   log2Width = tObj->Image[firstLevel]->WidthLog2;
+   log2Height = tObj->Image[firstLevel]->HeightLog2;
+
+
+   /* Figure out the amount of memory required to hold all the mipmap
+    * levels.  Choose the smallest pitch to accomodate the largest
+    * mipmap:
+    */
+   width = tObj->Image[firstLevel]->Width * t->texelBytes;
+   for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 )
+      log_pitch++;
+   
+   /* All images must be loaded at this pitch.  Count the number of
+    * lines required:
+    */
+   for ( height = i = 0 ; i < numLevels ; i++ ) {
+      t->image[i].image = tObj->Image[firstLevel + i];
+      t->image[i].offset = height * pitch;
+      t->image[i].internalFormat = baseImage->Format;
+      height += t->image[i].image->Height;
+      t->TextureBaseAddr[i] = (t->BufAddr + t->image[i].offset +
+         _TEXALIGN) & (CARD32)(~_TEXALIGN);
+   }
+
+   t->Pitch = pitch;
+   t->WidthLog2 = log2Width;
+   t->totalSize = height*pitch;
+   t->max_level = i-1;
+   vmesa->dirty |= S3V_UPLOAD_TEX0 /* | S3V_UPLOAD_TEX1*/;   
+   vmesa->restore_primitive = -1;
+   DEBUG(("<><>pitch = TexStride = %i\n", pitch));
+   DEBUG(("log2Width = %i\n", log2Width));
+
+   s3vUploadTexImages( vmesa, t );
+}
+
+static void s3vUpdateTexEnv( GLcontext *ctx, GLuint unit )
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+   const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+   const struct gl_texture_object *tObj = texUnit->_Current;
+   const GLuint format = tObj->Image[tObj->BaseLevel]->Format;
+/*
+   s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
+   GLuint tc;
+*/
+   GLuint alpha = 0;
+   CARD32 cmd = vmesa->CMD;
+#if TEX_DEBUG_ON
+   static unsigned int times=0;
+   DEBUG_TEX(("*** s3vUpdateTexEnv: %i ***\n", ++times));
+#endif
+
+   cmd &= ~TEX_COL_MASK;
+   cmd &= ~TEX_BLEND_MAKS;
+/*   cmd &= ~ALPHA_BLEND_MASK; */
+
+   DEBUG(("format = "));
+
+   switch (format) {
+   case GL_RGB:
+      DEBUG_TEX(("GL_RGB\n"));
+      cmd |= TEX_COL_ARGB1555;
+      break;
+   case GL_LUMINANCE:
+      DEBUG_TEX(("GL_LUMINANCE\n"));
+      cmd |= TEX_COL_ARGB4444;
+      alpha = 1; /* FIXME: check */
+      break;
+   case GL_ALPHA:
+      DEBUG_TEX(("GL_ALPHA\n"));
+      cmd |= TEX_COL_ARGB4444;
+      alpha = 1;
+      break;
+   case GL_LUMINANCE_ALPHA:
+      DEBUG_TEX(("GL_LUMINANCE_ALPHA\n"));
+      cmd |= TEX_COL_ARGB4444;
+      alpha = 1;
+      break;
+   case GL_INTENSITY:
+      DEBUG_TEX(("GL_INTENSITY\n"));
+      cmd |= TEX_COL_ARGB4444;
+      alpha = 1;
+      break;
+   case GL_RGBA:
+      DEBUG_TEX(("GL_RGBA\n"));
+      cmd |= TEX_COL_ARGB4444;
+      alpha = 1;
+      break;
+   case GL_COLOR_INDEX:
+      DEBUG_TEX(("GL_COLOR_INDEX\n"));
+      cmd |= TEX_COL_PAL;
+      break;
+   }
+
+   DEBUG_TEX(("EnvMode = "));
+
+   switch (texUnit->EnvMode) {
+   case GL_REPLACE:
+      DEBUG_TEX(("GL_REPLACE\n"));
+      cmd |= TEX_REFLECT; /* FIXME */
+      vmesa->_tri[1] = DO_TEX_UNLIT_TRI; /* FIXME: white tri hack */
+      vmesa->_alpha_tex = ALPHA_TEX /* * alpha */;
+      break;
+   case GL_MODULATE:
+      DEBUG_TEX(("GL_MODULATE\n"));
+      cmd |= TEX_MODULATE;
+      vmesa->_tri[1] = DO_TEX_LIT_TRI;
+#if 0
+       if (alpha)
+               vmesa->_alpha_tex = ALPHA_TEX /* * alpha */;
+       else
+               vmesa->_alpha_tex = ALPHA_SRC /* * alpha */;
+#else
+       vmesa->_alpha_tex = ALPHA_TEX ;
+#endif
+      break;
+   case GL_ADD:
+      DEBUG_TEX(("DEBUG_TEX\n"));
+      /* do nothing ???*/
+      break;
+   case GL_DECAL:
+      DEBUG_TEX(("GL_DECAL\n"));
+      cmd |= TEX_DECAL;
+      vmesa->_tri[1] = DO_TEX_LIT_TRI;
+      vmesa->_alpha_tex = ALPHA_OFF;
+      break;
+   case GL_BLEND:
+      DEBUG_TEX(("GL_BLEND\n"));
+      cmd |= TEX_DECAL;
+      vmesa->_tri[1] = DO_TEX_LIT_TRI;
+      vmesa->_alpha_tex = ALPHA_OFF; /* FIXME: sure? */
+      break;
+   default:
+      fprintf(stderr, "unknown tex env mode");
+      return;
+   }
+  
+   DEBUG_TEX(("\n\n    vmesa->CMD was 0x%x\n", vmesa->CMD));   
+   DEBUG_TEX((   "    vmesa->CMD is 0x%x\n\n", cmd ));
+
+   vmesa->_alpha[1] = vmesa->_alpha_tex;
+   vmesa->CMD = cmd; /* | MIPMAP_LEVEL(8); */
+   vmesa->restore_primitive = -1; 
+}
+
+static void s3vUpdateTexUnit( GLcontext *ctx, GLuint unit )
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+   CARD32 cmd = vmesa->CMD;
+#if TEX_DEBUG_ON
+   static unsigned int times=0;
+   DEBUG_TEX(("*** s3vUpdateTexUnit: %i ***\n", ++times));
+   DEBUG_TEX(("and vmesa->CMD was 0x%x\n", vmesa->CMD));
+#endif
+
+   if (texUnit->_ReallyEnabled == TEXTURE0_2D) 
+   {
+      struct gl_texture_object *tObj = texUnit->_Current;
+      s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
+
+      /* Upload teximages (not pipelined)
+       */
+      if (t->dirty_images) {
+#if _TEXFLUSH
+         DMAFLUSH();
+#endif
+         s3vSetTexImages( vmesa, tObj ); 
+         if (!t->MemBlock) {
+#if _TEXFALLBACK
+            FALLBACK( vmesa, S3V_FALLBACK_TEXTURE, GL_TRUE );
+#endif
+            return;
+         }
+      }
+
+      /* Update state if this is a different texture object to last
+       * time.
+       */
+#if 1
+      if (vmesa->CurrentTexObj[unit] != t) {
+         vmesa->dirty |= S3V_UPLOAD_TEX0 /* << unit */;
+         vmesa->CurrentTexObj[unit] = t;
+         s3vUpdateTexLRU( vmesa, t ); /* done too often */
+      }
+#endif
+      
+      /* Update texture environment if texture object image format or 
+       * texture environment state has changed.
+       */
+      if (tObj->Image[tObj->BaseLevel]->Format != vmesa->TexEnvImageFmt[unit]) {
+         vmesa->TexEnvImageFmt[unit] = tObj->Image[tObj->BaseLevel]->Format;
+         s3vUpdateTexEnv( ctx, unit );
+      }
+#if 1
+      cmd = vmesa->CMD & ~MIP_MASK;
+      vmesa->dirty |= S3V_UPLOAD_TEX0 /* << unit */;
+      vmesa->CurrentTexObj[unit] = t;
+      vmesa->TexOffset = t->TextureBaseAddr[tObj->BaseLevel];
+      vmesa->TexStride = t->Pitch;
+      cmd |= MIPMAP_LEVEL(t->WidthLog2);
+       
+      DEBUG_TEX(("\n\n>>  vmesa->CMD was 0x%x\n", vmesa->CMD));
+      DEBUG_TEX((    ">>  vmesa->CMD is 0x%x\n\n", cmd ));
+      DEBUG_TEX(("t->WidthLog2 = %i\n", t->WidthLog2));
+      DEBUG_TEX(("MIPMAP_LEVEL(t->WidthLog2) = 0x%x\n", MIPMAP_LEVEL(t->WidthLog2)));
+
+      vmesa->CMD = cmd;
+      vmesa->restore_primitive = -1;
+#endif
+   }
+   else if (texUnit->_ReallyEnabled) { /* _ReallyEnabled but != TEXTURE0_2D */
+#if _TEXFALLBACK
+      FALLBACK( vmesa, S3V_FALLBACK_TEXTURE, GL_TRUE );
+#endif
+   }
+   else /*if (vmesa->CurrentTexObj[unit])*/ { /* !_ReallyEnabled */
+      vmesa->CurrentTexObj[unit] = 0;
+      vmesa->TexEnvImageFmt[unit] = 0; 
+      vmesa->dirty &= ~(S3V_UPLOAD_TEX0<<unit); 
+   }
+}
+
+
+void s3vUpdateTextureState( GLcontext *ctx )
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+#if TEX_DEBUG_ON
+   static unsigned int times=0;
+   DEBUG_TEX(("*** s3vUpdateTextureState: #%i ***\n", ++times));
+#endif
+
+   if (!ctx->Texture._ReallyEnabled) {
+               DEBUG_TEX(("!ctx->Texture._ReallyEnabled\n"));
+               return;
+   }
+
+#if _TEXFALLBACK   
+   FALLBACK( vmesa, S3V_FALLBACK_TEXTURE, GL_FALSE );
+#endif
+   s3vUpdateTexUnit( ctx, 0 );
+#if 0
+   s3vUpdateTexUnit( ctx, 1 );
+#endif
+}
diff --git a/src/mesa/drivers/dri/s3v/s3v_tris.c b/src/mesa/drivers/dri/s3v/s3v_tris.c
new file mode 100644 (file)
index 0000000..3b52340
--- /dev/null
@@ -0,0 +1,850 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/ioctl.h>
+
+#include "s3v_context.h"
+#include "s3v_vb.h"
+#include "s3v_tris.h"
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "colormac.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+
+/***********************************************************************
+ *                   Build hardware rasterization functions            *
+ ***********************************************************************/
+
+#define DO_TRI                 1
+#define HAVE_RGBA              1
+#define HAVE_SPEC              0
+#define HAVE_BACK_COLORS       0
+#define HAVE_HW_FLATSHADE      1
+#define VERTEX                 s3vVertex
+#define TAB                            rast_tab
+
+#define VERT_SET_RGBA( v, c ) \
+do { \
+       UNCLAMPED_FLOAT_TO_RGBA_CHAN( v->ub4[4], c); \
+/*     *(v->ub4[4]) = c; \ */ \
+} while (0)
+#define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4]
+/*
+#define VERT_COPY_RGBA1( v0, v1 ) v0->ui[4] = v1->ui[4]
+*/
+#define VERT_SAVE_RGBA( idx )    color[idx] = v[idx]->ui[4]
+#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx]
+
+#define S3V_OFFSET_BIT         0x01
+#define S3V_TWOSIDE_BIT        0x02
+#define S3V_UNFILLED_BIT        0x04
+#define S3V_FALLBACK_BIT        0x08
+#define S3V_MAX_TRIFUNC        0x10
+
+
+static struct {
+       points_func     points;
+       line_func       line;
+       triangle_func   triangle;
+       quad_func       quad;
+} rast_tab[S3V_MAX_TRIFUNC];
+
+#define S3V_RAST_CULL_BIT      0x01
+#define S3V_RAST_FLAT_BIT      0x02
+#define S3V_RAST_TEX_BIT       0x04
+
+static s3v_point_func s3v_point_tab[0x8];
+static s3v_line_func s3v_line_tab[0x8];
+static s3v_tri_func s3v_tri_tab[0x8];
+static s3v_quad_func s3v_quad_tab[0x8];
+
+#define IND (0)
+#define TAG(x) x
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_CULL_BIT)
+#define TAG(x) x##_cull
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_FLAT_BIT)
+#define TAG(x) x##_flat
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_CULL_BIT|S3V_RAST_FLAT_BIT)
+#define TAG(x) x##_cull_flat
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_TEX_BIT)
+#define TAG(x) x##_tex
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_CULL_BIT|S3V_RAST_TEX_BIT)
+#define TAG(x) x##_cull_tex
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_FLAT_BIT|S3V_RAST_TEX_BIT)
+#define TAG(x) x##_flat_tex
+#include "s3v_tritmp.h"
+
+#define IND (S3V_RAST_CULL_BIT|S3V_RAST_FLAT_BIT|S3V_RAST_TEX_BIT)
+#define TAG(x) x##_cull_flat_tex
+#include "s3v_tritmp.h"
+
+static void init_rast_tab( void )
+{
+       DEBUG(("*** init_rast_tab ***\n"));
+
+       s3v_init();
+       s3v_init_cull();
+       s3v_init_flat();
+       s3v_init_cull_flat();
+       s3v_init_tex();
+       s3v_init_cull_tex();
+       s3v_init_flat_tex();
+       s3v_init_cull_flat_tex();
+}
+
+/***********************************************************************
+ *                    Rasterization fallback helpers                   *
+ ***********************************************************************/
+
+
+/* This code is hit only when a mix of accelerated and unaccelerated
+ * primitives are being drawn, and only for the unaccelerated
+ * primitives.  
+ */
+
+#if 0
+static void 
+s3v_fallback_quad( s3vContextPtr vmesa, 
+                   const s3vVertex *v0, 
+                   const s3vVertex *v1, 
+                   const s3vVertex *v2, 
+                   const s3vVertex *v3 )
+{
+   GLcontext *ctx = vmesa->glCtx;
+   SWvertex v[4];
+   s3v_translate_vertex( ctx, v0, &v[0] );
+   s3v_translate_vertex( ctx, v1, &v[1] );
+   s3v_translate_vertex( ctx, v2, &v[2] );
+   s3v_translate_vertex( ctx, v3, &v[3] );
+   DEBUG(("s3v_fallback_quad\n"));
+/*   _swrast_Quad( ctx, &v[0], &v[1], &v[2], &v[3] ); */
+}
+
+static void 
+s3v_fallback_tri( s3vContextPtr vmesa, 
+                   const s3vVertex *v0, 
+                   const s3vVertex *v1, 
+                   const s3vVertex *v2 )
+{
+   GLcontext *ctx = vmesa->glCtx;
+   SWvertex v[3];
+   s3v_translate_vertex( ctx, v0, &v[0] );
+   s3v_translate_vertex( ctx, v1, &v[1] );
+   s3v_translate_vertex( ctx, v2, &v[2] );
+   DEBUG(("s3v_fallback_tri\n"));
+/*   _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); */
+}
+
+static void
+s3v_fallback_line( s3vContextPtr vmesa,
+                    const s3vVertex *v0,
+                    const s3vVertex *v1 )
+{
+   GLcontext *ctx = vmesa->glCtx;
+   SWvertex v[2];
+   s3v_translate_vertex( ctx, v0, &v[0] );
+   s3v_translate_vertex( ctx, v1, &v[1] );
+   DEBUG(("s3v_fallback_line\n"));
+   _swrast_Line( ctx, &v[0], &v[1] );
+}
+
+/*
+static void 
+s3v_fallback_point( s3vContextPtr vmesa, 
+                     const s3vVertex *v0 )
+{
+   GLcontext *ctx = vmesa->glCtx;
+   SWvertex v[1];
+   s3v_translate_vertex( ctx, v0, &v[0] );
+   _swrast_Point( ctx, &v[0] );
+}
+*/
+#endif
+
+/***********************************************************************
+ *                    Choose rasterization functions                   *
+ ***********************************************************************/
+
+#define _S3V_NEW_RASTER_STATE  (_NEW_FOG | \
+                                _NEW_TEXTURE | \
+                                _DD_NEW_TRI_SMOOTH | \
+                                _DD_NEW_LINE_SMOOTH | \
+                                _DD_NEW_POINT_SMOOTH | \
+                                _DD_NEW_TRI_STIPPLE | \
+                                _DD_NEW_LINE_STIPPLE)
+
+#define LINE_FALLBACK (0)
+#define TRI_FALLBACK (0)
+
+static void s3v_nodraw_triangle(GLcontext *ctx, s3vVertex *v0,
+                                s3vVertex *v1, s3vVertex *v2)
+{
+       (void) (ctx && v0 && v1 && v2);
+}
+
+static void s3v_nodraw_quad(GLcontext *ctx,
+                            s3vVertex *v0, s3vVertex *v1,
+                            s3vVertex *v2, s3vVertex *v3)
+{
+       (void) (ctx && v0 && v1 && v2 && v3);
+}
+
+void s3vChooseRasterState(GLcontext *ctx);
+
+void s3vChooseRasterState(GLcontext *ctx)
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       GLuint flags = ctx->_TriangleCaps;
+       GLuint ind = 0;
+
+       DEBUG(("*** s3vChooseRasterState ***\n"));
+
+       if (ctx->Polygon.CullFlag) {
+               if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
+                       vmesa->draw_tri = (s3v_tri_func)s3v_nodraw_triangle;
+                       vmesa->draw_quad = (s3v_quad_func)s3v_nodraw_quad;
+                       return;
+               }
+               ind |= S3V_RAST_CULL_BIT;
+               /* s3v_update_cullsign(ctx); */
+       } /* else vmesa->backface_sign = 0; */
+
+       if ( flags & DD_FLATSHADE )
+               ind |= S3V_RAST_FLAT_BIT;
+
+       if ( ctx->Texture._ReallyEnabled ) {
+               ind |= S3V_RAST_TEX_BIT;
+       }
+
+       DEBUG(("ind = %i\n", ind));
+
+       vmesa->draw_line = s3v_line_tab[ind];
+       vmesa->draw_tri = s3v_tri_tab[ind];
+       vmesa->draw_quad = s3v_quad_tab[ind];
+       vmesa->draw_point = s3v_point_tab[ind];
+
+#if 0
+       /* Hook in fallbacks for specific primitives.  CURRENTLY DISABLED
+        */
+       
+       if (flags & LINE_FALLBACK) 
+               vmesa->draw_line = s3v_fallback_line;
+        
+       if (flags & TRI_FALLBACK) {
+               DEBUG(("TRI_FALLBACK\n"));
+               vmesa->draw_tri = s3v_fallback_tri;
+               vmesa->draw_quad = s3v_fallback_quad;
+       }
+#endif
+}
+
+
+
+
+/***********************************************************************
+ *          Macros for t_dd_tritmp.h to draw basic primitives          *
+ ***********************************************************************/
+
+#define TRI( v0, v1, v2 ) \
+do { \
+       /*
+       if (DO_FALLBACK) \
+               vmesa->draw_tri( vmesa, v0, v1, v2 ); \
+       else */ \
+       DEBUG(("TRI: max was here\n")); /* \
+       s3v_draw_tex_triangle( vmesa, v0, v1, v2 ); */ \
+       vmesa->draw_tri( vmesa, v0, v1, v2 ); \
+} while (0)
+
+#define QUAD( v0, v1, v2, v3 ) \
+do { \
+       DEBUG(("QUAD: max was here\n")); \
+       vmesa->draw_quad( vmesa, v0, v1, v2, v3 ); \
+} while (0)
+
+#define LINE( v0, v1 ) \
+do { \
+       DEBUG(("LINE: max was here\n")); \
+       vmesa->draw_line( vmesa, v0, v1 ); \
+} while (0)
+
+#define POINT( v0 ) \
+do { \
+       vmesa->draw_point( vmesa, v0 ); \
+} while (0)
+
+
+/***********************************************************************
+ *              Build render functions from dd templates               *
+ ***********************************************************************/
+
+/*
+#define S3V_OFFSET_BIT         0x01
+#define S3V_TWOSIDE_BIT        0x02
+#define S3V_UNFILLED_BIT       0x04
+#define S3V_FALLBACK_BIT       0x08
+#define S3V_MAX_TRIFUNC        0x10
+
+
+static struct {
+   points_func         points;
+   line_func           line;
+   triangle_func       triangle;
+   quad_func           quad;
+} rast_tab[S3V_MAX_TRIFUNC];
+*/
+
+#define DO_FALLBACK  (IND & S3V_FALLBACK_BIT)
+#define DO_OFFSET    (IND & S3V_OFFSET_BIT)
+#define DO_UNFILLED  (IND & S3V_UNFILLED_BIT)
+#define DO_TWOSIDE   (IND & S3V_TWOSIDE_BIT)
+#define DO_FLAT      0
+#define DO_TRI       1
+#define DO_QUAD      1
+#define DO_LINE      1
+#define DO_POINTS    1
+#define DO_FULL_QUAD 1
+
+#define HAVE_RGBA         1
+#define HAVE_SPEC         0
+#define HAVE_BACK_COLORS  0
+#define HAVE_HW_FLATSHADE 1
+#define VERTEX            s3vVertex
+#define TAB               rast_tab
+
+#define DEPTH_SCALE 1.0
+#define UNFILLED_TRI unfilled_tri
+#define UNFILLED_QUAD unfilled_quad
+#define VERT_X(_v) _v->v.x
+#define VERT_Y(_v) _v->v.y
+#define VERT_Z(_v) _v->v.z
+#define AREA_IS_CCW( a ) (a > 0)
+#define GET_VERTEX(e) (vmesa->verts + (e<<vmesa->vertex_stride_shift))
+
+#if 0
+#define VERT_SET_RGBA( v, c ) \
+do { \
+/*    UNCLAMPED_FLOAT_TO_RGBA_CHAN( v->ub4[4], c) */ \
+} while (0)
+
+#define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4]
+/*
+#define VERT_COPY_RGBA1( v0, v1 ) v0->ui[4] = v1->ui[4]
+*/
+#define VERT_SAVE_RGBA( idx )    color[idx] = v[idx]->ui[4]
+#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx]   
+#endif
+
+#define LOCAL_VARS(n) \
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
+       GLuint color[n]; \
+       (void) color;
+
+
+/***********************************************************************
+ *                Helpers for rendering unfilled primitives            *
+ ***********************************************************************/
+
+static const GLuint hw_prim[GL_POLYGON+1] = {
+       PrimType_Points,
+       PrimType_Lines,
+       PrimType_Lines,
+       PrimType_Lines,
+       PrimType_Triangles,
+       PrimType_Triangles,
+       PrimType_Triangles,
+       PrimType_Triangles,
+       PrimType_Triangles,
+       PrimType_Triangles
+};
+
+static void s3vResetLineStipple( GLcontext *ctx );
+static void s3vRasterPrimitive( GLcontext *ctx, GLuint hwprim );
+static void s3vRenderPrimitive( GLcontext *ctx, GLenum prim );
+/*
+extern static void s3v_lines_emit(GLcontext *ctx, GLuint start, GLuint end);
+extern static void s3v_tris_emit(GLcontext *ctx, GLuint start, GLuint end);
+*/
+#define RASTERIZE(x) if (vmesa->hw_primitive != hw_prim[x]) \
+                        s3vRasterPrimitive( ctx, hw_prim[x] )
+#define RENDER_PRIMITIVE vmesa->render_primitive
+#define TAG(x) x
+#define IND S3V_FALLBACK_BIT
+#include "tnl_dd/t_dd_unfilled.h"
+#undef IND
+
+/***********************************************************************
+ *                      Generate GL render functions                   *
+ ***********************************************************************/
+
+#define IND (0)
+#define TAG(x) x
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_TWOSIDE_BIT|S3V_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_UNFILLED_BIT)
+#define TAG(x) x##_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_OFFSET_BIT|S3V_UNFILLED_BIT)
+#define TAG(x) x##_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_TWOSIDE_BIT|S3V_UNFILLED_BIT)
+#define TAG(x) x##_twoside_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (S3V_TWOSIDE_BIT|S3V_OFFSET_BIT|S3V_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+
+static void init_render_tab( void )
+{
+       DEBUG(("*** init_render_tab ***\n"));
+
+       init();
+       init_offset();
+       init_twoside();
+       init_twoside_offset();
+       init_unfilled();
+       init_offset_unfilled();
+       init_twoside_unfilled();
+       init_twoside_offset_unfilled();
+}
+
+
+/**********************************************************************/
+/*               Render unclipped begin/end objects                   */
+/**********************************************************************/
+
+#define VERT(x) (s3vVertex *)(s3vverts + (x << shift))
+
+#define RENDER_POINTS( start, count ) \
+       DEBUG(("RENDER_POINTS...(ok)\n")); \
+       for ( ; start < count ; start++) \
+               vmesa->draw_line( vmesa, VERT(start), VERT(start) )
+       /*      vmesa->draw_point( vmesa, VERT(start) ) */
+
+#define RENDER_LINE( v0, v1 ) \
+       /* DEBUG(("RENDER_LINE...(ok)\n")); \ */ \
+       vmesa->draw_line( vmesa, VERT(v0), VERT(v1) ); \
+       DEBUG(("RENDER_LINE...(ok)\n"))
+
+#define RENDER_TRI( v0, v1, v2 )  \
+       DEBUG(("RENDER_TRI...(ok)\n")); \
+       vmesa->draw_tri( vmesa, VERT(v0), VERT(v1), VERT(v2) )
+
+#define RENDER_QUAD( v0, v1, v2, v3 ) \
+       DEBUG(("RENDER_QUAD...(ok)\n")); \
+       /* s3v_draw_quad( vmesa, VERT(v0), VERT(v1), VERT(v2),VERT(v3) ) */\
+       /* s3v_draw_triangle( vmesa, VERT(v0), VERT(v1), VERT(v2) ); \
+       s3v_draw_triangle( vmesa, VERT(v0), VERT(v2), VERT(v3) ) */ \
+       vmesa->draw_quad( vmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) ) 
+       
+#define INIT(x) s3vRenderPrimitive( ctx, x );
+#undef LOCAL_VARS
+#define LOCAL_VARS                                             \
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);             \
+   const GLuint shift = vmesa->vertex_stride_shift;            \
+   const char *s3vverts = (char *)vmesa->verts;                \
+   const GLboolean stipple = ctx->Line.StippleFlag;            \
+   (void) stipple;
+#define RESET_STIPPLE  if ( stipple ) s3vResetLineStipple( ctx );
+#define RESET_OCCLUSION
+#define PRESERVE_VB_DEFS
+#define ELT(x) (x)
+#define TAG(x) s3v_##x##_verts
+#include "tnl_dd/t_dd_rendertmp.h"
+
+
+/**********************************************************************/
+/*                   Render clipped primitives                        */
+/**********************************************************************/
+
+static void s3vRenderClippedPoly( GLcontext *ctx, const GLuint *elts, 
+                                  GLuint n )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+       TNLcontext *tnl = TNL_CONTEXT(ctx);
+       GLuint prim = vmesa->render_primitive;
+
+       DEBUG(("I AM in: s3vRenderClippedPoly\n"));
+
+       /* Render the new vertices as an unclipped polygon. 
+        */
+       if (1)
+       {
+       GLuint *tmp = VB->Elts;
+       VB->Elts = (GLuint *)elts;
+       tnl->Driver.Render.PrimTabElts[GL_POLYGON]
+               ( ctx, 0, n, PRIM_BEGIN|PRIM_END );
+
+       VB->Elts = tmp;
+       }
+
+       /* Restore the render primitive
+        */
+#if 1
+       if (prim != GL_POLYGON) {
+               DEBUG(("and prim != GL_POLYGON\n"));
+               tnl->Driver.Render.PrimitiveNotify( ctx, prim );
+       }
+       
+#endif
+}
+
+static void s3vRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   /*tnl->Driver.LineFunc = s3v_line_tab[2];*/ /* _swsetup_Line; */
+
+   DEBUG(("I AM in: s3vRenderClippedLine\n"));
+   tnl->Driver.Render.Line( ctx, ii, jj );
+}
+
+
+/**********************************************************************/
+/*                    Choose render functions                         */
+/**********************************************************************/
+
+
+
+#define _S3V_NEW_RENDERSTATE (_DD_NEW_TRI_UNFILLED |           \
+                              _DD_NEW_TRI_LIGHT_TWOSIDE |      \
+                              _DD_NEW_TRI_OFFSET)
+
+#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
+
+static void s3vChooseRenderState(GLcontext *ctx)
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   GLuint flags = ctx->_TriangleCaps;
+   GLuint index = 0;
+
+   DEBUG(("s3vChooseRenderState\n"));
+
+   if (flags & ANY_RASTER_FLAGS) {
+      if (flags & DD_TRI_LIGHT_TWOSIDE)       index |= S3V_TWOSIDE_BIT;
+      if (flags & DD_TRI_OFFSET)             index |= S3V_OFFSET_BIT;
+      if (flags & DD_TRI_UNFILLED)           index |= S3V_UNFILLED_BIT;
+   }
+
+   DEBUG(("vmesa->RenderIndex = %i\n", vmesa->RenderIndex));
+   DEBUG(("index = %i\n", index));
+
+   if (vmesa->RenderIndex != index) {
+      vmesa->RenderIndex = index;
+
+      tnl->Driver.Render.Points = rast_tab[index].points;
+      tnl->Driver.Render.Line = rast_tab[index].line;
+      tnl->Driver.Render.Triangle = rast_tab[index].triangle;
+      tnl->Driver.Render.Quad = rast_tab[index].quad;
+
+      if (vmesa->RenderIndex == 0)
+         tnl->Driver.Render.PrimTabVerts = s3v_render_tab_verts;
+      else
+         tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+      tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+      tnl->Driver.Render.ClippedLine = s3vRenderClippedLine;
+      tnl->Driver.Render.ClippedPolygon = s3vRenderClippedPoly;
+   }
+}
+
+
+/**********************************************************************/
+/*                 High level hooks for t_vb_render.c                 */
+/**********************************************************************/
+
+
+
+/* Determine the rasterized primitive when not drawing unfilled 
+ * polygons.
+ *
+ * Used only for the default render stage which always decomposes
+ * primitives to trianges/lines/points.  For the accelerated stage,
+ * which renders strips as strips, the equivalent calculations are
+ * performed in s3v_render.c.
+ */
+
+static void s3vRasterPrimitive( GLcontext *ctx, GLuint hwprim )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+/*     __DRIdrawablePrivate *dPriv = vmesa->driDrawable; */
+       CARD32 cmd = vmesa->CMD;
+       
+       unsigned int _hw_prim = hwprim;
+
+       DEBUG(("s3vRasterPrimitive: hwprim = 0x%x ", _hw_prim));
+
+/*     printf("* vmesa->CMD = 0x%x\n", vmesa->CMD); */
+
+       if (vmesa->hw_primitive != _hw_prim)
+       {
+               DEBUG(("(new one) ***\n"));
+               cmd &= ~DO_MASK;
+               cmd &= ~ALPHA_BLEND_MASK;
+               vmesa->hw_primitive = _hw_prim;
+
+               if (_hw_prim == PrimType_Triangles) {
+               /* TRI */
+                       DEBUG(("->switching to tri\n"));
+                       cmd |= (vmesa->_tri[vmesa->_3d_mode] | vmesa->_alpha[vmesa->_3d_mode]);
+               } else if (_hw_prim == PrimType_Lines
+                       || _hw_prim == PrimType_Points) {
+               /* LINE */
+                       DEBUG(("->switching to line\n"));
+                       cmd |= (DO_3D_LINE | vmesa->_alpha[0]);
+               } else  {
+               /* ugh? */
+                       DEBUG(("->switching to your sis'ass\n"));
+               }
+        
+               DEBUG(("\n"));
+
+               vmesa->restore_primitive = _hw_prim;
+               /* 0xacc16827: good value -> lightened newave!!! */
+               vmesa->CMD = cmd;
+               CMDCHANGE();
+       }
+}
+
+static void s3vRenderPrimitive( GLcontext *ctx, GLenum prim )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+       __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+       CARD32 cmd = vmesa->CMD;
+
+       unsigned int _hw_prim = hw_prim[prim];
+
+       vmesa->render_primitive = prim;
+       vmesa->hw_primitive = _hw_prim;
+   
+       DEBUG(("s3vRenderPrimitive #%i ", prim));
+       DEBUG(("_hw_prim = 0x%x\n", _hw_prim));
+
+/*     printf(" vmesa->CMD = 0x%x\n", vmesa->CMD); */
+
+       if (_hw_prim != vmesa->restore_primitive) {
+               DEBUG(("_hw_prim != vmesa->restore_primitive (was 0x%x)\n",
+                       vmesa->restore_primitive));
+#if 1
+               cmd &= ~DO_MASK;
+               cmd &= ~ALPHA_BLEND_MASK;
+/*             
+               printf(" cmd = 0x%x\n", cmd);
+               printf(" vmesa->_3d_mode=%i; vmesa->_tri[vmesa->_3d_mode]=0x%x\n",
+                       vmesa->_3d_mode, vmesa->_tri[vmesa->_3d_mode]);
+               printf("vmesa->alpha[0] = 0x%x; vmesa->alpha[1] = 0x%x\n",
+                       vmesa->_alpha[0], vmesa->_alpha[1]);
+*/             
+               if (_hw_prim == PrimType_Triangles) { /* TRI */
+                       DEBUG(("->switching to tri\n"));
+                       cmd |= (vmesa->_tri[vmesa->_3d_mode] | vmesa->_alpha[vmesa->_3d_mode]);
+                       DEBUG(("vmesa->TexStride = %i\n", vmesa->TexStride));
+                       DEBUG(("vmesa->TexOffset = %i\n", vmesa->TexOffset));
+                       DMAOUT_CHECK(3DTRI_Z_BASE, 12);
+               } else { /* LINE */
+                       DEBUG(("->switching to line\n"));
+                       cmd |= (DO_3D_LINE | vmesa->_alpha[0]);
+                       DMAOUT_CHECK(3DLINE_Z_BASE, 12);
+               }
+
+               DMAOUT(vmesa->s3vScreen->depthOffset & 0x003FFFF8);
+               DMAOUT(vmesa->DestBase);
+               /* DMAOUT(vmesa->ScissorLR); */
+               /* DMAOUT(vmesa->ScissorTB); */
+
+               /* NOTE: we need to restore all these values since we
+                * are coming back from a vmesa->restore_primitive */
+               DMAOUT( (0 << 16) | (dPriv->w-1) );
+               DMAOUT( (0 << 16) | (dPriv->h-1) );
+               DMAOUT( (vmesa->SrcStride << 16) | vmesa->TexStride );
+               DMAOUT(vmesa->SrcStride);
+               DMAOUT(vmesa->TexOffset);
+               DMAOUT(vmesa->TextureBorderColor);
+               DMAOUT(0); /* FOG */
+               DMAOUT(0);
+               DMAOUT(0);
+               DMAOUT(cmd);
+               /* 0xacc16827: good value -> lightened newave!!! */
+        DMAFINISH();
+
+       vmesa->CMD = cmd;
+#endif
+       }
+
+       DEBUG(("\n"));
+
+       vmesa->restore_primitive = _hw_prim;
+}
+
+static void s3vRunPipeline( GLcontext *ctx )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+
+       DEBUG(("*** s3vRunPipeline ***\n"));
+
+       if ( vmesa->new_state )
+               s3vDDUpdateHWState( ctx );
+
+       if (vmesa->new_gl_state) {
+
+               if (vmesa->new_gl_state & _NEW_TEXTURE) {
+                       s3vUpdateTextureState( ctx );
+               }
+
+               if (!vmesa->Fallback) {
+                       if (vmesa->new_gl_state & _S3V_NEW_VERTEX)
+                               s3vChooseVertexState( ctx );
+      
+                       if (vmesa->new_gl_state & _S3V_NEW_RASTER_STATE)
+                               s3vChooseRasterState( ctx );
+      
+                       if (vmesa->new_gl_state & _S3V_NEW_RENDERSTATE)
+                               s3vChooseRenderState( ctx );
+               }
+
+       vmesa->new_gl_state = 0;
+       
+       }
+
+       _tnl_run_pipeline( ctx );
+}
+
+static void s3vRenderStart( GLcontext *ctx )
+{
+       /* Check for projective texturing.  Make sure all texcoord
+        * pointers point to something.  (fix in mesa?)  
+        */
+
+       DEBUG(("s3vRenderStart\n"));
+       /* s3vCheckTexSizes( ctx ); */
+}
+
+static void s3vRenderFinish( GLcontext *ctx )
+{
+   if (0)
+      _swrast_flush( ctx );    /* never needed */
+}
+
+static void s3vResetLineStipple( GLcontext *ctx )
+{
+/*   s3vContextPtr vmesa = S3V_CONTEXT(ctx); */
+
+   /* Reset the hardware stipple counter.
+    */
+/*
+   CHECK_DMA_BUFFER(vmesa, 1);
+   WRITE(vmesa->buf, UpdateLineStippleCounters, 0);
+*/
+}
+
+
+/**********************************************************************/
+/*           Transition to/from hardware rasterization.               */
+/**********************************************************************/
+
+
+void s3vFallback( s3vContextPtr vmesa, GLuint bit, GLboolean mode )
+{
+   GLcontext *ctx = vmesa->glCtx;
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   GLuint oldfallback = vmesa->Fallback;
+
+   DEBUG(("*** s3vFallback: "));
+
+   if (mode) {
+      vmesa->Fallback |= bit;
+      if (oldfallback == 0) {
+                DEBUG(("oldfallback == 0 ***\n"));
+                _swsetup_Wakeup( ctx );
+                _tnl_need_projected_coords( ctx, GL_TRUE );
+                vmesa->RenderIndex = ~0;
+      }
+   }
+   else {
+      DEBUG(("***\n"));
+      vmesa->Fallback &= ~bit;
+      if (oldfallback == bit) {
+               _swrast_flush( ctx );
+               tnl->Driver.Render.Start = s3vRenderStart;
+               tnl->Driver.Render.PrimitiveNotify = s3vRenderPrimitive;
+               tnl->Driver.Render.Finish = s3vRenderFinish;
+               tnl->Driver.Render.BuildVertices = s3vBuildVertices;
+               tnl->Driver.Render.ResetLineStipple = s3vResetLineStipple;
+               vmesa->new_gl_state |= (_S3V_NEW_RENDERSTATE|
+                                       _S3V_NEW_RASTER_STATE|
+                                       _S3V_NEW_VERTEX);
+      }
+   }
+}
+
+
+/**********************************************************************/
+/*                            Initialization.                         */
+/**********************************************************************/
+
+
+void s3vInitTriFuncs( GLcontext *ctx )
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   static int firsttime = 1;
+
+   if (firsttime) {
+      init_rast_tab();
+      init_render_tab();
+      firsttime = 0;
+   }
+   
+   vmesa->RenderIndex = ~0;
+
+   tnl->Driver.RunPipeline = s3vRunPipeline;
+   tnl->Driver.Render.Start = s3vRenderStart;
+   tnl->Driver.Render.Finish = s3vRenderFinish; 
+   tnl->Driver.Render.PrimitiveNotify = s3vRenderPrimitive;
+   tnl->Driver.Render.ResetLineStipple = s3vResetLineStipple;
+/*
+   tnl->Driver.RenderInterp = _swsetup_RenderInterp;
+   tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
+*/
+   tnl->Driver.Render.BuildVertices = s3vBuildVertices;
+}
diff --git a/src/mesa/drivers/dri/s3v/s3v_tris.h b/src/mesa/drivers/dri/s3v/s3v_tris.h
new file mode 100644 (file)
index 0000000..0010a7f
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#ifndef _S3V_TRIS_H
+#define _S3V_TRIS_H
+
+extern void s3vDDTrifuncInit(void);
+extern void s3vDDChooseTriRenderState(GLcontext *);
+
+#endif /* !(_S3V_TRIS_H) */
diff --git a/src/mesa/drivers/dri/s3v/s3v_tritmp.h b/src/mesa/drivers/dri/s3v/s3v_tritmp.h
new file mode 100644 (file)
index 0000000..60a5e60
--- /dev/null
@@ -0,0 +1,899 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+/**** MACROS start ****/
+
+/* point/line macros */
+
+#define LINE_VERT_VARS \
+        SWvertex v[3]; \
+       s3vVertex* vvv[2]; \
+        int x[3], y[3], z[3]; \
+        int idx[3]; \
+        int dx01, dy01; \
+        int delt02; \
+        int deltzy, zstart; \
+        int start02, end01; \
+        int ystart, y01y12; \
+        int i, tmp, tmp2, tmp3; \
+        GLfloat ydiff, fy[3]
+
+#define LINE_FLAT_VARS \
+        int arstart, gbstart; \
+        int deltarx, deltgbx, deltary, deltgby; \
+        GLubyte *(col)[3]
+
+#define LINE_GOURAUD_VARS \
+        int arstart, gbstart; \
+        int deltary, deltgby; \
+        int ctmp, ctmp2, ctmp3, ctmp4; \
+        GLubyte *(col)[3]
+
+#define SORT_LINE_VERT() \
+do { \
+       if(v[0].win[1] <= v[1].win[1]) { \
+\
+                idx[0] = 0; \
+                idx[1] = 1; \
+\
+        } else if (v[0].win[1] > v[1].win[1]) { \
+\
+                idx[0] = 1; \
+                idx[1] = 0; \
+\
+        } \
+} while(0)
+
+#define SET_LINE_VERT() \
+do { \
+        x[0] = (v[idx[0]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \
+        y[0] = fy[0] = dPriv->h - v[idx[0]].win[1]; \
+        z[0] = (v[idx[0]].win[2]) * 1024.0f * 32.0f; /* 0x8000; */ \
+\
+        x[1] = (v[idx[1]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \
+        y[1] = dPriv->h - v[idx[1]].win[1]; \
+        z[1] = (v[idx[1]].win[2]) * 1024.0f * 32.0f; /* 0x8000 */ \
+} while(0)
+
+#define SET_LINE_XY() \
+do { \
+       tmp = v[idx[0]].win[0]; \
+        tmp2 = v[idx[1]].win[0]; \
+\
+       dx01 = x[0] - x[1]; \
+        dy01 = y[0] - y[1]; \
+\
+        ydiff = fy[0] - (float)y[0]; \
+        ystart = y[0]; \
+        y01y12 = dy01 + 1; \
+} while (0)
+
+#define SET_LINE_DIR() \
+do { \
+        if (tmp2 > tmp) { \
+                y01y12 |= 0x80000000; \
+                tmp3 = tmp2-tmp; \
+        } else { \
+                tmp3 = tmp-tmp2; \
+        } \
+\
+        end01 = ((tmp << 16) | tmp2); \
+\
+       if (dy01) \
+                delt02 = -(dx01/dy01); \
+        else \
+               delt02 = 0; \
+\
+        if (dy01 > tmp3) { /* Y MAJ */ \
+       /* NOTE: tmp3 always >=0 */ \
+                start02 = x[0]; \
+        } else if (delt02 >= 0){ /* X MAJ - positive delta */ \
+                start02 = x[0] + delt02/2; \
+                dy01 = tmp3; /* could be 0 */ \
+        } else { /* X MAJ - negative delta */ \
+                start02 = x[0] + delt02/2 + ((1 << 20) - 1); \
+                dy01 = tmp3; /* could be 0 */ \
+        } \
+} while(0)
+
+#define SET_LINE_Z() \
+do { \
+       zstart = z[0]; \
+\
+       if (dy01) { \
+                deltzy = (z[1] - z[0])/dy01; \
+        } else { \
+                deltzy = 0; /* dy01 = tmp3 = 0 (it's a point)*/ \
+        } \
+} while (0)
+
+#define SET_LINE_FLAT_COL() \
+do { \
+        col[0] = &(v[idx[0]].color[0]); \
+        deltarx = deltary = deltgbx = deltgby = 0; \
+        gbstart = (((col[0][1]) << 23) | ((col[0][2]) << 7)); \
+        arstart = (((col[0][3]) << 23) | ((col[0][0]) << 7)); \
+} while(0)
+
+#define SET_LINE_GOURAUD_COL() \
+do { \
+        col[0] = &(v[idx[0]].color[0]); \
+        col[1] = &(v[idx[1]].color[0]); \
+\
+        vvv[0] = _v0; \
+        vvv[1] = _v1; \
+\
+        for (i=0; i<2; i++) { \
+       /* FIXME: swapped ! */ \
+                col[i][0] = vvv[!idx[i]]->v.color.red; \
+                col[i][1] = vvv[!idx[i]]->v.color.green; \
+                col[i][2] = vvv[!idx[i]]->v.color.blue; \
+                col[i][3] = vvv[!idx[i]]->v.color.alpha; \
+        } \
+\
+       if (dy01) { \
+\
+        ctmp = ((col[0][1] - col[1][1]) << 7) / dy01; \
+        ctmp2 = ((col[0][2] - col[1][2]) << 7) / dy01; \
+        deltgby = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
+\
+        ctmp3 = ((col[0][3] - col[1][3]) << 7) / dy01; \
+        ctmp4 = ((col[0][0] - col[1][0]) << 7) / dy01; \
+        deltary = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
+        } else { \
+        ctmp = ((col[1][1] - col[0][1]) << 7); \
+        ctmp2 = ((col[1][2] - col[0][2]) << 7); \
+        deltgby = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
+\
+        ctmp3 = ((col[1][3] - col[0][3]) << 7); \
+        ctmp4 = ((col[1][0] - col[0][0]) << 7); \
+        deltary = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
+        deltgby = deltary = 0; \
+        } \
+\
+       idx[0] = 1; /* FIXME: swapped */ \
+\
+        gbstart = \
+       (((int)((ydiff * ctmp) + (col[idx[0]][1] << 7)) << 16) & 0x7FFF0000) \
+       | ((int)((ydiff * ctmp2) + (col[idx[0]][2] << 7)) & 0x7FFF); \
+        arstart = \
+       (((int)((ydiff * ctmp3) + (col[idx[0]][3] << 7)) << 16) & 0x7FFF0000) \
+       | ((int)((ydiff * ctmp4) + (col[idx[0]][0] << 7)) & 0x7FFF); \
+} while(0)
+
+#define SEND_LINE_COL() \
+do { \
+       DMAOUT(deltgby); \
+       DMAOUT(deltary); \
+       DMAOUT(gbstart); \
+       DMAOUT(arstart); \
+} while (0)
+
+#define SEND_LINE_VERT() \
+do { \
+       DMAOUT(deltzy); \
+       DMAOUT(zstart); \
+       DMAOUT(0); \
+       DMAOUT(0); \
+       DMAOUT(0); \
+       DMAOUT(end01); \
+       DMAOUT(delt02); \
+       DMAOUT(start02); \
+       DMAOUT(ystart); \
+       DMAOUT(y01y12); \
+} while (0)
+
+
+/* tri macros (mostly stolen from utah-glx...) */
+
+#define VERT_VARS \
+        SWvertex v[3]; \
+        int x[3], y[3], z[3]; \
+        int idx[3]; \
+        int dx01, dy01; \
+        int dx02, dy02; \
+        int dx12, dy12; \
+        int delt01, delt02, delt12; \
+        int deltzx, deltzy, zstart; \
+        int start02, end01, end12; \
+        int ystart, y01y12; \
+        int i, tmp, lr; \
+        GLfloat ydiff, fy[3]
+
+#define GOURAUD_VARS \
+        int arstart, gbstart; \
+        int deltarx, deltgbx, deltary, deltgby; \
+        int ctmp, ctmp2, ctmp3, ctmp4; \
+        GLubyte *(col)[3]
+
+#define FLAT_VARS \
+        int arstart, gbstart; \
+        int deltarx, deltgbx, deltary, deltgby; \
+        GLubyte *(col)[3]
+
+#define TEX_VARS \
+        int u0, u1, u2; \
+        GLfloat ru0, ru1, ru2; \
+        int v0, v1, v2; \
+        GLfloat rv0, rv1, rv2; \
+        GLfloat w0, w1, w2; \
+        GLfloat rw0, rw1, rw2; \
+        int baseu, basev; \
+        int d0, d1, d2; \
+        int deltdx, deltvx, deltux, deltdy, deltvy, deltuy; \
+        int deltwx, deltwy; \
+        int rbaseu, rbasev; \
+        int dstart, ustart, wstart, vstart; \
+        static int stmp = 0; \
+        s3vTextureObjectPtr t
+
+#define SORT_VERT() \
+do { \
+       for (i=0; i<3; i++) \
+               fy[i] = v[i].win[1]; \
+\
+               if (fy[1] > fy[0]) {  /* (fy[1] > fy[0]) */ \
+\
+                       if (fy[2] > fy[0]) { \
+                               idx[0] = 0; \
+                               if (fy[1] > fy[2]) { \
+                                       idx[1] = 2; \
+                                       idx[2] = 1; \
+                               } else { \
+                                       idx[1] = 1; \
+                                       idx[2] = 2; \
+                               } \
+                       } else { \
+                               idx[0] = 2; \
+                               idx[1] = 0; \
+                               idx[2] = 1; \
+                       } \
+               } else { /* (fy[1] < y[0]) */ \
+                       if (fy[2] > fy[0]) { \
+                               idx[0] = 1; \
+                               idx[1] = 0; \
+                               idx[2] = 2; \
+               } else { \
+                       idx[2] = 0; \
+                       if (fy[2] > fy[1]) { \
+                               idx[0] = 1; \
+                               idx[1] = 2; \
+                       } else { \
+                               idx[0] = 2; \
+                               idx[1] = 1; \
+                       } \
+               } \
+       } \
+} while(0)
+
+#define SET_VERT() \
+do { \
+       for (i=0; i<3; i++) \
+       { \
+               x[i] = ((v[idx[i]].win[0]) * /* 0x100000*/  1024.0 * 1024.0); \
+               y[i] = fy[i] = (dPriv->h - v[idx[i]].win[1]); \
+               z[i] = ((v[idx[i]].win[2]) * /* 0x8000 */ 1024.0 * 32.0); \
+       } \
+\
+       ydiff = fy[0] - (float)y[0]; \
+\
+       ystart = y[0]; \
+\
+       dx12 = x[2] - x[1]; \
+       dy12 = y[1] - y[2]; \
+       dx01 = x[1] - x[0]; \
+       dy01 = y[0] - y[1]; \
+       dx02 = x[2] - x[0]; \
+       dy02 = y[0] - y[2]; \
+\
+       delt01 = delt02 = delt12 = 0; \
+} while (0)
+
+
+#define SET_XY() \
+do { \
+       if (dy01) delt01 = dx01 / dy01; \
+       if (dy12) delt12 = dx12 / dy12; \
+       delt02 = dx02 / dy02; \
+\
+       start02 = x[0] + (ydiff * delt02); \
+       end01 = x[0] + (ydiff * delt01); \
+       end12 = x[1] + ((fy[1] - (GLfloat)y[1]) * delt12); \
+} while (0)
+
+#define SET_DIR() \
+do { \
+       tmp = x[1] - (dy01 * delt02 + x[0]); \
+       if (tmp > 0) { \
+               lr = 0x80000000; \
+       } else { \
+               tmp *= -1; \
+               lr = 0; \
+       } \
+       tmp >>= 20; \
+\
+        y01y12 = ((((y[0] - y[1]) & 0x7FF) << 16) \
+                 | ((y[1] - y[2]) & 0x7FF) | lr); \
+} while (0)
+
+#define SET_Z() \
+do { \
+       deltzy = (z[2] - z[0]) / dy02; \
+       if (tmp) { \
+               deltzx = (z[1] - (dy01 * deltzy + z[0])) / tmp; \
+       } else { \
+               deltzx = 0; \
+       } \
+       zstart = (deltzy * ydiff) + z[0]; \
+} while (0)
+
+#define SET_FLAT_COL() \
+do { \
+       col[0] = &(v[0].color[0]); \
+       deltarx = deltary = deltgbx = deltgby = 0; \
+       gbstart = (((col[0][1]) << 23) | ((col[0][2]) << 7)); \
+       arstart = (((col[0][3]) << 23) | ((col[0][0]) << 7)); \
+} while(0)
+
+#define SET_GOURAUD_COL() \
+do { \
+       col[0] = &(v[idx[0]].color[0]); \
+       col[1] = &(v[idx[1]].color[0]); \
+       col[2] = &(v[idx[2]].color[0]); \
+\
+       ctmp = ((col[2][3] - col[0][3]) << 7) / dy02; \
+       ctmp2 = ((col[2][0] - col[0][0]) << 7) / dy02; \
+       deltary = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
+       ctmp3 = ((col[2][1] - col[0][1]) << 7) / dy02; \
+       ctmp4 = ((col[2][2] - col[0][2]) << 7) / dy02; \
+       deltgby = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
+       gbstart = \
+       (((int)((ydiff * ctmp3) + (col[0][1] << 7)) << 16) & 0x7FFF0000) \
+       | ((int)((ydiff * ctmp4) + (col[0][2] << 7)) & 0x7FFF); \
+       arstart = \
+       (((int)((ydiff * ctmp) + (col[0][3] << 7)) << 16) & 0x7FFF0000) \
+       | ((int)((ydiff * ctmp2) + (col[0][0] << 7)) & 0x7FFF); \
+       if (tmp) { \
+       int ax, rx, gx, bx; \
+       ax = ((col[1][3] << 7) - (dy01 * ctmp + (col[0][3] << 7))) / tmp; \
+       rx = ((col[1][0] << 7) - (dy01 * ctmp2 + (col[0][0] << 7))) / tmp; \
+       gx = ((col[1][1] << 7) - (dy01 * ctmp3 + (col[0][1] << 7))) / tmp; \
+       bx = ((col[1][2] << 7) - (dy01 * ctmp4 + (col[0][2] << 7))) / tmp; \
+       deltarx = ((ax << 16) & 0xFFFF0000) | (rx & 0xFFFF); \
+       deltgbx = ((gx << 16) & 0xFFFF0000) | (bx & 0xFFFF); \
+       } else { \
+       deltgbx = deltarx = 0; \
+       } \
+} while (0)
+
+#define SET_TEX_VERT() \
+do { \
+        t = ((s3vTextureObjectPtr) \
+                ctx->Texture.Unit[0]._Current->DriverData); \
+        deltwx = deltwy = wstart = deltdx = deltdy = dstart = 0; \
+\
+        u0 = (v[idx[0]].texcoord[0][0] \
+                * (GLfloat)(t->image[0].image->Width) * 256.0); \
+        u1 = (v[idx[1]].texcoord[0][0] \
+                * (GLfloat)(t->globj->Image[0]->Width) * 256.0); \
+        u2 = (v[idx[2]].texcoord[0][0] \
+                * (GLfloat)(t->globj->Image[0]->Width) * 256.0); \
+        v0 = (v[idx[0]].texcoord[0][1] \
+                * (GLfloat)(t->globj->Image[0]->Height) * 256.0); \
+        v1 = (v[idx[1]].texcoord[0][1] \
+                * (GLfloat)(t->globj->Image[0]->Height) * 256.0); \
+        v2 = (v[idx[2]].texcoord[0][1] \
+                * (GLfloat)(t->globj->Image[0]->Height) * 256.0); \
+\
+        w0 = (v[idx[0]].win[3]); \
+        w1 = (v[idx[1]].win[3]); \
+        w2 = (v[idx[2]].win[3]); \
+} while (0)
+
+#define SET_BASEUV() \
+do { \
+        if (u0 < u1) { \
+                if (u0 < u2) { \
+                        baseu = u0; \
+                } else { \
+                        baseu = u2; \
+                } \
+        } else { \
+                if (u1 < u2) { \
+                        baseu = u1; \
+                } else { \
+                        baseu = u2; \
+                } \
+        } \
+\
+        if (v0 < v1) { \
+                if (v0 < v2) { \
+                        basev = v0; \
+                } else { \
+                        basev = v2; \
+                } \
+        } else { \
+                if (v1 < v2) { \
+                        basev = v1; \
+                } else { \
+                        basev = v2; \
+                } \
+        } \
+} while (0)
+
+
+#define SET_RW() \
+do { \
+        /* GLfloat minW; \
+\
+        if (w0 < w1) { \
+                if (w0 < w2) { \
+                        minW = w0; \
+                } else { \
+                        minW = w2; \
+                } \
+        } else { \
+                if (w1 < w2) { \
+                        minW = w1; \
+                } else { \
+                        minW = w2; \
+                } \
+        } */ \
+\
+        rw0 = (512.0 * w0); \
+        rw1 = (512.0 * w1); \
+        rw2 = (512.0 * w2); \
+} while (0)
+
+#define SET_D() \
+do { \
+        GLfloat sxy, suv; \
+        int lev; \
+\
+        suv = (v[idx[0]].texcoord[0][0] - \
+                v[idx[2]].texcoord[0][0]) * \
+                (v[idx[1]].texcoord[0][1] - \
+                v[idx[2]].texcoord[0][1]) - \
+                (v[idx[1]].texcoord[0][0] - \
+                v[idx[2]].texcoord[0][0]) * \
+                (v[idx[0]].texcoord[0][1] - \
+                v[idx[2]].texcoord[0][2]); \
+\
+        sxy = (v[idx[0]].texcoord[0][0] - \
+                v[idx[2]].texcoord[0][0]) * \
+                (v[idx[1]].texcoord[0][1] - \
+                v[idx[2]].texcoord[0][1]) - \
+                (v[idx[1]].texcoord[0][0] - \
+                v[idx[2]].texcoord[0][0]) * \
+                (v[idx[0]].texcoord[0][1] - \
+                v[idx[2]].texcoord[0][2]); \
+\
+       if (sxy < 0) sxy *= -1.0; \
+       if (suv < 0) suv *= -1.0; \
+\
+       lev = *(int*)&suv - *(int *)&sxy; \
+       if (lev < 0) \
+               lev = 0; \
+       else \
+               lev >>=23; \
+       dstart = (lev << 27); \
+} while (0)
+
+#define SET_UVWD() \
+do { \
+        SET_BASEUV(); \
+        SET_RW(); \
+        SET_D(); \
+        ru0 = (((u0 - baseu) * rw0)); \
+        ru1 = (((u1 - baseu) * rw1)); \
+        ru2 = (((u2 - baseu) * rw2)); \
+        rv0 = (((v0 - basev) * rw0)); \
+        rv1 = (((v1 - basev) * rw1)); \
+        rv2 = (((v2 - basev) * rw2)); \
+\
+        while (baseu < 0) { baseu += (t->globj->Image[0]->Width << 8); } \
+        while (basev < 0) { basev += (t->globj->Image[0]->Height << 8); } \
+\
+        if (!(baseu & 0xFF)) \
+                { baseu = (baseu >> 8); } \
+        else \
+                { baseu = (baseu >> 8) + 1; } \
+\
+        if ((basev & 0x80) || !(basev & 0xFF)) \
+                { basev = (basev >> 8); } \
+        else \
+                { basev = (basev >> 8) - 1; } \
+\
+        rbaseu = (baseu) << (16 - t->globj->Image[0]->WidthLog2); \
+        rbasev = (basev) << (16 - t->globj->Image[0]->WidthLog2); \
+        deltuy = (((ru2 - ru0) / dy02)); \
+        deltvy = (((rv2 - rv0) / dy02)); \
+        rw0 *= (1024.0 * 512.0); \
+        rw1 *= (1024.0 * 512.0); \
+        rw2 *= (1024.0 * 512.0); \
+        deltwy = ((rw2 - rw0) / dy02); \
+        if (tmp) { \
+                deltux = ((ru1 - (dy01 * deltuy + ru0)) / tmp); \
+                deltvx = ((rv1 - (dy01 * deltvy + rv0)) / tmp); \
+                deltwx = ((rw1 - (dy01 * deltwy + rw0)) / tmp); \
+        } else { deltux = deltvx = deltwx = 0; } \
+                ustart = (deltuy * ydiff) + (ru0); \
+                vstart = (deltvy * ydiff) + (rv0); \
+                wstart = (deltwy * ydiff) + (rw0); \
+} while (0)
+
+#define SEND_UVWD() \
+do { \
+        DMAOUT((rbasev & 0xFFFF)); \
+        DMAOUT((0xa0000000 | (rbaseu & 0xFFFF))); \
+        DMAOUT(deltwx); \
+        DMAOUT(deltwy); \
+        DMAOUT(wstart); \
+        DMAOUT(deltdx); \
+        DMAOUT(deltvx); \
+        DMAOUT(deltux); \
+        DMAOUT(deltdy); \
+        DMAOUT(deltvy); \
+        DMAOUT(deltuy); \
+        DMAOUT(dstart); \
+        DMAOUT(vstart); \
+        DMAOUT(ustart); \
+} while (0)
+
+#define SEND_VERT() \
+do { \
+       DMAOUT(deltzx); \
+       DMAOUT(deltzy); \
+       DMAOUT(zstart); \
+       DMAOUT(delt12); \
+       DMAOUT(end12); \
+       DMAOUT(delt01); \
+       DMAOUT(end01); \
+       DMAOUT(delt02); \
+       DMAOUT(start02); \
+       DMAOUT(ystart); \
+       DMAOUT(y01y12); \
+} while (0)
+
+#define SEND_COL() \
+do { \
+       DMAOUT(deltgbx); \
+       DMAOUT(deltarx); \
+       DMAOUT(deltgby); \
+       DMAOUT(deltary); \
+       DMAOUT(gbstart); \
+       DMAOUT(arstart); \
+} while (0)
+
+/**** MACROS end ****/
+
+
+
+
+static void TAG(s3v_point)( s3vContextPtr vmesa, 
+                            const s3vVertex *_v0 )
+{
+}
+
+static void TAG(s3v_line)( s3vContextPtr vmesa, 
+                            const s3vVertex *_v0,
+                            const s3vVertex *_v1 )
+{
+       GLcontext *ctx = vmesa->glCtx;
+       __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+
+       LINE_VERT_VARS;
+#if (IND & S3V_RAST_FLAT_BIT)
+       LINE_FLAT_VARS;
+#else
+       LINE_GOURAUD_VARS;
+#endif
+#if (IND & S3V_RAST_CULL_BIT)
+       GLfloat cull;
+#endif
+
+       DEBUG(("*** s3v_line: "));
+#if (IND & S3V_RAST_CULL_BIT)
+       DEBUG(("cull "));
+#endif
+#if (IND & S3V_RAST_FLAT_BIT)
+        DEBUG(("flat "));
+#endif
+
+       DEBUG(("***\n"));
+
+#if 0
+       s3v_print_vertex(ctx, _v0);
+       s3v_print_vertex(ctx, _v1);
+#endif
+
+       s3v_translate_vertex( ctx, _v0, &v[0] );
+       s3v_translate_vertex( ctx, _v1, &v[1] );
+
+#if (IND & S3V_RAST_CULL_BIT)
+       /* FIXME: should we cull lines too? */
+#endif
+       (void)v; /* v[0]; v[1]; */
+
+       SORT_LINE_VERT();
+       SET_LINE_VERT();
+
+       SET_LINE_XY();
+       SET_LINE_DIR();
+       SET_LINE_Z();
+
+#if (IND & S3V_RAST_FLAT_BIT)
+       SET_LINE_FLAT_COL();
+#else
+       SET_LINE_GOURAUD_COL();
+#endif
+
+       DMAOUT_CHECK(3DLINE_GBD, 15);
+               SEND_LINE_COL();
+               DMAOUT(0);
+               SEND_LINE_VERT();
+       DMAFINISH();
+}
+
+static void TAG(s3v_triangle)( s3vContextPtr vmesa,
+                                const s3vVertex *_v0,
+                                const s3vVertex *_v1, 
+                                const s3vVertex *_v2 )
+{
+       GLcontext *ctx = vmesa->glCtx;
+       __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+
+       VERT_VARS;
+#if (IND & S3v_RAST_FLAT_BIT)
+       FLAT_VARS;
+#else
+       GOURAUD_VARS;
+#endif
+#if (IND & S3V_RAST_TEX_BIT)
+       TEX_VARS;
+#endif
+#if (IND & S3V_RAST_CULL_BIT)
+       GLfloat cull;
+#endif
+
+       DEBUG(("*** s3v_triangle: "));
+#if (IND & S3V_RAST_CULL_BIT)
+       DEBUG(("cull "));
+#endif
+#if (IND & S3V_RAST_FLAT_BIT)
+        DEBUG(("flat "));
+#endif
+#if (IND & S3V_RAST_TEX_BIT)
+        DEBUG(("tex "));
+#endif
+
+DEBUG(("***\n"));
+
+#if 0
+       s3v_print_vertex(ctx, _v0);
+       s3v_print_vertex(ctx, _v1);
+       s3v_print_vertex(ctx, _v2);
+#endif
+
+       s3v_translate_vertex( ctx, _v0, &v[0] );
+       s3v_translate_vertex( ctx, _v1, &v[1] );
+       s3v_translate_vertex( ctx, _v2, &v[2] );
+
+#if (IND & S3V_RAST_CULL_BIT)
+       cull = vmesa->backface_sign *
+               ((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) +
+                (v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0]));
+
+       if (cull < vmesa->cull_zero /* -0.02f */) return;
+#endif
+
+       (void)v; /* v[0]; v[1]; v[2]; */
+
+       SORT_VERT();
+       SET_VERT();
+
+       if (dy02 == 0) return;
+
+       SET_XY();
+       SET_DIR();
+       SET_Z();
+       
+#if (IND & S3V_RAST_TEX_BIT)
+       SET_TEX_VERT();
+       SET_UVWD();
+#endif
+
+#if (IND & S3V_RAST_FLAT_BIT)
+       SET_FLAT_COL();
+#else
+       SET_GOURAUD_COL();
+#endif
+
+#if (IND & S3V_RAST_TEX_BIT)
+        DMAOUT_CHECK(3DTRI_BASEV, 31);
+               SEND_UVWD();
+               SEND_COL();
+               SEND_VERT();
+       DMAFINISH();
+#else
+       DMAOUT_CHECK(3DTRI_GBX, 17);
+               SEND_COL();
+               SEND_VERT();
+       DMAFINISH();
+#endif
+}
+
+static void TAG(s3v_quad)( s3vContextPtr vmesa,
+                           const s3vVertex *_v0,
+                           const s3vVertex *_v1,
+                           const s3vVertex *_v2,
+                           const s3vVertex *_v3 )
+{
+       GLcontext *ctx = vmesa->glCtx;
+        __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+
+       SWvertex temp_v[4];
+        VERT_VARS;
+#if (IND & S3v_RAST_FLAT_BIT)
+        FLAT_VARS;
+#else
+        GOURAUD_VARS;
+#endif
+#if (IND & S3V_RAST_TEX_BIT)
+        TEX_VARS;
+#endif
+#if (IND & S3V_RAST_CULL_BIT)
+        GLfloat cull;
+#endif
+
+       DEBUG(("*** s3v_quad: "));
+#if (IND & S3V_RAST_CULL_BIT)
+        DEBUG(("cull "));
+               /* printf(""); */ /* speed trick */
+#endif
+#if (IND & S3V_RAST_FLAT_BIT)
+        DEBUG(("flat "));
+#endif
+#if (IND & S3V_RAST_TEX_BIT)
+        DEBUG(("tex "));
+#endif
+
+       DEBUG(("***\n"));
+
+#if 0
+       s3v_print_vertex(ctx, _v0);
+       s3v_print_vertex(ctx, _v1);
+       s3v_print_vertex(ctx, _v2);
+       s3v_print_vertex(ctx, _v3);
+#endif
+       s3v_translate_vertex( ctx, _v0, &temp_v[0] );
+       s3v_translate_vertex( ctx, _v1, &temp_v[1] );
+       s3v_translate_vertex( ctx, _v2, &temp_v[2] );
+       s3v_translate_vertex( ctx, _v3, &temp_v[3] );
+
+       /* FIRST TRI (0,1,2) */
+
+       /* ROMEO */
+       /* printf(""); */ /* speed trick (a) [turn on if (a) is return]*/
+
+       v[0] = temp_v[0];
+       v[1] = temp_v[1];
+       v[2] = temp_v[2];
+
+#if (IND & S3V_RAST_CULL_BIT)
+       cull = vmesa->backface_sign *
+               ((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) +
+                (v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0]));
+
+       if (cull < vmesa->cull_zero /* -0.02f */) goto second; /* return; */ /* (a) */
+#endif
+       
+#if 0
+        v[0] = temp_v[0];
+       v[1] = temp_v[1];
+       v[2] = temp_v[2];
+#else
+        (void) v;
+#endif
+       SORT_VERT();
+       SET_VERT();
+
+       if (dy02 == 0) goto second;
+
+        SET_XY();
+        SET_DIR();
+        SET_Z();
+
+#if (IND & S3V_RAST_TEX_BIT)
+       SET_TEX_VERT();
+       SET_UVWD();
+#endif
+
+#if (IND & S3V_RAST_FLAT_BIT)
+       SET_FLAT_COL();
+#else
+       SET_GOURAUD_COL();
+#endif
+
+#if (IND & S3V_RAST_TEX_BIT)
+       DMAOUT_CHECK(3DTRI_BASEV, 31);
+               SEND_UVWD();
+               SEND_COL();
+               SEND_VERT();
+       DMAFINISH();
+#else
+       DMAOUT_CHECK(3DTRI_GBX, 17);
+               SEND_COL();
+               SEND_VERT();
+       DMAFINISH();
+#endif
+
+       /* SECOND TRI (0,2,3) */
+
+second:
+       v[0] = temp_v[0];
+       v[1] = temp_v[2];
+       v[2] = temp_v[3];
+
+#if (IND & S3V_RAST_CULL_BIT)
+       cull = vmesa->backface_sign *
+               ((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) +
+                (v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0]));
+                
+       if (cull < /* -0.02f */ vmesa->cull_zero) return;
+#endif
+
+/* second: */
+
+       /* ROMEO */
+       /* printf(""); */ /* speed trick */
+
+       v[0] = temp_v[0];
+       v[1] = temp_v[2];
+       v[2] = temp_v[3];
+
+       SORT_VERT();
+       SET_VERT();
+
+       if (dy02 == 0) return;
+
+       SET_XY();
+       SET_DIR();
+       SET_Z();
+
+#if (IND & S3V_RAST_TEX_BIT)
+       SET_TEX_VERT();
+       SET_UVWD();
+#endif
+
+#if (IND & S3V_RAST_FLAT_BIT)
+       SET_FLAT_COL();
+#else
+       SET_GOURAUD_COL();
+#endif
+
+#if (IND & S3V_RAST_TEX_BIT)
+       DMAOUT_CHECK(3DTRI_BASEV, 31);
+               SEND_UVWD();
+               SEND_COL();
+               SEND_VERT();
+       DMAFINISH();
+#else
+       DMAOUT_CHECK(3DTRI_GBX, 17);
+               SEND_COL();
+               SEND_VERT();
+       DMAFINISH();
+#endif
+}
+
+static void TAG(s3v_init)(void)
+{
+       s3v_point_tab[IND]      = TAG(s3v_point);
+       s3v_line_tab[IND]       = TAG(s3v_line);
+       s3v_tri_tab[IND]        = TAG(s3v_triangle);
+       s3v_quad_tab[IND]       = TAG(s3v_quad);
+}
+
+#undef IND
+#undef TAG
diff --git a/src/mesa/drivers/dri/s3v/s3v_vb.c b/src/mesa/drivers/dri/s3v/s3v_vb.c
new file mode 100644 (file)
index 0000000..f8ca6d1
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "mem.h"
+#include "macros.h"
+#include "colormac.h"
+#include "mmath.h"
+
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/t_context.h"
+#include "tnl/tnl.h"
+
+#include "s3v_context.h"
+#include "s3v_vb.h"
+#include "s3v_tris.h"
+
+#define S3V_XYZW_BIT       0x1
+#define S3V_RGBA_BIT       0x2
+#define S3V_TEX0_BIT       0x4
+#define S3V_PTEX_BIT       0x8
+#define S3V_FOG_BIT        0x10
+#define S3V_MAX_SETUP      0x20
+
+static struct {
+   void                (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
+   interp_func         interp;
+   copy_pv_func                copy_pv;
+   GLboolean           (*check_tex_sizes)( GLcontext *ctx );
+   GLuint               vertex_size;
+   GLuint               vertex_stride_shift;
+   GLuint               vertex_format;
+} setup_tab[S3V_MAX_SETUP];
+
+
+/* Only one vertex format, atm, so no need to give them names:
+ */
+#define TINY_VERTEX_FORMAT      1
+#define NOTEX_VERTEX_FORMAT     0
+#define TEX0_VERTEX_FORMAT      0
+#define TEX1_VERTEX_FORMAT      0
+#define PROJ_TEX1_VERTEX_FORMAT 0
+#define TEX2_VERTEX_FORMAT      0
+#define TEX3_VERTEX_FORMAT      0
+#define PROJ_TEX3_VERTEX_FORMAT 0
+
+#define DO_XYZW (IND & S3V_XYZW_BIT)
+#define DO_RGBA (IND & S3V_RGBA_BIT)
+#define DO_SPEC 0
+#define DO_FOG  (IND & S3V_FOG_BIT)
+#define DO_TEX0 (IND & S3V_TEX0_BIT)
+#define DO_TEX1 0
+#define DO_TEX2 0
+#define DO_TEX3 0
+#define DO_PTEX (IND & S3V_PTEX_BIT)
+                              
+#define VERTEX s3vVertex
+#define LOCALVARS /* s3vContextPtr vmesa = S3V_CONTEXT(ctx); */
+#define GET_VIEWPORT_MAT() 0 /* vmesa->hw_viewport */
+#define GET_TEXSOURCE(n)  n
+#define GET_VERTEX_FORMAT() 0
+#define GET_VERTEX_STORE() S3V_CONTEXT(ctx)->verts
+#define GET_VERTEX_STRIDE_SHIFT() S3V_CONTEXT(ctx)->vertex_stride_shift
+#define INVALIDATE_STORED_VERTICES()
+#define GET_UBYTE_COLOR_STORE() &S3V_CONTEXT(ctx)->UbyteColor
+#define GET_UBYTE_SPEC_COLOR_STORE() &S3V_CONTEXT(ctx)->UbyteSecondaryColor
+
+#define HAVE_HW_VIEWPORT    1  /* FIXME */
+#define HAVE_HW_DIVIDE      1
+#define HAVE_RGBA_COLOR     0  /* we're BGRA */
+#define HAVE_TINY_VERTICES  1
+#define HAVE_NOTEX_VERTICES 1
+#define HAVE_TEX0_VERTICES  1
+#define HAVE_TEX1_VERTICES  0
+#define HAVE_TEX2_VERTICES  0
+#define HAVE_TEX3_VERTICES  0
+#define HAVE_PTEX_VERTICES  1
+
+/*
+#define SUBPIXEL_X -.5
+#define SUBPIXEL_Y -.5
+#define UNVIEWPORT_VARS  GLfloat h = S3V_CONTEXT(ctx)->driDrawable->h
+#define UNVIEWPORT_X(x)  x - SUBPIXEL_X
+#define UNVIEWPORT_Y(y)  - y + h + SUBPIXEL_Y
+#define UNVIEWPORT_Z(z)  z / vmesa->depth_scale
+*/
+
+#define PTEX_FALLBACK()                /* never needed */
+
+#define IMPORT_QUALIFIER
+#define IMPORT_FLOAT_COLORS s3v_import_float_colors
+#define IMPORT_FLOAT_SPEC_COLORS s3v_import_float_spec_colors
+
+#define INTERP_VERTEX setup_tab[S3V_CONTEXT(ctx)->SetupIndex].interp
+#define COPY_PV_VERTEX setup_tab[S3V_CONTEXT(ctx)->SetupIndex].copy_pv
+
+
+
+/***********************************************************************
+ *         Generate  pv-copying and translation functions              *
+ ***********************************************************************/
+
+#define TAG(x) s3v_##x
+#include "tnl_dd/t_dd_vb.c"
+
+/***********************************************************************
+ *             Generate vertex emit and interp functions               *
+ ***********************************************************************/
+
+
+#define IND (S3V_XYZW_BIT|S3V_RGBA_BIT)
+#define TAG(x) x##_wg
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_TEX0_BIT)
+#define TAG(x) x##_wgt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_TEX0_BIT|S3V_PTEX_BIT)
+#define TAG(x) x##_wgpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (S3V_TEX0_BIT)
+#define TAG(x) x##_t0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (S3V_RGBA_BIT)
+#define TAG(x) x##_g
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (S3V_RGBA_BIT|S3V_TEX0_BIT)
+#define TAG(x) x##_gt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_FOG_BIT)
+#define TAG(x) x##_wgf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_FOG_BIT|S3V_TEX0_BIT)
+#define TAG(x) x##_wgft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_FOG_BIT|S3V_TEX0_BIT|S3V_PTEX_BIT)
+#define TAG(x) x##_wgfpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (S3V_FOG_BIT)
+#define TAG(x) x##_f
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (S3V_RGBA_BIT | S3V_FOG_BIT)
+#define TAG(x) x##_gf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (S3V_RGBA_BIT | S3V_FOG_BIT | S3V_TEX0_BIT)
+#define TAG(x) x##_gft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+static void init_setup_tab( void )
+{
+   init_wg();          /* pos + col */
+   init_wgt0();                /* pos + col + tex0 */
+   init_wgpt0();       /* pos + col + p-tex0 (?) */
+   init_t0();          /* tex0 */
+   init_g();           /* col */
+   init_gt0();         /* col + tex */
+   init_wgf();
+   init_wgft0();
+   init_wgfpt0();
+   init_f();
+   init_gf();
+   init_gft0();
+}
+
+
+#if 0
+void s3vPrintSetupFlags(char *msg, GLuint flags )
+{
+   fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
+          msg,
+          (int)flags,
+          (flags & S3V_XYZW_BIT)      ? " xyzw," : "", 
+          (flags & S3V_RGBA_BIT)     ? " rgba," : "",
+          (flags & S3V_SPEC_BIT)     ? " spec," : "",
+          (flags & S3V_FOG_BIT)      ? " fog," : "",
+          (flags & S3V_TEX0_BIT)     ? " tex-0," : "",
+          (flags & S3V_TEX1_BIT)     ? " tex-1," : "");
+}
+#endif
+
+
+void s3vCheckTexSizes( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+
+   if (!setup_tab[vmesa->SetupIndex].check_tex_sizes(ctx)) {
+
+      vmesa->SetupIndex |= (S3V_PTEX_BIT|S3V_RGBA_BIT);
+
+      if (1 || !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
+         tnl->Driver.Render.Interp = setup_tab[vmesa->SetupIndex].interp;
+         tnl->Driver.Render.CopyPV = setup_tab[vmesa->SetupIndex].copy_pv;
+      }
+   }
+}
+
+void s3vBuildVertices( GLcontext *ctx, 
+                        GLuint start, 
+                        GLuint count,
+                        GLuint newinputs )
+{
+       s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+       GLubyte *v = ((GLubyte *)vmesa->verts +
+               (start<<vmesa->vertex_stride_shift));
+       GLuint stride = 1<<vmesa->vertex_stride_shift;
+       GLuint ind = 0;
+
+       DEBUG(("*** s3vBuildVertices ***\n"));
+       DEBUG(("vmesa->SetupNewInputs = 0x%x\n", vmesa->SetupNewInputs));
+       DEBUG(("vmesa->SetupIndex = 0x%x\n", vmesa->SetupIndex));
+
+#if 1
+       setup_tab[vmesa->SetupIndex].emit( ctx, start, count, v, stride );
+#else
+       newinputs |= vmesa->SetupNewInputs;
+       vmesa->SetupNewInputs = 0;
+
+       DEBUG(("newinputs is 0x%x\n", newinputs));
+
+       if (!newinputs) {
+               DEBUG(("!newinputs\n"));
+               return;
+       }
+
+       if (newinputs & VERT_CLIP) {
+       setup_tab[vmesa->SetupIndex].emit( ctx, start, count, v, stride );
+       DEBUG(("newinputs & VERT_CLIP\n"));
+       return;
+       } /* else { */
+/*      GLuint ind = 0; */
+
+       if (newinputs & VERT_RGBA) {
+               DEBUG(("newinputs & VERT_RGBA\n"));
+               ind |= S3V_RGBA_BIT;
+       }
+       if (newinputs & VERT_TEX0) {
+               DEBUG(("newinputs & VERT_TEX0\n"));
+               ind |= S3V_TEX0_BIT;
+       }
+
+    if (newinputs & VERT_FOG_COORD)
+        ind |= S3V_FOG_BIT;
+
+       if (vmesa->SetupIndex & S3V_PTEX_BIT)
+               ind = ~0;
+
+    ind &= vmesa->SetupIndex;
+
+       DEBUG(("vmesa->SetupIndex = 0x%x\n", vmesa->SetupIndex));
+       DEBUG(("ind = 0x%x\n", ind));
+       DEBUG(("ind & vmesa->SetupIndex = 0x%x\n", (ind & vmesa->SetupIndex)));
+
+       if (ind) {
+               setup_tab[ind].emit( ctx, start, count, v, stride );   
+       }
+#endif
+}
+
+void s3vChooseVertexState( GLcontext *ctx )
+{
+   s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+   GLuint ind = S3V_XYZW_BIT | S3V_RGBA_BIT;
+
+   /* FIXME: will segv in tnl_dd/t_dd_vbtmp.h (line 196) on some demos */
+/*
+   if (ctx->Fog.Enabled)
+      ind |= S3V_FOG_BIT;
+*/
+
+
+   if (ctx->Texture._ReallyEnabled) {
+      _tnl_need_projected_coords( ctx, GL_FALSE );
+      ind |= S3V_TEX0_BIT;
+   } else {
+      _tnl_need_projected_coords( ctx, GL_TRUE );
+   }
+
+   vmesa->SetupIndex = ind;
+
+   if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
+      tnl->Driver.Render.Interp = s3v_interp_extras;
+      tnl->Driver.Render.CopyPV = s3v_copy_pv_extras;
+   } else {
+      tnl->Driver.Render.Interp = setup_tab[ind].interp;
+      tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
+   }
+}
+
+
+void s3vInitVB( GLcontext *ctx )
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+   GLuint size = TNL_CONTEXT(ctx)->vb.Size;
+
+   vmesa->verts = (char *)ALIGN_MALLOC(size * 4 * 16, 32);
+
+   {
+      static int firsttime = 1;
+      if (firsttime) {
+        init_setup_tab();
+        firsttime = 0;
+        vmesa->vertex_stride_shift = 6 /* 4 */; /* FIXME - only one vertex setup */
+      }
+   }
+}
+
+
+void s3vFreeVB( GLcontext *ctx )
+{
+   s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+   if (vmesa->verts) {
+      ALIGN_FREE(vmesa->verts);
+      vmesa->verts = 0;
+   }
+
+   if (vmesa->UbyteSecondaryColor.Ptr) {
+      ALIGN_FREE(vmesa->UbyteSecondaryColor.Ptr);
+      vmesa->UbyteSecondaryColor.Ptr = 0;
+   }
+
+   if (vmesa->UbyteColor.Ptr) {
+      ALIGN_FREE(vmesa->UbyteColor.Ptr);
+      vmesa->UbyteColor.Ptr = 0;
+   }
+}
diff --git a/src/mesa/drivers/dri/s3v/s3v_vb.h b/src/mesa/drivers/dri/s3v/s3v_vb.h
new file mode 100644 (file)
index 0000000..b35d804
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#ifndef S3VVB_INC
+#define S3VVB_INC
+
+#include "mtypes.h"
+#include "swrast/swrast.h"
+
+#define _S3V_NEW_VERTEX (_NEW_TEXTURE |                \
+                          _DD_NEW_TRI_UNFILLED |       \
+                          _DD_NEW_TRI_LIGHT_TWOSIDE)
+
+
+extern void s3vChooseVertexState( GLcontext *ctx );
+extern void s3vCheckTexSizes( GLcontext *ctx );
+extern void s3vBuildVertices( GLcontext *ctx, 
+                               GLuint start, 
+                               GLuint count,
+                               GLuint newinputs );
+
+
+extern void s3v_import_float_colors( GLcontext *ctx );
+extern void s3v_import_float_spec_colors( GLcontext *ctx );
+
+extern void s3v_translate_vertex( GLcontext *ctx, 
+                                   const s3vVertex *src, 
+                                   SWvertex *dst );
+
+extern void s3vInitVB( GLcontext *ctx );
+extern void s3vFreeVB( GLcontext *ctx );
+
+extern void s3v_print_vertex( GLcontext *ctx, const s3vVertex *v );
+#if 0
+extern void s3vPrintSetupFlags(char *msg, GLuint flags );
+#endif
+
+#endif
diff --git a/src/mesa/drivers/dri/s3v/s3v_xmesa.c b/src/mesa/drivers/dri/s3v/s3v_xmesa.c
new file mode 100644 (file)
index 0000000..b012c1b
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include "s3v_context.h"
+#include "s3v_vb.h"
+#include "context.h"
+#include "mmath.h"
+#include "matrix.h"
+#include "s3v_dri.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "array_cache/acache.h"
+
+/* #define DEBUG(str) printf str */
+
+static GLboolean 
+s3vInitDriver(__DRIscreenPrivate *sPriv)
+{
+    sPriv->private = (void *) s3vCreateScreen( sPriv );
+
+    if (!sPriv->private) {
+       s3vDestroyScreen( sPriv );
+       return GL_FALSE;
+    }
+
+    return GL_TRUE;
+}
+
+static void 
+s3vDestroyContext(__DRIcontextPrivate *driContextPriv)
+{
+    s3vContextPtr vmesa = (s3vContextPtr)driContextPriv->driverPrivate;
+
+    if (vmesa) {
+      _swsetup_DestroyContext( vmesa->glCtx );
+      _tnl_DestroyContext( vmesa->glCtx );
+      _ac_DestroyContext( vmesa->glCtx );
+      _swrast_DestroyContext( vmesa->glCtx );
+
+      s3vFreeVB( vmesa->glCtx );
+
+      /* free the Mesa context */
+      vmesa->glCtx->DriverCtx = NULL;
+      _mesa_destroy_context(vmesa->glCtx);
+
+      Xfree(vmesa);
+      driContextPriv->driverPrivate = NULL;
+    }
+}
+
+
+static GLboolean
+s3vCreateBuffer( Display *dpy,
+                   __DRIscreenPrivate *driScrnPriv,
+                   __DRIdrawablePrivate *driDrawPriv,
+                   const __GLcontextModes *mesaVis,
+                   GLboolean isPixmap )
+{
+   if (isPixmap) {
+      return GL_FALSE; /* not implemented */
+   }
+   else {
+      driDrawPriv->driverPrivate = (void *) 
+         _mesa_create_framebuffer(mesaVis,
+                                  GL_FALSE,  /* software depth buffer? */
+                                  mesaVis->stencilBits > 0,
+                                  mesaVis->accumRedBits > 0,
+                                  mesaVis->alphaBits > 0
+                                  );
+      return (driDrawPriv->driverPrivate != NULL);
+   }
+}
+
+
+static void
+s3vDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+   _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
+}
+
+static void
+s3vSwapBuffers(Display *dpy, void *drawablePrivate)
+{
+   __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
+   __DRIscreenPrivate *sPriv;
+   GLcontext *ctx;
+   s3vContextPtr vmesa;
+   s3vScreenPtr s3vscrn;
+   
+   vmesa = (s3vContextPtr) dPriv->driContextPriv->driverPrivate;
+   sPriv = vmesa->driScreen;
+   s3vscrn = vmesa->s3vScreen;
+   ctx = vmesa->glCtx;
+
+   DEBUG(("*** s3vSwapBuffers ***\n"));
+
+/* DMAFLUSH(); */
+
+   _mesa_swapbuffers( ctx );
+
+   vmesa = (s3vContextPtr) dPriv->driContextPriv->driverPrivate;
+/*    driScrnPriv = vmesa->driScreen; */
+
+/*    if (vmesa->EnabledFlags & S3V_BACK_BUFFER) */
+
+/*     _mesa_swapbuffers( ctx );  */
+#if 1
+{      
+       int x0, y0, x1, y1;
+/*     
+       int nRect = dPriv->numClipRects;
+       XF86DRIClipRectPtr pRect = dPriv->pClipRects;
+
+       __DRIscreenPrivate *driScrnPriv = vmesa->driScreen;
+*/
+
+/*     
+       DEBUG(("s3vSwapBuffers: S3V_BACK_BUFFER = 1 - nClip = %i\n", nRect));
+*/
+/*     vmesa->drawOffset=vmesa->s3vScreen->backOffset; */
+
+       x0 = dPriv->x;
+       y0 = dPriv->y;
+
+       x1 = x0 + dPriv->w - 1;
+       y1 = y0 + dPriv->h - 1;
+
+       DMAOUT_CHECK(BITBLT_SRC_BASE, 15);
+               DMAOUT(vmesa->s3vScreen->backOffset);
+               DMAOUT(0); /* 0xc0000000 */
+               DMAOUT( ((x0 << 16) | x1) );
+               DMAOUT( ((y0 << 16) | y1) );
+               DMAOUT( (vmesa->DestStride << 16) | vmesa->SrcStride );
+               DMAOUT( (~(0)) );
+               DMAOUT( (~(0)) );
+               DMAOUT(0);
+               DMAOUT(0);
+       /* FIXME */
+               DMAOUT(0);
+               DMAOUT(0);
+               DMAOUT( (0x01 | /* Autoexecute */
+                        0x02 | /* clip */
+                        0x04 | /* 16 bit */
+                        0x20 | /* draw */
+                       0x400 | /* word alignment (bit 10=1) */
+                       (0x2 << 11) | /*  offset = 1 byte */
+                       (0xCC << 17) |  /* rop #204 */
+                       (0x3 << 25)) ); /* l-r, t-b */
+               DMAOUT(vmesa->ScissorWH);
+               DMAOUT( /* 0 */ vmesa->SrcXY );
+               DMAOUT( (dPriv->x << 16) | dPriv->y );
+       DMAFINISH();
+
+       DMAFLUSH();
+
+       vmesa->restore_primitive = -1;
+
+}
+#endif
+}
+
+static GLboolean 
+s3vMakeCurrent(__DRIcontextPrivate *driContextPriv,
+                __DRIdrawablePrivate *driDrawPriv,
+                __DRIdrawablePrivate *driReadPriv)
+{
+       int x1,x2,y1,y2;
+       int cx, cy, cw, ch;
+       unsigned int src_stride, dest_stride;
+       int cl;
+
+       s3vContextPtr vmesa;
+       __DRIdrawablePrivate *dPriv = driDrawPriv;
+       
+       DEBUG(("s3vMakeCurrent\n"));
+
+       DEBUG(("dPriv->x=%i y=%i w=%i h=%i\n", dPriv->x, dPriv->y,
+               dPriv->w, dPriv->h));
+
+       if (driContextPriv) {
+       GET_CURRENT_CONTEXT(ctx);
+       s3vContextPtr oldVirgeCtx = ctx ? S3V_CONTEXT(ctx) : NULL;
+       s3vContextPtr newVirgeCtx = (s3vContextPtr) driContextPriv->driverPrivate;
+
+       if ( newVirgeCtx != oldVirgeCtx ) {
+
+               newVirgeCtx->dirty = ~0;
+               cl = 1;
+               DEBUG(("newVirgeCtx != oldVirgeCtx\n"));
+/*             s3vUpdateClipping(newVirgeCtx->glCtx ); */
+       }
+
+       if (newVirgeCtx->driDrawable != driDrawPriv) {
+           newVirgeCtx->driDrawable = driDrawPriv;
+               DEBUG(("driDrawable != driDrawPriv\n"));
+               s3vUpdateWindow ( newVirgeCtx->glCtx );
+               s3vUpdateViewportOffset( newVirgeCtx->glCtx );
+/*             s3vUpdateClipping(newVirgeCtx->glCtx ); */
+       }
+/*
+       s3vUpdateWindow ( newVirgeCtx->glCtx );
+       s3vUpdateViewportOffset( newVirgeCtx->glCtx );
+*/
+
+/*
+       _mesa_make_current2( newVirgeCtx->glCtx,
+                          (GLframebuffer *) driDrawPriv->driverPrivate,
+                          (GLframebuffer *) driReadPriv->driverPrivate );
+
+       _mesa_set_viewport(newVirgeCtx->glCtx, 0, 0,
+                         newVirgeCtx->driDrawable->w,
+                         newVirgeCtx->driDrawable->h);
+*/
+
+#if 0
+       newVirgeCtx->Window &= ~W_GIDMask;
+       newVirgeCtx->Window |= (driDrawPriv->index << 5);
+       CHECK_DMA_BUFFER(newVirgeCtx,1);
+       WRITE(newVirgeCtx->buf, S3VWindow, newVirgeCtx->Window);
+#endif
+
+
+
+       newVirgeCtx->new_state |= S3V_NEW_WINDOW; /* FIXME */
+
+       _mesa_make_current2( newVirgeCtx->glCtx, 
+                         (GLframebuffer *) driDrawPriv->driverPrivate,
+                         (GLframebuffer *) driReadPriv->driverPrivate );
+
+       if (!newVirgeCtx->glCtx->Viewport.Width) {
+           _mesa_set_viewport(newVirgeCtx->glCtx, 0, 0, 
+                                       driDrawPriv->w, driDrawPriv->h);
+
+/*             s3vUpdateClipping(newVirgeCtx->glCtx ); */
+       }
+
+/*
+       if (cl) {
+               s3vUpdateClipping(newVirgeCtx->glCtx );
+               cl =0;
+       }
+*/
+
+       newVirgeCtx->new_state |= S3V_NEW_CLIP;
+
+    if (1) {
+        cx = dPriv->x;
+        cw = dPriv->w;
+        cy = dPriv->y;
+        ch = dPriv->h;
+    }
+
+    x1 = y1 = 0;
+    x2 = cw-1;
+    y2 = ch-1;
+
+/*  src_stride = vmesa->s3vScreen->w * vmesa->s3vScreen->cpp; 
+    dest_stride = ((x2+31)&~31) * vmesa->s3vScreen->cpp; */
+    src_stride = vmesa->driScreen->fbWidth * 2;
+    dest_stride = ((x2+31)&~31) * 2;
+    } else {
+    _mesa_make_current( 0, 0 );
+    }
+
+    return GL_TRUE;
+}
+
+
+static GLboolean 
+s3vUnbindContext( __DRIcontextPrivate *driContextPriv )
+{
+   return GL_TRUE;
+}
+
+static GLboolean
+s3vOpenFullScreen(__DRIcontextPrivate *driContextPriv)
+{
+    return GL_TRUE;
+}
+
+static GLboolean
+s3vCloseFullScreen(__DRIcontextPrivate *driContextPriv)
+{
+    return GL_TRUE;
+}
+
+
+static struct __DriverAPIRec s3vAPI = {
+   s3vInitDriver,
+   s3vDestroyScreen,
+   s3vCreateContext,
+   s3vDestroyContext,
+   s3vCreateBuffer,
+   s3vDestroyBuffer,
+   s3vSwapBuffers,
+   s3vMakeCurrent,
+   s3vUnbindContext,
+   s3vOpenFullScreen,
+   s3vCloseFullScreen
+};
+
+
+
+/*
+ * This is the bootstrap function for the driver.
+ * The __driCreateScreen name is the symbol that libGL.so fetches.
+ * Return:  pointer to a __DRIscreenPrivate.
+ */
+void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
+                        int numConfigs, __GLXvisualConfig *config)
+{
+   __DRIscreenPrivate *psp=NULL;
+
+   DEBUG(("__driCreateScreen: psp = %p\n", psp));
+   psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &s3vAPI);
+   DEBUG(("__driCreateScreen: psp = %p\n", psp));
+   return (void *) psp;
+}
+
+void __driRegisterExtensions(void)
+{
+   /* No extensions */
+}
diff --git a/src/mesa/drivers/dri/s3v/s3virgetri.h b/src/mesa/drivers/dri/s3v/s3virgetri.h
new file mode 100644 (file)
index 0000000..5519cfd
--- /dev/null
@@ -0,0 +1,383 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#define LOCAL_VARS \
+       int vert0, vert1, vert2; \
+       GLfloat y0, y1, y2, ydiff; \
+       int iy0, iy1, iy2; \
+       int x0, x1, x2, z0, z1, z2; \
+       int dy01, dy02, dy12, dx01, dx02, dx12; \
+       int delt02, delt01, delt12, end01, end12, start02; \
+       int zstart, arstart, gbstart; \
+       int deltzy, deltzx, deltarx, deltgbx, deltary, deltgby; \
+       GLubyte (*colours)[4]; \
+       GLubyte (*scolours)[4]; \
+       static int tp = 0; \
+       int tmp, lr
+
+#define LOCAL_TEX_VARS \
+       int u0, u1, u2; \
+       GLfloat ru0, ru1, ru2; \
+       int v0, v1, v2; \
+       GLfloat rv0, rv1, rv2; \
+       GLfloat w0, w1, w2; \
+       GLfloat rw0, rw1, rw2; \
+       int baseu, basev; \
+       int d0, d1, d2; \
+       int deltdx, deltvx, deltux, deltdy, deltvy, deltuy; \
+       int deltwx, deltwy; \
+       int rbaseu, rbasev; \
+       int dstart, ustart, wstart, vstart; \
+       static int stmp = 0; \
+       s3virgeTextureObject_t *t
+
+#define CULL_BACKFACE() \
+       do { \
+               GLfloat *w0 = VB->Win.data[e0]; \
+               GLfloat *w1 = VB->Win.data[e1]; \
+               GLfloat *w2 = VB->Win.data[e2]; \
+               float cull; \
+               cull = ctx->backface_sign * ((w1[0] - w0[0]) * (w0[1] - w2[1]) + \
+                       (w1[1] - w0[1]) * (w2[0] - w0[0])); \
+               if (cull < 0) \
+                       return; \
+       } while (0)
+       
+#define SORT_VERTICES() \
+       do { \
+               y0 = VB->Win.data[e0][1]; \
+               y1 = VB->Win.data[e1][1]; \
+               y2 = VB->Win.data[e2][1]; \
+               if (y1 > y0) { \
+                       if (y2 > y0) {  \
+                               vert0 = e0; \
+                               if (y1 > y2) { vert2 = e1; vert1 = e2; } else { vert2 = e2; vert1 = e1; } \
+                       } else { vert0 = e2; vert1 = e0; vert2 = e1; } \
+               } else { \
+                       if (y2 > y0) { vert0 = e1; vert1 = e0; vert2 = e2; } else { \
+                               vert2 = e0; \
+                               if (y2 > y1) { vert0 = e1; vert1 = e2; } else { vert0 = e2; vert1 = e1; } \
+                       } \
+               } \
+       } while (0)
+
+#define SET_VARIABLES() \
+       do { \
+               iy0 = y0 = ((s3virgeDB->height - (VB->Win.data[vert0][1]))); \
+               iy1 = y1 = ((s3virgeDB->height - (VB->Win.data[vert1][1]))); \
+               iy2 = y2 = ((s3virgeDB->height - (VB->Win.data[vert2][1]))); \
+               if (iy0 == iy2) { return; } \
+               ydiff = y0 - (float)iy0; \
+               x0 = ((VB->Win.data[vert0][0]) * 1024.0 * 1024.0); \
+               x1 = ((VB->Win.data[vert1][0]) * 1024.0 * 1024.0); \
+               x2 = ((VB->Win.data[vert2][0]) * 1024.0 * 1024.0); \
+               z0 = (VB->Win.data[vert0][2] * 1024.0 * 32.0); \
+               z1 = (VB->Win.data[vert1][2] * 1024.0 * 32.0); \
+               z2 = (VB->Win.data[vert2][2] * 1024.0 * 32.0); \
+               dx12 = x2 - x1; \
+               dy12 = iy1 - iy2; \
+               dx01 = x1 - x0; \
+               dy01 = iy0 - iy1; \
+               dx02 = x2 - x0; \
+               dy02 = iy0 - iy2; \
+               delt12 = delt02 = delt01 = 0; \
+       } while (0)
+       
+#define SET_TEX_VARIABLES() \
+       do { \
+               t = ((s3virgeTextureObject_t *)ctx->Texture.Unit[0].Current->DriverData); \
+               deltwx = deltwy = wstart = deltdx = deltdy = dstart = 0; \
+               u0 = (VB->TexCoordPtr[0]->data[vert0][0] * (GLfloat)(t->tObj->Image[0]->Width) * 256.0); \
+               u1 = (VB->TexCoordPtr[0]->data[vert1][0] * (GLfloat)(t->tObj->Image[0]->Width) * 256.0); \
+               u2 = (VB->TexCoordPtr[0]->data[vert2][0] * (GLfloat)(t->tObj->Image[0]->Width) * 256.0); \
+               v0 = (VB->TexCoordPtr[0]->data[vert0][1] * (GLfloat)(t->tObj->Image[0]->Height) * 256.0); \
+               v1 = (VB->TexCoordPtr[0]->data[vert1][1] * (GLfloat)(t->tObj->Image[0]->Height) * 256.0); \
+               v2 = (VB->TexCoordPtr[0]->data[vert2][1] * (GLfloat)(t->tObj->Image[0]->Height) * 256.0); \
+               w0 = (VB->Win.data[vert0][3]); \
+               w1 = (VB->Win.data[vert1][3]); \
+               w2 = (VB->Win.data[vert2][3]); \
+       } while (0)
+
+#define FLATSHADE_COLORS() \
+       do { \
+               GLubyte *col = &(colours[pv][0]); \
+               deltarx = deltary = deltgbx = deltgby = 0; \
+               gbstart = (((col[1]) << 23) | ((col[2]) << 7)); \
+               arstart = (((col[3]) << 23) | ((col[0]) << 7)); \
+       } while (0)
+
+#define GOURAUD_COLORS() \
+       do { \
+               int ctmp, ctmp2, ctmp3, ctmp4; \
+               GLubyte *col0, *col1, *col2; \
+               col0 = &(colours[vert0][0]); \
+               col1 = &(colours[vert1][0]); \
+               col2 = &(colours[vert2][0]); \
+               ctmp = ((col2[3] - col0[3]) << 7) / dy02; \
+               ctmp2 = ((col2[0] - col0[0]) << 7) / dy02; \
+               deltary = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
+               ctmp3 = ((col2[1] - col0[1]) << 7) / dy02; \
+               ctmp4 = ((col2[2] - col0[2]) << 7) / dy02; \
+               deltgby = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
+               gbstart = (((int)((ydiff * ctmp3) + (col0[1] << 7)) << 16) & 0x7FFF0000) | \
+                         ((int)((ydiff * ctmp4) + (col0[2] << 7)) & 0x7FFF); \
+               arstart = (((int)((ydiff * ctmp) + (col0[3] << 7)) << 16) & 0x7FFF0000) | \
+                         ((int)((ydiff * ctmp2) + (col0[0] << 7)) & 0x7FFF); \
+               if (tmp) { \
+                       int ax, rx, gx, bx; \
+                       ax = ((col1[3] << 7) - (dy01 * ctmp + (col0[3] << 7))) / tmp; \
+                       rx = ((col1[0] << 7) - (dy01 * ctmp2 + (col0[0] << 7))) / tmp; \
+                       gx = ((col1[1] << 7) - (dy01 * ctmp3 + (col0[1] << 7))) / tmp; \
+                       bx = ((col1[2] << 7) - (dy01 * ctmp4 + (col0[2] << 7))) / tmp; \
+                       deltarx = ((ax << 16) & 0xFFFF0000) | (rx & 0xFFFF); \
+                       deltgbx = ((gx << 16) & 0xFFFF0000) | (bx & 0xFFFF); \
+               } else { \
+                       deltgbx = deltarx = 0; \
+               } \
+       } while (0)
+
+#define SET_XY() \
+       do { \
+               delt02 = dx02 / dy02; \
+               if (dy12) delt12 = dx12 / dy12; \
+               if (dy01) delt01 = dx01 / dy01; \
+               start02 = (ydiff * delt02) + x0; \
+               end01 = (ydiff * delt01) + x0; \
+               end12 = ((y1 - (GLfloat)iy1) * delt12) + x1; \
+       } while (0)
+
+#define SET_DIR() \
+       do { \
+               tmp = x1 - (dy01 * delt02 + x0); \
+               if (tmp > 0) { \
+                       lr = 0x80000000; \
+               } else { \
+                       tmp *= -1; \
+                       lr = 0; \
+               } \
+               tmp >>= 20; \
+       } while (0)
+
+#define SET_Z() \
+       do { \
+               deltzy = (z2 - z0) / dy02; \
+               if (tmp) { \
+                       deltzx = (z1 - (dy01 * deltzy + z0)) / tmp; \
+               } else { deltzx = 0; } \
+               zstart = (deltzy * ydiff) + z0; \
+       } while (0)
+
+#define SET_BASEUV() \
+       do { \
+               if (u0 < u1) { \
+                       if (u0 < u2) { \
+                               baseu = u0; \
+                       } else { \
+                               baseu = u2; \
+                       } \
+               } else { \
+                       if (u1 < u2) { \
+                               baseu = u1; \
+                       } else { \
+                               baseu = u2; \
+                       } \
+               } \
+               if (v0 < v1) { \
+                       if (v0 < v2) { \
+                               basev = v0; \
+                       } else { \
+                               basev = v2; \
+                       } \
+               } else { \
+                       if (v1 < v2) { \
+                               basev = v1; \
+                       } else { \
+                               basev = v2; \
+                       } \
+               } \
+       } while (0)
+
+#define SET_RW() \
+       do { \
+               /* GLfloat minW; \
+               if (w0 < w1) { \
+                       if (w0 < w2) { \
+                               minW = w0; \
+                       } else { \
+                               minW = w2; \
+                       } \
+               } else { \
+                       if (w1 < w2) { \
+                               minW = w1; \
+                       } else { \
+                               minW = w2; \
+                       } \
+               } */ \
+               rw0 = (512.0 * w0); \
+               rw1 = (512.0 * w1); \
+               rw2 = (512.0 * w2); \
+       } while (0)
+
+
+#define SET_D() \
+       do { \
+               GLfloat sxy, suv; \
+               int lev; \
+               suv = (VB->TexCoordPtr[0]->data[vert0][0] - \
+                      VB->TexCoordPtr[0]->data[vert2][0]) * \
+                     (VB->TexCoordPtr[0]->data[vert1][1] - \
+                      VB->TexCoordPtr[0]->data[vert2][1]) - \
+                     (VB->TexCoordPtr[0]->data[vert1][0] - \
+                      VB->TexCoordPtr[0]->data[vert2][0]) * \
+                     (VB->TexCoordPtr[0]->data[vert0][1] - \
+                      VB->TexCoordPtr[0]->data[vert2][2]); \
+               sxy = (VB->Win.data[vert0][0] - \
+                      VB->Win.data[vert2][0]) * \
+                     (VB->Win.data[vert1][1] - \
+                      VB->Win.data[vert2][1]) - \
+                     (VB->Win.data[vert1][0] - \
+                      VB->Win.data[vert2][0]) * \
+                     (VB->Win.data[vert0][1] - \
+                      VB->Win.data[vert2][2]); \
+               if (sxy < 0) sxy *= -1.0; \
+               if (suv < 0) suv *= -1.0; \
+               lev = *(int*)&suv - *(int *)&sxy; \
+               if (lev < 0) \
+                       lev = 0; \
+               else \
+                       lev >>=23; \
+               dstart = (lev << 27); \
+       } while (0)
+               
+
+
+#define SET_UVWD() \
+       do { \
+               SET_BASEUV(); \
+               SET_RW(); \
+               SET_D(); \
+               ru0 = (((u0 - baseu) * rw0)); \
+               ru1 = (((u1 - baseu) * rw1)); \
+               ru2 = (((u2 - baseu) * rw2)); \
+               rv0 = (((v0 - basev) * rw0)); \
+               rv1 = (((v1 - basev) * rw1)); \
+               rv2 = (((v2 - basev) * rw2)); \
+               while (baseu < 0) { baseu += (t->tObj->Image[0]->Width << 8); } \
+               while (basev < 0) { basev += (t->tObj->Image[0]->Height << 8); } \
+               if (!(baseu & 0xFF)) { baseu = (baseu >> 8); } else { baseu = (baseu >> 8) + 1; } \
+               if ((basev & 0x80) || !(basev & 0xFF)) { basev = (basev >> 8); } else { basev = (basev >> 8) - 1; } \
+               rbaseu = (baseu) << (16 - t->widthLog2); \
+               rbasev = (basev) << (16 - t->widthLog2); \
+               deltuy = (((ru2 - ru0) / dy02)); \
+               deltvy = (((rv2 - rv0) / dy02)); \
+               rw0 *= (1024.0 * 512.0); \
+               rw1 *= (1024.0 * 512.0); \
+               rw2 *= (1024.0 * 512.0); \
+               deltwy = ((rw2 - rw0) / dy02); \
+               if (tmp) { \
+                       deltux = ((ru1 - (dy01 * deltuy + ru0)) / tmp); \
+                       deltvx = ((rv1 - (dy01 * deltvy + rv0)) / tmp); \
+                       deltwx = ((rw1 - (dy01 * deltwy + rw0)) / tmp); \
+               } else { deltux = deltvx = deltwx = 0; } \
+               ustart = (deltuy * ydiff) + (ru0); \
+               vstart = (deltvy * ydiff) + (rv0); \
+               wstart = (deltwy * ydiff) + (rw0); \
+       } while (0)
+
+
+#define SEND_COLORS() \
+       do { \
+               WAITFIFOEMPTY(6); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_GBX), deltgbx); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_ARX), deltarx); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_GBY), deltgby); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_ARY), deltary); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_GS_BS), gbstart); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_AS_RS), arstart); \
+       } while (0)
+
+#define SEND_VERTICES() \
+       do { \
+               WAITFIFOEMPTY(6); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_ZSTART), zstart); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_ZXD), deltzx); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_ZYD), deltzy); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TXDELTA12), delt12); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TXEND12), end12); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TXDELTA01), delt01); \
+               WAITFIFOEMPTY(5); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TXEND01), end01); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TXDELTA02), delt02); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TXSTART02), start02); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TYS), iy0); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TY01_Y12), \
+                               ((((iy0 - iy1) & 0x7FF) << 16) | \
+                               ((iy1 - iy2) & 0x7FF) | lr)); \
+       } while (0)
+
+#define SEND_UVWD() \
+       do { \
+               WAITFIFOEMPTY(7); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_BASEV), (rbasev & 0xFFFF)); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_BASEU), (0xa0000000 | (rbaseu & 0xFFFF))); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_WXD), deltwx); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_WYD), deltwy); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_WSTART), wstart); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_DXD), deltdx); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_VXD), deltvx); \
+               WAITFIFOEMPTY(7); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_UXD), deltux); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_DYD), deltdy); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_VYD), deltvy); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_UYD), deltuy); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_DSTART), dstart); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_VSTART), vstart); \
+               OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_USTART), ustart); \
+       } while (0)
+
+#define DMA_SEND_UVWD() \
+       do { \
+               DMAOUT((rbasev & 0xFFFF)); \
+               DMAOUT((0xa0000000 | (rbaseu & 0xFFFF))); \
+               DMAOUT(deltwx); \
+               DMAOUT(deltwy); \
+               DMAOUT(wstart); \
+               DMAOUT(deltdx); \
+               DMAOUT(deltvx); \
+               DMAOUT(deltux); \
+               DMAOUT(deltdy); \
+               DMAOUT(deltvy); \
+               DMAOUT(deltuy); \
+               DMAOUT(dstart); \
+               DMAOUT(vstart); \
+               DMAOUT(ustart); \
+       } while (0)
+
+
+#define DMA_SEND_COLORS() \
+       do { \
+               DMAOUT(deltgbx); \
+               DMAOUT(deltarx); \
+               DMAOUT(deltgby); \
+               DMAOUT(deltary); \
+               DMAOUT(gbstart); \
+               DMAOUT(arstart); \
+       } while (0)
+
+#define DMA_SEND_VERTICES() \
+       do { \
+               DMAOUT(deltzx); \
+               DMAOUT(deltzy); \
+               DMAOUT(zstart); \
+               DMAOUT(delt12); \
+               DMAOUT(end12); \
+               DMAOUT(delt01); \
+               DMAOUT(end01); \
+               DMAOUT(delt02); \
+               DMAOUT(start02); \
+               DMAOUT(iy0); \
+               DMAOUT(((((iy0 - iy1) & 0x7FF) << 16) | \
+                       ((iy1 - iy2) & 0x7FF) | lr)); \
+       } while (0)
+
diff --git a/src/mesa/drivers/dri/trident/trident_context.c b/src/mesa/drivers/dri/trident/trident_context.c
new file mode 100644 (file)
index 0000000..168e7d1
--- /dev/null
@@ -0,0 +1,419 @@
+/*
+ * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Trident CyberBladeXP driver.
+ *
+ */
+#include "trident_dri.h"
+#include "trident_context.h"
+#include "trident_lock.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "array_cache/acache.h"
+
+#include "tnl/tnl.h"
+#include "tnl/t_pipeline.h"
+
+#include "context.h"
+#include "simple_list.h"
+#include "mem.h"
+#include "matrix.h"
+#include "extensions.h"
+#if defined(USE_X86_ASM)
+#include "X86/common_x86_asm.h"
+#endif
+#include "simple_list.h"
+#include "mem.h"
+#include "mm.h"
+
+static const struct gl_pipeline_stage *trident_pipeline[] = {
+   &_tnl_vertex_transform_stage, 
+   &_tnl_normal_transform_stage, 
+   &_tnl_lighting_stage,
+   &_tnl_texgen_stage, 
+   &_tnl_texture_transform_stage, 
+   &_tnl_render_stage,         
+   0,
+};
+
+
+GLboolean tridentCreateContext( Display *dpy, const __GLcontextModes *glVisual,
+                            __DRIcontextPrivate *driContextPriv,
+                            void *sharedContextPrivate)
+{
+   GLcontext *ctx, *shareCtx;
+   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   tridentContextPtr tmesa;
+   tridentScreenPtr tridentscrn;
+#if 0
+   drm_trident_sarea_t *saPriv=(drm_trident_sarea_t *)(((char*)sPriv->pSAREA)+
+                                                sizeof(XF86DRISAREARec));
+#endif
+
+   tmesa = (tridentContextPtr) CALLOC( sizeof(*tmesa) );
+   if ( !tmesa ) return GL_FALSE;
+
+   /* Allocate the Mesa context */
+   if (sharedContextPrivate)
+      shareCtx = ((tridentContextPtr) sharedContextPrivate)->glCtx;
+   else
+      shareCtx = NULL;
+
+   tmesa->glCtx = _mesa_create_context(glVisual, shareCtx, tmesa, GL_TRUE);
+   if (!tmesa->glCtx) {
+      FREE(tmesa);
+      return GL_FALSE;
+   }
+
+   tmesa->display = dpy;
+
+   tmesa->driContext = driContextPriv;
+   tmesa->driScreen = sPriv;
+   tmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */
+
+   tmesa->hHWContext = driContextPriv->hHWContext;
+   tmesa->driHwLock = &sPriv->pSAREA->lock;
+   tmesa->driFd = sPriv->fd;
+#if 0
+   tmesa->sarea = saPriv;
+#endif
+
+   tridentscrn = tmesa->tridentScreen = (tridentScreenPtr)(sPriv->private);
+
+   ctx = tmesa->glCtx;
+
+   ctx->Const.MaxTextureLevels = 13;  /* 4K by 4K?  Is that right? */
+   ctx->Const.MaxTextureUnits = 1; /* Permedia 3 */
+
+   ctx->Const.MinLineWidth = 0.0;
+   ctx->Const.MaxLineWidth = 255.0;
+
+   ctx->Const.MinLineWidthAA = 0.0;
+   ctx->Const.MaxLineWidthAA = 65536.0;
+
+   ctx->Const.MinPointSize = 0.0;
+   ctx->Const.MaxPointSize = 255.0;
+
+   ctx->Const.MinPointSizeAA = 0.5; /* 4x4 quality mode */
+   ctx->Const.MaxPointSizeAA = 16.0; 
+   ctx->Const.PointSizeGranularity = 0.25;
+
+#if 0
+   tmesa->texHeap = mmInit( 0, tmesa->tridentScreen->textureSize );
+
+   make_empty_list(&tmesa->TexObjList);
+   make_empty_list(&tmesa->SwappedOut);
+
+   tmesa->CurrentTexObj[0] = 0;
+   tmesa->CurrentTexObj[1] = 0; /* Permedia 3, second texture */
+
+   tmesa->RenderIndex = ~0;
+#endif
+
+   /* Initialize the software rasterizer and helper modules.
+    */
+   _swrast_CreateContext( ctx );
+   _ac_CreateContext( ctx );
+   _tnl_CreateContext( ctx );
+   _swsetup_CreateContext( ctx );
+
+   /* Install the customized pipeline:
+    */
+   _tnl_destroy_pipeline( ctx );
+   _tnl_install_pipeline( ctx, trident_pipeline );
+
+   /* Configure swrast to match hardware characteristics:
+    */
+   _swrast_allow_pixel_fog( ctx, GL_FALSE );
+   _swrast_allow_vertex_fog( ctx, GL_TRUE );
+
+   tridentInitVB( ctx );
+   tridentDDInitExtensions( ctx );
+   tridentDDInitDriverFuncs( ctx );
+   tridentDDInitStateFuncs( ctx );
+#if 0
+   tridentDDInitSpanFuncs( ctx );
+   tridentDDInitTextureFuncs( ctx );
+#endif
+   tridentDDInitTriFuncs( ctx );
+   tridentDDInitState( tmesa );
+
+    driContextPriv->driverPrivate = (void *)tmesa;
+
+   UNLOCK_HARDWARE(tmesa);
+
+    return GL_TRUE;
+}
+
+static void 
+tridentDestroyContext(__DRIcontextPrivate *driContextPriv)
+{
+    tridentContextPtr tmesa = (tridentContextPtr)driContextPriv->driverPrivate;
+
+    if (tmesa) {
+      _swsetup_DestroyContext( tmesa->glCtx );
+      _tnl_DestroyContext( tmesa->glCtx );
+      _ac_DestroyContext( tmesa->glCtx );
+      _swrast_DestroyContext( tmesa->glCtx );
+
+      /* free the Mesa context */
+      tmesa->glCtx->DriverCtx = NULL;
+      _mesa_destroy_context(tmesa->glCtx);
+
+      Xfree(tmesa);
+      driContextPriv->driverPrivate = NULL;
+    }
+}
+
+
+static GLboolean
+tridentCreateBuffer( Display *dpy,
+                   __DRIscreenPrivate *driScrnPriv,
+                   __DRIdrawablePrivate *driDrawPriv,
+                   const __GLcontextModes *mesaVis,
+                   GLboolean isPixmap )
+{
+   if (isPixmap) {
+      return GL_FALSE; /* not implemented */
+   }
+   else {
+      driDrawPriv->driverPrivate = (void *) 
+         _mesa_create_framebuffer(mesaVis,
+                                  GL_FALSE,  /* software depth buffer? */
+                                  mesaVis->stencilBits > 0,
+                                  mesaVis->accumRedBits > 0,
+                                  mesaVis->alphaBits > 0
+                                  );
+      return (driDrawPriv->driverPrivate != NULL);
+   }
+}
+
+
+static void
+tridentDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+   _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
+}
+
+static void
+tridentSwapBuffers(Display *dpy, void *drawablePrivate)
+{
+   __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
+   (void) dpy;
+
+   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+      tridentContextPtr tmesa;
+      GLcontext *ctx;
+      tmesa = (tridentContextPtr) dPriv->driContextPriv->driverPrivate;
+      ctx = tmesa->glCtx;
+      if (ctx->Visual.doubleBufferMode) {
+         _mesa_swapbuffers( ctx );  /* flush pending rendering comands */
+         tridentCopyBuffer( dPriv );
+      }
+   }
+   else {
+      /* XXX this shouldn't be an error but we can't handle it for now */
+      _mesa_problem(NULL, "tridentSwapBuffers: drawable has no context!\n");
+   }
+}
+
+static GLboolean 
+tridentMakeCurrent(__DRIcontextPrivate *driContextPriv,
+                __DRIdrawablePrivate *driDrawPriv,
+                __DRIdrawablePrivate *driReadPriv)
+{
+    if (driContextPriv) {
+       GET_CURRENT_CONTEXT(ctx);
+       tridentContextPtr oldCtx = ctx ? TRIDENT_CONTEXT(ctx) : NULL;
+       tridentContextPtr newCtx = (tridentContextPtr) driContextPriv->driverPrivate;
+
+       if ( newCtx != oldCtx ) {
+           newCtx->dirty = ~0;
+       }
+
+       if (newCtx->driDrawable != driDrawPriv) {
+           newCtx->driDrawable = driDrawPriv;
+#if 0
+           tridentUpdateWindow ( newCtx->glCtx );
+           tridentUpdateViewportOffset( newCtx->glCtx );
+#endif
+       }
+
+   newCtx->drawOffset = newCtx->tridentScreen->backOffset;
+   newCtx->drawPitch = newCtx->tridentScreen->backPitch;
+
+       _mesa_make_current2( newCtx->glCtx, 
+                         (GLframebuffer *) driDrawPriv->driverPrivate,
+                         (GLframebuffer *) driReadPriv->driverPrivate );
+
+       if (!newCtx->glCtx->Viewport.Width) {
+           _mesa_set_viewport(newCtx->glCtx, 0, 0, 
+                                       driDrawPriv->w, driDrawPriv->h);
+       }
+    } else {
+       _mesa_make_current( 0, 0 );
+    }
+    return GL_TRUE;
+}
+
+
+static GLboolean 
+tridentUnbindContext( __DRIcontextPrivate *driContextPriv )
+{
+   return GL_TRUE;
+}
+
+static GLboolean
+tridentOpenFullScreen(__DRIcontextPrivate *driContextPriv)
+{
+    return GL_TRUE;
+}
+
+static GLboolean
+tridentCloseFullScreen(__DRIcontextPrivate *driContextPriv)
+{
+    return GL_TRUE;
+}
+
+
+tridentScreenPtr tridentCreateScreen( __DRIscreenPrivate *sPriv )
+{
+   TRIDENTDRIPtr tDRIPriv = (TRIDENTDRIPtr)sPriv->pDevPriv;
+   tridentScreenPtr tridentScreen;
+   int i;
+
+#if 0
+   /* Check the DRI version */
+   {
+      int major, minor, patch;
+      if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) {
+         if ( major != 3 || minor != 1 || patch < 0 ) {
+           __driUtilMessage( "r128 DRI driver expected DRI version 3.1.x but got version %d.%d.%d", major, minor, patch );
+            return GL_FALSE;
+         }
+      }
+   }
+
+   /* Check that the DDX driver version is compatible */
+   if ( sPriv->ddxMajor != 4 ||
+       sPriv->ddxMinor != 0 ||
+       sPriv->ddxPatch < 0 ) {
+      __driUtilMessage( "r128 DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch );
+      return GL_FALSE;
+   }
+
+   /* Check that the DRM driver version is compatible */
+   if ( sPriv->drmMajor != 2 ||
+       sPriv->drmMinor != 1 ||
+       sPriv->drmPatch < 0 ) {
+      __driUtilMessage( "r128 DRI driver expected DRM driver version 2.1.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch );
+      return GL_FALSE;
+   }
+#endif
+
+    /* Allocate the private area */
+    tridentScreen = (tridentScreenPtr) CALLOC( sizeof(*tridentScreen) );
+    if ( !tridentScreen ) return NULL;
+
+   tridentScreen->driScreen = sPriv;
+
+   tridentScreen->frontOffset = tDRIPriv->frontOffset;
+   tridentScreen->backOffset = tDRIPriv->backOffset;
+   tridentScreen->depthOffset = tDRIPriv->depthOffset;
+   tridentScreen->frontPitch = tDRIPriv->frontPitch;
+   tridentScreen->backPitch = tDRIPriv->backPitch;
+   tridentScreen->depthPitch = tDRIPriv->depthPitch;
+   tridentScreen->width = tDRIPriv->width;
+   tridentScreen->height = tDRIPriv->height;
+
+printf("%d %d\n",tridentScreen->width,tridentScreen->height);
+printf("%d %d\n",tridentScreen->frontPitch,tridentScreen->backPitch);
+printf("offset 0x%x 0x%x\n",tridentScreen->backOffset,tridentScreen->depthOffset);
+
+   tridentScreen->mmio.handle = tDRIPriv->regs;
+   tridentScreen->mmio.size = 0x20000;
+    
+   if (drmMap(sPriv->fd,
+               tridentScreen->mmio.handle, tridentScreen->mmio.size,
+               (drmAddressPtr)&tridentScreen->mmio.map)) {
+           FREE(tridentScreen);
+           return GL_FALSE;
+    }
+printf("MAPPED at 0x%x\n",tridentScreen->mmio.map);
+
+   return tridentScreen;
+}
+
+/* Destroy the device specific screen private data struct.
+ */
+void tridentDestroyScreen( __DRIscreenPrivate *sPriv )
+{
+    tridentScreenPtr tridentScreen = (tridentScreenPtr)sPriv->private;
+
+    FREE(tridentScreen);
+}
+static GLboolean 
+tridentInitDriver(__DRIscreenPrivate *sPriv)
+{
+    sPriv->private = (void *) tridentCreateScreen( sPriv );
+
+    if (!sPriv->private) {
+       tridentDestroyScreen( sPriv );
+       return GL_FALSE;
+    }
+
+    return GL_TRUE;
+}
+
+static struct __DriverAPIRec tridentAPI = {
+   tridentInitDriver,
+   tridentDestroyScreen,
+   tridentCreateContext,
+   tridentDestroyContext,
+   tridentCreateBuffer,
+   tridentDestroyBuffer,
+   tridentSwapBuffers,
+   tridentMakeCurrent,
+   tridentUnbindContext,
+   tridentOpenFullScreen,
+   tridentCloseFullScreen
+};
+
+/*
+ * This is the bootstrap function for the driver.
+ * The __driCreateScreen name is the symbol that libGL.so fetches.
+ * Return:  pointer to a __DRIscreenPrivate.
+ */
+void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
+                        int numConfigs, __GLXvisualConfig *config)
+{
+   __DRIscreenPrivate *psp;
+   psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &tridentAPI);
+   return (void *) psp;
+}
+
+void __driRegisterExtensions(void)
+{
+   /* No extensions */
+}
diff --git a/src/mesa/drivers/dri/trident/trident_context.h b/src/mesa/drivers/dri/trident/trident_context.h
new file mode 100644 (file)
index 0000000..ee098e5
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Trident CyberBladeXP driver.
+ *
+ */
+#ifndef _TRIDENT_CONTEXT_H_
+#define _TRIDENT_CONTEXT_H_
+
+#include "compiler.h"
+#include "dri_util.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "drm.h"
+#include "mm.h"
+
+#define SUBPIXEL_X (0.0F)
+#define SUBPIXEL_Y (0.125F)
+
+#define _TRIDENT_NEW_VERTEX (_NEW_TEXTURE |            \
+                          _DD_NEW_TRI_UNFILLED |       \
+                          _DD_NEW_TRI_LIGHT_TWOSIDE)
+
+#define TRIDENT_FALLBACK_TEXTURE       0x01
+#define TRIDENT_FALLBACK_DRAW_BUFFER   0x02
+
+#define TRIDENT_NEW_CLIP               0x01
+
+#define TRIDENT_UPLOAD_COMMAND_D       0x00000001
+#define TRIDENT_UPLOAD_CONTEXT         0x04000000
+#define TRIDENT_UPLOAD_CLIPRECTS       0x80000000
+
+#define TAG(x) trident##x
+#include "tnl_dd/t_dd_vertex.h"
+#undef TAG
+
+struct trident_context;
+typedef struct trident_context tridentContextRec;
+typedef struct trident_context *tridentContextPtr;
+
+typedef void (*trident_quad_func)( tridentContextPtr, 
+                                const tridentVertex *, 
+                                const tridentVertex *,
+                                const tridentVertex *,
+                                const tridentVertex * );
+typedef void (*trident_tri_func)( tridentContextPtr, 
+                               const tridentVertex *, 
+                               const tridentVertex *,
+                               const tridentVertex * );
+typedef void (*trident_line_func)( tridentContextPtr, 
+                                const tridentVertex *, 
+                                const tridentVertex * );
+typedef void (*trident_point_func)( tridentContextPtr, 
+                                 const tridentVertex * );
+
+typedef struct {
+   drmHandle handle;                   /* Handle to the DRM region */
+   drmSize size;                       /* Size of the DRM region */
+   unsigned char *map;                 /* Mapping of the DRM region */
+} tridentRegionRec, *tridentRegionPtr;
+
+typedef struct {
+    __DRIscreenPrivate *driScreen; /* Back pointer to DRI screen */
+
+    drmBufMapPtr buffers;
+
+    unsigned int frontOffset;
+    unsigned int frontPitch;
+    unsigned int backOffset;
+    unsigned int backPitch;
+    unsigned int depthOffset;
+    unsigned int depthPitch;
+    unsigned int width;
+    unsigned int height;
+    unsigned int cpp;
+
+#if 0
+    unsigned int sarea_priv_offset;
+#endif
+
+    tridentRegionRec mmio;
+} tridentScreenRec, *tridentScreenPtr;
+
+struct trident_context {
+       GLcontext               *glCtx;         /* Mesa context */
+
+       __DRIcontextPrivate     *driContext;
+       __DRIscreenPrivate      *driScreen;
+       __DRIdrawablePrivate    *driDrawable;
+
+       GLuint                  new_gl_state;
+       GLuint                  new_state;
+       GLuint                  dirty;
+
+#if 0
+       drm_trident_sarea_t     *sarea; 
+#endif
+
+        /* Temporaries for translating away float colors:
+        */
+        struct gl_client_array UbyteColor;
+        struct gl_client_array UbyteSecondaryColor;
+
+       /* Mirrors of some DRI state
+        */
+       Display *display;                       /* X server display */
+
+       int lastStamp;                  /* mirror driDrawable->lastStamp */
+
+       drmContext hHWContext;
+       drmLock *driHwLock;
+       int driFd;
+
+       tridentScreenPtr tridentScreen; /* Screen private DRI data */
+
+       /* Visual, drawable, cliprect and scissor information
+        */
+       GLenum DrawBuffer;
+       GLint drawOffset, drawPitch;
+       GLint drawX, drawY;             /* origin of drawable in draw buffer */
+       GLint readOffset, readPitch;
+
+       GLuint numClipRects;            /* Cliprects for the draw buffer */
+       XF86DRIClipRectPtr pClipRects;
+
+       GLint scissor;
+       XF86DRIClipRectRec ScissorRect; /* Current software scissor */
+
+       GLuint Fallback;
+       GLuint RenderIndex;
+       GLuint SetupNewInputs;
+       GLuint SetupIndex;
+       GLfloat hw_viewport[16];
+       GLfloat depth_scale;
+       GLuint vertex_format;
+       GLuint vertex_size;
+       GLuint vertex_stride_shift;
+       char *verts;
+
+       GLint tmu_source[2];
+
+       GLuint hw_primitive;
+       GLenum render_primitive;
+
+       trident_point_func    draw_point;
+       trident_line_func     draw_line;
+       trident_tri_func      draw_tri;
+       trident_quad_func     draw_quad;
+
+#if 0
+       gammaTextureObjectPtr CurrentTexObj[2];
+       struct gamma_texture_object_t TexObjList;
+       struct gamma_texture_object_t SwappedOut; 
+       GLenum TexEnvImageFmt[2];
+
+       memHeap_t *texHeap;
+
+       int lastSwap;
+       int texAge;
+       int ctxAge;
+       int dirtyAge;
+        int lastStamp;
+#endif
+
+       /* Chip state */
+       
+       int     commandD;
+
+       /* Context State */
+       
+       int     ClearColor;
+};
+
+void tridentDDInitExtensions( GLcontext *ctx );
+void tridentDDInitDriverFuncs( GLcontext *ctx );
+void tridentDDInitSpanFuncs( GLcontext *ctx );
+void tridentDDInitState( tridentContextPtr tmesa );
+void tridentInitHW( tridentContextPtr tmesa );
+void tridentDDInitStateFuncs( GLcontext *ctx );
+void tridentDDInitTextureFuncs( GLcontext *ctx );
+void tridentDDInitTriFuncs( GLcontext *ctx );
+extern void tridentBuildVertices( GLcontext *ctx, 
+                               GLuint start, 
+                               GLuint count,
+                               GLuint newinputs );
+
+#define TRIDENT_CONTEXT(ctx)           ((tridentContextPtr)(ctx->DriverCtx))
+
+#endif /* _TRIDENT_CONTEXT_H_ */
diff --git a/src/mesa/drivers/dri/trident/trident_dd.c b/src/mesa/drivers/dri/trident/trident_dd.c
new file mode 100644 (file)
index 0000000..2f79ffc
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Trident CyberBladeXP driver.
+ *
+ */
+#include "trident_context.h"
+#include "trident_lock.h"
+#if defined(USE_X86_ASM)
+#include "X86/common_x86_asm.h"
+#endif
+
+#include "swrast/swrast.h"
+#include "context.h"
+
+#define TRIDENT_DATE   "20020318"
+
+
+/* Return the width and height of the current color buffer.
+ */
+static void tridentDDGetBufferSize( GLframebuffer *framebuffer,
+                                GLuint *width, GLuint *height )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+
+   LOCK_HARDWARE(tmesa);
+   *width  = tmesa->driDrawable->w;
+   *height = tmesa->driDrawable->h;
+   UNLOCK_HARDWARE(tmesa);
+}
+
+
+/* Return various strings for glGetString().
+ */
+static const GLubyte *tridentDDGetString( GLcontext *ctx, GLenum name )
+{
+   static char buffer[128];
+
+   switch ( name ) {
+   case GL_VENDOR:
+      return (GLubyte *)"Alan Hourihane";
+
+   case GL_RENDERER:
+      sprintf( buffer, "Mesa DRI Trident " TRIDENT_DATE );
+
+      /* Append any CPU-specific information.
+       */
+#ifdef USE_X86_ASM
+      if ( _mesa_x86_cpu_features ) {
+        strncat( buffer, " x86", 4 );
+      }
+#ifdef USE_MMX_ASM
+      if ( cpu_has_mmx ) {
+        strncat( buffer, "/MMX", 4 );
+      }
+#endif
+#ifdef USE_3DNOW_ASM
+      if ( cpu_has_3dnow ) {
+        strncat( buffer, "/3DNow!", 7 );
+      }
+#endif
+#ifdef USE_SSE_ASM
+      if ( cpu_has_xmm ) {
+        strncat( buffer, "/SSE", 4 );
+      }
+#endif
+#endif
+      return (GLubyte *)buffer;
+
+   default:
+      return NULL;
+   }
+}
+
+/* Enable the extensions supported by this driver.
+ */
+void tridentDDInitExtensions( GLcontext *ctx )
+{
+   /* None... */
+}
+
+/* Initialize the driver's misc functions.
+ */
+void tridentDDInitDriverFuncs( GLcontext *ctx )
+{
+   ctx->Driver.GetBufferSize           = tridentDDGetBufferSize;
+   ctx->Driver.GetString               = tridentDDGetString;
+
+   ctx->Driver.Error                   = NULL;
+
+   /* Pixel path fallbacks
+    */
+   ctx->Driver.Accum                    = _swrast_Accum;
+   ctx->Driver.Bitmap                   = _swrast_Bitmap;
+   ctx->Driver.CopyPixels               = _swrast_CopyPixels;
+   ctx->Driver.DrawPixels               = _swrast_DrawPixels;
+   ctx->Driver.ReadPixels               = _swrast_ReadPixels;
+   ctx->Driver.ResizeBuffers            = _swrast_alloc_buffers;
+
+   /* Swrast hooks for imaging extensions:
+    */
+   ctx->Driver.CopyColorTable          = _swrast_CopyColorTable;
+   ctx->Driver.CopyColorSubTable       = _swrast_CopyColorSubTable;
+   ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+   ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+}
diff --git a/src/mesa/drivers/dri/trident/trident_state.c b/src/mesa/drivers/dri/trident/trident_state.c
new file mode 100644 (file)
index 0000000..4931882
--- /dev/null
@@ -0,0 +1,552 @@
+/*
+ * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Trident CyberBladeXP driver.
+ *
+ */
+#include "trident_context.h"
+#include "trident_lock.h"
+#include "swrast/swrast.h"
+
+#define TRIDENTPACKCOLOR332(r, g, b)                                   \
+   (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6))
+
+#define TRIDENTPACKCOLOR1555(r, g, b, a)                                       \
+   ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) |  \
+    ((a) ? 0x8000 : 0))
+
+#define TRIDENTPACKCOLOR565(r, g, b)                                   \
+   ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+
+#define TRIDENTPACKCOLOR888(r, g, b)                                   \
+   (((r) << 16) | ((g) << 8) | (b))
+
+#define TRIDENTPACKCOLOR8888(r, g, b, a)                                       \
+   (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+
+#define TRIDENTPACKCOLOR4444(r, g, b, a)                                       \
+   ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
+
+static __inline__ GLuint tridentPackColor( GLuint cpp,
+                                         GLubyte r, GLubyte g,
+                                         GLubyte b, GLubyte a )
+{
+   switch ( cpp ) {
+   case 2:
+      return TRIDENTPACKCOLOR565( r, g, b );
+   case 4:
+      return TRIDENTPACKCOLOR8888( r, g, b, a );
+   default:
+      return 0;
+   }
+}
+
+void tridentUploadHwStateLocked( tridentContextPtr tmesa )
+{
+   unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+#if 0
+   ATISAREAPrivPtr sarea = tmesa->sarea;
+   trident_context_regs_t *regs = &(sarea->ContextState);
+#endif
+
+   if ( tmesa->dirty & TRIDENT_UPLOAD_COMMAND_D ) {
+      MMIO_OUT32(MMIO, 0x00281C, tmesa->commandD );
+      tmesa->dirty &= ~TRIDENT_UPLOAD_COMMAND_D;
+   }
+
+   if ( tmesa->dirty & TRIDENT_UPLOAD_CLIPRECTS ) {
+      /* XXX FIX ME ! */
+      MMIO_OUT32(MMIO, 0x002C80 , 0x20008000 | tmesa->tridentScreen->height );    
+      MMIO_OUT32(MMIO, 0x002C84 , 0x20000000 | tmesa->tridentScreen->width );    
+      tmesa->dirty &= ~TRIDENT_UPLOAD_CLIPRECTS;
+   }
+
+   tmesa->dirty = 0;
+}
+
+/* Copy the back color buffer to the front color buffer.
+ */
+void tridentCopyBuffer( const __DRIdrawablePrivate *dPriv )
+{
+   unsigned char *MMIO;
+   tridentContextPtr tmesa;
+   GLint nbox, i, ret;
+   int busy;
+   XF86DRIClipRectPtr pbox;
+
+   assert(dPriv);
+   assert(dPriv->driContextPriv);
+   assert(dPriv->driContextPriv->driverPrivate);
+
+   tmesa = (tridentContextPtr) dPriv->driContextPriv->driverPrivate;
+   MMIO = tmesa->tridentScreen->mmio.map;
+
+   LOCK_HARDWARE( tmesa );
+
+   /* use front buffer cliprects */
+   nbox = dPriv->numClipRects;
+   pbox = dPriv->pClipRects;
+
+   for ( i = 0 ; i < nbox ; i++ ) {
+#if 0
+      GLint nr = MIN2( i + MACH64_NR_SAREA_CLIPRECTS , nbox );
+      XF86DRIClipRectPtr b = tmesa->sarea->boxes;
+      GLint n = 0;
+
+      for ( ; i < nr ; i++ ) {
+        *b++ = pbox[i];
+        n++;
+      }
+      tmesa->sarea->nbox = n;
+#endif
+
+    MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->frontPitch << 20 | tmesa->tridentScreen->frontOffset>>4);
+    MMIO_OUT32(MMIO, 0x2154, tmesa->tridentScreen->backPitch << 20 | tmesa->tridentScreen->backOffset>>4);
+    MMIO_OUT8(MMIO, 0x2127, 0xCC); /* Copy Rop */
+    MMIO_OUT32(MMIO, 0x2128, 0x4); /* scr2scr */
+    MMIO_OUT32(MMIO, 0x2138, (pbox->x1 << 16) | pbox->y1);
+    MMIO_OUT32(MMIO, 0x213C, (pbox->x1 << 16) | pbox->y1);
+    MMIO_OUT32(MMIO, 0x2140, (pbox->x2 - pbox->x1) << 16 | (pbox->y2 - pbox->y1) );
+    MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */
+#define GE_BUSY 0x80
+    for (;;) {
+       busy = MMIO_IN8(MMIO, 0x2120);
+       if ( !(busy & GE_BUSY) )
+               break;
+    }
+   }
+
+   UNLOCK_HARDWARE( tmesa );
+
+#if 0
+   tmesa->dirty |= (MACH64_UPLOAD_CONTEXT |
+                   MACH64_UPLOAD_MISC |
+                   MACH64_UPLOAD_CLIPRECTS);
+#endif
+}
+
+
+static void tridentDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+                              GLint cx, GLint cy, GLint cw, GLint ch )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+   unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+   __DRIdrawablePrivate *dPriv = tmesa->driDrawable;
+   int busy;
+   GLuint flags = 0;
+   GLint i;
+   GLint ret;
+
+#define DRM_TRIDENT_FRONT      0x01
+#define DRM_TRIDENT_BACK       0x02
+#define DRM_TRIDENT_DEPTH      0x04
+
+   if ( tmesa->new_state )
+      tridentDDUpdateHWState( ctx );
+
+   if ( mask & DD_FRONT_LEFT_BIT ) {
+      flags |= DRM_TRIDENT_FRONT;
+      mask &= ~DD_FRONT_LEFT_BIT;
+   }
+
+   if ( mask & DD_BACK_LEFT_BIT ) {
+      flags |= DRM_TRIDENT_BACK;
+      mask &= ~DD_BACK_LEFT_BIT;
+   }
+
+   if ( ( mask & DD_DEPTH_BIT ) && ctx->Depth.Mask ) {
+      flags |= DRM_TRIDENT_DEPTH;
+      mask &= ~DD_DEPTH_BIT;
+   }
+
+   LOCK_HARDWARE(tmesa);
+
+   if ( flags ) {
+   
+      cx += tmesa->drawX;
+      cy += tmesa->drawY;
+   
+      /* HACK!!!
+       */
+      if ( tmesa->dirty & ~TRIDENT_UPLOAD_CLIPRECTS ) {
+         tridentUploadHwStateLocked( tmesa );
+      }
+   
+      for ( i = 0 ; i < tmesa->numClipRects ; i++ ) {
+#if 0
+         int nr = MIN2( i + TRIDENT_NR_SAREA_CLIPRECTS, tmesa->numClipRects );
+         XF86DRIClipRectPtr box = tmesa->pClipRects;
+         XF86DRIClipRectPtr b = tmesa->sarea->boxes;
+         GLint n = 0;
+   
+         if ( !all ) {
+           for ( ; i < nr ; i++ ) {
+              GLint x = box[i].x1;
+              GLint y = box[i].y1;
+              GLint w = box[i].x2 - x;
+              GLint h = box[i].y2 - y;
+              
+              if ( x < cx ) w -= cx - x, x = cx;
+              if ( y < cy ) h -= cy - y, y = cy;
+              if ( x + w > cx + cw ) w = cx + cw - x;
+              if ( y + h > cy + ch ) h = cy + ch - y;
+              if ( w <= 0 ) continue;
+              if ( h <= 0 ) continue;
+              
+              b->x1 = x;
+              b->y1 = y;
+              b->x2 = x + w;
+              b->y2 = y + h;
+              b++;
+              n++;
+           }
+         } else {
+           for ( ; i < nr ; i++ ) {
+              *b++ = box[i];
+              n++;
+           }
+         }
+   
+         tmesa->sarea->nbox = n;
+#endif
+   
+if (flags & DRM_TRIDENT_BACK) {
+    MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->backPitch << 20 | tmesa->tridentScreen->backOffset>>4);
+         MMIO_OUT8(MMIO, 0x2127, 0xF0); /* Pat Rop */
+         MMIO_OUT32(MMIO, 0x2158, tmesa->ClearColor);
+         MMIO_OUT32(MMIO, 0x2128, 0x4000); /* solidfill */
+         MMIO_OUT32(MMIO, 0x2138, cx << 16 | cy);
+         MMIO_OUT32(MMIO, 0x2140, cw << 16 | ch);
+         MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */
+#define GE_BUSY 0x80
+        for (;;) {
+               busy = MMIO_IN8(MMIO, 0x2120);
+               if ( !(busy & GE_BUSY) )
+                       break;
+        }
+}
+if (flags & DRM_TRIDENT_DEPTH) {
+    MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->depthPitch << 20 | tmesa->tridentScreen->depthOffset>>4);
+         MMIO_OUT8(MMIO, 0x2127, 0xF0); /* Pat Rop */
+         MMIO_OUT32(MMIO, 0x2158, tmesa->ClearColor);
+         MMIO_OUT32(MMIO, 0x2128, 0x4000); /* solidfill */
+         MMIO_OUT32(MMIO, 0x2138, cx << 16 | cy);
+         MMIO_OUT32(MMIO, 0x2140, cw << 16 | ch);
+         MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */
+#define GE_BUSY 0x80
+        for (;;) {
+               busy = MMIO_IN8(MMIO, 0x2120);
+               if ( !(busy & GE_BUSY) )
+                       break;
+        }
+}
+    MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->frontPitch << 20 | tmesa->tridentScreen->frontOffset>>4);
+if (flags & DRM_TRIDENT_FRONT) {
+         MMIO_OUT8(MMIO, 0x2127, 0xF0); /* Pat Rop */
+         MMIO_OUT32(MMIO, 0x2158, tmesa->ClearColor);
+         MMIO_OUT32(MMIO, 0x2128, 0x4000); /* solidfill */
+         MMIO_OUT32(MMIO, 0x2138, cx << 16 | cy);
+         MMIO_OUT32(MMIO, 0x2140, cw << 16 | ch);
+         MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */
+#define GE_BUSY 0x80
+        for (;;) {
+               busy = MMIO_IN8(MMIO, 0x2120);
+               if ( !(busy & GE_BUSY) )
+                       break;
+        }
+}
+   
+      }
+   
+#if 0
+      tmesa->dirty |= (TRIDENT_UPLOAD_CONTEXT |
+                      TRIDENT_UPLOAD_MISC |
+                      TRIDENT_UPLOAD_CLIPRECTS);
+#endif
+   }
+
+   UNLOCK_HARDWARE(tmesa);
+
+   if ( mask )
+      _swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
+}
+
+static void tridentDDShadeModel( GLcontext *ctx, GLenum mode )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+   GLuint s = tmesa->commandD;
+
+#define TRIDENT_FLAT_SHADE                     0x000000E0
+#define TRIDENT_FLAT_SHADE_VERTEX_C            0x00000060
+#define TRIDENT_FLAT_SHADE_GOURAUD             0x00000080
+
+   s &= ~TRIDENT_FLAT_SHADE;
+
+   switch ( mode ) {
+   case GL_FLAT:
+      s |= TRIDENT_FLAT_SHADE_VERTEX_C;
+      break;
+   case GL_SMOOTH:
+      s |= TRIDENT_FLAT_SHADE_GOURAUD;
+      break;
+   default:
+      return;
+   }
+
+   if ( tmesa->commandD != s ) {
+      tmesa->commandD = s;
+
+      tmesa->dirty |= TRIDENT_UPLOAD_COMMAND_D;
+   }
+}
+
+void tridentCalcViewport( GLcontext *ctx )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+   const GLfloat *v = ctx->Viewport._WindowMap.m;
+   GLfloat *m = tmesa->hw_viewport;
+
+   /* See also trident_translate_vertex.
+    */
+   m[MAT_SX] =   v[MAT_SX];
+   m[MAT_TX] =   v[MAT_TX] + tmesa->drawX + SUBPIXEL_X;
+   m[MAT_SY] = - v[MAT_SY];
+   m[MAT_TY] = - v[MAT_TY] + tmesa->driDrawable->h + tmesa->drawY + SUBPIXEL_Y;
+#if 0
+   m[MAT_SZ] =   v[MAT_SZ] * tmesa->depth_scale;
+   m[MAT_TZ] =   v[MAT_TZ] * tmesa->depth_scale;
+#else
+   m[MAT_SZ] =   v[MAT_SZ];
+   m[MAT_TZ] =   v[MAT_TZ];
+#endif
+
+   tmesa->SetupNewInputs = ~0;
+}
+
+static void tridentDDViewport( GLcontext *ctx,
+                         GLint x, GLint y,
+                         GLsizei width, GLsizei height )
+{
+   tridentCalcViewport( ctx );
+}
+
+static void tridentDDDepthRange( GLcontext *ctx,
+                           GLclampd nearval, GLclampd farval )
+{
+   tridentCalcViewport( ctx );
+}
+
+void tridentSetCliprects( tridentContextPtr tmesa, GLenum mode )
+{
+   __DRIdrawablePrivate *dPriv = tmesa->driDrawable;
+
+   switch ( mode ) {
+   case GL_FRONT_LEFT:
+      if (dPriv->numClipRects == 0) {
+        static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
+        tmesa->numClipRects = 1;
+        tmesa->pClipRects = &zeroareacliprect;
+      } else {
+        tmesa->numClipRects = dPriv->numClipRects;
+        tmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects;
+      }
+      tmesa->drawX = dPriv->x;
+      tmesa->drawY = dPriv->y;
+      break;
+   case GL_BACK_LEFT:
+      if ( dPriv->numBackClipRects == 0 ) {
+         if (dPriv->numClipRects == 0) {
+            static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
+            tmesa->numClipRects = 1;
+            tmesa->pClipRects = &zeroareacliprect;
+         } else {
+            tmesa->numClipRects = dPriv->numClipRects;
+            tmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects;
+            tmesa->drawX = dPriv->x;
+            tmesa->drawY = dPriv->y;
+         }
+      }
+      else {
+        tmesa->numClipRects = dPriv->numBackClipRects;
+        tmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pBackClipRects;
+        tmesa->drawX = dPriv->backX;
+        tmesa->drawY = dPriv->backY;
+      }
+      break;
+   default:
+      return;
+   }
+
+#if 0
+   tmesa->dirty |= TRIDENT_UPLOAD_CLIPRECTS;
+#endif
+}
+
+static GLboolean tridentDDSetDrawBuffer( GLcontext *ctx, GLenum mode )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+   int found = GL_TRUE;
+
+   if ( tmesa->DrawBuffer != mode ) {
+      tmesa->DrawBuffer = mode;
+      
+      switch ( mode ) {
+      case GL_FRONT_LEFT:
+        tridentFallback( tmesa, TRIDENT_FALLBACK_DRAW_BUFFER, GL_FALSE );
+        tmesa->drawOffset = tmesa->tridentScreen->frontOffset;
+        tmesa->drawPitch  = tmesa->tridentScreen->frontPitch;
+        tridentSetCliprects( tmesa, GL_FRONT_LEFT );
+        break;
+      case GL_BACK_LEFT:
+        tridentFallback( tmesa, TRIDENT_FALLBACK_DRAW_BUFFER, GL_FALSE );
+        tmesa->drawOffset = tmesa->tridentScreen->backOffset;
+        tmesa->drawPitch  = tmesa->tridentScreen->backPitch;
+        tridentSetCliprects( tmesa, GL_BACK_LEFT );
+        break;
+      default:
+        tridentFallback( tmesa, TRIDENT_FALLBACK_DRAW_BUFFER, GL_TRUE );
+        found = GL_FALSE;
+        break;
+      }
+
+#if 0
+      tmesa->setup.dst_off_pitch = (((tmesa->drawPitch/8) << 22) |
+                                   (tmesa->drawOffset >> 3));
+
+      tmesa->dirty |= MACH64_UPLOAD_DST_OFF_PITCH | MACH64_UPLOAD_CONTEXT;
+#endif
+      
+   }
+
+   return found;
+}
+
+static void tridentDDClearColor( GLcontext *ctx,
+                               const GLchan color[4] )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+
+   tmesa->ClearColor = tridentPackColor( tmesa->tridentScreen->cpp,
+                                       color[0], color[1], 
+                                       color[2], color[3] );
+}
+
+
+void tridentDDUpdateState( GLcontext *ctx, GLuint new_state )
+{
+   _swrast_InvalidateState( ctx, new_state );
+   _swsetup_InvalidateState( ctx, new_state );
+   _ac_InvalidateState( ctx, new_state );
+   _tnl_InvalidateState( ctx, new_state );
+   TRIDENT_CONTEXT(ctx)->new_gl_state |= new_state;
+}
+
+
+/* Initialize the context's hardware state.
+ */
+void tridentDDInitState( tridentContextPtr tmesa )
+{
+   tmesa->new_state = 0;
+
+   switch ( tmesa->glCtx->Visual.depthBits ) {
+   case 16:
+      tmesa->depth_scale = 1.0 / (GLfloat)0xffff;
+      break;
+   case 24:
+      tmesa->depth_scale = 1.0 / (GLfloat)0xffffff;
+      break;
+   }
+}
+
+void tridentDDUpdateHWState( GLcontext *ctx )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+   int new_state = tmesa->new_state;
+
+   if ( new_state )
+   {
+      tmesa->new_state = 0;
+
+#if 0
+      /* Update the various parts of the context's state.
+       */
+      if ( new_state & GAMMA_NEW_ALPHA )
+        tridentUpdateAlphaMode( ctx );
+
+      if ( new_state & GAMMA_NEW_DEPTH )
+        tridentUpdateZMode( ctx );
+
+      if ( new_state & GAMMA_NEW_FOG )
+        gammaUpdateFogAttrib( ctx );
+
+      if ( new_state & GAMMA_NEW_CLIP )
+        gammaUpdateClipping( ctx );
+
+      if ( new_state & GAMMA_NEW_POLYGON )
+        gammaUpdatePolygon( ctx );
+
+      if ( new_state & GAMMA_NEW_CULL )
+        gammaUpdateCull( ctx );
+
+      if ( new_state & GAMMA_NEW_MASKS )
+        gammaUpdateMasks( ctx );
+
+      if ( new_state & GAMMA_NEW_STIPPLE )
+        gammaUpdateStipple( ctx );
+#endif
+   }
+
+   /* HACK ! */
+
+#if 0
+   gammaEmitHwState( tmesa );
+#endif
+}
+
+/* Initialize the driver's state functions.
+ */
+void tridentDDInitStateFuncs( GLcontext *ctx )
+{
+   ctx->Driver.UpdateState             = tridentDDUpdateState;
+
+   ctx->Driver.Clear                   = tridentDDClear;
+   ctx->Driver.DepthRange              = tridentDDDepthRange;
+   ctx->Driver.ShadeModel              = tridentDDShadeModel;
+   ctx->Driver.Viewport                        = tridentDDViewport;
+
+   /* Pixel path fallbacks.
+    */
+   ctx->Driver.Accum = _swrast_Accum;
+   ctx->Driver.Bitmap = _swrast_Bitmap;
+   ctx->Driver.CopyPixels = _swrast_CopyPixels;
+   ctx->Driver.DrawPixels = _swrast_DrawPixels;
+   ctx->Driver.ReadPixels = _swrast_ReadPixels;
+   ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
+
+   /* Swrast hooks for imaging extensions:
+    */
+   ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
+   ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
+   ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+   ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+}
diff --git a/src/mesa/drivers/dri/trident/trident_tris.c b/src/mesa/drivers/dri/trident/trident_tris.c
new file mode 100644 (file)
index 0000000..890e34e
--- /dev/null
@@ -0,0 +1,1112 @@
+/*
+ * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Trident CyberBladeXP driver.
+ *
+ */
+
+#include "trident_context.h"
+#include "trident_lock.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+#include "swrast/swrast.h"
+
+static int first = 1;
+
+typedef struct reg {
+       int addr;
+       int data;
+} RegData;
+
+RegData initRegData[]={
+    {0x2804,  0x19980824},
+    {0x2F70,  0x46455858},
+    {0x2F74,    0x41584998},
+    {0x2F00,    0x00000000},
+    {0x2F04,    0x80000800},
+    {0x2F08,    0x00550200},
+    {0x2F40,    0x00000001},
+    {0x2F40,    0x00000001},
+    {0x2F44,    0x00830097},
+    {0x2F48,    0x0087009F},
+    {0x2F4C,    0x00BF0003},
+    {0x2F50,    0xF00B6C1B},
+    {0x2C04,    0x00000000},
+    {0x2D00,    0x00000080},
+    {0x2D00,    0x00000000},
+    {0x2DD4,    0x00100000},
+    {0x2DD4,    0x00100010},
+    {0x2DD8,    0x00100000},
+    {0x2DD8,    0x00100010},
+    {0x2C88,    0xFFFFFFFF},
+    {0x2C94 ,   0xFFFFFFFF},
+    {0x281C,    0x00008000},
+    {0x2C80,    0x00000000},
+    {0x2C80,    0x00000000},
+    {0x2C80 ,   0x00008000},
+    {0x2C00  ,  0x00000000},
+    {0x2C04  ,  0x00000000},
+    {0x2C08  ,  0x00000000},
+    {0x2C0C  ,  0x00000000},
+    {0x2C10  ,  0x00000000},
+    {0x2C14  ,  0x00000000},
+    {0x2C18  ,  0x00000000},
+    {0x2C1C  ,  0x00000000},
+    {0x2C20  ,  0x00000000},
+    {0x2C24  ,  0x00000000},
+    {0x2C2C  ,  0x00000000},
+    {0x2C30  ,  0x00000000},
+    {0x2C34  ,  0x00000000},
+    {0x2C38  ,  0x00000000},
+    {0x2C3C  ,  0x00000000},
+    {0x2C40  ,  0x00000000},
+    {0x2C44  ,  0x00000000},
+    {0x2C48  ,  0x00000000},
+    {0x2C4C  ,  0x00000000},
+    {0x2C50  ,  0x00000000},
+    {0x2C54  ,  0x00000000},
+    {0x2C58  ,  0x00000000},
+    {0x2C5C  ,  0x00000000},
+    {0x2C60  ,  0x00000000},
+    {0x2C64  ,  0x00000000},
+    {0x2C68  ,  0x00000000},
+    {0x2C6C  ,  0x00000000},
+    {0x2C70  ,  0x00000000},
+    {0x2C74  ,  0x00000000},
+    {0x2C78  ,  0x00000000},
+    {0x2C7C  ,  0x00000000},
+    {0x2C80  ,  0x00008000},
+    {0x2C84  ,  0x00000000},
+    {0x2C88  ,  0xFFFFFFFF},
+    {0x2C8C  ,  0x00000000},
+    {0x2C90  ,  0x00000000},
+    {0x2C94  ,  0xFFFFFFFF},
+    {0x2C98  ,  0x00000000},
+    {0x2C9C  ,  0x00000000},
+    {0x2CA0  ,  0x00000000},
+    {0x2CA4   , 0x00000000},
+    {0x2CA8   , 0x00000000},
+    {0x2CAC  ,  0x00000000},
+    {0x2CB0  ,  0x00000000},
+    {0x2CB4  ,  0x00000000},
+    {0x2CB8  ,  0x00000000},
+    {0x2CBC  ,  0x00000000},
+    {0x2CC0  ,  0x00000000},
+    {0x2CC4  ,  0x00000000},
+    {0x2CC8  ,  0x00000000},
+    {0x2CCC  ,  0x00000000},
+    {0x2CD0  ,  0x00000000},
+    {0x2CD4  ,  0x00000000},
+    {0x2CD8  ,  0x00000000},
+    {0x2CDC  ,  0x00000000},
+    {0x2CE0  ,  0x00000000},
+    {0x2CE4  ,  0x00000000},
+    {0x2CE8  ,  0x00000000},
+    {0x2CEC  ,  0x00000000},
+    {0x2CF0  ,  0x00000000},
+    {0x2CF4  ,  0x00000000},
+    {0x2CF8  ,  0x00000000},
+    {0x2CFC  ,  0x00000000},
+    {0x2D00  ,  0x00000000},
+    {0x2D04  ,  0x00000000},
+    {0x2D08  ,  0x00000000},
+    {0x2D0C  ,  0x00000000},
+    {0x2D10  ,  0x00000000},
+    {0x2D14  ,  0x00000000},
+    {0x2D18  ,  0x00000000},
+    {0x2D1C  ,  0x00000000},
+    {0x2D20  ,  0x00000000},
+    {0x2D24  ,  0x00000000},
+    {0x2D28  ,  0x00000000},
+    {0x2D2C  ,  0x00000000},
+    {0x2D30  ,  0x00000000},
+    {0x2D34  ,  0x00000000},
+    {0x2D38   , 0x00000000},
+    {0x2D3C   , 0x00000000},
+    {0x2D40   , 0x00000000},
+    {0x2D44   , 0x00000000},
+    {0x2D48   , 0x00000000},
+    {0x2D4C   , 0x00000000},
+    {0x2D50   , 0x00000000},
+    {0x2D54  ,  0x00000000},
+    {0x2D58  ,  0x00000000},
+    {0x2D5C  ,  0x00000000},
+    {0x2D60  ,  0x00000000},
+    {0x2D64  ,  0x00000000},
+    {0x2D68  ,  0x00000000},
+    {0x2D6C  ,  0x00000000},
+    {0x2D70   , 0x00000000},
+    {0x2D74   , 0x00000000},
+    {0x2D78   , 0x00000000},
+    {0x2D7C   , 0x00000000},
+    {0x2D80   , 0x00000000},
+    {0x2D84   , 0x00000000},
+    {0x2D88   , 0x00000000},
+    {0x2D8C   , 0x00000000},
+    {0x2D90   , 0x00000000},
+    {0x2D94   , 0x00000000},
+    {0x2D98   , 0x00000000},
+    {0x2D9C   , 0x00000000},
+    {0x2DA0   , 0x00000000},
+    {0x2DA4   , 0x00000000},
+    {0x2DA8   , 0x00000000},
+    {0x2DAC   , 0x00000000},
+    {0x2DB0   , 0x00000000},
+    {0x2DB4   , 0x00000000},
+    {0x2DB8   , 0x00000000},
+    {0x2DBC   , 0x00000000},
+    {0x2DC0   , 0x00000000},
+    {0x2DC4   , 0x00000000},
+    {0x2DC8   , 0x00000000},
+    {0x2DCC   , 0x00000000},
+    {0x2DD0   , 0x00000000},
+    {0x2DD4   , 0x00100010},
+    {0x2DD8   , 0x00100010},
+    {0x2DDC   , 0x00000000},
+    {0x2DE0   , 0x00000000},
+    {0x2DE4   , 0x00000000},
+    {0x2DE8   , 0x00000000},
+    {0x2DEC   , 0x00000000},
+    {0x2DF0   , 0x00000000},
+    {0x2DF4   , 0x00000000},
+    {0x2DF8   , 0x00000000},
+    {0x2DFC   , 0x00000000},
+    {0x2E00   , 0x00000000},
+    {0x2E04   , 0x00000000},
+    {0x2E08   , 0x00000000},
+    {0x2E0C   , 0x00000000},
+    {0x2E10   , 0x00000000},
+    {0x2E14   , 0x00000000},
+    {0x2E18   , 0x00000000},
+    {0x2E1C   , 0x00000000},
+    {0x2E20   , 0x00000000},
+    {0x2E24   , 0x00000000},
+    {0x2E28   , 0x00000000},
+    {0x2E2C   , 0x00000000},
+    {0x2E30   , 0x00000000},
+    {0x2E34   , 0x00000000},
+    {0x2E38   , 0x00000000},
+    {0x2E3C   , 0x00000000},
+    {0x2E40   , 0x00000000},
+    {0x2E44   , 0x00000000},
+    {0x2E48   , 0x00000000},
+    {0x2E4C   , 0x00000000},
+    {0x2E50   , 0x00000000},
+    {0x2E54   , 0x00000000},
+    {0x2E58   , 0x00000000},
+    {0x2E5C   , 0x00000000},
+    {0x2E60   , 0x00000000},
+    {0x2E64   , 0x00000000},
+    {0x2E68   , 0x00000000},
+    {0x2E6C   , 0x00000000},
+    {0x2E70   , 0x00000000},
+    {0x2E74   , 0x00000000},
+    {0x2E78   , 0x00000000},
+    {0x2E7C   , 0x00000000},
+    {0x2E80   , 0x00000000},
+    {0x2E84   , 0x00000000},
+    {0x2E88   , 0x00000000},
+    {0x2E8C   , 0x00000000},
+    {0x2E90   , 0x00000000},
+    {0x2E94   , 0x00000000},
+    {0x2E98   , 0x00000000},
+    {0x2E9C   , 0x00000000},
+    {0x2EA0   , 0x00000000},
+    {0x2EA4   , 0x00000000},
+    {0x2EA8   , 0x00000000},
+    {0x2EAC   , 0x00000000},
+    {0x2EB0   , 0x00000000},
+    {0x2EB4   , 0x00000000},
+    {0x2EB8   , 0x00000000},
+    {0x2EBC   , 0x00000000},
+    {0x2EC0   , 0x00000000},
+    {0x2EC4   , 0x00000000},
+    {0x2EC8   , 0x00000000},
+    {0x2ECC   , 0x00000000},
+    {0x2ED0   , 0x00000000},
+    {0x2ED4   , 0x00000000},
+    {0x2ED8   , 0x00000000},
+    {0x2EDC   , 0x00000000},
+    {0x2EE0   , 0x00000000},
+    {0x2EE4    ,0x00000000},
+    {0x2EE8    ,0x00000000},
+    {0x2EEC   , 0x00000000},
+    {0x2EF0   , 0x00000000},
+    {0x2EF4   , 0x00000000},
+    {0x2EF8   , 0x00000000},
+    {0x2EFC   , 0x00000000},
+    /*{0x2F60   , 0x00000000},*/
+};
+
+int initRegDataNum=sizeof(initRegData)/sizeof(RegData);
+
+typedef union {
+    unsigned int i;
+    float        f;
+} dmaBufRec, *dmaBuf;
+
+void Init3D( tridentContextPtr tmesa )
+{
+   unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+    int i;
+
+    for(i=0;i<initRegDataNum;++i)
+       MMIO_OUT32(MMIO, initRegData[i].addr, initRegData[i].data);
+}
+
+int DrawTriangle( tridentContextPtr tmesa)
+{
+   volatile unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+   dmaBufRec clr;
+
+printf("DRAW TRI\n");
+       Init3D(tmesa);
+
+printf("ENGINE STATUS 0x%x\n",MMIO_IN32(MMIO, 0x2800));
+    MMIO_OUT32(MMIO,  0x002800, 0x00000000 );
+#if 0
+    MMIO_OUT32(MMIO,  0x002368 , MMIO_IN32(MMIO,0x002368)|1 );
+#endif
+
+    MMIO_OUT32(MMIO, 0x002C00 , 0x00000014 );
+#if 0
+    MMIO_OUT32(MMIO, 0x002C04 , 0x0A8004C0 );
+#else
+    MMIO_OUT32(MMIO, 0x002C04 , 0x0A8000C0 );
+#endif
+
+#if 0
+    MMIO_OUT32(MMIO, 0x002C08 , 0x00000000 );
+    MMIO_OUT32(MMIO, 0x002C0C , 0xFFCCCCCC );
+    MMIO_OUT32(MMIO, 0x002C10 , 0x3F800000 );
+    MMIO_OUT32(MMIO, 0x002C14 , 0x3D0D3DCB );
+    MMIO_OUT32(MMIO, 0x002C2C , 0x70000000 );
+    MMIO_OUT32(MMIO, 0x002C24 , 0x00202C00 );
+    MMIO_OUT32(MMIO, 0x002C28 , 0xE0002500 );
+    MMIO_OUT32(MMIO, 0x002C30 , 0x00000000 );
+    MMIO_OUT32(MMIO, 0x002C34 , 0xE0000000 );
+    MMIO_OUT32(MMIO, 0x002C38 , 0x00000000 );
+#endif
+
+    MMIO_OUT32(MMIO, 0x002C50 , 0x00000000 );
+    MMIO_OUT32(MMIO, 0x002C54 , 0x0C320C80 );    
+    MMIO_OUT32(MMIO, 0x002C50 , 0x00000000 );
+    MMIO_OUT32(MMIO, 0x002C54 , 0x0C320C80 );    
+    MMIO_OUT32(MMIO, 0x002C80 , 0x20008258 );    
+    MMIO_OUT32(MMIO, 0x002C84 , 0x20000320 );    
+    MMIO_OUT32(MMIO, 0x002C94 , 0xFFFFFFFF );
+
+#if 0
+    MMIO_OUT32(MMIO, 0x002D00 , 0x00009009 );    
+    MMIO_OUT32(MMIO, 0x002D38 , 0x00000000 );
+    MMIO_OUT32(MMIO, 0x002D94 , 0x20002000 );
+    MMIO_OUT32(MMIO, 0x002D50 , 0xf0000000 );
+    MMIO_OUT32(MMIO, 0x002D80 , 0x24002000 );        
+    MMIO_OUT32(MMIO, 0x002D98 , 0x81000000 );        
+    MMIO_OUT32(MMIO, 0x002DB0 , 0x81000000 );        
+    MMIO_OUT32(MMIO, 0x002DC8 , 0x808000FF );
+    MMIO_OUT32(MMIO, 0x002DD4 , 0x02000200 );
+    MMIO_OUT32(MMIO, 0x002DD8 , 0x02000200 );
+    MMIO_OUT32(MMIO, 0x002D30 , 0x02092400 );    
+    MMIO_OUT32(MMIO, 0x002D04 , 0x00102120 );    
+    MMIO_OUT32(MMIO, 0x002D08 , 0xFFFFFFFF );
+    MMIO_OUT32(MMIO, 0x002D0C , 0xF00010D0 );    
+    MMIO_OUT32(MMIO, 0x002D10 , 0xC0000400 );
+#endif
+
+    MMIO_OUT32(MMIO, 0x002814,  0x00000000 );
+#if 0
+    MMIO_OUT32(MMIO, 0x002818 , 0x00036C20 );        
+#else
+    MMIO_OUT32(MMIO, 0x002818 , 0x00036020 );        
+#endif
+    MMIO_OUT32(MMIO, 0x00281C , 0x00098081 );  
+
+printf("first TRI\n");
+    clr.f = 5.0;
+    MMIO_OUT32(MMIO, 0x002820 , clr.i );               
+    clr.f = 595.0;
+    MMIO_OUT32(MMIO, 0x002824 , clr.i );               
+    clr.f = 1.0;
+    MMIO_OUT32(MMIO, 0x002828 , clr.i );
+    MMIO_OUT32(MMIO, 0x00282C , 0x00FF00 );        
+#if 0
+    clr.f = 0.0;
+    MMIO_OUT32(MMIO, 0x002830 , clr.i );
+    clr.f = 1.0;
+    MMIO_OUT32(MMIO, 0x002834 , clr.i );
+#endif
+
+    clr.f = 5.0;
+    MMIO_OUT32(MMIO, 0x002820 , clr.i );               
+    clr.f = 5.0;
+    MMIO_OUT32(MMIO, 0x002824 , clr.i );               
+    clr.f = 1.0;
+    MMIO_OUT32(MMIO, 0x002828 , clr.i );
+    MMIO_OUT32(MMIO, 0x00282C , 0xFF0000 );        
+#if 0
+    clr.f = 0.0;
+    MMIO_OUT32(MMIO, 0x002830 , clr.i );
+    clr.f = 0.0;
+    MMIO_OUT32(MMIO, 0x002834 , clr.i );
+#endif
+
+    clr.f = 395.0;
+printf("0x%x\n",clr.i);
+    MMIO_OUT32(MMIO, 0x002820 , clr.i );               
+    clr.f = 5.0;
+    MMIO_OUT32(MMIO, 0x002824 , clr.i );               
+    clr.f = 1.0;
+    MMIO_OUT32(MMIO, 0x002828 , clr.i );
+    MMIO_OUT32(MMIO, 0x00282C , 0xFF );        
+#if 0
+    clr.f = 1.0;
+    MMIO_OUT32(MMIO, 0x002830 , clr.i );
+    clr.f = 0.0;
+    MMIO_OUT32(MMIO, 0x002834 , clr.i );
+#endif
+
+printf("sec TRI\n");
+    MMIO_OUT32(MMIO, 0x00281C , 0x00093980 );    
+    clr.f = 395.0;
+    MMIO_OUT32(MMIO, 0x002820 , clr.i );               
+    clr.f = 595.0;
+    MMIO_OUT32(MMIO, 0x002824 , clr.i );               
+    clr.f = 1.0;
+    MMIO_OUT32(MMIO, 0x002828 , clr.i );               
+    MMIO_OUT32(MMIO, 0x00282C , 0x00FF00 );        
+#if 0
+    clr.f = 1.0;
+    MMIO_OUT32(MMIO, 0x002830 , clr.i );
+    clr.f = 1.0;
+    MMIO_OUT32(MMIO, 0x002834 , clr.i );
+#endif
+
+#if 0
+    MMIO_OUT32(MMIO,  0x002368 , MMIO_IN32(MMIO,0x002368)&0xfffffffe );
+#endif
+
+printf("fin TRI\n");
+
+    return 0;  
+}
+
+static INLINE void trident_draw_point(tridentContextPtr tmesa, 
+                            const tridentVertex *v0 )
+{
+   unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+}
+
+static INLINE void trident_draw_line( tridentContextPtr tmesa, 
+                            const tridentVertex *v0,
+                            const tridentVertex *v1 )
+{
+   unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+}
+
+static INLINE void trident_draw_triangle( tridentContextPtr tmesa,
+                                const tridentVertex *v0,
+                                const tridentVertex *v1, 
+                                const tridentVertex *v2 )
+{
+}
+
+static INLINE void trident_draw_quad( tridentContextPtr tmesa,
+                           const tridentVertex *v0,
+                           const tridentVertex *v1,
+                           const tridentVertex *v2,
+                           const tridentVertex *v3 )
+{
+   GLuint vertsize = tmesa->vertex_size;
+   GLint coloridx = (vertsize > 4) ? 4 : 3;
+   unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+   int clr;
+   float *ftmp = (float *)(&clr);
+
+   if (tmesa->dirty)
+       tridentUploadHwStateLocked( tmesa );
+#if 0
+       DrawTriangle(tmesa);
+       exit(0);
+#else
+#if 1
+       if (first) {
+       Init3D(tmesa);
+#if 0
+       DrawTriangle(tmesa);
+#endif
+       first = 0;
+       }
+#endif
+    
+    LOCK_HARDWARE( tmesa );
+
+    MMIO_OUT32(MMIO, 0x002C00 , 0x00000010 );
+    MMIO_OUT32(MMIO, 0x002C04 , 0x029C00C0 );
+
+    /* Z buffer */
+    MMIO_OUT32(MMIO, 0x002C24 , 0x00100000 /*| (tmesa->tridentScreen->depthOffset)*/ );
+    MMIO_OUT32(MMIO, 0x002C28 , 0xE0000000 | (tmesa->tridentScreen->depthPitch * 4) );
+
+    /* front buffer */
+    MMIO_OUT32(MMIO, 0x002C50 , 0x00000000 | (tmesa->drawOffset) );
+    MMIO_OUT32(MMIO, 0x002C54 , 0x0C320000 | (tmesa->drawPitch * 4) );    
+
+    /* clipper */
+    MMIO_OUT32(MMIO, 0x002C80 , 0x20008000 | tmesa->tridentScreen->height );    
+    MMIO_OUT32(MMIO, 0x002C84 , 0x20000000 | tmesa->tridentScreen->width );    
+
+    /* writemask */
+    MMIO_OUT32(MMIO, 0x002C94 , 0xFFFFFFFF );
+
+if (vertsize == 4) {
+    MMIO_OUT32(MMIO, 0x002818 , 0x0003A020 );        
+    MMIO_OUT32(MMIO, 0x00281C , 0x00098021 );  
+
+    *ftmp = v0->v.x;
+    MMIO_OUT32(MMIO, 0x002820 , clr );               
+    *ftmp = v0->v.y;
+    MMIO_OUT32(MMIO, 0x002824 , clr );               
+    *ftmp = v0->v.z;
+    MMIO_OUT32(MMIO, 0x002828 , clr );
+#if 0
+    *ftmp = v0->v.w;
+    MMIO_OUT32(MMIO, 0x00282C , clr );
+#endif
+    MMIO_OUT32(MMIO, 0x00282C , v0->ui[coloridx] );        
+
+    *ftmp = v1->v.x;
+    MMIO_OUT32(MMIO, 0x002820 , clr );               
+    *ftmp = v1->v.y;
+    MMIO_OUT32(MMIO, 0x002824 , clr );               
+    *ftmp = v1->v.z;
+    MMIO_OUT32(MMIO, 0x002828 , clr );
+#if 0
+    *ftmp = v1->v.w;
+    MMIO_OUT32(MMIO, 0x00282C , clr );
+#endif
+    MMIO_OUT32(MMIO, 0x00282C , v1->ui[coloridx] );        
+
+    *ftmp = v2->v.x;
+    MMIO_OUT32(MMIO, 0x002820 , clr );               
+    *ftmp = v2->v.y;
+    MMIO_OUT32(MMIO, 0x002824 , clr );               
+    *ftmp = v2->v.z;
+    MMIO_OUT32(MMIO, 0x002828 , clr );
+#if 0
+    *ftmp = v2->v.w;
+    MMIO_OUT32(MMIO, 0x00282C , clr );
+#endif
+    MMIO_OUT32(MMIO, 0x00282C , v2->ui[coloridx] );        
+
+    MMIO_OUT32(MMIO, 0x00281C , 0x00093020 );    
+    *ftmp = v3->v.x;
+    MMIO_OUT32(MMIO, 0x002820 , clr );               
+    *ftmp = v3->v.y;
+    MMIO_OUT32(MMIO, 0x002824 , clr );               
+    *ftmp = v3->v.z;
+    MMIO_OUT32(MMIO, 0x002828 , clr );
+#if 0
+    *ftmp = v3->v.w;
+    MMIO_OUT32(MMIO, 0x00282C , clr );
+#endif
+    MMIO_OUT32(MMIO, 0x00282C , v3->ui[coloridx] );        
+
+}
+#endif
+
+    UNLOCK_HARDWARE( tmesa );
+}
+/***********************************************************************
+ *                    Rasterization fallback helpers                   *
+ ***********************************************************************/
+
+
+/* This code is hit only when a mix of accelerated and unaccelerated
+ * primitives are being drawn, and only for the unaccelerated
+ * primitives.  
+ */
+static void 
+trident_fallback_quad( tridentContextPtr tmesa, 
+                   const tridentVertex *v0, 
+                   const tridentVertex *v1, 
+                   const tridentVertex *v2, 
+                   const tridentVertex *v3 )
+{
+   GLcontext *ctx = tmesa->glCtx;
+   SWvertex v[4];
+   trident_translate_vertex( ctx, v0, &v[0] );
+   trident_translate_vertex( ctx, v1, &v[1] );
+   trident_translate_vertex( ctx, v2, &v[2] );
+   trident_translate_vertex( ctx, v3, &v[3] );
+   _swrast_Quad( ctx, &v[0], &v[1], &v[2], &v[3] );
+}
+
+static void 
+trident_fallback_tri( tridentContextPtr tmesa, 
+                   const tridentVertex *v0, 
+                   const tridentVertex *v1, 
+                   const tridentVertex *v2 )
+{
+   GLcontext *ctx = tmesa->glCtx;
+   SWvertex v[3];
+   trident_translate_vertex( ctx, v0, &v[0] );
+   trident_translate_vertex( ctx, v1, &v[1] );
+   trident_translate_vertex( ctx, v2, &v[2] );
+   _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
+}
+
+static void 
+trident_fallback_line( tridentContextPtr tmesa,
+                    const tridentVertex *v0,
+                    const tridentVertex *v1 )
+{
+   GLcontext *ctx = tmesa->glCtx;
+   SWvertex v[2];
+   trident_translate_vertex( ctx, v0, &v[0] );
+   trident_translate_vertex( ctx, v1, &v[1] );
+   _swrast_Line( ctx, &v[0], &v[1] );
+}
+
+
+static void 
+trident_fallback_point( tridentContextPtr tmesa, 
+                     const tridentVertex *v0 )
+{
+   GLcontext *ctx = tmesa->glCtx;
+   SWvertex v[1];
+   trident_translate_vertex( ctx, v0, &v[0] );
+   _swrast_Point( ctx, &v[0] );
+}
+
+/***********************************************************************
+ *          Macros for t_dd_tritmp.h to draw basic primitives          *
+ ***********************************************************************/
+
+#define TRI( a, b, c )                         \
+do {                                           \
+   if (DO_FALLBACK)                            \
+      tmesa->draw_tri( tmesa, a, b, c );       \
+   else                                                \
+      trident_draw_triangle( tmesa, a, b, c ); \
+} while (0)
+
+#define QUAD( a, b, c, d )                     \
+do {                                           \
+   if (DO_FALLBACK) {                          \
+      tmesa->draw_tri( tmesa, a, b, d );       \
+      tmesa->draw_tri( tmesa, b, c, d );       \
+   } else                                      \
+      trident_draw_quad( tmesa, a, b, c, d );  \
+} while (0)
+
+#define LINE( v0, v1 )                         \
+do {                                           \
+   if (DO_FALLBACK)                            \
+      tmesa->draw_line( tmesa, v0, v1 );       \
+   else                                        \
+      trident_draw_line( tmesa, v0, v1 );      \
+} while (0)
+
+#define POINT( v0 )                            \
+do {                                           \
+   if (DO_FALLBACK)                            \
+      tmesa->draw_point( tmesa, v0 );          \
+   else                                        \
+      trident_draw_point( tmesa, v0 );         \
+} while (0)
+
+/***********************************************************************
+ *              Build render functions from dd templates               *
+ ***********************************************************************/
+
+#define TRIDENT_OFFSET_BIT     0x01
+#define TRIDENT_TWOSIDE_BIT    0x02
+#define TRIDENT_UNFILLED_BIT   0x04
+#define TRIDENT_FALLBACK_BIT   0x08
+#define TRIDENT_MAX_TRIFUNC    0x10
+
+
+static struct {
+   points_func         points;
+   line_func           line;
+   triangle_func       triangle;
+   quad_func           quad;
+} rast_tab[TRIDENT_MAX_TRIFUNC];
+
+
+#define DO_FALLBACK (IND & TRIDENT_FALLBACK_BIT)
+#define DO_OFFSET   (IND & TRIDENT_OFFSET_BIT)
+#define DO_UNFILLED (IND & TRIDENT_UNFILLED_BIT)
+#define DO_TWOSIDE  (IND & TRIDENT_TWOSIDE_BIT)
+#define DO_FLAT      0
+#define DO_TRI       1
+#define DO_QUAD      1
+#define DO_LINE      1
+#define DO_POINTS    1
+#define DO_FULL_QUAD 1
+
+#define HAVE_RGBA         1
+#define HAVE_SPEC         1
+#define HAVE_BACK_COLORS  0
+#define HAVE_HW_FLATSHADE 1
+#define VERTEX            tridentVertex
+#define TAB               rast_tab
+
+#define DEPTH_SCALE 1.0
+#define UNFILLED_TRI unfilled_tri
+#define UNFILLED_QUAD unfilled_quad
+#define VERT_X(_v) _v->v.x
+#define VERT_Y(_v) _v->v.y
+#define VERT_Z(_v) _v->v.z
+#define AREA_IS_CCW( a ) (a > 0)
+#define GET_VERTEX(e) (tmesa->verts + (e<<tmesa->vertex_stride_shift))
+
+#define TRIDENT_COLOR( dst, src )                \
+do {                                           \
+   dst[0] = src[2];                            \
+   dst[1] = src[1];                            \
+   dst[2] = src[0];                            \
+   dst[3] = src[3];                            \
+} while (0)
+
+#define TRIDENT_SPEC( dst, src )                       \
+do {                                           \
+   dst[0] = src[2];                            \
+   dst[1] = src[1];                            \
+   dst[2] = src[0];                            \
+} while (0)
+
+#define VERT_SET_RGBA( v, c )    TRIDENT_COLOR( v->ub4[coloroffset], c )
+#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
+#define VERT_SAVE_RGBA( idx )    color[idx] = v[idx]->ui[coloroffset]
+#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
+
+#define VERT_SET_SPEC( v, c )    if (havespec) TRIDENT_SPEC( v->ub4[5], c )
+#define VERT_COPY_SPEC( v0, v1 ) if (havespec) COPY_3V(v0->ub4[5], v1->ub4[5])
+#define VERT_SAVE_SPEC( idx )    if (havespec) spec[idx] = v[idx]->ui[5]
+#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
+
+#define LOCAL_VARS(n)                                          \
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);             \
+   GLuint color[n], spec[n];                                   \
+   GLuint coloroffset = (tmesa->vertex_size == 4 ? 3 : 4);     \
+   GLboolean havespec = (tmesa->vertex_size == 4 ? 0 : 1);     \
+   (void) color; (void) spec; (void) coloroffset; (void) havespec;
+/***********************************************************************
+ *                Helpers for rendering unfilled primitives            *
+ ***********************************************************************/
+#if 0
+static const GLuint hw_prim[GL_POLYGON+1] = {
+   B_PrimType_Points,
+   B_PrimType_Lines,
+   B_PrimType_Lines,
+   B_PrimType_Lines,
+   B_PrimType_Triangles,
+   B_PrimType_Triangles,
+   B_PrimType_Triangles,
+   B_PrimType_Triangles,
+   B_PrimType_Triangles,
+   B_PrimType_Triangles
+};
+#endif
+
+static void tridentResetLineStipple( GLcontext *ctx );
+static void tridentRasterPrimitive( GLcontext *ctx, GLuint hwprim );
+static void tridentRenderPrimitive( GLcontext *ctx, GLenum prim );
+
+#define RASTERIZE(x) /*if (tmesa->hw_primitive != hw_prim[x]) \
+                        tridentRasterPrimitive( ctx, hw_prim[x] ) */
+#define RENDER_PRIMITIVE tmesa->render_primitive
+#define TAG(x) x
+#define IND TRIDENT_FALLBACK_BIT
+#include "tnl_dd/t_dd_unfilled.h"
+#undef IND
+
+/***********************************************************************
+ *                      Generate GL render functions                   *
+ ***********************************************************************/
+
+#define IND (0)
+#define TAG(x) x
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_UNFILLED_BIT)
+#define TAG(x) x##_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_OFFSET_BIT|TRIDENT_UNFILLED_BIT)
+#define TAG(x) x##_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_UNFILLED_BIT)
+#define TAG(x) x##_twoside_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_OFFSET_BIT|TRIDENT_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_OFFSET_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_twoside_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_OFFSET_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_UNFILLED_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_OFFSET_BIT|TRIDENT_UNFILLED_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_UNFILLED_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_twoside_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_OFFSET_BIT|TRIDENT_UNFILLED_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+static void init_rast_tab( void )
+{
+   init();
+   init_offset();
+   init_twoside();
+   init_twoside_offset();
+   init_unfilled();
+   init_offset_unfilled();
+   init_twoside_unfilled();
+   init_twoside_offset_unfilled();
+   init_fallback();
+   init_offset_fallback();
+   init_twoside_fallback();
+   init_twoside_offset_fallback();
+   init_unfilled_fallback();
+   init_offset_unfilled_fallback();
+   init_twoside_unfilled_fallback();
+   init_twoside_offset_unfilled_fallback();
+}
+
+
+/**********************************************************************/
+/*               Render unclipped begin/end objects                   */
+/**********************************************************************/
+
+#define VERT(x) (tridentVertex *)(tridentverts + (x << shift))
+#define RENDER_POINTS( start, count )          \
+   for ( ; start < count ; start++)            \
+      trident_draw_point( tmesa, VERT(start) )
+#define RENDER_LINE( v0, v1 ) \
+   trident_draw_line( tmesa, VERT(v0), VERT(v1) )
+#define RENDER_TRI( v0, v1, v2 )  \
+   trident_draw_triangle( tmesa, VERT(v0), VERT(v1), VERT(v2) )
+#define RENDER_QUAD( v0, v1, v2, v3 ) \
+   trident_draw_quad( tmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
+#define INIT(x) tridentRenderPrimitive( ctx, x );
+#undef LOCAL_VARS
+#define LOCAL_VARS                                             \
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);             \
+   const GLuint shift = tmesa->vertex_stride_shift;            \
+   const char *tridentverts = (char *)tmesa->verts;            \
+   const GLboolean stipple = ctx->Line.StippleFlag;            \
+   const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;       \
+   (void) elt;
+#define RESET_STIPPLE  if ( stipple ) tridentResetLineStipple( ctx );
+#define RESET_OCCLUSION
+#define PRESERVE_VB_DEFS
+#define ELT(x) (x)
+#define TAG(x) trident_##x##_verts
+#include "tnl/t_vb_rendertmp.h"
+#undef ELT
+#undef TAG
+#define TAG(x) trident_##x##_elts
+#define ELT(x) elt[x]
+#include "tnl/t_vb_rendertmp.h"
+
+/**********************************************************************/
+/*                   Render clipped primitives                        */
+/**********************************************************************/
+
+static void tridentRenderClippedPoly( GLcontext *ctx, const GLuint *elts, 
+                                  GLuint n )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   GLuint prim = tmesa->render_primitive;
+
+   /* Render the new vertices as an unclipped polygon. 
+    */
+   {
+      GLuint *tmp = VB->Elts;
+      VB->Elts = (GLuint *)elts;
+      tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END );
+      VB->Elts = tmp;
+   }
+
+   /* Restore the render primitive
+    */
+   if (prim != GL_POLYGON)
+      tnl->Driver.Render.PrimitiveNotify( ctx, prim );
+}
+
+static void tridentRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   tnl->Driver.Render.Line( ctx, ii, jj );
+}
+
+
+/**********************************************************************/
+/*                    Choose render functions                         */
+/**********************************************************************/
+
+#define _TRIDENT_NEW_RENDER_STATE (_DD_NEW_LINE_STIPPLE |      \
+                                 _DD_NEW_LINE_SMOOTH |         \
+                                 _DD_NEW_POINT_SMOOTH |        \
+                                 _DD_NEW_TRI_SMOOTH |          \
+                                 _DD_NEW_TRI_UNFILLED |        \
+                                 _DD_NEW_TRI_LIGHT_TWOSIDE |   \
+                                 _DD_NEW_TRI_OFFSET)           \
+
+
+#define POINT_FALLBACK (DD_POINT_SMOOTH)
+#define LINE_FALLBACK (DD_LINE_STIPPLE|DD_LINE_SMOOTH)
+#define TRI_FALLBACK (DD_TRI_SMOOTH)
+#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
+#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
+
+
+static void tridentChooseRenderState(GLcontext *ctx)
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   GLuint flags = ctx->_TriangleCaps;
+   GLuint index = 0;
+
+   if (flags & (ANY_RASTER_FLAGS|ANY_FALLBACK_FLAGS)) {
+      tmesa->draw_point = trident_draw_point;
+      tmesa->draw_line = trident_draw_line;
+      tmesa->draw_tri = trident_draw_triangle;
+
+      if (flags & ANY_RASTER_FLAGS) {
+        if (flags & DD_TRI_LIGHT_TWOSIDE) index |= TRIDENT_TWOSIDE_BIT;
+        if (flags & DD_TRI_OFFSET)        index |= TRIDENT_OFFSET_BIT;
+        if (flags & DD_TRI_UNFILLED)      index |= TRIDENT_UNFILLED_BIT;
+      }
+
+      /* Hook in fallbacks for specific primitives.
+       */
+      if (flags & (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)) {
+        if (flags & POINT_FALLBACK) tmesa->draw_point = trident_fallback_point;
+        if (flags & LINE_FALLBACK)  tmesa->draw_line = trident_fallback_line;
+        if (flags & TRI_FALLBACK)   tmesa->draw_tri = trident_fallback_tri;
+        index |= TRIDENT_FALLBACK_BIT;
+      }
+   }
+
+   if (tmesa->RenderIndex != index) {
+      tmesa->RenderIndex = index;
+
+      tnl->Driver.Render.Points = rast_tab[index].points;
+      tnl->Driver.Render.Line = rast_tab[index].line;
+      tnl->Driver.Render.Triangle = rast_tab[index].triangle;
+      tnl->Driver.Render.Quad = rast_tab[index].quad;
+         
+      if (tmesa->RenderIndex == 0) {
+         tnl->Driver.Render.PrimTabVerts = trident_render_tab_verts;
+         tnl->Driver.Render.PrimTabElts = trident_render_tab_elts;
+      } else {
+         tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+         tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+      }
+      tnl->Driver.Render.ClippedLine = tridentRenderClippedLine;
+      tnl->Driver.Render.ClippedPolygon = tridentRenderClippedPoly;
+   }
+}
+
+
+/**********************************************************************/
+/*                 High level hooks for t_vb_render.c                 */
+/**********************************************************************/
+
+
+
+/* Determine the rasterized primitive when not drawing unfilled 
+ * polygons.
+ *
+ * Used only for the default render stage which always decomposes
+ * primitives to trianges/lines/points.  For the accelerated stage,
+ * which renders strips as strips, the equivalent calculations are
+ * performed in tridentrender.c.
+ */
+
+static void tridentRasterPrimitive( GLcontext *ctx, GLuint hwprim )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+   if (tmesa->hw_primitive != hwprim)
+      tmesa->hw_primitive = hwprim;
+}
+
+static void tridentRenderPrimitive( GLcontext *ctx, GLenum prim )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+   tmesa->render_primitive = prim;
+}
+
+static void tridentRunPipeline( GLcontext *ctx )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+
+   if ( tmesa->new_state )
+      tridentDDUpdateHWState( ctx );
+
+   if (tmesa->new_gl_state) {
+#if 0
+      if (tmesa->new_gl_state & _NEW_TEXTURE)
+        tridentUpdateTextureState( ctx );
+#endif
+
+   if (!tmesa->Fallback) {
+      if (tmesa->new_gl_state & _TRIDENT_NEW_VERTEX)
+        tridentChooseVertexState( ctx );
+      
+      if (tmesa->new_gl_state & _TRIDENT_NEW_RENDER_STATE)
+        tridentChooseRenderState( ctx );
+   }
+      
+      tmesa->new_gl_state = 0;
+   }
+
+   _tnl_run_pipeline( ctx );
+}
+
+static void tridentRenderStart( GLcontext *ctx )
+{
+   /* Check for projective texturing.  Make sure all texcoord
+    * pointers point to something.  (fix in mesa?)  
+    */
+   tridentCheckTexSizes( ctx );
+}
+
+static void tridentRenderFinish( GLcontext *ctx )
+{
+   if (0)
+      _swrast_flush( ctx );    /* never needed */
+}
+
+static void tridentResetLineStipple( GLcontext *ctx )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+
+   /* Reset the hardware stipple counter.
+    */
+}
+
+
+/**********************************************************************/
+/*           Transition to/from hardware rasterization.               */
+/**********************************************************************/
+
+
+void tridentFallback( tridentContextPtr tmesa, GLuint bit, GLboolean mode )
+{
+   GLcontext *ctx = tmesa->glCtx;
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   GLuint oldfallback = tmesa->Fallback;
+
+      _tnl_need_projected_coords( ctx, GL_FALSE );
+
+   if (mode) {
+      tmesa->Fallback |= bit;
+      if (oldfallback == 0) {
+        _swsetup_Wakeup( ctx );
+        tmesa->RenderIndex = ~0;
+      }
+   }
+   else {
+      tmesa->Fallback &= ~bit;
+      if (oldfallback == bit) {
+        _swrast_flush( ctx );
+        tnl->Driver.Render.Start = tridentRenderStart;
+        tnl->Driver.Render.PrimitiveNotify = tridentRenderPrimitive;
+        tnl->Driver.Render.Finish = tridentRenderFinish;
+        tnl->Driver.Render.BuildVertices = tridentBuildVertices;
+         tnl->Driver.Render.ResetLineStipple = tridentResetLineStipple;
+        tmesa->new_gl_state |= (_TRIDENT_NEW_RENDER_STATE|
+                                _TRIDENT_NEW_VERTEX);
+      }
+   }
+}
+
+
+/**********************************************************************/
+/*                            Initialization.                         */
+/**********************************************************************/
+
+
+void tridentDDInitTriFuncs( GLcontext *ctx )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   static int firsttime = 1;
+
+   if (firsttime) {
+      init_rast_tab();
+      firsttime = 0;
+   }
+   
+   tmesa->RenderIndex = ~0;
+
+   tnl->Driver.RunPipeline = tridentRunPipeline;
+   tnl->Driver.Render.Start = tridentRenderStart;
+   tnl->Driver.Render.Finish = tridentRenderFinish; 
+   tnl->Driver.Render.PrimitiveNotify = tridentRenderPrimitive;
+   tnl->Driver.Render.ResetLineStipple = tridentResetLineStipple;
+   tnl->Driver.Render.BuildVertices = tridentBuildVertices;
+}
diff --git a/src/mesa/drivers/dri/trident/trident_vb.c b/src/mesa/drivers/dri/trident/trident_vb.c
new file mode 100644 (file)
index 0000000..4c6e088
--- /dev/null
@@ -0,0 +1,435 @@
+/*
+ * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Trident CyberBladeXP driver.
+ *
+ */
+#include "glheader.h"
+#include "mtypes.h"
+#include "mem.h"
+#include "macros.h"
+#include "colormac.h"
+#include "mmath.h"
+
+#include "swrast_setup/swrast_setup.h"
+#include "swrast/swrast.h"
+#include "tnl/t_context.h"
+#include "tnl/tnl.h"
+
+#include "trident_context.h"
+
+#define TRIDENT_TEX1_BIT       0x1
+#define TRIDENT_TEX0_BIT       0x2
+#define TRIDENT_RGBA_BIT       0x4
+#define TRIDENT_SPEC_BIT       0x8
+#define TRIDENT_FOG_BIT        0x10
+#define TRIDENT_XYZW_BIT       0x20
+#define TRIDENT_PTEX_BIT       0x40
+#define TRIDENT_MAX_SETUP      0x80
+
+static struct {
+   void                (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
+   interp_func         interp;
+   copy_pv_func                copy_pv;
+   GLboolean           (*check_tex_sizes)( GLcontext *ctx );
+   GLuint               vertex_size;
+   GLuint               vertex_stride_shift;
+   GLuint               vertex_format;
+} setup_tab[TRIDENT_MAX_SETUP];
+
+#define TINY_VERTEX_FORMAT      1
+#define NOTEX_VERTEX_FORMAT     2
+#define TEX0_VERTEX_FORMAT      3
+#define TEX1_VERTEX_FORMAT      4
+#define PROJ_TEX1_VERTEX_FORMAT 5
+#define TEX2_VERTEX_FORMAT      6
+#define TEX3_VERTEX_FORMAT      7
+#define PROJ_TEX3_VERTEX_FORMAT 8
+
+#define DO_XYZW (IND & TRIDENT_XYZW_BIT)
+#define DO_RGBA (IND & TRIDENT_RGBA_BIT)
+#define DO_SPEC (IND & TRIDENT_SPEC_BIT)
+#define DO_FOG  (IND & TRIDENT_FOG_BIT)
+#define DO_TEX0 (IND & TRIDENT_TEX0_BIT)
+#define DO_TEX1 (IND & TRIDENT_TEX1_BIT)
+#define DO_TEX2 0
+#define DO_TEX3 0
+#define DO_PTEX (IND & TRIDENT_PTEX_BIT)
+
+#define VERTEX tridentVertex
+#define LOCALVARS tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+#define GET_VIEWPORT_MAT()             tmesa->hw_viewport
+#define GET_TEXSOURCE(n)               tmesa->tmu_source[n]
+#define GET_VERTEX_FORMAT()            tmesa->vertex_format
+#define GET_VERTEX_STORE()             tmesa->verts
+#define GET_VERTEX_STRIDE_SHIFT()      tmesa->vertex_stride_shift
+#define GET_UBYTE_COLOR_STORE()        &tmesa->UbyteColor
+#define GET_UBYTE_SPEC_COLOR_STORE()   &tmesa->UbyteSecondaryColor
+                              
+#define HAVE_HW_VIEWPORT    0
+#define HAVE_HW_DIVIDE      0
+#define HAVE_RGBA_COLOR     0 
+#define HAVE_TINY_VERTICES  1
+#define HAVE_NOTEX_VERTICES 1
+#define HAVE_TEX0_VERTICES  1
+#define HAVE_TEX1_VERTICES  1
+#define HAVE_TEX2_VERTICES  0
+#define HAVE_TEX3_VERTICES  0
+#define HAVE_PTEX_VERTICES  0
+
+#define UNVIEWPORT_VARS                                 \
+   const GLfloat dx = - tmesa->drawX - SUBPIXEL_X;     \
+   const GLfloat dy = (tmesa->driDrawable->h +                 \
+                      tmesa->drawY + SUBPIXEL_Y);      \
+   const GLfloat sz = 1.0 / tmesa->depth_scale
+
+#define UNVIEWPORT_X(x)    x  +  dx;
+#define UNVIEWPORT_Y(y)  - y  +  dy;
+#define UNVIEWPORT_Z(z)    z  *  sz;
+
+#define PTEX_FALLBACK()         tridentFallback(TRIDENT_CONTEXT(ctx), TRIDENT_FALLBACK_TEXTURE, 1)
+
+#define IMPORT_FLOAT_COLORS trident_import_float_colors
+#define IMPORT_FLOAT_SPEC_COLORS trident_import_float_spec_colors
+
+#define INTERP_VERTEX setup_tab[tmesa->SetupIndex].interp
+#define COPY_PV_VERTEX setup_tab[tmesa->SetupIndex].copy_pv
+
+/***********************************************************************
+ *         Generate  pv-copying and translation functions              *
+ ***********************************************************************/
+
+#define TAG(x) trident_##x
+#include "tnl_dd/t_dd_vb.c"
+
+/***********************************************************************
+ *             Generate vertex emit and interp functions               *
+ ***********************************************************************/
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT)
+#define TAG(x) x##_wg
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT)
+#define TAG(x) x##_wgs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_wgt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_wgt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT|TRIDENT_PTEX_BIT)
+#define TAG(x) x##_wgpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_wgst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_wgst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_PTEX_BIT)
+#define TAG(x) x##_wgspt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT)
+#define TAG(x) x##_wgf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT)
+#define TAG(x) x##_wgfs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_wgft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_wgft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT|TRIDENT_PTEX_BIT)
+#define TAG(x) x##_wgfpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_wgfst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_wgfst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_PTEX_BIT)
+#define TAG(x) x##_wgfspt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_TEX0_BIT)
+#define TAG(x) x##_t0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_t0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_FOG_BIT)
+#define TAG(x) x##_f
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_ft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_ft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT)
+#define TAG(x) x##_g
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT)
+#define TAG(x) x##_gs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_gt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_gt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_gst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_gst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT)
+#define TAG(x) x##_gf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT)
+#define TAG(x) x##_gfs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_gft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_gft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_gfst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_gfst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+static void init_setup_tab( void )
+{
+   init_wg();
+   init_wgs();
+   init_wgt0();
+   init_wgt0t1();
+   init_wgpt0();
+   init_wgst0();
+   init_wgst0t1();
+   init_wgspt0();
+   init_wgf();
+   init_wgfs();
+   init_wgft0();
+   init_wgft0t1();
+   init_wgfpt0();
+   init_wgfst0();
+   init_wgfst0t1();
+   init_wgfspt0();
+   init_t0();
+   init_t0t1();
+   init_f();
+   init_ft0();
+   init_ft0t1();
+   init_g();
+   init_gs();
+   init_gt0();
+   init_gt0t1();
+   init_gst0();
+   init_gst0t1();
+   init_gf();
+   init_gfs();
+   init_gft0();
+   init_gft0t1();
+   init_gfst0();
+   init_gfst0t1();
+}
+
+void tridentBuildVertices( GLcontext *ctx, 
+                        GLuint start, 
+                        GLuint count,
+                        GLuint newinputs )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT( ctx );
+   GLubyte *v = ((GLubyte *)tmesa->verts + (start<<tmesa->vertex_stride_shift));
+   GLuint stride = 1<<tmesa->vertex_stride_shift;
+
+   newinputs |= tmesa->SetupNewInputs;
+   tmesa->SetupNewInputs = 0;
+
+   if (!newinputs)
+      return;
+
+   if (newinputs & VERT_CLIP) {
+      setup_tab[tmesa->SetupIndex].emit( ctx, start, count, v, stride );   
+   } else {
+      GLuint ind = 0;
+
+      if (newinputs & VERT_RGBA)
+        ind |= TRIDENT_RGBA_BIT;
+
+      if (newinputs & VERT_SPEC_RGB)
+        ind |= TRIDENT_SPEC_BIT;
+
+      if (newinputs & VERT_TEX0)
+        ind |= TRIDENT_TEX0_BIT;
+
+      if (newinputs & VERT_TEX1)
+        ind |= TRIDENT_TEX1_BIT;
+
+      if (newinputs & VERT_FOG_COORD)
+        ind |= TRIDENT_FOG_BIT;
+
+      if (tmesa->SetupIndex & TRIDENT_PTEX_BIT)
+        ind = ~0;
+
+      ind &= tmesa->SetupIndex;
+
+      if (ind) {
+        setup_tab[ind].emit( ctx, start, count, v, stride );   
+      }
+   }
+}
+
+void tridentCheckTexSizes( GLcontext *ctx )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT( ctx );
+
+   if (!setup_tab[tmesa->SetupIndex].check_tex_sizes(ctx)) {
+      TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+      /* Invalidate stored verts
+       */
+      tmesa->SetupNewInputs = ~0;
+      tmesa->SetupIndex |= TRIDENT_PTEX_BIT;
+
+      if (!tmesa->Fallback &&
+         !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
+        tnl->Driver.Render.Interp = setup_tab[tmesa->SetupIndex].interp;
+        tnl->Driver.Render.CopyPV = setup_tab[tmesa->SetupIndex].copy_pv;
+      }
+   }
+}
+
+void tridentChooseVertexState( GLcontext *ctx )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT( ctx );
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   GLuint ind = TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT;
+
+   if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+      ind |= TRIDENT_SPEC_BIT;
+
+   if (ctx->Fog.Enabled)
+      ind |= TRIDENT_FOG_BIT;
+
+   if (ctx->Texture._ReallyEnabled) {
+      ind |= TRIDENT_TEX0_BIT;
+      if (ctx->Texture.Unit[0]._ReallyEnabled &&
+         ctx->Texture.Unit[1]._ReallyEnabled) {
+        ind |= TRIDENT_TEX1_BIT;
+      }
+   }
+
+   tmesa->SetupIndex = ind;
+
+   if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
+      tnl->Driver.Render.Interp = trident_interp_extras;
+      tnl->Driver.Render.CopyPV = trident_copy_pv_extras;
+   } else {
+      tnl->Driver.Render.Interp = setup_tab[ind].interp;
+      tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
+   }
+
+   if (setup_tab[ind].vertex_format != tmesa->vertex_format) {
+      tmesa->vertex_format = setup_tab[ind].vertex_format;
+      tmesa->vertex_size = setup_tab[ind].vertex_size;
+      tmesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift;
+   }
+}
+
+void tridentInitVB( GLcontext *ctx )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+   GLuint size = TNL_CONTEXT(ctx)->vb.Size;
+
+   tmesa->verts = (char *)ALIGN_MALLOC( size * 16 * 4, 32 );
+
+   {
+      static int firsttime = 1;
+      if (firsttime) {
+        init_setup_tab();
+        firsttime = 0;
+      }
+   }
+}
+
+void tridentFreeVB( GLcontext *ctx )
+{
+   tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+
+   if (tmesa->verts) {
+      ALIGN_FREE(tmesa->verts);
+      tmesa->verts = 0;
+   }
+
+   if (tmesa->UbyteSecondaryColor.Ptr) {
+      ALIGN_FREE(tmesa->UbyteSecondaryColor.Ptr);
+      tmesa->UbyteSecondaryColor.Ptr = 0;
+   }
+
+   if (tmesa->UbyteColor.Ptr) {
+      ALIGN_FREE(tmesa->UbyteColor.Ptr);
+      tmesa->UbyteColor.Ptr = 0;
+   }
+}