summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2010-03-11 14:18:41 +0100
committerLuc Verhaegen <libv@skynet.be>2010-03-11 14:18:41 +0100
commitbf6a158b95d810d06344b4ca9395e4ebbca8bda9 (patch)
tree36a709a98723329d45cf43154e0fb93278a07cbd
parent5dee9b7b19c1aa3a13618b08bc24f00677b5364b (diff)
Import unichrome dri driver from mesa 7.0.3.7.0.47.0.3
-rw-r--r--configure.ac5
-rw-r--r--src/Makefile.am22
-rw-r--r--src/server/via.h11
-rw-r--r--src/server/via_dri.c1252
-rw-r--r--src/server/via_dri.h78
-rw-r--r--src/server/via_driver.h309
-rw-r--r--src/server/via_priv.h70
-rw-r--r--src/server/via_regs.h198
-rw-r--r--src/via_3d_reg.h1652
-rw-r--r--src/via_context.c956
-rw-r--r--src/via_context.h423
-rw-r--r--src/via_drmclient.h29
-rw-r--r--src/via_fb.c243
-rw-r--r--src/via_fb.h42
-rw-r--r--src/via_ioctl.c981
-rw-r--r--src/via_ioctl.h133
-rw-r--r--src/via_memcpy.c138
-rw-r--r--src/via_render.c131
-rw-r--r--src/via_screen.c499
-rw-r--r--src/via_screen.h95
-rw-r--r--src/via_span.c195
-rw-r--r--src/via_span.h35
-rw-r--r--src/via_state.c1527
-rw-r--r--src/via_state.h39
-rw-r--r--src/via_tex.c988
-rw-r--r--src/via_tex.h41
-rw-r--r--src/via_texcombine.c424
-rw-r--r--src/via_tris.c1194
-rw-r--r--src/via_tris.h35
29 files changed, 11738 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac
index 2a78cfd..4ce1052 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
# Process this file with autoconf to produce a configure script
AC_PREREQ(2.57)
-AC_INIT([mesa-dri-xxx], 7.0.3, [], mesa-dri-xxx)
+AC_INIT([mesa-dri-unichrome], 7.0.3, [], mesa-dri-unichrome)
AM_INIT_AUTOMAKE([dist-bzip2])
@@ -16,7 +16,8 @@ AC_PROG_CC
AC_HEADER_STDC
PKG_CHECK_MODULES([DRM], [libdrm >= 2.3.0])
-PKG_CHECK_MODULES([DRI], [libmesadri = 7.0.3 libmesadricommon = 7.0.3])
+PKG_CHECK_MODULES([DRI], [libmesadri >= 7.0.3 libmesadri < 7.1.0
+ libmesadricommon >= 7.0.3 libmesadricommon < 7.1.0])
AC_OUTPUT([
Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index aa854c5..4984403 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,19 @@
AM_CFLAGS = -DIN_DRI_DRIVER -DGLX_DIRECT_RENDERING -DGLX_INDIRECT_RENDERING
-xxx_dri_la_LTLIBRARIES = xxx_dri.la
-xxx_dri_la_CFLAGS = $(AM_CFLAGS) $(DRM_CFLAGS) $(DRI_CFLAGS) -Iserver
-xxx_dri_la_LDFLAGS = -module -noprefix -lm -ldl $(DRM_LIBS) $(DRI_LIBS)
-xxx_dri_ladir = @libdir@/dri
-xxx_dri_la_SOURCES = \
+unichrome_dri_la_LTLIBRARIES = unichrome_dri.la
+unichrome_dri_la_CFLAGS = $(AM_CFLAGS) $(DRM_CFLAGS) $(DRI_CFLAGS) -Iserver
+unichrome_dri_la_LDFLAGS = -module -noprefix -avoid-version -lm -ldl \
+ $(DRM_LIBS) $(DRI_LIBS)
+unichrome_dri_ladir = @libdir@/dri
+unichrome_dri_la_SOURCES = \
+ via_context.c \
+ via_fb.c \
+ via_tex.c \
+ via_ioctl.c \
+ via_memcpy.c \
+ via_render.c \
+ via_screen.c \
+ via_span.c \
+ via_state.c \
+ via_texcombine.c \
+ via_tris.c
diff --git a/src/server/via.h b/src/server/via.h
new file mode 100644
index 0000000..2cfe663
--- /dev/null
+++ b/src/server/via.h
@@ -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/server/via_dri.c b/src/server/via_dri.c
new file mode 100644
index 0000000..6944bd6
--- /dev/null
+++ b/src/server/via_dri.c
@@ -0,0 +1,1252 @@
+/* $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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "driver.h"
+#include "drm.h"
+#include "imports.h"
+
+#include "dri_util.h"
+
+#include "via_context.h"
+#include "via_dri.h"
+#include "via_driver.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);
+
+/* _SOLO : missing macros normally defined by X code */
+#define xf86DrvMsg(a, b, ...) fprintf(stderr, __VA_ARGS__)
+#define MMIO_IN8(base, addr) ((*(((volatile u_int8_t*)base)+(addr)))+0)
+#define MMIO_OUT8(base, addr, val) ((*(((volatile u_int8_t*)base)+(addr)))=((u_int8_t)val))
+#define MMIO_OUT16(base, addr, val) ((*(volatile u_int16_t*)(((u_int8_t*)base)+(addr)))=((u_int16_t)val))
+
+#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 512
+#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)
+
+static char VIAKernelDriverName[] = "via";
+static char VIAClientDriverName[] = "unichrome";
+
+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 void VIADRIIrqInit( DRIDriverContext *ctx )
+{
+ VIAPtr pVia = VIAPTR(ctx);
+ VIADRIPtr pVIADRI = pVia->devPrivate;
+
+ pVIADRI->irqEnabled = drmGetInterruptFromBusID(pVia->drmFD,
+ ctx->pciBus,
+ ctx->pciDevice,
+ ctx->pciFunc);
+
+ if ((drmCtlInstHandler(pVia->drmFD, pVIADRI->irqEnabled))) {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[drm] Failure adding irq handler. "
+ "Falling back to irq-free operation.\n");
+ pVIADRI->irqEnabled = 0;
+ }
+
+ if (pVIADRI->irqEnabled)
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Irq handler installed, using IRQ %d.\n",
+ pVIADRI->irqEnabled);
+}
+
+static void VIADRIIrqExit( DRIDriverContext *ctx ) {
+ VIAPtr pVia = VIAPTR(ctx);
+ VIADRIPtr pVIADRI = pVia->devPrivate;
+
+ if (pVIADRI->irqEnabled) {
+ if (drmCtlUninstHandler(pVia->drmFD)) {
+ xf86DrvMsg(pScreen-myNum, X_INFO,"[drm] Irq handler uninstalled.\n");
+ } else {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] Could not uninstall irq handler.\n");
+ }
+ }
+}
+
+static void VIADRIRingBufferCleanup(DRIDriverContext *ctx)
+{
+ VIAPtr pVia = VIAPTR(ctx);
+ VIADRIPtr pVIADRI = pVia->devPrivate;
+ drm_via_dma_init_t ringBufInit;
+
+ if (pVIADRI->ringBufActive) {
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Cleaning up DMA ring-buffer.\n");
+ ringBufInit.func = VIA_CLEANUP_DMA;
+ if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit,
+ sizeof(ringBufInit))) {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[drm] Failed to clean up DMA ring-buffer: %d\n", errno);
+ }
+ pVIADRI->ringBufActive = 0;
+ }
+}
+
+static int VIADRIRingBufferInit(DRIDriverContext *ctx)
+{
+ VIAPtr pVia = VIAPTR(ctx);
+ VIADRIPtr pVIADRI = pVia->devPrivate;
+ drm_via_dma_init_t ringBufInit;
+ drmVersionPtr drmVer;
+
+ pVIADRI->ringBufActive = 0;
+
+ if (NULL == (drmVer = drmGetVersion(pVia->drmFD))) {
+ return GL_FALSE;
+ }
+
+ if (((drmVer->version_major <= 1) && (drmVer->version_minor <= 3))) {
+ return GL_FALSE;
+ }
+
+ /*
+ * Info frome code-snippet on DRI-DEVEL list; Erdi Chen.
+ */
+
+ switch (pVia->ChipId) {
+ case PCI_CHIP_VT3259:
+ ringBufInit.reg_pause_addr = 0x40c;
+ break;
+ default:
+ ringBufInit.reg_pause_addr = 0x418;
+ break;
+ }
+
+ ringBufInit.offset = pVia->agpSize;
+ ringBufInit.size = AGP_CMDBUF_SIZE;
+ ringBufInit.func = VIA_INIT_DMA;
+ if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit,
+ sizeof(ringBufInit))) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] Failed to initialize DMA ring-buffer: %d\n", errno);
+ return GL_FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Initialized AGP ring-buffer, size 0x%lx at AGP offset 0x%lx.\n",
+ ringBufInit.size, ringBufInit.offset);
+
+ pVIADRI->ringBufActive = 1;
+ return GL_TRUE;
+}
+
+static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia)
+{
+ unsigned long agp_phys;
+ drmAddress 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 GL_FALSE;
+ }
+
+ if (drmAgpEnable(pVia->drmFD, drmAgpGetMode(pVia->drmFD)&~0x0) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpEnable failed\n");
+ return GL_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 GL_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 GL_FALSE;
+ }
+
+ /*
+ * Place the ring-buffer last in the AGP region, and restrict the
+ * public map not to include the buffer for security reasons.
+ */
+
+ pVia->agpSize = AGP_SIZE - AGP_CMDBUF_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, (drm_handle_t)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 GL_FALSE;
+ }
+ /* Map AGP from kernel to Xserver - Not really needed */
+ drmMap(pVia->drmFD, pVIADRI->agp.handle,pVIADRI->agp.size, &agpaddr);
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] agpAddr = 0x%08lx\n", pVia->agpAddr);
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] agpSize = 0x%08lx\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-AGP_CMDBUF_SIZE;
+ if (drmCommandWrite(pVia->drmFD, DRM_VIA_AGP_INIT, &agp,
+ sizeof(drm_via_agp_t)) < 0) {
+ drmUnmap(&agpaddr,pVia->agpSize);
+ drmRmMap(pVia->drmFD,pVIADRI->agp.handle);
+ drmAgpUnbind(pVia->drmFD, pVia->agpHandle);
+ drmAgpFree(pVia->drmFD, pVia->agpHandle);
+ drmAgpRelease(pVia->drmFD);
+ return GL_FALSE;
+ }
+ }
+
+ return GL_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 GL_FALSE;
+ } else {
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] FBFreeStart= 0x%08x FBFreeEnd= 0x%08x "
+ "FBSize= 0x%08x\n",
+ pVia->FBFreeStart, pVia->FBFreeEnd, FBSize);
+ return GL_TRUE;
+ }
+ }
+}
+
+static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia)
+{
+ return GL_TRUE;
+}
+
+static int VIADRIScreenInit(DRIDriverContext * ctx)
+{
+ VIAPtr pVia = VIAPTR(ctx);
+ VIADRIPtr pVIADRI;
+ int err;
+
+#if 0
+ ctx->shared.SAREASize = ((sizeof(drm_sarea_t) + 0xfff) & 0x1000);
+#else
+ if (sizeof(drm_sarea_t)+sizeof(drm_via_sarea_t) > SAREA_MAX) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Data does not fit in SAREA\n");
+ return GL_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,
+ (drm_handle_t)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(sizeof(VIADRIRec));
+ if (!pVIADRI) {
+ drmClose(ctx->drmFD);
+ return GL_FALSE;
+ }
+ pVia->devPrivate = pVIADRI;
+ ctx->driverClientMsg = pVIADRI;
+ ctx->driverClientMsgSize = sizeof(*pVIADRI);
+
+ /* DRIScreenInit doesn't add all the common mappings. Add additional mappings here. */
+ if (!VIADRIMapInit(ctx, pVia)) {
+ VIADRICloseScreen(ctx);
+ return GL_FALSE;
+ }
+
+ pVIADRI->regs.size = VIA_MMIO_REGSIZE;
+ pVIADRI->regs.handle = pVia->registerHandle;
+ xf86DrvMsg(pScreen->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 GL_FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] mmio mapped.\n" );
+
+ VIAEnableMMIO(ctx);
+
+ /* Get video memory clock. */
+ VGAOUT8(0x3D4, 0x3D);
+ pVia->MemClk = (VGAIN8(0x3D5) & 0xF0) >> 4;
+ xf86DrvMsg(0, X_INFO, "[dri] MemClk (0x%x)\n", pVia->MemClk);
+
+ /* 3D rendering has noise if not enabled. */
+ VIAEnableExtendedFIFO(ctx);
+
+ VIAInitialize2DEngine(ctx);
+
+ /* Must disable MMIO or 3D won't work. */
+ VIADisableMMIO(ctx);
+
+ VIAInitialize3DEngine(ctx);
+
+ 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 fail .\n" );
+ return GL_FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] frame buffer initialized.\n" );
+
+ return VIADRIFinishScreenInit(ctx);
+}
+
+static void
+VIADRICloseScreen(DRIDriverContext * ctx)
+{
+ VIAPtr pVia = VIAPTR(ctx);
+ VIADRIPtr pVIADRI=(VIADRIPtr)pVia->devPrivate;
+
+ VIADRIRingBufferCleanup(ctx);
+
+ 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);
+ }
+
+#if 0
+ if (pVia->DRIIrqEnable)
+#endif
+ VIADRIIrqExit(ctx);
+}
+
+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 GL_FALSE;
+ }
+
+ DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0);
+
+
+ if (!VIADRIKernelInit(ctx, pVia)) {
+ VIADRICloseScreen(ctx);
+ return GL_FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] kernel data initialized.\n");
+
+ /* set SAREA value */
+ {
+ drm_via_sarea_t *saPriv;
+
+ saPriv=(drm_via_sarea_t*)(((char*)ctx->pSAREA) +
+ sizeof(drm_sarea_t));
+ 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(drm_sarea_t);
+ /* TODO */
+ pVIADRI->scrnX=pVIADRI->width;
+ pVIADRI->scrnY=pVIADRI->height;
+
+ /* Initialize IRQ */
+#if 0
+ if (pVia->DRIIrqEnable)
+#endif
+ VIADRIIrqInit(ctx);
+
+ pVIADRI->ringBufActive = 0;
+ VIADRIRingBufferInit(ctx);
+
+ return GL_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.sarea_priv_offset = sizeof(drm_sarea_t);
+ drmInfo.func = VIA_INIT_MAP;
+ drmInfo.fb_offset = pVia->FrameBufferBase;
+ drmInfo.mmio_offset = pVia->registerHandle;
+ if (pVia->IsPCI)
+ drmInfo.agpAddr = (u_int32_t)NULL;
+ else
+ drmInfo.agpAddr = (u_int32_t)pVia->agpAddr;
+
+ if ((drmCommandWrite(pVia->drmFD, DRM_VIA_MAP_INIT,&drmInfo,
+ sizeof(drm_via_init_t))) < 0)
+ return GL_FALSE;
+
+ return GL_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 GL_FALSE;
+ }
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] register handle = 0x%08lx\n", pVia->registerHandle);
+
+ return GL_TRUE;
+}
+
+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(0x3cc);
+ VGAOUT8(0x3c2, 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);
+ }
+
+ /* Unlock CRTC registers */
+ VGAOUT8(0x3d4, 0x47);
+ VGAOUT8(0x3d5, 0x00);
+
+ 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);
+ u_int32_t dwGE230, dwGE298;
+
+ /* Cause of exit XWindow will dump back register value, others chipset no
+ * need to set extended fifo value */
+ if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev < 15 &&
+ (ctx->shared.virtualWidth > 1024 || pVia->HasSecondary)) {
+ /* Turn off Extend FIFO */
+ /* 0x298[29] */
+ dwGE298 = VIAGETREG(0x298);
+ VIASETREG(0x298, dwGE298 | 0x20000000);
+ /* 0x230[21] */
+ dwGE230 = VIAGETREG(0x230);
+ VIASETREG(0x230, dwGE230 & ~0x00200000);
+ /* 0x298[29] */
+ dwGE298 = VIAGETREG(0x298);
+ VIASETREG(0x298, dwGE298 & ~0x20000000);
+ }
+}
+
+static void VIAEnableExtendedFIFO(DRIDriverContext *ctx)
+{
+ VIAPtr pVia = VIAPTR(ctx);
+ u_int8_t bRegTemp;
+ u_int32_t dwGE230, dwGE298;
+
+ switch (pVia->Chipset) {
+ case VIA_CLE266:
+ if (pVia->ChipRev > 14) { /* For 3123Cx */
+ if (pVia->HasSecondary) { /* SAMM or DuoView case */
+ if (ctx->shared.virtualWidth >= 1024)
+ {
+ /* 3c5.16[0:5] */
+ VGAOUT8(0x3C4, 0x16);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x3F;
+ bRegTemp |= 0x1C;
+ VGAOUT8(0x3C5, bRegTemp);
+ /* 3c5.17[0:6] */
+ VGAOUT8(0x3C4, 0x17);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x7F;
+ bRegTemp |= 0x3F;
+ VGAOUT8(0x3C5, bRegTemp);
+ pVia->EnableExtendedFIFO = GL_TRUE;
+ }
+ }
+ else /* Single view or Simultaneoue case */
+ {
+ if (ctx->shared.virtualWidth > 1024)
+ {
+ /* 3c5.16[0:5] */
+ VGAOUT8(0x3C4, 0x16);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x3F;
+ bRegTemp |= 0x17;
+ VGAOUT8(0x3C5, bRegTemp);
+ /* 3c5.17[0:6] */
+ VGAOUT8(0x3C4, 0x17);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x7F;
+ bRegTemp |= 0x2F;
+ VGAOUT8(0x3C5, bRegTemp);
+ pVia->EnableExtendedFIFO = GL_TRUE;
+ }
+ }
+ /* 3c5.18[0:5] */
+ VGAOUT8(0x3C4, 0x18);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x3F;
+ bRegTemp |= 0x17;
+ bRegTemp |= 0x40; /* force the preq always higher than treq */
+ VGAOUT8(0x3C5, bRegTemp);
+ }
+ else { /* for 3123Ax */
+ if (ctx->shared.virtualWidth > 1024 || pVia->HasSecondary) {
+ /* Turn on Extend FIFO */
+ /* 0x298[29] */
+ dwGE298 = VIAGETREG(0x298);
+ VIASETREG(0x298, dwGE298 | 0x20000000);
+ /* 0x230[21] */
+ dwGE230 = VIAGETREG(0x230);
+ VIASETREG(0x230, dwGE230 | 0x00200000);
+ /* 0x298[29] */
+ dwGE298 = VIAGETREG(0x298);
+ VIASETREG(0x298, dwGE298 & ~0x20000000);
+
+ /* 3c5.16[0:5] */
+ VGAOUT8(0x3C4, 0x16);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x3F;
+ bRegTemp |= 0x17;
+ /* bRegTemp |= 0x10; */
+ VGAOUT8(0x3C5, bRegTemp);
+ /* 3c5.17[0:6] */
+ VGAOUT8(0x3C4, 0x17);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x7F;
+ bRegTemp |= 0x2F;
+ /*bRegTemp |= 0x1F;*/
+ VGAOUT8(0x3C5, bRegTemp);
+ /* 3c5.18[0:5] */
+ VGAOUT8(0x3C4, 0x18);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x3F;
+ bRegTemp |= 0x17;
+ bRegTemp |= 0x40; /* force the preq always higher than treq */
+ VGAOUT8(0x3C5, bRegTemp);
+ pVia->EnableExtendedFIFO = GL_TRUE;
+ }
+ }
+ break;
+ case VIA_KM400:
+ if (pVia->HasSecondary) { /* SAMM or DuoView case */
+ if ((ctx->shared.virtualWidth >= 1600) &&
+ (pVia->MemClk <= VIA_MEM_DDR200)) {
+ /* enable CRT extendded FIFO */
+ VGAOUT8(0x3C4, 0x17);
+ VGAOUT8(0x3C5, 0x1C);
+ /* revise second display queue depth and read threshold */
+ VGAOUT8(0x3C4, 0x16);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x3F;
+ bRegTemp = (bRegTemp) | (0x09);
+ VGAOUT8(0x3C5, bRegTemp);
+ }
+ else {
+ /* enable CRT extendded FIFO */
+ VGAOUT8(0x3C4, 0x17);
+ VGAOUT8(0x3C5,0x3F);
+ /* revise second display queue depth and read threshold */
+ VGAOUT8(0x3C4, 0x16);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x3F;
+ bRegTemp = (bRegTemp) | (0x1C);
+ VGAOUT8(0x3C5, bRegTemp);
+ }
+ /* 3c5.18[0:5] */
+ VGAOUT8(0x3C4, 0x18);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x3F;
+ bRegTemp |= 0x17;
+ bRegTemp |= 0x40; /* force the preq always higher than treq */
+ VGAOUT8(0x3C5, bRegTemp);
+ pVia->EnableExtendedFIFO = GL_TRUE;
+ }
+ else {
+ if ( (ctx->shared.virtualWidth > 1024) && (ctx->shared.virtualWidth <= 1280) )
+ {
+ /* enable CRT extendded FIFO */
+ VGAOUT8(0x3C4, 0x17);
+ VGAOUT8(0x3C5, 0x3F);
+ /* revise second display queue depth and read threshold */
+ VGAOUT8(0x3C4, 0x16);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x3F;
+ bRegTemp = (bRegTemp) | (0x17);
+ VGAOUT8(0x3C5, bRegTemp);
+ pVia->EnableExtendedFIFO = GL_TRUE;
+ }
+ else if ((ctx->shared.virtualWidth > 1280))
+ {
+ /* enable CRT extendded FIFO */
+ VGAOUT8(0x3C4, 0x17);
+ VGAOUT8(0x3C5, 0x3F);
+ /* revise second display queue depth and read threshold */
+ VGAOUT8(0x3C4, 0x16);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x3F;
+ bRegTemp = (bRegTemp) | (0x1C);
+ VGAOUT8(0x3C5, bRegTemp);
+ pVia->EnableExtendedFIFO = GL_TRUE;
+ }
+ else
+ {
+ /* enable CRT extendded FIFO */
+ VGAOUT8(0x3C4, 0x17);
+ VGAOUT8(0x3C5, 0x3F);
+ /* revise second display queue depth and read threshold */
+ VGAOUT8(0x3C4, 0x16);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x3F;
+ bRegTemp = (bRegTemp) | (0x10);
+ VGAOUT8(0x3C5, bRegTemp);
+ }
+ /* 3c5.18[0:5] */
+ VGAOUT8(0x3C4, 0x18);
+ bRegTemp = VGAIN8(0x3C5);
+ bRegTemp &= ~0x3F;
+ bRegTemp |= 0x17;
+ bRegTemp |= 0x40; /* force the preq always higher than treq */
+ VGAOUT8(0x3C5, bRegTemp);
+ }
+ break;
+ case VIA_K8M800:
+ /*=* R1 Display FIFO depth (384 /8 -1 -> 0xbf) SR17[7:0] (8bits) *=*/
+ VGAOUT8(0x3c4, 0x17);
+ VGAOUT8(0x3c5, 0xbf);
+
+ /*=* R2 Display fetch datum threshold value (328/4 -> 0x52)
+ SR16[5:0], SR16[7] (7bits) *=*/
+ VGAOUT8(0x3c4, 0x16);
+ bRegTemp = VGAIN8(0x3c5) & ~0xBF;
+ bRegTemp |= (0x52 & 0x3F);
+ bRegTemp |= ((0x52 & 0x40) << 1);
+ VGAOUT8(0x3c5, bRegTemp);
+
+ /*=* R3 Switch to the highest agent threshold value (74 -> 0x4a)
+ SR18[5:0], SR18[7] (7bits) *=*/
+ VGAOUT8(0x3c4, 0x18);
+ bRegTemp = VGAIN8(0x3c5) & ~0xBF;
+ bRegTemp |= (0x4a & 0x3F);
+ bRegTemp |= ((0x4a & 0x40) << 1);
+ VGAOUT8(0x3c5, bRegTemp);
+#if 0
+ /*=* R4 Fetch Number for a scan line (unit: 8 bytes)
+ SR1C[7:0], SR1D[1:0] (10bits) *=*/
+ wRegTemp = (pBIOSInfo->offsetWidthByQWord >> 1) + 4;
+ VGAOUT8(0x3c4, 0x1c);
+ VGAOUT8(0x3c5, (u_int8_t)(wRegTemp & 0xFF));
+ VGAOUT8(0x3c4, 0x1d);
+ bRegTemp = VGAIN8(0x3c5) & ~0x03;
+ VGAOUT8(0x3c5, bRegTemp | ((wRegTemp & 0x300) >> 8));
+#endif
+ if (ctx->shared.virtualWidth >= 1400 && ctx->bpp == 32)
+ {
+ /*=* Max. length for a request SR22[4:0] (64/4 -> 0x10) *=*/
+ VGAOUT8(0x3c4, 0x22);
+ bRegTemp = VGAIN8(0x3c5) & ~0x1F;
+ VGAOUT8(0x3c5, bRegTemp | 0x10);
+ }
+ else
+ {
+ /*=* Max. length for a request SR22[4:0]
+ (128/4 -> over flow 0x0) *=*/
+ VGAOUT8(0x3c4, 0x22);
+ bRegTemp = VGAIN8(0x3c5) & ~0x1F;
+ VGAOUT8(0x3c5, bRegTemp);
+ }
+ break;
+ case VIA_PM800:
+ /*=* R1 Display FIFO depth (96-1 -> 0x5f) SR17[7:0] (8bits) *=*/
+ VGAOUT8(0x3c4, 0x17);
+ VGAOUT8(0x3c5, 0x5f);
+
+ /*=* R2 Display fetch datum threshold value (32 -> 0x20)
+ SR16[5:0], SR16[7] (7bits) *=*/
+ VGAOUT8(0x3c4, 0x16);
+ bRegTemp = VGAIN8(0x3c5) & ~0xBF;
+ bRegTemp |= (0x20 & 0x3F);
+ bRegTemp |= ((0x20 & 0x40) << 1);
+ VGAOUT8(0x3c5, bRegTemp);
+
+ /*=* R3 Switch to the highest agent threshold value (16 -> 0x10)
+ SR18[5:0], SR18[7] (7bits) *=*/
+ VGAOUT8(0x3c4, 0x18);
+ bRegTemp = VGAIN8(0x3c5) & ~0xBF;
+ bRegTemp |= (0x10 & 0x3F);
+ bRegTemp |= ((0x10 & 0x40) << 1);
+ VGAOUT8(0x3c5, bRegTemp);
+#if 0
+ /*=* R4 Fetch Number for a scan line (unit: 8 bytes)
+ SR1C[7:0], SR1D[1:0] (10bits) *=*/
+ wRegTemp = (pBIOSInfo->offsetWidthByQWord >> 1) + 4;
+ VGAOUT8(0x3c4, 0x1c);
+ VGAOUT8(0x3c5, (u_int8_t)(wRegTemp & 0xFF));
+ VGAOUT8(0x3c4, 0x1d);
+ bRegTemp = VGAIN8(0x3c5) & ~0x03;
+ VGAOUT8(0x3c5, bRegTemp | ((wRegTemp & 0x300) >> 8));
+#endif
+ if (ctx->shared.virtualWidth >= 1400 && ctx->bpp == 32)
+ {
+ /*=* Max. length for a request SR22[4:0] (64/4 -> 0x10) *=*/
+ VGAOUT8(0x3c4, 0x22);
+ bRegTemp = VGAIN8(0x3c5) & ~0x1F;
+ VGAOUT8(0x3c5, bRegTemp | 0x10);
+ }
+ else
+ {
+ /*=* Max. length for a request SR22[4:0] (0x1F) *=*/
+ VGAOUT8(0x3c4, 0x22);
+ bRegTemp = VGAIN8(0x3c5) & ~0x1F;
+ VGAOUT8(0x3c5, bRegTemp | 0x1F);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void VIAInitialize2DEngine(DRIDriverContext *ctx)
+{
+ VIAPtr pVia = VIAPTR(ctx);
+ u_int32_t dwVQStartAddr, dwVQEndAddr;
+ u_int32_t dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
+ u_int32_t 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);
+
+ VIADisableMMIO(ctx);
+
+ /* 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;
+ break;
+ 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
+
+ VIAEnableMMIO(ctx);
+
+ /* 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 int b3DRegsInitialized = 0;
+
+static void VIAInitialize3DEngine(DRIDriverContext *ctx)
+{
+ VIAPtr pVia = VIAPTR(ctx);
+ int i;
+
+ if (!b3DRegsInitialized)
+ {
+
+ VIASETREG(0x43C, 0x00010000);
+
+ for (i = 0; i <= 0x7D; i++)
+ {
+ VIASETREG(0x440, (u_int32_t) i << 24);
+ }
+
+ VIASETREG(0x43C, 0x00020000);
+
+ for (i = 0; i <= 0x94; i++)
+ {
+ VIASETREG(0x440, (u_int32_t) i << 24);
+ }
+
+ VIASETREG(0x440, 0x82400000);
+
+ VIASETREG(0x43C, 0x01020000);
+
+
+ for (i = 0; i <= 0x94; i++)
+ {
+ VIASETREG(0x440, (u_int32_t) i << 24);
+ }
+
+ VIASETREG(0x440, 0x82400000);
+ VIASETREG(0x43C, 0xfe020000);
+
+ for (i = 0; i <= 0x03; i++)
+ {
+ VIASETREG(0x440, (u_int32_t) 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);
+
+ 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
+WaitIdleCLE266(VIAPtr pVia)
+{
+ int loop = 0;
+
+ /*mem_barrier();*/
+
+ while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP))
+ ;
+
+ while ((VIAGETREG(VIA_REG_STATUS) &
+ (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
+ (loop++ < MAXLOOP))
+ ;
+
+ return loop >= MAXLOOP;
+}
+
+static int viaInitFBDev(DRIDriverContext *ctx)
+{
+ VIAPtr pVia = CALLOC(sizeof(*pVia));
+
+ ctx->driverPrivate = (void *)pVia;
+
+ switch (ctx->chipset) {
+ case PCI_CHIP_CLE3122:
+ case PCI_CHIP_CLE3022:
+ pVia->Chipset = VIA_CLE266;
+ break;
+ case PCI_CHIP_VT7205:
+ case PCI_CHIP_VT3205:
+ pVia->Chipset = VIA_KM400;
+ break;
+ case PCI_CHIP_VT3204:
+ case PCI_CHIP_VT3344:
+ pVia->Chipset = VIA_K8M800;
+ break;
+ case PCI_CHIP_VT3259:
+ pVia->Chipset = VIA_PM800;
+ break;
+ default:
+ xf86DrvMsg(0, X_ERROR, "VIA: Unknown device ID (0x%x)\n", ctx->chipset);
+ }
+
+ /* _SOLO TODO XXX need to read ChipRev too */
+ pVia->ChipRev = 0;
+
+ pVia->videoRambytes = ctx->shared.fbSize;
+ pVia->MmioBase = ctx->MMIOStart;
+ pVia->FrameBufferBase = ctx->FBStart & 0xfc000000;
+
+ pVia->FBFreeStart = ctx->shared.virtualWidth * ctx->cpp *
+ ctx->shared.virtualHeight;
+
+#if 1
+ /* Alloc a second framebuffer for the second head */
+ pVia->FBFreeStart += ctx->shared.virtualWidth * ctx->cpp *
+ ctx->shared.virtualHeight;
+#endif
+
+ pVia->VQStart = pVia->FBFreeStart;
+ pVia->VQEnd = pVia->FBFreeStart + VIA_VQ_SIZE - 1;
+
+ pVia->FBFreeStart += VIA_VQ_SIZE;
+
+ pVia->FBFreeEnd = pVia->videoRambytes;
+
+ if (!VIADRIScreenInit(ctx))
+ return 0;
+
+ 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 =
+{
+ viaValidateMode,
+ viaPostValidateMode,
+ viaInitFBDev,
+ viaHaltFBDev,
+ viaEngineShutdown,
+ viaEngineRestore,
+ 0,
+};
+
diff --git a/src/server/via_dri.h b/src/server/via_dri.h
new file mode 100644
index 0000000..b47397d
--- /dev/null
+++ b/src/server/via_dri.h
@@ -0,0 +1,78 @@
+/*
+ * 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+/*
+ * Keep this file in perfect sync between the ddx and dri drivers.
+ * At least bump the VIA_DRIDDX_VERSION defines appropriately.
+ *
+ */
+#ifndef _VIA_DRI_H_
+#define _VIA_DRI_H_ 1
+
+#define VIA_MAX_DRAWABLES 256
+
+#define VIA_DRIDDX_VERSION_MAJOR 5
+#define VIA_DRIDDX_VERSION_MINOR 0
+#define VIA_DRIDDX_VERSION_PATCH 0
+
+#ifndef XFree86Server
+typedef int Bool;
+#endif
+
+typedef struct {
+ drm_handle_t handle;
+ drmSize size;
+} 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;
+ Bool drixinerama;
+ int backOffset;
+ int depthOffset;
+ int textureOffset;
+ int textureSize;
+ int irqEnabled;
+ unsigned int scrnX, scrnY;
+ int sarea_priv_offset;
+ int ringBufActive;
+ unsigned int reg_pause_addr;
+} VIADRIRec, *VIADRIPtr;
+
+typedef struct {
+ int dummy;
+} VIAConfigPrivRec, *VIAConfigPrivPtr;
+
+typedef struct {
+ int dummy;
+} VIADRIContextRec, *VIADRIContextPtr;
+
+#endif /* _VIA_DRI_H_ */
diff --git a/src/server/via_driver.h b/src/server/via_driver.h
new file mode 100644
index 0000000..997b2e4
--- /dev/null
+++ b/src/server/via_driver.h
@@ -0,0 +1,309 @@
+/* $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
+
+#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_regs.h"
+
+#include "GL/internal/dri_interface.h"
+#include "via_dri.h"
+#endif
+
+/* _SOLO : copied from via_bios.h */
+/* System Memory CLK */
+#define VIA_MEM_SDR66 0x00
+#define VIA_MEM_SDR100 0x01
+#define VIA_MEM_SDR133 0x02
+#define VIA_MEM_DDR200 0x03
+#define VIA_MEM_DDR266 0x04
+#define VIA_MEM_DDR333 0x05
+#define VIA_MEM_DDR400 0x06
+
+#define DRIVER_NAME "via"
+#define DRIVER_VERSION "4.1.0"
+#define VERSION_MAJOR 4
+#define VERSION_MINOR 1
+#define PATCHLEVEL 41
+#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[83];
+ unsigned char TVRegs[0xCF];
+ unsigned char TVRegs2[0xCF];
+/* unsigned char LCDRegs[0x40];*/
+
+} VIARegRec, *VIARegPtr;
+
+
+typedef struct _VIA {
+ VIARegRec SavedReg;
+ VIARegRec ModeReg;
+#if 0
+ xf86CursorInfoPtr CursorInfoRec;
+ int stateMode;
+ VIAModeInfoPtr VIAModeList;
+#endif
+ int 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;
+
+ int PrimaryVidMapped;
+ int dacSpeedBpp;
+ int minClock, maxClock;
+ int MCLK, REFCLK, LCDclk;
+ double refclk_fact;
+
+ /* Here are all the Options */
+ int VQEnable;
+ int pci_burst;
+ int NoPCIRetry;
+ int hwcursor;
+ int NoAccel;
+ int shadowFB;
+ int NoDDCValue;
+ int rotate;
+
+#if 0
+ CloseScreenProcPtr CloseScreen;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+#endif
+ 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 */
+#if 0
+ XAAInfoRecPtr AccelInfoRec;
+ xRectangle Rect;
+#endif
+ u_int32_t SavedCmd;
+ u_int32_t SavedFgColor;
+ u_int32_t SavedBgColor;
+ u_int32_t SavedPattern0;
+ u_int32_t SavedPattern1;
+ u_int32_t SavedPatternAddr;
+
+#if 0
+ /* Support for Int10 processing */
+ xf86Int10InfoPtr pInt10;
+
+ /* BIOS Info Ptr */
+ VIABIOSInfoPtr pBIOSInfo;
+ VGABIOSVERPtr pBIOSVer;
+#endif
+
+ /* Support for DGA */
+ int numDGAModes;
+ /*DGAModePtr DGAModes;*/
+ int DGAactive;
+ int DGAViewportStatus;
+
+ /* The various wait handlers. */
+ int (*myWaitIdle)(struct _VIA*);
+
+#if 0
+ /* I2C & DDC */
+ I2CBusPtr I2C_Port1;
+ I2CBusPtr I2C_Port2;
+ xf86MonPtr DDC1;
+ xf86MonPtr DDC2;
+#endif
+
+ /* MHS */
+ int IsSecondary;
+ int HasSecondary;
+
+#if 0
+ /* Capture information */
+ VIACAPINFO CapInfo[2]; /* 2 capture information */
+#endif
+
+/*
+ u_int32_t Cap0_Deinterlace;
+ u_int32_t Cap1_Deinterlace;
+
+ int Cap0_FieldSwap;
+ int NoCap0_HFilter;
+ int Capture_OverScanOff;
+ int NoMPEGHQV_VFilter;
+*/
+#ifdef XF86DRI
+ int directRenderingEnabled;
+ DRIInfoPtr pDRIInfo;
+ int drmFD;
+ int numVisualConfigs;
+ __GLXvisualConfig* pVisualConfigs;
+ VIAConfigPrivPtr pVisualConfigsPriv;
+ unsigned long agpHandle;
+ unsigned long registerHandle;
+ u_int32_t agpAddr;
+ unsigned char *agpBase;
+ unsigned int agpSize;
+ int IsPCI;
+ int drixinerama;
+#else
+ int drmFD;
+ unsigned long agpHandle;
+ unsigned long registerHandle;
+ unsigned long agpAddr;
+ unsigned char *agpBase;
+ unsigned int agpSize;
+ int IsPCI;
+#endif
+
+ int V4LEnabled;
+ u_int16_t ActiveDevice; /* if SAMM, non-equal pBIOSInfo->ActiveDevice */
+ unsigned char *CursorImage;
+ u_int32_t CursorFG;
+ u_int32_t CursorBG;
+ u_int32_t CursorMC;
+
+ unsigned char MemClk;
+ int EnableExtendedFIFO;
+ VIADRIPtr devPrivate;
+} VIARec, *VIAPtr;
+
+
+/* Shortcuts. These depend on a local symbol "pVia". */
+
+#define WaitIdle() pVia->myWaitIdle(pVia)
+#define VIAPTR(p) ((VIAPtr)((p)->driverPrivate))
+
+#endif /* _VIA_DRIVER_H */
+
diff --git a/src/server/via_priv.h b/src/server/via_priv.h
new file mode 100644
index 0000000..587531b
--- /dev/null
+++ b/src/server/via_priv.h
@@ -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;
+
+ int MPEG_ON;
+ int 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/server/via_regs.h b/src/server/via_regs.h
new file mode 100644
index 0000000..87e1e9d
--- /dev/null
+++ b/src/server/via_regs.h
@@ -0,0 +1,198 @@
+/*
+ * 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
+
+#include "via_driver.h"
+
+/*#define VIA_SERIES(chip) (chip == VIA_CLE266)*/
+
+#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 0x3108
+#define PCI_CHIP_VT3259 0x3118
+#define PCI_CHIP_VT3344 0x3344
+
+
+#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/via_3d_reg.h b/src/via_3d_reg.h
new file mode 100644
index 0000000..77b24dc
--- /dev/null
+++ b/src/via_3d_reg.h
@@ -0,0 +1,1652 @@
+/*
+ * 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
+
+/* The "S" in FLS? means the S texture coordinate, and a "T" means the T
+ * texture coordinage. The "e" in FL?e means the magnification ("enlarge")
+ * mode, and the "s" in FL?s means the minification ("shrink") mode.
+ *
+ * The "D" in FLD? means the intermipmap level mode. That means that the
+ * GL_*_MIPMAP_LINEAR modes get FLDs_Linear, and the GL_*_MIPMAP_NEAREST modes
+ * get FLDs_Nearest.
+ */
+#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 /* 0 << 19 */
+#define HC_HTXnFM_Intensity 0x00080000 /* 1 << 19 */
+#define HC_HTXnFM_Lum 0x00100000 /* 2 << 19 */
+#define HC_HTXnFM_Alpha 0x00180000 /* 3 << 19 */
+#define HC_HTXnFM_DX 0x00280000 /* 5 << 19 */
+#define HC_HTXnFM_BUMPMAP 0x00380000 /* 7 << 19 */
+#define HC_HTXnFM_ARGB16 0x00880000 /* 17 << 19 */
+#define HC_HTXnFM_ARGB32 0x00980000 /* 19 << 19 */
+#define HC_HTXnFM_ABGR16 0x00a80000 /* 21 << 19 */
+#define HC_HTXnFM_ABGR32 0x00b80000 /* 23 << 19 */
+#define HC_HTXnFM_RGBA16 0x00c80000 /* 25 << 19 */
+#define HC_HTXnFM_RGBA32 0x00d80000 /* 27 << 19 */
+#define HC_HTXnFM_BGRA16 0x00e80000 /* 29 << 19 */
+#define HC_HTXnFM_BGRA32 0x00f80000 /* 31 << 19 */
+#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
+
+/*-- Define the input texture, for below
+ */
+#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
+/** HC_SubA_HTXnTBLCsat 0x0080
+ */
+#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_HTXnTBLDOT3 0x00800000
+#define HC_HTXnTBLDOT4 0x00c00000
+#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
+#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/via_context.c b/src/via_context.c
new file mode 100644
index 0000000..7c73877
--- /dev/null
+++ b/src/via_context.c
@@ -0,0 +1,956 @@
+/*
+ * 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_context.c
+ *
+ * \author John Sheng (presumably of either VIA Technologies or S3 Graphics)
+ * \author Others at VIA Technologies?
+ * \author Others at S3 Graphics?
+ */
+
+#include "glheader.h"
+#include "context.h"
+#include "matrix.h"
+#include "state.h"
+#include "simple_list.h"
+#include "extensions.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "vbo/vbo.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_ioctl.h"
+#include "via_fb.h"
+
+#include <stdio.h>
+#include "macros.h"
+#include "drirenderbuffer.h"
+
+#define need_GL_ARB_multisample
+#define need_GL_ARB_point_parameters
+#define need_GL_ARB_vertex_buffer_object
+#define need_GL_EXT_fog_coord
+#define need_GL_EXT_secondary_color
+#include "extension_helper.h"
+
+#define DRIVER_DATE "20060710"
+
+#include "vblank.h"
+#include "utils.h"
+
+GLuint VIA_DEBUG = 0;
+
+/**
+ * Return various strings for \c glGetString.
+ *
+ * \sa glGetString
+ */
+static const GLubyte *viaGetString(GLcontext *ctx, GLenum name)
+{
+ static char buffer[128];
+ unsigned offset;
+
+
+ switch (name) {
+ case GL_VENDOR:
+ return (GLubyte *)"VIA Technology";
+
+ case GL_RENDERER: {
+ static const char * const chipset_names[] = {
+ "UniChrome",
+ "CastleRock (CLE266)",
+ "UniChrome (KM400)",
+ "UniChrome (K8M800)",
+ "UniChrome (PM8x0/CN400)",
+ };
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ unsigned id = vmesa->viaScreen->deviceID;
+
+ offset = driGetRendererString( buffer,
+ chipset_names[(id > VIA_PM800) ? 0 : id],
+ DRIVER_DATE, 0 );
+ return (GLubyte *)buffer;
+ }
+
+ default:
+ return NULL;
+ }
+}
+
+
+/**
+ * Calculate a width that satisfies the hardware's alignment requirements.
+ * On the Unichrome hardware, each scanline must be aligned to a multiple of
+ * 16 pixels.
+ *
+ * \param width Minimum buffer width, in pixels.
+ *
+ * \returns A pixel width that meets the alignment requirements.
+ */
+static __inline__ unsigned
+buffer_align( unsigned width )
+{
+ return (width + 0x0f) & ~0x0f;
+}
+
+
+static void
+viaDeleteRenderbuffer(struct gl_renderbuffer *rb)
+{
+ /* Don't free() since we're contained in via_context struct. */
+}
+
+static GLboolean
+viaRenderbufferStorage(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat, GLuint width, GLuint height)
+{
+ rb->Width = width;
+ rb->Height = height;
+ rb->InternalFormat = internalFormat;
+ return GL_TRUE;
+}
+
+
+static void
+viaInitRenderbuffer(struct via_renderbuffer *vrb, GLenum format,
+ __DRIdrawablePrivate *dPriv)
+{
+ const GLuint name = 0;
+ struct gl_renderbuffer *rb = & vrb->Base;
+
+ vrb->dPriv = dPriv;
+ _mesa_init_renderbuffer(rb, name);
+
+ /* Make sure we're using a null-valued GetPointer routine */
+ assert(rb->GetPointer(NULL, rb, 0, 0) == NULL);
+
+ rb->InternalFormat = format;
+
+ if (format == GL_RGBA) {
+ /* Color */
+ rb->_BaseFormat = GL_RGBA;
+ rb->DataType = GL_UNSIGNED_BYTE;
+ }
+ else if (format == GL_DEPTH_COMPONENT16) {
+ /* Depth */
+ rb->_BaseFormat = GL_DEPTH_COMPONENT;
+ /* we always Get/Put 32-bit Z values */
+ rb->DataType = GL_UNSIGNED_INT;
+ }
+ else if (format == GL_DEPTH_COMPONENT24) {
+ /* Depth */
+ rb->_BaseFormat = GL_DEPTH_COMPONENT;
+ /* we always Get/Put 32-bit Z values */
+ rb->DataType = GL_UNSIGNED_INT;
+ }
+ else {
+ /* Stencil */
+ ASSERT(format == GL_STENCIL_INDEX8_EXT);
+ rb->_BaseFormat = GL_STENCIL_INDEX;
+ rb->DataType = GL_UNSIGNED_BYTE;
+ }
+
+ rb->Delete = viaDeleteRenderbuffer;
+ rb->AllocStorage = viaRenderbufferStorage;
+}
+
+
+/**
+ * Calculate the framebuffer parameters for all buffers (front, back, depth,
+ * and stencil) associated with the specified context.
+ *
+ * \warning
+ * This function also calls \c AllocateBuffer to actually allocate the
+ * buffers.
+ *
+ * \sa AllocateBuffer
+ */
+static GLboolean
+calculate_buffer_parameters(struct via_context *vmesa,
+ struct gl_framebuffer *fb,
+ __DRIdrawablePrivate *dPriv)
+{
+ const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16;
+ const unsigned extra = 32;
+ unsigned w;
+ unsigned h;
+
+ /* Normally, the renderbuffer would be added to the framebuffer just once
+ * when the framebuffer was created. The VIA driver is a bit funny
+ * though in that the front/back/depth renderbuffers are in the per-context
+ * state!
+ * That should be fixed someday.
+ */
+
+ if (!vmesa->front.Base.InternalFormat) {
+ /* do one-time init for the renderbuffers */
+ viaInitRenderbuffer(&vmesa->front, GL_RGBA, dPriv);
+ viaSetSpanFunctions(&vmesa->front, &fb->Visual);
+ _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &vmesa->front.Base);
+
+ if (fb->Visual.doubleBufferMode) {
+ viaInitRenderbuffer(&vmesa->back, GL_RGBA, dPriv);
+ viaSetSpanFunctions(&vmesa->back, &fb->Visual);
+ _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &vmesa->back.Base);
+ }
+
+ if (vmesa->glCtx->Visual.depthBits > 0) {
+ viaInitRenderbuffer(&vmesa->depth,
+ (vmesa->glCtx->Visual.depthBits == 16
+ ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24),
+ dPriv);
+ viaSetSpanFunctions(&vmesa->depth, &fb->Visual);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &vmesa->depth.Base);
+ }
+
+ if (vmesa->glCtx->Visual.stencilBits > 0) {
+ viaInitRenderbuffer(&vmesa->stencil, GL_STENCIL_INDEX8_EXT,
+ dPriv);
+ viaSetSpanFunctions(&vmesa->stencil, &fb->Visual);
+ _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &vmesa->stencil.Base);
+ }
+ }
+
+ assert(vmesa->front.Base.InternalFormat);
+ assert(vmesa->front.Base.AllocStorage);
+ if (fb->Visual.doubleBufferMode) {
+ assert(vmesa->back.Base.AllocStorage);
+ }
+ if (fb->Visual.depthBits) {
+ assert(vmesa->depth.Base.AllocStorage);
+ }
+
+
+ /* Allocate front-buffer */
+ if (vmesa->drawType == GLX_PBUFFER_BIT) {
+ w = vmesa->driDrawable->w;
+ h = vmesa->driDrawable->h;
+
+ vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel;
+ vmesa->front.pitch = buffer_align( w ) << shift; /* bytes, not pixels */
+ vmesa->front.size = vmesa->front.pitch * h;
+
+ if (vmesa->front.map)
+ via_free_draw_buffer(vmesa, &vmesa->front);
+ if (!via_alloc_draw_buffer(vmesa, &vmesa->front))
+ return GL_FALSE;
+
+ } else {
+ w = vmesa->viaScreen->width;
+ h = vmesa->viaScreen->height;
+
+ vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel;
+ vmesa->front.pitch = buffer_align( w ) << shift; /* bytes, not pixels */
+ vmesa->front.size = vmesa->front.pitch * h;
+ if (getenv("ALTERNATE_SCREEN"))
+ vmesa->front.offset = vmesa->front.size;
+ else
+ vmesa->front.offset = 0;
+ vmesa->front.map = (char *) vmesa->driScreen->pFB;
+ }
+
+
+ /* Allocate back-buffer */
+ if (vmesa->hasBack) {
+ vmesa->back.bpp = vmesa->viaScreen->bitsPerPixel;
+ vmesa->back.pitch = (buffer_align( vmesa->driDrawable->w ) << shift);
+ vmesa->back.pitch += extra;
+ vmesa->back.pitch = MIN2(vmesa->back.pitch, vmesa->front.pitch);
+ vmesa->back.size = vmesa->back.pitch * vmesa->driDrawable->h;
+ if (vmesa->back.map)
+ via_free_draw_buffer(vmesa, &vmesa->back);
+ if (!via_alloc_draw_buffer(vmesa, &vmesa->back))
+ return GL_FALSE;
+ }
+ else {
+ if (vmesa->back.map)
+ via_free_draw_buffer(vmesa, &vmesa->back);
+ (void) memset( &vmesa->back, 0, sizeof( vmesa->back ) );
+ }
+
+
+ /* Allocate depth-buffer */
+ if ( vmesa->hasStencil || vmesa->hasDepth ) {
+ vmesa->depth.bpp = vmesa->depthBits;
+ if (vmesa->depth.bpp == 24)
+ vmesa->depth.bpp = 32;
+
+ vmesa->depth.pitch = (buffer_align( vmesa->driDrawable->w ) *
+ (vmesa->depth.bpp/8)) + extra;
+ vmesa->depth.size = vmesa->depth.pitch * vmesa->driDrawable->h;
+
+ if (vmesa->depth.map)
+ via_free_draw_buffer(vmesa, &vmesa->depth);
+ if (!via_alloc_draw_buffer(vmesa, &vmesa->depth)) {
+ return GL_FALSE;
+ }
+ }
+ else {
+ if (vmesa->depth.map)
+ via_free_draw_buffer(vmesa, &vmesa->depth);
+ (void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) );
+ }
+
+ /* stencil buffer is same as depth buffer */
+ vmesa->stencil.handle = vmesa->depth.handle;
+ vmesa->stencil.size = vmesa->depth.size;
+ vmesa->stencil.offset = vmesa->depth.offset;
+ vmesa->stencil.index = vmesa->depth.index;
+ vmesa->stencil.pitch = vmesa->depth.pitch;
+ vmesa->stencil.bpp = vmesa->depth.bpp;
+ vmesa->stencil.map = vmesa->depth.map;
+ vmesa->stencil.orig = vmesa->depth.orig;
+ vmesa->stencil.origMap = vmesa->depth.origMap;
+
+ if( vmesa->viaScreen->width == vmesa->driDrawable->w &&
+ vmesa->viaScreen->height == vmesa->driDrawable->h ) {
+ vmesa->doPageFlip = vmesa->allowPageFlip;
+ if (vmesa->hasBack) {
+ assert(vmesa->back.pitch == vmesa->front.pitch);
+ }
+ }
+ else
+ vmesa->doPageFlip = GL_FALSE;
+
+ return GL_TRUE;
+}
+
+
+void viaReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer,
+ GLuint width, GLuint height)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ calculate_buffer_parameters(vmesa, drawbuffer, vmesa->driDrawable);
+
+ _mesa_resize_framebuffer(ctx, drawbuffer, width, height);
+}
+
+/* Extension strings exported by the Unichrome driver.
+ */
+const struct dri_extension card_extensions[] =
+{
+ { "GL_ARB_multisample", GL_ARB_multisample_functions },
+ { "GL_ARB_multitexture", NULL },
+ { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions },
+ { "GL_ARB_texture_env_add", NULL },
+ { "GL_ARB_texture_env_combine", NULL },
+/* { "GL_ARB_texture_env_dot3", NULL }, */
+ { "GL_ARB_texture_mirrored_repeat", NULL },
+ { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions },
+ { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
+ { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
+ { "GL_EXT_stencil_wrap", NULL },
+ { "GL_EXT_texture_env_combine", NULL },
+/* { "GL_EXT_texture_env_dot3", NULL }, */
+ { "GL_EXT_texture_lod_bias", NULL },
+ { "GL_NV_blend_square", NULL },
+ { NULL, NULL }
+};
+
+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 */
+#endif
+ &_tnl_render_stage,
+ 0,
+};
+
+
+static const struct dri_debug_control debug_control[] =
+{
+ { "fall", DEBUG_FALLBACKS },
+ { "tex", DEBUG_TEXTURE },
+ { "ioctl", DEBUG_IOCTL },
+ { "prim", DEBUG_PRIMS },
+ { "vert", DEBUG_VERTS },
+ { "state", DEBUG_STATE },
+ { "verb", DEBUG_VERBOSE },
+ { "dri", DEBUG_DRI },
+ { "dma", DEBUG_DMA },
+ { "san", DEBUG_SANITY },
+ { "sync", DEBUG_SYNC },
+ { "sleep", DEBUG_SLEEP },
+ { "pix", DEBUG_PIXEL },
+ { "2d", DEBUG_2D },
+ { NULL, 0 }
+};
+
+
+static GLboolean
+AllocateDmaBuffer(struct via_context *vmesa)
+{
+ if (vmesa->dma)
+ via_free_dma_buffer(vmesa);
+
+ if (!via_alloc_dma_buffer(vmesa))
+ return GL_FALSE;
+
+ vmesa->dmaLow = 0;
+ vmesa->dmaCliprectAddr = ~0;
+ return GL_TRUE;
+}
+
+static void
+FreeBuffer(struct via_context *vmesa)
+{
+ if (vmesa->front.map && vmesa->drawType == GLX_PBUFFER_BIT)
+ via_free_draw_buffer(vmesa, &vmesa->front);
+
+ if (vmesa->back.map)
+ via_free_draw_buffer(vmesa, &vmesa->back);
+
+ if (vmesa->depth.map)
+ via_free_draw_buffer(vmesa, &vmesa->depth);
+
+ if (vmesa->breadcrumb.map)
+ via_free_draw_buffer(vmesa, &vmesa->breadcrumb);
+
+ if (vmesa->dma)
+ via_free_dma_buffer(vmesa);
+}
+
+
+GLboolean
+viaCreateContext(const __GLcontextModes *visual,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate)
+{
+ GLcontext *ctx, *shareCtx;
+ struct via_context *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 = (struct via_context *) CALLOC_STRUCT(via_context);
+ if (!vmesa) {
+ return GL_FALSE;
+ }
+
+ /* Parse configuration files.
+ */
+ driParseConfigFiles (&vmesa->optionCache, &viaScreen->optionCache,
+ sPriv->myNum, "unichrome");
+
+ /* pick back buffer */
+ vmesa->hasBack = visual->doubleBufferMode;
+
+ switch(visual->depthBits) {
+ case 0:
+ vmesa->hasDepth = GL_FALSE;
+ vmesa->depthBits = 0;
+ vmesa->depth_max = 1.0;
+ break;
+ case 16:
+ vmesa->hasDepth = GL_TRUE;
+ vmesa->depthBits = visual->depthBits;
+ vmesa->have_hw_stencil = GL_FALSE;
+ vmesa->depth_max = (GLfloat)0xffff;
+ vmesa->depth_clear_mask = 0xf << 28;
+ vmesa->ClearDepth = 0xffff;
+ vmesa->polygon_offset_scale = 1.0 / vmesa->depth_max;
+ break;
+ case 24:
+ vmesa->hasDepth = GL_TRUE;
+ vmesa->depthBits = visual->depthBits;
+ vmesa->depth_max = (GLfloat) 0xffffff;
+ vmesa->depth_clear_mask = 0xe << 28;
+ vmesa->ClearDepth = 0xffffff00;
+
+ assert(visual->haveStencilBuffer);
+ assert(visual->stencilBits == 8);
+
+ vmesa->have_hw_stencil = GL_TRUE;
+ vmesa->stencilBits = visual->stencilBits;
+ vmesa->stencil_clear_mask = 0x1 << 28;
+ vmesa->polygon_offset_scale = 2.0 / vmesa->depth_max;
+ break;
+ case 32:
+ vmesa->hasDepth = GL_TRUE;
+ vmesa->depthBits = visual->depthBits;
+ assert(!visual->haveStencilBuffer);
+ vmesa->have_hw_stencil = GL_FALSE;
+ vmesa->depth_max = (GLfloat)0xffffffff;
+ vmesa->depth_clear_mask = 0xf << 28;
+ vmesa->ClearDepth = 0xffffffff;
+ vmesa->polygon_offset_scale = 2.0 / vmesa->depth_max;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ make_empty_list(&vmesa->freed_tex_buffers);
+ make_empty_list(&vmesa->tex_image_list[VIA_MEM_VIDEO]);
+ make_empty_list(&vmesa->tex_image_list[VIA_MEM_AGP]);
+ make_empty_list(&vmesa->tex_image_list[VIA_MEM_SYSTEM]);
+
+ _mesa_init_driver_functions(&functions);
+ viaInitTextureFuncs(&functions);
+
+ /* Allocate the Mesa context */
+ if (sharedContextPrivate)
+ shareCtx = ((struct via_context *) sharedContextPrivate)->glCtx;
+ else
+ shareCtx = NULL;
+
+ vmesa->glCtx = _mesa_create_context(visual, shareCtx, &functions,
+ (void*) vmesa);
+
+ vmesa->shareCtx = shareCtx;
+
+ if (!vmesa->glCtx) {
+ FREE(vmesa);
+ return GL_FALSE;
+ }
+ driContextPriv->driverPrivate = vmesa;
+
+ ctx = vmesa->glCtx;
+
+ if (driQueryOptionb(&vmesa->optionCache, "excess_mipmap"))
+ ctx->Const.MaxTextureLevels = 11;
+ else
+ ctx->Const.MaxTextureLevels = 10;
+
+ ctx->Const.MaxTextureUnits = 2;
+ ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
+ ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
+
+ ctx->Const.MinLineWidth = 1.0;
+ ctx->Const.MinLineWidthAA = 1.0;
+ ctx->Const.MaxLineWidth = 1.0;
+ ctx->Const.MaxLineWidthAA = 1.0;
+ ctx->Const.LineWidthGranularity = 1.0;
+
+ ctx->Const.MinPointSize = 1.0;
+ ctx->Const.MinPointSizeAA = 1.0;
+ ctx->Const.MaxPointSize = 1.0;
+ ctx->Const.MaxPointSizeAA = 1.0;
+ ctx->Const.PointSizeGranularity = 1.0;
+
+ ctx->Driver.GetString = viaGetString;
+
+ ctx->DriverCtx = (void *)vmesa;
+ vmesa->glCtx = ctx;
+
+ /* Initialize the software rasterizer and helper modules.
+ */
+ _swrast_CreateContext(ctx);
+ _vbo_CreateContext(ctx);
+ _tnl_CreateContext(ctx);
+ _swsetup_CreateContext(ctx);
+
+ /* Install the customized pipeline:
+ */
+ _tnl_destroy_pipeline(ctx);
+ _tnl_install_pipeline(ctx, via_pipeline);
+
+ /* Configure swrast and T&L to match hardware characteristics:
+ */
+ _swrast_allow_pixel_fog(ctx, GL_FALSE);
+ _swrast_allow_vertex_fog(ctx, GL_TRUE);
+ _tnl_allow_pixel_fog(ctx, GL_FALSE);
+ _tnl_allow_vertex_fog(ctx, GL_TRUE);
+
+/* vmesa->display = dpy; */
+ vmesa->display = sPriv->display;
+
+ vmesa->hHWContext = driContextPriv->hHWContext;
+ vmesa->driFd = sPriv->fd;
+ vmesa->driHwLock = &sPriv->pSAREA->lock;
+
+ vmesa->viaScreen = viaScreen;
+ vmesa->driScreen = sPriv;
+ vmesa->sarea = saPriv;
+
+ vmesa->renderIndex = ~0;
+ vmesa->setupIndex = ~0;
+ vmesa->hwPrimitive = GL_POLYGON+1;
+
+ /* KW: Hardwire this. Was previously set bogusly in
+ * viaCreateBuffer. Needs work before PBUFFER can be used:
+ */
+ vmesa->drawType = GLX_WINDOW_BIT;
+
+
+ _math_matrix_ctr(&vmesa->ViewportMatrix);
+
+ /* Do this early, before VIA_FLUSH_DMA can be called:
+ */
+ if (!AllocateDmaBuffer(vmesa)) {
+ fprintf(stderr ,"AllocateDmaBuffer fail\n");
+ FreeBuffer(vmesa);
+ FREE(vmesa);
+ return GL_FALSE;
+ }
+
+ /* Allocate a small piece of fb memory for synchronization:
+ */
+ vmesa->breadcrumb.bpp = 32;
+ vmesa->breadcrumb.pitch = buffer_align( 64 ) << 2;
+ vmesa->breadcrumb.size = vmesa->breadcrumb.pitch;
+
+ if (!via_alloc_draw_buffer(vmesa, &vmesa->breadcrumb)) {
+ fprintf(stderr ,"AllocateDmaBuffer fail\n");
+ FreeBuffer(vmesa);
+ FREE(vmesa);
+ return GL_FALSE;
+ }
+
+ driInitExtensions( ctx, card_extensions, GL_TRUE );
+ viaInitStateFuncs(ctx);
+ viaInitTriFuncs(ctx);
+ viaInitSpanFuncs(ctx);
+ viaInitIoctlFuncs(ctx);
+ viaInitState(ctx);
+
+ if (getenv("VIA_DEBUG"))
+ VIA_DEBUG = driParseDebugString( getenv( "VIA_DEBUG" ),
+ debug_control );
+
+ if (getenv("VIA_NO_RAST") ||
+ driQueryOptionb(&vmesa->optionCache, "no_rast"))
+ FALLBACK(vmesa, VIA_FALLBACK_USER_DISABLE, 1);
+
+ vmesa->vblank_flags =
+ vmesa->viaScreen->irqEnabled ?
+ driGetDefaultVBlankFlags(&vmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
+
+ if (getenv("VIA_PAGEFLIP"))
+ vmesa->allowPageFlip = 1;
+
+ (*dri_interface->getUST)( &vmesa->swap_ust );
+
+
+ vmesa->regMMIOBase = (GLuint *)((unsigned long)viaScreen->reg);
+ vmesa->pnGEMode = (GLuint *)((unsigned long)viaScreen->reg + 0x4);
+ vmesa->regEngineStatus = (GLuint *)((unsigned long)viaScreen->reg + 0x400);
+ vmesa->regTranSet = (GLuint *)((unsigned long)viaScreen->reg + 0x43C);
+ vmesa->regTranSpace = (GLuint *)((unsigned long)viaScreen->reg + 0x440);
+ vmesa->agpBase = viaScreen->agpBase;
+
+
+ return GL_TRUE;
+}
+
+void
+viaDestroyContext(__DRIcontextPrivate *driContextPriv)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct via_context *vmesa =
+ (struct via_context *)driContextPriv->driverPrivate;
+ struct via_context *current = ctx ? VIA_CONTEXT(ctx) : NULL;
+ assert(vmesa); /* should never be null */
+
+ /* check if we're deleting the currently bound context */
+ if (vmesa == current) {
+ VIA_FLUSH_DMA(vmesa);
+ _mesa_make_current(NULL, NULL, NULL);
+ }
+
+ if (vmesa) {
+ viaWaitIdle(vmesa, GL_FALSE);
+ if (vmesa->doPageFlip) {
+ LOCK_HARDWARE(vmesa);
+ if (vmesa->pfCurrentOffset != 0) {
+ fprintf(stderr, "%s - reset pf\n", __FUNCTION__);
+ viaResetPageFlippingLocked(vmesa);
+ }
+ UNLOCK_HARDWARE(vmesa);
+ }
+
+ _swsetup_DestroyContext(vmesa->glCtx);
+ _tnl_DestroyContext(vmesa->glCtx);
+ _vbo_DestroyContext(vmesa->glCtx);
+ _swrast_DestroyContext(vmesa->glCtx);
+ /* free the Mesa context */
+ _mesa_destroy_context(vmesa->glCtx);
+ /* release our data */
+ FreeBuffer(vmesa);
+
+ assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_AGP]));
+ assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_VIDEO]));
+ assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_SYSTEM]));
+ assert (is_empty_list(&vmesa->freed_tex_buffers));
+
+ driDestroyOptionCache(&vmesa->optionCache);
+
+ FREE(vmesa);
+ }
+}
+
+
+void viaXMesaWindowMoved(struct via_context *vmesa)
+{
+ __DRIdrawablePrivate *const drawable = vmesa->driDrawable;
+ __DRIdrawablePrivate *const readable = vmesa->driReadable;
+ struct via_renderbuffer * draw_buffer;
+ struct via_renderbuffer * read_buffer;
+ GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+
+ if (!drawable)
+ return;
+
+ draw_buffer = (struct via_renderbuffer *) drawable->driverPrivate;
+ read_buffer = (struct via_renderbuffer *) readable->driverPrivate;
+
+ switch (vmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0]) {
+ case BUFFER_BIT_BACK_LEFT:
+ if (drawable->numBackClipRects == 0) {
+ vmesa->numClipRects = drawable->numClipRects;
+ vmesa->pClipRects = drawable->pClipRects;
+ }
+ else {
+ vmesa->numClipRects = drawable->numBackClipRects;
+ vmesa->pClipRects = drawable->pBackClipRects;
+ }
+ break;
+ case BUFFER_BIT_FRONT_LEFT:
+ vmesa->numClipRects = drawable->numClipRects;
+ vmesa->pClipRects = drawable->pClipRects;
+ break;
+ default:
+ vmesa->numClipRects = 0;
+ break;
+ }
+
+ if ((draw_buffer->drawW != drawable->w)
+ || (draw_buffer->drawH != drawable->h)) {
+ calculate_buffer_parameters(vmesa, vmesa->glCtx->DrawBuffer,
+ drawable);
+ }
+
+ draw_buffer->drawX = drawable->x;
+ draw_buffer->drawY = drawable->y;
+ draw_buffer->drawW = drawable->w;
+ draw_buffer->drawH = drawable->h;
+
+ if (drawable != readable) {
+ if ((read_buffer->drawW != readable->w)
+ || (read_buffer->drawH != readable->h)) {
+ calculate_buffer_parameters(vmesa, vmesa->glCtx->ReadBuffer,
+ readable);
+ }
+
+ read_buffer->drawX = readable->x;
+ read_buffer->drawY = readable->y;
+ read_buffer->drawW = readable->w;
+ read_buffer->drawH = readable->h;
+ }
+
+ vmesa->front.orig = (vmesa->front.offset +
+ draw_buffer->drawY * vmesa->front.pitch +
+ draw_buffer->drawX * bytePerPixel);
+
+ vmesa->front.origMap = (vmesa->front.map +
+ draw_buffer->drawY * vmesa->front.pitch +
+ draw_buffer->drawX * bytePerPixel);
+
+ vmesa->back.orig = (vmesa->back.offset +
+ draw_buffer->drawY * vmesa->back.pitch +
+ draw_buffer->drawX * bytePerPixel);
+
+ vmesa->back.origMap = (vmesa->back.map +
+ draw_buffer->drawY * vmesa->back.pitch +
+ draw_buffer->drawX * bytePerPixel);
+
+ vmesa->depth.orig = (vmesa->depth.offset +
+ draw_buffer->drawY * vmesa->depth.pitch +
+ draw_buffer->drawX * bytePerPixel);
+
+ vmesa->depth.origMap = (vmesa->depth.map +
+ draw_buffer->drawY * vmesa->depth.pitch +
+ draw_buffer->drawX * bytePerPixel);
+
+ viaCalcViewport(vmesa->glCtx);
+}
+
+GLboolean
+viaUnbindContext(__DRIcontextPrivate *driContextPriv)
+{
+ return GL_TRUE;
+}
+
+GLboolean
+viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv)
+{
+ if (VIA_DEBUG & DEBUG_DRI) {
+ fprintf(stderr, "driContextPriv = %016lx\n", (unsigned long)driContextPriv);
+ fprintf(stderr, "driDrawPriv = %016lx\n", (unsigned long)driDrawPriv);
+ fprintf(stderr, "driReadPriv = %016lx\n", (unsigned long)driReadPriv);
+ }
+
+ if (driContextPriv) {
+ struct via_context *vmesa =
+ (struct via_context *)driContextPriv->driverPrivate;
+ GLcontext *ctx = vmesa->glCtx;
+ struct gl_framebuffer *drawBuffer, *readBuffer;
+
+ drawBuffer = (GLframebuffer *)driDrawPriv->driverPrivate;
+ readBuffer = (GLframebuffer *)driReadPriv->driverPrivate;
+
+ if (vmesa->driDrawable != driDrawPriv) {
+ driDrawableInitVBlank(driDrawPriv, vmesa->vblank_flags,
+ &vmesa->vbl_seq);
+ }
+
+ if ((vmesa->driDrawable != driDrawPriv)
+ || (vmesa->driReadable != driReadPriv)) {
+ vmesa->driDrawable = driDrawPriv;
+ vmesa->driReadable = driReadPriv;
+
+ if ((drawBuffer->Width != driDrawPriv->w)
+ || (drawBuffer->Height != driDrawPriv->h)) {
+ _mesa_resize_framebuffer(ctx, drawBuffer,
+ driDrawPriv->w, driDrawPriv->h);
+ drawBuffer->Initialized = GL_TRUE;
+ }
+
+ if (!calculate_buffer_parameters(vmesa, drawBuffer, driDrawPriv)) {
+ return GL_FALSE;
+ }
+
+ if (driDrawPriv != driReadPriv) {
+ if ((readBuffer->Width != driReadPriv->w)
+ || (readBuffer->Height != driReadPriv->h)) {
+ _mesa_resize_framebuffer(ctx, readBuffer,
+ driReadPriv->w, driReadPriv->h);
+ readBuffer->Initialized = GL_TRUE;
+ }
+
+ if (!calculate_buffer_parameters(vmesa, readBuffer, driReadPriv)) {
+ return GL_FALSE;
+ }
+ }
+ }
+
+ _mesa_make_current(vmesa->glCtx, drawBuffer, readBuffer);
+
+ ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
+
+ viaXMesaWindowMoved(vmesa);
+ ctx->Driver.Scissor(vmesa->glCtx,
+ vmesa->glCtx->Scissor.X,
+ vmesa->glCtx->Scissor.Y,
+ vmesa->glCtx->Scissor.Width,
+ vmesa->glCtx->Scissor.Height);
+ }
+ else {
+ _mesa_make_current(NULL, NULL, NULL);
+ }
+
+ return GL_TRUE;
+}
+
+void viaGetLock(struct via_context *vmesa, GLuint flags)
+{
+ __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+ __DRIscreenPrivate *sPriv = vmesa->driScreen;
+
+ drmGetLock(vmesa->driFd, vmesa->hHWContext, flags);
+
+ DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
+ if (dPriv != vmesa->driReadable) {
+ DRI_VALIDATE_DRAWABLE_INFO(sPriv, vmesa->driReadable);
+ }
+
+ if (vmesa->sarea->ctxOwner != vmesa->hHWContext) {
+ vmesa->sarea->ctxOwner = vmesa->hHWContext;
+ vmesa->newEmitState = ~0;
+ }
+
+ if (vmesa->lastStamp != dPriv->lastStamp) {
+ viaXMesaWindowMoved(vmesa);
+ driUpdateFramebufferSize(vmesa->glCtx, dPriv);
+ vmesa->newEmitState = ~0;
+ vmesa->lastStamp = dPriv->lastStamp;
+ }
+
+ if (vmesa->doPageFlip &&
+ vmesa->pfCurrentOffset != vmesa->sarea->pfCurrentOffset) {
+ fprintf(stderr, "%s - reset pf\n", __FUNCTION__);
+ viaResetPageFlippingLocked(vmesa);
+ }
+}
+
+
+void
+viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
+{
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *)drawablePrivate;
+
+ if (dPriv &&
+ dPriv->driContextPriv &&
+ dPriv->driContextPriv->driverPrivate) {
+ struct via_context *vmesa =
+ (struct via_context *)dPriv->driContextPriv->driverPrivate;
+ GLcontext *ctx = vmesa->glCtx;
+
+ _mesa_notifySwapBuffers(ctx);
+
+ if (ctx->Visual.doubleBufferMode) {
+ if (vmesa->doPageFlip) {
+ viaPageFlip(dPriv);
+ }
+ else {
+ viaCopyBuffer(dPriv);
+ }
+ }
+ else
+ VIA_FLUSH_DMA(vmesa);
+ }
+ else {
+ _mesa_problem(NULL, "viaSwapBuffers: drawable has no context!\n");
+ }
+}
diff --git a/src/via_context.h b/src/via_context.h
new file mode 100644
index 0000000..fecd278
--- /dev/null
+++ b/src/via_context.h
@@ -0,0 +1,423 @@
+/*
+ * 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
+
+#include "dri_util.h"
+
+#include "mtypes.h"
+#include "drm.h"
+#include "mm.h"
+#include "tnl/t_vertex.h"
+
+#include "via_screen.h"
+#include "via_tex.h"
+#include "via_drm.h"
+
+struct via_context;
+
+/* Chip tags. These are used to group the adapters into
+ * related families.
+ */
+enum VIACHIPTAGS {
+ VIA_UNKNOWN = 0,
+ VIA_CLE266,
+ VIA_KM400,
+ VIA_K8M800,
+ VIA_PM800,
+ VIA_LAST
+};
+
+#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_FALLBACK_USER_DISABLE 0x800
+#define VIA_FALLBACK_PROJ_TEXTURE 0x1000
+#define VIA_FALLBACK_POLY_STIPPLE 0x2000
+
+#define VIA_DMA_BUFSIZ 4096
+#define VIA_DMA_HIGHWATER (VIA_DMA_BUFSIZ - 128)
+
+#define VIA_NO_CLIPRECTS 0x1
+
+
+/* Use the templated vertex formats:
+ */
+#define TAG(x) via##x
+#include "tnl_dd/t_dd_vertex.h"
+#undef TAG
+
+typedef void (*via_tri_func)(struct via_context *, viaVertex *, viaVertex *,
+ viaVertex *);
+typedef void (*via_line_func)(struct via_context *, viaVertex *, viaVertex *);
+typedef void (*via_point_func)(struct via_context *, viaVertex *);
+
+/**
+ * Derived from gl_renderbuffer.
+ */
+struct via_renderbuffer {
+ struct gl_renderbuffer Base; /* must be first! */
+ drm_handle_t handle;
+ drmSize size;
+ unsigned long offset;
+ unsigned long index;
+ GLuint pitch;
+ GLuint bpp;
+ char *map;
+ GLuint orig; /* The drawing origin,
+ * at (drawX,drawY) in screen space.
+ */
+ char *origMap;
+
+ int drawX; /* origin of drawable in draw buffer */
+ int drawY;
+ int drawW;
+ int drawH;
+
+ __DRIdrawablePrivate *dPriv;
+};
+
+
+#define VIA_MAX_TEXLEVELS 10
+
+struct via_tex_buffer {
+ struct via_tex_buffer *next, *prev;
+ struct via_texture_image *image;
+ unsigned long index;
+ unsigned long offset;
+ GLuint size;
+ GLuint memType;
+ unsigned char *bufAddr;
+ GLuint texBase;
+ GLuint lastUsed;
+};
+
+
+
+struct via_texture_image {
+ struct gl_texture_image image;
+ struct via_tex_buffer *texMem;
+ GLint pitchLog2;
+};
+
+struct via_texture_object {
+ struct gl_texture_object obj; /* The "parent" object */
+
+ GLuint texelBytes;
+ GLuint memType;
+
+ 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] */
+};
+
+
+
+struct via_context {
+ GLint refcount;
+ GLcontext *glCtx;
+ GLcontext *shareCtx;
+
+ /* XXX These don't belong here. They should be per-drawable state. */
+ struct via_renderbuffer front;
+ struct via_renderbuffer back;
+ struct via_renderbuffer depth;
+ struct via_renderbuffer stencil; /* mirrors depth */
+ struct via_renderbuffer breadcrumb;
+
+ GLboolean hasBack;
+ GLboolean hasDepth;
+ GLboolean hasStencil;
+ GLboolean hasAccum;
+ GLuint depthBits;
+ GLuint stencilBits;
+
+ GLboolean have_hw_stencil;
+ GLuint ClearDepth;
+ GLuint depth_clear_mask;
+ GLuint stencil_clear_mask;
+ GLfloat depth_max;
+ GLfloat polygon_offset_scale;
+
+ GLubyte *dma;
+ viaRegion tex;
+
+ /* Bit flag to keep 0track of fallbacks.
+ */
+ GLuint Fallback;
+
+ /* State for via_tris.c.
+ */
+ GLuint newState; /* _NEW_* flags */
+ GLuint newEmitState; /* _NEW_* flags */
+ GLuint newRenderState; /* _NEW_* flags */
+
+ struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
+ GLuint vertex_attr_count;
+
+ GLuint setupIndex;
+ GLuint renderIndex;
+ GLmatrix ViewportMatrix;
+ GLenum renderPrimitive;
+ GLenum hwPrimitive;
+ GLenum hwShadeModel;
+ unsigned char *verts;
+
+ /* drmBufPtr dma_buffer;
+ */
+ GLuint dmaLow;
+ GLuint dmaCliprectAddr;
+ GLuint dmaLastPrim;
+ GLboolean useAgp;
+
+
+ /* Fallback rasterization functions
+ */
+ via_point_func drawPoint;
+ via_line_func drawLine;
+ via_tri_func drawTri;
+
+ /* Hardware register
+ */
+ 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 regHTXnCLOD[2];
+ GLuint regHTXnTB[2];
+ GLuint regHTXnMPMD[2];
+ GLuint regHTXnTBLCsat[2];
+ GLuint regHTXnTBLCop[2];
+ GLuint regHTXnTBLMPfog[2];
+ GLuint regHTXnTBLAsat[2];
+ GLuint regHTXnTBLRCb[2];
+ GLuint regHTXnTBLRAa[2];
+ GLuint regHTXnTBLRFog[2];
+ GLuint regHTXnTBLRCa[2];
+ GLuint regHTXnTBLRCc[2];
+ GLuint regHTXnTBLRCbias[2];
+ GLuint regHTXnTBC[2];
+ GLuint regHTXnTRAH[2];
+
+ int vertexSize;
+ int hwVertexSize;
+ GLboolean ptexHack;
+ int coloroffset;
+ int specoffset;
+
+ GLint lastStamp;
+
+ GLuint ClearColor;
+ GLuint ClearMask;
+
+ /* DRI stuff
+ */
+ GLboolean doPageFlip;
+
+ struct via_renderbuffer *drawBuffer;
+
+ GLuint numClipRects; /* cliprects for that buffer */
+ drm_clip_rect_t *pClipRects;
+
+ GLboolean scissor;
+ drm_clip_rect_t drawRect;
+ drm_clip_rect_t scissorRect;
+
+ drm_context_t hHWContext;
+ drm_hw_lock_t *driHwLock;
+ int driFd;
+ __DRInativeDisplay *display;
+
+ /**
+ * DRI drawable bound to this context for drawing.
+ */
+ __DRIdrawablePrivate *driDrawable;
+
+ /**
+ * DRI drawable bound to this context for reading.
+ */
+ __DRIdrawablePrivate *driReadable;
+
+ __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;
+
+ GLuint nDoneFirstFlip;
+ GLuint agpFullCount;
+
+ GLboolean clearTexCache;
+ GLboolean thrashing;
+
+ /* Configuration cache
+ */
+ driOptionCache optionCache;
+
+ GLuint vblank_flags;
+ GLuint vbl_seq;
+
+ int64_t swap_ust;
+ int64_t swap_missed_ust;
+
+ GLuint swap_count;
+ GLuint swap_missed_count;
+
+
+ GLuint pfCurrentOffset;
+ GLboolean allowPageFlip;
+
+ GLuint lastBreadcrumbRead;
+ GLuint lastBreadcrumbWrite;
+ GLuint lastSwap[2];
+ GLuint lastDma;
+
+ GLuint total_alloc[VIA_MEM_SYSTEM+1];
+
+ struct via_tex_buffer tex_image_list[VIA_MEM_SYSTEM+1];
+ struct via_tex_buffer freed_tex_buffers;
+
+};
+
+
+
+#define VIA_CONTEXT(ctx) ((struct via_context *)(ctx->DriverCtx))
+
+
+
+/* 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)
+
+
+/* Release the kernel lock.
+ */
+#define UNLOCK_HARDWARE(vmesa) \
+ DRM_UNLOCK(vmesa->driFd, vmesa->driHwLock, vmesa->hHWContext);
+
+
+
+extern GLuint VIA_DEBUG;
+
+#define DEBUG_TEXTURE 0x1
+#define DEBUG_STATE 0x2
+#define DEBUG_IOCTL 0x4
+#define DEBUG_PRIMS 0x8
+#define DEBUG_VERTS 0x10
+#define DEBUG_FALLBACKS 0x20
+#define DEBUG_VERBOSE 0x40
+#define DEBUG_DRI 0x80
+#define DEBUG_DMA 0x100
+#define DEBUG_SANITY 0x200
+#define DEBUG_SYNC 0x400
+#define DEBUG_SLEEP 0x800
+#define DEBUG_PIXEL 0x1000
+#define DEBUG_2D 0x2000
+
+
+extern void viaGetLock(struct via_context *vmesa, GLuint flags);
+extern void viaLock(struct via_context *vmesa, GLuint flags);
+extern void viaUnLock(struct via_context *vmesa, GLuint flags);
+extern void viaEmitHwStateLocked(struct via_context *vmesa);
+extern void viaEmitScissorValues(struct via_context *vmesa, int box_nr, int emit);
+extern void viaXMesaSetBackClipRects(struct via_context *vmesa);
+extern void viaXMesaSetFrontClipRects(struct via_context *vmesa);
+extern void viaReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer, GLuint width, GLuint height);
+extern void viaXMesaWindowMoved(struct via_context *vmesa);
+
+extern GLboolean viaTexCombineState(struct via_context *vmesa,
+ const struct gl_tex_env_combine_state * combine,
+ unsigned unit );
+
+/* Via hw already adjusted for GL pixel centers:
+ */
+#define SUBPIXEL_X 0
+#define SUBPIXEL_Y 0
+
+/* 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_BIT_CLIP
+#define VERT_BIT_CLIP 0x1000000
+#endif
+
+#endif
diff --git a/src/via_drmclient.h b/src/via_drmclient.h
new file mode 100644
index 0000000..7beff9a
--- /dev/null
+++ b/src/via_drmclient.h
@@ -0,0 +1,29 @@
+/*
+ *
+ * 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
+ * THE AUTHOR(S) AND/OR THE COPYRIGHT HOLDER(S) 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_DRMCLIENT_H_
+#define _VIA_DRMCLIENT_H_
+
+#define VIA_DMA_BUF_ORDER 12
+#define VIA_DMA_BUF_SZ (1 << VIA_DMA_BUF_ORDER)
+#define VIA_DMA_BUF_NR 256
+
+#endif /* _VIA_DRMCLIENT_H_ */
diff --git a/src/via_fb.c b/src/via_fb.c
new file mode 100644
index 0000000..48c7ed4
--- /dev/null
+++ b/src/via_fb.c
@@ -0,0 +1,243 @@
+/*
+ * 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 "xf86drm.h"
+#include "imports.h"
+#include "simple_list.h"
+#include <sys/ioctl.h>
+
+GLboolean
+via_alloc_draw_buffer(struct via_context *vmesa, struct via_renderbuffer *buf)
+{
+ drm_via_mem_t mem;
+ mem.context = vmesa->hHWContext;
+ mem.size = buf->size;
+ mem.type = VIA_MEM_VIDEO;
+ mem.offset = 0;
+ mem.index = 0;
+
+ if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &mem))
+ return GL_FALSE;
+
+
+ buf->offset = mem.offset;
+ buf->map = (char *)vmesa->driScreen->pFB + mem.offset;
+ buf->index = mem.index;
+ return GL_TRUE;
+}
+
+void
+via_free_draw_buffer(struct via_context *vmesa, struct via_renderbuffer *buf)
+{
+ drm_via_mem_t mem;
+
+ if (!vmesa) return;
+
+ mem.context = vmesa->hHWContext;
+ mem.index = buf->index;
+ mem.type = VIA_MEM_VIDEO;
+ mem.offset = buf->offset;
+ mem.size = buf->size;
+
+ ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &mem);
+ buf->map = NULL;
+}
+
+
+GLboolean
+via_alloc_dma_buffer(struct via_context *vmesa)
+{
+ drm_via_dma_init_t init;
+
+ vmesa->dma = (GLubyte *) malloc(VIA_DMA_BUFSIZ);
+
+ /*
+ * Check whether AGP DMA has been initialized.
+ */
+ memset(&init, 0, sizeof(init));
+ init.func = VIA_DMA_INITIALIZED;
+
+ vmesa->useAgp =
+ ( 0 == drmCommandWrite(vmesa->driFd, DRM_VIA_DMA_INIT,
+ &init, sizeof(init)));
+ if (VIA_DEBUG & DEBUG_DMA) {
+ if (vmesa->useAgp)
+ fprintf(stderr, "unichrome_dri.so: Using AGP.\n");
+ else
+ fprintf(stderr, "unichrome_dri.so: Using PCI.\n");
+ }
+
+ return ((vmesa->dma) ? GL_TRUE : GL_FALSE);
+}
+
+void
+via_free_dma_buffer(struct via_context *vmesa)
+{
+ if (!vmesa) return;
+ free(vmesa->dma);
+ vmesa->dma = 0;
+}
+
+
+/* These functions now allocate and free the via_tex_buffer struct as well:
+ */
+struct via_tex_buffer *
+via_alloc_texture(struct via_context *vmesa,
+ GLuint size,
+ GLuint memType)
+{
+ struct via_tex_buffer *t = CALLOC_STRUCT(via_tex_buffer);
+
+ if (!t)
+ goto cleanup;
+
+ t->size = size;
+ t->memType = memType;
+ insert_at_tail(&vmesa->tex_image_list[memType], t);
+
+ if (t->memType == VIA_MEM_AGP ||
+ t->memType == VIA_MEM_VIDEO) {
+ drm_via_mem_t fb;
+
+ fb.context = vmesa->hHWContext;
+ fb.size = t->size;
+ fb.type = t->memType;
+ fb.offset = 0;
+ fb.index = 0;
+
+ if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb) != 0 ||
+ fb.index == 0)
+ goto cleanup;
+
+ if (0)
+ fprintf(stderr, "offset %lx index %lx\n", fb.offset, fb.index);
+
+ t->offset = fb.offset;
+ t->index = fb.index;
+
+ if (t->memType == VIA_MEM_AGP) {
+ t->bufAddr = (GLubyte *)((unsigned long)vmesa->viaScreen->agpLinearStart +
+ fb.offset);
+ t->texBase = vmesa->agpBase + fb.offset;
+ }
+ else {
+ t->bufAddr = (GLubyte *)((unsigned long)vmesa->driScreen->pFB + fb.offset);
+ t->texBase = fb.offset;
+ }
+
+ vmesa->total_alloc[t->memType] += t->size;
+ return t;
+ }
+ else if (t->memType == VIA_MEM_SYSTEM) {
+
+ t->bufAddr = _mesa_malloc(t->size);
+ if (!t->bufAddr)
+ goto cleanup;
+
+ vmesa->total_alloc[t->memType] += t->size;
+ return t;
+ }
+
+ cleanup:
+ if (t) {
+ remove_from_list(t);
+ FREE(t);
+ }
+
+ return NULL;
+}
+
+
+static void
+via_do_free_texture(struct via_context *vmesa, struct via_tex_buffer *t)
+{
+ drm_via_mem_t fb;
+
+ remove_from_list( t );
+
+ vmesa->total_alloc[t->memType] -= t->size;
+
+ fb.context = vmesa->hHWContext;
+ fb.index = t->index;
+ fb.offset = t->offset;
+ fb.type = t->memType;
+ fb.size = t->size;
+
+ if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb)) {
+ fprintf(stderr, "via_free_texture fail\n");
+ }
+
+ FREE(t);
+}
+
+
+/* Release textures which were potentially still being referenced by
+ * hardware at the time when they were originally freed.
+ */
+void
+via_release_pending_textures( struct via_context *vmesa )
+{
+ struct via_tex_buffer *s, *tmp;
+
+ foreach_s( s, tmp, &vmesa->freed_tex_buffers ) {
+ if (!VIA_GEQ_WRAP(s->lastUsed, vmesa->lastBreadcrumbRead)) {
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "%s: release tex sz %d lastUsed %x\n",
+ __FUNCTION__, s->size, s->lastUsed);
+ via_do_free_texture(vmesa, s);
+ }
+ }
+}
+
+
+
+void
+via_free_texture(struct via_context *vmesa, struct via_tex_buffer *t)
+{
+ if (!t) {
+ return;
+ }
+ else if (t->memType == VIA_MEM_SYSTEM) {
+ remove_from_list(t);
+ vmesa->total_alloc[t->memType] -= t->size;
+ _mesa_free(t->bufAddr);
+ _mesa_free(t);
+ }
+ else if (t->index && viaCheckBreadcrumb(vmesa, t->lastUsed)) {
+ via_do_free_texture( vmesa, t );
+ }
+ else {
+ /* Close current breadcrumb so that we can free this eventually:
+ */
+ if (t->lastUsed == vmesa->lastBreadcrumbWrite)
+ viaEmitBreadcrumb(vmesa);
+
+ move_to_tail( &vmesa->freed_tex_buffers, t );
+ }
+}
diff --git a/src/via_fb.h b/src/via_fb.h
new file mode 100644
index 0000000..2d329ac
--- /dev/null
+++ b/src/via_fb.h
@@ -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 "via_context.h"
+
+extern GLboolean via_alloc_draw_buffer(struct via_context *vmesa, struct via_renderbuffer *buf);
+extern GLboolean via_alloc_dma_buffer(struct via_context *vmesa);
+
+struct via_tex_buffer *
+via_alloc_texture(struct via_context *vmesa,
+ GLuint size,
+ GLuint memType);
+
+extern void via_free_draw_buffer(struct via_context *vmesa, struct via_renderbuffer *buf);
+extern void via_free_dma_buffer(struct via_context *vmesa);
+extern void via_free_texture(struct via_context *vmesa, struct via_tex_buffer *t);
+void via_release_pending_textures( struct via_context *vmesa );
+#endif
diff --git a/src/via_ioctl.c b/src/via_ioctl.c
new file mode 100644
index 0000000..4a733fb
--- /dev/null
+++ b/src/via_ioctl.c
@@ -0,0 +1,981 @@
+/*
+ * 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_tris.h"
+#include "via_ioctl.h"
+#include "via_state.h"
+#include "via_fb.h"
+#include "via_3d_reg.h"
+
+#include "vblank.h"
+#include "drm.h"
+#include "xf86drm.h"
+#include <sys/ioctl.h>
+#include <errno.h>
+
+
+#define VIA_REG_STATUS 0x400
+#define VIA_REG_GEMODE 0x004
+#define VIA_REG_SRCBASE 0x030
+#define VIA_REG_DSTBASE 0x034
+#define VIA_REG_PITCH 0x038
+#define VIA_REG_SRCCOLORKEY 0x01C
+#define VIA_REG_KEYCONTROL 0x02C
+#define VIA_REG_SRCPOS 0x008
+#define VIA_REG_DSTPOS 0x00C
+#define VIA_REG_GECMD 0x000
+#define VIA_REG_DIMENSION 0x010 /* width and height */
+#define VIA_REG_FGCOLOR 0x018
+
+#define VIA_GEM_8bpp 0x00000000
+#define VIA_GEM_16bpp 0x00000100
+#define VIA_GEM_32bpp 0x00000300
+#define VIA_GEC_BLT 0x00000001
+#define VIA_PITCH_ENABLE 0x80000000
+#define VIA_GEC_INCX 0x00000000
+#define VIA_GEC_DECY 0x00004000
+#define VIA_GEC_INCY 0x00000000
+#define VIA_GEC_DECX 0x00008000
+#define VIA_GEC_FIXCOLOR_PAT 0x00002000
+
+
+#define VIA_BLIT_CLEAR 0x00
+#define VIA_BLIT_COPY 0xCC
+#define VIA_BLIT_FILL 0xF0
+#define VIA_BLIT_SET 0xFF
+
+static void dump_dma( struct via_context *vmesa )
+{
+ GLuint i;
+ GLuint *data = (GLuint *)vmesa->dma;
+ for (i = 0; i < vmesa->dmaLow; i += 16) {
+ fprintf(stderr, "%04x: ", i);
+ fprintf(stderr, "%08x ", *data++);
+ fprintf(stderr, "%08x ", *data++);
+ fprintf(stderr, "%08x ", *data++);
+ fprintf(stderr, "%08x\n", *data++);
+ }
+ fprintf(stderr, "******************************************\n");
+}
+
+
+
+void viaCheckDma(struct via_context *vmesa, GLuint bytes)
+{
+ VIA_FINISH_PRIM( vmesa );
+ if (vmesa->dmaLow + bytes > VIA_DMA_HIGHWATER) {
+ viaFlushDma(vmesa);
+ }
+}
+
+
+
+#define SetReg2DAGP(nReg, nData) do { \
+ OUT_RING( ((nReg) >> 2) | 0xF0000000 ); \
+ OUT_RING( nData ); \
+} while (0)
+
+
+static void viaBlit(struct via_context *vmesa, GLuint bpp,
+ GLuint srcBase, GLuint srcPitch,
+ GLuint dstBase, GLuint dstPitch,
+ GLuint w, GLuint h,
+ GLuint blitMode,
+ GLuint color, GLuint nMask )
+{
+
+ GLuint dwGEMode, srcX, dstX, cmd;
+ RING_VARS;
+
+ if (VIA_DEBUG & DEBUG_2D)
+ fprintf(stderr,
+ "%s bpp %d src %x/%x dst %x/%x w %d h %d "
+ " mode: %x color: 0x%08x mask 0x%08x\n",
+ __FUNCTION__, bpp, srcBase, srcPitch, dstBase,
+ dstPitch, w,h, blitMode, color, nMask);
+
+
+ if (!w || !h)
+ return;
+
+ switch (bpp) {
+ case 16:
+ dwGEMode = VIA_GEM_16bpp;
+ srcX = (srcBase & 0x1f) >> 1;
+ dstX = (dstBase & 0x1f) >> 1;
+ break;
+ case 32:
+ dwGEMode = VIA_GEM_32bpp;
+ srcX = (srcBase & 0x1f) >> 2;
+ dstX = (dstBase & 0x1f) >> 2;
+ break;
+ default:
+ return;
+ }
+
+ switch(blitMode) {
+ case VIA_BLIT_FILL:
+ cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (VIA_BLIT_FILL << 24);
+ break;
+ case VIA_BLIT_COPY:
+ cmd = VIA_GEC_BLT | (VIA_BLIT_COPY << 24);
+ break;
+ default:
+ return;
+ }
+
+ BEGIN_RING(22);
+ SetReg2DAGP( VIA_REG_GEMODE, dwGEMode);
+ SetReg2DAGP( VIA_REG_FGCOLOR, color);
+ SetReg2DAGP( 0x2C, nMask);
+ SetReg2DAGP( VIA_REG_SRCBASE, (srcBase & ~0x1f) >> 3);
+ SetReg2DAGP( VIA_REG_DSTBASE, (dstBase & ~0x1f) >> 3);
+ SetReg2DAGP( VIA_REG_PITCH, VIA_PITCH_ENABLE |
+ (srcPitch >> 3) | ((dstPitch >> 3) << 16));
+ SetReg2DAGP( VIA_REG_SRCPOS, srcX);
+ SetReg2DAGP( VIA_REG_DSTPOS, dstX);
+ SetReg2DAGP( VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
+ SetReg2DAGP( VIA_REG_GECMD, cmd);
+ SetReg2DAGP( 0x2C, 0x00000000);
+ ADVANCE_RING();
+}
+
+static void viaFillBuffer(struct via_context *vmesa,
+ struct via_renderbuffer *buffer,
+ drm_clip_rect_t *pbox,
+ int nboxes,
+ GLuint pixel,
+ GLuint mask)
+{
+ GLuint bytePerPixel = buffer->bpp >> 3;
+ GLuint i;
+
+ for (i = 0; i < nboxes ; i++) {
+ int x = pbox[i].x1 - buffer->drawX;
+ int y = pbox[i].y1 - buffer->drawY;
+ int w = pbox[i].x2 - pbox[i].x1;
+ int h = pbox[i].y2 - pbox[i].y1;
+
+ int offset = (buffer->offset +
+ y * buffer->pitch +
+ x * bytePerPixel);
+
+ viaBlit(vmesa,
+ buffer->bpp,
+ offset, buffer->pitch,
+ offset, buffer->pitch,
+ w, h,
+ VIA_BLIT_FILL, pixel, mask);
+ }
+}
+
+
+
+static void viaClear(GLcontext *ctx, GLbitfield mask)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+ struct via_renderbuffer *const vrb =
+ (struct via_renderbuffer *) dPriv->driverPrivate;
+ int flag = 0;
+ GLuint i = 0;
+ GLuint clear_depth_mask = 0xf << 28;
+ GLuint clear_depth = 0;
+
+ VIA_FLUSH_DMA(vmesa);
+
+ if (mask & BUFFER_BIT_FRONT_LEFT) {
+ flag |= VIA_FRONT;
+ mask &= ~BUFFER_BIT_FRONT_LEFT;
+ }
+
+ if (mask & BUFFER_BIT_BACK_LEFT) {
+ flag |= VIA_BACK;
+ mask &= ~BUFFER_BIT_BACK_LEFT;
+ }
+
+ if (mask & BUFFER_BIT_DEPTH) {
+ flag |= VIA_DEPTH;
+ clear_depth = (GLuint)(ctx->Depth.Clear * vmesa->ClearDepth);
+ clear_depth_mask &= ~vmesa->depth_clear_mask;
+ mask &= ~BUFFER_BIT_DEPTH;
+ }
+
+ if (mask & BUFFER_BIT_STENCIL) {
+ if (vmesa->have_hw_stencil) {
+ if ((ctx->Stencil.WriteMask[0] & 0xff) == 0xff) {
+ flag |= VIA_DEPTH;
+ clear_depth &= ~0xff;
+ clear_depth |= (ctx->Stencil.Clear & 0xff);
+ clear_depth_mask &= ~vmesa->stencil_clear_mask;
+ mask &= ~BUFFER_BIT_STENCIL;
+ }
+ else {
+ if (VIA_DEBUG & DEBUG_2D)
+ fprintf(stderr, "Clear stencil writemask %x\n",
+ ctx->Stencil.WriteMask[0]);
+ }
+ }
+ }
+
+ /* 16bpp doesn't support masked clears */
+ if (vmesa->viaScreen->bytesPerPixel == 2 &&
+ vmesa->ClearMask & 0xf0000000) {
+ if (flag & VIA_FRONT)
+ mask |= BUFFER_BIT_FRONT_LEFT;
+ if (flag & VIA_BACK)
+ mask |= BUFFER_BIT_BACK_LEFT;
+ flag &= ~(VIA_FRONT | VIA_BACK);
+ }
+
+ if (flag) {
+ drm_clip_rect_t *boxes, *tmp_boxes = 0;
+ int nr = 0;
+ GLint cx, cy, cw, ch;
+ GLboolean all;
+
+ LOCK_HARDWARE(vmesa);
+
+ /* get region after locking: */
+ cx = ctx->DrawBuffer->_Xmin;
+ cy = ctx->DrawBuffer->_Ymin;
+ cw = ctx->DrawBuffer->_Xmax - cx;
+ ch = ctx->DrawBuffer->_Ymax - cy;
+ all = (cw == ctx->DrawBuffer->Width && ch == ctx->DrawBuffer->Height);
+
+ /* flip top to bottom */
+ cy = dPriv->h - cy - ch;
+ cx += vrb->drawX;
+ cy += vrb->drawY;
+
+ if (!all) {
+ drm_clip_rect_t *b = vmesa->pClipRects;
+
+ boxes = tmp_boxes =
+ (drm_clip_rect_t *)malloc(vmesa->numClipRects *
+ sizeof(drm_clip_rect_t));
+ if (!boxes) {
+ UNLOCK_HARDWARE(vmesa);
+ return;
+ }
+
+ for (; i < vmesa->numClipRects; i++) {
+ GLint x = b[i].x1;
+ GLint y = b[i].y1;
+ GLint w = b[i].x2 - x;
+ GLint h = b[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;
+
+ boxes[nr].x1 = x;
+ boxes[nr].y1 = y;
+ boxes[nr].x2 = x + w;
+ boxes[nr].y2 = y + h;
+ nr++;
+ }
+ }
+ else {
+ boxes = vmesa->pClipRects;
+ nr = vmesa->numClipRects;
+ }
+
+ if (flag & VIA_FRONT) {
+ viaFillBuffer(vmesa, &vmesa->front, boxes, nr, vmesa->ClearColor,
+ vmesa->ClearMask);
+ }
+
+ if (flag & VIA_BACK) {
+ viaFillBuffer(vmesa, &vmesa->back, boxes, nr, vmesa->ClearColor,
+ vmesa->ClearMask);
+ }
+
+ if (flag & VIA_DEPTH) {
+ viaFillBuffer(vmesa, &vmesa->depth, boxes, nr, clear_depth,
+ clear_depth_mask);
+ }
+
+ viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS);
+ UNLOCK_HARDWARE(vmesa);
+
+ if (tmp_boxes)
+ free(tmp_boxes);
+ }
+
+ if (mask)
+ _swrast_Clear(ctx, mask);
+}
+
+
+
+
+static void viaDoSwapBuffers(struct via_context *vmesa,
+ drm_clip_rect_t *b,
+ GLuint nbox)
+{
+ GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
+ struct via_renderbuffer *front = &vmesa->front;
+ struct via_renderbuffer *back = &vmesa->back;
+ GLuint i;
+
+ for (i = 0; i < nbox; i++, b++) {
+ GLint x = b->x1 - back->drawX;
+ GLint y = b->y1 - back->drawY;
+ GLint w = b->x2 - b->x1;
+ GLint h = b->y2 - b->y1;
+
+ GLuint src = back->offset + y * back->pitch + x * bytePerPixel;
+ GLuint dest = front->offset + y * front->pitch + x * bytePerPixel;
+
+ viaBlit(vmesa,
+ bytePerPixel << 3,
+ src, back->pitch,
+ dest, front->pitch,
+ w, h,
+ VIA_BLIT_COPY, 0, 0);
+ }
+
+ viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); /* redundant */
+}
+
+
+static void viaEmitBreadcrumbLocked( struct via_context *vmesa )
+{
+ struct via_renderbuffer *buffer = &vmesa->breadcrumb;
+ GLuint value = vmesa->lastBreadcrumbWrite + 1;
+
+ if (VIA_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr, "%s %d\n", __FUNCTION__, value);
+
+ assert(!vmesa->dmaLow);
+
+ viaBlit(vmesa,
+ buffer->bpp,
+ buffer->offset, buffer->pitch,
+ buffer->offset, buffer->pitch,
+ 1, 1,
+ VIA_BLIT_FILL, value, 0);
+
+ viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); /* often redundant */
+ vmesa->lastBreadcrumbWrite = value;
+}
+
+void viaEmitBreadcrumb( struct via_context *vmesa )
+{
+ LOCK_HARDWARE(vmesa);
+ if (vmesa->dmaLow)
+ viaFlushDmaLocked(vmesa, 0);
+
+ viaEmitBreadcrumbLocked( vmesa );
+ UNLOCK_HARDWARE(vmesa);
+}
+
+static GLboolean viaCheckIdle( struct via_context *vmesa )
+{
+ if ((vmesa->regEngineStatus[0] & 0xFFFEFFFF) == 0x00020000) {
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+}
+
+
+GLboolean viaCheckBreadcrumb( struct via_context *vmesa, GLuint value )
+{
+ GLuint *buf = (GLuint *)vmesa->breadcrumb.map;
+ vmesa->lastBreadcrumbRead = *buf;
+
+ if (VIA_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr, "%s %d < %d: %d\n", __FUNCTION__, value,
+ vmesa->lastBreadcrumbRead,
+ !VIA_GEQ_WRAP(value, vmesa->lastBreadcrumbRead));
+
+ return !VIA_GEQ_WRAP(value, vmesa->lastBreadcrumbRead);
+}
+
+static void viaWaitBreadcrumb( struct via_context *vmesa, GLuint value )
+{
+ if (VIA_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr, "%s %d\n", __FUNCTION__, value);
+
+ assert(!VIA_GEQ_WRAP(value, vmesa->lastBreadcrumbWrite));
+
+ while (!viaCheckBreadcrumb( vmesa, value )) {
+ viaSwapOutWork( vmesa );
+ via_release_pending_textures( vmesa );
+ }
+}
+
+
+void viaWaitIdle( struct via_context *vmesa, GLboolean light )
+{
+ VIA_FLUSH_DMA(vmesa);
+
+ if (VIA_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr, "%s lastDma %d lastBreadcrumbWrite %d\n",
+ __FUNCTION__, vmesa->lastDma, vmesa->lastBreadcrumbWrite);
+
+ /* Need to emit a new breadcrumb?
+ */
+ if (vmesa->lastDma == vmesa->lastBreadcrumbWrite) {
+ LOCK_HARDWARE(vmesa);
+ viaEmitBreadcrumbLocked( vmesa );
+ UNLOCK_HARDWARE(vmesa);
+ }
+
+ /* Need to wait?
+ */
+ if (VIA_GEQ_WRAP(vmesa->lastDma, vmesa->lastBreadcrumbRead))
+ viaWaitBreadcrumb( vmesa, vmesa->lastDma );
+
+ if (light) return;
+
+ LOCK_HARDWARE(vmesa);
+ while(!viaCheckIdle(vmesa))
+ ;
+ UNLOCK_HARDWARE(vmesa);
+ via_release_pending_textures(vmesa);
+}
+
+
+void viaWaitIdleLocked( struct via_context *vmesa, GLboolean light )
+{
+ if (vmesa->dmaLow)
+ viaFlushDmaLocked(vmesa, 0);
+
+ if (VIA_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr, "%s lastDma %d lastBreadcrumbWrite %d\n",
+ __FUNCTION__, vmesa->lastDma, vmesa->lastBreadcrumbWrite);
+
+ /* Need to emit a new breadcrumb?
+ */
+ if (vmesa->lastDma == vmesa->lastBreadcrumbWrite) {
+ viaEmitBreadcrumbLocked( vmesa );
+ }
+
+ /* Need to wait?
+ */
+ if (vmesa->lastDma >= vmesa->lastBreadcrumbRead)
+ viaWaitBreadcrumb( vmesa, vmesa->lastDma );
+
+ if (light) return;
+
+ while(!viaCheckIdle(vmesa))
+ ;
+
+ via_release_pending_textures(vmesa);
+}
+
+
+
+/* Wait for command stream to be processed *and* the next vblank to
+ * occur. Equivalent to calling WAIT_IDLE() and then WaitVBlank,
+ * except that WAIT_IDLE() will spin the CPU polling, while this is
+ * IRQ driven.
+ */
+static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv,
+ struct via_context *vmesa,
+ GLuint value )
+{
+ GLboolean missed_target;
+
+ VIA_FLUSH_DMA(vmesa);
+
+ if (!value)
+ return;
+
+ do {
+ if (value < vmesa->lastBreadcrumbRead ||
+ vmesa->thrashing)
+ viaSwapOutWork(vmesa);
+
+ driWaitForVBlank( dPriv, & vmesa->vbl_seq,
+ vmesa->vblank_flags, & missed_target );
+ if ( missed_target ) {
+ vmesa->swap_missed_count++;
+ (*dri_interface->getUST)( &vmesa->swap_missed_ust );
+ }
+ }
+ while (!viaCheckBreadcrumb(vmesa, value));
+
+ vmesa->thrashing = 0; /* reset flag on swap */
+ vmesa->swap_count++;
+ via_release_pending_textures( vmesa );
+}
+
+
+
+static void viaDoPageFlipLocked(struct via_context *vmesa, GLuint offset)
+{
+ RING_VARS;
+
+ if (VIA_DEBUG & DEBUG_2D)
+ fprintf(stderr, "%s %x\n", __FUNCTION__, offset);
+
+ if (!vmesa->nDoneFirstFlip) {
+ vmesa->nDoneFirstFlip = GL_TRUE;
+ BEGIN_RING(4);
+ OUT_RING(HALCYON_HEADER2);
+ OUT_RING(0x00fe0000);
+ OUT_RING(0x0000000e);
+ OUT_RING(0x0000000e);
+ ADVANCE_RING();
+ }
+
+ BEGIN_RING(4);
+ OUT_RING( HALCYON_HEADER2 );
+ OUT_RING( 0x00fe0000 );
+ OUT_RING((HC_SubA_HFBBasL << 24) | (offset & 0xFFFFF8) | 0x2);
+ OUT_RING((HC_SubA_HFBDrawFirst << 24) |
+ ((offset & 0xFF000000) >> 24) | 0x0100);
+ ADVANCE_RING();
+
+ vmesa->pfCurrentOffset = vmesa->sarea->pfCurrentOffset = offset;
+
+ viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); /* often redundant */
+}
+
+void viaResetPageFlippingLocked(struct via_context *vmesa)
+{
+ if (VIA_DEBUG & DEBUG_2D)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ viaDoPageFlipLocked( vmesa, 0 );
+
+ if (vmesa->front.offset != 0) {
+ struct via_renderbuffer buffer_tmp;
+ memcpy(&buffer_tmp, &vmesa->back, sizeof(struct via_renderbuffer));
+ memcpy(&vmesa->back, &vmesa->front, sizeof(struct via_renderbuffer));
+ memcpy(&vmesa->front, &buffer_tmp, sizeof(struct via_renderbuffer));
+ }
+
+ assert(vmesa->front.offset == 0);
+ vmesa->doPageFlip = vmesa->allowPageFlip = 0;
+}
+
+
+/*
+ * Copy the back buffer to the front buffer.
+ */
+void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
+{
+ struct via_context *vmesa =
+ (struct via_context *)dPriv->driContextPriv->driverPrivate;
+
+ if (VIA_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr,
+ "%s: lastSwap[1] %d lastSwap[0] %d lastWrite %d lastRead %d\n",
+ __FUNCTION__,
+ vmesa->lastSwap[1],
+ vmesa->lastSwap[0],
+ vmesa->lastBreadcrumbWrite,
+ vmesa->lastBreadcrumbRead);
+
+ VIA_FLUSH_DMA(vmesa);
+
+ if (vmesa->vblank_flags == VBLANK_FLAG_SYNC &&
+ vmesa->lastBreadcrumbWrite > 1)
+ viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite-1);
+ else
+ viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastSwap[1]);
+
+ LOCK_HARDWARE(vmesa);
+
+ /* Catch and cleanup situation where we were pageflipping but have
+ * stopped.
+ */
+ if (dPriv->numClipRects && vmesa->sarea->pfCurrentOffset != 0) {
+ viaResetPageFlippingLocked(vmesa);
+ UNLOCK_HARDWARE(vmesa);
+ return;
+ }
+
+ viaDoSwapBuffers(vmesa, dPriv->pClipRects, dPriv->numClipRects);
+ vmesa->lastSwap[1] = vmesa->lastSwap[0];
+ vmesa->lastSwap[0] = vmesa->lastBreadcrumbWrite;
+ viaEmitBreadcrumbLocked(vmesa);
+ UNLOCK_HARDWARE(vmesa);
+
+ (*dri_interface->getUST)( &vmesa->swap_ust );
+}
+
+
+void viaPageFlip(const __DRIdrawablePrivate *dPriv)
+{
+ struct via_context *vmesa =
+ (struct via_context *)dPriv->driContextPriv->driverPrivate;
+ struct via_renderbuffer buffer_tmp;
+
+ VIA_FLUSH_DMA(vmesa);
+ if (vmesa->vblank_flags == VBLANK_FLAG_SYNC &&
+ vmesa->lastBreadcrumbWrite > 1)
+ viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite - 1);
+ else
+ viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastSwap[0]);
+
+ LOCK_HARDWARE(vmesa);
+ viaDoPageFlipLocked(vmesa, vmesa->back.offset);
+ vmesa->lastSwap[1] = vmesa->lastSwap[0];
+ vmesa->lastSwap[0] = vmesa->lastBreadcrumbWrite;
+ viaEmitBreadcrumbLocked(vmesa);
+ UNLOCK_HARDWARE(vmesa);
+
+ (*dri_interface->getUST)( &vmesa->swap_ust );
+
+
+ /* KW: FIXME: When buffers are freed, could free frontbuffer by
+ * accident:
+ */
+ memcpy(&buffer_tmp, &vmesa->back, sizeof(struct via_renderbuffer));
+ memcpy(&vmesa->back, &vmesa->front, sizeof(struct via_renderbuffer));
+ memcpy(&vmesa->front, &buffer_tmp, sizeof(struct via_renderbuffer));
+}
+
+
+
+
+#define VIA_CMDBUF_MAX_LAG 50000
+
+static int fire_buffer(struct via_context *vmesa)
+{
+ drm_via_cmdbuffer_t bufI;
+ int ret;
+
+ bufI.buf = (char *)vmesa->dma;
+ bufI.size = vmesa->dmaLow;
+
+ if (vmesa->useAgp) {
+ drm_via_cmdbuf_size_t bSiz;
+
+ /* Do the CMDBUF_SIZE ioctl:
+ */
+ bSiz.func = VIA_CMDBUF_LAG;
+ bSiz.wait = 1;
+ bSiz.size = VIA_CMDBUF_MAX_LAG;
+ do {
+ ret = drmCommandWriteRead(vmesa->driFd, DRM_VIA_CMDBUF_SIZE,
+ &bSiz, sizeof(bSiz));
+ } while (ret == -EAGAIN);
+ if (ret) {
+ UNLOCK_HARDWARE(vmesa);
+ fprintf(stderr, "%s: DRM_VIA_CMDBUF_SIZE returned %d\n",
+ __FUNCTION__, ret);
+ abort();
+ return ret;
+ }
+
+ /* Actually fire the buffer:
+ */
+ do {
+ ret = drmCommandWrite(vmesa->driFd, DRM_VIA_CMDBUFFER,
+ &bufI, sizeof(bufI));
+ } while (ret == -EAGAIN);
+ if (ret) {
+ UNLOCK_HARDWARE(vmesa);
+ fprintf(stderr, "%s: DRM_VIA_CMDBUFFER returned %d\n",
+ __FUNCTION__, ret);
+ abort();
+ /* If this fails, the original code fell back to the PCI path.
+ */
+ }
+ else
+ return 0;
+
+ /* Fall through to PCI handling?!?
+ */
+ viaWaitIdleLocked(vmesa, GL_FALSE);
+ }
+
+ ret = drmCommandWrite(vmesa->driFd, DRM_VIA_PCICMD, &bufI, sizeof(bufI));
+ if (ret) {
+ UNLOCK_HARDWARE(vmesa);
+ dump_dma(vmesa);
+ fprintf(stderr, "%s: DRM_VIA_PCICMD returned %d\n", __FUNCTION__, ret);
+ abort();
+ }
+
+ return ret;
+}
+
+
+/* Inserts the surface addresss and active cliprects one at a time
+ * into the head of the DMA buffer being flushed. Fires the buffer
+ * for each cliprect.
+ */
+static void via_emit_cliprect(struct via_context *vmesa,
+ drm_clip_rect_t *b)
+{
+ struct via_renderbuffer *buffer = vmesa->drawBuffer;
+ GLuint *vb = (GLuint *)(vmesa->dma + vmesa->dmaCliprectAddr);
+
+ GLuint format = (vmesa->viaScreen->bitsPerPixel == 0x20
+ ? HC_HDBFM_ARGB8888
+ : HC_HDBFM_RGB565);
+
+ GLuint pitch = buffer->pitch;
+ GLuint offset = buffer->offset;
+
+ if (0)
+ fprintf(stderr, "emit cliprect for box %d,%d %d,%d\n",
+ b->x1, b->y1, b->x2, b->y2);
+
+ vb[0] = HC_HEADER2;
+ vb[1] = (HC_ParaType_NotTex << 16);
+
+ if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
+ vb[2] = (HC_SubA_HClipTB << 24) | 0x0;
+ vb[3] = (HC_SubA_HClipLR << 24) | 0x0;
+ }
+ else {
+ vb[2] = (HC_SubA_HClipTB << 24) | (b->y1 << 12) | b->y2;
+ vb[3] = (HC_SubA_HClipLR << 24) | (b->x1 << 12) | b->x2;
+ }
+
+ vb[4] = (HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF);
+ vb[5] = (HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000) >> 24);
+
+ vb[6] = (HC_SubA_HSPXYOS << 24);
+ vb[7] = (HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch;
+}
+
+
+
+static int intersect_rect(drm_clip_rect_t *out,
+ drm_clip_rect_t *a,
+ drm_clip_rect_t *b)
+{
+ *out = *a;
+
+ if (0)
+ fprintf(stderr, "intersect %d,%d %d,%d and %d,%d %d,%d\n",
+ a->x1, a->y1, a->x2, a->y2,
+ b->x1, b->y1, b->x2, b->y2);
+
+ 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 viaFlushDmaLocked(struct via_context *vmesa, GLuint flags)
+{
+ int i;
+ RING_VARS;
+
+ if (VIA_DEBUG & (DEBUG_IOCTL|DEBUG_DMA))
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ if (*(GLuint *)vmesa->driHwLock != (DRM_LOCK_HELD|vmesa->hHWContext) &&
+ *(GLuint *)vmesa->driHwLock !=
+ (DRM_LOCK_HELD|DRM_LOCK_CONT|vmesa->hHWContext)) {
+ fprintf(stderr, "%s called without lock held\n", __FUNCTION__);
+ abort();
+ }
+
+ if (vmesa->dmaLow == 0) {
+ return;
+ }
+
+ assert(vmesa->dmaLastPrim == 0);
+
+ /* viaFinishPrimitive can add up to 8 bytes beyond VIA_DMA_HIGHWATER:
+ */
+ if (vmesa->dmaLow > VIA_DMA_HIGHWATER + 8) {
+ fprintf(stderr, "buffer overflow in Flush Prims = %d\n",vmesa->dmaLow);
+ abort();
+ }
+
+ switch (vmesa->dmaLow & 0x1F) {
+ case 8:
+ BEGIN_RING_NOCHECK( 6 );
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_NotTex << 16) );
+ OUT_RING( HC_DUMMY );
+ OUT_RING( HC_DUMMY );
+ OUT_RING( HC_DUMMY );
+ OUT_RING( HC_DUMMY );
+ ADVANCE_RING();
+ break;
+ case 16:
+ BEGIN_RING_NOCHECK( 4 );
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_NotTex << 16) );
+ OUT_RING( HC_DUMMY );
+ OUT_RING( HC_DUMMY );
+ ADVANCE_RING();
+ break;
+ case 24:
+ BEGIN_RING_NOCHECK( 10 );
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_NotTex << 16) );
+ OUT_RING( HC_DUMMY );
+ OUT_RING( HC_DUMMY );
+ OUT_RING( HC_DUMMY );
+ OUT_RING( HC_DUMMY );
+ OUT_RING( HC_DUMMY );
+ OUT_RING( HC_DUMMY );
+ OUT_RING( HC_DUMMY );
+ OUT_RING( HC_DUMMY );
+ ADVANCE_RING();
+ break;
+ case 0:
+ break;
+ default:
+ if (VIA_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr, "%s: unaligned value for vmesa->dmaLow: %x\n",
+ __FUNCTION__, vmesa->dmaLow);
+ }
+
+ vmesa->lastDma = vmesa->lastBreadcrumbWrite;
+
+ if (VIA_DEBUG & DEBUG_DMA)
+ dump_dma( vmesa );
+
+ if (flags & VIA_NO_CLIPRECTS) {
+ if (0) fprintf(stderr, "%s VIA_NO_CLIPRECTS\n", __FUNCTION__);
+ assert(vmesa->dmaCliprectAddr == ~0);
+ fire_buffer( vmesa );
+ }
+ else if (vmesa->dmaCliprectAddr == ~0) {
+ /* Contains only state. Could just dump the packet?
+ */
+ if (0) fprintf(stderr, "%s: no dmaCliprectAddr\n", __FUNCTION__);
+ if (0) fire_buffer( vmesa );
+ }
+ else if (vmesa->numClipRects) {
+ drm_clip_rect_t *pbox = vmesa->pClipRects;
+ __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+ struct via_renderbuffer *const vrb =
+ (struct via_renderbuffer *) dPriv->driverPrivate;
+
+ for (i = 0; i < vmesa->numClipRects; i++) {
+ drm_clip_rect_t b;
+
+ b.x1 = pbox[i].x1;
+ b.x2 = pbox[i].x2;
+ b.y1 = pbox[i].y1;
+ b.y2 = pbox[i].y2;
+
+ if (vmesa->scissor &&
+ !intersect_rect(&b, &b, &vmesa->scissorRect))
+ continue;
+
+ via_emit_cliprect(vmesa, &b);
+
+ if (fire_buffer(vmesa) != 0) {
+ dump_dma( vmesa );
+ goto done;
+ }
+ }
+ } else {
+ if (0) fprintf(stderr, "%s: no cliprects\n", __FUNCTION__);
+ UNLOCK_HARDWARE(vmesa);
+ sched_yield();
+ LOCK_HARDWARE(vmesa);
+ }
+
+ done:
+ /* Reset vmesa vars:
+ */
+ vmesa->dmaLow = 0;
+ vmesa->dmaCliprectAddr = ~0;
+ vmesa->newEmitState = ~0;
+}
+
+void viaWrapPrimitive( struct via_context *vmesa )
+{
+ GLenum renderPrimitive = vmesa->renderPrimitive;
+ GLenum hwPrimitive = vmesa->hwPrimitive;
+
+ if (VIA_DEBUG & DEBUG_PRIMS) fprintf(stderr, "%s\n", __FUNCTION__);
+
+ if (vmesa->dmaLastPrim)
+ viaFinishPrimitive( vmesa );
+
+ viaFlushDma(vmesa);
+
+ if (renderPrimitive != GL_POLYGON + 1)
+ viaRasterPrimitive( vmesa->glCtx,
+ renderPrimitive,
+ hwPrimitive );
+
+}
+
+void viaFlushDma(struct via_context *vmesa)
+{
+ if (vmesa->dmaLow) {
+ assert(!vmesa->dmaLastPrim);
+
+ LOCK_HARDWARE(vmesa);
+ viaFlushDmaLocked(vmesa, 0);
+ UNLOCK_HARDWARE(vmesa);
+ }
+}
+
+static void viaFlush(GLcontext *ctx)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ VIA_FLUSH_DMA(vmesa);
+}
+
+static void viaFinish(GLcontext *ctx)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ VIA_FLUSH_DMA(vmesa);
+ viaWaitIdle(vmesa, GL_FALSE);
+}
+
+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;
+}
+
+
+
diff --git a/src/via_ioctl.h b/src/via_ioctl.h
new file mode 100644
index 0000000..a81b427
--- /dev/null
+++ b/src/via_ioctl.h
@@ -0,0 +1,133 @@
+/*
+ * 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 viaFinishPrimitive(struct via_context *vmesa);
+void viaFlushDma(struct via_context *vmesa);
+void viaFlushDmaLocked(struct via_context *vmesa, GLuint flags);
+
+void viaInitIoctlFuncs(GLcontext *ctx);
+void viaCopyBuffer(const __DRIdrawablePrivate *dpriv);
+void viaPageFlip(const __DRIdrawablePrivate *dpriv);
+void viaCheckDma(struct via_context *vmesa, GLuint bytes);
+void viaResetPageFlippingLocked(struct via_context *vmesa);
+void viaWaitIdle(struct via_context *vmesa, GLboolean light);
+void viaWaitIdleLocked(struct via_context *vmesa, GLboolean light);
+
+GLboolean viaCheckBreadcrumb( struct via_context *vmesa, GLuint value );
+void viaEmitBreadcrumb( struct via_context *vmesa );
+
+
+#define VIA_FINISH_PRIM(vmesa) do { \
+ if (vmesa->dmaLastPrim) \
+ viaFinishPrimitive( vmesa ); \
+} while (0)
+
+#define VIA_FLUSH_DMA(vmesa) do { \
+ VIA_FINISH_PRIM(vmesa); \
+ if (vmesa->dmaLow) \
+ viaFlushDma(vmesa); \
+} while (0)
+
+
+void viaWrapPrimitive( struct via_context *vmesa );
+
+static __inline__ GLuint *viaAllocDma(struct via_context *vmesa, int bytes)
+{
+ if (vmesa->dmaLow + bytes > VIA_DMA_HIGHWATER) {
+ viaFlushDma(vmesa);
+ }
+
+ {
+ GLuint *start = (GLuint *)(vmesa->dma + vmesa->dmaLow);
+ vmesa->dmaLow += bytes;
+ return start;
+ }
+}
+
+
+static GLuint __inline__ *viaExtendPrimitive(struct via_context *vmesa, int bytes)
+{
+ if (vmesa->dmaLow + bytes > VIA_DMA_HIGHWATER) {
+ viaWrapPrimitive(vmesa);
+ }
+
+ {
+ GLuint *start = (GLuint *)(vmesa->dma + vmesa->dmaLow);
+ vmesa->dmaLow += bytes;
+ return start;
+ }
+}
+
+
+
+
+#define RING_VARS GLuint *_vb = 0, _nr, _x;
+
+#define BEGIN_RING(n) do { \
+ if (_vb != 0) abort(); \
+ _vb = viaAllocDma(vmesa, (n) * sizeof(GLuint)); \
+ _nr = (n); \
+ _x = 0; \
+} while (0)
+
+#define BEGIN_RING_NOCHECK(n) do { \
+ if (_vb != 0) abort(); \
+ _vb = (GLuint *)(vmesa->dma + vmesa->dmaLow); \
+ vmesa->dmaLow += (n) * sizeof(GLuint); \
+ _nr = (n); \
+ _x = 0; \
+} while (0)
+
+#define OUT_RING(n) _vb[_x++] = (n)
+
+#define ADVANCE_RING() do { \
+ if (_x != _nr) abort(); \
+ _vb = 0; \
+} while (0)
+
+#define ADVANCE_RING_VARIABLE() do { \
+ if (_x > _nr) abort(); \
+ vmesa->dmaLow -= (_nr - _x) * sizeof(GLuint); \
+ _vb = 0; \
+} while (0)
+
+
+#define QWORD_PAD_RING() do { \
+ if (vmesa->dmaLow & 0x4) { \
+ BEGIN_RING(1); \
+ OUT_RING(HC_DUMMY); \
+ ADVANCE_RING(); \
+ } \
+} while (0)
+
+#define VIA_GEQ_WRAP(left, right) \
+ (((left) - (right)) < ( 1 << 23))
+
+#endif
diff --git a/src/via_memcpy.c b/src/via_memcpy.c
new file mode 100644
index 0000000..d7b05bc
--- /dev/null
+++ b/src/via_memcpy.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2004 Thomas Hellstrom, 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
+ * THE CODE SUPPLIER(S) 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.
+ */
+
+/* Thomas' orginal gutted for mesa by Keith Whitwell
+ */
+
+#include "via_tex.h"
+
+#if defined( USE_SSE_ASM )
+
+#define SSE_PREFETCH " prefetchnta "
+#define FENCE __asm__ __volatile__ ("sfence":::"memory");
+
+
+#define PREFETCH1(arch_prefetch,from) \
+ __asm__ __volatile__ ( \
+ "1: " arch_prefetch "(%0)\n" \
+ arch_prefetch "32(%0)\n" \
+ arch_prefetch "64(%0)\n" \
+ arch_prefetch "96(%0)\n" \
+ arch_prefetch "128(%0)\n" \
+ arch_prefetch "160(%0)\n" \
+ arch_prefetch "192(%0)\n" \
+ arch_prefetch "256(%0)\n" \
+ arch_prefetch "288(%0)\n" \
+ "2:\n" \
+ : : "r" (from) );
+
+
+
+#define small_memcpy(to,from,n) \
+ { \
+ __asm__ __volatile__( \
+ "movl %2,%%ecx\n\t" \
+ "sarl $2,%%ecx\n\t" \
+ "rep ; movsl\n\t" \
+ "testb $2,%b2\n\t" \
+ "je 1f\n\t" \
+ "movsw\n" \
+ "1:\ttestb $1,%b2\n\t" \
+ "je 2f\n\t" \
+ "movsb\n" \
+ "2:" \
+ :"=&D" (to), "=&S" (from) \
+ :"q" (n),"0" ((long) to),"1" ((long) from) \
+ : "%ecx","memory"); \
+ }
+
+
+#define SSE_CPY(prefetch,from,to,dummy,lcnt) \
+ if ((unsigned long) from & 15) { \
+ __asm__ __volatile__ ( \
+ "1:\n" \
+ prefetch "320(%1)\n" \
+ " movups (%1), %%xmm0\n" \
+ " movups 16(%1), %%xmm1\n" \
+ " movntps %%xmm0, (%0)\n" \
+ " movntps %%xmm1, 16(%0)\n" \
+ prefetch "352(%1)\n" \
+ " movups 32(%1), %%xmm2\n" \
+ " movups 48(%1), %%xmm3\n" \
+ " movntps %%xmm2, 32(%0)\n" \
+ " movntps %%xmm3, 48(%0)\n" \
+ " addl $64,%0\n" \
+ " addl $64,%1\n" \
+ " decl %2\n" \
+ " jne 1b\n" \
+ :"=&D"(to), "=&S"(from), "=&r"(dummy) \
+ :"0" (to), "1" (from), "2" (lcnt): "memory"); \
+ } else { \
+ __asm__ __volatile__ ( \
+ "2:\n" \
+ prefetch "320(%1)\n" \
+ " movaps (%1), %%xmm0\n" \
+ " movaps 16(%1), %%xmm1\n" \
+ " movntps %%xmm0, (%0)\n" \
+ " movntps %%xmm1, 16(%0)\n" \
+ prefetch "352(%1)\n" \
+ " movaps 32(%1), %%xmm2\n" \
+ " movaps 48(%1), %%xmm3\n" \
+ " movntps %%xmm2, 32(%0)\n" \
+ " movntps %%xmm3, 48(%0)\n" \
+ " addl $64,%0\n" \
+ " addl $64,%1\n" \
+ " decl %2\n" \
+ " jne 2b\n" \
+ :"=&D"(to), "=&S"(from), "=&r"(dummy) \
+ :"0" (to), "1" (from), "2" (lcnt): "memory"); \
+ }
+
+
+
+/*
+ */
+void via_sse_memcpy(void *to,
+ const void *from,
+ size_t sz)
+
+{
+ int dummy;
+ int lcnt = sz >> 6;
+ int rest = sz & 63;
+
+ PREFETCH1(SSE_PREFETCH,from);
+
+ if (lcnt > 5) {
+ lcnt -= 5;
+ SSE_CPY(SSE_PREFETCH,from,to,dummy,lcnt);
+ lcnt = 5;
+ }
+ if (lcnt) {
+ SSE_CPY("#",from,to,dummy,lcnt);
+ }
+ if (rest) small_memcpy(to, from, rest);
+ FENCE;
+}
+
+#endif /* defined( USE_SSE_ASM ) */
diff --git a/src/via_render.c b/src/via_render.c
new file mode 100644
index 0000000..d7e373d
--- /dev/null
+++ b/src/via_render.c
@@ -0,0 +1,131 @@
+/*
+ * 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 "tnl/t_context.h"
+
+#include "via_context.h"
+#include "via_tris.h"
+#include "via_state.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
+#define HAVE_TRI_FANS 1
+#define HAVE_POLYGONS 1
+#define HAVE_QUADS 0
+#define HAVE_QUAD_STRIPS 0
+
+#define HAVE_ELTS 0
+
+#define LOCAL_VARS struct via_context *vmesa = VIA_CONTEXT(ctx)
+#define INIT(prim) do { \
+ viaRasterPrimitive(ctx, prim, prim); \
+} while (0)
+#define GET_CURRENT_VB_MAX_VERTS() \
+ ((VIA_DMA_BUF_SZ - (512 + (int)vmesa->dmaLow)) / (vmesa->vertexSize * 4))
+#define GET_SUBSEQUENT_VB_MAX_VERTS() \
+ (VIA_DMA_BUF_SZ - 512) / (vmesa->vertexSize * 4)
+
+#define ALLOC_VERTS( nr ) \
+ viaExtendPrimitive( vmesa, (nr) * vmesa->vertexSize * 4)
+
+#define EMIT_VERTS(ctx, j, nr, buf) \
+ _tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf )
+
+#define FLUSH() VIA_FINISH_PRIM( vmesa )
+
+#define TAG(x) via_fast##x
+#include "tnl_dd/t_dd_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)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ GLuint i;
+
+
+ tnl->Driver.Render.Start(ctx);
+
+ if (VB->ClipOrMask ||
+ vmesa->renderIndex != 0 ||
+ !via_fastvalidate_render( ctx, VB )) {
+ tnl->Driver.Render.Finish(ctx);
+ return GL_TRUE;
+ }
+
+ tnl->clipspace.new_inputs |= VERT_BIT_POS;
+
+ for (i = 0; i < VB->PrimitiveCount; ++i) {
+ GLuint mode = _tnl_translate_prim(&VB->Primitive[i]);
+ 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);
+
+ return GL_FALSE; /* finished the pipe */
+}
+
+const struct tnl_pipeline_stage _via_fastrender_stage =
+{
+ "via fast render",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ via_run_fastrender /* run */
+};
+
+
diff --git a/src/via_screen.c b/src/via_screen.c
new file mode 100644
index 0000000..90f76be
--- /dev/null
+++ b/src/via_screen.c
@@ -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 <stdio.h>
+
+#include "utils.h"
+#include "dri_util.h"
+#include "glheader.h"
+#include "context.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
+#include "matrix.h"
+#include "simple_list.h"
+#include "vblank.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_fb.h"
+#include "via_dri.h"
+
+#include "GL/internal/dri_interface.h"
+#include "drirenderbuffer.h"
+
+#include "xmlpool.h"
+
+const char __driConfigOptions[] =
+DRI_CONF_BEGIN
+ DRI_CONF_SECTION_PERFORMANCE
+ DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
+ DRI_CONF_SECTION_END
+ DRI_CONF_SECTION_QUALITY
+ DRI_CONF_EXCESS_MIPMAP(false)
+ DRI_CONF_SECTION_END
+ DRI_CONF_SECTION_DEBUG
+ DRI_CONF_NO_RAST(false)
+ DRI_CONF_SECTION_END
+DRI_CONF_END;
+static const GLuint __driNConfigOptions = 3;
+
+extern const struct dri_extension card_extensions[];
+
+static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
+
+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 void via_free_empty_buffers( drmBufMapPtr bufs )
+{
+ if (bufs && bufs->list)
+ FREE(bufs->list);
+
+ if (bufs)
+ FREE(bufs);
+}
+
+
+static GLboolean
+viaInitDriver(__DRIscreenPrivate *sPriv)
+{
+ viaScreenPrivate *viaScreen;
+ VIADRIPtr gDRIPriv = (VIADRIPtr)sPriv->pDevPriv;
+ PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
+ (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
+ void * const psc = sPriv->psc->screenConfigs;
+
+ if (sPriv->devPrivSize != sizeof(VIADRIRec)) {
+ fprintf(stderr,"\nERROR! sizeof(VIADRIRec) does not match passed size from device driver\n");
+ return GL_FALSE;
+ }
+
+ /* Allocate the private area */
+ viaScreen = (viaScreenPrivate *) CALLOC(sizeof(viaScreenPrivate));
+ if (!viaScreen) {
+ __driUtilMessage("viaInitDriver: alloc viaScreenPrivate struct failed");
+ return GL_FALSE;
+ }
+
+ /* parse information in __driConfigOptions */
+ driParseOptionInfo (&viaScreen->optionCache,
+ __driConfigOptions, __driNConfigOptions);
+
+
+ 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 * 8;
+ viaScreen->bytesPerPixel = gDRIPriv->bytesPerPixel;
+ viaScreen->fbOffset = 0;
+ viaScreen->fbSize = gDRIPriv->fbSize;
+ viaScreen->irqEnabled = gDRIPriv->irqEnabled;
+
+ if (VIA_DEBUG & DEBUG_DRI) {
+ 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);
+ }
+
+ 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,
+ &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) {
+ drmUnmap(viaScreen->reg, gDRIPriv->regs.size);
+ FREE(viaScreen);
+ sPriv->private = NULL;
+ __driUtilMessage("viaInitDriver: drmMap agp failed");
+ return GL_FALSE;
+ }
+
+ viaScreen->agpBase = drmAgpBase(sPriv->fd);
+ } else
+ viaScreen->agpLinearStart = 0;
+
+ viaScreen->sareaPrivOffset = gDRIPriv->sarea_priv_offset;
+
+ if ( glx_enable_extension != NULL ) {
+ if ( viaScreen->irqEnabled ) {
+ (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
+ (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
+ (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
+ }
+
+ (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
+ (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
+ }
+
+ return GL_TRUE;
+}
+
+static void
+viaDestroyScreen(__DRIscreenPrivate *sPriv)
+{
+ viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
+ VIADRIPtr gDRIPriv = (VIADRIPtr)sPriv->pDevPriv;
+
+ drmUnmap(viaScreen->reg, gDRIPriv->regs.size);
+ if (gDRIPriv->agp.size)
+ drmUnmap(viaScreen->agpLinearStart, gDRIPriv->agp.size);
+
+ via_free_empty_buffers(viaScreen->bufs);
+
+ driDestroyOptionInfo(&viaScreen->optionCache);
+
+ FREE(viaScreen);
+ sPriv->private = NULL;
+}
+
+
+static GLboolean
+viaCreateBuffer(__DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ const __GLcontextModes *mesaVis,
+ GLboolean isPixmap)
+{
+ viaScreenPrivate *screen = (viaScreenPrivate *) driScrnPriv->private;
+
+ GLboolean swStencil = (mesaVis->stencilBits > 0 &&
+ mesaVis->depthBits != 24);
+ GLboolean swAccum = mesaVis->accumRedBits > 0;
+
+ if (isPixmap) {
+ /* KW: This needs work, disabled for now:
+ */
+#if 0
+ driDrawPriv->driverPrivate = (void *)
+ _mesa_create_framebuffer(mesaVis,
+ GL_FALSE, /* software depth buffer? */
+ swStencil,
+ mesaVis->accumRedBits > 0,
+ GL_FALSE /* s/w alpha planes */);
+
+ return (driDrawPriv->driverPrivate != NULL);
+#endif
+ return GL_FALSE;
+ }
+ else {
+ struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
+
+ /* The front color, back color and depth renderbuffers are
+ * set up later in calculate_buffer_parameters().
+ * Only create/connect software-based buffers here.
+ */
+
+#if 000
+ /* This code _should_ be put to use. We have to move the
+ * viaRenderbuffer members out of the via_context structure.
+ * Those members should just be the renderbuffers hanging off the
+ * gl_framebuffer object.
+ */
+ /* XXX check/fix the offset/pitch parameters! */
+ {
+ driRenderbuffer *frontRb
+ = driNewRenderbuffer(GL_RGBA, NULL,
+ screen->bytesPerPixel,
+ 0, screen->width, driDrawPriv);
+ viaSetSpanFunctions(frontRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
+ }
+
+ if (mesaVis->doubleBufferMode) {
+ driRenderbuffer *backRb
+ = driNewRenderbuffer(GL_RGBA, NULL,
+ screen->bytesPerPixel,
+ 0, screen->width, driDrawPriv);
+ viaSetSpanFunctions(backRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
+ }
+
+ if (mesaVis->depthBits == 16) {
+ driRenderbuffer *depthRb
+ = driNewRenderbuffer(GL_DEPTH_COMPONENT16, NULL,
+ screen->bytesPerPixel,
+ 0, screen->width, driDrawPriv);
+ viaSetSpanFunctions(depthRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
+ }
+ else if (mesaVis->depthBits == 24) {
+ driRenderbuffer *depthRb
+ = driNewRenderbuffer(GL_DEPTH_COMPONENT24, NULL,
+ screen->bytesPerPixel,
+ 0, screen->width, driDrawPriv);
+ viaSetSpanFunctions(depthRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
+ }
+ else if (mesaVis->depthBits == 32) {
+ driRenderbuffer *depthRb
+ = driNewRenderbuffer(GL_DEPTH_COMPONENT32, NULL,
+ screen->bytesPerPixel,
+ 0, screen->width, driDrawPriv);
+ viaSetSpanFunctions(depthRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
+ }
+
+ if (mesaVis->stencilBits > 0 && !swStencil) {
+ driRenderbuffer *stencilRb
+ = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, NULL,
+ screen->bytesPerPixel,
+ 0, screen->width, driDrawPriv);
+ viaSetSpanFunctions(stencilRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
+ }
+#endif
+
+ _mesa_add_soft_renderbuffers(fb,
+ GL_FALSE, /* color */
+ GL_FALSE, /* depth */
+ swStencil,
+ swAccum,
+ GL_FALSE, /* alpha */
+ GL_FALSE /* aux */);
+ driDrawPriv->driverPrivate = (void *) fb;
+
+ return (driDrawPriv->driverPrivate != NULL);
+ }
+}
+
+
+static void
+viaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+ _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
+}
+
+
+
+static struct __DriverAPIRec viaAPI = {
+ .InitDriver = viaInitDriver,
+ .DestroyScreen = viaDestroyScreen,
+ .CreateContext = viaCreateContext,
+ .DestroyContext = viaDestroyContext,
+ .CreateBuffer = viaCreateBuffer,
+ .DestroyBuffer = viaDestroyBuffer,
+ .SwapBuffers = viaSwapBuffers,
+ .MakeCurrent = viaMakeCurrent,
+ .UnbindContext = viaUnbindContext,
+ .GetSwapInfo = getSwapInfo,
+ .GetMSC = driGetMSC32,
+ .WaitForMSC = driWaitForMSC32,
+ .WaitForSBC = NULL,
+ .SwapBuffersMSC = NULL
+};
+
+
+static __GLcontextModes *
+viaFillInModes( unsigned pixel_bits, GLboolean have_back_buffer )
+{
+ __GLcontextModes * modes;
+ __GLcontextModes * m;
+ unsigned num_modes;
+ const unsigned back_buffer_factor = (have_back_buffer) ? 2 : 1;
+ GLenum fb_format;
+ GLenum fb_type;
+
+ /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
+ * enough to add support. Basically, if a context is created with an
+ * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
+ * will never be used.
+ */
+ static const GLenum back_buffer_modes[] = {
+ GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
+ };
+
+ /* The 32-bit depth-buffer mode isn't supported yet, so don't actually
+ * enable it.
+ */
+ static const u_int8_t depth_bits_array[4] = { 0, 16, 24, 32 };
+ static const u_int8_t stencil_bits_array[4] = { 0, 0, 8, 0 };
+ const unsigned depth_buffer_factor = 3;
+
+
+ num_modes = depth_buffer_factor * back_buffer_factor * 4;
+
+ if ( pixel_bits == 16 ) {
+ fb_format = GL_RGB;
+ fb_type = GL_UNSIGNED_SHORT_5_6_5;
+ }
+ else {
+ fb_format = GL_BGRA;
+ fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+
+ modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) );
+ m = modes;
+ if ( ! driFillInModes( & m, fb_format, fb_type,
+ depth_bits_array, stencil_bits_array,
+ depth_buffer_factor,
+ back_buffer_modes, back_buffer_factor,
+ GLX_TRUE_COLOR ) ) {
+ fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
+ __func__, __LINE__ );
+ return NULL;
+ }
+
+ if ( ! driFillInModes( & m, fb_format, fb_type,
+ depth_bits_array, stencil_bits_array,
+ depth_buffer_factor,
+ back_buffer_modes, back_buffer_factor,
+ GLX_DIRECT_COLOR ) ) {
+ fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
+ __func__, __LINE__ );
+ return NULL;
+ }
+
+ return modes;
+}
+
+
+/**
+ * This is the bootstrap function for the driver. libGL supplies all of the
+ * requisite information about the system, and the driver initializes itself.
+ * This routine also fills in the linked list pointed to by \c driver_modes
+ * with the \c __GLcontextModes that the driver can support for windows or
+ * pbuffers.
+ *
+ * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
+ * failure.
+ */
+PUBLIC
+void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn,
+ __DRIscreen *psc,
+ const __GLcontextModes * modes,
+ const __DRIversion * ddx_version,
+ const __DRIversion * dri_version,
+ const __DRIversion * drm_version,
+ const __DRIframebuffer * frame_buffer,
+ drmAddress pSAREA, int fd,
+ int internal_api_version,
+ const __DRIinterfaceMethods * interface,
+ __GLcontextModes ** driver_modes )
+
+{
+ __DRIscreenPrivate *psp;
+ static const __DRIversion ddx_expected = { VIA_DRIDDX_VERSION_MAJOR,
+ VIA_DRIDDX_VERSION_MINOR,
+ VIA_DRIDDX_VERSION_PATCH };
+ static const __DRIversion dri_expected = { 4, 0, 0 };
+ static const __DRIversion drm_expected = { 2, 3, 0 };
+ static const char *driver_name = "Unichrome";
+
+ dri_interface = interface;
+
+ if ( ! driCheckDriDdxDrmVersions2( driver_name,
+ dri_version, & dri_expected,
+ ddx_version, & ddx_expected,
+ drm_version, & drm_expected) ) {
+ return NULL;
+ }
+
+ psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
+ ddx_version, dri_version, drm_version,
+ frame_buffer, pSAREA, fd,
+ internal_api_version, &viaAPI);
+ if ( psp != NULL ) {
+ VIADRIPtr dri_priv = (VIADRIPtr) psp->pDevPriv;
+ *driver_modes = viaFillInModes( dri_priv->bytesPerPixel * 8,
+ GL_TRUE );
+
+ /* Calling driInitExtensions here, with a NULL context pointer, does not actually
+ * enable the extensions. It just makes sure that all the dispatch offsets for all
+ * the extensions that *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create is called, but we can't
+ * enable the extensions until we have a context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ driInitExtensions( NULL, card_extensions, GL_FALSE );
+ }
+
+ return (void *) psp;
+}
+
+
+/**
+ * Get information about previous buffer swaps.
+ */
+static int
+getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
+{
+ struct via_context *vmesa;
+
+ if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
+ || (dPriv->driContextPriv->driverPrivate == NULL)
+ || (sInfo == NULL) ) {
+ return -1;
+ }
+
+ vmesa = (struct via_context *) dPriv->driContextPriv->driverPrivate;
+ sInfo->swap_count = vmesa->swap_count;
+ sInfo->swap_ust = vmesa->swap_ust;
+ sInfo->swap_missed_count = vmesa->swap_missed_count;
+
+ sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
+ ? driCalculateSwapUsage( dPriv, 0, vmesa->swap_missed_ust )
+ : 0.0;
+
+ return 0;
+}
diff --git a/src/via_screen.h b/src/via_screen.h
new file mode 100644
index 0000000..84aa5ae
--- /dev/null
+++ b/src/via_screen.h
@@ -0,0 +1,95 @@
+/*
+ * 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"
+#include "xmlconfig.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;
+
+ 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;
+ /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
+ int VQEnable;
+ int irqEnabled;
+
+ /* Configuration cache with default values for all contexts */
+ driOptionCache optionCache;
+} 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/via_span.c b/src/via_span.c
new file mode 100644
index 0000000..3a16dad
--- /dev/null
+++ b/src/via_span.c
@@ -0,0 +1,195 @@
+/*
+ * 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
+
+#define Y_FLIP(_y) (height - _y - 1)
+
+#define HW_LOCK()
+
+#define HW_UNLOCK()
+
+#undef LOCAL_VARS
+#define LOCAL_VARS \
+ struct via_renderbuffer *vrb = (struct via_renderbuffer *) rb; \
+ __DRIdrawablePrivate *dPriv = vrb->dPriv; \
+ GLuint pitch = vrb->pitch; \
+ GLuint height = dPriv->h; \
+ GLint p = 0; \
+ char *buf = (char *)(vrb->origMap); \
+ (void) p;
+
+/* ================================================================
+ * Color buffer
+ */
+
+/* 16 bit, RGB565 color spanline and pixel functions
+ */
+#define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch)
+#define SPANTMP_PIXEL_FMT GL_RGB
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
+
+#define TAG(x) via##x##_565
+#define TAG2(x,y) via##x##_565##y
+#include "spantmp2.h"
+
+
+/* 32 bit, ARGB8888 color spanline and pixel functions
+ */
+#define GET_PTR(_x, _y) (buf + (_x) * 4 + (_y) * pitch)
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
+
+#define TAG(x) via##x##_8888
+#define TAG2(x,y) via##x##_8888##y
+#include "spantmp2.h"
+
+
+/* 16 bit depthbuffer functions.
+ */
+#define LOCAL_DEPTH_VARS \
+ struct via_renderbuffer *vrb = (struct via_renderbuffer *) rb; \
+ __DRIdrawablePrivate *dPriv = vrb->dPriv; \
+ GLuint depth_pitch = vrb->pitch; \
+ GLuint height = dPriv->h; \
+ char *buf = (char *)(vrb->map)
+
+#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
+
+
+#define WRITE_DEPTH(_x, _y, d) \
+ *(GLushort *)(buf + (_x) * 2 + (_y) * depth_pitch) = d;
+
+#define READ_DEPTH(d, _x, _y) \
+ d = *(volatile GLushort *)(buf + (_x) * 2 + (_y) * depth_pitch);
+
+#define TAG(x) via##x##_z16
+#include "depthtmp.h"
+
+/* 32 bit depthbuffer functions.
+ */
+#define WRITE_DEPTH(_x, _y, d) \
+ *(GLuint *)(buf + (_x) * 4 + (_y) * depth_pitch) = d;
+
+#define READ_DEPTH(d, _x, _y) \
+ d = *(volatile GLuint *)(buf + (_x) * 4 + (_y) * depth_pitch);
+
+#define TAG(x) via##x##_z32
+#include "depthtmp.h"
+
+
+
+/* 24/8 bit interleaved depth/stencil functions
+ */
+#define WRITE_DEPTH( _x, _y, d ) { \
+ GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch); \
+ tmp &= 0x000000ff; \
+ tmp |= ((d)<<8); \
+ *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp; \
+}
+
+#define READ_DEPTH( d, _x, _y ) \
+ d = (*(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch)) >> 8;
+
+
+#define TAG(x) via##x##_z24_s8
+#include "depthtmp.h"
+
+#define WRITE_STENCIL( _x, _y, d ) { \
+ GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch); \
+ tmp &= 0xffffff00; \
+ tmp |= (d); \
+ *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp; \
+}
+
+#define READ_STENCIL( d, _x, _y ) \
+ d = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) & 0xff;
+
+#define TAG(x) via##x##_z24_s8
+#include "stenciltmp.h"
+
+
+
+
+/* Move locking out to get reasonable span performance.
+ */
+void viaSpanRenderStart( GLcontext *ctx )
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ viaWaitIdle(vmesa, GL_FALSE);
+ LOCK_HARDWARE(vmesa);
+}
+
+void viaSpanRenderFinish( GLcontext *ctx )
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ _swrast_flush( ctx );
+ UNLOCK_HARDWARE( vmesa );
+}
+
+void viaInitSpanFuncs(GLcontext *ctx)
+{
+ struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
+ swdd->SpanRenderStart = viaSpanRenderStart;
+ swdd->SpanRenderFinish = viaSpanRenderFinish;
+}
+
+
+
+/**
+ * Plug in the Get/Put routines for the given driRenderbuffer.
+ */
+void
+viaSetSpanFunctions(struct via_renderbuffer *vrb, const GLvisual *vis)
+{
+ if (vrb->Base.InternalFormat == GL_RGBA) {
+ if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
+ viaInitPointers_565(&vrb->Base);
+ }
+ else {
+ viaInitPointers_8888(&vrb->Base);
+ }
+ }
+ else if (vrb->Base.InternalFormat == GL_DEPTH_COMPONENT16) {
+ viaInitDepthPointers_z16(&vrb->Base);
+ }
+ else if (vrb->Base.InternalFormat == GL_DEPTH_COMPONENT24) {
+ viaInitDepthPointers_z24_s8(&vrb->Base);
+ }
+ else if (vrb->Base.InternalFormat == GL_DEPTH_COMPONENT32) {
+ viaInitDepthPointers_z32(&vrb->Base);
+ }
+ else if (vrb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
+ viaInitStencilPointers_z24_s8(&vrb->Base);
+ }
+}
diff --git a/src/via_span.h b/src/via_span.h
new file mode 100644
index 0000000..3dca0d5
--- /dev/null
+++ b/src/via_span.h
@@ -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 _VIA_SPAN_H
+#define _VIA_SPAN_H
+
+extern void viaInitSpanFuncs(GLcontext *ctx);
+extern void viaSpanRenderStart( GLcontext *ctx );
+extern void viaSpanRenderFinish( GLcontext *ctx );
+
+extern void
+viaSetSpanFunctions(struct via_renderbuffer *vrb, const GLvisual *vis);
+
+#endif
diff --git a/src/via_state.c b/src/via_state.c
new file mode 100644
index 0000000..bccdbe9
--- /dev/null
+++ b/src/via_state.c
@@ -0,0 +1,1527 @@
+/*
+ * 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_tris.h"
+#include "via_ioctl.h"
+#include "via_3d_reg.h"
+
+#include "swrast/swrast.h"
+#include "vbo/vbo.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 */
+};
+
+/*
+ * Compute the 'S5.5' lod bias factor from the floating point OpenGL bias.
+ */
+static GLuint viaComputeLodBias(GLfloat bias)
+{
+ int b = (int) (bias * 32.0);
+ if (b > 511)
+ b = 511;
+ else if (b < -512)
+ b = -512;
+ return (GLuint) b;
+}
+
+void viaEmitState(struct via_context *vmesa)
+{
+ GLcontext *ctx = vmesa->glCtx;
+ GLuint i = 0;
+ GLuint j = 0;
+ RING_VARS;
+
+ viaCheckDma(vmesa, 0x110);
+
+ BEGIN_RING(5);
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_NotTex << 16) );
+ OUT_RING( ((HC_SubA_HEnable << 24) | vmesa->regEnable) );
+ OUT_RING( ((HC_SubA_HFBBMSKL << 24) | vmesa->regHFBBMSKL) );
+ OUT_RING( ((HC_SubA_HROP << 24) | vmesa->regHROP) );
+ ADVANCE_RING();
+
+ if (vmesa->have_hw_stencil) {
+ GLuint pitch, format, offset;
+
+ format = HC_HZWBFM_24;
+ offset = vmesa->depth.offset;
+ pitch = vmesa->depth.pitch;
+
+ BEGIN_RING(6);
+ OUT_RING( (HC_SubA_HZWBBasL << 24) | (offset & 0xFFFFFF) );
+ OUT_RING( (HC_SubA_HZWBBasH << 24) | ((offset & 0xFF000000) >> 24) );
+ OUT_RING( (HC_SubA_HZWBType << 24) | HC_HDBLoc_Local | HC_HZONEasFF_MASK |
+ format | pitch );
+ OUT_RING( (HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD );
+ OUT_RING( (HC_SubA_HSTREF << 24) | vmesa->regHSTREF );
+ OUT_RING( (HC_SubA_HSTMD << 24) | vmesa->regHSTMD );
+ ADVANCE_RING();
+ }
+ else if (vmesa->hasDepth) {
+ GLuint pitch, format, offset;
+
+ if (vmesa->depthBits == 16) {
+ format = HC_HZWBFM_16;
+ }
+ else {
+ format = HC_HZWBFM_32;
+ }
+
+
+ offset = vmesa->depth.offset;
+ pitch = vmesa->depth.pitch;
+
+ BEGIN_RING(4);
+ OUT_RING( (HC_SubA_HZWBBasL << 24) | (offset & 0xFFFFFF) );
+ OUT_RING( (HC_SubA_HZWBBasH << 24) | ((offset & 0xFF000000) >> 24) );
+ OUT_RING( (HC_SubA_HZWBType << 24) | HC_HDBLoc_Local | HC_HZONEasFF_MASK |
+ format | pitch );
+ OUT_RING( (HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD );
+ ADVANCE_RING();
+ }
+
+ if (ctx->Color.AlphaEnabled) {
+ BEGIN_RING(1);
+ OUT_RING( (HC_SubA_HATMD << 24) | vmesa->regHATMD );
+ ADVANCE_RING();
+ i++;
+ }
+
+ if (ctx->Color.BlendEnabled) {
+ BEGIN_RING(11);
+ OUT_RING( (HC_SubA_HABLCsat << 24) | vmesa->regHABLCsat );
+ OUT_RING( (HC_SubA_HABLCop << 24) | vmesa->regHABLCop );
+ OUT_RING( (HC_SubA_HABLAsat << 24) | vmesa->regHABLAsat );
+ OUT_RING( (HC_SubA_HABLAop << 24) | vmesa->regHABLAop );
+ OUT_RING( (HC_SubA_HABLRCa << 24) | vmesa->regHABLRCa );
+ OUT_RING( (HC_SubA_HABLRFCa << 24) | vmesa->regHABLRFCa );
+ OUT_RING( (HC_SubA_HABLRCbias << 24) | vmesa->regHABLRCbias );
+ OUT_RING( (HC_SubA_HABLRCb << 24) | vmesa->regHABLRCb );
+ OUT_RING( (HC_SubA_HABLRFCb << 24) | vmesa->regHABLRFCb );
+ OUT_RING( (HC_SubA_HABLRAa << 24) | vmesa->regHABLRAa );
+ OUT_RING( (HC_SubA_HABLRAb << 24) | vmesa->regHABLRAb );
+ ADVANCE_RING();
+ }
+
+ if (ctx->Fog.Enabled) {
+ BEGIN_RING(3);
+ OUT_RING( (HC_SubA_HFogLF << 24) | vmesa->regHFogLF );
+ OUT_RING( (HC_SubA_HFogCL << 24) | vmesa->regHFogCL );
+ OUT_RING( (HC_SubA_HFogCH << 24) | vmesa->regHFogCH );
+ ADVANCE_RING();
+ }
+
+ if (ctx->Line.StippleFlag) {
+ BEGIN_RING(2);
+ OUT_RING( (HC_SubA_HLP << 24) | ctx->Line.StipplePattern );
+ OUT_RING( (HC_SubA_HLPRF << 24) | ctx->Line.StippleFactor );
+ ADVANCE_RING();
+ }
+
+ BEGIN_RING(1);
+ OUT_RING( (HC_SubA_HPixGC << 24) | 0x0 );
+ ADVANCE_RING();
+
+ QWORD_PAD_RING();
+
+
+ if (ctx->Texture._EnabledUnits) {
+
+ struct gl_texture_unit *texUnit0 = &ctx->Texture.Unit[0];
+ struct gl_texture_unit *texUnit1 = &ctx->Texture.Unit[1];
+
+ {
+ GLuint nDummyValue = 0;
+
+ BEGIN_RING( 8 );
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_Tex << 16) | (HC_SubType_TexGeneral << 24) );
+
+ if (texUnit0->Enabled && texUnit1->Enabled) {
+ nDummyValue = (HC_SubA_HTXSMD << 24) | (1 << 3);
+ }
+ else {
+ nDummyValue = (HC_SubA_HTXSMD << 24) | 0;
+ }
+
+ if (vmesa->clearTexCache) {
+ vmesa->clearTexCache = 0;
+ OUT_RING( nDummyValue | HC_HTXCHCLR_MASK );
+ OUT_RING( nDummyValue );
+ }
+ else {
+ OUT_RING( nDummyValue );
+ OUT_RING( nDummyValue );
+ }
+
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( HC_ParaType_NotTex << 16 );
+ OUT_RING( (HC_SubA_HEnable << 24) | vmesa->regEnable );
+ OUT_RING( (HC_SubA_HEnable << 24) | vmesa->regEnable );
+ ADVANCE_RING();
+ }
+
+ if (texUnit0->Enabled) {
+ struct gl_texture_object *texObj = texUnit0->_Current;
+ struct via_texture_object *t = (struct via_texture_object *)texObj;
+ GLuint numLevels = t->lastLevel - t->firstLevel + 1;
+ if (VIA_DEBUG & DEBUG_STATE) {
+ fprintf(stderr, "texture0 enabled\n");
+ }
+ if (numLevels == 8) {
+ BEGIN_RING(27);
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_Tex << 16) | (0 << 24) );
+ OUT_RING( t->regTexFM );
+ OUT_RING( (HC_SubA_HTXnL0OS << 24) |
+ ((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
+ OUT_RING( t->regTexWidthLog2[0] );
+ OUT_RING( t->regTexWidthLog2[1] );
+ OUT_RING( t->regTexHeightLog2[0] );
+ OUT_RING( t->regTexHeightLog2[1] );
+ OUT_RING( t->regTexBaseH[0] );
+ OUT_RING( t->regTexBaseH[1] );
+ OUT_RING( t->regTexBaseH[2] );
+ OUT_RING( t->regTexBaseAndPitch[0].baseL );
+ OUT_RING( t->regTexBaseAndPitch[0].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[1].baseL );
+ OUT_RING( t->regTexBaseAndPitch[1].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[2].baseL );
+ OUT_RING( t->regTexBaseAndPitch[2].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[3].baseL );
+ OUT_RING( t->regTexBaseAndPitch[3].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[4].baseL );
+ OUT_RING( t->regTexBaseAndPitch[4].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[5].baseL );
+ OUT_RING( t->regTexBaseAndPitch[5].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[6].baseL );
+ OUT_RING( t->regTexBaseAndPitch[6].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[7].baseL );
+ OUT_RING( t->regTexBaseAndPitch[7].pitchLog2 );
+ ADVANCE_RING();
+ }
+ else if (numLevels > 1) {
+
+ BEGIN_RING(12 + numLevels * 2);
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_Tex << 16) | (0 << 24) );
+ OUT_RING( t->regTexFM );
+ OUT_RING( (HC_SubA_HTXnL0OS << 24) |
+ ((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
+ OUT_RING( t->regTexWidthLog2[0] );
+ OUT_RING( t->regTexHeightLog2[0] );
+
+ if (numLevels > 6) {
+ OUT_RING( t->regTexWidthLog2[1] );
+ OUT_RING( t->regTexHeightLog2[1] );
+ }
+
+ OUT_RING( t->regTexBaseH[0] );
+
+ if (numLevels > 3) {
+ OUT_RING( t->regTexBaseH[1] );
+ }
+ if (numLevels > 6) {
+ OUT_RING( t->regTexBaseH[2] );
+ }
+ if (numLevels > 9) {
+ OUT_RING( t->regTexBaseH[3] );
+ }
+
+ for (j = 0; j < numLevels; j++) {
+ OUT_RING( t->regTexBaseAndPitch[j].baseL );
+ OUT_RING( t->regTexBaseAndPitch[j].pitchLog2 );
+ }
+
+ ADVANCE_RING_VARIABLE();
+ }
+ else {
+
+ BEGIN_RING(9);
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_Tex << 16) | (0 << 24) );
+ OUT_RING( t->regTexFM );
+ OUT_RING( (HC_SubA_HTXnL0OS << 24) |
+ ((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
+ OUT_RING( t->regTexWidthLog2[0] );
+ OUT_RING( t->regTexHeightLog2[0] );
+ OUT_RING( t->regTexBaseH[0] );
+ OUT_RING( t->regTexBaseAndPitch[0].baseL );
+ OUT_RING( t->regTexBaseAndPitch[0].pitchLog2 );
+ ADVANCE_RING();
+ }
+
+ BEGIN_RING(14);
+ OUT_RING( (HC_SubA_HTXnTB << 24) | vmesa->regHTXnTB[0] );
+ OUT_RING( (HC_SubA_HTXnMPMD << 24) | vmesa->regHTXnMPMD[0] );
+ OUT_RING( (HC_SubA_HTXnTBLCsat << 24) | vmesa->regHTXnTBLCsat[0] );
+ OUT_RING( (HC_SubA_HTXnTBLCop << 24) | vmesa->regHTXnTBLCop[0] );
+ OUT_RING( (HC_SubA_HTXnTBLMPfog << 24) | vmesa->regHTXnTBLMPfog[0] );
+ OUT_RING( (HC_SubA_HTXnTBLAsat << 24) | vmesa->regHTXnTBLAsat[0] );
+ OUT_RING( (HC_SubA_HTXnTBLRCb << 24) | vmesa->regHTXnTBLRCb[0] );
+ OUT_RING( (HC_SubA_HTXnTBLRAa << 24) | vmesa->regHTXnTBLRAa[0] );
+ OUT_RING( (HC_SubA_HTXnTBLRFog << 24) | vmesa->regHTXnTBLRFog[0] );
+ OUT_RING( (HC_SubA_HTXnTBLRCa << 24) | vmesa->regHTXnTBLRCa[0] );
+ OUT_RING( (HC_SubA_HTXnTBLRCc << 24) | vmesa->regHTXnTBLRCc[0] );
+ OUT_RING( (HC_SubA_HTXnTBLRCbias << 24) | vmesa->regHTXnTBLRCbias[0] );
+ OUT_RING( (HC_SubA_HTXnTBC << 24) | vmesa->regHTXnTBC[0] );
+ OUT_RING( (HC_SubA_HTXnTRAH << 24) | vmesa->regHTXnTRAH[0] );
+/* OUT_RING( (HC_SubA_HTXnCLODu << 24) | vmesa->regHTXnCLOD[0] ); */
+ ADVANCE_RING();
+
+ /* KW: This test never succeeds:
+ */
+ if (t->regTexFM == HC_HTXnFM_Index8) {
+ const struct gl_color_table *table = &texObj->Palette;
+ const GLfloat *tableF = table->TableF;
+
+ BEGIN_RING(2 + table->Size);
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_Palette << 16) | (0 << 24) );
+ for (j = 0; j < table->Size; j++)
+ OUT_RING( tableF[j] );
+ ADVANCE_RING();
+
+ }
+
+ QWORD_PAD_RING();
+ }
+
+ if (texUnit1->Enabled) {
+ struct gl_texture_object *texObj = texUnit1->_Current;
+ struct via_texture_object *t = (struct via_texture_object *)texObj;
+ GLuint numLevels = t->lastLevel - t->firstLevel + 1;
+ int texunit = (texUnit0->Enabled ? 1 : 0);
+ if (VIA_DEBUG & DEBUG_STATE) {
+ fprintf(stderr, "texture1 enabled\n");
+ }
+ if (numLevels == 8) {
+ BEGIN_RING(27);
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_Tex << 16) | (texunit << 24) );
+ OUT_RING( t->regTexFM );
+ OUT_RING( (HC_SubA_HTXnL0OS << 24) |
+ ((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
+ OUT_RING( t->regTexWidthLog2[0] );
+ OUT_RING( t->regTexWidthLog2[1] );
+ OUT_RING( t->regTexHeightLog2[0] );
+ OUT_RING( t->regTexHeightLog2[1] );
+ OUT_RING( t->regTexBaseH[0] );
+ OUT_RING( t->regTexBaseH[1] );
+ OUT_RING( t->regTexBaseH[2] );
+ OUT_RING( t->regTexBaseAndPitch[0].baseL );
+ OUT_RING( t->regTexBaseAndPitch[0].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[1].baseL );
+ OUT_RING( t->regTexBaseAndPitch[1].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[2].baseL );
+ OUT_RING( t->regTexBaseAndPitch[2].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[3].baseL );
+ OUT_RING( t->regTexBaseAndPitch[3].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[4].baseL );
+ OUT_RING( t->regTexBaseAndPitch[4].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[5].baseL );
+ OUT_RING( t->regTexBaseAndPitch[5].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[6].baseL );
+ OUT_RING( t->regTexBaseAndPitch[6].pitchLog2 );
+ OUT_RING( t->regTexBaseAndPitch[7].baseL );
+ OUT_RING( t->regTexBaseAndPitch[7].pitchLog2 );
+ ADVANCE_RING();
+ }
+ else if (numLevels > 1) {
+ BEGIN_RING(12 + numLevels * 2);
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_Tex << 16) | (texunit << 24) );
+ OUT_RING( t->regTexFM );
+ OUT_RING( (HC_SubA_HTXnL0OS << 24) |
+ ((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
+ OUT_RING( t->regTexWidthLog2[0] );
+ OUT_RING( t->regTexHeightLog2[0] );
+
+ if (numLevels > 6) {
+ OUT_RING( t->regTexWidthLog2[1] );
+ OUT_RING( t->regTexHeightLog2[1] );
+ i += 2;
+ }
+
+ OUT_RING( t->regTexBaseH[0] );
+
+ if (numLevels > 3) {
+ OUT_RING( t->regTexBaseH[1] );
+ }
+ if (numLevels > 6) {
+ OUT_RING( t->regTexBaseH[2] );
+ }
+ if (numLevels > 9) {
+ OUT_RING( t->regTexBaseH[3] );
+ }
+
+ for (j = 0; j < numLevels; j++) {
+ OUT_RING( t->regTexBaseAndPitch[j].baseL );
+ OUT_RING( t->regTexBaseAndPitch[j].pitchLog2 );
+ }
+ ADVANCE_RING_VARIABLE();
+ }
+ else {
+ BEGIN_RING(9);
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_Tex << 16) | (texunit << 24) );
+ OUT_RING( t->regTexFM );
+ OUT_RING( (HC_SubA_HTXnL0OS << 24) |
+ ((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
+ OUT_RING( t->regTexWidthLog2[0] );
+ OUT_RING( t->regTexHeightLog2[0] );
+ OUT_RING( t->regTexBaseH[0] );
+ OUT_RING( t->regTexBaseAndPitch[0].baseL );
+ OUT_RING( t->regTexBaseAndPitch[0].pitchLog2 );
+ ADVANCE_RING();
+ }
+
+ BEGIN_RING(14);
+ OUT_RING( (HC_SubA_HTXnTB << 24) | vmesa->regHTXnTB[1] );
+ OUT_RING( (HC_SubA_HTXnMPMD << 24) | vmesa->regHTXnMPMD[1] );
+ OUT_RING( (HC_SubA_HTXnTBLCsat << 24) | vmesa->regHTXnTBLCsat[1] );
+ OUT_RING( (HC_SubA_HTXnTBLCop << 24) | vmesa->regHTXnTBLCop[1] );
+ OUT_RING( (HC_SubA_HTXnTBLMPfog << 24) | vmesa->regHTXnTBLMPfog[1] );
+ OUT_RING( (HC_SubA_HTXnTBLAsat << 24) | vmesa->regHTXnTBLAsat[1] );
+ OUT_RING( (HC_SubA_HTXnTBLRCb << 24) | vmesa->regHTXnTBLRCb[1] );
+ OUT_RING( (HC_SubA_HTXnTBLRAa << 24) | vmesa->regHTXnTBLRAa[1] );
+ OUT_RING( (HC_SubA_HTXnTBLRFog << 24) | vmesa->regHTXnTBLRFog[1] );
+ OUT_RING( (HC_SubA_HTXnTBLRCa << 24) | vmesa->regHTXnTBLRCa[1] );
+ OUT_RING( (HC_SubA_HTXnTBLRCc << 24) | vmesa->regHTXnTBLRCc[1] );
+ OUT_RING( (HC_SubA_HTXnTBLRCbias << 24) | vmesa->regHTXnTBLRCbias[1] );
+ OUT_RING( (HC_SubA_HTXnTBC << 24) | vmesa->regHTXnTBC[1] );
+ OUT_RING( (HC_SubA_HTXnTRAH << 24) | vmesa->regHTXnTRAH[1] );
+/* OUT_RING( (HC_SubA_HTXnCLODu << 24) | vmesa->regHTXnCLOD[1] ); */
+ ADVANCE_RING();
+
+ /* KW: This test never succeeds:
+ */
+ if (t->regTexFM == HC_HTXnFM_Index8) {
+ const struct gl_color_table *table = &texObj->Palette;
+ const GLfloat *tableF = table->TableF;
+
+ BEGIN_RING(2 + table->Size);
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_Palette << 16) | (texunit << 24) );
+ for (j = 0; j < table->Size; j++) {
+ OUT_RING( tableF[j] );
+ }
+ ADVANCE_RING();
+ }
+
+ QWORD_PAD_RING();
+ }
+ }
+
+#if 0
+ /* Polygon stipple is broken - for certain stipple values,
+ * eg. 0xf0f0f0f0, the hardware will refuse to accept the stipple.
+ * Coincidentally, conform generates just such a stipple.
+ */
+ if (ctx->Polygon.StippleFlag) {
+ GLuint *stipple = &ctx->PolygonStipple[0];
+ __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+ struct via_renderbuffer *const vrb =
+ (struct via_renderbuffer *) dPriv->driverPrivate;
+ GLint i;
+
+ BEGIN_RING(38);
+ OUT_RING( HC_HEADER2 );
+
+ OUT_RING( ((HC_ParaType_Palette << 16) | (HC_SubType_Stipple << 24)) );
+ for (i = 31; i >= 0; i--) {
+ GLint j;
+ GLuint k = 0;
+
+ /* Need to flip bits left to right:
+ */
+ for (j = 0 ; j < 32; j++)
+ if (stipple[i] & (1<<j))
+ k |= 1 << (31-j);
+
+ OUT_RING( k );
+ }
+
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_NotTex << 16) );
+ OUT_RING( (HC_SubA_HSPXYOS << 24) );
+ OUT_RING( (HC_SubA_HSPXYOS << 24) );
+
+ ADVANCE_RING();
+ }
+#endif
+
+ vmesa->newEmitState = 0;
+}
+
+
+static __inline__ GLuint viaPackColor(GLuint bpp,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a)
+{
+ switch (bpp) {
+ case 16:
+ return PACK_COLOR_565(r, g, b);
+ case 32:
+ return PACK_COLOR_8888(a, r, g, b);
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+static void viaBlendEquationSeparate(GLcontext *ctx,
+ GLenum rgbMode,
+ GLenum aMode)
+{
+ if (VIA_DEBUG & DEBUG_STATE)
+ fprintf(stderr, "%s in\n", __FUNCTION__);
+
+ /* GL_EXT_blend_equation_separate not supported */
+ ASSERT(rgbMode == aMode);
+
+ /* Can only do GL_ADD equation in hardware */
+ FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_BLEND_EQ,
+ rgbMode != 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));
+}
+
+static void viaBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ GLboolean fallback = GL_FALSE;
+ if (VIA_DEBUG & DEBUG_STATE)
+ fprintf(stderr, "%s in\n", __FUNCTION__);
+
+ switch (ctx->Color.BlendSrcRGB) {
+ case GL_SRC_ALPHA_SATURATE:
+ 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:
+ break;
+ }
+
+ switch (ctx->Color.BlendDstRGB) {
+ 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:
+ break;
+ }
+
+ FALLBACK(vmesa, VIA_FALLBACK_BLEND_FUNC, fallback);
+}
+
+/* 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);
+}
+
+
+
+
+/* =============================================================
+ * Hardware clipping
+ */
+static void viaScissor(GLcontext *ctx, GLint x, GLint y,
+ GLsizei w, GLsizei h)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ if (!vmesa->driDrawable)
+ return;
+
+ if (VIA_DEBUG & DEBUG_STATE)
+ fprintf(stderr, "%s %d,%d %dx%d, drawH %d\n", __FUNCTION__,
+ x,y,w,h, vmesa->driDrawable->h);
+
+ if (vmesa->scissor) {
+ VIA_FLUSH_DMA(vmesa); /* don't pipeline cliprect changes */
+ }
+
+ vmesa->scissorRect.x1 = x;
+ vmesa->scissorRect.y1 = vmesa->driDrawable->h - y - h;
+ vmesa->scissorRect.x2 = x + w;
+ vmesa->scissorRect.y2 = vmesa->driDrawable->h - y;
+}
+
+static void viaEnable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ switch (cap) {
+ case GL_SCISSOR_TEST:
+ VIA_FLUSH_DMA(vmesa);
+ vmesa->scissor = state;
+ break;
+ default:
+ break;
+ }
+}
+
+
+
+/* Fallback to swrast for select and feedback.
+ */
+static void viaRenderMode(GLcontext *ctx, GLenum mode)
+{
+ FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_RENDERMODE, (mode != GL_RENDER));
+}
+
+
+static void viaDrawBuffer(GLcontext *ctx, GLenum mode)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ if (VIA_DEBUG & (DEBUG_DRI|DEBUG_STATE))
+ fprintf(stderr, "%s in\n", __FUNCTION__);
+
+ if (!ctx->DrawBuffer)
+ return;
+
+ switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
+ case BUFFER_BIT_FRONT_LEFT:
+ VIA_FLUSH_DMA(vmesa);
+ vmesa->drawBuffer = &vmesa->front;
+ FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_FALSE);
+ break;
+ case BUFFER_BIT_BACK_LEFT:
+ VIA_FLUSH_DMA(vmesa);
+ vmesa->drawBuffer = &vmesa->back;
+ FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_FALSE);
+ break;
+ default:
+ FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_TRUE);
+ return;
+ }
+
+
+ viaXMesaWindowMoved(vmesa);
+}
+
+static void viaClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ GLubyte pcolor[4];
+ CLAMPED_FLOAT_TO_UBYTE(pcolor[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(pcolor[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(pcolor[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(pcolor[3], color[3]);
+ vmesa->ClearColor = viaPackColor(vmesa->viaScreen->bitsPerPixel,
+ pcolor[0], pcolor[1],
+ pcolor[2], pcolor[3]);
+}
+
+#define WRITEMASK_ALPHA_SHIFT 31
+#define WRITEMASK_RED_SHIFT 30
+#define WRITEMASK_GREEN_SHIFT 29
+#define WRITEMASK_BLUE_SHIFT 28
+
+static void viaColorMask(GLcontext *ctx,
+ GLboolean r, GLboolean g,
+ GLboolean b, GLboolean a)
+{
+ struct via_context *vmesa = VIA_CONTEXT( ctx );
+
+ if (VIA_DEBUG & DEBUG_STATE)
+ fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a);
+
+ vmesa->ClearMask = (((!r) << WRITEMASK_RED_SHIFT) |
+ ((!g) << WRITEMASK_GREEN_SHIFT) |
+ ((!b) << WRITEMASK_BLUE_SHIFT) |
+ ((!a) << WRITEMASK_ALPHA_SHIFT));
+}
+
+
+
+/* This hardware just isn't capable of private back buffers without
+ * glitches and/or a hefty locking scheme.
+ */
+void viaCalcViewport(GLcontext *ctx)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+ struct via_renderbuffer *const vrb =
+ (struct via_renderbuffer *) dPriv->driverPrivate;
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+ GLfloat *m = vmesa->ViewportMatrix.m;
+
+ m[MAT_SX] = v[MAT_SX];
+ m[MAT_TX] = v[MAT_TX] + vrb->drawX + SUBPIXEL_X;
+ m[MAT_SY] = - v[MAT_SY];
+ m[MAT_TY] = - v[MAT_TY] + vrb->drawY + SUBPIXEL_Y + vrb->drawH;
+ m[MAT_SZ] = v[MAT_SZ] * (1.0 / vmesa->depth_max);
+ m[MAT_TZ] = v[MAT_TZ] * (1.0 / vmesa->depth_max);
+}
+
+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 viaInitState(GLcontext *ctx)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ vmesa->regCmdB = HC_ACMD_HCmdB;
+ vmesa->regEnable = HC_HenCW_MASK;
+
+ /* Mesa should do this for us:
+ */
+
+ ctx->Driver.BlendEquationSeparate( ctx,
+ ctx->Color.BlendEquationRGB,
+ ctx->Color.BlendEquationA);
+
+ ctx->Driver.BlendFuncSeparate( ctx,
+ ctx->Color.BlendSrcRGB,
+ ctx->Color.BlendDstRGB,
+ ctx->Color.BlendSrcA,
+ ctx->Color.BlendDstA);
+
+ ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
+ ctx->Scissor.Width, ctx->Scissor.Height );
+
+ ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
+}
+
+/**
+ * Convert S and T texture coordinate wrap modes to hardware bits.
+ */
+static u_int32_t
+get_wrap_mode( GLenum sWrap, GLenum tWrap )
+{
+ u_int32_t v = 0;
+
+
+ switch( sWrap ) {
+ case GL_REPEAT:
+ v |= HC_HTXnMPMD_Srepeat;
+ break;
+ case GL_CLAMP:
+ case GL_CLAMP_TO_EDGE:
+ v |= HC_HTXnMPMD_Sclamp;
+ break;
+ case GL_MIRRORED_REPEAT:
+ v |= HC_HTXnMPMD_Smirror;
+ break;
+ }
+
+ switch( tWrap ) {
+ case GL_REPEAT:
+ v |= HC_HTXnMPMD_Trepeat;
+ break;
+ case GL_CLAMP:
+ case GL_CLAMP_TO_EDGE:
+ v |= HC_HTXnMPMD_Tclamp;
+ break;
+ case GL_MIRRORED_REPEAT:
+ v |= HC_HTXnMPMD_Tmirror;
+ break;
+ }
+
+ return v;
+}
+
+static u_int32_t
+get_minmag_filter( GLenum min, GLenum mag )
+{
+ u_int32_t v = 0;
+
+ switch (min) {
+ case GL_NEAREST:
+ v = HC_HTXnFLSs_Nearest |
+ HC_HTXnFLTs_Nearest;
+ break;
+ case GL_LINEAR:
+ v = HC_HTXnFLSs_Linear |
+ HC_HTXnFLTs_Linear;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ v = HC_HTXnFLSs_Nearest |
+ HC_HTXnFLTs_Nearest;
+ v |= HC_HTXnFLDs_Nearest;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ v = HC_HTXnFLSs_Linear |
+ HC_HTXnFLTs_Linear;
+ v |= HC_HTXnFLDs_Nearest;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ v = HC_HTXnFLSs_Nearest |
+ HC_HTXnFLTs_Nearest;
+ v |= HC_HTXnFLDs_Linear;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ v = HC_HTXnFLSs_Linear |
+ HC_HTXnFLTs_Linear;
+ v |= HC_HTXnFLDs_Linear;
+ break;
+ default:
+ break;
+ }
+
+ switch (mag) {
+ case GL_LINEAR:
+ v |= HC_HTXnFLSe_Linear |
+ HC_HTXnFLTe_Linear;
+ break;
+ case GL_NEAREST:
+ v |= HC_HTXnFLSe_Nearest |
+ HC_HTXnFLTe_Nearest;
+ break;
+ default:
+ break;
+ }
+
+ return v;
+}
+
+
+static GLboolean viaChooseTextureState(GLcontext *ctx)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit0 = &ctx->Texture.Unit[0];
+ struct gl_texture_unit *texUnit1 = &ctx->Texture.Unit[1];
+
+ if (texUnit0->_ReallyEnabled || texUnit1->_ReallyEnabled) {
+ vmesa->regEnable |= HC_HenTXMP_MASK | HC_HenTXCH_MASK | HC_HenTXPP_MASK;
+
+ if (texUnit0->_ReallyEnabled) {
+ struct gl_texture_object *texObj = texUnit0->_Current;
+
+ vmesa->regHTXnTB[0] = get_minmag_filter( texObj->MinFilter,
+ texObj->MagFilter );
+
+ vmesa->regHTXnMPMD[0] &= ~(HC_HTXnMPMD_SMASK | HC_HTXnMPMD_TMASK);
+ vmesa->regHTXnMPMD[0] |= get_wrap_mode( texObj->WrapS,
+ texObj->WrapT );
+
+ vmesa->regHTXnTB[0] &= ~(HC_HTXnTB_TBC_S | HC_HTXnTB_TBC_T);
+ if (texObj->Image[0][texObj->BaseLevel]->Border > 0) {
+ vmesa->regHTXnTB[0] |= (HC_HTXnTB_TBC_S | HC_HTXnTB_TBC_T);
+ vmesa->regHTXnTBC[0] =
+ PACK_COLOR_888(FLOAT_TO_UBYTE(texObj->BorderColor[0]),
+ FLOAT_TO_UBYTE(texObj->BorderColor[1]),
+ FLOAT_TO_UBYTE(texObj->BorderColor[2]));
+ vmesa->regHTXnTRAH[0] = FLOAT_TO_UBYTE(texObj->BorderColor[3]);
+ }
+
+ if (texUnit0->LodBias != 0.0f) {
+ GLuint b = viaComputeLodBias(texUnit0->LodBias);
+ vmesa->regHTXnTB[0] &= ~HC_HTXnFLDs_MASK;
+ vmesa->regHTXnTB[0] |= HC_HTXnFLDs_ConstLOD;
+ vmesa->regHTXnCLOD[0] = (b&0x1f) | (((~b)&0x1f)<<10); /* FIXME */
+ }
+
+ if (!viaTexCombineState( vmesa, texUnit0->_CurrentCombine, 0 )) {
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "viaTexCombineState failed for unit 0\n");
+ return GL_FALSE;
+ }
+ }
+
+ if (texUnit1->_ReallyEnabled) {
+ struct gl_texture_object *texObj = texUnit1->_Current;
+
+ vmesa->regHTXnTB[1] = get_minmag_filter( texObj->MinFilter,
+ texObj->MagFilter );
+ vmesa->regHTXnMPMD[1] &= ~(HC_HTXnMPMD_SMASK | HC_HTXnMPMD_TMASK);
+ vmesa->regHTXnMPMD[1] |= get_wrap_mode( texObj->WrapS,
+ texObj->WrapT );
+
+ vmesa->regHTXnTB[1] &= ~(HC_HTXnTB_TBC_S | HC_HTXnTB_TBC_T);
+ if (texObj->Image[0][texObj->BaseLevel]->Border > 0) {
+ vmesa->regHTXnTB[1] |= (HC_HTXnTB_TBC_S | HC_HTXnTB_TBC_T);
+ vmesa->regHTXnTBC[1] =
+ PACK_COLOR_888(FLOAT_TO_UBYTE(texObj->BorderColor[0]),
+ FLOAT_TO_UBYTE(texObj->BorderColor[1]),
+ FLOAT_TO_UBYTE(texObj->BorderColor[2]));
+ vmesa->regHTXnTRAH[1] = FLOAT_TO_UBYTE(texObj->BorderColor[3]);
+ }
+
+
+ if (texUnit1->LodBias != 0.0f) {
+ GLuint b = viaComputeLodBias(texUnit1->LodBias);
+ vmesa->regHTXnTB[1] &= ~HC_HTXnFLDs_MASK;
+ vmesa->regHTXnTB[1] |= HC_HTXnFLDs_ConstLOD;
+ vmesa->regHTXnCLOD[1] = (b&0x1f) | (((~b)&0x1f)<<10); /* FIXME */
+ }
+
+ if (!viaTexCombineState( vmesa, texUnit1->_CurrentCombine, 1 )) {
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "viaTexCombineState failed for unit 1\n");
+ return GL_FALSE;
+ }
+ }
+ }
+ else {
+ vmesa->regEnable &= ~(HC_HenTXMP_MASK | HC_HenTXCH_MASK |
+ HC_HenTXPP_MASK);
+ }
+
+ return GL_TRUE;
+}
+
+static void viaChooseColorState(GLcontext *ctx)
+{
+ struct via_context *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
+ */
+
+ 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;
+
+ }
+ else {
+ vmesa->regEnable &= (~HC_HenABL_MASK);
+ }
+
+ if (ctx->Color.AlphaEnabled) {
+ vmesa->regEnable |= HC_HenAT_MASK;
+ vmesa->regHATMD = FLOAT_TO_UBYTE(ctx->Color.AlphaRef) |
+ ((ctx->Color.AlphaFunc - GL_NEVER) << 8);
+ }
+ else {
+ vmesa->regEnable &= (~HC_HenAT_MASK);
+ }
+
+ if (ctx->Color.DitherFlag && (vmesa->viaScreen->bitsPerPixel < 32)) {
+ if (ctx->Color.BlendEnabled) {
+ vmesa->regEnable &= ~HC_HenDT_MASK;
+ }
+ else {
+ vmesa->regEnable |= HC_HenDT_MASK;
+ }
+ }
+
+
+ vmesa->regEnable &= ~HC_HenDT_MASK;
+
+ if (ctx->Color.ColorLogicOpEnabled)
+ vmesa->regHROP = ROP[ctx->Color.LogicOp & 0xF];
+ else
+ vmesa->regHROP = HC_HROP_P;
+
+ vmesa->regHFBBMSKL = PACK_COLOR_888(ctx->Color.ColorMask[0],
+ ctx->Color.ColorMask[1],
+ ctx->Color.ColorMask[2]);
+ vmesa->regHROP |= ctx->Color.ColorMask[3];
+
+ if (ctx->Color.ColorMask[3])
+ vmesa->regEnable |= HC_HenAW_MASK;
+ else
+ vmesa->regEnable &= ~HC_HenAW_MASK;
+}
+
+static void viaChooseFogState(GLcontext *ctx)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ if (ctx->Fog.Enabled) {
+ GLubyte r, g, b, a;
+
+ 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;
+ }
+ else {
+ vmesa->regEnable &= ~HC_HenFOG_MASK;
+ }
+}
+
+static void viaChooseDepthState(GLcontext *ctx)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ if (ctx->Depth.Test) {
+ 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;
+
+ }
+ else {
+ 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);
+ }
+}
+
+static void viaChooseLineState(GLcontext *ctx)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ if (ctx->Line.StippleFlag) {
+ vmesa->regEnable |= HC_HenLP_MASK;
+ vmesa->regHLP = ctx->Line.StipplePattern;
+ vmesa->regHLPRF = ctx->Line.StippleFactor;
+ }
+ else {
+ vmesa->regEnable &= ~HC_HenLP_MASK;
+ }
+}
+
+static void viaChoosePolygonState(GLcontext *ctx)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+#if 0
+ /* Polygon stipple is broken - see via_state.c
+ */
+ if (ctx->Polygon.StippleFlag) {
+ vmesa->regEnable |= HC_HenSP_MASK;
+ }
+ else {
+ vmesa->regEnable &= ~HC_HenSP_MASK;
+ }
+#else
+ FALLBACK(vmesa, VIA_FALLBACK_POLY_STIPPLE,
+ ctx->Polygon.StippleFlag);
+#endif
+
+ if (ctx->Polygon.CullFlag) {
+ vmesa->regEnable |= HC_HenFBCull_MASK;
+ }
+ else {
+ vmesa->regEnable &= ~HC_HenFBCull_MASK;
+ }
+}
+
+static void viaChooseStencilState(GLcontext *ctx)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ 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;
+ }
+ else {
+ vmesa->regEnable &= ~HC_HenST_MASK;
+ }
+}
+
+
+
+static void viaChooseTriangle(GLcontext *ctx)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ 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;
+ }
+ }
+}
+
+void viaValidateState( GLcontext *ctx )
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ if (vmesa->newState & _NEW_TEXTURE) {
+ GLboolean ok = (viaChooseTextureState(ctx) &&
+ viaUpdateTextureState(ctx));
+
+ FALLBACK(vmesa, VIA_FALLBACK_TEXTURE, !ok);
+ }
+
+ if (vmesa->newState & _NEW_COLOR)
+ viaChooseColorState(ctx);
+
+ if (vmesa->newState & _NEW_DEPTH)
+ viaChooseDepthState(ctx);
+
+ if (vmesa->newState & _NEW_FOG)
+ viaChooseFogState(ctx);
+
+ if (vmesa->newState & _NEW_LINE)
+ viaChooseLineState(ctx);
+
+ if (vmesa->newState & (_NEW_POLYGON | _NEW_POLYGONSTIPPLE)) {
+ viaChoosePolygonState(ctx);
+ viaChooseTriangle(ctx);
+ }
+
+ if ((vmesa->newState & _NEW_STENCIL) && vmesa->have_hw_stencil)
+ viaChooseStencilState(ctx);
+
+ if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+ vmesa->regEnable |= HC_HenCS_MASK;
+ else
+ vmesa->regEnable &= ~HC_HenCS_MASK;
+
+ if (ctx->Point.SmoothFlag ||
+ ctx->Line.SmoothFlag ||
+ ctx->Polygon.SmoothFlag)
+ vmesa->regEnable |= HC_HenAA_MASK;
+ else
+ vmesa->regEnable &= ~HC_HenAA_MASK;
+
+ vmesa->newEmitState |= vmesa->newState;
+ vmesa->newState = 0;
+}
+
+static void viaInvalidateState(GLcontext *ctx, GLuint newState)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ VIA_FINISH_PRIM( vmesa );
+ vmesa->newState |= newState;
+
+ _swrast_InvalidateState(ctx, newState);
+ _swsetup_InvalidateState(ctx, newState);
+ _vbo_InvalidateState(ctx, newState);
+ _tnl_InvalidateState(ctx, newState);
+}
+
+void viaInitStateFuncs(GLcontext *ctx)
+{
+ /* Callbacks for internal Mesa events.
+ */
+ ctx->Driver.UpdateState = viaInvalidateState;
+
+ /* API callbacks
+ */
+ ctx->Driver.BlendEquationSeparate = viaBlendEquationSeparate;
+ ctx->Driver.BlendFuncSeparate = viaBlendFuncSeparate;
+ ctx->Driver.ClearColor = viaClearColor;
+ ctx->Driver.ColorMask = viaColorMask;
+ ctx->Driver.DrawBuffer = viaDrawBuffer;
+ ctx->Driver.RenderMode = viaRenderMode;
+ ctx->Driver.Scissor = viaScissor;
+ ctx->Driver.DepthRange = viaDepthRange;
+ ctx->Driver.Viewport = viaViewport;
+ ctx->Driver.Enable = viaEnable;
+
+ /* XXX this should go away */
+ ctx->Driver.ResizeBuffers = viaReAllocateBuffers;
+}
diff --git a/src/via_state.h b/src/via_state.h
new file mode 100644
index 0000000..065ec57
--- /dev/null
+++ b/src/via_state.h
@@ -0,0 +1,39 @@
+/*
+ * 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 viaCalcViewport(GLcontext *ctx);
+extern void viaValidateState(GLcontext *ctx);
+extern void viaEmitState(struct via_context *vmesa);
+
+extern void viaFallback(struct via_context *vmesa, GLuint bit, GLboolean mode);
+#define FALLBACK(vmesa, bit, mode) viaFallback(vmesa, bit, mode)
+
+#endif
diff --git a/src/via_tex.c b/src/via_tex.c
new file mode 100644
index 0000000..0261a3f
--- /dev/null
+++ b/src/via_tex.c
@@ -0,0 +1,988 @@
+/*
+ * 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 "enums.h"
+#include "colortab.h"
+#include "convolve.h"
+#include "context.h"
+#include "mipmap.h"
+#include "simple_list.h"
+#include "texcompress.h"
+#include "texformat.h"
+#include "texobj.h"
+#include "texstore.h"
+
+#include "mm.h"
+#include "via_context.h"
+#include "via_fb.h"
+#include "via_tex.h"
+#include "via_state.h"
+#include "via_ioctl.h"
+#include "via_3d_reg.h"
+
+static const struct gl_texture_format *
+viaChooseTexFormat( GLcontext *ctx, GLint internalFormat,
+ GLenum format, GLenum type )
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ const GLboolean do32bpt = ( vmesa->viaScreen->bitsPerPixel == 32
+/* && vmesa->viaScreen->textureSize > 4*1024*1024 */
+ );
+
+
+ switch ( internalFormat ) {
+ case 4:
+ case GL_RGBA:
+ case GL_COMPRESSED_RGBA:
+ if ( format == GL_BGRA ) {
+ if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ||
+ type == GL_UNSIGNED_BYTE ) {
+ return &_mesa_texformat_argb8888;
+ }
+ else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
+ return &_mesa_texformat_argb4444;
+ }
+ else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
+ return &_mesa_texformat_argb1555;
+ }
+ }
+ else if ( type == GL_UNSIGNED_BYTE ||
+ type == GL_UNSIGNED_INT_8_8_8_8_REV ||
+ type == GL_UNSIGNED_INT_8_8_8_8 ) {
+ return &_mesa_texformat_argb8888;
+ }
+ return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
+
+ case 3:
+ case GL_RGB:
+ case GL_COMPRESSED_RGB:
+ if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
+ return &_mesa_texformat_rgb565;
+ }
+ else if ( type == GL_UNSIGNED_BYTE ) {
+ return &_mesa_texformat_argb8888;
+ }
+ return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
+
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ return &_mesa_texformat_argb8888;
+
+ case GL_RGBA4:
+ case GL_RGBA2:
+ return &_mesa_texformat_argb4444;
+
+ case GL_RGB5_A1:
+ return &_mesa_texformat_argb1555;
+
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ return &_mesa_texformat_argb8888;
+
+ case GL_RGB5:
+ case GL_RGB4:
+ case GL_R3_G3_B2:
+ return &_mesa_texformat_rgb565;
+
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ case GL_COMPRESSED_ALPHA:
+ return &_mesa_texformat_a8;
+
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ case GL_COMPRESSED_LUMINANCE:
+ 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:
+ case GL_COMPRESSED_LUMINANCE_ALPHA:
+ return &_mesa_texformat_al88;
+
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ case GL_COMPRESSED_INTENSITY:
+ return &_mesa_texformat_i8;
+
+ case GL_YCBCR_MESA:
+ if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
+ type == GL_UNSIGNED_BYTE)
+ return &_mesa_texformat_ycbcr;
+ else
+ return &_mesa_texformat_ycbcr_rev;
+
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ return &_mesa_texformat_rgb_fxt1;
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ return &_mesa_texformat_rgba_fxt1;
+
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ return &_mesa_texformat_rgb_dxt1;
+
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ return &_mesa_texformat_rgba_dxt1;
+
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ return &_mesa_texformat_rgba_dxt3;
+
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ return &_mesa_texformat_rgba_dxt5;
+
+ 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:
+ fprintf(stderr, "unexpected texture format %s in %s\n",
+ _mesa_lookup_enum_by_nr(internalFormat),
+ __FUNCTION__);
+ return NULL;
+ }
+
+ return NULL; /* never get here */
+}
+
+static int logbase2(int n)
+{
+ GLint i = 1;
+ GLint log2 = 0;
+
+ while (n > i) {
+ i *= 2;
+ log2++;
+ }
+
+ return log2;
+}
+
+static const char *get_memtype_name( GLint memType )
+{
+ static const char *names[] = {
+ "VIA_MEM_VIDEO",
+ "VIA_MEM_AGP",
+ "VIA_MEM_SYSTEM",
+ "VIA_MEM_MIXED",
+ "VIA_MEM_UNKNOWN"
+ };
+
+ return names[memType];
+}
+
+
+static GLboolean viaMoveTexBuffers( struct via_context *vmesa,
+ struct via_tex_buffer **buffers,
+ GLuint nr,
+ GLint newMemType )
+{
+ struct via_tex_buffer *newTexBuf[VIA_MAX_TEXLEVELS];
+ GLint i;
+
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "%s to %s\n",
+ __FUNCTION__,
+ get_memtype_name(newMemType));
+
+ memset(newTexBuf, 0, sizeof(newTexBuf));
+
+ /* First do all the allocations (or fail):
+ */
+ for (i = 0; i < nr; i++) {
+ if (buffers[i]->memType != newMemType) {
+
+ /* Don't allow uploads in a thrash state. Should try and
+ * catch this earlier.
+ */
+ if (vmesa->thrashing && newMemType != VIA_MEM_SYSTEM)
+ goto cleanup;
+
+ newTexBuf[i] = via_alloc_texture(vmesa,
+ buffers[i]->size,
+ newMemType);
+ if (!newTexBuf[i])
+ goto cleanup;
+ }
+ }
+
+
+ /* Now copy all the image data and free the old texture memory.
+ */
+ for (i = 0; i < nr; i++) {
+ if (newTexBuf[i]) {
+ memcpy(newTexBuf[i]->bufAddr,
+ buffers[i]->bufAddr,
+ buffers[i]->size);
+
+ newTexBuf[i]->image = buffers[i]->image;
+ newTexBuf[i]->image->texMem = newTexBuf[i];
+ newTexBuf[i]->image->image.Data = newTexBuf[i]->bufAddr;
+ via_free_texture(vmesa, buffers[i]);
+ }
+ }
+
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "%s - success\n", __FUNCTION__);
+
+ return GL_TRUE;
+
+ cleanup:
+ /* Release any allocations made prior to failure:
+ */
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "%s - failed\n", __FUNCTION__);
+
+ for (i = 0; i < nr; i++) {
+ if (newTexBuf[i]) {
+ via_free_texture(vmesa, newTexBuf[i]);
+ }
+ }
+
+ return GL_FALSE;
+}
+
+
+static GLboolean viaMoveTexObject( struct via_context *vmesa,
+ struct via_texture_object *viaObj,
+ GLint newMemType )
+{
+ struct via_texture_image **viaImage =
+ (struct via_texture_image **)&viaObj->obj.Image[0][0];
+ struct via_tex_buffer *buffers[VIA_MAX_TEXLEVELS];
+ GLuint i, nr = 0;
+
+ for (i = viaObj->firstLevel; i <= viaObj->lastLevel; i++)
+ buffers[nr++] = viaImage[i]->texMem;
+
+ if (viaMoveTexBuffers( vmesa, &buffers[0], nr, newMemType )) {
+ viaObj->memType = newMemType;
+ return GL_TRUE;
+ }
+
+ return GL_FALSE;
+}
+
+
+
+static GLboolean viaSwapInTexObject( struct via_context *vmesa,
+ struct via_texture_object *viaObj )
+{
+ const struct via_texture_image *baseImage =
+ (struct via_texture_image *)viaObj->obj.Image[0][viaObj->obj.BaseLevel];
+
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ if (baseImage->texMem->memType != VIA_MEM_SYSTEM)
+ return viaMoveTexObject( vmesa, viaObj, baseImage->texMem->memType );
+
+ return (viaMoveTexObject( vmesa, viaObj, VIA_MEM_AGP ) ||
+ viaMoveTexObject( vmesa, viaObj, VIA_MEM_VIDEO ));
+}
+
+
+/* This seems crude, but it asks a fairly pertinent question and gives
+ * an accurate answer:
+ */
+static GLboolean viaIsTexMemLow( struct via_context *vmesa,
+ GLuint heap )
+{
+ struct via_tex_buffer *buf = via_alloc_texture(vmesa, 512 * 1024, heap );
+ if (!buf)
+ return GL_TRUE;
+
+ via_free_texture(vmesa, buf);
+ return GL_FALSE;
+}
+
+
+/* Speculatively move texture images which haven't been used in a
+ * while back to system memory.
+ *
+ * TODO: only do this when texture memory is low.
+ *
+ * TODO: use dma.
+ *
+ * TODO: keep the fb/agp version hanging around and use the local
+ * version as backing store, so re-upload might be avoided.
+ *
+ * TODO: do this properly in the kernel...
+ */
+GLboolean viaSwapOutWork( struct via_context *vmesa )
+{
+ struct via_tex_buffer *s, *tmp;
+ GLuint done = 0;
+ GLuint heap, target;
+
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "%s VID %d AGP %d SYS %d\n", __FUNCTION__,
+ vmesa->total_alloc[VIA_MEM_VIDEO],
+ vmesa->total_alloc[VIA_MEM_AGP],
+ vmesa->total_alloc[VIA_MEM_SYSTEM]);
+
+
+ for (heap = VIA_MEM_VIDEO; heap <= VIA_MEM_AGP; heap++) {
+ GLuint nr = 0, sz = 0;
+
+ if (vmesa->thrashing) {
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "Heap %d: trash flag\n", heap);
+ target = 1*1024*1024;
+ }
+ else if (viaIsTexMemLow(vmesa, heap)) {
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "Heap %d: low memory\n", heap);
+ target = 64*1024;
+ }
+ else {
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "Heap %d: nothing to do\n", heap);
+ continue;
+ }
+
+ foreach_s( s, tmp, &vmesa->tex_image_list[heap] ) {
+ if (s->lastUsed < vmesa->lastSwap[1]) {
+ struct via_texture_object *viaObj =
+ (struct via_texture_object *) s->image->image.TexObject;
+
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr,
+ "back copy tex sz %d, lastUsed %d lastSwap %d\n",
+ s->size, s->lastUsed, vmesa->lastSwap[1]);
+
+ if (viaMoveTexBuffers( vmesa, &s, 1, VIA_MEM_SYSTEM )) {
+ viaObj->memType = VIA_MEM_MIXED;
+ done += s->size;
+ }
+ else {
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "Failed to back copy texture!\n");
+ sz += s->size;
+ }
+ }
+ else {
+ nr ++;
+ sz += s->size;
+ }
+
+ if (done > target) {
+ vmesa->thrashing = GL_FALSE; /* might not get set otherwise? */
+ return GL_TRUE;
+ }
+ }
+
+ assert(sz == vmesa->total_alloc[heap]);
+
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "Heap %d: nr %d tot sz %d\n", heap, nr, sz);
+ }
+
+
+ return done != 0;
+}
+
+
+
+/* Basically, just collect the image dimensions and addresses for each
+ * image and update the texture object state accordingly.
+ */
+static GLboolean viaSetTexImages(GLcontext *ctx,
+ struct gl_texture_object *texObj)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ struct via_texture_object *viaObj = (struct via_texture_object *)texObj;
+ const struct via_texture_image *baseImage =
+ (struct via_texture_image *)texObj->Image[0][texObj->BaseLevel];
+ GLint firstLevel, lastLevel, numLevels;
+ GLuint texFormat;
+ GLint w, h, p;
+ GLint i, j = 0, k = 0, l = 0, m = 0;
+ GLuint texBase;
+ GLuint basH = 0;
+ GLuint widthExp = 0;
+ GLuint heightExp = 0;
+
+ switch (baseImage->image.TexFormat->MesaFormat) {
+ case MESA_FORMAT_ARGB8888:
+ 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_RGB888:
+ texFormat = HC_HTXnFM_ARGB0888;
+ 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;
+ case MESA_FORMAT_A8:
+ texFormat = HC_HTXnFM_A8;
+ break;
+ default:
+ _mesa_problem(vmesa->glCtx, "Bad texture format in viaSetTexImages");
+ return GL_FALSE;
+ }
+
+ /* 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 (texObj->MinFilter == GL_LINEAR || texObj->MinFilter == GL_NEAREST) {
+ firstLevel = lastLevel = texObj->BaseLevel;
+ }
+ else {
+ firstLevel = texObj->BaseLevel + (GLint)(texObj->MinLod + 0.5);
+ firstLevel = MAX2(firstLevel, texObj->BaseLevel);
+ lastLevel = texObj->BaseLevel + (GLint)(texObj->MaxLod + 0.5);
+ lastLevel = MAX2(lastLevel, texObj->BaseLevel);
+ lastLevel = MIN2(lastLevel, texObj->BaseLevel + baseImage->image.MaxLog2);
+ lastLevel = MIN2(lastLevel, texObj->MaxLevel);
+ lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
+ }
+
+ numLevels = lastLevel - firstLevel + 1;
+
+ /* The hardware supports only 10 mipmap levels; ignore higher levels.
+ */
+ if ((numLevels > 10) && (ctx->Const.MaxTextureLevels > 10)) {
+ lastLevel -= numLevels - 10;
+ numLevels = 10;
+ }
+
+ /* save these values, check if they effect the residency of the
+ * texture:
+ */
+ if (viaObj->firstLevel != firstLevel ||
+ viaObj->lastLevel != lastLevel) {
+ viaObj->firstLevel = firstLevel;
+ viaObj->lastLevel = lastLevel;
+ viaObj->memType = VIA_MEM_MIXED;
+ }
+
+ if (VIA_DEBUG & DEBUG_TEXTURE & 0)
+ fprintf(stderr, "%s, current memType: %s\n",
+ __FUNCTION__,
+ get_memtype_name(viaObj->memType));
+
+
+ if (viaObj->memType == VIA_MEM_MIXED ||
+ viaObj->memType == VIA_MEM_SYSTEM) {
+ if (!viaSwapInTexObject(vmesa, viaObj)) {
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ if (!vmesa->thrashing)
+ fprintf(stderr, "Thrashing flag set for frame %d\n",
+ vmesa->swap_count);
+ vmesa->thrashing = GL_TRUE;
+ return GL_FALSE;
+ }
+ }
+
+ if (viaObj->memType == VIA_MEM_AGP)
+ viaObj->regTexFM = (HC_SubA_HTXnFM << 24) | HC_HTXnLoc_AGP | texFormat;
+ else
+ viaObj->regTexFM = (HC_SubA_HTXnFM << 24) | HC_HTXnLoc_Local | texFormat;
+
+
+ for (i = 0; i < numLevels; i++) {
+ struct via_texture_image *viaImage =
+ (struct via_texture_image *)texObj->Image[0][firstLevel + i];
+
+ w = viaImage->image.WidthLog2;
+ h = viaImage->image.HeightLog2;
+ p = viaImage->pitchLog2;
+
+ assert(viaImage->texMem->memType == viaObj->memType);
+
+ texBase = viaImage->texMem->texBase;
+ if (!texBase) {
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "%s: no texBase[%d]\n", __FUNCTION__, i);
+ return GL_FALSE;
+ }
+
+ /* Image has to remain resident until the coming fence is retired.
+ */
+ move_to_head( &vmesa->tex_image_list[viaImage->texMem->memType],
+ viaImage->texMem );
+ viaImage->texMem->lastUsed = vmesa->lastBreadcrumbWrite;
+
+
+ viaObj->regTexBaseAndPitch[i].baseL =
+ ((HC_SubA_HTXnL0BasL + i) << 24) | (texBase & 0xFFFFFF);
+
+ viaObj->regTexBaseAndPitch[i].pitchLog2 =
+ ((HC_SubA_HTXnL0Pit + i) << 24) | (p << 20);
+
+
+ /* The base high bytes for each 3 levels are packed
+ * together into one register:
+ */
+ j = i / 3;
+ k = 3 - (i % 3);
+ basH |= ((texBase & 0xFF000000) >> (k << 3));
+ if (k == 1) {
+ viaObj->regTexBaseH[j] = ((j + HC_SubA_HTXnL012BasH) << 24) | basH;
+ basH = 0;
+ }
+
+ /* Likewise, sets of 6 log2width and log2height values are
+ * packed into individual registers:
+ */
+ l = i / 6;
+ m = i % 6;
+ widthExp |= (((GLuint)w & 0xF) << (m << 2));
+ heightExp |= (((GLuint)h & 0xF) << (m << 2));
+ if (m == 5) {
+ viaObj->regTexWidthLog2[l] =
+ (l + HC_SubA_HTXnL0_5WE) << 24 | widthExp;
+ viaObj->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) {
+ viaObj->regTexBaseH[j] = ((j + HC_SubA_HTXnL012BasH) << 24) | basH;
+ }
+ if (m != 5) {
+ viaObj->regTexWidthLog2[l] = (l + HC_SubA_HTXnL0_5WE) << 24 | widthExp;
+ viaObj->regTexHeightLog2[l] = (l + HC_SubA_HTXnL0_5HE) << 24 | heightExp;
+ }
+
+ return GL_TRUE;
+}
+
+
+GLboolean viaUpdateTextureState( GLcontext *ctx )
+{
+ struct gl_texture_unit *texUnit = ctx->Texture.Unit;
+ GLuint i;
+
+ for (i = 0; i < 2; i++) {
+ if (texUnit[i]._ReallyEnabled == TEXTURE_2D_BIT ||
+ texUnit[i]._ReallyEnabled == TEXTURE_1D_BIT) {
+
+ if (!viaSetTexImages(ctx, texUnit[i]._Current))
+ return GL_FALSE;
+ }
+ else if (texUnit[i]._ReallyEnabled) {
+ return GL_FALSE;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
+
+
+
+
+
+
+static void viaTexImage(GLcontext *ctx,
+ GLint dims,
+ GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ GLint postConvWidth = width;
+ GLint postConvHeight = height;
+ GLint texelBytes, sizeInBytes;
+ struct via_texture_object *viaObj = (struct via_texture_object *)texObj;
+ struct via_texture_image *viaImage = (struct via_texture_image *)texImage;
+ int heaps[3], nheaps, i;
+
+ if (!is_empty_list(&vmesa->freed_tex_buffers)) {
+ viaCheckBreadcrumb(vmesa, 0);
+ via_release_pending_textures(vmesa);
+ }
+
+ if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
+ _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
+ &postConvHeight);
+ }
+
+ /* choose the texture format */
+ texImage->TexFormat = viaChooseTexFormat(ctx, internalFormat,
+ format, type);
+
+ assert(texImage->TexFormat);
+
+ if (dims == 1) {
+ texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
+ texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
+ }
+ else {
+ texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
+ texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
+ }
+ texelBytes = texImage->TexFormat->TexelBytes;
+
+ if (texelBytes == 0) {
+ /* compressed format */
+ texImage->IsCompressed = GL_TRUE;
+ texImage->CompressedSize =
+ ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
+ texImage->Height, texImage->Depth,
+ texImage->TexFormat->MesaFormat);
+ }
+
+ /* Minimum pitch of 32 bytes */
+ if (postConvWidth * texelBytes < 32) {
+ postConvWidth = 32 / texelBytes;
+ texImage->RowStride = postConvWidth;
+ }
+
+ assert(texImage->RowStride == postConvWidth);
+ viaImage->pitchLog2 = logbase2(postConvWidth * texelBytes);
+
+ /* allocate memory */
+ if (texImage->IsCompressed)
+ sizeInBytes = texImage->CompressedSize;
+ else
+ sizeInBytes = postConvWidth * postConvHeight * texelBytes;
+
+
+ /* Attempt to allocate texture memory directly, otherwise use main
+ * memory and this texture will always be a fallback. FIXME!
+ *
+ * TODO: make room in agp if this fails.
+ * TODO: use fb ram for textures as well.
+ */
+
+
+ switch (viaObj->memType) {
+ case VIA_MEM_UNKNOWN:
+ heaps[0] = VIA_MEM_AGP;
+ heaps[1] = VIA_MEM_VIDEO;
+ heaps[2] = VIA_MEM_SYSTEM;
+ nheaps = 3;
+ break;
+ case VIA_MEM_AGP:
+ case VIA_MEM_VIDEO:
+ heaps[0] = viaObj->memType;
+ heaps[1] = VIA_MEM_SYSTEM;
+ nheaps = 2;
+ break;
+ case VIA_MEM_MIXED:
+ case VIA_MEM_SYSTEM:
+ default:
+ heaps[0] = VIA_MEM_SYSTEM;
+ nheaps = 1;
+ break;
+ }
+
+ for (i = 0; i < nheaps && !viaImage->texMem; i++) {
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "try %s (obj %s)\n", get_memtype_name(heaps[i]),
+ get_memtype_name(viaObj->memType));
+ viaImage->texMem = via_alloc_texture(vmesa, sizeInBytes, heaps[i]);
+ }
+
+ if (!viaImage->texMem) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+ return;
+ }
+
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "upload %d bytes to %s\n", sizeInBytes,
+ get_memtype_name(viaImage->texMem->memType));
+
+ viaImage->texMem->image = viaImage;
+ texImage->Data = viaImage->texMem->bufAddr;
+
+ if (viaObj->memType == VIA_MEM_UNKNOWN)
+ viaObj->memType = viaImage->texMem->memType;
+ else if (viaObj->memType != viaImage->texMem->memType)
+ viaObj->memType = VIA_MEM_MIXED;
+
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "%s, obj %s, image : %s\n",
+ __FUNCTION__,
+ get_memtype_name(viaObj->memType),
+ get_memtype_name(viaImage->texMem->memType));
+
+ vmesa->clearTexCache = 1;
+
+ pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
+ format, type,
+ pixels, packing, "glTexImage");
+ if (!pixels) {
+ /* Note: we check for a NULL image pointer here, _after_ we allocated
+ * memory for the texture. That's what the GL spec calls for.
+ */
+ return;
+ }
+ else {
+ GLint dstRowStride;
+ GLboolean success;
+ if (texImage->IsCompressed) {
+ dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
+ }
+ else {
+ dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
+ }
+ ASSERT(texImage->TexFormat->StoreImage);
+ success = texImage->TexFormat->StoreImage(ctx, dims,
+ texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, 1,
+ format, type, pixels, packing);
+ if (!success) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+ }
+ }
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, target,
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+ texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+}
+
+static void viaTexImage2D(GLcontext *ctx,
+ GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ viaTexImage( ctx, 2, target, level,
+ internalFormat, width, height, border,
+ format, type, pixels,
+ packing, texObj, texImage );
+}
+
+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)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ viaWaitIdle(vmesa, GL_TRUE);
+ vmesa->clearTexCache = 1;
+
+ _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
+ height, format, type, pixels, packing, texObj,
+ texImage);
+}
+
+static void viaTexImage1D(GLcontext *ctx,
+ GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ viaTexImage( ctx, 1, target, level,
+ internalFormat, width, 1, border,
+ format, type, pixels,
+ packing, texObj, texImage );
+}
+
+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)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ viaWaitIdle(vmesa, GL_TRUE);
+ vmesa->clearTexCache = 1;
+
+ _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
+ format, type, pixels, packing, texObj,
+ texImage);
+}
+
+
+
+static GLboolean viaIsTextureResident(GLcontext *ctx,
+ struct gl_texture_object *texObj)
+{
+ struct via_texture_object *viaObj =
+ (struct via_texture_object *)texObj;
+
+ return (viaObj->memType == VIA_MEM_AGP ||
+ viaObj->memType == VIA_MEM_VIDEO);
+}
+
+
+
+static struct gl_texture_image *viaNewTextureImage( GLcontext *ctx )
+{
+ (void) ctx;
+ return (struct gl_texture_image *)CALLOC_STRUCT(via_texture_image);
+}
+
+
+static struct gl_texture_object *viaNewTextureObject( GLcontext *ctx,
+ GLuint name,
+ GLenum target )
+{
+ struct via_texture_object *obj = CALLOC_STRUCT(via_texture_object);
+
+ _mesa_initialize_texture_object(&obj->obj, name, target);
+ (void) ctx;
+
+ obj->memType = VIA_MEM_UNKNOWN;
+
+ return &obj->obj;
+}
+
+
+static void viaFreeTextureImageData( GLcontext *ctx,
+ struct gl_texture_image *texImage )
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ struct via_texture_image *image = (struct via_texture_image *)texImage;
+
+ if (image->texMem) {
+ via_free_texture(vmesa, image->texMem);
+ image->texMem = NULL;
+ }
+
+ texImage->Data = NULL;
+}
+
+
+
+
+void viaInitTextureFuncs(struct dd_function_table * functions)
+{
+ functions->ChooseTextureFormat = viaChooseTexFormat;
+ functions->TexImage1D = viaTexImage1D;
+ functions->TexImage2D = viaTexImage2D;
+ functions->TexSubImage1D = viaTexSubImage1D;
+ functions->TexSubImage2D = viaTexSubImage2D;
+
+ functions->NewTextureObject = viaNewTextureObject;
+ functions->NewTextureImage = viaNewTextureImage;
+ functions->DeleteTexture = _mesa_delete_texture_object;
+ functions->FreeTexImageData = viaFreeTextureImageData;
+
+#if 0 && defined( USE_SSE_ASM )
+ /*
+ * XXX this code is disabled for now because the via_sse_memcpy()
+ * routine causes segfaults with flightgear.
+ * See Mesa3d-dev mail list messages from 7/15/2005 for details.
+ * Note that this function is currently disabled in via_tris.c too.
+ */
+ if (getenv("VIA_NO_SSE"))
+ functions->TextureMemCpy = _mesa_memcpy;
+ else
+ functions->TextureMemCpy = via_sse_memcpy;
+#else
+ functions->TextureMemCpy = _mesa_memcpy;
+#endif
+
+ functions->UpdateTexturePalette = 0;
+ functions->IsTextureResident = viaIsTextureResident;
+}
+
+
diff --git a/src/via_tex.h b/src/via_tex.h
new file mode 100644
index 0000000..73cfa91
--- /dev/null
+++ b/src/via_tex.h
@@ -0,0 +1,41 @@
+/*
+ * 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"
+
+struct via_context;
+
+GLboolean viaUpdateTextureState(GLcontext *ctx);
+void viaInitTextureFuncs(struct dd_function_table * functions);
+GLboolean viaSwapOutWork( struct via_context *vmesa );
+
+#if defined( USE_SSE_ASM )
+void via_sse_memcpy( void *to, const void *from, size_t sz );
+#endif /* defined( USE_SSE_ASM ) */
+
+#endif
diff --git a/src/via_texcombine.c b/src/via_texcombine.c
new file mode 100644
index 0000000..d604457
--- /dev/null
+++ b/src/via_texcombine.c
@@ -0,0 +1,424 @@
+/*
+ * (C) Copyright IBM Corporation 2004
+ * 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
+ * on 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
+ * IBM AND/OR THEIR 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_texcombine.c
+ * Calculate texture combine hardware state.
+ *
+ * \author Ian Romanick <idr@us.ibm.com>
+ */
+
+#include <stdio.h>
+
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "colormac.h"
+#include "enums.h"
+
+#include "via_context.h"
+#include "via_state.h"
+#include "via_tex.h"
+#include "via_3d_reg.h"
+
+
+#define VIA_USE_ALPHA (HC_XTC_Adif - HC_XTC_Dif)
+
+#define INPUT_A_SHIFT 14
+#define INPUT_B_SHIFT 7
+#define INPUT_C_SHIFT 0
+#define INPUT_CBias_SHIFT 14
+
+#define CONST_ONE (HC_XTC_0 | HC_XTC_InvTOPC)
+
+static const unsigned color_operand_modifier[4] = {
+ 0,
+ HC_XTC_InvTOPC,
+ VIA_USE_ALPHA,
+ VIA_USE_ALPHA | HC_XTC_InvTOPC,
+};
+
+static const unsigned alpha_operand_modifier[2] = {
+ 0, HC_XTA_InvTOPA
+};
+
+static const unsigned bias_alpha_operand_modifier[2] = {
+ 0, HC_HTXnTBLAbias_Inv
+};
+
+
+static const unsigned c_shift_table[3] = {
+ HC_HTXnTBLCshift_No, HC_HTXnTBLCshift_1, HC_HTXnTBLCshift_2
+};
+
+static const unsigned a_shift_table[3] = {
+ HC_HTXnTBLAshift_No, HC_HTXnTBLAshift_1, HC_HTXnTBLAshift_2
+};
+
+
+/**
+ * Calculate the hardware state for the specified texture combine mode
+ *
+ * \bug
+ * All forms of DOT3 bumpmapping are completely untested, and are most
+ * likely wrong. KW: Looks like it will never be quite right as the
+ * hardware seems to experience overflow in color calculation at the
+ * 4x shift levels, which need to be programed for DOT3. Maybe newer
+ * hardware fixes these issues.
+ *
+ * \bug
+ * KW: needs attention to the case where texunit 1 is enabled but
+ * texunit 0 is not.
+ */
+GLboolean
+viaTexCombineState( struct via_context *vmesa,
+ const struct gl_tex_env_combine_state * combine,
+ unsigned unit )
+{
+ unsigned color_arg[3];
+ unsigned alpha_arg[3];
+ unsigned bias_alpha_arg[3];
+ unsigned color = HC_HTXnTBLCsat_MASK;
+ unsigned alpha = HC_HTXnTBLAsat_MASK;
+ unsigned bias = 0;
+ unsigned op = 0;
+ unsigned a_shift = combine->ScaleShiftA;
+ unsigned c_shift = combine->ScaleShiftRGB;
+ unsigned i;
+ unsigned constant_color[3];
+ unsigned ordered_constant_color[4];
+ unsigned constant_alpha[3];
+ unsigned bias_alpha = 0;
+ unsigned abc_alpha = 0;
+ const struct gl_texture_unit * texUnit =
+ &vmesa->glCtx->Texture.Unit[unit];
+ unsigned env_color[4];
+
+ /* It seems that the color clamping can be overwhelmed at the 4x
+ * scale settings, necessitating this fallback:
+ */
+ if (c_shift == 2 || a_shift == 2) {
+ return GL_FALSE;
+ }
+
+ CLAMPED_FLOAT_TO_UBYTE(env_color[0], texUnit->EnvColor[0]);
+ CLAMPED_FLOAT_TO_UBYTE(env_color[1], texUnit->EnvColor[1]);
+ CLAMPED_FLOAT_TO_UBYTE(env_color[2], texUnit->EnvColor[2]);
+ CLAMPED_FLOAT_TO_UBYTE(env_color[3], texUnit->EnvColor[3]);
+
+ (void) memset( constant_color, 0, sizeof( constant_color ) );
+ (void) memset( ordered_constant_color, 0, sizeof( ordered_constant_color ) );
+ (void) memset( constant_alpha, 0, sizeof( constant_alpha ) );
+
+ for ( i = 0 ; i < combine->_NumArgsRGB ; i++ ) {
+ const GLint op = combine->OperandRGB[i] - GL_SRC_COLOR;
+
+ switch ( combine->SourceRGB[i] ) {
+ case GL_TEXTURE:
+ color_arg[i] = HC_XTC_Tex;
+ color_arg[i] += color_operand_modifier[op];
+ break;
+ case GL_CONSTANT:
+ color_arg[i] = HC_XTC_HTXnTBLRC;
+
+ switch( op ) {
+ case 0: /* GL_SRC_COLOR */
+ constant_color[i] = ((env_color[0] << 16) |
+ (env_color[1] << 8) |
+ env_color[2]);
+ break;
+ case 1: /* GL_ONE_MINUS_SRC_COLOR */
+ constant_color[i] = ~((env_color[0] << 16) |
+ (env_color[1] << 8) |
+ env_color[2]) & 0x00ffffff;
+ break;
+ case 2: /* GL_SRC_ALPHA */
+ constant_color[i] = ((env_color[3] << 16) |
+ (env_color[3] << 8) |
+ env_color[3]);
+ break;
+ case 3: /* GL_ONE_MINUS_SRC_ALPHA */
+ constant_color[i] = ~((env_color[3] << 16) |
+ (env_color[3] << 8) |
+ env_color[3]) & 0x00ffffff;
+ break;
+ }
+ break;
+ case GL_PRIMARY_COLOR:
+ color_arg[i] = HC_XTC_Dif;
+ color_arg[i] += color_operand_modifier[op];
+ break;
+ case GL_PREVIOUS:
+ color_arg[i] = (unit == 0) ? HC_XTC_Dif : HC_XTC_Cur;
+ color_arg[i] += color_operand_modifier[op];
+ break;
+ }
+ }
+
+
+ /* On the Unichrome, all combine operations take on some form of:
+ *
+ * (xA * (xB op xC) + xBias) << xShift
+ *
+ * 'op' can be selected as add, subtract, min, max, or mask. The min, max
+ * and mask modes are currently unused. With the exception of DOT3, all
+ * standard GL_COMBINE modes can be implemented simply by selecting the
+ * correct inputs for A, B, C, and Bias and the correct operation for op.
+ *
+ * NOTE: xBias (when read from the constant registers) is signed,
+ * and scaled to fit -255..255 in 8 bits, ie 0x1 == 2.
+ */
+
+ switch( combine->ModeRGB ) {
+ /* Ca = 1.0, Cb = arg0, Cc = 0, Cbias = 0
+ */
+ case GL_REPLACE:
+ color |= ((CONST_ONE << INPUT_A_SHIFT) |
+ (color_arg[0] << INPUT_B_SHIFT));
+
+ ordered_constant_color[1] = constant_color[0];
+ break;
+
+ /* Ca = arg[0], Cb = arg[1], Cc = 0, Cbias = 0
+ */
+ case GL_MODULATE:
+ color |= ((color_arg[0] << INPUT_A_SHIFT) |
+ (color_arg[1] << INPUT_B_SHIFT));
+
+ ordered_constant_color[0] = constant_color[0];
+ ordered_constant_color[1] = constant_color[1];
+ break;
+
+ /* Ca = 1.0, Cb = arg[0], Cc = arg[1], Cbias = 0
+ */
+ case GL_ADD:
+ case GL_SUBTRACT:
+ if ( combine->ModeRGB == GL_SUBTRACT ) {
+ op |= HC_HTXnTBLCop_Sub;
+ }
+
+ color |= ((CONST_ONE << INPUT_A_SHIFT) |
+ (color_arg[0] << INPUT_B_SHIFT) |
+ (color_arg[1] << INPUT_C_SHIFT));
+
+ ordered_constant_color[1] = constant_color[0];
+ ordered_constant_color[2] = constant_color[1];
+ break;
+
+ /* Ca = 1.0, Cb = arg[0], Cc = arg[1], Cbias = -0.5
+ */
+ case GL_ADD_SIGNED:
+ color |= ((CONST_ONE << INPUT_A_SHIFT) |
+ (color_arg[0] << INPUT_B_SHIFT) |
+ (color_arg[1] << INPUT_C_SHIFT));
+
+ bias |= HC_HTXnTBLCbias_HTXnTBLRC;
+
+ ordered_constant_color[1] = constant_color[0];
+ ordered_constant_color[2] = constant_color[1];
+ ordered_constant_color[3] = 0x00bfbfbf; /* -.5 */
+ break;
+
+ /* Ca = arg[2], Cb = arg[0], Cc = arg[1], Cbias = arg[1]
+ */
+ case GL_INTERPOLATE:
+ op |= HC_HTXnTBLCop_Sub;
+
+ color |= ((color_arg[2] << INPUT_A_SHIFT) |
+ (color_arg[0] << INPUT_B_SHIFT) |
+ (color_arg[1] << INPUT_C_SHIFT));
+
+ bias |= (color_arg[1] << INPUT_CBias_SHIFT);
+
+ ordered_constant_color[0] = constant_color[2];
+ ordered_constant_color[1] = constant_color[0];
+ ordered_constant_color[2] = constant_color[1];
+ ordered_constant_color[3] = (constant_color[1] >> 1) & 0x7f7f7f;
+ break;
+
+#if 0
+ /* At this point this code is completely untested. It appears that the
+ * Unichrome has the same limitation as the Radeon R100. The only
+ * supported post-scale when doing DOT3 bumpmapping is 1x.
+ */
+ case GL_DOT3_RGB_EXT:
+ case GL_DOT3_RGBA_EXT:
+ case GL_DOT3_RGB:
+ case GL_DOT3_RGBA:
+ c_shift = 2;
+ a_shift = 2;
+ color |= ((color_arg[0] << INPUT_A_SHIFT) |
+ (color_arg[1] << INPUT_B_SHIFT));
+ op |= HC_HTXnTBLDOT4;
+ break;
+#endif
+
+ default:
+ assert(0);
+ break;
+ }
+
+
+
+
+ /* The alpha blend stage has the annoying quirk of not having a
+ * hard-wired 0 input, like the color stage. As a result, we have
+ * to program the constant register with 0 and use that as our
+ * 0 input.
+ *
+ * (xA * (xB op xC) + xBias) << xShift
+ *
+ */
+
+ for ( i = 0 ; i < combine->_NumArgsA ; i++ ) {
+ const GLint op = combine->OperandA[i] - GL_SRC_ALPHA;
+
+ switch ( combine->SourceA[i] ) {
+ case GL_TEXTURE:
+ alpha_arg[i] = HC_XTA_Atex;
+ alpha_arg[i] += alpha_operand_modifier[op];
+ bias_alpha_arg[i] = HC_HTXnTBLAbias_Atex;
+ bias_alpha_arg[i] += bias_alpha_operand_modifier[op];
+ break;
+ case GL_CONSTANT:
+ alpha_arg[i] = HC_XTA_HTXnTBLRA;
+ bias_alpha_arg[i] = HC_HTXnTBLAbias_HTXnTBLRAbias;
+ constant_alpha[i] = (op == 0) ? env_color[3] : (~env_color[3] & 0xff);
+ break;
+ case GL_PRIMARY_COLOR:
+ alpha_arg[i] = HC_XTA_Adif;
+ alpha_arg[i] += alpha_operand_modifier[op];
+ bias_alpha_arg[i] = HC_HTXnTBLAbias_Adif;
+ bias_alpha_arg[i] += bias_alpha_operand_modifier[op];
+ break;
+ case GL_PREVIOUS:
+ alpha_arg[i] = (unit == 0) ? HC_XTA_Adif : HC_XTA_Acur;
+ alpha_arg[i] += alpha_operand_modifier[op];
+ bias_alpha_arg[i] = (unit == 0 ?
+ HC_HTXnTBLAbias_Adif :
+ HC_HTXnTBLAbias_Acur);
+ bias_alpha_arg[i] += bias_alpha_operand_modifier[op];
+ break;
+ }
+ }
+
+ switch( combine->ModeA ) {
+ /* Aa = 0, Ab = 0, Ac = 0, Abias = arg0
+ */
+ case GL_REPLACE:
+ alpha |= ((HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
+ (HC_XTA_HTXnTBLRA << INPUT_B_SHIFT) |
+ (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT));
+ abc_alpha = 0;
+
+ bias |= bias_alpha_arg[0];
+ bias_alpha = constant_alpha[0] >> 1;
+ break;
+
+ /* Aa = arg[0], Ab = arg[1], Ac = 0, Abias = 0
+ */
+ case GL_MODULATE:
+ alpha |= ((alpha_arg[1] << INPUT_A_SHIFT) |
+ (alpha_arg[0] << INPUT_B_SHIFT) |
+ (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT));
+
+ abc_alpha = ((constant_alpha[1] << HC_HTXnTBLRAa_SHIFT) |
+ (constant_alpha[0] << HC_HTXnTBLRAb_SHIFT) |
+ (0 << HC_HTXnTBLRAc_SHIFT));
+
+ bias |= HC_HTXnTBLAbias_HTXnTBLRAbias;
+ bias_alpha = 0;
+ break;
+
+ /* Aa = 1.0, Ab = arg[0], Ac = arg[1], Abias = 0
+ */
+ case GL_ADD:
+ case GL_SUBTRACT:
+ if ( combine->ModeA == GL_SUBTRACT ) {
+ op |= HC_HTXnTBLAop_Sub;
+ }
+
+ alpha |= ((HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
+ (alpha_arg[0] << INPUT_B_SHIFT) |
+ (alpha_arg[1] << INPUT_C_SHIFT));
+
+ abc_alpha = ((0xff << HC_HTXnTBLRAa_SHIFT) |
+ (constant_alpha[0] << HC_HTXnTBLRAb_SHIFT) |
+ (constant_alpha[1] << HC_HTXnTBLRAc_SHIFT));
+
+ bias |= HC_HTXnTBLAbias_HTXnTBLRAbias;
+ bias_alpha = 0;
+ break;
+
+ /* Aa = 1.0, Ab = arg[0], Ac = arg[1], Abias = -0.5
+ */
+ case GL_ADD_SIGNED:
+ alpha |= ((HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
+ (alpha_arg[0] << INPUT_B_SHIFT) |
+ (alpha_arg[1] << INPUT_C_SHIFT));
+ abc_alpha = ((0xff << HC_HTXnTBLRAa_SHIFT) |
+ (constant_alpha[0] << HC_HTXnTBLRAb_SHIFT) |
+ (constant_alpha[1] << HC_HTXnTBLRAc_SHIFT));
+
+ bias |= HC_HTXnTBLAbias_HTXnTBLRAbias;
+ bias_alpha = 0xbf;
+ break;
+
+ /* Aa = arg[2], Ab = arg[0], Ac = arg[1], Abias = arg[1]
+ */
+ case GL_INTERPOLATE:
+ op |= HC_HTXnTBLAop_Sub;
+
+ alpha |= ((alpha_arg[2] << INPUT_A_SHIFT) |
+ (alpha_arg[0] << INPUT_B_SHIFT) |
+ (alpha_arg[1] << INPUT_C_SHIFT));
+ abc_alpha = ((constant_alpha[2] << HC_HTXnTBLRAa_SHIFT) |
+ (constant_alpha[0] << HC_HTXnTBLRAb_SHIFT) |
+ (constant_alpha[1] << HC_HTXnTBLRAc_SHIFT));
+
+ bias |= bias_alpha_arg[1];
+ bias_alpha = constant_alpha[1] >> 1;
+ break;
+ }
+
+
+ op |= c_shift_table[ c_shift ] | a_shift_table[ a_shift ];
+
+
+ vmesa->regHTXnTBLMPfog[unit] = HC_HTXnTBLMPfog_Fog;
+
+ vmesa->regHTXnTBLCsat[unit] = color;
+ vmesa->regHTXnTBLAsat[unit] = alpha;
+ vmesa->regHTXnTBLCop[unit] = op | bias;
+ vmesa->regHTXnTBLRAa[unit] = abc_alpha;
+ vmesa->regHTXnTBLRFog[unit] = bias_alpha;
+
+ vmesa->regHTXnTBLRCa[unit] = ordered_constant_color[0];
+ vmesa->regHTXnTBLRCb[unit] = ordered_constant_color[1];
+ vmesa->regHTXnTBLRCc[unit] = ordered_constant_color[2];
+ vmesa->regHTXnTBLRCbias[unit] = ordered_constant_color[3];
+
+ return GL_TRUE;
+}
+
diff --git a/src/via_tris.c b/src/via_tris.c
new file mode 100644
index 0000000..b97dacd
--- /dev/null
+++ b/src/via_tris.c
@@ -0,0 +1,1194 @@
+/*
+ * 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 "enums.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_span.h"
+#include "via_ioctl.h"
+#include "via_3d_reg.h"
+#include "via_tex.h"
+
+/***********************************************************************
+ * Emit primitives as inline vertices *
+ ***********************************************************************/
+#define LINE_FALLBACK (0)
+#define POINT_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)
+
+
+#if 0
+#define COPY_DWORDS(vb, vertsize, v) \
+do { \
+ via_sse_memcpy(vb, v, vertsize * 4); \
+ vb += vertsize; \
+} while (0)
+#else
+#if defined( USE_X86_ASM )
+#define COPY_DWORDS(vb, vertsize, v) \
+ do { \
+ int j; \
+ 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(vb, vertsize, v) \
+ do { \
+ int j; \
+ for (j = 0; j < vertsize; j++) \
+ vb[j] = ((GLuint *)v)[j]; \
+ vb += vertsize; \
+ } while (0)
+#endif
+#endif
+
+static void via_draw_triangle(struct via_context *vmesa,
+ viaVertexPtr v0,
+ viaVertexPtr v1,
+ viaVertexPtr v2)
+{
+ GLuint vertsize = vmesa->vertexSize;
+ GLuint *vb = viaExtendPrimitive(vmesa, 3 * 4 * vertsize);
+
+ COPY_DWORDS(vb, vertsize, v0);
+ COPY_DWORDS(vb, vertsize, v1);
+ COPY_DWORDS(vb, vertsize, v2);
+}
+
+
+static void via_draw_quad(struct via_context *vmesa,
+ viaVertexPtr v0,
+ viaVertexPtr v1,
+ viaVertexPtr v2,
+ viaVertexPtr v3)
+{
+ GLuint vertsize = vmesa->vertexSize;
+ GLuint *vb = viaExtendPrimitive(vmesa, 6 * 4 * vertsize);
+
+ COPY_DWORDS(vb, vertsize, v0);
+ COPY_DWORDS(vb, vertsize, v1);
+ COPY_DWORDS(vb, vertsize, v3);
+ COPY_DWORDS(vb, vertsize, v1);
+ COPY_DWORDS(vb, vertsize, v2);
+ COPY_DWORDS(vb, vertsize, v3);
+}
+
+static void via_draw_line(struct via_context *vmesa,
+ viaVertexPtr v0,
+ viaVertexPtr v1)
+{
+ GLuint vertsize = vmesa->vertexSize;
+ GLuint *vb = viaExtendPrimitive(vmesa, 2 * 4 * vertsize);
+ COPY_DWORDS(vb, vertsize, v0);
+ COPY_DWORDS(vb, vertsize, v1);
+}
+
+
+static void via_draw_point(struct via_context *vmesa,
+ viaVertexPtr v0)
+{
+ GLuint vertsize = vmesa->vertexSize;
+ GLuint *vb = viaExtendPrimitive(vmesa, 4 * vertsize);
+ COPY_DWORDS(vb, vertsize, v0);
+}
+
+
+/* Fallback drawing functions for the ptex hack.
+ */
+#define PTEX_VERTEX( tmp, vertex_size, v) \
+do { \
+ GLuint j; \
+ GLfloat rhw = 1.0 / v->f[vertex_size]; \
+ for ( j = 0 ; j < vertex_size ; j++ ) \
+ tmp.f[j] = v->f[j]; \
+ tmp.f[3] *= v->f[vertex_size]; \
+ tmp.f[vertex_size-2] *= rhw; \
+ tmp.f[vertex_size-1] *= rhw; \
+} while (0)
+
+static void via_ptex_tri (struct via_context *vmesa,
+ viaVertexPtr v0,
+ viaVertexPtr v1,
+ viaVertexPtr v2)
+{
+ GLuint vertsize = vmesa->hwVertexSize;
+ GLuint *vb = viaExtendPrimitive(vmesa, 3*4*vertsize);
+ viaVertex tmp;
+
+ PTEX_VERTEX(tmp, vertsize, v0); COPY_DWORDS(vb, vertsize, &tmp);
+ PTEX_VERTEX(tmp, vertsize, v1); COPY_DWORDS(vb, vertsize, &tmp);
+ PTEX_VERTEX(tmp, vertsize, v2); COPY_DWORDS(vb, vertsize, &tmp);
+}
+
+static void via_ptex_line (struct via_context *vmesa,
+ viaVertexPtr v0,
+ viaVertexPtr v1)
+{
+ GLuint vertsize = vmesa->hwVertexSize;
+ GLuint *vb = viaExtendPrimitive(vmesa, 2*4*vertsize);
+ viaVertex tmp;
+
+ PTEX_VERTEX(tmp, vertsize, v0); COPY_DWORDS(vb, vertsize, &tmp);
+ PTEX_VERTEX(tmp, vertsize, v1); COPY_DWORDS(vb, vertsize, &tmp);
+}
+
+static void via_ptex_point (struct via_context *vmesa,
+ viaVertexPtr v0)
+{
+ GLuint vertsize = vmesa->hwVertexSize;
+ GLuint *vb = viaExtendPrimitive(vmesa, 1*4*vertsize);
+ viaVertex tmp;
+
+ PTEX_VERTEX(tmp, vertsize, v0); COPY_DWORDS(vb, vertsize, &tmp);
+}
+
+
+
+
+
+/***********************************************************************
+ * Macros for via_dd_tritmp.h to draw basic primitives *
+ ***********************************************************************/
+
+#define TRI(a, b, c) \
+ do { \
+ 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 (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 (DO_FALLBACK) \
+ vmesa->drawLine(vmesa, v0, v1); \
+ else \
+ via_draw_line(vmesa, v0, v1); \
+ } while (0)
+
+#define POINT(v0) \
+ do { \
+ 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 {
+ tnl_points_func points;
+ tnl_line_func line;
+ tnl_triangle_func triangle;
+ tnl_quad_func quad;
+} rast_tab[VIA_MAX_TRIFUNC + 1];
+
+
+#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 vmesa->polygon_offset_scale
+#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->vertexSize * sizeof(int)))
+
+#define VERT_SET_RGBA( v, c ) \
+do { \
+ via_color_t *color = (via_color_t *)&((v)->ui[coloroffset]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
+} while (0)
+
+#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
+
+#define VERT_SET_SPEC( v, c ) \
+do { \
+ if (specoffset) { \
+ via_color_t *color = (via_color_t *)&((v)->ui[specoffset]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
+ } \
+} while (0)
+#define VERT_COPY_SPEC( v0, v1 ) \
+do { \
+ if (specoffset) { \
+ v0->ub4[specoffset][0] = v1->ub4[specoffset][0]; \
+ v0->ub4[specoffset][1] = v1->ub4[specoffset][1]; \
+ v0->ub4[specoffset][2] = v1->ub4[specoffset][2]; \
+ } \
+} while (0)
+
+
+#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
+#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
+#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
+#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
+
+
+#define LOCAL_VARS(n) \
+ struct via_context *vmesa = VIA_CONTEXT(ctx); \
+ GLuint color[n], spec[n]; \
+ GLuint coloroffset = vmesa->coloroffset; \
+ GLuint specoffset = vmesa->specoffset; \
+ (void)color; (void)spec; (void)coloroffset; (void)specoffset;
+
+
+/***********************************************************************
+ * Helpers for rendering unfilled primitives *
+ ***********************************************************************/
+
+static const GLenum hwPrim[GL_POLYGON + 2] = {
+ GL_POINTS,
+ GL_LINES,
+ GL_LINES,
+ GL_LINES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_POLYGON+1
+};
+
+
+#define RASTERIZE(x) viaRasterPrimitive( ctx, x, hwPrim[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 "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_UNFILLED_BIT)
+#define TAG(x) x##_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT)
+#define TAG(x) x##_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT)
+#define TAG(x) x##_twoside_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_FALLBACK_BIT)
+#define TAG(x) x##_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_OFFSET_BIT|VIA_FALLBACK_BIT)
+#define TAG(x) x##_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT|VIA_FALLBACK_BIT)
+#define TAG(x) x##_twoside_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
+#define TAG(x) x##_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
+#define TAG(x) x##_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
+#define TAG(x) x##_twoside_unfilled_fallback
+#include "tnl_dd/t_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 "tnl_dd/t_dd_tritmp.h"
+
+
+/* Catchall case for flat, separate specular triangles (via has flat
+ * diffuse shading, but always does specular color with gouraud).
+ */
+#undef DO_FALLBACK
+#undef DO_OFFSET
+#undef DO_UNFILLED
+#undef DO_TWOSIDE
+#undef DO_FLAT
+#define DO_FALLBACK (0)
+#define DO_OFFSET (ctx->_TriangleCaps & DD_TRI_OFFSET)
+#define DO_UNFILLED (ctx->_TriangleCaps & DD_TRI_UNFILLED)
+#define DO_TWOSIDE (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE)
+#define DO_FLAT 1
+#define TAG(x) x##_flat_specular
+#define IND VIA_MAX_TRIFUNC
+#include "tnl_dd/t_dd_tritmp.h"
+
+
+static void init_rast_tab(void)
+{
+ init();
+ init_offset();
+ init_twoside();
+ init_twoside_offset();
+ init_unfilled();
+ init_offset_unfilled();
+ init_twoside_unfilled();
+ init_twoside_offset_unfilled();
+ init_fallback();
+ init_offset_fallback();
+ init_twoside_fallback();
+ init_twoside_offset_fallback();
+ init_unfilled_fallback();
+ init_offset_unfilled_fallback();
+ init_twoside_unfilled_fallback();
+ init_twoside_offset_unfilled_fallback();
+
+ init_flat_specular(); /* special! */
+}
+
+
+/***********************************************************************
+ * 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(struct via_context *vmesa,
+ viaVertex *v0,
+ viaVertex *v1,
+ viaVertex *v2)
+{
+ GLcontext *ctx = vmesa->glCtx;
+ SWvertex v[3];
+ _swsetup_Translate(ctx, v0, &v[0]);
+ _swsetup_Translate(ctx, v1, &v[1]);
+ _swsetup_Translate(ctx, v2, &v[2]);
+ viaSpanRenderStart( ctx );
+ _swrast_Triangle(ctx, &v[0], &v[1], &v[2]);
+ viaSpanRenderFinish( ctx );
+}
+
+
+static void
+via_fallback_line(struct via_context *vmesa,
+ viaVertex *v0,
+ viaVertex *v1)
+{
+ GLcontext *ctx = vmesa->glCtx;
+ SWvertex v[2];
+ _swsetup_Translate(ctx, v0, &v[0]);
+ _swsetup_Translate(ctx, v1, &v[1]);
+ viaSpanRenderStart( ctx );
+ _swrast_Line(ctx, &v[0], &v[1]);
+ viaSpanRenderFinish( ctx );
+}
+
+
+static void
+via_fallback_point(struct via_context *vmesa,
+ viaVertex *v0)
+{
+ GLcontext *ctx = vmesa->glCtx;
+ SWvertex v[1];
+ _swsetup_Translate(ctx, v0, &v[0]);
+ viaSpanRenderStart( ctx );
+ _swrast_Point(ctx, &v[0]);
+ viaSpanRenderFinish( ctx );
+}
+
+static void viaResetLineStipple( GLcontext *ctx )
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ vmesa->regCmdB |= HC_HLPrst_MASK;
+}
+
+/**********************************************************************/
+/* Render unclipped begin/end objects */
+/**********************************************************************/
+#define IND 0
+#define V(x) (viaVertex *)(vertptr + ((x) * vertsize * sizeof(int)))
+#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) 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, hwPrim[x])
+#undef LOCAL_VARS
+#define LOCAL_VARS \
+ struct via_context *vmesa = VIA_CONTEXT(ctx); \
+ GLubyte *vertptr = (GLubyte *)vmesa->verts; \
+ const GLuint vertsize = vmesa->vertexSize; \
+ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
+ const GLboolean stipple = ctx->Line.StippleFlag; \
+ (void) elt; (void) stipple;
+#define RESET_STIPPLE if ( stipple ) viaResetLineStipple( ctx );
+#define RESET_OCCLUSION
+#define PRESERVE_VB_DEFS
+#define ELT(x) x
+#define TAG(x) via_##x##_verts
+#include "tnl/t_vb_rendertmp.h"
+#undef ELT
+#undef TAG
+#define TAG(x) via_##x##_elts
+#define ELT(x) elt[x]
+#include "tnl/t_vb_rendertmp.h"
+#undef ELT
+#undef TAG
+#undef NEED_EDGEFLAG_SETUP
+#undef EDGEFLAG_GET
+#undef EDGEFLAG_SET
+#undef RESET_OCCLUSION
+
+
+/**********************************************************************/
+/* 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;
+ GLuint prim = VIA_CONTEXT(ctx)->renderPrimitive;
+
+ /* Render the new vertices as an unclipped polygon.
+ */
+ {
+ GLuint *tmp = VB->Elts;
+ VB->Elts = (GLuint *)elts;
+ tnl->Driver.Render.PrimTabElts[GL_POLYGON](ctx, 0, n,
+ PRIM_BEGIN|PRIM_END);
+ VB->Elts = tmp;
+ }
+
+ /* Restore the render primitive
+ */
+ if (prim != GL_POLYGON &&
+ prim != GL_POLYGON + 1)
+ tnl->Driver.Render.PrimitiveNotify( ctx, prim );
+}
+
+static void viaRenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj)
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ tnl->Driver.Render.Line(ctx, ii, jj);
+}
+
+static void viaFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
+ GLuint n)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ GLuint vertsize = vmesa->vertexSize;
+ GLuint *vb = viaExtendPrimitive(vmesa, (n - 2) * 3 * 4 * vertsize);
+ GLubyte *vertptr = (GLubyte *)vmesa->verts;
+ const GLuint *start = (const GLuint *)V(elts[0]);
+ int i;
+
+ for (i = 2; i < n; i++) {
+ COPY_DWORDS(vb, vertsize, V(elts[i - 1]));
+ COPY_DWORDS(vb, vertsize, V(elts[i]));
+ COPY_DWORDS(vb, vertsize, start);
+ }
+}
+
+
+/**********************************************************************/
+/* Choose render functions */
+/**********************************************************************/
+
+
+#define _VIA_NEW_VERTEX (_NEW_TEXTURE | \
+ _DD_NEW_SEPARATE_SPECULAR | \
+ _DD_NEW_TRI_UNFILLED | \
+ _DD_NEW_TRI_LIGHT_TWOSIDE | \
+ _NEW_FOG)
+
+#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)
+
+
+static void viaChooseRenderState(GLcontext *ctx)
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ GLuint flags = ctx->_TriangleCaps;
+ GLuint index = 0;
+
+ if (vmesa->ptexHack) {
+ vmesa->drawPoint = via_ptex_point;
+ vmesa->drawLine = via_ptex_line;
+ vmesa->drawTri = via_ptex_tri;
+ index |= VIA_FALLBACK_BIT;
+ }
+ else {
+ vmesa->drawPoint = via_draw_point;
+ vmesa->drawLine = via_draw_line;
+ vmesa->drawTri = via_draw_triangle;
+ }
+
+ if (flags & (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS)) {
+ if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
+ index |= VIA_TWOSIDE_BIT;
+ if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL)
+ index |= VIA_UNFILLED_BIT;
+ if (flags & DD_TRI_OFFSET)
+ index |= VIA_OFFSET_BIT;
+ if (flags & ANY_FALLBACK_FLAGS)
+ index |= VIA_FALLBACK_BIT;
+
+ /* Hook in fallbacks for specific primitives. */
+ 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;
+ }
+
+ if ((flags & DD_SEPARATE_SPECULAR) && ctx->Light.ShadeModel == GL_FLAT)
+ index = VIA_MAX_TRIFUNC; /* flat specular */
+
+ if (vmesa->renderIndex != index) {
+ vmesa->renderIndex = index;
+
+ tnl->Driver.Render.Points = rast_tab[index].points;
+ tnl->Driver.Render.Line = rast_tab[index].line;
+ tnl->Driver.Render.Triangle = rast_tab[index].triangle;
+ tnl->Driver.Render.Quad = rast_tab[index].quad;
+
+ if (index == 0) {
+ tnl->Driver.Render.PrimTabVerts = via_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = via_render_tab_elts;
+ tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
+ tnl->Driver.Render.ClippedPolygon = viaFastRenderClippedPoly;
+ }
+ else {
+ tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+ tnl->Driver.Render.ClippedLine = viaRenderClippedLine;
+ tnl->Driver.Render.ClippedPolygon = viaRenderClippedPoly;
+ }
+ }
+}
+
+
+#define VIA_EMIT_TEX1 0x01
+#define VIA_EMIT_TEX0 0x02
+#define VIA_EMIT_PTEX0 0x04
+#define VIA_EMIT_RGBA 0x08
+#define VIA_EMIT_SPEC 0x10
+#define VIA_EMIT_FOG 0x20
+#define VIA_EMIT_W 0x40
+
+#define EMIT_ATTR( ATTR, STYLE, INDEX, REGB ) \
+do { \
+ vmesa->vertex_attrs[vmesa->vertex_attr_count].attrib = (ATTR); \
+ vmesa->vertex_attrs[vmesa->vertex_attr_count].format = (STYLE); \
+ vmesa->vertex_attr_count++; \
+ setupIndex |= (INDEX); \
+ regCmdB |= (REGB); \
+} while (0)
+
+#define EMIT_PAD( N ) \
+do { \
+ vmesa->vertex_attrs[vmesa->vertex_attr_count].attrib = 0; \
+ vmesa->vertex_attrs[vmesa->vertex_attr_count].format = EMIT_PAD; \
+ vmesa->vertex_attrs[vmesa->vertex_attr_count].offset = (N); \
+ vmesa->vertex_attr_count++; \
+} while (0)
+
+
+
+static void viaChooseVertexState( GLcontext *ctx )
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ DECLARE_RENDERINPUTS(index_bitset);
+ GLuint regCmdB = HC_HVPMSK_X | HC_HVPMSK_Y | HC_HVPMSK_Z;
+ GLuint setupIndex = 0;
+
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
+ vmesa->vertex_attr_count = 0;
+
+ /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
+ * build up a hardware vertex.
+ */
+ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX ) ||
+ RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
+ EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VIA_EMIT_W, HC_HVPMSK_W );
+ vmesa->coloroffset = 4;
+ }
+ else {
+ EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 );
+ vmesa->coloroffset = 3;
+ }
+
+ /* t_context.c always includes a diffuse color */
+ EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VIA_EMIT_RGBA,
+ HC_HVPMSK_Cd );
+
+ vmesa->specoffset = 0;
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
+ RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
+ vmesa->specoffset = vmesa->coloroffset + 1;
+ EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VIA_EMIT_SPEC,
+ HC_HVPMSK_Cs );
+ }
+ else
+ EMIT_PAD( 3 );
+
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
+ EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, VIA_EMIT_FOG, HC_HVPMSK_Cs );
+ else
+ EMIT_PAD( 1 );
+ }
+
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) {
+ if (vmesa->ptexHack)
+ EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, VIA_EMIT_PTEX0,
+ (HC_HVPMSK_S | HC_HVPMSK_T) );
+ else
+ EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, VIA_EMIT_TEX0,
+ (HC_HVPMSK_S | HC_HVPMSK_T) );
+ }
+
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) {
+ EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, VIA_EMIT_TEX1,
+ (HC_HVPMSK_S | HC_HVPMSK_T) );
+ }
+
+ if (setupIndex != vmesa->setupIndex) {
+ vmesa->vertexSize = _tnl_install_attrs( ctx,
+ vmesa->vertex_attrs,
+ vmesa->vertex_attr_count,
+ vmesa->ViewportMatrix.m, 0 );
+ vmesa->vertexSize >>= 2;
+ vmesa->setupIndex = setupIndex;
+ vmesa->regCmdB &= ~HC_HVPMSK_MASK;
+ vmesa->regCmdB |= regCmdB;
+
+ if (vmesa->ptexHack)
+ vmesa->hwVertexSize = vmesa->vertexSize - 1;
+ else
+ vmesa->hwVertexSize = vmesa->vertexSize;
+ }
+}
+
+
+
+
+/* Check if projective texture coordinates are used and if we can fake
+ * them. Fallback to swrast if we can't. Returns GL_TRUE if projective
+ * texture coordinates must be faked, GL_FALSE otherwise.
+ */
+static GLboolean viaCheckPTexHack( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ DECLARE_RENDERINPUTS(index_bitset);
+ GLboolean fallback = GL_FALSE;
+ GLboolean ptexHack = GL_FALSE;
+
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
+
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 ) && VB->TexCoordPtr[0]->size == 4) {
+ if (!RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_ATTRIB_TEX1, _TNL_LAST_TEX ))
+ ptexHack = GL_TRUE;
+ else
+ fallback = GL_TRUE;
+ }
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 ) && VB->TexCoordPtr[1]->size == 4)
+ fallback = GL_TRUE;
+
+ FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_PROJ_TEXTURE, fallback);
+ return ptexHack;
+}
+
+
+
+
+/**********************************************************************/
+/* High level hooks for t_vb_render.c */
+/**********************************************************************/
+
+
+static void viaRenderStart(GLcontext *ctx)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+
+ {
+ GLboolean ptexHack = viaCheckPTexHack( ctx );
+ if (ptexHack != vmesa->ptexHack) {
+ vmesa->ptexHack = ptexHack;
+ vmesa->newRenderState |= _VIA_NEW_RENDERSTATE;
+ }
+ }
+
+ if (vmesa->newState) {
+ vmesa->newRenderState |= vmesa->newState;
+ viaValidateState( ctx );
+ }
+
+ if (vmesa->Fallback) {
+ tnl->Driver.Render.Start(ctx);
+ return;
+ }
+
+ if (vmesa->newRenderState) {
+ viaChooseVertexState(ctx);
+ viaChooseRenderState(ctx);
+ vmesa->newRenderState = 0;
+ }
+
+ /* Important:
+ */
+ VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
+}
+
+static void viaRenderFinish(GLcontext *ctx)
+{
+ VIA_FINISH_PRIM(VIA_CONTEXT(ctx));
+}
+
+
+/* System to flush dma and emit state changes based on the rasterized
+ * primitive.
+ */
+void viaRasterPrimitive(GLcontext *ctx,
+ GLenum glprim,
+ GLenum hwprim)
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+ GLuint regCmdB;
+ RING_VARS;
+
+ if (VIA_DEBUG & DEBUG_PRIMS)
+ fprintf(stderr, "%s: %s/%s/%s\n",
+ __FUNCTION__, _mesa_lookup_enum_by_nr(glprim),
+ _mesa_lookup_enum_by_nr(hwprim),
+ _mesa_lookup_enum_by_nr(ctx->Light.ShadeModel));
+
+ assert (!vmesa->newState);
+
+ vmesa->renderPrimitive = glprim;
+
+ if (hwprim != vmesa->hwPrimitive ||
+ ctx->Light.ShadeModel != vmesa->hwShadeModel) {
+
+ VIA_FINISH_PRIM(vmesa);
+
+ /* Ensure no wrapping inside this function */
+ viaCheckDma( vmesa, 1024 );
+
+ if (vmesa->newEmitState) {
+ viaEmitState(vmesa);
+ }
+
+ vmesa->regCmdA_End = HC_ACMD_HCmdA;
+
+ if (ctx->Light.ShadeModel == GL_SMOOTH) {
+ vmesa->regCmdA_End |= HC_HShading_Gouraud;
+ }
+
+ vmesa->hwShadeModel = ctx->Light.ShadeModel;
+ regCmdB = vmesa->regCmdB;
+
+ switch (hwprim) {
+ case GL_POINTS:
+ vmesa->regCmdA_End |= HC_HPMType_Point | HC_HVCycle_Full;
+ vmesa->regCmdA_End |= HC_HShading_Gouraud; /* always Gouraud
+ shade points?!? */
+ break;
+ case GL_LINES:
+ vmesa->regCmdA_End |= HC_HPMType_Line | HC_HVCycle_Full;
+ regCmdB |= HC_HLPrst_MASK;
+ if (ctx->Light.ShadeModel == GL_FLAT)
+ vmesa->regCmdA_End |= HC_HShading_FlatB;
+ break;
+ case GL_LINE_LOOP:
+ case GL_LINE_STRIP:
+ vmesa->regCmdA_End |= 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:
+ vmesa->regCmdA_End |= HC_HPMType_Tri | HC_HVCycle_Full;
+ if (ctx->Light.ShadeModel == GL_FLAT)
+ vmesa->regCmdA_End |= HC_HShading_FlatC;
+ break;
+ case GL_TRIANGLE_STRIP:
+ vmesa->regCmdA_End |= 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_FlatC;
+ break;
+ case GL_TRIANGLE_FAN:
+ vmesa->regCmdA_End |= 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:
+ abort();
+ return;
+ case GL_QUAD_STRIP:
+ abort();
+ return;
+ case GL_POLYGON:
+ vmesa->regCmdA_End |= 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:
+ abort();
+ return;
+ }
+
+/* assert((vmesa->dmaLow & 0x4) == 0); */
+
+ if (vmesa->dmaCliprectAddr == ~0) {
+ if (VIA_DEBUG & DEBUG_DMA)
+ fprintf(stderr, "reserve cliprect space at %x\n", vmesa->dmaLow);
+ vmesa->dmaCliprectAddr = vmesa->dmaLow;
+ BEGIN_RING(8);
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_NotTex << 16) );
+ OUT_RING( 0xCCCCCCCC );
+ OUT_RING( 0xCCCCCCCC );
+ OUT_RING( 0xCCCCCCCC );
+ OUT_RING( 0xCCCCCCCC );
+ OUT_RING( 0xCCCCCCCC );
+ OUT_RING( 0xCCCCCCCC );
+ ADVANCE_RING();
+ }
+
+ assert(vmesa->dmaLastPrim == 0);
+
+ BEGIN_RING(8);
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_NotTex << 16) );
+ OUT_RING( 0xCCCCCCCC );
+ OUT_RING( 0xDDDDDDDD );
+
+ OUT_RING( HC_HEADER2 );
+ OUT_RING( (HC_ParaType_CmdVdata << 16) );
+ OUT_RING( regCmdB );
+ OUT_RING( vmesa->regCmdA_End );
+ ADVANCE_RING();
+
+ vmesa->hwPrimitive = hwprim;
+ vmesa->dmaLastPrim = vmesa->dmaLow;
+ }
+ else {
+ assert(!vmesa->newEmitState);
+ }
+}
+
+/* Callback for mesa:
+ */
+static void viaRenderPrimitive( GLcontext *ctx, GLuint prim )
+{
+ viaRasterPrimitive( ctx, prim, hwPrim[prim] );
+}
+
+
+void viaFinishPrimitive(struct via_context *vmesa)
+{
+ if (VIA_DEBUG & (DEBUG_DMA|DEBUG_PRIMS))
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ if (!vmesa->dmaLastPrim || vmesa->dmaCliprectAddr == ~0) {
+ assert(0);
+ }
+ else if (vmesa->dmaLow != vmesa->dmaLastPrim) {
+ GLuint cmdA = (vmesa->regCmdA_End | HC_HPLEND_MASK |
+ HC_HPMValidN_MASK | HC_HE3Fire_MASK);
+ RING_VARS;
+
+ vmesa->dmaLastPrim = 0;
+
+ /* KW: modified 0x1 to 0x4 below:
+ */
+ if ((vmesa->dmaLow & 0x4) || !vmesa->useAgp) {
+ BEGIN_RING_NOCHECK( 1 );
+ OUT_RING( cmdA );
+ ADVANCE_RING();
+ }
+ else {
+ BEGIN_RING_NOCHECK( 2 );
+ OUT_RING( cmdA );
+ OUT_RING( cmdA );
+ ADVANCE_RING();
+ }
+
+ if (vmesa->dmaLow > VIA_DMA_HIGHWATER)
+ viaFlushDma( vmesa );
+ }
+ else {
+ if (VIA_DEBUG & (DEBUG_DMA|DEBUG_PRIMS))
+ fprintf(stderr, "remove empty primitive\n");
+
+ /* Remove the primitive header:
+ */
+ vmesa->dmaLastPrim = 0;
+ vmesa->dmaLow -= 8 * sizeof(GLuint);
+
+ /* Maybe remove the cliprect as well:
+ */
+ if (vmesa->dmaCliprectAddr == vmesa->dmaLow - 8 * sizeof(GLuint)) {
+ vmesa->dmaLow -= 8 * sizeof(GLuint);
+ vmesa->dmaCliprectAddr = ~0;
+ }
+ }
+
+ vmesa->renderPrimitive = GL_POLYGON + 1;
+ vmesa->hwPrimitive = GL_POLYGON + 1;
+ vmesa->dmaLastPrim = 0;
+}
+
+
+/**********************************************************************/
+/* Transition to/from hardware rasterization. */
+/**********************************************************************/
+
+
+void viaFallback(struct via_context *vmesa, GLuint bit, GLboolean mode)
+{
+ GLcontext *ctx = vmesa->glCtx;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint oldfallback = vmesa->Fallback;
+
+ if (mode) {
+ vmesa->Fallback |= bit;
+ if (oldfallback == 0) {
+ VIA_FLUSH_DMA(vmesa);
+
+ if (VIA_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr, "ENTER FALLBACK %x\n", bit);
+
+ _swsetup_Wakeup(ctx);
+ vmesa->renderIndex = ~0;
+ }
+ }
+ else {
+ vmesa->Fallback &= ~bit;
+ if (oldfallback == bit) {
+ _swrast_flush( ctx );
+
+ if (VIA_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr, "LEAVE FALLBACK %x\n", bit);
+
+ tnl->Driver.Render.Start = viaRenderStart;
+ tnl->Driver.Render.PrimitiveNotify = viaRenderPrimitive;
+ tnl->Driver.Render.Finish = viaRenderFinish;
+
+ tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
+ tnl->Driver.Render.CopyPV = _tnl_copy_pv;
+ tnl->Driver.Render.Interp = _tnl_interp;
+ tnl->Driver.Render.ResetLineStipple = viaResetLineStipple;
+
+ _tnl_invalidate_vertex_state( ctx, ~0 );
+ _tnl_invalidate_vertices( ctx, ~0 );
+ _tnl_install_attrs( ctx,
+ vmesa->vertex_attrs,
+ vmesa->vertex_attr_count,
+ vmesa->ViewportMatrix.m, 0 );
+
+ vmesa->newState |= (_VIA_NEW_RENDERSTATE|_VIA_NEW_VERTEX);
+ }
+ }
+}
+
+static void viaRunPipeline( GLcontext *ctx )
+{
+ struct via_context *vmesa = VIA_CONTEXT(ctx);
+
+ if (vmesa->newState) {
+ vmesa->newRenderState |= vmesa->newState;
+ viaValidateState( ctx );
+ }
+
+ _tnl_run_pipeline( ctx );
+}
+
+
+/**********************************************************************/
+/* Initialization. */
+/**********************************************************************/
+
+
+void viaInitTriFuncs(GLcontext *ctx)
+{
+ struct via_context *vmesa = VIA_CONTEXT(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 = viaResetLineStipple;
+ tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
+ tnl->Driver.Render.CopyPV = _tnl_copy_pv;
+ tnl->Driver.Render.Interp = _tnl_interp;
+
+ _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
+ (6 + 2*ctx->Const.MaxTextureUnits) * sizeof(GLfloat) );
+
+ vmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf;
+
+}
diff --git a/src/via_tris.h b/src/via_tris.h
new file mode 100644
index 0000000..b4f0880
--- /dev/null
+++ b/src/via_tris.h
@@ -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