Via Unichrome/cle266 driver (Erdi Chen)
authorBrian Paul <brian.paul@tungstengraphics.com>
Fri, 30 Jan 2004 23:26:19 +0000 (23:26 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 30 Jan 2004 23:26:19 +0000 (23:26 +0000)
36 files changed:
src/mesa/drivers/dri/unichrome/Makefile.solo [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/server/via.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/server/via_dri.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/server/via_driver.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/server/via_priv.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/server/via_regs.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_3d_reg.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_common.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_context.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_context.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_dd_tritmp.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_dd_vbtmp.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_dmatmp.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_dri.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_fb.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_fb.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_ioctl.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_ioctl.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_render.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_screen.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_screen.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_span.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_span.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_state.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_state.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_tex.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_tex.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_texmem.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_texstate.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_tris.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_tris.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_vb.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_vb.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/via_vb_rendertmp.h [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/xf86drmVIA.c [new file with mode: 0644]
src/mesa/drivers/dri/unichrome/xf86drmVIA.h [new file with mode: 0644]

diff --git a/src/mesa/drivers/dri/unichrome/Makefile.solo b/src/mesa/drivers/dri/unichrome/Makefile.solo
new file mode 100644 (file)
index 0000000..4cab499
--- /dev/null
@@ -0,0 +1,122 @@
+
+# Mesa 3-D graphics library
+# Version:  5.0
+# Copyright (C) 1995-2002  Brian Paul
+
+TOP = ../../../../..
+
+default: linux-solo
+
+SHARED_INCLUDES = $(INCLUDE_DIRS) -I. -I../common -Iserver
+MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini
+
+DEFINES += \
+       -D_HAVE_SWRAST=1 \
+       -D_HAVE_SWTNL=1 \
+       -D_HAVE_SANITY=1 \
+       -D_HAVE_CODEGEN=1 \
+       -D_HAVE_LIGHTING=1 \
+       -D_HAVE_TEXGEN=1 \
+       -D_HAVE_USERCLIP=1 \
+       -DGLX_DIRECT_RENDERING 
+
+MINIGLX_SOURCES = server/via_dri.c 
+
+DRIVER_SOURCES = \
+               via_context.c \
+               via_fb.c \
+               via_ioctl.c \
+               via_render.c \
+               via_screen.c \
+               via_span.c \
+               via_state.c \
+               via_tex.c \
+               via_texmem.c \
+               via_texstate.c \
+               via_tris.c \
+               via_vb.c \
+               xf86drmVIA.c \
+                ../common/mm.c \
+                ../common/utils.c \
+                ../common/texmem.c \
+                ../common/vblank.c \
+               ../common/xmlconfig.c \
+               ../../common/driverfuncs.c
+
+INCLUDES = $(MINIGLX_INCLUDES) \
+          $(SHARED_INCLUDES)
+
+
+C_SOURCES = $(DRIVER_SOURCES) \
+           $(MINIGLX_SOURCES) 
+
+MESA_MODULES = $(TOP)/src/mesa/mesa.a
+
+
+ifeq ($(WINDOW_SYSTEM),dri)
+WINOBJ=$(MESABUILDDIR)/dri/dri.a
+WINLIB=
+else
+WINOBJ=
+WINLIB=-L$(MESA)/src/glx/mini
+endif
+
+ASM_SOURCES = 
+OBJECTS = $(C_SOURCES:.c=.o) \
+         $(ASM_SOURCES:.S=.o) 
+
+### Include directories
+
+INCLUDE_DIRS = \
+       -I$(TOP)/include \
+       -I$(TOP)/src/mesa \
+       -I$(TOP)/src/mesa/main \
+       -I$(TOP)/src/mesa/glapi \
+       -I$(TOP)/src/mesa/math \
+       -I$(TOP)/src/mesa/transform \
+       -I$(TOP)/src/mesa/swrast \
+       -I$(TOP)/src/mesa/swrast_setup
+
+
+##### RULES #####
+
+.c.o:
+       $(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+.S.o:
+       $(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES)  $< -o $@
+
+
+##### TARGETS #####
+
+targets: depend unichrome_dri.so
+
+unichrome_dri.so:  $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile.solo
+       rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lc $(GL_LIB_DEPS)
+       rm -f $(TOP)/lib/unichrome_dri.so && \
+       install unichrome_dri.so $(TOP)/lib/unichrome_dri.so
+
+$(TOP)/lib/unichrome_dri.so:   unichrome_dri.so
+       rm -f $(TOP)/lib/unichrome_dri.so && \
+       install unichrome_dri.so $(TOP)/lib/unichrome_dri.so
+
+# Run 'make -f Makefile.solo dep' to update the dependencies if you change
+# what's included by any source file.
+depend: $(C_SOURCES) $(ASM_SOURCES)
+       makedepend -fdepend -Y $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) \
+               $(C_SOURCES) $(ASM_SOURCES) >& /dev/null
+
+
+# Emacs tags
+tags:
+       etags `find . -name \*.[ch]` `find ../include`
+
+
+# Remove .o and backup files
+clean:
+       -rm -f *.o */*.o *~ *.o *~ *.so server/*.o
+
+
+include $(TOP)/Make-config
+
+include depend
diff --git a/src/mesa/drivers/dri/unichrome/server/via.h b/src/mesa/drivers/dri/unichrome/server/via.h
new file mode 100644 (file)
index 0000000..2cfe663
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __VIA_H__
+#define __VIA_H__
+
+typedef struct VIAInfo
+{
+    size_t registerSize;
+    void * registerHandle;
+    void * data;
+} * VIAInfoPtr;
+
+#endif /* __VIA_H__ */
diff --git a/src/mesa/drivers/dri/unichrome/server/via_dri.c b/src/mesa/drivers/dri/unichrome/server/via_dri.c
new file mode 100644 (file)
index 0000000..db661b4
--- /dev/null
@@ -0,0 +1,876 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_dri.c,v 1.4 2003/09/24 02:43:30 dawes Exp $ */
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#if 0
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Priv.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#define _XF86DRI_SERVER_
+#include "GL/glxtokens.h"
+
+#else
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include "driver.h"
+#include "drm.h"
+#endif
+
+#include "dri_util.h"
+#include "sarea.h"
+
+#include "via_context.h"
+#include "via_dri.h"
+#include "via_driver.h"
+#include "via_common.h"
+#include "xf86drm.h"
+
+static void VIAEnableMMIO(DRIDriverContext * ctx);
+static void VIADisableMMIO(DRIDriverContext * ctx);
+static void VIADisableExtendedFIFO(DRIDriverContext *ctx);
+static void VIAEnableExtendedFIFO(DRIDriverContext *ctx);
+static void VIAInitialize2DEngine(DRIDriverContext *ctx);
+static void VIAInitialize3DEngine(DRIDriverContext *ctx);
+
+static int VIADRIScreenInit(DRIDriverContext * ctx);
+static void VIADRICloseScreen(DRIDriverContext * ctx);
+static int VIADRIFinishScreenInit(DRIDriverContext * ctx);
+
+/* TODO XXX _SOLO temp macros */
+typedef unsigned char CARD8;
+typedef unsigned short CARD16;
+#define xf86DrvMsg(a, b, ...) fprintf(stderr, __VA_ARGS__)
+#define MMIO_IN8(base, addr) ((*(((volatile CARD8*)base)+(addr)))+0)
+#define MMIO_OUT8(base, addr, val) ((*(((volatile CARD8*)base)+(addr)))=((CARD8)val))
+#define MMIO_OUT16(base, addr, val) ((*(volatile CARD16*)(((CARD8*)base)+(addr)))=((CARD16)val))
+#define VGA_MISC_OUT_R  0x3cc
+#define VGA_MISC_OUT_W  0x3c2
+
+#define VIDEO  0 
+#define AGP            1
+#define AGP_PAGE_SIZE 4096
+#define AGP_PAGES 8192
+#define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES)
+#define AGP_CMDBUF_PAGES 256
+#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)
+
+static char VIAKernelDriverName[] = "via";
+static char VIAClientDriverName[] = "via";
+
+static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia);
+static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia);
+static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia);
+static int VIADRIKernelInit(DRIDriverContext * ctx, VIAPtr pVia);
+static int VIADRIMapInit(DRIDriverContext * ctx, VIAPtr pVia);
+
+static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia)
+{
+    unsigned long  agp_phys;
+    unsigned int agpaddr;
+    VIADRIPtr pVIADRI;
+    pVIADRI = pVia->devPrivate;
+    pVia->agpSize = 0;
+
+    if (drmAgpAcquire(pVia->drmFD) < 0) {
+        xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed %d\n", errno);
+        return FALSE;
+    }
+
+    if (drmAgpEnable(pVia->drmFD, drmAgpGetMode(pVia->drmFD)&~0x0) < 0) {
+         xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpEnable failed\n");
+        return FALSE;
+    }
+    
+    xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] drmAgpEnabled succeeded\n");
+
+    if (drmAgpAlloc(pVia->drmFD, AGP_SIZE, 0, &agp_phys, &pVia->agpHandle) < 0) {
+        xf86DrvMsg(pScreen->myNum, X_ERROR,
+                 "[drm] drmAgpAlloc failed\n");
+        drmAgpRelease(pVia->drmFD);
+        return FALSE;
+    }
+   
+    if (drmAgpBind(pVia->drmFD, pVia->agpHandle, 0) < 0) {
+        xf86DrvMsg(pScreen->myNum, X_ERROR,
+                 "[drm] drmAgpBind failed\n");
+        drmAgpFree(pVia->drmFD, pVia->agpHandle);
+        drmAgpRelease(pVia->drmFD);
+
+        return FALSE;
+    }
+
+    pVia->agpSize = AGP_SIZE;
+    pVia->agpAddr = drmAgpBase(pVia->drmFD);
+    xf86DrvMsg(pScreen->myNum, X_INFO,
+                 "[drm] agpAddr = 0x%08lx\n",pVia->agpAddr);
+                
+    pVIADRI->agp.size = pVia->agpSize;
+    if (drmAddMap(pVia->drmFD, (drmHandle)0,
+                 pVIADRI->agp.size, DRM_AGP, 0, 
+                 &pVIADRI->agp.handle) < 0) {
+       xf86DrvMsg(pScreen->myNum, X_ERROR,
+           "[drm] Failed to map public agp area\n");
+        pVIADRI->agp.size = 0;
+        return FALSE;
+    }  
+    /* Map AGP from kernel to Xserver - Not really needed */
+    drmMap(pVia->drmFD, pVIADRI->agp.handle,pVIADRI->agp.size,
+       (drmAddressPtr)&agpaddr);
+
+#if 0
+    xf86DrvMsg(pScreen->myNum, X_INFO, 
+                "[drm] agpBase = %p\n", pVia->agpBase);
+    xf86DrvMsg(pScreen->myNum, X_INFO, 
+                "[drm] agpAddr = 0x%08lx\n", pVia->agpAddr);
+#endif
+    xf86DrvMsg(pScreen->myNum, X_INFO, 
+                "[drm] agpSize = 0x%08x\n", pVia->agpSize);
+    xf86DrvMsg(pScreen->myNum, X_INFO, 
+                "[drm] agp physical addr = 0x%08lx\n", agp_phys);
+
+    {
+       drm_via_agp_t agp;
+       agp.offset = 0;
+       agp.size = AGP_SIZE;
+       if (drmCommandWrite(pVia->drmFD, DRM_VIA_AGP_INIT, &agp,
+                           sizeof(drm_via_agp_t)) < 0)
+           return FALSE;
+    }
+
+    return TRUE;
+}
+
+static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia)
+{   
+    int FBSize = pVia->FBFreeEnd-pVia->FBFreeStart;
+    int FBOffset = pVia->FBFreeStart; 
+    VIADRIPtr pVIADRI = pVia->devPrivate;
+    pVIADRI->fbOffset = FBOffset;
+    pVIADRI->fbSize = pVia->videoRambytes;
+    
+    {
+       drm_via_fb_t fb;
+       fb.offset = FBOffset;
+       fb.size = FBSize;
+       
+       if (drmCommandWrite(pVia->drmFD, DRM_VIA_FB_INIT, &fb,
+                           sizeof(drm_via_fb_t)) < 0) {
+           xf86DrvMsg(pScreen->myNum, X_ERROR,
+                      "[drm] failed to init frame buffer area\n");
+           return FALSE;
+       } else {
+           xf86DrvMsg(pScreen->myNum, X_INFO,
+                      "[drm] FBFreeStart= 0x%08x FBFreeEnd= 0x%08x "
+                      "FBSize= 0x%08x\n",
+                      pVia->FBFreeStart, pVia->FBFreeEnd, FBSize);
+           return TRUE;        
+       }   
+    }
+}
+
+static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia)
+{
+    return TRUE;       
+}
+
+static int VIADRIScreenInit(DRIDriverContext * ctx)
+{
+    VIAPtr pVia = VIAPTR(ctx);
+    VIADRIPtr pVIADRI;
+    int err;
+
+#if 0
+    ctx->shared.SAREASize = ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000);
+#else
+    if (sizeof(XF86DRISAREARec)+sizeof(VIASAREAPriv) > SAREA_MAX) {
+       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                       "Data does not fit in SAREA\n");
+       return FALSE;
+    }
+    ctx->shared.SAREASize = SAREA_MAX;
+#endif
+
+    ctx->drmFD = drmOpen(VIAKernelDriverName, NULL);
+    if (ctx->drmFD < 0) {
+        fprintf(stderr, "[drm] drmOpen failed\n");
+        return 0;
+    }
+    pVia->drmFD = ctx->drmFD;
+
+    err = drmSetBusid(ctx->drmFD, ctx->pciBusID);
+    if (err < 0) {
+        fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
+                ctx->drmFD, ctx->pciBusID, strerror(-err));
+        return 0;
+    }
+
+    err = drmAddMap(ctx->drmFD, 0, ctx->shared.SAREASize, DRM_SHM,
+                  DRM_CONTAINS_LOCK, &ctx->shared.hSAREA);
+    if (err < 0) {
+        fprintf(stderr, "[drm] drmAddMap failed\n");
+        return 0;
+    }
+    fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n",
+            ctx->shared.SAREASize, ctx->shared.hSAREA);
+
+    if (drmMap(ctx->drmFD,
+               ctx->shared.hSAREA,
+               ctx->shared.SAREASize,
+               (drmAddressPtr)(&ctx->pSAREA)) < 0)
+    {
+        fprintf(stderr, "[drm] drmMap failed\n");
+        return 0;
+    }
+    memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
+    fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
+            ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
+
+    /* Need to AddMap the framebuffer and mmio regions here:
+     */
+    if (drmAddMap(ctx->drmFD,
+                  (drmHandle)ctx->FBStart,
+                  ctx->FBSize,
+                  DRM_FRAME_BUFFER,
+#ifndef _EMBEDDED
+                   0,
+#else
+                   DRM_READ_ONLY,
+#endif
+                   &ctx->shared.hFrameBuffer) < 0)
+    {
+        fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
+        return 0;
+    }
+
+    fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
+            ctx->shared.hFrameBuffer);
+
+    pVIADRI = (VIADRIPtr) calloc(1, sizeof(VIADRIRec));
+    if (!pVIADRI) {
+        drmClose(ctx->drmFD);
+        return FALSE;
+    }
+    pVia->devPrivate = pVIADRI;
+    ctx->driverClientMsg = pVIADRI;
+    ctx->driverClientMsgSize = sizeof(*pVIADRI);
+
+    pVia->IsPCI = !VIADRIAgpInit(ctx, pVia);
+
+    if (pVia->IsPCI) {
+        VIADRIPciInit(ctx, pVia);
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use pci.\n" );
+    }
+    else
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use agp.\n" );
+
+    if (!(VIADRIFBInit(ctx, pVia))) {
+       VIADRICloseScreen(ctx);
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] frame buffer initialize fial .\n" );
+        return FALSE;
+    }
+    
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] frame buffer initialized.\n" );
+    /* DRIScreenInit doesn't add all the common mappings.  Add additional mappings here. */
+    if (!VIADRIMapInit(ctx, pVia)) {
+       VIADRICloseScreen(ctx);
+       return FALSE;
+    }
+    pVIADRI->regs.size = VIA_MMIO_REGSIZE;
+    pVIADRI->regs.map = 0;
+    pVIADRI->regs.handle = pVia->registerHandle;
+    xf86DrvMsg(ctx->myNum, X_INFO, "[drm] mmio Registers = 0x%08lx\n",
+       pVIADRI->regs.handle);
+
+    if (drmMap(pVia->drmFD,
+               pVIADRI->regs.handle,
+               pVIADRI->regs.size,
+               (drmAddress *)&pVia->MapBase) != 0)
+    {
+        VIADRICloseScreen(ctx);
+        return FALSE;
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] mmio mapped.\n" );
+
+    return VIADRIFinishScreenInit(ctx);
+}
+
+static void
+VIADRICloseScreen(DRIDriverContext * ctx)
+{
+    VIAPtr pVia = VIAPTR(ctx);
+    VIADRIPtr pVIADRI=(VIADRIPtr)pVia->devPrivate;
+
+    if (pVia->MapBase) {
+       xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Unmapping MMIO registers\n");
+        drmUnmap(pVia->MapBase, pVIADRI->regs.size);
+    }
+
+    if (pVia->agpSize) {
+       xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Freeing agp memory\n");
+        drmAgpFree(pVia->drmFD, pVia->agpHandle);
+       xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Releasing agp module\n");
+       drmAgpRelease(pVia->drmFD);
+    }
+}
+
+static int
+VIADRIFinishScreenInit(DRIDriverContext * ctx)
+{
+    VIAPtr pVia = VIAPTR(ctx);
+    VIADRIPtr pVIADRI;
+    int err;
+
+    err = drmCreateContext(ctx->drmFD, &ctx->serverContext);
+    if (err != 0) {
+        fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
+        return FALSE;
+    }
+
+    DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0);
+
+
+    if (!VIADRIKernelInit(ctx, pVia)) {
+       VIADRICloseScreen(ctx);
+       return FALSE;
+    }
+    xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] kernel data initialized.\n");
+
+    /* set SAREA value */
+    {
+       VIASAREAPriv *saPriv;
+
+       saPriv=(VIASAREAPriv*)(((char*)ctx->pSAREA) +
+                               sizeof(XF86DRISAREARec));
+       assert(saPriv);
+       memset(saPriv, 0, sizeof(*saPriv));
+       saPriv->CtxOwner = -1;
+    }
+    pVIADRI=(VIADRIPtr)pVia->devPrivate;
+    pVIADRI->deviceID=pVia->Chipset;  
+    pVIADRI->width=ctx->shared.virtualWidth;
+    pVIADRI->height=ctx->shared.virtualHeight;
+    pVIADRI->mem=ctx->shared.fbSize;
+    pVIADRI->bytesPerPixel= (ctx->bpp+7) / 8; 
+    pVIADRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
+    /* TODO */
+    pVIADRI->scrnX=pVIADRI->width;
+    pVIADRI->scrnY=pVIADRI->height;
+
+    return TRUE;
+}
+
+/* Initialize the kernel data structures. */
+static int VIADRIKernelInit(DRIDriverContext * ctx, VIAPtr pVia)
+{
+    drm_via_init_t drmInfo;
+    memset(&drmInfo, 0, sizeof(drm_via_init_t));
+    drmInfo.func = VIA_INIT_MAP;
+    drmInfo.sarea_priv_offset   = sizeof(XF86DRISAREARec);
+    drmInfo.fb_offset           = pVia->FrameBufferBase;
+    drmInfo.mmio_offset         = pVia->registerHandle;
+    if (pVia->IsPCI)
+       drmInfo.agpAddr = (CARD32)NULL;
+    else
+       drmInfo.agpAddr = (CARD32)pVia->agpAddr;
+
+       if ((drmCommandWrite(pVia->drmFD, DRM_VIA_MAP_INIT,&drmInfo,
+                            sizeof(drm_via_init_t))) < 0)
+           return FALSE;
+
+    return TRUE;
+}
+/* Add a map for the MMIO registers */
+static int VIADRIMapInit(DRIDriverContext * ctx, VIAPtr pVia)
+{
+    int flags = 0;
+
+    if (drmAddMap(pVia->drmFD, pVia->MmioBase, VIA_MMIO_REGSIZE,
+                 DRM_REGISTERS, flags, &pVia->registerHandle) < 0) {
+       return FALSE;
+    }
+
+    xf86DrvMsg(pScreen->myNum, X_INFO,
+       "[drm] register handle = 0x%08lx\n", pVia->registerHandle);
+
+    return TRUE;
+}
+
+const __GLcontextModes __glModes[] =
+{
+    /* 32 bit, RGBA Depth=24 Stencil=8 */
+    {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE,
+     .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_TRUE,
+     .redBits = 8, .greenBits = 8, .blueBits = 8, .alphaBits = 8,
+     .redMask = 0xff0000, .greenMask = 0xff00, .blueMask = 0xff, .alphaMask = 0xff000000,
+     .rgbBits = 32, .indexBits = 0,
+     .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0,
+     .depthBits = 16, .stencilBits = 8,
+     .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, },
+
+    /* 16 bit, RGB Depth=16 */
+    {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE,
+     .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_FALSE,
+     .redBits = 5, .greenBits = 6, .blueBits = 5, .alphaBits = 0,
+     .redMask = 0xf800, .greenMask = 0x07e0, .blueMask = 0x001f, .alphaMask = 0x0,
+     .rgbBits = 16, .indexBits = 0,
+     .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0,
+     .depthBits = 16, .stencilBits = 0,
+     .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, },
+};
+
+static int viaInitContextModes(const DRIDriverContext *ctx,
+                                  int *numModes, const __GLcontextModes **modes)
+{
+    *numModes = sizeof(__glModes)/sizeof(__GLcontextModes *);
+    *modes = &__glModes[0];
+    return 1;
+}
+
+static int viaValidateMode(const DRIDriverContext *ctx)
+{
+    VIAPtr pVia = VIAPTR(ctx);
+
+    return 1;
+}
+
+static int viaPostValidateMode(const DRIDriverContext *ctx)
+{
+    VIAPtr pVia = VIAPTR(ctx);
+
+    return 1;
+}
+
+static void VIAEnableMMIO(DRIDriverContext * ctx)
+{
+    /*vgaHWPtr hwp = VGAHWPTR(ctx);*/
+    VIAPtr pVia = VIAPTR(ctx);
+    unsigned char val;
+
+#if 0
+    if (xf86IsPrimaryPci(pVia->PciInfo)) {
+        /* If we are primary card, we still use std vga port. If we use
+         * MMIO, system will hang in vgaHWSave when our card used in
+         * PLE and KLE (integrated Trident MVP4)
+         */
+        vgaHWSetStdFuncs(hwp);
+    }
+    else {
+        vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000);
+    }
+#endif
+
+    val = VGAIN8(0x3c3);
+    VGAOUT8(0x3c3, val | 0x01);
+    val = VGAIN8(VGA_MISC_OUT_R);
+    VGAOUT8(VGA_MISC_OUT_W, val | 0x01);
+
+    /* Unlock Extended IO Space */
+    VGAOUT8(0x3c4, 0x10);
+    VGAOUT8(0x3c5, 0x01);
+
+    /* Enable MMIO */
+    if(!pVia->IsSecondary) {
+       VGAOUT8(0x3c4, 0x1a);
+       val = VGAIN8(0x3c5);
+#ifdef DEBUG
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "primary val = %x\n", val);
+#endif
+       VGAOUT8(0x3c5, val | 0x68);
+    }
+    else {
+       VGAOUT8(0x3c4, 0x1a);
+       val = VGAIN8(0x3c5);
+#ifdef DEBUG
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "secondary val = %x\n", val);
+#endif
+       VGAOUT8(0x3c5, val | 0x38);
+    }
+
+    return;
+}
+
+static void VIADisableMMIO(DRIDriverContext * ctx)
+{
+    VIAPtr pVia = VIAPTR(ctx);
+    unsigned char val;
+
+    VGAOUT8(0x3c4, 0x1a);
+    val = VGAIN8(0x3c5);
+    VGAOUT8(0x3c5, val & 0x97);
+
+    return;
+}
+
+static void VIADisableExtendedFIFO(DRIDriverContext *ctx)
+{
+    VIAPtr  pVia = VIAPTR(ctx);
+    CARD32          dwTemp;
+
+    dwTemp = (CARD32)VIAGETREG(0x298);
+    dwTemp |= 0x20000000;
+    VIASETREG(0x298, dwTemp);
+
+    dwTemp = (CARD32)VIAGETREG(0x230);
+    dwTemp &= ~0x00200000;
+    VIASETREG(0x230, dwTemp);
+
+    dwTemp = (CARD32)VIAGETREG(0x298);
+    dwTemp &= ~0x20000000;
+    VIASETREG(0x298, dwTemp);
+}
+
+static void VIAEnableExtendedFIFO(DRIDriverContext *ctx)
+{
+    VIAPtr  pVia = VIAPTR(ctx);
+    CARD32          dwTemp;
+    CARD8           bTemp;
+
+    dwTemp = (CARD32)VIAGETREG(0x298);
+    dwTemp |= 0x20000000;
+    VIASETREG(0x298, dwTemp);
+
+    dwTemp = (CARD32)VIAGETREG(0x230);
+    dwTemp |= 0x00200000;
+    VIASETREG(0x230, dwTemp);
+
+    dwTemp = (CARD32)VIAGETREG(0x298);
+    dwTemp &= ~0x20000000;
+    VIASETREG(0x298, dwTemp);
+
+    VGAOUT8(0x3C4, 0x17);
+    bTemp = VGAIN8(0x3C5);
+    bTemp &= ~0x7F;
+    bTemp |= 0x2F;
+    VGAOUT8(0x3C5, bTemp);
+
+    VGAOUT8(0x3C4, 0x16);
+    bTemp = VGAIN8(0x3C5);
+    bTemp &= ~0x3F;
+    bTemp |= 0x17;
+    VGAOUT8(0x3C5, bTemp);
+
+    VGAOUT8(0x3C4, 0x18);
+    bTemp = VGAIN8(0x3C5);
+    bTemp &= ~0x3F;
+    bTemp |= 0x17;
+    bTemp |= 0x40; /* force the preq always higher than treq */
+    VGAOUT8(0x3C5, bTemp);
+}
+
+static void VIAInitialize2DEngine(DRIDriverContext *ctx)
+{
+    VIAPtr  pVia = VIAPTR(ctx);
+    CARD32  dwVQStartAddr, dwVQEndAddr;
+    CARD32  dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
+    CARD32  dwGEMode;
+
+    /* init 2D engine regs to reset 2D engine */
+    VIASETREG(0x04, 0x0);
+    VIASETREG(0x08, 0x0);
+    VIASETREG(0x0c, 0x0);
+    VIASETREG(0x10, 0x0);
+    VIASETREG(0x14, 0x0);
+    VIASETREG(0x18, 0x0);
+    VIASETREG(0x1c, 0x0);
+    VIASETREG(0x20, 0x0);
+    VIASETREG(0x24, 0x0);
+    VIASETREG(0x28, 0x0);
+    VIASETREG(0x2c, 0x0);
+    VIASETREG(0x30, 0x0);
+    VIASETREG(0x34, 0x0);
+    VIASETREG(0x38, 0x0);
+    VIASETREG(0x3c, 0x0);
+    VIASETREG(0x40, 0x0);
+
+    /* Init AGP and VQ regs */
+    VIASETREG(0x43c, 0x00100000);
+    VIASETREG(0x440, 0x00000000);
+    VIASETREG(0x440, 0x00333004);
+    VIASETREG(0x440, 0x60000000);
+    VIASETREG(0x440, 0x61000000);
+    VIASETREG(0x440, 0x62000000);
+    VIASETREG(0x440, 0x63000000);
+    VIASETREG(0x440, 0x64000000);
+    VIASETREG(0x440, 0x7D000000);
+
+    VIASETREG(0x43c, 0xfe020000);
+    VIASETREG(0x440, 0x00000000);
+
+    if (pVia->VQStart != 0) {
+        /* Enable VQ */
+        dwVQStartAddr = pVia->VQStart;
+        dwVQEndAddr = pVia->VQEnd;
+        dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
+        dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
+        dwVQStartEndH = 0x52000000 | ((dwVQStartAddr & 0xFF000000) >> 24) |
+                        ((dwVQEndAddr & 0xFF000000) >> 16);
+        dwVQLen = 0x53000000 | (VIA_VQ_SIZE >> 3);
+
+        VIASETREG(0x43c, 0x00fe0000);
+        VIASETREG(0x440, 0x080003fe);
+        VIASETREG(0x440, 0x0a00027c);
+        VIASETREG(0x440, 0x0b000260);
+        VIASETREG(0x440, 0x0c000274);
+        VIASETREG(0x440, 0x0d000264);
+        VIASETREG(0x440, 0x0e000000);
+        VIASETREG(0x440, 0x0f000020);
+        VIASETREG(0x440, 0x1000027e);
+        VIASETREG(0x440, 0x110002fe);
+        VIASETREG(0x440, 0x200f0060);
+
+        VIASETREG(0x440, 0x00000006);
+        VIASETREG(0x440, 0x40008c0f);
+        VIASETREG(0x440, 0x44000000);
+        VIASETREG(0x440, 0x45080c04);
+        VIASETREG(0x440, 0x46800408);
+
+        VIASETREG(0x440, dwVQStartEndH);
+        VIASETREG(0x440, dwVQStartL);
+        VIASETREG(0x440, dwVQEndL);
+        VIASETREG(0x440, dwVQLen);
+    }
+    else {
+        /* Diable VQ */
+        VIASETREG(0x43c, 0x00fe0000);
+        VIASETREG(0x440, 0x00000004);
+        VIASETREG(0x440, 0x40008c0f);
+        VIASETREG(0x440, 0x44000000);
+        VIASETREG(0x440, 0x45080c04);
+        VIASETREG(0x440, 0x46800408);
+    }
+
+    dwGEMode = 0;
+
+    switch (ctx->bpp) {
+    case 16:
+        dwGEMode |= VIA_GEM_16bpp;
+        break;
+    case 32:
+        dwGEMode |= VIA_GEM_32bpp;
+    default:
+        dwGEMode |= VIA_GEM_8bpp;
+        break;
+    }
+
+#if 0
+    switch (ctx->shared.virtualWidth) {
+    case 800:
+        dwGEMode |= VIA_GEM_800;
+        break;
+    case 1024:
+        dwGEMode |= VIA_GEM_1024;
+        break;
+    case 1280:
+        dwGEMode |= VIA_GEM_1280;
+        break;
+    case 1600:
+        dwGEMode |= VIA_GEM_1600;
+        break;
+    case 2048:
+        dwGEMode |= VIA_GEM_2048;
+        break;
+    default:
+        dwGEMode |= VIA_GEM_640;
+        break;
+    }
+#endif
+
+    /* Set BPP and Pitch */
+    VIASETREG(VIA_REG_GEMODE, dwGEMode);
+
+    /* Set Src and Dst base address and pitch, pitch is qword */
+    VIASETREG(VIA_REG_SRCBASE, 0x0);
+    VIASETREG(VIA_REG_DSTBASE, 0x0);
+    VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE |
+              ((ctx->shared.virtualWidth * ctx->bpp >> 3) >> 3) |
+              (((ctx->shared.virtualWidth * ctx->bpp >> 3) >> 3) << 16));
+}
+
+static void VIAInitialize3DEngine(DRIDriverContext *ctx)
+{
+    VIAPtr  pVia = VIAPTR(ctx);
+    int i;
+
+    if (!pVia->sharedData->b3DRegsInitialized)
+    {
+
+        VIASETREG(0x43C, 0x00010000);
+
+        for (i = 0; i <= 0x7D; i++)
+        {
+            VIASETREG(0x440, (CARD32) i << 24);
+        }
+
+        VIASETREG(0x43C, 0x00020000);
+
+        for (i = 0; i <= 0x94; i++)
+        {
+            VIASETREG(0x440, (CARD32) i << 24);
+        }
+
+        VIASETREG(0x440, 0x82400000);
+
+        VIASETREG(0x43C, 0x01020000);
+
+
+        for (i = 0; i <= 0x94; i++)
+        {
+            VIASETREG(0x440, (CARD32) i << 24);
+        }
+
+        VIASETREG(0x440, 0x82400000);
+        VIASETREG(0x43C, 0xfe020000);
+
+        for (i = 0; i <= 0x03; i++)
+        {
+            VIASETREG(0x440, (CARD32) i << 24);
+        }
+
+        VIASETREG(0x43C, 0x00030000);
+
+        for (i = 0; i <= 0xff; i++)
+        {
+            VIASETREG(0x440, 0);
+        }
+        VIASETREG(0x43C, 0x00100000);
+        VIASETREG(0x440, 0x00333004);
+        VIASETREG(0x440, 0x10000002);
+        VIASETREG(0x440, 0x60000000);
+        VIASETREG(0x440, 0x61000000);
+        VIASETREG(0x440, 0x62000000);
+        VIASETREG(0x440, 0x63000000);
+        VIASETREG(0x440, 0x64000000);
+
+        VIASETREG(0x43C, 0x00fe0000);
+
+        if (pVia->ChipRev >= 3 )
+            VIASETREG(0x440,0x40008c0f);
+        else
+            VIASETREG(0x440,0x4000800f);
+
+        VIASETREG(0x440,0x44000000);
+        VIASETREG(0x440,0x45080C04);
+        VIASETREG(0x440,0x46800408);
+        VIASETREG(0x440,0x50000000);
+        VIASETREG(0x440,0x51000000);
+        VIASETREG(0x440,0x52000000);
+        VIASETREG(0x440,0x53000000);
+
+        pVia->sharedData->b3DRegsInitialized = 1;
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                   "3D Engine has been initialized.\n");
+    }
+
+    VIASETREG(0x43C,0x00fe0000);
+    VIASETREG(0x440,0x08000001);
+    VIASETREG(0x440,0x0A000183);
+    VIASETREG(0x440,0x0B00019F);
+    VIASETREG(0x440,0x0C00018B);
+    VIASETREG(0x440,0x0D00019B);
+    VIASETREG(0x440,0x0E000000);
+    VIASETREG(0x440,0x0F000000);
+    VIASETREG(0x440,0x10000000);
+    VIASETREG(0x440,0x11000000);
+    VIASETREG(0x440,0x20000000);
+}
+
+static int viaInitFBDev(DRIDriverContext *ctx)
+{
+    VIAPtr pVia = calloc(1, sizeof(*pVia));
+
+    ctx->driverPrivate = (void *)pVia;
+
+    pVia->Chipset = ctx->chipset;
+
+    pVia->videoRambytes = ctx->shared.fbSize;
+    pVia->MmioBase = ctx->MMIOStart;
+    pVia->FrameBufferBase = ctx->FBStart & 0xfc000000;
+
+    pVia->FBFreeStart = ctx->shared.virtualWidth * ctx->cpp *
+        ctx->shared.virtualHeight;
+    pVia->FBFreeEnd = pVia->videoRambytes;
+
+    pVia->sharedData = (ViaSharedPtr) calloc(1, sizeof(ViaSharedRec));
+
+    if (!VIADRIScreenInit(ctx))
+        return 0;
+
+    VIAEnableMMIO(ctx);
+
+    /* 3D rendering has noise if not enabled. */
+    VIAEnableExtendedFIFO(ctx);
+
+    VIAInitialize2DEngine(ctx);
+    VIAInitialize3DEngine(ctx);
+
+    /* Must disable MMIO or 3D won't work. */
+    VIADisableMMIO(ctx);
+
+    return 1;
+}
+
+static void viaHaltFBDev(DRIDriverContext *ctx)
+{
+    drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
+    drmClose(ctx->drmFD);
+
+    if (ctx->driverPrivate) {
+        free(ctx->driverPrivate);
+        ctx->driverPrivate = 0;
+    }
+}
+
+static int viaEngineShutdown(const DRIDriverContext *ctx)
+{
+    return 1;
+}
+
+static int viaEngineRestore(const DRIDriverContext *ctx)
+{
+    return 1;
+}
+
+const struct DRIDriverRec __driDriver =
+{
+    viaInitContextModes,
+    viaValidateMode,
+    viaPostValidateMode,
+    viaInitFBDev,
+    viaHaltFBDev,
+    viaEngineShutdown,
+    viaEngineRestore,  
+    0,
+};
+
diff --git a/src/mesa/drivers/dri/unichrome/server/via_driver.h b/src/mesa/drivers/dri/unichrome/server/via_driver.h
new file mode 100644 (file)
index 0000000..f97704c
--- /dev/null
@@ -0,0 +1,574 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_driver.h,v 1.7 2003/11/06 18:38:11 tsi Exp $ */
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _VIA_DRIVER_H_
+#define _VIA_DRIVER_H_ 1
+
+#if 0 /* DEBUG is use in VIA DRI code as a flag */
+/* #define DEBUG_PRINT */
+#ifdef DEBUG_PRINT
+#define DEBUG(x) x
+#else
+#define DEBUG(x)
+#endif
+#endif
+
+#if 0
+#include "vgaHW.h"
+#include "xf86.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xf86_OSproc.h"
+#include "compiler.h"
+#include "xf86Cursor.h"
+#include "mipointer.h"
+#include "micmap.h"
+
+#define USE_FB
+#ifdef USE_FB
+#include "fb.h"
+#else
+#include "cfb.h"
+#include "cfb16.h"
+#include "cfb32.h"
+#endif
+
+#include "xf86cmap.h"
+#include "vbe.h"
+#include "xaa.h"
+
+#include "via_regs.h"
+#include "via_bios.h"
+#include "via_gpioi2c.h"
+#include "via_priv.h"
+#include "ginfo.h"
+
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "sarea.h"
+#include "dri.h"
+#include "GL/glxint.h"
+#include "via_dri.h"
+#endif
+#else
+#include "via_priv.h"
+#include "via_regs.h"
+
+#include "sarea.h"
+#include "dri.h"
+#include "via_dri.h"
+#endif
+
+#define DRIVER_NAME     "via"
+#define DRIVER_VERSION  "4.1.0"
+#define VERSION_MAJOR   4
+#define VERSION_MINOR   1
+#define PATCHLEVEL      30
+#define VIA_VERSION     ((VERSION_MAJOR<<24) | (VERSION_MINOR<<16) | PATCHLEVEL)
+
+#define VGAIN8(addr)        MMIO_IN8(pVia->MapBase+0x8000, addr)
+#define VGAIN16(addr)       MMIO_IN16(pVia->MapBase+0x8000, addr)
+#define VGAIN(addr)         MMIO_IN32(pVia->MapBase+0x8000, addr)
+
+#define VGAOUT8(addr, val)  MMIO_OUT8(pVia->MapBase+0x8000, addr, val)
+#define VGAOUT16(addr, val) MMIO_OUT16(pVia->MapBase+0x8000, addr, val)
+#define VGAOUT(addr, val)   MMIO_OUT32(pVia->MapBase+0x8000, addr, val)
+
+#define INREG(addr)         MMIO_IN32(pVia->MapBase, addr)
+#define OUTREG(addr, val)   MMIO_OUT32(pVia->MapBase, addr, val)
+#define INREG16(addr)       MMIO_IN16(pVia->MapBase, addr)
+#define OUTREG16(addr, val) MMIO_OUT16(pVia->MapBase, addr, val)
+
+#define VIA_PIXMAP_CACHE_SIZE   (256 * 1024)
+#define VIA_CURSOR_SIZE         (4 * 1024)
+#define VIA_VQ_SIZE             (256 * 1024)
+
+typedef struct {
+    unsigned int    mode, refresh, resMode;
+    int             countWidthByQWord;
+    int             offsetWidthByQWord;
+    unsigned char   SR08, SR0A, SR0F;
+
+    /*   extended Sequencer registers */
+    unsigned char   SR10, SR11, SR12, SR13,SR14,SR15,SR16;
+    unsigned char   SR17, SR18, SR19, SR1A,SR1B,SR1C,SR1D,SR1E;
+    unsigned char   SR1F, SR20, SR21, SR22,SR23,SR24,SR25,SR26;
+    unsigned char   SR27, SR28, SR29, SR2A,SR2B,SR2C,SR2D,SR2E;
+    unsigned char   SR2F, SR30, SR31, SR32,SR33,SR34,SR40,SR41;
+    unsigned char   SR42, SR43, SR44, SR45,SR46,SR47;
+
+    unsigned char   Clock;
+
+    /*   extended CRTC registers */
+    unsigned char   CR13, CR30, CR31, CR32, CR33, CR34, CR35, CR36;
+    unsigned char   CR37, CR38, CR39, CR3A, CR40, CR41, CR42, CR43;
+    unsigned char   CR44, CR45, CR46, CR47, CR48, CR49, CR4A;
+    unsigned char   CRTCRegs[68];
+    unsigned char   TVRegs[0xFF];
+/*    unsigned char   LCDRegs[0x40];*/
+} VIARegRec, *VIARegPtr;
+
+/*Definition for  CapturePortID*/
+#define PORT0     0      /* Capture Port 0*/
+#define PORT1     1      /* Capture Port 1*/
+
+typedef struct __viaVideoControl {
+  CARD32 PORTID;
+  CARD32 dwCompose;
+  CARD32 dwHighQVDO;
+  CARD32 VideoStatus;
+  CARD32 dwAction;
+#define ACTION_SET_PORTID      0
+#define ACTION_SET_COMPOSE     1
+#define ACTION_SET_HQV         2
+#define ACTION_SET_BOB        4
+#define ACTION_SET_VIDEOSTATUS 8
+  Bool  Cap0OnScreen1;   /* True: Capture0 On Screen1 ; False: Capture0 On Screen0 */
+  Bool  Cap1OnScreen1;   /* True: Capture1 On Screen1 ; False: Capture1 On Screen0 */
+  Bool  MPEGOnScreen1;   /* True: MPEG On Screen1 ; False: MPEG On Screen0 */
+} VIAVideoControlRec, VIAVideoControlPtr;
+
+/*For Video HW Difference */
+#define VIA_REVISION_CLEC0        0x10
+#define VIA_REVISION_CLEC1        0x11
+#define VIA_REVISION_CLECX        0x10
+
+#define VID_HWDIFF_TRUE           0x00000001
+#define VID_HWDIFF_FALSE          0x00000000
+
+/*
+ *     Video HW Difference Structure
+ */
+
+typedef struct __VIAHWRec
+{
+    unsigned long dwThreeHQVBuffer;            /* Use Three HQV Buffers*/
+    unsigned long dwV3SrcHeightSetting;                /* Set Video Source Width and Height*/
+    unsigned long dwSupportExtendFIFO;         /* Support Extand FIFO*/
+    unsigned long dwHQVFetchByteUnit;          /* HQV Fetch Count unit is byte*/
+    unsigned long dwHQVInitPatch;              /* Initialize HQV Engine 2 times*/
+    unsigned long dwSupportV3Gamma;            /* Support V3 Gamma */
+    unsigned long dwUpdFlip;                   /* Set HQV3D0[15] to flip video*/
+    unsigned long dwHQVDisablePatch;           /* Change Video Engine Clock setting for HQV disable bug*/
+    unsigned long dwSUBFlip;                   /* Set HQV3D0[15] to flip video for sub-picture blending*/
+    unsigned long dwNeedV3Prefetch;            /* V3 pre-fetch function for K8*/
+    unsigned long dwNeedV4Prefetch;            /* V4 pre-fetch function for K8*/
+    unsigned long dwUseSystemMemory;           /* Use system memory for DXVA compressed data buffers*/
+    unsigned long dwExpandVerPatch;            /* Patch video HW bug in expand SIM mode or same display path*/
+    unsigned long dwExpandVerHorPatch;         /* Patch video HW bug in expand SAMM mode or same display path*/
+    unsigned long dwV3ExpireNumTune;           /* Change V3 expire number setting for V3 bandwidth issue*/
+    unsigned long dwV3FIFOThresholdTune;       /* Change V3 FIFO, Threshold and Pre-threshold setting for V3 bandwidth issue*/
+    unsigned long dwCheckHQVFIFOEmpty;          /* HW Flip path, need to check HQV FIFO status */
+    unsigned long dwUseMPEGAGP;                 /* Use MPEG AGP function*/
+    unsigned long dwV3FIFOPatch;                /* For CLE V3 FIFO Bug (srcWidth <= 8)*/
+    unsigned long dwSupportTwoColorKey;         /* Support two color key*/
+    unsigned long dwCxColorSpace;               /* CLE_Cx ColorSpace*/
+} VIAHWRec;
+
+/*Wait Function Structure and Flag*/
+typedef struct _WaitHWINFO
+{
+    unsigned char *    pjVideo;                /* MMIO Address Info*/
+    unsigned long      dwVideoFlag;            /* Video Flag*/
+}WaitHWINFO, * LPWaitHWINFO;
+
+#if 0
+/* VIA Tuners */
+typedef struct
+{
+    int                        decoderType;            /* Decoder I2C Type */
+#define SAA7108H               0
+#define SAA7113H               1
+#define SAA7114H               2
+    I2CDevPtr          I2C;                    /* Decoder I2C */
+    I2CDevPtr          FMI2C;                  /* FM Tuner I2C */
+    
+    /* Not yet used */
+    int                        autoDetect;             /* Autodetect mode */
+    int                        tunerMode;              /* Fixed mode */
+} ViaTunerRec, *ViaTunerPtr;
+#endif
+
+/*
+ * New style overlay structure for the SubPicture overlay
+ */
+
+#if 0
+typedef struct
+{
+    VIAMem Memory;
+    int visible:1;     /* Idea is for the top bits to become a generic class */
+    CARD32 width;
+    CARD32 height;
+    CARD32 pitch;
+    CARD32 base[2];    /* Some channels have 3 so 3 for the generic unit */
+    struct
+    {
+       CARD8 Y;
+       CARD8 Cb;
+       CARD8 Cr;
+    } palette[16];
+} ViaSubPictureRecord;
+
+typedef struct
+{
+    VIAMem Memory;
+    int visible:1;     /* Visible */
+    CARD32 width;
+    CARD32 height;
+    CARD32 pitch;
+    CARD32 base[3];
+    int Channel;
+    int HQV;           /* Own HQV */
+} ViaTVRecord;
+    
+typedef struct
+{
+    VIAMem Memory;
+    CARD32 base[3];
+    int Busy;
+} ViaHQVRecord;
+#endif
+
+/*
+ * Variables that need to be shared among different screens.
+ */
+typedef struct {
+    Bool b3DRegsInitialized;
+} ViaSharedRec, *ViaSharedPtr;
+
+
+typedef struct _VIA {
+    VIARegRec           SavedReg;
+    VIARegRec           ModeReg;
+    //xf86CursorInfoPtr   CursorInfoRec;
+    Bool                ModeStructInit;
+    int                 Bpp, Bpl, ScissB;
+    unsigned            PlaneMask;
+
+    unsigned long       videoRambytes;
+    int                 videoRamKbytes;
+    int                 FBFreeStart;
+    int                 FBFreeEnd;
+    int                 CursorStart;
+    int                 VQStart;
+    int                 VQEnd;
+
+    /* These are physical addresses. */
+    unsigned long       FrameBufferBase;
+    unsigned long       MmioBase;
+
+    /* These are linear addresses. */
+    unsigned char*      MapBase;
+    unsigned char*      VidMapBase;
+    unsigned char*      BltBase;
+    unsigned char*      MapBaseDense;
+    unsigned char*      FBBase;
+    unsigned char*      FBStart;
+    
+    /* Private memory pool management */
+    int                        SWOVUsed[MEM_BLOCKS]; /* Free map for SWOV pool */
+    unsigned long      SWOVPool;       /* Base of SWOV pool */
+    unsigned long      SWOVSize;       /* Size of SWOV blocks */
+
+    Bool                PrimaryVidMapped;
+    int                 dacSpeedBpp;
+    int                 minClock, maxClock;
+    int                 MCLK, REFCLK, LCDclk;
+    double              refclk_fact;
+
+    /* Here are all the Options */
+    Bool                VQEnable;
+    Bool                pci_burst;
+    Bool                NoPCIRetry;
+    Bool                hwcursor;
+    Bool                NoAccel;
+    Bool                shadowFB;
+    Bool                NoDDCValue;
+    int                 rotate;
+
+    //CloseScreenProcPtr  CloseScreen;
+    //pciVideoPtr         PciInfo;
+    //PCITAG              PciTag;
+    int                 Chipset;
+    int                 ChipId;
+    int                 ChipRev;
+    //vbeInfoPtr          pVbe;
+    int                 EntityIndex;
+
+    /* Support for shadowFB and rotation */
+    unsigned char*      ShadowPtr;
+    int                 ShadowPitch;
+    void                (*PointerMoved)(int index, int x, int y);
+
+    /* Support for XAA acceleration */
+    //XAAInfoRecPtr       AccelInfoRec;
+    //xRectangle          Rect;
+    CARD32              SavedCmd;
+    CARD32              SavedFgColor;
+    CARD32              SavedBgColor;
+    CARD32              SavedPattern0;
+    CARD32              SavedPattern1;
+    CARD32              SavedPatternAddr;
+
+    /* Support for Int10 processing */
+    //xf86Int10InfoPtr    pInt10;
+
+    /* BIOS Info Ptr */
+    //VIABIOSInfoPtr      pBIOSInfo;
+
+    /* Support for DGA */
+    int                 numDGAModes;
+    //DGAModePtr          DGAModes;
+    Bool                DGAactive;
+    int                 DGAViewportStatus;
+    int                        DGAOldDisplayWidth;
+    int                        DGAOldBitsPerPixel;
+    int                        DGAOldDepth;
+    /* The various wait handlers. */
+    int                 (*myWaitIdle)(struct _VIA*);
+
+    /* I2C & DDC */
+    //I2CBusPtr           I2C_Port1;
+    //I2CBusPtr           I2C_Port2;
+    //xf86MonPtr          DDC1;
+    //xf86MonPtr          DDC2;
+
+    /* MHS */
+    Bool                IsSecondary;
+    Bool                HasSecondary;
+
+    /* Capture de-interlace Mode */
+    CARD32              Cap0_Deinterlace;
+    CARD32              Cap1_Deinterlace;
+
+    Bool                Cap0_FieldSwap;
+
+#ifdef XF86DRI
+    Bool               directRenderingEnabled;
+    DRIInfoPtr         pDRIInfo;
+    int                drmFD;
+    int                numVisualConfigs;
+    __GLXvisualConfig*         pVisualConfigs;
+    VIAConfigPrivPtr   pVisualConfigsPriv;
+    unsigned long      agpHandle;
+    unsigned long      registerHandle;
+    unsigned long      agpAddr;
+    unsigned char      *agpBase;
+    unsigned int       agpSize;
+    Bool               IsPCI;
+    Bool               drixinerama;
+#else
+    int                drmFD;
+    unsigned long      agpHandle;
+    unsigned long      registerHandle;
+    unsigned long      agpAddr;
+    unsigned char      *agpBase;
+    unsigned int       agpSize;
+    Bool               IsPCI;
+#endif
+    Bool               OldDRI;         /* True if DRM < 2.0 found */
+    
+    unsigned char      ActiveDevice;   /* if SAMM, non-equal pBIOSInfo->ActiveDevice */
+    unsigned char       *CursorImage;
+    CARD32             CursorFG;
+    CARD32             CursorBG;
+    CARD32             CursorMC;
+
+#if 0
+    /* Video */
+    swovRec            swov;
+    VIAVideoControlRec  Video;
+    VIAHWRec           ViaHW;
+    unsigned long      dwV1, dwV3;
+    unsigned long      OverlaySupported;
+    unsigned long      dwFrameNum;
+
+    pointer            VidReg;
+    unsigned long      gdwVidRegCounter;
+    unsigned long      old_dwUseExtendedFIFO;
+    
+    /* Overlay TV Tuners */
+    ViaTunerPtr                Tuner[2];
+    I2CDevPtr          CXA2104S;
+    int                        AudioMode;
+    int                        AudioMute;
+#endif
+
+    /* SubPicture */
+    //ViaSubPictureRecord      SubPicture;
+    //ViaHQVRecord     HQV;
+    //ViaTVRecord              TV0, TV1;
+    
+    /* TODO: MPEG TV0 TV1 */
+    
+    /* Global 2D state block - needs to slowly die */
+    //ViaGraphicRec    graphicInfo;    
+    ViaSharedPtr       sharedData;
+
+    VIADRIPtr devPrivate;
+} VIARec, *VIAPtr;
+
+
+#if 0
+typedef struct
+{
+    Bool IsDRIEnabled;
+
+    Bool HasSecondary;
+    Bool BypassSecondary;
+    /*These two registers are used to make sure the CRTC2 is
+      retored before CRTC_EXT, otherwise it could lead to blank screen.*/
+    Bool IsSecondaryRestored;
+    Bool RestorePrimary;
+
+    ScrnInfoPtr pSecondaryScrn;
+    ScrnInfoPtr pPrimaryScrn;
+}VIAEntRec, *VIAEntPtr;
+#endif
+
+
+/* Shortcuts.  These depend on a local symbol "pVia". */
+
+#define WaitIdle()      pVia->myWaitIdle(pVia)
+#define VIAPTR(p)       ((VIAPtr)((p)->driverPrivate))
+
+
+#if 0
+/* Prototypes. */
+void VIAAdjustFrame(int scrnIndex, int y, int x, int flags);
+Bool VIASwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+
+/* In HwDiff.c */
+void VIAvfInitHWDiff(VIAPtr pVia );
+
+/* In via_cursor.c. */
+Bool VIAHWCursorInit(ScreenPtr pScreen);
+void VIAShowCursor(ScrnInfoPtr);
+void VIAHideCursor(ScrnInfoPtr);
+
+
+/* In via_accel.c. */
+Bool VIAInitAccel(ScreenPtr);
+void VIAInitialize2DEngine(ScrnInfoPtr);
+void VIAAccelSync(ScrnInfoPtr);
+void VIAInitLinear(ScreenPtr pScreen);
+
+
+/* In via_shadow.c */
+void VIAPointerMoved(int index, int x, int y);
+void VIARefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void VIARefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void VIARefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void VIARefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void VIARefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+
+
+/* In via_bios.c */
+void VIAEnableLCD(VIABIOSInfoPtr pBIOSInfo);
+void VIADisableLCD(VIABIOSInfoPtr pBIOSInfo);
+
+/* In via_dga.c */
+Bool VIADGAInit(ScreenPtr);
+
+/* In via_i2c.c */
+Bool VIAI2CInit(ScrnInfoPtr pScrn);
+
+/* In via_gpioi2c.c */
+Bool VIAGPIOI2C_Write(VIABIOSInfoPtr pBIOSInfo, int SubAddress, CARD8 Data);
+Bool VIAGPIOI2C_Read(VIABIOSInfoPtr pBIOSInfo, int SubAddress, CARD8 *Buffer, int BufferLen);
+Bool VIAGPIOI2C_ReadByte(VIABIOSInfoPtr pBIOSInfo, int SubAddress, CARD8 *Buffer);
+Bool VIAGPIOI2C_Initial(VIABIOSInfoPtr pBIOSInfo, CARD8 SlaveDevice);
+
+/*In via_video.c*/
+void viaInitVideo(ScreenPtr pScreen);
+void viaExitVideo(ScrnInfoPtr pScrn);
+void viaResetVideo(ScrnInfoPtr pScrn);
+void viaSaveVideo(ScrnInfoPtr pScrn);
+void viaRestoreVideo(ScrnInfoPtr pScrn);
+
+/*In via_utility.c */
+void VIAXVUtilityProc(ScrnInfoPtr pScrn, unsigned char* buf);
+Bool VIAUTGetInfo(VIABIOSInfoPtr pBIOSInfo);
+Bool VIALoadUserSetting(VIABIOSInfoPtr pBIOSInfo);
+Bool VIALoadGammaSetting(VIABIOSInfoPtr pBIOSInfo);
+Bool VIARestoreUserSetting(VIABIOSInfoPtr pBIOSInfo);
+void VIAUTRemoveRestartFlag(VIABIOSInfoPtr pBIOSInfo);
+
+/* in via_overlay.c */
+unsigned long viaOverlayHQVCalcZoomHeight (VIAPtr pVia, unsigned long srcHeight,unsigned long dstHeight,
+                             unsigned long * lpzoomCtl, unsigned long * lpminiCtl, unsigned long * lpHQVfilterCtl, unsigned long * lpHQVminiCtl,unsigned long * lpHQVzoomflag);
+unsigned long viaOverlayGetSrcStartAddress (VIAPtr pVia, unsigned long dwVideoFlag,RECTL rSrc,RECTL rDest, unsigned long dwSrcPitch,LPDDPIXELFORMAT lpDPF,unsigned long * lpHQVoffset );
+void viaOverlayGetDisplayCount(VIAPtr pVIa, unsigned long dwVideoFlag,LPDDPIXELFORMAT lpDPF,unsigned long dwSrcWidth,unsigned long * lpDisplayCountW);
+unsigned long viaOverlayHQVCalcZoomWidth(VIAPtr pVia, unsigned long dwVideoFlag, unsigned long srcWidth , unsigned long dstWidth,
+                           unsigned long * lpzoomCtl, unsigned long * lpminiCtl, unsigned long * lpHQVfilterCtl, unsigned long * lpHQVminiCtl,unsigned long * lpHQVzoomflag);
+void viaOverlayGetV1Format(VIAPtr pVia, unsigned long dwVideoFlag,LPDDPIXELFORMAT lpDPF, unsigned long * lpdwVidCtl,unsigned long * lpdwHQVCtl );
+void viaOverlayGetV3Format(VIAPtr pVia, unsigned long dwVideoFlag,LPDDPIXELFORMAT lpDPF, unsigned long * lpdwVidCtl,unsigned long * lpdwHQVCtl );
+
+/* In via_memory.c */
+void VIAFreeLinear(VIAMemPtr);
+unsigned long VIAAllocLinear(VIAMemPtr, ScrnInfoPtr, unsigned long);
+void VIAInitPool(VIAPtr, unsigned long, unsigned long);
+
+/* In via_tuner.c */
+void ViaTunerStandard(ViaTunerPtr, int);
+void ViaTunerBrightness(ViaTunerPtr, int);
+void ViaTunerContrast(ViaTunerPtr, int);
+void ViaTunerHue(ViaTunerPtr, int);
+void ViaTunerLuminance(ViaTunerPtr, int);
+void ViaTunerSaturation(ViaTunerPtr, int);
+void ViaTunerInput(ViaTunerPtr, int);
+#define MODE_TV                0
+#define MODE_SVIDEO    1
+#define MODE_COMPOSITE 2
+
+void ViaTunerChannel(ViaTunerPtr, int, int);
+void ViaAudioSelect(VIAPtr pVia, int tuner);
+void ViaAudioInit(VIAPtr pVia);
+void ViaAudioMode(VIAPtr pVia, int mode);
+void ViaAudioMute(VIAPtr pVia, int mute);
+void ViaTunerProbe(ScrnInfoPtr pScrn);
+void ViaTunerDestroy(ScrnInfoPtr pScrn);
+
+/* In via_lib.c */
+int VIACLECXChipset(VIAPtr pVia);
+void VIASetColorspace(VIAPtr pVia, int check_secondary);
+void VIAYUVFillBlack(VIAPtr pVia, int offset, int pixels);
+
+/* In via_subp.c */
+unsigned long VIACreateSubPictureSurface(ScrnInfoPtr pScrn, CARD32 width, CARD32 height);
+void VIADestroySubPictureSurface(ScrnInfoPtr pScrn);
+void VIASubPicturePalette(ScrnInfoPtr pScrn);
+void VIASubPictureStart(ScrnInfoPtr pScrn, int frame);
+void VIASubPictureStop(ScrnInfoPtr pScrn);
+
+/* In via_tv0.c */
+unsigned long VIACreateTV0Surface(ScrnInfoPtr pScrn, CARD32 width, CARD32 height);
+void VIADestroyTV0Surface(ScrnInfoPtr pScrn);
+#endif
+
+#endif /* _VIA_DRIVER_H_ */
diff --git a/src/mesa/drivers/dri/unichrome/server/via_priv.h b/src/mesa/drivers/dri/unichrome/server/via_priv.h
new file mode 100644 (file)
index 0000000..c5a8bb9
--- /dev/null
@@ -0,0 +1,70 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_priv.h,v 1.3 2003/08/27 15:16:12 tsi Exp $ */
+
+#ifndef _VIA_PRIV_H_
+#define _VIA_PRIV_H_ 1
+
+//#include "ddmpeg.h"
+#include "via_common.h"
+
+#define MEM_BLOCKS             4
+
+typedef struct {
+    unsigned long   base;              /* Offset into fb */
+    int    pool;                       /* Pool we drew from */
+    int    drm_fd;                     /* Fd in DRM mode */
+    drm_via_mem_t drm;                 /* DRM management object */
+    int    slot;                       /* Pool 3 slot */
+    void  *pVia;                       /* VIA driver pointer */
+    //FBLinearPtr linear;                      /* X linear pool info ptr */
+} VIAMem;
+
+typedef VIAMem *VIAMemPtr;
+
+
+
+#if 0
+typedef struct  {
+    unsigned long   gdwVideoFlagTV1;
+    unsigned long   gdwVideoFlagSW;
+    unsigned long   gdwVideoFlagMPEG;
+    unsigned long   gdwAlphaEnabled;           /* For Alpha blending use*/
+
+    VIAMem SWOVMem;
+    VIAMem HQVMem;
+    VIAMem SWfbMem;
+
+    DDPIXELFORMAT DPFsrc; 
+    DDUPDATEOVERLAY UpdateOverlayBackup;    /* For HQVcontrol func use
+                                           // To save MPEG updateoverlay info.*/
+
+/* device struct */
+    SWDEVICE   SWDevice;
+    SUBDEVICE   SUBDevice;
+    MPGDEVICE   MPGDevice;
+    OVERLAYRECORD   overlayRecordV1;
+    OVERLAYRECORD   overlayRecordV3;
+
+    BoxRec  AvailFBArea;
+    FBLinearPtr   SWOVlinear;
+
+    Bool MPEG_ON;
+    Bool SWVideo_ON;
+
+/*To solve the bandwidth issue */
+    unsigned long   gdwUseExtendedFIFO;
+
+/* For panning mode use */
+    int panning_old_x;
+    int panning_old_y;
+    int panning_x;
+    int panning_y;
+
+/*To solve the bandwidth issue */
+    unsigned char Save_3C4_16;
+    unsigned char Save_3C4_17;
+    unsigned char Save_3C4_18;
+
+} swovRec, *swovPtr;
+#endif
+
+#endif /* _VIA_PRIV_H_ */
diff --git a/src/mesa/drivers/dri/unichrome/server/via_regs.h b/src/mesa/drivers/dri/unichrome/server/via_regs.h
new file mode 100644 (file)
index 0000000..3e2fb0a
--- /dev/null
@@ -0,0 +1,212 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_regs.h,v 1.3 2003/08/27 15:16:13 tsi Exp $ */
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*************************************************************************
+ *
+ *  File:       via_regs.c
+ *  Content:    The defines of Via registers
+ *
+ ************************************************************************/
+
+#ifndef _VIA_REGS_H_
+#define _VIA_REGS_H_ 1
+
+#include "via_driver.h"
+
+#define VIA_SERIES(chip)  (chip == VIA_CLE266)
+
+
+/* Chip tags.  These are used to group the adapters into
+ * related families.
+ */
+
+enum VIACHIPTAGS {
+    VIA_UNKNOWN = 0,
+    VIA_CLE266,
+    VIA_KM400,
+    VIA_K8M800,
+    VIA_LAST
+};
+
+
+#define PCI_VIA_VENDOR_ID       0x1106
+
+#define PCI_CHIP_CLE3122        0x3122
+#define PCI_CHIP_CLE3022        0x3022
+#define PCI_CHIP_VT3205         0x3205
+#define PCI_CHIP_VT7205         0x7205
+#define PCI_CHIP_VT3204         0x3204
+#define PCI_CHIP_VT7204         0x7204
+
+
+#define BIOS_BSIZE              1024
+#define BIOS_BASE               0xc0000
+
+
+#define VIA_MMIO_REGSIZE        0x9000
+#define VIA_MMIO_REGBASE        0x0
+#define VIA_MMIO_VGABASE        0x8000
+#define VIA_MMIO_BLTBASE        0x200000
+#define VIA_MMIO_BLTSIZE        0x10000
+
+
+/* defines for VIA 2D registers */
+#define VIA_REG_GECMD           0x000
+#define VIA_REG_GEMODE          0x004
+#define VIA_REG_GESTATUS        0x004       /* as same as VIA_REG_GEMODE */
+#define VIA_REG_SRCPOS          0x008
+#define VIA_REG_DSTPOS          0x00C
+#define VIA_REG_LINE_K1K2       0x008
+#define VIA_REG_LINE_XY         0x00C
+#define VIA_REG_DIMENSION       0x010       /* width and height */
+#define VIA_REG_PATADDR         0x014
+#define VIA_REG_FGCOLOR         0x018
+#define VIA_REG_DSTCOLORKEY     0x018       /* as same as VIA_REG_FG */
+#define VIA_REG_BGCOLOR         0x01C
+#define VIA_REG_SRCCOLORKEY     0x01C       /* as same as VIA_REG_BG */
+#define VIA_REG_CLIPTL          0x020       /* top and left of clipping */
+#define VIA_REG_CLIPBR          0x024       /* bottom and right of clipping */
+#define VIA_REG_OFFSET          0x028
+#define VIA_REG_LINE_ERROR      0x028
+#define VIA_REG_KEYCONTROL      0x02C       /* color key control */
+#define VIA_REG_SRCBASE         0x030
+#define VIA_REG_DSTBASE         0x034
+#define VIA_REG_PITCH           0x038       /* pitch of src and dst */
+#define VIA_REG_MONOPAT0        0x03C
+#define VIA_REG_MONOPAT1        0x040
+#define VIA_REG_COLORPAT        0x100       /* from 0x100 to 0x1ff */
+
+
+
+/* defines for VIA video registers */
+#define VIA_REG_INTERRUPT       0x200
+#define VIA_REG_CRTCSTART       0x214
+
+
+/* defines for VIA HW cursor registers */
+#define VIA_REG_CURSOR_MODE     0x2D0
+#define VIA_REG_CURSOR_POS      0x2D4
+#define VIA_REG_CURSOR_ORG      0x2D8
+#define VIA_REG_CURSOR_BG       0x2DC
+#define VIA_REG_CURSOR_FG       0x2E0
+
+
+/* defines for VIA 3D registers */
+#define VIA_REG_STATUS          0x400
+#define VIA_REG_TRANSET         0x43C
+#define VIA_REG_TRANSPACE       0x440
+
+/* VIA_REG_STATUS(0x400): Engine Status */
+#define VIA_CMD_RGTR_BUSY       0x00000080  /* Command Regulator is busy */
+#define VIA_2D_ENG_BUSY         0x00000001  /* 2D Engine is busy */
+#define VIA_3D_ENG_BUSY         0x00000002  /* 3D Engine is busy */
+#define VIA_VR_QUEUE_BUSY       0x00020000 /* Virtual Queue is busy */
+
+
+/* VIA_REG_GECMD(0x00): 2D Engine Command  */
+#define VIA_GEC_NOOP            0x00000000
+#define VIA_GEC_BLT             0x00000001
+#define VIA_GEC_LINE            0x00000005
+
+#define VIA_GEC_SRC_XY          0x00000000
+#define VIA_GEC_SRC_LINEAR      0x00000010
+#define VIA_GEC_DST_XY          0x00000000
+#define VIA_GEC_DST_LINRAT      0x00000020
+
+#define VIA_GEC_SRC_FB          0x00000000
+#define VIA_GEC_SRC_SYS         0x00000040
+#define VIA_GEC_DST_FB          0x00000000
+#define VIA_GEC_DST_SYS         0x00000080
+
+#define VIA_GEC_SRC_MONO        0x00000100  /* source is mono */
+#define VIA_GEC_PAT_MONO        0x00000200  /* pattern is mono */
+
+#define VIA_GEC_MSRC_OPAQUE     0x00000000  /* mono src is opaque */
+#define VIA_GEC_MSRC_TRANS      0x00000400  /* mono src is transparent */
+
+#define VIA_GEC_PAT_FB          0x00000000  /* pattern is in frame buffer */
+#define VIA_GEC_PAT_REG         0x00000800  /* pattern is from reg setting */
+
+#define VIA_GEC_CLIP_DISABLE    0x00000000
+#define VIA_GEC_CLIP_ENABLE     0x00001000
+
+#define VIA_GEC_FIXCOLOR_PAT    0x00002000
+
+#define VIA_GEC_INCX            0x00000000
+#define VIA_GEC_DECY            0x00004000
+#define VIA_GEC_INCY            0x00000000
+#define VIA_GEC_DECX            0x00008000
+
+#define VIA_GEC_MPAT_OPAQUE     0x00000000  /* mono pattern is opaque */
+#define VIA_GEC_MPAT_TRANS      0x00010000  /* mono pattern is transparent */
+
+#define VIA_GEC_MONO_UNPACK     0x00000000
+#define VIA_GEC_MONO_PACK       0x00020000
+#define VIA_GEC_MONO_DWORD      0x00000000
+#define VIA_GEC_MONO_WORD       0x00040000
+#define VIA_GEC_MONO_BYTE       0x00080000
+
+#define VIA_GEC_LASTPIXEL_ON    0x00000000
+#define VIA_GEC_LASTPIXEL_OFF   0x00100000
+#define VIA_GEC_X_MAJOR         0x00000000
+#define VIA_GEC_Y_MAJOR         0x00200000
+#define VIA_GEC_QUICK_START     0x00800000
+
+
+/* VIA_REG_GEMODE(0x04): GE mode */
+#define VIA_GEM_8bpp            0x00000000
+#define VIA_GEM_16bpp           0x00000100
+#define VIA_GEM_32bpp           0x00000300
+
+#define VIA_GEM_640             0x00000000   /* 640*480 */
+#define VIA_GEM_800             0x00000400   /* 800*600 */
+#define VIA_GEM_1024            0x00000800   /* 1024*768 */
+#define VIA_GEM_1280            0x00000C00   /* 1280*1024 */
+#define VIA_GEM_1600            0x00001000   /* 1600*1200 */
+#define VIA_GEM_2048            0x00001400   /* 2048*1536 */
+
+/* VIA_REG_PITCH(0x38): Pitch Setting */
+#define VIA_PITCH_ENABLE        0x80000000
+
+
+#define MAXLOOP                 0xffffff
+
+
+#define VerticalRetraceWait() \
+{ \
+    VGAOUT8(vgaCRIndex, 0x17); \
+    if (VGAIN8(vgaCRReg) & 0x80) { \
+        while ((VGAIN8(vgaIOBase + 0x0a) & 0x08) == 0x00) ; \
+        while ((VGAIN8(vgaIOBase + 0x0a) & 0x08) == 0x08) ; \
+        while ((VGAIN8(vgaIOBase + 0x0a) & 0x08) == 0x00) ; \
+    } \
+}
+
+
+#define VIASETREG(addr, data)   *(volatile unsigned int *)(pVia->MapBase + (addr)) = (data)
+#define VIAGETREG(addr)         *(volatile unsigned int *)(pVia->MapBase + (addr))
+
+
+#endif /* _VIA_REGS_H_ */
diff --git a/src/mesa/drivers/dri/unichrome/via_3d_reg.h b/src/mesa/drivers/dri/unichrome/via_3d_reg.h
new file mode 100644 (file)
index 0000000..424ce28
--- /dev/null
@@ -0,0 +1,1644 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VIA_3D_REG_H
+#define VIA_3D_REG_H
+#define HC_REG_BASE             0x0400
+
+#define HC_ParaN_MASK           0xffffffff
+#define HC_Para_MASK            0x00ffffff
+#define HC_SubA_MASK            0xff000000
+#define HC_SubA_SHIFT           24
+/* Transmission Setting
+ */
+#define HC_REG_TRANS_SET        0x003c
+#define HC_ParaSubType_MASK     0xff000000
+#define HC_ParaType_MASK        0x00ff0000
+#define HC_ParaOS_MASK          0x0000ff00
+#define HC_ParaAdr_MASK         0x000000ff
+#define HC_ParaSubType_SHIFT    24
+#define HC_ParaType_SHIFT       16
+#define HC_ParaOS_SHIFT         8
+#define HC_ParaAdr_SHIFT        0
+
+#define HC_ParaType_CmdVdata    0x0000
+#define HC_ParaType_NotTex      0x0001
+#define HC_ParaType_Tex         0x0002
+#define HC_ParaType_Palette     0x0003
+#define HC_ParaType_PreCR       0x0010
+#define HC_ParaType_Auto        0x00fe
+
+/* Transmission Space
+ */
+#define HC_REG_Hpara0           0x0040          
+#define HC_REG_HpataAF          0x02fc          
+
+/* Read
+ */
+#define HC_REG_HREngSt          0x0000
+#define HC_REG_HRFIFOempty      0x0004
+#define HC_REG_HRFIFOfull       0x0008
+#define HC_REG_HRErr            0x000c
+#define HC_REG_FIFOstatus       0x0010
+/* HC_REG_HREngSt          0x0000
+ */
+#define HC_HDASZC_MASK          0x00010000
+#define HC_HSGEMI_MASK          0x0000f000
+#define HC_HLGEMISt_MASK        0x00000f00
+#define HC_HCRSt_MASK           0x00000080
+#define HC_HSE0St_MASK          0x00000040
+#define HC_HSE1St_MASK          0x00000020
+#define HC_HPESt_MASK           0x00000010
+#define HC_HXESt_MASK           0x00000008
+#define HC_HBESt_MASK           0x00000004
+#define HC_HE2St_MASK           0x00000002
+#define HC_HE3St_MASK           0x00000001
+/* HC_REG_HRFIFOempty      0x0004
+ */
+#define HC_HRZDempty_MASK       0x00000010
+#define HC_HRTXAempty_MASK      0x00000008
+#define HC_HRTXDempty_MASK      0x00000004
+#define HC_HWZDempty_MASK       0x00000002
+#define HC_HWCDempty_MASK       0x00000001
+/* HC_REG_HRFIFOfull       0x0008
+ */
+#define HC_HRZDfull_MASK        0x00000010
+#define HC_HRTXAfull_MASK       0x00000008
+#define HC_HRTXDfull_MASK       0x00000004
+#define HC_HWZDfull_MASK        0x00000002
+#define HC_HWCDfull_MASK        0x00000001
+/* HC_REG_HRErr            0x000c
+ */
+#define HC_HAGPCMErr_MASK       0x80000000
+#define HC_HAGPCMErrC_MASK      0x70000000
+/* HC_REG_FIFOstatus       0x0010
+ */
+#define HC_HRFIFOATall_MASK     0x80000000
+#define HC_HRFIFOATbusy_MASK    0x40000000
+#define HC_HRATFGMDo_MASK       0x00000100
+#define HC_HRATFGMDi_MASK       0x00000080
+#define HC_HRATFRZD_MASK        0x00000040
+#define HC_HRATFRTXA_MASK       0x00000020
+#define HC_HRATFRTXD_MASK       0x00000010
+#define HC_HRATFWZD_MASK        0x00000008
+#define HC_HRATFWCD_MASK        0x00000004
+#define HC_HRATTXTAG_MASK       0x00000002
+#define HC_HRATTXCH_MASK        0x00000001
+
+/* AGP Command Setting
+ */
+#define HC_SubA_HAGPBstL        0x0060
+#define HC_SubA_HAGPBendL       0x0061
+#define HC_SubA_HAGPCMNT        0x0062
+#define HC_SubA_HAGPBpL         0x0063
+#define HC_SubA_HAGPBpH         0x0064
+/* HC_SubA_HAGPCMNT        0x0062
+ */
+#define HC_HAGPCMNT_MASK        0x00800000
+#define HC_HCmdErrClr_MASK      0x00400000
+#define HC_HAGPBendH_MASK       0x0000ff00
+#define HC_HAGPBstH_MASK        0x000000ff
+#define HC_HAGPBendH_SHIFT      8
+#define HC_HAGPBstH_SHIFT       0
+/* HC_SubA_HAGPBpL         0x0063
+ */
+#define HC_HAGPBpL_MASK         0x00fffffc
+#define HC_HAGPBpID_MASK        0x00000003
+#define HC_HAGPBpID_PAUSE       0x00000000
+#define HC_HAGPBpID_JUMP        0x00000001
+#define HC_HAGPBpID_STOP        0x00000002
+/* HC_SubA_HAGPBpH         0x0064
+ */
+#define HC_HAGPBpH_MASK         0x00ffffff
+
+/* Miscellaneous Settings
+ */
+#define HC_SubA_HClipTB         0x0070
+#define HC_SubA_HClipLR         0x0071
+#define HC_SubA_HFPClipTL       0x0072
+#define HC_SubA_HFPClipBL       0x0073
+#define HC_SubA_HFPClipLL       0x0074
+#define HC_SubA_HFPClipRL       0x0075
+#define HC_SubA_HFPClipTBH      0x0076
+#define HC_SubA_HFPClipLRH      0x0077
+#define HC_SubA_HLP             0x0078
+#define HC_SubA_HLPRF           0x0079
+#define HC_SubA_HSolidCL        0x007a
+#define HC_SubA_HPixGC          0x007b
+#define HC_SubA_HSPXYOS         0x007c
+#define HC_SubA_HVertexCNT      0x007d
+
+#define HC_HClipT_MASK          0x00fff000
+#define HC_HClipT_SHIFT         12
+#define HC_HClipB_MASK          0x00000fff
+#define HC_HClipB_SHIFT         0
+#define HC_HClipL_MASK          0x00fff000
+#define HC_HClipL_SHIFT         12
+#define HC_HClipR_MASK          0x00000fff
+#define HC_HClipR_SHIFT         0
+#define HC_HFPClipBH_MASK       0x0000ff00
+#define HC_HFPClipBH_SHIFT      8
+#define HC_HFPClipTH_MASK       0x000000ff
+#define HC_HFPClipTH_SHIFT      0
+#define HC_HFPClipRH_MASK       0x0000ff00
+#define HC_HFPClipRH_SHIFT      8
+#define HC_HFPClipLH_MASK       0x000000ff
+#define HC_HFPClipLH_SHIFT      0
+#define HC_HSolidCH_MASK        0x000000ff
+#define HC_HPixGC_MASK          0x00800000
+#define HC_HSPXOS_MASK          0x00fff000
+#define HC_HSPXOS_SHIFT         12
+#define HC_HSPYOS_MASK          0x00000fff
+
+/* Command
+ * Command A
+ */
+#define HC_HCmdHeader_MASK      0xfe000000  /*0xffe00000*/
+#define HC_HE3Fire_MASK         0x00100000
+#define HC_HPMType_MASK         0x000f0000
+#define HC_HEFlag_MASK          0x0000e000
+#define HC_HShading_MASK        0x00001c00
+#define HC_HPMValidN_MASK       0x00000200
+#define HC_HPLEND_MASK          0x00000100
+#define HC_HVCycle_MASK         0x000000ff
+#define HC_HVCycle_Style_MASK   0x000000c0
+#define HC_HVCycle_ChgA_MASK    0x00000030
+#define HC_HVCycle_ChgB_MASK    0x0000000c
+#define HC_HVCycle_ChgC_MASK    0x00000003
+#define HC_HPMType_Point        0x00000000
+#define HC_HPMType_Line         0x00010000
+#define HC_HPMType_Tri          0x00020000
+#define HC_HPMType_TriWF        0x00040000
+#define HC_HEFlag_NoAA          0x00000000
+#define HC_HEFlag_ab            0x00008000
+#define HC_HEFlag_bc            0x00004000
+#define HC_HEFlag_ca            0x00002000
+#define HC_HShading_Solid       0x00000000
+#define HC_HShading_FlatA       0x00000400
+#define HC_HShading_FlatB       0x00000800
+#define HC_HShading_FlatC       0x00000c00
+#define HC_HShading_Gouraud     0x00001000
+#define HC_HVCycle_Full         0x00000000
+#define HC_HVCycle_AFP          0x00000040
+#define HC_HVCycle_One          0x000000c0
+#define HC_HVCycle_NewA         0x00000000
+#define HC_HVCycle_AA           0x00000010
+#define HC_HVCycle_AB           0x00000020
+#define HC_HVCycle_AC           0x00000030
+#define HC_HVCycle_NewB         0x00000000
+#define HC_HVCycle_BA           0x00000004
+#define HC_HVCycle_BB           0x00000008
+#define HC_HVCycle_BC           0x0000000c
+#define HC_HVCycle_NewC         0x00000000
+#define HC_HVCycle_CA           0x00000001
+#define HC_HVCycle_CB           0x00000002
+#define HC_HVCycle_CC           0x00000003
+
+/* Command B
+ */
+#define HC_HLPrst_MASK          0x00010000
+#define HC_HLLastP_MASK         0x00008000
+#define HC_HVPMSK_MASK          0x00007f80
+#define HC_HBFace_MASK          0x00000040
+#define HC_H2nd1VT_MASK         0x0000003f
+#define HC_HVPMSK_X             0x00004000
+#define HC_HVPMSK_Y             0x00002000
+#define HC_HVPMSK_Z             0x00001000
+#define HC_HVPMSK_W             0x00000800
+#define HC_HVPMSK_Cd            0x00000400
+#define HC_HVPMSK_Cs            0x00000200
+#define HC_HVPMSK_S             0x00000100
+#define HC_HVPMSK_T             0x00000080
+
+/* Enable Setting
+ */
+#define HC_SubA_HEnable         0x0000
+#define HC_HenTXEnvMap_MASK     0x00200000
+#define HC_HenVertexCNT_MASK    0x00100000
+#define HC_HenCPUDAZ_MASK       0x00080000
+#define HC_HenDASZWC_MASK       0x00040000
+#define HC_HenFBCull_MASK       0x00020000
+#define HC_HenCW_MASK           0x00010000
+#define HC_HenAA_MASK           0x00008000
+#define HC_HenST_MASK           0x00004000
+#define HC_HenZT_MASK           0x00002000
+#define HC_HenZW_MASK           0x00001000
+#define HC_HenAT_MASK           0x00000800
+#define HC_HenAW_MASK           0x00000400
+#define HC_HenSP_MASK           0x00000200
+#define HC_HenLP_MASK           0x00000100
+#define HC_HenTXCH_MASK         0x00000080
+#define HC_HenTXMP_MASK         0x00000040
+#define HC_HenTXPP_MASK         0x00000020
+#define HC_HenTXTR_MASK         0x00000010
+#define HC_HenCS_MASK           0x00000008
+#define HC_HenFOG_MASK          0x00000004
+#define HC_HenABL_MASK          0x00000002
+#define HC_HenDT_MASK           0x00000001
+
+/* Z Setting
+ */
+#define HC_SubA_HZWBBasL        0x0010
+#define HC_SubA_HZWBBasH        0x0011
+#define HC_SubA_HZWBType        0x0012
+#define HC_SubA_HZBiasL         0x0013
+#define HC_SubA_HZWBend         0x0014
+#define HC_SubA_HZWTMD          0x0015
+#define HC_SubA_HZWCDL          0x0016
+#define HC_SubA_HZWCTAGnum      0x0017
+#define HC_SubA_HZCYNum         0x0018
+#define HC_SubA_HZWCFire        0x0019
+/* HC_SubA_HZWBType
+ */
+#define HC_HZWBType_MASK        0x00800000
+#define HC_HZBiasedWB_MASK      0x00400000
+#define HC_HZONEasFF_MASK       0x00200000
+#define HC_HZOONEasFF_MASK      0x00100000
+#define HC_HZWBFM_MASK          0x00030000
+#define HC_HZWBLoc_MASK         0x0000c000
+#define HC_HZWBPit_MASK         0x00003fff
+#define HC_HZWBFM_16            0x00000000
+#define HC_HZWBFM_32            0x00020000
+#define HC_HZWBFM_24            0x00030000
+#define HC_HZWBLoc_Local        0x00000000
+#define HC_HZWBLoc_SyS          0x00004000
+/* HC_SubA_HZWBend
+ */
+#define HC_HZWBend_MASK         0x00ffe000
+#define HC_HZBiasH_MASK         0x000000ff
+#define HC_HZWBend_SHIFT        10
+/* HC_SubA_HZWTMD
+ */
+#define HC_HZWTMD_MASK          0x00070000
+#define HC_HEBEBias_MASK        0x00007f00
+#define HC_HZNF_MASK            0x000000ff
+#define HC_HZWTMD_NeverPass     0x00000000
+#define HC_HZWTMD_LT            0x00010000
+#define HC_HZWTMD_EQ            0x00020000
+#define HC_HZWTMD_LE            0x00030000
+#define HC_HZWTMD_GT            0x00040000
+#define HC_HZWTMD_NE            0x00050000
+#define HC_HZWTMD_GE            0x00060000
+#define HC_HZWTMD_AllPass       0x00070000
+#define HC_HEBEBias_SHIFT       8
+/* HC_SubA_HZWCDL          0x0016 
+ */
+#define HC_HZWCDL_MASK          0x00ffffff
+/* HC_SubA_HZWCTAGnum      0x0017 
+ */
+#define HC_HZWCTAGnum_MASK      0x00ff0000
+#define HC_HZWCTAGnum_SHIFT     16
+#define HC_HZWCDH_MASK          0x000000ff
+#define HC_HZWCDH_SHIFT         0
+/* HC_SubA_HZCYNum         0x0018
+ */
+#define HC_HZCYNum_MASK         0x00030000
+#define HC_HZCYNum_SHIFT        16
+#define HC_HZWCQWnum_MASK       0x00003fff
+#define HC_HZWCQWnum_SHIFT      0
+/* HC_SubA_HZWCFire        0x0019
+ */
+#define HC_ZWCFire_MASK         0x00010000
+#define HC_HZWCQWnumLast_MASK   0x00003fff
+#define HC_HZWCQWnumLast_SHIFT  0
+
+/* Stencil Setting
+ */
+#define HC_SubA_HSTREF          0x0023
+#define HC_SubA_HSTMD           0x0024
+/* HC_SubA_HSBFM
+ */
+#define HC_HSBFM_MASK           0x00030000
+#define HC_HSBLoc_MASK          0x0000c000
+#define HC_HSBPit_MASK          0x00003fff
+/* HC_SubA_HSTREF
+ */
+#define HC_HSTREF_MASK          0x00ff0000
+#define HC_HSTOPMSK_MASK        0x0000ff00
+#define HC_HSTBMSK_MASK         0x000000ff
+#define HC_HSTREF_SHIFT         16
+#define HC_HSTOPMSK_SHIFT       8
+/* HC_SubA_HSTMD
+ */
+#define HC_HSTMD_MASK           0x00070000
+#define HC_HSTOPSF_MASK         0x000001c0
+#define HC_HSTOPSPZF_MASK       0x00000038
+#define HC_HSTOPSPZP_MASK       0x00000007
+#define HC_HSTMD_NeverPass      0x00000000
+#define HC_HSTMD_LT             0x00010000
+#define HC_HSTMD_EQ             0x00020000
+#define HC_HSTMD_LE             0x00030000
+#define HC_HSTMD_GT             0x00040000
+#define HC_HSTMD_NE             0x00050000
+#define HC_HSTMD_GE             0x00060000
+#define HC_HSTMD_AllPass        0x00070000
+#define HC_HSTOPSF_KEEP         0x00000000
+#define HC_HSTOPSF_ZERO         0x00000040
+#define HC_HSTOPSF_REPLACE      0x00000080
+#define HC_HSTOPSF_INCRSAT      0x000000c0
+#define HC_HSTOPSF_DECRSAT      0x00000100
+#define HC_HSTOPSF_INVERT       0x00000140
+#define HC_HSTOPSF_INCR         0x00000180
+#define HC_HSTOPSF_DECR         0x000001c0
+#define HC_HSTOPSPZF_KEEP       0x00000000
+#define HC_HSTOPSPZF_ZERO       0x00000008
+#define HC_HSTOPSPZF_REPLACE    0x00000010
+#define HC_HSTOPSPZF_INCRSAT    0x00000018
+#define HC_HSTOPSPZF_DECRSAT    0x00000020
+#define HC_HSTOPSPZF_INVERT     0x00000028
+#define HC_HSTOPSPZF_INCR       0x00000030
+#define HC_HSTOPSPZF_DECR       0x00000038
+#define HC_HSTOPSPZP_KEEP       0x00000000
+#define HC_HSTOPSPZP_ZERO       0x00000001
+#define HC_HSTOPSPZP_REPLACE    0x00000002
+#define HC_HSTOPSPZP_INCRSAT    0x00000003
+#define HC_HSTOPSPZP_DECRSAT    0x00000004
+#define HC_HSTOPSPZP_INVERT     0x00000005
+#define HC_HSTOPSPZP_INCR       0x00000006
+#define HC_HSTOPSPZP_DECR       0x00000007
+
+/* Alpha Setting
+ */
+#define HC_SubA_HABBasL         0x0030
+#define HC_SubA_HABBasH         0x0031
+#define HC_SubA_HABFM           0x0032
+#define HC_SubA_HATMD           0x0033
+#define HC_SubA_HABLCsat        0x0034
+#define HC_SubA_HABLCop         0x0035
+#define HC_SubA_HABLAsat        0x0036
+#define HC_SubA_HABLAop         0x0037
+#define HC_SubA_HABLRCa         0x0038
+#define HC_SubA_HABLRFCa        0x0039
+#define HC_SubA_HABLRCbias      0x003a
+#define HC_SubA_HABLRCb         0x003b
+#define HC_SubA_HABLRFCb        0x003c
+#define HC_SubA_HABLRAa         0x003d
+#define HC_SubA_HABLRAb         0x003e
+/* HC_SubA_HABFM
+ */
+#define HC_HABFM_MASK           0x00030000
+#define HC_HABLoc_MASK          0x0000c000
+#define HC_HABPit_MASK          0x000007ff
+/* HC_SubA_HATMD
+ */
+#define HC_HATMD_MASK           0x00000700
+#define HC_HATREF_MASK          0x000000ff
+#define HC_HATMD_NeverPass      0x00000000
+#define HC_HATMD_LT             0x00000100
+#define HC_HATMD_EQ             0x00000200
+#define HC_HATMD_LE             0x00000300
+#define HC_HATMD_GT             0x00000400
+#define HC_HATMD_NE             0x00000500
+#define HC_HATMD_GE             0x00000600
+#define HC_HATMD_AllPass        0x00000700
+/* HC_SubA_HABLCsat
+ */
+#define HC_HABLCsat_MASK        0x00010000
+#define HC_HABLCa_MASK          0x0000fc00
+#define HC_HABLCa_C_MASK        0x0000c000
+#define HC_HABLCa_OPC_MASK      0x00003c00
+#define HC_HABLFCa_MASK         0x000003f0
+#define HC_HABLFCa_C_MASK       0x00000300
+#define HC_HABLFCa_OPC_MASK     0x000000f0
+#define HC_HABLCbias_MASK       0x0000000f
+#define HC_HABLCbias_C_MASK     0x00000008
+#define HC_HABLCbias_OPC_MASK   0x00000007
+/*-- Define the input color.
+ */
+#define HC_XC_Csrc              0x00000000
+#define HC_XC_Cdst              0x00000001
+#define HC_XC_Asrc              0x00000002
+#define HC_XC_Adst              0x00000003
+#define HC_XC_Fog               0x00000004
+#define HC_XC_HABLRC            0x00000005
+#define HC_XC_minSrcDst         0x00000006
+#define HC_XC_maxSrcDst         0x00000007
+#define HC_XC_mimAsrcInvAdst    0x00000008
+#define HC_XC_OPC               0x00000000
+#define HC_XC_InvOPC            0x00000010
+#define HC_XC_OPCp5             0x00000020
+/*-- Define the input Alpha
+ */
+#define HC_XA_OPA               0x00000000
+#define HC_XA_InvOPA            0x00000010
+#define HC_XA_OPAp5             0x00000020
+#define HC_XA_0                 0x00000000
+#define HC_XA_Asrc              0x00000001
+#define HC_XA_Adst              0x00000002
+#define HC_XA_Fog               0x00000003
+#define HC_XA_minAsrcFog        0x00000004
+#define HC_XA_minAsrcAdst       0x00000005
+#define HC_XA_maxAsrcFog        0x00000006
+#define HC_XA_maxAsrcAdst       0x00000007
+#define HC_XA_HABLRA            0x00000008
+#define HC_XA_minAsrcInvAdst    0x00000008
+#define HC_XA_HABLFRA           0x00000009
+/*--
+ */
+#define HC_HABLCa_OPC           (HC_XC_OPC << 10)
+#define HC_HABLCa_InvOPC        (HC_XC_InvOPC << 10)
+#define HC_HABLCa_OPCp5         (HC_XC_OPCp5 << 10)
+#define HC_HABLCa_Csrc          (HC_XC_Csrc << 10)
+#define HC_HABLCa_Cdst          (HC_XC_Cdst << 10)
+#define HC_HABLCa_Asrc          (HC_XC_Asrc << 10)
+#define HC_HABLCa_Adst          (HC_XC_Adst << 10)
+#define HC_HABLCa_Fog           (HC_XC_Fog << 10)
+#define HC_HABLCa_HABLRCa       (HC_XC_HABLRC << 10)
+#define HC_HABLCa_minSrcDst     (HC_XC_minSrcDst << 10)
+#define HC_HABLCa_maxSrcDst     (HC_XC_maxSrcDst << 10)
+#define HC_HABLFCa_OPC              (HC_XC_OPC << 4)
+#define HC_HABLFCa_InvOPC           (HC_XC_InvOPC << 4)
+#define HC_HABLFCa_OPCp5            (HC_XC_OPCp5 << 4)
+#define HC_HABLFCa_Csrc             (HC_XC_Csrc << 4)
+#define HC_HABLFCa_Cdst             (HC_XC_Cdst << 4)
+#define HC_HABLFCa_Asrc             (HC_XC_Asrc << 4)
+#define HC_HABLFCa_Adst             (HC_XC_Adst << 4)
+#define HC_HABLFCa_Fog              (HC_XC_Fog << 4)
+#define HC_HABLFCa_HABLRCa          (HC_XC_HABLRC << 4)
+#define HC_HABLFCa_minSrcDst        (HC_XC_minSrcDst << 4)
+#define HC_HABLFCa_maxSrcDst        (HC_XC_maxSrcDst << 4)
+#define HC_HABLFCa_mimAsrcInvAdst   (HC_XC_mimAsrcInvAdst << 4)
+#define HC_HABLCbias_HABLRCbias 0x00000000
+#define HC_HABLCbias_Asrc       0x00000001
+#define HC_HABLCbias_Adst       0x00000002
+#define HC_HABLCbias_Fog        0x00000003
+#define HC_HABLCbias_Cin        0x00000004
+/* HC_SubA_HABLCop         0x0035
+ */
+#define HC_HABLdot_MASK         0x00010000
+#define HC_HABLCop_MASK         0x00004000
+#define HC_HABLCb_MASK          0x00003f00
+#define HC_HABLCb_C_MASK        0x00003000
+#define HC_HABLCb_OPC_MASK      0x00000f00
+#define HC_HABLFCb_MASK         0x000000fc
+#define HC_HABLFCb_C_MASK       0x000000c0
+#define HC_HABLFCb_OPC_MASK     0x0000003c
+#define HC_HABLCshift_MASK      0x00000003
+#define HC_HABLCb_OPC           (HC_XC_OPC << 8)
+#define HC_HABLCb_InvOPC        (HC_XC_InvOPC << 8)
+#define HC_HABLCb_OPCp5         (HC_XC_OPCp5 << 8)
+#define HC_HABLCb_Csrc          (HC_XC_Csrc << 8)
+#define HC_HABLCb_Cdst          (HC_XC_Cdst << 8)
+#define HC_HABLCb_Asrc          (HC_XC_Asrc << 8)
+#define HC_HABLCb_Adst          (HC_XC_Adst << 8)
+#define HC_HABLCb_Fog           (HC_XC_Fog << 8)
+#define HC_HABLCb_HABLRCa       (HC_XC_HABLRC << 8)
+#define HC_HABLCb_minSrcDst     (HC_XC_minSrcDst << 8)
+#define HC_HABLCb_maxSrcDst     (HC_XC_maxSrcDst << 8)
+#define HC_HABLFCb_OPC              (HC_XC_OPC << 2)
+#define HC_HABLFCb_InvOPC           (HC_XC_InvOPC << 2)
+#define HC_HABLFCb_OPCp5            (HC_XC_OPCp5 << 2)
+#define HC_HABLFCb_Csrc             (HC_XC_Csrc << 2)
+#define HC_HABLFCb_Cdst             (HC_XC_Cdst << 2)
+#define HC_HABLFCb_Asrc             (HC_XC_Asrc << 2)
+#define HC_HABLFCb_Adst             (HC_XC_Adst << 2)
+#define HC_HABLFCb_Fog              (HC_XC_Fog << 2)
+#define HC_HABLFCb_HABLRCb          (HC_XC_HABLRC << 2)
+#define HC_HABLFCb_minSrcDst        (HC_XC_minSrcDst << 2)
+#define HC_HABLFCb_maxSrcDst        (HC_XC_maxSrcDst << 2)
+#define HC_HABLFCb_mimAsrcInvAdst   (HC_XC_mimAsrcInvAdst << 2)
+/* HC_SubA_HABLAsat        0x0036
+ */
+#define HC_HABLAsat_MASK        0x00010000
+#define HC_HABLAa_MASK          0x0000fc00
+#define HC_HABLAa_A_MASK        0x0000c000
+#define HC_HABLAa_OPA_MASK      0x00003c00
+#define HC_HABLFAa_MASK         0x000003f0
+#define HC_HABLFAa_A_MASK       0x00000300
+#define HC_HABLFAa_OPA_MASK     0x000000f0
+#define HC_HABLAbias_MASK       0x0000000f
+#define HC_HABLAbias_A_MASK     0x00000008
+#define HC_HABLAbias_OPA_MASK   0x00000007
+#define HC_HABLAa_OPA           (HC_XA_OPA << 10)
+#define HC_HABLAa_InvOPA        (HC_XA_InvOPA << 10)
+#define HC_HABLAa_OPAp5         (HC_XA_OPAp5 << 10)
+#define HC_HABLAa_0             (HC_XA_0 << 10)
+#define HC_HABLAa_Asrc          (HC_XA_Asrc << 10)
+#define HC_HABLAa_Adst          (HC_XA_Adst << 10)
+#define HC_HABLAa_Fog           (HC_XA_Fog << 10)
+#define HC_HABLAa_minAsrcFog    (HC_XA_minAsrcFog << 10)
+#define HC_HABLAa_minAsrcAdst   (HC_XA_minAsrcAdst << 10)
+#define HC_HABLAa_maxAsrcFog    (HC_XA_maxAsrcFog << 10)
+#define HC_HABLAa_maxAsrcAdst   (HC_XA_maxAsrcAdst << 10)
+#define HC_HABLAa_HABLRA        (HC_XA_HABLRA << 10)
+#define HC_HABLFAa_OPA          (HC_XA_OPA << 4)
+#define HC_HABLFAa_InvOPA       (HC_XA_InvOPA << 4)
+#define HC_HABLFAa_OPAp5        (HC_XA_OPAp5 << 4)
+#define HC_HABLFAa_0            (HC_XA_0 << 4)
+#define HC_HABLFAa_Asrc         (HC_XA_Asrc << 4)
+#define HC_HABLFAa_Adst         (HC_XA_Adst << 4)
+#define HC_HABLFAa_Fog          (HC_XA_Fog << 4)
+#define HC_HABLFAa_minAsrcFog   (HC_XA_minAsrcFog << 4)
+#define HC_HABLFAa_minAsrcAdst  (HC_XA_minAsrcAdst << 4)
+#define HC_HABLFAa_maxAsrcFog   (HC_XA_maxAsrcFog << 4)
+#define HC_HABLFAa_maxAsrcAdst  (HC_XA_maxAsrcAdst << 4)
+#define HC_HABLFAa_minAsrcInvAdst   (HC_XA_minAsrcInvAdst << 4)
+#define HC_HABLFAa_HABLFRA          (HC_XA_HABLFRA << 4)
+#define HC_HABLAbias_HABLRAbias 0x00000000
+#define HC_HABLAbias_Asrc       0x00000001
+#define HC_HABLAbias_Adst       0x00000002
+#define HC_HABLAbias_Fog        0x00000003
+#define HC_HABLAbias_Aaa        0x00000004
+/* HC_SubA_HABLAop         0x0037
+ */
+#define HC_HABLAop_MASK         0x00004000
+#define HC_HABLAb_MASK          0x00003f00
+#define HC_HABLAb_OPA_MASK      0x00000f00
+#define HC_HABLFAb_MASK         0x000000fc
+#define HC_HABLFAb_OPA_MASK     0x0000003c
+#define HC_HABLAshift_MASK      0x00000003
+#define HC_HABLAb_OPA           (HC_XA_OPA << 8)
+#define HC_HABLAb_InvOPA        (HC_XA_InvOPA << 8)
+#define HC_HABLAb_OPAp5         (HC_XA_OPAp5 << 8)
+#define HC_HABLAb_0             (HC_XA_0 << 8)
+#define HC_HABLAb_Asrc          (HC_XA_Asrc << 8)
+#define HC_HABLAb_Adst          (HC_XA_Adst << 8)
+#define HC_HABLAb_Fog           (HC_XA_Fog << 8)
+#define HC_HABLAb_minAsrcFog    (HC_XA_minAsrcFog << 8)
+#define HC_HABLAb_minAsrcAdst   (HC_XA_minAsrcAdst << 8)
+#define HC_HABLAb_maxAsrcFog    (HC_XA_maxAsrcFog << 8)
+#define HC_HABLAb_maxAsrcAdst   (HC_XA_maxAsrcAdst << 8)
+#define HC_HABLAb_HABLRA        (HC_XA_HABLRA << 8)
+#define HC_HABLFAb_OPA          (HC_XA_OPA << 2)
+#define HC_HABLFAb_InvOPA       (HC_XA_InvOPA << 2)
+#define HC_HABLFAb_OPAp5        (HC_XA_OPAp5 << 2)
+#define HC_HABLFAb_0            (HC_XA_0 << 2)
+#define HC_HABLFAb_Asrc         (HC_XA_Asrc << 2)
+#define HC_HABLFAb_Adst         (HC_XA_Adst << 2)
+#define HC_HABLFAb_Fog          (HC_XA_Fog << 2)
+#define HC_HABLFAb_minAsrcFog   (HC_XA_minAsrcFog << 2)
+#define HC_HABLFAb_minAsrcAdst  (HC_XA_minAsrcAdst << 2)
+#define HC_HABLFAb_maxAsrcFog   (HC_XA_maxAsrcFog << 2)
+#define HC_HABLFAb_maxAsrcAdst  (HC_XA_maxAsrcAdst << 2)
+#define HC_HABLFAb_minAsrcInvAdst   (HC_XA_minAsrcInvAdst << 2)
+#define HC_HABLFAb_HABLFRA          (HC_XA_HABLFRA << 2)
+/* HC_SubA_HABLRAa         0x003d
+ */
+#define HC_HABLRAa_MASK         0x00ff0000
+#define HC_HABLRFAa_MASK        0x0000ff00
+#define HC_HABLRAbias_MASK      0x000000ff
+#define HC_HABLRAa_SHIFT        16
+#define HC_HABLRFAa_SHIFT       8
+/* HC_SubA_HABLRAb         0x003e
+ */
+#define HC_HABLRAb_MASK         0x0000ff00
+#define HC_HABLRFAb_MASK        0x000000ff
+#define HC_HABLRAb_SHIFT        8
+
+/* Destination Setting
+ */
+#define HC_SubA_HDBBasL         0x0040
+#define HC_SubA_HDBBasH         0x0041
+#define HC_SubA_HDBFM           0x0042
+#define HC_SubA_HFBBMSKL        0x0043
+#define HC_SubA_HROP            0x0044
+/* HC_SubA_HDBFM           0x0042
+ */
+#define HC_HDBFM_MASK           0x001f0000
+#define HC_HDBLoc_MASK          0x0000c000
+#define HC_HDBPit_MASK          0x00003fff
+#define HC_HDBFM_RGB555         0x00000000
+#define HC_HDBFM_RGB565         0x00010000
+#define HC_HDBFM_ARGB4444       0x00020000
+#define HC_HDBFM_ARGB1555       0x00030000
+#define HC_HDBFM_BGR555         0x00040000
+#define HC_HDBFM_BGR565         0x00050000
+#define HC_HDBFM_ABGR4444       0x00060000
+#define HC_HDBFM_ABGR1555       0x00070000
+#define HC_HDBFM_ARGB0888       0x00080000
+#define HC_HDBFM_ARGB8888       0x00090000
+#define HC_HDBFM_ABGR0888       0x000a0000
+#define HC_HDBFM_ABGR8888       0x000b0000
+#define HC_HDBLoc_Local         0x00000000
+#define HC_HDBLoc_Sys           0x00004000
+/* HC_SubA_HROP            0x0044
+ */
+#define HC_HROP_MASK            0x00000f00
+#define HC_HFBBMSKH_MASK        0x000000ff
+#define HC_HROP_BLACK           0x00000000
+#define HC_HROP_DPon            0x00000100
+#define HC_HROP_DPna            0x00000200
+#define HC_HROP_Pn              0x00000300
+#define HC_HROP_PDna            0x00000400
+#define HC_HROP_Dn              0x00000500
+#define HC_HROP_DPx             0x00000600
+#define HC_HROP_DPan            0x00000700
+#define HC_HROP_DPa             0x00000800
+#define HC_HROP_DPxn            0x00000900
+#define HC_HROP_D               0x00000a00
+#define HC_HROP_DPno            0x00000b00
+#define HC_HROP_P               0x00000c00
+#define HC_HROP_PDno            0x00000d00
+#define HC_HROP_DPo             0x00000e00
+#define HC_HROP_WHITE           0x00000f00
+
+/* Fog Setting
+ */
+#define HC_SubA_HFogLF          0x0050
+#define HC_SubA_HFogCL          0x0051
+#define HC_SubA_HFogCH          0x0052
+#define HC_SubA_HFogStL         0x0053
+#define HC_SubA_HFogStH         0x0054
+#define HC_SubA_HFogOOdMF       0x0055
+#define HC_SubA_HFogOOdEF       0x0056
+#define HC_SubA_HFogEndL        0x0057
+#define HC_SubA_HFogDenst       0x0058
+/* HC_SubA_FogLF           0x0050
+ */
+#define HC_FogLF_MASK           0x00000010
+#define HC_FogEq_MASK           0x00000008
+#define HC_FogMD_MASK           0x00000007
+#define HC_FogMD_LocalFog        0x00000000
+#define HC_FogMD_LinearFog       0x00000002
+#define HC_FogMD_ExponentialFog  0x00000004
+#define HC_FogMD_Exponential2Fog 0x00000005
+/* #define HC_FogMD_FogTable       0x00000003 */
+
+/* HC_SubA_HFogDenst        0x0058
+ */
+#define HC_FogDenst_MASK        0x001fff00
+#define HC_FogEndL_MASK         0x000000ff
+
+/* Texture subtype definitions
+ */
+#define HC_SubType_Tex0         0x00000000
+#define HC_SubType_Tex1         0x00000001
+#define HC_SubType_TexGeneral   0x000000fe
+
+/* Attribute of texture n
+ */
+#define HC_SubA_HTXnL0BasL      0x0000
+#define HC_SubA_HTXnL1BasL      0x0001
+#define HC_SubA_HTXnL2BasL      0x0002
+#define HC_SubA_HTXnL3BasL      0x0003
+#define HC_SubA_HTXnL4BasL      0x0004
+#define HC_SubA_HTXnL5BasL      0x0005
+#define HC_SubA_HTXnL6BasL      0x0006
+#define HC_SubA_HTXnL7BasL      0x0007
+#define HC_SubA_HTXnL8BasL      0x0008
+#define HC_SubA_HTXnL9BasL      0x0009
+#define HC_SubA_HTXnLaBasL      0x000a
+#define HC_SubA_HTXnLbBasL      0x000b
+#define HC_SubA_HTXnLcBasL      0x000c
+#define HC_SubA_HTXnLdBasL      0x000d
+#define HC_SubA_HTXnLeBasL      0x000e
+#define HC_SubA_HTXnLfBasL      0x000f
+#define HC_SubA_HTXnL10BasL     0x0010
+#define HC_SubA_HTXnL11BasL     0x0011
+#define HC_SubA_HTXnL012BasH    0x0020
+#define HC_SubA_HTXnL345BasH    0x0021
+#define HC_SubA_HTXnL678BasH    0x0022
+#define HC_SubA_HTXnL9abBasH    0x0023
+#define HC_SubA_HTXnLcdeBasH    0x0024
+#define HC_SubA_HTXnLf1011BasH  0x0025
+#define HC_SubA_HTXnL0Pit       0x002b
+#define HC_SubA_HTXnL1Pit       0x002c
+#define HC_SubA_HTXnL2Pit       0x002d
+#define HC_SubA_HTXnL3Pit       0x002e
+#define HC_SubA_HTXnL4Pit       0x002f
+#define HC_SubA_HTXnL5Pit       0x0030
+#define HC_SubA_HTXnL6Pit       0x0031
+#define HC_SubA_HTXnL7Pit       0x0032
+#define HC_SubA_HTXnL8Pit       0x0033
+#define HC_SubA_HTXnL9Pit       0x0034
+#define HC_SubA_HTXnLaPit       0x0035
+#define HC_SubA_HTXnLbPit       0x0036
+#define HC_SubA_HTXnLcPit       0x0037
+#define HC_SubA_HTXnLdPit       0x0038
+#define HC_SubA_HTXnLePit       0x0039
+#define HC_SubA_HTXnLfPit       0x003a
+#define HC_SubA_HTXnL10Pit      0x003b
+#define HC_SubA_HTXnL11Pit      0x003c
+#define HC_SubA_HTXnL0_5WE      0x004b
+#define HC_SubA_HTXnL6_bWE      0x004c
+#define HC_SubA_HTXnLc_11WE     0x004d
+#define HC_SubA_HTXnL0_5HE      0x0051
+#define HC_SubA_HTXnL6_bHE      0x0052
+#define HC_SubA_HTXnLc_11HE     0x0053
+#define HC_SubA_HTXnL0OS        0x0077
+#define HC_SubA_HTXnTB          0x0078
+#define HC_SubA_HTXnMPMD        0x0079
+#define HC_SubA_HTXnCLODu       0x007a
+#define HC_SubA_HTXnFM          0x007b
+#define HC_SubA_HTXnTRCH        0x007c
+#define HC_SubA_HTXnTRCL        0x007d
+#define HC_SubA_HTXnTBC         0x007e
+#define HC_SubA_HTXnTRAH        0x007f
+#define HC_SubA_HTXnTBLCsat     0x0080
+#define HC_SubA_HTXnTBLCop      0x0081
+#define HC_SubA_HTXnTBLMPfog    0x0082
+#define HC_SubA_HTXnTBLAsat     0x0083
+#define HC_SubA_HTXnTBLRCa      0x0085
+#define HC_SubA_HTXnTBLRCb      0x0086
+#define HC_SubA_HTXnTBLRCc      0x0087
+#define HC_SubA_HTXnTBLRCbias   0x0088
+#define HC_SubA_HTXnTBLRAa      0x0089
+#define HC_SubA_HTXnTBLRFog     0x008a
+#define HC_SubA_HTXnBumpM00     0x0090
+#define HC_SubA_HTXnBumpM01     0x0091
+#define HC_SubA_HTXnBumpM10     0x0092
+#define HC_SubA_HTXnBumpM11     0x0093
+#define HC_SubA_HTXnLScale      0x0094
+#define HC_SubA_HTXSMD          0x0000
+/* HC_SubA_HTXnL012BasH    0x0020
+ */
+#define HC_HTXnL0BasH_MASK      0x000000ff
+#define HC_HTXnL1BasH_MASK      0x0000ff00
+#define HC_HTXnL2BasH_MASK      0x00ff0000
+#define HC_HTXnL1BasH_SHIFT     8
+#define HC_HTXnL2BasH_SHIFT     16
+/* HC_SubA_HTXnL345BasH    0x0021
+ */
+#define HC_HTXnL3BasH_MASK      0x000000ff
+#define HC_HTXnL4BasH_MASK      0x0000ff00
+#define HC_HTXnL5BasH_MASK      0x00ff0000
+#define HC_HTXnL4BasH_SHIFT     8
+#define HC_HTXnL5BasH_SHIFT     16
+/* HC_SubA_HTXnL678BasH    0x0022
+ */
+#define HC_HTXnL6BasH_MASK      0x000000ff
+#define HC_HTXnL7BasH_MASK      0x0000ff00
+#define HC_HTXnL8BasH_MASK      0x00ff0000
+#define HC_HTXnL7BasH_SHIFT     8
+#define HC_HTXnL8BasH_SHIFT     16
+/* HC_SubA_HTXnL9abBasH    0x0023
+ */
+#define HC_HTXnL9BasH_MASK      0x000000ff
+#define HC_HTXnLaBasH_MASK      0x0000ff00
+#define HC_HTXnLbBasH_MASK      0x00ff0000
+#define HC_HTXnLaBasH_SHIFT     8
+#define HC_HTXnLbBasH_SHIFT     16
+/* HC_SubA_HTXnLcdeBasH    0x0024
+ */
+#define HC_HTXnLcBasH_MASK      0x000000ff
+#define HC_HTXnLdBasH_MASK      0x0000ff00
+#define HC_HTXnLeBasH_MASK      0x00ff0000
+#define HC_HTXnLdBasH_SHIFT     8
+#define HC_HTXnLeBasH_SHIFT     16
+/* HC_SubA_HTXnLcdeBasH    0x0025
+ */
+#define HC_HTXnLfBasH_MASK      0x000000ff
+#define HC_HTXnL10BasH_MASK      0x0000ff00
+#define HC_HTXnL11BasH_MASK      0x00ff0000
+#define HC_HTXnL10BasH_SHIFT     8
+#define HC_HTXnL11BasH_SHIFT     16
+/* HC_SubA_HTXnL0Pit       0x002b
+ */
+#define HC_HTXnLnPit_MASK       0x00003fff
+#define HC_HTXnEnPit_MASK       0x00080000
+#define HC_HTXnLnPitE_MASK      0x00f00000
+#define HC_HTXnLnPitE_SHIFT     20
+/* HC_SubA_HTXnL0_5WE      0x004b
+ */
+#define HC_HTXnL0WE_MASK        0x0000000f
+#define HC_HTXnL1WE_MASK        0x000000f0
+#define HC_HTXnL2WE_MASK        0x00000f00
+#define HC_HTXnL3WE_MASK        0x0000f000
+#define HC_HTXnL4WE_MASK        0x000f0000
+#define HC_HTXnL5WE_MASK        0x00f00000
+#define HC_HTXnL1WE_SHIFT       4
+#define HC_HTXnL2WE_SHIFT       8
+#define HC_HTXnL3WE_SHIFT       12
+#define HC_HTXnL4WE_SHIFT       16
+#define HC_HTXnL5WE_SHIFT       20
+/* HC_SubA_HTXnL6_bWE      0x004c
+ */
+#define HC_HTXnL6WE_MASK        0x0000000f
+#define HC_HTXnL7WE_MASK        0x000000f0
+#define HC_HTXnL8WE_MASK        0x00000f00
+#define HC_HTXnL9WE_MASK        0x0000f000
+#define HC_HTXnLaWE_MASK        0x000f0000
+#define HC_HTXnLbWE_MASK        0x00f00000
+#define HC_HTXnL7WE_SHIFT       4
+#define HC_HTXnL8WE_SHIFT       8
+#define HC_HTXnL9WE_SHIFT       12
+#define HC_HTXnLaWE_SHIFT       16
+#define HC_HTXnLbWE_SHIFT       20
+/* HC_SubA_HTXnLc_11WE      0x004d
+ */
+#define HC_HTXnLcWE_MASK        0x0000000f
+#define HC_HTXnLdWE_MASK        0x000000f0
+#define HC_HTXnLeWE_MASK        0x00000f00
+#define HC_HTXnLfWE_MASK        0x0000f000
+#define HC_HTXnL10WE_MASK       0x000f0000
+#define HC_HTXnL11WE_MASK       0x00f00000
+#define HC_HTXnLdWE_SHIFT       4
+#define HC_HTXnLeWE_SHIFT       8
+#define HC_HTXnLfWE_SHIFT       12
+#define HC_HTXnL10WE_SHIFT      16
+#define HC_HTXnL11WE_SHIFT      20
+/* HC_SubA_HTXnL0_5HE      0x0051
+ */
+#define HC_HTXnL0HE_MASK        0x0000000f
+#define HC_HTXnL1HE_MASK        0x000000f0
+#define HC_HTXnL2HE_MASK        0x00000f00
+#define HC_HTXnL3HE_MASK        0x0000f000
+#define HC_HTXnL4HE_MASK        0x000f0000
+#define HC_HTXnL5HE_MASK        0x00f00000
+#define HC_HTXnL1HE_SHIFT       4
+#define HC_HTXnL2HE_SHIFT       8
+#define HC_HTXnL3HE_SHIFT       12
+#define HC_HTXnL4HE_SHIFT       16
+#define HC_HTXnL5HE_SHIFT       20
+/* HC_SubA_HTXnL6_bHE      0x0052
+ */
+#define HC_HTXnL6HE_MASK        0x0000000f
+#define HC_HTXnL7HE_MASK        0x000000f0
+#define HC_HTXnL8HE_MASK        0x00000f00
+#define HC_HTXnL9HE_MASK        0x0000f000
+#define HC_HTXnLaHE_MASK        0x000f0000
+#define HC_HTXnLbHE_MASK        0x00f00000
+#define HC_HTXnL7HE_SHIFT       4
+#define HC_HTXnL8HE_SHIFT       8
+#define HC_HTXnL9HE_SHIFT       12
+#define HC_HTXnLaHE_SHIFT       16
+#define HC_HTXnLbHE_SHIFT       20
+/* HC_SubA_HTXnLc_11HE      0x0053
+ */
+#define HC_HTXnLcHE_MASK        0x0000000f
+#define HC_HTXnLdHE_MASK        0x000000f0
+#define HC_HTXnLeHE_MASK        0x00000f00
+#define HC_HTXnLfHE_MASK        0x0000f000
+#define HC_HTXnL10HE_MASK       0x000f0000
+#define HC_HTXnL11HE_MASK       0x00f00000
+#define HC_HTXnLdHE_SHIFT       4
+#define HC_HTXnLeHE_SHIFT       8
+#define HC_HTXnLfHE_SHIFT       12
+#define HC_HTXnL10HE_SHIFT      16
+#define HC_HTXnL11HE_SHIFT      20
+/* HC_SubA_HTXnL0OS        0x0077
+ */
+#define HC_HTXnL0OS_MASK        0x003ff000
+#define HC_HTXnLVmax_MASK       0x00000fc0
+#define HC_HTXnLVmin_MASK       0x0000003f
+#define HC_HTXnL0OS_SHIFT       12
+#define HC_HTXnLVmax_SHIFT      6
+/* HC_SubA_HTXnTB          0x0078
+ */
+#define HC_HTXnTB_MASK          0x00f00000
+#define HC_HTXnFLSe_MASK        0x0000e000
+#define HC_HTXnFLSs_MASK        0x00001c00
+#define HC_HTXnFLTe_MASK        0x00000380
+#define HC_HTXnFLTs_MASK        0x00000070
+#define HC_HTXnFLDs_MASK        0x0000000f
+#define HC_HTXnTB_NoTB          0x00000000
+#define HC_HTXnTB_TBC_S         0x00100000
+#define HC_HTXnTB_TBC_T         0x00200000
+#define HC_HTXnTB_TB_S          0x00400000
+#define HC_HTXnTB_TB_T          0x00800000
+#define HC_HTXnFLSe_Nearest     0x00000000
+#define HC_HTXnFLSe_Linear      0x00002000
+#define HC_HTXnFLSe_NonLinear   0x00004000
+#define HC_HTXnFLSe_Sharp       0x00008000
+#define HC_HTXnFLSe_Flat_Gaussian_Cubic 0x0000c000
+#define HC_HTXnFLSs_Nearest     0x00000000
+#define HC_HTXnFLSs_Linear      0x00000400
+#define HC_HTXnFLSs_NonLinear   0x00000800
+#define HC_HTXnFLSs_Flat_Gaussian_Cubic 0x00001800
+#define HC_HTXnFLTe_Nearest     0x00000000
+#define HC_HTXnFLTe_Linear      0x00000080
+#define HC_HTXnFLTe_NonLinear   0x00000100
+#define HC_HTXnFLTe_Sharp       0x00000180
+#define HC_HTXnFLTe_Flat_Gaussian_Cubic 0x00000300
+#define HC_HTXnFLTs_Nearest     0x00000000
+#define HC_HTXnFLTs_Linear      0x00000010
+#define HC_HTXnFLTs_NonLinear   0x00000020
+#define HC_HTXnFLTs_Flat_Gaussian_Cubic 0x00000060
+#define HC_HTXnFLDs_Tex0        0x00000000
+#define HC_HTXnFLDs_Nearest     0x00000001
+#define HC_HTXnFLDs_Linear      0x00000002
+#define HC_HTXnFLDs_NonLinear   0x00000003
+#define HC_HTXnFLDs_Dither      0x00000004
+#define HC_HTXnFLDs_ConstLOD    0x00000005
+#define HC_HTXnFLDs_Ani         0x00000006
+#define HC_HTXnFLDs_AniDither   0x00000007
+/* HC_SubA_HTXnMPMD        0x0079
+ */
+#define HC_HTXnMPMD_SMASK       0x00070000
+#define HC_HTXnMPMD_TMASK       0x00380000
+#define HC_HTXnLODDTf_MASK      0x00000007
+#define HC_HTXnXY2ST_MASK       0x00000008
+#define HC_HTXnMPMD_Tsingle     0x00000000
+#define HC_HTXnMPMD_Tclamp      0x00080000
+#define HC_HTXnMPMD_Trepeat     0x00100000
+#define HC_HTXnMPMD_Tmirror     0x00180000
+#define HC_HTXnMPMD_Twrap       0x00200000
+#define HC_HTXnMPMD_Ssingle     0x00000000
+#define HC_HTXnMPMD_Sclamp      0x00010000
+#define HC_HTXnMPMD_Srepeat     0x00020000
+#define HC_HTXnMPMD_Smirror     0x00030000
+#define HC_HTXnMPMD_Swrap       0x00040000
+/* HC_SubA_HTXnCLODu       0x007a
+ */
+#define HC_HTXnCLODu_MASK       0x000ffc00
+#define HC_HTXnCLODd_MASK       0x000003ff
+#define HC_HTXnCLODu_SHIFT      10
+/* HC_SubA_HTXnFM          0x007b
+ */
+#define HC_HTXnFM_MASK          0x00ff0000
+#define HC_HTXnLoc_MASK         0x00000003
+#define HC_HTXnFM_INDEX         0x00000000
+#define HC_HTXnFM_Intensity     0x00080000
+#define HC_HTXnFM_Lum           0x00100000
+#define HC_HTXnFM_Alpha         0x00180000
+#define HC_HTXnFM_DX            0x00280000
+#define HC_HTXnFM_ARGB16        0x00880000
+#define HC_HTXnFM_ARGB32        0x00980000
+#define HC_HTXnFM_ABGR16        0x00a80000
+#define HC_HTXnFM_ABGR32        0x00b80000
+#define HC_HTXnFM_RGBA16        0x00c80000
+#define HC_HTXnFM_RGBA32        0x00d80000
+#define HC_HTXnFM_BGRA16        0x00e80000
+#define HC_HTXnFM_BGRA32        0x00f80000
+#define HC_HTXnFM_BUMPMAP       0x00380000
+#define HC_HTXnFM_Index1        (HC_HTXnFM_INDEX     | 0x00000000)
+#define HC_HTXnFM_Index2        (HC_HTXnFM_INDEX     | 0x00010000)
+#define HC_HTXnFM_Index4        (HC_HTXnFM_INDEX     | 0x00020000)
+#define HC_HTXnFM_Index8        (HC_HTXnFM_INDEX     | 0x00030000)
+#define HC_HTXnFM_T1            (HC_HTXnFM_Intensity | 0x00000000)
+#define HC_HTXnFM_T2            (HC_HTXnFM_Intensity | 0x00010000)
+#define HC_HTXnFM_T4            (HC_HTXnFM_Intensity | 0x00020000)
+#define HC_HTXnFM_T8            (HC_HTXnFM_Intensity | 0x00030000)
+#define HC_HTXnFM_L1            (HC_HTXnFM_Lum       | 0x00000000)
+#define HC_HTXnFM_L2            (HC_HTXnFM_Lum       | 0x00010000)
+#define HC_HTXnFM_L4            (HC_HTXnFM_Lum       | 0x00020000)
+#define HC_HTXnFM_L8            (HC_HTXnFM_Lum       | 0x00030000)
+#define HC_HTXnFM_AL44          (HC_HTXnFM_Lum       | 0x00040000)
+#define HC_HTXnFM_AL88          (HC_HTXnFM_Lum       | 0x00050000)
+#define HC_HTXnFM_A1            (HC_HTXnFM_Alpha     | 0x00000000)
+#define HC_HTXnFM_A2            (HC_HTXnFM_Alpha     | 0x00010000)
+#define HC_HTXnFM_A4            (HC_HTXnFM_Alpha     | 0x00020000)
+#define HC_HTXnFM_A8            (HC_HTXnFM_Alpha     | 0x00030000)
+#define HC_HTXnFM_DX1           (HC_HTXnFM_DX        | 0x00010000)
+#define HC_HTXnFM_DX23          (HC_HTXnFM_DX        | 0x00020000)
+#define HC_HTXnFM_DX45          (HC_HTXnFM_DX        | 0x00030000)
+#define HC_HTXnFM_RGB555        (HC_HTXnFM_ARGB16    | 0x00000000)
+#define HC_HTXnFM_RGB565        (HC_HTXnFM_ARGB16    | 0x00010000)
+#define HC_HTXnFM_ARGB1555      (HC_HTXnFM_ARGB16    | 0x00020000)
+#define HC_HTXnFM_ARGB4444      (HC_HTXnFM_ARGB16    | 0x00030000)
+#define HC_HTXnFM_ARGB0888      (HC_HTXnFM_ARGB32    | 0x00000000)
+#define HC_HTXnFM_ARGB8888      (HC_HTXnFM_ARGB32    | 0x00010000)
+#define HC_HTXnFM_BGR555        (HC_HTXnFM_ABGR16    | 0x00000000)
+#define HC_HTXnFM_BGR565        (HC_HTXnFM_ABGR16    | 0x00010000)
+#define HC_HTXnFM_ABGR1555      (HC_HTXnFM_ABGR16    | 0x00020000)
+#define HC_HTXnFM_ABGR4444      (HC_HTXnFM_ABGR16    | 0x00030000)
+#define HC_HTXnFM_ABGR0888      (HC_HTXnFM_ABGR32    | 0x00000000)
+#define HC_HTXnFM_ABGR8888      (HC_HTXnFM_ABGR32    | 0x00010000)
+#define HC_HTXnFM_RGBA5550      (HC_HTXnFM_RGBA16    | 0x00000000)
+#define HC_HTXnFM_RGBA5551      (HC_HTXnFM_RGBA16    | 0x00020000)
+#define HC_HTXnFM_RGBA4444      (HC_HTXnFM_RGBA16    | 0x00030000)
+#define HC_HTXnFM_RGBA8880      (HC_HTXnFM_RGBA32    | 0x00000000)
+#define HC_HTXnFM_RGBA8888      (HC_HTXnFM_RGBA32    | 0x00010000)
+#define HC_HTXnFM_BGRA5550      (HC_HTXnFM_BGRA16    | 0x00000000)
+#define HC_HTXnFM_BGRA5551      (HC_HTXnFM_BGRA16    | 0x00020000)
+#define HC_HTXnFM_BGRA4444      (HC_HTXnFM_BGRA16    | 0x00030000)
+#define HC_HTXnFM_BGRA8880      (HC_HTXnFM_BGRA32    | 0x00000000)
+#define HC_HTXnFM_BGRA8888      (HC_HTXnFM_BGRA32    | 0x00010000)
+#define HC_HTXnFM_VU88          (HC_HTXnFM_BUMPMAP   | 0x00000000)
+#define HC_HTXnFM_LVU655        (HC_HTXnFM_BUMPMAP   | 0x00010000)
+#define HC_HTXnFM_LVU888        (HC_HTXnFM_BUMPMAP   | 0x00020000)
+#define HC_HTXnLoc_Local        0x00000000
+#define HC_HTXnLoc_Sys          0x00000002
+#define HC_HTXnLoc_AGP          0x00000003
+/* HC_SubA_HTXnTRAH        0x007f
+ */
+#define HC_HTXnTRAH_MASK        0x00ff0000
+#define HC_HTXnTRAL_MASK        0x0000ff00
+#define HC_HTXnTBA_MASK         0x000000ff
+#define HC_HTXnTRAH_SHIFT       16
+#define HC_HTXnTRAL_SHIFT       8
+/* HC_SubA_HTXnTBLCsat     0x0080
+ *-- Define the input texture.
+ */
+#define HC_XTC_TOPC             0x00000000
+#define HC_XTC_InvTOPC          0x00000010
+#define HC_XTC_TOPCp5           0x00000020
+#define HC_XTC_Cbias            0x00000000
+#define HC_XTC_InvCbias         0x00000010
+#define HC_XTC_0                0x00000000
+#define HC_XTC_Dif              0x00000001
+#define HC_XTC_Spec             0x00000002
+#define HC_XTC_Tex              0x00000003
+#define HC_XTC_Cur              0x00000004
+#define HC_XTC_Adif             0x00000005
+#define HC_XTC_Fog              0x00000006
+#define HC_XTC_Atex             0x00000007
+#define HC_XTC_Acur             0x00000008
+#define HC_XTC_HTXnTBLRC        0x00000009
+#define HC_XTC_Ctexnext         0x0000000a 
+/*--
+ */
+#define HC_HTXnTBLCsat_MASK     0x00800000
+#define HC_HTXnTBLCa_MASK       0x000fc000
+#define HC_HTXnTBLCb_MASK       0x00001f80
+#define HC_HTXnTBLCc_MASK       0x0000003f
+#define HC_HTXnTBLCa_TOPC       (HC_XTC_TOPC << 14)
+#define HC_HTXnTBLCa_InvTOPC    (HC_XTC_InvTOPC << 14)
+#define HC_HTXnTBLCa_TOPCp5     (HC_XTC_TOPCp5 << 14)
+#define HC_HTXnTBLCa_0          (HC_XTC_0 << 14)
+#define HC_HTXnTBLCa_Dif        (HC_XTC_Dif << 14)
+#define HC_HTXnTBLCa_Spec       (HC_XTC_Spec << 14)
+#define HC_HTXnTBLCa_Tex        (HC_XTC_Tex << 14)
+#define HC_HTXnTBLCa_Cur        (HC_XTC_Cur << 14)
+#define HC_HTXnTBLCa_Adif       (HC_XTC_Adif << 14)
+#define HC_HTXnTBLCa_Fog        (HC_XTC_Fog << 14)
+#define HC_HTXnTBLCa_Atex       (HC_XTC_Atex << 14)
+#define HC_HTXnTBLCa_Acur       (HC_XTC_Acur << 14)
+#define HC_HTXnTBLCa_HTXnTBLRC  (HC_XTC_HTXnTBLRC << 14)
+#define HC_HTXnTBLCa_Ctexnext   (HC_XTC_Ctexnext << 14) 
+#define HC_HTXnTBLCb_TOPC       (HC_XTC_TOPC << 7)
+#define HC_HTXnTBLCb_InvTOPC    (HC_XTC_InvTOPC << 7)
+#define HC_HTXnTBLCb_TOPCp5     (HC_XTC_TOPCp5 << 7)
+#define HC_HTXnTBLCb_0          (HC_XTC_0 << 7)
+#define HC_HTXnTBLCb_Dif        (HC_XTC_Dif << 7)
+#define HC_HTXnTBLCb_Spec       (HC_XTC_Spec << 7)
+#define HC_HTXnTBLCb_Tex        (HC_XTC_Tex << 7)
+#define HC_HTXnTBLCb_Cur        (HC_XTC_Cur << 7)
+#define HC_HTXnTBLCb_Adif       (HC_XTC_Adif << 7)
+#define HC_HTXnTBLCb_Fog        (HC_XTC_Fog << 7)
+#define HC_HTXnTBLCb_Atex       (HC_XTC_Atex << 7)
+#define HC_HTXnTBLCb_Acur       (HC_XTC_Acur << 7)
+#define HC_HTXnTBLCb_HTXnTBLRC  (HC_XTC_HTXnTBLRC << 7)
+#define HC_HTXnTBLCb_Ctexnext   (HC_XTC_Ctexnext << 7) 
+#define HC_HTXnTBLCc_TOPC       (HC_XTC_TOPC << 0)
+#define HC_HTXnTBLCc_InvTOPC    (HC_XTC_InvTOPC << 0)
+#define HC_HTXnTBLCc_TOPCp5     (HC_XTC_TOPCp5 << 0)
+#define HC_HTXnTBLCc_0          (HC_XTC_0 << 0)
+#define HC_HTXnTBLCc_Dif        (HC_XTC_Dif << 0)
+#define HC_HTXnTBLCc_Spec       (HC_XTC_Spec << 0)
+#define HC_HTXnTBLCc_Tex        (HC_XTC_Tex << 0)
+#define HC_HTXnTBLCc_Cur        (HC_XTC_Cur << 0)
+#define HC_HTXnTBLCc_Adif       (HC_XTC_Adif << 0)
+#define HC_HTXnTBLCc_Fog        (HC_XTC_Fog << 0)
+#define HC_HTXnTBLCc_Atex       (HC_XTC_Atex << 0)
+#define HC_HTXnTBLCc_Acur       (HC_XTC_Acur << 0)
+#define HC_HTXnTBLCc_HTXnTBLRC  (HC_XTC_HTXnTBLRC << 0)
+#define HC_HTXnTBLCc_Ctexnext   (HC_XTC_Ctexnext << 0) 
+/* HC_SubA_HTXnTBLCop      0x0081
+ */
+#define HC_HTXnTBLdot_MASK      0x00c00000
+#define HC_HTXnTBLCop_MASK      0x00380000
+#define HC_HTXnTBLCbias_MASK    0x0007c000
+#define HC_HTXnTBLCshift_MASK   0x00001800
+#define HC_HTXnTBLAop_MASK      0x00000380
+#define HC_HTXnTBLAbias_MASK    0x00000078
+#define HC_HTXnTBLAshift_MASK   0x00000003
+#define HC_HTXnTBLCop_Add       0x00000000
+#define HC_HTXnTBLCop_Sub       0x00080000
+#define HC_HTXnTBLCop_Min       0x00100000
+#define HC_HTXnTBLCop_Max       0x00180000
+#define HC_HTXnTBLCop_Mask      0x00200000
+#define HC_HTXnTBLCbias_Cbias           (HC_XTC_Cbias << 14)
+#define HC_HTXnTBLCbias_InvCbias        (HC_XTC_InvCbias << 14)
+#define HC_HTXnTBLCbias_0               (HC_XTC_0 << 14)
+#define HC_HTXnTBLCbias_Dif             (HC_XTC_Dif << 14)
+#define HC_HTXnTBLCbias_Spec            (HC_XTC_Spec << 14)
+#define HC_HTXnTBLCbias_Tex             (HC_XTC_Tex << 14)
+#define HC_HTXnTBLCbias_Cur             (HC_XTC_Cur << 14)
+#define HC_HTXnTBLCbias_Adif            (HC_XTC_Adif << 14)
+#define HC_HTXnTBLCbias_Fog             (HC_XTC_Fog << 14)
+#define HC_HTXnTBLCbias_Atex            (HC_XTC_Atex << 14)
+#define HC_HTXnTBLCbias_Acur            (HC_XTC_Acur << 14)
+#define HC_HTXnTBLCbias_HTXnTBLRC       (HC_XTC_HTXnTBLRC << 14)
+#define HC_HTXnTBLCshift_1      0x00000000
+#define HC_HTXnTBLCshift_2      0x00000800
+#define HC_HTXnTBLCshift_No     0x00001000
+#define HC_HTXnTBLCshift_DotP   0x00001800
+/*=* John Sheng [2003.7.18] texture combine *=*/
+#define HC_HTXnTBLDOT3   0x00080000
+#define HC_HTXnTBLDOT4   0x000C0000
+
+#define HC_HTXnTBLAop_Add       0x00000000
+#define HC_HTXnTBLAop_Sub       0x00000080
+#define HC_HTXnTBLAop_Min       0x00000100
+#define HC_HTXnTBLAop_Max       0x00000180
+#define HC_HTXnTBLAop_Mask      0x00000200
+#define HC_HTXnTBLAbias_Inv             0x00000040
+#define HC_HTXnTBLAbias_Adif            0x00000000
+#define HC_HTXnTBLAbias_Fog             0x00000008
+#define HC_HTXnTBLAbias_Acur            0x00000010
+#define HC_HTXnTBLAbias_HTXnTBLRAbias   0x00000018
+#define HC_HTXnTBLAbias_Atex            0x00000020
+#define HC_HTXnTBLAshift_1      0x00000000
+#define HC_HTXnTBLAshift_2      0x00000001
+#define HC_HTXnTBLAshift_No     0x00000002
+/* #define HC_HTXnTBLAshift_DotP   0x00000003 */
+/* HC_SubA_HTXnTBLMPFog    0x0082
+ */
+#define HC_HTXnTBLMPfog_MASK    0x00e00000
+#define HC_HTXnTBLMPfog_0       0x00000000
+#define HC_HTXnTBLMPfog_Adif    0x00200000
+#define HC_HTXnTBLMPfog_Fog     0x00400000
+#define HC_HTXnTBLMPfog_Atex    0x00600000
+#define HC_HTXnTBLMPfog_Acur    0x00800000
+#define HC_HTXnTBLMPfog_GHTXnTBLRFog    0x00a00000
+/* HC_SubA_HTXnTBLAsat     0x0083
+ *-- Define the texture alpha input.
+ */
+#define HC_XTA_TOPA             0x00000000
+#define HC_XTA_InvTOPA          0x00000008
+#define HC_XTA_TOPAp5           0x00000010
+#define HC_XTA_Adif             0x00000000
+#define HC_XTA_Fog              0x00000001
+#define HC_XTA_Acur             0x00000002
+#define HC_XTA_HTXnTBLRA        0x00000003
+#define HC_XTA_Atex             0x00000004
+#define HC_XTA_Atexnext         0x00000005 
+/*--
+ */
+#define HC_HTXnTBLAsat_MASK     0x00800000
+#define HC_HTXnTBLAMB_MASK      0x00700000
+#define HC_HTXnTBLAa_MASK       0x0007c000
+#define HC_HTXnTBLAb_MASK       0x00000f80
+#define HC_HTXnTBLAc_MASK       0x0000001f
+#define HC_HTXnTBLAMB_SHIFT     20
+#define HC_HTXnTBLAa_TOPA       (HC_XTA_TOPA << 14)
+#define HC_HTXnTBLAa_InvTOPA    (HC_XTA_InvTOPA << 14)
+#define HC_HTXnTBLAa_TOPAp5     (HC_XTA_TOPAp5 << 14)
+#define HC_HTXnTBLAa_Adif       (HC_XTA_Adif << 14)
+#define HC_HTXnTBLAa_Fog        (HC_XTA_Fog << 14)
+#define HC_HTXnTBLAa_Acur       (HC_XTA_Acur << 14)
+#define HC_HTXnTBLAa_HTXnTBLRA  (HC_XTA_HTXnTBLRA << 14)
+#define HC_HTXnTBLAa_Atex       (HC_XTA_Atex << 14)
+#define HC_HTXnTBLAa_Atexnext   (HC_XTA_Atexnext << 14) 
+#define HC_HTXnTBLAb_TOPA       (HC_XTA_TOPA << 7)
+#define HC_HTXnTBLAb_InvTOPA    (HC_XTA_InvTOPA << 7)
+#define HC_HTXnTBLAb_TOPAp5     (HC_XTA_TOPAp5 << 7)
+#define HC_HTXnTBLAb_Adif       (HC_XTA_Adif << 7)
+#define HC_HTXnTBLAb_Fog        (HC_XTA_Fog << 7)
+#define HC_HTXnTBLAb_Acur       (HC_XTA_Acur << 7)
+#define HC_HTXnTBLAb_HTXnTBLRA  (HC_XTA_HTXnTBLRA << 7)
+#define HC_HTXnTBLAb_Atex       (HC_XTA_Atex << 7)
+#define HC_HTXnTBLAb_Atexnext   (HC_XTA_Atexnext << 7) 
+#define HC_HTXnTBLAc_TOPA       (HC_XTA_TOPA << 0)
+#define HC_HTXnTBLAc_InvTOPA    (HC_XTA_InvTOPA << 0)
+#define HC_HTXnTBLAc_TOPAp5     (HC_XTA_TOPAp5 << 0)
+#define HC_HTXnTBLAc_Adif       (HC_XTA_Adif << 0)
+#define HC_HTXnTBLAc_Fog        (HC_XTA_Fog << 0)
+#define HC_HTXnTBLAc_Acur       (HC_XTA_Acur << 0)
+#define HC_HTXnTBLAc_HTXnTBLRA  (HC_XTA_HTXnTBLRA << 0)
+#define HC_HTXnTBLAc_Atex       (HC_XTA_Atex << 0)
+#define HC_HTXnTBLAc_Atexnext   (HC_XTA_Atexnext << 0) 
+/* HC_SubA_HTXnTBLRAa      0x0089
+ */
+#define HC_HTXnTBLRAa_MASK      0x00ff0000
+#define HC_HTXnTBLRAb_MASK      0x0000ff00
+#define HC_HTXnTBLRAc_MASK      0x000000ff
+#define HC_HTXnTBLRAa_SHIFT     16
+#define HC_HTXnTBLRAb_SHIFT     8
+#define HC_HTXnTBLRAc_SHIFT     0
+/* HC_SubA_HTXnTBLRFog     0x008a
+ */
+#define HC_HTXnTBLRFog_MASK     0x0000ff00
+#define HC_HTXnTBLRAbias_MASK   0x000000ff
+#define HC_HTXnTBLRFog_SHIFT    8
+#define HC_HTXnTBLRAbias_SHIFT  0
+/* HC_SubA_HTXnLScale      0x0094
+ */
+#define HC_HTXnLScale_MASK      0x0007fc00
+#define HC_HTXnLOff_MASK        0x000001ff
+#define HC_HTXnLScale_SHIFT     10
+/* HC_SubA_HTXSMD          0x0000
+ */
+#define HC_HTXSMD_MASK          0x00000080
+#define HC_HTXTMD_MASK          0x00000040
+#define HC_HTXNum_MASK          0x00000038
+#define HC_HTXTRMD_MASK         0x00000006
+#define HC_HTXCHCLR_MASK        0x00000001
+#define HC_HTXNum_SHIFT         3
+
+/* Texture Palette n
+ */
+#define HC_SubType_TexPalette0  0x00000000
+#define HC_SubType_TexPalette1  0x00000001
+#define HC_SubType_FogTable     0x00000010
+#define HC_SubType_Stipple      0x00000014
+/* HC_SubA_TexPalette0     0x0000
+ */
+#define HC_HTPnA_MASK           0xff000000
+#define HC_HTPnR_MASK           0x00ff0000
+#define HC_HTPnG_MASK           0x0000ff00
+#define HC_HTPnB_MASK           0x000000ff
+/* HC_SubA_FogTable        0x0010
+ */
+#define HC_HFPn3_MASK           0xff000000
+#define HC_HFPn2_MASK           0x00ff0000
+#define HC_HFPn1_MASK           0x0000ff00
+#define HC_HFPn_MASK            0x000000ff
+#define HC_HFPn3_SHIFT          24
+#define HC_HFPn2_SHIFT          16
+#define HC_HFPn1_SHIFT          8
+
+/* Auto Testing & Security
+ */
+#define HC_SubA_HenFIFOAT       0x0000
+#define HC_SubA_HFBDrawFirst    0x0004
+#define HC_SubA_HFBBasL         0x0005
+#define HC_SubA_HFBDst          0x0006
+/* HC_SubA_HenFIFOAT       0x0000
+ */
+#define HC_HenFIFOAT_MASK       0x00000020
+#define HC_HenGEMILock_MASK     0x00000010
+#define HC_HenFBASwap_MASK      0x00000008
+#define HC_HenOT_MASK           0x00000004
+#define HC_HenCMDQ_MASK         0x00000002
+#define HC_HenTXCTSU_MASK       0x00000001
+/* HC_SubA_HFBDrawFirst    0x0004
+ */
+#define HC_HFBDrawFirst_MASK    0x00000800
+#define HC_HFBQueue_MASK        0x00000400
+#define HC_HFBLock_MASK         0x00000200
+#define HC_HEOF_MASK            0x00000100
+#define HC_HFBBasH_MASK         0x000000ff
+
+/* GEMI Setting
+ */
+#define HC_SubA_HTArbRCM        0x0008
+#define HC_SubA_HTArbRZ         0x000a
+#define HC_SubA_HTArbWZ         0x000b
+#define HC_SubA_HTArbRTX        0x000c
+#define HC_SubA_HTArbRCW        0x000d
+#define HC_SubA_HTArbE2         0x000e
+#define HC_SubA_HArbRQCM        0x0010
+#define HC_SubA_HArbWQCM        0x0011
+#define HC_SubA_HGEMITout       0x0020
+#define HC_SubA_HFthRTXD        0x0040
+#define HC_SubA_HFthRTXA        0x0044
+#define HC_SubA_HCMDQstL        0x0050
+#define HC_SubA_HCMDQendL       0x0051
+#define HC_SubA_HCMDQLen        0x0052
+/* HC_SubA_HTArbRCM        0x0008
+ */
+#define HC_HTArbRCM_MASK        0x0000ffff
+/* HC_SubA_HTArbRZ         0x000a
+ */
+#define HC_HTArbRZ_MASK         0x0000ffff
+/* HC_SubA_HTArbWZ         0x000b
+ */
+#define HC_HTArbWZ_MASK         0x0000ffff
+/* HC_SubA_HTArbRTX        0x000c
+ */
+#define HC_HTArbRTX_MASK        0x0000ffff
+/* HC_SubA_HTArbRCW        0x000d
+ */
+#define HC_HTArbRCW_MASK        0x0000ffff
+/* HC_SubA_HTArbE2         0x000e
+ */
+#define HC_HTArbE2_MASK         0x0000ffff
+/* HC_SubA_HArbRQCM        0x0010
+ */
+#define HC_HTArbRQCM_MASK       0x0000ffff
+/* HC_SubA_HArbWQCM        0x0011
+ */
+#define HC_HArbWQCM_MASK        0x0000ffff
+/* HC_SubA_HGEMITout       0x0020
+ */
+#define HC_HGEMITout_MASK       0x000f0000
+#define HC_HNPArbZC_MASK        0x0000ffff
+#define HC_HGEMITout_SHIFT      16
+/* HC_SubA_HFthRTXD        0x0040
+ */
+#define HC_HFthRTXD_MASK        0x00ff0000
+#define HC_HFthRZD_MASK         0x0000ff00
+#define HC_HFthWZD_MASK         0x000000ff
+#define HC_HFthRTXD_SHIFT       16
+#define HC_HFthRZD_SHIFT        8
+/* HC_SubA_HFthRTXA        0x0044
+ */
+#define HC_HFthRTXA_MASK        0x000000ff
+
+/******************************************************************************
+** Define the Halcyon Internal register access constants. For simulator only.
+******************************************************************************/
+#define HC_SIMA_HAGPBstL        0x0000
+#define HC_SIMA_HAGPBendL       0x0001
+#define HC_SIMA_HAGPCMNT        0x0002
+#define HC_SIMA_HAGPBpL         0x0003
+#define HC_SIMA_HAGPBpH         0x0004
+#define HC_SIMA_HClipTB         0x0005
+#define HC_SIMA_HClipLR         0x0006
+#define HC_SIMA_HFPClipTL       0x0007
+#define HC_SIMA_HFPClipBL       0x0008
+#define HC_SIMA_HFPClipLL       0x0009
+#define HC_SIMA_HFPClipRL       0x000a
+#define HC_SIMA_HFPClipTBH      0x000b
+#define HC_SIMA_HFPClipLRH      0x000c
+#define HC_SIMA_HLP             0x000d
+#define HC_SIMA_HLPRF           0x000e
+#define HC_SIMA_HSolidCL        0x000f
+#define HC_SIMA_HPixGC          0x0010
+#define HC_SIMA_HSPXYOS         0x0011
+#define HC_SIMA_HCmdA           0x0012
+#define HC_SIMA_HCmdB           0x0013
+#define HC_SIMA_HEnable         0x0014
+#define HC_SIMA_HZWBBasL        0x0015
+#define HC_SIMA_HZWBBasH        0x0016
+#define HC_SIMA_HZWBType        0x0017
+#define HC_SIMA_HZBiasL         0x0018
+#define HC_SIMA_HZWBend         0x0019
+#define HC_SIMA_HZWTMD          0x001a
+#define HC_SIMA_HZWCDL          0x001b
+#define HC_SIMA_HZWCTAGnum      0x001c
+#define HC_SIMA_HZCYNum         0x001d
+#define HC_SIMA_HZWCFire        0x001e
+/* #define HC_SIMA_HSBBasL         0x001d */
+/* #define HC_SIMA_HSBBasH         0x001e */
+/* #define HC_SIMA_HSBFM           0x001f */
+#define HC_SIMA_HSTREF          0x0020
+#define HC_SIMA_HSTMD           0x0021
+#define HC_SIMA_HABBasL         0x0022
+#define HC_SIMA_HABBasH         0x0023
+#define HC_SIMA_HABFM           0x0024
+#define HC_SIMA_HATMD           0x0025
+#define HC_SIMA_HABLCsat        0x0026
+#define HC_SIMA_HABLCop         0x0027
+#define HC_SIMA_HABLAsat        0x0028
+#define HC_SIMA_HABLAop         0x0029
+#define HC_SIMA_HABLRCa         0x002a
+#define HC_SIMA_HABLRFCa        0x002b
+#define HC_SIMA_HABLRCbias      0x002c
+#define HC_SIMA_HABLRCb         0x002d
+#define HC_SIMA_HABLRFCb        0x002e
+#define HC_SIMA_HABLRAa         0x002f
+#define HC_SIMA_HABLRAb         0x0030
+#define HC_SIMA_HDBBasL         0x0031
+#define HC_SIMA_HDBBasH         0x0032
+#define HC_SIMA_HDBFM           0x0033
+#define HC_SIMA_HFBBMSKL        0x0034
+#define HC_SIMA_HROP            0x0035
+#define HC_SIMA_HFogLF          0x0036
+#define HC_SIMA_HFogCL          0x0037
+#define HC_SIMA_HFogCH          0x0038
+#define HC_SIMA_HFogStL         0x0039
+#define HC_SIMA_HFogStH         0x003a
+#define HC_SIMA_HFogOOdMF       0x003b
+#define HC_SIMA_HFogOOdEF       0x003c
+#define HC_SIMA_HFogEndL        0x003d
+#define HC_SIMA_HFogDenst       0x003e
+/*---- start of texture 0 setting ----
+ */
+#define HC_SIMA_HTX0L0BasL      0x0040
+#define HC_SIMA_HTX0L1BasL      0x0041
+#define HC_SIMA_HTX0L2BasL      0x0042
+#define HC_SIMA_HTX0L3BasL      0x0043
+#define HC_SIMA_HTX0L4BasL      0x0044
+#define HC_SIMA_HTX0L5BasL      0x0045
+#define HC_SIMA_HTX0L6BasL      0x0046
+#define HC_SIMA_HTX0L7BasL      0x0047
+#define HC_SIMA_HTX0L8BasL      0x0048
+#define HC_SIMA_HTX0L9BasL      0x0049
+#define HC_SIMA_HTX0LaBasL      0x004a
+#define HC_SIMA_HTX0LbBasL      0x004b
+#define HC_SIMA_HTX0LcBasL      0x004c
+#define HC_SIMA_HTX0LdBasL      0x004d
+#define HC_SIMA_HTX0LeBasL      0x004e
+#define HC_SIMA_HTX0LfBasL      0x004f
+#define HC_SIMA_HTX0L10BasL     0x0050
+#define HC_SIMA_HTX0L11BasL     0x0051
+#define HC_SIMA_HTX0L012BasH    0x0052
+#define HC_SIMA_HTX0L345BasH    0x0053
+#define HC_SIMA_HTX0L678BasH    0x0054
+#define HC_SIMA_HTX0L9abBasH    0x0055
+#define HC_SIMA_HTX0LcdeBasH    0x0056
+#define HC_SIMA_HTX0Lf1011BasH  0x0057
+#define HC_SIMA_HTX0L0Pit       0x0058
+#define HC_SIMA_HTX0L1Pit       0x0059
+#define HC_SIMA_HTX0L2Pit       0x005a
+#define HC_SIMA_HTX0L3Pit       0x005b
+#define HC_SIMA_HTX0L4Pit       0x005c
+#define HC_SIMA_HTX0L5Pit       0x005d
+#define HC_SIMA_HTX0L6Pit       0x005e
+#define HC_SIMA_HTX0L7Pit       0x005f
+#define HC_SIMA_HTX0L8Pit       0x0060
+#define HC_SIMA_HTX0L9Pit       0x0061
+#define HC_SIMA_HTX0LaPit       0x0062
+#define HC_SIMA_HTX0LbPit       0x0063
+#define HC_SIMA_HTX0LcPit       0x0064
+#define HC_SIMA_HTX0LdPit       0x0065
+#define HC_SIMA_HTX0LePit       0x0066
+#define HC_SIMA_HTX0LfPit       0x0067
+#define HC_SIMA_HTX0L10Pit      0x0068
+#define HC_SIMA_HTX0L11Pit      0x0069
+#define HC_SIMA_HTX0L0_5WE      0x006a
+#define HC_SIMA_HTX0L6_bWE      0x006b
+#define HC_SIMA_HTX0Lc_11WE     0x006c
+#define HC_SIMA_HTX0L0_5HE      0x006d
+#define HC_SIMA_HTX0L6_bHE      0x006e
+#define HC_SIMA_HTX0Lc_11HE     0x006f
+#define HC_SIMA_HTX0L0OS        0x0070
+#define HC_SIMA_HTX0TB          0x0071
+#define HC_SIMA_HTX0MPMD        0x0072
+#define HC_SIMA_HTX0CLODu       0x0073
+#define HC_SIMA_HTX0FM          0x0074
+#define HC_SIMA_HTX0TRCH        0x0075
+#define HC_SIMA_HTX0TRCL        0x0076
+#define HC_SIMA_HTX0TBC         0x0077
+#define HC_SIMA_HTX0TRAH        0x0078
+#define HC_SIMA_HTX0TBLCsat     0x0079
+#define HC_SIMA_HTX0TBLCop      0x007a
+#define HC_SIMA_HTX0TBLMPfog    0x007b
+#define HC_SIMA_HTX0TBLAsat     0x007c
+#define HC_SIMA_HTX0TBLRCa      0x007d
+#define HC_SIMA_HTX0TBLRCb      0x007e
+#define HC_SIMA_HTX0TBLRCc      0x007f
+#define HC_SIMA_HTX0TBLRCbias   0x0080
+#define HC_SIMA_HTX0TBLRAa      0x0081
+#define HC_SIMA_HTX0TBLRFog     0x0082
+#define HC_SIMA_HTX0BumpM00     0x0083
+#define HC_SIMA_HTX0BumpM01     0x0084
+#define HC_SIMA_HTX0BumpM10     0x0085
+#define HC_SIMA_HTX0BumpM11     0x0086
+#define HC_SIMA_HTX0LScale      0x0087
+/*---- end of texture 0 setting ----      0x008f
+ */
+#define HC_SIMA_TX0TX1_OFF      0x0050
+/*---- start of texture 1 setting ----
+ */
+#define HC_SIMA_HTX1L0BasL      (HC_SIMA_HTX0L0BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L1BasL      (HC_SIMA_HTX0L1BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L2BasL      (HC_SIMA_HTX0L2BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L3BasL      (HC_SIMA_HTX0L3BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L4BasL      (HC_SIMA_HTX0L4BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L5BasL      (HC_SIMA_HTX0L5BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6BasL      (HC_SIMA_HTX0L6BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L7BasL      (HC_SIMA_HTX0L7BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L8BasL      (HC_SIMA_HTX0L8BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L9BasL      (HC_SIMA_HTX0L9BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LaBasL      (HC_SIMA_HTX0LaBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LbBasL      (HC_SIMA_HTX0LbBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LcBasL      (HC_SIMA_HTX0LcBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LdBasL      (HC_SIMA_HTX0LdBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LeBasL      (HC_SIMA_HTX0LeBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LfBasL      (HC_SIMA_HTX0LfBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L10BasL     (HC_SIMA_HTX0L10BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L11BasL     (HC_SIMA_HTX0L11BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L012BasH    (HC_SIMA_HTX0L012BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L345BasH    (HC_SIMA_HTX0L345BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L678BasH    (HC_SIMA_HTX0L678BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L9abBasH    (HC_SIMA_HTX0L9abBasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LcdeBasH    (HC_SIMA_HTX0LcdeBasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1Lf1011BasH  (HC_SIMA_HTX0Lf1011BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0Pit       (HC_SIMA_HTX0L0Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L1Pit       (HC_SIMA_HTX0L1Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L2Pit       (HC_SIMA_HTX0L2Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L3Pit       (HC_SIMA_HTX0L3Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L4Pit       (HC_SIMA_HTX0L4Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L5Pit       (HC_SIMA_HTX0L5Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6Pit       (HC_SIMA_HTX0L6Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L7Pit       (HC_SIMA_HTX0L7Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L8Pit       (HC_SIMA_HTX0L8Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L9Pit       (HC_SIMA_HTX0L9Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LaPit       (HC_SIMA_HTX0LaPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LbPit       (HC_SIMA_HTX0LbPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LcPit       (HC_SIMA_HTX0LcPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LdPit       (HC_SIMA_HTX0LdPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LePit       (HC_SIMA_HTX0LePit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LfPit       (HC_SIMA_HTX0LfPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L10Pit      (HC_SIMA_HTX0L10Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L11Pit      (HC_SIMA_HTX0L11Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0_5WE      (HC_SIMA_HTX0L0_5WE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6_bWE      (HC_SIMA_HTX0L6_bWE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1Lc_11WE     (HC_SIMA_HTX0Lc_11WE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0_5HE      (HC_SIMA_HTX0L0_5HE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6_bHE      (HC_SIMA_HTX0L6_bHE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1Lc_11HE      (HC_SIMA_HTX0Lc_11HE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0OS        (HC_SIMA_HTX0L0OS + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TB          (HC_SIMA_HTX0TB + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1MPMD        (HC_SIMA_HTX0MPMD + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1CLODu       (HC_SIMA_HTX0CLODu + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1FM          (HC_SIMA_HTX0FM + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TRCH        (HC_SIMA_HTX0TRCH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TRCL        (HC_SIMA_HTX0TRCL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBC         (HC_SIMA_HTX0TBC + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TRAH        (HC_SIMA_HTX0TRAH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LTC         (HC_SIMA_HTX0LTC + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LTA         (HC_SIMA_HTX0LTA + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLCsat     (HC_SIMA_HTX0TBLCsat + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLCop      (HC_SIMA_HTX0TBLCop + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLMPfog    (HC_SIMA_HTX0TBLMPfog + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLAsat     (HC_SIMA_HTX0TBLAsat + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCa      (HC_SIMA_HTX0TBLRCa + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCb      (HC_SIMA_HTX0TBLRCb + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCc      (HC_SIMA_HTX0TBLRCc + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCbias   (HC_SIMA_HTX0TBLRCbias + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRAa      (HC_SIMA_HTX0TBLRAa + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRFog     (HC_SIMA_HTX0TBLRFog + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM00     (HC_SIMA_HTX0BumpM00 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM01     (HC_SIMA_HTX0BumpM01 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM10     (HC_SIMA_HTX0BumpM10 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM11     (HC_SIMA_HTX0BumpM11 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LScale      (HC_SIMA_HTX0LScale + HC_SIMA_TX0TX1_OFF)
+/*---- end of texture 1 setting ---- 0xaf
+ */
+#define HC_SIMA_HTXSMD          0x00b0
+#define HC_SIMA_HenFIFOAT       0x00b1
+#define HC_SIMA_HFBDrawFirst    0x00b2
+#define HC_SIMA_HFBBasL         0x00b3
+#define HC_SIMA_HTArbRCM        0x00b4
+#define HC_SIMA_HTArbRZ         0x00b5
+#define HC_SIMA_HTArbWZ         0x00b6
+#define HC_SIMA_HTArbRTX        0x00b7
+#define HC_SIMA_HTArbRCW        0x00b8
+#define HC_SIMA_HTArbE2         0x00b9
+#define HC_SIMA_HGEMITout       0x00ba
+#define HC_SIMA_HFthRTXD        0x00bb
+#define HC_SIMA_HFthRTXA        0x00bc
+/* Define the texture palette 0
+ */
+#define HC_SIMA_HTP0            0x0100
+#define HC_SIMA_HTP1            0x0200
+#define HC_SIMA_FOGTABLE        0x0300
+#define HC_SIMA_STIPPLE         0x0400
+#define HC_SIMA_HE3Fire         0x0440
+#define HC_SIMA_TRANS_SET       0x0441
+#define HC_SIMA_HREngSt         0x0442
+#define HC_SIMA_HRFIFOempty     0x0443
+#define HC_SIMA_HRFIFOfull      0x0444
+#define HC_SIMA_HRErr           0x0445
+#define HC_SIMA_FIFOstatus      0x0446
+
+/******************************************************************************
+** Define the AGP command header.
+******************************************************************************/
+#define HC_ACMD_MASK            0xfe000000      
+#define HC_ACMD_SUB_MASK        0x0c000000      
+#define HC_ACMD_HCmdA           0xee000000      
+#define HC_ACMD_HCmdB           0xec000000      
+#define HC_ACMD_HCmdC           0xea000000      
+#define HC_ACMD_H1              0xf0000000      
+#define HC_ACMD_H2              0xf2000000      
+#define HC_ACMD_H3              0xf4000000      
+#define HC_ACMD_H4              0xf6000000      
+
+#define HC_ACMD_H1IO_MASK       0x000001ff
+#define HC_ACMD_H2IO1_MASK      0x001ff000      
+#define HC_ACMD_H2IO2_MASK      0x000001ff
+#define HC_ACMD_H2IO1_SHIFT     12              
+#define HC_ACMD_H2IO2_SHIFT     0
+#define HC_ACMD_H3IO_MASK       0x000001ff
+#define HC_ACMD_H3COUNT_MASK    0x01fff000      
+#define HC_ACMD_H3COUNT_SHIFT   12              
+#define HC_ACMD_H4ID_MASK       0x000001ff
+#define HC_ACMD_H4COUNT_MASK    0x01fffe00
+#define HC_ACMD_H4COUNT_SHIFT   9
+
+/********************************************************************************
+** Define Header 
+********************************************************************************/
+#define HC_HEADER2             0xF210F110
+
+/********************************************************************************
+** Define Dummy Value 
+********************************************************************************/
+#define HC_DUMMY               0xCCCCCCCC
+/********************************************************************************
+** Define for DMA use 
+********************************************************************************/
+#define HALCYON_HEADER2     0XF210F110
+#define HALCYON_FIRECMD     0XEE100000  
+#define HALCYON_FIREMASK    0XFFF00000
+#define HALCYON_CMDB        0XEC000000  
+#define HALCYON_CMDBMASK    0XFFFE0000
+#define HALCYON_SUB_ADDR0   0X00000000
+#define HALCYON_HEADER1MASK 0XFFFFFF00
+#define HALCYON_HEADER1     0XF0000000
+#define HC_SubA_HAGPBstL        0x0060
+#define HC_SubA_HAGPBendL       0x0061
+#define HC_SubA_HAGPCMNT        0x0062
+#define HC_SubA_HAGPBpL         0x0063
+#define HC_SubA_HAGPBpH         0x0064
+#define HC_HAGPCMNT_MASK        0x00800000
+#define HC_HCmdErrClr_MASK      0x00400000
+#define HC_HAGPBendH_MASK       0x0000ff00
+#define HC_HAGPBstH_MASK        0x000000ff
+#define HC_HAGPBendH_SHIFT      8
+#define HC_HAGPBstH_SHIFT       0
+#define HC_HAGPBpL_MASK         0x00fffffc
+#define HC_HAGPBpID_MASK        0x00000003
+#define HC_HAGPBpID_PAUSE       0x00000000
+#define HC_HAGPBpID_JUMP        0x00000001
+#define HC_HAGPBpID_STOP        0x00000002
+#define HC_HAGPBpH_MASK         0x00ffffff
+
+#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_common.h b/src/mesa/drivers/dri/unichrome/via_common.h
new file mode 100644 (file)
index 0000000..214c872
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _VIA_DRM_H_
+#define _VIA_DRM_H_
+
+/* WARNING: These defines must be the same as what the Xserver uses.
+ * if you change them, you must change the defines in the Xserver.
+ */
+
+#ifndef _VIA_DEFINES_
+#define _VIA_DEFINES_
+
+#define VIA_DMA_BUF_ORDER              12
+#define VIA_DMA_BUF_SZ                         (1 << VIA_DMA_BUF_ORDER)
+#define VIA_DMA_BUF_NR                         256
+#define VIA_NR_SAREA_CLIPRECTS                 8
+
+#define VIA_NR_TEX_REGIONS 64
+#define VIA_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+#define VIA_UPLOAD_TEX0IMAGE  0x1
+#define VIA_UPLOAD_TEX1IMAGE  0x2
+#define VIA_UPLOAD_CTX        0x4
+#define VIA_UPLOAD_BUFFERS    0x8
+#define VIA_UPLOAD_TEX0       0x10
+#define VIA_UPLOAD_TEX1       0x20
+#define VIA_UPLOAD_CLIPRECTS  0x40
+/*#define VIA_UPLOAD_ALL        0xff*/
+
+/* VIA specific ioctls */
+#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(0x40, drm_via_mem_t)
+#define DRM_IOCTL_VIA_FREEMEM  DRM_IOW(0x41, drm_via_mem_t)
+#define DRM_IOCTL_VIA_AGP_INIT DRM_IOWR(0x42, drm_via_agp_t)
+#define DRM_IOCTL_VIA_FB_INIT  DRM_IOWR(0x43, drm_via_fb_t)
+#define DRM_IOCTL_VIA_MAP_INIT DRM_IOWR(0x44, drm_via_init_t)
+#define DRM_IOCTL_VIA_FLUSH_AGP        DRM_IOW(0x45, drm_via_flush_agp_t)
+#define DRM_IOCTL_VIA_FLUSH_SYS        DRM_IOW(0x46, drm_via_flush_sys_t)
+
+#define VIA_TEX_SETUP_SIZE 8
+
+#define DRM_VIA_ALLOCMEM    0
+#define DRM_VIA_FREEMEM     1
+#define DRM_VIA_AGP_INIT    2
+#define DRM_VIA_FB_INIT     3
+#define DRM_VIA_MAP_INIT    4
+
+#define VIA_FRONT   0x1
+#define VIA_BACK    0x2
+#define VIA_DEPTH   0x4
+#define VIA_STENCIL 0x8
+#define VIDEO 0
+#define AGP 1
+typedef struct {
+    unsigned int offset;
+    unsigned int size;
+} drm_via_agp_t;    
+
+typedef struct {
+    unsigned int offset;
+    unsigned int size;
+} drm_via_fb_t;    
+
+typedef struct {
+    unsigned int context;
+    unsigned int type;
+    unsigned int size;
+    unsigned long index;
+    unsigned long offset;
+} drm_via_mem_t;    
+
+typedef struct _drm_via_init {
+    enum {
+       VIA_INIT_MAP = 0x01,
+       VIA_CLEANUP_MAP = 0x02
+    } func;
+    unsigned long sarea_priv_offset;
+    unsigned long fb_offset;
+    unsigned long mmio_offset;
+    unsigned long agpAddr;
+} drm_via_init_t;
+
+
+typedef struct _drm_via_tex_region {
+    unsigned char next, prev;
+    unsigned char inUse;
+    int age;
+} drm_via_tex_region_t;
+
+typedef struct _drm_via_sarea {
+    unsigned int dirty;
+    unsigned int nbox;
+    drm_clip_rect_t boxes[VIA_NR_SAREA_CLIPRECTS];   
+    drm_via_tex_region_t texList[VIA_NR_TEX_REGIONS + 1]; 
+    int texAge;
+    int ctxOwner;
+    int vertexPrim;
+} drm_via_sarea_t;
+
+typedef struct _drm_via_flush_agp {
+    unsigned int offset;
+    unsigned int size;
+    unsigned int index;                
+    int discard;
+} drm_via_flush_agp_t;
+
+typedef struct _drm_via_flush_sys {
+    unsigned int offset;
+    unsigned int size;
+    unsigned long index;               
+    int discard;
+} drm_via_flush_sys_t;
+
+#ifdef __KERNEL__
+int via_fb_init(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg);             
+int via_mem_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg);                             
+int via_mem_free(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg);             
+int via_agp_init(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg);                             
+int via_dma_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg);                             
+int via_dma_free(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg);                             
+int via_map_init(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg);                             
+int via_flush_agp(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg);                             
+int via_flush_sys(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg);                             
+#endif
+#endif /* _VIA_DRM_H_ */
diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c
new file mode 100644 (file)
index 0000000..f38dec0
--- /dev/null
@@ -0,0 +1,1185 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glheader.h"
+#include "context.h"
+/*#include "mem.h"*/
+#include "matrix.h"
+#include "simple_list.h"
+#include "extensions.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "array_cache/acache.h"
+
+#include "tnl/t_pipeline.h"
+
+#include "drivers/common/driverfuncs.h"
+
+#include "via_screen.h"
+#include "via_dri.h"
+
+#include "via_state.h"
+#include "via_tex.h"
+#include "via_span.h"
+#include "via_tris.h"
+#include "via_vb.h"
+#include "via_ioctl.h"
+#include "via_fb.h"
+
+#ifndef _SOLO
+#include <X11/Xlibint.h>
+#endif
+#include <stdio.h>
+#include "macros.h"
+
+viaContextPtr current_mesa;
+GLuint VIA_DEBUG = 0;
+GLuint DRAW_FRONT = 0;
+#define DMA_SIZE 2
+GLuint VIA_PERFORMANCE = 0;
+#ifdef PERFORMANCE_MEASURE
+GLuint busy = 0;
+GLuint idle = 0;
+hash_element hash_table[HASH_TABLE_SIZE][HASH_TABLE_DEPTH];
+#endif
+/*=* John Sheng [2003.5.31]  agp tex *=*/
+extern GLuint agpFullCount;
+
+static GLboolean
+AllocateBuffer(viaContextPtr vmesa)
+{
+    vmesa->front_base = vmesa->driScreen->pFB;
+    if (vmesa->drawType == GLX_PBUFFER_BIT) {
+        if (vmesa->front.map)
+            via_free_front_buffer(vmesa);
+        if (!via_alloc_front_buffer(vmesa))
+            return GL_FALSE;
+    }
+    
+    if (vmesa->hasBack) {
+        if (vmesa->back.map)
+            via_free_back_buffer(vmesa);
+        if (!via_alloc_back_buffer(vmesa))
+            return GL_FALSE;
+    }
+
+    if (vmesa->hasDepth || vmesa->hasStencil) {
+        if (vmesa->depth.map)
+            via_free_depth_buffer(vmesa);
+        if (!via_alloc_depth_buffer(vmesa)) {
+            via_free_depth_buffer(vmesa);
+            return GL_FALSE;
+        }
+    }
+
+    return GL_TRUE;
+}
+
+static const GLubyte *viaGetString(GLcontext *ctx, GLenum name)
+{
+    switch (name) {
+    case GL_VENDOR:
+        return (GLubyte *)"VIA Technology";
+    case GL_RENDERER:
+        return (GLubyte *)"Mesa DRI VIA CLE266 20020221";
+    default:
+        return 0;
+    }
+}
+
+void viaReAllocateBuffers(GLframebuffer *drawbuffer)
+{
+    GLcontext *ctx;
+    viaContextPtr vmesa = current_mesa;
+    
+    ctx = vmesa->glCtx;
+    ctx->DrawBuffer->Width = drawbuffer->Width;
+    ctx->DrawBuffer->Height = drawbuffer->Height;
+
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    ctx->DrawBuffer->Accum = 0;
+     
+    vmesa->driDrawable->w = ctx->DrawBuffer->Width;
+    vmesa->driDrawable->h = ctx->DrawBuffer->Height;
+    LOCK_HARDWARE(vmesa);
+    
+    /* Allocate back & depth buffer */
+    {
+       int w, h, bpp;      
+       w = vmesa->driDrawable->w;
+       h = vmesa->driDrawable->h;
+       /* back buffer */
+       bpp = vmesa->viaScreen->bitsPerPixel;
+#ifdef DEBUG       
+       if (VIA_DEBUG) fprintf(stderr, "driScreen->fbBPP = %d\n", bpp);     
+#endif     
+       if (bpp == 32) {
+           w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
+           vmesa->back.size = w * h * bpp / 8;
+           vmesa->back.pitch = w << 2;
+       }
+       else {
+           w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2 + 16;
+           vmesa->back.size = w * h * bpp / 8;
+           vmesa->back.pitch = w << 1;        
+       }
+#ifdef DEBUG
+       if (VIA_DEBUG) fprintf(stderr, "resizebuffer backbuffer: w = %d h = %d bpp = %d sizs = %d\n", 
+                           w, h, bpp, vmesa->back.size);
+#endif
+       /* depth buffer */
+       w = vmesa->driDrawable->w;
+       if (vmesa->hasDepth && vmesa->hasStencil) {
+           w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
+           vmesa->depth.size = w * h * 4;
+           vmesa->depth.pitch = w << 2;
+           vmesa->depth.bpp = 32;
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "depthBits = 24\n");
+           if (VIA_DEBUG) fprintf(stderr, "StencilBits = 8\n");
+#endif
+       }
+       else if (vmesa->hasDepth) {
+           /*=* John Sheng [2003.6.16] patch viewperf drv-08 draw nothing */
+           /*if(vmesa->viaScreen->bitsPerPixel == 32)*/
+               /*vmesa->depthBits = 16;*/
+               
+           if (vmesa->depthBits == 16) {
+               w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2 + 16;
+               vmesa->depth.size = w * h * 2;         
+               vmesa->depth.pitch = w << 1;
+               vmesa->depth.bpp = 16;
+#ifdef DEBUG
+               if (VIA_DEBUG) fprintf(stderr, "depthBits = 16\n");
+#endif
+           }
+           else {
+               w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
+               vmesa->depth.size = w * h * 4;
+               vmesa->depth.pitch = w << 2;
+               vmesa->depth.bpp = 32;
+#ifdef DEBUG
+               if (VIA_DEBUG) fprintf(stderr, "depthBits = 32\n");
+#endif
+           }
+       }
+       else if (vmesa->hasStencil) {
+           w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
+           vmesa->depth.size = w * h * 4;
+           vmesa->depth.pitch = w << 2;
+           vmesa->depth.bpp = 32;
+#ifdef DEBUG           
+           if (VIA_DEBUG) fprintf(stderr, "StencilBits = 8\n");
+#endif
+       }
+#ifdef DEBUG
+       if (VIA_DEBUG) fprintf(stderr, "resizebuffer depthbuffer: w = %d h = %d bpp = %d sizs = %d\n", 
+                                   w, h, vmesa->depth.bpp, vmesa->depth.size);
+#endif 
+       /*=* John Sheng [2003.5.31] flip *=*/
+       {
+           if(vmesa->viaScreen->width == vmesa->driDrawable->w &&
+               vmesa->viaScreen->height == vmesa->driDrawable->h) {
+               vmesa->back.pitch = vmesa->front.pitch;
+               vmesa->back.size = vmesa->front.size;
+           }
+       }
+    
+       if (!AllocateBuffer(vmesa)) {
+           FREE(vmesa);
+       }
+    }
+    UNLOCK_HARDWARE(vmesa);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+static void viaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
+
+{      
+    /* MESA5.0 */
+    viaContextPtr vmesa = current_mesa;
+    *width = vmesa->driDrawable->w;
+    *height = vmesa->driDrawable->h;
+}
+
+static void viaInitExtensions(GLcontext *ctx)
+{
+    _mesa_enable_imaging_extensions(ctx);
+    _mesa_enable_extension(ctx, "GL_ARB_multitexture");
+    _mesa_enable_extension(ctx, "GL_ARB_texture_env_add");
+    _mesa_enable_extension(ctx, "GL_EXT_texture_env_add");
+    _mesa_enable_extension(ctx, "GL_EXT_stencil_wrap");
+    _mesa_enable_extension(ctx, "GL_EXT_texture_lod_bias");
+    /*=* John Sheng [2003.7.18] texture combine *=*/
+    _mesa_enable_extension(ctx, "GL_ARB_texture_env_combine");
+    _mesa_enable_extension(ctx, "GL_EXT_texture_env_combine");
+    /*=* John Sheng [2003.7.18] texture dot3 *=*/
+    _mesa_enable_extension(ctx, "GL_ARB_texture_env_dot3");
+    _mesa_enable_extension(ctx, "GL_EXT_texture_env_dot3");
+    /*=* John Sheng [2003.7.18] point parameters */
+    _mesa_enable_extension(ctx, "GL_ARB_point_parameters");
+    _mesa_enable_extension(ctx, "GL_EXT_point_parameters");
+}
+
+extern const struct tnl_pipeline_stage _via_fastrender_stage;
+extern const struct tnl_pipeline_stage _via_render_stage;
+
+static const struct tnl_pipeline_stage *via_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
+    &_via_fastrender_stage,     /* ADD: unclipped rastersetup-to-dma */
+    &_via_render_stage,         /* ADD: modification from _tnl_render_stage */
+#endif
+    &_tnl_render_stage,
+    0,
+};
+
+
+static GLboolean
+AllocateDmaBuffer(const GLvisual *visual, viaContextPtr vmesa)
+{
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    if (vmesa->dma[0].map && vmesa->dma[1].map)
+        via_free_dma_buffer(vmesa);
+    
+    if (!via_alloc_dma_buffer(vmesa)) {
+       if (vmesa->front.map)
+           via_free_front_buffer(vmesa);
+        if (vmesa->back.map) 
+           via_free_back_buffer(vmesa);
+        if (vmesa->depth.map)
+           via_free_depth_buffer(vmesa);
+           
+        return GL_FALSE;
+    }   
+#ifdef DEBUG 
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+    return GL_TRUE;
+}
+
+static void
+InitVertexBuffer(viaContextPtr vmesa)
+{
+    GLuint *addr;
+
+    addr = (GLuint *)vmesa->dma[0].map;
+    *addr = 0xF210F110;
+    *addr = (HC_ParaType_NotTex << 16);
+    *addr = 0xcccccccc;
+    *addr = 0xdddddddd;
+    
+    addr = (GLuint *)vmesa->dma[1].map;
+    *addr = 0xF210F110;
+    *addr = (HC_ParaType_NotTex << 16);
+    *addr = 0xcccccccc;
+    *addr = 0xdddddddd;
+
+    vmesa->dmaIndex = 0;
+    vmesa->dmaLow = DMA_OFFSET;
+    vmesa->dmaHigh = vmesa->dma[0].size;
+    vmesa->dmaAddr = (unsigned char *)vmesa->dma[0].map;
+    vmesa->dmaLastPrim = vmesa->dmaLow;
+}
+
+static void
+FreeBuffer(viaContextPtr vmesa)
+{
+    if (vmesa->front.map)
+       via_free_front_buffer(vmesa);
+
+    if (vmesa->back.map)
+        via_free_back_buffer(vmesa);
+
+    if (vmesa->depth.map)
+        via_free_depth_buffer(vmesa);
+
+    if (vmesa->dma[0].map && vmesa->dma[1].map)
+        via_free_dma_buffer(vmesa);
+}
+
+GLboolean
+viaCreateContext(const __GLcontextModes *mesaVis,
+                 __DRIcontextPrivate *driContextPriv,
+                 void *sharedContextPrivate)
+{
+    GLcontext *ctx, *shareCtx;
+    viaContextPtr vmesa;
+    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+    viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
+    drm_via_sarea_t *saPriv = (drm_via_sarea_t *)
+        (((GLubyte *)sPriv->pSAREA) + viaScreen->sareaPrivOffset);
+    struct dd_function_table functions;
+
+    /* Allocate via context */
+    vmesa = (viaContextPtr) CALLOC_STRUCT(via_context_t);
+    if (!vmesa) {
+        return GL_FALSE;
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+    current_mesa = vmesa;    
+    /* pick back buffer */
+    if (mesaVis->doubleBufferMode) {
+       vmesa->hasBack = GL_TRUE;
+    }
+    else {
+       vmesa->hasBack = GL_FALSE;
+    }
+    /* pick z buffer */        
+    if (mesaVis->haveDepthBuffer) {
+       vmesa->hasDepth = GL_TRUE;
+       vmesa->depthBits = mesaVis->depthBits;
+    }
+    else {
+       vmesa->hasDepth = GL_FALSE;
+       vmesa->depthBits = 0;
+    }
+    /* pick stencil buffer */
+    if (mesaVis->haveStencilBuffer) {
+       vmesa->hasStencil = GL_TRUE;
+       vmesa->stencilBits = mesaVis->stencilBits;
+    }
+    else {
+       vmesa->hasStencil = GL_FALSE;
+       vmesa->stencilBits = 0;
+    }
+
+    _mesa_init_driver_functions(&functions);
+    viaInitTextureFuncs(&functions);
+
+    /* Allocate the Mesa context */
+    if (sharedContextPrivate)
+        shareCtx = ((viaContextPtr) sharedContextPrivate)->glCtx;
+    else
+        shareCtx = NULL;
+
+    vmesa->glCtx = _mesa_create_context(mesaVis, shareCtx, &functions, (void*) vmesa);
+    
+    vmesa->shareCtx = shareCtx;
+    
+    if (!vmesa->glCtx) {
+        FREE(vmesa);
+        return GL_FALSE;
+    }
+    driContextPriv->driverPrivate = vmesa;
+
+    ctx = vmesa->glCtx;
+    
+    /* check */
+    /*=* John Sheng [2003.7.2] for visual config number can't excess 8 *=*/
+    /*if (viaScreen->textureSize < 2 * 1024 * 1024) {
+        ctx->Const.MaxTextureLevels = 9;
+    }
+    else if (viaScreen->textureSize < 8 * 1024 * 1024) {
+        ctx->Const.MaxTextureLevels = 10;
+    }
+    else {
+        ctx->Const.MaxTextureLevels = 11;
+    }*/
+    ctx->Const.MaxTextureLevels = 11;
+    
+    ctx->Const.MaxTextureUnits = 2;
+
+    ctx->Const.MinLineWidth = 1.0;
+    ctx->Const.MinLineWidthAA = 1.0;
+    ctx->Const.MaxLineWidth = 3.0;
+    ctx->Const.MaxLineWidthAA = 3.0;
+    ctx->Const.LineWidthGranularity = 1.0;
+
+    ctx->Const.MinPointSize = 1.0;
+    ctx->Const.MinPointSizeAA = 1.0;
+    ctx->Const.MaxPointSize = 3.0;
+    ctx->Const.MaxPointSizeAA = 3.0;
+    ctx->Const.PointSizeGranularity = 1.0;
+
+    ctx->Driver.GetBufferSize = viaBufferSize;
+/*    ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;  *//* FIXME ?? */
+    ctx->Driver.GetString = viaGetString;
+
+    ctx->DriverCtx = (void *)vmesa;
+    vmesa->glCtx = ctx;
+
+    /* 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, via_pipeline);
+
+    /* Configure swrast to match hardware characteristics:
+     */
+    _swrast_allow_pixel_fog(ctx, GL_FALSE);
+    _swrast_allow_vertex_fog(ctx, GL_TRUE);
+
+#ifndef _SOLO
+    vmesa->display = dpy;
+    vmesa->display = sPriv->display;
+#endif
+    
+    vmesa->hHWContext = driContextPriv->hHWContext;
+    vmesa->driFd = sPriv->fd;
+    vmesa->driHwLock = &sPriv->pSAREA->lock;
+
+    vmesa->viaScreen = viaScreen;
+    vmesa->driScreen = sPriv;
+    vmesa->sarea = saPriv;
+    vmesa->glBuffer = NULL;
+
+    vmesa->texHeap = mmInit(0, viaScreen->textureSize);
+    vmesa->stippleInHw = 1;
+    vmesa->renderIndex = ~0;
+    vmesa->dirty = VIA_UPLOAD_ALL;
+    vmesa->uploadCliprects = GL_TRUE;
+    vmesa->needUploadAllState = 1;
+
+    make_empty_list(&vmesa->TexObjList);
+    make_empty_list(&vmesa->SwappedOut);
+
+    vmesa->CurrentTexObj[0] = 0;
+    vmesa->CurrentTexObj[1] = 0;
+    
+    vmesa->dma[0].size = DMA_SIZE * 1024 * 1024;
+    vmesa->dma[1].size = DMA_SIZE * 1024 * 1024;
+
+    _math_matrix_ctr(&vmesa->ViewportMatrix);
+
+    viaInitExtensions(ctx);
+    viaInitStateFuncs(ctx);
+    viaInitTextures(ctx);
+    viaInitTriFuncs(ctx);
+    viaInitSpanFuncs(ctx);
+    viaInitIoctlFuncs(ctx);
+    viaInitVB(ctx);
+    viaInitState(ctx);
+        
+    if (getenv("VIA_DEBUG"))
+       VIA_DEBUG = 1;
+    else
+       VIA_DEBUG = 0;  
+       
+    if (getenv("DRAW_FRONT"))
+       DRAW_FRONT = 1;
+    else
+       DRAW_FRONT = 0; 
+       
+#ifdef PERFORMANCE_MEASURE
+    if (getenv("VIA_PERFORMANCE"))
+       VIA_PERFORMANCE = 1;
+    else
+       VIA_PERFORMANCE = 0;    
+       
+    {
+       int i, j;
+       for (i = 0; i < HASH_TABLE_SIZE; i++) {
+           for (j = 0; j < HASH_TABLE_DEPTH; j ++) {
+               hash_table[i][j].count = 0;
+               sprintf(hash_table[i][j].func, "%s", "NULL");
+           }
+       }
+    }
+#endif 
+
+    if (!AllocateDmaBuffer(mesaVis, vmesa)) {
+       fprintf(stderr ,"AllocateDmaBuffer fail\n");
+        FREE(vmesa);
+        return GL_FALSE;
+    }
+
+    InitVertexBuffer(vmesa);
+    
+    vmesa->regMMIOBase = (GLuint *)((GLuint)viaScreen->reg);
+    vmesa->pnGEMode = (GLuint *)((GLuint)viaScreen->reg + 0x4);
+    vmesa->regEngineStatus = (GLuint *)((GLuint)viaScreen->reg + 0x400);
+    vmesa->regTranSet = (GLuint *)((GLuint)viaScreen->reg + 0x43C);
+    vmesa->regTranSpace = (GLuint *)((GLuint)viaScreen->reg + 0x440);
+    vmesa->agpBase = viaScreen->agpBase;
+#ifdef DEBUG    
+    if (VIA_DEBUG) {
+       fprintf(stderr, "regEngineStatus = %x\n", *vmesa->regEngineStatus);
+    }
+    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+    {
+       GLboolean saam;
+       int count = 0, fbSize;
+#ifdef _SOLO
+        vmesa->saam = 0;
+#else
+       saam = XineramaIsActive(vmesa->display);
+       if (saam && vmesa->viaScreen->drixinerama) {
+           vmesa->xsi = XineramaQueryScreens(vmesa->display, &count);
+           /* Test RightOf or Down */
+           if (vmesa->xsi[0].x_org == 0 && vmesa->xsi[0].y_org == 0) {
+               if (vmesa->xsi[1].x_org == vmesa->xsi[1].width) {
+                   vmesa->saam = RightOf;
+               }
+               else {
+                   vmesa->saam = Down;
+               }
+           }
+           /* Test LeftOf or Up */
+           else if (vmesa->xsi[0].x_org == vmesa->xsi[0].width) {
+               vmesa->saam = LeftOf;
+           }
+           else if (vmesa->xsi[0].y_org == vmesa->xsi[0].height) {
+               vmesa->saam = Up;
+           }
+           else
+               vmesa->saam = 0;
+               
+                   
+           fbSize = vmesa->viaScreen->fbSize;
+       }
+       else
+           vmesa->saam = 0;
+#endif
+    }
+    
+    vmesa->pSaamRects = (XF86DRIClipRectPtr) malloc(sizeof(XF86DRIClipRectRec));    
+    return GL_TRUE;
+}
+
+void
+viaDestroyContext(__DRIcontextPrivate *driContextPriv)
+{
+    viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+    assert(vmesa); /* should never be null */
+    viaFlushPrimsLocked(vmesa);
+    WAIT_IDLE
+    if (vmesa) {
+       /*=* John Sheng [2003.5.31] flip *=*/
+       if(vmesa->doPageFlip) {
+           *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x43c)) = 0x00fe0000;
+           *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x440)) = 0x00001004;
+           WAIT_IDLE
+           *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x214)) = 0;
+       }
+       /*=* John Sheng [2003.5.31]  agp tex *=*/
+       if(VIA_DEBUG) fprintf(stderr, "agpFullCount = %d\n", agpFullCount);    
+       
+       _swsetup_DestroyContext(vmesa->glCtx);
+        _tnl_DestroyContext(vmesa->glCtx);
+        _ac_DestroyContext(vmesa->glCtx);
+        _swrast_DestroyContext(vmesa->glCtx);
+        viaFreeVB(vmesa->glCtx);
+       FreeBuffer(vmesa);
+        /* free the Mesa context */
+       _mesa_destroy_context(vmesa->glCtx);
+       vmesa->glCtx->DriverCtx = NULL;
+        FREE(vmesa);
+    }
+    
+    P_M_R;
+
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) fprintf(stderr, "idle = %d\n", idle);
+    if (VIA_PERFORMANCE) fprintf(stderr, "busy = %d\n", busy);
+#endif    
+#ifdef DEBUG        
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+void viaXMesaSetFrontClipRects(viaContextPtr vmesa)
+{
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+
+    vmesa->numClipRects = dPriv->numClipRects;
+    vmesa->pClipRects = dPriv->pClipRects;
+    vmesa->drawX = dPriv->x;
+    vmesa->drawY = dPriv->y;
+    vmesa->drawW = dPriv->w;
+    vmesa->drawH = dPriv->h;
+
+    viaEmitDrawingRectangle(vmesa);
+    vmesa->uploadCliprects = GL_TRUE;
+}
+
+void viaXMesaSetBackClipRects(viaContextPtr vmesa)
+{
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+    /*=* John Sheng [2003.6.9] fix glxgears dirty screen */
+    /*if (vmesa->saam) {*/
+           vmesa->numClipRects = dPriv->numClipRects;
+           vmesa->pClipRects = dPriv->pClipRects;
+           vmesa->drawX = dPriv->x;
+           vmesa->drawY = dPriv->y;
+           vmesa->drawW = dPriv->w;
+           vmesa->drawH = dPriv->h;
+    /*}
+    else {
+       if (dPriv->numBackClipRects == 0) {
+           vmesa->numClipRects = dPriv->numClipRects;
+           vmesa->pClipRects = dPriv->pClipRects;
+           vmesa->drawX = dPriv->x;
+           vmesa->drawY = dPriv->y;
+           vmesa->drawW = dPriv->w;
+           vmesa->drawH = dPriv->h;
+       }
+       else {
+           vmesa->numClipRects = dPriv->numBackClipRects;
+           vmesa->pClipRects = dPriv->pBackClipRects;
+           vmesa->drawX = dPriv->backX;
+           vmesa->drawY = dPriv->backY;
+           vmesa->drawW = dPriv->w;
+           vmesa->drawH = dPriv->h;
+       }
+    }*/
+    viaEmitDrawingRectangle(vmesa);
+    vmesa->uploadCliprects = GL_TRUE;
+}
+
+void viaXMesaWindowMoved(viaContextPtr vmesa)
+{
+    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+    GLuint side = 0;
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+    
+    GLuint destMask = vmesa->glCtx->Color._DrawDestMask;
+    if (destMask & FRONT_LEFT_BIT)
+        viaXMesaSetFrontClipRects(vmesa);
+    if (destMask & BACK_LEFT_BIT)
+        viaXMesaSetBackClipRects(vmesa);
+
+#ifdef _SOLO
+    vmesa->viaScreen->fbOffset = 0;
+    vmesa->saam &= ~S1;
+    vmesa->saam |= S0;
+#else
+    side = vmesa->saam & P_MASK;
+    
+    switch (side) {
+       case RightOf:
+           /* full in screen 1 */
+           if (vmesa->drawX >= vmesa->xsi[0].width) {
+               vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
+               vmesa->drawX = vmesa->drawX - vmesa->xsi[1].width;
+               vmesa->numClipRects = dPriv->numBackClipRects;
+               vmesa->pClipRects = dPriv->pBackClipRects;
+               vmesa->drawX = dPriv->backX;
+               vmesa->drawY = dPriv->backY;
+               vmesa->saam &= ~S0;
+               vmesa->saam |= S1;
+           }
+           /* full in screen 0 */
+           else if ((vmesa->drawX + vmesa->drawW) <= vmesa->xsi[0].width) {
+               vmesa->viaScreen->fbOffset = 0;
+               vmesa->saam &= ~S1;
+               vmesa->saam |= S0;
+           }
+           /* between screen 0 && screen 1 */
+           else {
+               vmesa->numSaamRects = dPriv->numBackClipRects;
+               vmesa->pSaamRects = dPriv->pBackClipRects;
+               vmesa->drawXSaam = dPriv->backX;
+               vmesa->drawYSaam = dPriv->backY;
+               vmesa->viaScreen->fbOffset = 0;
+               vmesa->saam |= S0;
+               vmesa->saam |= S1;
+           }
+           break;
+       case LeftOf:
+           /* full in screen 1 */
+           if (vmesa->drawX + vmesa->drawW <= 0) {
+               vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
+               vmesa->drawX = vmesa->drawX + vmesa->xsi[1].width;
+               vmesa->numClipRects = dPriv->numBackClipRects;
+               vmesa->pClipRects = dPriv->pBackClipRects;
+               vmesa->drawX = dPriv->backX;
+               vmesa->drawY = dPriv->backY;            
+               vmesa->saam &= ~S0;
+               vmesa->saam |= S1;
+           }
+           /* full in screen 0 */
+           else if (vmesa->drawX >= 0) {
+               vmesa->viaScreen->fbOffset = 0;
+               vmesa->saam &= ~S1;
+               vmesa->saam |= S0;
+           }
+           /* between screen 0 && screen 1 */
+           else {
+               vmesa->numSaamRects = dPriv->numBackClipRects;
+               vmesa->pSaamRects = dPriv->pBackClipRects;
+               vmesa->drawXSaam = dPriv->backX;
+               vmesa->drawYSaam = dPriv->backY;
+               vmesa->viaScreen->fbOffset = 0;
+               vmesa->saam |= S0;
+               vmesa->saam |= S1;
+           }
+           break;
+       case Down :
+           /* full in screen 1 */
+           if (vmesa->drawY >= vmesa->xsi[0].height) {
+               vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
+               vmesa->drawY = vmesa->drawY - vmesa->xsi[1].height;
+               vmesa->numClipRects = dPriv->numBackClipRects;
+               vmesa->pClipRects = dPriv->pBackClipRects;
+               vmesa->drawX = dPriv->backX;
+               vmesa->drawY = dPriv->backY;
+               vmesa->saam &= ~S0;
+               vmesa->saam |= S1;
+           }
+           /* full in screen 0 */
+           else if ((vmesa->drawY + vmesa->drawH) <= vmesa->xsi[0].height) {
+               vmesa->viaScreen->fbOffset = 0;
+               vmesa->saam &= ~S1;
+               vmesa->saam |= S0;
+           }
+           /* between screen 0 && screen 1 */
+           else {
+               vmesa->numSaamRects = dPriv->numBackClipRects;
+               vmesa->pSaamRects = dPriv->pBackClipRects;
+               vmesa->drawXSaam = dPriv->backX;
+               vmesa->drawYSaam = dPriv->backY;
+               vmesa->viaScreen->fbOffset = 0;
+               vmesa->saam |= S0;
+               vmesa->saam |= S1;
+           }
+           break;
+       case Up :
+           /* full in screen 1 */
+           if ((vmesa->drawY + vmesa->drawH) <= 0) {
+               vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
+               vmesa->drawY = vmesa->drawY + vmesa->xsi[1].height;
+               vmesa->numClipRects = dPriv->numBackClipRects;
+               vmesa->pClipRects = dPriv->pBackClipRects;
+               vmesa->drawX = dPriv->backX;
+               vmesa->drawY = dPriv->backY;
+               vmesa->saam &= ~S0;
+               vmesa->saam |= S1;
+           }
+           /* full in screen 0 */
+           else if (vmesa->drawY >= 0) {
+               vmesa->viaScreen->fbOffset = 0;
+               vmesa->saam &= ~S1;
+               vmesa->saam |= S0;
+           }
+           /* between screen 0 && screen 1 */
+           else {
+               vmesa->numSaamRects = dPriv->numBackClipRects;
+               vmesa->pSaamRects = dPriv->pBackClipRects;
+               vmesa->drawXSaam = dPriv->backX;
+               vmesa->drawYSaam = dPriv->backY;
+               vmesa->viaScreen->fbOffset = 0;
+               vmesa->saam |= S0;
+               vmesa->saam |= S1;
+           }
+           break;
+       default:
+           vmesa->viaScreen->fbOffset = 0;
+    }
+#endif
+    
+    {
+       GLuint pitch, offset;
+       pitch = vmesa->front.pitch;
+       offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel);
+       vmesa->drawXoff = (GLuint)((offset & 0x1f) / bytePerPixel);
+       if (vmesa->saam) {
+           if (vmesa->pSaamRects) {
+               offset = vmesa->viaScreen->fbOffset + (vmesa->pSaamRects[0].y1 * pitch + 
+                   vmesa->pSaamRects[0].x1 * bytePerPixel);
+               vmesa->drawXoffSaam = (GLuint)((offset & 0x1f) / bytePerPixel);
+           }
+           else
+               vmesa->drawXoffSaam = 0;
+       }
+       else
+           vmesa->drawXoffSaam = 0;
+    }
+    
+    vmesa->glCtx->Driver.Viewport(vmesa->glCtx,0 ,0 ,0 ,0);
+}
+
+GLboolean
+viaUnbindContext(__DRIcontextPrivate *driContextPriv)
+{
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+    return GL_TRUE;
+}
+
+GLboolean
+viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
+               __DRIdrawablePrivate *driDrawPriv,
+               __DRIdrawablePrivate *driReadPriv)
+{
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+  
+    if (VIA_DEBUG) {
+       fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driContextPriv);
+       fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driDrawPriv);    
+       fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driReadPriv);
+    }  
+#endif    
+    
+    if (driContextPriv) {
+        viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
+       current_mesa = vmesa;
+       
+       vmesa->driDrawable = driDrawPriv;
+       if (vmesa->drawType == GLX_PBUFFER_BIT) {
+           int w, h, bpp;
+           
+           w = vmesa->driDrawable->w;
+           h = vmesa->driDrawable->h;
+           bpp = vmesa->viaScreen->bitsPerPixel;
+           if (bpp == 32) {
+               w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4;
+               vmesa->front.size = w * h * bpp / 8;
+               vmesa->front.pitch = w << 2;
+           }
+           else {
+               w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2;
+               vmesa->front.size = w * h * bpp / 8;
+               vmesa->front.pitch = w << 1;           
+           }   
+       }
+       /*=* John Sheng [2003.6.20] fix resolution 720x480/720x576 front pitch error *=*/
+       else { 
+           GLuint w;
+           GLuint h;
+           GLuint bpp;
+           bpp = vmesa->viaScreen->bitsPerPixel;
+           h = vmesa->viaScreen->height;
+           w = vmesa->viaScreen->width;
+           if (bpp == 0x20) {
+               w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4;
+               vmesa->front.size = w * h * bpp / 8;
+               vmesa->front.pitch = w << 2;
+#ifdef DEBUG
+               if (VIA_DEBUG) fprintf(stderr, "viaScreen->bitsPerPixel = %d\n", 32);       
+#endif
+           } 
+           else if (bpp == 0x10) {
+               w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2;
+               vmesa->front.size = w * h * bpp / 8;
+               vmesa->front.pitch = w << 1;           
+#ifdef DEBUG
+               if (VIA_DEBUG) fprintf(stderr, "viaScreen->bitsPerPixel = %d\n", 16);       
+#endif
+           }
+           vmesa->front.offset = 0;
+           vmesa->front.map = (char *) vmesa->driScreen->pFB;
+           vmesa->front.size = w * h * vmesa->viaScreen->bitsPerPixel /8;
+       }
+       
+       /* Allocate back & depth buffer */
+       {
+           int w, h, bpp;
+           
+           w = vmesa->driDrawable->w;
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent: w = %d\n", w);          
+#endif     
+           h = vmesa->driDrawable->h;
+           
+           /* back buffer */
+           bpp = vmesa->viaScreen->bitsPerPixel;
+#ifdef DEBUG       
+           if (VIA_DEBUG) fprintf(stderr, "driScreen->fbBPP = %d\n", bpp);         
+#endif     
+           if (bpp == 32) {
+               if (vmesa->drawType == GLX_PBUFFER_BIT)
+                   w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4;
+               else
+                   w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
+               
+               vmesa->back.size = w * h * bpp / 8;
+               vmesa->back.pitch = w << 2;
+           }
+           else {
+               if (vmesa->drawType == GLX_PBUFFER_BIT)
+                   w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2;
+               else
+                   w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2 + 16;
+               
+               vmesa->back.size = w * h * bpp / 8;
+               vmesa->back.pitch = w << 1;            
+           }
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent backbuffer: w = %d h = %d bpp = %d sizs = %d\n", 
+                                   w, h, bpp, vmesa->back.size);
+#endif
+           /* depth buffer */
+           w = vmesa->driDrawable->w;
+
+           if (vmesa->hasDepth && vmesa->hasStencil) {
+               if (vmesa->drawType == GLX_PBUFFER_BIT)
+                   w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4;
+               else
+                   w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
+
+               vmesa->depth.size = w * h * 4;
+               vmesa->depth.pitch = w << 2;
+               vmesa->depth.bpp = 32;
+#ifdef DEBUG
+               if (VIA_DEBUG) fprintf(stderr, "depthBits = 24\n");
+               if (VIA_DEBUG) fprintf(stderr, "StencilBits = 8\n");
+#endif
+           }
+           else if (vmesa->hasDepth) {
+
+               /*=* John Sheng [2003.6.16] patch viewperf drv-08 draw nothing */
+               /*if(vmesa->viaScreen->bitsPerPixel == 32)*/
+                   /*vmesa->depthBits = 16;*/
+                   
+               if (vmesa->depthBits == 16) {
+                   if (vmesa->drawType == GLX_PBUFFER_BIT)
+                       w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2;
+                   else
+                       w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2 + 16;
+
+                   vmesa->depth.size = w * h * 2;             
+                   vmesa->depth.pitch = w << 1;
+                   vmesa->depth.bpp = 16;
+#ifdef DEBUG
+                   if (VIA_DEBUG) fprintf(stderr, "depthBits = 16\n");
+#endif
+               }
+               else {
+                   if (vmesa->drawType == GLX_PBUFFER_BIT)
+                       w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4;
+                   else
+                       w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
+
+                   vmesa->depth.size = w * h * 4;
+                   vmesa->depth.pitch = w << 2;
+                   vmesa->depth.bpp = 32;
+#ifdef DEBUG
+                   if (VIA_DEBUG) fprintf(stderr, "depthBits = 32\n");
+#endif
+               }
+           }
+           else if (vmesa->hasStencil) {
+               if (vmesa->drawType == GLX_PBUFFER_BIT)
+                   w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4;
+               else
+                   w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8;
+
+               vmesa->depth.size = w * h * 4;
+               vmesa->depth.pitch = w << 2;
+               vmesa->depth.bpp = 32;
+#ifdef DEBUG           
+               if (VIA_DEBUG) fprintf(stderr, "StencilBits = 8\n");
+#endif
+           }
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent depthbuffer: w = %d h = %d bpp = %d sizs = %d\n", 
+                                  w, h, vmesa->depth.bpp, vmesa->depth.size);
+#endif     
+           /*=* John Sheng [2003.5.31] flip *=*/
+           {
+               viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;     
+               if(vmesa->viaScreen->width == vmesa->driDrawable->w &&
+                   vmesa->viaScreen->height == vmesa->driDrawable->h) {
+                   vmesa->doPageFlip = GL_FALSE;
+                   vmesa->currentPage = 0;
+                   vmesa->back.pitch = vmesa->front.pitch;
+               }
+           }
+
+           if (!AllocateBuffer(vmesa)) {
+               FREE(vmesa);
+               return GL_FALSE;
+           }
+       }
+        _mesa_make_current2(vmesa->glCtx,
+                            (GLframebuffer *)driDrawPriv->driverPrivate,
+                            (GLframebuffer *)driReadPriv->driverPrivate);
+#ifdef DEBUG   
+       if (VIA_DEBUG) fprintf(stderr, "Context %d MakeCurrent\n", vmesa->hHWContext);
+#endif
+        viaXMesaWindowMoved(vmesa);
+        if (!vmesa->glCtx->Viewport.Width)
+            _mesa_set_viewport(vmesa->glCtx, 0, 0,
+                               driDrawPriv->w, driDrawPriv->h);
+    }
+    else {
+        _mesa_make_current(0,0);
+    }
+        
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+    return GL_TRUE;
+}
+
+void viaGetLock(viaContextPtr vmesa, GLuint flags)
+{
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+    __DRIscreenPrivate *sPriv = vmesa->driScreen;
+    drm_via_sarea_t *sarea = vmesa->sarea;
+    int me = vmesa->hHWContext;
+    __DRIdrawablePrivate *pdp;
+    __DRIscreenPrivate *psp;
+    pdp = dPriv;
+    psp = sPriv;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);  
+    if (VIA_DEBUG) fprintf(stderr, "drmGetLock - in\n");
+#endif
+    drmGetLock(vmesa->driFd, vmesa->hHWContext, flags);
+
+    do {
+           DRM_UNLOCK(psp->fd, &psp->pSAREA->lock,
+                  pdp->driContextPriv->hHWContext);
+           DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+#ifdef _SOLO
+            __driUtilUpdateDrawableInfo(dPriv);
+#else
+           __driUtilUpdateDrawableInfo(vmesa->display, psp->myNum, dPriv);
+#endif
+           DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+           DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock,
+                      pdp->driContextPriv->hHWContext);
+    } while (0);
+
+    if (sarea->ctxOwner != me) {
+        vmesa->uploadCliprects = GL_TRUE;
+        sarea->ctxOwner = me;
+    }
+
+    viaXMesaWindowMoved(vmesa);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
+void viaLock(viaContextPtr vmesa, GLuint flags)
+{
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+    __DRIscreenPrivate *sPriv = vmesa->driScreen;
+    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+   
+    /*=* John Sheng [2003.6.16] for xf43 */
+    if(dPriv->pStamp == NULL)
+       dPriv->pStamp = &dPriv->lastStamp;
+
+    if (*(dPriv->pStamp) != dPriv->lastStamp || vmesa->saam) {
+       GLuint scrn;
+       scrn = vmesa->saam & S_MASK;
+       
+       DRM_SPINLOCK(&sPriv->pSAREA->drawable_lock, sPriv->drawLockID);
+
+#ifdef _SOLO
+        __driUtilUpdateDrawableInfo(dPriv);
+#else
+       if (scrn == S1)
+           __driUtilUpdateDrawableInfo(vmesa->display, scrn, dPriv);
+       else
+           DRI_VALIDATE_DRAWABLE_INFO_ONCE(vmesa->display, scrn, dPriv);
+#endif
+           
+       viaXMesaWindowMoved(vmesa);
+       DRM_SPINUNLOCK(&sPriv->pSAREA->drawable_lock, sPriv->drawLockID);
+    }
+
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+    
+    return;
+}
+
+void viaUnLock(viaContextPtr vmesa, GLuint flags)
+{
+    drm_via_sarea_t *sarea = vmesa->sarea;
+    int me = vmesa->hHWContext;
+    
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+    if (VIA_DEBUG) fprintf(stderr, "sarea->ctxOwner = %d\n", sarea->ctxOwner);
+    if (VIA_DEBUG) fprintf(stderr, "me = %d\n", me);
+#endif    
+    if (sarea->ctxOwner == me) {
+        sarea->ctxOwner = 0;
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
+void
+viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
+{
+    __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *)drawablePrivate;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); 
+#endif
+    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+        viaContextPtr vmesa;
+        GLcontext *ctx;
+       
+        vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate;
+        ctx = vmesa->glCtx;
+        if (ctx->Visual.doubleBufferMode) {
+#ifdef _SOLO
+            _mesa_notifySwapBuffers(ctx);
+#else
+            _mesa_swapbuffers(ctx);
+#endif
+            if (vmesa->doPageFlip) {
+                viaPageFlip(dPriv);
+            }
+            else {
+                viaCopyBuffer(dPriv);
+            }
+        }
+       else
+           VIA_FIREVERTICES(vmesa);
+    }
+    else {
+        _mesa_problem(NULL, "viaSwapBuffers: drawable has no context!\n");
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);        
+#endif
+}
diff --git a/src/mesa/drivers/dri/unichrome/via_context.h b/src/mesa/drivers/dri/unichrome/via_context.h
new file mode 100644 (file)
index 0000000..06e7b8b
--- /dev/null
@@ -0,0 +1,486 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _VIACONTEXT_H
+#define _VIACONTEXT_H
+
+typedef struct via_context_t viaContext;
+typedef struct via_context_t *viaContextPtr;
+typedef struct via_texture_object_t *viaTextureObjectPtr;
+
+#include "dri_util.h"
+
+#ifndef _SOLO
+#include <X11/Xlibint.h>
+#endif
+
+#include "mtypes.h"
+#include "drm.h"
+#include "mm.h"
+
+#include "via_screen.h"
+#include "via_tex.h"
+#include "via_common.h"
+#include "xf86drmVIA.h"
+#ifndef _SOLO
+#include "../../../../../include/extensions/Xinerama.h"
+#endif
+#define VIA_FALLBACK_TEXTURE                   0x1
+#define VIA_FALLBACK_DRAW_BUFFER               0x2
+#define VIA_FALLBACK_READ_BUFFER               0x4
+#define VIA_FALLBACK_COLORMASK                 0x8
+#define VIA_FALLBACK_SPECULAR                  0x20
+#define VIA_FALLBACK_LOGICOP                   0x40
+#define VIA_FALLBACK_RENDERMODE                0x80
+#define VIA_FALLBACK_STENCIL                   0x100
+#define VIA_FALLBACK_BLEND_EQ                  0x200
+#define VIA_FALLBACK_BLEND_FUNC                0x400
+
+#define VIA_UPLOAD_NONE                        0x0000
+#define VIA_UPLOAD_ALPHATEST           0x0001
+#define VIA_UPLOAD_BLEND               0x0002
+#define VIA_UPLOAD_FOG                         0x0004
+#define VIA_UPLOAD_MASK_ROP            0x0008
+#define VIA_UPLOAD_LINESTIPPLE         0x0010
+#define VIA_UPLOAD_POLYGONSTIPPLE      0x0020
+#define VIA_UPLOAD_DEPTH               0x0040
+#define VIA_UPLOAD_TEXTURE             0x0080
+#define VIA_UPLOAD_STENCIL             0x0100
+#define VIA_UPLOAD_CLIPPING            0x0200
+#define VIA_UPLOAD_DESTBUFFER          0x0400
+#define VIA_UPLOAD_DEPTHBUFFER         0x0800
+#define VIA_UPLOAD_ENABLE              0x0800
+#define VIA_UPLOAD_ALL                         0x1000
+               
+/* Use the templated vertex formats:
+ */
+#define TAG(x) via##x
+#include "tnl_dd/t_dd_vertex.h"
+#undef TAG
+#define BUFFER_ALIGNMENT 32
+#define BUFFER_ALIGN_WIDTH1(w, a)   (((w) + ((a) - 1)) & ~((a) - 1))
+#define BUFFER_ALIGN_WIDTH(w, a)    (((w) & ((a) - 1)) ? BUFFER_ALIGN_WIDTH1(w, a) : (w))
+#define BUFFER_ALIGN_ADDRESS(p, a)  ((GLvoid *)(((GLint)(p)) + ((a)-1) & ~((a)-1)))
+#define RightOf 1
+#define LeftOf 2
+#define Down 4
+#define Up 8
+#define S0 16
+#define S1 32
+#define P_MASK 0x0f;
+#define S_MASK 0x30;
+typedef void (*via_tri_func)(viaContextPtr, viaVertex *, viaVertex *,
+                             viaVertex *);
+typedef void (*via_line_func)(viaContextPtr, viaVertex *, viaVertex *);
+typedef void (*via_point_func)(viaContextPtr, viaVertex *);
+
+typedef struct {
+    drmHandle handle;
+    drmSize size;
+    GLuint offset;
+    GLuint index;
+    GLuint pitch;
+    GLuint bpp;
+    char *map;
+} viaBuffer, *viaBufferPtr;
+
+typedef struct {
+    drmHandle handle;
+    drmSize size;
+    GLuint offset;
+    GLuint index;
+    unsigned char* map;
+} viaDmaBuffer, *viaDmaBufferPtr;
+
+struct via_context_t {
+    GLint refcount;   
+    GLcontext *glCtx;
+    GLcontext *shareCtx;
+    unsigned char* front_base;
+    viaBuffer front;
+    viaBuffer back;
+    viaBuffer depth;
+    GLboolean hasBack;
+    GLboolean hasDepth;
+    GLboolean hasStencil;
+    GLboolean hasAccum;
+    GLuint    depthBits;
+    GLuint    stencilBits;
+    viaDmaBuffer dma[2];
+    viaRegion tex;
+    
+    GLuint isAGP;
+
+    /* Textures
+    */
+    viaTextureObjectPtr CurrentTexObj[2];
+    struct via_texture_object_t TexObjList;
+    struct via_texture_object_t SwappedOut;
+    memHeap_t *texHeap;
+
+    /* Bit flag to keep 0track of fallbacks.
+     */
+    GLuint Fallback;
+
+    /* Temporaries for translating away float colors:
+     */
+    struct gl_client_array UbyteColor;
+    struct gl_client_array UbyteSecondaryColor;
+
+    /* State for via_vb.c and via_tris.c.
+     */
+    GLuint newState;            /* _NEW_* flags */
+    GLuint setupNewInputs;
+    GLuint setupIndex;
+    GLuint renderIndex;
+    GLmatrix ViewportMatrix;
+    GLenum renderPrimitive;
+    GLenum reducedPrimitive;
+    GLuint hwPrimitive;
+    unsigned char *verts;
+
+    /* drmBufPtr dma_buffer;
+    */
+    unsigned char* dmaAddr;
+    GLuint dmaIndex;
+    GLuint dmaLow;
+    GLuint dmaHigh;
+    GLuint dmaLastPrim;
+    GLboolean useAgp;
+   
+    GLboolean uploadCliprects;
+
+    GLuint needUploadAllState;
+    GLuint primitiveRendered;
+    
+
+    /* Fallback rasterization functions 
+     */
+    via_point_func drawPoint;
+    via_line_func drawLine;
+    via_tri_func drawTri;
+
+    /* Hardware register
+     */
+    GLuint regCmdA;
+    GLuint regCmdA_End;
+    GLuint regCmdB;
+
+    GLuint regEnable;
+    GLuint regHFBBMSKL;
+    GLuint regHROP;
+
+    GLuint regHZWTMD;
+    GLuint regHSTREF;
+    GLuint regHSTMD;
+
+    GLuint regHATMD;
+    GLuint regHABLCsat;
+    GLuint regHABLCop;
+    GLuint regHABLAsat;
+    GLuint regHABLAop;
+    GLuint regHABLRCa;
+    GLuint regHABLRFCa;
+    GLuint regHABLRCbias;
+    GLuint regHABLRCb;
+    GLuint regHABLRFCb;
+    GLuint regHABLRAa;
+    GLuint regHABLRAb;
+    GLuint regHFogLF;
+    GLuint regHFogCL;
+    GLuint regHFogCH;
+
+    GLuint regHLP;
+    GLuint regHLPRF;
+
+    GLuint regHTXnTB_0;
+    GLuint regHTXnMPMD_0;
+    GLuint regHTXnTBLCsat_0;
+    GLuint regHTXnTBLCop_0;
+    GLuint regHTXnTBLMPfog_0;
+    GLuint regHTXnTBLAsat_0;
+    GLuint regHTXnTBLRCb_0;
+    GLuint regHTXnTBLRAa_0;
+    GLuint regHTXnTBLRFog_0;
+    /*=* John Sheng [2003.7.18] texture combine *=*/
+    GLuint regHTXnTBLRCa_0;
+    GLuint regHTXnTBLRCc_0;
+    GLuint regHTXnTBLRCbias_0;
+
+    GLuint regHTXnTB_1;
+    GLuint regHTXnMPMD_1;
+    GLuint regHTXnTBLCsat_1;
+    GLuint regHTXnTBLCop_1;
+    GLuint regHTXnTBLMPfog_1;
+    GLuint regHTXnTBLAsat_1;
+    GLuint regHTXnTBLRCb_1;
+    GLuint regHTXnTBLRAa_1;
+    GLuint regHTXnTBLRFog_1;
+
+    /* Hardware state 
+     */
+    GLuint dirty;             
+    int vertex_size;
+    int vertex_stride_shift;
+    GLint lastStamp;
+    GLboolean stippleInHw;
+
+    GLenum TexEnvImageFmt[2];
+    GLuint ClearColor;
+    /* DRI stuff
+     */
+    GLuint needClip;
+    GLframebuffer *glBuffer;
+    GLboolean doPageFlip;
+    /*=* John Sheng [2003.5.31] flip *=*/
+    GLuint currentPage;
+    char *drawMap;               /* draw buffer address in virtual mem */
+    char *readMap;       
+    int drawX;                   /* origin of drawable in draw buffer */
+    int drawY;
+    
+    int drawW;                  
+    int drawH;
+    GLuint saam;
+#ifndef _SOLO
+    XineramaScreenInfo *xsi;
+#endif
+    int drawXoffSaam;
+    XF86DRIClipRectPtr pSaamRects;
+    int drawXSaam;
+    int drawYSaam;
+    GLuint numSaamRects;
+    
+    int drawPitch;
+    int readPitch;
+    int drawXoff;
+    GLuint numClipRects;         /* cliprects for that buffer */
+    XF86DRIClipRectPtr pClipRects;
+
+    int lastSwap;
+    int texAge;
+    int ctxAge;
+    int dirtyAge;
+
+    GLboolean scissor;
+    drm_clip_rect_t drawRect;
+    drm_clip_rect_t scissorRect;
+
+    drmContext hHWContext;
+    drmLock *driHwLock;
+    int driFd;
+#ifndef _SOLO
+    Display *display;
+#endif
+
+    __DRIdrawablePrivate *driDrawable;
+    __DRIscreenPrivate *driScreen;
+    viaScreenPrivate *viaScreen;
+    drm_via_sarea_t *sarea;
+    volatile GLuint* regMMIOBase;
+    volatile GLuint* pnGEMode;
+    volatile GLuint* regEngineStatus;
+    volatile GLuint* regTranSet;
+    volatile GLuint* regTranSpace;
+    GLuint* agpBase;
+    GLuint drawType;
+};
+/*#define DMA_OFFSET 16*/
+#define DMA_OFFSET 32
+/*#define PERFORMANCE_MEASURE*/
+
+extern GLuint VIA_PERFORMANCE;
+
+#ifdef PERFORMANCE_MEASURE
+#define HASH_TABLE_SIZE 1000
+#define HASH_TABLE_DEPTH 10
+typedef struct {
+    char func[50];
+    GLuint count;
+} hash_element;
+extern hash_element hash_table[HASH_TABLE_SIZE][HASH_TABLE_DEPTH];
+#define P_M                                                                      \
+    do {                                                                         \
+       GLuint h_index,h_depth;                                                  \
+       h_index = (GLuint)(((GLuint) __FUNCTION__)%HASH_TABLE_SIZE);             \
+       for (h_depth = 0; h_depth < HASH_TABLE_DEPTH; h_depth++) {                \
+           if (!strcmp(hash_table[h_index][h_depth].func, "NULL")) {             \
+               sprintf(hash_table[h_index][h_depth].func, "%s", __FUNCTION__);  \
+               hash_table[h_index][h_depth].count++;                            \
+               break;                                                           \
+           }                                                                    \
+           else if (!strcmp(hash_table[h_index][h_depth].func, __FUNCTION__)) {  \
+               hash_table[h_index][h_depth].count++;                            \
+               break;                                                           \
+           }                                                                    \
+       }                                                                        \
+    } while (0)
+
+#define P_M_X                                                                          \
+    do {                                                                               \
+       GLuint h_index,h_depth;                                                         \
+       char str[80];                                                                   \
+       strcpy(str, __FUNCTION__);                                                      \
+       h_index = (GLuint)(((GLuint) __FUNCTION__)%HASH_TABLE_SIZE);                    \
+       for (h_depth = 0; h_depth < HASH_TABLE_DEPTH; h_depth++) {                      \
+           if (!strcmp(hash_table[h_index][h_depth].func, "NULL")) {                   \
+               sprintf(hash_table[h_index][h_depth].func, "%s_X", __FUNCTION__);       \
+               hash_table[h_index][h_depth].count++;                                   \
+               break;                                                                  \
+           }                                                                           \
+           else if (!strcmp(hash_table[h_index][h_depth].func, strcat(str, "_X"))) {   \
+               hash_table[h_index][h_depth].count++;                                   \
+               break;                                                                  \
+           }                                                                           \
+       }                                                                               \
+    } while (0)
+
+#define P_M_R                                                                                                                  \
+    do {                                                                                                                       \
+       GLuint h_size, h_depth;                                                                                                 \
+       for (h_size = 0; h_size < HASH_TABLE_SIZE; h_size++) {                                                                  \
+           for (h_depth = 0; h_depth < HASH_TABLE_DEPTH; h_depth++) {                                                          \
+               if (hash_table[h_size][h_depth].count) {                                                                        \
+                   fprintf(stderr, "func:%s count:%d\n", hash_table[h_size][h_depth].func, hash_table[h_size][h_depth].count); \
+               }                                                                                                               \
+           }                                                                                                                   \
+       }                                                                                                                       \
+    } while (0)
+#else /* PERFORMANCE_MEASURE */
+#define P_M {}
+#define P_M_X {}
+#define P_M_R {}
+#endif
+
+#define VIA_CONTEXT(ctx)   ((viaContextPtr)(ctx->DriverCtx))
+
+#define GET_DISPATCH_AGE(vmesa) vmesa->sarea->lastDispatch
+#define GET_ENQUEUE_AGE(vmesa) vmesa->sarea->lastEnqueue
+
+
+/* Lock the hardware and validate our state.  
+ */
+/*
+#define LOCK_HARDWARE(vmesa)                                \
+    do {                                                    \
+        char __ret = 0;                                     \
+        DRM_CAS(vmesa->driHwLock, vmesa->hHWContext,        \
+            (DRM_LOCK_HELD|vmesa->hHWContext), __ret);      \
+        if (__ret)                                          \
+            viaGetLock(vmesa, 0);                           \
+    } while (0)
+*/
+/*=* John Sheng [2003.6.20] fix pci *=*/
+/*=* John Sheng [2003.7.25] fix viewperf black shadow *=*/
+#define LOCK_HARDWARE(vmesa)                                   \
+    if(1)                                              \
+       do {                                                    \
+           char __ret = 0;                                     \
+           DRM_CAS(vmesa->driHwLock, vmesa->hHWContext,        \
+               (DRM_LOCK_HELD|vmesa->hHWContext), __ret);      \
+           if (__ret)                                          \
+               viaGetLock(vmesa, 0);                           \
+       } while (0);                                            \
+    else                                                        \
+       viaLock(vmesa, 0)
+       
+
+/*
+#define LOCK_HARDWARE(vmesa)                                   \
+    viaLock(vmesa, 0);                           
+*/
+
+/* Release the kernel lock.
+ */
+/*
+#define UNLOCK_HARDWARE(vmesa)                                  \
+    DRM_UNLOCK(vmesa->driFd, vmesa->driHwLock, vmesa->hHWContext);
+*/
+/*=* John Sheng [2003.6.20] fix pci *=*/
+/*=* John Sheng [2003.7.25] fix viewperf black shadow *=*/
+#define UNLOCK_HARDWARE(vmesa)                                         \
+    if(1)                                                      \
+       DRM_UNLOCK(vmesa->driFd, vmesa->driHwLock, vmesa->hHWContext);  \
+    else                                                               \
+       viaUnLock(vmesa, 0);                            
+/*     
+#define UNLOCK_HARDWARE(vmesa)                                 \
+    viaUnLock(vmesa, 0);
+*/
+#define WAIT_IDLE                                                              \
+    while (1) {                                                                \
+       if ((((GLuint)*vmesa->regEngineStatus) & 0xFFFEFFFF) == 0x00020000)     \
+           break;                                                              \
+    }
+       
+#define LOCK_HARDWARE_QUIESCENT(vmesa)          \
+    do {                                        \
+        LOCK_HARDWARE(vmesa);                   \
+        viaRegetLockQuiescent(vmesa);           \
+    } while (0)
+
+
+extern GLuint VIA_DEBUG;
+extern GLuint DRAW_FRONT;
+extern void viaGetLock(viaContextPtr vmesa, GLuint flags);
+extern void viaLock(viaContextPtr vmesa, GLuint flags);
+extern void viaUnLock(viaContextPtr vmesa, GLuint flags);
+extern void viaEmitHwStateLocked(viaContextPtr vmesa);
+extern void viaEmitScissorValues(viaContextPtr vmesa, int box_nr, int emit);
+extern void viaEmitDrawingRectangle(viaContextPtr vmesa);
+extern void viaXMesaSetBackClipRects(viaContextPtr vmesa);
+extern void viaXMesaSetFrontClipRects(viaContextPtr vmesa);
+extern void viaReAllocateBuffers(GLframebuffer *drawbuffer);
+extern void viaXMesaWindowMoved(viaContextPtr vmesa);
+
+#define SUBPIXEL_X -.5
+#define SUBPIXEL_Y -.5
+
+/* TODO XXX _SOLO temp defines to make code compilable */
+#ifndef GLX_PBUFFER_BIT
+#define GLX_PBUFFER_BIT        0x00000004
+#endif
+#ifndef GLX_WINDOW_BIT
+#define GLX_WINDOW_BIT 0x00000001
+#endif
+#ifndef VERT_CLIP
+#define VERT_CLIP       0x1000000
+#endif
+#ifndef VERT_RGBA
+#define VERT_RGBA       0x2
+#endif
+#ifndef PRIM_PARITY
+#define PRIM_PARITY     0x400
+#endif
+#ifndef PRIM_LAST
+#define PRIM_LAST       0x800
+#endif
+#ifndef VERT_TEX
+#define VERT_TEX        _TNL_BIT_TEX
+#endif
+
+typedef enum Bool { FALSE, TRUE } Bool;
+
+#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_dd_tritmp.h b/src/mesa/drivers/dri/unichrome/via_dd_tritmp.h
new file mode 100644 (file)
index 0000000..e9af518
--- /dev/null
@@ -0,0 +1,759 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#if HAVE_RGBA
+#define VERT_SET_IND(v, c) (void)c
+#define VERT_COPY_IND(v0, v1)
+#define VERT_SAVE_IND(idx)
+#define VERT_RESTORE_IND(idx)
+#if HAVE_BACK_COLORS
+#define VERT_SET_RGBA(v, c)
+#endif
+#else
+#define VERT_SET_RGBA(v, c) (void)c
+#define VERT_COPY_RGBA(v0, v1)
+#define VERT_SAVE_RGBA(idx)
+#define VERT_RESTORE_RGBA(idx)
+#if HAVE_BACK_COLORS
+#define VERT_SET_IND(v, c)
+#endif
+#endif
+
+#if !HAVE_SPEC
+#define VERT_SET_SPEC(v, c) (void)c
+#define VERT_COPY_SPEC(v0, v1)
+#define VERT_SAVE_SPEC(idx)
+#define VERT_RESTORE_SPEC(idx)
+#if HAVE_BACK_COLORS
+#define VERT_COPY_SPEC1(v)
+#endif
+#else
+#if HAVE_BACK_COLORS
+#define VERT_SET_SPEC(v, c)
+#endif
+#endif
+
+#if !HAVE_BACK_COLORS
+#define VERT_COPY_SPEC1(v)
+#define VERT_COPY_IND1(v)
+#define VERT_COPY_RGBA1(v)
+#endif
+
+#ifndef INSANE_VERTICES
+#define VERT_SET_Z(v, val) VERT_Z(v) = val
+#define VERT_Z_ADD(v, val) VERT_Z(v) += val
+#endif
+
+#if DO_TRI
+static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2)
+{
+    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+    VERTEX *v[3];
+    GLfloat offset;
+    GLfloat z[3];
+    GLenum mode = GL_FILL;
+    GLuint facing;
+    LOCAL_VARS(3);
+
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif
+    
+    v[0] = (VERTEX *)GET_VERTEX(e0);
+    v[1] = (VERTEX *)GET_VERTEX(e1);
+    v[2] = (VERTEX *)GET_VERTEX(e2);
+
+    if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) {
+       GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]);
+        GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]);
+        GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]);
+        GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]);
+        GLfloat cc = ex * fy - ey * fx;
+
+        if (DO_TWOSIDE || DO_UNFILLED) {
+           facing = AREA_IS_CCW(cc) ^ ctx->Polygon._FrontBit;
+
+           if (DO_UNFILLED) {
+               if (facing) {
+                   mode = ctx->Polygon.BackMode;
+                   if (ctx->Polygon.CullFlag &&
+                       ctx->Polygon.CullFaceMode != GL_FRONT) {
+                       return;
+                   }
+               } 
+               else {
+                   mode = ctx->Polygon.FrontMode;
+                   if (ctx->Polygon.CullFlag &&
+                       ctx->Polygon.CullFaceMode != GL_BACK) {
+                       return;
+                   }
+               }
+           }
+
+           if (DO_TWOSIDE && facing == 1) {
+               if (HAVE_RGBA) {
+                   if (HAVE_BACK_COLORS) {
+                       if (!DO_FLAT) {
+                           VERT_SAVE_RGBA(0);
+                           VERT_SAVE_RGBA(1);
+                           VERT_COPY_RGBA1(v[0]);
+                           VERT_COPY_RGBA1(v[1]);
+                       }
+                       VERT_SAVE_RGBA(2);
+                       VERT_COPY_RGBA1(v[2]);
+                       if (HAVE_SPEC) {
+                           if (!DO_FLAT) {
+                               VERT_SAVE_SPEC(0);
+                               VERT_SAVE_SPEC(1);
+                               VERT_COPY_SPEC1(v[0]);
+                               VERT_COPY_SPEC1(v[1]);
+                           }
+                           VERT_SAVE_SPEC(2);
+                           VERT_COPY_SPEC1(v[2]);
+                       }
+                   }
+                   else {
+                       GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
+                        ASSERT(VB->ColorPtr[1]->stride == 4*sizeof(GLfloat));
+                       (void)vbcolor;
+
+                       if (!DO_FLAT) {
+                           VERT_SAVE_RGBA(0);
+                           VERT_SAVE_RGBA(1);
+                           VERT_SET_RGBA(v[0], vbcolor[e0]);
+                           VERT_SET_RGBA(v[1], vbcolor[e1]);
+                       }
+                       VERT_SAVE_RGBA(2);
+                       VERT_SET_RGBA(v[2], vbcolor[e2]);
+
+                       if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
+                           GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
+
+                           if (!DO_FLAT) {
+                               VERT_SAVE_SPEC(0);
+                               VERT_SAVE_SPEC(1);
+                               VERT_SET_SPEC(v[0], vbspec[e0]);
+                               VERT_SET_SPEC(v[1], vbspec[e1]);
+                           }
+                           VERT_SAVE_SPEC(2);
+                           VERT_SET_SPEC(v[2], vbspec[e2]);
+                       }
+                   }
+               }
+               else {
+                   GLfloat *vbindex = (GLfloat*) VB->IndexPtr[1]->data;
+                   if (!DO_FLAT) {
+                        //VERT_SAVE_IND( 0 );
+                        //VERT_SAVE_IND( 1 );
+                       VERT_SET_IND(v[0], vbindex[e0]);
+                       VERT_SET_IND(v[1], vbindex[e1]);
+                   }
+                    //VERT_SAVE_IND( 2 );
+                    VERT_SET_IND(v[2], vbindex[e2]);
+               }
+           }
+       }
+
+       if (DO_OFFSET) {
+           offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
+           z[0] = VERT_Z(v[0]);
+           z[1] = VERT_Z(v[1]);
+           z[2] = VERT_Z(v[2]);
+           if (cc * cc > 1e-16) {
+               GLfloat ic = 1.0 / cc;
+               GLfloat ez = z[0] - z[2];
+               GLfloat fz = z[1] - z[2];
+               GLfloat a = ey * fz - ez * fy;
+               GLfloat b = ez * fx - ex * fz;
+               GLfloat ac = a * ic;
+               GLfloat bc = b * ic;
+               if (ac < 0.0f) ac = -ac;
+               if (bc < 0.0f) bc = -bc;
+               offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor;
+           }
+           offset *= ctx->MRD;
+        }
+    }
+
+    if (DO_FLAT) {
+        if (HAVE_RGBA) {
+           VERT_SAVE_RGBA(0);
+           VERT_SAVE_RGBA(1);
+           VERT_COPY_RGBA(v[0], v[2]);
+           VERT_COPY_RGBA(v[1], v[2]);
+           if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
+               VERT_SAVE_SPEC(0);
+               VERT_SAVE_SPEC(1);
+               VERT_COPY_SPEC(v[0], v[2]);
+               VERT_COPY_SPEC(v[1], v[2]);
+           }
+        }
+        else {
+           VERT_SAVE_IND(0);
+           VERT_SAVE_IND(1);
+           VERT_COPY_IND(v[0], v[2]);
+           VERT_COPY_IND(v[1], v[2]);
+        }
+    }
+
+    if (mode == GL_POINT) {
+        if (DO_OFFSET && ctx->Polygon.OffsetPoint) {
+           VERT_Z_ADD(v[0], offset);
+           VERT_Z_ADD(v[1], offset);
+           VERT_Z_ADD(v[2], offset);
+        }
+        UNFILLED_TRI(ctx, GL_POINT, e0, e1, e2);
+    } 
+    else if (mode == GL_LINE) {
+        if (DO_OFFSET && ctx->Polygon.OffsetLine) {
+           VERT_Z_ADD(v[0], offset);
+           VERT_Z_ADD(v[1], offset);
+           VERT_Z_ADD(v[2], offset);
+        }
+        UNFILLED_TRI(ctx, GL_LINE, e0, e1, e2);
+    } 
+    else {
+        if (DO_OFFSET && ctx->Polygon.OffsetFill) {
+           VERT_Z_ADD(v[0], offset);
+           VERT_Z_ADD(v[1], offset);
+           VERT_Z_ADD(v[2], offset);
+        }
+        if (DO_UNFILLED)
+           RASTERIZE(GL_TRIANGLES);
+        TRI(v[0], v[1], v[2]);
+    }
+
+    if (DO_OFFSET) {
+        VERT_SET_Z(v[0], z[0]);
+        VERT_SET_Z(v[1], z[1]);
+        VERT_SET_Z(v[2], z[2]);
+    }
+
+    if (DO_TWOSIDE && facing == 1) {
+        if (HAVE_RGBA) {
+           if (!DO_FLAT) {
+               VERT_RESTORE_RGBA(0);
+               VERT_RESTORE_RGBA(1);
+           }
+           VERT_RESTORE_RGBA(2);
+           if (HAVE_SPEC) {
+               if (!DO_FLAT) {
+                   VERT_RESTORE_SPEC(0);
+                   VERT_RESTORE_SPEC(1);
+               }
+               VERT_RESTORE_SPEC(2);
+           }
+        }
+        else {
+#if 0   // XXX TODO _SOLO
+           GLuint *vbindex = VB->IndexPtr[0]->data;
+           if (!DO_FLAT) {
+               VERT_SET_IND(v[0], vbindex[e0]);
+               VERT_SET_IND(v[1], vbindex[e1]);
+           }
+           VERT_SET_IND(v[2], vbindex[e2]);
+#else
+            if (!DO_FLAT) {
+                VERT_RESTORE_IND( 0 );
+                VERT_RESTORE_IND( 1 );
+            }
+            VERT_RESTORE_IND( 2 );
+#endif
+        }
+    }
+
+
+    if (DO_FLAT) {
+        if (HAVE_RGBA) {
+           VERT_RESTORE_RGBA(0);
+           VERT_RESTORE_RGBA(1);
+           if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
+               VERT_RESTORE_SPEC(0);
+               VERT_RESTORE_SPEC(1);
+           }
+        }
+        else {
+           VERT_RESTORE_IND(0);
+           VERT_RESTORE_IND(1);
+        }
+    }
+    SET_PRIMITIVE_RENDERED  
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+#endif
+
+#if DO_QUAD
+#if DO_FULL_QUAD
+static void TAG(quad)(GLcontext *ctx,
+                     GLuint e0, GLuint e1, GLuint e2, GLuint e3)
+{
+    struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
+    VERTEX *v[4];
+    GLfloat offset;
+    GLfloat z[4];
+    GLenum mode = GL_FILL;
+    GLuint facing;
+    LOCAL_VARS(4);
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif        
+    v[0] = (VERTEX *)GET_VERTEX(e0);
+    v[1] = (VERTEX *)GET_VERTEX(e1);
+    v[2] = (VERTEX *)GET_VERTEX(e2);
+    v[3] = (VERTEX *)GET_VERTEX(e3);
+
+    if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) {
+        GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]);
+        GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]);
+        GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]);
+        GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]);
+        GLfloat cc = ex * fy - ey * fx;
+
+        if (DO_TWOSIDE || DO_UNFILLED) {
+           facing = AREA_IS_CCW(cc) ^ ctx->Polygon._FrontBit;
+
+           if (DO_UNFILLED) {
+               if (facing) {
+                   mode = ctx->Polygon.BackMode;
+                   if (ctx->Polygon.CullFlag &&
+                       ctx->Polygon.CullFaceMode != GL_FRONT) {
+                       return;
+                   }
+               } 
+               else {
+                   mode = ctx->Polygon.FrontMode;
+                   if (ctx->Polygon.CullFlag &&
+                       ctx->Polygon.CullFaceMode != GL_BACK) {
+                       return;
+                   }
+               }
+           }
+
+           if (DO_TWOSIDE && facing == 1) {
+               if (HAVE_RGBA) {
+                   GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
+                   (void)vbcolor;
+
+                   if (HAVE_BACK_COLORS) {
+                       if (!DO_FLAT) {
+                           VERT_SAVE_RGBA(0);
+                           VERT_SAVE_RGBA(1);
+                           VERT_SAVE_RGBA(2);
+                           VERT_COPY_RGBA1(v[0]);
+                           VERT_COPY_RGBA1(v[1]);
+                           VERT_COPY_RGBA1(v[2]);
+                       }
+                       VERT_SAVE_RGBA(3);
+                       VERT_COPY_RGBA1(v[3]);
+                       if (HAVE_SPEC) {
+                           if (!DO_FLAT) {
+                               VERT_SAVE_SPEC(0);
+                               VERT_SAVE_SPEC(1);
+                               VERT_SAVE_SPEC(2);
+                               VERT_COPY_SPEC1(v[0]);
+                               VERT_COPY_SPEC1(v[1]);
+                               VERT_COPY_SPEC1(v[2]);
+                           }
+                           VERT_SAVE_SPEC(3);
+                           VERT_COPY_SPEC1(v[3]);
+                       }
+                   }
+                   else {
+                       if (!DO_FLAT) {
+                           VERT_SAVE_RGBA(0);
+                           VERT_SAVE_RGBA(1);
+                           VERT_SAVE_RGBA(2);
+                           VERT_SET_RGBA(v[0], vbcolor[e0]);
+                           VERT_SET_RGBA(v[1], vbcolor[e1]);
+                           VERT_SET_RGBA(v[2], vbcolor[e2]);
+                       }
+                       VERT_SAVE_RGBA(3);
+                       VERT_SET_RGBA(v[3], vbcolor[e3]);
+
+                       if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
+                            GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
+                            ASSERT(VB->SecondaryColorPtr[1]->stride==4*sizeof(GLfloat));
+
+                           if (!DO_FLAT) {
+                               VERT_SAVE_SPEC(0);
+                               VERT_SAVE_SPEC(1);
+                               VERT_SAVE_SPEC(2);
+                               VERT_SET_SPEC(v[0], vbspec[e0]);
+                               VERT_SET_SPEC(v[1], vbspec[e1]);
+                               VERT_SET_SPEC(v[2], vbspec[e2]);
+                           }
+                           VERT_SAVE_SPEC(3);
+                           VERT_SET_SPEC(v[3], vbspec[e3]);
+                       }
+                   }
+               }
+               else {
+                   GLfloat *vbindex = (GLfloat*) VB->IndexPtr[1]->data;
+                    if (!DO_FLAT) {
+                        //VERT_SAVE_IND( 0 );
+                        //VERT_SAVE_IND( 1 );
+                        //VERT_SAVE_IND( 2 );
+                       VERT_SET_IND(v[0], vbindex[e0]);
+                       VERT_SET_IND(v[1], vbindex[e1]);
+                       VERT_SET_IND(v[2], vbindex[e2]);
+                   }
+                    //VERT_SAVE_IND( 3 );
+                    VERT_SET_IND(v[3], vbindex[e3]);
+               }
+           }
+        }
+
+
+        if (DO_OFFSET) {
+           offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
+           z[0] = VERT_Z(v[0]);
+           z[1] = VERT_Z(v[1]);
+           z[2] = VERT_Z(v[2]);
+           z[3] = VERT_Z(v[3]);
+           if (cc * cc > 1e-16) {
+               GLfloat ez = z[2] - z[0];
+               GLfloat fz = z[3] - z[1];
+               GLfloat a = ey * fz - ez * fy;
+               GLfloat b = ez * fx - ex * fz;
+               GLfloat ic = 1.0 / cc;
+               GLfloat ac = a * ic;
+               GLfloat bc = b * ic;
+               if ( ac < 0.0f ) ac = -ac;
+               if ( bc < 0.0f ) bc = -bc;
+               offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor;
+           }
+           offset *= ctx->MRD;
+        }
+    }
+
+    if (DO_FLAT) {
+        if (HAVE_RGBA) {
+           VERT_SAVE_RGBA(0);
+           VERT_SAVE_RGBA(1);
+           VERT_SAVE_RGBA(2);
+           VERT_COPY_RGBA(v[0], v[3]);
+           VERT_COPY_RGBA(v[1], v[3]);
+           VERT_COPY_RGBA(v[2], v[3]);
+           if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
+               VERT_SAVE_SPEC(0);
+               VERT_SAVE_SPEC(1);
+               VERT_SAVE_SPEC(2);
+               VERT_COPY_SPEC(v[0], v[3]);
+               VERT_COPY_SPEC(v[1], v[3]);
+               VERT_COPY_SPEC(v[2], v[3]);
+           }
+        }
+         else {
+           VERT_SAVE_IND(0);
+           VERT_SAVE_IND(1);
+           VERT_SAVE_IND(2);
+           VERT_COPY_IND(v[0], v[3]);
+           VERT_COPY_IND(v[1], v[3]);
+           VERT_COPY_IND(v[2], v[3]);
+        }
+    }
+
+    if (mode == GL_POINT) {
+        if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) {
+           VERT_Z_ADD(v[0], offset);
+           VERT_Z_ADD(v[1], offset);
+           VERT_Z_ADD(v[2], offset);
+           VERT_Z_ADD(v[3], offset);
+        }
+        UNFILLED_QUAD(ctx, GL_POINT, e0, e1, e2, e3);
+    } 
+    else if (mode == GL_LINE) {
+        if (DO_OFFSET && ctx->Polygon.OffsetLine) {
+           VERT_Z_ADD(v[0], offset);
+           VERT_Z_ADD(v[1], offset);
+           VERT_Z_ADD(v[2], offset);
+           VERT_Z_ADD(v[3], offset);
+        }
+        UNFILLED_QUAD(ctx, GL_LINE, e0, e1, e2, e3);
+    } 
+    else {
+        if (DO_OFFSET && ctx->Polygon.OffsetFill) {
+           VERT_Z_ADD(v[0], offset);
+           VERT_Z_ADD(v[1], offset);
+           VERT_Z_ADD(v[2], offset);
+           VERT_Z_ADD(v[3], offset);
+        }
+        RASTERIZE(GL_TRIANGLES);
+        QUAD((v[0]), (v[1]), (v[2]), (v[3]));
+    }
+
+    if (DO_OFFSET) {
+        VERT_SET_Z(v[0], z[0]);
+        VERT_SET_Z(v[1], z[1]);
+        VERT_SET_Z(v[2], z[2]);
+        VERT_SET_Z(v[3], z[3]);
+    }
+
+    if (DO_TWOSIDE && facing == 1) {
+        if (HAVE_RGBA) {
+           if (!DO_FLAT) {
+               VERT_RESTORE_RGBA(0);
+               VERT_RESTORE_RGBA(1);
+               VERT_RESTORE_RGBA(2);
+           }
+           VERT_RESTORE_RGBA(3);
+           if (HAVE_SPEC) {
+               if (!DO_FLAT) {
+                   VERT_RESTORE_SPEC(0);
+                   VERT_RESTORE_SPEC(1);
+                   VERT_RESTORE_SPEC(2);
+               }
+               VERT_RESTORE_SPEC(3);
+           }
+        }
+        else {
+#if 0 // XXX TODO _SOLO
+           GLuint *vbindex = VB->IndexPtr[0]->data;
+           if (!DO_FLAT) {
+               VERT_SET_IND(v[0], vbindex[e0]);
+               VERT_SET_IND(v[1], vbindex[e1]);
+               VERT_SET_IND(v[2], vbindex[e2]);
+           }
+           VERT_SET_IND(v[3], vbindex[e3]);
+#else
+            if (!DO_FLAT) {
+                VERT_RESTORE_IND( 0 );
+                VERT_RESTORE_IND( 1 );
+                VERT_RESTORE_IND( 2 );
+            }
+            VERT_RESTORE_IND( 3 );
+#endif
+        }
+    }
+
+    if (DO_FLAT) {
+        if (HAVE_RGBA) {
+           VERT_RESTORE_RGBA(0);
+           VERT_RESTORE_RGBA(1);
+           VERT_RESTORE_RGBA(2);
+           if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
+               VERT_RESTORE_SPEC(0);
+               VERT_RESTORE_SPEC(1);
+               VERT_RESTORE_SPEC(2);
+           }
+        }
+        else {
+           VERT_RESTORE_IND(0);
+           VERT_RESTORE_IND(1);
+           VERT_RESTORE_IND(2);
+        }
+    }
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+#else
+static void TAG(quad)(GLcontext *ctx, GLuint e0,
+                     GLuint e1, GLuint e2, GLuint e3)
+{
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    if (DO_UNFILLED) {
+        struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+        GLubyte ef1 = VB->EdgeFlag[e1];
+        GLubyte ef3 = VB->EdgeFlag[e3];
+        VB->EdgeFlag[e1] = 0;
+        TAG(triangle)(ctx, e0, e1, e3);
+        VB->EdgeFlag[e1] = ef1;
+        VB->EdgeFlag[e3] = 0;
+        TAG(triangle)(ctx, e1, e2, e3);
+        VB->EdgeFlag[e3] = ef3;
+    } 
+    else {
+        TAG(triangle)(ctx, e0, e1, e3);
+        TAG(triangle)(ctx, e1, e2, e3);
+    }
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+#endif
+#endif
+
+#if DO_LINE
+static void TAG(line)(GLcontext *ctx, GLuint e0, GLuint e1)
+{
+    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+    VERTEX *v[2];
+    LOCAL_VARS(2);
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    v[0] = (VERTEX *)GET_VERTEX(e0);
+    v[1] = (VERTEX *)GET_VERTEX(e1);
+
+    if (DO_FLAT) {
+        if (HAVE_RGBA) {
+           VERT_SAVE_RGBA( 0 );
+           VERT_COPY_RGBA( v[0], v[1] );
+           if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
+               VERT_SAVE_SPEC(0);
+               VERT_COPY_SPEC(v[0], v[1]);
+           }
+        }
+        else {
+           VERT_SAVE_IND(0);
+           VERT_COPY_IND(v[0], v[1]);
+        }
+    }
+
+    LINE(v[0], v[1]);
+
+    if (DO_FLAT) {
+        if (HAVE_RGBA) {
+           VERT_RESTORE_RGBA(0);
+
+           if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
+               VERT_RESTORE_SPEC(0);
+           }
+        }
+        else {
+           VERT_RESTORE_IND(0);
+        }
+    }
+    SET_PRIMITIVE_RENDERED   
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+#endif
+
+#if DO_POINTS
+static void TAG(points)(GLcontext *ctx, GLuint first, GLuint last)
+{
+    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+    int i;
+    LOCAL_VARS(1);
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    if (VB->Elts == 0) {
+        for (i = first; i < last; i++) {
+           if (VB->ClipMask[i] == 0) {
+               VERTEX *v = (VERTEX *)GET_VERTEX(i);
+               POINT(v);
+               SET_PRIMITIVE_RENDERED
+           }
+        }
+    } 
+    else {
+        for (i = first; i < last; i++) {
+            GLuint e = VB->Elts[i];
+           if (VB->ClipMask[e] == 0) {
+               VERTEX *v = (VERTEX *)GET_VERTEX(e);
+               POINT(v);
+               SET_PRIMITIVE_RENDERED
+           }
+        }
+    }
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+#endif
+
+static void TAG(init)(void)
+{
+#if DO_QUAD
+    TAB[IND].quad = TAG(quad);
+#endif
+#if DO_TRI
+    TAB[IND].triangle = TAG(triangle);
+#endif
+#if DO_LINE
+    TAB[IND].line = TAG(line);
+#endif
+#if DO_POINTS
+    TAB[IND].points = TAG(points);
+#endif
+}
+
+#undef IND
+#undef TAG
+
+#if HAVE_RGBA
+#undef VERT_SET_IND
+#undef VERT_COPY_IND
+#undef VERT_SAVE_IND
+#undef VERT_RESTORE_IND
+#if HAVE_BACK_COLORS
+#undef VERT_SET_RGBA
+#endif
+#else
+#undef VERT_SET_RGBA
+#undef VERT_COPY_RGBA
+#undef VERT_SAVE_RGBA
+#undef VERT_RESTORE_RGBA
+#if HAVE_BACK_COLORS
+#undef VERT_SET_IND
+#endif
+#endif
+
+#if !HAVE_SPEC
+#undef VERT_SET_SPEC
+#undef VERT_COPY_SPEC
+#undef VERT_SAVE_SPEC
+#undef VERT_RESTORE_SPEC
+#if HAVE_BACK_COLORS
+#undef VERT_COPY_SPEC1
+#endif
+#else
+#if HAVE_BACK_COLORS
+#undef VERT_SET_SPEC
+#endif
+#endif
+
+#if !HAVE_BACK_COLORS
+#undef VERT_COPY_SPEC1
+#undef VERT_COPY_IND1
+#undef VERT_COPY_RGBA1
+#endif
+
+#ifndef INSANE_VERTICES
+#undef VERT_SET_Z
+#undef VERT_Z_ADD
+#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_dd_vbtmp.h b/src/mesa/drivers/dri/unichrome/via_dd_vbtmp.h
new file mode 100644 (file)
index 0000000..f551232
--- /dev/null
@@ -0,0 +1,731 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+/* Unlike the other templates here, this assumes quite a bit about the
+ * underlying hardware.  Specifically it assumes a d3d-like vertex
+ * format, with a layout more or less constrained to look like the
+ * following:
+ *
+ * union {
+ *    struct {
+ *        float x, y, z, w;
+ *        struct { char r, g, b, a; } color;
+ *        struct { char r, g, b, fog; } spec;
+ *        float u0, v0;
+ *        float u1, v1;
+ *        float u2, v2;
+ *        float u3, v3;
+ *    } v;
+ *    struct {
+ *        float x, y, z, w;
+ *        struct { char r, g, b, a; } color;
+ *        struct { char r, g, b, fog; } spec;
+ *        float u0, v0, q0;
+ *        float u1, v1, q1;
+ *        float u2, v2, q2;
+ *        float u3, v3, q3;
+ *    } pv;
+ *    struct {
+ *        float x, y, z;
+ *        struct { char r, g, b, a; } color;
+ *    } tv;
+ *    float f[16];
+ *    unsigned int ui[16];
+ *    unsigned char ub4[4][16];
+ * }
+ *
+
+ * DO_XYZW:  Emit xyz and maybe w coordinates.
+ * DO_RGBA:  Emit color.
+ * DO_SPEC:  Emit specular color.
+ * DO_FOG:   Emit fog coordinate in specular alpha.
+ * DO_TEX0:  Emit tex0 u,v coordinates.
+ * DO_TEX1:  Emit tex1 u,v coordinates.
+ * DO_TEX2:  Emit tex2 u,v coordinates.
+ * DO_TEX3:  Emit tex3 u,v coordinates.
+ * DO_PTEX:  Emit tex0,1,2,3 q coordinates where possible.
+ *
+ * HAVE_RGBA_COLOR: Hardware takes color in rgba order (else bgra).
+ *
+ * HAVE_HW_VIEWPORT:  Hardware performs viewport transform.
+ * HAVE_HW_DIVIDE:  Hardware performs perspective divide.
+ *
+ * HAVE_TINY_VERTICES:  Hardware understands v.tv format.
+ * HAVE_PTEX_VERTICES:  Hardware understands v.pv format.
+ * HAVE_NOTEX_VERTICES:  Hardware understands v.v format with texcount 0.
+ *
+ * Additionally, this template assumes it is emitting *transformed*
+ * vertices; the modifications to emit untransformed vertices (ie. to
+ * t&l hardware) are probably too great to cooexist with the code
+ * already in this file.
+ *
+ * NOTE: The PTEX vertex format always includes TEX0 and TEX1, even if
+ * only TEX0 is enabled, in order to maintain a vertex size which is
+ * an exact number of quadwords.
+ */
+
+#if (HAVE_HW_VIEWPORT)
+#define VIEWPORT_X(dst, x) dst = x
+#define VIEWPORT_Y(dst, y) dst = y
+#define VIEWPORT_Z(dst, z) dst = z
+#else
+#define VIEWPORT_X(dst, x) dst = s[0] * x + s[12]
+#define VIEWPORT_Y(dst, y) dst = s[5] * y + s[13]
+#define VIEWPORT_Z(dst, z) dst = s[10] * z + s[14]
+#endif
+
+#if (HAVE_HW_DIVIDE && !HAVE_PTEX_VERTICES)
+#error "can't cope with this combination" 
+#endif 
+
+#ifndef LOCALVARS
+#define LOCALVARS
+#endif
+
+#ifndef CHECK_HW_DIVIDE
+#define CHECK_HW_DIVIDE 1
+#endif
+
+#if (HAVE_HW_DIVIDE || DO_SPEC || DO_TEX0 || DO_FOG || !HAVE_TINY_VERTICES)
+
+static void TAG(emit)(GLcontext *ctx,
+                     GLuint start, GLuint end,
+                     void *dest,
+                     GLuint stride)
+{
+    LOCALVARS
+    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+    GLfloat (*tc0)[4], (*tc1)[4], (*fog)[4];
+    GLfloat (*tc2)[4], (*tc3)[4];
+    GLfloat (*col)[4], (*spec)[4];
+    GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride;
+    GLuint tc2_stride, tc3_stride;
+    GLuint tc0_size, tc1_size;
+    GLuint tc2_size, tc3_size;
+    GLfloat (*coord)[4];
+    GLuint coord_stride;
+    VERTEX *v = (VERTEX *)dest;
+    const GLfloat *s = GET_VIEWPORT_MAT();
+    const GLubyte *mask = VB->ClipMask;
+    int i;
+
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "TAG-emit for HAVE_HW_DIVIDE || DO_SPEC || DO_TEX0 || DO_FOG || !HAVE_TINY_VERTICE\n");
+#endif    
+    
+    if (HAVE_HW_VIEWPORT && HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
+        (void) s;
+        coord = VB->ClipPtr->data;
+        coord_stride = VB->ClipPtr->stride;
+    }
+    else {
+        coord = VB->NdcPtr->data;
+        coord_stride = VB->NdcPtr->stride;
+    }
+
+    if (DO_TEX3) {
+        const GLuint t3 = GET_TEXSOURCE(3);
+        tc3 = VB->TexCoordPtr[t3]->data;
+        tc3_stride = VB->TexCoordPtr[t3]->stride;
+        if (DO_PTEX)
+           tc3_size = VB->TexCoordPtr[t3]->size;
+    }
+
+    if (DO_TEX2) {
+        const GLuint t2 = GET_TEXSOURCE(2);
+        tc2 = VB->TexCoordPtr[t2]->data;
+        tc2_stride = VB->TexCoordPtr[t2]->stride;
+        if (DO_PTEX)
+           tc2_size = VB->TexCoordPtr[t2]->size;
+    }
+
+    if (DO_TEX1) {
+        const GLuint t1 = GET_TEXSOURCE(1);
+        tc1 = VB->TexCoordPtr[t1]->data;
+        tc1_stride = VB->TexCoordPtr[t1]->stride;
+        if (DO_PTEX)
+           tc1_size = VB->TexCoordPtr[t1]->size;
+    }
+
+    if (DO_TEX0) {
+        const GLuint t0 = GET_TEXSOURCE(0);
+        /* test */
+       tc0_stride = VB->TexCoordPtr[t0]->stride;
+       tc0 = VB->TexCoordPtr[t0]->data;
+       if (DO_PTEX) 
+           tc0_size = VB->TexCoordPtr[t0]->size;
+    }
+
+    if (DO_RGBA) {
+        col = VB->ColorPtr[0]->data;
+        col_stride = VB->ColorPtr[0]->stride;
+    }
+
+    if (DO_SPEC) {
+        spec = VB->SecondaryColorPtr[0]->data;
+        spec_stride = VB->SecondaryColorPtr[0]->stride;
+    }
+
+    if (DO_FOG) {
+      if (VB->FogCoordPtr) {
+        fog = VB->FogCoordPtr->data;
+        fog_stride = VB->FogCoordPtr->stride;
+      }
+      else {
+        static GLfloat tmp[4] = { 0, 0, 0, 0 };
+        fog = &tmp;
+        fog_stride = 0;
+      }
+   }
+
+    /* May have nonstandard strides:
+     */
+    if (start) {
+        STRIDE_4F(coord, start * coord_stride);
+        if (DO_TEX0)
+            STRIDE_4F(tc0, start * tc0_stride);
+        if (DO_TEX1) 
+            STRIDE_4F(tc1, start * tc1_stride);
+        if (DO_TEX2) 
+            STRIDE_4F(tc2, start * tc2_stride);
+        if (DO_TEX3) 
+            STRIDE_4F(tc3, start * tc3_stride);
+        if (DO_RGBA) 
+            STRIDE_4F(col, start * col_stride);
+        if (DO_SPEC)
+            STRIDE_4F(spec, start * spec_stride);
+        if (DO_FOG)
+            STRIDE_4F(fog, start * fog_stride);
+    }
+
+    for (i = start; i < end; i++, v = (VERTEX *)((GLubyte *)v + stride)) {
+        if (DO_XYZW) {
+            if (HAVE_HW_VIEWPORT || mask[i] == 0) {
+                VIEWPORT_X(v->v.x, coord[0][0]);
+                VIEWPORT_Y(v->v.y, coord[0][1]);
+                VIEWPORT_Z(v->v.z, coord[0][2]);
+            }
+            v->v.w = coord[0][3];              
+            STRIDE_4F(coord, coord_stride);
+        }
+        if (DO_RGBA) {
+            UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.red, col[0][0]);
+            UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.green, col[0][1]);
+            UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.blue, col[0][2]);
+            UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.alpha, col[0][3]);
+            STRIDE_4F(col, col_stride);
+        }
+
+        if (DO_SPEC) {
+            UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.red, spec[0][0]);
+            UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.green, spec[0][1]);
+            UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.blue, spec[0][2]);
+            STRIDE_4F(spec, spec_stride);
+        }
+        else { 
+            v->v.specular.red = 0;
+            v->v.specular.green = 0;
+            v->v.specular.blue = 0;
+        }
+
+        if (DO_FOG) {
+            //UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.alpha, fog[0][0]);
+            v->v.specular.alpha = fog[0][0];
+            /*=* [DBG]  exy : fix lighting on + fog off error *=*/
+            STRIDE_4F(fog, fog_stride);
+        }
+        else {
+            v->v.specular.alpha = 0.0;
+        }
+
+        if (DO_TEX0) {
+            v->v.u0 = tc0[0][0];
+            v->v.v0 = tc0[0][1];
+            if (DO_PTEX) {
+                if (HAVE_PTEX_VERTICES) {
+                    if (tc0_size == 4) 
+                        v->pv.q0 = tc0[0][3];
+                    else
+                        v->pv.q0 = 1.0;
+                } 
+                else if (tc0_size == 4) {
+                    float rhw = 1.0 / tc0[0][3];
+                    v->v.w *= tc0[0][3];
+                    v->v.u0 *= rhw;
+                    v->v.v0 *= rhw;
+                }
+            }
+            STRIDE_4F(tc0, tc0_stride);
+        }
+        if (DO_TEX1) {
+            if (DO_PTEX && HAVE_PTEX_VERTICES) {                   
+                v->pv.u1 = tc1[0][0];
+                v->pv.v1 = tc1[0][1];              
+                if (tc1_size == 4) 
+                    v->pv.q1 = tc1[0][3];
+                else
+                    v->pv.q1 = 1.0;
+            } 
+            else {
+                v->v.u1 = tc1[0][0];
+                v->v.v1 = tc1[0][1];
+            }
+            STRIDE_4F(tc1, tc1_stride);
+        } 
+        else if (DO_PTEX) {
+            *(GLuint *)&v->pv.q1 = 0;
+        }
+        if (DO_TEX2) {
+            if (DO_PTEX) {
+                v->pv.u2 = tc2[0][0];
+                v->pv.v2 = tc2[0][1];
+                if (tc2_size == 4) 
+                    v->pv.q2 = tc2[0][3];
+                else
+                    v->pv.q2 = 1.0;
+            } 
+            else {
+                v->v.u2 = tc2[0][0];
+                v->v.v2 = tc2[0][1];
+            }
+            STRIDE_4F(tc2, tc2_stride);
+        } 
+        if (DO_TEX3) {
+            if (DO_PTEX) {
+                v->pv.u3 = tc3[0][0];
+                v->pv.v3 = tc3[0][1];
+                if (tc3_size == 4) 
+                    v->pv.q3 = tc3[0][3];
+                else
+                    v->pv.q3 = 1.0;
+            } 
+            else {
+                v->v.u3 = tc3[0][0];
+                v->v.v3 = tc3[0][1];
+            }
+            STRIDE_4F(tc3, tc3_stride);
+        } 
+    }
+}
+#else
+#if DO_XYZW
+
+#if HAVE_HW_DIVIDE
+#error "cannot use tiny vertices with hw perspective divide"
+#endif
+
+static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
+                     void *dest, GLuint stride)
+{
+    LOCALVARS
+    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+    GLfloat (*col)[4];
+    GLuint col_stride;
+    GLfloat (*coord)[4] = VB->NdcPtr->data;
+    GLuint coord_stride = VB->NdcPtr->stride;
+    GLfloat *v = (GLfloat *)dest;
+    const GLubyte *mask = VB->ClipMask;
+    const GLfloat *s = GET_VIEWPORT_MAT();
+    int i;
+
+    (void) s;
+
+    //ASSERT(stride == 4);
+#ifdef DEBUG    
+    if (VIA_DEBUG) {
+       fprintf(stderr, "TAG-emit for DO_XYZW\n");
+       fprintf(stderr, "%s\n", __FUNCTION__);  
+    }  
+#endif
+
+    col = VB->ColorPtr[0]->data;
+    col_stride = VB->ColorPtr[0]->stride;
+
+    if (start) {
+        STRIDE_4F(coord, start * coord_stride);
+        STRIDE_4F(col, start * col_stride);
+    }
+
+    for (i = start; i < end; i++, v += 4) {
+        if (DO_XYZW) {
+            if (HAVE_HW_VIEWPORT || mask[i] == 0) {
+                VIEWPORT_X(v[0], coord[0][0]);
+                VIEWPORT_Y(v[1], coord[0][1]);
+                VIEWPORT_Z(v[2], coord[0][2]);
+            }
+            STRIDE_4F(coord, coord_stride);
+        }
+        if (DO_RGBA) {
+            VERTEX_COLOR *c = (VERTEX_COLOR *)&v[3];
+            UNCLAMPED_FLOAT_TO_UBYTE(c->red, col[0][0]);
+            UNCLAMPED_FLOAT_TO_UBYTE(c->green, col[0][1]);
+            UNCLAMPED_FLOAT_TO_UBYTE(c->blue, col[0][2]);
+            UNCLAMPED_FLOAT_TO_UBYTE(c->alpha, col[0][3]);
+            STRIDE_4F( col, col_stride );
+        }
+    }
+}
+#else
+static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
+                     void *dest, GLuint stride)
+{
+    LOCALVARS
+    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+    GLubyte (*col)[4];
+    GLuint col_stride;
+    GLfloat *v = (GLfloat *)dest;
+    int i;
+#ifdef DEBUG
+    if (VIA_DEBUG) {
+       fprintf(stderr, "TAG-emit for No DO_XYZW\n");
+       fprintf(stderr, "%s\n", __FUNCTION__);
+    }
+#endif 
+
+    if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE)
+        IMPORT_FLOAT_COLORS( ctx );
+
+    col = VB->ColorPtr[0]->Ptr;
+    col_stride = VB->ColorPtr[0]->StrideB;
+
+    if (start)
+        STRIDE_4UB(col, col_stride * start);
+
+    /* Need to figure out where color is:
+     */
+    if (GET_VERTEX_FORMAT() == TINY_VERTEX_FORMAT)
+        v += 3;
+    else
+        v += 4;
+
+    for (i = start; i < end; i++, STRIDE_F(v, stride)) {
+        if (HAVE_RGBA_COLOR) {
+           *(GLuint *)v = *(GLuint *)col[0];
+        }
+        else {
+           GLubyte *b = (GLubyte *)v;
+           b[0] = col[0][2];
+           b[1] = col[0][1];
+           b[2] = col[0][0];
+           b[3] = col[0][3];
+        }
+        STRIDE_4UB(col, col_stride);
+    }
+}
+#endif /* emit */
+#endif /* emit */
+
+#if (DO_XYZW) && (DO_RGBA)
+
+#if (HAVE_PTEX_VERTICES)
+static GLboolean TAG(check_tex_sizes)(GLcontext *ctx)
+{
+    LOCALVARS
+    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+
+    /* Force 'missing' texcoords to something valid.
+     */
+#ifdef DEBUG
+    fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
+        VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
+
+    if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
+        VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
+
+    if (DO_TEX1 && VB->TexCoordPtr[0] == 0)
+        VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
+
+    if (DO_PTEX)
+        return GL_TRUE;
+   
+    if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
+        (DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
+        (DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4) ||
+        (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4))
+        return GL_FALSE;
+#ifdef DEBUG
+    fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+    return GL_TRUE;
+}
+#else
+static GLboolean TAG(check_tex_sizes)(GLcontext *ctx)
+{
+    LOCALVARS
+    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+
+    /* Force 'missing' texcoords to something valid.
+     */
+    if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
+        VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
+
+    if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
+        VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
+
+    if (DO_TEX1 && VB->TexCoordPtr[0] == 0) {
+        VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
+    }
+
+    if (DO_PTEX)
+        return GL_TRUE;
+
+    if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
+        (DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
+        (DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4)) {
+        /*PTEX_FALLBACK();*/
+        return GL_FALSE;
+    }
+    
+    if (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4) {
+        if (DO_TEX1 || DO_TEX2 || DO_TEX3) {
+           /*PTEX_FALLBACK();*/
+        }
+        return GL_FALSE;
+    }
+    return GL_TRUE;
+}
+#endif /* ptex */
+
+
+static void TAG(interp)(GLcontext *ctx,
+                       GLfloat t,
+                       GLuint edst, GLuint eout, GLuint ein,
+                       GLboolean force_boundary)
+{
+    LOCALVARS
+    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+    GLubyte *ddverts = GET_VERTEX_STORE();
+    GLuint shift = GET_VERTEX_STRIDE_SHIFT();
+    const GLfloat *dstclip = VB->ClipPtr->data[edst];
+    GLfloat w;
+    const GLfloat *s = GET_VIEWPORT_MAT();
+    
+    VERTEX *dst = (VERTEX *)(ddverts + (edst << shift));
+    VERTEX *in = (VERTEX *)(ddverts + (ein << shift));
+    VERTEX *out = (VERTEX *)(ddverts + (eout << shift));
+
+    (void)s;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+    if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
+        VIEWPORT_X(dst->v.x, dstclip[0]);
+        VIEWPORT_Y(dst->v.y, dstclip[1]);
+        VIEWPORT_Z(dst->v.z, dstclip[2]);
+        w = dstclip[3];
+    }
+    else {
+        w = 1.0 / dstclip[3];
+        VIEWPORT_X(dst->v.x, dstclip[0] * w);
+        VIEWPORT_Y(dst->v.y, dstclip[1] * w);
+        VIEWPORT_Z(dst->v.z, dstclip[2] * w);
+    }
+
+    if ((HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) || 
+        DO_FOG || DO_SPEC || DO_TEX0 || DO_TEX1 ||
+        DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES) {
+
+        dst->v.w = w;
+       
+        INTERP_UB(t, dst->ub4[4][0], out->ub4[4][0], in->ub4[4][0]);
+        INTERP_UB(t, dst->ub4[4][1], out->ub4[4][1], in->ub4[4][1]);
+        INTERP_UB(t, dst->ub4[4][2], out->ub4[4][2], in->ub4[4][2]);
+        INTERP_UB(t, dst->ub4[4][3], out->ub4[4][3], in->ub4[4][3]);
+       
+        if (DO_SPEC) {
+           INTERP_UB(t, dst->ub4[5][0], out->ub4[5][0], in->ub4[5][0]);
+           INTERP_UB(t, dst->ub4[5][1], out->ub4[5][1], in->ub4[5][1]);
+           INTERP_UB(t, dst->ub4[5][2], out->ub4[5][2], in->ub4[5][2]);
+        }
+        if (DO_FOG) {
+           INTERP_UB(t, dst->ub4[5][3], out->ub4[5][3], in->ub4[5][3]);
+        }
+        if (DO_TEX0) {
+           if (DO_PTEX) {
+               if (HAVE_PTEX_VERTICES) {
+                   INTERP_F(t, dst->pv.u0, out->pv.u0, in->pv.u0);
+                   INTERP_F(t, dst->pv.v0, out->pv.v0, in->pv.v0);
+                   INTERP_F(t, dst->pv.q0, out->pv.q0, in->pv.q0);
+               } 
+               else {
+                   INTERP_F(t, dst->v.u0, out->v.u0, in->v.u0);
+                   INTERP_F(t, dst->v.v0, out->v.v0, in->v.v0);
+               }
+           }
+           else {
+               INTERP_F(t, dst->v.u0, out->v.u0, in->v.u0);
+               INTERP_F(t, dst->v.v0, out->v.v0, in->v.v0);
+           }
+        }
+        if (DO_TEX1) {
+           if (DO_PTEX) {
+               if (HAVE_PTEX_VERTICES) {           
+                   INTERP_F(t, dst->pv.u1, out->pv.u1, in->pv.u1);
+                   INTERP_F(t, dst->pv.v1, out->pv.v1, in->pv.v1);
+                   INTERP_F(t, dst->pv.q1, out->pv.q1, in->pv.q1);
+               }
+               else {
+                   INTERP_F(t, dst->v.u1, out->v.u1, in->v.u1);
+                   INTERP_F(t, dst->v.v1, out->v.v1, in->v.v1);
+               }                   
+           } 
+           else {
+               INTERP_F(t, dst->v.u1, out->v.u1, in->v.u1);
+               INTERP_F(t, dst->v.v1, out->v.v1, in->v.v1);
+           }
+        }
+        else if (DO_PTEX) {
+           dst->pv.q0 = 0.0;   /* must be a valid float on radeon */
+        }
+        if (DO_TEX2) {
+           if (DO_PTEX) {
+               INTERP_F(t, dst->pv.u2, out->pv.u2, in->pv.u2);
+               INTERP_F(t, dst->pv.v2, out->pv.v2, in->pv.v2);
+               INTERP_F(t, dst->pv.q2, out->pv.q2, in->pv.q2);
+           } 
+           else {
+               INTERP_F(t, dst->v.u2, out->v.u2, in->v.u2);
+               INTERP_F(t, dst->v.v2, out->v.v2, in->v.v2);
+           }
+        }
+        if (DO_TEX3) {
+           if (DO_PTEX) {
+               INTERP_F(t, dst->pv.u3, out->pv.u3, in->pv.u3);
+               INTERP_F(t, dst->pv.v3, out->pv.v3, in->pv.v3);
+               INTERP_F(t, dst->pv.q3, out->pv.q3, in->pv.q3);
+           } 
+           else {
+               INTERP_F(t, dst->v.u3, out->v.u3, in->v.u3);
+               INTERP_F(t, dst->v.v3, out->v.v3, in->v.v3);
+           }
+        }
+    } 
+    else {
+        /* 4-dword vertex.  Color is in v[3] and there is no oow coordinate.
+         */
+        INTERP_UB(t, dst->ub4[3][0], out->ub4[3][0], in->ub4[3][0]);
+        INTERP_UB(t, dst->ub4[3][1], out->ub4[3][1], in->ub4[3][1]);
+        INTERP_UB(t, dst->ub4[3][2], out->ub4[3][2], in->ub4[3][2]);
+        INTERP_UB(t, dst->ub4[3][3], out->ub4[3][3], in->ub4[3][3]);
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+#endif /* rgba && xyzw */
+
+static void TAG(init)(void)
+{
+    setup_tab[IND].emit = TAG(emit);
+
+#if (DO_XYZW && DO_RGBA)
+    setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes);
+    setup_tab[IND].interp = TAG(interp);
+#endif
+
+    if (DO_SPEC)
+        setup_tab[IND].copy_pv = copy_pv_rgba4_spec5;
+     else if (HAVE_HW_DIVIDE || DO_SPEC || DO_FOG || DO_TEX0 || DO_TEX1 ||
+             DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES)
+        setup_tab[IND].copy_pv = copy_pv_rgba4;
+    else
+        setup_tab[IND].copy_pv = copy_pv_rgba3;
+
+    if (DO_TEX3) {
+        if (DO_PTEX && HAVE_PTEX_VERTICES) {
+           ASSERT(HAVE_PTEX_VERTICES);
+           setup_tab[IND].vertex_format = PROJ_TEX3_VERTEX_FORMAT;
+           setup_tab[IND].vertex_size = 18;
+           setup_tab[IND].vertex_stride_shift = 7;
+        }
+        else {
+           setup_tab[IND].vertex_format = TEX3_VERTEX_FORMAT;
+           setup_tab[IND].vertex_size = 14;
+           setup_tab[IND].vertex_stride_shift = 6;
+        }
+    }
+    else if (DO_TEX2) {
+        if (DO_PTEX && HAVE_PTEX_VERTICES) {
+           ASSERT(HAVE_PTEX_VERTICES);
+           setup_tab[IND].vertex_format = PROJ_TEX3_VERTEX_FORMAT;
+           setup_tab[IND].vertex_size = 18;
+           setup_tab[IND].vertex_stride_shift = 7;
+        }
+        else {
+           setup_tab[IND].vertex_format = TEX2_VERTEX_FORMAT;
+           setup_tab[IND].vertex_size = 12;
+           setup_tab[IND].vertex_stride_shift = 6;
+        }
+    }
+    else if (DO_TEX1) {
+        if (DO_PTEX && HAVE_PTEX_VERTICES) {
+           ASSERT(HAVE_PTEX_VERTICES);
+           setup_tab[IND].vertex_format = PROJ_TEX1_VERTEX_FORMAT;
+           setup_tab[IND].vertex_size = 12;
+           setup_tab[IND].vertex_stride_shift = 6;
+        }
+        else {
+           setup_tab[IND].vertex_format = TEX1_VERTEX_FORMAT;
+           setup_tab[IND].vertex_size = 10;
+           setup_tab[IND].vertex_stride_shift = 6;
+        }
+    }
+    else if (DO_TEX0) {
+        if (DO_PTEX && HAVE_PTEX_VERTICES) {
+           setup_tab[IND].vertex_format = PROJ_TEX1_VERTEX_FORMAT;
+           setup_tab[IND].vertex_size = 12;
+           setup_tab[IND].vertex_stride_shift = 6;
+        } 
+       else {
+           setup_tab[IND].vertex_format = TEX0_VERTEX_FORMAT;
+           setup_tab[IND].vertex_size = 8;
+           setup_tab[IND].vertex_stride_shift = 5;
+        }
+    }
+    else if (!HAVE_HW_DIVIDE && !DO_SPEC && !DO_FOG && HAVE_TINY_VERTICES) {
+        setup_tab[IND].vertex_format = TINY_VERTEX_FORMAT;
+        setup_tab[IND].vertex_size = 4;
+        setup_tab[IND].vertex_stride_shift = 4;
+    } 
+    else if (HAVE_NOTEX_VERTICES) {
+        setup_tab[IND].vertex_format = NOTEX_VERTEX_FORMAT;
+        setup_tab[IND].vertex_size = 6;
+        setup_tab[IND].vertex_stride_shift = 5;
+    } 
+    else {
+        setup_tab[IND].vertex_format = TEX0_VERTEX_FORMAT;
+        setup_tab[IND].vertex_size = 8;
+        setup_tab[IND].vertex_stride_shift = 5;
+    }
+
+    assert(setup_tab[IND].vertex_size * 4 <=
+           1 << setup_tab[IND].vertex_stride_shift);
+}
+
+#undef IND
+#undef TAG
diff --git a/src/mesa/drivers/dri/unichrome/via_dmatmp.h b/src/mesa/drivers/dri/unichrome/via_dmatmp.h
new file mode 100644 (file)
index 0000000..458ccea
--- /dev/null
@@ -0,0 +1,601 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* Template for render stages which build and emit vertices directly
+ * to fixed-size dma buffers.  Useful for rendering strips and other
+ * native primitives where clipping and per-vertex tweaks such as
+ * those in t_dd_tritmp.h are not required.
+ *
+ * Produces code for both inline triangles and indexed triangles.
+ * Where various primitive types are unaccelerated by hardware, the
+ * code attempts to fallback to other primitive types (quadstrips to
+ * tristrips, lineloops to linestrips), or to indexed vertices.
+ * Ultimately, a FALLBACK() macro is invoked if there is no way to
+ * render the primitive natively.
+ */
+
+#if !defined(HAVE_TRIANGLES)
+#error "must have at least triangles to use render template"
+#endif
+
+#if !HAVE_ELTS
+#define ELTS_VARS
+#define ALLOC_ELTS(nr)
+#define EMIT_ELT(offset, elt)
+#define EMIT_TWO_ELTS(offset, elt0, elt1)
+#define INCR_ELTS(nr)
+#define ELT_INIT(prim)
+#define GET_CURRENT_VB_MAX_ELTS() 0
+#define GET_SUBSEQUENT_VB_MAX_ELTS() 0
+#define ALLOC_ELTS_NEW_PRIMITIVE(nr)
+#define RELEASE_ELT_VERTS()
+#define EMIT_INDEXED_VERTS(ctx, start, count)
+#endif
+
+#ifndef EMIT_TWO_ELTS
+#define EMIT_TWO_ELTS(offset, elt0, elt1)           \
+    do {                                            \
+        EMIT_ELT(offset, elt0);                     \
+        EMIT_ELT(offset + 1, elt1);                 \
+    } while (0)
+#endif
+
+#ifndef FINISH
+#define FINISH
+#endif
+
+/***********************************************************************
+ *                    Render non-indexed primitives.
+ ***********************************************************************/
+
+static void TAG(render_points_verts)(GLcontext *ctx,
+                                     GLuint start,
+                                     GLuint count,
+                                     GLuint flags)
+{
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M_X;
+#endif
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    if (HAVE_POINTS) {
+        LOCAL_VARS;
+        int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+        int currentsz = GET_CURRENT_VB_MAX_VERTS();
+        GLuint j, nr;
+
+        INIT(GL_POINTS);
+
+        if (currentsz < 8)
+            currentsz = dmasz;
+
+        for (j = start; j < count; j += nr) {
+            nr = MIN2(currentsz, count - j);
+            EMIT_VERTS(ctx, j, nr);
+            currentsz = dmasz;
+        }
+
+        FINISH;
+    }
+    else {
+        VERT_FALLBACK(ctx, start, count, flags);
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
+#endif
+}
+
+static void TAG(render_lines_verts)(GLcontext *ctx,
+                                    GLuint start,
+                                    GLuint count,
+                                    GLuint flags)
+{
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M_X;
+#endif
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    if (HAVE_LINES) {
+        LOCAL_VARS;
+        int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+        int currentsz = GET_CURRENT_VB_MAX_VERTS();
+        GLuint j, nr;
+
+        INIT(GL_LINES);
+
+        /* Emit whole number of lines in total and in each buffer:
+         */
+        count -= (count - start) & 1;
+        currentsz -= currentsz & 1;
+        dmasz -= dmasz & 1;
+
+        if (currentsz < 8)
+            currentsz = dmasz;
+
+        for (j = start; j < count; j += nr) {
+            nr = MIN2(currentsz, count - j);
+            EMIT_VERTS(ctx, j, nr);
+            currentsz = dmasz;
+        }
+
+        FINISH;
+    }
+    else {
+        VERT_FALLBACK(ctx, start, count, flags);
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
+#endif
+}
+
+
+static void TAG(render_line_strip_verts)(GLcontext *ctx,
+                                         GLuint start,
+                                         GLuint count,
+                                         GLuint flags)
+{
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M_X;
+#endif
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    if (HAVE_LINE_STRIPS) {
+        LOCAL_VARS;
+        int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+        int currentsz = GET_CURRENT_VB_MAX_VERTS();
+        GLuint j, nr;
+
+        INIT(GL_LINE_STRIP);
+
+        if (currentsz < 8)
+            currentsz = dmasz;
+
+        for (j = start; j + 1 < count; j += nr - 1) {
+            nr = MIN2(currentsz, count - j);
+            EMIT_VERTS(ctx, j, nr);
+            currentsz = dmasz;
+        }
+
+        FINISH;
+    }
+    else {
+        VERT_FALLBACK(ctx, start, count, flags);
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
+#endif
+}
+
+
+static void TAG(render_line_loop_verts)(GLcontext *ctx,
+                                        GLuint start,
+                                        GLuint count,
+                                        GLuint flags)
+{
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M_X;
+#endif
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    if (HAVE_LINE_STRIPS) {
+        LOCAL_VARS;
+        int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+        int currentsz = GET_CURRENT_VB_MAX_VERTS();
+        GLuint j, nr;
+
+        INIT(GL_LINE_STRIP);
+
+        if (flags & PRIM_BEGIN)
+            j = start;
+        else
+            j = start + 1;
+
+        /* Ensure last vertex won't wrap buffers:
+         */
+        currentsz--;
+        dmasz--;
+
+        if (currentsz < 8)
+            currentsz = dmasz;
+
+        for (; j + 1 < count; j += nr - 1) {
+            nr = MIN2(currentsz, count - j);
+            EMIT_VERTS(ctx, j, nr);
+            currentsz = dmasz;
+        }
+
+        if (start < count - 1 && (flags & PRIM_END))
+            EMIT_VERTS(ctx, start, 1);
+
+        FINISH;
+    }
+    else {
+        VERT_FALLBACK(ctx, start, count, flags);
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
+#endif
+}
+
+
+static void TAG(render_triangles_verts)(GLcontext *ctx,
+                                        GLuint start,
+                                        GLuint count,
+                                        GLuint flags)
+{
+    LOCAL_VARS;
+    int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS() / 3) * 3;
+    int currentsz = (GET_CURRENT_VB_MAX_VERTS() / 3) * 3;
+    GLuint j, nr;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M_X;
+#endif    
+    INIT(GL_TRIANGLES);
+
+    /* Emit whole number of tris in total.  dmasz is already a multiple
+     * of 3.
+     */
+    count -= (count - start) % 3;
+
+    if (currentsz < 8)
+        currentsz = dmasz;
+
+     for (j = start; j < count; j += nr) {
+         nr = MIN2(currentsz, count - j);
+         EMIT_VERTS(ctx, j, nr);
+         currentsz = dmasz;
+     }
+     FINISH;
+#ifdef DEBUG
+     if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+
+static void TAG(render_tri_strip_verts)(GLcontext *ctx,
+                                        GLuint start,
+                                        GLuint count,
+                                        GLuint flags)
+{
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M_X;
+#endif
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    if (HAVE_TRI_STRIPS) {
+        LOCAL_VARS;
+        GLuint j, nr;
+        int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+        int currentsz = GET_CURRENT_VB_MAX_VERTS();
+
+        INIT(GL_TRIANGLE_STRIP);
+
+        if (currentsz < 8) {
+            NEW_BUFFER();
+            currentsz = dmasz;
+        }
+
+        if ((flags & PRIM_PARITY) && count - start > 2) {
+            EMIT_VERTS(ctx, start, 1);
+            currentsz--;
+        }
+
+        /* From here on emit even numbers of tris when wrapping over buffers:
+         */
+        dmasz -= (dmasz & 1);
+        currentsz -= (currentsz & 1);
+
+        for (j = start; j + 2 < count; j += nr - 2) {
+            nr = MIN2(currentsz, count - j);
+            EMIT_VERTS(ctx, j, nr);
+            currentsz = dmasz;
+        }
+
+        FINISH;
+    }
+    else {
+        VERT_FALLBACK(ctx, start, count, flags);
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
+#endif
+}
+
+static void TAG(render_tri_fan_verts)(GLcontext *ctx,
+                                      GLuint start,
+                                      GLuint count,
+                                      GLuint flags)
+{
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M_X;
+#endif    
+    if (HAVE_TRI_FANS) {
+       LOCAL_VARS;
+        GLuint j, nr;
+        int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+        int currentsz = GET_CURRENT_VB_MAX_VERTS();
+
+        INIT(GL_TRIANGLE_FAN);
+
+        if (currentsz < 8) {
+            NEW_BUFFER();
+            currentsz = dmasz;
+        }
+
+        for (j = start + 1; j + 1 < count; j += nr - 1) {
+            nr = MIN2(currentsz, count - j + 1);
+            EMIT_VERTS(ctx, start, 1);
+            EMIT_VERTS(ctx, j, nr - 1);
+            currentsz = dmasz;
+        }
+
+        FINISH;
+    }
+    else {
+        /* Could write code to emit these as indexed vertices (for the
+         * g400, for instance).
+         */
+        VERT_FALLBACK(ctx, start, count, flags);
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+
+static void TAG(render_poly_verts)(GLcontext *ctx,
+                                   GLuint start,
+                                   GLuint count,
+                                   GLuint flags)
+{
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M_X;
+#endif
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    if (HAVE_POLYGONS) {
+        LOCAL_VARS;
+        GLuint j, nr;
+        int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+        int currentsz = GET_CURRENT_VB_MAX_VERTS();
+
+        INIT(GL_POLYGON);
+
+        if (currentsz < 8) {
+            NEW_BUFFER();
+            currentsz = dmasz;
+        }
+
+        for (j = start + 1; j + 1 < count; j += nr - 1) {
+            nr = MIN2(currentsz, count - j + 1);
+            EMIT_VERTS(ctx, start, 1);
+            EMIT_VERTS(ctx, j, nr - 1);
+            currentsz = dmasz;
+        }
+
+        FINISH;
+    }
+    else if (HAVE_TRI_FANS && !(ctx->_TriangleCaps & DD_FLATSHADE)) {
+        TAG(render_tri_fan_verts)(ctx, start, count, flags);
+    }
+    else {
+        VERT_FALLBACK(ctx, start, count, flags);
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
+#endif
+}
+
+static void TAG(render_quad_strip_verts)(GLcontext *ctx,
+                                         GLuint start,
+                                         GLuint count,
+                                         GLuint flags)
+{
+    GLuint j, nr;
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M_X;
+#endif
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    if (HAVE_QUAD_STRIPS) {
+        LOCAL_VARS;
+        GLuint j, nr;
+        int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+        int currentsz;
+
+        INIT(GL_QUAD_STRIP);
+
+        currentsz = GET_CURRENT_VB_MAX_VERTS();
+
+        if (currentsz < 8) {
+            NEW_BUFFER();
+            currentsz = dmasz;
+        }
+
+        dmasz -= (dmasz & 2);
+        currentsz -= (currentsz & 2);
+
+        for (j = start; j + 3 < count; j += nr - 2) {
+            nr = MIN2(currentsz, count - j);
+            EMIT_VERTS(ctx, j, nr);
+            currentsz = dmasz;
+        }
+
+        FINISH;
+    }
+    else if (HAVE_TRI_STRIPS) {
+        LOCAL_VARS;
+        int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+        int currentsz = GET_CURRENT_VB_MAX_VERTS();
+
+        /* Emit smooth-shaded quadstrips as tristrips:
+         */
+        INIT(GL_TRIANGLE_STRIP);
+
+        /* Emit whole number of quads in total, and in each buffer.
+         */
+        dmasz -= dmasz & 1;
+        currentsz -= currentsz & 1;
+        count -= (count - start) & 1;
+
+        if (currentsz < 8) {
+            NEW_BUFFER();
+            currentsz = dmasz;
+        }
+
+        for (j = start; j + 3 < count; j += nr - 2) {
+            nr = MIN2(currentsz, count - j);
+            EMIT_VERTS(ctx, j, nr);
+            currentsz = dmasz;
+        }
+
+        FINISH;
+    }
+    else {
+        VERT_FALLBACK(ctx, start, count, flags);
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
+#endif
+}
+
+
+static void TAG(render_quads_verts)(GLcontext *ctx,
+                                    GLuint start,
+                                    GLuint count,
+                                    GLuint flags)
+{
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M_X;
+#endif    
+    if (HAVE_QUADS) {
+        LOCAL_VARS;
+        int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS() / 4) * 4;
+        int currentsz = (GET_CURRENT_VB_MAX_VERTS() / 4) * 4;
+        GLuint j, nr;
+
+        INIT(GL_QUADS);
+
+        /* Emit whole number of quads in total.  dmasz is already a multiple
+         * of 4.
+         */
+        count -= (count - start) % 4;
+
+        if (currentsz < 8)
+            currentsz = dmasz;
+
+        for (j = start; j < count; j += nr) {
+            nr = MIN2(currentsz, count - j);
+            EMIT_VERTS(ctx, j, nr);
+            currentsz = dmasz;
+        }
+        FINISH;
+    }
+    else if (HAVE_TRIANGLES) {
+        /* Hardware doesn't have a quad primitive type -- try to
+         * simulate it using triangle primitive.
+         */
+        LOCAL_VARS;
+        int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
+        int currentsz;
+        GLuint j;
+
+        INIT(GL_TRIANGLES);
+
+        currentsz = GET_CURRENT_VB_MAX_VERTS();
+
+        /* Emit whole number of quads in total, and in each buffer.
+         */
+        dmasz -= dmasz & 3;
+        count -= (count - start) & 3;
+        currentsz -= currentsz & 3;
+
+        /* Adjust for rendering as triangles:
+         */
+        currentsz = currentsz / 6 * 4;
+        dmasz = dmasz / 6 * 4;
+
+        if (currentsz < 8)
+            currentsz = dmasz;
+
+        for (j = start; j < count; j += 4) {
+            /* Send v0, v1, v3
+             */
+            EMIT_VERTS(ctx, j, 2);
+            EMIT_VERTS(ctx, j + 3, 1);
+            /* Send v1, v2, v3
+             */
+            EMIT_VERTS(ctx, j + 1, 3);
+        }
+        FINISH;
+    }
+    else {
+        /* Vertices won't fit in a single buffer, fallback.
+         */
+        VERT_FALLBACK(ctx, start, count, flags);
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+static void TAG(render_noop)(GLcontext *ctx,
+                             GLuint start,
+                             GLuint count,
+                             GLuint flags)
+{
+}
+
+
+static render_func TAG(render_tab_verts)[GL_POLYGON + 2] =
+{
+    TAG(render_points_verts),
+    TAG(render_lines_verts),
+    TAG(render_line_loop_verts),
+    TAG(render_line_strip_verts),
+    TAG(render_triangles_verts),
+    TAG(render_tri_strip_verts),
+    TAG(render_tri_fan_verts),
+    TAG(render_quads_verts),
+    TAG(render_quad_strip_verts),
+    TAG(render_poly_verts),
+    TAG(render_noop),
+};
+
diff --git a/src/mesa/drivers/dri/unichrome/via_dri.h b/src/mesa/drivers/dri/unichrome/via_dri.h
new file mode 100644 (file)
index 0000000..b4293e5
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef _VIA_DRI_
+#define _VIA_DRI_
+
+#include "xf86drm.h"
+
+#define VIA_MAX_DRAWABLES 256
+
+#define VIA_VERSION_MAJOR              4
+#define VIA_VERSION_MINOR              1
+
+typedef struct {
+    int CtxOwner;
+} VIASAREAPriv;
+
+typedef struct {
+    drmHandle handle;
+    drmSize size;
+    drmAddress map;
+} viaRegion, *viaRegionPtr;
+
+typedef struct {
+    viaRegion regs, agp;
+    int deviceID;
+    int width;
+    int height;
+    int mem;
+    int bytesPerPixel;
+    int priv1;
+    int priv2;
+    int fbOffset;
+    int fbSize;
+#ifndef _SOLO
+    Bool drixinerama;
+#endif
+    int backOffset;
+    int depthOffset;
+    int textureOffset;
+    int textureSize;
+    int irqEnabled;
+    unsigned int scrnX, scrnY;
+    int sarea_priv_offset;
+} VIADRIRec, *VIADRIPtr;
+
+typedef struct {
+    int dummy;
+} VIAConfigPrivRec, *VIAConfigPrivPtr;
+
+typedef struct {
+    int dummy;
+} VIADRIContextRec, *VIADRIContextPtr;
+
+#ifdef XFree86Server
+
+#include "screenint.h"
+
+Bool VIADRIScreenInit(ScreenPtr pScreen);
+void VIADRICloseScreen(ScreenPtr pScreen);
+Bool VIADRIFinishScreenInit(ScreenPtr pScreen);
+
+#endif
+#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_fb.c b/src/mesa/drivers/dri/unichrome/via_fb.c
new file mode 100644 (file)
index 0000000..9d9a5b1
--- /dev/null
@@ -0,0 +1,373 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "via_context.h"
+#include "via_ioctl.h"
+#include "via_fb.h"
+#include <sys/ioctl.h>
+
+GLboolean
+via_alloc_back_buffer(viaContextPtr vmesa)
+{
+    drm_via_mem_t fb;
+    unsigned char *pFB;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    fb.context = vmesa->hHWContext;
+    fb.size = vmesa->back.size;
+    fb.type = VIDEO;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "context = %d, size =%d, type = %d\n", fb.context, fb.size, fb.type);
+#endif
+    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb))
+        return GL_FALSE;
+    
+    pFB = vmesa->driScreen->pFB;
+    
+    vmesa->back.offset = fb.offset;
+    vmesa->back.map = (char *)(fb.offset + (GLuint)pFB);
+    vmesa->back.index = fb.index;
+#ifdef DEBUG    
+    if (VIA_DEBUG) {
+       fprintf(stderr, "offset = %08x\n", vmesa->back.offset);
+       fprintf(stderr, "index = %d\n", vmesa->back.index);
+    }
+
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif    
+    return GL_TRUE;
+}
+
+GLboolean
+via_alloc_front_buffer(viaContextPtr vmesa)
+{
+    drm_via_mem_t fb;
+    unsigned char *pFB;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    fb.context = vmesa->hHWContext;
+    fb.size = vmesa->back.size;
+    fb.type = VIDEO;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "context = %d, size =%d, type = %d\n", fb.context, fb.size, fb.type);
+#endif
+    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb))
+        return GL_FALSE;
+    
+    pFB = vmesa->driScreen->pFB;
+    
+    vmesa->front.offset = fb.offset;
+    vmesa->front.map = (char *)(fb.offset + (GLuint)pFB);
+    vmesa->front.index = fb.index;
+#ifdef DEBUG    
+    if (VIA_DEBUG) {
+       fprintf(stderr, "offset = %08x\n", vmesa->front.offset);
+       fprintf(stderr, "index = %d\n", vmesa->front.index);
+    }
+
+
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif    
+    return GL_TRUE;
+}
+
+void
+via_free_back_buffer(viaContextPtr vmesa)
+{
+    drm_via_mem_t fb;
+
+    if (!vmesa) return;
+    fb.context = vmesa->hHWContext;
+    fb.index = vmesa->back.index;
+    fb.type = VIDEO;
+    ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
+    vmesa->back.map = NULL;
+}
+
+void
+via_free_front_buffer(viaContextPtr vmesa)
+{
+    drm_via_mem_t fb;
+
+    if (!vmesa) return;
+    fb.context = vmesa->hHWContext;
+    fb.index = vmesa->front.index;
+    fb.type = VIDEO;
+    ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
+    vmesa->front.map = NULL;
+}
+
+GLboolean
+via_alloc_depth_buffer(viaContextPtr vmesa)
+{
+    drm_via_mem_t fb;
+    unsigned char *pFB;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif 
+    fb.context = vmesa->hHWContext;
+    fb.size = vmesa->depth.size;
+    fb.type = VIDEO;
+
+    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
+       return GL_FALSE;
+    }
+
+    pFB = vmesa->driScreen->pFB;
+    
+    vmesa->depth.offset = fb.offset;
+    vmesa->depth.map = (char *)(fb.offset + (GLuint)pFB);
+    vmesa->depth.index = fb.index;
+#ifdef DEBUG    
+    if (VIA_DEBUG) {
+       fprintf(stderr, "offset = %08x\n", vmesa->depth.offset);
+       fprintf(stderr, "index = %d\n", vmesa->depth.index);    
+    }  
+
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+    return GL_TRUE;
+}
+
+void
+via_free_depth_buffer(viaContextPtr vmesa)
+{
+    drm_via_mem_t fb;
+       
+    if (!vmesa) return;
+    fb.context = vmesa->hHWContext;
+    fb.index = vmesa->depth.index;
+    fb.type = VIDEO;
+    ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
+    vmesa->depth.map = NULL;
+}
+
+GLboolean
+via_alloc_dma_buffer(viaContextPtr vmesa)
+{
+    drm_via_mem_t fb;
+    drmVIADMABuf dma;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    if (vmesa->viaScreen->agpLinearStart) {
+       /* Allocate DMA in AGP memory*/
+       fb.context = vmesa->hHWContext;
+       fb.size = vmesa->dma[0].size;
+       fb.type = AGP;
+       if (!ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
+           vmesa->dma[0].offset = fb.offset;
+           vmesa->dma[0].index = fb.index;
+           vmesa->dma[0].map = (unsigned char *)((GLuint)vmesa->viaScreen->agpLinearStart + fb.offset);
+           if (!ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
+               vmesa->dma[1].offset = fb.offset;
+               vmesa->dma[1].index = fb.index;
+               vmesa->dma[1].map = (unsigned char *)((GLuint)vmesa->viaScreen->agpLinearStart + fb.offset);    
+               vmesa->useAgp = GL_TRUE;
+               
+               return GL_TRUE;
+           } 
+           else {
+               /* release dma[0]*/
+               return GL_FALSE;                
+           }
+       }
+       return GL_FALSE;        
+    } 
+    else {
+       /* Allocate DMA in System memory */
+       dma.size = vmesa->dma[0].size;
+
+       if (drmVIAAllocateDMA(vmesa->driFd,&dma) < 0) {
+           return GL_FALSE;
+       }
+
+       vmesa->dma[0].offset = 0;
+       vmesa->dma[0].map = (unsigned char *)dma.address;
+       vmesa->dma[0].index = dma.index;
+
+       drmVIAAllocateDMA(vmesa->driFd, &dma);
+
+       vmesa->dma[1].offset = 0;
+       vmesa->dma[1].map = (unsigned char *)dma.address;
+       vmesa->dma[1].index = dma.index;
+       vmesa->useAgp = GL_FALSE;
+       
+       return GL_TRUE;
+    }
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
+void
+via_free_dma_buffer(viaContextPtr vmesa)
+{
+    drmVIADMABuf dma;
+    drm_via_mem_t fb;
+    
+    
+    if (!vmesa) return;
+    
+    /* Release AGP command buffer */
+    if (vmesa->useAgp) {
+       fb.context = vmesa->hHWContext;
+       fb.index = vmesa->dma[0].index;
+       fb.type = AGP;
+       ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
+       vmesa->dma[0].map = NULL;    
+       fb.index = vmesa->dma[1].index;
+       ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
+       vmesa->dma[1].map = NULL;    
+    }
+    /* Release System command buffer */
+    else {
+       
+       dma.address = (unsigned long *)vmesa->dma[0].map;
+       /*=* John Sheng [2003.6.16] fix pci path *=*/
+       dma.size = (unsigned int)vmesa->dma[0].size;
+       drmVIAReleaseDMA(vmesa->driFd, &dma);
+       
+       dma.address = (unsigned long *)vmesa->dma[1].map;
+       /*=* John Sheng [2003.6.16] fix pci path *=*/
+       dma.size = (unsigned int)vmesa->dma[1].size;
+       drmVIAReleaseDMA(vmesa->driFd, &dma);
+       vmesa->dma[0].map = 0;
+       vmesa->dma[1].map = 0;
+    }
+} 
+
+GLboolean
+via_alloc_texture(viaContextPtr vmesa, viaTextureObjectPtr t)
+{
+    drm_via_mem_t fb;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    fb.context = vmesa->hHWContext;
+    fb.size = t->texMem.size;
+    fb.type = VIDEO;
+#ifdef DEBUG    
+    if (VIA_DEBUG) {
+       fprintf(stderr, "texture size = %d\n", fb.size);
+       fprintf(stderr, "texture type = %d\n", fb.type);
+    }
+#endif
+    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
+       fprintf(stderr, "via_alloc_texture fail\n");
+        return GL_FALSE;
+    }  
+    
+    t->texMem.offset = fb.offset;
+    t->texMem.index = fb.index;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "texture index = %d\n", (GLuint)fb.index);
+#endif
+    
+    t->bufAddr = (unsigned char *)(fb.offset + (GLuint)vmesa->driScreen->pFB);
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+    return GL_TRUE;
+}
+/*=* John Sheng [2003.5.31]  agp tex *=*/
+GLboolean
+via_alloc_texture_agp(viaContextPtr vmesa, viaTextureObjectPtr t)
+{
+    drm_via_mem_t fb;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    fb.context = vmesa->hHWContext;
+    fb.size = t->texMem.size;
+    fb.type = AGP;
+#ifdef DEBUG    
+    if (VIA_DEBUG) {
+       fprintf(stderr, "texture_agp size = %d\n", fb.size);
+       fprintf(stderr, "texture type = %d\n", fb.type);
+    }
+#endif
+    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
+       fprintf(stderr, "via_alloc_texture_agp fail\n");
+        return GL_FALSE;
+    }  
+    
+    t->texMem.offset = fb.offset;
+    t->texMem.index = fb.index;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "texture agp index = %d\n", (GLuint)fb.index);
+#endif
+    
+    t->bufAddr = (unsigned char *)((GLuint)vmesa->viaScreen->agpLinearStart + fb.offset);      
+    /*=* John Sheng [2003.5.31]  agp tex *=*/
+    t->inAGP = GL_TRUE;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+    return GL_TRUE;
+}
+
+void
+via_free_texture(viaContextPtr vmesa, viaTextureObjectPtr t)
+{
+    drm_via_mem_t fb;
+#ifdef DEBUG           
+    if (VIA_DEBUG) {
+       fprintf(stderr, "via_free_texture: index = %d\n",
+            t->texMem.index);
+       fprintf(stderr, "via_free_texture: size = %d\n",
+            t->texMem.size);
+    }
+#endif
+    if (!vmesa) {
+       fprintf(stderr, "!mesa\n");
+       return;
+    }
+    
+    fb.context = vmesa->hHWContext;
+    fb.index = t->texMem.index;
+    
+    /*=* John Sheng [2003.5.31]  agp tex *=*/
+    if(t->inAGP)
+       fb.type = AGP;
+    else
+        fb.type = VIDEO;
+           
+    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb)) {
+       if(vmesa->shareCtx) {
+           fb.context = ((viaContextPtr)((GLcontext *)(vmesa->shareCtx)->DriverCtx))->hHWContext;
+           if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb)) {
+               fprintf(stderr, "via_free_texture fail\n");
+           }
+       }
+       else
+           fprintf(stderr, "via_free_texture fail\n");
+    }
+
+    t->bufAddr = NULL;
+}
diff --git a/src/mesa/drivers/dri/unichrome/via_fb.h b/src/mesa/drivers/dri/unichrome/via_fb.h
new file mode 100644 (file)
index 0000000..c4378c2
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _VIAFB_INC
+#define _VIAFB_INC
+
+#include "mtypes.h"
+#include "swrast/swrast.h"
+extern GLboolean via_alloc_front_buffer(viaContextPtr vmesa);
+extern GLboolean via_alloc_back_buffer(viaContextPtr vmesa);
+extern void via_free_back_buffer(viaContextPtr vmesa);
+extern void via_free_front_buffer(viaContextPtr vmesa);
+extern GLboolean via_alloc_depth_buffer(viaContextPtr vmesa);
+extern void via_free_depth_buffer(viaContextPtr vmesa);
+extern GLboolean via_alloc_dma_buffer(viaContextPtr vmesa);
+extern void via_free_dma_buffer(viaContextPtr vmesa);
+extern GLboolean via_alloc_texture(viaContextPtr vmesa, viaTextureObjectPtr t);
+/*=* John Sheng [2003.5.31]  agp tex *=*/
+extern GLboolean via_alloc_texture_agp(viaContextPtr vmesa, viaTextureObjectPtr t);
+extern void via_free_texture(viaContextPtr vmesa, viaTextureObjectPtr t);
+#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c
new file mode 100644 (file)
index 0000000..04dc130
--- /dev/null
@@ -0,0 +1,2217 @@
+#/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <stdio.h>
+#include <unistd.h>
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "dd.h"
+#include "swrast/swrast.h"
+
+#include "mm.h"
+#include "via_context.h"
+#include "via_ioctl.h"
+#include "via_state.h"
+
+#include "drm.h"
+#include <sys/ioctl.h>
+
+GLuint FrameCount = 0;
+GLuint dmaLow = 0;
+/*=* John Sheng [2003.5.31] flip *=*/
+GLuint nFirstSwap = GL_TRUE;
+GLuint nFirstFlip = GL_TRUE;
+#define SetReg2DAGP(nReg, nData) {                     \
+    *((GLuint *)(vb)) = ((nReg) >> 2) | 0xF0000000;     \
+    *((GLuint *)(vb) + 1) = (nData);                   \
+    vb += 2;                                           \
+    vmesa->dmaLow +=8;                                 \
+}
+
+#define DEPTH_SCALE ((1 << 16) - 1)
+
+static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
+                     GLint cx, GLint cy, GLint cw, GLint ch)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+    const GLuint colorMask = *((GLuint *)&ctx->Color.ColorMask);
+    int flag = 0;
+    GLuint scrn = 0, i = 0, side = 0;
+    scrn = vmesa->saam & S_MASK;
+    side = vmesa->saam & P_MASK;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);    
+#endif
+    VIA_FIREVERTICES(vmesa);
+
+    if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) {
+       flag |= VIA_FRONT;
+        mask &= ~DD_FRONT_LEFT_BIT;
+    }
+
+    if ((mask & DD_BACK_LEFT_BIT) && colorMask == ~0) {
+       flag |= VIA_BACK;       
+        mask &= ~DD_BACK_LEFT_BIT;
+    }
+
+    if (mask & DD_DEPTH_BIT) {
+        if (ctx->Depth.Mask)
+           flag |= VIA_DEPTH;      
+        mask &= ~DD_DEPTH_BIT;
+    }
+    
+    if (mask & DD_STENCIL_BIT) {
+       if (ctx->Stencil.Enabled)
+           flag |= VIA_STENCIL;            
+        mask &= ~DD_STENCIL_BIT;
+    }
+    
+    /*=* [DBG] make draw to front buffer *=*/
+    if(DRAW_FRONT) {
+       flag |= VIA_FRONT;
+       flag &= ~VIA_BACK;
+    }
+    
+    if (flag) {
+       LOCK_HARDWARE(vmesa);
+        /* flip top to bottom */
+        cy = dPriv->h - cy - ch;
+        cx += vmesa->drawX;
+        cy += vmesa->drawY;
+        
+       if (vmesa->numClipRects) {
+            int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, vmesa->numClipRects);
+            XF86DRIClipRectRec *box = vmesa->pClipRects;
+            drm_clip_rect_t *b = vmesa->sarea->boxes;
+            int n = 0;
+           
+           if (!vmesa->saam) {
+               if (!all) {
+#ifdef DEBUG    
+                   if (VIA_DEBUG) fprintf(stderr,"!all");
+#endif        
+                   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++ = *(drm_clip_rect_t *)&box[i];
+                       n++;
+                   }
+               }
+               vmesa->sarea->nbox = n;
+           }
+           else {
+               GLuint scrn = 0;
+               scrn = vmesa->saam & S_MASK;
+
+               if (scrn == S0 || scrn == S1) {
+                   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++ = *(drm_clip_rect_t *)&box[i];
+                           n++;
+                       }
+                   }
+                   vmesa->sarea->nbox = n;             
+               }
+               /* between */
+               else {
+                   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++ = *(drm_clip_rect_t *)&box[n];
+                           n++;
+                       }
+                   }
+                   *b++ = *(drm_clip_rect_t *)vmesa->pSaamRects;
+                   vmesa->sarea->nbox = n;
+               }
+           }
+           
+           {
+               if (flag & VIA_FRONT) {
+
+                   if (vmesa->drawType == GLX_PBUFFER_BIT)
+                       viaFillFrontPBuffer(vmesa);
+                   else
+                       viaFillFrontBuffer(vmesa);
+                   
+                   if (vmesa->saam && (scrn == (S0 | S1))) {
+                       nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, vmesa->numSaamRects);
+                       box = vmesa->pSaamRects;
+                       b = vmesa->sarea->boxes;
+                       n = 0;
+
+                       for (i = 0; i < nr; i++) {
+                           *b++ = *(drm_clip_rect_t *)&box[n];
+                           n++;
+                       }
+
+                       vmesa->sarea->nbox = n;                 
+                       viaFillFrontBufferSaam(vmesa);
+                   }
+               } 
+               
+               if (flag & VIA_BACK) {
+                   viaFillBackBuffer(vmesa);
+               }
+
+               if (flag & VIA_DEPTH) {
+                   double depth_clamp, range = 0xffffffff;
+                   if (vmesa->hasStencil == 0) {
+                       if (vmesa->depthBits == 32) {
+                           depth_clamp = ((double)ctx->Depth.Clear)*range;
+                           viaFillDepthBuffer(vmesa, (GLuint)depth_clamp);
+                       }
+                       else {
+                           depth_clamp = ((double)ctx->Depth.Clear)*range;
+                           viaFillDepthBuffer(vmesa, (GLuint)depth_clamp);
+                       }
+                   }
+                   else {
+                       depth_clamp = ((double)ctx->Depth.Clear)*range;
+                       viaFillStencilDepthBuffer(vmesa, (GLuint)depth_clamp);
+                   }
+               }               
+               /*=* [DBG] Fix tuxracer depth error *=*/
+               else if (flag & VIA_STENCIL) {
+                   viaFillStencilBuffer(vmesa, (GLuint)ctx->Stencil.Clear);
+               }
+           }
+        }
+        UNLOCK_HARDWARE(vmesa);
+        vmesa->uploadCliprects = GL_TRUE;
+    }
+
+    if (mask)
+        _swrast_Clear(ctx, mask, all, cx, cy, cw, ch);
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);    
+#endif
+}
+
+/*
+ * Copy the back buffer to the front buffer. 
+ */
+void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
+{
+    viaContextPtr vmesa;
+    XF86DRIClipRectPtr pbox;
+    int nbox, i;
+    GLuint scrn = 0, side = 0;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);        
+#endif
+    assert(dPriv);
+    assert(dPriv->driContextPriv);
+    assert(dPriv->driContextPriv->driverPrivate);
+
+    vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate;
+    
+    VIA_FIREVERTICES(vmesa);
+    LOCK_HARDWARE(vmesa);
+    
+    scrn = vmesa->saam & S_MASK;
+    side = vmesa->saam & P_MASK;
+    
+    pbox = vmesa->pClipRects;
+    nbox = vmesa->numClipRects;
+
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s %d cliprects (%d), SAAM (%d)\n", 
+       __FUNCTION__, nbox, vmesa->drawType, vmesa->saam);
+#endif
+    
+       
+    if (vmesa->drawType == GLX_PBUFFER_BIT) {
+       viaDoSwapPBuffers(vmesa);
+#ifdef DEBUG    
+        if (VIA_DEBUG) fprintf(stderr, "%s SwapPBuffers\n", __FUNCTION__);    
+#endif /*=* [DBG] for pbuffer *=*/
+       /*viaDoSwapBufferSoftFront(vmesa);*/
+    }
+    else {
+       GLuint scrn = 0;
+       scrn = vmesa->saam & S_MASK;
+       if (!vmesa->saam) {
+           for (i = 0; i < nbox; ) {
+               int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
+               XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)vmesa->sarea->boxes;
+
+               vmesa->sarea->nbox = nr - i;
+
+               for (; i < nr; i++)
+                   *b++ = pbox[i];
+               viaDoSwapBuffers(vmesa);
+#ifdef DEBUG    
+               if (VIA_DEBUG) fprintf(stderr, "%s SwapBuffers\n", __FUNCTION__);    
+#endif
+           }
+       }
+       else if (scrn == S0 || scrn == S1) {
+           for (i = 0; i < nbox; ) {
+               int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, vmesa->numClipRects);
+               XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)vmesa->sarea->boxes;
+
+               vmesa->sarea->nbox = nr - i;
+               
+               for (; i < nr; i++) {
+                   *b++ = pbox[i];
+               }
+               viaDoSwapBuffers(vmesa);
+           }
+       }
+       /* between */
+       else {
+           for (i = 0; i < nbox; ) {
+               int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
+               XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)vmesa->sarea->boxes;
+
+               vmesa->sarea->nbox = nr - i;
+
+               for (; i < nr; i++)
+                   *b++ = pbox[i];
+               viaDoSwapBuffers(vmesa);
+           }
+
+           pbox = vmesa->pSaamRects;
+           nbox = vmesa->numSaamRects;
+
+           for (i = 0; i < nbox; ) {
+               int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, vmesa->numSaamRects);
+               XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)vmesa->sarea->boxes;
+
+               vmesa->sarea->nbox = nr - i;
+
+               for (; i < nr; i++)
+                   *b++ = pbox[i];
+
+               viaDoSwapBuffersSaam(vmesa);
+           }
+       }
+    }
+    UNLOCK_HARDWARE(vmesa);
+    vmesa->uploadCliprects = GL_TRUE;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);        
+#endif
+}
+
+/*
+ * XXX implement when full-screen extension is done.
+ */
+void viaPageFlip(const __DRIdrawablePrivate *dPriv)
+{
+    /*=* John Sheng [2003.5.31] flip *=*/
+    viaContextPtr vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate;
+    GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56);
+    GLuint nBackBase;
+    viaBuffer buffer_tmp;
+    GLcontext *ctx;
+
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);        
+#endif
+    assert(dPriv);
+    assert(dPriv->driContextPriv);
+    assert(dPriv->driContextPriv->driverPrivate);
+
+    ctx = vmesa->glCtx;
+    
+    /*=* [DBG] make draw to front buffer *=*/
+    if(DRAW_FRONT)
+       return;
+    
+    /* Page Flip*/
+    if(GL_FALSE) {
+       viaFlushPrimsLocked(vmesa);
+       while ((*(volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x200) & 0x2) != 0x2);
+       while (*(volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x200) & 0x2);
+       nBackBase = vmesa->back.offset >> 1;
+       
+       /*if (nFirstFlip) {
+           *vb++ = HALCYON_HEADER2;
+           *vb++ = 0x00fe0000;
+           *vb++ = 0x00001004;
+           *vb++ = 0x00001004;
+           vmesa->dmaLow += 16;
+
+           nFirstFlip = GL_FALSE;
+       }
+       SetReg2DAGP(0x214, nBackBase);
+       viaFlushPrimsLocked(vmesa);*/
+       if (nFirstFlip) {
+           *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x43c)) = 0x00fe0000;
+           *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x440)) = 0x00001004;
+           nFirstFlip = GL_FALSE;
+       }
+       *((GLuint *)((GLuint)vmesa->regMMIOBase + 0x214)) = nBackBase;
+    }
+    /* Auto Swap */
+    else {
+       viaFlushPrimsLocked(vmesa);
+       vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56);
+       if (nFirstSwap) {
+           *vb++ = HALCYON_HEADER2;
+           *vb++ = 0x00fe0000;
+           *vb++ = 0x0000000e;
+           *vb++ = 0x0000000e;
+           vmesa->dmaLow += 16;
+
+           nFirstSwap = GL_FALSE;
+       }
+       nBackBase = (vmesa->back.offset << 1);
+
+       *vb++ = HALCYON_HEADER2;
+       *vb++ = 0x00fe0000;
+       *vb++ = (HC_SubA_HFBBasL << 24) | (nBackBase & 0xFFFFF8) | 0x2;
+       *vb++ = (HC_SubA_HFBDrawFirst << 24) |
+                          ((nBackBase & 0xFF000000) >> 24) | 0x0100;
+       vmesa->dmaLow += 16;
+       viaFlushPrimsLocked(vmesa);
+    }
+    
+    
+    memcpy(&buffer_tmp, &vmesa->back, sizeof(viaBuffer));
+    memcpy(&vmesa->back, &vmesa->front, sizeof(viaBuffer));
+    memcpy(&vmesa->front, &buffer_tmp, sizeof(viaBuffer));
+    
+    if(vmesa->currentPage) {
+       vmesa->currentPage = 0;
+       if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) {
+               ctx->Driver.DrawBuffer(ctx, GL_BACK_LEFT);
+       }
+       else {
+               ctx->Driver.DrawBuffer(ctx, GL_FRONT_LEFT);
+       }
+    }
+    else {
+       vmesa->currentPage = 1;
+       if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) {
+               ctx->Driver.DrawBuffer(ctx, GL_BACK_LEFT);
+       }
+       else {
+               ctx->Driver.DrawBuffer(ctx, GL_FRONT_LEFT);
+       }
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);        
+#endif
+
+}
+
+/* This waits for *everybody* to finish rendering -- overkill.
+ */
+void viaDmaFinish(viaContextPtr vmesa)
+{
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);        
+#endif
+    VIA_FIREVERTICES(vmesa);
+    LOCK_HARDWARE(vmesa);
+    UNLOCK_HARDWARE(vmesa);
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);    
+#endif
+}
+
+void viaRegetLockQuiescent(viaContextPtr vmesa)
+{
+    drmUnlock(vmesa->driFd, vmesa->hHWContext);
+}
+
+static int intersect_rect(drm_clip_rect_t *out,
+                          drm_clip_rect_t *a,
+                          drm_clip_rect_t *b)
+{
+    *out = *a;
+
+    if (b->x1 > out->x1) out->x1 = b->x1;
+    if (b->x2 < out->x2) out->x2 = b->x2;
+    if (out->x1 >= out->x2) return 0;
+
+    if (b->y1 > out->y1) out->y1 = b->y1;
+    if (b->y2 < out->y2) out->y2 = b->y2;
+    if (out->y1 >= out->y2) return 0;
+
+    return 1;
+}
+
+void viaFlushPrimsLocked(viaContextPtr vmesa)
+{
+    drm_clip_rect_t *pbox = (drm_clip_rect_t *)vmesa->pClipRects;
+    int nbox = vmesa->numClipRects;
+    drm_via_sarea_t *sarea = vmesa->sarea;
+    drm_via_flush_agp_t agpCmd;
+    drm_via_flush_sys_t sysCmd;
+    GLuint *vb = viaCheckDma(vmesa, 0);
+    int i;
+
+    if (vmesa->dmaLow == DMA_OFFSET) {
+       return;
+    }
+    if (vmesa->dmaLow > 2097152)
+       fprintf(stderr, "buffer overflow in Flush Prims = %d\n",vmesa->dmaLow);
+    
+    switch (vmesa->dmaLow & 0x1F) {    
+    case 8:
+       *vb++ = HC_HEADER2;
+       *vb++ = (HC_ParaType_NotTex << 16);
+       *vb++ = HC_DUMMY;
+       *vb++ = HC_DUMMY;
+       *vb++ = HC_DUMMY;
+       *vb++ = HC_DUMMY;
+       vmesa->dmaLow += 24;
+       break;
+    case 16:
+       *vb++ = HC_HEADER2;
+       *vb++ = (HC_ParaType_NotTex << 16);
+       *vb++ = HC_DUMMY;
+       *vb++ = HC_DUMMY;
+       vmesa->dmaLow += 16;
+       break;    
+    case 24:
+       *vb++ = HC_HEADER2;
+       *vb++ = (HC_ParaType_NotTex << 16);
+       *vb++ = HC_DUMMY;
+       *vb++ = HC_DUMMY;
+       *vb++ = HC_DUMMY;
+       *vb++ = HC_DUMMY;
+       *vb++ = HC_DUMMY;
+       *vb++ = HC_DUMMY;
+       *vb++ = HC_DUMMY;
+       *vb++ = HC_DUMMY;       
+       vmesa->dmaLow += 40;
+       break;    
+    case 0:
+       break;
+    default:
+       break;
+    }
+    
+    if (vmesa->useAgp) {
+       agpCmd.offset = 0x0;
+       agpCmd.size = vmesa->dmaLow;
+       agpCmd.index = vmesa->dma[vmesa->dmaIndex].index;
+       agpCmd.discard = 0;
+    } 
+    else {
+       sysCmd.offset = 0x0;
+       sysCmd.size = vmesa->dmaLow;
+       sysCmd.index = (GLuint)vmesa->dma[vmesa->dmaIndex].map;
+       sysCmd.discard = 0;
+    }
+    
+    sarea->vertexPrim = vmesa->hwPrimitive;
+
+    if (!nbox) {
+       if (vmesa->useAgp)
+           agpCmd.size = 0;
+       else
+           sysCmd.size = 0;
+    }
+    else if (nbox > VIA_NR_SAREA_CLIPRECTS) {
+        vmesa->uploadCliprects = GL_TRUE;
+    }
+/*=* John Sheng [2003.5.31] flip *=*/
+/*#ifdef DEBUG    
+    if (VIA_DEBUG) {
+       GLuint i;
+       GLuint *data = (GLuint *)vmesa->dmaAddr;
+       for (i = 0; i < vmesa->dmaLow; i += 16) {
+            fprintf(stderr, "%08x  ", *data++);
+           fprintf(stderr, "%08x  ", *data++);
+           fprintf(stderr, "%08x  ", *data++);
+           fprintf(stderr, "%08x\n", *data++);
+       }
+       fprintf(stderr, "******************************************\n");
+    }   
+#endif*/
+    if (!nbox || !vmesa->uploadCliprects) {
+        if (nbox == 1)
+            sarea->nbox = 0;
+        else
+            sarea->nbox = nbox;
+
+       if (vmesa->useAgp) {
+           agpCmd.discard = 1;
+           flush_agp(vmesa, &agpCmd);
+       }
+       else {
+           sysCmd.discard = 1;
+           flush_sys(vmesa, &sysCmd);
+       }
+    }
+    else {
+       GLuint scrn;
+       GLuint side;
+       scrn = vmesa->saam & S_MASK;
+       side = vmesa->saam & P_MASK;
+        
+       for (i = 0; i < nbox; ) {
+            int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, nbox);
+            drm_clip_rect_t *b = sarea->boxes;
+
+            if (!vmesa->saam) {
+               if (vmesa->glCtx->Scissor.Enabled) {
+                   sarea->nbox = 0;
+
+                   for (; i < nr; i++) {
+                       b->x1 = pbox[i].x1 - vmesa->drawX;
+                       b->y1 = pbox[i].y1 - vmesa->drawY;
+                       b->x2 = pbox[i].x2 - vmesa->drawX;
+                       b->y2 = pbox[i].y2 - vmesa->drawY;
+                       if (intersect_rect(b, b, &vmesa->scissorRect)) {
+                           sarea->nbox++;
+                           b++;
+                       }
+                   }
+                   if (!sarea->nbox) {
+                       if (nr < nbox) continue;
+                       agpCmd.size = 0;
+                   }
+               }
+               else {
+                   sarea->nbox = nr - i;
+                   for (; i < nr; i++, b++) {
+                       b->x1 = pbox[i].x1 - vmesa->drawX;
+                       b->y1 = pbox[i].y1 - vmesa->drawY;
+                       b->x2 = pbox[i].x2 - vmesa->drawX;
+                       b->y2 = pbox[i].y2 - vmesa->drawY;
+                   }
+               }
+           }
+           else if (scrn == S0 || scrn == S1){
+               if (vmesa->scissor) {
+                   sarea->nbox = 0;
+                   for (; i < nr; i++) {
+                       b->x1 = pbox[i].x1 - vmesa->drawX;
+                       b->y1 = pbox[i].y1 - vmesa->drawY;
+                       b->x2 = pbox[i].x2 - vmesa->drawX;
+                       b->y2 = pbox[i].y2 - vmesa->drawY;
+                       if (intersect_rect(b, b, &vmesa->scissorRect)) {
+                           sarea->nbox++;
+                           b++;
+                       }
+                   }
+                   if (!sarea->nbox) {
+                       if (nr < nbox) continue;
+                       agpCmd.size = 0;
+                   }
+               }
+               else {
+                   sarea->nbox = nr - i;
+                   for (; i < nr; i++, b++) {
+                       b->x1 = pbox[i].x1 - vmesa->drawX;
+                       b->y1 = pbox[i].y1 - vmesa->drawY;
+                       b->x2 = pbox[i].x2 - vmesa->drawX;
+                       b->y2 = pbox[i].y2 - vmesa->drawY;
+                   }
+               }
+           
+           }
+           /* between */
+           else {
+               if (vmesa->scissor) {
+                   sarea->nbox = 0;
+                   for (; i < nr; i++) {
+                       b->x1 = pbox[i].x1 - vmesa->drawX;
+                       b->y1 = pbox[i].y1 - vmesa->drawY;
+                       b->x2 = pbox[i].x2 - vmesa->drawX;
+                       b->y2 = pbox[i].y2 - vmesa->drawY;
+
+                       if (intersect_rect(b, b, &vmesa->scissorRect)) {
+                           sarea->nbox++;
+                           b++;
+                       }
+                   }
+                   if (!sarea->nbox) {
+                       if (nr < nbox) continue;
+                       agpCmd.size = 0;
+                   }
+               }
+               else {
+                   sarea->nbox = nr - i;
+                   for (; i < nr; i++, b++) {
+                       b->x1 = pbox[i].x1 - vmesa->drawX;
+                       b->y1 = pbox[i].y1 - vmesa->drawY;
+                       b->x2 = pbox[i].x2 - vmesa->drawX;
+                       b->y2 = pbox[i].y2 - vmesa->drawY;
+                   }
+               }
+           }
+
+            if (nr == nbox) {
+               if (vmesa->useAgp) {
+                   agpCmd.discard = 1;
+                   flush_agp(vmesa, &agpCmd);
+               } 
+               else {
+                   sysCmd.discard = 1;
+                   flush_sys(vmesa, &sysCmd);
+               }
+           }
+
+           if (scrn == (S0 | S1)) {
+               pbox = (drm_clip_rect_t *)vmesa->pSaamRects;
+               nbox = vmesa->numSaamRects;
+               for (i = 0; i < nbox; ) {
+                   int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, nbox);
+                   drm_clip_rect_t *b = sarea->boxes;
+                   if (vmesa->scissor) {
+                       sarea->nbox = 0;
+                       for (; i < nr; i++) {
+                           b->x1 = pbox[i].x1 - vmesa->drawXSaam;
+                           b->y1 = pbox[i].y1 - vmesa->drawYSaam;
+                           b->x2 = pbox[i].x2 - vmesa->drawXSaam;
+                           b->y2 = pbox[i].y2 - vmesa->drawYSaam;
+
+                           if (intersect_rect(b, b, &vmesa->scissorRect)) {
+                               sarea->nbox++;
+                               b++;
+                           }
+                       }
+                       if (!sarea->nbox) {
+                           if (nr < nbox) continue;
+                           agpCmd.size = 0;
+                       }
+                   }
+                   else {
+                       sarea->nbox = nr - i;
+                       for (; i < nr; i++, b++) {
+                           b->x1 = pbox[i].x1 - vmesa->drawXSaam;
+                           b->y1 = pbox[i].y1 - vmesa->drawYSaam;
+                           b->x2 = pbox[i].x2 - vmesa->drawXSaam;
+                           b->y2 = pbox[i].y2 - vmesa->drawYSaam;
+                       }
+                   }
+               }
+               flush_agp_saam(vmesa, &agpCmd);
+           }
+        }
+    }
+#ifdef DEBUG        
+    if (VIA_DEBUG) {
+       GLuint i;
+       GLuint *data = (GLuint *)vmesa->dmaAddr;
+       for (i = 0; i < vmesa->dmaLow; i += 16) {
+            fprintf(stderr, "%08x  ", *data++);
+           fprintf(stderr, "%08x  ", *data++);
+           fprintf(stderr, "%08x  ", *data++);
+           fprintf(stderr, "%08x\n", *data++);
+       }
+       fprintf(stderr, "******************************************\n");
+    }  
+#endif
+    /* Reset vmesa vars:
+     */
+    vmesa->dmaLow = DMA_OFFSET;
+    if (vmesa->dmaIndex) {
+        vmesa->dmaAddr = vmesa->dma[0].map;
+        vmesa->dmaHigh = vmesa->dma[0].size;
+        vmesa->dmaLastPrim = DMA_OFFSET;
+       vmesa->dmaIndex = 0;
+    }
+    else {
+        vmesa->dmaAddr = vmesa->dma[1].map;
+        vmesa->dmaHigh = vmesa->dma[1].size;
+        vmesa->dmaLastPrim = DMA_OFFSET;
+       vmesa->dmaIndex = 1;    
+    }
+}
+
+void viaFlushPrims(viaContextPtr vmesa)
+{
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    if (vmesa->dmaLow) {
+        LOCK_HARDWARE(vmesa);
+        viaFlushPrimsLocked(vmesa);
+        UNLOCK_HARDWARE(vmesa);
+    }
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+}
+
+static void viaFlush(GLcontext *ctx)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);    
+#endif    
+    VIA_FIREVERTICES(vmesa);
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);    
+#endif
+}
+
+static void viaFinish(GLcontext *ctx)
+{
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);    
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);    
+#endif
+    return;
+}
+
+static void viaClearStencil(GLcontext *ctx,  int s)
+{
+    return;
+}
+
+void viaInitIoctlFuncs(GLcontext *ctx)
+{
+    ctx->Driver.Flush = viaFlush;
+    ctx->Driver.Clear = viaClear;
+    ctx->Driver.Finish = viaFinish;
+    ctx->Driver.ClearStencil = viaClearStencil;
+}
+
+void viaFillFrontBuffer(viaContextPtr vmesa)
+{
+    GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset,i; 
+    drm_clip_rect_t *b = vmesa->sarea->boxes;
+    GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*48);
+    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+    GLuint pixel = (GLuint)vmesa->ClearColor;
+
+    offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * vmesa->front.pitch + vmesa->drawX * bytePerPixel);
+#ifdef DEBUG        
+    if (VIA_DEBUG) fprintf(stderr, "Fill Front offset = %08x\n", offset);
+#endif    
+    nDestBase = offset & 0xffffffe0;
+    nDestPitch = vmesa->front.pitch;
+
+    for (i = 0; i < vmesa->sarea->nbox ; i++) {        
+        nDestWidth = b->x2 - b->x1 - 1;
+       nDestHeight = b->y2 - b->y1 - 1;
+       
+       if (bytePerPixel == 4)
+           offsetX = (b->x1 - vmesa->drawX) + (vmesa->drawX & 7);
+       else 
+           offsetX = (b->x1 - vmesa->drawX) + (vmesa->drawX & 15);
+    
+
+       if (GL_TRUE) {
+           /* GEFGCOLOR*/
+           SetReg2DAGP(0x18, pixel | 0x00000000);
+           /* GEWD*/
+           SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
+           /* GEDST*/
+           SetReg2DAGP(0x0C, (offsetX | ((b->y1 - vmesa->drawY) << 16)));
+           /* GEDSTBASE*/
+           SetReg2DAGP(0x34, (nDestBase >> 3));
+           /* GEPITCH*/
+           SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
+           /* BITBLT*/
+           SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
+       }
+       b++;
+    }
+
+    viaFlushPrimsLocked(vmesa);
+}
+
+void viaFillFrontBufferSaam(viaContextPtr vmesa)
+{
+    GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset,i; 
+    drm_clip_rect_t *b = vmesa->sarea->boxes;
+    GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*48);
+    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+    GLuint pixel = (GLuint)vmesa->ClearColor;
+
+    offset = vmesa->viaScreen->fbSize + 
+       (vmesa->drawYSaam * vmesa->front.pitch + vmesa->drawXSaam * bytePerPixel);
+    nDestBase = offset & 0xffffffe0;
+    nDestPitch = vmesa->front.pitch;
+
+    for (i = 0; i < vmesa->sarea->nbox ; i++) {        
+        nDestWidth = b->x2 - b->x1 - 1;
+       nDestHeight = b->y2 - b->y1 - 1;
+       
+       if (bytePerPixel == 4)
+           offsetX = (b->x1 - vmesa->drawXSaam) + (vmesa->drawXSaam & 7);
+       else 
+           offsetX = (b->x1 - vmesa->drawXSaam) + (vmesa->drawXSaam & 15);
+    
+       if (GL_TRUE) {
+           /* GEFGCOLOR*/
+           SetReg2DAGP(0x18, pixel | 0x00000000);
+           /* GEWD*/
+           SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
+           /* GEDST*/
+           SetReg2DAGP(0x0C, (offsetX | ((b->y1 - vmesa->drawYSaam) << 16)));
+           /* GEDSTBASE*/
+           SetReg2DAGP(0x34, (nDestBase >> 3));
+           /* GEPITCH*/
+           SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
+           /* BITBLT*/
+           SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
+       }
+       b++;
+    }
+
+    viaFlushPrimsLocked(vmesa);
+}
+
+void viaFillFrontPBuffer(viaContextPtr vmesa)
+{
+    GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset; 
+    GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*48);
+    GLuint pixel = (GLuint)vmesa->ClearColor;
+
+    offset = vmesa->front.offset;
+#ifdef DEBUG        
+    if (VIA_DEBUG) fprintf(stderr, "Fill PFront offset = %08x\n", offset);
+#endif    
+    nDestBase = offset;
+    nDestPitch = vmesa->front.pitch;
+
+    nDestWidth = vmesa->driDrawable->w - 1;
+    nDestHeight = vmesa->driDrawable->h - 1;
+       
+    offsetX = 0;
+
+    /* GEFGCOLOR*/
+    SetReg2DAGP(0x18, pixel | 0x00000000);
+    /* GEWD*/
+    SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
+    /* GEDST*/
+    SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
+    /* GEDSTBASE*/
+    SetReg2DAGP(0x34, (nDestBase >> 3));
+    /* GEPITCH*/
+    SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
+    /* BITBLT*/
+    SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
+    
+    viaFlushPrimsLocked(vmesa);
+}
+
+void viaFillBackBuffer(viaContextPtr vmesa)
+{
+    GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset; 
+    GLcontext *ctx = vmesa->glCtx;
+    GLuint *vb = viaCheckDma(vmesa, 48);
+    GLuint pixel = (GLuint)vmesa->ClearColor;
+    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+
+    offset = vmesa->back.offset;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "Fill Back offset = %08x\n", offset);
+#endif
+    nDestBase = offset;
+    nDestPitch = vmesa->back.pitch;
+    offsetX = vmesa->drawXoff;
+    
+    {
+       if (!ctx->Scissor.Enabled) {
+           
+           nDestWidth = (vmesa->back.pitch / vmesa->viaScreen->bitsPerPixel * 8) - 1;
+           nDestHeight = vmesa->driDrawable->h -1;
+           
+           /* GEFGCOLOR */
+           SetReg2DAGP(0x18, pixel | 0x00000000);
+           /* GEWD */
+           SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
+           /* GEDST */
+           SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
+           /* GEDSTBASE */
+           SetReg2DAGP(0x34, (nDestBase >> 3));
+           /* GEPITCH */
+           SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
+           /* BITBLT */
+           SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
+       }
+       /*=* John Sheng [2003.7.18] texenv *=*/
+       else {
+           int i;
+           drm_clip_rect_t *b = vmesa->sarea->boxes;
+           for (i = 0; i < vmesa->sarea->nbox ; i++) {        
+               nDestWidth = b->x2 - b->x1 - 1;
+               nDestHeight = b->y2 - b->y1 - 1;
+               
+               if (bytePerPixel == 4)
+                   offsetX = (b->x1 - vmesa->drawX) + (vmesa->drawX & 7);
+               else 
+                   offsetX = (b->x1 - vmesa->drawX) + (vmesa->drawX & 15);
+               
+               /* GEFGCOLOR */
+               SetReg2DAGP(0x18, pixel | 0x00000000);
+               /* GEWD */
+               SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
+               /* GEDST */
+               SetReg2DAGP(0x0C, ((offsetX + (b->x1 - vmesa->drawX)) | ((b->y1 - vmesa->drawY) << 16)));
+               /* GEDSTBASE */
+               SetReg2DAGP(0x34, (nDestBase >> 3));
+               /* GEPITCH */
+               SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
+               /* BITBLT */
+               SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
+               b++;
+           }
+       }
+#ifdef DEBUG           
+       if (VIA_DEBUG) {
+           fprintf(stderr," width = %08x\n", nDestWidth);      
+           fprintf(stderr," height = %08x\n", nDestHeight);    
+       }            
+#endif
+    }
+}
+
+void viaFillStencilDepthBuffer(viaContextPtr vmesa, GLuint pixel)
+{
+    GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset; 
+    GLuint *vb = viaCheckDma(vmesa, 80);
+    GLuint nMask;
+    
+    offset = vmesa->depth.offset;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "Fill Stencil Depth offset = %08x\n", offset);
+#endif    
+    nDestBase = offset;
+    nDestPitch = vmesa->depth.pitch;
+    offsetX = vmesa->drawXoff;
+    pixel = pixel & 0xffffff00;
+    nMask = 0x10000000;
+    
+    {        
+       nDestWidth = (vmesa->depth.pitch / vmesa->depthBits * 8) - 1 - offsetX;
+       nDestHeight = vmesa->driDrawable->h -1;
+       
+       if (vmesa->viaScreen->bitsPerPixel == vmesa->depth.bpp) {
+           /* GEFGCOLOR */
+           SetReg2DAGP(0x18, pixel);
+           /* GEMASK */
+           SetReg2DAGP(0x2C, nMask);
+           /* GEWD */
+           SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
+           /* GEDST */
+           SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
+           /* GEDSTBASE */
+           SetReg2DAGP(0x34, (nDestBase >> 3));
+           /* GEPITCH */
+           SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
+           /* BITBLT */
+           SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
+           /* GEMASK */
+           SetReg2DAGP(0x2C, 0x00000000);
+       }
+       else {
+           GLuint EngStatus = *(vmesa->pnGEMode);
+           /* GEMODE */
+           SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | 0x300);
+           /* GEFGCOLOR */
+           SetReg2DAGP(0x18, pixel);
+           /* GEMASK */
+           SetReg2DAGP(0x2C, nMask);
+           /* GEWD */
+           SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
+           /* GEDST */
+           SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
+           /* GEDSTBASE */
+           SetReg2DAGP(0x34, (nDestBase >> 3));
+           /* GEPITCH */
+           SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
+           /* BITBLT */
+           SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
+           /* GEMODE */
+           SetReg2DAGP(0x04, EngStatus);
+           /* GEMASK */
+           SetReg2DAGP(0x2C, 0x00000000);
+           
+           WAIT_IDLE
+       }
+    }
+
+    if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) {
+       viaFlushPrimsLocked(vmesa);
+    }
+}
+
+void viaFillStencilBuffer(viaContextPtr vmesa, GLuint pixel)
+{
+    GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset; 
+    GLuint *vb = viaCheckDma(vmesa, 80);
+    GLuint nMask;
+    
+    offset = vmesa->depth.offset;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "Fill Stencil offset = %08x\n", offset);
+#endif
+    nDestBase = offset;
+    nDestPitch = vmesa->depth.pitch;
+    offsetX = vmesa->drawXoff; 
+    pixel = pixel & 0x000000ff;
+    nMask = 0xe0000000;
+    
+    {        
+       nDestWidth = (vmesa->depth.pitch / vmesa->depthBits * 8) - 1 - offsetX;
+       nDestHeight = vmesa->driDrawable->h -1;
+       
+       if (vmesa->viaScreen->bitsPerPixel == vmesa->depth.bpp) {
+           /* GEFGCOLOR */
+           SetReg2DAGP(0x18, pixel);
+           /* GEMASK */
+           SetReg2DAGP(0x2C, nMask);
+           /* GEWD */
+           SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
+           /* GEDST */
+           SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
+           /* GEDSTBASE */
+           SetReg2DAGP(0x34, (nDestBase >> 3));
+           /* GEPITCH */
+           SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
+           /* BITBLT */
+           SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
+           /* GEMASK */
+           SetReg2DAGP(0x2C, 0x00000000);
+       }
+       else {
+           GLuint EngStatus = *(vmesa->pnGEMode);
+           /* GEMODE */
+           SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | 0x300);
+           /* GEFGCOLOR */
+           SetReg2DAGP(0x18, pixel);
+           /* GEMASK */
+           SetReg2DAGP(0x2C, nMask);
+           /* GEWD */
+           SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
+           /* GEDST */
+           SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
+           /* GEDSTBASE */
+           SetReg2DAGP(0x34, (nDestBase >> 3));
+           /* GEPITCH */
+           SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
+           /* BITBLT */
+           SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
+           /* GEMODE */
+           SetReg2DAGP(0x04, EngStatus);
+           /* GEMASK */
+           SetReg2DAGP(0x2C, 0x00000000);
+       }
+    }
+
+    if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) {
+       viaFlushPrimsLocked(vmesa);
+    }
+}
+
+void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel)
+{
+    GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset;
+    GLuint *vb = viaCheckDma(vmesa, 72);
+    offset = vmesa->depth.offset;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "Fill Depth offset = %08x\n", offset);
+#endif
+    nDestBase = offset;
+    nDestPitch = vmesa->depth.pitch;
+    offsetX = vmesa->drawXoff;
+    
+    {
+       nDestWidth = (vmesa->depth.pitch / vmesa->depthBits * 8) - 1 - offsetX;
+       nDestHeight = vmesa->driDrawable->h -1;
+       
+       if (vmesa->viaScreen->bitsPerPixel == vmesa->depth.bpp) {
+           /* GEFGCOLOR */
+           SetReg2DAGP(0x18, pixel);
+           /* GEMASK */
+           SetReg2DAGP(0x2C, 0x0);
+           /* GEWD */
+           SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
+           /* GEDST */
+           SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
+           /* GEDSTBASE */
+           SetReg2DAGP(0x34, (nDestBase >> 3));
+           /* GEPITCH */
+           SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
+           /* BITBLT */
+           SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
+       }
+       /* depth = 16, color = 32 */
+       else if (vmesa->depth.bpp == 16) {
+           GLuint EngStatus = *(vmesa->pnGEMode);
+           
+           /* GEMODE */
+           SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | 0x100);
+           /* GEMASK */
+           SetReg2DAGP(0x2C, 0x0);
+           /* GEFGCOLOR */
+           SetReg2DAGP(0x18, pixel);
+           /* GEWD */
+           SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
+           /* GEDST */
+           SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
+           /* GEDSTBASE */
+           SetReg2DAGP(0x34, (nDestBase >> 3));
+           /* GEPITCH */
+           SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
+           /* BITBLT */
+           SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
+           /* GEMODE */
+           SetReg2DAGP(0x04, EngStatus);
+       }
+       /* depth = 32, color = 16 */
+       else {
+           GLuint EngStatus = *(vmesa->pnGEMode);
+           
+           /* GEMODE */
+           SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | 0x300);
+           /* GEMASK */
+           SetReg2DAGP(0x2C, 0x0);
+           /* GEFGCOLOR */
+           SetReg2DAGP(0x18, pixel);
+           /* GEWD */
+           SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
+           /* GEDST */
+           SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
+           /* GEDSTBASE */
+           SetReg2DAGP(0x34, (nDestBase >> 3));
+           /* GEPITCH */
+           SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
+           /* BITBLT */
+           SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
+           /* GEMODE */
+           SetReg2DAGP(0x04, EngStatus);
+       }
+    }
+    
+    if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) {
+       viaFlushPrimsLocked(vmesa);
+    }
+}
+
+void viaDoSwapBuffers(viaContextPtr vmesa)
+{    
+    GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56);
+    GLuint nFrontPitch;
+    GLuint nBackPitch;
+    GLuint nFrontWidth, nFrontHeight, nBackWidth, nBackHeight;
+    GLuint nFrontBase, nBackBase;
+    GLuint nFrontOffsetX, nFrontOffsetY, nBackOffsetX, nBackOffsetY;
+    drm_clip_rect_t *b = vmesa->sarea->boxes;
+    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+    GLuint i;
+    
+    nFrontPitch = vmesa->front.pitch;
+    nBackPitch = vmesa->back.pitch;
+    
+    /* Caculate Base */
+    nFrontBase = vmesa->viaScreen->fbOffset + (vmesa->drawY * nFrontPitch + vmesa->drawX * bytePerPixel);
+    nBackBase = vmesa->back.offset;
+    /* 128 bit alignment*/
+    nFrontBase = nFrontBase & 0xffffffe0;
+    
+    /*=* [DBG] make draw to front buffer *=*/
+    if(DRAW_FRONT)
+       return;
+    
+    for (i = 0; i < vmesa->sarea->nbox; i++) {        
+       /* Width, Height */
+        nFrontWidth = nBackWidth = b->x2 - b->x1 - 1;
+       nFrontHeight = nBackHeight = b->y2 - b->y1 - 1;
+       /* Offset */
+       nFrontOffsetX = (b->x1 - vmesa->drawX) + vmesa->drawXoff;
+       nFrontOffsetY = b->y1 - vmesa->drawY;
+       
+       nBackOffsetX = nFrontOffsetX;
+       nBackOffsetY = nFrontOffsetY;
+       /* GEWD */
+       SetReg2DAGP(0x10, nFrontWidth | (nFrontHeight << 16));
+        /* GEDST */
+        SetReg2DAGP(0x0C, nFrontOffsetX | (nFrontOffsetY << 16));
+        /* GESRC */
+        SetReg2DAGP(0x08, nBackOffsetX | (nBackOffsetY << 16));
+        /* GEDSTBASE */
+        SetReg2DAGP(0x34, (nFrontBase >> 3));
+        /* GESCRBASE */
+        SetReg2DAGP(0x30, (nBackBase >> 3));
+        /* GEPITCH */
+        SetReg2DAGP(0x38, (((nFrontPitch >> 3) << 16) & 0x7FF0000) | 0x80000000 |
+                          ((nBackPitch >> 3) & 0x7FF));
+       /* BITBLT */
+       SetReg2DAGP(0x0, 0x1 | 0xCC000000);
+       b++;
+    }
+
+    viaFlushPrimsLocked(vmesa);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "Do Swap Buffer\n");
+#endif
+}
+
+void viaDoSwapBuffersSaam(viaContextPtr vmesa)
+{    
+    GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56);
+    GLuint nFrontPitch;
+    GLuint nBackPitch;
+    GLuint nFrontWidth, nFrontHeight, nBackWidth, nBackHeight;
+    GLuint nFrontBase, nBackBase;
+    GLuint nFrontOffsetX, nFrontOffsetY, nBackOffsetX, nBackOffsetY;
+    drm_clip_rect_t *b = vmesa->sarea->boxes;
+    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+    GLuint i;
+    
+    nFrontPitch = vmesa->front.pitch;
+    nBackPitch = vmesa->back.pitch;
+    
+    /* Caculate Base */
+    nFrontBase = vmesa->viaScreen->fbSize + (vmesa->drawYSaam * nFrontPitch + vmesa->drawXSaam * bytePerPixel);
+    nBackBase = vmesa->back.offset;
+    /* 128 bit alignment*/
+    nFrontBase = nFrontBase & 0xffffffe0;
+    
+    /*=* [DBG] make draw to front buffer *=*/
+    if(DRAW_FRONT)
+       return;
+    
+    for (i = 0; i < vmesa->sarea->nbox; i++) {        
+       /* Width, Height */
+        nFrontWidth = nBackWidth = b->x2 - b->x1 - 1;
+       nFrontHeight = nBackHeight = b->y2 - b->y1 - 1;
+       /* Offset */
+       nFrontOffsetX = (b->x1 - vmesa->drawXSaam) + vmesa->drawXoff;
+       nFrontOffsetY = b->y1 - vmesa->drawYSaam;
+       
+       nBackOffsetX = nFrontOffsetX;
+       nBackOffsetY = nFrontOffsetY;
+       /* GEWD */
+       SetReg2DAGP(0x10, nFrontWidth | (nFrontHeight << 16));
+        /* GEDST */
+        SetReg2DAGP(0x0C, nFrontOffsetX | (nFrontOffsetY << 16));
+        /* GESRC */
+        SetReg2DAGP(0x08, nBackOffsetX | (nBackOffsetY << 16));
+        /* GEDSTBASE */
+        SetReg2DAGP(0x34, (nFrontBase >> 3));
+        /* GESCRBASE */
+        SetReg2DAGP(0x30, (nBackBase >> 3));
+        /* GEPITCH */
+        SetReg2DAGP(0x38, (((nFrontPitch >> 3) << 16) & 0x7FF0000) | 0x80000000 |
+                          ((nBackPitch >> 3) & 0x7FF));
+       /* BITBLT */
+       SetReg2DAGP(0x0, 0x1 | 0xCC000000);
+       b++;
+    }
+
+    viaFlushPrimsLocked(vmesa);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "Do Swap Buffer\n");
+#endif
+}
+
+void viaDoSwapPBuffers(viaContextPtr vmesa)
+{    
+    GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56);
+    GLuint nFrontPitch;
+    GLuint nBackPitch;
+    GLuint nFrontWidth, nFrontHeight;
+    GLuint nFrontBase, nBackBase;
+    GLuint nFrontOffsetX, nFrontOffsetY, nBackOffsetX, nBackOffsetY;
+    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+    
+    nFrontPitch = vmesa->front.pitch;
+    nBackPitch = vmesa->back.pitch;
+    
+    /* Caculate Base */
+    nFrontBase = vmesa->front.offset;
+    nBackBase = vmesa->back.offset;
+    
+    /* Width, Height */
+    nFrontWidth = nFrontPitch / bytePerPixel;
+    nFrontHeight = nBackPitch / bytePerPixel;
+    
+    /* Offset */
+    nFrontOffsetX = 0;
+    nFrontOffsetY = 0;
+    nBackOffsetX = nFrontOffsetX;
+    nBackOffsetY = nFrontOffsetY;
+    /* GEWD */
+    SetReg2DAGP(0x10, nFrontWidth | (nFrontHeight << 16));
+    /* GEDST */
+    SetReg2DAGP(0x0C, nFrontOffsetX | (nFrontOffsetY << 16));
+    /* GESRC */
+    SetReg2DAGP(0x08, nBackOffsetX | (nBackOffsetY << 16));
+    /* GEDSTBASE */
+    SetReg2DAGP(0x34, (nFrontBase >> 3));
+    /* GESCRBASE */
+    SetReg2DAGP(0x30, (nBackBase >> 3));
+    /* GEPITCH */
+    SetReg2DAGP(0x38, (((nFrontPitch >> 3) << 16) & 0x7FF0000) | 0x80000000 |
+                      ((nBackPitch >> 3) & 0x7FF));
+    /* BITBLT */
+    SetReg2DAGP(0x0, 0x1 | 0xCC000000);
+
+    viaFlushPrimsLocked(vmesa);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "Do Swap PBuffer\n");
+#endif
+}
+
+void viaDoSwapBufferSoft(viaContextPtr vmesa)
+{    
+    GLuint nFrontPitch;
+    GLuint nBackPitch;
+    GLuint nFrontBase, nBackBase;
+    GLuint i, j;
+    GLubyte *by, *fy;
+    GLuint w;
+    
+    w = vmesa->viaScreen->width;
+    w = BUFFER_ALIGN_WIDTH(w, BUFFER_ALIGNMENT);
+    
+    if (vmesa->viaScreen->bitsPerPixel == 0x20)
+       nFrontPitch = w << 2;
+    else
+       nFrontPitch = w << 1;
+    
+    nBackPitch = vmesa->back.pitch;
+    
+    /* Caculate Base */
+    nFrontBase = (GLuint) vmesa->driScreen->pFB;
+    nBackBase = ((GLuint) vmesa->back.offset) + ((GLuint) vmesa->driScreen->pFB);
+    by = (GLubyte *) nBackBase;
+    fy = (GLubyte *) nFrontBase;
+    
+    viaFlushPrimsLocked(vmesa);
+    
+    for (i = 0; i < vmesa->driDrawable->h; i++) {
+       fy = (GLubyte *)(nFrontBase + i * nFrontPitch);
+       for (j = 0; j < nBackPitch; j++) {
+           *((GLubyte*)fy) = *((GLubyte*)by);
+           fy = fy + 1;
+           by = by + 1;
+       }
+       
+    }
+
+}
+
+void viaDoSwapBufferSoftFront(viaContextPtr vmesa)
+{    
+    GLuint nFrontPitch;
+    GLuint nBackPitch;
+    GLuint nFrontBase, nBackBase;
+    GLuint i, j;
+    GLubyte *by, *fy;
+    GLuint w;
+    
+    w = vmesa->viaScreen->width;
+    w = BUFFER_ALIGN_WIDTH(w, BUFFER_ALIGNMENT);
+    
+    if (vmesa->viaScreen->bitsPerPixel == 0x20)
+       nFrontPitch = w << 2;
+    else
+       nFrontPitch = w << 1;
+       
+    nBackPitch = vmesa->front.pitch;
+    
+    /* Caculate Base */
+    nFrontBase = (GLuint) vmesa->driScreen->pFB;
+    nBackBase = ((GLuint) vmesa->front.offset) + ((GLuint) vmesa->driScreen->pFB);
+    by = (GLubyte *) nBackBase;
+    fy = (GLubyte *) nFrontBase;
+    
+    viaFlushPrimsLocked(vmesa);
+    
+    for (i = 0; i < vmesa->driDrawable->h; i++) {
+       fy = (GLubyte *)(nFrontBase + i * nFrontPitch);
+       for (j = 0; j < nBackPitch; j++) {
+           *((GLubyte*)fy) = *((GLubyte*)by);
+           fy = fy + 1;
+           by = by + 1;
+       }
+       
+    }
+
+}
+int flush_agp(viaContextPtr vmesa, drm_via_flush_agp_t* agpCmd) 
+{   
+    GLuint *pnAGPCurrentPhysStart;
+    GLuint *pnAGPCurrentPhysEnd;
+    GLuint *pnAGPCurrentStart;
+    GLuint *pnAGPCurrentEnd;
+    volatile GLuint *pnMMIOBase;
+    volatile GLuint *pnEngBaseTranSet;
+    volatile GLuint *pnEngBaseTranSpace;
+    GLuint *agpBase;
+    GLuint ofs = vmesa->dma[vmesa->dmaIndex].offset;
+    GLuint *vb = (GLuint *)vmesa->dmaAddr; 
+    GLuint i = 0;
+    
+    pnMMIOBase = vmesa->regMMIOBase;
+    pnEngBaseTranSet = vmesa->regTranSet;
+    pnEngBaseTranSpace = vmesa->regTranSpace;
+    *pnEngBaseTranSet = (0x0010 << 16);
+    agpBase = vmesa->agpBase;
+
+    if (!agpCmd->size) {
+        return -1;
+    }  
+
+    {
+        volatile GLuint *pnEngBase = vmesa->regEngineStatus;
+        int nStatus;
+       
+        while (1) {
+            nStatus = *pnEngBase;
+           if ((nStatus & 0xFFFEFFFF) == 0x00020000)
+               break;
+           i++;
+        }
+    }
+
+    pnAGPCurrentStart = (GLuint *)(ofs + agpCmd->offset);
+    pnAGPCurrentEnd = (GLuint *)((GLuint)pnAGPCurrentStart + vmesa->dmaHigh);
+    pnAGPCurrentPhysStart = (GLuint *)( (GLuint)pnAGPCurrentStart + (GLuint)agpBase );
+    pnAGPCurrentPhysEnd = (GLuint *)( (GLuint)pnAGPCurrentEnd + (GLuint)agpBase );
+
+    /*=* [DBG] make draw to front buffer *=*/
+    if(DRAW_FRONT)
+       vmesa->glCtx->Color._DrawDestMask = FRONT_LEFT_BIT;
+    
+    if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) {
+       
+       *vb++ = HC_HEADER2;
+       *vb++ = (HC_ParaType_NotTex << 16);
+       if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
+           *vb++ = (HC_SubA_HClipTB << 24) | 0x0;
+           *vb++ = (HC_SubA_HClipLR << 24) | 0x0;
+       }
+       else {
+           *vb++ = ((HC_SubA_HClipTB << 24) | (0x0 << 12) | vmesa->driDrawable->h);
+           *vb++ = ((HC_SubA_HClipLR << 24) | (vmesa->drawXoff << 12) | (vmesa->driDrawable->w + vmesa->drawXoff));
+       }
+
+       {    
+           GLuint pitch, format, offset;
+        
+           if (vmesa->viaScreen->bitsPerPixel == 0x20) {
+               format = HC_HDBFM_ARGB8888;
+           }           
+           else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
+               format = HC_HDBFM_RGB565;
+           }
+           else
+           {
+               return -1;
+           }
+
+           offset = vmesa->back.offset;
+           pitch = vmesa->back.pitch;
+           
+           *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
+           *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);      
+           *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);            
+           *vb++ = 0xcccccccc;
+       }
+       
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBstL << 24) |
+           ((GLuint)(pnAGPCurrentPhysStart) & 0xFFFFFF);
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBendL << 24) |
+           ((GLuint)(pnAGPCurrentPhysEnd) & 0xFFFFFF);
+       *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
+           ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
+           ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24;
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBpH << 24) |
+           ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFF000000) >> 24;
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBpL << 24) |
+           ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFFFFFF) |
+           HC_HAGPBpID_STOP;
+       *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
+                ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
+                ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24 |
+                HC_HAGPCMNT_MASK;
+    }
+    else {
+       GLuint *head;
+       GLuint clipL, clipR, clipT, clipB;
+       drm_clip_rect_t *b = vmesa->sarea->boxes;
+       *vb++ = HC_HEADER2;
+       *vb++ = (HC_ParaType_NotTex << 16);
+       head = vb;
+       
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBstL << 24) |
+           ((GLuint)(pnAGPCurrentPhysStart) & 0xFFFFFF);
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBendL << 24) |
+           ((GLuint)(pnAGPCurrentPhysEnd) & 0xFFFFFF);
+       *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
+           ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
+           ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24;
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBpH << 24) |
+           ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFF000000) >> 24;
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBpL << 24) |
+           ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFFFFFF) |
+           HC_HAGPBpID_STOP;
+       
+       for (i = 0; i < vmesa->sarea->nbox; i++) {        
+           if (1) {
+               volatile GLuint *pnEngBase = vmesa->regEngineStatus;
+               int nStatus;
+               
+               while (1) {
+                   nStatus = *pnEngBase;
+                   if ((nStatus & 0xFFFEFFFF) == 0x00020000)
+                       break;
+               }
+           }
+           
+           clipL = b->x1 + vmesa->drawXoff;
+           clipR = b->x2;          
+           clipT = b->y1;
+           clipB = b->y2;
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "clip = %d\n", i);
+#endif
+           if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
+
+               *vb = (HC_SubA_HClipTB << 24) | 0x0;
+               vb++;
+               
+               *vb = (HC_SubA_HClipLR << 24) | 0x0;
+               vb++;
+           }
+           else {
+               *vb = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB;
+               vb++;
+               
+               *vb = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR;
+               vb++;
+           }
+
+           {    
+               GLuint pitch, format, offset;
+               GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+        
+               if (vmesa->viaScreen->bitsPerPixel == 0x20) {
+                   format = HC_HDBFM_ARGB8888;
+               }           
+               else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
+                   format = HC_HDBFM_RGB565;
+               }           
+               else
+                       return -1;
+        
+               pitch = vmesa->front.pitch;
+               offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel);
+               offset = offset & 0xffffffe0;
+            
+               *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
+               *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);      
+               *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);            
+               *vb++ = 0xcccccccc;
+           }
+           *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
+                ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
+                ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24 |
+                HC_HAGPCMNT_MASK;
+#ifdef DEBUG           
+           if (VIA_DEBUG) {
+               GLuint i;
+               GLuint *data = (GLuint *)vmesa->dmaAddr;
+               for (i = 0; i < vmesa->dmaLow; i += 16) {
+                   fprintf(stderr, "%08x  ", *data++);
+                   fprintf(stderr, "%08x  ", *data++);
+                   fprintf(stderr, "%08x  ", *data++);
+                   fprintf(stderr, "%08x\n", *data++);
+               }
+               fprintf(stderr, "******************************************\n");
+           }
+#endif
+           b++;        
+           vb = head;
+       }
+    }
+
+#ifdef DEBUG
+    if (VIA_DEBUG && 0/*FIXME*/) {
+        volatile GLuint *pnEngBase = (volatile GLuint *)((GLuint)pnMMIOBase + 0x400);
+        int nStatus;
+       int i = 0;
+
+        while (1) {
+            nStatus = *pnEngBase;
+           if ((nStatus & 0xFFFEFFFF) == 0x00020000) {
+               break;
+           }
+           else {
+               GLuint j;
+               GLuint *data;
+               /* dump current command buffer */
+               data = (GLuint *)vmesa->dmaAddr;
+
+               if (i == 500000) {
+                   fprintf(stderr, "current command buffer");
+                   fprintf(stderr, "i = %d\n", i);
+                   for (j = 0; j < vmesa->dmaLow; j += 16) {
+                       fprintf(stderr, "%08x  ", *data++);
+                       fprintf(stderr, "%08x  ", *data++);
+                       fprintf(stderr, "%08x  ", *data++);
+                       fprintf(stderr, "%08x\n", *data++);
+                   }
+               }
+               /* dump previous command buffer */
+               if (vmesa->dmaIndex) {
+                   data = (GLuint *)vmesa->dma[0].map;
+               }
+               else {
+                   data = (GLuint *)vmesa->dma[1].map;
+               }
+               if (i == 500000) {
+                   fprintf(stderr, "previous command buffer");
+                   fprintf(stderr, "i = %d\n", i);
+                   for (j = 0; j < dmaLow; j += 16) {
+                       fprintf(stderr, "%08x  ", *data++);
+                       fprintf(stderr, "%08x  ", *data++);
+                       fprintf(stderr, "%08x  ", *data++);
+                       fprintf(stderr, "%08x\n", *data++);
+                   }
+               }
+           }
+           i++;
+        }
+    }
+#endif
+    dmaLow = vmesa->dmaLow; 
+    return 0;
+}
+
+int flush_agp_saam(viaContextPtr vmesa, drm_via_flush_agp_t* agpCmd) 
+{   
+    GLuint *pnAGPCurrentPhysStart;
+    GLuint *pnAGPCurrentPhysEnd;
+    GLuint *pnAGPCurrentStart;
+    GLuint *pnAGPCurrentEnd;
+    volatile GLuint *pnMMIOBase;
+    volatile GLuint *pnEngBaseTranSet;
+    volatile GLuint *pnEngBaseTranSpace;
+    GLuint *agpBase;
+    GLuint ofs = vmesa->dma[vmesa->dmaIndex].offset;
+    GLuint *vb = (GLuint *)vmesa->dmaAddr; 
+    GLuint i = 0;
+    
+    pnMMIOBase = vmesa->regMMIOBase;
+    pnEngBaseTranSet = vmesa->regTranSet;
+    pnEngBaseTranSpace = vmesa->regTranSpace;
+    *pnEngBaseTranSet = (0x0010 << 16);
+    agpBase = vmesa->agpBase;
+
+    if (!agpCmd->size) {
+        return -1;
+    }  
+
+    {
+        volatile GLuint *pnEngBase = vmesa->regEngineStatus;
+        int nStatus;
+       
+        while (1) {
+            nStatus = *pnEngBase;
+           if ((nStatus & 0xFFFEFFFF) == 0x00020000)
+               break;
+           i++;
+        }
+    }
+
+    pnAGPCurrentStart = (GLuint *)(ofs + agpCmd->offset);
+    pnAGPCurrentEnd = (GLuint *)((GLuint)pnAGPCurrentStart + vmesa->dmaHigh);
+    pnAGPCurrentPhysStart = (GLuint *)( (GLuint)pnAGPCurrentStart + (GLuint)agpBase );
+    pnAGPCurrentPhysEnd = (GLuint *)( (GLuint)pnAGPCurrentEnd + (GLuint)agpBase );
+
+    /*=* [DBG] make draw to front buffer *=*/
+    if(DRAW_FRONT)
+       vmesa->glCtx->Color._DrawDestMask = FRONT_LEFT_BIT;
+    
+    if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) {
+       
+       *vb++ = HC_HEADER2;
+       *vb++ = (HC_ParaType_NotTex << 16);
+       if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
+           *vb++ = (HC_SubA_HClipTB << 24) | 0x0;
+           *vb++ = (HC_SubA_HClipLR << 24) | 0x0;
+       }
+       else {
+           *vb++ = ((HC_SubA_HClipTB << 24) | (0x0 << 12) | vmesa->driDrawable->h);
+           *vb++ = ((HC_SubA_HClipLR << 24) | (vmesa->drawXoff << 12) | (vmesa->driDrawable->w + vmesa->drawXoff));
+       }
+
+       {    
+           GLuint pitch, format, offset;
+        
+           if (vmesa->viaScreen->bitsPerPixel == 0x20) {
+               format = HC_HDBFM_ARGB8888;
+           }           
+           else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
+               format = HC_HDBFM_RGB565;
+           }           
+           else
+               return -1;
+        
+           offset = vmesa->back.offset;
+           pitch = vmesa->back.pitch;
+            
+           *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
+           *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);      
+           *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);            
+           *vb++ = 0xcccccccc;
+       }
+       
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBstL << 24) |
+           ((GLuint)(pnAGPCurrentPhysStart) & 0xFFFFFF);
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBendL << 24) |
+           ((GLuint)(pnAGPCurrentPhysEnd) & 0xFFFFFF);
+       *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
+           ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
+           ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24;
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBpH << 24) |
+           ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFF000000) >> 24;
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBpL << 24) |
+           ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFFFFFF) |
+           HC_HAGPBpID_STOP;
+       *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
+                ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
+                ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24 |
+                HC_HAGPCMNT_MASK;
+    }
+    else {
+       GLuint *head;
+       GLuint clipL, clipR, clipT, clipB;
+       drm_clip_rect_t *b = vmesa->sarea->boxes;
+       *vb++ = HC_HEADER2;
+       *vb++ = (HC_ParaType_NotTex << 16);
+       head = vb;
+       
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBstL << 24) |
+           ((GLuint)(pnAGPCurrentPhysStart) & 0xFFFFFF);
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBendL << 24) |
+           ((GLuint)(pnAGPCurrentPhysEnd) & 0xFFFFFF);
+       *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
+           ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
+           ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24;
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBpH << 24) |
+           ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFF000000) >> 24;
+       *pnEngBaseTranSpace = (HC_SubA_HAGPBpL << 24) |
+           ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFFFFFF) |
+           HC_HAGPBpID_STOP;
+       
+       for (i = 0; i < vmesa->sarea->nbox; i++) {        
+           if (1) {
+               volatile GLuint *pnEngBase = vmesa->regEngineStatus;
+               int nStatus;
+               
+               while (1) {
+                   nStatus = *pnEngBase;
+                   if ((nStatus & 0xFFFEFFFF) == 0x00020000)
+                       break;
+               }
+           }
+           
+           clipL = b->x1 + vmesa->drawXoff;
+           clipR = b->x2;
+           clipT = b->y1;
+           clipB = b->y2;
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "clip = %d\n", i);
+#endif
+           if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
+
+               *vb = (HC_SubA_HClipTB << 24) | 0x0;
+               vb++;
+               
+               *vb = (HC_SubA_HClipLR << 24) | 0x0;
+               vb++;
+           }
+           else {
+               *vb = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB;
+               vb++;
+               
+               *vb = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR;
+               vb++;
+           }
+
+           {    
+               GLuint pitch, format, offset;
+               GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+        
+               if (vmesa->viaScreen->bitsPerPixel == 0x20) {
+                   format = HC_HDBFM_ARGB8888;
+               }           
+               else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
+                   format = HC_HDBFM_RGB565;
+               }           
+               else
+                       return -1;
+        
+               pitch = vmesa->front.pitch;
+               offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel);
+               offset = offset & 0xffffffe0;
+            
+               *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
+               *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);      
+               *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);            
+               *vb++ = 0xcccccccc;
+           }
+           *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
+                ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
+                ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24 |
+                HC_HAGPCMNT_MASK;
+#ifdef DEBUG           
+           if (VIA_DEBUG) {
+               GLuint i;
+               GLuint *data = (GLuint *)vmesa->dmaAddr;
+               for (i = 0; i < vmesa->dmaLow; i += 16) {
+                   fprintf(stderr, "%08x  ", *data++);
+                   fprintf(stderr, "%08x  ", *data++);
+                   fprintf(stderr, "%08x  ", *data++);
+                   fprintf(stderr, "%08x\n", *data++);
+               }
+               fprintf(stderr, "******************************************\n");
+           }
+#endif
+           b++;        
+           vb = head;
+       }
+    }
+    
+#ifdef DEBUG
+    if (VIA_DEBUG) {
+        volatile GLuint *pnEngBase = (GLuint *)((GLuint)pnMMIOBase + 0x400);
+        int nStatus;
+       int i = 0;
+
+        while (1) {
+            nStatus = *pnEngBase;
+           if ((nStatus & 0xFFFEFFFF) == 0x00020000) {
+               break;
+           }
+           else {
+               GLuint j;
+               GLuint *data;
+               /* dump current command buffer */
+               data = (GLuint *)vmesa->dmaAddr;
+
+               if (i == 500000) {
+                   fprintf(stderr, "current command buffer");
+                   fprintf(stderr, "i = %d\n", i);
+                   for (j = 0; j < vmesa->dmaLow; j += 16) {
+                       fprintf(stderr, "%08x  ", *data++);
+                       fprintf(stderr, "%08x  ", *data++);
+                       fprintf(stderr, "%08x  ", *data++);
+                       fprintf(stderr, "%08x\n", *data++);
+                   }
+               }
+               /* dump previous command buffer */
+               if (vmesa->dmaIndex) {
+                   data = (GLuint *)vmesa->dma[0].map;
+               }
+               else {
+                   data = (GLuint *)vmesa->dma[1].map;
+               }
+               if (i == 500000) {
+                   fprintf(stderr, "previous command buffer");
+                   fprintf(stderr, "i = %d\n", i);
+                   for (j = 0; j < dmaLow; j += 16) {
+                       fprintf(stderr, "%08x  ", *data++);
+                       fprintf(stderr, "%08x  ", *data++);
+                       fprintf(stderr, "%08x  ", *data++);
+                       fprintf(stderr, "%08x\n", *data++);
+                   }
+               }
+           }
+           i++;
+        }
+    }
+#endif
+    dmaLow = vmesa->dmaLow; 
+    return 0;
+}
+
+int flush_sys(viaContextPtr vmesa, drm_via_flush_sys_t* buf) 
+
+{
+    GLuint *pnBuf;
+    GLuint *pnEnd;
+    volatile GLuint *pnMMIOBase;
+    volatile GLuint *pnEngBaseTranSet;
+    volatile GLuint *pnEngBaseTranSpace;
+    GLuint uCheck2DCmd = GL_TRUE;
+    GLuint addr;
+    GLuint *vb = (GLuint *)vmesa->dmaAddr; 
+    GLuint i = 0;
+    
+    pnMMIOBase = vmesa->regMMIOBase;
+    pnEngBaseTranSet = vmesa->regTranSet;
+    pnEngBaseTranSpace = vmesa->regTranSpace;
+    
+    pnBuf = (GLuint *)(buf->index + buf->offset);
+    pnEnd = (GLuint *)((GLuint)pnBuf + buf->size);     
+    
+    /*=* [DBG] make draw to front buffer *=*/
+    if(DRAW_FRONT)
+       vmesa->glCtx->Color._DrawDestMask = FRONT_LEFT_BIT;
+    
+    /*=* John Sheng [2003.6.20] fix pci *=*/
+    {
+        volatile GLuint *pnEngBase = vmesa->regEngineStatus;
+        int nStatus;
+       
+        while (1) {
+            nStatus = *pnEngBase;
+           if ((nStatus & 0xFFFEFFFF) == 0x00020000)
+               break;
+           i++;
+        }
+    }
+
+    if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) {
+       *vb++ = HC_HEADER2;
+       *vb++ = (HC_ParaType_NotTex << 16);
+       
+       if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
+           *vb++ = (HC_SubA_HClipTB << 24) | 0x0;
+           *vb++ = (HC_SubA_HClipLR << 24) | 0x0;
+       }
+       else {
+           *vb++ = ((HC_SubA_HClipTB << 24) | (0x0 << 12) | vmesa->driDrawable->h);
+           *vb++ = ((HC_SubA_HClipLR << 24) | (vmesa->drawXoff << 12) | (vmesa->driDrawable->w + vmesa->drawXoff));
+       }
+       
+       /*=* John Sheng [2003.6.16] fix pci path *=*/
+       {    
+           GLuint pitch, format, offset;
+        
+           if (vmesa->viaScreen->bitsPerPixel == 0x20) {
+               format = HC_HDBFM_ARGB8888;
+           }           
+           else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
+               format = HC_HDBFM_RGB565;
+           }           
+           else
+               return -1;
+
+           offset = vmesa->back.offset;
+           pitch = vmesa->back.pitch;
+           
+           *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
+           *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);      
+           *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);            
+           *vb++ = 0xcccccccc;
+       }
+       
+       while (pnBuf != pnEnd) {        
+           if (*pnBuf == HALCYON_HEADER2) {
+               pnBuf++;
+               if (*pnBuf == HALCYON_SUB_ADDR0) {
+                   *pnEngBaseTranSet = *pnBuf;
+                   pnBuf++;
+                   uCheck2DCmd = GL_FALSE;
+               }
+               else {
+                   *pnEngBaseTranSet = *pnBuf;
+                   pnBuf++;
+                   uCheck2DCmd = GL_TRUE;
+               }
+           }
+           else if (uCheck2DCmd && ((*pnBuf&HALCYON_HEADER1MASK)==HALCYON_HEADER1)) {
+               addr = ((*pnBuf)&0x0000001f) << 2;
+               pnBuf++;
+               *((GLuint*)((GLuint)pnMMIOBase+addr)) = *pnBuf;
+               pnBuf++;
+           }
+           else if ((*pnBuf&HALCYON_FIREMASK) == HALCYON_FIRECMD) {
+               *pnEngBaseTranSpace = *pnBuf;
+               pnBuf++;
+               if ((pnBuf!=pnEnd)&&((*pnBuf&HALCYON_FIREMASK)==HALCYON_FIRECMD))
+                   pnBuf++;
+               if ((*pnBuf&HALCYON_CMDBMASK) != HC_ACMD_HCmdB)
+                   uCheck2DCmd = GL_TRUE;
+           }
+           else {
+               *pnEngBaseTranSpace = *pnBuf;
+               pnBuf++;
+           }
+       }
+    }
+    else {
+       GLuint *head;
+       GLuint clipL, clipR, clipT, clipB;
+       drm_clip_rect_t *b = vmesa->sarea->boxes;
+       GLuint *pnTmp;
+       
+       *vb++ = HC_HEADER2;
+       *vb++ = (HC_ParaType_NotTex << 16);
+       
+       head = vb;
+       pnTmp = pnBuf;
+               
+       for (i = 0; i < vmesa->sarea->nbox; i++) {        
+           clipL = b->x1 + vmesa->drawXoff;
+           clipR = b->x2 + vmesa->drawXoff;
+           clipT = b->y1;
+           clipB = b->y2;
+           
+           if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
+               *vb = (HC_SubA_HClipTB << 24) | 0x0;
+               vb++;
+               *vb = (HC_SubA_HClipLR << 24) | 0x0;
+               vb++;
+           }
+           else {
+               *vb = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB;
+               vb++;
+               *vb = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR;
+               vb++;
+           }
+           
+           /*=* John Sheng [2003.6.16] fix pci path *=*/
+           {    
+               GLuint pitch, format, offset;
+               GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+        
+               if (vmesa->viaScreen->bitsPerPixel == 0x20) {
+                   format = HC_HDBFM_ARGB8888;
+               }           
+               else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
+                   format = HC_HDBFM_RGB565;
+               }           
+               else
+                       return -1;
+        
+               pitch = vmesa->front.pitch;
+               offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel);
+               offset = offset & 0xffffffe0;
+            
+               *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
+               *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);      
+               *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);            
+               *vb++ = 0xcccccccc;
+           }
+           
+           pnBuf = pnTmp;
+           
+           while (pnBuf != pnEnd) {    
+               if (*pnBuf == HALCYON_HEADER2) {
+                   pnBuf++;
+                   if (*pnBuf == HALCYON_SUB_ADDR0) {
+                       *pnEngBaseTranSet = *pnBuf;
+                       pnBuf++;
+                       uCheck2DCmd = GL_FALSE;
+                   }
+                   else {
+                       *pnEngBaseTranSet = *pnBuf;
+                       pnBuf++;
+                       uCheck2DCmd = GL_TRUE;
+                   }
+               }
+               else if (uCheck2DCmd && ((*pnBuf&HALCYON_HEADER1MASK)==HALCYON_HEADER1)) {
+                   addr = ((*pnBuf)&0x0000001f) << 2;
+                   pnBuf++;
+                   *((GLuint*)((GLuint)pnMMIOBase+addr)) = *pnBuf;
+                   pnBuf++;
+               }
+               else if ((*pnBuf&HALCYON_FIREMASK) == HALCYON_FIRECMD) {
+                   *pnEngBaseTranSpace = *pnBuf;
+                   pnBuf++;
+                   if ((pnBuf!=pnEnd)&&((*pnBuf&HALCYON_FIREMASK)==HALCYON_FIRECMD))
+                       pnBuf++;
+                   if ((*pnBuf&HALCYON_CMDBMASK) != HC_ACMD_HCmdB)
+                       uCheck2DCmd = GL_TRUE;
+               }
+               else {
+                   *pnEngBaseTranSpace = *pnBuf;
+                   pnBuf++;
+               }
+           }
+           b++;        
+           vb = head;
+       }
+    }
+    return 0;
+}
diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.h b/src/mesa/drivers/dri/unichrome/via_ioctl.h
new file mode 100644 (file)
index 0000000..e9030e6
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _VIAIOCTL_H
+#define _VIAIOCTL_H
+
+#include "via_context.h"
+
+
+void viaEmitPrim(viaContextPtr vmesa);
+void viaFlushPrims(viaContextPtr vmesa);
+void viaFlushPrimsLocked(viaContextPtr vmesa);
+
+void viaDmaFinish(viaContextPtr vmesa);
+void viaRegetLockQuiescent(viaContextPtr vmesa);
+void viaInitIoctlFuncs(GLcontext *ctx);
+void viaCopyBuffer(const __DRIdrawablePrivate *dpriv);
+void viaPageFlip(const __DRIdrawablePrivate *dpriv);
+int via_check_copy(int fd);
+void viaFillFrontBuffer(viaContextPtr vmesa);
+void viaFillFrontBufferSaam(viaContextPtr vmesa);
+void viaFillFrontPBuffer(viaContextPtr vmesa);
+void viaFillBackBuffer(viaContextPtr vmesa);
+void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel);
+void viaFillStencilBuffer(viaContextPtr vmesa, GLuint pixel);
+void viaFillStencilDepthBuffer(viaContextPtr vmesa, GLuint pixel);
+void viaDoSwapBuffers(viaContextPtr vmesa);
+void viaDoSwapBuffersSaam(viaContextPtr vmesa);
+void viaDoSwapBufferSoft(viaContextPtr vmesa);
+void viaDoSwapBufferSoftFront(viaContextPtr vmesa);
+void viaDoSwapPBuffers(viaContextPtr vmesa);
+
+int flush_agp(viaContextPtr vmesa, drm_via_flush_agp_t* agpCmd); 
+int flush_agp_saam(viaContextPtr vmesa, drm_via_flush_agp_t* agpCmd); 
+int flush_sys(viaContextPtr vmesa, drm_via_flush_sys_t* buf); 
+
+#define VIA_STATECHANGE(vmesa, flag)                            \
+    do {                                                        \
+        if (vmesa->dmaLow != vmesa->dmaLastPrim)                \
+            viaFlushPrims(vmesa);                               \
+        vmesa->dirty |= flag;                                   \
+    } while (0)                                                 \
+
+
+#define VIA_FIREVERTICES(vmesa)                                 \
+    do {                                                        \
+        if (vmesa->dmaLow) {                                    \
+            viaFlushPrims(vmesa);                               \
+        }                                                       \
+    } while (0)
+    
+
+static __inline GLuint *viaCheckDma(viaContextPtr vmesa, int bytes)
+{
+    if (vmesa->dmaLow + bytes > vmesa->dmaHigh) {
+#ifdef DEBUG
+       if (VIA_DEBUG) fprintf(stderr, "buffer overflow in check dma = %d + %d = %d\n", vmesa->dmaLow, bytes, vmesa->dmaLow + bytes);
+#endif
+       viaFlushPrims(vmesa);
+    }
+
+    {
+        GLuint *start = (GLuint *)(vmesa->dmaAddr + vmesa->dmaLow);
+        return start;
+    }
+}
+#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_render.c b/src/mesa/drivers/dri/unichrome/via_render.c
new file mode 100644 (file)
index 0000000..ea3289f
--- /dev/null
@@ -0,0 +1,545 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Render unclipped vertex buffers by emitting vertices directly to
+ * dma buffers.  Use strip/fan hardware acceleration where possible.
+ *
+ */
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "mtypes.h"
+/*#include "mmath.h" _SOLO */
+
+#include "tnl/t_context.h"
+
+#include "via_context.h"
+#include "via_tris.h"
+#include "via_state.h"
+#include "via_vb.h"
+#include "via_ioctl.h"
+
+/*
+ * Render unclipped vertex buffers by emitting vertices directly to
+ * dma buffers.  Use strip/fan hardware primitives where possible.
+ * Try to simulate missing primitives with indexed vertices.
+ */
+#define HAVE_POINTS      1
+#define HAVE_LINES       1
+#define HAVE_LINE_STRIPS 1
+#define HAVE_LINE_LOOP   1
+#define HAVE_TRIANGLES   1
+#define HAVE_TRI_STRIPS  1
+#define HAVE_TRI_STRIP_1 0      /* has it, template can't use it yet */
+#define HAVE_TRI_FANS    1
+#define HAVE_POLYGONS    1
+#define HAVE_QUADS       0
+#define HAVE_QUAD_STRIPS 0
+
+#define HAVE_ELTS        0
+
+static const GLenum reducedPrim[GL_POLYGON + 1] = {
+    GL_POINTS,
+    GL_LINES,
+    GL_LINES,
+    GL_LINES,
+    GL_TRIANGLES,
+    GL_TRIANGLES,
+    GL_TRIANGLES,
+    GL_TRIANGLES,
+    GL_TRIANGLES,
+    GL_TRIANGLES
+};
+
+/* Fallback to normal rendering.
+ */
+static void VERT_FALLBACK(GLcontext *ctx,
+                          GLuint start,
+                          GLuint count,
+                          GLuint flags)
+{
+    TNLcontext *tnl = TNL_CONTEXT(ctx);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    fprintf(stderr, "VERT_FALLBACK\n");
+    tnl->Driver.Render.PrimitiveNotify(ctx, flags & PRIM_MODE_MASK);
+    tnl->Driver.Render.BuildVertices(ctx, start, count, ~0);
+    tnl->Driver.Render.PrimTabVerts[flags & PRIM_MODE_MASK](ctx, start,
+                                                            count, flags);
+    VIA_CONTEXT(ctx)->setupNewInputs = VERT_CLIP;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
+
+#define LOCAL_VARS viaContextPtr vmesa = VIA_CONTEXT(ctx)
+/*
+#define INIT(prim)                                                          \
+    do {                                                                    \
+        VIA_STATECHANGE(vmesa, 0);                                          \
+        viaRasterPrimitive(ctx, reducedPrim[prim], prim);                   \
+    } while (0)
+*/
+#define INIT(prim)                                                          \
+    do {                                                                    \
+        viaRasterPrimitive(ctx, reducedPrim[prim], prim);                   \
+    } while (0)
+#define NEW_PRIMITIVE()  VIA_STATECHANGE(vmesa, 0)
+#define NEW_BUFFER()  VIA_FIREVERTICES(vmesa)
+#define GET_CURRENT_VB_MAX_VERTS() \
+    (((int)vmesa->dmaHigh - (int)vmesa->dmaLow) / (vmesa->vertex_size * 4))
+#define GET_SUBSEQUENT_VB_MAX_VERTS() \
+    (VIA_DMA_BUF_SZ - 4) / (vmesa->vertex_size * 4)
+
+
+#define EMIT_VERTS(ctx, j, nr) \
+    via_emit_contiguous_verts(ctx, j, (j) + (nr))
+    
+#define FINISH                                                          \
+    do {                                                                \
+        vmesa->primitiveRendered = GL_TRUE;                             \
+        viaRasterPrimitiveFinish(ctx);                                  \
+    } while (0)                                                       
+
+
+#define TAG(x) via_fast##x
+#include "via_dmatmp.h"
+#undef TAG
+#undef LOCAL_VARS
+#undef INIT
+
+/**********************************************************************/
+/*                          Fast Render pipeline stage                */
+/**********************************************************************/
+static GLboolean via_run_fastrender(GLcontext *ctx,
+                                    struct tnl_pipeline_stage *stage)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    TNLcontext *tnl = TNL_CONTEXT(ctx);
+    struct vertex_buffer *VB = &tnl->vb;
+    GLuint i, length, flags = 0;
+    
+    /* Don't handle clipping or indexed vertices.
+     */
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif
+    
+    if (VB->ClipOrMask || vmesa->renderIndex != 0 || VB->Elts) {
+#ifdef DEBUG
+       if (VIA_DEBUG) { 
+           fprintf(stderr, "slow path\n");    
+           fprintf(stderr, "ClipOrMask = %08x\n", VB->ClipOrMask);
+           fprintf(stderr, "renderIndex = %08x\n", vmesa->renderIndex);        
+           fprintf(stderr, "Elts = %08x\n", (GLuint)VB->Elts); 
+       }           
+#endif
+        return GL_TRUE;
+    }
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif    
+    vmesa->setupNewInputs = VERT_CLIP;
+    vmesa->primitiveRendered = GL_TRUE;
+
+    tnl->Driver.Render.Start(ctx);
+    
+    for (i = 0; i < VB->PrimitiveCount; ++i) {
+        GLuint mode = VB->Primitive[i].mode;
+        GLuint start = VB->Primitive[i].start;
+        GLuint length = VB->Primitive[i].count;
+        if (length)
+            via_fastrender_tab_verts[mode & PRIM_MODE_MASK](ctx, start, start+length, mode);
+    }
+
+    tnl->Driver.Render.Finish(ctx);
+    
+    /*=* DBG - viewperf7.0 : fix command buffer overflow *=*/
+    if (vmesa->dmaLow > (vmesa->dma[0].size / 2))
+       viaFlushPrims(vmesa);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+    return GL_FALSE;            /* finished the pipe */
+}
+
+
+static void via_check_fastrender(GLcontext *ctx, struct tnl_pipeline_stage *stage)
+{
+    GLuint inputs = VERT_CLIP | VERT_RGBA;
+    
+    if (ctx->RenderMode == GL_RENDER) {
+        if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+            inputs |= VERT_BIT_COLOR1;
+
+        if (ctx->Texture.Unit[0]._ReallyEnabled)
+            inputs |= VERT_TEX(0);
+
+        if (ctx->Texture.Unit[1]._ReallyEnabled)
+            inputs |= VERT_TEX(1);
+
+        if (ctx->Fog.Enabled)
+            inputs |= VERT_BIT_FOG;
+    }
+
+    stage->inputs = inputs;
+}
+
+
+static void fastdtr(struct tnl_pipeline_stage *stage)
+{
+    (void)stage;
+}
+
+
+const struct tnl_pipeline_stage _via_fastrender_stage =
+{
+    "via fast 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 */
+    fastdtr,                     /* destructor */
+    via_check_fastrender,        /* check - initially set to alloc data */
+    via_run_fastrender           /* run */
+};
+
+
+/*
+ * Render whole vertex buffers, including projection of vertices from
+ * clip space and clipping of primitives.
+ *
+ * This file makes calls to project vertices and to the point, line
+ * and triangle rasterizers via the function pointers:
+ *
+ *    context->Driver.Render.*
+ *
+ */
+
+
+/**********************************************************************/
+/*                        Clip single primitives                      */
+/**********************************************************************/
+#if defined(USE_IEEE)
+#define NEGATIVE(x) (GET_FLOAT_BITS(x) & (1 << 31))
+#define DIFFERENT_SIGNS(x, y) ((GET_FLOAT_BITS(x) ^ GET_FLOAT_BITS(y)) & (1 << 31))
+#else
+#define NEGATIVE(x) (x < 0)
+#define DIFFERENT_SIGNS(x,y) (x * y <= 0 && x - y != 0)
+/* Could just use (x*y<0) except for the flatshading requirements.
+ * Maybe there's a better way?
+ */
+#endif
+
+#define W(i) coord[i][3]
+#define Z(i) coord[i][2]
+#define Y(i) coord[i][1]
+#define X(i) coord[i][0]
+#define SIZE 4
+#define TAG(x) x##_4
+#include "tnl/t_vb_cliptmp.h" /* tnl_ */
+
+
+/**********************************************************************/
+/*              Clip and render whole begin/end objects               */
+/**********************************************************************/
+#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED)
+#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx]
+#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val
+
+
+/* Vertices, with the possibility of clipping.
+ */
+#define RENDER_POINTS(start, count)            \
+   tnl->Driver.Render.Points(ctx, start, count)
+
+#define RENDER_LINE(v1, v2)                            \
+    do {                                               \
+       GLubyte c1 = mask[v1], c2 = mask[v2];           \
+       GLubyte ormask = c1 | c2;                       \
+       if (!ormask)                                    \
+           LineFunc(ctx, v1, v2);                      \
+       else if (!(c1 & c2 & 0x3f))                     \
+           clip_line_4(ctx, v1, v2, ormask);           \
+    } while (0)
+
+#define RENDER_TRI(v1, v2, v3)                                 \
+    do {                                                       \
+       GLubyte c1 = mask[v1], c2 = mask[v2], c3 = mask[v3];    \
+       GLubyte ormask = c1 | c2 | c3;                          \
+       if (!ormask)                                            \
+           TriangleFunc(ctx, v1, v2, v3);                      \
+       else if (!(c1 & c2 & c3 & 0x3f))                        \
+           clip_tri_4(ctx, v1, v2, v3, ormask);                \
+    } while (0)
+
+#define RENDER_QUAD(v1, v2, v3, v4)                            \
+    do {                                                       \
+       GLubyte c1 = mask[v1], c2 = mask[v2];                   \
+       GLubyte c3 = mask[v3], c4 = mask[v4];                   \
+       GLubyte ormask = c1 | c2 | c3 | c4;                     \
+       if (!ormask)                                            \
+           QuadFunc(ctx, v1, v2, v3, v4);                      \
+       else if (!(c1 & c2 & c3 & c4 & 0x3f))                   \
+           clip_quad_4(ctx, v1, v2, v3, v4, ormask);           \
+    } while (0)
+
+
+#define LOCAL_VARS                                                     \
+    TNLcontext *tnl = TNL_CONTEXT(ctx);                                        \
+    struct vertex_buffer *VB = &tnl->vb;                               \
+    const GLuint * const elt = VB->Elts;                               \
+    const GLubyte *mask = VB->ClipMask;                                        \
+    const GLuint sz = VB->ClipPtr->size;                               \
+    const line_func LineFunc = tnl->Driver.Render.Line;                        \
+    const triangle_func TriangleFunc = tnl->Driver.Render.Triangle;    \
+    const quad_func QuadFunc = tnl->Driver.Render.Quad;                        \
+    const GLboolean stipple = ctx->Line.StippleFlag;                   \
+    (void) (LineFunc && TriangleFunc && QuadFunc);                     \
+    (void) elt; (void) mask; (void) sz; (void) stipple;
+    
+#define POSTFIX                                                         \
+    viaRasterPrimitiveFinish(ctx)                          
+
+#define TAG(x) clip_##x##_verts
+#define INIT(x) tnl->Driver.Render.PrimitiveNotify(ctx, x)
+#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple(ctx)
+#define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE
+#define PRESERVE_VB_DEFS
+#include "tnl/t_vb_rendertmp.h"
+
+
+/* Elts, with the possibility of clipping.
+ */
+#undef ELT
+#undef TAG
+#define ELT(x) elt[x]
+#define TAG(x) clip_##x##_elts
+#include "tnl/t_vb_rendertmp.h"
+
+/* TODO: do this for all primitives, verts and elts:
+ */
+static void clip_elt_triangles(GLcontext *ctx,
+                              GLuint start,
+                              GLuint count,
+                              GLuint flags)
+{
+    TNLcontext *tnl = TNL_CONTEXT(ctx);
+    render_func render_tris = tnl->Driver.Render.PrimTabElts[GL_TRIANGLES];
+    struct vertex_buffer *VB = &tnl->vb;
+    const GLuint * const elt = VB->Elts;
+    GLubyte *mask = VB->ClipMask;
+    GLuint last = count-2;
+    GLuint j;
+    (void)flags;
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    tnl->Driver.Render.PrimitiveNotify(ctx, GL_TRIANGLES);
+
+    for (j = start; j < last; j += 3) {
+        GLubyte c1 = mask[elt[j]];
+        GLubyte c2 = mask[elt[j + 1]];
+        GLubyte c3 = mask[elt[j + 2]];
+        GLubyte ormask = c1 | c2 | c3;
+        if (ormask) {
+           if (start < j)
+               render_tris(ctx, start, j, 0);
+           if (!(c1 & c2 & c3 & 0x3f))
+               clip_tri_4(ctx, elt[j], elt[j + 1], elt[j + 2], ormask);
+           start = j+3;
+        }
+    }  
+
+    if (start < j)
+       render_tris(ctx, start, j, 0);
+    
+    viaRasterPrimitiveFinish(ctx);
+}
+
+
+/**********************************************************************/
+/*              Helper functions for drivers                         */
+/**********************************************************************/
+/*
+void _tnl_RenderClippedPolygon(GLcontext *ctx, const GLuint *elts, GLuint n)
+{
+    TNLcontext *tnl = TNL_CONTEXT(ctx);
+    struct vertex_buffer *VB = &tnl->vb;
+    GLuint *tmp = VB->Elts;
+
+    VB->Elts = (GLuint *)elts;
+    tnl->Driver.Render.PrimTabElts[GL_POLYGON](ctx, 0, n, PRIM_BEGIN|PRIM_END);
+    VB->Elts = tmp;
+}
+
+void _tnl_RenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj)
+{
+    TNLcontext *tnl = TNL_CONTEXT(ctx);
+    tnl->Driver.Render.Line(ctx, ii, jj);
+}
+*/
+
+/**********************************************************************/
+/*                          Render pipeline stage                     */
+/**********************************************************************/
+static GLboolean via_run_render(GLcontext *ctx,
+                                struct tnl_pipeline_stage *stage)
+{
+    TNLcontext *tnl = TNL_CONTEXT(ctx);
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    struct vertex_buffer *VB = &tnl->vb;
+    /* DBG */
+    GLuint newInputs = stage->changed_inputs;
+    /*GLuint newInputs = stage->inputs;*/
+    
+    render_func *tab;
+    GLuint pass = 0;
+    
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif
+    tnl->Driver.Render.Start(ctx);
+    tnl->Driver.Render.BuildVertices(ctx, 0, VB->Count, newInputs);
+    if (VB->ClipOrMask) {
+       tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts;
+       clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles;
+    }
+    else {
+       tab = VB->Elts ? tnl->Driver.Render.PrimTabElts : tnl->Driver.Render.PrimTabVerts;
+    }
+       
+    do {
+       GLuint i;
+       
+        for (i = 0; i < VB->PrimitiveCount; i++) {
+            GLuint flags = VB->Primitive[i].mode;
+            GLuint start = VB->Primitive[i].start;
+           GLuint length= VB->Primitive[i].count;
+           ASSERT(length || (flags & PRIM_LAST));
+           ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON + 1);
+           if (length)
+               tab[flags & PRIM_MODE_MASK](ctx, start, start + length,flags);
+       }               
+    }
+    while (tnl->Driver.Render.Multipass && tnl->Driver.Render.Multipass(ctx, ++pass));
+    tnl->Driver.Render.Finish(ctx);
+    
+    /*=* DBG - flush : if hw idel *=*/
+    {
+        GLuint volatile *pnEnginStatus = vmesa->regEngineStatus;
+       GLuint nStatus;
+        nStatus = *pnEnginStatus;
+       if ((nStatus & 0xFFFEFFFF) == 0x00020000)
+           viaFlushPrims(vmesa);
+    }
+    
+    /*=* DBG viewperf7.0 : fix command buffer overflow *=*/
+    if (vmesa->dmaLow > (vmesa->dma[0].size / 2))
+       viaFlushPrims(vmesa);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+    return GL_FALSE;            /* finished the pipe */
+}
+
+/* Quite a bit of work involved in finding out the inputs for the
+ * render stage.
+ */
+
+static void via_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
+{
+    GLuint inputs = VERT_CLIP;
+    
+    if (ctx->Visual.rgbMode) {
+       inputs |= VERT_RGBA;
+       
+        if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+           inputs |= VERT_BIT_COLOR1;
+           
+        if (ctx->Texture.Unit[0]._ReallyEnabled) {
+                   inputs |= VERT_TEX(0);          
+       }
+       
+       if (ctx->Texture.Unit[1]._ReallyEnabled) {
+                   inputs |= VERT_TEX(1);          
+       }
+    }
+    else {
+        /*inputs |= VERT_INDEX; _SOLO*/
+    }  
+           
+    /*if (ctx->Point._Attenuated)
+        inputs |= VERT_POINT_SIZE;*/
+
+    if (ctx->Fog.Enabled)
+        inputs |= VERT_BIT_FOG;
+
+    /*if (ctx->_TriangleCaps & DD_TRI_UNFILLED)
+        inputs |= VERT_EDGE;
+
+    if (ctx->RenderMode == GL_FEEDBACK)
+        inputs |= VERT_TEX_ANY;*/
+
+    stage->inputs = inputs;
+}
+
+
+static void dtr(struct tnl_pipeline_stage *stage)
+{
+    (void)stage;
+}
+
+
+const struct tnl_pipeline_stage _via_render_stage =
+{
+    "via render",
+    (_NEW_BUFFERS |
+     _DD_NEW_SEPARATE_SPECULAR |
+     _DD_NEW_FLATSHADE |
+     _NEW_TEXTURE |
+     _NEW_LIGHT |     
+     _NEW_POINT |
+     _NEW_FOG |
+     _DD_NEW_TRI_UNFILLED |
+     _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 */
+     via_check_render,           /* check - initially set to alloc data */
+     via_run_render              /* run */
+};
diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c
new file mode 100644 (file)
index 0000000..1f30e54
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*#include <X11/Xlibint.h> _SOLO*/
+#include <stdio.h>
+
+#include "utils.h"
+#include "dri_util.h"
+#include "glheader.h"
+#include "context.h"
+#include "matrix.h"
+#include "simple_list.h"
+
+#include "via_state.h"
+#include "via_tex.h"
+#include "via_span.h"
+#include "via_tris.h"
+#include "via_ioctl.h"
+#include "via_screen.h"
+
+#include "via_dri.h"
+extern viaContextPtr current_mesa;
+
+static drmBufMapPtr via_create_empty_buffers(void)
+{
+    drmBufMapPtr retval;
+
+    retval = (drmBufMapPtr)MALLOC(sizeof(drmBufMap));
+    if (retval == NULL) return NULL;
+    memset(retval, 0, sizeof(drmBufMap));
+
+    retval->list = (drmBufPtr)MALLOC(sizeof(drmBuf) * VIA_DMA_BUF_NR);
+    if (retval->list == NULL) {
+       FREE(retval);
+       return NULL;
+    }
+    memset(retval->list, 0, sizeof(drmBuf) * VIA_DMA_BUF_NR);
+    return retval;
+}
+
+static GLboolean
+viaInitDriver(__DRIscreenPrivate *sPriv)
+{
+    viaScreenPrivate *viaScreen;
+    VIADRIPtr gDRIPriv = (VIADRIPtr)sPriv->pDevPriv;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    if (!driCheckDriDdxDrmVersions(sPriv, "Via", 4, 0, 4, 0, 1, 1))
+        return GL_FALSE;
+
+    /* Allocate the private area */
+    viaScreen = (viaScreenPrivate *) CALLOC(sizeof(viaScreenPrivate));
+    if (!viaScreen) {
+        __driUtilMessage("viaInitDriver: alloc viaScreenPrivate struct failed");
+        return GL_FALSE;
+    }
+
+    viaScreen->driScrnPriv = sPriv;
+    sPriv->private = (void *)viaScreen;
+
+    viaScreen->deviceID = gDRIPriv->deviceID;
+    viaScreen->width = gDRIPriv->width;
+    viaScreen->height = gDRIPriv->height;
+    viaScreen->mem = gDRIPriv->mem;
+    viaScreen->bitsPerPixel = gDRIPriv->bytesPerPixel << 3;
+    viaScreen->bytesPerPixel = gDRIPriv->bytesPerPixel;
+    viaScreen->fbOffset = 0;
+    viaScreen->fbSize = gDRIPriv->fbSize;
+#ifndef _SOLO
+    viaScreen->drixinerama = gDRIPriv->drixinerama;
+#endif
+#ifdef DEBUG    
+    if (VIA_DEBUG) {
+       fprintf(stderr, "deviceID = %08x\n", viaScreen->deviceID);
+       fprintf(stderr, "width = %08x\n", viaScreen->width);    
+       fprintf(stderr, "height = %08x\n", viaScreen->height);  
+       fprintf(stderr, "cpp = %08x\n", viaScreen->cpp);        
+       fprintf(stderr, "fbOffset = %08x\n", viaScreen->fbOffset);      
+    }
+#endif
+    /* DBG */
+    /*
+    if (gDRIPriv->bitsPerPixel == 15)
+        viaScreen->fbFormat = DV_PF_555;
+    else
+        viaScreen->fbFormat = DV_PF_565;
+    */ 
+
+    viaScreen->bufs = via_create_empty_buffers();
+    if (viaScreen->bufs == NULL) {
+        __driUtilMessage("viaInitDriver: via_create_empty_buffers() failed");
+        FREE(viaScreen);
+        return GL_FALSE;
+    }
+
+    if (drmMap(sPriv->fd,
+               gDRIPriv->regs.handle,
+               gDRIPriv->regs.size,
+               (drmAddress *)&viaScreen->reg) != 0) {
+        FREE(viaScreen);
+        sPriv->private = NULL;
+        __driUtilMessage("viaInitDriver: drmMap regs failed");
+        return GL_FALSE;
+    }
+
+    if (gDRIPriv->agp.size) {
+        if (drmMap(sPriv->fd,
+                   gDRIPriv->agp.handle,
+                   gDRIPriv->agp.size,
+                  (drmAddress *)&viaScreen->agpLinearStart) != 0) {
+           FREE(viaScreen);
+           drmUnmap(viaScreen->reg, gDRIPriv->agp.size);
+           sPriv->private = NULL;
+           __driUtilMessage("viaInitDriver: drmMap agp failed");
+           return GL_FALSE;
+       }           
+       viaScreen->agpBase = (GLuint *)gDRIPriv->agp.handle;
+    } else
+       viaScreen->agpLinearStart = 0;
+
+    viaScreen->sareaPrivOffset = gDRIPriv->sarea_priv_offset;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+    return GL_TRUE;
+}
+
+static void
+viaDestroyScreen(__DRIscreenPrivate *sPriv)
+{
+    viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
+    VIADRIPtr gDRIPriv = (VIADRIPtr)sPriv->pDevPriv;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    drmUnmap(viaScreen->reg, gDRIPriv->regs.size);
+    if (gDRIPriv->agp.size)
+        drmUnmap(viaScreen->agpLinearStart, gDRIPriv->agp.size);
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);        
+#endif    
+    FREE(viaScreen);
+    sPriv->private = NULL;
+}
+
+static GLboolean
+viaCreateBuffer(__DRIscreenPrivate *driScrnPriv,
+                __DRIdrawablePrivate *driDrawPriv,
+                const __GLcontextModes *mesaVis,
+                GLboolean isPixmap)
+{
+    viaContextPtr vmesa = current_mesa;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif    
+#if 0
+    /*=* John Sheng [2003.7.2] for visual config & patch viewperf *=*/
+    if (mesaVis->depthBits == 32 && vmesa->depthBits == 16) {
+       vmesa->depthBits = mesaVis->depthBits;
+       vmesa->depth.size *= 2;
+       vmesa->depth.pitch *= 2;
+       vmesa->depth.bpp *= 2;
+       if (vmesa->depth.map)
+           via_free_depth_buffer(vmesa);
+       if (!via_alloc_depth_buffer(vmesa)) {
+           via_free_depth_buffer(vmesa);
+           return GL_FALSE;
+       }
+       
+       mesaVis->depthBits = 16;
+    }
+#endif    
+    
+    if (isPixmap) {
+#ifdef _SOLO
+        ASSERT(0);
+        return GL_FALSE; /* not implemented */
+#else
+       driDrawPriv->driverPrivate = (void *)
+            _mesa_create_framebuffer(mesaVis,
+                                     GL_FALSE, /* software depth buffer? */
+                                     mesaVis->stencilBits > 0,
+                                     mesaVis->accumRedBits > 0,
+                                     GL_FALSE  /* s/w alpha planes */);
+
+       if (vmesa) vmesa->drawType = GLX_PBUFFER_BIT;
+#ifdef DEBUG    
+        if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);                                 
+#endif 
+        return (driDrawPriv->driverPrivate != NULL);
+#endif
+    }
+    else {
+        driDrawPriv->driverPrivate = (void *)
+            _mesa_create_framebuffer(mesaVis,
+                                     GL_FALSE, /* software depth buffer? */
+                                     mesaVis->stencilBits > 0,
+                                     mesaVis->accumRedBits > 0,
+                                     GL_FALSE  /* s/w alpha planes */);
+       
+       if (vmesa) vmesa->drawType = GLX_WINDOW_BIT;
+#ifdef DEBUG    
+        if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);                                 
+#endif 
+        return (driDrawPriv->driverPrivate != NULL);
+   }
+}
+
+
+static void
+viaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    _mesa_destroy_framebuffer((GLframebuffer *)(driDrawPriv->driverPrivate));
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+
+#if 0
+/* Initialize the fullscreen mode.
+ */
+GLboolean
+XMesaOpenFullScreen(__DRIcontextPrivate *driContextPriv)
+{
+    viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
+    vmesa->doPageFlip = 1;
+    vmesa->currentPage = 0;
+    return GL_TRUE;
+}
+
+/* Shut down the fullscreen mode.
+ */
+GLboolean
+XMesaCloseFullScreen(__DRIcontextPrivate *driContextPriv)
+{
+    viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
+
+    if (vmesa->currentPage == 1) {
+        viaPageFlip(vmesa);
+        vmesa->currentPage = 0;
+    }
+
+    vmesa->doPageFlip = GL_FALSE;
+    vmesa->Setup[VIA_DESTREG_DI0] = vmesa->driScreen->front_offset;
+    return GL_TRUE;
+}
+
+#else
+
+static GLboolean
+viaOpenFullScreen(__DRIcontextPrivate *driContextPriv)
+{
+    return GL_TRUE;
+}
+
+static GLboolean
+viaCloseFullScreen(__DRIcontextPrivate *driContextPriv)
+{
+    return GL_TRUE;
+}
+
+#endif
+
+
+static struct __DriverAPIRec viaAPI = {
+    viaInitDriver,
+    viaDestroyScreen,
+    viaCreateContext,
+    viaDestroyContext,
+    viaCreateBuffer,
+    viaDestroyBuffer,
+    viaSwapBuffers,
+    viaMakeCurrent,
+    viaUnbindContext,
+    viaOpenFullScreen,
+    viaCloseFullScreen
+};
+
+
+/*
+ * This is the bootstrap function for the driver.
+ * The __driCreateScreen name is the symbol that libGL.so fetches.
+ * Return:  pointer to a __DRIscreenPrivate.
+ */
+#ifndef _SOLO
+void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
+                        int numConfigs, __GLXvisualConfig *config)
+{
+    __DRIscreenPrivate *psp;
+    psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &viaAPI);
+    return (void *)psp;
+}
+#else
+void *__driCreateScreen(struct DRIDriverRec *driver,
+                        struct DRIDriverContextRec *driverContext)
+{
+    __DRIscreenPrivate *psp;
+    psp = __driUtilCreateScreen(driver, driverContext, &viaAPI);
+    return (void *) psp;
+}
+#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_screen.h b/src/mesa/drivers/dri/unichrome/via_screen.h
new file mode 100644 (file)
index 0000000..a61a68c
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _VIAINIT_H
+#define _VIAINIT_H
+
+#include <sys/time.h>
+#include "dri_util.h"
+#include "via_dri.h"
+
+typedef struct {
+    viaRegion regs;
+    viaRegion agp;
+    int deviceID;
+    int width;
+    int height;
+    int mem;
+
+    int cpp;                    
+    int bitsPerPixel;
+    int bytesPerPixel;
+    int fbFormat;
+    int fbOffset;
+    int fbSize;
+#ifndef _SOLO
+    Bool drixinerama;
+#endif
+    
+    int fbStride;
+
+    int backOffset;
+    int depthOffset;
+
+    int backPitch;
+    int backPitchBits;
+
+    int textureOffset;
+    int textureSize;
+    int logTextureGranularity;
+    
+    drmAddress reg;
+    drmAddress agpLinearStart;
+    GLuint* agpBase;
+
+    __DRIscreenPrivate *driScrnPriv;
+    drmBufMapPtr bufs;
+    unsigned int sareaPrivOffset;
+} viaScreenPrivate;
+
+extern GLboolean
+viaCreateContext(const __GLcontextModes *mesaVis,
+                 __DRIcontextPrivate *driContextPriv,
+                 void *sharedContextPrivate);
+
+extern void
+viaDestroyContext(__DRIcontextPrivate *driContextPriv);
+
+extern GLboolean
+viaUnbindContext(__DRIcontextPrivate *driContextPriv);
+
+extern GLboolean
+viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
+               __DRIdrawablePrivate *driDrawPriv,
+               __DRIdrawablePrivate *driReadPriv);
+
+extern void
+viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate);
+
+#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_span.c b/src/mesa/drivers/dri/unichrome/via_span.c
new file mode 100644 (file)
index 0000000..fb5a82a
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "colormac.h"
+#include "via_context.h"
+#include "via_span.h"
+#include "via_ioctl.h"
+#include "swrast/swrast.h"
+
+#define DBG 0
+#if 0
+#define LOCAL_VARS                                      \
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);             \
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;   \
+    viaScreenPrivate *viaScreen = vmesa->viaScreen;     \
+    GLuint pitch = vmesa->drawPitch;                    \
+    GLuint height = dPriv->h;                           \
+    GLushort p;                                         \
+    char *buf = (char *)(vmesa->drawMap +               \
+       dPriv->x * viaScreen->bytesPerPixel +           \
+                         dPriv->y * pitch);             \
+    char *read_buf = (char *)(vmesa->readMap +          \
+        dPriv->x * viaScreen->bytesPerPixel +           \
+                              dPriv->y * pitch);        \
+    (void)read_buf; (void)buf; (void)p
+#endif
+
+#define LOCAL_DEPTH_VARS                                \
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);             \
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;   \
+    viaScreenPrivate *viaScreen = vmesa->viaScreen;     \
+    GLuint pitch = viaScreen->backPitch;                \
+    GLuint height = dPriv->h;                           \
+    char *buf = (char *)(vmesa->depth.map +             \
+                         dPriv->x * 2 +                 \
+                         dPriv->y * pitch)
+
+#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)
+
+#define HW_LOCK()                               \
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);     \
+    LOCK_HARDWARE_QUIESCENT(vmesa);
+
+/*=* [DBG] csmash saam : bitmap option menu can't be drawn in saam *=*/        
+/*#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_CLIPLOOP()                                               \
+    do {                                                            \
+        __DRIdrawablePrivate *dPriv = vmesa->driDrawable;           \
+        int _nc = dPriv->numClipRects;                              \
+       GLuint scrn = vmesa->saam & S_MASK;                         \
+       if(scrn == S1) _nc = 1;                                     \
+        while (_nc--) {                                             \
+           int minx;                                               \
+           int miny;                                               \
+           int maxx;                                               \
+           int maxy;                                               \
+           if (!vmesa->saam) {                                     \
+               minx = dPriv->pClipRects[_nc].x1 - dPriv->x;        \
+               miny = dPriv->pClipRects[_nc].y1 - dPriv->y;        \
+               maxx = dPriv->pClipRects[_nc].x2 - dPriv->x;        \
+               maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;        \
+           }                                                       \
+           else {                                                  \
+               minx = -10000;                                      \
+               miny = -10000;                                      \
+               maxx = 10000;                                       \
+               maxy = 10000;                                       \
+           }
+           
+           /*else if (scrn == S0) {                                \
+               minx = dPriv->pClipRects[_nc].x1 - dPriv->x;        \
+               miny = dPriv->pClipRects[_nc].y1 - dPriv->y;        \
+               maxx = dPriv->pClipRects[_nc].x2 - dPriv->x;        \
+               maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;        \
+           }                                                       \
+           else if (scrn == S1) {                                  \
+               drm_clip_rect_t *b = vmesa->sarea->boxes;           \
+               minx = b->x1;                                       \
+               miny = b->y1;                                       \
+               maxx = b->x2;                                       \
+               maxy = b->y2;                                       \
+           }                                                       \
+           else {                                                  \
+               drm_clip_rect_t *b = vmesa->sarea->boxes + vmesa->numClipRects;\
+               minx = b->x1;        \
+               miny = b->y1;        \
+               maxx = b->x2;        \
+               maxy = b->y2;        \
+           }*/
+
+#define HW_ENDCLIPLOOP()                                            \
+        }                                                           \
+    } while (0)
+
+#define HW_UNLOCK()                                    \
+    UNLOCK_HARDWARE(vmesa);
+
+
+/* 16 bit, 565 rgb color spanline and pixel functions
+ */
+/*=* [DBG] csmash : fix options worng position *=*/
+/*#define LOCAL_VARS                                    \
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;   \
+    GLuint pitch = vmesa->drawPitch;                    \
+    GLuint height = dPriv->h;                           \
+    GLushort p;                                         \
+    char *buf = (char *)(vmesa->drawMap +               \
+                         dPriv->x * 2 +                 \
+                         dPriv->y * pitch);             \
+    char *read_buf = (char *)(vmesa->readMap +          \
+                              dPriv->x * 2 +            \
+                              dPriv->y * pitch);        \
+    (void)read_buf; (void)buf; (void)p*/
+    
+#define LOCAL_VARS                                                     \
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;                  \
+    GLuint pitch = vmesa->drawPitch;                                   \
+    GLuint height = dPriv->h;                                          \
+    GLushort p;                                                        \
+    char *buf, *read_buf;                                              \
+    p = 0;                                                             \
+    if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) {   \
+       buf = (char *)(vmesa->drawMap);                                 \
+       read_buf = (char *)(vmesa->readMap);                            \
+    }                                                                  \
+    else {                                                             \
+       buf = (char *)(vmesa->drawMap +                                 \
+                         dPriv->x * 2 +                                \
+                         dPriv->y * pitch);                            \
+       read_buf = (char *)(vmesa->readMap +                            \
+                              dPriv->x * 2 +                           \
+                              dPriv->y * pitch);                       \
+    }
+
+#define INIT_MONO_PIXEL(p, color)                       \
+    p = PACK_COLOR_565(color[0], color[1], color[2])
+    
+#define WRITE_RGBA(_x, _y, r, g, b, a)                                      \
+    *(GLushort *)(buf + _x * 2 + _y * pitch) = ((((int)r & 0xf8) << 8) |    \
+                                                (((int)g & 0xfc) << 3) |    \
+                                                (((int)b & 0xf8) >> 3))
+
+#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 >> 8) & 0xf8) * 255 / 0xf8;                           \
+        rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc;                           \
+        rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8;                           \
+        rgba[3] = 255;                                                      \
+    } while (0)
+
+#define TAG(x) via##x##_565
+#include "spantmp.h"
+
+/* 32 bit, 8888 argb color spanline and pixel functions
+ */
+#undef LOCAL_VARS
+#undef LOCAL_DEPTH_VARS
+/*=* [DBG] csmash : fix options worng position *=*/
+/*#define LOCAL_VARS                                    \
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);            \
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;   \
+    GLuint pitch = vmesa->drawPitch;                    \
+    GLuint height = dPriv->h;                           \
+    GLuint p;                                           \
+    char *buf = (char *)(vmesa->drawMap +               \
+                         dPriv->x * 4 +                 \
+                         dPriv->y * pitch);             \
+    char *read_buf = (char *)(vmesa->readMap +          \
+                              dPriv->x * 4 +            \
+                              dPriv->y * pitch);        \
+    (void)read_buf; (void)buf; (void)p*/
+#define LOCAL_VARS                                                     \
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);                            \
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;                  \
+    GLuint pitch = vmesa->drawPitch;                                   \
+    GLuint height = dPriv->h;                                          \
+    GLuint p;                                                          \
+    char *buf, *read_buf;                                              \
+    p = 0;                                                             \
+    if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) {   \
+       buf = (char *)(vmesa->drawMap);                                 \
+       read_buf = (char *)(vmesa->readMap);                            \
+    }                                                                  \
+    else {                                                             \
+       buf = (char *)(vmesa->drawMap +                                 \
+                         dPriv->x * 4 +                                \
+                         dPriv->y * pitch);                            \
+       read_buf = (char *)(vmesa->readMap +                            \
+                              dPriv->x * 4 +                           \
+                              dPriv->y * pitch);                       \
+    }
+
+
+#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) = ((r << 16) |              \
+                                              (g << 8) |               \
+                                              (b << 0) |               \
+                                              (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] = 255;                                                  \
+    } while (0)
+
+#define TAG(x) via##x##_8888
+#include "spantmp.h"
+/*#include "via_spantmp.h"*/
+
+/* 16 bit depthbuffer functions.
+ */
+/*=* John Sheng [2003.6.16] fix exy press 'i' dirty screen *=*/
+/*#define LOCAL_DEPTH_VARS                                \
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;   \
+    GLuint pitch = vmesa->depth.pitch;                  \
+    GLuint height = dPriv->h;                           \
+    char *buf = (char *)(vmesa->depth.map +             \
+                         dPriv->x * 2 +                 \
+                         dPriv->y * pitch)   */
+#define LOCAL_DEPTH_VARS                                \
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);            \
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;   \
+    /*viaScreenPrivate *viaScreen = vmesa->viaScreen;*/ \
+    GLuint pitch = vmesa->depth.pitch;                  \
+    GLuint height = dPriv->h;                           \
+    char *buf = (char *)(vmesa->depth.map)   
+
+
+#define WRITE_DEPTH(_x, _y, d)                      \
+    *(GLushort *)(buf + _x * 2 + _y * pitch) = d;
+
+#define READ_DEPTH(d, _x, _y)                       \
+    d = *(GLushort *)(buf + _x * 2 + _y * pitch);
+
+#define TAG(x) via##x##_16
+#include "depthtmp.h"
+
+/* 32 bit depthbuffer functions.
+ */
+#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) via##x##_32
+#include "depthtmp.h"
+
+/* 24/8 bit depthbuffer functions.
+ */
+/* 
+#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) >> 8; 
+
+#define TAG(x) via##x##_24_8
+#include "depthtmp.h"
+*/
+
+
+void viaSetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
+                      GLuint bufferBit)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    if (bufferBit == FRONT_LEFT_BIT) {
+       vmesa->drawMap = (char *)vmesa->driScreen->pFB;
+        vmesa->readMap = (char *)vmesa->driScreen->pFB;
+       vmesa->drawPitch = vmesa->front.pitch;
+       vmesa->readPitch = vmesa->front.pitch;
+    }
+    else if (bufferBit == BACK_LEFT_BIT) {
+       vmesa->drawMap = vmesa->back.map;
+        vmesa->readMap = vmesa->back.map;
+       vmesa->drawPitch = vmesa->back.pitch;
+       vmesa->readPitch = vmesa->back.pitch;   
+    }
+    else {
+        ASSERT(0);
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
+#endif
+}
+
+
+void viaInitSpanFuncs(GLcontext *ctx)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
+
+    swdd->SetBuffer = viaSetBuffer;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    if (vmesa->viaScreen->bitsPerPixel == 0x10) {
+       swdd->WriteRGBASpan = viaWriteRGBASpan_565;
+       swdd->WriteRGBSpan = viaWriteRGBSpan_565;
+       swdd->WriteMonoRGBASpan = viaWriteMonoRGBASpan_565;
+       swdd->WriteRGBAPixels = viaWriteRGBAPixels_565;
+       swdd->WriteMonoRGBAPixels = viaWriteMonoRGBAPixels_565;
+       swdd->ReadRGBASpan = viaReadRGBASpan_565;
+       swdd->ReadRGBAPixels = viaReadRGBAPixels_565;
+    }
+    else if (vmesa->viaScreen->bitsPerPixel == 0x20) {
+       swdd->WriteRGBASpan = viaWriteRGBASpan_8888;
+       swdd->WriteRGBSpan = viaWriteRGBSpan_8888;
+       swdd->WriteMonoRGBASpan = viaWriteMonoRGBASpan_8888;
+       swdd->WriteRGBAPixels = viaWriteRGBAPixels_8888;
+       swdd->WriteMonoRGBAPixels = viaWriteMonoRGBAPixels_8888;
+       swdd->ReadRGBASpan = viaReadRGBASpan_8888;
+       swdd->ReadRGBAPixels = viaReadRGBAPixels_8888;
+    }
+    else 
+       ASSERT(0);
+       
+    if (vmesa->glCtx->Visual.depthBits == 0x10) {
+       swdd->ReadDepthSpan = viaReadDepthSpan_16;
+       swdd->WriteDepthSpan = viaWriteDepthSpan_16;
+       swdd->ReadDepthPixels = viaReadDepthPixels_16;
+       swdd->WriteDepthPixels = viaWriteDepthPixels_16;
+    }  
+    else if (vmesa->glCtx->Visual.depthBits == 0x20) {
+       swdd->ReadDepthSpan = viaReadDepthSpan_32;
+       swdd->WriteDepthSpan = viaWriteDepthSpan_32;
+       swdd->ReadDepthPixels = viaReadDepthPixels_32;
+       swdd->WriteDepthPixels = viaWriteDepthPixels_32;
+    }
+    
+    swdd->WriteCI8Span = NULL;
+    swdd->WriteCI32Span = NULL;
+    swdd->WriteMonoCISpan = NULL;
+    swdd->WriteCI32Pixels = NULL;
+    swdd->WriteMonoCIPixels = NULL;
+    swdd->ReadCI32Span = NULL;
+    swdd->ReadCI32Pixels = NULL;       
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
+#endif
+}
diff --git a/src/mesa/drivers/dri/unichrome/via_span.h b/src/mesa/drivers/dri/unichrome/via_span.h
new file mode 100644 (file)
index 0000000..6045f2c
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _VIA_SPAN_H
+#define _VIA_SPAN_H
+
+extern void viaInitSpanFuncs(GLcontext *ctx);
+
+#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_state.c b/src/mesa/drivers/dri/unichrome/via_state.c
new file mode 100644 (file)
index 0000000..88eb011
--- /dev/null
@@ -0,0 +1,6376 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "colormac.h"
+#include "enums.h"
+#include "dd.h"
+
+#include "mm.h"
+#include "via_context.h"
+#include "via_state.h"
+#include "via_tex.h"
+#include "via_vb.h"
+#include "via_tris.h"
+#include "via_ioctl.h"
+
+#include "swrast/swrast.h"
+#include "array_cache/acache.h"
+#include "tnl/tnl.h"
+#include "swrast_setup/swrast_setup.h"
+
+#include "tnl/t_pipeline.h"
+
+static GLuint ROP[16] = {
+    HC_HROP_BLACK,    /* GL_CLEAR           0                          */
+    HC_HROP_DPa,      /* GL_AND             s & d                      */
+    HC_HROP_PDna,     /* GL_AND_REVERSE     s & ~d                     */
+    HC_HROP_P,        /* GL_COPY            s                          */
+    HC_HROP_DPna,     /* GL_AND_INVERTED    ~s & d                      */
+    HC_HROP_D,        /* GL_NOOP            d                                  */
+    HC_HROP_DPx,      /* GL_XOR             s ^ d                       */
+    HC_HROP_DPo,      /* GL_OR              s | d                       */
+    HC_HROP_DPon,     /* GL_NOR             ~(s | d)                    */
+    HC_HROP_DPxn,     /* GL_EQUIV           ~(s ^ d)                    */
+    HC_HROP_Dn,       /* GL_INVERT          ~d                         */
+    HC_HROP_PDno,     /* GL_OR_REVERSE      s | ~d                      */
+    HC_HROP_Pn,       /* GL_COPY_INVERTED   ~s                         */
+    HC_HROP_DPno,     /* GL_OR_INVERTED     ~s | d                      */
+    HC_HROP_DPan,     /* GL_NAND            ~(s & d)                    */
+    HC_HROP_WHITE     /* GL_SET             1                          */
+};
+
+static __inline__ GLuint viaPackColor(GLuint format,
+                                      GLubyte r, GLubyte g,
+                                      GLubyte b, GLubyte a)
+{
+    switch (format) {
+    case 0x10:
+        return PACK_COLOR_565(r, g, b);
+    case 0x20:
+        return PACK_COLOR_8888(a, r, g, b);        
+    default:
+#ifdef DEBUG
+        if (VIA_DEBUG) fprintf(stderr, "unknown format %d\n", (int)format);
+#endif
+        return PACK_COLOR_8888(a, r, g, b);
+   }
+}
+
+static void viaAlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    vmesa = vmesa;
+}
+
+static void viaBlendEquation(GLcontext *ctx, GLenum mode)
+{
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    /* Can only do GL_ADD equation in hardware */
+    FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_BLEND_EQ, mode != GL_FUNC_ADD_EXT);
+
+    /* BlendEquation sets ColorLogicOpEnabled in an unexpected
+     * manner.
+     */
+    FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_LOGICOP,
+             (ctx->Color.ColorLogicOpEnabled &&
+              ctx->Color.LogicOp != GL_COPY));
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
+#endif
+}
+
+static void viaBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    GLboolean fallback = GL_FALSE;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    switch (ctx->Color.BlendSrcRGB) {
+    case GL_ZERO:                break;
+    case GL_SRC_ALPHA:           break;
+    case GL_ONE:                 break;
+    case GL_DST_COLOR:           break;
+    case GL_ONE_MINUS_DST_COLOR: break;
+    case GL_ONE_MINUS_SRC_ALPHA: break;
+    case GL_DST_ALPHA:           break;
+    case GL_ONE_MINUS_DST_ALPHA: break;
+    case GL_SRC_ALPHA_SATURATE:  /*a |= SDM_SRC_SRC_ALPHA; break;*/
+    case GL_CONSTANT_COLOR:
+    case GL_ONE_MINUS_CONSTANT_COLOR:
+    case GL_CONSTANT_ALPHA:
+    case GL_ONE_MINUS_CONSTANT_ALPHA:
+        fallback = GL_TRUE;
+        break;
+    default:
+        return;
+    }
+
+    switch (ctx->Color.BlendDstRGB) {
+    case GL_SRC_ALPHA:           break;
+    case GL_ONE_MINUS_SRC_ALPHA: break;
+    case GL_ZERO:                break;
+    case GL_ONE:                 break;
+    case GL_SRC_COLOR:           break;
+    case GL_ONE_MINUS_SRC_COLOR: break;
+    case GL_DST_ALPHA:           break;
+    case GL_ONE_MINUS_DST_ALPHA: break;
+    case GL_CONSTANT_COLOR:
+    case GL_ONE_MINUS_CONSTANT_COLOR:
+    case GL_CONSTANT_ALPHA:
+    case GL_ONE_MINUS_CONSTANT_ALPHA:
+        fallback = GL_TRUE;
+        break;
+    default:
+        return;
+    }
+
+    FALLBACK(vmesa, VIA_FALLBACK_BLEND_FUNC, fallback);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
+#endif
+}
+
+/* Shouldn't be called as the extension is disabled.
+ */
+static void viaBlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB,
+                                 GLenum dfactorRGB, GLenum sfactorA,
+                                 GLenum dfactorA)
+{
+    if (dfactorRGB != dfactorA || sfactorRGB != sfactorA) {
+        _mesa_error(ctx, GL_INVALID_OPERATION, "glBlendEquation (disabled)");
+    }
+
+    viaBlendFunc(ctx, sfactorRGB, dfactorRGB);
+}
+
+
+static void viaDepthFunc(GLcontext *ctx, GLenum func)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    vmesa = vmesa;
+}
+
+static void viaDepthMask(GLcontext *ctx, GLboolean flag)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    vmesa = vmesa;    
+}
+
+static void viaPolygonStipple(GLcontext *ctx, const GLubyte *mask)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    vmesa = vmesa;    
+}
+
+
+/* =============================================================
+ * Hardware clipping
+ */
+static void viaScissor(GLcontext *ctx, GLint x, GLint y,
+                       GLsizei w, GLsizei h)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);    
+#endif
+    if (ctx->Scissor.Enabled) {
+        VIA_FIREVERTICES(vmesa); /* don't pipeline cliprect changes */
+        vmesa->uploadCliprects = GL_TRUE;
+    }
+
+    vmesa->scissorRect.x1 = x;
+    vmesa->scissorRect.y1 = vmesa->driDrawable->h - (y + h);
+    vmesa->scissorRect.x2 = x + w;
+    vmesa->scissorRect.y2 = vmesa->driDrawable->h - y;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);    
+#endif
+}
+
+
+static void viaLogicOp(GLcontext *ctx, GLenum opcode)
+{
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+    if (VIA_DEBUG) fprintf(stderr, "opcode = %x\n", opcode);
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
+#endif
+}
+
+/* Fallback to swrast for select and feedback.
+ */
+static void viaRenderMode(GLcontext *ctx, GLenum mode)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    FALLBACK(vmesa, VIA_FALLBACK_RENDERMODE, (mode != GL_RENDER));
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
+#endif
+}
+
+
+static void viaDrawBuffer(GLcontext *ctx, GLenum mode)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
+#endif
+    if (mode == GL_FRONT_LEFT) {
+        VIA_FIREVERTICES(vmesa);
+        VIA_STATECHANGE(vmesa, VIA_UPLOAD_BUFFERS);
+        vmesa->drawMap = (char *)vmesa->driScreen->pFB;
+        vmesa->readMap = (char *)vmesa->driScreen->pFB;
+       vmesa->drawPitch = vmesa->front.pitch;
+       vmesa->readPitch = vmesa->front.pitch;
+        viaXMesaSetFrontClipRects(vmesa);
+        FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_FALSE);
+        return;
+    }
+    else if (mode == GL_BACK_LEFT) {
+        VIA_FIREVERTICES(vmesa);
+        VIA_STATECHANGE(vmesa, VIA_UPLOAD_BUFFERS);
+        vmesa->drawMap = vmesa->back.map;
+        vmesa->readMap = vmesa->back.map;
+       vmesa->drawPitch = vmesa->back.pitch;
+       vmesa->readPitch = vmesa->back.pitch;   
+        viaXMesaSetBackClipRects(vmesa);
+        FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_FALSE);
+        return;
+    }
+    else {
+        FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_TRUE);
+        return;
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);    
+#endif
+}
+
+static void viaClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    GLubyte pcolor[4];
+    pcolor[0] = (GLubyte) (255 * color[0]);
+    pcolor[1] = (GLubyte) (255 * color[1]);
+    pcolor[2] = (GLubyte) (255 * color[2]);
+    pcolor[3] = (GLubyte) (255 * color[3]);
+    vmesa->ClearColor = viaPackColor(vmesa->viaScreen->bitsPerPixel,
+                                     pcolor[0], pcolor[1],
+                                     pcolor[2], pcolor[3]);
+       
+}
+
+/* =============================================================
+ * Culling - the via isn't quite as clean here as the rest of
+ *           its interfaces, but it's not bad.
+ */
+static void viaCullFaceFrontFace(GLcontext *ctx, GLenum unused)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    vmesa = vmesa;    
+}
+
+static void viaLineWidth(GLcontext *ctx, GLfloat widthf)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    vmesa = vmesa;    
+}
+
+static void viaPointSize(GLcontext *ctx, GLfloat sz)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    vmesa = vmesa;    
+}
+
+static void viaBitmap( GLcontext *ctx, GLint px, GLint py,
+               GLsizei width, GLsizei height,
+               const struct gl_pixelstore_attrib *unpack,
+               const GLubyte *bitmap ) 
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+        
+    /*=* [DBG] csmash : fix background overlap option menu *=*/
+    LOCK_HARDWARE(vmesa);
+    viaFlushPrimsLocked(vmesa);
+    UNLOCK_HARDWARE(vmesa);
+    
+    WAIT_IDLE
+    /*=* [DBG] csmash : fix segmentation fault *=*/
+    /*=* John Sheng [2003.7.18] texenv *=*/
+    /*if (!vmesa->drawMap && !vmesa->readMap) {*/
+    if (1) {
+       if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) {
+           viaDrawBuffer(ctx, GL_BACK_LEFT);
+       }
+       else {
+           viaDrawBuffer(ctx, GL_FRONT_LEFT);
+       }
+    }
+    /*=* [DBG] csmash : white option words become brown *=*/
+    /*_swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap );*/
+    {
+       GLboolean fog;
+       fog = ctx->Fog.Enabled;
+       ctx->Fog.Enabled = GL_FALSE;
+       _swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap );
+       ctx->Fog.Enabled = fog;
+    }
+}
+
+/* =============================================================
+ * Color masks
+ */
+static void viaColorMask(GLcontext *ctx,
+                         GLboolean r, GLboolean g,
+                         GLboolean b, GLboolean a)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    vmesa = vmesa;    
+}
+
+/* Seperate specular not fully implemented on the via.
+ */
+static void viaLightModelfv(GLcontext *ctx, GLenum pname,
+                            const GLfloat *param)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    vmesa = vmesa;    
+}
+
+
+/* In Mesa 3.5 we can reliably do native flatshading.
+ */
+static void viaShadeModel(GLcontext *ctx, GLenum mode)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    vmesa = vmesa;    
+}
+
+/* =============================================================
+ * Fog
+ */
+static void viaFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    vmesa = vmesa;    
+}
+
+/* =============================================================
+ */
+static void viaEnable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    vmesa = vmesa;    
+}
+
+/* =============================================================
+ */
+void viaEmitDrawingRectangle(viaContextPtr vmesa)
+{
+    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+    viaScreenPrivate *viaScreen = vmesa->viaScreen;
+    int x0 = vmesa->drawX;
+    int y0 = vmesa->drawY;
+    int x1 = x0 + dPriv->w;
+    int y1 = y0 + dPriv->h;
+/*    GLuint dr2, dr3, dr4;
+*/
+
+    /* Coordinate origin of the window - may be offscreen.
+     */
+/*   dr4 = vmesa->BufferSetup[VIA_DESTREG_DR4] = ((y0 << 16) |
+                                                  (((unsigned)x0) & 0xFFFF));
+*/                                
+
+    /* Clip to screen.
+     */
+    if (x0 < 0) x0 = 0;
+    if (y0 < 0) y0 = 0;
+    if (x1 > viaScreen->width - 1) x1 = viaScreen->width - 1;
+    if (y1 > viaScreen->height - 1) y1 = viaScreen->height - 1;
+
+    /* Onscreen drawing rectangle.
+     */
+/*   dr2 = vmesa->BufferSetup[VIA_DESTREG_DR2] = ((y0 << 16) | x0);
+    dr3 = vmesa->BufferSetup[VIA_DESTREG_DR3] = (((y1 + 1) << 16) | (x1 + 1));
+*/  
+
+    vmesa->dirty |= VIA_UPLOAD_BUFFERS;
+}
+
+
+static void viaCalcViewport(GLcontext *ctx)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    const GLfloat *v = ctx->Viewport._WindowMap.m;
+    GLfloat *m = vmesa->ViewportMatrix.m;
+    
+    /* See also via_translate_vertex.  SUBPIXEL adjustments can be done
+     * via state vars, too.
+     */
+    m[MAT_SX] =  v[MAT_SX];
+    m[MAT_TX] =  v[MAT_TX] + vmesa->drawXoff;
+    m[MAT_SY] = - v[MAT_SY];
+    m[MAT_TY] = - v[MAT_TY] + vmesa->driDrawable->h;
+    /*=* John Sheng [2003.7.2] for visual config & viewperf drv-08 *=*/
+    if (vmesa->depth.bpp == 16) {
+       m[MAT_SZ] =  v[MAT_SZ] * (1.0 / 0xffff);
+       m[MAT_TZ] =  v[MAT_TZ] * (1.0 / 0xffff);
+    }
+    else {
+       m[MAT_SZ] =  v[MAT_SZ] * (1.0 / 0xffffffff);
+       m[MAT_TZ] =  v[MAT_TZ] * (1.0 / 0xffffffff);
+    }
+}
+
+static void viaViewport(GLcontext *ctx,
+                        GLint x, GLint y,
+                        GLsizei width, GLsizei height)
+{
+    viaCalcViewport(ctx);
+}
+
+static void viaDepthRange(GLcontext *ctx,
+                          GLclampd nearval, GLclampd farval)
+{
+    viaCalcViewport(ctx);
+}
+
+void viaPrintDirty(const char *msg, GLuint state)
+{
+#ifdef DEBUG
+    if (VIA_DEBUG)
+       fprintf(stderr, "%s (0x%x): %s%s%s%s\n",
+            msg,
+            (unsigned int) state,
+            (state & VIA_UPLOAD_TEX0)   ? "upload-tex0, " : "",
+            (state & VIA_UPLOAD_TEX1)   ? "upload-tex1, " : "",
+            (state & VIA_UPLOAD_CTX)    ? "upload-ctx, " : "",
+            (state & VIA_UPLOAD_BUFFERS)    ? "upload-bufs, " : ""
+            );
+#endif
+}
+
+
+void viaInitState(GLcontext *ctx)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+
+    vmesa->regCmdA = HC_ACMD_HCmdA;
+    vmesa->regCmdB = HC_ACMD_HCmdB | HC_HVPMSK_X | HC_HVPMSK_Y | HC_HVPMSK_Z;
+    vmesa->regEnable = HC_HenCW_MASK;
+
+    if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) {
+        vmesa->drawMap = vmesa->back.map;
+        vmesa->readMap = vmesa->back.map;
+    }
+    else {
+        vmesa->drawMap = (char *)vmesa->driScreen->pFB;
+        vmesa->readMap = (char *)vmesa->driScreen->pFB;
+    }
+}
+
+void viaChooseTextureState(GLcontext *ctx) 
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    struct gl_texture_unit *texUnit0 = &ctx->Texture.Unit[0];
+    struct gl_texture_unit *texUnit1 = &ctx->Texture.Unit[1];
+    /*=* John Sheng [2003.7.18] texture combine *=*/
+    GLboolean AlphaCombine[3];
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif    
+    if (texUnit0->_ReallyEnabled || texUnit1->_ReallyEnabled) {
+#ifdef DEBUG
+       if (VIA_DEBUG) {
+           fprintf(stderr, "Texture._ReallyEnabled - in\n");    
+           fprintf(stderr, "texUnit0->_ReallyEnabled = %x\n",texUnit0->_ReallyEnabled);
+       }
+#endif
+
+        if (texUnit0->_ReallyEnabled) {
+            struct gl_texture_object *texObj = texUnit0->_Current;
+            struct gl_texture_image *texImage = texObj->Image[0];            
+            GLint r, g, b, a;
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "texUnit0->_ReallyEnabled\n");    
+#endif            
+            if (texImage->Border) {
+                FALLBACK(vmesa, VIA_FALLBACK_TEXTURE, GL_TRUE);
+                return;
+            }
+            vmesa->regCmdB |= HC_HVPMSK_S | HC_HVPMSK_T | HC_HVPMSK_W | HC_HVPMSK_Cs;
+            vmesa->regEnable |= HC_HenTXMP_MASK | HC_HenTXCH_MASK | HC_HenTXPP_MASK;
+   
+            switch (texObj->MinFilter) {
+            case GL_NEAREST:
+                vmesa->regHTXnTB_0 = HC_HTXnFLSs_Nearest |
+                                     HC_HTXnFLTs_Nearest;
+                break;
+            case GL_LINEAR:
+                vmesa->regHTXnTB_0 = HC_HTXnFLSs_Linear |
+                                     HC_HTXnFLTs_Linear;
+                break;
+            case GL_NEAREST_MIPMAP_NEAREST:
+                vmesa->regHTXnTB_0 = HC_HTXnFLSs_Nearest |
+                                     HC_HTXnFLTs_Nearest;
+                vmesa->regHTXnTB_0 |= HC_HTXnFLDs_Nearest;
+                break;
+            case GL_LINEAR_MIPMAP_NEAREST:
+                vmesa->regHTXnTB_0 = HC_HTXnFLSs_Linear |
+                                     HC_HTXnFLTs_Linear;
+                vmesa->regHTXnTB_0 |= HC_HTXnFLDs_Nearest;
+                break;
+            case GL_NEAREST_MIPMAP_LINEAR:
+                vmesa->regHTXnTB_0 = HC_HTXnFLSs_Nearest |
+                                     HC_HTXnFLTs_Nearest;
+                vmesa->regHTXnTB_0 |= HC_HTXnFLDs_Linear;
+                break;
+            case GL_LINEAR_MIPMAP_LINEAR:
+                vmesa->regHTXnTB_0 = HC_HTXnFLSs_Linear |
+                                     HC_HTXnFLTs_Linear;
+                vmesa->regHTXnTB_0 |= HC_HTXnFLDs_Linear;
+                break;
+            default:
+                break;
+            }
+
+           if (texObj->MagFilter) {
+                vmesa->regHTXnTB_0 |= HC_HTXnFLSe_Linear |
+                                      HC_HTXnFLTe_Linear;
+            }
+            else {
+                vmesa->regHTXnTB_0 |= HC_HTXnFLSe_Nearest |
+                                      HC_HTXnFLTe_Nearest;
+            }
+
+            if (texObj->WrapS == GL_REPEAT)
+                vmesa->regHTXnMPMD_0 = HC_HTXnMPMD_Srepeat;
+            else
+                vmesa->regHTXnMPMD_0 = HC_HTXnMPMD_Sclamp;
+
+            if (GL_TRUE) {
+                if (texObj->WrapT == GL_REPEAT)
+                    vmesa->regHTXnMPMD_0 |= HC_HTXnMPMD_Trepeat;
+                else
+                    vmesa->regHTXnMPMD_0 |= HC_HTXnMPMD_Tclamp;
+            }
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "texUnit0->EnvMode %x\n",texUnit0->EnvMode);    
+#endif
+            switch (texUnit0->EnvMode) {
+            case GL_MODULATE:
+               switch (texImage->Format) {
+                case GL_ALPHA:
+                    /* C = Cf, A = At*Af
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 | HC_HTXnTBLCb_TOPC |
+                        HC_HTXnTBLCb_0 | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Adif | HC_HTXnTBLAb_TOPA |
+                        HC_HTXnTBLAb_Atex | HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    vmesa->regHTXnTBLRFog_0 = 0x0;
+                    break;
+                case GL_LUMINANCE:
+                    /* C = Lt*Cf, A = Af
+                     * RGB part.
+                     * Ca = Lt, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                        HC_HTXnTBLCb_Dif | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    break;
+                case GL_LUMINANCE_ALPHA:
+                    /* C = Lt*Cf, A = At*Af
+                     * RGB part.
+                     * Ca = Lt, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                        HC_HTXnTBLCb_Dif | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    vmesa->regHTXnTBLRFog_0 = 0x0;
+                    break;
+                case GL_INTENSITY:
+                    /* C = It*Cf, A = It*Af
+                     * RGB part.
+                     * Ca = It, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                        HC_HTXnTBLCb_Dif | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = It, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    vmesa->regHTXnTBLRFog_0 = 0x0;
+                    break;
+                case GL_RGB:
+                    /* C = Ct*Cf, A = Af
+                     * RGB part.
+                     * Ca = Ct, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                        HC_HTXnTBLCb_Dif | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+#ifdef DEBUG
+                   if (VIA_DEBUG) fprintf(stderr, "texUnit0->EnvMode: GL_MODULATE: GL_RGB\n");    
+#endif
+                    break;
+                case GL_RGBA:
+                    /* C = Ct*Cf, A = At*Af
+                     * RGB part.
+                     * Ca = Ct, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                        HC_HTXnTBLCb_Dif | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                       HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_HTXnTBLRAbias
+                       | HC_HTXnTBLAshift_No;
+                    
+                   vmesa->regHTXnTBLRAa_0 = 0x0;
+                    vmesa->regHTXnTBLRFog_0 = 0x0;
+#ifdef DEBUG
+                   if (VIA_DEBUG) fprintf(stderr, "texUnit0->EnvMode: GL_MODULATE: GL_RGBA\n");        
+#endif
+                    break;
+                case GL_COLOR_INDEX:
+                    switch (texObj->Palette.Format) {
+                    case GL_ALPHA:
+                        /* C = Cf, A = At*Af
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 | HC_HTXnTBLCb_TOPC |
+                            HC_HTXnTBLCb_0 | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex | HC_HTXnTBLAb_TOPA |
+                            HC_HTXnTBLAb_Adif | HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        vmesa->regHTXnTBLRFog_0 = 0x0;
+                        break;
+                    case GL_LUMINANCE:
+                        /* C = Lt*Cf, A = Af
+                         * RGB part.
+                         * Ca = Lt, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                            HC_HTXnTBLCb_Dif | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        break;
+                    case GL_LUMINANCE_ALPHA:
+                        /* C = Lt*Cf, A = At*Af
+                         * RGB part.
+                         * Ca = Lt, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                            HC_HTXnTBLCb_Dif | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        vmesa->regHTXnTBLRFog_0 = 0x0;
+                        break;
+                    case GL_INTENSITY:
+                        /* C = It*Cf, A = It*Af
+                         * RGB part.
+                         * Ca = It, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                            HC_HTXnTBLCb_Dif | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = It, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        vmesa->regHTXnTBLRFog_0 = 0x0;
+                        break;
+                    case GL_RGB:
+                        /* C = Ct*Cf, A = Af
+                         * RGB part.
+                         * Ca = Ct, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                            HC_HTXnTBLCb_Dif | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        break;
+                    case GL_RGBA:
+                        /* C = Ct*Cf, A = At*Af
+                         * RGB part.
+                         * Ca = Ct, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                            HC_HTXnTBLCb_Dif | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        vmesa->regHTXnTBLRFog_0 = 0x0;
+                        break;
+                    }
+                    break;
+                }
+                break;
+            case GL_DECAL:
+               switch (texImage->Format) {
+                case GL_ALPHA:
+                case GL_LUMINANCE:
+                case GL_LUMINANCE_ALPHA:
+                case GL_INTENSITY:
+                    /* Undefined.
+                     */
+                    break;
+                case GL_RGB:
+                    /* C = Ct, A = Af
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Ct, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+#ifdef DEBUG
+                   if (VIA_DEBUG) fprintf(stderr, "texUnit0->EnvMode: GL_DECAL: GL_RGB\n");
+#endif
+                    break;
+                case GL_RGBA:
+                    /* C = (1-At)*Cf+At*Ct, A = Af --> At*(Ct-Cf)+Cf
+                     * RGB part.
+                     * Ca = At, Cb = Ct, Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Atex |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_Tex |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+#ifdef DEBUG
+                   if (VIA_DEBUG) fprintf(stderr, "texUnit0->EnvMode: GL_DECAL: GL_RGBA\n");
+#endif
+                    break;
+                case GL_COLOR_INDEX:
+                    switch (texObj->Palette.Format) {
+                    case GL_ALPHA:
+                    case GL_LUMINANCE:
+                    case GL_LUMINANCE_ALPHA:
+                    case GL_INTENSITY:
+                        /* Undefined.
+                         */
+                        break;
+                    case GL_RGB:
+                        /* C = Ct, A = Af
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Ct, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+#ifdef DEBUG
+                       if (VIA_DEBUG) fprintf(stderr, "texUnit0->EnvMode: GL_COLOR_INDEX: GL_RGB\n");    
+#endif
+                        break;
+                    case GL_RGBA:
+                        /* C = (1-At)*Cf+At*Ct, A = Af --> At*(Ct-Cf)+Cf
+                         * RGB part.
+                         * Ca = At, Cb = Ct, Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Atex |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_Tex |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+#ifdef DEBUG
+                       if (VIA_DEBUG) fprintf(stderr, "texUnit0->EnvMode: GL_COLOR_INDEX: GL_RGBA\n");    
+#endif
+                        break;
+                    }
+                    break;
+                }
+                break;
+            case GL_BLEND:
+               switch (texImage->Format) {
+                case GL_ALPHA:
+                    /* C = Cf, A = Af
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    break;
+                case GL_LUMINANCE:
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                    /* C = (1-Lt)*Cf+Lt*Cc, A = Af --> Lt*(Cc-Cf)+Cf
+                     * RGB part.
+                     * Ca = Lt, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    break;
+                case GL_LUMINANCE_ALPHA:
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                    /* C = (1-Lt)*Cf+Lt*Cc, A = At*Af --> Lt*(Cc-Cf)+Cf
+                     * RGB part.
+                     * Ca = Lt, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                    /* Alpha part.
+                     * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    vmesa->regHTXnTBLRFog_0 = 0x0;
+                    break;
+                case GL_INTENSITY:
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                    /* C = (1-It)*Cf+It*Cc, A = (1-It)*Af+It*Ac
+                     * --> It*(Cc-Cf)+Cf, It*(Ac-Af)+Af
+                     * RGB part.
+                     * Ca = It, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                    /* Alpha part.
+                     * Aa = It, Ab = Ac(Reg), Cop = -, Ac = Af, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_Adif;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Sub |
+                        HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = (a << 8);
+                    break;
+                case GL_RGB:
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                    /* C = (1-Ct)*Cf+Ct*Cc, A = Af --> Ct*(Cc-Cf)+Cf
+                     * RGB part.
+                     * Ca = Ct, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+#ifdef DEBUG
+                   if (VIA_DEBUG) fprintf(stderr, "texUnit0->EnvMode: GL_BLEND: GL_RGB\n");    
+#endif
+                    break;
+                case GL_RGBA:
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                    /* C = (1-Ct)*Cf+Ct*Cc, A = At*Af --> Ct*(Cc-Cf)+Cf
+                     * RGB part.
+                     * Ca = Ct, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                    /* Alpha part.
+                     * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    vmesa->regHTXnTBLRFog_0 = 0x0;
+#ifdef DEBUG
+                   if (VIA_DEBUG) fprintf(stderr, "texUnit0->EnvMode: GL_BLEND: GL_RGBA\n");    
+#endif
+                    break;
+                case GL_COLOR_INDEX:
+                    switch (texObj->Palette.Format) {
+                    case GL_ALPHA:
+                        /* C = Cf, A = Af
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        break;
+                    case GL_LUMINANCE:
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                        /* C = (1-Lt)*Cf+Lt*Cc, A = Af --> Lt*(Cc-Cf)+Cf
+                         * RGB part.
+                         * Ca = Lt, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        break;
+                    case GL_LUMINANCE_ALPHA:
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                        /* C = (1-Lt)*Cf+Lt*Cc, A = At*Af --> Lt*(Cc-Cf)+Cf
+                         * RGB part.
+                         * Ca = Lt, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        /* Alpha part.
+                         * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        vmesa->regHTXnTBLRFog_0 = 0x0;
+                        break;
+                    case GL_INTENSITY:
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        /* C = (1-It)*Cf+It*Cc, A = (1-It)*Af+It*Ac
+                         * --> It*(Cc-Cf)+Cf, It*(Ac-Af)+Af
+                         * RGB part.
+                         * Ca = It, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        /* Alpha part.
+                         * Aa = It, Ab = Ac(Reg), Cop = -, Ac = Af, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_Adif;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Sub |
+                            HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = (a << 8);
+                        break;
+                    case GL_RGB:
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        /* C = (1-Ct)*Cf+Ct*Cc, A = Af --> Ct*(Cc-Cf)+Cf
+                         * RGB part.
+                         * Ca = Ct, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        break;
+                    case GL_RGBA:
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        /* C = (1-Ct)*Cf+Ct*Cc, A = At*Af --> Ct*(Cc-Cf)+Cf
+                         * RGB part.
+                         * Ca = Ct, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        /* Alpha part.
+                         * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        vmesa->regHTXnTBLRFog_0 = 0x0;
+                        break;
+                    }
+                    break;
+                }
+                break;
+            case GL_REPLACE:
+               switch (texImage->Format) {
+                case GL_ALPHA:
+                    /* C = Cf, A = At
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = At, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    break;
+                case GL_LUMINANCE:
+                    /* C = Lt, A = Af
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Lt, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    break;
+                case GL_LUMINANCE_ALPHA:
+                    /* C = Lt, A = At
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Lt, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = At, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    break;
+                case GL_INTENSITY:
+                    /* C = It, A = It
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = It, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = It, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    break;
+                case GL_RGB:
+                    /* C = Ct, A = Af
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Ct, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+#ifdef DEBUG
+                   if (VIA_DEBUG) fprintf(stderr, "texUnit0->EnvMode: GL_REPLACE: GL_RGB\n");    
+#endif
+                    break;
+                case GL_RGBA:
+                    /* C = Ct, A = At
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Ct, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = At, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+#ifdef DEBUG
+                   if (VIA_DEBUG) fprintf(stderr, "texUnit0->EnvMode: GL_REPLACE: GL_RGBA\n");    
+#endif
+                    break;
+                case GL_COLOR_INDEX:
+                    switch (texObj->Palette.Format) {
+                    case GL_ALPHA:
+                        /* C = Cf, A = At
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = At, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        break;
+                    case GL_LUMINANCE:
+                        /* C = Lt, A = Af
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Lt, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        break;
+                    case GL_LUMINANCE_ALPHA:
+                        /* C = Lt, A = At
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Lt, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = At, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        break;
+                    case GL_INTENSITY:
+                        /* C = It, A = It
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = It, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = It, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        break;
+                    case GL_RGB:
+                        /* C = Ct, A = Af
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Ct, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        break;
+                    case GL_RGBA:
+                        /* C = Ct, A = At
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Ct, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = At, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_0 = 0x0;
+                        break;
+                    }
+                    break;
+                }
+                break;
+           /*=* John Sheng [2003.7.18] texture combine *=*/
+           case GL_COMBINE:
+               switch (texUnit0->CombineModeRGB) {
+               case GL_REPLACE:
+                   switch (texUnit0->CombineSourceRGB[0]) {
+                   case GL_TEXTURE:
+                       switch (texUnit0->CombineOperandRGB[0]) {
+                       case GL_SRC_COLOR:  
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                           HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                           vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex;
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           break;
+                       case GL_ONE_MINUS_SRC_COLOR:
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                           HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                           vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_Tex;
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           break;
+                       case GL_SRC_ALPHA:  
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                           HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                           vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Atex; 
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           break;
+                       case GL_ONE_MINUS_SRC_ALPHA:
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                           HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                           vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_Atex;
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           break;
+                       }
+                       break;
+                   case GL_CONSTANT :
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                       switch (texUnit0->CombineOperandRGB[0]) {
+                       case GL_SRC_COLOR:  
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                           HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_HTXnTBLRC; 
+                        
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                           break;
+                       case GL_ONE_MINUS_SRC_COLOR:
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                           HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                           vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_HTXnTBLRC;
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                           break;
+                       case GL_SRC_ALPHA:  
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                           vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_HTXnTBLRC;
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           vmesa->regHTXnTBLRCb_0 = (a << 16) | (a << 8) | a;
+                           break;
+                        case GL_ONE_MINUS_SRC_ALPHA:
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_HTXnTBLRC;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           vmesa->regHTXnTBLRCb_0 = (a << 16) | (a << 8) | a;
+                            break;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                       switch (texUnit0->CombineOperandRGB[0]) {
+                        case GL_SRC_COLOR:  
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        case GL_ONE_MINUS_SRC_COLOR:
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_Dif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        case GL_SRC_ALPHA:  
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Adif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        case GL_ONE_MINUS_SRC_ALPHA:
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_Adif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        }
+                        break;
+                    case GL_PREVIOUS :
+                        switch (texUnit0->CombineOperandRGB[0]) {
+                        case GL_SRC_COLOR:  
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        case GL_ONE_MINUS_SRC_COLOR:
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_Dif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        case GL_SRC_ALPHA:  
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Adif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        case GL_ONE_MINUS_SRC_ALPHA:
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_Adif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        }
+                        break;
+                    }
+                    switch ((GLint)(texUnit0->CombineScaleShiftRGB)) {
+                    case 1:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_No;
+                       break;
+                    case 2:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_2;
+                        break;
+                    }
+                    break;
+
+                case GL_MODULATE:
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    switch (texUnit0->CombineOperandRGB[0]) {
+                    case GL_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_TOPC; 
+                        AlphaCombine[0]=0;
+                        break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_InvTOPC; 
+                        AlphaCombine[0]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_TOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_InvTOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    }
+                    switch (texUnit0->CombineOperandRGB[1]) {
+                    case GL_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC; 
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC;
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC;
+                        AlphaCombine[1]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC;
+                        AlphaCombine[1]=1;
+                        break;
+                    }
+                    switch (texUnit0->CombineSourceRGB[0]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Tex; 
+                        }
+                        else {
+                           vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Atex;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_HTXnTBLRC;
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLRCa_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCa_0 = (a << 16) | (a << 8) | a;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Dif; 
+                       }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Adif;
+                        }
+                        break;
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Dif; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Adif;
+                       }
+                       break;
+                    }
+                   switch (texUnit0->CombineSourceRGB[1]) {
+                    case GL_TEXTURE:
+                       if (AlphaCombine[1]==0) {
+                           vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Tex; 
+                       }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Atex;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_HTXnTBLRC;
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        }
+                       else {
+                           vmesa->regHTXnTBLRCb_0 = (a << 16) | (a << 8) | a;
+                       }
+                       break;
+                    case GL_PRIMARY_COLOR :
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Dif; 
+                       }
+                       else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Adif;
+                        }
+                       break;
+                    case GL_PREVIOUS :
+                       if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Dif; 
+                       }
+                       else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Adif;
+                       }
+                       break;
+                   }
+                   switch ((GLint)(texUnit0->CombineScaleShiftRGB)) {
+                    case 1:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_No;
+                       break;
+                   case 2:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_1;
+                       break;
+                    case 4:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_2;
+                       break;
+                   }
+                   break;
+               case GL_ADD:
+                case GL_SUBTRACT :
+                   if (texUnit0->CombineModeRGB==GL_ADD) {
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0;
+                    }
+                   else {
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0;
+                   }
+                   vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                   vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK | HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC;
+                    vmesa->regHTXnTBLRCa_0 = ( 255<<16 | 255<<8 |255 );
+                    switch (texUnit0->CombineOperandRGB[0]) {
+                    case GL_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC; 
+                       AlphaCombine[0]=0;
+                        break;
+                   case GL_ONE_MINUS_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC; 
+                        AlphaCombine[0]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    }
+                    switch (texUnit0->CombineOperandRGB[1]) {
+                    case GL_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_TOPC; 
+                       AlphaCombine[1]=0;
+                       break;
+                   case GL_ONE_MINUS_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_InvTOPC;
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_TOPC;
+                        AlphaCombine[1]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_InvTOPC;
+                        AlphaCombine[1]=1;
+                        break;
+                   }
+                    switch (texUnit0->CombineSourceRGB[0]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Tex; 
+                       }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Atex;
+                       }
+                       break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_HTXnTBLRC;
+                        if (AlphaCombine[0]==0) {
+                           vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCb_0 = (a << 16) | (a << 8) | a;
+                       }
+                       break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Dif; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Adif;
+                       }
+                       break;
+                    }
+                    switch (texUnit0->CombineSourceRGB[1]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Tex; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Atex;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_HTXnTBLRC;
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLRCc_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCc_0 = (a << 16) | (a << 8) | a;
+                       }
+                       break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Dif; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Adif;
+                        }
+                       break;
+                   }
+                   switch ((GLint)(texUnit0->CombineScaleShiftRGB)) {
+                    case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_2;
+                        break;
+                    }
+                    break;
+                case GL_ADD_SIGNED :
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub;
+                   vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                   vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                       HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC|
+                       HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_HTXnTBLRC;
+                   vmesa->regHTXnTBLRCa_0 = ( 255<<16 | 255<<8 |255 );
+                    vmesa->regHTXnTBLRCc_0 = ( 128<<16 | 128<<8 |128 );
+                    switch (texUnit0->CombineOperandRGB[0]) {
+                    case GL_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC; 
+                        AlphaCombine[0]=0;
+                        break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC; 
+                        AlphaCombine[0]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    }
+                    switch (texUnit0->CombineOperandRGB[1]) {
+                    case GL_SRC_COLOR:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Cbias;
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_InvCbias;
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Cbias;
+                        AlphaCombine[1]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_InvCbias;
+                       AlphaCombine[1]=1;
+                        break;
+                    }
+                    switch (texUnit0->CombineSourceRGB[0]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Tex; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Atex;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_HTXnTBLRC;
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCb_0 = (a << 16) | (a << 8) | a;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Dif; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Adif;
+                        }
+                        break;
+                    }
+                   switch (texUnit0->CombineSourceRGB[1]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Tex; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Atex; 
+                        }
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_HTXnTBLRC; 
+                       if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLRCbias_0 = (r << 16) | (g << 8) | b;
+                        }
+                       else {
+                            vmesa->regHTXnTBLRCbias_0 = (a << 16) | (a << 8) | a;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Dif; 
+                        }
+                       else {
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Adif;
+                        }
+                        break;
+                    }
+                    switch ((GLint)(texUnit0->CombineScaleShiftRGB)) {
+                    case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_2;
+                        break;
+                    }
+                   break;
+                case GL_INTERPOLATE :
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub;
+                   vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                   switch (texUnit0->CombineOperandRGB[0]) {
+                    case GL_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCb_TOPC; 
+                       AlphaCombine[0]=0;
+                       break;
+                   case GL_ONE_MINUS_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCb_InvTOPC; 
+                        AlphaCombine[0]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCb_TOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCb_InvTOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    }
+                    switch (texUnit0->CombineOperandRGB[1]) {
+                    case GL_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCc_TOPC;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Cbias;
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCc_InvTOPC;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_InvCbias;
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                       vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCc_TOPC;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Cbias;
+                        AlphaCombine[1]=1;
+                       break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCc_InvTOPC;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_InvCbias;
+                        AlphaCombine[1]=1;
+                        break;
+                    }
+                    switch (texUnit0->CombineOperandRGB[2]) {
+                    case GL_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCa_TOPC; 
+                        AlphaCombine[2]=0;
+                        break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCa_InvTOPC;
+                        AlphaCombine[2]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCa_TOPC;
+                        AlphaCombine[2]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCa_InvTOPC;
+                        AlphaCombine[2]=1;
+                        break;
+                    }
+                    switch (texUnit0->CombineSourceRGB[0]) {
+                    case GL_TEXTURE:
+                       if (AlphaCombine[0]==0) {
+                           vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Tex; 
+                        }
+                        else {
+                           vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Atex;
+                        }
+                       break;
+                   case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_HTXnTBLRC;
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCb_0 = (a << 16) | (a << 8) | a;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Dif; 
+                        }
+                       else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Adif;
+                        }
+                        break;
+                    }
+                    switch (texUnit0->CombineSourceRGB[1]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Tex; 
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Tex;
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Atex;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Atex;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_HTXnTBLRC;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_HTXnTBLRC;
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLRCc_0 = (r << 16) | (g << 8) | b;
+                            vmesa->regHTXnTBLRCbias_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCc_0 = (a << 16) | (a << 8) | a;
+                            vmesa->regHTXnTBLRCbias_0 = (a << 16) | (a << 8) | a;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Dif; 
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Dif;
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Adif;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Adif;
+                        }
+                        break;
+                    }
+                    switch (texUnit0->CombineSourceRGB[2]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Tex; 
+                        }
+                       else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Atex;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_HTXnTBLRC;
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLRCa_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCa_0 = (a << 16) | (a << 8) | a;
+                        }
+                       break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Dif; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Adif;
+                        }
+                        break;
+                    }
+                    switch ((GLint)(texUnit0->CombineScaleShiftRGB)) {
+                    case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_2;
+                        break;
+                    }
+                    break;
+                }
+               switch (texUnit0->CombineModeA) {
+                case GL_REPLACE:
+                    switch (texUnit0->CombineSourceA[0]) {
+                    case GL_TEXTURE:
+                        switch (texUnit0->CombineOperandA[0]) {
+                       case GL_SRC_ALPHA:  
+                            vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Atex;
+                            vmesa->regHTXnTBLRAa_0 = 0x0;
+                            break;
+                        case GL_ONE_MINUS_SRC_ALPHA:
+                            vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Inv | HC_HTXnTBLAbias_Atex;
+                            vmesa->regHTXnTBLRAa_0 = 0x0;
+                            break;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        switch (texUnit0->CombineOperandA[0]) {
+                        case GL_SRC_ALPHA:  
+                            vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias;
+                            vmesa->regHTXnTBLRAa_0 = 0x0;
+                            vmesa->regHTXnTBLRFog_0 = a;
+                            break;
+                        case GL_ONE_MINUS_SRC_ALPHA:
+                            vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Inv | HC_HTXnTBLAbias_HTXnTBLRAbias;
+                            vmesa->regHTXnTBLRAa_0 = 0x0;
+                            vmesa->regHTXnTBLRFog_0 = a;
+                            break;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        switch (texUnit0->CombineOperandA[0]) {
+                        case GL_SRC_ALPHA:  
+                            vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                           HC_HTXnTBLAbias_Adif;
+                            vmesa->regHTXnTBLRAa_0 = 0x0;
+                            break;
+                        case GL_ONE_MINUS_SRC_ALPHA:
+                            vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Inv | HC_HTXnTBLAbias_Adif;
+                           vmesa->regHTXnTBLRAa_0 = 0x0;
+                            break;
+                       }
+                   break;
+                    }
+                    switch ((GLint)(texUnit0->CombineScaleShiftA)) {
+                    case 1:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_2;
+                        break;
+                    }
+                    break;
+                case GL_MODULATE:
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                     HC_HTXnTBLAbias_HTXnTBLRAbias;
+                    vmesa->regHTXnTBLRFog_0 = 0x0;
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK | HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                   vmesa->regHTXnTBLRAa_0= 0x0;
+                    switch (texUnit0->CombineOperandA[0]) {
+                    case GL_SRC_ALPHA:
+                       vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_TOPA; 
+                       break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_InvTOPA; 
+                        break;
+                    }
+                    switch (texUnit0->CombineOperandA[1]) {
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_TOPA; 
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_InvTOPA; 
+                        break;
+                    }
+                    switch (texUnit0->CombineSourceA[0]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_Atex; 
+                        break;
+                    case GL_CONSTANT :
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= a<<16;
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_Adif; 
+                        break;
+                    }
+                    switch (texUnit0->CombineSourceA[1]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Atex;
+                        break;
+                    case GL_CONSTANT :
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= a<<8;
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Adif;
+                        break;
+                    }
+                    switch ((GLint)(texUnit0->CombineScaleShiftA)) {
+                   case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_2;
+                        break;
+                    }
+                    break;
+                case GL_ADD:
+                case GL_SUBTRACT :
+                    if(texUnit0->CombineModeA==GL_ADD) {
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add | HC_HTXnTBLAbias_HTXnTBLRAbias;
+                   }
+                   else {
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Sub | HC_HTXnTBLAbias_HTXnTBLRAbias;
+                    }
+                    vmesa->regHTXnTBLRFog_0 = 0;
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK | HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA;
+                    vmesa->regHTXnTBLRAa_0 = 0x0 |  ( 255<<16 );
+                    switch (texUnit0->CombineOperandA[0]) {
+                    case GL_SRC_ALPHA:
+                       vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_TOPA; 
+                       break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_InvTOPA; 
+                        break;
+                    }
+                   switch (texUnit0->CombineOperandA[1]) {
+                    case GL_SRC_ALPHA:
+                       vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_TOPA;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_InvTOPA;
+                        break;
+                    }
+                    switch (texUnit0->CombineSourceA[0]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Atex;
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= (a << 8);
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Adif;
+                        break;
+                    }
+                    switch (texUnit0->CombineSourceA[1]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_Atex;
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= a;
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_Adif;
+                        break;
+                    }
+                    switch ((GLint)(texUnit0->CombineScaleShiftA)) {
+                    case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_2;
+                        break;
+                    }
+                    break;
+                case GL_ADD_SIGNED :
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Sub;
+                    vmesa->regHTXnTBLRFog_0 = 0x0;
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA|
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLRAa_0 = ( 255<<16 | 0<<8 |128 );
+                    switch (texUnit0->CombineOperandA[0]) {
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_TOPA; 
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_InvTOPA; 
+                        break;
+                    }
+                    switch (texUnit0->CombineOperandA[1]) {
+                    case GL_SRC_ALPHA:
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_Inv;
+                        break;
+                    }
+                    switch (texUnit0->CombineSourceA[0]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Atex;
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= (a << 8);
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Adif;
+                        break;
+                    }
+                    switch (texUnit0->CombineSourceA[1]) {
+                   case GL_TEXTURE:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_Atex; 
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_HTXnTBLRAbias; 
+                        vmesa->regHTXnTBLRFog_0 |= a;
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_Adif;
+                        break;
+                    }
+                    switch ((GLint)(texUnit0->CombineScaleShiftA)) {
+                    case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_2;
+                        break;
+                    }
+                    break;
+               case GL_INTERPOLATE :
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Sub;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    vmesa->regHTXnTBLRFog_0 =  0x0;
+                    switch (texUnit0->CombineOperandA[0]) {
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAb_TOPA; 
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAb_InvTOPA; 
+                        break;
+                    }
+                    switch (texUnit0->CombineOperandA[1]) {
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAc_TOPA;
+                        break;
+                   case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAc_InvTOPA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_Inv;
+                        break;
+                    }
+                    switch (texUnit0->CombineOperandA[2]) {
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAa_TOPA;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAa_InvTOPA;
+                        break;
+                    }
+                    switch (texUnit0->CombineSourceA[0]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Atex;
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= (a << 8);
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Adif;
+                        break;
+                    }
+                    switch (texUnit0->CombineSourceA[1]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_Atex;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_Atex;
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_HTXnTBLRA;
+                       vmesa->regHTXnTBLRAa_0 |= a;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_HTXnTBLRAbias;
+                        vmesa->regHTXnTBLRFog_0 |= a;
+                        break;
+                   case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_Adif;
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_Adif;
+                        break;
+                   }
+                    switch (texUnit0->CombineSourceA[2]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_Atex;
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= (a << 16);
+                        break;
+                    case GL_PRIMARY_COLOR :
+                   case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_Adif;
+                        break;
+                   }
+                    switch (texUnit0->CombineScaleShiftA) {
+                    case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_2;
+                        break;
+                    }
+                   break;
+               case GL_DOT3_RGB :
+               case GL_DOT3_RGBA :
+                   break;
+               }
+               break;
+       /*=* John Sheng [2003.7.18] texture add *=*/
+        case GL_ADD:
+            switch(texImage->Format) {
+            case GL_ALPHA:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_0 | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Adif | HC_HTXnTBLAb_TOPA |
+                    HC_HTXnTBLAb_Atex | HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                break;
+            case GL_LUMINANCE:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                break;
+            case GL_LUMINANCE_ALPHA:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                break;
+            case GL_INTENSITY:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Atex |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_Adif;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+               /*=* John Sheng [2003.7.18] texenv *=*/
+               /*vmesa->regHTXnTBLRAa_0 = 0x0;*/
+                vmesa->regHTXnTBLRAa_0 = (255<<16) | (255<<8) | 255;;
+                vmesa->regHTXnTBLRFog_0 = 0x0 | 255<<16;
+                break;
+            case GL_RGB:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                break;
+            case GL_RGBA:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                break;
+            case GL_COLOR_INDEX:
+                switch(texObj->Palette.Format) {
+                case GL_ALPHA:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_0 | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Adif | HC_HTXnTBLAb_TOPA |
+                    HC_HTXnTBLAb_Atex | HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                break;
+                case GL_LUMINANCE:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                break;
+                case GL_LUMINANCE_ALPHA:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                break;
+                case GL_INTENSITY:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Atex |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_Adif;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0 | 255<<16;
+                break;
+                case GL_RGB:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                break;
+                case GL_RGBA:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                break;
+                }
+                break;
+            }
+            break;
+       /*=* John Sheng [2003.7.18] texture dot3 *=*/
+           case GL_DOT3_RGB :
+           case GL_DOT3_RGBA :
+               vmesa->regHTXnTBLCop_0 = HC_HTXnTBLDOT4 | HC_HTXnTBLCop_Add | 
+                                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 | 
+                                         HC_HTXnTBLCshift_2 | HC_HTXnTBLAop_Add |
+                                         HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                                       HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK | 
+                                       HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                                       HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                                       HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                switch (texUnit0->CombineOperandRGB[0]) {
+                case GL_SRC_COLOR:
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_TOPC; 
+                   break;
+                case GL_ONE_MINUS_SRC_COLOR:
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_InvTOPC; 
+                    break;
+                }
+                switch (texUnit0->CombineOperandRGB[1]) {
+                case GL_SRC_COLOR:
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC; 
+                    break;
+                case GL_ONE_MINUS_SRC_COLOR:
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC; 
+                    break;
+                }
+                switch (texUnit0->CombineSourceRGB[0]) {
+                case GL_TEXTURE:
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Tex; 
+                    break;
+                case GL_CONSTANT :
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                   CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                   CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_HTXnTBLRC;
+                    vmesa->regHTXnTBLRCa_0 = (r << 16) | (g << 8) | b;
+                    break;
+               case GL_PRIMARY_COLOR :
+                case GL_PREVIOUS :
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Dif; 
+                    break;
+                }
+                switch (texUnit0->CombineSourceRGB[1]) {
+                case GL_TEXTURE:
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Tex; 
+                    break;
+                case GL_CONSTANT :
+                   CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[0], r);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[1], g);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit0->EnvColor[2], b);
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_HTXnTBLRC;
+                    vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                    break;
+                case GL_PRIMARY_COLOR :
+                case GL_PREVIOUS :
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Dif; 
+                    break;
+                }
+               break;
+            default:
+               break;
+            }
+        }
+       else {
+       /* Should turn Cs off if actually no Cs */
+       }
+
+        if (texUnit1->_ReallyEnabled) {
+            struct gl_texture_object *texObj = texUnit1->_Current;
+            struct gl_texture_image *texImage = texObj->Image[0];
+            GLint r, g, b, a;
+
+            if (texImage->Border) {
+                FALLBACK(vmesa, VIA_FALLBACK_TEXTURE, GL_TRUE);
+                return;
+            }
+
+            switch (texObj->MinFilter) {
+            case GL_NEAREST:
+                vmesa->regHTXnTB_1 = HC_HTXnFLSs_Nearest |
+                                     HC_HTXnFLTs_Nearest;
+                break;
+            case GL_LINEAR:
+                vmesa->regHTXnTB_1 = HC_HTXnFLSs_Linear |
+                                     HC_HTXnFLTs_Linear;
+                break;
+            case GL_NEAREST_MIPMAP_NEAREST:
+                vmesa->regHTXnTB_1 = HC_HTXnFLSs_Nearest |
+                                     HC_HTXnFLTs_Nearest;
+                vmesa->regHTXnTB_1 |= HC_HTXnFLDs_Nearest;
+                break ;
+            case GL_LINEAR_MIPMAP_NEAREST:
+                vmesa->regHTXnTB_1 = HC_HTXnFLSs_Linear |
+                                     HC_HTXnFLTs_Linear;
+                vmesa->regHTXnTB_1 |= HC_HTXnFLDs_Nearest;
+                break ;
+            case GL_NEAREST_MIPMAP_LINEAR:
+                vmesa->regHTXnTB_1 = HC_HTXnFLSs_Nearest |
+                                     HC_HTXnFLTs_Nearest;
+                vmesa->regHTXnTB_1 |= HC_HTXnFLDs_Linear;
+                break ;
+            case GL_LINEAR_MIPMAP_LINEAR:
+                vmesa->regHTXnTB_1 = HC_HTXnFLSs_Linear |
+                                     HC_HTXnFLTs_Linear;
+                vmesa->regHTXnTB_1 |= HC_HTXnFLDs_Linear;
+                break ;
+            default:
+                break;
+            }
+
+           switch(texObj->MagFilter) {
+               case GL_NEAREST:
+                   vmesa->regHTXnTB_1 |= HC_HTXnFLSs_Nearest |
+                                     HC_HTXnFLTs_Nearest;
+                   break;
+               case GL_LINEAR:
+                   vmesa->regHTXnTB_1 |= HC_HTXnFLSs_Linear |
+                                     HC_HTXnFLTs_Linear;
+                   break;
+           }
+           
+            if (texObj->WrapS == GL_REPEAT)
+                vmesa->regHTXnMPMD_1 = HC_HTXnMPMD_Srepeat;
+            else
+                vmesa->regHTXnMPMD_1 = HC_HTXnMPMD_Sclamp;
+
+            if (GL_TRUE) {
+                if (texObj->WrapT == GL_REPEAT)
+                    vmesa->regHTXnMPMD_1 |= HC_HTXnMPMD_Trepeat;
+                else
+                    vmesa->regHTXnMPMD_1 |= HC_HTXnMPMD_Tclamp;
+            }
+
+            switch (texUnit1->EnvMode) {
+            case GL_MODULATE:
+               switch (texImage->Format) {
+                case GL_ALPHA:
+                    /* C = Cf, A = At*Af
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 | HC_HTXnTBLCb_TOPC |
+                        HC_HTXnTBLCb_0 | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex | HC_HTXnTBLAb_TOPA |
+                        HC_HTXnTBLAb_Acur | HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    vmesa->regHTXnTBLRFog_1 = 0x0;
+                    break;
+                case GL_LUMINANCE:
+                    /* C = Lt*Cf, A = Af
+                     * RGB part.
+                     * Ca = Lt, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                        HC_HTXnTBLCb_Cur | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    break;
+                case GL_LUMINANCE_ALPHA:
+                    /* C = Lt*Cf, A = At*Af
+                     * RGB part.
+                     * Ca = Lt, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                        HC_HTXnTBLCb_Cur | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Acur |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    vmesa->regHTXnTBLRFog_1 = 0x0;
+                    break;
+                case GL_INTENSITY:
+                    /* C = It*Cf, A = It*Af
+                     * RGB part.
+                     * Ca = It, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                        HC_HTXnTBLCb_Cur | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = It, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Acur |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    vmesa->regHTXnTBLRFog_1 = 0x0;
+                    break;
+                case GL_RGB:
+                    /* C = Ct*Cf, A = Af
+                     * RGB part.
+                     * Ca = Ct, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                        HC_HTXnTBLCb_Cur | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    break;
+                case GL_RGBA:
+                    /* C = Ct*Cf, A = At*Af
+                     * RGB part.
+                     * Ca = Ct, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                        HC_HTXnTBLCb_Cur | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Acur |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                       HC_HTXnTBLAbias_HTXnTBLRAbias
+                       | HC_HTXnTBLAshift_No;
+                    
+                   vmesa->regHTXnTBLRAa_1 = 0x0;
+                    vmesa->regHTXnTBLRFog_1 = 0x0;
+                    break;
+                case GL_COLOR_INDEX:
+                    switch (texObj->Palette.Format) {
+                    case GL_ALPHA:
+                        /* C = Cf, A = At*Af
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 | HC_HTXnTBLCb_TOPC |
+                            HC_HTXnTBLCb_0 | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex | HC_HTXnTBLAb_TOPA |
+                            HC_HTXnTBLAb_Acur | HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        vmesa->regHTXnTBLRFog_1 = 0x0;
+                        break;
+                    case GL_LUMINANCE:
+                        /* C = Lt*Cf, A = Af
+                         * RGB part.
+                         * Ca = Lt, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                            HC_HTXnTBLCb_Cur | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        break;
+                    case GL_LUMINANCE_ALPHA:
+                        /* C = Lt*Cf, A = At*Af
+                         * RGB part.
+                         * Ca = Lt, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                            HC_HTXnTBLCb_Cur | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Acur |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        vmesa->regHTXnTBLRFog_1 = 0x0;
+                        break;
+                    case GL_INTENSITY:
+                        /* C = It*Cf, A = It*Af
+                         * RGB part.
+                         * Ca = It, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                            HC_HTXnTBLCb_Cur | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = It, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Acur |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        vmesa->regHTXnTBLRFog_1 = 0x0;
+                        break;
+                    case GL_RGB:
+                        /* C = Ct*Cf, A = Af
+                         * RGB part.
+                         * Ca = Ct, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                            HC_HTXnTBLCb_Cur | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        break;
+                    case GL_RGBA:
+                        /* C = Ct*Cf, A = At*Af
+                         * RGB part.
+                         * Ca = Ct, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | HC_HTXnTBLCb_TOPC |
+                            HC_HTXnTBLCb_Cur | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Acur |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        vmesa->regHTXnTBLRFog_1 = 0x0;
+                        break;
+                    }
+                    break;
+                }
+                break;
+            case GL_DECAL:
+                switch (texImage->Format) {
+                case GL_ALPHA:
+                case GL_LUMINANCE:
+                case GL_LUMINANCE_ALPHA:
+                case GL_INTENSITY:
+                    /* Undefined.
+                     */
+                    break;
+                case GL_RGB:
+                    /* C = Ct, A = Af
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Ct, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    break;
+                case GL_RGBA:
+                    /* C = (1-At)*Cf+At*Ct, A = Af --> At*(Ct-Cf)+Cf
+                     * RGB part.
+                     * Ca = At, Cb = Ct, Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Atex |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_Tex |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Cur;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    break;
+                case GL_COLOR_INDEX:
+                    switch (texObj->Palette.Format) {
+                    case GL_ALPHA:
+                    case GL_LUMINANCE:
+                    case GL_LUMINANCE_ALPHA:
+                    case GL_INTENSITY:
+                        /* Undefined.
+                         */
+                        break;
+                    case GL_RGB:
+                        /* C = Ct, A = Af
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Ct, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        break;
+                    case GL_RGBA:
+                        /* C = (1-At)*Cf+At*Ct, A = Af --> At*(Ct-Cf)+Cf
+                         * RGB part.
+                         * Ca = At, Cb = Ct, Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Atex |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_Tex |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Cur;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Sub |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        break;
+                    }
+                    break;
+                }
+                break;
+            case GL_BLEND:
+                switch (texImage->Format) {
+                case GL_ALPHA:
+                    /* C = Cf, A = Af
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    break;
+                case GL_LUMINANCE:
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                    /* C = (1-Lt)*Cf+Lt*Cc, A = Af --> Lt*(Cc-Cf)+Cf
+                     * RGB part.
+                     * Ca = Lt, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Cur;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    vmesa->regHTXnTBLRCb_1 = (r << 16) | (g << 8) | b;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    break;
+                case GL_LUMINANCE_ALPHA:
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                    /* C = (1-Lt)*Cf+Lt*Cc, A = At*Af --> Lt*(Cc-Cf)+Cf
+                     * RGB part.
+                     * Ca = Lt, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Cur;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    vmesa->regHTXnTBLRCb_1 = (r << 16) | (g << 8) | b;
+                    /* Alpha part.
+                     * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Acur |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    vmesa->regHTXnTBLRFog_1 = 0x0;
+                    break;
+                case GL_INTENSITY:
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                    /* C = (1-It)*Cf+It*Cc, A = (1-It)*Af+It*Ac
+                     * --> It*(Cc-Cf)+Cf, It*(Ac-Af)+Af
+                     * RGB part.
+                     * Ca = It, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Cur;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    vmesa->regHTXnTBLRCb_1 = (r << 16) | (g << 8) | b;
+                    /* Alpha part.
+                     * Aa = It, Ab = Ac(Reg), Cop = -, Ac = Af, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_Acur;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Sub |
+                        HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = (a << 8);
+                    break;
+                case GL_RGB:
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                    /* C = (1-Ct)*Cf+Ct*Cc, A = Af --> Ct*(Cc-Cf)+Cf
+                     * RGB part.
+                     * Ca = Ct, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Cur;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    vmesa->regHTXnTBLRCb_1 = (r << 16) | (g << 8) | b;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    break;
+                case GL_RGBA:
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                    /* C = (1-Ct)*Cf+Ct*Cc, A = At*Af --> Ct*(Cc-Cf)+Cf
+                     * RGB part.
+                     * Ca = Ct, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Cur;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    vmesa->regHTXnTBLRCb_1 = (r << 16) | (g << 8) | b;
+                    /* Alpha part.
+                     * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Acur |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    vmesa->regHTXnTBLRFog_1 = 0x0;
+                    break;
+                case GL_COLOR_INDEX:
+                    switch (texObj->Palette.Format) {
+                    case GL_ALPHA:
+                        /* C = Cf, A = Af
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        break;
+                    case GL_LUMINANCE:
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                        /* C = (1-Lt)*Cf+Lt*Cc, A = Af --> Lt*(Cc-Cf)+Cf
+                         * RGB part.
+                         * Ca = Lt, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Cur;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Sub |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        vmesa->regHTXnTBLRCb_1 = (r << 16) | (g << 8) | b;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        break;
+                    case GL_LUMINANCE_ALPHA:
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                        /* C = (1-Lt)*Cf+Lt*Cc, A = At*Af --> Lt*(Cc-Cf)+Cf
+                         * RGB part.
+                         * Ca = Lt, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Cur;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Sub |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        vmesa->regHTXnTBLRCb_1 = (r << 16) | (g << 8) | b;
+                        /* Alpha part.
+                         * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Acur |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        vmesa->regHTXnTBLRFog_1 = 0x0;
+                        break;
+                    case GL_INTENSITY:
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        /* C = (1-It)*Cf+It*Cc, A = (1-It)*Af+It*Ac
+                         * --> It*(Cc-Cf)+Cf, It*(Ac-Af)+Af
+                         * RGB part.
+                         * Ca = It, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Cur;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Sub |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        vmesa->regHTXnTBLRCb_1 = (r << 16) | (g << 8) | b;
+                        /* Alpha part.
+                         * Aa = It, Ab = Ac(Reg), Cop = -, Ac = Af, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_Acur;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Sub |
+                            HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = (a << 8);
+                        break;
+                    case GL_RGB:
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        /* C = (1-Ct)*Cf+Ct*Cc, A = Af --> Ct*(Cc-Cf)+Cf
+                         * RGB part.
+                         * Ca = Ct, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Cur;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Sub |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        vmesa->regHTXnTBLRCb_1 = (r << 16) | (g << 8) | b;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        break;
+                    case GL_RGBA:
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        /* C = (1-Ct)*Cf+Ct*Cc, A = At*Af --> Ct*(Cc-Cf)+Cf
+                         * RGB part.
+                         * Ca = Ct, Cb = Cc(Reg), Cop = -, Cc = Cf, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_HTXnTBLRC |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Cur;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Sub |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        vmesa->regHTXnTBLRCb_1 = (r << 16) | (g << 8) | b;
+                        /* Alpha part.
+                         * Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Acur |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        vmesa->regHTXnTBLRFog_1 = 0x0;
+                        break;
+                    }
+                    break;
+                }
+                break;
+            case GL_REPLACE:
+                switch (texImage->Format) {
+                case GL_ALPHA:
+                    /* C = Cf, A = At
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Cf, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = At, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    break;
+                case GL_LUMINANCE:
+                    /* C = Lt, A = Af
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Lt, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    break;
+                case GL_LUMINANCE_ALPHA:
+                    /* C = Lt, A = At
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Lt, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = At, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    break;
+                case GL_INTENSITY:
+                    /* C = It, A = It
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = It, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = It, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    break;
+                case GL_RGB:
+                    /* C = Ct, A = Af
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Ct, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    break;
+                case GL_RGBA:
+                    /* C = Ct, A = At
+                     * RGB part.
+                     * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Ct, Cshift = No.
+                     */
+                    vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                        HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                        HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                        HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                        HC_HTXnTBLCshift_No;
+                    vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                    /* Alpha part.
+                     * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = At, Ashift = No.
+                     */
+                    vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                        HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                        HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLRAa_1 = 0x0;
+                    break;
+                case GL_COLOR_INDEX:
+                    switch (texObj->Palette.Format) {
+                    case GL_ALPHA:
+                        /* C = Cf, A = At
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Cf, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Cur |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = At, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        break;
+                    case GL_LUMINANCE:
+                        /* C = Lt, A = Af
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Lt, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        break;
+                    case GL_LUMINANCE_ALPHA:
+                        /* C = Lt, A = At
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Lt, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = At, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        break;
+                    case GL_INTENSITY:
+                        /* C = It, A = It
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = It, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = It, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        break;
+                    case GL_RGB:
+                        /* C = Ct, A = Af
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Ct, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Acur | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        break;
+                    case GL_RGBA:
+                        /* C = Ct, A = At
+                         * RGB part.
+                         * Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Ct, Cshift = No.
+                         */
+                        vmesa->regHTXnTBLCsat_1 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                        vmesa->regHTXnTBLCop_1 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex |
+                            HC_HTXnTBLCshift_No;
+                        vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
+                        /* Alpha part.
+                         * Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = At, Ashift = No.
+                         */
+                        vmesa->regHTXnTBLAsat_1 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLCop_1 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No;
+                        vmesa->regHTXnTBLRAa_1 = 0x0;
+                        break;
+                    }
+                    break;
+                }
+                break;
+           /*=* John Sheng [2003.7.18] texture combine *=*/
+           case GL_COMBINE:
+               switch (texUnit1->CombineModeRGB) {
+               case GL_REPLACE:
+                   switch (texUnit1->CombineSourceRGB[0]) {
+                   case GL_TEXTURE:
+                       switch (texUnit1->CombineOperandRGB[0]) {
+                       case GL_SRC_COLOR:  
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                           HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                           vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex;
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           break;
+                       case GL_ONE_MINUS_SRC_COLOR:
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                           HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                           vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_Tex;
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           break;
+                       case GL_SRC_ALPHA:  
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                           HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                           vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Atex; 
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           break;
+                       case GL_ONE_MINUS_SRC_ALPHA:
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                           HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                           vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_Atex;
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           break;
+                       }
+                       break;
+                   case GL_CONSTANT :
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                       switch (texUnit1->CombineOperandRGB[0]) {
+                       case GL_SRC_COLOR:  
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                           HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_HTXnTBLRC; 
+                        
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                           break;
+                       case GL_ONE_MINUS_SRC_COLOR:
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                           HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                           vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_HTXnTBLRC;
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                           break;
+                       case GL_SRC_ALPHA:  
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                           HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                           vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                           HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_HTXnTBLRC;
+                           vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           vmesa->regHTXnTBLRCb_0 = (a << 16) | (a << 8) | a;
+                           break;
+                        case GL_ONE_MINUS_SRC_ALPHA:
+                           vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                           HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_HTXnTBLRC;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                           vmesa->regHTXnTBLRCb_0 = (a << 16) | (a << 8) | a;
+                            break;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                       switch (texUnit1->CombineOperandRGB[0]) {
+                        case GL_SRC_COLOR:  
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        case GL_ONE_MINUS_SRC_COLOR:
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_Dif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        case GL_SRC_ALPHA:  
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Adif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        case GL_ONE_MINUS_SRC_ALPHA:
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_Adif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        }
+                        break;
+                    case GL_PREVIOUS :
+                        switch (texUnit1->CombineOperandRGB[0]) {
+                        case GL_SRC_COLOR:  
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        case GL_ONE_MINUS_SRC_COLOR:
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_Dif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        case GL_SRC_ALPHA:  
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Adif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        case GL_ONE_MINUS_SRC_ALPHA:
+                            vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                            HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 |
+                            HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 |
+                            HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                            vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                            HC_HTXnTBLCbias_InvCbias | HC_HTXnTBLCbias_Adif;
+                            vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                            break;
+                        }
+                        break;
+                    }
+                    switch ((GLint)(texUnit1->CombineScaleShiftRGB)) {
+                    case 1:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_No;
+                       break;
+                    case 2:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_2;
+                        break;
+                    }
+                    break;
+
+                case GL_MODULATE:
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    switch (texUnit1->CombineOperandRGB[0]) {
+                    case GL_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_TOPC; 
+                        AlphaCombine[0]=0;
+                        break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_InvTOPC; 
+                        AlphaCombine[0]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_TOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_InvTOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    }
+                    switch (texUnit1->CombineOperandRGB[1]) {
+                    case GL_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC; 
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC;
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC;
+                        AlphaCombine[1]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC;
+                        AlphaCombine[1]=1;
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceRGB[0]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Tex; 
+                        }
+                        else {
+                           vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Atex;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_HTXnTBLRC;
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLRCa_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCa_0 = (a << 16) | (a << 8) | a;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Dif; 
+                       }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Adif;
+                        }
+                        break;
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Dif; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Adif;
+                       }
+                       break;
+                    }
+                   switch (texUnit1->CombineSourceRGB[1]) {
+                    case GL_TEXTURE:
+                       if (AlphaCombine[1]==0) {
+                           vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Tex; 
+                       }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Atex;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_HTXnTBLRC;
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        }
+                       else {
+                           vmesa->regHTXnTBLRCb_0 = (a << 16) | (a << 8) | a;
+                       }
+                       break;
+                    case GL_PRIMARY_COLOR :
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Dif; 
+                       }
+                       else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Adif;
+                        }
+                       break;
+                    case GL_PREVIOUS :
+                       if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Dif; 
+                       }
+                       else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Adif;
+                       }
+                       break;
+                   }
+                   switch ((GLint)(texUnit1->CombineScaleShiftRGB)) {
+                    case 1:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_No;
+                       break;
+                   case 2:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_1;
+                       break;
+                    case 4:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_2;
+                       break;
+                   }
+                   break;
+               case GL_ADD:
+                case GL_SUBTRACT :
+                   if (texUnit1->CombineModeRGB==GL_ADD) {
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0;
+                    }
+                   else {
+                        vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub |
+                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0;
+                   }
+                   vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                   vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK | HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC;
+                    vmesa->regHTXnTBLRCa_0 = ( 255<<16 | 255<<8 |255 );
+                    switch (texUnit1->CombineOperandRGB[0]) {
+                    case GL_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC; 
+                       AlphaCombine[0]=0;
+                        break;
+                   case GL_ONE_MINUS_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC; 
+                        AlphaCombine[0]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    }
+                    switch (texUnit1->CombineOperandRGB[1]) {
+                    case GL_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_TOPC; 
+                       AlphaCombine[1]=0;
+                       break;
+                   case GL_ONE_MINUS_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_InvTOPC;
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_TOPC;
+                        AlphaCombine[1]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_InvTOPC;
+                        AlphaCombine[1]=1;
+                        break;
+                   }
+                    switch (texUnit1->CombineSourceRGB[0]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Tex; 
+                       }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Atex;
+                       }
+                       break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_HTXnTBLRC;
+                        if (AlphaCombine[0]==0) {
+                           vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCb_0 = (a << 16) | (a << 8) | a;
+                       }
+                       break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Dif; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Adif;
+                       }
+                       break;
+                    }
+                    switch (texUnit1->CombineSourceRGB[1]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Tex; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Atex;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_HTXnTBLRC;
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLRCc_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCc_0 = (a << 16) | (a << 8) | a;
+                       }
+                       break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Dif; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Adif;
+                        }
+                       break;
+                   }
+                   switch ((GLint)(texUnit1->CombineScaleShiftRGB)) {
+                    case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_2;
+                        break;
+                    }
+                    break;
+                case GL_ADD_SIGNED :
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub;
+                   vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                   vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                       HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC|
+                       HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_HTXnTBLRC;
+                   vmesa->regHTXnTBLRCa_0 = ( 255<<16 | 255<<8 |255 );
+                    vmesa->regHTXnTBLRCc_0 = ( 128<<16 | 128<<8 |128 );
+                    switch (texUnit1->CombineOperandRGB[0]) {
+                    case GL_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC; 
+                        AlphaCombine[0]=0;
+                        break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC; 
+                        AlphaCombine[0]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    }
+                    switch (texUnit1->CombineOperandRGB[1]) {
+                    case GL_SRC_COLOR:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Cbias;
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_InvCbias;
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Cbias;
+                        AlphaCombine[1]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_InvCbias;
+                       AlphaCombine[1]=1;
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceRGB[0]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Tex; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Atex;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_HTXnTBLRC;
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCb_0 = (a << 16) | (a << 8) | a;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Dif; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Adif;
+                        }
+                        break;
+                    }
+                   switch (texUnit1->CombineSourceRGB[1]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Tex; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Atex; 
+                        }
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_HTXnTBLRC; 
+                       if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLRCbias_0 = (r << 16) | (g << 8) | b;
+                        }
+                       else {
+                            vmesa->regHTXnTBLRCbias_0 = (a << 16) | (a << 8) | a;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[1]==0) {
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Dif; 
+                        }
+                       else {
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Adif;
+                        }
+                        break;
+                    }
+                    switch ((GLint)(texUnit1->CombineScaleShiftRGB)) {
+                    case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_2;
+                        break;
+                    }
+                   break;
+                case GL_INTERPOLATE :
+                    vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Sub;
+                   vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                   switch (texUnit1->CombineOperandRGB[0]) {
+                    case GL_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCb_TOPC; 
+                       AlphaCombine[0]=0;
+                       break;
+                   case GL_ONE_MINUS_SRC_COLOR:
+                       vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCb_InvTOPC; 
+                        AlphaCombine[0]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCb_TOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCb_InvTOPC; 
+                        AlphaCombine[0]=1;
+                        break;
+                    }
+                    switch (texUnit1->CombineOperandRGB[1]) {
+                    case GL_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCc_TOPC;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Cbias;
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCc_InvTOPC;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_InvCbias;
+                        AlphaCombine[1]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                       vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCc_TOPC;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Cbias;
+                        AlphaCombine[1]=1;
+                       break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCc_InvTOPC;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_InvCbias;
+                        AlphaCombine[1]=1;
+                        break;
+                    }
+                    switch (texUnit1->CombineOperandRGB[2]) {
+                    case GL_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCa_TOPC; 
+                        AlphaCombine[2]=0;
+                        break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCa_InvTOPC;
+                        AlphaCombine[2]=0;
+                        break;
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCa_TOPC;
+                        AlphaCombine[2]=1;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCa_InvTOPC;
+                        AlphaCombine[2]=1;
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceRGB[0]) {
+                    case GL_TEXTURE:
+                       if (AlphaCombine[0]==0) {
+                           vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Tex; 
+                        }
+                        else {
+                           vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Atex;
+                        }
+                       break;
+                   case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_HTXnTBLRC;
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCb_0 = (a << 16) | (a << 8) | a;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Dif; 
+                        }
+                       else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Adif;
+                        }
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceRGB[1]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Tex; 
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Tex;
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Atex;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Atex;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_HTXnTBLRC;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_HTXnTBLRC;
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLRCc_0 = (r << 16) | (g << 8) | b;
+                            vmesa->regHTXnTBLRCbias_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCc_0 = (a << 16) | (a << 8) | a;
+                            vmesa->regHTXnTBLRCbias_0 = (a << 16) | (a << 8) | a;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Dif; 
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Dif;
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCc_Adif;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCbias_Adif;
+                        }
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceRGB[2]) {
+                    case GL_TEXTURE:
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Tex; 
+                        }
+                       else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Atex;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_HTXnTBLRC;
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLRCa_0 = (r << 16) | (g << 8) | b;
+                        }
+                        else {
+                            vmesa->regHTXnTBLRCa_0 = (a << 16) | (a << 8) | a;
+                        }
+                       break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        if (AlphaCombine[0]==0) {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Dif; 
+                        }
+                        else {
+                            vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Adif;
+                        }
+                        break;
+                    }
+                    switch ((GLint)(texUnit1->CombineScaleShiftRGB)) {
+                    case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLCshift_2;
+                        break;
+                    }
+                    break;
+
+               case GL_DOT3_RGB :
+               case GL_DOT3_RGBA :
+                   vmesa->regHTXnTBLCop_0 = HC_HTXnTBLDOT4 | HC_HTXnTBLCop_Add | 
+                                         HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 | 
+                                          HC_HTXnTBLCshift_2 | HC_HTXnTBLAop_Add |
+                                          HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                    vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                    vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                                           HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                    vmesa->regHTXnTBLRFog_0 = 0x0;
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK | 
+                                           HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                                           HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                                           HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    switch (texUnit1->CombineOperandRGB[0]) {
+                    case GL_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_TOPC; 
+                       break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_InvTOPC; 
+                        break;
+                    }
+                    switch (texUnit1->CombineOperandRGB[1]) {
+                    case GL_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC; 
+                        break;
+                    case GL_ONE_MINUS_SRC_COLOR:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC; 
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceRGB[0]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Tex; 
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_HTXnTBLRC;
+                        vmesa->regHTXnTBLRCa_0 = (r << 16) | (g << 8) | b;
+                        break;
+                   case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Dif; 
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceRGB[1]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Tex; 
+                        break;
+                    case GL_CONSTANT :
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_HTXnTBLRC;
+                        vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Dif; 
+                        break;
+                    }
+                   break;
+                   
+                }
+               switch (texUnit1->CombineModeA) {
+                case GL_REPLACE:
+                    switch (texUnit1->CombineSourceA[0]) {
+                    case GL_TEXTURE:
+                        switch (texUnit1->CombineOperandA[0]) {
+                       case GL_SRC_ALPHA:  
+                            vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Atex;
+                            vmesa->regHTXnTBLRAa_0 = 0x0;
+                            break;
+                        case GL_ONE_MINUS_SRC_ALPHA:
+                            vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Inv | HC_HTXnTBLAbias_Atex;
+                            vmesa->regHTXnTBLRAa_0 = 0x0;
+                            break;
+                        }
+                        break;
+                    case GL_CONSTANT :
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        switch (texUnit1->CombineOperandA[0]) {
+                        case GL_SRC_ALPHA:  
+                            vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_HTXnTBLRAbias;
+                            vmesa->regHTXnTBLRAa_0 = 0x0;
+                            vmesa->regHTXnTBLRFog_0 = a;
+                            break;
+                        case GL_ONE_MINUS_SRC_ALPHA:
+                            vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Inv | HC_HTXnTBLAbias_HTXnTBLRAbias;
+                            vmesa->regHTXnTBLRAa_0 = 0x0;
+                            vmesa->regHTXnTBLRFog_0 = a;
+                            break;
+                        }
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        switch (texUnit1->CombineOperandA[0]) {
+                        case GL_SRC_ALPHA:  
+                            vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                           HC_HTXnTBLAbias_Adif;
+                            vmesa->regHTXnTBLRAa_0 = 0x0;
+                            break;
+                        case GL_ONE_MINUS_SRC_ALPHA:
+                            vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                            HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                            HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                            HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                            vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                            HC_HTXnTBLAbias_Inv | HC_HTXnTBLAbias_Adif;
+                           vmesa->regHTXnTBLRAa_0 = 0x0;
+                            break;
+                       }
+                   break;
+                    }
+                    switch ((GLint)(texUnit1->CombineScaleShiftA)) {
+                    case 1:
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_2;
+                        break;
+                    }
+                    break;
+                case GL_MODULATE:
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                     HC_HTXnTBLAbias_HTXnTBLRAbias;
+                    vmesa->regHTXnTBLRFog_0 = 0x0;
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK | HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                   vmesa->regHTXnTBLRAa_0= 0x0;
+                    switch (texUnit1->CombineOperandA[0]) {
+                    case GL_SRC_ALPHA:
+                       vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_TOPA; 
+                       break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_InvTOPA; 
+                        break;
+                    }
+                    switch (texUnit1->CombineOperandA[1]) {
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_TOPA; 
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_InvTOPA; 
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceA[0]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_Atex; 
+                        break;
+                    case GL_CONSTANT :
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= a<<16;
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_Adif; 
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceA[1]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Atex;
+                        break;
+                    case GL_CONSTANT :
+                       CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= a<<8;
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Adif;
+                        break;
+                    }
+                    switch ((GLint)(texUnit1->CombineScaleShiftA)) {
+                   case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_2;
+                        break;
+                    }
+                    break;
+                case GL_ADD:
+                case GL_SUBTRACT :
+                    if(texUnit1->CombineModeA==GL_ADD) {
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add | HC_HTXnTBLAbias_HTXnTBLRAbias;
+                   }
+                   else {
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Sub | HC_HTXnTBLAbias_HTXnTBLRAbias;
+                    }
+                    vmesa->regHTXnTBLRFog_0 = 0;
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK | HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA;
+                    vmesa->regHTXnTBLRAa_0 = 0x0 |  ( 255<<16 );
+                    switch (texUnit1->CombineOperandA[0]) {
+                    case GL_SRC_ALPHA:
+                       vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_TOPA; 
+                       break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_InvTOPA; 
+                        break;
+                    }
+                   switch (texUnit1->CombineOperandA[1]) {
+                    case GL_SRC_ALPHA:
+                       vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_TOPA;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_InvTOPA;
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceA[0]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Atex;
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= (a << 8);
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Adif;
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceA[1]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_Atex;
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= a;
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_Adif;
+                        break;
+                    }
+                    switch ((GLint)(texUnit1->CombineScaleShiftA)) {
+                    case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_2;
+                        break;
+                    }
+                    break;
+                case GL_ADD_SIGNED :
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Sub;
+                    vmesa->regHTXnTBLRFog_0 = 0x0;
+                    vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                        HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA|
+                        HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                    vmesa->regHTXnTBLRAa_0 = ( 255<<16 | 0<<8 |128 );
+                    switch (texUnit1->CombineOperandA[0]) {
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_TOPA; 
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_InvTOPA; 
+                        break;
+                    }
+                    switch (texUnit1->CombineOperandA[1]) {
+                    case GL_SRC_ALPHA:
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_Inv;
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceA[0]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Atex;
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= (a << 8);
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Adif;
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceA[1]) {
+                   case GL_TEXTURE:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_Atex; 
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_HTXnTBLRAbias; 
+                        vmesa->regHTXnTBLRFog_0 |= a;
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_Adif;
+                        break;
+                    }
+                    switch ((GLint)(texUnit1->CombineScaleShiftA)) {
+                    case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_2;
+                        break;
+                    }
+                    break;
+               case GL_INTERPOLATE :
+                    vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Sub;
+                    vmesa->regHTXnTBLRAa_0 = 0x0;
+                    vmesa->regHTXnTBLRFog_0 =  0x0;
+                    switch (texUnit1->CombineOperandA[0]) {
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAb_TOPA; 
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAb_InvTOPA; 
+                        break;
+                    }
+                    switch (texUnit1->CombineOperandA[1]) {
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAc_TOPA;
+                        break;
+                   case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAc_InvTOPA;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_Inv;
+                        break;
+                    }
+                    switch (texUnit1->CombineOperandA[2]) {
+                    case GL_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAa_TOPA;
+                        break;
+                    case GL_ONE_MINUS_SRC_ALPHA:
+                        vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAa_InvTOPA;
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceA[0]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Atex;
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= (a << 8);
+                        break;
+                    case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAb_Adif;
+                        break;
+                    }
+                    switch (texUnit1->CombineSourceA[1]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_Atex;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_Atex;
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_HTXnTBLRA;
+                       vmesa->regHTXnTBLRAa_0 |= a;
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_HTXnTBLRAbias;
+                        vmesa->regHTXnTBLRFog_0 |= a;
+                        break;
+                   case GL_PRIMARY_COLOR :
+                    case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAc_Adif;
+                       vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_Adif;
+                        break;
+                   }
+                    switch (texUnit1->CombineSourceA[2]) {
+                    case GL_TEXTURE:
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_Atex;
+                        break;
+                    case GL_CONSTANT :
+                        CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[3], a);
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_HTXnTBLRA;
+                        vmesa->regHTXnTBLRAa_0 |= (a << 16);
+                        break;
+                    case GL_PRIMARY_COLOR :
+                   case GL_PREVIOUS :
+                        vmesa->regHTXnTBLAsat_0 |= HC_HTXnTBLAa_Adif;
+                        break;
+                   }
+                    switch (texUnit1->CombineScaleShiftA) {
+                    case 1:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_No;
+                        break;
+                    case 2:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_1;
+                        break;
+                    case 4:
+                        vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAshift_2;
+                        break;
+                    }
+                   break;
+               case GL_DOT3_RGB :
+               case GL_DOT3_RGBA :
+                   break;
+               }
+               break;
+
+       /*=* John Sheng [2003.7.18] texture add *=*/
+        case GL_ADD:
+            switch(texImage->Format) {
+            case GL_ALPHA:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_0 | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Adif | HC_HTXnTBLAb_TOPA |
+                    HC_HTXnTBLAb_Atex | HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                break;
+            case GL_LUMINANCE:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                break;
+            case GL_LUMINANCE_ALPHA:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                break;
+            case GL_INTENSITY:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Atex |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_Adif;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+               /*=* John Sheng [2003.7.18] texenv *=*/
+               /*vmesa->regHTXnTBLRAa_0 = 0x0;*/
+                vmesa->regHTXnTBLRAa_0 = (255<<16) | (255<<8) | 255;;
+                vmesa->regHTXnTBLRFog_0 = 0x0 | 255<<16;
+                break;
+            case GL_RGB:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                break;
+            case GL_RGBA:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                break;
+            case GL_COLOR_INDEX:
+                switch(texObj->Palette.Format) {
+                case GL_ALPHA:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_0 | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Dif |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Adif | HC_HTXnTBLAb_TOPA |
+                    HC_HTXnTBLAb_Atex | HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                break;
+                case GL_LUMINANCE:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                break;
+                case GL_LUMINANCE_ALPHA:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                break;
+                case GL_INTENSITY:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Atex |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_Adif;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0 | 255<<16;
+                break;
+                case GL_RGB:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                break;
+                case GL_RGBA:
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                    HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_HTXnTBLRC | HC_HTXnTBLCb_TOPC |
+                    HC_HTXnTBLCb_Tex | HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_Dif;
+                vmesa->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add |
+                    HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 |
+                    HC_HTXnTBLCshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLRCa_0 = (255<<16) | (255<<8) | 255;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK |
+                    HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex |
+                    HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif |
+                    HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add |
+                    HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                break;
+                }
+                break;
+            }
+            break;
+           /*=* John Sheng [2003.7.18] texture dot3 *=*/
+           case GL_DOT3_RGB :
+           case GL_DOT3_RGBA :
+               vmesa->regHTXnTBLCop_0 = HC_HTXnTBLDOT4 | HC_HTXnTBLCop_Add | 
+                                        HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 | 
+                                         HC_HTXnTBLCshift_2 | HC_HTXnTBLAop_Add |
+                                         HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No;
+                vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+                vmesa->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK |
+                                       HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0;
+                vmesa->regHTXnTBLRFog_0 = 0x0;
+                vmesa->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK | 
+                                       HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA |
+                                       HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA |
+                                       HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA;
+                vmesa->regHTXnTBLRAa_0 = 0x0;
+                switch (texUnit1->CombineOperandRGB[0]) {
+                case GL_SRC_COLOR:
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_TOPC; 
+                   break;
+                case GL_ONE_MINUS_SRC_COLOR:
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_InvTOPC; 
+                    break;
+                }
+                switch (texUnit1->CombineOperandRGB[1]) {
+                case GL_SRC_COLOR:
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_TOPC; 
+                    break;
+                case GL_ONE_MINUS_SRC_COLOR:
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_InvTOPC; 
+                    break;
+                }
+                switch (texUnit1->CombineSourceRGB[0]) {
+                case GL_TEXTURE:
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Tex; 
+                    break;
+                case GL_CONSTANT :
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                   CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                   CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_HTXnTBLRC;
+                    vmesa->regHTXnTBLRCa_0 = (r << 16) | (g << 8) | b;
+                    break;
+               case GL_PRIMARY_COLOR :
+                case GL_PREVIOUS :
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCa_Dif; 
+                    break;
+                }
+                switch (texUnit1->CombineSourceRGB[1]) {
+                case GL_TEXTURE:
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Tex; 
+                    break;
+                case GL_CONSTANT :
+                   CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[0], r);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[1], g);
+                    CLAMPED_FLOAT_TO_UBYTE(texUnit1->EnvColor[2], b);
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_HTXnTBLRC;
+                    vmesa->regHTXnTBLRCb_0 = (r << 16) | (g << 8) | b;
+                    break;
+                case GL_PRIMARY_COLOR :
+                case GL_PREVIOUS :
+                    vmesa->regHTXnTBLCsat_0 |= HC_HTXnTBLCb_Dif; 
+                    break;
+                }
+               break;
+            default:
+                break;
+            }
+        }
+        vmesa->dirty |= VIA_UPLOAD_TEXTURE;
+    }
+    else {
+       if (ctx->Fog.Enabled)
+           vmesa->regCmdB &= (~(HC_HVPMSK_S | HC_HVPMSK_T));   
+       else        
+           vmesa->regCmdB &= (~(HC_HVPMSK_S | HC_HVPMSK_T | HC_HVPMSK_W));
+        vmesa->regEnable &= (~(HC_HenTXMP_MASK | HC_HenTXCH_MASK | HC_HenTXPP_MASK));
+        vmesa->dirty |= VIA_UPLOAD_ENABLE;
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+    
+}
+
+void viaChooseColorState(GLcontext *ctx) 
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    GLenum s = ctx->Color.BlendSrcRGB;
+    GLenum d = ctx->Color.BlendDstRGB;
+
+    /* The HW's blending equation is:
+     * (Ca * FCa + Cbias + Cb * FCb) << Cshift
+     */
+#ifdef DEBUG
+     if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+
+    if (ctx->Color.BlendEnabled) {
+        vmesa->regEnable |= HC_HenABL_MASK;
+        /* Ca  -- always from source color.
+         */
+        vmesa->regHABLCsat = HC_HABLCsat_MASK | HC_HABLCa_OPC |
+                             HC_HABLCa_Csrc;
+        /* Aa  -- always from source alpha.
+         */
+        vmesa->regHABLAsat = HC_HABLAsat_MASK | HC_HABLAa_OPA |
+                             HC_HABLAa_Asrc;
+        /* FCa -- depend on following condition.
+         * FAa -- depend on following condition.
+         */
+        switch (s) {
+        case GL_ZERO:
+            /* (0, 0, 0, 0)
+             */
+            vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_HABLRCa;
+            vmesa->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_HABLFRA;
+            vmesa->regHABLRFCa = 0x0;
+            vmesa->regHABLRAa = 0x0;
+            break;
+        case GL_ONE:
+            /* (1, 1, 1, 1)
+             */
+            vmesa->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_HABLRCa;
+            vmesa->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_HABLFRA;
+            vmesa->regHABLRFCa = 0x0;
+            vmesa->regHABLRAa = 0x0;
+            break;
+        case GL_SRC_COLOR:
+            /* (Rs, Gs, Bs, As)
+             */
+            vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_Csrc;
+            vmesa->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_Asrc;
+            break;
+        case GL_ONE_MINUS_SRC_COLOR:
+            /* (1, 1, 1, 1) - (Rs, Gs, Bs, As)
+             */
+            vmesa->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_Csrc;
+            vmesa->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_Asrc;
+            break;
+        case GL_DST_COLOR:
+            /* (Rd, Gd, Bd, Ad)
+             */
+            vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_Cdst;
+            vmesa->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_Adst;
+            break;
+        case GL_ONE_MINUS_DST_COLOR:
+            /* (1, 1, 1, 1) - (Rd, Gd, Bd, Ad)
+             */
+            vmesa->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_Cdst;
+            vmesa->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_Adst;
+            break;
+        case GL_SRC_ALPHA:
+            /* (As, As, As, As)
+             */
+            vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_Asrc;
+            vmesa->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_Asrc;
+            break;
+        case GL_ONE_MINUS_SRC_ALPHA:
+            /* (1, 1, 1, 1) - (As, As, As, As)
+             */
+            vmesa->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_Asrc;
+            vmesa->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_Asrc;
+            break;
+        case GL_DST_ALPHA:
+            {
+                if (vmesa->viaScreen->bitsPerPixel == 16) {
+                    /* (1, 1, 1, 1)
+                     */
+                    vmesa->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_HABLRCa;
+                    vmesa->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_HABLFRA;
+                    vmesa->regHABLRFCa = 0x0;
+                    vmesa->regHABLRAa = 0x0;
+                }
+                else {
+                    /* (Ad, Ad, Ad, Ad)
+                     */
+                    vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_Adst;
+                    vmesa->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_Adst;
+                }
+            }
+            break;
+        case GL_ONE_MINUS_DST_ALPHA:
+            {
+                if (vmesa->viaScreen->bitsPerPixel == 16) {
+                    /* (1, 1, 1, 1) - (1, 1, 1, 1) = (0, 0, 0, 0)
+                     */
+                    vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_HABLRCa;
+                    vmesa->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_HABLFRA;
+                    vmesa->regHABLRFCa = 0x0;
+                    vmesa->regHABLRAa = 0x0;
+                }
+                else {
+                    /* (1, 1, 1, 1) - (Ad, Ad, Ad, Ad)
+                     */
+                    vmesa->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_Adst;
+                    vmesa->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_Adst;
+                }
+            }
+            break;
+        case GL_SRC_ALPHA_SATURATE:
+            {
+                if (vmesa->viaScreen->bitsPerPixel == 16) {
+                    /* (f, f, f, 1), f = min(As, 1 - Ad) = min(As, 1 - 1) = 0
+                     * So (f, f, f, 1) = (0, 0, 0, 1)
+                     */
+                    vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_HABLRCa;
+                    vmesa->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_HABLFRA;
+                    vmesa->regHABLRFCa = 0x0;
+                    vmesa->regHABLRAa = 0x0;
+                }
+                else {
+                    /* (f, f, f, 1), f = min(As, 1 - Ad)
+                     */
+                    vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_mimAsrcInvAdst;
+                    vmesa->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_HABLFRA;
+                    vmesa->regHABLRFCa = 0x0;
+                    vmesa->regHABLRAa = 0x0;
+                }
+            }
+            break;
+        }
+
+        /* Op is add.
+         */
+
+        /* bias is 0.
+         */
+        vmesa->regHABLCsat |= HC_HABLCbias_HABLRCbias;
+        vmesa->regHABLAsat |= HC_HABLAbias_HABLRAbias;
+
+        /* Cb  -- always from destination color.
+         */
+        vmesa->regHABLCop = HC_HABLCb_OPC | HC_HABLCb_Cdst;
+        /* Ab  -- always from destination alpha.
+         */
+        vmesa->regHABLAop = HC_HABLAb_OPA | HC_HABLAb_Adst;
+        /* FCb -- depend on following condition.
+         */
+        switch (d) {
+        case GL_ZERO:
+            /* (0, 0, 0, 0)
+             */
+            vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_HABLRCb;
+            vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_HABLFRA;
+            vmesa->regHABLRFCb = 0x0;
+            vmesa->regHABLRAb = 0x0;
+            break;
+        case GL_ONE:
+            /* (1, 1, 1, 1)
+             */
+            vmesa->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_HABLRCb;
+            vmesa->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_HABLFRA;
+            vmesa->regHABLRFCb = 0x0;
+            vmesa->regHABLRAb = 0x0;
+            break;
+        case GL_SRC_COLOR:
+            /* (Rs, Gs, Bs, As)
+             */
+            vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_Csrc;
+            vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_Asrc;
+            break;
+        case GL_ONE_MINUS_SRC_COLOR:
+            /* (1, 1, 1, 1) - (Rs, Gs, Bs, As)
+             */
+            vmesa->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_Csrc;
+            vmesa->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_Asrc;
+            break;
+        case GL_DST_COLOR:
+            /* (Rd, Gd, Bd, Ad)
+             */
+            vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_Cdst;
+            vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_Adst;
+            break;
+        case GL_ONE_MINUS_DST_COLOR:
+            /* (1, 1, 1, 1) - (Rd, Gd, Bd, Ad)
+             */
+            vmesa->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_Cdst;
+            vmesa->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_Adst;
+            break;
+        case GL_SRC_ALPHA:
+            /* (As, As, As, As)
+             */
+            vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_Asrc;
+            vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_Asrc;
+            break;
+        case GL_ONE_MINUS_SRC_ALPHA:
+            /* (1, 1, 1, 1) - (As, As, As, As)
+             */
+            vmesa->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_Asrc;
+            vmesa->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_Asrc;
+            break;
+        case GL_DST_ALPHA:
+            {
+                if (vmesa->viaScreen->bitsPerPixel == 16) {
+                    /* (1, 1, 1, 1)
+                     */
+                    vmesa->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_HABLRCb;
+                    vmesa->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_HABLFRA;
+                    vmesa->regHABLRFCb = 0x0;
+                    vmesa->regHABLRAb = 0x0;
+                }
+                else {
+                    /* (Ad, Ad, Ad, Ad)
+                     */
+                    vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_Adst;
+                    vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_Adst;
+                }
+            }
+            break;
+        case GL_ONE_MINUS_DST_ALPHA:
+            {
+                if (vmesa->viaScreen->bitsPerPixel == 16) {
+                    /* (1, 1, 1, 1) - (1, 1, 1, 1) = (0, 0, 0, 0)
+                     */
+                    vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_HABLRCb;
+                    vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_HABLFRA;
+                    vmesa->regHABLRFCb = 0x0;
+                    vmesa->regHABLRAb = 0x0;
+                }
+                else {
+                    /* (1, 1, 1, 1) - (Ad, Ad, Ad, Ad)
+                     */
+                    vmesa->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_Adst;
+                    vmesa->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_Adst;
+                }
+            }
+            break;
+        default:
+            vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_HABLRCb;
+            vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_HABLFRA;
+            vmesa->regHABLRFCb = 0x0;
+            vmesa->regHABLRAb = 0x0;
+            break;
+        }
+
+        if (vmesa->viaScreen->bitsPerPixel <= 16)
+            vmesa->regEnable &= ~HC_HenDT_MASK;
+
+        vmesa->dirty |= (VIA_UPLOAD_BLEND | VIA_UPLOAD_ENABLE);
+    }
+    else {
+        vmesa->regEnable &= (~HC_HenABL_MASK);
+        vmesa->dirty |= VIA_UPLOAD_ENABLE;
+    }
+
+    if (ctx->Color.AlphaEnabled) {
+        vmesa->regEnable |= HC_HenAT_MASK;
+        vmesa->regHATMD = (((GLchan)ctx->Color.AlphaRef) & 0xFF) |
+            ((ctx->Color.AlphaFunc - GL_NEVER) << 8);
+        vmesa->dirty |= (VIA_UPLOAD_ALPHATEST | VIA_UPLOAD_ENABLE);
+    }
+    else {
+        vmesa->regEnable &= (~HC_HenAT_MASK);
+        vmesa->dirty |= VIA_UPLOAD_ENABLE;
+    }
+
+    if (ctx->Color.DitherFlag && (vmesa->viaScreen->bitsPerPixel < 32)) {
+        if (ctx->Color.BlendEnabled) {
+            vmesa->regEnable &= ~HC_HenDT_MASK;
+        }
+        else {
+            vmesa->regEnable |= HC_HenDT_MASK;
+        }
+        vmesa->dirty |= VIA_UPLOAD_ENABLE;
+    }
+
+    if (ctx->Color.ColorLogicOpEnabled) 
+        vmesa->regHROP = ROP[ctx->Color.LogicOp & 0xF];
+    else
+        vmesa->regHROP = HC_HROP_P;
+
+    vmesa->regHFBBMSKL = (*(GLuint *)&ctx->Color.ColorMask[0]) & 0xFFFFFF;
+    vmesa->regHROP |= ((*(GLuint *)&ctx->Color.ColorMask[0]) >> 24) & 0xFF;
+    vmesa->dirty |= VIA_UPLOAD_MASK_ROP;
+
+    if ((GLuint)((GLuint *)&ctx->Color.ColorMask[0]) & 0xFF000000)
+        vmesa->regEnable |= HC_HenAW_MASK;
+    else
+        vmesa->regEnable &= (~HC_HenAW_MASK);
+    vmesa->dirty |= VIA_UPLOAD_ENABLE;  
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+void viaChooseFogState(GLcontext *ctx) 
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+
+    if (ctx->Fog.Enabled) {
+        GLubyte r, g, b, a;
+
+        vmesa->regCmdB |= (HC_HVPMSK_Cd | HC_HVPMSK_Cs | HC_HVPMSK_W);
+        vmesa->regEnable |= HC_HenFOG_MASK;
+
+        /* Use fog equation 0 (OpenGL's default) & local fog.
+         */
+        vmesa->regHFogLF = 0x0;
+
+        r = (GLubyte)(ctx->Fog.Color[0] * 255.0F);
+        g = (GLubyte)(ctx->Fog.Color[1] * 255.0F);
+        b = (GLubyte)(ctx->Fog.Color[2] * 255.0F);
+        a = (GLubyte)(ctx->Fog.Color[3] * 255.0F);
+        vmesa->regHFogCL = (r << 16) | (g << 8) | b;
+        vmesa->regHFogCH = a;
+        vmesa->dirty |= (VIA_UPLOAD_FOG | VIA_UPLOAD_ENABLE);
+    }
+    else {
+       if((!ctx->Texture.Unit[0]._ReallyEnabled) &&
+          (!ctx->Texture.Unit[1]._ReallyEnabled)) {
+            vmesa->regCmdB &= ~ HC_HVPMSK_W;
+           vmesa->regCmdB &= ~ HC_HVPMSK_Cs;
+       }           
+        vmesa->regEnable &= ~HC_HenFOG_MASK;
+        vmesa->dirty |= VIA_UPLOAD_ENABLE;
+    }
+}
+
+void viaChooseDepthState(GLcontext *ctx) 
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    if (ctx->Depth.Test) {
+        vmesa->regCmdB |= HC_HVPMSK_Z;
+        vmesa->regEnable |= HC_HenZT_MASK;
+        if (ctx->Depth.Mask)
+            vmesa->regEnable |= HC_HenZW_MASK;
+        else
+            vmesa->regEnable &= (~HC_HenZW_MASK);
+       vmesa->regHZWTMD = (ctx->Depth.Func - GL_NEVER) << 16;
+        vmesa->dirty |= (VIA_UPLOAD_DEPTH | VIA_UPLOAD_ENABLE);
+       
+    }
+    else {
+        /* Still need to send parameter Z.
+         */
+        
+       vmesa->regCmdB |= HC_HVPMSK_Z;
+        vmesa->regEnable &= ~HC_HenZT_MASK;
+        
+        /*=* [DBG] racer : can't display cars in car selection menu *=*/
+       /*if (ctx->Depth.Mask)
+            vmesa->regEnable |= HC_HenZW_MASK;
+        else
+            vmesa->regEnable &= (~HC_HenZW_MASK);*/
+       vmesa->regEnable &= (~HC_HenZW_MASK);
+
+        vmesa->dirty |= VIA_UPLOAD_ENABLE;                  
+    }
+}
+
+void viaChooseLightState(GLcontext *ctx) 
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+
+    if (ctx->Light.ShadeModel == GL_SMOOTH) {
+        vmesa->regCmdA |= HC_HShading_Gouraud;
+        vmesa->regCmdB |= HC_HVPMSK_Cd;
+    }
+    else {
+        vmesa->regCmdA &= ~HC_HShading_Gouraud;
+        vmesa->regCmdB |= HC_HVPMSK_Cd;
+    }
+}
+
+void viaChooseLineState(GLcontext *ctx) 
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+
+    if (ctx->Line.SmoothFlag) {
+        vmesa->regEnable |= HC_HenAA_MASK;
+    }
+    else {
+        if (!ctx->Polygon.SmoothFlag) {
+            vmesa->regEnable &= ~HC_HenAA_MASK;
+        }
+    }
+
+    if (ctx->Line.StippleFlag) {
+        vmesa->regEnable |= HC_HenLP_MASK;
+        vmesa->regHLP = ctx->Line.StipplePattern;
+        vmesa->regHLPRF = ctx->Line.StippleFactor;
+        vmesa->dirty |= VIA_UPLOAD_LINESTIPPLE;
+    }
+    else {
+        vmesa->regEnable &= ~HC_HenLP_MASK;
+    }
+    vmesa->dirty |= VIA_UPLOAD_ENABLE;
+}
+
+void viaChoosePolygonState(GLcontext *ctx) 
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+
+    if (ctx->Polygon.SmoothFlag) {
+        vmesa->regEnable |= HC_HenAA_MASK;
+    }
+    else {
+        if (!ctx->Line.SmoothFlag) {
+            vmesa->regEnable &= ~HC_HenAA_MASK;
+        }
+    }
+
+    if (ctx->Polygon.StippleFlag) {
+        vmesa->regEnable |= HC_HenSP_MASK;
+        vmesa->dirty |= VIA_UPLOAD_POLYGONSTIPPLE;
+    }
+    else {
+        vmesa->regEnable &= ~HC_HenSP_MASK;
+    }
+
+    if (ctx->Polygon.CullFlag) {
+        vmesa->regEnable |= HC_HenFBCull_MASK;
+    }
+    else {
+        vmesa->regEnable &= ~HC_HenFBCull_MASK;
+    }
+    vmesa->dirty |= VIA_UPLOAD_ENABLE;
+}
+
+void viaChooseStencilState(GLcontext *ctx) 
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+    
+    if (ctx->Stencil.Enabled) {
+        GLuint temp;
+
+        vmesa->regEnable |= HC_HenST_MASK;
+        temp = (ctx->Stencil.Ref[0] & 0xFF) << HC_HSTREF_SHIFT;
+        temp |= 0xFF << HC_HSTOPMSK_SHIFT;
+        temp |= (ctx->Stencil.ValueMask[0] & 0xFF);
+        vmesa->regHSTREF = temp;
+
+        temp = (ctx->Stencil.Function[0] - GL_NEVER) << 16;
+
+        switch (ctx->Stencil.FailFunc[0]) {
+        case GL_KEEP:
+            temp |= HC_HSTOPSF_KEEP;
+            break;
+        case GL_ZERO:
+            temp |= HC_HSTOPSF_ZERO;
+            break;
+        case GL_REPLACE:
+            temp |= HC_HSTOPSF_REPLACE;
+            break;
+        case GL_INVERT:
+            temp |= HC_HSTOPSF_INVERT;
+            break;
+        case GL_INCR:
+            temp |= HC_HSTOPSF_INCR;
+            break;
+        case GL_DECR:
+            temp |= HC_HSTOPSF_DECR;
+            break;
+        }
+
+        switch (ctx->Stencil.ZFailFunc[0]) {
+        case GL_KEEP:
+            temp |= HC_HSTOPSPZF_KEEP;
+            break;
+        case GL_ZERO:
+            temp |= HC_HSTOPSPZF_ZERO;
+            break;
+        case GL_REPLACE:
+            temp |= HC_HSTOPSPZF_REPLACE;
+            break;
+        case GL_INVERT:
+            temp |= HC_HSTOPSPZF_INVERT;
+            break;
+        case GL_INCR:
+            temp |= HC_HSTOPSPZF_INCR;
+            break;
+        case GL_DECR:
+            temp |= HC_HSTOPSPZF_DECR;
+            break;
+        }
+
+        switch (ctx->Stencil.ZPassFunc[0]) {
+        case GL_KEEP:
+            temp |= HC_HSTOPSPZP_KEEP;
+            break;
+        case GL_ZERO:
+            temp |= HC_HSTOPSPZP_ZERO;
+            break;
+        case GL_REPLACE:
+            temp |= HC_HSTOPSPZP_REPLACE;
+            break;
+        case GL_INVERT:
+            temp |= HC_HSTOPSPZP_INVERT;
+            break;
+        case GL_INCR:
+            temp |= HC_HSTOPSPZP_INCR;
+            break;
+        case GL_DECR:
+            temp |= HC_HSTOPSPZP_DECR;
+            break;
+        }
+        vmesa->regHSTMD = temp;
+
+        vmesa->dirty |= (VIA_UPLOAD_STENCIL | VIA_UPLOAD_STENCIL);
+    }
+    else {
+        vmesa->regEnable &= ~HC_HenST_MASK;
+        vmesa->dirty |= VIA_UPLOAD_ENABLE;
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+void viaChoosePoint(GLcontext *ctx) 
+{
+    ctx = ctx;
+}
+
+void viaChooseLine(GLcontext *ctx) 
+{
+    ctx = ctx;
+}
+
+void viaChooseTriangle(GLcontext *ctx) 
+{       
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+    
+    if (VIA_DEBUG) fprintf(stderr, "GL_CULL_FACE = %x\n", GL_CULL_FACE);    
+    if (VIA_DEBUG) fprintf(stderr, "ctx->Polygon.CullFlag = %x\n", ctx->Polygon.CullFlag);    
+    
+    if (VIA_DEBUG) fprintf(stderr, "GL_FRONT = %x\n", GL_FRONT);    
+    if (VIA_DEBUG) fprintf(stderr, "ctx->Polygon.CullFaceMode = %x\n", ctx->Polygon.CullFaceMode);    
+    if (VIA_DEBUG) fprintf(stderr, "GL_CCW = %x\n", GL_CCW);    
+    if (VIA_DEBUG) fprintf(stderr, "ctx->Polygon.FrontFace = %x\n", ctx->Polygon.FrontFace);    
+#endif
+    if (ctx->Polygon.CullFlag == GL_TRUE) {
+        switch (ctx->Polygon.CullFaceMode) {
+        case GL_FRONT:
+            if (ctx->Polygon.FrontFace == GL_CCW)
+                vmesa->regCmdB |= HC_HBFace_MASK;
+            else
+                vmesa->regCmdB &= ~HC_HBFace_MASK;
+            break;
+        case GL_BACK:
+            if (ctx->Polygon.FrontFace == GL_CW)
+                vmesa->regCmdB |= HC_HBFace_MASK;
+            else
+                vmesa->regCmdB &= ~HC_HBFace_MASK;
+            break;
+        case GL_FRONT_AND_BACK:
+            return;
+        }
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+static void viaChooseState(GLcontext *ctx, GLuint newState)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    struct gl_texture_unit *texUnit0 = &ctx->Texture.Unit[0];
+    struct gl_texture_unit *texUnit1 = &ctx->Texture.Unit[1];
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+    
+    if (VIA_DEBUG) fprintf(stderr, "newState = %x\n", newState);        
+#endif    
+    if (!(newState & (_NEW_COLOR |
+                      _NEW_TEXTURE |
+                      _NEW_DEPTH |
+                      _NEW_FOG |
+                      _NEW_LIGHT |
+                      _NEW_LINE |
+                      _NEW_POLYGON |
+                      _NEW_POLYGONSTIPPLE |
+                      _NEW_STENCIL)))
+        return;
+
+    vmesa->dirty = 0;
+    vmesa->newState = newState;
+
+    if (texUnit0->_ReallyEnabled || texUnit1->_ReallyEnabled || ctx->Fog.Enabled) {
+       vmesa->regCmdB |= HC_HVPMSK_Cs;
+    }
+    else {
+       vmesa->regCmdB &= ~ HC_HVPMSK_Cs;
+    }
+    
+    if (newState & _NEW_TEXTURE)
+        viaChooseTextureState(ctx);
+
+    if (newState & _NEW_COLOR)
+        viaChooseColorState(ctx);
+
+    if (newState & _NEW_DEPTH)
+        viaChooseDepthState(ctx);
+
+    if (newState & _NEW_FOG)
+        viaChooseFogState(ctx);
+
+    if (newState & _NEW_LIGHT)
+        viaChooseLightState(ctx);
+
+    if (newState & _NEW_LINE)
+        viaChooseLineState(ctx);
+
+    if (newState & (_NEW_POLYGON | _NEW_POLYGONSTIPPLE))
+        viaChoosePolygonState(ctx);
+
+    if (newState & _NEW_STENCIL)
+        viaChooseStencilState(ctx);
+    
+    viaChooseTriangle(ctx);
+            
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);        
+#endif
+}
+
+static void viaInvalidateState(GLcontext *ctx, GLuint newState)
+{
+    _swrast_InvalidateState(ctx, newState);
+    _swsetup_InvalidateState(ctx, newState);
+    _ac_InvalidateState(ctx, newState);
+    _tnl_InvalidateState(ctx, newState);
+    viaChooseState(ctx, newState);
+}
+
+void viaInitStateFuncs(GLcontext *ctx)
+{
+    /* Callbacks for internal Mesa events.
+     */
+    ctx->Driver.UpdateState = viaInvalidateState;
+
+    /* API callbacks
+     */
+    ctx->Driver.AlphaFunc = viaAlphaFunc;
+    ctx->Driver.BlendEquation = viaBlendEquation;
+    //ctx->Driver.BlendFunc = viaBlendFunc;
+    ctx->Driver.BlendFuncSeparate = viaBlendFuncSeparate;
+    ctx->Driver.ClearColor = viaClearColor;
+    ctx->Driver.ColorMask = viaColorMask;
+    ctx->Driver.CullFace = viaCullFaceFrontFace;
+    ctx->Driver.DepthFunc = viaDepthFunc;
+    ctx->Driver.DepthMask = viaDepthMask;
+    ctx->Driver.DrawBuffer = viaDrawBuffer;
+    ctx->Driver.Enable = viaEnable;
+    ctx->Driver.Fogfv = viaFogfv;
+    ctx->Driver.FrontFace = viaCullFaceFrontFace;
+    ctx->Driver.LineWidth = viaLineWidth;
+    ctx->Driver.LogicOpcode = viaLogicOp;
+    ctx->Driver.PolygonStipple = viaPolygonStipple;
+    ctx->Driver.RenderMode = viaRenderMode;
+    ctx->Driver.Scissor = viaScissor;
+    ctx->Driver.ShadeModel = viaShadeModel;
+    ctx->Driver.DepthRange = viaDepthRange;
+    ctx->Driver.Viewport = viaViewport;
+    ctx->Driver.PointSize = viaPointSize;
+    ctx->Driver.LightModelfv = viaLightModelfv;
+
+    /* Pixel path fallbacks.
+     */
+    ctx->Driver.Accum = _swrast_Accum;
+    ctx->Driver.Bitmap = viaBitmap;
+    
+    ctx->Driver.CopyPixels = _swrast_CopyPixels;
+    ctx->Driver.DrawPixels = _swrast_DrawPixels;
+    ctx->Driver.ReadPixels = _swrast_ReadPixels;
+    ctx->Driver.ResizeBuffers = viaReAllocateBuffers;
+
+    /* 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/unichrome/via_state.h b/src/mesa/drivers/dri/unichrome/via_state.h
new file mode 100644 (file)
index 0000000..76d81c2
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _VIA_STATE_H
+#define _VIA_STATE_H
+
+#include "via_context.h"
+
+extern void viaInitState(GLcontext *ctx);
+extern void viaInitStateFuncs(GLcontext *ctx);
+extern void viaPrintDirty(const char *msg, GLuint state);
+extern void viaChooseTextureState(GLcontext *ctx);
+extern void viaChooseColorState(GLcontext *ctx);
+extern void viaChooseDepthState(GLcontext *ctx);
+extern void viaChoosePolygonState(GLcontext *ctx);
+extern void viaChoosePoint(GLcontext *ctx);
+extern void viaChooseLine(GLcontext *ctx);
+extern void viaChooseTriangle(GLcontext *ctx);
+extern void viaChooseFogState(GLcontext *ctx);
+extern void viaChooseStencilState(GLcontext *ctx);
+extern void viaChooseLightState(GLcontext *ctx);
+extern void viaChooseLineState(GLcontext *ctx);
+
+extern void viaFallback(viaContextPtr vmesa, GLuint bit, GLboolean mode);
+#define FALLBACK(vmesa, bit, mode) viaFallback(vmesa, bit, mode)
+
+#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_tex.c b/src/mesa/drivers/dri/unichrome/via_tex.c
new file mode 100644 (file)
index 0000000..326fa93
--- /dev/null
@@ -0,0 +1,432 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "glheader.h"
+/*#include "mem.h" _SOLO */
+#include "mtypes.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "teximage.h"
+#include "texobj.h"
+#include "texstore.h"
+#include "texformat.h"
+#include "swrast/swrast.h"
+#include "context.h"
+#include "via_context.h"
+#include "via_tex.h"
+#include "via_state.h"
+#include "via_ioctl.h"
+
+
+/*
+ * Compute the 'S2.4' lod bias factor from the floating point OpenGL bias.
+ */
+/* 
+static GLuint viaComputeLodBias(GLfloat bias)
+{
+    int b = (int)(bias * 16.0) + 12;
+    if (b > 63)
+        b = 63;
+    else if (b < -64)
+        b = -64;
+    return (GLuint)(b & MLC_LOD_BIAS_MASK);
+}
+*/
+
+viaTextureObjectPtr viaAllocTextureObject(struct gl_texture_object *texObj)
+{
+    viaTextureObjectPtr t;
+
+    t = (viaTextureObjectPtr)CALLOC_STRUCT(via_texture_object_t);
+    if (!t)
+        return NULL;
+
+    /* Initialize non-image-dependent parts of the state:
+     */
+    t->bufAddr = NULL;
+    t->dirtyImages = ~0;
+    t->actualLevel = 0;
+    t->globj = texObj;
+    make_empty_list(t);
+
+    return t;
+}
+
+static void viaTexParameter(GLcontext *ctx, GLenum target,
+                            struct gl_texture_object *texObj,
+                            GLenum pname, const GLfloat *params)
+{
+    viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
+    if (!t)
+        return;
+
+    if (target != GL_TEXTURE_2D)
+        return;
+}
+
+static void viaTexEnv(GLcontext *ctx, GLenum target,
+                      GLenum pname, const GLfloat *param)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    vmesa = vmesa;
+} 
+
+static void viaTexImage1D(GLcontext *ctx, GLenum target, GLint level,
+                          GLint internalFormat,
+                          GLint width, 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)
+{
+    viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "viaTexImage1D - in\n");
+#endif
+    if (t) {
+        if (level == 0) {
+           viaSwapOutTexObj(VIA_CONTEXT(ctx), t);
+           t->actualLevel = 0;
+       }
+       else
+           t->actualLevel++;
+    }
+    else {
+               t = viaAllocTextureObject(texObj);
+       if (!t) {
+               _mesa_error(ctx, GL_OUT_OF_MEMORY, "viaTexImage1D");
+            return;
+        }
+        texObj->DriverData = t;
+    }
+    _mesa_store_teximage1d(ctx, target, level, internalFormat,
+                           width, border, format, type,
+                           pixels, packing, texObj, texImage);
+#ifdef DEBUG                      
+    if (VIA_DEBUG) fprintf(stderr, "viaTexImage1D - out\n");
+#endif
+}
+static void viaTexSubImage1D(GLcontext *ctx,
+                             GLenum target,
+                             GLint level,
+                             GLint xoffset,
+                             GLsizei width,
+                             GLenum format, GLenum type,
+                             const GLvoid *pixels,
+                             const struct gl_pixelstore_attrib *packing,
+                             struct gl_texture_object *texObj,
+                             struct gl_texture_image *texImage)
+
+{
+    viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
+    
+    if (t) {
+        viaSwapOutTexObj(VIA_CONTEXT(ctx), t);
+    }
+    _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
+                             format, type, pixels, packing, texObj,
+                              texImage);
+
+}
+
+
+static void viaTexImage2D(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)
+{
+    viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "viaTexImage2D - in\n");
+#endif    
+    if (t) {
+        if (level == 0) {
+           viaSwapOutTexObj(VIA_CONTEXT(ctx), t);
+           t->actualLevel = 0;
+       }
+       else
+           t->actualLevel++;
+    }
+    else {
+               t = viaAllocTextureObject(texObj);
+       if (!t) {
+               _mesa_error(ctx, GL_OUT_OF_MEMORY, "viaTexImage2D");
+            return;
+        }
+        texObj->DriverData = t;
+    }
+    _mesa_store_teximage2d(ctx, target, level, internalFormat,
+                           width, height, border, format, type,
+                           pixels, packing, texObj, texImage);
+#ifdef DEBUG                      
+    if (VIA_DEBUG) fprintf(stderr, "viaTexImage2D - out\n");
+#endif
+}
+
+static void viaTexSubImage2D(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)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    
+    viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
+    
+    if (t) {
+        viaSwapOutTexObj(VIA_CONTEXT(ctx), t);
+    }
+    _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
+                              height, format, type, pixels, packing, texObj,
+                              texImage);
+
+    if(vmesa->shareCtx)
+       vmesa->shareCtx->NewState |= _NEW_TEXTURE;
+
+}
+
+static void viaBindTexture(GLcontext *ctx, GLenum target,
+                           struct gl_texture_object *texObj)
+{
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "viaBindTexture - in\n");
+#endif
+    if (target == GL_TEXTURE_2D) {
+        viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
+
+        if (!t) {
+
+            t = viaAllocTextureObject(texObj);
+           if (!t) {
+                   _mesa_error(ctx, GL_OUT_OF_MEMORY, "viaBindTexture");
+                return;
+            }
+            texObj->DriverData = t;
+        }
+    }
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "viaBindTexture - out\n");
+#endif
+}
+
+static void viaDeleteTexture(GLcontext *ctx, struct gl_texture_object *texObj)
+{
+    viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "viaDeleteTexture - in\n");    
+#endif
+    if (t) {
+        viaContextPtr vmesa = VIA_CONTEXT(ctx);
+        if (vmesa) {
+           /*=* John Sheng [2003.7.18] viewperf frames/sec *=*/
+           /*VIA_FIREVERTICES(vmesa);*/
+           if (vmesa->dma[0].map) { /* imply vmesa is not under destroying */
+               VIA_FIREVERTICES(vmesa);
+           }
+           viaDestroyTexObj(vmesa, t);
+       }
+        texObj->DriverData = 0;
+    }
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "viaDeleteTexture - out\n");    
+#endif
+}
+
+static GLboolean viaIsTextureResident(GLcontext *ctx,
+                                      struct gl_texture_object *texObj)
+{
+    viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
+
+    return t && t->bufAddr;
+}
+
+static const struct gl_texture_format *
+viaChooseTexFormat(GLcontext *ctx, GLint internalFormat,
+                  GLenum format, GLenum type)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    (void)format;
+    (void)type;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);    
+    if (VIA_DEBUG) fprintf(stderr, "internalFormat:%d format:%d\n", internalFormat, format);    
+#endif    
+    switch (internalFormat) {
+    case 1:
+    case GL_LUMINANCE:
+    case GL_LUMINANCE4:    
+    case GL_LUMINANCE8:    
+    case GL_LUMINANCE12:    
+    case GL_LUMINANCE16:    
+        return &_mesa_texformat_l8;
+    case 2:
+    case GL_LUMINANCE_ALPHA:    
+    case GL_LUMINANCE4_ALPHA4:        
+    case GL_LUMINANCE6_ALPHA2:    
+    case GL_LUMINANCE8_ALPHA8:    
+    case GL_LUMINANCE12_ALPHA4:    
+    case GL_LUMINANCE12_ALPHA12:
+    case GL_LUMINANCE16_ALPHA16:        
+        return &_mesa_texformat_al88;
+    case GL_R3_G3_B2:  
+    case GL_RGB4:    
+    case GL_RGB5:
+#ifdef DEBUG    
+       if (VIA_DEBUG) fprintf(stderr, "2 &_mesa_texformat_arg565\n");    
+#endif
+        return &_mesa_texformat_rgb565;    
+    case 3:
+    case GL_RGB:
+    case GL_RGB8:    
+    case GL_RGB10:
+    case GL_RGB12:    
+    case GL_RGB16:
+       if (vmesa->viaScreen->bitsPerPixel == 0x20) {
+#ifdef DEBUG    
+           if (VIA_DEBUG) fprintf(stderr,"3 argb8888\n");
+#endif
+           return &_mesa_texformat_argb8888;
+       }           
+       else {
+#ifdef DEBUG    
+           if (VIA_DEBUG) fprintf(stderr,"3 rgb565\n");        
+#endif
+            return &_mesa_texformat_rgb565;
+       }
+    case 4:
+       if (vmesa->viaScreen->bitsPerPixel == 0x20) {
+#ifdef DEBUG    
+           if (VIA_DEBUG) fprintf(stderr, "4 &_mesa_texformat_argb8888\n");
+#endif
+           return &_mesa_texformat_argb8888;
+       }
+       else {
+#ifdef DEBUG    
+           if (VIA_DEBUG) fprintf(stderr, "4 &_mesa_texformat_argb4444\n");
+#endif
+           return &_mesa_texformat_argb4444;               
+       }
+    case GL_RGBA2:    
+    case GL_RGBA4:         
+#ifdef DEBUG
+       if (VIA_DEBUG) fprintf(stderr, "GL_RGBA4 &_mesa_texformat_argb4444\n");    
+#endif
+        return &_mesa_texformat_argb4444;
+
+    case GL_RGB5_A1:
+#ifdef DEBUG
+       if (VIA_DEBUG) fprintf(stderr, "GL_RGB5_A1 &_mesa_texformat_argb1555\n");
+#endif
+        return &_mesa_texformat_argb1555;    
+    case GL_RGBA:
+    case GL_RGBA8:
+    case GL_RGBA12:
+    case GL_RGBA16:    
+    case GL_RGB10_A2:
+#ifdef DEBUG
+       if (VIA_DEBUG) fprintf(stderr, "GL_RGBA &_mesa_texformat_argb8888\n");
+#endif
+        return &_mesa_texformat_argb8888;
+    case GL_ALPHA:     
+    case GL_ALPHA4:            
+    case GL_ALPHA8:            
+    case GL_ALPHA12:
+    case GL_ALPHA16:    
+        return &_mesa_texformat_a8;    
+    case GL_INTENSITY:
+    case GL_INTENSITY4:        
+    case GL_INTENSITY8:        
+    case GL_INTENSITY12:
+    case GL_INTENSITY16:    
+        return &_mesa_texformat_i8;
+    case GL_COLOR_INDEX:       
+    case GL_COLOR_INDEX1_EXT:  
+    case GL_COLOR_INDEX2_EXT:  
+    case GL_COLOR_INDEX4_EXT:  
+    case GL_COLOR_INDEX8_EXT:  
+    case GL_COLOR_INDEX12_EXT:     
+    case GL_COLOR_INDEX16_EXT:
+        return &_mesa_texformat_ci8;    
+    default:
+        _mesa_problem(ctx, "unexpected format in viaChooseTextureFormat");
+        return NULL;
+    }  
+}                 
+
+void viaInitTextureFuncs(struct dd_function_table * functions)
+{
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "viaInitTextureFuncs - in\n");
+#endif    
+    functions->TexEnv = viaTexEnv;
+    functions->ChooseTextureFormat = viaChooseTexFormat;
+    functions->TexImage1D = viaTexImage1D;
+    functions->TexImage2D = viaTexImage2D;
+    functions->TexImage3D = _mesa_store_teximage3d;
+    functions->TexSubImage1D = viaTexSubImage1D;
+    functions->TexSubImage2D = viaTexSubImage2D;
+    functions->TexSubImage3D = _mesa_store_texsubimage3d;
+    functions->CopyTexImage1D = _swrast_copy_teximage1d;
+    functions->CopyTexImage2D = _swrast_copy_teximage2d;
+    functions->CopyTexSubImage1D = _swrast_copy_texsubimage1d;
+    functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+    functions->CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+
+    functions->NewTextureObject = _mesa_new_texture_object;
+    functions->BindTexture = viaBindTexture;
+    functions->DeleteTexture = viaDeleteTexture;
+    functions->TexParameter = viaTexParameter;
+    functions->UpdateTexturePalette = 0;
+    functions->IsTextureResident = viaIsTextureResident;
+    functions->TestProxyTexImage = _mesa_test_proxy_teximage;
+
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "viaInitTextureFuncs - out\n");
+#endif
+}
+
+void viaInitTextures(GLcontext *ctx)
+{
+    GLuint tmp = ctx->Texture.CurrentUnit;
+    ctx->Texture.CurrentUnit = 0;
+    viaBindTexture(ctx, GL_TEXTURE_1D, ctx->Texture.Unit[0].Current1D);
+    viaBindTexture(ctx, GL_TEXTURE_2D, ctx->Texture.Unit[0].Current2D);
+    ctx->Texture.CurrentUnit = 1;
+    viaBindTexture(ctx, GL_TEXTURE_1D, ctx->Texture.Unit[1].Current1D);
+    viaBindTexture(ctx, GL_TEXTURE_2D, ctx->Texture.Unit[1].Current2D);
+    ctx->Texture.CurrentUnit = tmp;
+}
diff --git a/src/mesa/drivers/dri/unichrome/via_tex.h b/src/mesa/drivers/dri/unichrome/via_tex.h
new file mode 100644 (file)
index 0000000..e8710b5
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _VIATEX_H
+#define _VIATEX_H
+
+#include "mtypes.h"
+/*#include "mmath.h"*/
+#include "mm.h"
+
+#include "via_context.h"
+#include "via_3d_reg.h"
+
+#define VIA_TEX_MAXLEVELS      10
+
+
+/* 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 via_texture_object_t {
+    struct via_texture_object_t *next, *prev;
+
+    GLuint age;
+    struct gl_texture_object *globj;
+
+    int texelBytes;
+    int totalSize;
+
+    struct {
+       GLuint index;
+       GLuint offset;
+       GLuint size;
+    } texMem;
+    unsigned char* bufAddr;
+    
+    GLuint inAGP;
+    GLuint needClearCache;    
+    GLuint actualLevel;
+
+    GLuint maxLevel;
+    GLuint dirtyImages;
+
+    struct {
+        const struct gl_texture_image *image;
+        int offset;               /* into bufAddr */
+        int height;
+        int internalFormat;
+    } image[VIA_TEX_MAXLEVELS];
+
+    GLuint dirty;
+    
+    GLuint regTexFM;
+    GLuint regTexWidthLog2[2];
+    GLuint regTexHeightLog2[2];
+    GLuint regTexBaseH[4];
+    struct {
+       GLuint baseL;
+       GLuint pitchLog2;
+    } regTexBaseAndPitch[12];
+
+    GLint firstLevel, lastLevel;  /* upload tObj->Image[first .. lastLevel] */
+};              
+
+viaTextureObjectPtr viaAllocTextureObject(struct gl_texture_object *texObj);
+void viaUpdateTextureState(GLcontext *ctx);
+void viaInitTextureFuncs(struct dd_function_table * functions);
+void viaInitTextures(GLcontext *ctx);
+
+void viaDestroyTexObj(viaContextPtr vmesa, viaTextureObjectPtr t);
+void viaSwapOutTexObj(viaContextPtr vmesa, viaTextureObjectPtr t);
+void viaUploadTexImages(viaContextPtr vmesa, viaTextureObjectPtr t);
+
+void viaResetGlobalLRU(viaContextPtr vmesa);
+void viaTexturesGone(viaContextPtr vmesa,
+                     GLuint start, GLuint end,
+                     GLuint in_use);
+
+void viaPrintLocalLRU(viaContextPtr vmesa);
+void viaPrintGlobalLRU(viaContextPtr vmesa);
+void viaUpdateTexLRU(viaContextPtr vmesa, viaTextureObjectPtr t);
+
+#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_texmem.c b/src/mesa/drivers/dri/unichrome/via_texmem.c
new file mode 100644 (file)
index 0000000..f1f6b75
--- /dev/null
@@ -0,0 +1,499 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "texformat.h"
+
+#include "mm.h"
+#include "via_context.h"
+#include "via_tex.h"
+#include "via_state.h"
+#include "via_ioctl.h"
+#include "via_fb.h"
+/*=* John Sheng [2003.5.31]  agp tex *=*/
+GLuint agpFullCount = 0;
+
+void viaDestroyTexObj(viaContextPtr vmesa, viaTextureObjectPtr t)
+{
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif    
+    if (!t) 
+       return;
+
+    /* This is sad - need to sync *in case* we upload a texture
+     * to this newly free memory...
+     */
+    if (t->bufAddr) {
+       via_free_texture(vmesa, t);
+
+        if (vmesa && t->age > vmesa->dirtyAge)
+            vmesa->dirtyAge = t->age;
+    }
+
+    if (t->globj)
+        t->globj->DriverData = 0;
+
+    if (vmesa) {
+        if (vmesa->CurrentTexObj[0] == t) {
+            vmesa->CurrentTexObj[0] = 0;
+            vmesa->dirty &= ~VIA_UPLOAD_TEX0;
+        }
+
+        if (vmesa->CurrentTexObj[1] == t) {
+            vmesa->CurrentTexObj[1] = 0;
+            vmesa->dirty &= ~VIA_UPLOAD_TEX1;
+        }
+    }
+
+    remove_from_list(t);
+    free(t);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
+void viaSwapOutTexObj(viaContextPtr vmesa, viaTextureObjectPtr t)
+{
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    if (t->bufAddr) {
+       via_free_texture(vmesa, t);
+
+        if (t->age > vmesa->dirtyAge)
+            vmesa->dirtyAge = t->age;
+    }
+
+    t->dirtyImages = ~0;
+    move_to_tail(&(vmesa->SwappedOut), t);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
+/* Upload an image from mesa's internal copy.
+ */
+static void viaUploadTexLevel(viaTextureObjectPtr t, int level)
+{
+    const struct gl_texture_image *image = t->image[level].image;
+    int i, j;
+#ifdef DEBUG
+    if (VIA_DEBUG) {
+       fprintf(stderr, "%s - in\n", __FUNCTION__);    
+       fprintf(stderr, "width = %d, height = %d \n", image->Width, image->Height);    
+    }  
+#endif
+    switch (t->image[level].internalFormat) {
+    case GL_RGB:
+    {
+       if (image->TexFormat->MesaFormat == MESA_FORMAT_ARGB8888) {
+           GLuint *dst = (GLuint *)(t->bufAddr + t->image[level].offset);
+           GLuint *src = (GLuint *)image->Data;
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "GL_RGB MESA_FORMAT_ARGB8888\n");    
+#endif             
+           if (image->Width < 8) {
+                for (i = 0; i < image->Height ; i++) {
+                   for (j = 0; j < image->Width ; j++) {
+                       dst[j] = *src;
+                       src++;
+                   }
+                   dst += 8;
+               }
+           }
+           else {
+               for (j = 0; j < image->Height * image->Width; j++) {
+                   *dst = *src;
+                   dst++;
+                   src++;
+               }
+           }
+           /*memcpy(dst, src, image->Height * image->Width * sizeof(GLuint));*/
+       }
+       else {
+           GLushort *dst = (GLushort *)(t->bufAddr + t->image[level].offset);
+           GLushort *src = (GLushort *)image->Data;
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "GL_RGB !MESA_FORMAT_ARGB8888\n");    
+#endif     
+           if (image->Width < 16) {
+                for (i = 0; i < image->Height ; i++) {
+                   for (j = 0; j < image->Width ; j++) {
+                       dst[j] = *src;
+                       src++;
+                   }
+                   dst += 16;
+               }
+           }
+           else {
+               for (j = 0; j < image->Height * image->Width; j++) {
+                   *dst = *src;
+                   dst++;
+                   src++;
+               }
+           }
+           /*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
+       }
+    }
+    break;
+
+    case GL_RGBA:
+    {
+        if (image->TexFormat->MesaFormat == MESA_FORMAT_ARGB4444) {    
+
+           GLushort *dst = (GLushort *)(t->bufAddr + t->image[level].offset);
+            GLushort *src = (GLushort *)image->Data;
+           if (image->Width < 16) {
+                for (i = 0; i < image->Height ; i++) {
+                   for (j = 0; j < image->Width ; j++) {
+                       dst[j] = *src;
+                       src++;
+                   }
+                   dst += 16;
+               }
+           }
+           else {
+               for (j = 0; j < image->Height * image->Width; j++) {
+                       *dst = *src; 
+                       src++;
+                       dst++;
+               }
+           }
+           /*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "GL_RGBA MESA_FORMAT_ARGB4444\n");    
+#endif
+        }
+       else if(image->TexFormat->MesaFormat == MESA_FORMAT_ARGB8888) {
+            GLuint *dst = (GLuint *)(t->bufAddr + t->image[level].offset);
+            GLuint *src = (GLuint *)image->Data;
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "GL_RGBA !MESA_FORMAT_ARGB4444\n");    
+#endif
+           if (image->Width < 8) {
+                for (i = 0; i < image->Height ; i++) {
+                   for (j = 0; j < image->Width ; j++) {
+                       dst[j] = *src;
+                       src++;
+                   }
+                   dst += 8;
+               }
+           }
+           else {
+               for (j = 0; j < image->Height * image->Width; j++) {
+                   *dst = *src;
+                   dst++;
+                   src++;
+               }
+           }
+           /*memcpy(dst, src, image->Height * image->Width * sizeof(GLuint));*/
+       }
+       else if(image->TexFormat->MesaFormat == MESA_FORMAT_ARGB1555) {
+           GLushort *dst = (GLushort *)(t->bufAddr + t->image[level].offset);
+            GLushort *src = (GLushort *)image->Data;
+           if (image->Width < 16) {
+                for (i = 0; i < image->Height ; i++) {
+                   for (j = 0; j < image->Width ; j++) {
+                       dst[j] = *src;
+                       src++;
+                   }
+                   dst += 16;
+               }
+           }
+           else {
+               for (j = 0; j < image->Height * image->Width; j++) {
+                       *dst = *src; 
+                       src++;
+                       dst++;
+               }
+           }
+           /*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "GL_RGBA MESA_FORMAT_ARGB1555\n");    
+#endif
+        }
+    }
+    break;
+
+    case GL_LUMINANCE:
+    {
+        GLubyte *dst = (GLubyte *)(t->bufAddr + t->image[level].offset);
+        GLubyte *src = (GLubyte *)image->Data;
+
+        for (j = 0; j < image->Height * image->Width; j++) {
+            *dst = *src;
+           dst++;
+            src++;
+        }
+    }
+    break;
+
+    case GL_INTENSITY:
+    {
+        GLubyte *dst = (GLubyte *)(t->bufAddr + t->image[level].offset);
+        GLubyte *src = (GLubyte *)image->Data;
+
+        for (j = 0; j < image->Height * image->Width; j++) {
+            *dst = *src;
+           dst++;
+            src++;
+        }
+    }
+    break;
+
+    case GL_LUMINANCE_ALPHA:
+    {
+        GLushort *dst = (GLushort *)(t->bufAddr + t->image[level].offset);
+        GLushort *src = (GLushort *)image->Data;
+
+        for (j = 0; j < image->Height * image->Width; j++) {
+            *dst = *src;
+            dst++;
+            src++;
+        }
+    }
+    break;
+
+    case GL_ALPHA:
+    {
+        GLubyte *dst = (GLubyte *)(t->bufAddr + t->image[level].offset);
+        GLubyte *src = (GLubyte *)image->Data;
+
+        for (j = 0; j < image->Height * image->Width; j++) {
+            *dst = *src;
+            dst++;    
+            src++;
+        }
+    }
+    break;
+
+    /* TODO: Translate color indices *now*:
+     */
+    case GL_COLOR_INDEX:
+    {
+        GLubyte *dst = (GLubyte *)(t->bufAddr + t->image[level].offset);
+        GLubyte *src = (GLubyte *)image->Data;
+
+        for (j = 0; j < image->Height * image->Width; j++) {
+            *dst = *src;
+            dst++;
+            src++;
+        }
+    }
+    break;
+
+    default:;
+#ifdef DEBUG
+        if (VIA_DEBUG) fprintf(stderr, "Not supported texture format %s\n",
+                _mesa_lookup_enum_by_nr(image->Format));
+#endif
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
+void viaPrintLocalLRU(viaContextPtr vmesa)
+{
+    viaTextureObjectPtr t;
+
+    foreach (t, &vmesa->TexObjList) {
+        if (!t->globj) {
+#ifdef DEBUG
+            if (VIA_DEBUG) {
+               fprintf(stderr, "offset = %x, index = %x, size = %x\n",
+                    t->texMem.offset,
+                    t->texMem.index,
+                    t->texMem.size);
+           }
+           else {
+               if (VIA_DEBUG) {
+                   fprintf(stderr, "offset = %x, siez = %x\n",
+                       t->texMem.offset,
+                    t->texMem.size);
+               }
+           }
+#endif
+       }                   
+    }
+}
+
+void viaPrintGlobalLRU(viaContextPtr vmesa)
+{
+    int i, j;
+    drm_via_tex_region_t *list = vmesa->sarea->texList;
+
+    for (i = 0, j = VIA_NR_TEX_REGIONS; i < VIA_NR_TEX_REGIONS; i++) {
+#ifdef DEBUG
+        if (VIA_DEBUG) fprintf(stderr, "list[%d] age %d next %d prev %d\n",
+                j, list[j].age, list[j].next, list[j].prev);
+#endif
+        j = list[j].next;
+        if (j == VIA_NR_TEX_REGIONS) break;
+    }
+#ifdef DEBUG
+    if (j != VIA_NR_TEX_REGIONS)
+       if (VIA_DEBUG) fprintf(stderr, "Loop detected in global LRU\n");
+#endif
+}
+
+void viaResetGlobalLRU(viaContextPtr vmesa)
+{
+    drm_via_tex_region_t *list = vmesa->sarea->texList;
+    int sz = 1 << vmesa->viaScreen->logTextureGranularity;
+    int i;
+
+    /* (Re)initialize the global circular LRU list.  The last element
+     * in the array (VIA_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->viaScreen->textureSize; i++) {
+        list[i].prev = i - 1;
+        list[i].next = i + 1;
+        list[i].age = 0;
+    }
+
+    i--;
+    list[0].prev = VIA_NR_TEX_REGIONS;
+    list[i].prev = i - 1;
+    list[i].next = VIA_NR_TEX_REGIONS;
+    list[VIA_NR_TEX_REGIONS].prev = i;
+    list[VIA_NR_TEX_REGIONS].next = 0;
+    vmesa->sarea->texAge = 0;
+}
+
+void viaUpdateTexLRU(viaContextPtr vmesa, viaTextureObjectPtr t)
+{
+    vmesa->texAge = ++vmesa->sarea->texAge;
+    move_to_head(&(vmesa->TexObjList), t);
+}
+
+/* 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 viaTexturesGone(viaContextPtr vmesa,
+                     GLuint offset,
+                     GLuint size,
+                     GLuint inUse)
+{
+    viaTextureObjectPtr t, tmp;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+    foreach_s (t, tmp, &vmesa->TexObjList) {
+        viaSwapOutTexObj(vmesa, t);
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#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 viaUploadTexImages(viaContextPtr vmesa, viaTextureObjectPtr t)
+{
+    int i, j;
+    int numLevels;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    LOCK_HARDWARE(vmesa);
+
+     j = 0;
+    if (!t->bufAddr) {
+        while (1) {
+
+           /*=* John Sheng [2003.5.31]  agp tex *=*/
+           via_alloc_texture(vmesa, t);
+           /*via_alloc_texture_agp(vmesa, t);*/
+
+           if (t->texMem.offset)
+                break;
+           else
+               agpFullCount++;
+
+            if (vmesa->TexObjList.prev == vmesa->CurrentTexObj[0] ||
+                vmesa->TexObjList.prev == vmesa->CurrentTexObj[1]) {
+#ifdef DEBUG
+                if (VIA_DEBUG) fprintf(stderr, "Hit bound texture in upload\n");
+#endif
+                viaPrintLocalLRU(vmesa);
+                UNLOCK_HARDWARE(vmesa);
+                return;
+            }
+
+            if (vmesa->TexObjList.prev == &(vmesa->TexObjList)) {
+#ifdef DEBUG
+                if (VIA_DEBUG) fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize);
+#endif
+                mmDumpMemInfo(vmesa->texHeap);
+                UNLOCK_HARDWARE(vmesa);
+                return;
+            }
+
+            viaSwapOutTexObj(vmesa, vmesa->TexObjList.prev);
+        }
+       /*=* John Sheng [2003.5.31]  agp tex *=*/
+        /*t->bufAddr = (char *)((GLuint)vmesa->driScreen->pFB + t->texMem.offset);*/
+
+        if (t == vmesa->CurrentTexObj[0])
+            VIA_STATECHANGE(vmesa, VIA_UPLOAD_TEX0);
+
+        if (t == vmesa->CurrentTexObj[1])
+            VIA_STATECHANGE(vmesa, VIA_UPLOAD_TEX1);
+
+        viaUpdateTexLRU(vmesa, t);
+       
+       j++;
+    }
+
+    numLevels = t->lastLevel - t->firstLevel + 1;
+
+    for (i = 0; i < numLevels; i++)
+        if (t->dirtyImages & (1 << i))
+            viaUploadTexLevel(t, i);
+
+    t->dirtyImages = 0;
+
+    UNLOCK_HARDWARE(vmesa);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
diff --git a/src/mesa/drivers/dri/unichrome/via_texstate.c b/src/mesa/drivers/dri/unichrome/via_texstate.c
new file mode 100644 (file)
index 0000000..fb83fcf
--- /dev/null
@@ -0,0 +1,725 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "context.h"
+#include "texformat.h"
+
+#include "mm.h"
+#include "via_context.h"
+#include "via_tex.h"
+#include "via_state.h"
+#include "via_ioctl.h"
+
+GLint texSize8bpp[12][12] = {
+    {32,32,32,32,32,32,64,128,256,512,1024,2048},
+    {64,64,64,64,64,64,128,256,512,1024,2048,4096},
+    {128,128,128,128,128,128,256,512,1024,2048,4096,8192},
+    {256,256,256,256,256,256,512,1024,2048,4096,8192,16384},
+    {512,512,512,512,512,512,1024,2048,4096,8192,16384,32768},
+    {1024,1024,1024,1024,1024,1024,2048,4096,8192,16384,32768,65536},
+    {2048,2048,2048,2048,2048,2048,4096,8192,16384,32768,65536,131072},
+    {4096,4096,4096,4096,4096,4096,8192,16384,32768,65536,131072,262144},
+    {8192,8192,8192,8192,8192,8192,16384,32768,65536,131072,262144,524288},
+    {16384,16384,16384,16384,16384,16384,32768,65536,131072,262144,524288,1048576},
+    {32768,32768,32768,32768,32768,32768,65536,131072,262144,524288,1048576,2097152},
+    {65536,65536,65536,65536,65536,65536,131072,262144,524288,1048576,2097152,4194304
+}
+};
+
+GLint texSize16bpp[12][12] = {
+    {32,32,32,32,32,64,128,256,512,1024,2048,4096},
+    {64,64,64,64,64,128,256,512,1024,2048,4096,8192},
+    {128,128,128,128,128,256,512,1024,2048,4096,8192,16384},
+    {256,256,256,256,256,512,1024,2048,4096,8192,16384,32768},
+    {512,512,512,512,512,1024,2048,4096,8192,16384,32768,65536},
+    {1024,1024,1024,1024,1024,2048,4096,8192,16384,32768,65536,131072},
+    {2048,2048,2048,2048,2048,4096,8192,16384,32768,65536,131072,262144},
+    {4096,4096,4096,4096,4096,8192,16384,32768,65536,131072,262144,524288},
+    {8192,8192,8192,8192,8192,16384,32768,65536,131072,262144,524288,1048576},
+    {16384,16384,16384,16384,16384,32768,65536,131072,262144,524288,1048576,2097152},
+    {32768,32768,32768,32768,32768,65536,131072,262144,524288,1048576,2097152,4194304},
+    {65536,65536,65536,65536,65536,131072,262144,524288,1048576,2097152,4194304,8388608}
+};
+
+GLint texSize32bpp[12][12] = {
+    {32,32,32,32,64,128,256,512,1024,2048,4096,8192},
+    {64,64,64,64,128,256,512,1024,2048,4096,8192,16384},
+    {128,128,128,128,256,512,1024,2048,4096,8192,16384,32768},
+    {256,256,256,256,512,1024,2048,4096,8192,16384,32768,65536},
+    {512,512,512,512,1024,2048,4096,8192,16384,32768,65536,131072},
+    {1024,1024,1024,1024,2048,4096,8192,16384,32768,65536,131072,262144},
+    {2048,2048,2048,2048,4096,8192,16384,32768,65536,131072,262144,524288},
+    {4096,4096,4096,4096,8192,16384,32768,65536,131072,262144,524288,1048576},
+    {8192,8192,8192,8192,16384,32768,65536,131072,262144,524288,1048576,2097152},
+    {16384,16384,16384,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304},
+    {32768,32768,32768,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608},
+    {65536,65536,65536,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216}
+};
+
+GLint mipmapTexSize8bpp[12][12] = {
+    {32,64,96,128,160,192,256,384,640,1152,2176,4224},
+    {96,96,128,160,192,224,320,512,896,1664,3200,6272},
+    {224,224,224,256,288,320,480,832,1536,2944,5760,11392},
+    {480,480,480,480,512,544,832,1504,2880,5632,11136,22144},
+    {992,992,992,992,992,1024,1568,2880,5600,11072,22016,43904},
+    {2016,2016,2016,2016,2016,2016,3072,5664,11072,21984,43840,87552},
+    {4064,4064,4064,4064,4064,4064,6112,11264,22048,43840,87520,174912},
+    {8160,8160,8160,8160,8160,8160,12256,22496,44032,87584,174912,349664},
+    {16352,16352,16352,16352,16352,16352,24544,45024,88032,175104,349728,699200},
+    {32736,32736,32736,32736,32736,32736,49120,90080,176096,350176,699392,1398304},
+    {65504,65504,65504,65504,65504,65504,98272,180192,352224,700384,1398752,2796544},
+    {131040,131040,131040,131040,131040,131040,196576,360416,704480,1400800,2797536,5593056
+}
+};
+
+GLint mipmapTexSize16bpp[12][12] = {
+    {32,64,96,128,160,224,352,608,1120,2144,4192,8288},
+    {96,96,128,160,192,288,480,864,1632,3168,6240,12384},
+    {224,224,224,256,288,448,800,1504,2912,5728,11360,22624},
+    {480,480,480,480,512,800,1472,2848,5600,11104,22112,44128},
+    {992,992,992,992,992,1536,2848,5568,11040,21984,43872,87648},
+    {2016,2016,2016,2016,2016,3040,5632,11040,21952,43808,87520,174944},
+    {4064,4064,4064,4064,4064,6112,11232,22016,43808,87488,174880,349664},
+    {8160,8160,8160,8160,8160,12256,22496,44000,87552,174880,349632,699168},
+    {16352,16352,16352,16352,16352,24544,45024,88032,175072,349696,699168,1398208},
+    {32736,32736,32736,32736,32736,49120,90080,176096,350176,699360,1398272,2796320},
+    {65504,65504,65504,65504,65504,98272,180192,352224,700384,1398752,2796512,5592576},
+    {131040,131040,131040,131040,131040,196576,360416,704480,1400800,2797536,5593056,11185120}
+};
+
+GLint mipmapTexSize32bpp[12][12] = {
+    {32,64,96,128,192,320,576,1088,2112,4160,8256,16448},
+    {96,96,128,160,256,448,832,1600,3136,6208,12352,24640},
+    {224,224,224,256,416,768,1472,2880,5696,11328,22592,45120},
+    {480,480,480,480,768,1440,2816,5568,11072,22080,44096,88128},
+    {992,992,992,992,1504,2816,5536,11008,21952,43840,87616,175168},
+    {2016,2016,2016,2016,3040,5600,11008,21920,43776,87488,174912,349760},
+    {4064,4064,4064,4064,6112,11232,21984,43776,87456,174848,349632,699200},
+    {8160,8160,8160,8160,12256,22496,44000,87520,174848,349600,699136,1398208},
+    {16352,16352,16352,16352,24544,45024,88032,175072,349664,699136,1398176,2796288},
+    {32736,32736,32736,32736,49120,90080,176096,350176,699360,1398240,2796288,5592480},
+    {65504,65504,65504,65504,98272,180192,352224,700384,1398752,2796512,5592544,11184896},
+    {131040,131040,131040,131040,196576,360416,704480,1400800,2797536,5593056,11185120,22369760}
+};
+
+static int logbase2(int n)
+{
+    GLint i = 1;
+    GLint log2 = 0;
+
+    if (n < 0) {
+        return -1;
+    }
+
+    while (n > i) {
+        i *= 2;
+        log2++;
+    }
+
+    if (i != n) {
+        return -1;
+    }
+    else {
+        return log2;
+    }
+}
+
+static void viaSetTexImages(viaContextPtr vmesa,
+                            struct gl_texture_object *tObj)
+{
+    GLuint texFormat;
+    viaTextureObjectPtr t = (viaTextureObjectPtr)tObj->DriverData;
+    const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel];
+    GLint firstLevel, lastLevel, numLevels;
+    GLint log2Width, log2Height, log2Pitch;
+    GLint (*texSize)[12][12];
+    GLint w, h, p;
+    GLint i, j, k, l, m;
+    GLint mipmapSize;
+    GLuint texBase;
+    GLuint basH = 0;
+    GLuint widthExp = 0;
+    GLuint heightExp = 0;    
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); 
+#endif
+    switch (baseImage->TexFormat->MesaFormat) {
+    case MESA_FORMAT_ARGB8888:
+       if (t->image[tObj->BaseLevel].internalFormat == GL_RGB)
+           texFormat = HC_HTXnFM_ARGB0888;
+       else
+           texFormat = HC_HTXnFM_ARGB8888;
+        break;
+    case MESA_FORMAT_ARGB4444:
+        texFormat = HC_HTXnFM_ARGB4444; 
+        break;
+    case MESA_FORMAT_RGB565:
+        texFormat = HC_HTXnFM_RGB565;   
+        break;
+    case MESA_FORMAT_ARGB1555:
+        texFormat = HC_HTXnFM_ARGB1555;   
+        break;
+    case MESA_FORMAT_L8:
+        texFormat = HC_HTXnFM_L8;       
+        break;
+    case MESA_FORMAT_I8:
+        texFormat = HC_HTXnFM_T8;       
+        break;
+    case MESA_FORMAT_CI8:
+        texFormat = HC_HTXnFM_Index8;   
+        break;
+    case MESA_FORMAT_AL88:
+        texFormat = HC_HTXnFM_AL88;     
+        break;
+    /*=* John Sheng [2003.7.18] texenv *=*/
+    case MESA_FORMAT_A8:
+        texFormat = HC_HTXnFM_A8;     
+        break;
+    default:
+        _mesa_problem(vmesa->glCtx, "Bad texture format in viaSetTexImages");
+       fprintf(stderr, "-- TexFormat = %d\n",baseImage->TexFormat->MesaFormat);
+    };
+
+    /* 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;
+    
+    /*=* [DBG] fgfs : fix mipmap level 11 over hw limitations and result in segmentation fault *=*/
+    if(numLevels > 10) {
+       numLevels = 10;
+       t->lastLevel = firstLevel + 9;
+    }
+
+    log2Width = tObj->Image[firstLevel]->WidthLog2;
+    log2Height = tObj->Image[firstLevel]->HeightLog2;
+    log2Pitch = logbase2(tObj->Image[firstLevel]->Width * baseImage->TexFormat->TexelBytes);
+    
+    
+    for (i = 0; i < numLevels; i++) {
+       t->image[i].image = tObj->Image[i];
+       t->image[i].internalFormat = baseImage->Format; 
+    }
+
+    if (baseImage->TexFormat->TexelBytes == 1) {
+        if (numLevels > 1)
+            texSize = &mipmapTexSize8bpp;
+        else
+            texSize = &texSize8bpp;
+    }
+    else if (baseImage->TexFormat->TexelBytes == 2) {
+        if (numLevels > 1)
+            texSize = &mipmapTexSize16bpp;
+        else
+            texSize = &texSize16bpp;
+    }    
+    else {
+        if (numLevels > 1)
+            texSize = &mipmapTexSize32bpp;
+        else
+            texSize = &texSize32bpp;
+    }
+    t->totalSize = (*texSize)[log2Height][log2Width];
+    t->texMem.size = t->totalSize;
+    t->maxLevel = i - 1;
+    t->dirty = VIA_UPLOAD_TEX0 | VIA_UPLOAD_TEX1;
+#ifdef DEBUG
+    if (VIA_DEBUG) {
+       fprintf(stderr, "log2Width = %d\n", log2Width);  
+       fprintf(stderr, "log2Height = %d\n", log2Height);    
+       fprintf(stderr, "log2Pitch = %d\n", log2Pitch);    
+       fprintf(stderr, "bytePerTexel = %d\n", baseImage->TexFormat->TexelBytes);
+       fprintf(stderr, "total size = %d\n", t->totalSize);
+       fprintf(stderr, "actual level = %d\n", t->actualLevel);
+        fprintf(stderr, "numlevel = %d\n", numLevels);    
+    }  
+#endif
+
+    {
+       w = log2Width;
+        h = log2Height;        
+       for (i = 0; i < numLevels; i++) {
+           t->image[i].offset = t->totalSize -  (*texSize)[h][w];
+           if (w) w--;
+            if (h) h--;
+        }
+    }    
+    
+    viaUploadTexImages(vmesa, t);
+    
+    if (t->bufAddr) {
+       if (t->inAGP)
+            t->regTexFM = (HC_SubA_HTXnFM << 24) | HC_HTXnLoc_AGP | texFormat;
+        else
+            t->regTexFM = (HC_SubA_HTXnFM << 24) | HC_HTXnLoc_Local | texFormat;
+        
+        w = log2Width;
+        h = log2Height;
+        p = log2Pitch;
+        mipmapSize = 0;     
+
+        for (i = 0; i < numLevels; i++) {    
+           if (i == (numLevels - 1))
+               mipmapSize = 0;
+           else
+               mipmapSize = (*texSize)[h][w];
+           
+           /*=* John Sheng [2003.5.31]  agp tex *=*/
+            if (t->inAGP)
+                texBase = (GLuint)vmesa->agpBase + t->texMem.offset + t->image[i].offset;
+            else
+               texBase = t->texMem.offset + t->image[i].offset;
+#ifdef DEBUG
+           if (VIA_DEBUG) {
+               fprintf(stderr, "texmem offset = %x\n", t->texMem.offset);    
+               fprintf(stderr, "mipmap%d addr = %x\n", i, t->image[i].offset);    
+               fprintf(stderr, "mipmap%d size = %d, h = %d, w = %d\n", i, (*texSize)[h][w], h, w);    
+               fprintf(stderr, "texBase%d = %x\n", i, texBase);
+           }   
+#endif      
+           t->regTexBaseAndPitch[i].baseL = ((HC_SubA_HTXnL0BasL + i) << 24) | (texBase & 0xFFFFFF);
+            
+           if (p < 5) {
+                t->regTexBaseAndPitch[i].pitchLog2 = ((HC_SubA_HTXnL0Pit + i) << 24) |
+                                                     (0x5 << 20);
+           }
+            else {         
+                t->regTexBaseAndPitch[i].pitchLog2 = ((HC_SubA_HTXnL0Pit + i) << 24) |
+                                                     ((GLuint)p << 20);
+           }                        
+            j = i / 3;
+            k = 3 - (i % 3);                                              
+            basH |= ((texBase & 0xFF000000) >> (k << 3));
+            if (k == 1) {
+                t->regTexBaseH[j] = ((j + HC_SubA_HTXnL012BasH) << 24) | basH;
+                basH = 0;
+            }
+            
+            l = i / 6;
+            m = i % 6;
+            widthExp |= (((GLuint)w & 0xF) << (m << 2));
+            heightExp |= (((GLuint)h & 0xF) << (m << 2));
+            if (m == 5) {
+                t->regTexWidthLog2[l] = ((l + HC_SubA_HTXnL0_5WE) << 24 | widthExp);
+                t->regTexHeightLog2[l] = ((l + HC_SubA_HTXnL0_5HE) << 24 | heightExp);  
+                widthExp = 0;
+                heightExp = 0;
+            }
+            if (w) w--;
+            if (h) h--;
+            if (p) p--;                                           
+        }
+        
+        if (k != 1) {
+            t->regTexBaseH[j] = ((j + HC_SubA_HTXnL012BasH) << 24) | basH;      
+        }
+        if (m != 5) {
+            t->regTexWidthLog2[l] = ((l + HC_SubA_HTXnL0_5WE) << 24 | widthExp);
+            t->regTexHeightLog2[l] = ((l + HC_SubA_HTXnL0_5HE) << 24 | heightExp);
+        }    
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+/* ================================================================
+ * Texture combine functions
+ */
+#define VIA_DISABLE            0
+#define VIA_PASSTHRU           1
+#define VIA_REPLACE            2
+#define VIA_MODULATE           3
+#define VIA_DECAL              4
+#define VIA_BLEND              5
+#define VIA_ALPHA_BLEND        6
+#define VIA_ADD                7
+#define VIA_MAX_COMBFUNC       8
+
+static GLuint via_color_combine[][VIA_MAX_COMBFUNC] =
+{
+    /* Unit 0:
+     */
+    {
+        /* Disable combiner stage
+         */
+        0,
+        
+        /* Passthru
+         */
+        1,
+
+        /* GL_REPLACE
+         */
+        2,
+        
+        /* GL_MODULATE
+         */
+        3,
+
+        /* GL_DECAL
+         */
+        4,
+
+        /* GL_BLEND
+         */
+        5,
+
+        /* GL_BLEND according to alpha
+         */
+        6,
+
+        /* GL_ADD
+         */
+        7,
+    },
+
+    /* Unit 1:
+     */
+    {
+        /* Disable combiner stage (Note: disables all subsequent stages)
+         */
+        0,
+
+        /* Passthru
+         */
+        1,
+
+        /* GL_REPLACE
+         */
+        2,
+
+        /* GL_MODULATE
+         */
+        3,
+
+        /* GL_DECAL
+         */
+        4,
+
+        /* GL_BLEND
+         */
+        5,
+
+        /* GL_BLEND according to alpha
+         */
+        6,
+
+        /* GL_ADD
+         */
+        7,
+    }
+};
+
+static GLuint via_alpha_combine[][VIA_MAX_COMBFUNC] =
+{
+    /* Unit 0:
+     */
+    {
+        /* Disable combiner stage
+         */
+        0,
+
+        /* Passthru
+         */
+        1,
+
+        /* GL_REPLACE
+         */
+        2,
+
+        /* GL_MODULATE
+         */
+        3,
+
+        /* GL_DECAL
+         */
+        4,
+
+        /* GL_BLEND
+         */
+        5,
+
+        /* GL_BLEND according to alpha (same as above)
+         */
+        6,
+
+        /* GL_ADD
+         */
+        7,
+    },
+
+    /* Unit 1:
+     */
+    {
+        /* Disable combiner stage
+         */
+        0,
+
+        /* Passthru
+         */
+        1,
+
+        /* GL_REPLACE
+         */
+        2,
+
+        /* GL_MODULATE
+         */
+        3,
+
+        /* GL_DECAL
+         */
+        4,
+
+        /* GL_BLEND
+         */
+        5,
+
+        /* GL_BLEND according to alpha (same as above)
+         */
+        6,
+
+        /* GL_ADD
+         */
+        7,
+    }
+};
+
+static void viaUpdateTexEnv(GLcontext *ctx, GLuint unit)
+{
+    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;
+    GLuint color_combine, alpha_combine;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); 
+#endif
+    switch (texUnit->EnvMode) {
+    case GL_REPLACE:
+        if (format == GL_ALPHA) {
+            color_combine = via_color_combine[unit][VIA_PASSTHRU];
+            alpha_combine = via_alpha_combine[unit][VIA_REPLACE];
+        }
+        else if (format == GL_LUMINANCE || format == GL_RGB) {
+            color_combine = via_color_combine[unit][VIA_REPLACE];
+            alpha_combine = via_alpha_combine[unit][VIA_PASSTHRU];
+        }
+        else {
+            color_combine = via_color_combine[unit][VIA_REPLACE];
+            alpha_combine = via_alpha_combine[unit][VIA_REPLACE];
+        }
+        break;
+
+    case GL_MODULATE:
+        if (format == GL_ALPHA) {
+            color_combine = via_color_combine[unit][VIA_PASSTHRU];
+            alpha_combine = via_alpha_combine[unit][VIA_MODULATE];
+        }
+        else {
+            color_combine = via_color_combine[unit][VIA_MODULATE];
+            alpha_combine = via_alpha_combine[unit][VIA_MODULATE];
+        }
+        break;
+
+    case GL_DECAL:
+        switch (format) {
+        case GL_RGBA:
+            color_combine = via_color_combine[unit][VIA_ALPHA_BLEND];
+            alpha_combine = via_alpha_combine[unit][VIA_PASSTHRU];
+            break;
+        case GL_RGB:
+            color_combine = via_color_combine[unit][VIA_REPLACE];
+            alpha_combine = via_alpha_combine[unit][VIA_PASSTHRU];
+            break;
+        case GL_ALPHA:
+        case GL_LUMINANCE:
+        case GL_LUMINANCE_ALPHA:
+        case GL_INTENSITY:
+            color_combine = via_color_combine[unit][VIA_PASSTHRU];
+            alpha_combine = via_alpha_combine[unit][VIA_PASSTHRU];
+            break;
+        case GL_COLOR_INDEX:
+        default:
+            return;
+        }
+        break;
+
+    case GL_BLEND:
+        switch (format) {
+        case GL_RGB:
+        case GL_LUMINANCE:
+            color_combine = via_color_combine[unit][VIA_BLEND];
+            alpha_combine = via_alpha_combine[unit][VIA_PASSTHRU];
+            break;
+        case GL_RGBA:
+        case GL_LUMINANCE_ALPHA:
+            color_combine = via_color_combine[unit][VIA_BLEND];
+            alpha_combine = via_alpha_combine[unit][VIA_MODULATE];
+            break;
+        case GL_ALPHA:
+            color_combine = via_color_combine[unit][VIA_PASSTHRU];
+            alpha_combine = via_alpha_combine[unit][VIA_MODULATE];
+            break;
+        case GL_INTENSITY:
+            color_combine = via_color_combine[unit][VIA_BLEND];
+            alpha_combine = via_alpha_combine[unit][VIA_BLEND];
+            break;
+        case GL_COLOR_INDEX:
+        default:
+            return;
+        }
+        break;
+
+    case GL_ADD:
+        switch (format) {
+        case GL_RGB:
+        case GL_LUMINANCE:
+            color_combine = via_color_combine[unit][VIA_ADD];
+            alpha_combine = via_alpha_combine[unit][VIA_PASSTHRU];
+            break;
+        case GL_RGBA:
+        case GL_LUMINANCE_ALPHA:
+            color_combine = via_color_combine[unit][VIA_ADD];
+            alpha_combine = via_alpha_combine[unit][VIA_MODULATE];
+            break;
+        case GL_ALPHA:
+            color_combine = via_color_combine[unit][VIA_PASSTHRU];
+            alpha_combine = via_alpha_combine[unit][VIA_MODULATE];
+            break;
+        case GL_INTENSITY:
+            color_combine = via_color_combine[unit][VIA_ADD];
+            alpha_combine = via_alpha_combine[unit][VIA_ADD];
+            break;
+        case GL_COLOR_INDEX:
+        default:
+            return;
+        }
+        break;
+
+    default:
+        return;
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+static void viaUpdateTexUnit(GLcontext *ctx, GLuint unit)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);     
+#endif
+    if (texUnit->_ReallyEnabled) {
+        struct gl_texture_object *tObj = texUnit->_Current;
+        viaTextureObjectPtr t = (viaTextureObjectPtr)tObj->DriverData;
+
+        /* Upload teximages (not pipelined)
+         */
+        if (t->dirtyImages) {
+            VIA_FIREVERTICES(vmesa);
+            viaSetTexImages(vmesa, tObj);
+            if (!t->bufAddr) {
+                FALLBACK(vmesa, VIA_FALLBACK_TEXTURE, GL_TRUE);
+                return;
+            }
+        }
+
+        if (tObj->Image[tObj->BaseLevel]->Border > 0) {
+            FALLBACK(vmesa, VIA_FALLBACK_TEXTURE, GL_TRUE);
+            return;
+        }
+
+        /* Update state if this is a different texture object to last
+         * time.
+         */
+        if (vmesa->CurrentTexObj[unit] != t) {
+            VIA_STATECHANGE(vmesa, (VIA_UPLOAD_TEX0 << unit));
+            vmesa->CurrentTexObj[unit] = t;
+            viaUpdateTexLRU(vmesa, t); /* done too often */
+        }
+
+        /* 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;
+            viaUpdateTexEnv(ctx, unit);
+        }
+    }
+    else {
+        vmesa->CurrentTexObj[unit] = 0;
+        vmesa->TexEnvImageFmt[unit] = 0;
+        vmesa->dirty &= ~(VIA_UPLOAD_TEX0 << unit);
+        VIA_STATECHANGE(vmesa, VIA_UPLOAD_CTX);
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
+void viaUpdateTextureState(GLcontext *ctx)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); 
+#endif
+    FALLBACK(vmesa, VIA_FALLBACK_TEXTURE, GL_FALSE);
+    viaUpdateTexUnit(ctx, 0);
+    viaUpdateTexUnit(ctx, 1);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
diff --git a/src/mesa/drivers/dri/unichrome/via_tris.c b/src/mesa/drivers/dri/unichrome/via_tris.c
new file mode 100644 (file)
index 0000000..47f081d
--- /dev/null
@@ -0,0 +1,1717 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "glheader.h"
+#include "context.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "colormac.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+#include "via_context.h"
+#include "via_tris.h"
+#include "via_state.h"
+#include "via_vb.h"
+#include "via_ioctl.h"
+
+static void viaRenderPrimitive(GLcontext *ctx, GLenum prim);
+GLuint RasterCounter = 0;
+extern GLuint idle;
+extern GLuint busy;
+/***********************************************************************
+ *                    Emit primitives as inline vertices               *
+ ***********************************************************************/
+
+#if defined(USE_X86_ASM)
+#define COPY_DWORDS(j, vb, vertsize, v)                                 \
+    do {                                                                \
+        int __tmp;                                                      \
+        __asm__ __volatile__("rep ; movsl"                              \
+                              : "=%c" (j), "=D" (vb), "=S" (__tmp)      \
+                              : "0" (vertsize),                         \
+                                "D" ((long)vb),                         \
+                                "S" ((long)v));                         \
+    } while (0)
+#else
+#define COPY_DWORDS(j, vb, vertsize, v)                                 \
+    do {                                                                \
+        for (j = 0; j < vertsize; j++)                                  \
+            vb[j] = ((GLuint *)v)[j];                                   \
+        vb += vertsize;                                                 \
+    } while (0)
+#endif
+
+static void __inline__ via_draw_triangle(viaContextPtr vmesa,
+                                         viaVertexPtr v0,
+                                         viaVertexPtr v1,
+                                         viaVertexPtr v2)
+{
+    GLuint vertsize = vmesa->vertex_size;
+    GLuint *vb = viaCheckDma(vmesa, 3 * 4 * vertsize);
+    int j;
+    
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif
+    COPY_DWORDS(j, vb, vertsize, v0);
+    COPY_DWORDS(j, vb, vertsize, v1);
+    COPY_DWORDS(j, vb, vertsize, v2);
+    vmesa->dmaLow += 3 * 4 * vertsize;
+    vmesa->primitiveRendered = GL_TRUE;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+
+static void __inline__ via_draw_quad(viaContextPtr vmesa,
+                                     viaVertexPtr v0,
+                                     viaVertexPtr v1,
+                                     viaVertexPtr v2,
+                                     viaVertexPtr v3)
+{
+    GLuint vertsize = vmesa->vertex_size;
+    GLuint *vb = viaCheckDma(vmesa, 6 * 4 * vertsize);
+    int j;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    COPY_DWORDS(j, vb, vertsize, v0);
+    COPY_DWORDS(j, vb, vertsize, v1);
+    COPY_DWORDS(j, vb, vertsize, v3);
+    COPY_DWORDS(j, vb, vertsize, v1);
+    COPY_DWORDS(j, vb, vertsize, v2);
+    COPY_DWORDS(j, vb, vertsize, v3);
+    vmesa->dmaLow += 6 * 4 * vertsize;
+    vmesa->primitiveRendered = GL_TRUE;    
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+
+static __inline__ void via_draw_point(viaContextPtr vmesa,
+                                      viaVertexPtr v0)
+{
+    /*GLfloat sz = vmesa->glCtx->Point._Size * .5;*/
+    int vertsize = vmesa->vertex_size;
+    /*GLuint *vb = viaCheckDma(vmesa, 2 * 4 * vertsize);*/
+    GLuint *vb = viaCheckDma(vmesa, 4 * vertsize);
+    int j;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif
+    COPY_DWORDS(j, vb, vertsize, v0);
+    vmesa->dmaLow += 4 * vertsize;
+    vmesa->primitiveRendered = GL_TRUE;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+
+/*
+ *     Draw line in hardware.
+ *     Checked out - AC.
+ */
+static __inline__ void via_draw_line(viaContextPtr vmesa,
+                                     viaVertexPtr v0,
+                                     viaVertexPtr v1)
+{
+    GLuint vertsize = vmesa->vertex_size;
+    GLuint *vb = viaCheckDma(vmesa, 2 * 4 * vertsize);
+    int j;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    COPY_DWORDS(j, vb, vertsize, v0);
+    COPY_DWORDS(j, vb, vertsize, v1);
+    vmesa->dmaLow += 2 * 4 * vertsize;
+    vmesa->primitiveRendered = GL_TRUE;    
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
+
+/***********************************************************************
+ *          Macros for via_dd_tritmp.h to draw basic primitives        *
+ ***********************************************************************/
+
+#define TRI(a, b, c)                                \
+    do {                                            \
+        if (VIA_DEBUG) fprintf(stderr, "hw TRI\n"); \
+        if (DO_FALLBACK)                            \
+            vmesa->drawTri(vmesa, a, b, c);         \
+        else                                        \
+            via_draw_triangle(vmesa, a, b, c);      \
+    } while (0)
+
+#define QUAD(a, b, c, d)                            \
+    do {                                            \
+        if (VIA_DEBUG) fprintf(stderr, "hw QUAD\n");\
+        if (DO_FALLBACK) {                          \
+            vmesa->drawTri(vmesa, a, b, d);         \
+            vmesa->drawTri(vmesa, b, c, d);         \
+        }                                           \
+        else                                        \
+            via_draw_quad(vmesa, a, b, c, d);       \
+    } while (0)
+
+#define LINE(v0, v1)                                \
+    do {                                            \
+        if( VIA_DEBUG) fprintf(stderr, "hw LINE\n");\
+        if (DO_FALLBACK)                            \
+            vmesa->drawLine(vmesa, v0, v1);         \
+        else                                        \
+            via_draw_line(vmesa, v0, v1);           \
+    } while (0)
+
+#define POINT(v0)                                    \
+    do {                                             \
+        if (VIA_DEBUG) fprintf(stderr, "hw POINT\n");\
+        if (DO_FALLBACK)                             \
+            vmesa->drawPoint(vmesa, v0);             \
+        else                                         \
+            via_draw_point(vmesa, v0);               \
+    } while (0)
+
+
+/***********************************************************************
+ *              Build render functions from dd templates               *
+ ***********************************************************************/
+
+#define VIA_OFFSET_BIT         0x01
+#define VIA_TWOSIDE_BIT        0x02
+#define VIA_UNFILLED_BIT       0x04
+#define VIA_FALLBACK_BIT       0x08
+#define VIA_MAX_TRIFUNC        0x10
+
+
+static struct {
+    points_func          points;
+    line_func            line;
+    triangle_func        triangle;
+    quad_func            quad;
+} rast_tab[VIA_MAX_TRIFUNC];
+
+
+#define DO_FALLBACK (IND & VIA_FALLBACK_BIT)
+#define DO_OFFSET   (IND & VIA_OFFSET_BIT)
+#define DO_UNFILLED (IND & VIA_UNFILLED_BIT)
+#define DO_TWOSIDE  (IND & VIA_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            viaVertex
+#define TAB               rast_tab
+
+/* Only used to pull back colors into vertices (ie, we know color is
+ * floating point).
+ */
+#define VIA_COLOR(dst, src)                     \
+    do {                                        \
+        dst[0] = src[2];                        \
+        dst[1] = src[1];                        \
+        dst[2] = src[0];                        \
+        dst[3] = src[3];                        \
+    } while (0)
+
+#define VIA_SPEC(dst, src)                      \
+    do {                                        \
+        dst[0] = src[2];                        \
+        dst[1] = src[1];                        \
+        dst[2] = src[0];                        \
+    } while (0)
+
+
+#define DEPTH_SCALE (1.0 / 0xffff)
+#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))
+
+#define VERT_SET_RGBA(v, c)    VIA_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) VIA_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 SET_PRIMITIVE_RENDERED vmesa->primitiveRendered = GL_TRUE;
+
+#define LOCAL_VARS(n)                                                   \
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);                             \
+    GLuint color[n], spec[n];                                           \
+    GLuint coloroffset = (vmesa->vertex_size == 4 ? 3 : 4);              \
+    GLboolean havespec = (vmesa->vertex_size > 4);                       \
+    (void)color; (void)spec; (void)coloroffset; (void)havespec;
+
+
+/***********************************************************************
+ *                Helpers for rendering unfilled primitives            *
+ ***********************************************************************/
+/*
+static const GLuint hwPrim[GL_POLYGON + 1] = {
+    PR_LINES,
+    PR_LINES,
+    PR_LINES,
+    PR_LINES,
+    PR_TRIANGLES,
+    PR_TRIANGLES,
+    PR_TRIANGLES,
+    PR_TRIANGLES,
+    PR_TRIANGLES,
+    PR_TRIANGLES
+};
+*/
+
+#define RASTERIZE(x)                                   \
+    if (vmesa->hwPrimitive != x) {             \
+        viaRasterPrimitiveFinish(ctx);         \
+        viaRasterPrimitive(ctx, x, x);         \
+    }                  
+       
+#define RENDER_PRIMITIVE vmesa->renderPrimitive
+#define TAG(x) x
+#define IND VIA_FALLBACK_BIT
+#include "tnl_dd/t_dd_unfilled.h"
+#undef IND
+#undef RASTERIZE
+
+/***********************************************************************
+ *                      Generate GL render functions                   *
+ ***********************************************************************/
+#define RASTERIZE(x)
+
+#define IND (0)
+#define TAG(x) x
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_UNFILLED_BIT)
+#define TAG(x) x##_unfilled
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT)
+#define TAG(x) x##_offset_unfilled
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT)
+#define TAG(x) x##_twoside_unfilled
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_unfilled
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_FALLBACK_BIT)
+#define TAG(x) x##_fallback
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_OFFSET_BIT|VIA_FALLBACK_BIT)
+#define TAG(x) x##_offset_fallback
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT|VIA_FALLBACK_BIT)
+#define TAG(x) x##_twoside_fallback
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_fallback
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
+#define TAG(x) x##_unfilled_fallback
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
+#define TAG(x) x##_offset_unfilled_fallback
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
+#define TAG(x) x##_twoside_unfilled_fallback
+#include "via_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_UNFILLED_BIT| \
+             VIA_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_unfilled_fallback
+#include "via_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();
+}
+
+
+/***********************************************************************
+ *                    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
+via_fallback_tri(viaContextPtr vmesa,
+                 viaVertex *v0,
+                 viaVertex *v1,
+                 viaVertex *v2)
+{    
+    GLcontext *ctx = vmesa->glCtx;
+    SWvertex v[3];
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif
+    via_translate_vertex(ctx, v0, &v[0]);
+    via_translate_vertex(ctx, v1, &v[1]);
+    via_translate_vertex(ctx, v2, &v[2]);
+    _swrast_Triangle(ctx, &v[0], &v[1], &v[2]);
+}
+
+
+static void
+via_fallback_line(viaContextPtr vmesa,
+                  viaVertex *v0,
+                  viaVertex *v1)
+{
+    GLcontext *ctx = vmesa->glCtx;
+    SWvertex v[2];
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif
+    via_translate_vertex(ctx, v0, &v[0]);
+    via_translate_vertex(ctx, v1, &v[1]);
+    _swrast_Line(ctx, &v[0], &v[1]);
+}
+
+
+static void
+via_fallback_point(viaContextPtr vmesa,
+                   viaVertex *v0)
+{
+    GLcontext *ctx = vmesa->glCtx;
+    SWvertex v[1];
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif
+    via_translate_vertex(ctx, v0, &v[0]);
+    _swrast_Point(ctx, &v[0]);
+}
+
+/**********************************************************************/
+/*               Render unclipped begin/end objects                   */
+/*              (No Twoside / Offset / Unfilled)                     */
+/**********************************************************************/
+#define IND 0
+#define V(x) (viaVertex *)(vertptr + ((x) << vertshift))
+#define RENDER_POINTS(start, count)   \
+    for (; start < count; start++) POINT(V(ELT(start)));
+#define RENDER_LINE(v0, v1)         LINE(V(v0), V(v1))
+
+#define RENDER_TRI( v0, v1, v2)                                \
+    if (VIA_DEBUG) fprintf(stderr, "RENDER_TRI - simple\n");   \
+    TRI( V(v0), V(v1), V(v2))
+    
+#define RENDER_QUAD(v0, v1, v2, v3) QUAD(V(v0), V(v1), V(v2), V(v3))
+
+#define INIT(x) viaRasterPrimitive(ctx, x, x)
+
+#undef LOCAL_VARS
+#define LOCAL_VARS                                              \
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);                     \
+    GLubyte *vertptr = (GLubyte *)vmesa->verts;                 \
+    const GLuint vertshift = vmesa->vertex_stride_shift;          \
+    const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;       \
+    (void)elt;
+#define POSTFIX                                                        \
+    viaRasterPrimitiveFinish(ctx)    
+#define RESET_STIPPLE
+#define RESET_OCCLUSION
+#define PRESERVE_VB_DEFS
+#define ELT(x) x
+#define TAG(x) via_fast##x##_verts
+#include "via_vb_rendertmp.h"
+#undef ELT
+#undef TAG
+#define TAG(x) via_fast##x##_elts
+#define ELT(x) elt[x]
+#include "via_vb_rendertmp.h"
+#undef ELT
+#undef TAG
+#undef NEED_EDGEFLAG_SETUP
+#undef EDGEFLAG_GET
+#undef EDGEFLAG_SET
+#undef RESET_OCCLUSION
+
+/**********************************************************************/
+/*               Render unclipped begin/end objects                   */
+/*              (Can handle Twoside / Offset / Unfilled              */
+/**********************************************************************/
+#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED)
+#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx]
+#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val
+
+#define RENDER_POINTS(start, count)            \
+   tnl->Driver.Render.Points(ctx, start, count)
+
+#define RENDER_LINE(v1, v2)                    \
+    LineFunc(ctx, v1, v2)                              
+
+#define RENDER_TRI(v1, v2, v3)                                                         \
+    if (VIA_DEBUG) fprintf(stderr, "RENDER_TRI - complex\n");                          \
+    if (VIA_DEBUG) fprintf(stderr, "TriangleFunc = %x\n", (unsigned int)TriangleFunc);         \
+    TriangleFunc(ctx, v1, v2, v3)
+
+#define RENDER_QUAD(v1, v2, v3, v4)            \
+    QuadFunc(ctx, v1, v2, v3, v4)              
+
+#define LOCAL_VARS                                                     \
+    TNLcontext *tnl = TNL_CONTEXT(ctx);                                        \
+    struct vertex_buffer *VB = &tnl->vb;                               \
+    const GLuint * const elt = VB->Elts;                               \
+    const line_func LineFunc = tnl->Driver.Render.Line;                        \
+    const triangle_func TriangleFunc = tnl->Driver.Render.Triangle;    \
+    const quad_func QuadFunc = tnl->Driver.Render.Quad;                        \
+    const GLboolean stipple = ctx->Line.StippleFlag;                   \
+    (void) (LineFunc && TriangleFunc && QuadFunc);                     \
+    (void) elt; (void) stipple;
+
+#define POSTFIX                                                         \
+    viaRasterPrimitiveFinish(ctx)                          
+#define ELT(x) x
+#define TAG(x) via_##x##_verts
+/*#define INIT(x) tnl->Driver.Render.PrimitiveNotify(ctx, x)*/
+#define INIT(x) viaRasterPrimitive(ctx, x, x)
+#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple(ctx)
+#define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE
+#define PRESERVE_VB_DEFS
+#include "via_vb_rendertmp.h"
+#undef ELT
+#undef TAG
+#define ELT(x) elt[x]
+#define TAG(x) via_##x##_elts
+#include "via_vb_rendertmp.h"
+
+/**********************************************************************/
+/*                   Render clipped primitives                        */
+/**********************************************************************/
+
+
+
+static void viaRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
+                                 GLuint n)
+{
+    TNLcontext *tnl = TNL_CONTEXT(ctx);
+    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif
+    /* 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;
+    }
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);        
+#endif
+}
+
+static void viaRenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    TNLcontext *tnl = TNL_CONTEXT(ctx);
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    vmesa->primitiveRendered = GL_TRUE;
+    
+    tnl->Driver.Render.Line(ctx, ii, jj);
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+static void viaFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
+                                     GLuint n)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    GLuint vertsize = vmesa->vertex_size;
+    GLuint *vb = viaCheckDma(vmesa, (n - 2) * 3 * 4 * vertsize);
+    GLubyte *vertptr = (GLubyte *)vmesa->verts;
+    const GLuint vertshift = vmesa->vertex_stride_shift;
+    const GLuint *start = (const GLuint *)V(elts[0]);
+    GLuint *temp1;
+    GLuint *temp2;
+    int i,j;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif
+    vmesa->primitiveRendered = GL_TRUE;
+
+    for (i = 2; i < n; i++) {
+       /*=* [DBG] exy : fix flat-shading + clipping error *=*/
+        /*COPY_DWORDS(j, vb, vertsize, start);
+        COPY_DWORDS(j, vb, vertsize, V(elts[i - 1]));
+       temp1 = (GLuint *)V(elts[i - 1]);       
+        COPY_DWORDS(j, vb, vertsize, V(elts[i]));
+       temp2 = (GLuint *)V(elts[i]);*/
+       COPY_DWORDS(j, vb, vertsize, V(elts[i - 1]));
+        COPY_DWORDS(j, vb, vertsize, V(elts[i]));
+       temp1 = (GLuint *)V(elts[i - 1]);
+       COPY_DWORDS(j, vb, vertsize, start);    
+       temp2 = (GLuint *)V(elts[i]);
+#ifdef DEBUG
+       if (VIA_DEBUG) fprintf(stderr, "start = %d -  x = %f, y = %f, z = %f, w = %f, u = %f, v = %f\n", elts[0], *(GLfloat *)&start[0], *(GLfloat *)&start[1], *(GLfloat *)&start[2], *(GLfloat *)&start[3], *(GLfloat *)&start[6], *(GLfloat *)&start[7]);
+       if (VIA_DEBUG) fprintf(stderr, "%d -  x = %f, y = %f, z = %f, w = %f, u = %f, v = %f\n", elts[i - 1], *(GLfloat *)&temp1[0], *(GLfloat *)&temp1[1], *(GLfloat *)&temp1[2], *(GLfloat *)&temp1[3], *(GLfloat *)&temp1[6], *(GLfloat *)&temp1[7]);
+       if (VIA_DEBUG) fprintf(stderr, "%d -  x = %f, y = %f, z = %f, w = %f, u = %f, v = %f\n", elts[i], *(GLfloat *)&temp2[0], *(GLfloat *)&temp2[1], *(GLfloat *)&temp2[2], *(GLfloat *)&temp2[3], *(GLfloat *)&temp2[6], *(GLfloat *)&temp2[7]);    
+#endif
+    }
+    vmesa->dmaLow += (n - 2) * 3 * 4 * vertsize;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+/**********************************************************************/
+/*                    Choose render functions                         */
+/**********************************************************************/
+
+
+
+#define _VIA_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE |            \
+                              _DD_NEW_TRI_UNFILLED |            \
+                              _DD_NEW_TRI_LIGHT_TWOSIDE |       \
+                              _DD_NEW_TRI_OFFSET |              \
+                              _DD_NEW_TRI_STIPPLE |             \
+                              _NEW_POLYGONSTIPPLE)
+
+#define POINT_FALLBACK (0)
+/*#define LINE_FALLBACK (DD_LINE_STIPPLE)
+*/
+#define LINE_FALLBACK (0)
+#define TRI_FALLBACK (0)
+#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 viaChooseRenderState(GLcontext *ctx)
+{
+    TNLcontext *tnl = TNL_CONTEXT(ctx);
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    GLuint flags = ctx->_TriangleCaps;
+    GLuint index = 0;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+    
+    if (VIA_DEBUG) fprintf(stderr, "_TriangleCaps = %x\n", flags);    
+#endif
+    if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) {
+        if (flags & ANY_RASTER_FLAGS) {
+            if (flags & DD_TRI_LIGHT_TWOSIDE)    index |= VIA_TWOSIDE_BIT;
+            if (flags & DD_TRI_OFFSET)           index |= VIA_OFFSET_BIT;
+            if (flags & DD_TRI_UNFILLED)         index |= VIA_UNFILLED_BIT;
+        }
+
+        vmesa->drawPoint = via_draw_point;
+        vmesa->drawLine = via_draw_line;
+        vmesa->drawTri = via_draw_triangle;
+
+        /* Hook in fallbacks for specific primitives.
+         */
+        if (flags & ANY_FALLBACK_FLAGS) {
+            if (flags & POINT_FALLBACK)
+                vmesa->drawPoint = via_fallback_point;
+
+            if (flags & LINE_FALLBACK)
+                vmesa->drawLine = via_fallback_line;
+
+            if (flags & TRI_FALLBACK)
+                vmesa->drawTri = via_fallback_tri;
+
+            index |= VIA_FALLBACK_BIT;
+        }
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) {
+       fprintf(stderr, "index = %x\n", index);    
+       fprintf(stderr, "renderIndex = %x\n", vmesa->renderIndex);
+    }  
+#endif
+    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;
+#ifdef DEBUG
+       if (VIA_DEBUG) fprintf(stderr, "tnl->Driver.Render.xxx = rast_tab[index].xxx = %x\n", (unsigned int)tnl->Driver.Render.Triangle);
+#endif
+        tnl->Driver.Render.Quad = rast_tab[index].quad;
+
+        if (index == 0) {
+            tnl->Driver.Render.PrimTabVerts = via_fastrender_tab_verts;
+            tnl->Driver.Render.PrimTabElts = via_fastrender_tab_elts;
+            tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
+            tnl->Driver.Render.ClippedPolygon = viaFastRenderClippedPoly;
+        }
+        else {
+            tnl->Driver.Render.PrimTabVerts = via_render_tab_verts;
+            tnl->Driver.Render.PrimTabElts = via_render_tab_elts;
+            tnl->Driver.Render.ClippedLine = viaRenderClippedLine;
+            tnl->Driver.Render.ClippedPolygon = viaRenderClippedPoly;
+        }
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+static const GLenum reducedPrim[GL_POLYGON + 1] = {
+    GL_POINTS,
+    GL_LINES,
+    GL_LINES,
+    GL_LINES,
+    GL_TRIANGLES,
+    GL_TRIANGLES,
+    GL_TRIANGLES,
+    GL_TRIANGLES,
+    GL_TRIANGLES,
+    GL_TRIANGLES
+};
+
+
+static void emit_all_state(viaContextPtr vmesa)
+{
+    GLcontext *ctx = vmesa->glCtx;
+    GLuint *vb = viaCheckDma(vmesa, 0x110);
+    GLuint i = 0;
+    GLuint j = 0;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    
+    *vb++ = HC_HEADER2;
+    *vb++ = (HC_ParaType_NotTex << 16);
+    *vb++ = ((HC_SubA_HEnable << 24) | vmesa->regEnable);
+    *vb++ = ((HC_SubA_HFBBMSKL << 24) | vmesa->regHFBBMSKL);    
+    *vb++ = ((HC_SubA_HROP << 24) | vmesa->regHROP);        
+    i += 5;
+    
+    if (vmesa->hasDepth && vmesa->hasStencil) {
+       GLuint pitch, format, offset;
+       
+       format = HC_HZWBFM_24;      
+       
+       offset = vmesa->depth.offset;
+       pitch = vmesa->depth.pitch;
+       
+        *vb++ = ((HC_SubA_HZWBBasL << 24) | (offset & 0xFFFFFF));
+
+        *vb++ = ((HC_SubA_HZWBBasH << 24) | ((offset & 0xFF000000) >> 24));    
+        *vb++ = ((HC_SubA_HZWBType << 24) | HC_HDBLoc_Local | HC_HZONEasFF_MASK | 
+                format | pitch);            
+        *vb++ = ((HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD);
+       /* set stencil */
+       *vb++ = ((HC_SubA_HSTREF << 24) | vmesa->regHSTREF);
+       *vb++ = ((HC_SubA_HSTMD << 24) | vmesa->regHSTMD);
+       
+       i += 6; 
+    }
+    else if (vmesa->hasDepth) {
+       GLuint pitch, format, offset;
+       
+       if (vmesa->depthBits == 16) {
+           /* We haven't support 16bit depth yet */
+           format = HC_HZWBFM_16;
+           /*format = HC_HZWBFM_32;*/
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "z format = 16\n");
+#endif
+       }           
+       else {
+           format = HC_HZWBFM_32;
+#ifdef DEBUG
+           if (VIA_DEBUG) fprintf(stderr, "z format = 32\n");
+#endif
+       }
+           
+           
+       offset = vmesa->depth.offset;
+       pitch = vmesa->depth.pitch;
+       
+        *vb++ = ((HC_SubA_HZWBBasL << 24) | (offset & 0xFFFFFF));
+
+        *vb++ = ((HC_SubA_HZWBBasH << 24) | ((offset & 0xFF000000) >> 24));    
+        *vb++ = ((HC_SubA_HZWBType << 24) | HC_HDBLoc_Local | HC_HZONEasFF_MASK | 
+                format | pitch);            
+        *vb++ = ((HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD);
+       i += 4; 
+    }
+    else if (vmesa->hasStencil) {
+       GLuint pitch, format, offset;
+       
+       format = HC_HZWBFM_24;      
+       
+       offset = vmesa->depth.offset;
+       pitch = vmesa->depth.pitch;
+       
+        *vb++ = ((HC_SubA_HZWBBasL << 24) | (offset & 0xFFFFFF));
+
+        *vb++ = ((HC_SubA_HZWBBasH << 24) | ((offset & 0xFF000000) >> 24));    
+        *vb++ = ((HC_SubA_HZWBType << 24) | HC_HDBLoc_Local | HC_HZONEasFF_MASK | 
+                format | pitch);            
+        *vb++ = ((HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD);
+       /* set stencil */
+       *vb++ = ((HC_SubA_HSTREF << 24) | vmesa->regHSTREF);
+       *vb++ = ((HC_SubA_HSTMD << 24) | vmesa->regHSTMD);
+       
+       i += 6; 
+    }
+    
+    if (ctx->Color.AlphaEnabled) {
+        *vb++ = ((HC_SubA_HATMD << 24) | vmesa->regHATMD);
+        i++;
+    }   
+
+    if (ctx->Color.BlendEnabled) {
+        *vb++ = ((HC_SubA_HABLCsat << 24) | vmesa->regHABLCsat);
+        *vb++ = ((HC_SubA_HABLCop  << 24) | vmesa->regHABLCop); 
+        *vb++ = ((HC_SubA_HABLAsat << 24) | vmesa->regHABLAsat);        
+        *vb++ = ((HC_SubA_HABLAop  << 24) | vmesa->regHABLAop); 
+        *vb++ = ((HC_SubA_HABLRCa  << 24) | vmesa->regHABLRCa); 
+        *vb++ = ((HC_SubA_HABLRFCa << 24) | vmesa->regHABLRFCa);        
+        *vb++ = ((HC_SubA_HABLRCbias << 24) | vmesa->regHABLRCbias);    
+        *vb++ = ((HC_SubA_HABLRCb  << 24) | vmesa->regHABLRCb); 
+        *vb++ = ((HC_SubA_HABLRFCb << 24) | vmesa->regHABLRFCb);        
+        *vb++ = ((HC_SubA_HABLRAa  << 24) | vmesa->regHABLRAa); 
+        *vb++ = ((HC_SubA_HABLRAb  << 24) | vmesa->regHABLRAb); 
+        i += 11;
+    }
+    
+    if (ctx->Fog.Enabled) {
+        *vb++ = ((HC_SubA_HFogLF << 24) | vmesa->regHFogLF);        
+        *vb++ = ((HC_SubA_HFogCL << 24) | vmesa->regHFogCL);            
+        *vb++ = ((HC_SubA_HFogCH << 24) | vmesa->regHFogCH);            
+        i += 3;
+    }
+    
+    if (ctx->Line.StippleFlag) {
+        *vb++ = ((HC_SubA_HLP << 24) | ctx->Line.StipplePattern);           
+        *vb++ = ((HC_SubA_HLPRF << 24) | ctx->Line.StippleFactor);                  
+    }
+    else {
+        *vb++ = ((HC_SubA_HLP << 24) | 0xFFFF);         
+        *vb++ = ((HC_SubA_HLPRF << 24) | 0x1);              
+    }
+
+    i += 2;
+    
+    *vb++ = ((HC_SubA_HPixGC << 24) | 0x0);             
+    i++;
+    
+    if (i & 0x1) {
+        *vb++ = HC_DUMMY;
+        i++;    
+    }    
+    
+    if (ctx->Texture.Unit[0]._ReallyEnabled) {
+    
+       struct gl_texture_unit *texUnit0 = &ctx->Texture.Unit[0];
+       struct gl_texture_unit *texUnit1 = &ctx->Texture.Unit[1];
+
+        {
+           viaTextureObjectPtr t = (viaTextureObjectPtr)texUnit0->_Current->DriverData;
+           GLuint nDummyValue = 0;
+            
+           *vb++ = HC_HEADER2;
+            *vb++ = (HC_ParaType_Tex << 16) | (HC_SubType_TexGeneral << 24);
+
+           if (ctx->Texture.Unit[1]._ReallyEnabled) {
+#ifdef DEBUG
+               if (VIA_DEBUG) fprintf(stderr, "multi texture\n");
+#endif                
+               nDummyValue = (HC_SubA_HTXSMD << 24) | (1 << 3);
+                
+               if (t && t->needClearCache) {
+                    *vb++ = nDummyValue | HC_HTXCHCLR_MASK;
+                    *vb++ = nDummyValue;
+                }
+                else {
+                    *vb++ = nDummyValue;
+                    *vb++ = nDummyValue;
+                }
+            }
+            else {
+#ifdef DEBUG
+               if (VIA_DEBUG) fprintf(stderr, "single texture\n");
+#endif                
+               nDummyValue = (HC_SubA_HTXSMD << 24) | 0;
+                
+               if (t && t->needClearCache) {
+                    *vb++ = nDummyValue | HC_HTXCHCLR_MASK;
+                    *vb++ = nDummyValue;
+                }
+                else {
+                    *vb++ = nDummyValue;
+                    *vb++ = nDummyValue;
+                }
+            }
+            *vb++ = HC_HEADER2;
+            *vb++ = HC_ParaType_NotTex << 16;
+            *vb++ = (HC_SubA_HEnable << 24) | vmesa->regEnable;
+            *vb++ = (HC_SubA_HEnable << 24) | vmesa->regEnable;
+            i += 8;
+        }
+
+        if (texUnit0->Enabled) {
+           struct gl_texture_object *texObj = texUnit0->_Current;
+           viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
+           GLuint numLevels = t->lastLevel - t->firstLevel + 1;
+           GLuint nDummyValue = 0;
+#ifdef DEBUG
+           if (VIA_DEBUG) {
+               fprintf(stderr, "texture0 enabled\n");
+               fprintf(stderr, "texture level %d\n", t->actualLevel);
+           }           
+#endif     
+            if (numLevels == 8) {
+                nDummyValue = t->regTexFM;
+                *vb++ = HC_HEADER2;
+                *vb++ = (HC_ParaType_Tex << 16) |  (0 << 24);
+                *vb++ = t->regTexFM;
+                *vb++ = (HC_SubA_HTXnL0OS << 24) |
+                        ((t->actualLevel) << HC_HTXnLVmax_SHIFT);
+                *vb++ = t->regTexWidthLog2[0];
+                *vb++ = t->regTexWidthLog2[1];
+                *vb++ = t->regTexHeightLog2[0];
+                *vb++ = t->regTexHeightLog2[1];
+                *vb++ = t->regTexBaseH[0];
+                *vb++ = t->regTexBaseH[1];
+                *vb++ = t->regTexBaseH[2];
+
+                *vb++ = t->regTexBaseAndPitch[0].baseL;
+                *vb++ = t->regTexBaseAndPitch[0].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[1].baseL;
+                *vb++ = t->regTexBaseAndPitch[1].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[2].baseL;
+                *vb++ = t->regTexBaseAndPitch[2].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[3].baseL;
+                *vb++ = t->regTexBaseAndPitch[3].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[4].baseL;
+                *vb++ = t->regTexBaseAndPitch[4].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[5].baseL;
+                *vb++ = t->regTexBaseAndPitch[5].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[6].baseL;
+                *vb++ = t->regTexBaseAndPitch[6].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[7].baseL;
+                *vb++ = t->regTexBaseAndPitch[7].pitchLog2;
+                i += 27;
+            }
+            else if (numLevels > 1) {
+                nDummyValue = t->regTexFM;
+                *vb++ = HC_HEADER2;
+                *vb++ = (HC_ParaType_Tex << 16) |  (0 << 24);
+                *vb++ = t->regTexFM;
+                *vb++ = (HC_SubA_HTXnL0OS << 24) |
+                           ((t->actualLevel) << HC_HTXnLVmax_SHIFT);
+               *vb++ = t->regTexWidthLog2[0];
+               *vb++ = t->regTexHeightLog2[0];
+               
+               if (numLevels > 6) {
+                   *vb++ = t->regTexWidthLog2[1];
+                   *vb++ = t->regTexHeightLog2[1];
+                   i += 2;
+               }
+                
+               *vb++ = t->regTexBaseH[0];
+               
+                if (numLevels > 3) { 
+                   *vb++ = t->regTexBaseH[1];
+                   i++;
+               }
+               if (numLevels > 6) {
+                   *vb++ = t->regTexBaseH[2];
+                   i++;
+               }
+               if (numLevels > 9)  {
+                   *vb++ = t->regTexBaseH[3];
+                   i++;
+               }
+               
+               i += 7;
+
+                for (j = 0; j < numLevels; j++) {
+                    *vb++ = t->regTexBaseAndPitch[j].baseL;
+                    *vb++ = t->regTexBaseAndPitch[j].pitchLog2;
+                   i += 2;
+                }
+            }
+            else {
+                nDummyValue = t->regTexFM;
+                *vb++ = HC_HEADER2;
+                *vb++ = (HC_ParaType_Tex << 16) |  (0 << 24);
+                *vb++ = t->regTexFM;
+                *vb++ = (HC_SubA_HTXnL0OS << 24) |
+                           ((t->actualLevel) << HC_HTXnLVmax_SHIFT);
+                *vb++ = t->regTexWidthLog2[0];
+                *vb++ = t->regTexHeightLog2[0];
+                *vb++ = t->regTexBaseH[0];
+                *vb++ = t->regTexBaseAndPitch[0].baseL;
+                *vb++ = t->regTexBaseAndPitch[0].pitchLog2;
+                i += 9;
+            }
+
+            *vb++ = (HC_SubA_HTXnTB << 24) | vmesa->regHTXnTB_0;
+            *vb++ = (HC_SubA_HTXnMPMD << 24) | vmesa->regHTXnMPMD_0;
+            *vb++ = (HC_SubA_HTXnTBLCsat << 24) | vmesa->regHTXnTBLCsat_0;
+            *vb++ = (HC_SubA_HTXnTBLCop << 24) | vmesa->regHTXnTBLCop_0;
+            *vb++ = (HC_SubA_HTXnTBLMPfog << 24) | vmesa->regHTXnTBLMPfog_0;
+            *vb++ = (HC_SubA_HTXnTBLAsat << 24) | vmesa->regHTXnTBLAsat_0;
+            *vb++ = (HC_SubA_HTXnTBLRCb << 24) | vmesa->regHTXnTBLRCb_0;
+            *vb++ = (HC_SubA_HTXnTBLRAa << 24) | vmesa->regHTXnTBLRAa_0;
+            *vb++ = (HC_SubA_HTXnTBLRFog << 24) | vmesa->regHTXnTBLRFog_0;
+            i += 9;
+           /*=* John Sheng [2003.7.18] texture combine */
+           *vb++ = (HC_SubA_HTXnTBLRCa << 24) | vmesa->regHTXnTBLRCa_0;
+            *vb++ = (HC_SubA_HTXnTBLRCc << 24) | vmesa->regHTXnTBLRCc_0;
+            *vb++ = (HC_SubA_HTXnTBLRCbias << 24) | vmesa->regHTXnTBLRCbias_0;
+           i += 3;
+
+            if (t->regTexFM == HC_HTXnFM_Index8) {
+                struct gl_color_table *table = &texObj->Palette;
+               GLfloat *tableF = (GLfloat *)table->Table;
+
+                *vb++ = HC_HEADER2;
+                *vb++ = (HC_ParaType_Palette << 16) | (0 << 24);
+                i += 2;
+                for (j = 0; j < table->Size; j++) {
+                    *vb++ = tableF[j];
+                   i++;
+                }
+            }
+            if (i & 0x1) {
+               *vb++ = HC_DUMMY;
+               i++;    
+           }
+        }
+       
+       if (texUnit1->Enabled) {
+           struct gl_texture_object *texObj = texUnit1->_Current;
+           viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
+           GLuint numLevels = t->lastLevel - t->firstLevel + 1;
+           GLuint nDummyValue = 0;
+#ifdef DEBUG
+           if (VIA_DEBUG) {
+               fprintf(stderr, "texture1 enabled\n");
+               fprintf(stderr, "texture level %d\n", t->actualLevel);
+           }           
+#endif     
+            if (numLevels == 8) {
+                nDummyValue = t->regTexFM;
+                *vb++ = HC_HEADER2;
+                *vb++ = (HC_ParaType_Tex << 16) |  (1 << 24);
+                *vb++ = t->regTexFM;
+                *vb++ = (HC_SubA_HTXnL0OS << 24) |
+                        ((t->actualLevel) << HC_HTXnLVmax_SHIFT);
+                *vb++ = t->regTexWidthLog2[0];
+                *vb++ = t->regTexWidthLog2[1];
+                *vb++ = t->regTexHeightLog2[0];
+                *vb++ = t->regTexHeightLog2[1];
+                *vb++ = t->regTexBaseH[0];
+                *vb++ = t->regTexBaseH[1];
+                *vb++ = t->regTexBaseH[2];
+
+                *vb++ = t->regTexBaseAndPitch[0].baseL;
+                *vb++ = t->regTexBaseAndPitch[0].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[1].baseL;
+                *vb++ = t->regTexBaseAndPitch[1].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[2].baseL;
+                *vb++ = t->regTexBaseAndPitch[2].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[3].baseL;
+                *vb++ = t->regTexBaseAndPitch[3].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[4].baseL;
+                *vb++ = t->regTexBaseAndPitch[4].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[5].baseL;
+                *vb++ = t->regTexBaseAndPitch[5].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[6].baseL;
+                *vb++ = t->regTexBaseAndPitch[6].pitchLog2;
+                *vb++ = t->regTexBaseAndPitch[7].baseL;
+                *vb++ = t->regTexBaseAndPitch[7].pitchLog2;
+                i += 27;
+            }
+            else if (numLevels > 1) {
+                nDummyValue = t->regTexFM;
+                *vb++ = HC_HEADER2;
+                *vb++ = (HC_ParaType_Tex << 16) |  (1 << 24);
+                *vb++ = t->regTexFM;
+                *vb++ = (HC_SubA_HTXnL0OS << 24) |
+                           ((t->actualLevel) << HC_HTXnLVmax_SHIFT);
+               *vb++ = t->regTexWidthLog2[0];
+               *vb++ = t->regTexHeightLog2[0];
+               
+               if (numLevels > 6) {
+                   *vb++ = t->regTexWidthLog2[1];
+                   *vb++ = t->regTexHeightLog2[1];
+                   i += 2;
+               }
+                
+               *vb++ = t->regTexBaseH[0];
+               
+                if (numLevels > 3) { 
+                   *vb++ = t->regTexBaseH[1];
+                   i++;
+               }
+               if (numLevels > 6) {
+                   *vb++ = t->regTexBaseH[2];
+                   i++;
+               }
+               if (numLevels > 9)  {
+                   *vb++ = t->regTexBaseH[3];
+                   i++;
+               }
+               
+               i += 7;
+
+                for (j = 0; j < numLevels; j++) {
+                    *vb++ = t->regTexBaseAndPitch[j].baseL;
+                    *vb++ = t->regTexBaseAndPitch[j].pitchLog2;
+                   i += 2;
+                }
+            }
+            else {
+                nDummyValue = t->regTexFM;
+                *vb++ = HC_HEADER2;
+                *vb++ = (HC_ParaType_Tex << 16) |  (1 << 24);
+                *vb++ = t->regTexFM;
+                *vb++ = (HC_SubA_HTXnL0OS << 24) |
+                           ((t->actualLevel) << HC_HTXnLVmax_SHIFT);
+                *vb++ = t->regTexWidthLog2[0];
+                *vb++ = t->regTexHeightLog2[0];
+                *vb++ = t->regTexBaseH[0];
+                *vb++ = t->regTexBaseAndPitch[0].baseL;
+                *vb++ = t->regTexBaseAndPitch[0].pitchLog2;
+                i += 9;
+            }
+
+            *vb++ = (HC_SubA_HTXnTB << 24) | vmesa->regHTXnTB_1;
+            *vb++ = (HC_SubA_HTXnMPMD << 24) | vmesa->regHTXnMPMD_1;
+            *vb++ = (HC_SubA_HTXnTBLCsat << 24) | vmesa->regHTXnTBLCsat_1;
+            *vb++ = (HC_SubA_HTXnTBLCop << 24) | vmesa->regHTXnTBLCop_1;
+            *vb++ = (HC_SubA_HTXnTBLMPfog << 24) | vmesa->regHTXnTBLMPfog_1;
+            *vb++ = (HC_SubA_HTXnTBLAsat << 24) | vmesa->regHTXnTBLAsat_1;
+            *vb++ = (HC_SubA_HTXnTBLRCb << 24) | vmesa->regHTXnTBLRCb_1;
+            *vb++ = (HC_SubA_HTXnTBLRAa << 24) | vmesa->regHTXnTBLRAa_1;
+            *vb++ = (HC_SubA_HTXnTBLRFog << 24) | vmesa->regHTXnTBLRFog_1;
+            i += 9;
+
+            if (t->regTexFM == HC_HTXnFM_Index8) {
+                struct gl_color_table *table = &texObj->Palette;
+               GLfloat *tableF = (GLfloat *)table->Table;
+
+                *vb++ = HC_HEADER2;
+                *vb++ = (HC_ParaType_Palette << 16) | (1 << 24);
+                i += 2;
+                for (j = 0; j < table->Size; j++) {
+                    *vb++ = tableF[j];
+                   i++;
+                }
+            }
+            if (i & 0x1) {
+               *vb++ = HC_DUMMY;
+               i++;    
+           }
+        }
+    }
+    
+    
+    if (ctx->Polygon.StippleFlag) {
+        GLuint *stipple = &ctx->PolygonStipple[0];
+        
+        *vb++ = HC_HEADER2;             
+        *vb++ = ((HC_ParaType_Palette << 16) | (HC_SubType_Stipple << 24));
+
+        *vb++ = stipple[31];            
+        *vb++ = stipple[30];            
+        *vb++ = stipple[29];            
+        *vb++ = stipple[28];            
+        *vb++ = stipple[27];            
+        *vb++ = stipple[26];            
+        *vb++ = stipple[25];            
+        *vb++ = stipple[24];            
+        *vb++ = stipple[23];            
+        *vb++ = stipple[22];            
+        *vb++ = stipple[21];            
+        *vb++ = stipple[20];            
+        *vb++ = stipple[19];            
+        *vb++ = stipple[18];            
+        *vb++ = stipple[17];            
+        *vb++ = stipple[16];            
+        *vb++ = stipple[15];            
+        *vb++ = stipple[14];            
+        *vb++ = stipple[13];            
+        *vb++ = stipple[12];            
+        *vb++ = stipple[11];            
+        *vb++ = stipple[10];            
+        *vb++ = stipple[9];             
+        *vb++ = stipple[8];             
+        *vb++ = stipple[7];             
+        *vb++ = stipple[6];             
+        *vb++ = stipple[5];             
+        *vb++ = stipple[4];             
+        *vb++ = stipple[3];             
+        *vb++ = stipple[2];             
+        *vb++ = stipple[1];             
+        *vb++ = stipple[0];             
+        
+        *vb++ = HC_HEADER2;                     
+        *vb++ = (HC_ParaType_NotTex << 16);
+        *vb++ = ((HC_SubA_HSPXYOS << 24) | (0x20 - (vmesa->driDrawable->h & 0x1F)));
+        *vb++ = ((HC_SubA_HSPXYOS << 24) | (0x20 - (vmesa->driDrawable->h & 0x1F)));
+        i += 38;
+    }
+    
+    vmesa->dmaLow += (i << 2);
+
+    vmesa->dirty = 0;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
+
+static void emit_partial_state(viaContextPtr vmesa)
+{
+    GLcontext *ctx = vmesa->glCtx;
+    GLuint dirty = vmesa->dirty;
+    GLuint *vb = viaCheckDma(vmesa, 0x110);
+    GLuint i = 0;
+
+#ifdef DEBUG    
+    if( VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif    
+
+#ifdef PERFORMANCE_MEASURE
+    if (VIA_PERFORMANCE) P_M;
+#endif
+    vb = vb;
+    
+    *vb++ = HC_HEADER2;
+    *vb++ = (HC_ParaType_NotTex << 16);
+    *vb++ = ((HC_SubA_HEnable << 24) | vmesa->regEnable);
+    *vb++ = ((HC_SubA_HFBBMSKL << 24) | vmesa->regHFBBMSKL);    
+    *vb++ = ((HC_SubA_HROP << 24) | vmesa->regHROP);        
+    i += 5;
+
+    if (dirty & VIA_UPLOAD_DESTBUFFER) {
+    }
+
+    if (dirty & VIA_UPLOAD_DEPTHBUFFER) {
+    }
+    
+    if (dirty * VIA_UPLOAD_DEPTH) {
+        *vb++ = ((HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD);
+        i++;
+    }
+    
+    if (dirty * VIA_UPLOAD_ALPHATEST) {
+        *vb++ = ((HC_SubA_HATMD << 24) | vmesa->regHATMD);
+        i++;
+    }
+
+
+    if (dirty & VIA_UPLOAD_BLEND) {
+        *vb++ = ((HC_SubA_HABLCsat << 24) | vmesa->regHABLCsat);
+        *vb++ = ((HC_SubA_HABLCop  << 24) | vmesa->regHABLCop); 
+        *vb++ = ((HC_SubA_HABLAsat << 24) | vmesa->regHABLAsat);        
+        *vb++ = ((HC_SubA_HABLAop  << 24) | vmesa->regHABLAop); 
+        *vb++ = ((HC_SubA_HABLRCa  << 24) | vmesa->regHABLRCa); 
+        *vb++ = ((HC_SubA_HABLRFCa << 24) | vmesa->regHABLRFCa);        
+        *vb++ = ((HC_SubA_HABLRCbias << 24) | vmesa->regHABLRCbias);    
+        *vb++ = ((HC_SubA_HABLRCb  << 24) | vmesa->regHABLRCb); 
+        *vb++ = ((HC_SubA_HABLRFCb << 24) | vmesa->regHABLRFCb);        
+        *vb++ = ((HC_SubA_HABLRAa  << 24) | vmesa->regHABLRAa); 
+        *vb++ = ((HC_SubA_HABLRAb  << 24) | vmesa->regHABLRAb); 
+        i += 11;
+    }
+    
+    if (dirty & VIA_UPLOAD_FOG) {
+        *vb++ = ((HC_SubA_HFogLF << 24) | vmesa->regHFogLF);        
+        *vb++ = ((HC_SubA_HFogCL << 24) | vmesa->regHFogCL);            
+        *vb++ = ((HC_SubA_HFogCH << 24) | vmesa->regHFogCH);            
+        i += 3;
+    }
+    
+    if (dirty & VIA_UPLOAD_LINESTIPPLE) {
+        *vb++ = ((HC_SubA_HLP << 24) | ctx->Line.StipplePattern);           
+        *vb++ = ((HC_SubA_HLPRF << 24) | ctx->Line.StippleFactor);                  
+    }
+    else {
+        *vb++ = ((HC_SubA_HLP << 24) | 0xFFFF);         
+        *vb++ = ((HC_SubA_HLPRF << 24) | 0x1);              
+    }
+    i += 2;
+    
+    *vb++ = ((HC_SubA_HPixGC << 24) | 0x0);             
+    i++;
+    
+    if (i & 0x1) {
+        *vb++ = HC_DUMMY;
+        i++;    
+    }    
+
+    if (dirty & VIA_UPLOAD_TEXTURE) {
+                
+    }
+    
+    if (dirty & VIA_UPLOAD_POLYGONSTIPPLE) {
+    
+    }
+    
+    vmesa->dmaLow += (i << 2);
+
+    vmesa->dirty = 0;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif    
+}
+
+/**********************************************************************/
+/*                 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 via_render.c.
+ */
+static void viaRenderPrimitive(GLcontext *ctx, GLenum prim)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    GLuint rprim = reducedPrim[prim];
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif    
+    vmesa->renderPrimitive = prim;
+    viaRasterPrimitive(ctx, rprim, rprim);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+static void viaRunPipeline(GLcontext *ctx)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+    
+    if (VIA_DEBUG) fprintf(stderr, "newState = %x\n", vmesa->newState);        
+#endif
+    
+    if (vmesa->newState) {
+        if (vmesa->newState & _NEW_TEXTURE)
+            viaUpdateTextureState(ctx); /* may modify vmesa->newState */
+
+       viaChooseVertexState(ctx);
+       viaChooseRenderState(ctx);
+        vmesa->newState = 0;
+    }
+
+    if (vmesa->needUploadAllState)
+       emit_all_state(vmesa);
+    else
+        emit_partial_state(vmesa);
+
+    _tnl_run_pipeline(ctx);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);        
+#endif
+}
+
+static void viaRenderStart(GLcontext *ctx)
+{
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    
+    /* Check for projective texturing.  Make sure all texcoord
+     * pointers point to something.  (fix in mesa?)
+     */
+    viaCheckTexSizes(ctx);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
+static void viaRenderFinish(GLcontext *ctx)
+{
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif    
+    if (VIA_CONTEXT(ctx)->renderIndex & VIA_FALLBACK_BIT)
+        _swrast_flush(ctx);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);        
+#endif
+}
+
+
+/* System to flush dma and emit state changes based on the rasterized
+ * primitive.
+ */
+void viaRasterPrimitive(GLcontext *ctx,
+                        GLenum rprim,
+                        GLuint hwprim)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    GLuint *vb = viaCheckDma(vmesa, 32);
+    GLuint regCmdB;
+#ifdef DEBUG
+    if (VIA_DEBUG) {
+       fprintf(stderr, "%s - in\n", __FUNCTION__);
+       fprintf(stderr, "hwprim = %x\n", hwprim);
+    }
+#endif    
+    /*=* [DBG] exy : fix wireframe + clipping error *=*/
+    if (((rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)))) {
+       hwprim = GL_LINES;
+    }
+    
+    if (RasterCounter > 0) {
+    
+#ifdef DEBUG
+       if (VIA_DEBUG) fprintf(stderr, "enter twice:%d\n",RasterCounter);
+#endif
+       RasterCounter++;
+       return;
+    }
+    RasterCounter++;
+    
+    vmesa->primitiveRendered = GL_FALSE;
+    regCmdB = vmesa->regCmdB;
+
+    switch (hwprim) {
+    case GL_POINTS:
+#ifdef DEBUG
+        if (VIA_DEBUG) fprintf(stderr, "Points\n");
+#endif
+        vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Point | HC_HVCycle_Full;
+        if (ctx->Light.ShadeModel == GL_FLAT)
+            vmesa->regCmdA_End |= HC_HShading_FlatA;
+        break;
+    case GL_LINES:
+#ifdef DEBUG
+        if (VIA_DEBUG) fprintf(stderr, "Lines\n");    
+#endif
+        vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Line | HC_HVCycle_Full;
+        if (ctx->Light.ShadeModel == GL_FLAT)
+            vmesa->regCmdA_End |= HC_HShading_FlatB; 
+        break;
+    case GL_LINE_LOOP:
+    case GL_LINE_STRIP:
+#ifdef DEBUG
+        if (VIA_DEBUG) fprintf(stderr, "Line Loop / Line Strip\n");
+#endif
+        vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Line | HC_HVCycle_AFP |
+                             HC_HVCycle_AB | HC_HVCycle_NewB;
+        regCmdB |= HC_HVCycle_AB | HC_HVCycle_NewB | HC_HLPrst_MASK;
+        if (ctx->Light.ShadeModel == GL_FLAT)
+            vmesa->regCmdA_End |= HC_HShading_FlatB; 
+        break;
+    case GL_TRIANGLES:
+#ifdef DEBUG
+        if (VIA_DEBUG) fprintf(stderr, "Triangles\n");        
+#endif
+        vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Tri | HC_HVCycle_Full;
+        if (ctx->Light.ShadeModel == GL_FLAT)
+            vmesa->regCmdA_End |= HC_HShading_FlatC; 
+        break;
+    case GL_TRIANGLE_STRIP:
+#ifdef DEBUG
+        if (VIA_DEBUG) fprintf(stderr, "Triangle Strip\n");
+#endif
+        vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Tri | HC_HVCycle_AFP |
+                             HC_HVCycle_AC | HC_HVCycle_BB | HC_HVCycle_NewC;
+        regCmdB |= HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
+        if (ctx->Light.ShadeModel == GL_FLAT)
+            vmesa->regCmdA_End |= HC_HShading_FlatB; 
+        break;
+    case GL_TRIANGLE_FAN:
+#ifdef DEBUG
+        if (VIA_DEBUG) fprintf(stderr, "Triangle Fan\n");
+#endif
+        vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Tri | HC_HVCycle_AFP |
+                             HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
+        regCmdB |= HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
+        if (ctx->Light.ShadeModel == GL_FLAT)
+            vmesa->regCmdA_End |= HC_HShading_FlatC; 
+        break;
+    case GL_QUADS:
+#ifdef DEBUG
+        if (VIA_DEBUG) fprintf(stderr, "No HW Quads\n");
+#endif
+        return;
+    case GL_QUAD_STRIP:
+#ifdef DEBUG
+        if (VIA_DEBUG) fprintf(stderr, "No HW Quad Strip\n");
+#endif
+        return;
+    case GL_POLYGON:
+#ifdef DEBUG
+        if (VIA_DEBUG) fprintf(stderr, "Polygon\n");        
+#endif
+        vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Tri | HC_HVCycle_AFP |
+                             HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
+        regCmdB |= HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
+        if (ctx->Light.ShadeModel == GL_FLAT)
+            vmesa->regCmdA_End |= HC_HShading_FlatC; 
+        break;                          
+    default:
+#ifdef DEBUG
+        if (VIA_DEBUG) fprintf(stderr, "Unknow\n");        
+#endif
+        return;
+    }
+    
+    *vb++ = HC_HEADER2;    
+    *vb++ = (HC_ParaType_NotTex << 16);
+    *vb++ = 0xCCCCCCCC;
+    *vb++ = 0xDDDDDDDD;
+
+    *vb++ = HC_HEADER2;    
+    *vb++ = (HC_ParaType_CmdVdata << 16);
+    *vb++ = regCmdB;
+    *vb++ = vmesa->regCmdA_End;
+    vmesa->dmaLow += 32;
+    
+    vmesa->reducedPrimitive = rprim;
+    vmesa->hwPrimitive = rprim;    
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+void viaRasterPrimitiveFinish(GLcontext *ctx)
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+    
+    if (VIA_DEBUG) fprintf(stderr, "primitiveRendered = %x\n", vmesa->primitiveRendered);    
+#endif    
+    if (RasterCounter > 1) {
+       RasterCounter--;
+#ifdef DEBUG
+       if (VIA_DEBUG) fprintf(stderr, "finish enter twice: %d\n",RasterCounter);
+#endif
+       return;
+    }
+    RasterCounter = 0;
+
+    
+    if (vmesa->primitiveRendered) {
+        GLuint *vb = viaCheckDma(vmesa, 0);
+       GLuint cmdA = vmesa->regCmdA_End | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK;    
+       
+        if ((vmesa->dmaLow & 0x1) || !vmesa->useAgp) {
+            *vb++ = cmdA ;
+            vmesa->dmaLow += 4;
+       }   
+       else {      
+           *vb++ = cmdA;
+            *vb++ = cmdA;
+           vmesa->dmaLow += 8;
+        }   
+    }
+    else {
+       if (vmesa->dmaLow >=  (32 + DMA_OFFSET))        
+           vmesa->dmaLow -= 32;
+    }
+    
+    if (0) viaFlushPrimsLocked(vmesa);
+    if (0) {   
+       volatile GLuint *pnMMIOBase = vmesa->regMMIOBase;
+        volatile GLuint *pnEngBase = (volatile GLuint *)((GLuint)pnMMIOBase + 0x400);
+        int nStatus = *pnEngBase;
+       if (((nStatus & 0xFFFEFFFF) == 0x00020000)) {
+#ifdef PERFORMANCE_MEASURE    
+           idle++;
+#endif
+           viaFlushPrims(vmesa);        
+       }
+#ifdef PERFORMANCE_MEASURE    
+       else {
+           busy++;
+       }
+#endif
+    }  
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+
+/**********************************************************************/
+/*           Transition to/from hardware rasterization.               */
+/**********************************************************************/
+
+
+void viaFallback(viaContextPtr vmesa, GLuint bit, GLboolean mode)
+{
+    GLcontext *ctx = vmesa->glCtx;
+    TNLcontext *tnl = TNL_CONTEXT(ctx);
+    GLuint oldfallback = vmesa->Fallback;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s old %x bit %x mode %d\n", __FUNCTION__,
+                   vmesa->Fallback, bit, mode);
+#endif
+    
+    if (mode) {
+        vmesa->Fallback |= bit;
+        if (oldfallback == 0) {
+#ifdef DEBUG
+            if (VIA_DEBUG) fprintf(stderr, "ENTER FALLBACK\n");
+#endif
+           VIA_FIREVERTICES(vmesa);
+            _swsetup_Wakeup(ctx);
+            vmesa->renderIndex = ~0;
+        }
+    }
+    else {
+        vmesa->Fallback &= ~bit;
+        if (oldfallback == bit) {
+#ifdef DEBUG
+            if (VIA_DEBUG) fprintf(stderr, "LEAVE FALLBACK\n");
+#endif
+           tnl->Driver.Render.Start = viaRenderStart;
+            tnl->Driver.Render.PrimitiveNotify = viaRenderPrimitive;
+            tnl->Driver.Render.Finish = viaRenderFinish;
+            tnl->Driver.Render.BuildVertices = viaBuildVertices;
+            vmesa->newState |= (_VIA_NEW_RENDERSTATE|_VIA_NEW_VERTEX);
+        }
+    }
+    
+}
+
+
+/**********************************************************************/
+/*                            Initialization.                         */
+/**********************************************************************/
+
+
+void viaInitTriFuncs(GLcontext *ctx)
+{
+    TNLcontext *tnl = TNL_CONTEXT(ctx);
+    static int firsttime = 1;
+
+    if (firsttime) {
+        init_rast_tab();
+        firsttime = 0;
+    }
+
+    tnl->Driver.RunPipeline = viaRunPipeline;
+    tnl->Driver.Render.Start = viaRenderStart;
+    tnl->Driver.Render.Finish = viaRenderFinish;
+    tnl->Driver.Render.PrimitiveNotify = viaRenderPrimitive;
+    tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
+    tnl->Driver.Render.BuildVertices = viaBuildVertices;
+}
diff --git a/src/mesa/drivers/dri/unichrome/via_tris.h b/src/mesa/drivers/dri/unichrome/via_tris.h
new file mode 100644 (file)
index 0000000..b4f0880
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _VIATRIS_H
+#define _VIATRIS_H
+
+#include "mtypes.h"
+
+extern void viaPrintRenderState(const char *msg, GLuint state);
+extern void viaInitTriFuncs(GLcontext *ctx);
+extern void viaRasterPrimitive(GLcontext *ctx, GLenum rPrim, GLuint hwPrim);
+extern void viaRasterPrimitiveFinish(GLcontext *ctx);
+
+#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_vb.c b/src/mesa/drivers/dri/unichrome/via_vb.c
new file mode 100644 (file)
index 0000000..d29e3a0
--- /dev/null
@@ -0,0 +1,415 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "imports.h"
+#include "macros.h"
+#include "colormac.h"
+/*#include "mmath.h" _SOLO*/
+/*#include "mem.h" _SOLO*/
+
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/t_context.h"
+
+#include "via_context.h"
+#include "via_vb.h"
+#include "via_ioctl.h"
+#include "via_tris.h"
+#include "via_state.h"
+
+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[VIA_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 0
+#define TEX2_VERTEX_FORMAT      0
+#define TEX3_VERTEX_FORMAT      0
+#define PROJ_TEX3_VERTEX_FORMAT 0
+
+#define DO_XYZW (IND & VIA_XYZW_BIT)
+#define DO_RGBA (IND & VIA_RGBA_BIT)
+#define DO_SPEC (IND & VIA_SPEC_BIT)
+#define DO_FOG  (IND & VIA_FOG_BIT)
+#define DO_TEX0 (IND & VIA_TEX0_BIT)
+#define DO_TEX1 (IND & VIA_TEX1_BIT)
+#define DO_TEX2 0
+#define DO_TEX3 0
+#define DO_PTEX (IND & VIA_PTEX_BIT)
+
+#define VERTEX viaVertex
+#define VERTEX_COLOR via_color_t
+#define GET_VIEWPORT_MAT() VIA_CONTEXT(ctx)->ViewportMatrix.m
+#define GET_TEXSOURCE(n)  n
+#define GET_VERTEX_FORMAT() VIA_CONTEXT(ctx)->vertex_size
+#define GET_VERTEX_SIZE() VIA_CONTEXT(ctx)->vertex_size
+#define GET_VERTEX_STORE() VIA_CONTEXT(ctx)->verts
+#define GET_VERTEX_STRIDE_SHIFT() VIA_CONTEXT(ctx)->vertex_stride_shift
+#define GET_UBYTE_COLOR_STORE() &VIA_CONTEXT(ctx)->UbyteColor
+#define GET_UBYTE_SPEC_COLOR_STORE() &VIA_CONTEXT(ctx)->UbyteSecondaryColor
+#define INVALIDATE_STORED_VERTICES()
+
+#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  GLfloat h = VIA_CONTEXT(ctx)->driDrawable->h
+#define UNVIEWPORT_X(x)  x - SUBPIXEL_X
+#define UNVIEWPORT_Y(y)  - y + h + SUBPIXEL_Y
+#define UNVIEWPORT_Z(z)  z * (float)0xffffffff
+
+#define PTEX_FALLBACK() FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_TEXTURE, 1)
+
+#define IMPORT_FLOAT_COLORS via_import_float_colors
+#define IMPORT_FLOAT_SPEC_COLORS via_import_float_spec_colors
+
+#define INTERP_VERTEX setup_tab[VIA_CONTEXT(ctx)->setupIndex].interp
+#define COPY_PV_VERTEX setup_tab[VIA_CONTEXT(ctx)->setupIndex].copy_pv
+
+
+/***********************************************************************
+ *         Generate  pv-copying and translation functions              *
+ ***********************************************************************/
+
+#define TAG(x) via_##x
+#include "tnl_dd/t_dd_vb.c"
+
+/***********************************************************************
+ *             Generate vertex emit and interp functions               *
+ ***********************************************************************/
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT)
+#define TAG(x) x##_wg
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT)
+#define TAG(x) x##_wgs
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT)
+#define TAG(x) x##_wgt0
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT | VIA_TEX1_BIT)
+#define TAG(x) x##_wgt0t1
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT | VIA_PTEX_BIT)
+#define TAG(x) x##_wgpt0
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT | VIA_TEX1_BIT |\
+             VIA_PTEX_BIT)
+#define TAG(x) x##_wgpt0t1
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT)
+#define TAG(x) x##_wgst0
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT |\
+             VIA_TEX1_BIT)
+#define TAG(x) x##_wgst0t1
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT |\
+             VIA_PTEX_BIT)
+#define TAG(x) x##_wgspt0
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT |\
+             VIA_TEX1_BIT | VIA_PTEX_BIT)           
+#define TAG(x) x##_wgspt0t1
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT)
+#define TAG(x) x##_wgf
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT)
+#define TAG(x) x##_wgfs
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT)
+#define TAG(x) x##_wgft0
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT |\
+             VIA_TEX1_BIT)
+#define TAG(x) x##_wgft0t1
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT |\
+             VIA_PTEX_BIT)
+#define TAG(x) x##_wgfpt0
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT |\
+             VIA_TEX1_BIT | VIA_PTEX_BIT)
+#define TAG(x) x##_wgfpt0t1
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
+             VIA_TEX0_BIT)
+#define TAG(x) x##_wgfst0
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
+             VIA_TEX0_BIT | VIA_TEX1_BIT)
+#define TAG(x) x##_wgfst0t1
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
+             VIA_TEX0_BIT | VIA_PTEX_BIT)
+#define TAG(x) x##_wgfspt0
+#include "via_dd_vbtmp.h"
+
+#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
+             VIA_TEX0_BIT | VIA_TEX1_BIT | VIA_PTEX_BIT)
+#define TAG(x) x##_wgfspt0t1
+#include "via_dd_vbtmp.h"
+
+static void init_setup_tab(void) {
+
+    init_wg();
+    init_wgs();
+    init_wgt0();
+    init_wgt0t1();
+    init_wgpt0();
+    init_wgpt0t1();    
+    init_wgst0();
+    init_wgst0t1();
+    init_wgspt0();
+    init_wgspt0t1();
+    init_wgf();
+    init_wgfs();
+    init_wgft0();
+    init_wgft0t1();
+    init_wgfpt0();
+    init_wgfpt0t1();
+    init_wgfst0();
+    init_wgfst0t1();
+    init_wgfspt0();
+    init_wgfspt0t1();
+}
+
+void viaPrintSetupFlags(char *msg, GLuint flags) {
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
+            msg,
+            (int)flags,
+            (flags & VIA_XYZW_BIT)     ? " xyzw," : "",
+            (flags & VIA_RGBA_BIT)     ? " rgba," : "",
+            (flags & VIA_SPEC_BIT)     ? " spec," : "",
+            (flags & VIA_FOG_BIT)      ? " fog," : "",
+            (flags & VIA_TEX0_BIT)     ? " tex-0," : "",
+            (flags & VIA_TEX1_BIT)     ? " tex-1," : "");
+#endif
+}
+
+void viaCheckTexSizes(GLcontext *ctx) {
+    TNLcontext *tnl = TNL_CONTEXT(ctx);
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+#ifdef DEBUG    
+    if (VIA_DEBUG) {    
+       fprintf(stderr, "%s - in\n", __FUNCTION__);
+       fprintf(stderr, "setupIndex = %x\n", vmesa->setupIndex);
+    }  
+#endif
+    if (!setup_tab[vmesa->setupIndex].check_tex_sizes(ctx)) {
+        /* Invalidate stored verts
+         */
+        vmesa->setupNewInputs = ~0;
+        vmesa->setupIndex |= VIA_PTEX_BIT;
+
+        if (!vmesa->Fallback &&
+            !(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;
+        }
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+void viaBuildVertices(GLcontext *ctx,
+                      GLuint start,
+                      GLuint count,
+                      GLuint newinputs) 
+{
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    GLubyte *v = ((GLubyte *)vmesa->verts + (start << vmesa->vertex_stride_shift));
+    GLuint stride = 1 << vmesa->vertex_stride_shift;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    newinputs |= vmesa->setupNewInputs;
+    vmesa->setupNewInputs = 0;
+    if (!newinputs)
+        return;
+    if (newinputs & VERT_CLIP) {
+        setup_tab[vmesa->setupIndex].emit(ctx, start, count, v, stride);
+    }
+    else {
+        GLuint ind = 0;
+
+        if (newinputs & VERT_RGBA)
+            ind |= VIA_RGBA_BIT;
+
+        if (newinputs & VERT_BIT_COLOR1)
+            ind |= VIA_SPEC_BIT;
+
+        if (newinputs & VERT_TEX(0))
+            ind |= VIA_TEX0_BIT;
+
+        if (newinputs & VERT_TEX(1))
+            ind |= VIA_TEX1_BIT;
+
+        if (newinputs & VERT_BIT_FOG)
+            ind |= VIA_FOG_BIT;
+
+        if (vmesa->setupIndex & VIA_PTEX_BIT)
+            ind = ~0;
+       
+        ind &= vmesa->setupIndex;
+       ind |= VIA_XYZW_BIT;
+        
+       if (ind) {
+            setup_tab[ind].emit(ctx, start, count, v, stride);
+        }
+    }
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+void viaChooseVertexState(GLcontext *ctx) {
+    TNLcontext *tnl = TNL_CONTEXT(ctx);
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    GLuint ind = VIA_XYZW_BIT | VIA_RGBA_BIT;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+    if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+        ind |= VIA_SPEC_BIT;
+
+    if (ctx->Fog.Enabled)
+        ind |= VIA_FOG_BIT;
+
+    if (ctx->Texture.Unit[1]._ReallyEnabled)
+        ind |= VIA_TEX1_BIT | VIA_TEX0_BIT;
+    else if (ctx->Texture.Unit[0]._ReallyEnabled)
+        ind |= VIA_TEX0_BIT;
+
+    vmesa->setupIndex = ind;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "setupIndex = %x\n", vmesa->setupIndex);
+#endif
+
+    if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
+        tnl->Driver.Render.Interp = via_interp_extras;
+        tnl->Driver.Render.CopyPV = via_copy_pv_extras;
+    }
+    else {
+        tnl->Driver.Render.Interp = setup_tab[ind].interp;
+        tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
+    }
+
+        vmesa->vertex_size = setup_tab[ind].vertex_size;
+        vmesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+    
+}
+
+void via_emit_contiguous_verts(GLcontext *ctx,
+                               GLuint start,
+                               GLuint count) {
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    GLuint vertex_size = vmesa->vertex_size * 4;
+    GLuint *dest = viaCheckDma(vmesa, (count - start) * vertex_size);
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+    
+    if (VIA_DEBUG) fprintf(stderr, "choose setup_tab[0x%x]\n", vmesa->setupIndex);    
+#endif
+    setup_tab[vmesa->setupIndex].emit(ctx, start, count, dest, vertex_size);
+    vmesa->dmaLow += (count - start) * vertex_size;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+void viaInitVB(GLcontext *ctx) {
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+    GLuint size = TNL_CONTEXT(ctx)->vb.Size;
+
+    vmesa->verts = ALIGN_MALLOC(size * 4 * 16, 32);
+
+    {
+        static int firsttime = 1;
+        if (firsttime) {
+            init_setup_tab();
+            firsttime = 0;
+        }
+    }
+}
+
+void viaFreeVB(GLcontext *ctx) {
+    viaContextPtr vmesa = VIA_CONTEXT(ctx);
+
+    if (vmesa->verts) {
+        ALIGN_FREE(vmesa->verts);
+        vmesa->verts = 0;
+    }
+
+    if (vmesa->UbyteSecondaryColor.Ptr) {
+        ALIGN_FREE((void*)vmesa->UbyteSecondaryColor.Ptr);
+        vmesa->UbyteSecondaryColor.Ptr = 0;
+    }
+
+    if (vmesa->UbyteColor.Ptr) {
+        ALIGN_FREE((void*)vmesa->UbyteColor.Ptr);
+        vmesa->UbyteColor.Ptr = 0;
+    }
+}
diff --git a/src/mesa/drivers/dri/unichrome/via_vb.h b/src/mesa/drivers/dri/unichrome/via_vb.h
new file mode 100644 (file)
index 0000000..63d8c04
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _VIAVB_H
+#define _VIAVB_H
+
+#include "mtypes.h"
+#include "swrast/swrast.h"
+
+#define VIA_TEX1_BIT   0x0001
+#define VIA_TEX0_BIT   0x0002
+#define VIA_RGBA_BIT   0x0004
+#define VIA_SPEC_BIT   0x0008
+#define VIA_FOG_BIT    0x0010
+#define VIA_XYZW_BIT   0x0020
+#define VIA_PTEX_BIT   0x0040
+#define VIA_MAX_SETUP  0x0080
+
+#define _VIA_NEW_VERTEX (_NEW_TEXTURE |                         \
+                         _DD_NEW_SEPARATE_SPECULAR |            \
+                         _DD_NEW_TRI_UNFILLED |                 \
+                         _DD_NEW_TRI_LIGHT_TWOSIDE |            \
+                         _NEW_FOG)
+
+
+extern void viaChooseVertexState(GLcontext *ctx);
+extern void viaCheckTexSizes(GLcontext *ctx);
+extern void viaBuildVertices(GLcontext *ctx,
+                             GLuint start,
+                             GLuint count,
+                             GLuint newinputs);
+
+
+extern void via_emit_contiguous_verts(GLcontext *ctx,
+                                      GLuint start,
+                                      GLuint count);
+
+extern void via_translate_vertex(GLcontext *ctx,
+                                 const viaVertex *src,
+                                 SWvertex *dst);
+
+extern void viaInitVB(GLcontext *ctx);
+extern void viaFreeVB(GLcontext *ctx);
+
+extern void via_print_vertex(GLcontext *ctx, const viaVertex *v);
+extern void viaPrintSetupFlags(char *msg, GLuint flags);
+
+#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_vb_rendertmp.h b/src/mesa/drivers/dri/unichrome/via_vb_rendertmp.h
new file mode 100644 (file)
index 0000000..aa130f9
--- /dev/null
@@ -0,0 +1,509 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef POSTFIX
+#define POSTFIX
+#endif
+
+#ifndef INIT
+#define INIT(x)
+#endif
+
+#ifndef NEED_EDGEFLAG_SETUP
+#define NEED_EDGEFLAG_SETUP 0
+#define EDGEFLAG_GET(a) 0
+#define EDGEFLAG_SET(a,b) (void)b
+#endif
+
+#ifndef RESET_STIPPLE
+#define RESET_STIPPLE
+#endif
+
+#ifndef RESET_OCCLUSION
+#define RESET_OCCLUSION
+#endif
+
+#ifndef TEST_PRIM_END
+#define TEST_PRIM_END(flags) (flags & PRIM_END)
+#define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN)
+#define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY)
+#endif
+
+#ifndef ELT
+#define ELT(x) x
+#endif
+
+#ifndef RENDER_TAB_QUALIFIER
+#define RENDER_TAB_QUALIFIER static
+#endif
+
+static void TAG(render_points)(GLcontext *ctx,
+                               GLuint start,
+                               GLuint count,
+                               GLuint flags)
+{
+    LOCAL_VARS;
+    (void)flags;
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif
+
+    RESET_OCCLUSION;
+    INIT(GL_POINTS);
+    RENDER_POINTS(start, count);
+    POSTFIX;
+}
+
+static void TAG(render_lines)(GLcontext *ctx,
+                              GLuint start,
+                              GLuint count,
+                              GLuint flags)
+{
+    GLuint j;
+    LOCAL_VARS;
+    (void)flags;
+    
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif
+    RESET_OCCLUSION;
+    INIT(GL_LINES);
+    for (j = start + 1; j < count; j += 2) {
+        RESET_STIPPLE;
+        RENDER_LINE(ELT(j - 1), ELT(j));
+    }
+    POSTFIX;
+}
+
+static void TAG(render_line_strip)(GLcontext *ctx,
+                                   GLuint start,
+                                   GLuint count,
+                                   GLuint flags)
+{
+    GLuint j;
+    LOCAL_VARS;
+    (void)flags;
+#ifdef DEBUG    
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif
+    RESET_OCCLUSION;
+    INIT(GL_LINES);
+
+    if (TEST_PRIM_BEGIN(flags)) {
+        RESET_STIPPLE;
+    }
+
+    for (j = start + 1; j < count; j++)
+        RENDER_LINE(ELT(j - 1), ELT(j));
+
+    POSTFIX;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+static void TAG(render_line_loop)(GLcontext *ctx,
+                                  GLuint start,
+                                  GLuint count,
+                                  GLuint flags)
+{
+    GLuint i;
+    LOCAL_VARS;
+    (void)flags;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    RESET_OCCLUSION;
+    INIT(GL_LINES);
+
+    if (start + 1 < count) {
+        if (TEST_PRIM_BEGIN(flags)) {
+            RESET_STIPPLE;
+            RENDER_LINE(ELT(start), ELT(start + 1));
+        }
+
+        for (i = start + 2 ; i < count ; i++) {
+            RENDER_LINE(ELT(i - 1), ELT(i));
+        }
+
+        if (TEST_PRIM_END(flags)) {
+            RENDER_LINE(ELT(count - 1), ELT(start));
+        }
+    }
+
+    POSTFIX;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+static void TAG(render_triangles)(GLcontext *ctx,
+                                  GLuint start,
+                                  GLuint count,
+                                  GLuint flags)
+{
+    GLuint j;
+    LOCAL_VARS;
+    (void)flags;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    INIT(GL_TRIANGLES);
+    if (NEED_EDGEFLAG_SETUP) {
+        for (j = start + 2; j < count; j += 3) {
+           /* Leave the edgeflags as supplied by the user.
+            */
+           RESET_STIPPLE;
+           RENDER_TRI(ELT(j - 2), ELT(j - 1), ELT(j));
+        }
+    }
+    else {
+        for (j = start + 2; j < count; j += 3) {
+            RENDER_TRI(ELT(j - 2), ELT(j - 1), ELT(j));
+        }
+    }
+    POSTFIX;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
+static void TAG(render_tri_strip)(GLcontext *ctx,
+                                  GLuint start,
+                                  GLuint count,
+                                  GLuint flags)
+{
+    GLuint j;
+    GLuint parity = 0;
+    LOCAL_VARS;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    if (TEST_PRIM_PARITY(flags))
+        parity = 1;
+
+    INIT(GL_TRIANGLES);
+    
+    if (NEED_EDGEFLAG_SETUP) {
+        for (j = start + 2; j < count; j++, parity ^= 1) {
+            GLuint ej2 = ELT(j - 2 + parity);
+            GLuint ej1 = ELT(j - 1 - parity);
+            GLuint ej = ELT(j);
+            GLboolean ef2 = EDGEFLAG_GET(ej2);
+            GLboolean ef1 = EDGEFLAG_GET(ej1);
+            GLboolean ef = EDGEFLAG_GET(ej);
+            if (TEST_PRIM_BEGIN(flags)) {
+                RESET_STIPPLE;
+            }
+            EDGEFLAG_SET(ej2, GL_TRUE);
+            EDGEFLAG_SET(ej1, GL_TRUE);
+            EDGEFLAG_SET(ej, GL_TRUE);
+            RENDER_TRI(ej2, ej1, ej);
+            EDGEFLAG_SET(ej2, ef2);
+            EDGEFLAG_SET(ej1, ef1);
+            EDGEFLAG_SET(ej, ef);
+        }
+    }
+    else {
+        for (j = start + 2; j < count; j++, parity ^= 1) {
+            RENDER_TRI(ELT(j - 2 + parity), ELT(j - 1 - parity), ELT(j));
+        }
+    }
+    POSTFIX;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+static void TAG(render_tri_fan)(GLcontext *ctx,
+                                GLuint start,
+                                GLuint count,
+                                GLuint flags)
+{
+    GLuint j;
+    LOCAL_VARS;
+    (void)flags;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    INIT(GL_TRIANGLES);
+    if (NEED_EDGEFLAG_SETUP) {
+        for (j = start + 2; j < count; j++) {
+            /* For trifans, all edges are boundary.
+             */
+            GLuint ejs = ELT(start);
+            GLuint ej1 = ELT(j - 1);
+            GLuint ej = ELT(j);
+            GLboolean efs = EDGEFLAG_GET(ejs);
+            GLboolean ef1 = EDGEFLAG_GET(ej1);
+            GLboolean ef = EDGEFLAG_GET(ej);
+            if (TEST_PRIM_BEGIN(flags)) {
+                RESET_STIPPLE;
+            }
+            EDGEFLAG_SET(ejs, GL_TRUE);
+            EDGEFLAG_SET(ej1, GL_TRUE);
+            EDGEFLAG_SET(ej, GL_TRUE);
+            RENDER_TRI(ejs, ej1, ej);
+            EDGEFLAG_SET(ejs, efs);
+            EDGEFLAG_SET(ej1, ef1);
+            EDGEFLAG_SET(ej, ef);
+        }
+    }
+    else {
+        for (j = start + 2; j < count; j++) {
+            RENDER_TRI(ELT(start), ELT(j - 1), ELT(j));
+        }
+    }
+    
+    POSTFIX;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
+#endif
+}
+
+static void TAG(render_poly)(GLcontext *ctx,
+                             GLuint start,
+                             GLuint count,
+                             GLuint flags)
+{
+    GLuint j = start + 2;
+    LOCAL_VARS;
+    (void)flags;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    INIT(GL_TRIANGLES);
+    
+    if (NEED_EDGEFLAG_SETUP) {
+        GLboolean efstart = EDGEFLAG_GET(ELT(start));
+        GLboolean efcount = EDGEFLAG_GET(ELT(count - 1));
+
+        /* If the primitive does not begin here, the first edge
+         * is non-boundary.
+         */
+        if (!TEST_PRIM_BEGIN(flags)) {
+            EDGEFLAG_SET(ELT(start), GL_FALSE);
+       }
+        else {
+            RESET_STIPPLE;
+        }
+
+        /* If the primitive does not end here, the final edge is
+         * non-boundary.
+         */
+        if (!TEST_PRIM_END(flags)) {
+            EDGEFLAG_SET(ELT(count - 1), GL_FALSE);
+       }
+
+        /* Draw the first triangles (possibly zero)
+         */
+        if (j+1<count) {
+            GLboolean ef = EDGEFLAG_GET(ELT(j));
+            EDGEFLAG_SET(ELT(j), GL_FALSE);
+            RENDER_TRI(ELT(j - 1), ELT(j), ELT(start));
+            EDGEFLAG_SET(ELT(j), ef);
+            j++;
+
+            /* Don't render the first edge again:
+             */
+            EDGEFLAG_SET(ELT(start), GL_FALSE);
+           
+            for (;j+1<count;j++) {
+                GLboolean efj = EDGEFLAG_GET(ELT(j));
+                EDGEFLAG_SET(ELT(j), GL_FALSE);
+                RENDER_TRI(ELT(j - 1), ELT(j), ELT(start));
+                EDGEFLAG_SET(ELT(j), efj);
+            }
+        }
+
+        /* Draw the last or only triangle
+         */
+        if (j < count) {
+            RENDER_TRI(ELT(j-1), ELT(j), ELT(start));
+       }
+
+        /* Restore the first and last edgeflags:
+         */
+        EDGEFLAG_SET(ELT(count - 1), efcount);
+        EDGEFLAG_SET(ELT(start), efstart);
+     }
+     else {
+        for (j = start + 2; j < count; j++) {
+            RENDER_TRI(ELT(j - 1), ELT(j), ELT(start));
+        }
+    }
+    POSTFIX;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+static void TAG(render_quads)(GLcontext *ctx,
+                              GLuint start,
+                              GLuint count,
+                              GLuint flags)
+{
+    GLuint j;
+    LOCAL_VARS;
+    (void)flags;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
+#endif
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    INIT(GL_TRIANGLES);
+    if (NEED_EDGEFLAG_SETUP) {
+        for (j = start + 3; j < count; j += 4) {
+            /* Use user-specified edgeflags for quads.
+             */
+            RESET_STIPPLE;
+            RENDER_QUAD(ELT(j - 3), ELT(j - 2), ELT(j - 1), ELT(j));
+        }
+    }
+    else {
+        for (j = start + 3; j < count; j += 4) {
+            RENDER_QUAD(ELT(j - 3), ELT(j - 2), ELT(j - 1), ELT(j));
+        }
+    }
+    POSTFIX;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+static void TAG(render_quad_strip)(GLcontext *ctx,
+                                   GLuint start,
+                                   GLuint count,
+                                   GLuint flags)
+{
+    GLuint j;
+    LOCAL_VARS;
+    (void)flags;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);    
+#endif
+#ifdef PERFORMANCE_MEASURE    
+    if (VIA_PERFORMANCE) P_M;
+#endif    
+    INIT(GL_TRIANGLES);
+    if (NEED_EDGEFLAG_SETUP) {
+        for (j = start + 3; j < count; j += 2) {
+            /* All edges are boundary.  Set edgeflags to 1, draw the
+             * quad, and restore them to the original values.
+             */
+            GLboolean ef3 = EDGEFLAG_GET(ELT(j - 3));
+            GLboolean ef2 = EDGEFLAG_GET(ELT(j - 2));
+            GLboolean ef1 = EDGEFLAG_GET(ELT(j - 1));
+            GLboolean ef = EDGEFLAG_GET(ELT(j));
+            if (TEST_PRIM_BEGIN(flags)) {
+                RESET_STIPPLE;
+            }
+            EDGEFLAG_SET(ELT(j - 3), GL_TRUE);
+            EDGEFLAG_SET(ELT(j - 2), GL_TRUE);
+            EDGEFLAG_SET(ELT(j - 1), GL_TRUE);
+            EDGEFLAG_SET(ELT(j), GL_TRUE);
+            RENDER_QUAD(ELT(j - 1), ELT(j - 3), ELT(j - 2), ELT(j));
+            EDGEFLAG_SET(ELT(j - 3), ef3);
+            EDGEFLAG_SET(ELT(j - 2), ef2);
+            EDGEFLAG_SET(ELT(j - 1), ef1);
+            EDGEFLAG_SET(ELT(j), ef);
+        }
+    }
+    else {
+        for (j = start + 3; j < count; j += 2) {
+            RENDER_QUAD(ELT(j - 1), ELT(j - 3), ELT(j - 2), ELT(j));
+        }
+    }
+    POSTFIX;
+#ifdef DEBUG
+    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
+#endif
+}
+
+static void TAG(render_noop)(GLcontext *ctx,
+                             GLuint start,
+                             GLuint count,
+                             GLuint flags)
+{
+    (void)(ctx && start && count && flags);
+}
+
+RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON + 2])(GLcontext *,
+                                                             GLuint,
+                                                             GLuint,
+                                                             GLuint) =
+{
+    TAG(render_points),
+    TAG(render_lines),
+    TAG(render_line_loop),
+    TAG(render_line_strip),
+    TAG(render_triangles),
+    TAG(render_tri_strip),
+    TAG(render_tri_fan),
+    TAG(render_quads),
+    TAG(render_quad_strip),
+    TAG(render_poly),
+    TAG(render_noop),
+};
+
+#ifndef PRESERVE_VB_DEFS
+#undef RENDER_TRI
+#undef RENDER_QUAD
+#undef RENDER_LINE
+#undef RENDER_POINTS
+#undef LOCAL_VARS
+#undef INIT
+#undef POSTFIX
+#undef RESET_STIPPLE
+#undef DBG
+#undef ELT
+#undef RENDER_TAB_QUALIFIER
+#endif
+
+#ifndef PRESERVE_TAG
+#undef TAG
+#endif
+
+#undef PRESERVE_VB_DEFS
+#undef PRESERVE_TAG
diff --git a/src/mesa/drivers/dri/unichrome/xf86drmVIA.c b/src/mesa/drivers/dri/unichrome/xf86drmVIA.c
new file mode 100644 (file)
index 0000000..e39bdf7
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef XFree86Server
+# include "xf86.h"
+# include "xf86_OSproc.h"
+# include "xf86_ansic.h"
+# define _DRM_MALLOC xalloc
+# define _DRM_FREE   xfree
+# ifndef XFree86LOADER
+#  include <sys/mman.h>
+# endif
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <ctype.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <signal.h>
+# include <sys/types.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/time.h>
+# ifdef DRM_USE_MALLOC
+#  define _DRM_MALLOC malloc
+#  define _DRM_FREE   free
+extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *);
+extern int xf86RemoveSIGIOHandler(int fd);
+# else
+#  include <X11/Xlibint.h>
+#  define _DRM_MALLOC Xmalloc
+#  define _DRM_FREE   Xfree
+# endif
+#endif
+
+/* Not all systems have MAP_FAILED defined */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#ifdef __linux__
+#include <sys/sysmacros.h>     /* for makedev() */
+#endif
+#include "xf86drm.h"
+#include "xf86drmVIA.h"
+#include "drm.h"
+#include "via_common.h"
+int drmVIAAgpInit(int fd, int offset, int size)
+{
+    drm_via_agp_t agp;
+    agp.offset = offset;
+    agp.size = size;
+
+    if (ioctl(fd, DRM_IOCTL_VIA_AGP_INIT, &agp) < 0) {
+         return -errno;
+    }
+    else {
+        return 0;
+    }
+}
+
+int drmVIAFBInit(int fd, int offset, int size)
+{
+    drm_via_fb_t fb;
+    fb.offset = offset;
+    fb.size = size;
+
+    if (ioctl(fd, DRM_IOCTL_VIA_FB_INIT, &fb) < 0) {
+       return -errno;
+    }
+    else
+       return 0;
+}
+
+int drmVIAInitMAP(int fd, drmVIAInit *info)
+{
+    drm_via_init_t init;
+
+    memset(&init, 0, sizeof(drm_via_init_t));
+    init.func = VIA_INIT_MAP;  
+    init.sarea_priv_offset = info->sarea_priv_offset;  
+    init.fb_offset = info->fb_offset;
+    init.mmio_offset = info->mmio_offset;
+    init.agpAddr = info->agpAddr;
+   
+    if (ioctl(fd, DRM_IOCTL_VIA_MAP_INIT, &init ) < 0) {
+        return -errno;
+    }
+    else
+        return 0;
+}
+
+int drmVIAAllocateDMA(int fd, drmVIADMABuf *buf)
+{
+    if (drmAddMap(fd, 0, buf->size,
+                  DRM_SHM, 0,
+                  &buf->index) < 0) {
+               return -errno;
+    }
+    
+    if (drmMap(fd,(drmHandle)buf->index,
+               buf->size,(drmAddressPtr)(&buf->address)) < 0) {
+       return -errno;
+    }
+    
+    memset(buf->address, 0, buf->size);
+       
+    return 0;
+}
+
+int drmVIAReleaseDMA(int fd, drmVIADMABuf *buf)
+{      
+    if (drmUnmap((drmAddress)(buf->address), buf->size) < 0)
+       return -errno;
+    
+    return 0;
+}
diff --git a/src/mesa/drivers/dri/unichrome/xf86drmVIA.h b/src/mesa/drivers/dri/unichrome/xf86drmVIA.h
new file mode 100644 (file)
index 0000000..4b64579
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __XF86DRI_VIA_H__
+#define __XF86DRI_VIA_H__
+
+typedef struct {
+    unsigned long sarea_priv_offset;
+    unsigned long fb_offset;
+    unsigned long mmio_offset;
+    unsigned long agpAddr;
+} drmVIAInit;
+
+typedef struct {
+    unsigned int offset;
+    unsigned int size;
+       unsigned int index;
+} drmVIAAGPBuf;
+
+typedef struct {
+    unsigned int offset;
+    unsigned int size;
+    unsigned long index;
+    unsigned long *address;
+} drmVIADMABuf;
+
+extern int drmVIAAgpInit(int fd, int offset, int size);
+extern int drmVIAFBInit(int fd, int offset, int size);
+extern int drmVIAInitMAP(int fd, drmVIAInit *info);
+extern int drmVIAAllocateDMA(int fd, drmVIADMABuf *buf);
+extern int drmVIAReleaseDMA(int fd, drmVIADMABuf *buf);
+
+#endif