summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2010-03-11 06:16:30 +0100
committerLuc Verhaegen <libv@skynet.be>2010-03-11 06:16:30 +0100
commit23b56dd30d3ae68fe1bbce089c95ec3fab48c90b (patch)
treee273c21356e53be35e4ad46d70ec9da906bab21b
parent5dee9b7b19c1aa3a13618b08bc24f00677b5364b (diff)
Import sis dri driver from mesa 7.0.3.7.0.47.0.3
-rw-r--r--configure.ac5
-rw-r--r--src/Makefile.am26
-rw-r--r--src/server/sis_common.h63
-rw-r--r--src/server/sis_dri.h85
-rw-r--r--src/sis6326_clear.c229
-rw-r--r--src/sis6326_reg.h408
-rw-r--r--src/sis6326_state.c735
-rw-r--r--src/sis_alloc.c199
-rw-r--r--src/sis_alloc.h44
-rw-r--r--src/sis_clear.c410
-rw-r--r--src/sis_context.c728
-rw-r--r--src/sis_context.h477
-rw-r--r--src/sis_dd.c269
-rw-r--r--src/sis_dd.h39
-rw-r--r--src/sis_fog.c207
-rw-r--r--src/sis_lock.c81
-rw-r--r--src/sis_lock.h87
-rw-r--r--src/sis_reg.h903
-rw-r--r--src/sis_screen.c382
-rw-r--r--src/sis_screen.h62
-rw-r--r--src/sis_span.c194
-rw-r--r--src/sis_span.h46
-rw-r--r--src/sis_state.c866
-rw-r--r--src/sis_state.h69
-rw-r--r--src/sis_stencil.c206
-rw-r--r--src/sis_stencil.h37
-rw-r--r--src/sis_tex.c573
-rw-r--r--src/sis_tex.h38
-rw-r--r--src/sis_texstate.c710
-rw-r--r--src/sis_tris.c1154
-rw-r--r--src/sis_tris.h71
-rw-r--r--src/sis_tritmp.h250
32 files changed, 9646 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac
index 2a78cfd..e05c34a 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-sis], 7.0.3, [], mesa-dri-sis)
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..1b926b2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,23 @@
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 = \
+sis_dri_la_LTLIBRARIES = sis_dri.la
+sis_dri_la_CFLAGS = $(AM_CFLAGS) $(DRM_CFLAGS) $(DRI_CFLAGS) -Iserver
+sis_dri_la_LDFLAGS = -module -noprefix -avoid-version -lm -ldl \
+ $(DRM_LIBS) $(DRI_LIBS)
+sis_dri_ladir = @libdir@/dri
+sis_dri_la_SOURCES = \
+ sis6326_state.c \
+ sis6326_clear.c \
+ sis_alloc.c \
+ sis_clear.c \
+ sis_context.c \
+ sis_dd.c \
+ sis_fog.c \
+ sis_lock.c \
+ sis_screen.c \
+ sis_span.c \
+ sis_state.c \
+ sis_stencil.c \
+ sis_tex.c \
+ sis_texstate.c \
+ sis_tris.c
diff --git a/src/server/sis_common.h b/src/server/sis_common.h
new file mode 100644
index 0000000..cbddf0c
--- /dev/null
+++ b/src/server/sis_common.h
@@ -0,0 +1,63 @@
+/* * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_common.h,v 1.1 2003/08/29 08:52:12 twini Exp $ */
+/*
+ * Common header definitions for SiS 2D/3D/DRM suite
+ *
+ * Copyright (C) 2003 Eric Anholt
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holder makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author:
+ * Eric Anholt <anholt@FreeBSD.org>
+ *
+ */
+
+#ifndef _SIS_COMMON_H_
+#define _SIS_COMMON_H_
+
+#define DRM_SIS_FB_ALLOC 0x04
+#define DRM_SIS_FB_FREE 0x05
+#define DRM_SIS_FLIP 0x08
+#define DRM_SIS_FLIP_INIT 0x09
+#define DRM_SIS_FLIP_FINAL 0x10
+#define DRM_SIS_AGP_INIT 0x13
+#define DRM_SIS_AGP_ALLOC 0x14
+#define DRM_SIS_AGP_FREE 0x15
+#define DRM_SIS_FB_INIT 0x16
+
+typedef struct {
+ int context;
+ unsigned long offset;
+ unsigned long size;
+ void *free;
+} drm_sis_mem_t;
+
+typedef struct {
+ unsigned long offset, size;
+} drm_sis_agp_t;
+
+typedef struct {
+ unsigned long offset, size;
+} drm_sis_fb_t;
+
+typedef struct {
+ unsigned int left, right;
+} drm_sis_flip_t;
+
+#endif /* _SIS_COMMON_H_ */
+
diff --git a/src/server/sis_dri.h b/src/server/sis_dri.h
new file mode 100644
index 0000000..a056624
--- /dev/null
+++ b/src/server/sis_dri.h
@@ -0,0 +1,85 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.h,v 1.9 2003/08/29 08:50:54 twini Exp $ */
+
+/* modified from tdfx_dri.h */
+
+#ifndef _SIS_DRI_
+#define _SIS_DRI_
+
+#include "xf86drm.h"
+#include "drm.h"
+
+#define SIS_MAX_DRAWABLES 256
+#define SISIOMAPSIZE (64*1024)
+
+typedef struct {
+ int CtxOwner;
+ int QueueLength;
+ unsigned int AGPCmdBufNext;
+ unsigned int FrameCount;
+#ifdef SIS315DRI
+ /* For 315 series */
+ unsigned long sharedWPoffset;
+#endif
+#if 0
+ unsigned char *AGPCmdBufBase;
+ unsigned long AGPCmdBufAddr;
+ unsigned long AGPCmdBufOffset;
+ unsigned int AGPCmdBufSize;
+ unsigned long AGPCmdBufNext;
+#endif
+} SISSAREAPriv, *SISSAREAPrivPtr;
+
+#define AGPVtxBufNext AGPCmdBufNext
+
+#define SIS_FRONT 0
+#define SIS_BACK 1
+#define SIS_DEPTH 2
+
+typedef struct {
+ drm_handle_t handle;
+ drmSize size;
+} sisRegion, *sisRegionPtr;
+
+typedef struct {
+ sisRegion regs, agp;
+ int deviceID;
+ int width;
+ int height;
+ int mem; /* unused in Mesa 3 DRI */
+ int bytesPerPixel;
+ int priv1; /* unused in Mesa 3 DRI */
+ int priv2; /* unused in Mesa 3 DRI */
+ int fbOffset; /* unused in Mesa 3 DRI */
+ int backOffset; /* unused in Mesa 3 DRI */
+ int depthOffset; /* unused in Mesa 3 DRI */
+ int textureOffset; /* unused in Mesa 3 DRI */
+ int textureSize; /* unused in Mesa 3 DRI */
+ unsigned int AGPCmdBufOffset;
+ unsigned int AGPCmdBufSize;
+ int irqEnabled; /* unused in Mesa 3 DRI */
+ unsigned int scrnX, scrnY; /* unused in Mesa 3 DRI */
+} SISDRIRec, *SISDRIPtr;
+
+#define AGPVtxBufOffset AGPCmdBufOffset
+#define AGPVtxBufSize AGPCmdBufSize
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} SISConfigPrivRec, *SISConfigPrivPtr;
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} SISDRIContextRec, *SISDRIContextPtr;
+
+#ifdef XFree86Server
+
+#include "screenint.h"
+
+Bool SISDRIScreenInit(ScreenPtr pScreen);
+void SISDRICloseScreen(ScreenPtr pScreen);
+Bool SISDRIFinishScreenInit(ScreenPtr pScreen);
+
+#endif
+#endif
diff --git a/src/sis6326_clear.c b/src/sis6326_clear.c
new file mode 100644
index 0000000..48db195
--- /dev/null
+++ b/src/sis6326_clear.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2005 Eric Anholt
+ * 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, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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 NONINFRINGEMENT. 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.
+ *
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ *
+ */
+
+#include "sis_context.h"
+#include "sis_state.h"
+#include "sis_lock.h"
+#include "sis_reg.h"
+
+#include "swrast/swrast.h"
+#include "macros.h"
+
+static void sis_clear_front_buffer(GLcontext *ctx, GLenum mask, GLint x,
+ GLint y, GLint width, GLint height);
+static void sis_clear_back_buffer(GLcontext *ctx, GLenum mask, GLint x,
+ GLint y, GLint width, GLint height);
+static void sis_clear_z_buffer(GLcontext * ctx, GLbitfield mask, GLint x,
+ GLint y, GLint width, GLint height );
+
+static void
+set_color_pattern( sisContextPtr smesa, GLubyte red, GLubyte green,
+ GLubyte blue, GLubyte alpha )
+{
+ /* XXX only RGB565 and ARGB8888 */
+ switch (smesa->colorFormat)
+ {
+ case DST_FORMAT_ARGB_8888:
+ smesa->clearColorPattern = (alpha << 24) +
+ (red << 16) + (green << 8) + (blue);
+ break;
+ case DST_FORMAT_RGB_565:
+ smesa->clearColorPattern = ((red >> 3) << 11) +
+ ((green >> 2) << 5) + (blue >> 3);
+ smesa->clearColorPattern |= smesa->clearColorPattern << 16;
+ break;
+ default:
+ sis_fatal_error("Bad dst color format\n");
+ }
+}
+
+void
+sis6326UpdateZPattern(sisContextPtr smesa, GLclampd z)
+{
+ CLAMPED_FLOAT_TO_USHORT(smesa->clearZStencilPattern, z * 65535.0);
+}
+
+void
+sis6326DDClear(GLcontext *ctx, GLbitfield mask)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ GLint x1, y1, width1, height1;
+
+ /* get region after locking: */
+ x1 = ctx->DrawBuffer->_Xmin;
+ y1 = ctx->DrawBuffer->_Ymin;
+ width1 = ctx->DrawBuffer->_Xmax - x1;
+ height1 = ctx->DrawBuffer->_Ymax - y1;
+ y1 = Y_FLIP(y1 + height1 - 1);
+
+ /* XXX: Scissoring */
+
+ fprintf(stderr, "Clear\n");
+
+ /* Mask out any non-existent buffers */
+ if (smesa->depth.offset == 0 || !ctx->Depth.Mask)
+ mask &= ~BUFFER_BIT_DEPTH;
+
+ LOCK_HARDWARE();
+
+ if (mask & BUFFER_BIT_FRONT_LEFT) {
+ sis_clear_front_buffer(ctx, mask, x1, y1, width1, height1);
+ mask &= ~BUFFER_BIT_FRONT_LEFT;
+ }
+
+ if (mask & BUFFER_BIT_BACK_LEFT) {
+ sis_clear_back_buffer(ctx, mask, x1, y1, width1, height1);
+ mask &= ~BUFFER_BIT_BACK_LEFT;
+ }
+
+ if (mask & BUFFER_BIT_DEPTH) {
+ sis_clear_z_buffer(ctx, mask, x1, y1, width1, height1);
+ mask &= ~BUFFER_BIT_DEPTH;
+ }
+
+ UNLOCK_HARDWARE();
+
+ if (mask != 0)
+ _swrast_Clear(ctx, mask);
+}
+
+
+void
+sis6326DDClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ GLubyte c[4];
+
+ CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
+
+ set_color_pattern( smesa, c[0], c[1], c[2], c[3] );
+}
+
+void
+sis6326DDClearDepth(GLcontext *ctx, GLclampd d)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ sis6326UpdateZPattern(smesa, d);
+}
+
+static void
+sis_clear_back_buffer(GLcontext *ctx, GLenum mask, GLint x, GLint y,
+ GLint width, GLint height)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ /* XXX: The order of writing these registers seems to matter, while
+ * it actually shouldn't.
+ */
+ mWait3DCmdQueue(6);
+ MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->back.pitch << 16);
+ MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY |
+ smesa->clearColorPattern);
+ MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY |
+ smesa->clearColorPattern);
+ MMIO(REG_6326_BitBlt_DstAddr, smesa->back.offset +
+ (y+height) * smesa->back.pitch +
+ (x+width) * smesa->bytesPerPixel);
+ MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) |
+ (width * smesa->bytesPerPixel));
+ MMIO_WMB();
+ MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG);
+}
+
+static void
+sis_clear_front_buffer(GLcontext *ctx, GLenum mask, GLint x, GLint y,
+ GLint width, GLint height)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ int count;
+ drm_clip_rect_t *pExtents = NULL;
+
+ pExtents = smesa->driDrawable->pClipRects;
+ count = smesa->driDrawable->numClipRects;
+
+ mWait3DCmdQueue(3);
+ MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->front.pitch << 16);
+ MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY |
+ smesa->clearColorPattern);
+ MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY |
+ smesa->clearColorPattern);
+
+ while (count--) {
+ GLint x1 = pExtents->x1 - smesa->driDrawable->x;
+ GLint y1 = pExtents->y1 - smesa->driDrawable->y;
+ GLint x2 = pExtents->x2 - smesa->driDrawable->x;
+ GLint y2 = pExtents->y2 - smesa->driDrawable->y;
+
+ if (x > x1)
+ x1 = x;
+ if (y > y1)
+ y1 = y;
+
+ if (x + width < x2)
+ x2 = x + width;
+ if (y + height < y2)
+ y2 = y + height;
+ width = x2 - x1;
+ height = y2 - y1;
+
+ pExtents++;
+
+ if (width <= 0 || height <= 0)
+ continue;
+
+ mWait3DCmdQueue(3);
+ MMIO(REG_6326_BitBlt_DstAddr, smesa->front.offset +
+ (y2-1) * smesa->front.pitch + x2 * smesa->bytesPerPixel);
+ MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) |
+ (width * smesa->bytesPerPixel));
+ MMIO_WMB();
+ MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG);
+ }
+}
+
+static void
+sis_clear_z_buffer(GLcontext * ctx, GLbitfield mask, GLint x, GLint y,
+ GLint width, GLint height)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ mWait3DCmdQueue(6);
+ MMIO(REG_6326_BitBlt_DstAddr,
+ smesa->depth.offset + y * smesa->depth.pitch + x * 2);
+ MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->depth.pitch << 16);
+ MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) | (width * 2));
+ MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY | smesa->clearZStencilPattern);
+ MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY | smesa->clearZStencilPattern);
+ MMIO_WMB();
+ MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG | BLT_XINC | BLT_YINC);
+}
+
diff --git a/src/sis6326_reg.h b/src/sis6326_reg.h
new file mode 100644
index 0000000..8e645f0
--- /dev/null
+++ b/src/sis6326_reg.h
@@ -0,0 +1,408 @@
+/*
+ * Copyright 2005 Eric Anholt
+ * 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, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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 NONINFRINGEMENT. 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.
+ *
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ *
+ */
+
+#ifndef _sis6326_reg_h_
+#define _sis6326_reg_h_
+
+#define REG_6326_BitBlt_SrcAddr 0x8280
+#define REG_6326_BitBlt_DstAddr 0x8284
+#define REG_6326_BitBlt_DstSrcPitch 0x8288
+#define REG_6326_BitBlt_HeightWidth 0x828c
+#define REG_6326_BitBlt_fgColor 0x8290
+#define REG_6326_BitBlt_bgColor 0x8294
+#define REG_6326_BitBlt_Mask30 0x8298
+#define REG_6326_BitBlt_Mask74 0x829c
+#define REG_6326_BitBlt_ClipTopLeft 0x82a0
+#define REG_6326_BitBlt_ClitBottomRight 0x82a4
+#define REG_6326_BitBlt_Cmd 0x82a8
+#define REG_6326_BitBlt_Pat 0x82ac
+
+#define REG_6326_3D_TSFSa 0x8800
+#define REG_6326_3D_TSZa 0x8804
+#define REG_6326_3D_TSXa 0x8808
+#define REG_6326_3D_TSYa 0x880C
+#define REG_6326_3D_TSARGBa 0x8810
+#define REG_6326_3D_TSUa 0x8814
+#define REG_6326_3D_TSVa 0x8818
+#define REG_6326_3D_TSWa 0x881C
+
+#define REG_6326_3D_TSFSb 0x8820
+#define REG_6326_3D_TSZb 0x8824
+#define REG_6326_3D_TSXb 0x8828
+#define REG_6326_3D_TSYb 0x882C
+#define REG_6326_3D_TSARGBb 0x8830
+#define REG_6326_3D_TSUb 0x8834
+#define REG_6326_3D_TSVb 0x8838
+#define REG_6326_3D_TSWb 0x883C
+
+#define REG_6326_3D_TSFSc 0x8840
+#define REG_6326_3D_TSZc 0x8844
+#define REG_6326_3D_TSXc 0x8848
+#define REG_6326_3D_TSYc 0x884C
+#define REG_6326_3D_TSARGBc 0x8850
+#define REG_6326_3D_TSUc 0x8854
+#define REG_6326_3D_TSVc 0x8858
+#define REG_6326_3D_TSWc 0x885C
+
+#define REG_6326_3D_TEnable 0x8A00
+#define REG_6326_3D_ZSet 0x8A04
+#define REG_6326_3D_ZAddress 0x8A08
+
+#define REG_6326_3D_AlphaSet 0x8A0C
+#define REG_6326_3D_AlphaAddress 0x8A10
+#define REG_6326_3D_DstSet 0x8A14
+#define REG_6326_3D_DstAddress 0x8A18
+#define REG_6326_3D_LinePattern 0x8A1C
+#define REG_6326_3D_FogSet 0x8A20
+
+#define REG_6326_3D_DstSrcBlendMode 0x8A28
+
+#define REG_6326_3D_ClipTopBottom 0x8A30
+#define REG_6326_3D_ClipLeftRight 0x8A34
+
+#define REG_6326_3D_TextureSet 0x8A38
+#define REG_6326_3D_TextureBlendSet 0x8A3C
+/* Low transparency value is in TextureBlendSet */
+#define REG_6326_3D_TextureTransparencyColorHigh 0x8A40
+
+#define REG_6326_3D_TextureAddress0 0x8A44
+#define REG_6326_3D_TextureAddress1 0x8A48
+#define REG_6326_3D_TextureAddress2 0x8A4C
+#define REG_6326_3D_TextureAddress3 0x8A50
+#define REG_6326_3D_TextureAddress4 0x8A54
+#define REG_6326_3D_TextureAddress5 0x8A58
+#define REG_6326_3D_TextureAddress6 0x8A5C
+#define REG_6326_3D_TextureAddress7 0x8A60
+#define REG_6326_3D_TextureAddress8 0x8A64
+#define REG_6326_3D_TextureAddress9 0x8A68
+
+#define REG_6326_3D_TexturePitch01 0x8A6C
+#define REG_6326_3D_TexturePitch23 0x8A70
+#define REG_6326_3D_TexturePitch45 0x8A74
+#define REG_6326_3D_TexturePitch67 0x8A78
+#define REG_6326_3D_TexturePitch89 0x8A7C
+
+#define REG_6326_3D_TextureWidthHeight 0x8A80
+#define REG_6326_3D_TextureBorderColor 0x8A90
+
+#define REG_6326_3D_EndPrimitiveList 0x8Aff
+
+/*
+ * REG_6326_BitBlt_fgColor (0x8290-0x8293)
+ * REG_6326_BitBlt_bgColor (0x8294-0x8297)
+ */
+#define MASK_BltRop 0xff000000
+#define MASK_BltColor 0x00ffffff
+
+#define SiS_ROP_SRCCOPY 0xcc000000
+#define SiS_ROP_PATCOPY 0xf0000000
+
+/*
+ * REG_6326_BitBlt_Cmd (0x82a8-0x82ab)
+ */
+#define MASK_QueueStatus 0x0000ffff
+#define MASK_BltCmd0 0x00ff0000
+#define MASK_BltCmd1 0xff000000
+
+#define BLT_SRC_BG 0x00000000
+#define BLT_SRC_FG 0x00010000
+#define BLT_SRC_VID 0x00020000
+#define BLT_SRC_CPU 0x00030000
+#define BLT_PAT_BG 0x00000000
+#define BLT_PAT_FG 0x00040000
+#define BLT_PAT_PAT 0x000b0000
+#define BLT_XINC 0x00100000
+#define BLT_YINC 0x00200000
+#define BLT_CLIP 0x00400000
+#define BLT_BUSY 0x04000000
+
+/*
+ * REG_3D_PrimitiveSet -- Define Fire Primitive Mask (89F8h-89FBh)
+ */
+#define MASK_6326_DrawPrimitiveCommand 0x00000007
+#define MASK_6326_SetFirePosition 0x00000F00
+#define MASK_6326_ShadingMode 0x001c0000
+#define MASK_6326_Direction 0x0003f000
+
+/* OP_3D_{POINT,LINE,TRIANGLE}_DRAW same as 300-series */
+/* OP_3D_DIRECTION*_ same as 300-series */
+
+#define OP_6326_3D_FIRE_TFIRE 0x00000000
+#define OP_6326_3D_FIRE_TSARGBa 0x00000100
+#define OP_6326_3D_FIRE_TSWa 0x00000200
+#define OP_6326_3D_FIRE_TSARGBb 0x00000300
+#define OP_6326_3D_FIRE_TSWb 0x00000400
+#define OP_6326_3D_FIRE_TSARGBc 0x00000500
+#define OP_6326_3D_FIRE_TSWc 0x00000600
+#define OP_6326_3D_FIRE_TSVc 0x00000700
+
+#define OP_6326_3D_ATOP 0x00000000
+#define OP_6326_3D_BTOP 0x00010000
+#define OP_6326_3D_CTOP 0x00020000
+#define OP_6326_3D_AMID 0x00000000
+#define OP_6326_3D_BMID 0x00004000
+#define OP_6326_3D_CMID 0x00008000
+#define OP_6326_3D_ABOT 0x00000000
+#define OP_6326_3D_BBOT 0x00001000
+#define OP_6326_3D_CBOT 0x00002000
+
+#define OP_6326_3D_SHADE_FLAT_TOP 0x00040000
+#define OP_6326_3D_SHADE_FLAT_MID 0x00080000
+#define OP_6326_3D_SHADE_FLAT_BOT 0x000c0000
+#define OP_6326_3D_SHADE_FLAT_GOURAUD 0x00100000
+
+
+/*
+ * REG_6326_3D_EngineFire
+ */
+#define MASK_CmdQueueLen 0x0FFF0000
+#define ENG_3DIDLEQE 0x00000002
+#define ENG_3DIDLE 0x00000001
+
+/*
+ * REG_6326_3D_TEnable -- Define Capility Enable Mask (8A00h-8A03h)
+ */
+#define S_ENABLE_Dither (1 << 0)
+#define S_ENABLE_Transparency (1 << 1)
+#define S_ENABLE_Blend (1 << 2)
+#define S_ENABLE_Fog (1 << 3)
+#define S_ENABLE_Specular (1 << 4)
+#define S_ENABLE_LargeCache (1 << 5)
+#define S_ENABLE_TextureCache (1 << 7)
+#define S_ENABLE_TextureTransparency (1 << 8)
+#define S_ENABLE_TexturePerspective (1 << 9)
+#define S_ENABLE_Texture (1 << 10)
+#define S_ENABLE_PrimSetup (1 << 11)
+#define S_ENABLE_LinePattern (1 << 12)
+#define S_ENABLE_StippleAlpha (1 << 13) /* requires S_ENABLE_Stipple */
+#define S_ENABLE_Stipple (1 << 14)
+#define S_ENABLE_AlphaBuffer (1 << 16)
+#define S_ENABLE_AlphaTest (1 << 17)
+#define S_ENABLE_AlphaWrite (1 << 18)
+#define S_ENABLE_ZTest (1 << 20)
+#define S_ENABLE_ZWrite (1 << 21)
+
+/*
+ * REG_3D_ZSet -- Define Z Buffer Setting Mask (8A08h-8A0Bh)
+ */
+#define MASK_6326_ZBufferPitch 0x00003FFF
+#define MASK_6326_ZTestMode 0x00070000
+#define MASK_6326_ZBufferFormat 0x00100000
+
+#define S_ZSET_FORMAT_8 0x00000000
+#define S_ZSET_FORMAT_16 0x00100000
+
+#define S_ZSET_PASS_NEVER 0x00000000
+#define S_ZSET_PASS_LESS 0x00010000
+#define S_ZSET_PASS_EQUAL 0x00020000
+#define S_ZSET_PASS_LEQUAL 0x00030000
+#define S_ZSET_PASS_GREATER 0x00040000
+#define S_ZSET_PASS_NOTEQUAL 0x00050000
+#define S_ZSET_PASS_GEQUAL 0x00060000
+#define S_ZSET_PASS_ALWAYS 0x00070000
+
+/*
+ * REG_3D_AlphaSet -- Define Alpha Buffer Setting Mask (8A0Ch-8A0Fh)
+ */
+#define MASK_AlphaBufferPitch 0x000003FF
+#define MASK_AlphaRefValue 0x00FF0000
+#define MASK_AlphaTestMode 0x07000000
+#define MASK_AlphaBufferFormat 0x30000000
+
+#define S_ASET_FORMAT_8 0x30000000
+
+#define S_ASET_PASS_NEVER 0x00000000
+#define S_ASET_PASS_LESS 0x01000000
+#define S_ASET_PASS_EQUAL 0x02000000
+#define S_ASET_PASS_LEQUAL 0x03000000
+#define S_ASET_PASS_GREATER 0x04000000
+#define S_ASET_PASS_NOTEQUAL 0x05000000
+#define S_ASET_PASS_GEQUAL 0x06000000
+#define S_ASET_PASS_ALWAYS 0x07000000
+
+/*
+ * REG_3D_DstSet -- Define Destination Buffer Setting Mask (8A14h-8A17h)
+ */
+/* pitch, format, depth, rgborder, rop bits same as 300-series */
+
+/*
+ * REG_6326_3D_FogSet -- Define Fog Mask (8A20h-8A23h)
+ */
+#define MASK_6326_FogColor 0x00FFFFFF
+#define MASK_6326_FogMode 0x01000000
+
+#define FOGMODE_6326_CONST 0x00000000
+#define FOGMODE_6326_LINEAR 0x01000000
+
+/*
+ * REG_6326_3D_DstSrcBlendMode (0x8A28 - 0x8A2B)
+ */
+#define MASK_6326_SrcBlendMode 0xf0000000
+#define MASK_6326_DstBlendMode 0x0f000000
+#define MASK_6326_TransparencyColor 0x00ffffff
+
+#define S_DBLEND_ZERO 0x00000000
+#define S_DBLEND_ONE 0x10000000
+#define S_DBLEND_SRC_COLOR 0x20000000
+#define S_DBLEND_INV_SRC_COLOR 0x30000000
+#define S_DBLEND_SRC_ALPHA 0x40000000
+#define S_DBLEND_INV_SRC_ALPHA 0x50000000
+#define S_DBLEND_DST_ALPHA 0x60000000
+#define S_DBLEND_INV_DST_ALPHA 0x70000000
+
+#define S_SBLEND_ZERO 0x00000000
+#define S_SBLEND_ONE 0x01000000
+#define S_SBLEND_SRC_ALPHA 0x04000000
+#define S_SBLEND_INV_SRC_ALPHA 0x05000000
+#define S_SBLEND_DST_ALPHA 0x06000000
+#define S_SBLEND_INV_DST_ALPHA 0x07000000
+#define S_SBLEND_DST_COLOR 0x08000000
+#define S_SBLEND_INV_DST_COLOR 0x09000000
+#define S_SBLEND_SRC_ALPHA_SAT 0x0A000000
+#define S_SBLEND_BOTH_SRC_ALPHA 0x0B000000
+#define S_SBLEND_BOTH_INV_SRC_ALPHA 0x0C000000
+
+/*
+ * REG_6326_3D_TextureSet (0x8A38 - 0x8A3B)
+ */
+#define MASK_6326_TextureMinFilter 0x00000007
+#define MASK_6326_TextureMagFilter 0x00000008
+#define MASK_6326_ClearTexCache 0x00000010
+#define MASK_6326_TextureInSystem 0x00000020
+#define MASK_6326_TextureLevel 0x00000F00
+#define MASK_6326_TextureSignYUVFormat 0x00008000
+#define MASK_6326_TextureMappingMode 0x00FF0000
+
+#define TEXEL_6326_BGR_ORDER 0x80000000
+
+#define TEXEL_6326_INDEX1 0x00000000
+#define TEXEL_6326_INDEX2 0x01000000
+#define TEXEL_6326_INDEX4 0x02000000
+
+#define TEXEL_6326_M4 0x10000000
+#define TEXEL_6326_AM44 0x16000000
+
+#define TEXEL_6326_YUV422 0x20000000 /* YUYV */
+#define TEXEL_6326_YVU422 0x21000000 /* YVYU */
+#define TEXEL_6326_UVY422 0x22000000 /* UYVY */
+#define TEXEL_6326_VUY422 0x23000000 /* VYUY */
+
+#define TEXEL_6326_L1 0x30000000
+#define TEXEL_6326_L2 0x31000000
+#define TEXEL_6326_L4 0x32000000
+#define TEXEL_6326_L8 0x33000000
+
+#define TEXEL_6326_AL22 0x35000000
+#define TEXEL_6326_AL44 0x38000000
+#define TEXEL_6326_AL88 0x3c000000
+
+#define TEXEL_6326_RGB_332_8 0x40000000
+#define TEXEL_6326_RGB_233_8 0x41000000
+#define TEXEL_6326_RGB_232_8 0x42000000
+#define TEXEL_6326_ARGB_1232_8 0x43000000
+
+#define TEXEL_6326_RGB_555_16 0x50000000
+#define TEXEL_6326_RGB_565_16 0x51000000
+#define TEXEL_6326_ARGB_1555_16 0x52000000
+#define TEXEL_6326_ARGB_4444_16 0x53000000
+#define TEXEL_6326_ARGB_8332_16 0x54000000
+#define TEXEL_6326_ARGB_8233_16 0x55000000
+#define TEXEL_6326_ARGB_8232_16 0x56000000
+
+#define TEXEL_6326_ARGB_8565_24 0x63000000
+#define TEXEL_6326_ARGB_8555_24 0x67000000
+#define TEXEL_6326_RGB_888_24 0x68000000
+
+#define TEXEL_6326_ARGB_8888_32 0x73000000
+#define TEXEL_6326_ARGB_0888_32 0x74000000
+
+#define TEX_MAP_WRAP_U 0x00010000
+#define TEX_MAP_WRAP_V 0x00020000
+#define TEX_MAP_MIRROR_U 0x00040000
+#define TEX_MAP_MIRROR_V 0x00080000
+#define TEX_MAP_CLAMP_U 0x00100000
+#define TEX_MAP_CLAMP_V 0x00200000
+#define TEX_MAP_USE_CTB_SMOOTH 0x00400000
+#define TEX_MAP_USE_CTB 0x00800000
+
+#define TEX_FILTER_NEAREST 0x00000000
+#define TEX_FILTER_LINEAR 0x00000001
+#define TEX_FILTER_NEAREST_MIP_NEAREST 0x00000002
+#define TEX_FILTER_NEAREST_MIP_LINEAR 0x00000003
+#define TEX_FILTER_LINEAR_MIP_NEAREST 0x00000004
+#define TEX_FILTER_LINEAR_MIP_LINEAR 0x00000005
+#define TEX_FILTER_MAG_NEAREST 0x00000000
+#define TEX_FILTER_MAG_LINEAR 0x00000008
+
+/*
+ * REG_6326_3D_TextureBlendSet (0x8A3C - 0x8A3F)
+ */
+#define MASK_TextureTransparencyLowB 0x000000ff
+#define MASK_TextureTransparencyLowG 0x0000FF00
+#define MASK_TextureTransparencyLowR 0x00ff0000
+#define MASK_TextureBlend 0x0f000000
+
+#define TB_C_CS (0 << 26)
+#define TB_C_CF (1 << 26)
+#define TB_C_CFCS (2 << 26) /* also 3 << 26 */
+#define TB_C_CFOMAS_ASCS (4 << 26)
+#define TB_C_CSOMAF_AFCF (6 << 26) /* also 7 << 26 */
+
+#define TB_A_AS (0 << 24)
+#define TB_A_AF (1 << 24)
+#define TB_A_AFAS (1 << 24)
+
+/*
+ * REG_6326_3D_TextureTransparencyColorHigh (0x8A40 - 0x8A43)
+ */
+#define MASK_TextureTransparencyHighB 0x000000FF
+#define MASK_TextureTransparencyHighG 0x0000FF00
+#define MASK_TextureTransparencyHighR 0x00FF0000
+
+/*
+ * REG_3D_TexturePitch01-89 (0x8A6C - 0x8A7F)
+ */
+#define MASK_TexturePitchOdd 0x000003FF
+#define MASK_TexturePitchEven 0x03FF0000
+#define SHIFT_TexturePitchEven 16
+
+/*
+ * REG_3D_TextureWidthHeightMix (0x8A80 - 0x8A83)
+ */
+#define MASK_TextureWidthLog2 0xf0000000
+#define MASK_TextureHeightLog2 0x0f000000
+
+/*
+ * REG_3D_TextureBorderColor (0x8A90 - 0x8A93)
+ */
+#define MASK_TextureBorderColorB 0x000000FF
+#define MASK_TextureBorderColorG 0x0000FF00
+#define MASK_TextureBorderColorR 0x00FF0000
+#define MASK_TextureBorderColorA 0xFF000000
+
+#endif /* _sis6326_reg_h_ */
diff --git a/src/sis6326_state.c b/src/sis6326_state.c
new file mode 100644
index 0000000..08402fb
--- /dev/null
+++ b/src/sis6326_state.c
@@ -0,0 +1,735 @@
+/*
+ * Copyright 2005 Eric Anholt
+ * 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, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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 NONINFRINGEMENT. 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.
+ *
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ *
+ */
+
+#include "sis_context.h"
+#include "sis_state.h"
+#include "sis_tris.h"
+#include "sis_lock.h"
+#include "sis_tex.h"
+#include "sis_reg.h"
+
+#include "context.h"
+#include "enums.h"
+#include "colormac.h"
+#include "swrast/swrast.h"
+#include "vbo/vbo.h"
+#include "tnl/tnl.h"
+#include "swrast_setup/swrast_setup.h"
+
+#include "tnl/t_pipeline.h"
+
+/* =============================================================
+ * Alpha blending
+ */
+
+static void
+sis6326DDAlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ GLubyte refbyte;
+
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ CLAMPED_FLOAT_TO_UBYTE(refbyte, ref);
+ current->hwAlpha = refbyte << 16;
+
+ /* Alpha Test function */
+ switch (func)
+ {
+ case GL_NEVER:
+ current->hwAlpha |= S_ASET_PASS_NEVER;
+ break;
+ case GL_LESS:
+ current->hwAlpha |= S_ASET_PASS_LESS;
+ break;
+ case GL_EQUAL:
+ current->hwAlpha |= S_ASET_PASS_EQUAL;
+ break;
+ case GL_LEQUAL:
+ current->hwAlpha |= S_ASET_PASS_LEQUAL;
+ break;
+ case GL_GREATER:
+ current->hwAlpha |= S_ASET_PASS_GREATER;
+ break;
+ case GL_NOTEQUAL:
+ current->hwAlpha |= S_ASET_PASS_NOTEQUAL;
+ break;
+ case GL_GEQUAL:
+ current->hwAlpha |= S_ASET_PASS_GEQUAL;
+ break;
+ case GL_ALWAYS:
+ current->hwAlpha |= S_ASET_PASS_ALWAYS;
+ break;
+ }
+
+ prev->hwAlpha = current->hwAlpha;
+ smesa->GlobalFlag |= GFLAG_ALPHASETTING;
+}
+
+static void
+sis6326DDBlendFuncSeparate( GLcontext *ctx,
+ GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ current->hwDstSrcBlend = 0;
+
+ switch (dfactorRGB)
+ {
+ case GL_ZERO:
+ current->hwDstSrcBlend |= S_DBLEND_ZERO;
+ break;
+ case GL_ONE:
+ current->hwDstSrcBlend |= S_DBLEND_ONE;
+ break;
+ case GL_SRC_COLOR:
+ current->hwDstSrcBlend |= S_DBLEND_SRC_COLOR;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ current->hwDstSrcBlend |= S_DBLEND_INV_SRC_COLOR;
+ break;
+ case GL_SRC_ALPHA:
+ current->hwDstSrcBlend |= S_DBLEND_SRC_ALPHA;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ current->hwDstSrcBlend |= S_DBLEND_INV_SRC_ALPHA;
+ break;
+ case GL_DST_ALPHA:
+ current->hwDstSrcBlend |= S_DBLEND_DST_ALPHA;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ current->hwDstSrcBlend |= S_DBLEND_INV_DST_ALPHA;
+ break;
+ }
+
+ switch (sfactorRGB)
+ {
+ case GL_ZERO:
+ current->hwDstSrcBlend |= S_SBLEND_ZERO;
+ break;
+ case GL_ONE:
+ current->hwDstSrcBlend |= S_SBLEND_ONE;
+ break;
+ case GL_SRC_ALPHA:
+ current->hwDstSrcBlend |= S_SBLEND_SRC_ALPHA;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ current->hwDstSrcBlend |= S_SBLEND_INV_SRC_ALPHA;
+ break;
+ case GL_DST_ALPHA:
+ current->hwDstSrcBlend |= S_SBLEND_DST_ALPHA;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ current->hwDstSrcBlend |= S_SBLEND_INV_DST_ALPHA;
+ break;
+ case GL_DST_COLOR:
+ current->hwDstSrcBlend |= S_SBLEND_DST_COLOR;
+ break;
+ case GL_ONE_MINUS_DST_COLOR:
+ current->hwDstSrcBlend |= S_SBLEND_INV_DST_COLOR;
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ current->hwDstSrcBlend |= S_SBLEND_SRC_ALPHA_SAT;
+ break;
+ }
+
+ if (current->hwDstSrcBlend != prev->hwDstSrcBlend) {
+ prev->hwDstSrcBlend = current->hwDstSrcBlend;
+ smesa->GlobalFlag |= GFLAG_DSTBLEND;
+ }
+}
+
+/* =============================================================
+ * Depth testing
+ */
+
+static void
+sis6326DDDepthFunc( GLcontext *ctx, GLenum func )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ current->hwZ &= ~MASK_6326_ZTestMode;
+ switch (func)
+ {
+ case GL_LESS:
+ current->hwZ |= S_ZSET_PASS_LESS;
+ break;
+ case GL_GEQUAL:
+ current->hwZ |= S_ZSET_PASS_GEQUAL;
+ break;
+ case GL_LEQUAL:
+ current->hwZ |= S_ZSET_PASS_LEQUAL;
+ break;
+ case GL_GREATER:
+ current->hwZ |= S_ZSET_PASS_GREATER;
+ break;
+ case GL_NOTEQUAL:
+ current->hwZ |= S_ZSET_PASS_NOTEQUAL;
+ break;
+ case GL_EQUAL:
+ current->hwZ |= S_ZSET_PASS_EQUAL;
+ break;
+ case GL_ALWAYS:
+ current->hwZ |= S_ZSET_PASS_ALWAYS;
+ break;
+ case GL_NEVER:
+ current->hwZ |= S_ZSET_PASS_NEVER;
+ break;
+ }
+
+ if (current->hwZ != prev->hwZ) {
+ prev->hwZ = current->hwZ;
+ smesa->GlobalFlag |= GFLAG_ZSETTING;
+ }
+}
+
+static void
+sis6326DDDepthMask( GLcontext *ctx, GLboolean flag )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *current = &smesa->current;
+
+ if (ctx->Depth.Test)
+ current->hwCapEnable |= S_ENABLE_ZWrite;
+ else
+ current->hwCapEnable &= ~S_ENABLE_ZWrite;
+}
+
+/* =============================================================
+ * Fog
+ */
+
+static void
+sis6326DDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *current = &smesa->current;
+ __GLSiSHardware *prev = &smesa->prev;
+
+ GLint fogColor;
+
+ switch(pname)
+ {
+ case GL_FOG_COLOR:
+ fogColor = FLOAT_TO_UBYTE( ctx->Fog.Color[0] ) << 16;
+ fogColor |= FLOAT_TO_UBYTE( ctx->Fog.Color[1] ) << 8;
+ fogColor |= FLOAT_TO_UBYTE( ctx->Fog.Color[2] );
+ current->hwFog = 0x01000000 | fogColor;
+ if (current->hwFog != prev->hwFog) {
+ prev->hwFog = current->hwFog;
+ smesa->GlobalFlag |= GFLAG_FOGSETTING;
+ }
+ break;
+ }
+}
+
+/* =============================================================
+ * Clipping
+ */
+
+void
+sis6326UpdateClipping(GLcontext *ctx)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ GLint x1, y1, x2, y2;
+
+ x1 = 0;
+ y1 = 0;
+ x2 = smesa->width - 1;
+ y2 = smesa->height - 1;
+
+ if (ctx->Scissor.Enabled) {
+ if (ctx->Scissor.X > x1)
+ x1 = ctx->Scissor.X;
+ if (ctx->Scissor.Y > y1)
+ y1 = ctx->Scissor.Y;
+ if (ctx->Scissor.X + ctx->Scissor.Width - 1 < x2)
+ x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
+ if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < y2)
+ y2 = ctx->Scissor.Y + ctx->Scissor.Height - 1;
+ }
+
+ y1 = Y_FLIP(y1);
+ y2 = Y_FLIP(y2);
+
+ /*current->clipTopBottom = (y2 << 13) | y1;
+ current->clipLeftRight = (x1 << 13) | x2;*/ /* XXX */
+ current->clipTopBottom = (0 << 13) | smesa->height;
+ current->clipLeftRight = (0 << 13) | smesa->width;
+
+ if ((current->clipTopBottom != prev->clipTopBottom) ||
+ (current->clipLeftRight != prev->clipLeftRight)) {
+ prev->clipTopBottom = current->clipTopBottom;
+ prev->clipLeftRight = current->clipLeftRight;
+ smesa->GlobalFlag |= GFLAG_CLIPPING;
+ }
+}
+
+static void
+sis6326DDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
+{
+ if (ctx->Scissor.Enabled)
+ sis6326UpdateClipping( ctx );
+}
+
+/* =============================================================
+ * Culling
+ */
+
+static void
+sis6326UpdateCull( GLcontext *ctx )
+{
+ /* XXX culling */
+}
+
+
+static void
+sis6326DDCullFace( GLcontext *ctx, GLenum mode )
+{
+ sis6326UpdateCull( ctx );
+}
+
+static void
+sis6326DDFrontFace( GLcontext *ctx, GLenum mode )
+{
+ sis6326UpdateCull( ctx );
+}
+
+/* =============================================================
+ * Masks
+ */
+
+static void sis6326DDColorMask( GLcontext *ctx,
+ GLboolean r, GLboolean g,
+ GLboolean b, GLboolean a )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ if (r && g && b && ((ctx->Visual.alphaBits == 0) || a)) {
+ FALLBACK(smesa, SIS_FALLBACK_WRITEMASK, 0);
+ } else {
+ FALLBACK(smesa, SIS_FALLBACK_WRITEMASK, 1);
+ }
+}
+
+/* =============================================================
+ * Rendering attributes
+ */
+
+static void sis6326UpdateSpecular(GLcontext *ctx)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *current = &smesa->current;
+
+ if (NEED_SECONDARY_COLOR(ctx))
+ current->hwCapEnable |= S_ENABLE_Specular;
+ else
+ current->hwCapEnable &= ~S_ENABLE_Specular;
+}
+
+static void sis6326DDLightModelfv(GLcontext *ctx, GLenum pname,
+ const GLfloat *param)
+{
+ if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
+ sis6326UpdateSpecular(ctx);
+ }
+}
+static void sis6326DDShadeModel( GLcontext *ctx, GLenum mode )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ /* Signal to sisRasterPrimitive to recalculate dwPrimitiveSet */
+ smesa->hw_primitive = -1;
+}
+
+/* =============================================================
+ * Window position
+ */
+
+/* =============================================================
+ * Viewport
+ */
+
+static void sis6326CalcViewport( GLcontext *ctx )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+ GLfloat *m = smesa->hw_viewport;
+
+ /* See also sis_translate_vertex.
+ */
+ m[MAT_SX] = v[MAT_SX];
+ m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
+ m[MAT_SY] = - v[MAT_SY];
+ m[MAT_TY] = - v[MAT_TY] + smesa->driDrawable->h + SUBPIXEL_Y;
+ m[MAT_SZ] = v[MAT_SZ] * smesa->depth_scale;
+ m[MAT_TZ] = v[MAT_TZ] * smesa->depth_scale;
+}
+
+static void sis6326DDViewport( GLcontext *ctx,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height )
+{
+ sis6326CalcViewport( ctx );
+}
+
+static void sis6326DDDepthRange( GLcontext *ctx,
+ GLclampd nearval, GLclampd farval )
+{
+ sis6326CalcViewport( ctx );
+}
+
+/* =============================================================
+ * Miscellaneous
+ */
+
+static void
+sis6326DDLogicOpCode( GLcontext *ctx, GLenum opcode )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ if (!ctx->Color.ColorLogicOpEnabled)
+ return;
+
+ current->hwDstSet &= ~MASK_ROP2;
+ switch (opcode)
+ {
+ case GL_CLEAR:
+ current->hwDstSet |= LOP_CLEAR;
+ break;
+ case GL_SET:
+ current->hwDstSet |= LOP_SET;
+ break;
+ case GL_COPY:
+ current->hwDstSet |= LOP_COPY;
+ break;
+ case GL_COPY_INVERTED:
+ current->hwDstSet |= LOP_COPY_INVERTED;
+ break;
+ case GL_NOOP:
+ current->hwDstSet |= LOP_NOOP;
+ break;
+ case GL_INVERT:
+ current->hwDstSet |= LOP_INVERT;
+ break;
+ case GL_AND:
+ current->hwDstSet |= LOP_AND;
+ break;
+ case GL_NAND:
+ current->hwDstSet |= LOP_NAND;
+ break;
+ case GL_OR:
+ current->hwDstSet |= LOP_OR;
+ break;
+ case GL_NOR:
+ current->hwDstSet |= LOP_NOR;
+ break;
+ case GL_XOR:
+ current->hwDstSet |= LOP_XOR;
+ break;
+ case GL_EQUIV:
+ current->hwDstSet |= LOP_EQUIV;
+ break;
+ case GL_AND_REVERSE:
+ current->hwDstSet |= LOP_AND_REVERSE;
+ break;
+ case GL_AND_INVERTED:
+ current->hwDstSet |= LOP_AND_INVERTED;
+ break;
+ case GL_OR_REVERSE:
+ current->hwDstSet |= LOP_OR_REVERSE;
+ break;
+ case GL_OR_INVERTED:
+ current->hwDstSet |= LOP_OR_INVERTED;
+ break;
+ }
+
+ if (current->hwDstSet != prev->hwDstSet) {
+ prev->hwDstSet = current->hwDstSet;
+ smesa->GlobalFlag |= GFLAG_DESTSETTING;
+ }
+}
+
+void sis6326DDDrawBuffer( GLcontext *ctx, GLenum mode )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ if(getenv("SIS_DRAW_FRONT"))
+ ctx->DrawBuffer->_ColorDrawBufferMask[0] = GL_FRONT_LEFT;
+
+ /*
+ * _DrawDestMask is easier to cope with than <mode>.
+ */
+ current->hwDstSet &= ~MASK_DstBufferPitch;
+ switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
+ case BUFFER_BIT_FRONT_LEFT:
+ current->hwOffsetDest = smesa->front.offset;
+ current->hwDstSet |= smesa->front.pitch;
+ FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE );
+ break;
+ case BUFFER_BIT_BACK_LEFT:
+ current->hwOffsetDest = smesa->back.offset;
+ current->hwDstSet |= smesa->back.pitch;
+ FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE );
+ break;
+ default:
+ /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
+ FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_TRUE );
+ return;
+ }
+
+ if (current->hwDstSet != prev->hwDstSet) {
+ prev->hwDstSet = current->hwDstSet;
+ smesa->GlobalFlag |= GFLAG_DESTSETTING;
+ }
+
+ if (current->hwOffsetDest != prev->hwOffsetDest) {
+ prev->hwOffsetDest = current->hwOffsetDest;
+ smesa->GlobalFlag |= GFLAG_DESTSETTING;
+ }
+}
+
+/* =============================================================
+ * Polygon stipple
+ */
+
+/* =============================================================
+ * Render mode
+ */
+
+/* =============================================================
+ * State enable/disable
+ */
+
+static void
+sis6326DDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ __GLSiSHardware *current = &smesa->current;
+
+ switch (cap)
+ {
+ case GL_ALPHA_TEST:
+ if (state)
+ current->hwCapEnable |= S_ENABLE_AlphaTest;
+ else
+ current->hwCapEnable &= ~S_ENABLE_AlphaTest;
+ break;
+ case GL_BLEND:
+ /* TODO: */
+ if (state)
+ /* if (state & !ctx->Color.ColorLogicOpEnabled) */
+ current->hwCapEnable |= S_ENABLE_Blend;
+ else
+ current->hwCapEnable &= ~S_ENABLE_Blend;
+ break;
+ case GL_CULL_FACE:
+ /* XXX culling */
+ break;
+ case GL_DEPTH_TEST:
+ if (state && smesa->depth.offset != 0)
+ current->hwCapEnable |= S_ENABLE_ZTest;
+ else
+ current->hwCapEnable &= ~S_ENABLE_ZTest;
+ sis6326DDDepthMask( ctx, ctx->Depth.Mask );
+ break;
+ case GL_DITHER:
+ if (state)
+ current->hwCapEnable |= S_ENABLE_Dither;
+ else
+ current->hwCapEnable &= ~S_ENABLE_Dither;
+ break;
+ case GL_FOG:
+ if (state)
+ current->hwCapEnable |= S_ENABLE_Fog;
+ else
+ current->hwCapEnable &= ~S_ENABLE_Fog;
+ break;
+ case GL_COLOR_LOGIC_OP:
+ if (state)
+ sis6326DDLogicOpCode( ctx, ctx->Color.LogicOp );
+ else
+ sis6326DDLogicOpCode( ctx, GL_COPY );
+ break;
+ case GL_SCISSOR_TEST:
+ sis6326UpdateClipping( ctx );
+ break;
+ case GL_STENCIL_TEST:
+ if (state) {
+ FALLBACK(smesa, SIS_FALLBACK_STENCIL, 1);
+ } else {
+ FALLBACK(smesa, SIS_FALLBACK_STENCIL, 0);
+ }
+ break;
+ case GL_LIGHTING:
+ case GL_COLOR_SUM_EXT:
+ sis6326UpdateSpecular(ctx);
+ break;
+ }
+}
+
+/* =============================================================
+ * State initialization, management
+ */
+
+/* Called before beginning of rendering. */
+void
+sis6326UpdateHWState( GLcontext *ctx )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ if (smesa->NewGLState & _NEW_TEXTURE)
+ sisUpdateTextureState( ctx );
+
+ if (current->hwCapEnable ^ prev->hwCapEnable) {
+ prev->hwCapEnable = current->hwCapEnable;
+ smesa->GlobalFlag |= GFLAG_ENABLESETTING;
+ }
+
+ if (smesa->GlobalFlag & GFLAG_RENDER_STATES)
+ sis_update_render_state( smesa );
+
+ if (smesa->GlobalFlag & GFLAG_TEXTURE_STATES)
+ sis_update_texture_state( smesa );
+}
+
+static void
+sis6326DDInvalidateState( GLcontext *ctx, GLuint new_state )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ _swrast_InvalidateState( ctx, new_state );
+ _swsetup_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
+ _tnl_InvalidateState( ctx, new_state );
+ smesa->NewGLState |= new_state;
+}
+
+/* Initialize the context's hardware state.
+ */
+void sis6326DDInitState( sisContextPtr smesa )
+{
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+ GLcontext *ctx = smesa->glCtx;
+
+ /* add Texture Perspective Enable */
+ current->hwCapEnable = S_ENABLE_TextureCache |
+ S_ENABLE_TexturePerspective | S_ENABLE_Dither;
+
+ /* Z test mode is LESS */
+ current->hwZ = S_ZSET_PASS_LESS | S_ZSET_FORMAT_16;
+ if (ctx->Visual.depthBits > 0)
+ current->hwCapEnable |= S_ENABLE_ZWrite;
+
+ /* Alpha test mode is ALWAYS, alpha ref value is 0 */
+ current->hwAlpha = S_ASET_PASS_ALWAYS;
+
+ /* ROP2 is COPYPEN */
+ current->hwDstSet = LOP_COPY;
+
+ /* LinePattern is 0, Repeat Factor is 0 */
+ current->hwLinePattern = 0x00008000;
+
+ /* Src blend is BLEND_ONE, Dst blend is D3DBLEND_ZERO */
+ current->hwDstSrcBlend = S_SBLEND_ONE | S_DBLEND_ZERO;
+
+ switch (smesa->bytesPerPixel)
+ {
+ case 2:
+ current->hwDstSet |= DST_FORMAT_RGB_565;
+ break;
+ case 4:
+ current->hwDstSet |= DST_FORMAT_ARGB_8888;
+ break;
+ }
+
+ smesa->depth_scale = 1.0 / (GLfloat)0xffff;
+
+ smesa->clearTexCache = GL_TRUE;
+
+ smesa->clearColorPattern = 0;
+
+ sis6326UpdateZPattern(smesa, 1.0);
+ sis6326UpdateCull(ctx);
+
+ /* Set initial fog settings. Start and end are the same case. */
+ sis6326DDFogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
+ sis6326DDFogfv( ctx, GL_FOG_END, &ctx->Fog.End );
+ sis6326DDFogfv( ctx, GL_FOG_MODE, NULL );
+
+ memcpy(prev, current, sizeof(__GLSiSHardware));
+}
+
+/* Initialize the driver's state functions.
+ */
+void sis6326DDInitStateFuncs( GLcontext *ctx )
+{
+ ctx->Driver.UpdateState = sis6326DDInvalidateState;
+
+ ctx->Driver.Clear = sis6326DDClear;
+ ctx->Driver.ClearColor = sis6326DDClearColor;
+ ctx->Driver.ClearDepth = sis6326DDClearDepth;
+
+ ctx->Driver.AlphaFunc = sis6326DDAlphaFunc;
+ ctx->Driver.BlendFuncSeparate = sis6326DDBlendFuncSeparate;
+ ctx->Driver.ColorMask = sis6326DDColorMask;
+ ctx->Driver.CullFace = sis6326DDCullFace;
+ ctx->Driver.DepthMask = sis6326DDDepthMask;
+ ctx->Driver.DepthFunc = sis6326DDDepthFunc;
+ ctx->Driver.DepthRange = sis6326DDDepthRange;
+ ctx->Driver.DrawBuffer = sis6326DDDrawBuffer;
+ ctx->Driver.Enable = sis6326DDEnable;
+ ctx->Driver.FrontFace = sis6326DDFrontFace;
+ ctx->Driver.Fogfv = sis6326DDFogfv;
+ ctx->Driver.LogicOpcode = sis6326DDLogicOpCode;
+ ctx->Driver.Scissor = sis6326DDScissor;
+ ctx->Driver.ShadeModel = sis6326DDShadeModel;
+ ctx->Driver.LightModelfv = sis6326DDLightModelfv;
+ ctx->Driver.Viewport = sis6326DDViewport;
+}
diff --git a/src/sis_alloc.c b/src/sis_alloc.c
new file mode 100644
index 0000000..b696eeb
--- /dev/null
+++ b/src/sis_alloc.c
@@ -0,0 +1,199 @@
+/**************************************************************************
+
+Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
+
+**************************************************************************/
+/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_alloc.c,v 1.7 2001/01/08 01:07:29 martin Exp $ */
+
+/*
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "sis_context.h"
+#include "sis_alloc.h"
+
+#include "sis_common.h"
+
+#include <unistd.h>
+
+#define Z_BUFFER_HW_ALIGNMENT 16
+#define Z_BUFFER_HW_PLUS (16 + 4)
+
+/* 3D engine uses 2, and bitblt uses 4 */
+#define DRAW_BUFFER_HW_ALIGNMENT 16
+#define DRAW_BUFFER_HW_PLUS (16 + 4)
+
+#define ALIGNMENT(value, align) (((value) + (align) - 1) / (align) * (align))
+
+static int _total_video_memory_used = 0;
+static int _total_video_memory_count = 0;
+
+void *
+sisAllocFB( sisContextPtr smesa, GLuint size, void **handle )
+{
+ drm_sis_mem_t fb;
+
+ _total_video_memory_used += size;
+
+ fb.context = smesa->hHWContext;
+ fb.size = size;
+ if (drmCommandWriteRead( smesa->driFd, DRM_SIS_FB_ALLOC, &fb,
+ sizeof(drm_sis_mem_t) ) || fb.offset == 0)
+ {
+ return NULL;
+ }
+ *handle = (void *)fb.free;
+
+ if (SIS_VERBOSE & VERBOSE_SIS_MEMORY) {
+ fprintf(stderr, "sisAllocFB: size=%d, offset=%lu, pid=%d, count=%d\n",
+ size, fb.offset, (GLint)getpid(),
+ ++_total_video_memory_count);
+ }
+
+ return (void *)(smesa->FbBase + fb.offset);
+}
+
+void
+sisFreeFB( sisContextPtr smesa, void *handle )
+{
+ drm_sis_mem_t fb;
+
+ if (SIS_VERBOSE & VERBOSE_SIS_MEMORY) {
+ fprintf(stderr, "sisFreeFB: free=%p, pid=%d, count=%d\n",
+ handle, (GLint)getpid(), --_total_video_memory_count);
+ }
+
+ fb.context = smesa->hHWContext;
+ fb.free = handle;
+ drmCommandWrite( smesa->driFd, DRM_SIS_FB_FREE, &fb, sizeof(drm_sis_mem_t) );
+}
+
+void *
+sisAllocAGP( sisContextPtr smesa, GLuint size, void **handle )
+{
+ drm_sis_mem_t agp;
+
+ if (smesa->AGPSize == 0)
+ return NULL;
+
+ agp.context = smesa->hHWContext;
+ agp.size = size;
+ if (drmCommandWriteRead( smesa->driFd, DRM_SIS_AGP_ALLOC, &agp,
+ sizeof(drm_sis_mem_t) ) || agp.offset == 0)
+ {
+ return NULL;
+ }
+ *handle = (void *)agp.free;
+
+ if (SIS_VERBOSE & VERBOSE_SIS_MEMORY) {
+ fprintf(stderr, "sisAllocAGP: size=%u, offset=%lu, pid=%d, count=%d\n",
+ size, agp.offset, (GLint)getpid(),
+ ++_total_video_memory_count);
+ }
+
+ return (void *)(smesa->AGPBase + agp.offset);
+}
+
+void
+sisFreeAGP( sisContextPtr smesa, void *handle )
+{
+ drm_sis_mem_t agp;
+
+ if (SIS_VERBOSE & VERBOSE_SIS_MEMORY) {
+ fprintf(stderr, "sisFreeAGP: free=%p, pid=%d, count=%d\n",
+ handle, (GLint)getpid(), --_total_video_memory_count);
+ }
+
+ agp.context = smesa->hHWContext;
+ agp.free = handle;
+ drmCommandWrite( smesa->driFd, DRM_SIS_AGP_FREE, &agp,
+ sizeof(drm_sis_mem_t) );
+}
+
+void
+sisAllocZStencilBuffer( sisContextPtr smesa )
+{
+ int cpp = ( smesa->glCtx->Visual.depthBits +
+ smesa->glCtx->Visual.stencilBits ) / 8;
+ unsigned char *addr;
+
+ smesa->depth.bpp = cpp * 8;
+ smesa->depth.pitch = ALIGNMENT(smesa->driDrawable->w * cpp, 4);
+ smesa->depth.size = smesa->depth.pitch * smesa->driDrawable->h;
+ smesa->depth.size += Z_BUFFER_HW_PLUS;
+
+ addr = sisAllocFB(smesa, smesa->depth.size, &smesa->depth.handle);
+ if (addr == NULL)
+ sis_fatal_error("Failure to allocate Z buffer.\n");
+ addr = (char *)ALIGNMENT((unsigned long)addr, Z_BUFFER_HW_ALIGNMENT);
+
+ smesa->depth.map = addr;
+ smesa->depth.offset = addr - smesa->FbBase;
+
+ /* stencil buffer is same as depth buffer */
+ smesa->stencil.size = smesa->depth.size;
+ smesa->stencil.offset = smesa->depth.offset;
+ smesa->stencil.handle = smesa->depth.handle;
+ smesa->stencil.pitch = smesa->depth.pitch;
+ smesa->stencil.bpp = smesa->depth.bpp;
+ smesa->stencil.map = smesa->depth.map;
+}
+
+void
+sisFreeZStencilBuffer( sisContextPtr smesa )
+{
+ sisFreeFB(smesa, smesa->depth.handle);
+ smesa->depth.map = NULL;
+ smesa->depth.offset = 0;
+}
+
+void
+sisAllocBackbuffer( sisContextPtr smesa )
+{
+ int cpp = smesa->bytesPerPixel;
+ unsigned char *addr;
+
+ smesa->back.bpp = smesa->bytesPerPixel * 8;
+ smesa->back.pitch = ALIGNMENT(smesa->driDrawable->w * cpp, 4);
+ smesa->back.size = smesa->back.pitch * smesa->driDrawable->h;
+ smesa->back.size += DRAW_BUFFER_HW_PLUS;
+
+ addr = sisAllocFB(smesa, smesa->back.size, &smesa->back.handle);
+ if (addr == NULL)
+ sis_fatal_error("Failure to allocate back buffer.\n");
+ addr = (char *)ALIGNMENT((unsigned long)addr, DRAW_BUFFER_HW_ALIGNMENT);
+
+ smesa->back.map = addr;
+ smesa->back.offset = addr - smesa->FbBase;
+}
+
+void
+sisFreeBackbuffer( sisContextPtr smesa )
+{
+ sisFreeFB(smesa, smesa->back.handle);
+ smesa->back.map = NULL;
+ smesa->back.offset = 0;
+}
diff --git a/src/sis_alloc.h b/src/sis_alloc.h
new file mode 100644
index 0000000..e76fc53
--- /dev/null
+++ b/src/sis_alloc.h
@@ -0,0 +1,44 @@
+/**************************************************************************
+
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT 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.
+
+**************************************************************************/
+/* $XFree86$ */
+
+/*
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+enum {
+ VIDEO_TYPE,
+ AGP_TYPE
+};
+
+void sisAllocZStencilBuffer( sisContextPtr smesa );
+void sisFreeZStencilBuffer( sisContextPtr smesa );
+void sisAllocBackbuffer( sisContextPtr smesa );
+void sisFreeBackbuffer ( sisContextPtr smesa );
+void *sisAllocFB( sisContextPtr smesa, GLuint size, void **handle );
+void sisFreeFB( sisContextPtr smesa, void *handle );
+void *sisAllocAGP( sisContextPtr smesa, GLuint size, void **handle );
+void sisFreeAGP( sisContextPtr smesa, void *handle );
diff --git a/src/sis_clear.c b/src/sis_clear.c
new file mode 100644
index 0000000..fb92d06
--- /dev/null
+++ b/src/sis_clear.c
@@ -0,0 +1,410 @@
+/**************************************************************************
+
+Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
+
+**************************************************************************/
+/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_clear.c,v 1.5 2000/09/26 15:56:48 tsi Exp $ */
+
+/*
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "sis_context.h"
+#include "sis_state.h"
+#include "sis_lock.h"
+
+#include "swrast/swrast.h"
+#include "macros.h"
+
+static GLbitfield sis_3D_Clear( GLcontext * ctx, GLbitfield mask,
+ GLint x, GLint y, GLint width,
+ GLint height );
+static void sis_clear_color_buffer( GLcontext *ctx, GLenum mask, GLint x,
+ GLint y, GLint width, GLint height );
+static void sis_clear_z_stencil_buffer( GLcontext * ctx,
+ GLbitfield mask, GLint x,
+ GLint y, GLint width,
+ GLint height );
+
+static void
+set_color_pattern( sisContextPtr smesa, GLubyte red, GLubyte green,
+ GLubyte blue, GLubyte alpha )
+{
+ /* XXX only RGB565 and ARGB8888 */
+ switch (smesa->colorFormat)
+ {
+ case DST_FORMAT_ARGB_8888:
+ smesa->clearColorPattern = (alpha << 24) +
+ (red << 16) + (green << 8) + (blue);
+ break;
+ case DST_FORMAT_RGB_565:
+ smesa->clearColorPattern = ((red >> 3) << 11) +
+ ((green >> 2) << 5) + (blue >> 3);
+ smesa->clearColorPattern |= smesa->clearColorPattern << 16;
+ break;
+ default:
+ sis_fatal_error("Bad dst color format\n");
+ }
+}
+
+void
+sisUpdateZStencilPattern( sisContextPtr smesa, GLclampd z, GLint stencil )
+{
+ GLuint zPattern;
+
+ switch (smesa->zFormat)
+ {
+ case SiS_ZFORMAT_Z16:
+ CLAMPED_FLOAT_TO_USHORT(zPattern, z);
+ zPattern |= zPattern << 16;
+ break;
+ case SiS_ZFORMAT_S8Z24:
+ zPattern = FLOAT_TO_UINT(z) >> 8;
+ zPattern |= stencil << 24;
+ break;
+ case SiS_ZFORMAT_Z32:
+ zPattern = FLOAT_TO_UINT(z);
+ break;
+ default:
+ sis_fatal_error("Bad Z format\n");
+ }
+ smesa->clearZStencilPattern = zPattern;
+}
+
+void
+sisDDClear( GLcontext * ctx, GLbitfield mask )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ GLint x1, y1, width1, height1;
+
+ /* get region after locking: */
+ x1 = ctx->DrawBuffer->_Xmin;
+ y1 = ctx->DrawBuffer->_Ymin;
+ width1 = ctx->DrawBuffer->_Xmax - x1;
+ height1 = ctx->DrawBuffer->_Ymax - y1;
+ y1 = Y_FLIP(y1 + height1 - 1);
+
+ /* Mask out any non-existent buffers */
+ if (ctx->Visual.depthBits == 0 || !ctx->Depth.Mask)
+ mask &= ~BUFFER_BIT_DEPTH;
+ if (ctx->Visual.stencilBits == 0)
+ mask &= ~BUFFER_BIT_STENCIL;
+
+ LOCK_HARDWARE();
+
+ /* The 3d clear code is use for masked clears because apparently the SiS
+ * 300-series can't do write masks for 2d blits. 3d isn't used in general
+ * because it's slower, even in the case of clearing multiple buffers.
+ */
+ /* XXX: Appears to be broken with stencil. */
+ if ((smesa->current.hwCapEnable2 & (MASK_AlphaMaskWriteEnable |
+ MASK_ColorMaskWriteEnable) &&
+ (mask & (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_FRONT_LEFT)) != 0) ||
+ ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff &&
+ (mask & BUFFER_BIT_STENCIL) != 0) )
+ {
+ mask = sis_3D_Clear( ctx, mask, x1, y1, width1, height1 );
+ }
+
+ if ( mask & BUFFER_BIT_FRONT_LEFT || mask & BUFFER_BIT_BACK_LEFT) {
+ sis_clear_color_buffer( ctx, mask, x1, y1, width1, height1 );
+ mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
+ }
+
+ if (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
+ if (smesa->depth.offset != 0)
+ sis_clear_z_stencil_buffer( ctx, mask, x1, y1, width1, height1 );
+ mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
+ }
+
+ UNLOCK_HARDWARE();
+
+ if (mask != 0)
+ _swrast_Clear( ctx, mask);
+}
+
+
+void
+sisDDClearColor( GLcontext * ctx, const GLfloat color[4] )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ GLubyte c[4];
+
+ CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
+
+ set_color_pattern( smesa, c[0], c[1], c[2], c[3] );
+}
+
+void
+sisDDClearDepth( GLcontext * ctx, GLclampd d )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ sisUpdateZStencilPattern( smesa, d, ctx->Stencil.Clear );
+}
+
+void
+sisDDClearStencil( GLcontext * ctx, GLint s )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ sisUpdateZStencilPattern( smesa, ctx->Depth.Clear, s );
+}
+
+static GLbitfield
+sis_3D_Clear( GLcontext * ctx, GLbitfield mask,
+ GLint x, GLint y, GLint width, GLint height )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ __GLSiSHardware *current = &smesa->current;
+
+ float left, top, right, bottom, zClearVal;
+ GLboolean bClrColor, bClrDepth, bClrStencil;
+ GLint dwPrimitiveSet;
+ GLint dwEnable1 = 0, dwEnable2 = MASK_ColorMaskWriteEnable;
+ GLint dwDepthMask = 0, dwSten1 = 0, dwSten2 = 0;
+ GLint dirtyflags = GFLAG_ENABLESETTING | GFLAG_ENABLESETTING2 |
+ GFLAG_CLIPPING | GFLAG_DESTSETTING;
+ int count;
+ drm_clip_rect_t *pExtents;
+
+ bClrColor = (mask & (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_FRONT_LEFT)) != 0;
+ bClrDepth = (mask & BUFFER_BIT_DEPTH) != 0;
+ bClrStencil = (mask & BUFFER_BIT_STENCIL) != 0;
+
+ if (smesa->GlobalFlag & GFLAG_RENDER_STATES)
+ sis_update_render_state( smesa );
+
+ if (bClrStencil) {
+ dwSten1 = STENCIL_FORMAT_8 | SiS_STENCIL_ALWAYS |
+ ((ctx->Stencil.Clear & 0xff) << 8) | 0xff;
+ dwSten2 = SiS_SFAIL_REPLACE | SiS_SPASS_ZFAIL_REPLACE |
+ SiS_SPASS_ZPASS_REPLACE;
+ dwEnable1 = MASK_ZWriteEnable | MASK_StencilWriteEnable |
+ MASK_StencilTestEnable;
+ dwEnable2 |= MASK_ZMaskWriteEnable;
+ dwDepthMask |= (ctx->Stencil.WriteMask[0] & 0xff) << 24;
+ } else if (bClrDepth) {
+ dwEnable1 = MASK_ZWriteEnable;
+ dwEnable2 |= MASK_ZMaskWriteEnable;
+ }
+
+ if (bClrDepth) {
+ zClearVal = ctx->Depth.Clear;
+ if (ctx->Visual.depthBits != 32)
+ dwDepthMask |= 0x00ffffff;
+ else
+ dwDepthMask = 0xffffffff;
+ } else
+ zClearVal = 0.0;
+
+ mWait3DCmdQueue(9);
+ MMIO(REG_3D_TEnable, dwEnable1);
+ MMIO(REG_3D_TEnable2, dwEnable2);
+ if (bClrDepth || bClrStencil) {
+ MMIO(REG_3D_ZSet, (current->hwZ & ~MASK_ZTestMode) | SiS_Z_COMP_ALWAYS);
+ dirtyflags |= GFLAG_ZSETTING;
+ }
+ if (bClrColor) {
+ MMIO(REG_3D_DstSet, (current->hwDstSet & ~MASK_ROP2) | LOP_COPY);
+ } else {
+ MMIO(REG_3D_DstAlphaWriteMask, 0L);
+ }
+ if (bClrStencil) {
+ MMIO(REG_3D_StencilSet, dwSten1);
+ MMIO(REG_3D_StencilSet2, dwSten2);
+ dirtyflags |= GFLAG_STENCILSETTING;
+ }
+
+ if (mask & BUFFER_BIT_FRONT_LEFT) {
+ pExtents = smesa->driDrawable->pClipRects;
+ count = smesa->driDrawable->numClipRects;
+ } else {
+ pExtents = NULL;
+ count = 1;
+ }
+
+ while(count--) {
+ left = x;
+ right = x + width;
+ top = y;
+ bottom = y + height;
+
+ if (pExtents != NULL) {
+ GLuint x1, y1, x2, y2;
+
+ x1 = pExtents->x1 - smesa->driDrawable->x;
+ y1 = pExtents->y1 - smesa->driDrawable->y;
+ x2 = pExtents->x2 - smesa->driDrawable->x - 1;
+ y2 = pExtents->y2 - smesa->driDrawable->y - 1;
+
+ left = (left > x1) ? left : x1;
+ right = (right > x2) ? x2 : right;
+ top = (top > y1) ? top : y1;
+ bottom = (bottom > y2) ? y2 : bottom;
+ pExtents++;
+ if (left > right || top > bottom)
+ continue;
+ }
+
+ mWait3DCmdQueue(20);
+
+ MMIO(REG_3D_ClipTopBottom, ((GLint)top << 13) | (GLint)bottom);
+ MMIO(REG_3D_ClipLeftRight, ((GLint)left << 13) | (GLint)right);
+
+ /* the first triangle */
+ dwPrimitiveSet = OP_3D_TRIANGLE_DRAW | OP_3D_FIRE_TSARGBc |
+ SHADE_FLAT_VertexC;
+ MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet);
+
+ MMIO(REG_3D_TSZa, *(GLint *) &zClearVal);
+ MMIO(REG_3D_TSXa, *(GLint *) &right);
+ MMIO(REG_3D_TSYa, *(GLint *) &top);
+ MMIO(REG_3D_TSARGBa, smesa->clearColorPattern);
+
+ MMIO(REG_3D_TSZb, *(GLint *) &zClearVal);
+ MMIO(REG_3D_TSXb, *(GLint *) &left);
+ MMIO(REG_3D_TSYb, *(GLint *) &top);
+ MMIO(REG_3D_TSARGBb, smesa->clearColorPattern);
+
+ MMIO(REG_3D_TSZc, *(GLint *) &zClearVal);
+ MMIO(REG_3D_TSXc, *(GLint *) &left);
+ MMIO(REG_3D_TSYc, *(GLint *) &bottom);
+ MMIO(REG_3D_TSARGBc, smesa->clearColorPattern);
+
+ /* second triangle */
+ dwPrimitiveSet = OP_3D_TRIANGLE_DRAW | OP_3D_FIRE_TSARGBb |
+ SHADE_FLAT_VertexB;
+ MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet);
+
+ MMIO(REG_3D_TSZb, *(GLint *) &zClearVal);
+ MMIO(REG_3D_TSXb, *(GLint *) &right);
+ MMIO(REG_3D_TSYb, *(GLint *) &bottom);
+ MMIO(REG_3D_TSARGBb, smesa->clearColorPattern);
+ }
+
+ mEndPrimitive();
+
+ /* If BUFFER_BIT_FRONT_LEFT is set, we've only cleared the front buffer so far */
+ if ((mask & BUFFER_BIT_FRONT_LEFT) != 0 && (mask & BUFFER_BIT_BACK_LEFT) != 0)
+ sis_3D_Clear( ctx, BUFFER_BIT_BACK_LEFT, x, y, width, height );
+
+ smesa->GlobalFlag |= dirtyflags;
+
+ return mask & ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL | BUFFER_BIT_BACK_LEFT |
+ BUFFER_BIT_FRONT_LEFT);
+}
+
+static void
+sis_clear_color_buffer( GLcontext *ctx, GLenum mask, GLint x, GLint y,
+ GLint width, GLint height )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ int count;
+ drm_clip_rect_t *pExtents = NULL;
+ GLint xx, yy;
+ GLint x0, y0, width0, height0;
+
+ /* Clear back buffer */
+ if (mask & BUFFER_BIT_BACK_LEFT) {
+ mWait3DCmdQueue (8);
+ MMIO(REG_SRC_PITCH, (smesa->bytesPerPixel == 4) ?
+ BLIT_DEPTH_32 : BLIT_DEPTH_16);
+ MMIO(REG_DST_X_Y, (x << 16) | y);
+ MMIO(REG_DST_ADDR, smesa->back.offset);
+ MMIO(REG_DST_PITCH_HEIGHT, (smesa->virtualY << 16) | smesa->back.pitch);
+ MMIO(REG_WIDTH_HEIGHT, (height << 16) | width);
+ MMIO(REG_PATFG, smesa->clearColorPattern);
+ MMIO(REG_BLIT_CMD, CMD_DIR_X_INC | CMD_DIR_Y_INC | CMD_ROP_PAT);
+ MMIO(REG_CommandQueue, -1);
+ }
+
+ if ((mask & BUFFER_BIT_FRONT_LEFT) == 0)
+ return;
+
+ /* Clear front buffer */
+ x0 = x;
+ y0 = y;
+ width0 = width;
+ height0 = height;
+
+ pExtents = smesa->driDrawable->pClipRects;
+ count = smesa->driDrawable->numClipRects;
+
+ while (count--) {
+ GLint x2 = pExtents->x1 - smesa->driDrawable->x;
+ GLint y2 = pExtents->y1 - smesa->driDrawable->y;
+ GLint xx2 = pExtents->x2 - smesa->driDrawable->x;
+ GLint yy2 = pExtents->y2 - smesa->driDrawable->y;
+
+ x = (x0 > x2) ? x0 : x2;
+ y = (y0 > y2) ? y0 : y2;
+ xx = ((x0 + width0) > (xx2)) ? xx2 : x0 + width0;
+ yy = ((y0 + height0) > (yy2)) ? yy2 : y0 + height0;
+ width = xx - x;
+ height = yy - y;
+ pExtents++;
+
+ if (width <= 0 || height <= 0)
+ continue;
+
+ mWait3DCmdQueue (8);
+ MMIO(REG_SRC_PITCH, (smesa->bytesPerPixel == 4) ?
+ BLIT_DEPTH_32 : BLIT_DEPTH_16);
+ MMIO(REG_DST_X_Y, (x << 16) | y);
+ MMIO(REG_DST_ADDR, smesa->front.offset);
+ MMIO(REG_DST_PITCH_HEIGHT, (smesa->virtualY << 16) | smesa->front.pitch);
+ MMIO(REG_WIDTH_HEIGHT, (height << 16) | width);
+ MMIO(REG_PATFG, smesa->clearColorPattern);
+ MMIO(REG_BLIT_CMD, CMD_DIR_X_INC | CMD_DIR_Y_INC | CMD_ROP_PAT);
+ MMIO(REG_CommandQueue, -1);
+ }
+}
+
+static void
+sis_clear_z_stencil_buffer( GLcontext * ctx, GLbitfield mask,
+ GLint x, GLint y, GLint width, GLint height )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ int cmd;
+
+ mWait3DCmdQueue (8);
+ MMIO(REG_SRC_PITCH, (smesa->zFormat == SiS_ZFORMAT_Z16) ?
+ BLIT_DEPTH_16 : BLIT_DEPTH_32);
+ MMIO(REG_DST_X_Y, (x << 16) | y);
+ MMIO(REG_DST_ADDR, smesa->depth.offset);
+ MMIO(REG_DST_PITCH_HEIGHT, (smesa->virtualY << 16) | smesa->depth.pitch);
+ MMIO(REG_WIDTH_HEIGHT, (height << 16) | width);
+ MMIO(REG_PATFG, smesa->clearZStencilPattern);
+ MMIO(REG_BLIT_CMD, CMD_DIR_X_INC | CMD_DIR_Y_INC | CMD_ROP_PAT);
+ MMIO(REG_CommandQueue, -1);
+}
+
diff --git a/src/sis_context.c b/src/sis_context.c
new file mode 100644
index 0000000..b21df0a
--- /dev/null
+++ b/src/sis_context.c
@@ -0,0 +1,728 @@
+/**************************************************************************
+
+Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
+
+**************************************************************************/
+/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_ctx.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */
+
+/*
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "sis_dri.h"
+
+#include "sis_context.h"
+#include "sis_state.h"
+#include "sis_dd.h"
+#include "sis_span.h"
+#include "sis_stencil.h"
+#include "sis_tex.h"
+#include "sis_tris.h"
+#include "sis_alloc.h"
+
+#include "imports.h"
+#include "matrix.h"
+#include "extensions.h"
+#include "utils.h"
+#include "framebuffer.h"
+
+#include "drivers/common/driverfuncs.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "vbo/vbo.h"
+
+#include "tnl/tnl.h"
+#include "tnl/t_pipeline.h"
+
+#define need_GL_ARB_multisample
+#define need_GL_ARB_texture_compression
+#define need_GL_ARB_vertex_buffer_object
+#define need_GL_EXT_fog_coord
+#define need_GL_EXT_secondary_color
+#include "extension_helper.h"
+
+#ifndef SIS_DEBUG
+int SIS_DEBUG = 0;
+#endif
+
+int GlobalCurrentHwcx = -1;
+int GlobalHwcxCountBase = 1;
+int GlobalCmdQueueLen = 0;
+
+struct dri_extension card_extensions[] =
+{
+ { "GL_ARB_multisample", GL_ARB_multisample_functions },
+ { "GL_ARB_multitexture", NULL },
+ { "GL_ARB_texture_border_clamp", NULL },
+ { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
+ { "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_texture_lod_bias", NULL },
+ { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
+ { "GL_EXT_stencil_wrap", NULL },
+ { "GL_MESA_ycbcr_texture", NULL },
+ { "GL_NV_blend_square", NULL },
+ { NULL, NULL }
+};
+
+struct dri_extension card_extensions_6326[] =
+{
+ { "GL_ARB_multisample", GL_ARB_multisample_functions },
+ /*{ "GL_ARB_texture_border_clamp", NULL },*/
+ { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
+ /*{ "GL_ARB_texture_mirrored_repeat", NULL },*/
+ /*{ "GL_MESA_ycbcr_texture", NULL },*/
+ { NULL, NULL }
+};
+
+static const struct dri_debug_control debug_control[] =
+{
+ { "fall", DEBUG_FALLBACKS },
+ { NULL, 0 }
+};
+
+void
+WaitEngIdle (sisContextPtr smesa)
+{
+ GLuint engineState;
+
+ if (smesa->is6326) {
+ do {
+ engineState = MMIO_READ(REG_3D_EngineFire); /* XXX right reg? */
+ } while ((engineState & ENG_3DIDLEQE) != 0);
+ } else {
+ do {
+ engineState = MMIO_READ(REG_CommandQueue);
+ } while ((engineState & SiS_EngIdle) != SiS_EngIdle);
+ }
+}
+
+void
+Wait2DEngIdle (sisContextPtr smesa)
+{
+ GLuint engineState;
+
+ if (smesa->is6326) {
+ do {
+ engineState = MMIO_READ(REG_6326_BitBlt_Cmd);
+ } while ((engineState & BLT_BUSY) != 0);
+ } else {
+ do {
+ engineState = MMIO_READ(REG_CommandQueue);
+ } while ((engineState & SiS_EngIdle2d) != SiS_EngIdle2d);
+ }
+}
+
+/* To be called from mWait3DCmdQueue. Separate function for profiling
+ * purposes, and speed doesn't matter because we're spinning anyway.
+ */
+void
+WaitingFor3dIdle(sisContextPtr smesa, int wLen)
+{
+ if (smesa->is6326) {
+ while (*(smesa->CurrentQueueLenPtr) < wLen) {
+ *(smesa->CurrentQueueLenPtr) =
+ ((GLuint)MMIO_READ(REG_3D_EngineFire) >> 16) * 2;
+ }
+ } else {
+ while (*(smesa->CurrentQueueLenPtr) < wLen) {
+ *(smesa->CurrentQueueLenPtr) =
+ (MMIO_READ(REG_CommandQueue) & MASK_QueueLen) - 20;
+ }
+ }
+}
+
+void sisReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer,
+ GLuint width, GLuint height)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ sisUpdateBufferSize(smesa);
+
+ _mesa_resize_framebuffer(ctx, drawbuffer, width, height);
+}
+
+GLboolean
+sisCreateContext( const __GLcontextModes *glVisual,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate )
+{
+ GLcontext *ctx, *shareCtx;
+ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+ sisContextPtr smesa;
+ sisScreenPtr sisScreen;
+ int i;
+ struct dd_function_table functions;
+
+ smesa = (sisContextPtr)CALLOC( sizeof(*smesa) );
+ if (smesa == NULL)
+ return GL_FALSE;
+
+ /* Init default driver functions then plug in our SIS-specific functions
+ * (the texture functions are especially important)
+ */
+ _mesa_init_driver_functions(&functions);
+ sisInitDriverFuncs(&functions);
+ sisInitTextureFuncs(&functions);
+
+ /* Allocate the Mesa context */
+ if (sharedContextPrivate)
+ shareCtx = ((sisContextPtr)sharedContextPrivate)->glCtx;
+ else
+ shareCtx = NULL;
+ smesa->glCtx = _mesa_create_context( glVisual, shareCtx,
+ &functions, (void *) smesa);
+ if (!smesa->glCtx) {
+ FREE(smesa);
+ return GL_FALSE;
+ }
+ driContextPriv->driverPrivate = smesa;
+ ctx = smesa->glCtx;
+
+ sisScreen = smesa->sisScreen = (sisScreenPtr)(sPriv->private);
+
+ smesa->is6326 = GL_FALSE; /* XXX */
+ smesa->driContext = driContextPriv;
+ smesa->driScreen = sPriv;
+ smesa->driDrawable = NULL;
+ smesa->hHWContext = driContextPriv->hHWContext;
+ smesa->driHwLock = &sPriv->pSAREA->lock;
+ smesa->driFd = sPriv->fd;
+
+ smesa->virtualX = sisScreen->screenX;
+ smesa->virtualY = sisScreen->screenY;
+ smesa->bytesPerPixel = sisScreen->cpp;
+ smesa->IOBase = sisScreen->mmio.map;
+ smesa->Chipset = sisScreen->deviceID;
+
+ smesa->FbBase = sPriv->pFB;
+ smesa->displayWidth = sPriv->fbWidth;
+ smesa->front.pitch = sPriv->fbStride;
+
+ smesa->sarea = (SISSAREAPriv *)((char *)sPriv->pSAREA +
+ sisScreen->sarea_priv_offset);
+
+ /* support ARGB8888 and RGB565 */
+ switch (smesa->bytesPerPixel)
+ {
+ case 4:
+ smesa->redMask = 0x00ff0000;
+ smesa->greenMask = 0x0000ff00;
+ smesa->blueMask = 0x000000ff;
+ smesa->alphaMask = 0xff000000;
+ smesa->colorFormat = DST_FORMAT_ARGB_8888;
+ break;
+ case 2:
+ smesa->redMask = 0xf800;
+ smesa->greenMask = 0x07e0;
+ smesa->blueMask = 0x001f;
+ smesa->alphaMask = 0;
+ smesa->colorFormat = DST_FORMAT_RGB_565;
+ break;
+ default:
+ sis_fatal_error("Bad bytesPerPixel %d.\n", smesa->bytesPerPixel);
+ }
+
+ if (smesa->is6326) {
+ ctx->Const.MaxTextureUnits = 1;
+ ctx->Const.MaxTextureLevels = 9;
+ } else {
+ ctx->Const.MaxTextureUnits = 2;
+ ctx->Const.MaxTextureLevels = 11;
+ }
+ ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
+ ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
+
+ /* Parse configuration files */
+ driParseConfigFiles (&smesa->optionCache, &sisScreen->optionCache,
+ sisScreen->driScreen->myNum, "sis");
+
+#if DO_DEBUG
+ SIS_DEBUG = driParseDebugString(getenv("SIS_DEBUG"), debug_control);
+#endif
+
+ /* TODO: index mode */
+
+ smesa->CurrentQueueLenPtr = &(smesa->sarea->QueueLength);
+ smesa->FrameCountPtr = &(smesa->sarea->FrameCount);
+
+ /* set AGP */
+ smesa->AGPSize = sisScreen->agp.size;
+ smesa->AGPBase = sisScreen->agp.map;
+ smesa->AGPAddr = sisScreen->agpBaseOffset;
+
+ /* Create AGP command buffer */
+ if (smesa->AGPSize != 0 &&
+ !driQueryOptionb(&smesa->optionCache, "agp_disable"))
+ {
+ smesa->vb = sisAllocAGP(smesa, 64 * 1024, &smesa->vb_agp_handle);
+ if (smesa->vb != NULL) {
+ smesa->using_agp = GL_TRUE;
+ smesa->vb_cur = smesa->vb;
+ smesa->vb_last = smesa->vb;
+ smesa->vb_end = smesa->vb + 64 * 1024;
+ smesa->vb_agp_offset = ((long)smesa->vb - (long)smesa->AGPBase +
+ (long)smesa->AGPAddr);
+ }
+ }
+ if (!smesa->using_agp) {
+ smesa->vb = malloc(64 * 1024);
+ if (smesa->vb == NULL) {
+ FREE(smesa);
+ return GL_FALSE;
+ }
+ smesa->vb_cur = smesa->vb;
+ smesa->vb_last = smesa->vb;
+ smesa->vb_end = smesa->vb + 64 * 1024;
+ }
+
+ smesa->GlobalFlag = 0L;
+
+ smesa->Fallback = 0;
+
+ /* Initialize the software rasterizer and helper modules.
+ */
+ _swrast_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
+ _tnl_CreateContext( ctx );
+ _swsetup_CreateContext( ctx );
+
+ _swrast_allow_pixel_fog( ctx, GL_TRUE );
+ _swrast_allow_vertex_fog( ctx, GL_FALSE );
+ _tnl_allow_pixel_fog( ctx, GL_TRUE );
+ _tnl_allow_vertex_fog( ctx, GL_FALSE );
+
+ /* XXX these should really go right after _mesa_init_driver_functions() */
+ if (smesa->is6326) {
+ sis6326DDInitStateFuncs( ctx );
+ sis6326DDInitState( smesa ); /* Initializes smesa->zFormat, important */
+ } else {
+ sisDDInitStateFuncs( ctx );
+ sisDDInitState( smesa ); /* Initializes smesa->zFormat, important */
+ sisDDInitStencilFuncs( ctx );
+ }
+ sisInitTriFuncs( ctx );
+ sisDDInitSpanFuncs( ctx );
+
+ driInitExtensions( ctx, card_extensions, GL_FALSE );
+
+ for (i = 0; i < SIS_MAX_TEXTURES; i++) {
+ smesa->TexStates[i] = 0;
+ smesa->PrevTexFormat[i] = 0;
+ }
+
+ if (driQueryOptionb(&smesa->optionCache, "no_rast")) {
+ fprintf(stderr, "disabling 3D acceleration\n");
+ FALLBACK(smesa, SIS_FALLBACK_DISABLE, 1);
+ }
+ smesa->texture_depth = driQueryOptioni(&smesa->optionCache, "texture_depth");
+
+ return GL_TRUE;
+}
+
+void
+sisDestroyContext ( __DRIcontextPrivate *driContextPriv )
+{
+ sisContextPtr smesa = (sisContextPtr)driContextPriv->driverPrivate;
+
+ assert( smesa != NULL );
+
+ if ( smesa != NULL ) {
+ _swsetup_DestroyContext( smesa->glCtx );
+ _tnl_DestroyContext( smesa->glCtx );
+ _vbo_DestroyContext( smesa->glCtx );
+ _swrast_DestroyContext( smesa->glCtx );
+
+ if (smesa->using_agp)
+ sisFreeAGP(smesa, smesa->vb_agp_handle);
+
+ /* free the Mesa context */
+ /* XXX: Is the next line needed? The DriverCtx (smesa) reference is
+ * needed for sisDDDeleteTexture, since it needs to call the FB/AGP free
+ * function.
+ */
+ /* smesa->glCtx->DriverCtx = NULL; */
+ _mesa_destroy_context(smesa->glCtx);
+ }
+
+ FREE( smesa );
+}
+
+GLboolean
+sisMakeCurrent( __DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv )
+{
+ if ( driContextPriv ) {
+ GET_CURRENT_CONTEXT(ctx);
+ sisContextPtr oldSisCtx = ctx ? SIS_CONTEXT(ctx) : NULL;
+ sisContextPtr newSisCtx = (sisContextPtr) driContextPriv->driverPrivate;
+ struct gl_framebuffer *drawBuffer, *readBuffer;
+
+ if ( newSisCtx != oldSisCtx) {
+ newSisCtx->GlobalFlag = GFLAG_ALL;
+ }
+
+ newSisCtx->driDrawable = driDrawPriv;
+
+ drawBuffer = (GLframebuffer *)driDrawPriv->driverPrivate;
+ readBuffer = (GLframebuffer *)driReadPriv->driverPrivate;
+
+ _mesa_make_current( newSisCtx->glCtx, drawBuffer, readBuffer );
+
+ sisUpdateBufferSize( newSisCtx );
+ sisUpdateClipping( newSisCtx->glCtx );
+ } else {
+ _mesa_make_current( NULL, NULL, NULL );
+ }
+
+ return GL_TRUE;
+}
+
+GLboolean
+sisUnbindContext( __DRIcontextPrivate *driContextPriv )
+{
+ return GL_TRUE;
+}
+
+void
+sis_update_render_state( sisContextPtr smesa )
+{
+ __GLSiSHardware *prev = &smesa->prev;
+
+ mWait3DCmdQueue (45);
+
+ if (smesa->GlobalFlag & GFLAG_ENABLESETTING) {
+ if (!smesa->clearTexCache) {
+ MMIO(REG_3D_TEnable, prev->hwCapEnable);
+ } else {
+ MMIO(REG_3D_TEnable, prev->hwCapEnable | MASK_TextureCacheClear);
+ MMIO(REG_3D_TEnable, prev->hwCapEnable);
+ smesa->clearTexCache = GL_FALSE;
+ }
+ }
+
+ if (smesa->GlobalFlag & GFLAG_ENABLESETTING2)
+ MMIO(REG_3D_TEnable2, prev->hwCapEnable2);
+
+ /* Z Setting */
+ if (smesa->GlobalFlag & GFLAG_ZSETTING)
+ {
+ MMIO(REG_3D_ZSet, prev->hwZ);
+ MMIO(REG_3D_ZStWriteMask, prev->hwZMask);
+ MMIO(REG_3D_ZAddress, prev->hwOffsetZ);
+ }
+
+ /* Alpha Setting */
+ if (smesa->GlobalFlag & GFLAG_ALPHASETTING)
+ MMIO(REG_3D_AlphaSet, prev->hwAlpha);
+
+ if (smesa->GlobalFlag & GFLAG_DESTSETTING) {
+ MMIO(REG_3D_DstSet, prev->hwDstSet);
+ MMIO(REG_3D_DstAlphaWriteMask, prev->hwDstMask);
+ MMIO(REG_3D_DstAddress, prev->hwOffsetDest);
+ }
+
+ /* Line Setting */
+#if 0
+ if (smesa->GlobalFlag & GFLAG_LINESETTING)
+ MMIO(REG_3D_LinePattern, prev->hwLinePattern);
+#endif
+
+ /* Fog Setting */
+ if (smesa->GlobalFlag & GFLAG_FOGSETTING)
+ {
+ MMIO(REG_3D_FogSet, prev->hwFog);
+ MMIO(REG_3D_FogInverseDistance, prev->hwFogInverse);
+ MMIO(REG_3D_FogFarDistance, prev->hwFogFar);
+ MMIO(REG_3D_FogFactorDensity, prev->hwFogDensity);
+ }
+
+ /* Stencil Setting */
+ if (smesa->GlobalFlag & GFLAG_STENCILSETTING) {
+ MMIO(REG_3D_StencilSet, prev->hwStSetting);
+ MMIO(REG_3D_StencilSet2, prev->hwStSetting2);
+ }
+
+ /* Miscellaneous Setting */
+ if (smesa->GlobalFlag & GFLAG_DSTBLEND)
+ MMIO(REG_3D_DstBlendMode, prev->hwDstSrcBlend);
+ if (smesa->GlobalFlag & GFLAG_CLIPPING) {
+ MMIO(REG_3D_ClipTopBottom, prev->clipTopBottom);
+ MMIO(REG_3D_ClipLeftRight, prev->clipLeftRight);
+ }
+
+ smesa->GlobalFlag &= ~GFLAG_RENDER_STATES;
+}
+
+void
+sis_update_texture_state (sisContextPtr smesa)
+{
+ __GLSiSHardware *prev = &smesa->prev;
+
+ mWait3DCmdQueue (55);
+ if (smesa->clearTexCache || (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS)) {
+ MMIO(REG_3D_TEnable, prev->hwCapEnable | MASK_TextureCacheClear);
+ MMIO(REG_3D_TEnable, prev->hwCapEnable);
+ smesa->clearTexCache = GL_FALSE;
+ }
+
+ /* Texture Setting */
+ if (smesa->GlobalFlag & CFLAG_TEXTURERESET)
+ MMIO(REG_3D_TextureSet, prev->texture[0].hwTextureSet);
+
+ if (smesa->GlobalFlag & GFLAG_TEXTUREMIPMAP)
+ MMIO(REG_3D_TextureMip, prev->texture[0].hwTextureMip);
+
+ /*
+ MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
+ MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
+ */
+
+ if (smesa->GlobalFlag & GFLAG_TEXBORDERCOLOR)
+ MMIO(REG_3D_TextureBorderColor, prev->texture[0].hwTextureBorderColor);
+
+ if (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS) {
+ switch ((prev->texture[0].hwTextureSet & MASK_TextureLevel) >> 8)
+ {
+ case 11:
+ MMIO(REG_3D_TextureAddress11, prev->texture[0].texOffset11);
+ case 10:
+ MMIO(REG_3D_TextureAddress10, prev->texture[0].texOffset10);
+ MMIO(REG_3D_TexturePitch10, prev->texture[0].texPitch10);
+ case 9:
+ MMIO(REG_3D_TextureAddress9, prev->texture[0].texOffset9);
+ case 8:
+ MMIO(REG_3D_TextureAddress8, prev->texture[0].texOffset8);
+ MMIO(REG_3D_TexturePitch8, prev->texture[0].texPitch89);
+ case 7:
+ MMIO(REG_3D_TextureAddress7, prev->texture[0].texOffset7);
+ case 6:
+ MMIO(REG_3D_TextureAddress6, prev->texture[0].texOffset6);
+ MMIO(REG_3D_TexturePitch6, prev->texture[0].texPitch67);
+ case 5:
+ MMIO(REG_3D_TextureAddress5, prev->texture[0].texOffset5);
+ case 4:
+ MMIO(REG_3D_TextureAddress4, prev->texture[0].texOffset4);
+ MMIO(REG_3D_TexturePitch4, prev->texture[0].texPitch45);
+ case 3:
+ MMIO(REG_3D_TextureAddress3, prev->texture[0].texOffset3);
+ case 2:
+ MMIO(REG_3D_TextureAddress2, prev->texture[0].texOffset2);
+ MMIO(REG_3D_TexturePitch2, prev->texture[0].texPitch23);
+ case 1:
+ MMIO(REG_3D_TextureAddress1, prev->texture[0].texOffset1);
+ case 0:
+ MMIO(REG_3D_TextureAddress0, prev->texture[0].texOffset0);
+ MMIO(REG_3D_TexturePitch0, prev->texture[0].texPitch01);
+ }
+ }
+ if (smesa->GlobalFlag & CFLAG_TEXTURERESET_1)
+ MMIO(REG_3D_Texture1Set, prev->texture[1].hwTextureSet);
+ if (smesa->GlobalFlag & GFLAG_TEXTUREMIPMAP_1)
+ MMIO(REG_3D_Texture1Mip, prev->texture[1].hwTextureMip);
+
+ if (smesa->GlobalFlag & GFLAG_TEXBORDERCOLOR_1) {
+ MMIO(REG_3D_Texture1BorderColor,
+ prev->texture[1].hwTextureBorderColor);
+ }
+ if (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS_1) {
+ switch ((prev->texture[1].hwTextureSet & MASK_TextureLevel) >> 8)
+ {
+ case 11:
+ MMIO(REG_3D_Texture1Address11, prev->texture[1].texOffset11);
+ case 10:
+ MMIO(REG_3D_Texture1Address10, prev->texture[1].texOffset10);
+ MMIO(REG_3D_Texture1Pitch10, prev->texture[1].texPitch10);
+ case 9:
+ MMIO(REG_3D_Texture1Address9, prev->texture[1].texOffset9);
+ case 8:
+ MMIO(REG_3D_Texture1Address8, prev->texture[1].texOffset8);
+ MMIO(REG_3D_Texture1Pitch8, prev->texture[1].texPitch89);
+ case 7:
+ MMIO(REG_3D_Texture1Address7, prev->texture[1].texOffset7);
+ case 6:
+ MMIO(REG_3D_Texture1Address6, prev->texture[1].texOffset6);
+ MMIO(REG_3D_Texture1Pitch6, prev->texture[1].texPitch67);
+ case 5:
+ MMIO(REG_3D_Texture1Address5, prev->texture[1].texOffset5);
+ case 4:
+ MMIO(REG_3D_Texture1Address4, prev->texture[1].texOffset4);
+ MMIO(REG_3D_Texture1Pitch4, prev->texture[1].texPitch45);
+ case 3:
+ MMIO(REG_3D_Texture1Address3, prev->texture[1].texOffset3);
+ case 2:
+ MMIO(REG_3D_Texture1Address2, prev->texture[1].texOffset2);
+ MMIO(REG_3D_Texture1Pitch2, prev->texture[1].texPitch23);
+ case 1:
+ MMIO(REG_3D_Texture1Address1, prev->texture[1].texOffset1);
+ case 0:
+ MMIO(REG_3D_Texture1Address0, prev->texture[1].texOffset0);
+ MMIO(REG_3D_Texture1Pitch0, prev->texture[1].texPitch01);
+ }
+ }
+
+ /* texture environment */
+ if (smesa->GlobalFlag & GFLAG_TEXTUREENV) {
+ MMIO(REG_3D_TextureBlendFactor, prev->hwTexEnvColor);
+ MMIO(REG_3D_TextureColorBlendSet0, prev->hwTexBlendColor0);
+ MMIO(REG_3D_TextureAlphaBlendSet0, prev->hwTexBlendAlpha0);
+ }
+ if (smesa->GlobalFlag & GFLAG_TEXTUREENV_1) {
+ MMIO(REG_3D_TextureBlendFactor, prev->hwTexEnvColor);
+ MMIO(REG_3D_TextureColorBlendSet1, prev->hwTexBlendColor1);
+ MMIO(REG_3D_TextureAlphaBlendSet1, prev->hwTexBlendAlpha1);
+ }
+
+ smesa->GlobalFlag &= ~GFLAG_TEXTURE_STATES;
+}
+
+void
+sis6326_update_render_state( sisContextPtr smesa )
+{
+ __GLSiSHardware *prev = &smesa->prev;
+
+ mWait3DCmdQueue (45);
+
+ if (smesa->GlobalFlag & GFLAG_ENABLESETTING) {
+ if (!smesa->clearTexCache) {
+ MMIO(REG_6326_3D_TEnable, prev->hwCapEnable);
+ } else {
+ MMIO(REG_6326_3D_TEnable, prev->hwCapEnable & ~S_ENABLE_TextureCache);
+ MMIO(REG_6326_3D_TEnable, prev->hwCapEnable);
+ smesa->clearTexCache = GL_FALSE;
+ }
+ }
+
+ /* Z Setting */
+ if (smesa->GlobalFlag & GFLAG_ZSETTING) {
+ MMIO(REG_6326_3D_ZSet, prev->hwZ);
+ MMIO(REG_6326_3D_ZAddress, prev->hwOffsetZ);
+ }
+
+ /* Alpha Setting */
+ if (smesa->GlobalFlag & GFLAG_ALPHASETTING)
+ MMIO(REG_6326_3D_AlphaSet, prev->hwAlpha);
+
+ if (smesa->GlobalFlag & GFLAG_DESTSETTING) {
+ MMIO(REG_6326_3D_DstSet, prev->hwDstSet);
+ MMIO(REG_6326_3D_DstAddress, prev->hwOffsetDest);
+ }
+
+ /* Fog Setting */
+ if (smesa->GlobalFlag & GFLAG_FOGSETTING) {
+ MMIO(REG_6326_3D_FogSet, prev->hwFog);
+ }
+
+ /* Miscellaneous Setting */
+ if (smesa->GlobalFlag & GFLAG_DSTBLEND)
+ MMIO(REG_6326_3D_DstSrcBlendMode, prev->hwDstSrcBlend);
+
+ if (smesa->GlobalFlag & GFLAG_CLIPPING) {
+ MMIO(REG_6326_3D_ClipTopBottom, prev->clipTopBottom);
+ MMIO(REG_6326_3D_ClipLeftRight, prev->clipLeftRight);
+ }
+
+ smesa->GlobalFlag &= ~GFLAG_RENDER_STATES;
+}
+
+void
+sis6326_update_texture_state (sisContextPtr smesa)
+{
+ __GLSiSHardware *prev = &smesa->prev;
+
+ mWait3DCmdQueue (55);
+ if (smesa->clearTexCache || (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS)) {
+ MMIO(REG_6326_3D_TEnable, prev->hwCapEnable & ~S_ENABLE_TextureCache);
+ MMIO(REG_6326_3D_TEnable, prev->hwCapEnable);
+ smesa->clearTexCache = GL_FALSE;
+ }
+
+ /* Texture Setting */
+ if (smesa->GlobalFlag & CFLAG_TEXTURERESET)
+ MMIO(REG_6326_3D_TextureSet, prev->texture[0].hwTextureSet);
+
+ if (smesa->GlobalFlag & GFLAG_TEXTUREMIPMAP)
+ MMIO(REG_6326_3D_TextureWidthHeight, prev->texture[0].hwTexWidthHeight);
+
+ /*
+ MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
+ MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
+ */
+
+ if (smesa->GlobalFlag & GFLAG_TEXBORDERCOLOR)
+ MMIO(REG_6326_3D_TextureBorderColor, prev->texture[0].hwTextureBorderColor);
+
+ if (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS) {
+ switch ((prev->texture[0].hwTextureSet & MASK_6326_TextureLevel) >> 8)
+ {
+ case 9:
+ MMIO(REG_6326_3D_TextureAddress9, prev->texture[0].texOffset9);
+ /* FALLTHROUGH */
+ case 8:
+ MMIO(REG_6326_3D_TextureAddress8, prev->texture[0].texOffset8);
+ MMIO(REG_6326_3D_TexturePitch89, prev->texture[0].texPitch89);
+ /* FALLTHROUGH */
+ case 7:
+ MMIO(REG_6326_3D_TextureAddress7, prev->texture[0].texOffset7);
+ /* FALLTHROUGH */
+ case 6:
+ MMIO(REG_6326_3D_TextureAddress6, prev->texture[0].texOffset6);
+ MMIO(REG_6326_3D_TexturePitch67, prev->texture[0].texPitch67);
+ /* FALLTHROUGH */
+ case 5:
+ MMIO(REG_6326_3D_TextureAddress5, prev->texture[0].texOffset5);
+ /* FALLTHROUGH */
+ case 4:
+ MMIO(REG_6326_3D_TextureAddress4, prev->texture[0].texOffset4);
+ MMIO(REG_6326_3D_TexturePitch45, prev->texture[0].texPitch45);
+ /* FALLTHROUGH */
+ case 3:
+ MMIO(REG_6326_3D_TextureAddress3, prev->texture[0].texOffset3);
+ /* FALLTHROUGH */
+ case 2:
+ MMIO(REG_6326_3D_TextureAddress2, prev->texture[0].texOffset2);
+ MMIO(REG_6326_3D_TexturePitch23, prev->texture[0].texPitch23);
+ /* FALLTHROUGH */
+ case 1:
+ MMIO(REG_6326_3D_TextureAddress1, prev->texture[0].texOffset1);
+ /* FALLTHROUGH */
+ case 0:
+ MMIO(REG_6326_3D_TextureAddress0, prev->texture[0].texOffset0);
+ MMIO(REG_6326_3D_TexturePitch01, prev->texture[0].texPitch01);
+ break;
+ }
+ }
+
+ /* texture environment */
+ if (smesa->GlobalFlag & GFLAG_TEXTUREENV) {
+ MMIO(REG_6326_3D_TextureBlendSet, prev->hwTexBlendSet);
+ }
+
+ smesa->GlobalFlag &= ~GFLAG_TEXTURE_STATES;
+}
diff --git a/src/sis_context.h b/src/sis_context.h
new file mode 100644
index 0000000..c349bf9
--- /dev/null
+++ b/src/sis_context.h
@@ -0,0 +1,477 @@
+/**************************************************************************
+
+Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
+
+**************************************************************************/
+/* $XFree86$ */
+
+/*
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#ifndef _sis_ctx_h_
+#define _sis_ctx_h_
+
+#include "context.h"
+#include "dri_util.h"
+#include "drm.h"
+#include "drm_sarea.h"
+#include "xmlconfig.h"
+#include "tnl/t_vertex.h"
+
+#include "sis_screen.h"
+#include "sis_reg.h"
+#include "sis6326_reg.h"
+#include "sis_dri.h"
+
+/* for GLboolean */
+#include <GL/gl.h>
+
+#define PCI_CHIP_SIS300 0x0300
+#define PCI_CHIP_SIS630 0x6300
+#define PCI_CHIP_SIS540 0x5300
+
+#define NEW_TEXTURING 0x1
+#define NEW_TEXTURE_ENV 0x2
+
+/* Flags for software fallback cases:
+ */
+#define SIS_FALLBACK_TEXTURE 0x0001
+#define SIS_FALLBACK_TEXTURE0 0x0002
+#define SIS_FALLBACK_TEXTURE1 0x0004
+#define SIS_FALLBACK_TEXENV0 0x0008
+#define SIS_FALLBACK_TEXENV1 0x0010
+#define SIS_FALLBACK_DRAW_BUFFER 0x0020
+#define SIS_FALLBACK_STENCIL 0x0040
+#define SIS_FALLBACK_WRITEMASK 0x0080
+#define SIS_FALLBACK_DISABLE 0x0100
+
+/* Flags for hardware state that needs to be updated */
+#define GFLAG_ENABLESETTING 0x00000001
+#define GFLAG_ENABLESETTING2 0x00000002
+#define GFLAG_ZSETTING 0x00000004
+#define GFLAG_ALPHASETTING 0x00000008
+#define GFLAG_DESTSETTING 0x00000010
+#define GFLAG_LINESETTING 0x00000020
+#define GFLAG_STENCILSETTING 0x00000040
+#define GFLAG_FOGSETTING 0x00000080
+#define GFLAG_DSTBLEND 0x00000100
+#define GFLAG_CLIPPING 0x00000200
+#define CFLAG_TEXTURERESET 0x00000400
+#define GFLAG_TEXTUREMIPMAP 0x00000800
+#define GFLAG_TEXBORDERCOLOR 0x00001000
+#define GFLAG_TEXTUREADDRESS 0x00002000
+#define GFLAG_TEXTUREENV 0x00004000
+#define CFLAG_TEXTURERESET_1 0x00008000
+#define GFLAG_TEXTUREMIPMAP_1 0x00010000
+#define GFLAG_TEXBORDERCOLOR_1 0x00020000
+#define GFLAG_TEXTUREADDRESS_1 0x00040000
+#define GFLAG_TEXTUREENV_1 0x00080000
+#define GFLAG_ALL 0x000fffff
+
+#define GFLAG_TEXTURE_STATES (CFLAG_TEXTURERESET | GFLAG_TEXTUREMIPMAP | \
+ GFLAG_TEXBORDERCOLOR | GFLAG_TEXTUREADDRESS | \
+ CFLAG_TEXTURERESET_1 | GFLAG_TEXTUREMIPMAP_1 | \
+ GFLAG_TEXBORDERCOLOR_1 | \
+ GFLAG_TEXTUREADDRESS_1 | \
+ GFLAG_TEXTUREENV | GFLAG_TEXTUREENV_1)
+
+
+#define GFLAG_RENDER_STATES (GFLAG_ENABLESETTING | GFLAG_ENABLESETTING2 | \
+ GFLAG_ZSETTING | GFLAG_ALPHASETTING | \
+ GFLAG_DESTSETTING | GFLAG_FOGSETTING | \
+ GFLAG_STENCILSETTING | GFLAG_DSTBLEND | \
+ GFLAG_CLIPPING)
+
+/* Use the templated vertex format:
+ */
+#define TAG(x) sis##x
+#include "tnl_dd/t_dd_vertex.h"
+#undef TAG
+
+/* Subpixel offsets for window coordinates (triangles):
+ */
+#define SUBPIXEL_X (-0.5F)
+#define SUBPIXEL_Y (-0.5F)
+
+#define SIS_MAX_TEXTURE_SIZE 2048
+#define SIS_MAX_TEXTURES 2
+#define SIS_MAX_TEXTURE_LEVELS 11
+#define SIS_MAX_FRAME_LENGTH 3
+
+typedef struct {
+ GLubyte *Data; /* Pointer to texture in offscreen */
+ GLuint memType; /* VIDEO_TYPE or AGP_TYPE */
+ void *handle; /* Handle for sisFree*() */
+ GLuint pitch;
+ GLuint size;
+} sisTexImage;
+
+typedef struct sis_tex_obj {
+ sisTexImage image[SIS_MAX_TEXTURE_LEVELS]; /* Image data for each mipmap
+ * level */
+ GLenum format; /* One of GL_ALPHA, GL_INTENSITY, GL_LUMINANCE,
+ * GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA
+ * MESA_YCBCR */
+ GLint hwformat; /* One of the TEXEL_ defines */
+ GLint numImages; /* Number of images loaded into .image */
+} sisTexObj, *sisTexObjPtr;
+
+/*
+ ** Device dependent context state
+ */
+typedef struct __GLSiSTextureRec
+{
+ GLint hwTextureSet;
+ GLint hwTextureMip;
+ GLint hwTextureClrHigh;
+ GLint hwTextureClrLow;
+ GLint hwTexWidthHeight; /* 6326: Texture Blending Setting */
+ GLint hwTextureBorderColor;
+
+ GLint texOffset0;
+ GLint texOffset1;
+ GLint texOffset2;
+ GLint texOffset3;
+ GLint texOffset4;
+ GLint texOffset5;
+ GLint texOffset6;
+ GLint texOffset7;
+ GLint texOffset8;
+ GLint texOffset9;
+ GLint texOffset10;
+ GLint texOffset11;
+
+ GLint texPitch01;
+ GLint texPitch23;
+ GLint texPitch45;
+ GLint texPitch67;
+ GLint texPitch89;
+ GLint texPitch10;
+} __GLSiSTexture;
+
+typedef struct __GLSiSHardwareRec
+{
+ GLint hwCapEnable, hwCapEnable2; /* Enable Setting */
+
+ GLint hwOffsetZ, hwZ; /* Z Setting */
+
+ GLint hwZBias, hwZMask; /* Z Setting */
+
+ GLint hwAlpha; /* Alpha Setting */
+
+ GLint hwDstSet, hwDstMask; /* Destination Setting */
+
+ GLint hwOffsetDest; /* Destination Setting */
+
+ GLint hwLinePattern; /* Line Setting */
+
+ GLint hwFog; /* Fog Setting */
+
+ GLint hwFogFar, hwFogInverse; /* Fog Distance setting */
+
+ GLint hwFogDensity; /* Fog factor & density */
+
+ GLint hwStSetting, hwStSetting2; /* Stencil Setting */
+
+ GLint hwStOffset; /* Stencil Setting */
+
+ GLint hwDstSrcBlend; /* Blending mode Setting */
+
+ GLint clipTopBottom; /* Clip for Top & Bottom */
+
+ GLint clipLeftRight; /* Clip for Left & Right */
+
+ struct __GLSiSTextureRec texture[2];
+
+ GLint hwTexEnvColor; /* Texture Blending Setting */
+
+ GLint hwTexBlendSet; /* 6326 */
+ GLint hwTexBlendColor0;
+ GLint hwTexBlendColor1;
+ GLint hwTexBlendAlpha0;
+ GLint hwTexBlendAlpha1;
+
+}
+__GLSiSHardware;
+
+typedef struct sis_context sisContextRec;
+typedef struct sis_context *sisContextPtr;
+
+typedef void (*sis_quad_func)( sisContextPtr,
+ sisVertex *,
+ sisVertex *,
+ sisVertex *,
+ sisVertex * );
+
+typedef void (*sis_tri_func)( sisContextPtr,
+ sisVertex *,
+ sisVertex *,
+ sisVertex * );
+
+typedef void (*sis_line_func)( sisContextPtr,
+ sisVertex *,
+ sisVertex * );
+
+typedef void (*sis_point_func)( sisContextPtr,
+ sisVertex * );
+
+/**
+ * Derived from gl_renderbuffer.
+ */
+struct sis_renderbuffer {
+ struct gl_renderbuffer Base; /* must be first! */
+ drmSize size;
+ GLuint offset;
+ void *handle;
+ GLuint pitch;
+ GLuint bpp;
+ char *map;
+};
+
+/* Device dependent context state */
+
+struct sis_context
+{
+ /* This must be first in this structure */
+ GLcontext *glCtx;
+
+ /* Vertex state */
+ GLuint vertex_size;
+ struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
+ GLuint vertex_attr_count;
+ char *verts; /* points to tnl->clipspace.vertex_buf */
+
+ /* Vertex buffer (in system memory or AGP) state. */
+ unsigned char *vb; /* Beginning of vertex buffer */
+ unsigned char *vb_cur; /* Current write location in vertex buffer */
+ unsigned char *vb_last; /* Last written location in vertex buffer */
+ unsigned char *vb_end; /* End of vertex buffer */
+ void *vb_agp_handle;
+ GLuint vb_agp_offset;
+ GLboolean using_agp;
+ GLint coloroffset; /* Offset in vertex format of current color */
+ GLint specoffset; /* Offset in vertex format of specular color */
+
+ GLuint NewGLState;
+ GLuint Fallback;
+ GLuint RenderIndex;
+ GLfloat hw_viewport[16];
+ GLfloat depth_scale;
+
+ unsigned int virtualX, virtualY;
+ unsigned int bytesPerPixel;
+ unsigned char *IOBase;
+ unsigned char *FbBase;
+ unsigned int displayWidth;
+
+ /* HW RGBA layout */
+ unsigned int redMask, greenMask, blueMask, alphaMask;
+ unsigned int colorFormat;
+
+ /* Z format */
+ unsigned int zFormat;
+
+ /* Clear patterns, 4 bytes */
+ unsigned int clearColorPattern;
+ unsigned int clearZStencilPattern;
+
+ /* Fallback rasterization functions
+ */
+ sis_point_func draw_point;
+ sis_line_func draw_line;
+ sis_tri_func draw_tri;
+ sis_quad_func draw_quad;
+
+ GLuint hw_primitive;
+ GLenum raster_primitive;
+ GLenum render_primitive;
+
+ /* DRM fd */
+ int driFd;
+
+ /* AGP Memory */
+ unsigned int AGPSize;
+ unsigned char *AGPBase;
+ unsigned int AGPAddr;
+
+ /* register 0x89F4 */
+ GLint AGPParseSet;
+
+ /* register 0x89F8 */
+ GLint dwPrimitiveSet;
+
+ __GLSiSHardware prev, current;
+
+ int Chipset;
+ GLboolean is6326;
+
+ GLint drawableID;
+
+ GLint GlobalFlag;
+ DECLARE_RENDERINPUTS(last_tcl_state_bitset);
+
+ /* Stereo */
+ GLboolean useStereo;
+ GLboolean stereoEnabled;
+ int stereo_drawIndex;
+ int stereo_drawSide;
+ GLboolean irqEnabled;
+
+ GLboolean clearTexCache;
+
+ GLuint TexStates[SIS_MAX_TEXTURES];
+ GLuint PrevTexFormat[SIS_MAX_TEXTURES];
+
+ int *CurrentQueueLenPtr;
+ unsigned int *FrameCountPtr;
+
+ /* Front/back/depth buffer info */
+ GLuint width, height; /* size of buffers */
+ GLint bottom; /* used for FLIP macro */
+ /* XXX These don't belong here. They should be per-drawable state. */
+ struct sis_renderbuffer front;
+ struct sis_renderbuffer back;
+ struct sis_renderbuffer depth;
+ struct sis_renderbuffer stencil; /* mirrors depth */
+
+ /* Mirrors of some DRI state
+ */
+ __DRIcontextPrivate *driContext; /* DRI context */
+ __DRIscreenPrivate *driScreen; /* DRI screen */
+ __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */
+
+ unsigned int lastStamp; /* mirror driDrawable->lastStamp */
+
+ drm_context_t hHWContext;
+ drm_hw_lock_t *driHwLock;
+
+ sisScreenPtr sisScreen; /* Screen private DRI data */
+ SISSAREAPrivPtr sarea; /* Private SAREA data */
+
+ /* Configuration cache */
+ driOptionCache optionCache;
+ GLint texture_depth;
+};
+
+#define SIS_CONTEXT(ctx) ((sisContextPtr)(ctx->DriverCtx))
+
+/* Macros */
+#define GET_IOBase(x) ((x)->IOBase)
+
+#define Y_FLIP(Y) (smesa->bottom - (Y))
+
+#define SISPACKCOLOR565( r, g, b ) \
+ ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+
+#define SISPACKCOLOR8888( r, g, b, a ) \
+ (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+
+#define SIS_VERBOSE 0
+
+
+#define MMIO(reg, value) \
+{\
+ *(volatile GLint *)(smesa->IOBase + (reg)) = value; \
+}
+
+#define MMIO_READ(reg) *(volatile GLint *)(smesa->IOBase + (reg))
+#define MMIO_READf(reg) *(volatile GLfloat *)(smesa->IOBase + (reg))
+
+#if defined(__i386__) || defined(__amd64__)
+#define MMIO_WMB() __asm __volatile("" : : : "memory")
+#else
+#error platform needs WMB
+#endif
+
+#define mEndPrimitive() \
+{ \
+ *(volatile GLubyte *)(smesa->IOBase + REG_3D_EndPrimitiveList) = 0xff; \
+ *(volatile GLuint *)(smesa->IOBase + 0x8b60) = 0xffffffff; \
+}
+
+#define sis_fatal_error(...) \
+do { \
+ fprintf(stderr, "[%s:%d]:", __FILE__, __LINE__); \
+ fprintf(stderr, __VA_ARGS__); \
+ exit(-1); \
+} while (0)
+
+/* Lock required */
+#define mWait3DCmdQueue(wLen) \
+/* Update the mirrored queue pointer if it doesn't indicate enough space */ \
+if (*(smesa->CurrentQueueLenPtr) < (wLen)) { \
+ *(smesa->CurrentQueueLenPtr) = \
+ (*(GLint *)(GET_IOBase(smesa) + REG_CommandQueue) & MASK_QueueLen) - 20; \
+ /* Spin and wait if the queue is actually too full */ \
+ if (*(smesa->CurrentQueueLenPtr) < (wLen)) \
+ WaitingFor3dIdle(smesa, wLen); \
+ *(smesa->CurrentQueueLenPtr) -= wLen; \
+}
+
+enum _sis_verbose {
+ VERBOSE_SIS_BUFFER = 0x1,
+ VERBOSE_SIS_MEMORY = 0x2
+};
+
+extern GLboolean sisCreateContext( const __GLcontextModes *glVisual,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate );
+extern void sisDestroyContext( __DRIcontextPrivate * );
+
+void sisReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer,
+ GLuint width, GLuint height);
+
+extern GLboolean sisMakeCurrent( __DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv );
+
+extern GLboolean sisUnbindContext( __DRIcontextPrivate *driContextPriv );
+
+void WaitEngIdle (sisContextPtr smesa);
+void Wait2DEngIdle (sisContextPtr smesa);
+void WaitingFor3dIdle(sisContextPtr smesa, int wLen);
+
+/* update to hw */
+extern void sis_update_texture_state( sisContextPtr smesa );
+extern void sis_update_render_state( sisContextPtr smesa );
+extern void sis6326_update_texture_state( sisContextPtr smesa );
+extern void sis6326_update_render_state( sisContextPtr smesa );
+
+/* ================================================================
+ * Debugging:
+ */
+#define DO_DEBUG 1
+
+#if DO_DEBUG
+extern int SIS_DEBUG;
+#else
+#define SIS_DEBUG 0
+#endif
+
+#define DEBUG_FALLBACKS 0x01
+
+#endif /* _sis_ctx_h_ */
diff --git a/src/sis_dd.c b/src/sis_dd.c
new file mode 100644
index 0000000..8fc7896
--- /dev/null
+++ b/src/sis_dd.c
@@ -0,0 +1,269 @@
+/**************************************************************************
+
+Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
+
+**************************************************************************/
+/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_ctx.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */
+
+/*
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ * Eric Anholt <anholt@FreeBSD.org>
+ *
+ */
+
+#include "sis_context.h"
+#include "sis_dd.h"
+#include "sis_lock.h"
+#include "sis_alloc.h"
+#include "sis_span.h"
+#include "sis_state.h"
+#include "sis_tris.h"
+
+#include "swrast/swrast.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
+
+#include "utils.h"
+
+#define DRIVER_DATE "20060710"
+
+/* Return the width and height of the given buffer.
+ */
+static void
+sisGetBufferSize( GLframebuffer *buffer,
+ GLuint *width, GLuint *height )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ LOCK_HARDWARE();
+ *width = smesa->driDrawable->w;
+ *height = smesa->driDrawable->h;
+ UNLOCK_HARDWARE();
+}
+
+/* Return various strings for glGetString().
+ */
+static const GLubyte *
+sisGetString( GLcontext *ctx, GLenum name )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ static char buffer[128];
+ unsigned offset;
+ GLuint agp_mode = (smesa->AGPSize > 0);
+
+ switch ( name )
+ {
+ case GL_VENDOR:
+ return (GLubyte *)"Eric Anholt";
+
+ case GL_RENDERER:
+ offset = driGetRendererString( buffer, "SiS", DRIVER_DATE, agp_mode );
+
+ return (GLubyte *)buffer;
+
+ default:
+ return NULL;
+ }
+}
+
+/* Send all commands to the hardware.
+ */
+static void
+sisFlush( GLcontext *ctx )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ SIS_FIREVERTICES(smesa);
+}
+
+/* Make sure all commands have been sent to the hardware and have
+ * completed processing.
+ */
+static void
+sisFinish( GLcontext *ctx )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ SIS_FIREVERTICES(smesa);
+ LOCK_HARDWARE();
+ WaitEngIdle( smesa );
+ UNLOCK_HARDWARE();
+}
+
+static void
+sisDeleteRenderbuffer(struct gl_renderbuffer *rb)
+{
+ /* Don't free() since we're contained in sis_context struct. */
+}
+
+static GLboolean
+sisRenderbufferStorage(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
+sisInitRenderbuffer(struct gl_renderbuffer *rb, GLenum format)
+{
+ const GLuint name = 0;
+
+ _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 = sisDeleteRenderbuffer;
+ rb->AllocStorage = sisRenderbufferStorage;
+}
+
+void
+sisUpdateBufferSize(sisContextPtr smesa)
+{
+ __GLSiSHardware *current = &smesa->current;
+ __GLSiSHardware *prev = &smesa->prev;
+ struct gl_framebuffer *fb = smesa->glCtx->DrawBuffer;
+
+ if (!smesa->front.Base.InternalFormat) {
+ /* do one-time init for the renderbuffers */
+ sisInitRenderbuffer(&smesa->front.Base, GL_RGBA);
+ sisSetSpanFunctions(&smesa->front, &fb->Visual);
+ _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &smesa->front.Base);
+
+ if (fb->Visual.doubleBufferMode) {
+ sisInitRenderbuffer(&smesa->back.Base, GL_RGBA);
+ sisSetSpanFunctions(&smesa->back, &fb->Visual);
+ _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &smesa->back.Base);
+ }
+
+ if (smesa->glCtx->Visual.depthBits > 0) {
+ sisInitRenderbuffer(&smesa->depth.Base,
+ (smesa->glCtx->Visual.depthBits == 16
+ ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24));
+ sisSetSpanFunctions(&smesa->depth, &fb->Visual);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &smesa->depth.Base);
+ }
+
+ if (smesa->glCtx->Visual.stencilBits > 0) {
+ sisInitRenderbuffer(&smesa->stencil.Base, GL_STENCIL_INDEX8_EXT);
+ sisSetSpanFunctions(&smesa->stencil, &fb->Visual);
+ _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &smesa->stencil.Base);
+ }
+ }
+
+ /* Make sure initialization did what we think it should */
+ assert(smesa->front.Base.InternalFormat);
+ assert(smesa->front.Base.AllocStorage);
+ if (fb->Visual.doubleBufferMode) {
+ assert(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+ assert(smesa->front.Base.AllocStorage);
+ }
+ if (fb->Visual.depthBits) {
+ assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
+ assert(smesa->depth.Base.AllocStorage);
+ }
+
+ /* XXX Should get the base offset of the frontbuffer from the X Server */
+ smesa->front.offset = smesa->driDrawable->x * smesa->bytesPerPixel +
+ smesa->driDrawable->y * smesa->front.pitch;
+ smesa->front.map = (char *) smesa->driScreen->pFB + smesa->front.offset;
+
+ if ( smesa->width == smesa->driDrawable->w &&
+ smesa->height == smesa->driDrawable->h )
+ {
+ return;
+ }
+
+ smesa->front.bpp = smesa->bytesPerPixel * 8;
+ /* Front pitch set on context create */
+ smesa->front.size = smesa->front.pitch * smesa->driDrawable->h;
+
+ smesa->width = smesa->driDrawable->w;
+ smesa->height = smesa->driDrawable->h;
+ smesa->bottom = smesa->height - 1;
+
+ if (smesa->back.offset)
+ sisFreeBackbuffer( smesa );
+ if (smesa->depth.offset)
+ sisFreeZStencilBuffer( smesa );
+
+ if ( smesa->glCtx->Visual.depthBits > 0 )
+ sisAllocZStencilBuffer( smesa );
+ if ( smesa->glCtx->Visual.doubleBufferMode )
+ sisAllocBackbuffer( smesa );
+
+ current->hwZ &= ~MASK_ZBufferPitch;
+ current->hwZ |= smesa->depth.pitch >> 2;
+ current->hwOffsetZ = smesa->depth.offset >> 2;
+
+ if ((current->hwOffsetZ != prev->hwOffsetZ) || (current->hwZ != prev->hwZ)) {
+ prev->hwOffsetZ = current->hwOffsetZ;
+ prev->hwZ = current->hwZ;
+ smesa->GlobalFlag |= GFLAG_ZSETTING;
+ }
+
+ sisUpdateClipping( smesa->glCtx );
+}
+
+/* Initialize the driver's misc functions.
+ */
+void
+sisInitDriverFuncs( struct dd_function_table *functions )
+{
+ functions->GetBufferSize = sisGetBufferSize;
+ functions->GetString = sisGetString;
+ functions->Finish = sisFinish;
+ functions->Flush = sisFlush;
+}
diff --git a/src/sis_dd.h b/src/sis_dd.h
new file mode 100644
index 0000000..da76596
--- /dev/null
+++ b/src/sis_dd.h
@@ -0,0 +1,39 @@
+/**************************************************************************
+
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT 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.
+
+**************************************************************************/
+/* $XFree86$ */
+
+/*
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#ifndef __SIS_DD_H__
+#define __SIS_DD_H__
+
+extern void sisUpdateBufferSize( sisContextPtr smesa );
+
+extern void sisInitDriverFuncs( struct dd_function_table *functions );
+
+#endif
diff --git a/src/sis_fog.c b/src/sis_fog.c
new file mode 100644
index 0000000..fe9a3c9
--- /dev/null
+++ b/src/sis_fog.c
@@ -0,0 +1,207 @@
+/**************************************************************************
+
+Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
+
+**************************************************************************/
+/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_fog.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */
+
+/*
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "sis_context.h"
+#include "sis_state.h"
+#include "swrast/swrast.h"
+
+#include "macros.h"
+
+static GLint convertFtToFogFt( GLfloat dwInValue );
+static GLint doFPtoFixedNoRound( GLfloat dwInValue, int nFraction );
+
+void
+sisDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ float fArg;
+ GLint fogColor;
+
+ switch (pname)
+ {
+ case GL_FOG_COORDINATE_SOURCE_EXT:
+ current->hwFog &= ~MASK_FogMode;
+ switch (ctx->Fog.FogCoordinateSource)
+ {
+ case GL_FOG_COORDINATE_EXT:
+ current->hwFog &= ~MASK_FogZLookup;
+ break;
+ case GL_FRAGMENT_DEPTH_EXT:
+ current->hwFog |= MASK_FogZLookup;
+ break;
+ }
+ if (current->hwFog != prev->hwFog) {
+ prev->hwFog = current->hwFog;
+ smesa->GlobalFlag |= GFLAG_FOGSETTING;
+ }
+ break;
+ case GL_FOG_MODE:
+ current->hwFog &= ~MASK_FogMode;
+ switch (ctx->Fog.Mode)
+ {
+ case GL_LINEAR:
+ current->hwFog |= FOGMODE_LINEAR;
+ break;
+ case GL_EXP:
+ current->hwFog |= FOGMODE_EXP;
+ break;
+ case GL_EXP2:
+ current->hwFog |= FOGMODE_EXP2;
+ break;
+ }
+ if (current->hwFog != prev->hwFog) {
+ prev->hwFog = current->hwFog;
+ smesa->GlobalFlag |= GFLAG_FOGSETTING;
+ }
+ break;
+ case GL_FOG_DENSITY:
+ current->hwFogDensity = convertFtToFogFt( ctx->Fog.Density );
+ if (current->hwFogDensity != prev->hwFogDensity) {
+ prev->hwFogDensity = current->hwFogDensity;
+ smesa->GlobalFlag |= GFLAG_FOGSETTING;
+ }
+ break;
+ case GL_FOG_START:
+ case GL_FOG_END:
+ fArg = 1.0 / (ctx->Fog.End - ctx->Fog.Start);
+ current->hwFogInverse = doFPtoFixedNoRound( fArg, 10 );
+ if (pname == GL_FOG_END)
+ {
+ if (smesa->Chipset == PCI_CHIP_SIS300)
+ current->hwFogFar = doFPtoFixedNoRound( ctx->Fog.End, 10 );
+ else
+ current->hwFogFar = doFPtoFixedNoRound( ctx->Fog.End, 6 );
+ }
+ if (current->hwFogFar != prev->hwFogFar ||
+ current->hwFogInverse != prev->hwFogInverse)
+ {
+ prev->hwFogFar = current->hwFogFar;
+ prev->hwFogInverse = current->hwFogInverse;
+ smesa->GlobalFlag |= GFLAG_FOGSETTING;
+ }
+ break;
+ case GL_FOG_INDEX:
+ /* TODO */
+ break;
+ case GL_FOG_COLOR:
+ fogColor = FLOAT_TO_UBYTE( ctx->Fog.Color[0] ) << 16;
+ fogColor |= FLOAT_TO_UBYTE( ctx->Fog.Color[1] ) << 8;
+ fogColor |= FLOAT_TO_UBYTE( ctx->Fog.Color[2] );
+ current->hwFog &= 0xff000000;
+ current->hwFog |= fogColor;
+ if (current->hwFog != prev->hwFog) {
+ prev->hwFog = current->hwFog;
+ smesa->GlobalFlag |= GFLAG_FOGSETTING;
+ }
+ break;
+ }
+}
+
+static GLint
+doFPtoFixedNoRound( GLfloat dwInValue, int nFraction )
+{
+ GLint dwMantissa;
+ int nTemp;
+ union { int i; float f; } u;
+ GLint val;
+
+ u.f = dwInValue;
+ val = u.i;
+
+ if (val == 0)
+ return 0;
+ nTemp = (int) (val & 0x7F800000) >> 23;
+ nTemp = nTemp - 127 + nFraction - 23;
+ dwMantissa = (val & 0x007FFFFF) | 0x00800000;
+
+ if (nTemp < -25)
+ return 0;
+ if (nTemp > 0)
+ dwMantissa <<= nTemp;
+ else {
+ nTemp = -nTemp;
+ dwMantissa >>= nTemp;
+ }
+ if (val & 0x80000000)
+ dwMantissa = ~dwMantissa + 1;
+ return dwMantissa;
+}
+
+/* s[8].23->s[7].10 */
+static GLint
+convertFtToFogFt( GLfloat dwInValue )
+{
+ GLint dwMantissa, dwExp;
+ GLint dwRet;
+ union { int i; float f; } u;
+ GLint val;
+
+ u.f = dwInValue;
+ val = u.i;
+
+ if (val == 0)
+ return 0;
+
+ /* ----- Standard float Format: s[8].23 -----
+ * ----- = (-1)^S * 2^(E - 127) * (1 + M / 2^23) -----
+ * ----- = (-1)^S * 2^((E-63) - 64) * (1 + (M/2^13) / 2^10) -----
+ * ----- Density float Format: s[7].10 -----
+ * ----- New Exponential = E - 63 -----
+ * ----- New Mantissa = M / 2^13 -----
+ * ----- -----
+ */
+
+ dwExp = (val & 0x7F800000) >> 23;
+ dwExp -= 63;
+
+ if (dwExp < 0)
+ return 0;
+
+ if (dwExp <= 0x7F)
+ dwMantissa = (val & 0x007FFFFF) >> (23 - 10);
+ else {
+ /* ----- To Return +Max(or -Max) ----- */
+ dwExp = 0x7F;
+ dwMantissa = 0x3FF;
+ }
+
+ dwRet = (val & 0x80000000) >> (31 - 17); /* Shift Sign Bit */
+
+ dwRet |= (dwExp << 10) | dwMantissa;
+
+ return dwRet;
+}
diff --git a/src/sis_lock.c b/src/sis_lock.c
new file mode 100644
index 0000000..70ca8e6
--- /dev/null
+++ b/src/sis_lock.c
@@ -0,0 +1,81 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "context.h"
+#include "sis_context.h"
+#include "sis_lock.h"
+#include "sis_dd.h"
+#include "sis_state.h"
+#include "drirenderbuffer.h"
+
+/* Update the hardware state. This is called if another context has
+ * grabbed the hardware lock, which includes the X server. This
+ * function also updates the driver's window state after the X server
+ * moves, resizes or restacks a window -- the change will be reflected
+ * in the drawable position and clip rects. Since the X server grabs
+ * the hardware lock when it changes the window state, this routine will
+ * automatically be called after such a change.
+ */
+void
+sisGetLock( sisContextPtr smesa, GLuint flags )
+{
+ __DRIdrawablePrivate *dPriv = smesa->driDrawable;
+ __DRIscreenPrivate *sPriv = smesa->driScreen;
+ SISSAREAPrivPtr sarea = smesa->sarea;
+
+ drmGetLock( smesa->driFd, smesa->hHWContext, flags );
+
+ /* The window might have moved, so we might need to get new clip
+ * rects.
+ *
+ * NOTE: This releases and regrabs the hw lock to allow the X server
+ * to respond to the DRI protocol request for new drawable info.
+ * Since the hardware state depends on having the latest drawable
+ * clip rects, all state checking must be done _after_ this call.
+ */
+ DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
+
+ if ( smesa->lastStamp != dPriv->lastStamp ) {
+ sisUpdateBufferSize( smesa );
+ sisUpdateClipping( smesa->glCtx );
+ if (smesa->is6326)
+ sis6326DDDrawBuffer( smesa->glCtx, smesa->glCtx->Color.DrawBuffer[0] );
+ else
+ sisDDDrawBuffer( smesa->glCtx, smesa->glCtx->Color.DrawBuffer[0] );
+ driUpdateFramebufferSize(smesa->glCtx, dPriv);
+ smesa->lastStamp = dPriv->lastStamp;
+ }
+
+ if ( sarea->CtxOwner != smesa->hHWContext ) {
+ sarea->CtxOwner = smesa->hHWContext;
+ smesa->GlobalFlag = GFLAG_ALL;
+ }
+}
diff --git a/src/sis_lock.h b/src/sis_lock.h
new file mode 100644
index 0000000..fef9931
--- /dev/null
+++ b/src/sis_lock.h
@@ -0,0 +1,87 @@
+/**************************************************************************
+
+Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
+
+**************************************************************************/
+/* $XFree86$ */
+
+/*
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#ifndef __SIS_LOCK_H
+#define __SIS_LOCK_H
+
+extern void sisGetLock( sisContextPtr smesa, GLuint flags );
+
+#ifdef DEBUG_LOCKING
+extern char *prevLockFile;
+extern int prevLockLine;
+#define DEBUG_LOCK() \
+ do { \
+ prevLockFile=(__FILE__); \
+ prevLockLine=(__LINE__); \
+ } while (0)
+#define DEBUG_RESET() \
+ do { \
+ prevLockFile=NULL; \
+ prevLockLine=0; \
+ } while (0)
+#define DEBUG_CHECK_LOCK() \
+ do { \
+ if(prevLockFile){ \
+ fprintf(stderr, "LOCK SET : %s:%d\n", __FILE__, __LINE__); \
+ } \
+ } while (0)
+#else
+#define DEBUG_LOCK()
+#define DEBUG_RESET()
+#define DEBUG_CHECK_LOCK()
+#endif
+
+/* Lock the hardware using the global current context */
+#define LOCK_HARDWARE() \
+ do { \
+ char __ret=0; \
+ mEndPrimitive(); \
+ DEBUG_CHECK_LOCK(); \
+ DRM_CAS( smesa->driHwLock, smesa->hHWContext, \
+ (DRM_LOCK_HELD | smesa->hHWContext), __ret ); \
+ if ( __ret != 0 ) \
+ sisGetLock( smesa, 0 ); \
+ DEBUG_LOCK(); \
+ } while (0)
+
+/* Unlock the hardware using the global current context */
+#define UNLOCK_HARDWARE() \
+ do { \
+ mEndPrimitive(); \
+ DRM_UNLOCK(smesa->driFd, smesa->driHwLock, \
+ smesa->hHWContext); \
+ DEBUG_RESET(); \
+ } while (0)
+
+#endif
diff --git a/src/sis_reg.h b/src/sis_reg.h
new file mode 100644
index 0000000..78c6660
--- /dev/null
+++ b/src/sis_reg.h
@@ -0,0 +1,903 @@
+/**************************************************************************
+
+Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
+
+**************************************************************************/
+/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_reg.h,v 1.3 2000/09/26 15:56:48 tsi Exp $ */
+
+/*
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#ifndef _sis_reg_h_
+#define _sis_reg_h_
+
+/*
+ * Define All the Register Address of 6327
+ */
+#define REG_SRC_ADDR 0x8200
+#define REG_SRC_PITCH 0x8204
+# define BLIT_DEPTH_8 0x00000000
+# define BLIT_DEPTH_15 0x40000000
+# define BLIT_DEPTH_16 0x80000000
+# define BLIT_DEPTH_32 0xc0000000
+#define REG_SRC_X_Y 0x8208
+#define REG_DST_X_Y 0x820c
+#define REG_DST_ADDR 0x8210
+#define REG_DST_PITCH_HEIGHT 0x8214
+#define REG_WIDTH_HEIGHT 0x8218
+#define REG_PATFG 0x821c
+#define REG_PATBG 0x8220
+#define REG_SRCFG 0x8224
+#define REG_SRCBG 0x8228
+#define REG_MONOPAT0 0x822c
+#define REG_MONOPAT1 0x8230
+#define REG_CLIPLT 0x8234
+#define REG_CLIPRB 0x8238
+#define REG_BLIT_CMD 0x823c
+# define CMD_ROP_PAT 0x0000f000
+# define CMD_ROP_SRC 0x0000cc00
+# define CMD_DD_ENABLE 0x00000006
+# define CMD_SRC_VIDEO 0x00000000
+# define CMD_SRC_CPU 0x00000010
+# define CMD_DIR_X_DEC 0x00000000
+# define CMD_DIR_X_INC 0x00010000
+# define CMD_DIR_Y_DEC 0x00000000
+# define CMD_DIR_Y_INC 0x00020000
+
+#define REG_CommandQueue 0x8240
+
+#define REG_3D_TSFSa 0x8800
+#define REG_3D_TSZa 0x8804
+#define REG_3D_TSXa 0x8808
+#define REG_3D_TSYa 0x880C
+#define REG_3D_TSARGBa 0x8810
+#define REG_3D_TSWGa 0x8814
+#define REG_3D_TSUAa 0x8818
+#define REG_3D_TSVAa 0x881C
+#define REG_3D_TSUBa 0x8820
+#define REG_3D_TSVBa 0x8824
+#define REG_3D_TSUCa 0x8828
+#define REG_3D_TSVCa 0x882C
+
+#define REG_3D_TSFSb 0x8830
+#define REG_3D_TSZb 0x8834
+#define REG_3D_TSXb 0x8838
+#define REG_3D_TSYb 0x883C
+#define REG_3D_TSARGBb 0x8840
+#define REG_3D_TSWGb 0x8844
+#define REG_3D_TSUAb 0x8848
+#define REG_3D_TSVAb 0x884C
+#define REG_3D_TSUBb 0x8850
+#define REG_3D_TSVBb 0x8854
+#define REG_3D_TSUCb 0x8858
+#define REG_3D_TSVCb 0x885C
+
+#define REG_3D_TSFSc 0x8860
+#define REG_3D_TSZc 0x8864
+#define REG_3D_TSXc 0x8868
+#define REG_3D_TSYc 0x886C
+#define REG_3D_TSARGBc 0x8870
+#define REG_3D_TSWGc 0x8874
+#define REG_3D_TSUAc 0x8878
+#define REG_3D_TSVAc 0x887C
+#define REG_3D_TSUBc 0x8880
+#define REG_3D_TSVBc 0x8884
+#define REG_3D_TSUCc 0x8888
+#define REG_3D_TSVCc 0x888C
+
+/*
+ * REG_3D_AGPCmdSetting (89e4h-89f7)
+ */
+#define REG_3D_AGPCmBase 0x89E4
+#define REG_3D_AGPRmDwNum 0x89E8
+#define REG_3D_AGPTtDwNum 0x89EC
+#define REG_3D_AGPCmFire 0x89F0
+
+#define REG_3D_ParsingSet 0x89F4
+#define REG_3D_PrimitiveSet 0x89F8
+#define REG_3D_ShadeMode 0x89F8
+#define REG_3D_EngineFire 0x89FC
+#define REG_3D_EngineStatus 0x89FC
+#define REG_3D_TEnable 0x8A00
+#define REG_3D_TEnable2 0x8A04
+
+#define REG_3D_ZSet 0x8A08
+#define REG_3D_ZBias 0x8A0C
+#define REG_3D_ZStWriteMask 0x8A10
+
+#define REG_3D_ZAddress 0x8A14
+#define REG_3D_AlphaSet 0x8A18
+#define REG_3D_AlphaAddress 0x8A1C
+#define REG_3D_DstSet 0x8A20
+#define REG_3D_DstAlphaWriteMask 0x8A24
+
+#define REG_3D_DstAddress 0x8A28
+
+#define REG_3D_LinePattern 0x8A2C
+
+#define REG_3D_FogSet 0x8A30
+
+#define REG_3D_FogFarDistance 0x8A34
+#define REG_3D_FogInverseDistance 0x8A38
+#define REG_3D_FogFactorDensity 0x8A3C
+
+#define REG_3D_StencilSet 0x8A44
+#define REG_3D_StencilSet2 0x8A48
+#define REG_3D_StencilAddress 0x8A4C
+
+#define REG_3D_DstBlendMode 0x8A50
+#define REG_3D_SrcBlendMode 0x8A50
+#define REG_3D_ClipTopBottom 0x8A54
+#define REG_3D_ClipLeftRight 0x8A58
+
+#define REG_3D_Brightness 0x8A5C
+
+#define REG_3D_BumpMapSet 0x8A68
+#define REG_3D_BumpMapAddress 0x8A6C
+#define REG_3D_BumpMapPitch 0x8A70
+#define REG_3D_BumpMapMatrix0 0x8A74
+#define REG_3D_BumpMapMatrix1 0x8A78
+
+/*
+ * Define the Texture Register Address of 6326
+ */
+#define REG_3D_TextureSet 0x8A7C
+#define REG_3D_TextureWidthHeight 0x8A7C
+#define REG_3D_TextureMip 0x8A80
+
+#define REG_3D_TextureTransparencyColorHigh 0x8A84
+#define REG_3D_TextureTransparencyColorLow 0x8A88
+#define REG_3D_TextureBorderColor 0x8A8C
+#define REG_3D_TextureAddress0 0x8A90
+#define REG_3D_TextureAddress1 0x8A94
+#define REG_3D_TextureAddress2 0x8A98
+#define REG_3D_TextureAddress3 0x8A9C
+#define REG_3D_TextureAddress4 0x8AA0
+#define REG_3D_TextureAddress5 0x8AA4
+#define REG_3D_TextureAddress6 0x8AA8
+#define REG_3D_TextureAddress7 0x8AAC
+#define REG_3D_TextureAddress8 0x8AB0
+#define REG_3D_TextureAddress9 0x8AB4
+#define REG_3D_TextureAddress10 0x8AB8
+#define REG_3D_TextureAddress11 0x8ABC
+#define REG_3D_TexturePitch0 0x8AC0
+#define REG_3D_TexturePitch1 0x8AC0
+#define REG_3D_TexturePitch2 0x8AC4
+#define REG_3D_TexturePitch3 0x8AC4
+#define REG_3D_TexturePitch4 0x8AC8
+#define REG_3D_TexturePitch5 0x8AC8
+#define REG_3D_TexturePitch6 0x8ACC
+#define REG_3D_TexturePitch7 0x8ACC
+#define REG_3D_TexturePitch8 0x8AD0
+#define REG_3D_TexturePitch9 0x8AD0
+#define REG_3D_TexturePitch10 0x8AD4
+
+#define REG_3D_Texture1Set 0x8ADC
+#define REG_3D_Texture1WidthHeight 0x8ADC
+#define REG_3D_Texture1Mip 0x8AE0
+
+#define REG_3D_Texture1TransparencyColorHigh 0x8AE4
+#define REG_3D_Texture1TransparencyColorLow 0x8AE8
+#define REG_3D_Texture1BorderColor 0x8AEC
+#define REG_3D_Texture1Address0 0x8AF0
+#define REG_3D_Texture1Address1 0x8AF4
+#define REG_3D_Texture1Address2 0x8AF8
+#define REG_3D_Texture1Address3 0x8AFC
+#define REG_3D_Texture1Address4 0x8B00
+#define REG_3D_Texture1Address5 0x8B04
+#define REG_3D_Texture1Address6 0x8B08
+#define REG_3D_Texture1Address7 0x8B0C
+#define REG_3D_Texture1Address8 0x8B10
+#define REG_3D_Texture1Address9 0x8B14
+#define REG_3D_Texture1Address10 0x8B18
+#define REG_3D_Texture1Address11 0x8B1C
+#define REG_3D_Texture1Pitch0 0x8B20
+#define REG_3D_Texture1Pitch1 0x8B20
+#define REG_3D_Texture1Pitch2 0x8B24
+#define REG_3D_Texture1Pitch3 0x8B24
+#define REG_3D_Texture1Pitch4 0x8B28
+#define REG_3D_Texture1Pitch5 0x8B28
+#define REG_3D_Texture1Pitch6 0x8B2C
+#define REG_3D_Texture1Pitch7 0x8B2C
+#define REG_3D_Texture1Pitch8 0x8B30
+#define REG_3D_Texture1Pitch9 0x8B30
+#define REG_3D_Texture1Pitch10 0x8B34
+
+#define REG_3D_TextureBlendFactor 0x8B3C
+#define REG_3D_TextureColorBlendSet0 0x8B40
+#define REG_3D_TextureColorBlendSet1 0x8B44
+#define REG_3D_TextureAlphaBlendSet0 0x8B48
+#define REG_3D_TextureAlphaBlendSet1 0x8B4C
+/*
+ * Define the End of Primitive List of 6326
+ */
+#define REG_3D_EndPrimitiveList 0X8B50
+
+
+/*
+ * Define the Stipple Register Address of 6326
+ */
+#define REG_3D_Stipple0 0X8B60
+
+#define REG_3D_TexturePalette 0x8C00
+
+/*
+ * REG_CommandQueue -- (8240h-8243h)
+ */
+#define MASK_QueueLen 0x0000ffff
+#define SiS_EngIdle2d 0x80000000
+#define SiS_EngIdle 0xe0000000
+#define MASK_EngState 0xf0000000
+
+/*
+ * REG_3D_ParsingSet -- Define Parsing Mask (89F4h-89F7h)
+ */
+#define MASK_VertexDWSize 0xf0000000
+#define MASK_VertexDataFormat 0x0fff0000
+/* Because the original MASK_PsVertex_* names of these bits appared to be
+ * wrong, new names SiS_PS_* based off of the 4.3.0 driver and research are
+ * below.
+ */
+#define SiS_PS_HAS_XYZ MASK_PsVertex_HAS_RHW
+#define SiS_PS_HAS_W MASK_PsVertex_HAS_NORMALXYZ
+#define SiS_PS_HAS_DIFFUSE MASK_PsVertex_HAS_SPECULAR
+#define SiS_PS_HAS_SPECULAR MASK_PsVertex_HAS_DIFFUSE
+#define SiS_PS_HAS_UV0 MASK_PsVertex_HAS_UVSet2
+#define SiS_PS_HAS_UV1 MASK_PsVertex_HAS_UVSet3
+#define MASK_PsVertex_HAS_RHW 0x08000000
+#define MASK_PsVertex_HAS_NORMALXYZ 0x04000000
+#define MASK_PsVertex_HAS_DIFFUSE 0x02000000
+#define MASK_PsVertex_HAS_SPECULAR 0x01000000
+#define MASK_PsUVSet 0x00ff0000
+#define MASK_PsVertex_HAS_1SetUV 0x00800000
+#define MASK_PsVertex_HAS_2SetUV 0x00c00000
+#define MASK_PsVertex_HAS_3SetUV 0x00e00000
+#define MASK_PsVertex_HAS_UVSet1 0x00800000
+#define MASK_PsVertex_HAS_UVSet2 0x00400000
+#define MASK_PsVertex_HAS_UVSet3 0x00200000
+#define MASK_PsCullDirection_CCW 0x00008000
+#define MASK_PsShadingMode 0x00007000
+/* XXX Shading modes just a guess, but seem to work*/
+#define MASK_PsShadingFlatA 0x00001000
+#define MASK_PsShadingFlatB 0x00002000
+#define MASK_PsShadingFlatC 0x00003000
+#define MASK_PsShadingSmooth 0x00004000
+#define MASK_PsTextureFrom 0x000003f0
+#define MASK_PsTexture0FromA 0x00000000
+#define MASK_PsTexture1FromA 0x00000000
+#define MASK_PsTexture1FromB 0x00000040
+#define MASK_PsBumpTextureFromA 0x00000000
+#define MASK_PsBumpTextureFromB 0x00000010
+#define MASK_PsBumpTextureFromC 0x00000020
+#define MASK_PsDataType 0x0000000f
+#define MASK_PsPointList 0x00000000
+#define MASK_PsLineList 0x00000004
+#define MASK_PsLineStrip 0x00000005
+#define MASK_PsTriangleList 0x00000008
+#define MASK_PsTriangleStrip 0x00000009
+#define MASK_PsTriangleFan 0x0000000a
+
+/*
+ * REG_3D_PrimitiveSet -- Define Fire Primitive Mask (89F8h-89FBh)
+ */
+#define MASK_DrawPrimitiveCommand 0x00000007
+#define MASK_SetFirePosition 0x00001F00
+#define MASK_BumpTextureFrom 0x00030000
+#define MASK_Texture1From 0x000C0000
+#define MASK_Texture0From 0x00300000
+#define MASK_ShadingMode 0x07000000
+#define MASK_CullDirection 0x08000000
+
+#define OP_3D_POINT_DRAW 0x00000000
+#define OP_3D_LINE_DRAW 0x00000001
+#define OP_3D_TRIANGLE_DRAW 0x00000002
+
+#define OP_3D_DIRECTION_RIGHT 0x00000000
+#define OP_3D_DIRECTION_LEFT 0x00000100
+#define OP_3D_DIRECTION_HORIZONTAL 0x00000000
+#define OP_3D_DIRECTION_VERTICAL 0x00000100
+
+#define OP_3D_FIRE_TFIRE 0x00000000
+#define OP_3D_FIRE_TSARGBa 0x00000100
+#define OP_3D_FIRE_TSWa 0x00000200
+#define OP_3D_FIRE_TSVAa 0x00000300
+#define OP_3D_FIRE_TSVBa 0x00000400
+#define OP_3D_FIRE_TSVCa 0x00000500
+
+#define OP_3D_FIRE_TSARGBb 0x00000900
+#define OP_3D_FIRE_TSWb 0x00000a00
+#define OP_3D_FIRE_TSVAb 0x00000b00
+#define OP_3D_FIRE_TSVBb 0x00000c00
+#define OP_3D_FIRE_TSVCb 0x00000d00
+
+#define OP_3D_FIRE_TSARGBc 0x00001100
+#define OP_3D_FIRE_TSWc 0x00001200
+#define OP_3D_FIRE_TSVAc 0x00001300
+#define OP_3D_FIRE_TSVBc 0x00001400
+#define OP_3D_FIRE_TSVCc 0x00001500
+
+#define OP_3D_Texture0FromA 0x00000000
+#define OP_3D_Texture0FromB 0x00100000
+#define OP_3D_Texture0FromC 0x00200000
+#define OP_3D_Texture1FromA 0x00000000
+#define OP_3D_Texture1FromB 0x00040000
+#define OP_3D_Texture1FromC 0x00080000
+#define OP_3D_TextureBumpFromA 0x00000000
+#define OP_3D_TextureBumpFromB 0x00010000
+#define OP_3D_TextureBumpFromC 0x00020000
+
+#define OP_3D_CullDirection_CCW 0x08000000
+
+#define SHADE_FLAT_VertexA 0x01000000
+#define SHADE_FLAT_VertexB 0x02000000
+#define SHADE_FLAT_VertexC 0x03000000
+#define SHADE_GOURAUD 0x04000000
+
+/*
+ * Define Command Queue Length Mask (89FCh-89FF)
+ */
+#define MASK_CmdQueueLen 0x0FFF0000
+
+/*
+ * REG_3D_TEnable -- Define Capility Enable Mask (8A00h-8A03h)
+ */
+#define MASK_DitherEnable 0x00000001
+#define MASK_BlendEnable 0x00000002
+#define MASK_FogTestEnable 0x00000004
+#define MASK_FogEnable 0x00000008
+#define MASK_SpecularEnable 0x00000010
+#define MASK_FogPerspectiveEnable 0x00000020
+#define MASK_TextureCacheClear 0x00000040
+#define MASK_TextureCacheEnable 0x00000080
+#define MASK_BumpMapEnable 0x00000100
+#define MASK_TexturePerspectiveEnable 0x00000200
+#define MASK_TextureEnable 0x00000400
+#define MASK_CullEnable 0x00000800
+#define MASK_TextureNumUsed 0x0000F000
+#define MASK_AlphaBufferEnable 0x00010000
+#define MASK_AlphaTestEnable 0x00020000
+#define MASK_AlphaWriteEnable 0x00040000
+#define MASK_ZTestEnable 0x00080000
+#define MASK_ZWriteEnable 0x00100000
+#define MASK_StencilBufferEnable 0x00200000
+#define MASK_StencilTestEnable 0x00400000
+#define MASK_StencilWriteEnable 0x00800000
+#define MASK_Texture0TransparencyEnable 0x01000000
+#define MASK_Texture1TransparencyEnable 0x02000000
+#define MASK_TextureAWrapUCorrection 0x04000000
+#define MASK_TextureAWrapVCorrection 0x08000000
+#define MASK_TextureBWrapUCorrection 0x10000000
+#define MASK_TextureBWrapVCorrection 0x20000000
+#define MASK_TextureCWrapUCorrection 0x40000000
+#define MASK_TextureCWrapVCorrection 0x80000000
+
+/*
+ * REG_3D_TEnable2 -- Define Capility Enable Mask2 (8A04h-8A07h)
+ */
+#define MASK_Texture0BlockTextureEnable 0x00000001
+#define MASK_Texture1BlockTextureEnable 0x00000002
+#define MASK_Texture0AnisotropicEnable 0x00000010
+#define MASK_Texture1AnisotropicEnable 0x00000020
+#define MASK_TextureMipmapBiasEnable 0x00000040
+#define MASK_LinePatternEnable 0x00000100
+#define MASK_StippleAlphaEnable 0x00000200
+#define MASK_StippleEnable 0x00000400
+#define MASK_AntiAliasEnable 0x00000800
+#define MASK_ZMaskWriteEnable 0x00001000
+#define MASK_StencilMaskWriteEnable 0x00002000
+#define MASK_AlphaMaskWriteEnable 0x00004000
+#define MASK_ColorMaskWriteEnable 0x00008000
+#define MASK_ZCacheClear 0x00010000
+#define MASK_ZCacheEnable 0x00020000
+#define MASK_StencilCacheClear 0x00040000
+#define MASK_StencilCacheEnable 0x00080000
+#define MASK_AlphaCacheClear 0x00100000
+#define MASK_AlphaCacheEnable 0x00200000
+#define MASK_ColorCacheClear 0x00400000
+#define MASK_ColorCacheEnable 0x00800000
+
+/*
+ * REG_3D_ZSet -- Define Z Buffer Setting Mask (8A08h-8A0Bh)
+ */
+#define MASK_ZBufferPitch 0x00000FFF
+#define MASK_ZTestMode 0x00070000
+#define MASK_ZBufferInSystem 0x00080000
+#define MASK_ZBufferFormat 0x01F00000
+
+#define SiS_Z_COMP_NEVER 0x00000000
+#define SiS_Z_COMP_S_LT_B 0x00010000
+#define SiS_Z_COMP_S_EQ_B 0x00020000
+#define SiS_Z_COMP_S_LE_B 0x00030000
+#define SiS_Z_COMP_S_GT_B 0x00040000
+#define SiS_Z_COMP_S_NE_B 0x00050000
+#define SiS_Z_COMP_S_GE_B 0x00060000
+#define SiS_Z_COMP_ALWAYS 0x00070000
+
+#define SiS_ZFORMAT_Z16 0x00000000
+#define SiS_ZFORMAT_Z16_INT 0x00100000
+#define SiS_ZFORMAT_S1Z15 0x00400000
+#define SiS_ZFORMAT_S1Z15_INT 0x00500000
+#define SiS_ZFORMAT_Z32 0x00800000
+#define SiS_ZFORMAT_S1Z31 0x00C00000
+#define SiS_ZFORMAT_S2Z30 0x00D00000
+#define SiS_ZFORMAT_S4Z28 0x00E00000
+#define SiS_ZFORMAT_S8Z24 0x00F00000
+#define SiS_ZFORMAT_FZ30 0x01800000
+#define SiS_ZFORMAT_FS1Z30 0x01C00000
+#define SiS_ZFORMAT_FS2Z30 0x01D00000
+
+/*
+ * REG_3D_ZBias -- Define Z Buffer Setting Mask (8A0Ch-8A0Fh)
+ */
+#define MASK_ZBias 0xFFFFFFFF
+
+/*
+ * REG_3D_ZStWriteMask -- Define Z and Stencil Buffer Mask (8A10h-8A13h)
+ */
+#define MASK_ZWriteMask 0x00FFFFFF
+
+/*
+ * REG_3D_ZAddress -- Define Z Buffer Base Address(8A14h-8A17h)
+ */
+#define MASK_ZAddress 0xFFFFFFFF
+
+/*
+ * REG_3D_AlphaSet -- Define Alpha Buffer Setting Mask (8A18h-8A1Bh)
+ */
+#define MASK_AlphaBufferPitch 0x000003FF
+#define MASK_AlphaRefValue 0x00FF0000
+#define MASK_AlphaTestMode 0x07000000
+#define MASK_AlphaBufferInSystem 0x08000000
+#define MASK_AlphaBufferFormat 0x30000000
+
+#define SiS_ALPHA_NEVER 0x00000000
+#define SiS_ALPHA_LESS 0x01000000
+#define SiS_ALPHA_EQUAL 0x02000000
+#define SiS_ALPHA_LEQUAL 0x03000000
+#define SiS_ALPHA_GREATER 0x04000000
+#define SiS_ALPHA_NOTEQUAL 0x05000000
+#define SiS_ALPHA_GEQUAL 0x06000000
+#define SiS_ALPHA_ALWAYS 0x07000000
+
+/*
+ * REG_3D_AlphaAddress -- Define Alpha Buffer Base Address(8A1Ch-8A1Fh)
+ */
+#define MASK_AlphaAddress 0xFFFFFFFF
+
+/*
+ * REG_3D_DstSet -- Define Destination Buffer Setting Mask (8A20h-8A23h)
+ */
+#define MASK_DstBufferPitch 0x00000FFF
+#define MASK_DstBufferFormat 0x000F0000
+#define MASK_DstBufferBitDepth 0x00300000
+#define MASK_DstBufferRgbOrder 0x00400000
+#define MASK_DstBufferInSystem 0x00800000
+#define MASK_Dst7BitFormat 0x007F0000
+#define MASK_ROP2 0x0F000000
+
+#define DST_FORMAT_RGB_555 0x00100000
+#define DST_FORMAT_RGB_565 0x00110000
+#define DST_FORMAT_ARGB_1555 0x00120000
+#define DST_FORMAT_ARGB_4444 0x00130000
+#define DST_FORMAT_ARGB_1888 0x00300000
+#define DST_FORMAT_ARGB_2888 0x00310000
+#define DST_FORMAT_ARGB_4888 0x00320000
+#define DST_FORMAT_ARGB_8888 0x00330000
+#define DST_FORMAT_ARGB_0888 0x00340000
+
+#define DST_FORMAT_BGR_555 0x00500000
+#define DST_FORMAT_BGR_565 0x00510000
+#define DST_FORMAT_ABGR_1555 0x00520000
+#define DST_FORMAT_ABGR_4444 0x00530000
+#define DST_FORMAT_ABGR_1888 0x00700000
+#define DST_FORMAT_ABGR_2888 0x00710000
+#define DST_FORMAT_ABGR_4888 0x00720000
+#define DST_FORMAT_ABGR_8888 0x00730000
+#define DST_FORMAT_ABGR_0888 0x00740000
+
+#define LOP_CLEAR 0x00000000
+#define LOP_NOR 0x01000000
+#define LOP_AND_INVERTED 0x02000000
+#define LOP_COPY_INVERTED 0x03000000
+#define LOP_AND_REVERSE 0x04000000
+#define LOP_INVERT 0x05000000
+#define LOP_XOR 0x06000000
+#define LOP_NAND 0x07000000
+#define LOP_AND 0x08000000
+#define LOP_EQUIV 0x09000000
+#define LOP_NOOP 0x0a000000
+#define LOP_OR_INVERTED 0x0b000000
+#define LOP_COPY 0x0c000000
+#define LOP_OR_REVERSE 0x0d000000
+#define LOP_OR 0x0e000000
+#define LOP_SET 0x0f000000
+
+/*
+ * REG_3D_DstAlphaWriteMask -- Define Destination/Alpha Buffer Write Mask (8A24h-8A27h)
+ */
+#define MASK_ColorWriteMask 0x00FFFFFF
+#define MASK_AlphaWriteMask 0xFF000000
+
+/*
+ * REG_3D_DstAddress -- Define Destination Buffer Base Address(8A1Ch-8A1Fh)
+ */
+#define MASK_DstAddress 0xFFFFFFFF
+
+/*
+ * REG_3D_LinePattern -- Define Line Pattern (8A2Ch-8A2Fh)
+ */
+#define MASK_LinePatternRepeatFactor 0x00007FFF
+#define MASK_LinePatternLastPixelFlag 0x00008000
+#define MASK_LinePattern 0xFFFF0000
+
+/*
+ * REG_3D_FogSet -- Define Fog Mask (8A30h-8A33h)
+ */
+#define MASK_FogColor 0x00FFFFFF
+#define MASK_FogMode 0x07000000
+#define MASK_FogZLookup 0x08000000
+
+#define FOGMODE_CHEAP 0x04000000
+#define FOGMODE_LINEAR 0x05000000
+#define FOGMODE_EXP 0x06000000
+#define FOGMODE_EXP2 0x07000000
+
+/*
+ * REG_3D_FogStartEnd -- Define Fog Start End Setting (0x8A34 - 0x8A37)
+ */
+#define MASK_FogFarDistance 0x0007FFFF
+
+/*
+ * REG_3D_FogStartEnd -- Define Fog End Setting (0x8A38 - 0x8A3B)
+ */
+#define MASK_FogInvFarDistance 0x0007FFFF
+
+/*
+ * REG_3D_FogFactorDensity (0x8A3C - 0x8A3F)
+ */
+#define MASK_FogDensity 0x0003FFFF
+#define MASK_FogFactor 0xFF000000
+
+/*
+ * REG_3D_StencilSet -- Define stencil test (8A44h-8A47h)
+ */
+#define MASK_StencilValueMask 0x000000ff
+#define MASK_StencilRefMask 0x0000ff00
+#define MASK_StencilTestMode 0x07000000
+#define MASK_StencilBufferInSystem 0x08000000
+#define MASK_StencilFormat 0x30000000
+
+#define SiS_STENCIL_NEVER 0x00000000
+#define SiS_STENCIL_LESS 0x01000000
+#define SiS_STENCIL_EQUAL 0x02000000
+#define SiS_STENCIL_LEQUAL 0x03000000
+#define SiS_STENCIL_GREATER 0x04000000
+#define SiS_STENCIL_NOTEQUAL 0x05000000
+#define SiS_STENCIL_GEQUAL 0x06000000
+#define SiS_STENCIL_ALWAYS 0x07000000
+
+#define STENCIL_FORMAT_1 0x00000000
+#define STENCIL_FORMAT_2 0x10000000
+#define STENCIL_FORMAT_4 0x20000000
+#define STENCIL_FORMAT_8 0x30000000
+
+/*
+ * REG_3D_StencilSet2 -- Define stencil test (8A4h-8A47h)
+ */
+#define MASK_StencilBufferPitch 0x00000FFF
+#define MASK_StencilZPassOp 0x00007000
+#define MASK_StencilZFailOp 0x00070000
+#define MASK_StencilFailOp 0x00700000
+#define MASK_StencilWriteMask 0xFF000000
+
+#define SiS_SFAIL_KEEP 0x00000000
+#define SiS_SFAIL_ZERO 0x00100000
+#define SiS_SFAIL_REPLACE 0x00200000
+#define SiS_SFAIL_INCR 0x00300000 /* guess -- was _WRAP */
+#define SiS_SFAIL_DECR 0x00400000 /* guess -- was _WRAP */
+#define SiS_SFAIL_INVERT 0x00500000
+#define SiS_SFAIL_INCR_WRAP 0x00600000 /* guess */
+#define SiS_SFAIL_DECR_WRAP 0x00700000 /* guess */
+
+#define SiS_SPASS_ZFAIL_KEEP 0x00000000
+#define SiS_SPASS_ZFAIL_ZERO 0x00010000
+#define SiS_SPASS_ZFAIL_REPLACE 0x00020000
+#define SiS_SPASS_ZFAIL_INCR 0x00030000 /* guess -- was _WRAP */
+#define SiS_SPASS_ZFAIL_DECR 0x00040000 /* guess -- was _WRAP */
+#define SiS_SPASS_ZFAIL_INVERT 0x00050000
+#define SiS_SPASS_ZFAIL_INCR_WRAP 0x00060000 /* guess */
+#define SiS_SPASS_ZFAIL_DECR_WRAP 0x00070000 /* guess */
+
+#define SiS_SPASS_ZPASS_KEEP 0x00000000
+#define SiS_SPASS_ZPASS_ZERO 0x00001000
+#define SiS_SPASS_ZPASS_REPLACE 0x00002000
+#define SiS_SPASS_ZPASS_INCR 0x00003000 /* guess -- was _WRAP */
+#define SiS_SPASS_ZPASS_DECR 0x00004000 /* guess -- was _WRAP */
+#define SiS_SPASS_ZPASS_INVERT 0x00005000
+#define SiS_SPASS_ZPASS_INCR_WRAP 0x00006000 /* guess */
+#define SiS_SPASS_ZPASS_DECR_WRAP 0x00007000 /* guess */
+
+/*
+ * REG_3D_DstBlendMode (0x8A50 - 0x8A53)
+ */
+#define MASK_SrcBlendMode 0x0000000F
+#define MASK_DstBlendMode 0x000000F0
+
+#define SiS_D_ZERO 0x00000000
+#define SiS_D_ONE 0x00000010
+#define SiS_D_SRC_COLOR 0x00000020
+#define SiS_D_ONE_MINUS_SRC_COLOR 0x00000030
+#define SiS_D_SRC_ALPHA 0x00000040
+#define SiS_D_ONE_MINUS_SRC_ALPHA 0x00000050
+#define SiS_D_DST_ALPHA 0x00000060
+#define SiS_D_ONE_MINUS_DST_ALPHA 0x00000070
+#define SiS_D_DST_COLOR 0x00000080
+#define SiS_D_ONE_MINUS_DST_COLOR 0x00000090
+#define SiS_D_SRC_ALPHA_SAT 0x000000a0
+
+#define SiS_S_ZERO 0x00000000
+#define SiS_S_ONE 0x00000001
+#define SiS_S_SRC_COLOR 0x00000002
+#define SiS_S_ONE_MINUS_SRC_COLOR 0x00000003
+#define SiS_S_SRC_ALPHA 0x00000004
+#define SiS_S_ONE_MINUS_SRC_ALPHA 0x00000005
+#define SiS_S_DST_ALPHA 0x00000006
+#define SiS_S_ONE_MINUS_DST_ALPHA 0x00000007
+#define SiS_S_DST_COLOR 0x00000008
+#define SiS_S_ONE_MINUS_DST_COLOR 0x00000009
+#define SiS_S_SRC_ALPHA_SATURATE 0x0000000a
+#define SiS_S_BOTH_SRC_ALPHA 0x0000000b
+#define SiS_S_BOTH_ONE_MINUS_SRC_ALPHA 0x0000000c
+
+/*
+ * REG_3D_ClipTopBottom (0x8A54 - 0x8A57)
+ */
+#define MASK_BottomClip 0x00001FFF
+#define MASK_TopClip 0x03FFE000
+
+/*
+ * REG_3D_ClipLeftRight (0x8A58 - 0x8A5B)
+ */
+#define MASK_RightClip 0x00001FFF
+#define MASK_LeftClip 0x03FFE000
+
+/*
+ * REG_3D_TextureSet (0x8A7C - 0x8A7F)
+ * REG_3D_Texture1Set (0x8ADC - 0x8ADF)
+ */
+#define MASK_TextureHeight 0x0000000F
+#define MASK_TextureWidth 0x000000F0
+#define MASK_TextureLevel 0x00000F00
+#define MASK_TextureSignYUVFormat 0x00001000
+#define MASK_TextureMappingMode 0x00FF0000
+#define MASK_TextureWrapU 0x00010000
+#define MASK_TextureWrapV 0x00020000
+#define MASK_TextureMirrorU 0x00040000
+#define MASK_TextureMirrorV 0x00080000
+#define MASK_TextureClampU 0x00100000
+#define MASK_TextureClampV 0x00200000
+#define MASK_TextureBorderU 0x00400000
+#define MASK_TextureBorderV 0x00800000
+#define MASK_TextureFormat 0xFF000000
+#define MASK_TextureBitDepth 0x70000000
+#define MASK_TextureRgbOrder 0x80000000
+
+#define TEXEL_INDEX1 0x00000000
+#define TEXEL_INDEX2 0x01000000
+#define TEXEL_INDEX4 0x02000000
+#define TEXEL_INDEX8 0x03000000
+
+#define TEXEL_INDEX1WithAlpha 0x04000000
+#define TEXEL_INDEX2WithAlpha 0x05000000
+#define TEXEL_INDEX4WithAlpha 0x06000000
+#define TEXEL_INDEX8WithAlpha 0x07000000
+
+#define TEXEL_I1 0x10000000
+#define TEXEL_I2 0x11000000
+#define TEXEL_I4 0x12000000
+#define TEXEL_I8 0x13000000
+
+#define TEXEL_DXT1 0x19000000
+#define TEXEL_DXT2 0x1A000000
+#define TEXEL_DXT3 0x1B000000
+
+#define TEXEL_YUV422 0x20000000
+#define TEXEL_YVU422 0x21000000
+#define TEXEL_UVY422 0x22000000
+#define TEXEL_VUY422 0x23000000
+#define TEXEL_YUV411 0x24000000
+
+#define TEXEL_L1 0x30000000
+#define TEXEL_L2 0x31000000
+#define TEXEL_L4 0x32000000
+#define TEXEL_L8 0x33000000
+
+#define TEXEL_AL11 0x34000000
+#define TEXEL_AL44 0x35000000
+#define TEXEL_AL26 0x37000000
+#define TEXEL_AL88 0x38000000
+
+#define TEXEL_A1 0x40000000
+#define TEXEL_A2 0x41000000
+#define TEXEL_A4 0x42000000
+#define TEXEL_A8 0x43000000
+
+#define TEXEL_RGB_332_8 0x50000000
+#define TEXEL_RGB_233_8 0x51000000
+#define TEXEL_RGB_232_8 0x52000000
+#define TEXEL_ARGB_1232_8 0x53000000
+#define TEXEL_ARGB_2222_8 0x54000000
+
+#define TEXEL_RGB_555_16 0x60000000
+#define TEXEL_RGB_565_16 0x61000000
+#define TEXEL_ARGB_1555_16 0x62000000
+#define TEXEL_ARGB_4444_16 0x63000000
+
+#define TEXEL_ARGB_1888_32 0x70000000
+#define TEXEL_ARGB_2888_32 0x71000000
+#define TEXEL_ARGB_4888_32 0x72000000
+#define TEXEL_ARGB_8888_32 0x73000000
+#define TEXEL_ARGB_0888_32 0x74000000
+
+#define TEXEL_BGR_332_8 0xD0000000
+#define TEXEL_BGR_233_8 0xD1000000
+#define TEXEL_BGR_232_8 0xD2000000
+#define TEXEL_ABGR_1232_8 0xD3000000
+#define TEXEL_ABGR_2222_8 0xD4000000
+
+#define TEXEL_BGR_555_16 0xE0000000
+#define TEXEL_BGR_565_16 0xE1000000
+#define TEXEL_ABGR_1555_16 0xE2000000
+#define TEXEL_ABGR_4444_16 0xE3000000
+
+#define TEXEL_ABGR_1888_32 0xF0000000
+#define TEXEL_ABGR_2888_32 0xF1000000
+#define TEXEL_ABGR_4888_32 0xF2000000
+#define TEXEL_ABGR_8888_32 0xF3000000
+#define TEXEL_ABGR_0888_32 0xF4000000
+
+#define TEXEL_VU88 0x00000000
+#define TEXEL_LVU655 0x00800000
+#define TEXEL_LVU888 0x01000000
+#define TEXEL_UV88 0x02000000
+#define TEXEL_LUV655 0x02800000
+#define TEXEL_LUV888 0x03000000
+
+/*
+ * REG_3D_TextureMip (0x8A80 - 0x8A83)
+ * REG_3D_Texture1Mip (0x8AE0 - 0x8AE3)
+ */
+#define MASK_TextureAnisotropyRatio 0x0000000F
+#define MASK_TextureMipmapLodBias 0x00003FF0
+#define MASK_TextureFilterMin 0x0001C000
+#define MASK_TextureFilterMag 0x00020000
+#define MASK_TextureFilter 0x0003C000
+#define MASK_TextureLevelInSystem 0x3FFC0000
+#define MASK_TextureLevel0InSystem 0x00040000
+#define MASK_TextureBlockLength 0xF0000000
+
+#define TEXTURE_FILTER_NEAREST 0x00000000
+#define TEXTURE_FILTER_LINEAR 0x00004000
+#define TEXTURE_FILTER_NEAREST_MIP_NEAREST 0x00008000
+#define TEXTURE_FILTER_NEAREST_MIP_LINEAR 0x00010000
+#define TEXTURE_FILTER_LINEAR_MIP_NEAREST 0x0000c000
+#define TEXTURE_FILTER_LINEAR_MIP_LINEAR 0x00014000
+
+/*
+ * REG_3D_TextureTransparencyColorHigh (0x8A84 - 0x8A87)
+ * REG_3D_Texture1TransparencyColorHigh (0x8AE4 - 0x8AE7)
+ */
+#define MASK_TextureTransparencyColorHighB 0x000000FF
+#define MASK_TextureTransparencyColorHighG 0x0000FF00
+#define MASK_TextureTransparencyColorHighR 0x00FF0000
+#define MASK_TextureAlphaTransparencyMode 0x08000000
+
+/*
+ * REG_3D_TextureTransparencyColorLow (0x8A88 - 0x8A8B)
+ * REG_3D_Texture1TransparencyColorLow (0x8AE8 - 0x8AEB)
+ */
+#define MASK_TextureTransparencyColorLowB 0x000000FF
+#define MASK_TextureTransparencyColorLowG 0x0000FF00
+#define MASK_TextureTransparencyColorLowR 0x00FF0000
+#define MASK_TextureBlockHeight 0x07000000
+#define MASK_TextureBlockWidth 0x70000000
+
+/*
+ * REG_3D_TextureTransparencyColorLow (0x8A8C - 0x8A8F)
+ * REG_3D_Texture1TransparencyColorLow (0x8AEC - 0x8AEF)
+ */
+#define MASK_TextureBorderColorB 0x000000FF
+#define MASK_TextureBorderColorG 0x0000FF00
+#define MASK_TextureBorderColorR 0x00FF0000
+#define MASK_TextureBorderColorA 0xFF000000
+
+/*
+ * REG_3D_TexturePitch0-10 (0x8AC0 - 0x8AD7)
+ * REG_3D_Texture1Pitch0-10 (0x8B20 - 0x8B37)
+ */
+#define MASK_TexturePitchOdd 0x000003FF
+#define MASK_TexturePitchEven 0x03FF0000
+#define SHIFT_TexturePitchEven 16
+
+/*
+ * REG_3D_TextureColorBlendSet0 (0x8B40 - 0x8B43)
+ * REG_3D_TextureColorBlendSet1 (0x8B44 - 0x8B46)
+ * REG_3D_TextureAlphaBlendSet0 (0x8B40 - 0x8B43)
+ * REG_3D_TextureAlphaBlendSet1 (0x8B44 - 0x8B46)
+ */
+#define STAGE0_C_CF 0xa1485000
+#define STAGE0_C_CS 0xc1485000
+#define STAGE0_C_CFCS 0xa1705000
+#define STAGE0_C_CFOMAS_CSAS 0xc534c001
+#define STAGE0_C_CFOMCS_CCCS 0x4530c001
+
+#define STAGE0_A_AF 0x63230000
+#define STAGE0_A_AS 0xc3230000
+#define STAGE0_A_AFAS 0x63c30000
+#define STAGE0_A_AFOMAS_ACAS 0x46c60001
+
+#define STAGE1_C_CF 0xa1485000
+#define STAGE1_C_CS 0xe1485000
+#define STAGE1_C_CFCS 0xa1785000
+#define STAGE1_C_CFOMAS_CSAS 0xe5394001
+#define STAGE1_C_CFOMCS_CCCS 0x45394001
+
+#define STAGE1_A_AF 0xa3230000
+#define STAGE1_A_AS 0xe3230000
+#define STAGE1_A_AFAS 0xa3e30000
+#define STAGE1_A_AFOMAS_ACAS 0x4aea0001
+
+/* What registers are these associated with? */
+#define MASK_BMMemoryInSystem 0x00000080
+#define MASK_BMHeight 0x00000F00
+#define MASK_BMWidth 0x0000F000
+#define MASK_BMFilter 0x00010000
+#define MASK_BMMappingMode 0x007E0000
+#define MASK_BMFormat 0x07800000
+#define MASK_BMTxBumpmap 0x08000000
+
+#define MASK_BMAddress 0xFFFFFFFC
+
+#define MASK_BMOffset 0xFF800000
+#define MASK_BMScale 0x007FE000
+#define MASK_BMPitch 0x00001FFF
+
+#define MASK_BMMatrix00 0x000007FF
+#define MASK_BMMatrix01 0x07FF0000
+#define MASK_BMMatrix10 0x000007FF
+#define MASK_BMMatrix11 0x07FF0000
+
+#define MASK_TextureRealInSystem 0x00000001
+#define MASK_TextureDowngrade 0x00000002
+
+#define ALPHA_BUFFER_FORMAT_1 0x00000000
+#define ALPHA_BUFFER_FORMAT_2 0x10000000
+#define ALPHA_BUFFER_FORMAT_4 0x20000000
+#define ALPHA_BUFFER_FORMAT_8 0x30000000
+
+#endif
diff --git a/src/sis_screen.c b/src/sis_screen.c
new file mode 100644
index 0000000..89d734b
--- /dev/null
+++ b/src/sis_screen.c
@@ -0,0 +1,382 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "dri_util.h"
+
+#include "context.h"
+#include "utils.h"
+#include "imports.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
+
+#include "sis_context.h"
+#include "sis_dri.h"
+#include "sis_lock.h"
+#include "sis_span.h"
+
+#include "xmlpool.h"
+
+#include "GL/internal/dri_interface.h"
+
+#define SIS_AGP_DISABLE(def) \
+DRI_CONF_OPT_BEGIN(agp_disable,bool,def) \
+ DRI_CONF_DESC(en,"Disable AGP vertex dispatch") \
+DRI_CONF_OPT_END
+
+PUBLIC const char __driConfigOptions[] =
+DRI_CONF_BEGIN
+ DRI_CONF_SECTION_QUALITY
+ DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
+ DRI_CONF_SECTION_END
+ DRI_CONF_SECTION_DEBUG
+ SIS_AGP_DISABLE(true)
+ 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 __GLcontextModes *
+sisFillInModes(int bpp)
+{
+ __GLcontextModes *modes;
+ __GLcontextModes *m;
+ unsigned num_modes;
+ unsigned depth_buffer_factor;
+ unsigned back_buffer_factor;
+ GLenum fb_format;
+ GLenum fb_type;
+ static const GLenum back_buffer_modes[] = {
+ GLX_NONE, GLX_SWAP_UNDEFINED_OML
+ };
+ u_int8_t depth_bits_array[4];
+ u_int8_t stencil_bits_array[4];
+
+ depth_bits_array[0] = 0;
+ stencil_bits_array[0] = 0;
+ depth_bits_array[1] = 16;
+ stencil_bits_array[1] = 0;
+ depth_bits_array[2] = 24;
+ stencil_bits_array[2] = 8;
+ depth_bits_array[3] = 32;
+ stencil_bits_array[3] = 0;
+
+ depth_buffer_factor = 4;
+ back_buffer_factor = 2;
+
+ /* Last 4 is for GLX_TRUE_COLOR & GLX_DIRECT_COLOR, with/without accum */
+ num_modes = depth_buffer_factor * back_buffer_factor * 4;
+
+ if (bpp == 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;
+}
+
+
+/* Create the device specific screen private data struct.
+ */
+static sisScreenPtr
+sisCreateScreen( __DRIscreenPrivate *sPriv )
+{
+ sisScreenPtr sisScreen;
+ SISDRIPtr sisDRIPriv = (SISDRIPtr)sPriv->pDevPriv;
+
+ if (sPriv->devPrivSize != sizeof(SISDRIRec)) {
+ fprintf(stderr,"\nERROR! sizeof(SISDRIRec) does not match passed size from device driver\n");
+ return GL_FALSE;
+ }
+
+ /* Allocate the private area */
+ sisScreen = (sisScreenPtr)CALLOC( sizeof(*sisScreen) );
+ if ( sisScreen == NULL )
+ return NULL;
+
+ sisScreen->screenX = sisDRIPriv->width;
+ sisScreen->screenY = sisDRIPriv->height;
+ sisScreen->cpp = sisDRIPriv->bytesPerPixel;
+ sisScreen->deviceID = sisDRIPriv->deviceID;
+ sisScreen->AGPCmdBufOffset = sisDRIPriv->AGPCmdBufOffset;
+ sisScreen->AGPCmdBufSize = sisDRIPriv->AGPCmdBufSize;
+ sisScreen->sarea_priv_offset = sizeof(drm_sarea_t);
+
+ sisScreen->mmio.handle = sisDRIPriv->regs.handle;
+ sisScreen->mmio.size = sisDRIPriv->regs.size;
+ if ( drmMap( sPriv->fd, sisScreen->mmio.handle, sisScreen->mmio.size,
+ &sisScreen->mmio.map ) )
+ {
+ FREE( sisScreen );
+ return NULL;
+ }
+
+ if (sisDRIPriv->agp.size) {
+ sisScreen->agp.handle = sisDRIPriv->agp.handle;
+ sisScreen->agpBaseOffset = drmAgpBase(sPriv->fd);
+ sisScreen->agp.size = sisDRIPriv->agp.size;
+ if ( drmMap( sPriv->fd, sisScreen->agp.handle, sisScreen->agp.size,
+ &sisScreen->agp.map ) )
+ {
+ sisScreen->agp.size = 0;
+ }
+ }
+
+ sisScreen->driScreen = sPriv;
+
+ /* parse information in __driConfigOptions */
+ driParseOptionInfo(&sisScreen->optionCache,
+ __driConfigOptions, __driNConfigOptions);
+
+ return sisScreen;
+}
+
+/* Destroy the device specific screen private data struct.
+ */
+static void
+sisDestroyScreen( __DRIscreenPrivate *sPriv )
+{
+ sisScreenPtr sisScreen = (sisScreenPtr)sPriv->private;
+
+ if ( sisScreen == NULL )
+ return;
+
+ if (sisScreen->agp.size != 0)
+ drmUnmap( sisScreen->agp.map, sisScreen->agp.size );
+ drmUnmap( sisScreen->mmio.map, sisScreen->mmio.size );
+
+ FREE( sisScreen );
+ sPriv->private = NULL;
+}
+
+
+/* Create and initialize the Mesa and driver specific pixmap buffer
+ * data.
+ */
+static GLboolean
+sisCreateBuffer( __DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ const __GLcontextModes *mesaVis,
+ GLboolean isPixmap )
+{
+ /*sisScreenPtr screen = (sisScreenPtr) driScrnPriv->private;*/
+ struct gl_framebuffer *fb;
+
+ if (isPixmap)
+ return GL_FALSE; /* not implemented */
+
+ fb = _mesa_create_framebuffer(mesaVis);
+
+ _mesa_add_soft_renderbuffers(fb,
+ GL_FALSE, /* color */
+ GL_FALSE, /* depth */
+ mesaVis->stencilBits > 0,
+ mesaVis->accumRedBits > 0,
+ GL_FALSE, /* alpha */
+ GL_FALSE /* aux */);
+ driDrawPriv->driverPrivate = (void *) fb;
+
+ return (driDrawPriv->driverPrivate != NULL);
+}
+
+
+static void
+sisDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+ _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
+}
+
+static void sisCopyBuffer( __DRIdrawablePrivate *dPriv )
+{
+ sisContextPtr smesa = (sisContextPtr)dPriv->driContextPriv->driverPrivate;
+ int i;
+
+ while ((*smesa->FrameCountPtr) - MMIO_READ(0x8a2c) > SIS_MAX_FRAME_LENGTH)
+ ;
+
+ LOCK_HARDWARE();
+
+ for (i = 0; i < dPriv->numClipRects; i++) {
+ drm_clip_rect_t *box = &dPriv->pClipRects[i];
+
+ mWait3DCmdQueue(10);
+ MMIO(REG_SRC_ADDR, smesa->back.offset);
+ MMIO(REG_SRC_PITCH, smesa->back.pitch | ((smesa->bytesPerPixel == 4) ?
+ BLIT_DEPTH_32 : BLIT_DEPTH_16));
+ MMIO(REG_SRC_X_Y, ((box->x1 - dPriv->x) << 16) | (box->y1 - dPriv->y));
+ MMIO(REG_DST_X_Y, ((box->x1 - dPriv->x) << 16) | (box->y1 - dPriv->y));
+ MMIO(REG_DST_ADDR, smesa->front.offset);
+ MMIO(REG_DST_PITCH_HEIGHT, (smesa->virtualY << 16) | smesa->front.pitch);
+ MMIO(REG_WIDTH_HEIGHT, ((box->y2 - box->y1) << 16) | (box->x2 - box->x1));
+ MMIO(REG_BLIT_CMD, CMD_DIR_X_INC | CMD_DIR_Y_INC | CMD_ROP_SRC);
+ MMIO(REG_CommandQueue, -1);
+ }
+
+ *(GLint *)(smesa->IOBase+0x8a2c) = *smesa->FrameCountPtr;
+ (*smesa->FrameCountPtr)++;
+
+ UNLOCK_HARDWARE ();
+}
+
+
+/* Copy the back color buffer to the front color buffer */
+static void
+sisSwapBuffers(__DRIdrawablePrivate *dPriv)
+{
+ if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+ sisContextPtr smesa = (sisContextPtr) dPriv->driContextPriv->driverPrivate;
+ GLcontext *ctx = smesa->glCtx;
+
+ if (ctx->Visual.doubleBufferMode) {
+ _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
+ sisCopyBuffer( dPriv );
+ }
+ } else {
+ /* XXX this shouldn't be an error but we can't handle it for now */
+ _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
+ }
+}
+
+
+/* Initialize the driver specific screen private data.
+ */
+static GLboolean
+sisInitDriver( __DRIscreenPrivate *sPriv )
+{
+ sPriv->private = (void *) sisCreateScreen( sPriv );
+
+ if ( !sPriv->private ) {
+ sisDestroyScreen( sPriv );
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static struct __DriverAPIRec sisAPI = {
+ .InitDriver = sisInitDriver,
+ .DestroyScreen = sisDestroyScreen,
+ .CreateContext = sisCreateContext,
+ .DestroyContext = sisDestroyContext,
+ .CreateBuffer = sisCreateBuffer,
+ .DestroyBuffer = sisDestroyBuffer,
+ .SwapBuffers = sisSwapBuffers,
+ .MakeCurrent = sisMakeCurrent,
+ .UnbindContext = sisUnbindContext,
+ .GetSwapInfo = NULL,
+ .GetMSC = NULL,
+ .WaitForMSC = NULL,
+ .WaitForSBC = NULL,
+ .SwapBuffersMSC = NULL
+
+};
+
+
+/**
+ * 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 = {0, 8, 0};
+ static const __DRIversion dri_expected = {4, 0, 0};
+ static const __DRIversion drm_expected = {1, 0, 0};
+ static const char *driver_name = "SiS";
+ 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, &sisAPI);
+ if (psp != NULL) {
+ SISDRIPtr dri_priv = (SISDRIPtr)psp->pDevPriv;
+ *driver_modes = sisFillInModes(dri_priv->bytesPerPixel * 8);
+
+ /* 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;
+}
diff --git a/src/sis_screen.h b/src/sis_screen.h
new file mode 100644
index 0000000..d5b2101
--- /dev/null
+++ b/src/sis_screen.h
@@ -0,0 +1,62 @@
+/**************************************************************************
+
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT 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.
+
+**************************************************************************/
+/* $XFree86$ */
+
+/*
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#ifndef __SIS_SCREEN_H
+#define __SIS_SCREEN_H
+
+typedef struct {
+ drm_handle_t handle; /* Handle to the DRM region */
+ drmSize size; /* Size of the DRM region */
+ drmAddress map; /* Mapping of the DRM region */
+} sisRegionRec2, *sisRegionPtr2;
+
+typedef struct {
+ sisRegionRec2 mmio;
+ sisRegionRec2 agp;
+ unsigned long agpBaseOffset;
+
+ unsigned int AGPCmdBufOffset;
+ unsigned int AGPCmdBufSize;
+
+ int deviceID;
+
+ int cpp;
+ unsigned int screenX, screenY;
+
+ __DRIscreenPrivate *driScreen;
+ unsigned int sarea_priv_offset;
+
+ /* Configuration cache with default values for all contexts */
+ driOptionCache optionCache;
+
+} sisScreenRec, *sisScreenPtr;
+
+#endif
diff --git a/src/sis_span.c b/src/sis_span.c
new file mode 100644
index 0000000..ea6db67
--- /dev/null
+++ b/src/sis_span.c
@@ -0,0 +1,194 @@
+/**************************************************************************
+
+Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
+
+**************************************************************************/
+/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_span.c,v 1.5 2001/03/21 16:14:26 dawes Exp $ */
+
+/*
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "sis_context.h"
+#include "sis_span.h"
+#include "sis_lock.h"
+#include "sis_tris.h"
+
+#include "swrast/swrast.h"
+
+#define DBG 0
+
+#define LOCAL_VARS \
+ sisContextPtr smesa = SIS_CONTEXT(ctx); \
+ __DRIdrawablePrivate *dPriv = smesa->driDrawable; \
+ struct sis_renderbuffer *srb = (struct sis_renderbuffer *) rb; \
+ GLuint pitch = srb->pitch; \
+ char *buf = srb->map; \
+ GLuint p; \
+ (void) buf; (void) p;
+
+
+#define LOCAL_DEPTH_VARS \
+ sisContextPtr smesa = SIS_CONTEXT(ctx); \
+ __DRIdrawablePrivate *dPriv = smesa->driDrawable; \
+ struct sis_renderbuffer *srb = (struct sis_renderbuffer *) rb; \
+ char *buf = srb->map;
+
+#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
+
+#define HW_LOCK() do {} while(0);
+
+#define HW_UNLOCK() do {} while(0);
+
+/* RGB565 */
+#define SPANTMP_PIXEL_FMT GL_RGB
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
+
+#define TAG(x) sis##x##_RGB565
+#define TAG2(x,y) sis##x##_RGB565##y
+#include "spantmp2.h"
+
+
+/* ARGB8888 */
+/* FIXME the old code always read back alpha as 0xff, i.e. fully opaque.
+ Was there a reason to do so ? If so that'll won't work with that template... */
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
+
+#define TAG(x) sis##x##_ARGB8888
+#define TAG2(x,y) sis##x##_ARGB8888##y
+#include "spantmp2.h"
+
+
+/* 16 bit depthbuffer functions.
+ */
+#define WRITE_DEPTH( _x, _y, d ) \
+ *(GLushort *)(buf + (_x)*2 + (_y)*srb->pitch) = d;
+
+#define READ_DEPTH( d, _x, _y ) \
+ d = *(GLushort *)(buf + (_x)*2 + (_y)*srb->pitch);
+
+#define TAG(x) sis##x##_z16
+#include "depthtmp.h"
+
+
+/* 32 bit depthbuffer functions.
+ */
+#define WRITE_DEPTH( _x, _y, d ) \
+ *(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch) = d;
+
+#define READ_DEPTH( d, _x, _y ) \
+ d = *(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch);
+
+#define TAG(x) sis##x##_z32
+#include "depthtmp.h"
+
+
+/* 8/24 bit interleaved depth/stencil functions
+ */
+#define WRITE_DEPTH( _x, _y, d ) { \
+ GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch); \
+ tmp &= 0xff000000; \
+ tmp |= (d & 0x00ffffff); \
+ *(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch) = tmp; \
+}
+
+#define READ_DEPTH( d, _x, _y ) { \
+ d = *(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch) & 0x00ffffff; \
+}
+
+#define TAG(x) sis##x##_z24_s8
+#include "depthtmp.h"
+
+#define WRITE_STENCIL( _x, _y, d ) { \
+ GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*smesa->depth.pitch); \
+ tmp &= 0x00ffffff; \
+ tmp |= (d << 24); \
+ *(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch) = tmp; \
+}
+
+#define READ_STENCIL( d, _x, _y ) \
+ d = (*(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch) & 0xff000000) >> 24;
+
+#define TAG(x) sis##x##_z24_s8
+#include "stenciltmp.h"
+
+
+
+void sisSpanRenderStart( GLcontext *ctx )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ SIS_FIREVERTICES(smesa);
+ LOCK_HARDWARE();
+ WaitEngIdle( smesa );
+}
+
+void sisSpanRenderFinish( GLcontext *ctx )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ _swrast_flush( ctx );
+ UNLOCK_HARDWARE();
+}
+
+void
+sisDDInitSpanFuncs( GLcontext *ctx )
+{
+ struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
+ swdd->SpanRenderStart = sisSpanRenderStart;
+ swdd->SpanRenderFinish = sisSpanRenderFinish;
+}
+
+
+
+/**
+ * Plug in the Get/Put routines for the given driRenderbuffer.
+ */
+void
+sisSetSpanFunctions(struct sis_renderbuffer *srb, const GLvisual *vis)
+{
+ if (srb->Base.InternalFormat == GL_RGBA) {
+ if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
+ sisInitPointers_RGB565( &srb->Base );
+ }
+ else {
+ sisInitPointers_ARGB8888( &srb->Base );
+ }
+ }
+ else if (srb->Base.InternalFormat == GL_DEPTH_COMPONENT16) {
+ sisInitDepthPointers_z16(&srb->Base);
+ }
+ else if (srb->Base.InternalFormat == GL_DEPTH_COMPONENT24) {
+ sisInitDepthPointers_z24_s8(&srb->Base);
+ }
+ else if (srb->Base.InternalFormat == GL_DEPTH_COMPONENT32) {
+ sisInitDepthPointers_z32(&srb->Base);
+ }
+ else if (srb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
+ sisInitStencilPointers_z24_s8(&srb->Base);
+ }
+}
diff --git a/src/sis_span.h b/src/sis_span.h
new file mode 100644
index 0000000..4b0add2
--- /dev/null
+++ b/src/sis_span.h
@@ -0,0 +1,46 @@
+/**************************************************************************
+
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT 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.
+
+**************************************************************************/
+/* $XFree86$ */
+
+/*
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#ifndef __SIS_SPAN_H__
+#define __SIS_SPAN_H__
+
+#include "drirenderbuffer.h"
+
+
+extern void sisSpanRenderStart( GLcontext *ctx );
+extern void sisSpanRenderFinish( GLcontext *ctx );
+
+extern void sisDDInitSpanFuncs( GLcontext *ctx );
+
+extern void
+sisSetSpanFunctions(struct sis_renderbuffer *srb, const GLvisual *vis);
+
+#endif
diff --git a/src/sis_state.c b/src/sis_state.c
new file mode 100644
index 0000000..33a2f08
--- /dev/null
+++ b/src/sis_state.c
@@ -0,0 +1,866 @@
+/**************************************************************************
+
+Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
+
+**************************************************************************/
+/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_ctx.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */
+
+/*
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "sis_context.h"
+#include "sis_state.h"
+#include "sis_tris.h"
+#include "sis_lock.h"
+#include "sis_tex.h"
+
+#include "context.h"
+#include "enums.h"
+#include "colormac.h"
+#include "swrast/swrast.h"
+#include "vbo/vbo.h"
+#include "tnl/tnl.h"
+#include "swrast_setup/swrast_setup.h"
+
+#include "tnl/t_pipeline.h"
+
+/* =============================================================
+ * Alpha blending
+ */
+
+static void
+sisDDAlphaFunc( GLcontext * ctx, GLenum func, GLfloat ref )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ GLubyte refbyte;
+
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ CLAMPED_FLOAT_TO_UBYTE(refbyte, ref);
+ current->hwAlpha = refbyte << 16;
+
+ /* Alpha Test function */
+ switch (func)
+ {
+ case GL_NEVER:
+ current->hwAlpha |= SiS_ALPHA_NEVER;
+ break;
+ case GL_LESS:
+ current->hwAlpha |= SiS_ALPHA_LESS;
+ break;
+ case GL_EQUAL:
+ current->hwAlpha |= SiS_ALPHA_EQUAL;
+ break;
+ case GL_LEQUAL:
+ current->hwAlpha |= SiS_ALPHA_LEQUAL;
+ break;
+ case GL_GREATER:
+ current->hwAlpha |= SiS_ALPHA_GREATER;
+ break;
+ case GL_NOTEQUAL:
+ current->hwAlpha |= SiS_ALPHA_NOTEQUAL;
+ break;
+ case GL_GEQUAL:
+ current->hwAlpha |= SiS_ALPHA_GEQUAL;
+ break;
+ case GL_ALWAYS:
+ current->hwAlpha |= SiS_ALPHA_ALWAYS;
+ break;
+ }
+
+ prev->hwAlpha = current->hwAlpha;
+ smesa->GlobalFlag |= GFLAG_ALPHASETTING;
+}
+
+static void
+sisDDBlendFuncSeparate( GLcontext *ctx,
+ GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ current->hwDstSrcBlend = 0;
+
+ switch (dfactorRGB)
+ {
+ case GL_ZERO:
+ current->hwDstSrcBlend |= SiS_D_ZERO;
+ break;
+ case GL_ONE:
+ current->hwDstSrcBlend |= SiS_D_ONE;
+ break;
+ case GL_SRC_COLOR:
+ current->hwDstSrcBlend |= SiS_D_SRC_COLOR;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ current->hwDstSrcBlend |= SiS_D_ONE_MINUS_SRC_COLOR;
+ break;
+ case GL_SRC_ALPHA:
+ current->hwDstSrcBlend |= SiS_D_SRC_ALPHA;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ current->hwDstSrcBlend |= SiS_D_ONE_MINUS_SRC_ALPHA;
+ break;
+ case GL_DST_COLOR:
+ current->hwDstSrcBlend |= SiS_D_DST_COLOR;
+ break;
+ case GL_ONE_MINUS_DST_COLOR:
+ current->hwDstSrcBlend |= SiS_D_ONE_MINUS_DST_COLOR;
+ break;
+ case GL_DST_ALPHA:
+ current->hwDstSrcBlend |= SiS_D_DST_ALPHA;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ current->hwDstSrcBlend |= SiS_D_ONE_MINUS_DST_ALPHA;
+ break;
+ default:
+ fprintf(stderr, "Unknown dst blend function 0x%x\n", dfactorRGB);
+ break;
+ }
+
+ switch (sfactorRGB)
+ {
+ case GL_ZERO:
+ current->hwDstSrcBlend |= SiS_S_ZERO;
+ break;
+ case GL_ONE:
+ current->hwDstSrcBlend |= SiS_S_ONE;
+ break;
+ case GL_SRC_COLOR:
+ current->hwDstSrcBlend |= SiS_S_SRC_COLOR;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ current->hwDstSrcBlend |= SiS_S_ONE_MINUS_SRC_COLOR;
+ break;
+ case GL_SRC_ALPHA:
+ current->hwDstSrcBlend |= SiS_S_SRC_ALPHA;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ current->hwDstSrcBlend |= SiS_S_ONE_MINUS_SRC_ALPHA;
+ break;
+ case GL_DST_COLOR:
+ current->hwDstSrcBlend |= SiS_S_DST_COLOR;
+ break;
+ case GL_ONE_MINUS_DST_COLOR:
+ current->hwDstSrcBlend |= SiS_S_ONE_MINUS_DST_COLOR;
+ break;
+ case GL_DST_ALPHA:
+ current->hwDstSrcBlend |= SiS_S_DST_ALPHA;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ current->hwDstSrcBlend |= SiS_S_ONE_MINUS_DST_ALPHA;
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ current->hwDstSrcBlend |= SiS_S_SRC_ALPHA_SATURATE;
+ break;
+ default:
+ fprintf(stderr, "Unknown src blend function 0x%x\n", sfactorRGB);
+ break;
+ }
+
+ if (current->hwDstSrcBlend != prev->hwDstSrcBlend) {
+ prev->hwDstSrcBlend = current->hwDstSrcBlend;
+ smesa->GlobalFlag |= GFLAG_DSTBLEND;
+ }
+}
+
+/* =============================================================
+ * Depth testing
+ */
+
+static void
+sisDDDepthFunc( GLcontext * ctx, GLenum func )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ current->hwZ &= ~MASK_ZTestMode;
+ switch (func)
+ {
+ case GL_LESS:
+ current->hwZ |= SiS_Z_COMP_S_LT_B;
+ break;
+ case GL_GEQUAL:
+ current->hwZ |= SiS_Z_COMP_S_GE_B;
+ break;
+ case GL_LEQUAL:
+ current->hwZ |= SiS_Z_COMP_S_LE_B;
+ break;
+ case GL_GREATER:
+ current->hwZ |= SiS_Z_COMP_S_GT_B;
+ break;
+ case GL_NOTEQUAL:
+ current->hwZ |= SiS_Z_COMP_S_NE_B;
+ break;
+ case GL_EQUAL:
+ current->hwZ |= SiS_Z_COMP_S_EQ_B;
+ break;
+ case GL_ALWAYS:
+ current->hwZ |= SiS_Z_COMP_ALWAYS;
+ break;
+ case GL_NEVER:
+ current->hwZ |= SiS_Z_COMP_NEVER;
+ break;
+ }
+
+ if (current->hwZ != prev->hwZ) {
+ prev->hwZ = current->hwZ;
+ smesa->GlobalFlag |= GFLAG_ZSETTING;
+ }
+}
+
+void
+sisDDDepthMask( GLcontext * ctx, GLboolean flag )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ if (!ctx->Depth.Test)
+ flag = GL_FALSE;
+
+ if (ctx->Visual.stencilBits) {
+ if (flag || (ctx->Stencil.WriteMask[0] != 0)) {
+ current->hwCapEnable |= MASK_ZWriteEnable;
+ if (flag && ((ctx->Stencil.WriteMask[0] & 0xff) == 0xff)) {
+ current->hwCapEnable2 &= ~MASK_ZMaskWriteEnable;
+ } else {
+ current->hwCapEnable2 |= MASK_ZMaskWriteEnable;
+ current->hwZMask = (ctx->Stencil.WriteMask[0] << 24) |
+ ((flag) ? 0x00ffffff : 0);
+
+ if (current->hwZMask ^ prev->hwZMask) {
+ prev->hwZMask = current->hwZMask;
+ smesa->GlobalFlag |= GFLAG_ZSETTING;
+ }
+ }
+ } else {
+ current->hwCapEnable &= ~MASK_ZWriteEnable;
+ }
+ } else {
+ if (flag) {
+ current->hwCapEnable |= MASK_ZWriteEnable;
+ current->hwCapEnable2 &= ~MASK_ZMaskWriteEnable;
+ } else {
+ current->hwCapEnable &= ~MASK_ZWriteEnable;
+ }
+ }
+}
+
+/* =============================================================
+ * Clipping
+ */
+
+void
+sisUpdateClipping( GLcontext *ctx )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ GLint x1, y1, x2, y2;
+
+ if (smesa->is6326) {
+ /* XXX: 6326 has its own clipping for now. Should be fixed */
+ sis6326UpdateClipping(ctx);
+ return;
+ }
+
+ x1 = 0;
+ y1 = 0;
+ x2 = smesa->width - 1;
+ y2 = smesa->height - 1;
+
+ if (ctx->Scissor.Enabled) {
+ if (ctx->Scissor.X > x1)
+ x1 = ctx->Scissor.X;
+ if (ctx->Scissor.Y > y1)
+ y1 = ctx->Scissor.Y;
+ if (ctx->Scissor.X + ctx->Scissor.Width - 1 < x2)
+ x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
+ if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < y2)
+ y2 = ctx->Scissor.Y + ctx->Scissor.Height - 1;
+ }
+
+ y1 = Y_FLIP(y1);
+ y2 = Y_FLIP(y2);
+
+ current->clipTopBottom = (y2 << 13) | y1;
+ current->clipLeftRight = (x1 << 13) | x2;
+
+ if ((current->clipTopBottom ^ prev->clipTopBottom) ||
+ (current->clipLeftRight ^ prev->clipLeftRight))
+ {
+ prev->clipTopBottom = current->clipTopBottom;
+ prev->clipLeftRight = current->clipLeftRight;
+ smesa->GlobalFlag |= GFLAG_CLIPPING;
+ }
+}
+
+static void
+sisDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
+{
+ if (ctx->Scissor.Enabled)
+ sisUpdateClipping( ctx );
+}
+
+/* =============================================================
+ * Culling
+ */
+
+static void
+sisUpdateCull( GLcontext *ctx )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ GLint cullflag, frontface;
+
+ cullflag = ctx->Polygon.CullFaceMode;
+ frontface = ctx->Polygon.FrontFace;
+
+ smesa->AGPParseSet &= ~(MASK_PsCullDirection_CCW);
+ smesa->dwPrimitiveSet &= ~(MASK_CullDirection);
+
+ if((cullflag == GL_FRONT && frontface == GL_CCW) ||
+ (cullflag == GL_BACK && frontface == GL_CW))
+ {
+ smesa->AGPParseSet |= MASK_PsCullDirection_CCW;
+ smesa->dwPrimitiveSet |= OP_3D_CullDirection_CCW;
+ }
+}
+
+
+static void
+sisDDCullFace( GLcontext *ctx, GLenum mode )
+{
+ sisUpdateCull( ctx );
+}
+
+static void
+sisDDFrontFace( GLcontext *ctx, GLenum mode )
+{
+ sisUpdateCull( ctx );
+}
+
+/* =============================================================
+ * Masks
+ */
+
+static void sisDDColorMask( GLcontext *ctx,
+ GLboolean r, GLboolean g,
+ GLboolean b, GLboolean a )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ if (r && g && b && ((ctx->Visual.alphaBits == 0) || a)) {
+ current->hwCapEnable2 &= ~(MASK_AlphaMaskWriteEnable |
+ MASK_ColorMaskWriteEnable);
+ } else {
+ current->hwCapEnable2 |= (MASK_AlphaMaskWriteEnable |
+ MASK_ColorMaskWriteEnable);
+
+ current->hwDstMask = (r) ? smesa->redMask : 0 |
+ (g) ? smesa->greenMask : 0 |
+ (b) ? smesa->blueMask : 0 |
+ (a) ? smesa->alphaMask : 0;
+ }
+
+ if (current->hwDstMask != prev->hwDstMask) {
+ prev->hwDstMask = current->hwDstMask;
+ smesa->GlobalFlag |= GFLAG_DESTSETTING;
+ }
+}
+
+/* =============================================================
+ * Rendering attributes
+ */
+
+static void sisUpdateSpecular(GLcontext *ctx)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *current = &smesa->current;
+
+ if (NEED_SECONDARY_COLOR(ctx))
+ current->hwCapEnable |= MASK_SpecularEnable;
+ else
+ current->hwCapEnable &= ~MASK_SpecularEnable;
+}
+
+static void sisDDLightModelfv(GLcontext *ctx, GLenum pname,
+ const GLfloat *param)
+{
+ if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
+ sisUpdateSpecular(ctx);
+ }
+}
+
+static void sisDDShadeModel( GLcontext *ctx, GLenum mode )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ /* Signal to sisRasterPrimitive to recalculate dwPrimitiveSet */
+ smesa->hw_primitive = -1;
+}
+
+/* =============================================================
+ * Window position
+ */
+
+/* =============================================================
+ * Viewport
+ */
+
+static void sisCalcViewport( GLcontext *ctx )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+ GLfloat *m = smesa->hw_viewport;
+
+ /* See also sis_translate_vertex.
+ */
+ m[MAT_SX] = v[MAT_SX];
+ m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
+ m[MAT_SY] = - v[MAT_SY];
+ m[MAT_TY] = - v[MAT_TY] + smesa->driDrawable->h + SUBPIXEL_Y;
+ m[MAT_SZ] = v[MAT_SZ] * smesa->depth_scale;
+ m[MAT_TZ] = v[MAT_TZ] * smesa->depth_scale;
+}
+
+static void sisDDViewport( GLcontext *ctx,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height )
+{
+ sisCalcViewport( ctx );
+}
+
+static void sisDDDepthRange( GLcontext *ctx,
+ GLclampd nearval, GLclampd farval )
+{
+ sisCalcViewport( ctx );
+}
+
+/* =============================================================
+ * Miscellaneous
+ */
+
+static void
+sisDDLogicOpCode( GLcontext *ctx, GLenum opcode )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ current->hwDstSet &= ~MASK_ROP2;
+ switch (opcode)
+ {
+ case GL_CLEAR:
+ current->hwDstSet |= LOP_CLEAR;
+ break;
+ case GL_SET:
+ current->hwDstSet |= LOP_SET;
+ break;
+ case GL_COPY:
+ current->hwDstSet |= LOP_COPY;
+ break;
+ case GL_COPY_INVERTED:
+ current->hwDstSet |= LOP_COPY_INVERTED;
+ break;
+ case GL_NOOP:
+ current->hwDstSet |= LOP_NOOP;
+ break;
+ case GL_INVERT:
+ current->hwDstSet |= LOP_INVERT;
+ break;
+ case GL_AND:
+ current->hwDstSet |= LOP_AND;
+ break;
+ case GL_NAND:
+ current->hwDstSet |= LOP_NAND;
+ break;
+ case GL_OR:
+ current->hwDstSet |= LOP_OR;
+ break;
+ case GL_NOR:
+ current->hwDstSet |= LOP_NOR;
+ break;
+ case GL_XOR:
+ current->hwDstSet |= LOP_XOR;
+ break;
+ case GL_EQUIV:
+ current->hwDstSet |= LOP_EQUIV;
+ break;
+ case GL_AND_REVERSE:
+ current->hwDstSet |= LOP_AND_REVERSE;
+ break;
+ case GL_AND_INVERTED:
+ current->hwDstSet |= LOP_AND_INVERTED;
+ break;
+ case GL_OR_REVERSE:
+ current->hwDstSet |= LOP_OR_REVERSE;
+ break;
+ case GL_OR_INVERTED:
+ current->hwDstSet |= LOP_OR_INVERTED;
+ break;
+ }
+
+ if (current->hwDstSet ^ prev->hwDstSet) {
+ prev->hwDstSet = current->hwDstSet;
+ smesa->GlobalFlag |= GFLAG_DESTSETTING;
+ }
+}
+
+void sisDDDrawBuffer( GLcontext *ctx, GLenum mode )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ /*
+ * _DrawDestMask is easier to cope with than <mode>.
+ */
+ current->hwDstSet &= ~MASK_DstBufferPitch;
+ switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
+ case BUFFER_BIT_FRONT_LEFT:
+ FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE );
+ current->hwOffsetDest = smesa->front.offset >> 1;
+ current->hwDstSet |= smesa->front.pitch >> 2;
+ break;
+ case BUFFER_BIT_BACK_LEFT:
+ FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE );
+ current->hwOffsetDest = smesa->back.offset >> 1;
+ current->hwDstSet |= smesa->back.pitch >> 2;
+ break;
+ default:
+ /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
+ FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_TRUE );
+ return;
+ }
+
+ if (current->hwDstSet != prev->hwDstSet) {
+ prev->hwDstSet = current->hwDstSet;
+ smesa->GlobalFlag |= GFLAG_DESTSETTING;
+ }
+
+ if (current->hwOffsetDest != prev->hwOffsetDest) {
+ prev->hwOffsetDest = current->hwOffsetDest;
+ smesa->GlobalFlag |= GFLAG_DESTSETTING;
+ }
+}
+
+/* =============================================================
+ * Polygon stipple
+ */
+
+/* =============================================================
+ * Render mode
+ */
+
+/* =============================================================
+ * State enable/disable
+ */
+
+static void
+sisDDEnable( GLcontext * ctx, GLenum cap, GLboolean state )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ __GLSiSHardware *current = &smesa->current;
+
+ switch (cap)
+ {
+ case GL_ALPHA_TEST:
+ if (state)
+ current->hwCapEnable |= MASK_AlphaTestEnable;
+ else
+ current->hwCapEnable &= ~MASK_AlphaTestEnable;
+ break;
+ case GL_BLEND:
+ /* TODO: */
+ if (state)
+ /* if (state & !ctx->Color.ColorLogicOpEnabled) */
+ current->hwCapEnable |= MASK_BlendEnable;
+ else
+ current->hwCapEnable &= ~MASK_BlendEnable;
+ break;
+ case GL_CULL_FACE:
+ if (state)
+ current->hwCapEnable |= MASK_CullEnable;
+ else
+ current->hwCapEnable &= ~MASK_CullEnable;
+ break;
+ case GL_DEPTH_TEST:
+ if (state && smesa->depth.offset != 0)
+ current->hwCapEnable |= MASK_ZTestEnable;
+ else
+ current->hwCapEnable &= ~MASK_ZTestEnable;
+ sisDDDepthMask( ctx, ctx->Depth.Mask );
+ break;
+ case GL_DITHER:
+ if (state)
+ current->hwCapEnable |= MASK_DitherEnable;
+ else
+ current->hwCapEnable &= ~MASK_DitherEnable;
+ break;
+ case GL_FOG:
+ if (state)
+ current->hwCapEnable |= MASK_FogEnable;
+ else
+ current->hwCapEnable &= ~MASK_FogEnable;
+ break;
+ case GL_COLOR_LOGIC_OP:
+ if (state)
+ sisDDLogicOpCode( ctx, ctx->Color.LogicOp );
+ else
+ sisDDLogicOpCode( ctx, GL_COPY );
+ break;
+ case GL_SCISSOR_TEST:
+ sisUpdateClipping( ctx );
+ break;
+ case GL_STENCIL_TEST:
+ if (state) {
+ if (smesa->zFormat != SiS_ZFORMAT_S8Z24)
+ FALLBACK(smesa, SIS_FALLBACK_STENCIL, 1);
+ else
+ current->hwCapEnable |= (MASK_StencilTestEnable |
+ MASK_StencilWriteEnable);
+ } else {
+ FALLBACK(smesa, SIS_FALLBACK_STENCIL, 0);
+ current->hwCapEnable &= ~(MASK_StencilTestEnable |
+ MASK_StencilWriteEnable);
+ }
+ break;
+ case GL_LIGHTING:
+ case GL_COLOR_SUM_EXT:
+ sisUpdateSpecular(ctx);
+ break;
+ }
+}
+
+
+/* =============================================================
+ * State initialization, management
+ */
+
+/* Called before beginning of rendering. */
+void
+sisUpdateHWState( GLcontext *ctx )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ /* enable setting 1 */
+ if (current->hwCapEnable ^ prev->hwCapEnable) {
+ prev->hwCapEnable = current->hwCapEnable;
+ smesa->GlobalFlag |= GFLAG_ENABLESETTING;
+ }
+
+ /* enable setting 2 */
+ if (current->hwCapEnable2 ^ prev->hwCapEnable2) {
+ prev->hwCapEnable2 = current->hwCapEnable2;
+ smesa->GlobalFlag |= GFLAG_ENABLESETTING2;
+ }
+
+ if (smesa->GlobalFlag & GFLAG_RENDER_STATES)
+ sis_update_render_state( smesa );
+
+ if (smesa->GlobalFlag & GFLAG_TEXTURE_STATES)
+ sis_update_texture_state( smesa );
+}
+
+static void
+sisDDInvalidateState( GLcontext *ctx, GLuint new_state )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ _swrast_InvalidateState( ctx, new_state );
+ _swsetup_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
+ _tnl_InvalidateState( ctx, new_state );
+ smesa->NewGLState |= new_state;
+}
+
+/* Initialize the context's hardware state.
+ */
+void sisDDInitState( sisContextPtr smesa )
+{
+ __GLSiSHardware *current = &smesa->current;
+ __GLSiSHardware *prev = &(smesa->prev);
+ GLcontext *ctx = smesa->glCtx;
+
+ /* add Texture Perspective Enable */
+ prev->hwCapEnable = MASK_FogPerspectiveEnable | MASK_TextureCacheEnable |
+ MASK_TexturePerspectiveEnable | MASK_DitherEnable;
+
+ /*
+ prev->hwCapEnable2 = 0x00aa0080;
+ */
+ /* if multi-texture enabled, disable Z pre-test */
+ prev->hwCapEnable2 = MASK_TextureMipmapBiasEnable;
+
+ /* Z test mode is LESS */
+ prev->hwZ = SiS_Z_COMP_S_LT_B;
+
+ /* Depth mask */
+ prev->hwZMask = 0xffffffff;
+
+ /* Alpha test mode is ALWAYS, alpha ref value is 0 */
+ prev->hwAlpha = SiS_ALPHA_ALWAYS;
+
+ /* ROP2 is COPYPEN */
+ prev->hwDstSet = LOP_COPY;
+
+ /* color mask */
+ prev->hwDstMask = 0xffffffff;
+
+ /* LinePattern is 0, Repeat Factor is 0 */
+ prev->hwLinePattern = 0x00008000;
+
+ /* Src blend is BLEND_ONE, Dst blend is D3DBLEND_ZERO */
+ prev->hwDstSrcBlend = SiS_S_ONE | SiS_D_ZERO;
+
+ /* Stenciling disabled, function ALWAYS, ref value zero, mask all ones */
+ prev->hwStSetting = STENCIL_FORMAT_8 | SiS_STENCIL_ALWAYS | 0xff;
+ /* Op is KEEP for all three operations */
+ prev->hwStSetting2 = SiS_SFAIL_KEEP | SiS_SPASS_ZFAIL_KEEP |
+ SiS_SPASS_ZPASS_KEEP;
+
+ /* Texture mapping mode is Tile */
+#if 0
+ prev->texture[0].hwTextureSet = 0x00030000;
+#endif
+ /* Magnified & minified texture filter is NEAREST */
+#if 0
+ prev->texture[0].hwTextureMip = 0;
+#endif
+
+ /* Texture Blending setting -- use fragment color/alpha*/
+ prev->hwTexBlendColor0 = STAGE0_C_CF;
+ prev->hwTexBlendColor1 = STAGE1_C_CF;
+ prev->hwTexBlendAlpha0 = STAGE0_A_AF;
+ prev->hwTexBlendAlpha1 = STAGE1_A_AF;
+
+ switch (smesa->bytesPerPixel)
+ {
+ case 2:
+ prev->hwDstSet |= DST_FORMAT_RGB_565;
+ break;
+ case 4:
+ prev->hwDstSet |= DST_FORMAT_ARGB_8888;
+ break;
+ }
+
+ switch (ctx->Visual.depthBits)
+ {
+ case 0:
+ prev->hwCapEnable &= ~MASK_ZWriteEnable;
+ case 16:
+ smesa->zFormat = SiS_ZFORMAT_Z16;
+ prev->hwCapEnable |= MASK_ZWriteEnable;
+ smesa->depth_scale = 1.0 / (GLfloat)0xffff;
+ break;
+ case 32:
+ smesa->zFormat = SiS_ZFORMAT_Z32;
+ prev->hwCapEnable |= MASK_ZWriteEnable;
+ smesa->depth_scale = 1.0 / (GLfloat)0xffffffff;
+ break;
+ case 24:
+ assert (ctx->Visual.stencilBits);
+ smesa->zFormat = SiS_ZFORMAT_S8Z24;
+ prev->hwCapEnable |= MASK_StencilBufferEnable;
+ prev->hwCapEnable |= MASK_ZWriteEnable;
+ smesa->depth_scale = 1.0 / (GLfloat)0xffffff;
+ break;
+ }
+
+ prev->hwZ |= smesa->zFormat;
+
+ /* TODO: need to clear cache? */
+ smesa->clearTexCache = GL_TRUE;
+
+ smesa->clearColorPattern = 0;
+
+ smesa->AGPParseSet = MASK_PsTexture1FromB | MASK_PsBumpTextureFromC;
+ smesa->dwPrimitiveSet = OP_3D_Texture1FromB | OP_3D_TextureBumpFromC;
+
+ sisUpdateZStencilPattern( smesa, 1.0, 0 );
+ sisUpdateCull( ctx );
+
+ memcpy( current, prev, sizeof (__GLSiSHardware) );
+
+ /* Set initial fog settings. Start and end are the same case. */
+ sisDDFogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
+ sisDDFogfv( ctx, GL_FOG_END, &ctx->Fog.End );
+ sisDDFogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL );
+ sisDDFogfv( ctx, GL_FOG_MODE, NULL );
+}
+
+/* Initialize the driver's state functions.
+ */
+void sisDDInitStateFuncs( GLcontext *ctx )
+{
+ ctx->Driver.UpdateState = sisDDInvalidateState;
+
+ ctx->Driver.Clear = sisDDClear;
+ ctx->Driver.ClearColor = sisDDClearColor;
+ ctx->Driver.ClearDepth = sisDDClearDepth;
+ ctx->Driver.ClearStencil = sisDDClearStencil;
+
+ ctx->Driver.AlphaFunc = sisDDAlphaFunc;
+ ctx->Driver.BlendFuncSeparate = sisDDBlendFuncSeparate;
+ ctx->Driver.ColorMask = sisDDColorMask;
+ ctx->Driver.CullFace = sisDDCullFace;
+ ctx->Driver.DepthMask = sisDDDepthMask;
+ ctx->Driver.DepthFunc = sisDDDepthFunc;
+ ctx->Driver.DepthRange = sisDDDepthRange;
+ ctx->Driver.DrawBuffer = sisDDDrawBuffer;
+ ctx->Driver.Enable = sisDDEnable;
+ ctx->Driver.FrontFace = sisDDFrontFace;
+ ctx->Driver.Fogfv = sisDDFogfv;
+ ctx->Driver.Hint = NULL;
+ ctx->Driver.Lightfv = NULL;
+ ctx->Driver.LogicOpcode = sisDDLogicOpCode;
+ ctx->Driver.PolygonMode = NULL;
+ ctx->Driver.PolygonStipple = NULL;
+ ctx->Driver.ReadBuffer = NULL;
+ ctx->Driver.RenderMode = NULL;
+ ctx->Driver.Scissor = sisDDScissor;
+ ctx->Driver.ShadeModel = sisDDShadeModel;
+ ctx->Driver.LightModelfv = sisDDLightModelfv;
+ ctx->Driver.Viewport = sisDDViewport;
+
+ /* XXX this should go away */
+ ctx->Driver.ResizeBuffers = sisReAllocateBuffers;
+}
diff --git a/src/sis_state.h b/src/sis_state.h
new file mode 100644
index 0000000..8f7e2ac
--- /dev/null
+++ b/src/sis_state.h
@@ -0,0 +1,69 @@
+/**************************************************************************
+
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT 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.
+
+**************************************************************************/
+/* $XFree86$ */
+
+/*
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#ifndef __SIS_STATE_H__
+#define __SIS_STATE_H__
+
+#include "sis_context.h"
+
+/* sis6326_clear.c */
+extern void sis6326DDClear( GLcontext *ctx, GLbitfield mask );
+extern void sis6326DDClearColor( GLcontext * ctx, const GLfloat color[4] );
+extern void sis6326DDClearDepth( GLcontext * ctx, GLclampd d );
+extern void sis6326UpdateZPattern(sisContextPtr smesa, GLclampd z);
+
+/* sis_clear.c */
+extern void sisDDClear( GLcontext *ctx, GLbitfield mask );
+extern void sisDDClearColor( GLcontext * ctx, const GLfloat color[4] );
+extern void sisDDClearDepth( GLcontext * ctx, GLclampd d );
+extern void sisDDClearStencil( GLcontext * ctx, GLint s );
+extern void sisUpdateZStencilPattern( sisContextPtr smesa, GLclampd z,
+ int stencil );
+
+/* sis_fog.c */
+extern void sisDDFogfv( GLcontext * ctx, GLenum pname, const GLfloat * params );
+
+/* sis6326_state.c */
+extern void sis6326DDInitState( sisContextPtr smesa );
+extern void sis6326DDInitStateFuncs( GLcontext *ctx );
+extern void sis6326UpdateClipping( GLcontext * gc );
+extern void sis6326DDDrawBuffer( GLcontext *ctx, GLenum mode );
+extern void sis6326UpdateHWState( GLcontext *ctx );
+
+/* sis_state.c */
+extern void sisDDInitState( sisContextPtr smesa );
+extern void sisDDInitStateFuncs( GLcontext *ctx );
+extern void sisDDDepthMask( GLcontext * ctx, GLboolean flag );
+extern void sisUpdateClipping( GLcontext * gc );
+extern void sisDDDrawBuffer( GLcontext *ctx, GLenum mode );
+extern void sisUpdateHWState( GLcontext *ctx );
+
+#endif
diff --git a/src/sis_stencil.c b/src/sis_stencil.c
new file mode 100644
index 0000000..a1ce296
--- /dev/null
+++ b/src/sis_stencil.c
@@ -0,0 +1,206 @@
+/**************************************************************************
+
+Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
+
+**************************************************************************/
+/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_stencil.c,v 1.3 2000/09/26 15:56:49 tsi Exp $ */
+
+/*
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "sis_context.h"
+#include "sis_state.h"
+#include "sis_stencil.h"
+
+static void
+sisDDStencilFuncSeparate( GLcontext * ctx, GLenum face,
+ GLenum func, GLint ref, GLuint mask )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ /* set reference */
+ current->hwStSetting = (STENCIL_FORMAT_8 |
+ ((ctx->Stencil.Ref[0] & 0xff) << 8) |
+ (ctx->Stencil.ValueMask[0] & 0xff));
+
+ switch (func)
+ {
+ case GL_NEVER:
+ current->hwStSetting |= SiS_STENCIL_NEVER;
+ break;
+ case GL_LESS:
+ current->hwStSetting |= SiS_STENCIL_LESS;
+ break;
+ case GL_EQUAL:
+ current->hwStSetting |= SiS_STENCIL_EQUAL;
+ break;
+ case GL_LEQUAL:
+ current->hwStSetting |= SiS_STENCIL_LEQUAL;
+ break;
+ case GL_GREATER:
+ current->hwStSetting |= SiS_STENCIL_GREATER;
+ break;
+ case GL_NOTEQUAL:
+ current->hwStSetting |= SiS_STENCIL_NOTEQUAL;
+ break;
+ case GL_GEQUAL:
+ current->hwStSetting |= SiS_STENCIL_GEQUAL;
+ break;
+ case GL_ALWAYS:
+ current->hwStSetting |= SiS_STENCIL_ALWAYS;
+ break;
+ }
+
+ if (current->hwStSetting != prev->hwStSetting)
+ {
+ prev->hwStSetting = current->hwStSetting;
+
+ smesa->GlobalFlag |= GFLAG_STENCILSETTING;
+ }
+}
+
+static void
+sisDDStencilMaskSeparate( GLcontext * ctx, GLenum face, GLuint mask )
+{
+ if (!ctx->Visual.stencilBits)
+ return;
+
+ /* set Z buffer Write Enable */
+ sisDDDepthMask (ctx, ctx->Depth.Mask);
+}
+
+static void
+sisDDStencilOpSeparate( GLcontext * ctx, GLenum face, GLenum fail,
+ GLenum zfail, GLenum zpass )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ current->hwStSetting2 &= ~(MASK_StencilZPassOp | MASK_StencilZFailOp |
+ MASK_StencilFailOp);
+
+ switch (fail)
+ {
+ case GL_KEEP:
+ current->hwStSetting2 |= SiS_SFAIL_KEEP;
+ break;
+ case GL_ZERO:
+ current->hwStSetting2 |= SiS_SFAIL_ZERO;
+ break;
+ case GL_REPLACE:
+ current->hwStSetting2 |= SiS_SFAIL_REPLACE;
+ break;
+ case GL_INVERT:
+ current->hwStSetting2 |= SiS_SFAIL_INVERT;
+ break;
+ case GL_INCR:
+ current->hwStSetting2 |= SiS_SFAIL_INCR;
+ break;
+ case GL_DECR:
+ current->hwStSetting2 |= SiS_SFAIL_DECR;
+ break;
+ case GL_INCR_WRAP:
+ current->hwStSetting2 |= SiS_SFAIL_INCR_WRAP;
+ break;
+ case GL_DECR_WRAP:
+ current->hwStSetting2 |= SiS_SFAIL_DECR_WRAP;
+ break;
+ }
+
+ switch (zfail)
+ {
+ case GL_KEEP:
+ current->hwStSetting2 |= SiS_SPASS_ZFAIL_KEEP;
+ break;
+ case GL_ZERO:
+ current->hwStSetting2 |= SiS_SPASS_ZFAIL_ZERO;
+ break;
+ case GL_REPLACE:
+ current->hwStSetting2 |= SiS_SPASS_ZFAIL_REPLACE;
+ break;
+ case GL_INVERT:
+ current->hwStSetting2 |= SiS_SPASS_ZFAIL_INVERT;
+ break;
+ case GL_INCR:
+ current->hwStSetting2 |= SiS_SPASS_ZFAIL_INCR;
+ break;
+ case GL_DECR:
+ current->hwStSetting2 |= SiS_SPASS_ZFAIL_DECR;
+ break;
+ case GL_INCR_WRAP:
+ current->hwStSetting2 |= SiS_SPASS_ZFAIL_INCR_WRAP;
+ break;
+ case GL_DECR_WRAP:
+ current->hwStSetting2 |= SiS_SPASS_ZFAIL_DECR_WRAP;
+ break;
+ }
+
+ switch (zpass)
+ {
+ case GL_KEEP:
+ current->hwStSetting2 |= SiS_SPASS_ZPASS_KEEP;
+ break;
+ case GL_ZERO:
+ current->hwStSetting2 |= SiS_SPASS_ZPASS_ZERO;
+ break;
+ case GL_REPLACE:
+ current->hwStSetting2 |= SiS_SPASS_ZPASS_REPLACE;
+ break;
+ case GL_INVERT:
+ current->hwStSetting2 |= SiS_SPASS_ZPASS_INVERT;
+ break;
+ case GL_INCR:
+ current->hwStSetting2 |= SiS_SPASS_ZPASS_INCR;
+ break;
+ case GL_DECR:
+ current->hwStSetting2 |= SiS_SPASS_ZPASS_DECR;
+ break;
+ case GL_INCR_WRAP:
+ current->hwStSetting2 |= SiS_SPASS_ZPASS_INCR_WRAP;
+ break;
+ case GL_DECR_WRAP:
+ current->hwStSetting2 |= SiS_SPASS_ZPASS_DECR_WRAP;
+ break;
+ }
+
+ if (current->hwStSetting2 != prev->hwStSetting2)
+ {
+ prev->hwStSetting2 = current->hwStSetting2;
+ smesa->GlobalFlag |= GFLAG_STENCILSETTING;
+ }
+}
+
+void
+sisDDInitStencilFuncs( GLcontext *ctx )
+{
+ ctx->Driver.StencilFuncSeparate = sisDDStencilFuncSeparate;
+ ctx->Driver.StencilMaskSeparate = sisDDStencilMaskSeparate;
+ ctx->Driver.StencilOpSeparate = sisDDStencilOpSeparate;
+}
diff --git a/src/sis_stencil.h b/src/sis_stencil.h
new file mode 100644
index 0000000..4a36c98
--- /dev/null
+++ b/src/sis_stencil.h
@@ -0,0 +1,37 @@
+/**************************************************************************
+
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT 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.
+
+**************************************************************************/
+/* $XFree86$ */
+
+/*
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#ifndef __SIS_STENCIL_H__
+#define __SIS_STENCIL_H__
+
+extern void sisDDInitStencilFuncs( GLcontext *ctx );
+
+#endif
diff --git a/src/sis_tex.c b/src/sis_tex.c
new file mode 100644
index 0000000..8fd7b26
--- /dev/null
+++ b/src/sis_tex.c
@@ -0,0 +1,573 @@
+/**************************************************************************
+
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT 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.
+
+**************************************************************************/
+/* $XFree86$ */
+
+/*
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "sis_context.h"
+#include "sis_alloc.h"
+#include "sis_tex.h"
+
+#include "swrast/swrast.h"
+#include "imports.h"
+#include "texformat.h"
+#include "texstore.h"
+#include "teximage.h"
+#include "texobj.h"
+
+#include "xmlpool.h"
+
+#define ALIGN(value, align) (GLubyte *)((long)(value + align - 1) & ~(align - 1))
+
+#define TEXTURE_HW_ALIGNMENT 4
+#define TEXTURE_HW_PLUS (4 + 4)
+
+static sisTexObjPtr
+sisAllocTexObj( struct gl_texture_object *texObj )
+{
+ sisTexObjPtr t;
+
+ t = (sisTexObjPtr) CALLOC_STRUCT( sis_tex_obj );
+ texObj->DriverData = t;
+ return t;
+}
+
+static void
+sisAllocTexImage( sisContextPtr smesa, sisTexObjPtr t, int level,
+ const struct gl_texture_image *image )
+{
+ char *addr;
+ int size, texel_size;
+
+ if (t->format == 0) {
+ t->format = image->_BaseFormat;
+ switch (image->TexFormat->MesaFormat)
+ {
+ case MESA_FORMAT_ARGB8888:
+ t->hwformat = TEXEL_ARGB_8888_32;
+ break;
+ case MESA_FORMAT_ARGB4444:
+ t->hwformat = TEXEL_ARGB_4444_16;
+ break;
+ case MESA_FORMAT_ARGB1555:
+ t->hwformat = TEXEL_ARGB_1555_16;
+ break;
+ case MESA_FORMAT_RGB565:
+ t->hwformat = TEXEL_RGB_565_16;
+ break;
+ case MESA_FORMAT_RGB332:
+ t->hwformat = TEXEL_RGB_332_8;
+ break;
+ case MESA_FORMAT_I8:
+ t->hwformat = TEXEL_I8;
+ break;
+ case MESA_FORMAT_A8:
+ t->hwformat = TEXEL_A8;
+ break;
+ case MESA_FORMAT_L8:
+ t->hwformat = TEXEL_L8;
+ break;
+ case MESA_FORMAT_AL88:
+ t->hwformat = TEXEL_AL88;
+ break;
+ case MESA_FORMAT_YCBCR:
+ t->hwformat = TEXEL_YUV422;
+ break;
+ case MESA_FORMAT_YCBCR_REV:
+ t->hwformat = TEXEL_VUY422;
+ break;
+ default:
+ sis_fatal_error("Bad texture format 0x%x.\n",
+ image->TexFormat->MesaFormat);
+ }
+ }
+ assert(t->format == image->_BaseFormat);
+
+ texel_size = image->TexFormat->TexelBytes;
+ size = image->Width * image->Height * texel_size + TEXTURE_HW_PLUS;
+
+ addr = sisAllocFB( smesa, size, &t->image[level].handle );
+ if (addr == NULL) {
+ addr = sisAllocAGP( smesa, size, &t->image[level].handle );
+ if (addr == NULL)
+ sis_fatal_error("Failure to allocate texture memory.\n");
+ t->image[level].memType = AGP_TYPE;
+ }
+ else
+ t->image[level].memType = VIDEO_TYPE;
+
+ t->image[level].Data = ALIGN(addr, TEXTURE_HW_ALIGNMENT);
+ t->image[level].pitch = image->Width * texel_size;
+ t->image[level].size = image->Width * image->Height * texel_size;
+ t->numImages++;
+}
+
+static void
+sisFreeTexImage( sisContextPtr smesa, sisTexObjPtr t, int level )
+{
+ assert(level >= 0);
+ assert(level < SIS_MAX_TEXTURE_LEVELS);
+ if (t->image[level].Data == NULL)
+ return;
+
+ switch (t->image[level].memType)
+ {
+ case VIDEO_TYPE:
+ sisFreeFB( smesa, t->image[level].handle );
+ break;
+ case AGP_TYPE:
+ sisFreeAGP( smesa, t->image[level].handle );
+ break;
+ }
+ t->image[level].Data = NULL;
+ t->image[level].handle = NULL;
+ /* If there are no textures loaded any more, reset the hw format so the
+ * object can be reused for new formats
+ */
+ t->numImages--;
+ if (t->numImages == 0) {
+ t->format = 0;
+ t->hwformat = 0;
+ }
+}
+
+static void
+sisTexEnv( GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURE_ENV;
+}
+
+static void
+sisTexParameter( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj, GLenum pname,
+ const GLfloat *params )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURING;
+}
+
+static void
+sisBindTexture( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ sisTexObjPtr t;
+
+ if ( target == GL_TEXTURE_2D || target == GL_TEXTURE_1D ) {
+ if ( texObj->DriverData == NULL ) {
+ sisAllocTexObj( texObj );
+ }
+ }
+
+ t = texObj->DriverData;
+ if (!t)
+ return;
+
+ if (smesa->PrevTexFormat[ctx->Texture.CurrentUnit] != t->format) {
+ smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURE_ENV;
+ smesa->PrevTexFormat[ctx->Texture.CurrentUnit] = t->format;
+ }
+ smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURING;
+}
+
+static void
+sisDeleteTexture( GLcontext * ctx, struct gl_texture_object *texObj )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ sisTexObjPtr t;
+ int i;
+
+ smesa->clearTexCache = GL_TRUE;
+
+ t = texObj->DriverData;
+ if (t == NULL) {
+ /*
+ * this shows the texture is default object and never be a
+ * argument of sisTexImage*
+ */
+ return;
+ }
+ for (i = 0; i < SIS_MAX_TEXTURE_LEVELS; i++) {
+ sisFreeTexImage( smesa, t, i );
+ }
+
+ FREE(t);
+ texObj->DriverData = NULL;
+ /* Free mipmap images and the texture object itself */
+ _mesa_delete_texture_object(ctx, texObj);
+}
+
+static GLboolean sisIsTextureResident( GLcontext * ctx,
+ struct gl_texture_object *texObj )
+{
+ return (texObj->DriverData != NULL);
+}
+
+static const struct gl_texture_format *
+sisChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
+ GLenum format, GLenum type )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ const GLboolean do32bpt =
+ (smesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
+ const GLboolean force16bpt =
+ (smesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
+
+ switch ( internalFormat ) {
+ case 4:
+ case GL_RGBA:
+ case GL_COMPRESSED_RGBA:
+ switch ( type ) {
+ case GL_UNSIGNED_INT_10_10_10_2:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555;
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ return &_mesa_texformat_argb4444;
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ return &_mesa_texformat_argb1555;
+ default:
+ return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
+ }
+
+ case 3:
+ case GL_RGB:
+ case GL_COMPRESSED_RGB:
+ switch ( type ) {
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ return &_mesa_texformat_argb4444;
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ return &_mesa_texformat_argb1555;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ return &_mesa_texformat_rgb565;
+ default:
+ return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
+ }
+
+ case GL_RGBA8:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ return !force16bpt ?
+ &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
+
+ case GL_RGB10_A2:
+ return !force16bpt ?
+ &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555;
+
+ 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 !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
+
+ case GL_RGB5:
+ case GL_RGB4:
+ return &_mesa_texformat_rgb565;
+
+ case GL_R3_G3_B2:
+ return &_mesa_texformat_rgb332;
+
+ case GL_ALPHA:
+ case GL_ALPHA4: /* FIXME: This could use its own texstore */
+ 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: /* FIXME: This could use its own texstore */
+ 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: /* FIXME: This could use its own texstore */
+ case GL_LUMINANCE6_ALPHA2: /* FIXME: This could use its own texstore */
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4: /* FIXME: This could use its own texstore */
+ 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_APPLE ||
+ type == GL_UNSIGNED_BYTE)
+ return &_mesa_texformat_ycbcr;
+ else
+ return &_mesa_texformat_ycbcr_rev;
+
+ default:
+ _mesa_problem(ctx, "unexpected format in sisDDChooseTextureFormat: %d",
+ internalFormat);
+ return NULL;
+ }
+}
+
+static void sisTexImage1D( GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ sisTexObjPtr t;
+
+ if ( texObj->DriverData == NULL )
+ sisAllocTexObj( texObj );
+ t = texObj->DriverData;
+
+ /* Note, this will call sisChooseTextureFormat */
+ _mesa_store_teximage1d( ctx, target, level, internalFormat,
+ width, border, format, type,
+ pixels, packing, texObj, texImage );
+
+ /* Allocate offscreen space for the texture */
+ sisFreeTexImage(smesa, t, level);
+ sisAllocTexImage(smesa, t, level, texImage);
+
+ /* Upload the texture */
+ WaitEngIdle(smesa);
+ memcpy(t->image[level].Data, texImage->Data, t->image[level].size);
+
+ if (smesa->PrevTexFormat[ctx->Texture.CurrentUnit] != t->format)
+ {
+ smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURE_ENV;
+ smesa->PrevTexFormat[ctx->Texture.CurrentUnit] = t->format;
+ }
+ smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURING;
+}
+
+
+static void sisTexSubImage1D( 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 )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ sisTexObjPtr t;
+ GLuint copySize;
+ GLint texelBytes;
+ const char *src;
+ GLubyte *dst;
+
+ if ( texObj->DriverData == NULL )
+ sisAllocTexObj( texObj );
+ t = texObj->DriverData;
+
+ _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
+ format, type, pixels, packing, texObj,
+ texImage);
+
+ /* Allocate offscreen space for the texture */
+ sisFreeTexImage(smesa, t, level);
+ sisAllocTexImage(smesa, t, level, texImage);
+
+ /* Upload the texture */
+ WaitEngIdle(smesa);
+ texelBytes = texImage->TexFormat->TexelBytes;
+
+ copySize = width * texelBytes;
+ src = (char *)texImage->Data + xoffset * texelBytes;
+ dst = t->image[level].Data + xoffset * texelBytes;
+
+ memcpy( dst, src, copySize );
+
+ smesa->clearTexCache = GL_TRUE;
+
+ if (smesa->PrevTexFormat[ctx->Texture.CurrentUnit] != t->format)
+ {
+ smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURE_ENV;
+ smesa->PrevTexFormat[ctx->Texture.CurrentUnit] = t->format;
+ }
+ smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURING;
+}
+
+static void sisTexImage2D( GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ sisTexObjPtr t;
+
+ if ( texObj->DriverData == NULL )
+ sisAllocTexObj( texObj );
+ t = texObj->DriverData;
+
+ /* Note, this will call sisChooseTextureFormat */
+ _mesa_store_teximage2d(ctx, target, level, internalFormat,
+ width, height, border, format, type, pixels,
+ &ctx->Unpack, texObj, texImage);
+
+ /* Allocate offscreen space for the texture */
+ sisFreeTexImage(smesa, t, level);
+ sisAllocTexImage(smesa, t, level, texImage);
+
+ /* Upload the texture */
+ WaitEngIdle(smesa);
+ memcpy(t->image[level].Data, texImage->Data, t->image[level].size);
+
+ if (smesa->PrevTexFormat[ctx->Texture.CurrentUnit] != t->format)
+ {
+ smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURE_ENV;
+ smesa->PrevTexFormat[ctx->Texture.CurrentUnit] = t->format;
+ }
+ smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURING;
+}
+
+static void sisTexSubImage2D( 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 )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ sisTexObjPtr t;
+ GLuint copySize;
+ GLint texelBytes;
+ const char *src;
+ GLubyte *dst;
+ int j;
+ GLuint soffset;
+
+ if ( texObj->DriverData == NULL )
+ sisAllocTexObj( texObj );
+ t = texObj->DriverData;
+
+ _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
+ height, format, type, pixels, packing, texObj,
+ texImage);
+
+ /* Allocate offscreen space for the texture */
+ sisFreeTexImage(smesa, t, level);
+ sisAllocTexImage(smesa, t, level, texImage);
+
+ /* Upload the texture */
+ WaitEngIdle(smesa);
+ texelBytes = texImage->TexFormat->TexelBytes;
+
+ copySize = width * texelBytes;
+ src = (char *)texImage->Data + (xoffset + yoffset * texImage->Width) *
+ texelBytes;
+ dst = t->image[level].Data + (xoffset + yoffset * texImage->Width) *
+ texelBytes;
+ soffset = texImage->Width * texelBytes;
+
+ for (j = yoffset; j < yoffset + height; j++) {
+ memcpy( dst, src, copySize );
+ src += soffset;
+ dst += soffset;
+ }
+
+ smesa->clearTexCache = GL_TRUE;
+
+ if (smesa->PrevTexFormat[ctx->Texture.CurrentUnit] != t->format)
+ {
+ smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURE_ENV;
+ smesa->PrevTexFormat[ctx->Texture.CurrentUnit] = t->format;
+ }
+ smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURING;
+}
+
+
+/**
+ * Allocate a new texture object.
+ * Called via ctx->Driver.NewTextureObject.
+ * Note: this function will be called during context creation to
+ * allocate the default texture objects.
+ * Note: we could use containment here to 'derive' the driver-specific
+ * texture object from the core mesa gl_texture_object. Not done at this time.
+ */
+static struct gl_texture_object *
+sisNewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
+{
+ struct gl_texture_object *obj;
+ obj = _mesa_new_texture_object(ctx, name, target);
+ return obj;
+}
+
+
+void sisInitTextureFuncs( struct dd_function_table *functions )
+{
+ functions->TexEnv = sisTexEnv;
+ functions->ChooseTextureFormat = sisChooseTextureFormat;
+ functions->TexImage1D = sisTexImage1D;
+ functions->TexSubImage1D = sisTexSubImage1D;
+ functions->TexImage2D = sisTexImage2D;
+ functions->TexSubImage2D = sisTexSubImage2D;
+ functions->TexParameter = sisTexParameter;
+ functions->BindTexture = sisBindTexture;
+ functions->NewTextureObject = sisNewTextureObject;
+ functions->DeleteTexture = sisDeleteTexture;
+ functions->IsTextureResident = sisIsTextureResident;
+}
diff --git a/src/sis_tex.h b/src/sis_tex.h
new file mode 100644
index 0000000..8ddc7c4
--- /dev/null
+++ b/src/sis_tex.h
@@ -0,0 +1,38 @@
+/**************************************************************************
+
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT 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.
+
+**************************************************************************/
+/* $XFree86$ */
+
+/*
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#ifndef __SIS_TEX_H__
+#define __SIS_TEX_H__
+
+extern void sisInitTextureFuncs( struct dd_function_table *table );
+extern void sisUpdateTextureState( GLcontext *ctx );
+
+#endif /* __SIS_TEX_H__ */
diff --git a/src/sis_texstate.c b/src/sis_texstate.c
new file mode 100644
index 0000000..7ef20f8
--- /dev/null
+++ b/src/sis_texstate.c
@@ -0,0 +1,710 @@
+/**************************************************************************
+
+Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
+
+**************************************************************************/
+/* $XFree86$ */
+
+/*
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#include "colormac.h"
+#include "context.h"
+#include "macros.h"
+#include "texformat.h"
+
+#include "sis_context.h"
+#include "sis_state.h"
+#include "sis_tex.h"
+#include "sis_tris.h"
+#include "sis_alloc.h"
+
+static GLint TransferTexturePitch (GLint dwPitch);
+
+/* Handle texenv stuff, called from validate_texture (renderstart) */
+static void
+sis_set_texture_env0( GLcontext *ctx, struct gl_texture_object *texObj,
+ int unit )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ GLubyte c[4];
+
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ struct gl_texture_unit *texture_unit = &ctx->Texture.Unit[unit];
+
+ sisTexObjPtr t = texObj->DriverData;
+
+ switch (texture_unit->EnvMode)
+ {
+ case GL_REPLACE:
+ switch (t->format)
+ {
+ case GL_ALPHA:
+ current->hwTexBlendColor0 = STAGE0_C_CF;
+ current->hwTexBlendAlpha0 = STAGE0_A_AS;
+ break;
+ case GL_LUMINANCE:
+ case GL_RGB:
+ case GL_YCBCR_MESA:
+ current->hwTexBlendColor0 = STAGE0_C_CS;
+ current->hwTexBlendAlpha0 = STAGE0_A_AF;
+ break;
+ case GL_INTENSITY:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGBA:
+ current->hwTexBlendColor0 = STAGE0_C_CS;
+ current->hwTexBlendAlpha0 = STAGE0_A_AS;
+ break;
+ default:
+ sis_fatal_error("unknown base format 0x%x\n", t->format);
+ }
+ break;
+
+ case GL_MODULATE:
+ switch (t->format)
+ {
+ case GL_ALPHA:
+ current->hwTexBlendColor0 = STAGE0_C_CF;
+ current->hwTexBlendAlpha0 = STAGE0_A_AFAS;
+ break;
+ case GL_LUMINANCE:
+ case GL_RGB:
+ case GL_YCBCR_MESA:
+ current->hwTexBlendColor0 = STAGE0_C_CFCS;
+ current->hwTexBlendAlpha0 = STAGE0_A_AF;
+ break;
+ case GL_INTENSITY:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGBA:
+ current->hwTexBlendColor0 = STAGE0_C_CFCS;
+ current->hwTexBlendAlpha0 = STAGE0_A_AFAS;
+ break;
+ default:
+ sis_fatal_error("unknown base format 0x%x\n", t->format);
+ }
+ break;
+
+ case GL_DECAL:
+ switch (t->format)
+ {
+ case GL_RGB:
+ case GL_YCBCR_MESA:
+ current->hwTexBlendColor0 = STAGE0_C_CS;
+ current->hwTexBlendAlpha0 = STAGE0_A_AF;
+ break;
+ case GL_RGBA:
+ current->hwTexBlendColor0 = STAGE0_C_CFOMAS_CSAS;
+ current->hwTexBlendAlpha0 = STAGE0_A_AF;
+ break;
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_INTENSITY:
+ case GL_LUMINANCE_ALPHA:
+ current->hwTexBlendColor0 = STAGE0_C_CF;
+ current->hwTexBlendAlpha0 = STAGE0_A_AF;
+ break;
+ default:
+ sis_fatal_error("unknown base format 0x%x\n", t->format);
+ }
+ break;
+
+ case GL_BLEND:
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN(c, texture_unit->EnvColor);
+ current->hwTexEnvColor = ((GLint) (c[3])) << 24 |
+ ((GLint) (c[0])) << 16 |
+ ((GLint) (c[1])) << 8 |
+ ((GLint) (c[2]));
+ switch (t->format)
+ {
+ case GL_ALPHA:
+ current->hwTexBlendColor0 = STAGE0_C_CF;
+ current->hwTexBlendAlpha0 = STAGE0_A_AFAS;
+ break;
+ case GL_LUMINANCE:
+ case GL_RGB:
+ case GL_YCBCR_MESA:
+ current->hwTexBlendColor0 = STAGE0_C_CFOMCS_CCCS;
+ current->hwTexBlendAlpha0 = STAGE0_A_AF;
+ break;
+ case GL_INTENSITY:
+ current->hwTexBlendColor0 = STAGE0_C_CFOMCS_CCCS;
+ current->hwTexBlendAlpha0 = STAGE0_A_AFOMAS_ACAS;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGBA:
+ current->hwTexBlendColor0 = STAGE0_C_CFOMCS_CCCS;
+ current->hwTexBlendAlpha0 = STAGE0_A_AFAS;
+ break;
+ default:
+ sis_fatal_error("unknown base format 0x%x\n", t->format);
+ }
+ break;
+
+ default:
+ sis_fatal_error("unknown env mode 0x%x\n", texture_unit->EnvMode);
+ }
+
+ if ((current->hwTexBlendColor0 != prev->hwTexBlendColor0) ||
+ (current->hwTexBlendAlpha0 != prev->hwTexBlendAlpha0) ||
+ (current->hwTexEnvColor != prev->hwTexEnvColor))
+ {
+ prev->hwTexEnvColor = current->hwTexEnvColor;
+ prev->hwTexBlendColor0 = current->hwTexBlendColor0;
+ prev->hwTexBlendAlpha0 = current->hwTexBlendAlpha0;
+ smesa->GlobalFlag |= GFLAG_TEXTUREENV;
+ }
+}
+
+/* Handle texenv stuff, called from validate_texture (renderstart) */
+static void
+sis_set_texture_env1( GLcontext *ctx, struct gl_texture_object *texObj,
+ int unit)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ GLubyte c[4];
+
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ struct gl_texture_unit *texture_unit = &ctx->Texture.Unit[unit];
+
+ sisTexObjPtr t = texObj->DriverData;
+
+ switch (texture_unit->EnvMode)
+ {
+ case GL_REPLACE:
+ switch (t->format)
+ {
+ case GL_ALPHA:
+ current->hwTexBlendColor1 = STAGE1_C_CF;
+ current->hwTexBlendAlpha1 = STAGE1_A_AS;
+ break;
+ case GL_LUMINANCE:
+ case GL_RGB:
+ case GL_YCBCR_MESA:
+ current->hwTexBlendColor1 = STAGE1_C_CS;
+ current->hwTexBlendAlpha1 = STAGE1_A_AF;
+ break;
+ case GL_INTENSITY:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGBA:
+ current->hwTexBlendColor1 = STAGE1_C_CS;
+ current->hwTexBlendAlpha1 = STAGE1_A_AS;
+ break;
+ default:
+ sis_fatal_error("unknown base format 0x%x\n", t->format);
+ }
+ break;
+
+ case GL_MODULATE:
+ switch (t->format)
+ {
+ case GL_ALPHA:
+ current->hwTexBlendColor1 = STAGE1_C_CF;
+ current->hwTexBlendAlpha1 = STAGE1_A_AFAS;
+ break;
+ case GL_LUMINANCE:
+ case GL_RGB:
+ case GL_YCBCR_MESA:
+ current->hwTexBlendColor1 = STAGE1_C_CFCS;
+ current->hwTexBlendAlpha1 = STAGE1_A_AF;
+ break;
+ case GL_INTENSITY:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGBA:
+ current->hwTexBlendColor1 = STAGE1_C_CFCS;
+ current->hwTexBlendAlpha1 = STAGE1_A_AFAS;
+ break;
+ default:
+ sis_fatal_error("unknown base format 0x%x\n", t->format);
+ }
+ break;
+
+ case GL_DECAL:
+ switch (t->format)
+ {
+ case GL_RGB:
+ case GL_YCBCR_MESA:
+ current->hwTexBlendColor1 = STAGE1_C_CS;
+ current->hwTexBlendAlpha1 = STAGE1_A_AF;
+ break;
+ case GL_RGBA:
+ current->hwTexBlendColor1 = STAGE1_C_CFOMAS_CSAS;
+ current->hwTexBlendAlpha1 = STAGE1_A_AF;
+ break;
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_INTENSITY:
+ case GL_LUMINANCE_ALPHA:
+ current->hwTexBlendColor1 = STAGE1_C_CF;
+ current->hwTexBlendAlpha1 = STAGE1_A_AF;
+ break;
+ default:
+ sis_fatal_error("unknown base format 0x%x\n", t->format);
+ }
+ break;
+
+ case GL_BLEND:
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN(c, texture_unit->EnvColor);
+ current->hwTexEnvColor = ((GLint) (c[3])) << 24 |
+ ((GLint) (c[0])) << 16 |
+ ((GLint) (c[1])) << 8 |
+ ((GLint) (c[2]));
+ switch (t->format)
+ {
+ case GL_ALPHA:
+ current->hwTexBlendColor1 = STAGE1_C_CF;
+ current->hwTexBlendAlpha1 = STAGE1_A_AFAS;
+ break;
+ case GL_LUMINANCE:
+ case GL_RGB:
+ case GL_YCBCR_MESA:
+ current->hwTexBlendColor1 = STAGE1_C_CFOMCS_CCCS;
+ current->hwTexBlendAlpha1 = STAGE1_A_AF;
+ break;
+ case GL_INTENSITY:
+ current->hwTexBlendColor1 = STAGE1_C_CFOMCS_CCCS;
+ current->hwTexBlendAlpha1 = STAGE1_A_AFOMAS_ACAS;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGBA:
+ current->hwTexBlendColor1 = STAGE1_C_CFOMCS_CCCS;
+ current->hwTexBlendAlpha1 = STAGE1_A_AFAS;
+ break;
+ default:
+ sis_fatal_error("unknown base format 0x%x\n", t->format);
+ }
+ break;
+
+ default:
+ sis_fatal_error("unknown env mode 0x%x\n", texture_unit->EnvMode);
+ }
+
+ if ((current->hwTexBlendColor1 != prev->hwTexBlendColor1) ||
+ (current->hwTexBlendAlpha1 != prev->hwTexBlendAlpha1) ||
+ (current->hwTexEnvColor != prev->hwTexEnvColor))
+ {
+ prev->hwTexBlendColor1 = current->hwTexBlendColor1;
+ prev->hwTexBlendAlpha1 = current->hwTexBlendAlpha1;
+ prev->hwTexEnvColor = current->hwTexEnvColor;
+ smesa->GlobalFlag |= GFLAG_TEXTUREENV_1;
+ }
+}
+
+/* Returns 0 if a software fallback is necessary */
+static GLboolean
+sis_set_texobj_parm( GLcontext *ctx, struct gl_texture_object *texObj,
+ int hw_unit )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ int ok = 1;
+
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ sisTexObjPtr t = texObj->DriverData;
+
+ GLint firstLevel, lastLevel;
+ GLint i;
+
+ current->texture[hw_unit].hwTextureMip = 0UL;
+ current->texture[hw_unit].hwTextureSet = t->hwformat;
+
+ if ((texObj->MinFilter == GL_NEAREST) || (texObj->MinFilter == GL_LINEAR)) {
+ firstLevel = lastLevel = texObj->BaseLevel;
+ } else {
+ /* 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.
+ */
+
+ 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 +
+ texObj->Image[0][texObj->BaseLevel]->MaxLog2);
+ lastLevel = MIN2(lastLevel, texObj->MaxLevel);
+ lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
+ }
+
+ current->texture[hw_unit].hwTextureSet |= (lastLevel << 8);
+
+ switch (texObj->MagFilter)
+ {
+ case GL_NEAREST:
+ current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_NEAREST;
+ break;
+ case GL_LINEAR:
+ current->texture[hw_unit].hwTextureMip |= (TEXTURE_FILTER_LINEAR << 3);
+ break;
+ }
+
+ {
+ GLint b;
+
+ /* The mipmap lod biasing is based on experiment. It seems there's a
+ * limit of around +4/-4 to the bias value; we're being conservative.
+ */
+ b = (GLint) (ctx->Texture.Unit[hw_unit].LodBias * 32.0);
+ if (b > 127)
+ b = 127;
+ else if (b < -128)
+ b = -128;
+
+ current->texture[hw_unit].hwTextureMip |= ((b << 4) &
+ MASK_TextureMipmapLodBias);
+ }
+
+ switch (texObj->MinFilter)
+ {
+ case GL_NEAREST:
+ current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_NEAREST;
+ break;
+ case GL_LINEAR:
+ current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_LINEAR;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ current->texture[hw_unit].hwTextureMip |=
+ TEXTURE_FILTER_NEAREST_MIP_NEAREST;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ current->texture[hw_unit].hwTextureMip |=
+ TEXTURE_FILTER_NEAREST_MIP_LINEAR;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ current->texture[hw_unit].hwTextureMip |=
+ TEXTURE_FILTER_LINEAR_MIP_NEAREST;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ current->texture[hw_unit].hwTextureMip |=
+ TEXTURE_FILTER_LINEAR_MIP_LINEAR;
+ break;
+ }
+
+ switch (texObj->WrapS)
+ {
+ case GL_REPEAT:
+ current->texture[hw_unit].hwTextureSet |= MASK_TextureWrapU;
+ break;
+ case GL_MIRRORED_REPEAT:
+ current->texture[hw_unit].hwTextureSet |= MASK_TextureMirrorU;
+ break;
+ case GL_CLAMP:
+ current->texture[hw_unit].hwTextureSet |= MASK_TextureClampU;
+ /* XXX: GL_CLAMP isn't conformant, but falling back makes the situation
+ * worse in other programs at the moment.
+ */
+ /*ok = 0;*/
+ break;
+ case GL_CLAMP_TO_EDGE:
+ current->texture[hw_unit].hwTextureSet |= MASK_TextureClampU;
+ break;
+ case GL_CLAMP_TO_BORDER:
+ current->texture[hw_unit].hwTextureSet |= MASK_TextureBorderU;
+ break;
+ }
+
+ switch (texObj->WrapT)
+ {
+ case GL_REPEAT:
+ current->texture[hw_unit].hwTextureSet |= MASK_TextureWrapV;
+ break;
+ case GL_MIRRORED_REPEAT:
+ current->texture[hw_unit].hwTextureSet |= MASK_TextureMirrorV;
+ break;
+ case GL_CLAMP:
+ current->texture[hw_unit].hwTextureSet |= MASK_TextureClampV;
+ /* XXX: GL_CLAMP isn't conformant, but falling back makes the situation
+ * worse in other programs at the moment.
+ */
+ /*ok = 0;*/
+ break;
+ case GL_CLAMP_TO_EDGE:
+ current->texture[hw_unit].hwTextureSet |= MASK_TextureClampV;
+ break;
+ case GL_CLAMP_TO_BORDER:
+ current->texture[hw_unit].hwTextureSet |= MASK_TextureBorderV;
+ break;
+ }
+
+ current->texture[hw_unit].hwTextureBorderColor =
+ ((GLuint) texObj->_BorderChan[3] << 24) +
+ ((GLuint) texObj->_BorderChan[0] << 16) +
+ ((GLuint) texObj->_BorderChan[1] << 8) +
+ ((GLuint) texObj->_BorderChan[2]);
+
+ if (current->texture[hw_unit].hwTextureBorderColor !=
+ prev->texture[hw_unit].hwTextureBorderColor)
+ {
+ prev->texture[hw_unit].hwTextureBorderColor =
+ current->texture[hw_unit].hwTextureBorderColor;
+ if (hw_unit == 1)
+ smesa->GlobalFlag |= GFLAG_TEXBORDERCOLOR_1;
+ else
+ smesa->GlobalFlag |= GFLAG_TEXBORDERCOLOR;
+ }
+
+ current->texture[hw_unit].hwTextureSet |=
+ texObj->Image[0][firstLevel]->WidthLog2 << 4;
+ current->texture[hw_unit].hwTextureSet |=
+ texObj->Image[0][firstLevel]->HeightLog2;
+
+ if (hw_unit == 0)
+ smesa->GlobalFlag |= GFLAG_TEXTUREADDRESS;
+ else
+ smesa->GlobalFlag |= GFLAG_TEXTUREADDRESS_1;
+
+ for (i = firstLevel; i <= lastLevel; i++)
+ {
+ GLuint texOffset = 0;
+ GLuint texPitch = TransferTexturePitch( t->image[i].pitch );
+
+ switch (t->image[i].memType)
+ {
+ case VIDEO_TYPE:
+ texOffset = ((unsigned long)t->image[i].Data - (unsigned long)smesa->FbBase);
+ break;
+ case AGP_TYPE:
+ texOffset = ((unsigned long)t->image[i].Data - (unsigned long)smesa->AGPBase) +
+ (unsigned long) smesa->AGPAddr;
+ current->texture[hw_unit].hwTextureMip |=
+ (MASK_TextureLevel0InSystem << i);
+ break;
+ }
+
+ switch (i)
+ {
+ case 0:
+ prev->texture[hw_unit].texOffset0 = texOffset;
+ prev->texture[hw_unit].texPitch01 = texPitch << 16;
+ break;
+ case 1:
+ prev->texture[hw_unit].texOffset1 = texOffset;
+ prev->texture[hw_unit].texPitch01 |= texPitch;
+ break;
+ case 2:
+ prev->texture[hw_unit].texOffset2 = texOffset;
+ prev->texture[hw_unit].texPitch23 = texPitch << 16;
+ break;
+ case 3:
+ prev->texture[hw_unit].texOffset3 = texOffset;
+ prev->texture[hw_unit].texPitch23 |= texPitch;
+ break;
+ case 4:
+ prev->texture[hw_unit].texOffset4 = texOffset;
+ prev->texture[hw_unit].texPitch45 = texPitch << 16;
+ break;
+ case 5:
+ prev->texture[hw_unit].texOffset5 = texOffset;
+ prev->texture[hw_unit].texPitch45 |= texPitch;
+ break;
+ case 6:
+ prev->texture[hw_unit].texOffset6 = texOffset;
+ prev->texture[hw_unit].texPitch67 = texPitch << 16;
+ break;
+ case 7:
+ prev->texture[hw_unit].texOffset7 = texOffset;
+ prev->texture[hw_unit].texPitch67 |= texPitch;
+ break;
+ case 8:
+ prev->texture[hw_unit].texOffset8 = texOffset;
+ prev->texture[hw_unit].texPitch89 = texPitch << 16;
+ break;
+ case 9:
+ prev->texture[hw_unit].texOffset9 = texOffset;
+ prev->texture[hw_unit].texPitch89 |= texPitch;
+ break;
+ case 10:
+ prev->texture[hw_unit].texOffset10 = texOffset;
+ prev->texture[hw_unit].texPitch10 = texPitch << 16;
+ break;
+ case 11:
+ prev->texture[hw_unit].texOffset11 = texOffset;
+ prev->texture[hw_unit].texPitch10 |= texPitch;
+ break;
+ }
+ }
+
+ if (current->texture[hw_unit].hwTextureSet !=
+ prev->texture[hw_unit].hwTextureSet)
+ {
+ prev->texture[hw_unit].hwTextureSet =
+ current->texture[hw_unit].hwTextureSet;
+ if (hw_unit == 1)
+ smesa->GlobalFlag |= CFLAG_TEXTURERESET_1;
+ else
+ smesa->GlobalFlag |= CFLAG_TEXTURERESET;
+ }
+ if (current->texture[hw_unit].hwTextureMip !=
+ prev->texture[hw_unit].hwTextureMip)
+ {
+ prev->texture[hw_unit].hwTextureMip =
+ current->texture[hw_unit].hwTextureMip;
+ if (hw_unit == 1)
+ smesa->GlobalFlag |= GFLAG_TEXTUREMIPMAP_1;
+ else
+ smesa->GlobalFlag |= GFLAG_TEXTUREMIPMAP;
+ }
+
+ return ok;
+}
+
+/* Disable a texture unit, called from validate_texture */
+static void
+sis_reset_texture_env (GLcontext *ctx, int hw_unit)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ __GLSiSHardware *prev = &smesa->prev;
+ __GLSiSHardware *current = &smesa->current;
+
+ if (hw_unit == 1)
+ {
+ current->hwTexBlendColor1 = STAGE1_C_CF;
+ current->hwTexBlendAlpha1 = STAGE1_A_AF;
+
+ if ((current->hwTexBlendColor1 != prev->hwTexBlendColor1) ||
+ (current->hwTexBlendAlpha1 != prev->hwTexBlendAlpha1) ||
+ (current->hwTexEnvColor != prev->hwTexEnvColor))
+ {
+ prev->hwTexBlendColor1 = current->hwTexBlendColor1;
+ prev->hwTexBlendAlpha1 = current->hwTexBlendAlpha1;
+ prev->hwTexEnvColor = current->hwTexEnvColor;
+ smesa->GlobalFlag |= GFLAG_TEXTUREENV_1;
+ }
+ } else {
+ current->hwTexBlendColor0 = STAGE0_C_CF;
+ current->hwTexBlendAlpha0 = STAGE0_A_AF;
+
+ if ((current->hwTexBlendColor0 != prev->hwTexBlendColor0) ||
+ (current->hwTexBlendAlpha0 != prev->hwTexBlendAlpha0) ||
+ (current->hwTexEnvColor != prev->hwTexEnvColor))
+ {
+ prev->hwTexBlendColor0 = current->hwTexBlendColor0;
+ prev->hwTexBlendAlpha0 = current->hwTexBlendAlpha0;
+ prev->hwTexEnvColor = current->hwTexEnvColor;
+ smesa->GlobalFlag |= GFLAG_TEXTUREENV;
+ }
+ }
+}
+
+static void updateTextureUnit( GLcontext *ctx, int unit )
+{
+ sisContextPtr smesa = SIS_CONTEXT( ctx );
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *texObj = texUnit->_Current;
+ GLint fallbackbit;
+
+ if (unit == 0)
+ fallbackbit = SIS_FALLBACK_TEXTURE0;
+ else
+ fallbackbit = SIS_FALLBACK_TEXTURE1;
+
+ if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) {
+ if (smesa->TexStates[unit] & NEW_TEXTURING) {
+ GLboolean ok;
+
+ ok = sis_set_texobj_parm (ctx, texObj, unit);
+ FALLBACK( smesa, fallbackbit, !ok );
+ }
+ if (smesa->TexStates[unit] & NEW_TEXTURE_ENV) {
+ if (unit == 0)
+ sis_set_texture_env0( ctx, texObj, unit );
+ else
+ sis_set_texture_env1( ctx, texObj, unit );
+ }
+ smesa->TexStates[unit] = 0;
+ } else if ( texUnit->_ReallyEnabled ) {
+ /* fallback */
+ FALLBACK( smesa, fallbackbit, 1 );
+ } else {
+ sis_reset_texture_env( ctx, unit );
+ FALLBACK( smesa, fallbackbit, 0 );
+ }
+}
+
+
+void sisUpdateTextureState( GLcontext *ctx )
+{
+ sisContextPtr smesa = SIS_CONTEXT( ctx );
+ int i;
+ __GLSiSHardware *current = &smesa->current;
+
+#if 1
+ /* TODO : if unmark these, error in multitexture */ /* XXX */
+ for (i = 0; i < SIS_MAX_TEXTURES; i++)
+ smesa->TexStates[i] |= (NEW_TEXTURING | NEW_TEXTURE_ENV);
+#endif
+
+ updateTextureUnit( ctx, 0 );
+ updateTextureUnit( ctx, 1 );
+
+ /* XXX Issues with the 2nd unit but not the first being enabled? */
+ if ( ctx->Texture.Unit[0]._ReallyEnabled &
+ (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ||
+ ctx->Texture.Unit[1]._ReallyEnabled &
+ (TEXTURE_1D_BIT | TEXTURE_2D_BIT) )
+ {
+ current->hwCapEnable |= MASK_TextureEnable;
+ current->hwCapEnable &= ~MASK_TextureNumUsed;
+ if (ctx->Texture.Unit[1]._ReallyEnabled)
+ current->hwCapEnable |= 0x00002000;
+ else
+ current->hwCapEnable |= 0x00001000;
+ } else {
+ current->hwCapEnable &= ~MASK_TextureEnable;
+ }
+}
+
+static GLint
+BitScanForward( GLshort w )
+{
+ GLint i;
+
+ for (i = 0; i < 16; i++) {
+ if (w & (1 << i))
+ break;
+ }
+ return i;
+}
+
+static GLint
+TransferTexturePitch( GLint dwPitch )
+{
+ GLint dwRet, i;
+
+ i = BitScanForward( (GLshort)dwPitch );
+ dwRet = dwPitch >> i;
+ dwRet |= i << 9;
+ return dwRet;
+}
diff --git a/src/sis_tris.c b/src/sis_tris.c
new file mode 100644
index 0000000..a0e39dc
--- /dev/null
+++ b/src/sis_tris.c
@@ -0,0 +1,1154 @@
+/* $XFree86*/ /* -*- c-basic-offset: 3 -*- */
+/**************************************************************************
+
+Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "colormac.h"
+#include "macros.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+#include "sis_context.h"
+#include "sis_tris.h"
+#include "sis_state.h"
+#include "sis_lock.h"
+#include "sis_span.h"
+#include "sis_alloc.h"
+#include "sis_tex.h"
+
+/* 6326 and 300-series shared */
+static const GLuint hw_prim[GL_POLYGON+1] = {
+ OP_3D_POINT_DRAW, /* GL_POINTS */
+ OP_3D_LINE_DRAW, /* GL_LINES */
+ OP_3D_LINE_DRAW, /* GL_LINE_LOOP */
+ OP_3D_LINE_DRAW, /* GL_LINE_STRIP */
+ OP_3D_TRIANGLE_DRAW, /* GL_TRIANGLES */
+ OP_3D_TRIANGLE_DRAW, /* GL_TRIANGLE_STRIP */
+ OP_3D_TRIANGLE_DRAW, /* GL_TRIANGLE_FAN */
+ OP_3D_TRIANGLE_DRAW, /* GL_QUADS */
+ OP_3D_TRIANGLE_DRAW, /* GL_QUAD_STRIP */
+ OP_3D_TRIANGLE_DRAW /* GL_POLYGON */
+};
+
+static const GLuint hw_prim_mmio_fire[OP_3D_TRIANGLE_DRAW+1] = {
+ OP_3D_FIRE_TSARGBa,
+ OP_3D_FIRE_TSARGBb,
+ OP_3D_FIRE_TSARGBc
+};
+static const GLuint hw_prim_6326_mmio_fire[OP_3D_TRIANGLE_DRAW+1] = {
+ OP_6326_3D_FIRE_TSARGBa,
+ OP_6326_3D_FIRE_TSARGBb,
+ OP_6326_3D_FIRE_TSARGBc
+};
+
+static const GLuint hw_prim_mmio_shade[OP_3D_TRIANGLE_DRAW+1] = {
+ SHADE_FLAT_VertexA,
+ SHADE_FLAT_VertexB,
+ SHADE_FLAT_VertexC
+};
+
+static const GLuint hw_prim_agp_type[OP_3D_TRIANGLE_DRAW+1] = {
+ MASK_PsPointList,
+ MASK_PsLineList,
+ MASK_PsTriangleList
+};
+
+static const GLuint hw_prim_agp_shade[OP_3D_TRIANGLE_DRAW+1] = {
+ MASK_PsShadingFlatA,
+ MASK_PsShadingFlatB,
+ MASK_PsShadingFlatC
+};
+
+static void sisRasterPrimitive( GLcontext *ctx, GLuint hwprim );
+static void sisRenderPrimitive( GLcontext *ctx, GLenum prim );
+
+/***********************************************************************
+ * Emit primitives as inline vertices *
+ ***********************************************************************/
+
+#define HAVE_QUADS 0
+#define HAVE_LINES 1
+#define HAVE_POINTS 1
+#define CTX_ARG sisContextPtr smesa
+#define GET_VERTEX_DWORDS() smesa->vertex_size
+#define ALLOC_VERTS( n, size ) sisAllocDmaLow( smesa, n * size * sizeof(int) )
+#undef LOCAL_VARS
+#define LOCAL_VARS \
+ sisContextPtr smesa = SIS_CONTEXT(ctx); \
+ const char *vertptr = smesa->verts;
+#define VERT(x) (sisVertex *)(vertptr + (x * vertsize * sizeof(int)))
+#define VERTEX sisVertex
+#undef TAG
+#define TAG(x) sis_##x
+#include "tnl_dd/t_dd_triemit.h"
+#undef TAG
+#undef LOCAL_VARS
+
+/***********************************************************************
+ * Dispatch vertices to hardware through MMIO *
+ ***********************************************************************/
+
+/* The ARGB write of the last vertex of the primitive fires the 3d engine, so
+ * save it until the end.
+ */
+#define SIS_MMIO_WRITE_VERTEX(_v, i, lastvert) \
+do { \
+ GLuint __color, __i = 0; \
+ MMIO(REG_3D_TSXa+(i)*0x30, _v->ui[__i++]); \
+ MMIO(REG_3D_TSYa+(i)*0x30, _v->ui[__i++]); \
+ MMIO(REG_3D_TSZa+(i)*0x30, _v->ui[__i++]); \
+ if (SIS_STATES & VERT_W) \
+ MMIO(REG_3D_TSWGa+(i)*0x30, _v->ui[__i++]); \
+ __color = _v->ui[__i++]; \
+ if (SIS_STATES & VERT_SPEC) \
+ MMIO(REG_3D_TSFSa+(i)*0x30, _v->ui[__i++]); \
+ if (SIS_STATES & VERT_UV0) { \
+ MMIO(REG_3D_TSUAa+(i)*0x30, _v->ui[__i++]); \
+ MMIO(REG_3D_TSVAa+(i)*0x30, _v->ui[__i++]); \
+ } \
+ if (SIS_STATES & VERT_UV1) { \
+ MMIO(REG_3D_TSUBa+(i)*0x30, _v->ui[__i++]); \
+ MMIO(REG_3D_TSVBa+(i)*0x30, _v->ui[__i++]); \
+ } \
+ if (lastvert || (SIS_STATES & VERT_SMOOTH)) \
+ MMIO(REG_3D_TSARGBa+(i)*0x30, __color); \
+} while (0)
+
+#define SIS6326_MMIO_WRITE_VERTEX(_v, i, lastvert) \
+do { \
+ GLuint __color, __i = 0; \
+ MMIO(REG_6326_3D_TSXa+(i)*0x20, _v->ui[__i++]); \
+ MMIO(REG_6326_3D_TSYa+(i)*0x20, _v->ui[__i++]); \
+ MMIO(REG_6326_3D_TSZa+(i)*0x20, _v->ui[__i++]); \
+ if (SIS_STATES & VERT_W) \
+ MMIO(REG_6326_3D_TSWa+(i)*0x20, _v->ui[__i++]); \
+ __color = _v->ui[__i++]; \
+ if (SIS_STATES & VERT_SPEC) \
+ MMIO(REG_6326_3D_TSFSa+(i)*0x20, _v->ui[__i++]); \
+ if (SIS_STATES & VERT_UV0) { \
+ MMIO(REG_6326_3D_TSUa+(i)*0x20, _v->ui[__i++]); \
+ MMIO(REG_6326_3D_TSVa+(i)*0x20, _v->ui[__i++]); \
+ } \
+ if (lastvert || (SIS_STATES & VERT_SMOOTH)) \
+ MMIO(REG_6326_3D_TSARGBa+(i)*0x30, __color); \
+} while (0)
+
+#define MMIO_VERT_REG_COUNT 10
+
+#define VERT_SMOOTH 0x01
+#define VERT_W 0x02
+#define VERT_SPEC 0x04
+#define VERT_UV0 0x08
+#define VERT_UV1 0x10
+#define VERT_6326 0x20 /* Right after UV1, but won't have a UV1 set */
+
+typedef void (*mmio_draw_func)(sisContextPtr smesa, char *verts);
+static mmio_draw_func sis_tri_func_mmio[48];
+static mmio_draw_func sis_line_func_mmio[48];
+static mmio_draw_func sis_point_func_mmio[48];
+
+#define SIS_STATES (0)
+#define TAG(x) x##_none
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH)
+#define TAG(x) x##_g
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_W)
+#define TAG(x) x##_w
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_W)
+#define TAG(x) x##_gw
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SPEC)
+#define TAG(x) x##_s
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_SPEC)
+#define TAG(x) x##_gs
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_W | VERT_SPEC)
+#define TAG(x) x##_ws
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC)
+#define TAG(x) x##_gws
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_UV0)
+#define TAG(x) x##_t0
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_UV0)
+#define TAG(x) x##_gt0
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_W | VERT_UV0)
+#define TAG(x) x##_wt0
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV0)
+#define TAG(x) x##_gwt0
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SPEC | VERT_UV0)
+#define TAG(x) x##_st0
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV0)
+#define TAG(x) x##_gst0
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV0)
+#define TAG(x) x##_wst0
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV0)
+#define TAG(x) x##_gwst0
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_UV1)
+#define TAG(x) x##_t1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_UV1)
+#define TAG(x) x##_gt1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_W | VERT_UV1)
+#define TAG(x) x##_wt1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV1)
+#define TAG(x) x##_gwt1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SPEC | VERT_UV1)
+#define TAG(x) x##_st1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV1)
+#define TAG(x) x##_gst1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV1)
+#define TAG(x) x##_wst1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV1)
+#define TAG(x) x##_gwst1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_UV0 | VERT_UV1)
+#define TAG(x) x##_t0t1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_UV0 | VERT_UV1)
+#define TAG(x) x##_gt0t1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_W | VERT_UV0 | VERT_UV1)
+#define TAG(x) x##_wt0t1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV0 | VERT_UV1)
+#define TAG(x) x##_gwt0t1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SPEC | VERT_UV0 | VERT_UV1)
+#define TAG(x) x##_st0t1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV0 | VERT_UV1)
+#define TAG(x) x##_gst0t1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV0 | VERT_UV1)
+#define TAG(x) x##_wst0t1
+#include "sis_tritmp.h"
+
+#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV0 | VERT_UV1)
+#define TAG(x) x##_gwst0t1
+#include "sis_tritmp.h"
+
+/***********************************************************************
+ * Macros for t_dd_tritmp.h to draw basic primitives *
+ ***********************************************************************/
+
+#define TRI( a, b, c ) \
+do { \
+ if (DO_FALLBACK) \
+ smesa->draw_tri( smesa, a, b, c ); \
+ else \
+ sis_triangle( smesa, a, b, c ); \
+} while (0)
+
+#define QUAD( a, b, c, d ) \
+do { \
+ if (DO_FALLBACK) { \
+ smesa->draw_tri( smesa, a, b, d ); \
+ smesa->draw_tri( smesa, b, c, d ); \
+ } else \
+ sis_quad( smesa, a, b, c, d ); \
+} while (0)
+
+#define LINE( v0, v1 ) \
+do { \
+ if (DO_FALLBACK) \
+ smesa->draw_line( smesa, v0, v1 ); \
+ else \
+ sis_line( smesa, v0, v1 ); \
+} while (0)
+
+#define POINT( v0 ) \
+do { \
+ if (DO_FALLBACK) \
+ smesa->draw_point( smesa, v0 ); \
+ else \
+ sis_point( smesa, v0 ); \
+} while (0)
+
+/***********************************************************************
+ * Build render functions from dd templates *
+ ***********************************************************************/
+
+#define SIS_OFFSET_BIT 0x01
+#define SIS_TWOSIDE_BIT 0x02
+#define SIS_UNFILLED_BIT 0x04
+#define SIS_FALLBACK_BIT 0x08
+#define SIS_MAX_TRIFUNC 0x10
+
+
+static struct {
+ tnl_points_func points;
+ tnl_line_func line;
+ tnl_triangle_func triangle;
+ tnl_quad_func quad;
+} rast_tab[SIS_MAX_TRIFUNC];
+
+
+#define DO_FALLBACK (IND & SIS_FALLBACK_BIT)
+#define DO_OFFSET (IND & SIS_OFFSET_BIT)
+#define DO_UNFILLED (IND & SIS_UNFILLED_BIT)
+#define DO_TWOSIDE (IND & SIS_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 sisVertex
+#define TAB rast_tab
+
+#define DEPTH_SCALE smesa->depth_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) (smesa->verts + (e * smesa->vertex_size * sizeof(int)))
+
+#define VERT_SET_RGBA( v, c ) \
+do { \
+ sis_color_t *color = (sis_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 != 0) { \
+ sis_color_t *spec = (sis_color_t *)&((v)->ui[specoffset]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(spec->red, (c)[0]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(spec->green, (c)[1]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(spec->blue, (c)[2]); \
+ } \
+} while (0)
+#define VERT_COPY_SPEC( v0, v1 ) \
+do { \
+ if (specoffset != 0) { \
+ sis_color_t *spec0 = (sis_color_t *)&((v0)->ui[specoffset]); \
+ sis_color_t *spec1 = (sis_color_t *)&((v1)->ui[specoffset]); \
+ spec0->red = spec1->red; \
+ spec0->green = spec1->green; \
+ spec0->blue = spec1->blue; \
+ } \
+} 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 != 0) spec[idx] = v[idx]->ui[specoffset]
+#define VERT_RESTORE_SPEC( idx ) if (specoffset != 0) v[idx]->ui[specoffset] = spec[idx]
+
+#define LOCAL_VARS(n) \
+ sisContextPtr smesa = SIS_CONTEXT(ctx); \
+ GLuint color[n], spec[n]; \
+ GLuint coloroffset = smesa->coloroffset; \
+ GLuint specoffset = smesa->specoffset; \
+ (void) color; (void) spec; (void) coloroffset; (void) specoffset;
+
+/***********************************************************************
+ * Helpers for rendering unfilled primitives *
+ ***********************************************************************/
+
+#define RASTERIZE(x) if (smesa->hw_primitive != hw_prim[x]) \
+ sisRasterPrimitive( ctx, hw_prim[x] )
+#define RENDER_PRIMITIVE smesa->render_primitive
+#define IND SIS_FALLBACK_BIT
+#define TAG(x) x
+#include "tnl_dd/t_dd_unfilled.h"
+#undef IND
+
+
+/***********************************************************************
+ * Generate GL render functions *
+ ***********************************************************************/
+
+
+#define IND (0)
+#define TAG(x) x
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_UNFILLED_BIT)
+#define TAG(x) x##_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_OFFSET_BIT|SIS_UNFILLED_BIT)
+#define TAG(x) x##_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_TWOSIDE_BIT|SIS_UNFILLED_BIT)
+#define TAG(x) x##_twoside_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT|SIS_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_FALLBACK_BIT)
+#define TAG(x) x##_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_OFFSET_BIT|SIS_FALLBACK_BIT)
+#define TAG(x) x##_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_TWOSIDE_BIT|SIS_FALLBACK_BIT)
+#define TAG(x) x##_twoside_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT|SIS_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_UNFILLED_BIT|SIS_FALLBACK_BIT)
+#define TAG(x) x##_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_OFFSET_BIT|SIS_UNFILLED_BIT|SIS_FALLBACK_BIT)
+#define TAG(x) x##_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_TWOSIDE_BIT|SIS_UNFILLED_BIT|SIS_FALLBACK_BIT)
+#define TAG(x) x##_twoside_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT|SIS_UNFILLED_BIT| \
+ SIS_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+
+static void init_rast_tab( void )
+{
+ init();
+ init_offset();
+ init_twoside();
+ init_twoside_offset();
+ init_unfilled();
+ init_offset_unfilled();
+ init_twoside_unfilled();
+ init_twoside_offset_unfilled();
+ init_fallback();
+ init_offset_fallback();
+ init_twoside_fallback();
+ init_twoside_offset_fallback();
+ init_unfilled_fallback();
+ init_offset_unfilled_fallback();
+ init_twoside_unfilled_fallback();
+ init_twoside_offset_unfilled_fallback();
+}
+
+
+
+/***********************************************************************
+ * 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
+sis_fallback_tri( sisContextPtr smesa,
+ sisVertex *v0,
+ sisVertex *v1,
+ sisVertex *v2 )
+{
+ GLcontext *ctx = smesa->glCtx;
+ SWvertex v[3];
+ _swsetup_Translate( ctx, v0, &v[0] );
+ _swsetup_Translate( ctx, v1, &v[1] );
+ _swsetup_Translate( ctx, v2, &v[2] );
+ sisSpanRenderStart( ctx );
+ _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
+ sisSpanRenderFinish( ctx );
+ _swrast_flush( ctx );
+}
+
+
+static void
+sis_fallback_line( sisContextPtr smesa,
+ sisVertex *v0,
+ sisVertex *v1 )
+{
+ GLcontext *ctx = smesa->glCtx;
+ SWvertex v[2];
+ _swsetup_Translate( ctx, v0, &v[0] );
+ _swsetup_Translate( ctx, v1, &v[1] );
+ sisSpanRenderStart( ctx );
+ _swrast_Line( ctx, &v[0], &v[1] );
+ sisSpanRenderFinish( ctx );
+ _swrast_flush( ctx );
+}
+
+
+static void
+sis_fallback_point( sisContextPtr smesa,
+ sisVertex *v0 )
+{
+ GLcontext *ctx = smesa->glCtx;
+ SWvertex v[1];
+ _swsetup_Translate( ctx, v0, &v[0] );
+ sisSpanRenderStart( ctx );
+ _swrast_Point( ctx, &v[0] );
+ sisSpanRenderFinish( ctx );
+ _swrast_flush( ctx );
+}
+
+
+
+/**********************************************************************/
+/* Render unclipped begin/end objects */
+/**********************************************************************/
+
+#define IND 0
+#define V(x) (sisVertex *)(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) sisRenderPrimitive( ctx, x )
+#undef LOCAL_VARS
+#define LOCAL_VARS \
+ sisContextPtr smesa = SIS_CONTEXT(ctx); \
+ const GLuint vertsize = smesa->vertex_size; \
+ const char *vertptr = (char *)smesa->verts; \
+ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
+ (void) elt;
+#define RESET_STIPPLE
+#define RESET_OCCLUSION
+#define PRESERVE_VB_DEFS
+#define ELT(x) (x)
+#define TAG(x) sis_##x##_verts
+#include "tnl/t_vb_rendertmp.h"
+#undef ELT
+#undef TAG
+#define TAG(x) sis_##x##_elts
+#define ELT(x) elt[x]
+#include "tnl/t_vb_rendertmp.h"
+
+
+/**********************************************************************/
+/* Choose render functions */
+/**********************************************************************/
+
+#define POINT_FALLBACK (DD_POINT_SMOOTH)
+#define LINE_FALLBACK (DD_LINE_STIPPLE|DD_LINE_SMOOTH)
+#define TRI_FALLBACK (DD_TRI_STIPPLE|DD_TRI_SMOOTH)
+#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
+#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
+#define _SIS_NEW_RENDER_STATE (ANY_RASTER_FLAGS | ANY_FALLBACK_FLAGS)
+
+static void sisChooseRenderState(GLcontext *ctx)
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ sisContextPtr smesa = SIS_CONTEXT( ctx );
+ GLuint flags = ctx->_TriangleCaps;
+ GLuint index = 0;
+
+ if (smesa->Fallback)
+ return;
+
+ if (flags & (ANY_RASTER_FLAGS|ANY_FALLBACK_FLAGS)) {
+
+ if (flags & ANY_RASTER_FLAGS) {
+ if (flags & DD_TRI_LIGHT_TWOSIDE) index |= SIS_TWOSIDE_BIT;
+ if (flags & DD_TRI_OFFSET) index |= SIS_OFFSET_BIT;
+ if (flags & DD_TRI_UNFILLED) index |= SIS_UNFILLED_BIT;
+ }
+
+ smesa->draw_point = sis_point;
+ smesa->draw_line = sis_line;
+ smesa->draw_tri = sis_triangle;
+ /* Hook in fallbacks for specific primitives.
+ */
+ if (flags & ANY_FALLBACK_FLAGS) {
+ if (flags & POINT_FALLBACK)
+ smesa->draw_point = sis_fallback_point;
+ if (flags & LINE_FALLBACK)
+ smesa->draw_line = sis_fallback_line;
+ if (flags & TRI_FALLBACK)
+ smesa->draw_tri = sis_fallback_tri;
+ index |= SIS_FALLBACK_BIT;
+ }
+ }
+
+ if (index != smesa->RenderIndex) {
+ smesa->RenderIndex = index;
+
+ tnl->Driver.Render.Points = rast_tab[index].points;
+ tnl->Driver.Render.Line = rast_tab[index].line;
+ tnl->Driver.Render.ClippedLine = 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 = sis_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = sis_render_tab_elts;
+ tnl->Driver.Render.ClippedPolygon = sis_fast_clipped_poly;
+ } else {
+ tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+ tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
+ }
+ }
+}
+
+/**********************************************************************/
+/* Multipass rendering for front buffering */
+/**********************************************************************/
+static GLboolean multipass_cliprect( GLcontext *ctx, GLuint pass )
+{
+ sisContextPtr smesa = SIS_CONTEXT( ctx );
+
+ if (pass >= smesa->driDrawable->numClipRects) {
+ return GL_FALSE;
+ } else {
+ GLint x1, y1, x2, y2;
+
+ x1 = smesa->driDrawable->pClipRects[pass].x1 - smesa->driDrawable->x;
+ y1 = smesa->driDrawable->pClipRects[pass].y1 - smesa->driDrawable->y;
+ x2 = smesa->driDrawable->pClipRects[pass].x2 - smesa->driDrawable->x;
+ y2 = smesa->driDrawable->pClipRects[pass].y2 - smesa->driDrawable->y;
+
+ if (ctx->Scissor.Enabled) {
+ GLint scisy1 = Y_FLIP(ctx->Scissor.Y + ctx->Scissor.Height - 1);
+ GLint scisy2 = Y_FLIP(ctx->Scissor.Y);
+
+ if (ctx->Scissor.X > x1)
+ x1 = ctx->Scissor.X;
+ if (scisy1 > y1)
+ y1 = scisy1;
+ if (ctx->Scissor.X + ctx->Scissor.Width - 1 < x2)
+ x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
+ if (scisy2 < y2)
+ y2 = scisy2;
+ }
+
+ MMIO(REG_3D_ClipTopBottom, y1 << 13 | y2);
+ MMIO(REG_3D_ClipLeftRight, x1 << 13 | x2);
+ /* Mark that we clobbered these registers */
+ smesa->GlobalFlag |= GFLAG_CLIPPING;
+ return GL_TRUE;
+ }
+}
+
+
+
+/**********************************************************************/
+/* Validate state at pipeline start */
+/**********************************************************************/
+
+static void sisRunPipeline( GLcontext *ctx )
+{
+ sisContextPtr smesa = SIS_CONTEXT( ctx );
+
+ if (smesa->NewGLState) {
+ SIS_FIREVERTICES(smesa);
+ if (smesa->NewGLState & _NEW_TEXTURE) {
+ sisUpdateTextureState(ctx);
+ }
+
+ if (smesa->NewGLState & _SIS_NEW_RENDER_STATE)
+ sisChooseRenderState( ctx );
+
+ smesa->NewGLState = 0;
+ }
+
+ _tnl_run_pipeline( ctx );
+
+ /* XXX: If we put flushing in sis_state.c and friends, we can avoid this.
+ * Is it worth it?
+ */
+ SIS_FIREVERTICES(smesa);
+}
+
+/**********************************************************************/
+/* High level hooks for t_vb_render.c */
+/**********************************************************************/
+
+/* This is called when Mesa switches between rendering triangle
+ * primitives (such as GL_POLYGON, GL_QUADS, GL_TRIANGLE_STRIP, etc),
+ * and lines, points and bitmaps.
+ */
+
+static void sisRasterPrimitive( GLcontext *ctx, GLuint hwprim )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ if (smesa->hw_primitive != hwprim) {
+ SIS_FIREVERTICES(smesa);
+ smesa->hw_primitive = hwprim;
+
+ smesa->AGPParseSet &= ~(MASK_PsDataType | MASK_PsShadingMode);
+ smesa->AGPParseSet |= hw_prim_agp_type[hwprim];
+
+ if (smesa->is6326) {
+ smesa->dwPrimitiveSet &= ~(MASK_6326_DrawPrimitiveCommand |
+ MASK_6326_SetFirePosition | MASK_6326_ShadingMode);
+ smesa->dwPrimitiveSet |= hwprim | hw_prim_6326_mmio_fire[hwprim];
+ } else {
+ smesa->dwPrimitiveSet &= ~(MASK_DrawPrimitiveCommand |
+ MASK_SetFirePosition | MASK_ShadingMode);
+ smesa->dwPrimitiveSet |= hwprim | hw_prim_mmio_fire[hwprim];
+ }
+
+ if (ctx->Light.ShadeModel == GL_FLAT) {
+ smesa->AGPParseSet |= hw_prim_agp_shade[hwprim];
+ smesa->dwPrimitiveSet |= hw_prim_mmio_shade[hwprim];
+ } else {
+ smesa->AGPParseSet |= MASK_PsShadingSmooth;
+ if (smesa->is6326) {
+ smesa->dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_GOURAUD;
+ } else {
+ smesa->dwPrimitiveSet |= SHADE_GOURAUD;
+ }
+ }
+ }
+}
+
+static void sisRenderPrimitive( GLcontext *ctx, GLenum prim )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ smesa->render_primitive = prim;
+
+ if (prim >= GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
+ return;
+ sisRasterPrimitive( ctx, hw_prim[prim] );
+}
+
+#define EMIT_ATTR( ATTR, STYLE) \
+do { \
+ smesa->vertex_attrs[smesa->vertex_attr_count].attrib = (ATTR); \
+ smesa->vertex_attrs[smesa->vertex_attr_count].format = (STYLE); \
+ smesa->vertex_attr_count++; \
+} while (0)
+
+#define EMIT_PAD( N ) \
+do { \
+ smesa->vertex_attrs[smesa->vertex_attr_count].attrib = 0; \
+ smesa->vertex_attrs[smesa->vertex_attr_count].format = EMIT_PAD; \
+ smesa->vertex_attrs[smesa->vertex_attr_count].offset = (N); \
+ smesa->vertex_attr_count++; \
+} while (0)
+
+static void sisRenderStart( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ DECLARE_RENDERINPUTS(index_bitset);
+ GLuint AGPParseSet = smesa->AGPParseSet;
+ GLboolean tex_fallback = GL_FALSE;
+
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
+
+ if (ctx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT &&
+ smesa->driDrawable->numClipRects != 0)
+ {
+ multipass_cliprect(ctx, 0);
+ if (smesa->driDrawable->numClipRects > 1)
+ tnl->Driver.Render.Multipass = multipass_cliprect;
+ else
+ tnl->Driver.Render.Multipass = NULL;
+ } else {
+ tnl->Driver.Render.Multipass = NULL;
+ }
+
+ /* Important:
+ */
+ VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
+ smesa->vertex_attr_count = 0;
+
+ /* EMIT_ATTR's must be in order as they tell t_vertex.c how to build up a
+ * hardware vertex.
+ */
+
+ AGPParseSet &= ~(MASK_VertexDWSize | MASK_VertexDataFormat);
+ AGPParseSet |= SiS_PS_HAS_XYZ | SiS_PS_HAS_DIFFUSE;
+ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
+ EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT);
+ AGPParseSet |= SiS_PS_HAS_W;
+ smesa->coloroffset = 4;
+ } else {
+ EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT);
+ smesa->coloroffset = 3;
+ }
+
+ EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA);
+
+ smesa->specoffset = 0;
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
+ RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
+ AGPParseSet |= SiS_PS_HAS_SPECULAR;
+
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
+ EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR);
+ smesa->specoffset = smesa->coloroffset + 1;
+ } else {
+ EMIT_PAD(3);
+ }
+
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
+ EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F);
+ } else {
+ EMIT_PAD(1);
+ }
+ }
+
+ /* projective textures are not supported by the hardware */
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) {
+ if (VB->TexCoordPtr[0]->size > 2)
+ tex_fallback = GL_TRUE;
+ EMIT_ATTR(_TNL_ATTRIB_TEX0, EMIT_2F);
+ AGPParseSet |= SiS_PS_HAS_UV0;
+ }
+ /* Will only hit tex1 on SiS300 */
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) {
+ if (VB->TexCoordPtr[1]->size > 2)
+ tex_fallback = GL_TRUE;
+ EMIT_ATTR(_TNL_ATTRIB_TEX1, EMIT_2F);
+ AGPParseSet |= SiS_PS_HAS_UV1;
+ }
+ FALLBACK(smesa, SIS_FALLBACK_TEXTURE, tex_fallback);
+
+ if (!RENDERINPUTS_EQUAL( smesa->last_tcl_state_bitset, index_bitset )) {
+ smesa->AGPParseSet = AGPParseSet;
+
+ smesa->vertex_size = _tnl_install_attrs( ctx, smesa->vertex_attrs,
+ smesa->vertex_attr_count, smesa->hw_viewport, 0 );
+
+ smesa->vertex_size >>= 2;
+ smesa->AGPParseSet |= smesa->vertex_size << 28;
+ }
+}
+
+static void sisRenderFinish( GLcontext *ctx )
+{
+}
+
+/**********************************************************************/
+/* AGP/PCI vertex submission */
+/**********************************************************************/
+
+void
+sisFlushPrimsLocked(sisContextPtr smesa)
+{
+ if (smesa->vb_cur == smesa->vb_last)
+ return;
+
+ if (smesa->is6326)
+ sis6326UpdateHWState(smesa->glCtx);
+ else
+ sisUpdateHWState(smesa->glCtx);
+
+ if (smesa->using_agp) {
+ mWait3DCmdQueue(8);
+ mEndPrimitive();
+ MMIO(REG_3D_AGPCmBase, (smesa->vb_last - smesa->vb) +
+ smesa->vb_agp_offset);
+ MMIO(REG_3D_AGPTtDwNum, ((smesa->vb_cur - smesa->vb_last) / 4) |
+ 0x50000000);
+ MMIO(REG_3D_ParsingSet, smesa->AGPParseSet);
+ MMIO(REG_3D_AGPCmFire, (GLint)(-1));
+ mEndPrimitive();
+ } else {
+ int mmio_index = 0, incr = 0;
+ void (*sis_emit_func)(sisContextPtr smesa, char *verts) = NULL;
+
+ if (smesa->AGPParseSet & MASK_PsShadingSmooth)
+ mmio_index |= VERT_SMOOTH;
+ if (smesa->AGPParseSet & SiS_PS_HAS_SPECULAR)
+ mmio_index |= VERT_SPEC;
+ if (smesa->AGPParseSet & SiS_PS_HAS_W)
+ mmio_index |= VERT_W;
+ if (smesa->AGPParseSet & SiS_PS_HAS_UV0)
+ mmio_index |= VERT_UV0;
+ if (smesa->AGPParseSet & SiS_PS_HAS_UV1)
+ mmio_index |= VERT_UV1;
+ if (smesa->is6326)
+ mmio_index |= VERT_6326;
+
+ switch (smesa->AGPParseSet & MASK_PsDataType) {
+ case MASK_PsPointList:
+ incr = smesa->vertex_size * 4;
+ sis_emit_func = sis_point_func_mmio[mmio_index];
+ break;
+ case MASK_PsLineList:
+ incr = smesa->vertex_size * 4 * 2;
+ sis_emit_func = sis_line_func_mmio[mmio_index];
+ break;
+ case MASK_PsTriangleList:
+ incr = smesa->vertex_size * 4 * 3;
+ sis_emit_func = sis_tri_func_mmio[mmio_index];
+ break;
+ }
+
+ if (!smesa->is6326) {
+ mWait3DCmdQueue(1);
+ MMIO(REG_3D_PrimitiveSet, smesa->dwPrimitiveSet);
+ }
+ while (smesa->vb_last < smesa->vb_cur) {
+ sis_emit_func(smesa, smesa->vb_last);
+ smesa->vb_last += incr;
+ }
+ mWait3DCmdQueue(1);
+ mEndPrimitive();
+
+ /* With PCI, we can just start writing to the start of the VB again. */
+ smesa->vb_cur = smesa->vb;
+ }
+ smesa->vb_last = smesa->vb_cur;
+}
+
+void sisFlushPrims(sisContextPtr smesa)
+{
+ LOCK_HARDWARE();
+ sisFlushPrimsLocked(smesa);
+ UNLOCK_HARDWARE();
+}
+
+/**********************************************************************/
+/* Transition to/from hardware rasterization. */
+/**********************************************************************/
+
+static const char * const fallbackStrings[] = {
+ "Texture mode",
+ "Texture 0 mode",
+ "Texture 1 mode",
+ "Texture 0 env", /* Note: unused */
+ "Texture 1 env", /* Note: unused */
+ "glDrawBuffer(GL_FRONT_AND_BACK)",
+ "glEnable(GL_STENCIL) without hw stencil buffer",
+ "write mask",
+ "no_rast",
+};
+
+static const char *getFallbackString(GLuint bit)
+{
+ int i = 0;
+ while (bit > 1) {
+ i++;
+ bit >>= 1;
+ }
+ return fallbackStrings[i];
+}
+
+void sisFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ GLuint oldfallback = smesa->Fallback;
+
+ if (mode) {
+ smesa->Fallback |= bit;
+ if (oldfallback == 0) {
+ SIS_FIREVERTICES(smesa);
+ _swsetup_Wakeup( ctx );
+ smesa->RenderIndex = ~0;
+ if (SIS_DEBUG & DEBUG_FALLBACKS) {
+ fprintf(stderr, "SiS begin rasterization fallback: 0x%x %s\n",
+ bit, getFallbackString(bit));
+ }
+ }
+ }
+ else {
+ smesa->Fallback &= ~bit;
+ if (oldfallback == bit) {
+ _swrast_flush( ctx );
+ tnl->Driver.Render.Start = sisRenderStart;
+ tnl->Driver.Render.PrimitiveNotify = sisRenderPrimitive;
+ tnl->Driver.Render.Finish = sisRenderFinish;
+
+ tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
+ tnl->Driver.Render.CopyPV = _tnl_copy_pv;
+ tnl->Driver.Render.Interp = _tnl_interp;
+
+ _tnl_invalidate_vertex_state( ctx, ~0 );
+ _tnl_invalidate_vertices( ctx, ~0 );
+ _tnl_install_attrs( ctx,
+ smesa->vertex_attrs,
+ smesa->vertex_attr_count,
+ smesa->hw_viewport, 0 );
+
+ smesa->NewGLState |= _SIS_NEW_RENDER_STATE;
+ if (SIS_DEBUG & DEBUG_FALLBACKS) {
+ fprintf(stderr, "SiS end rasterization fallback: 0x%x %s\n",
+ bit, getFallbackString(bit));
+ }
+ }
+ }
+}
+
+
+/**********************************************************************/
+/* Initialization. */
+/**********************************************************************/
+
+void sisInitTriFuncs( GLcontext *ctx )
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ static int firsttime = 1;
+
+ if (firsttime) {
+ init_rast_tab();
+ firsttime = 0;
+
+ sis_vert_init_none();
+ sis_vert_init_g();
+ sis_vert_init_w();
+ sis_vert_init_gw();
+ sis_vert_init_s();
+ sis_vert_init_gs();
+ sis_vert_init_ws();
+ sis_vert_init_gws();
+ sis_vert_init_t0();
+ sis_vert_init_gt0();
+ sis_vert_init_wt0();
+ sis_vert_init_gwt0();
+ sis_vert_init_st0();
+ sis_vert_init_gst0();
+ sis_vert_init_wst0();
+ sis_vert_init_gwst0();
+ sis_vert_init_t1();
+ sis_vert_init_gt1();
+ sis_vert_init_wt1();
+ sis_vert_init_gwt1();
+ sis_vert_init_st1();
+ sis_vert_init_gst1();
+ sis_vert_init_wst1();
+ sis_vert_init_gwst1();
+ sis_vert_init_t0t1();
+ sis_vert_init_gt0t1();
+ sis_vert_init_wt0t1();
+ sis_vert_init_gwt0t1();
+ sis_vert_init_st0t1();
+ sis_vert_init_gst0t1();
+ sis_vert_init_wst0t1();
+ sis_vert_init_gwst0t1();
+ }
+
+ smesa->RenderIndex = ~0;
+ smesa->NewGLState |= _SIS_NEW_RENDER_STATE;
+
+ tnl->Driver.RunPipeline = sisRunPipeline;
+ tnl->Driver.Render.Start = sisRenderStart;
+ tnl->Driver.Render.Finish = sisRenderFinish;
+ tnl->Driver.Render.PrimitiveNotify = sisRenderPrimitive;
+ tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
+
+ 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) );
+
+ smesa->verts = (char *)tnl->clipspace.vertex_buf;
+}
diff --git a/src/sis_tris.h b/src/sis_tris.h
new file mode 100644
index 0000000..5e07acc
--- /dev/null
+++ b/src/sis_tris.h
@@ -0,0 +1,71 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.h,v 1.8 2002/10/30 12:51:43 alanh Exp $ */
+/**************************************************************************
+
+Copyright 2003 Eric Anholt
+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
+ERIC ANHOLT 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#ifndef __SIS_TRIS_H__
+#define __SIS_TRIS_H__
+
+#include "sis_lock.h"
+#include "mtypes.h"
+
+extern void sisInitTriFuncs( GLcontext *ctx );
+extern void sisFlushPrims( sisContextPtr smesa );
+extern void sisFlushPrimsLocked( sisContextPtr smesa );
+extern void sisFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
+
+#define FALLBACK( smesa, bit, mode ) sisFallback( smesa->glCtx, bit, mode )
+
+#define SIS_FIREVERTICES(smesa) \
+do { \
+ if (smesa->vb_cur != smesa->vb_last) \
+ sisFlushPrims(smesa); \
+} while (0)
+
+static __inline GLuint *sisAllocDmaLow(sisContextPtr smesa, int bytes)
+{
+ GLuint *start;
+
+ if (smesa->vb_cur + bytes >= smesa->vb_end) {
+ LOCK_HARDWARE();
+ sisFlushPrimsLocked(smesa);
+ if (smesa->using_agp) {
+ WaitEngIdle(smesa);
+ smesa->vb_cur = smesa->vb;
+ smesa->vb_last = smesa->vb_cur;
+ }
+ UNLOCK_HARDWARE();
+ }
+
+ start = (GLuint *)smesa->vb_cur;
+ smesa->vb_cur += bytes;
+ return start;
+}
+
+#endif /* __SIS_TRIS_H__ */
diff --git a/src/sis_tritmp.h b/src/sis_tritmp.h
new file mode 100644
index 0000000..e670a5b
--- /dev/null
+++ b/src/sis_tritmp.h
@@ -0,0 +1,250 @@
+/* $XFree86*/ /* -*- c-basic-offset: 3 -*- */
+/*
+ * Copyright 2005 Eric Anholt
+ * 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, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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 NONINFRINGEMENT. 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.
+ *
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ * Jim Duchek <jim@linuxpimps.com> -- Utah GLX 6326 code
+ * Alan Cox <alan@redhat.com> -- 6326 Debugging
+ *
+ */
+
+static void TAG(sis_draw_tri_mmio)(sisContextPtr smesa, char *verts)
+{
+ sisVertexPtr v0 = (sisVertexPtr)verts;
+ sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4);
+ sisVertexPtr v2 = (sisVertexPtr)(verts + smesa->vertex_size * 4 * 2);
+
+ mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 3);
+ SIS_MMIO_WRITE_VERTEX(v0, 0, 0);
+ SIS_MMIO_WRITE_VERTEX(v1, 1, 0);
+ SIS_MMIO_WRITE_VERTEX(v2, 2, 1);
+}
+
+static void TAG(sis_draw_line_mmio)(sisContextPtr smesa, char *verts)
+{
+ sisVertexPtr v0 = (sisVertexPtr)verts;
+ sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4);
+
+ mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 2);
+ SIS_MMIO_WRITE_VERTEX(v0, 0, 0);
+ SIS_MMIO_WRITE_VERTEX(v1, 1, 1);
+}
+
+static void TAG(sis_draw_point_mmio)(sisContextPtr smesa, char *verts)
+{
+ sisVertexPtr v0 = (sisVertexPtr)verts;
+
+ mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 1);
+ SIS_MMIO_WRITE_VERTEX(v0, 1, 1);
+}
+
+#if !(SIS_STATES & VERT_UV1)
+static void TAG(sis6326_draw_tri_mmio)(sisContextPtr smesa, char *verts)
+{
+ sisVertexPtr v0 = (sisVertexPtr)verts;
+ sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4);
+ sisVertexPtr v2 = (sisVertexPtr)(verts + smesa->vertex_size * 4 * 2);
+ GLfloat x0, x1, x2;
+ GLfloat y0, y1, y2;
+ GLfloat delt02, diffx02, diffy02, diffy12;
+ GLint dwPrimitiveSet = smesa->dwPrimitiveSet;
+ sisVertex tv0, tv1, tv2;
+
+ /* XXX Culling? */
+
+ tv0 = *v0;
+ tv1 = *v1;
+ tv2 = *v2;
+ tv0.v.y = Y_FLIP(tv0.v.y);
+ tv1.v.y = Y_FLIP(tv1.v.y);
+ tv2.v.y = Y_FLIP(tv2.v.y);
+ v0 = &tv0;
+ v1 = &tv1;
+ v2 = &tv2;
+
+ /* Cull polygons we won't draw. The hardware draws funky things if it
+ is fed these */
+ if((((v1->v.x - v0->v.x) * (v0->v.y - v2->v.y)) +
+ ((v1->v.y - v0->v.y) * (v2->v.x - v0->v.x))) < 0)
+ return;
+ y0 = v0->v.y;
+ y1 = v1->v.y;
+ y2 = v2->v.y;
+
+
+ if (y0 > y1) {
+ if (y1 > y2) {
+ x0 = v0->v.x;
+ x1 = v1->v.x;
+ x2 = v2->v.x;
+ dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_BMID | OP_6326_3D_CBOT;
+ if ((SIS_STATES & VERT_SMOOTH) == 0)
+ dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_BOT;
+ } else {
+ if (y0 > y2) {
+ x0 = v0->v.x;
+ x1 = v2->v.x;
+ y1 = v2->v.y;
+ dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_CMID |
+ OP_6326_3D_BBOT;
+ if ((SIS_STATES & VERT_SMOOTH) == 0)
+ dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_MID;
+ } else {
+ x0 = v2->v.x;
+ y0 = v2->v.y;
+ x1 = v0->v.x;
+ y1 = v0->v.y;
+ dwPrimitiveSet |= OP_6326_3D_CTOP | OP_6326_3D_AMID |
+ OP_6326_3D_BBOT;
+ if ((SIS_STATES & VERT_SMOOTH) == 0)
+ dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_TOP;
+ }
+ x2 = v1->v.x;
+ y2 = v1->v.y;
+ }
+ } else {
+ if (y0 > y2) {
+ x0 = v1->v.x;
+ y0 = v1->v.y;
+ x1 = v0->v.x;
+ y1 = v0->v.y;
+ x2 = v2->v.x;
+ dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_AMID | OP_6326_3D_CBOT;
+ if ((SIS_STATES & VERT_SMOOTH) == 0)
+ dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_BOT;
+ } else {
+ if (y1 > y2) {
+ x0 = v1->v.x;
+ y0 = v1->v.y;
+ x1 = v2->v.x;
+ y1 = v2->v.y;
+ dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_CMID |
+ OP_6326_3D_ABOT;
+ if ((SIS_STATES & VERT_SMOOTH) == 0)
+ dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_MID;
+ } else {
+ x0 = v2->v.x;
+ y0 = v2->v.y;
+ x1 = v1->v.x;
+ dwPrimitiveSet |= OP_6326_3D_CTOP | OP_6326_3D_BMID |
+ OP_6326_3D_ABOT;
+ if ((SIS_STATES & VERT_SMOOTH) == 0)
+ dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_TOP;
+ }
+ x2 = v0->v.x;
+ y2 = v0->v.y;
+ }
+ }
+
+ if (x1 <= x0 && x1 <= x2) {
+ dwPrimitiveSet |= OP_3D_DIRECTION_LEFT;
+ } else if (x1 < x0 || x1 < x2) {
+ GLfloat tmp;
+
+ diffx02 = x0 - x2;
+ diffy02 = y0 - y2;
+ diffy12 = y1 - y2;
+
+ delt02 = diffx02 / diffy02;
+ tmp = x1 - (diffy12 * delt02 + x2);
+
+ if (tmp <= 0.0)
+ dwPrimitiveSet |= OP_3D_DIRECTION_LEFT;
+ }
+
+ tv0 = *v0;
+ tv1 = *v1;
+ tv2 = *v2;
+ tv0.v.y = Y_FLIP(tv0.v.y);
+ tv1.v.y = Y_FLIP(tv1.v.y);
+ tv2.v.y = Y_FLIP(tv2.v.y);
+ v0 = &tv0;
+ v1 = &tv1;
+ v2 = &tv2;
+
+ y0 = v0->v.y;
+ y1 = v1->v.y;
+ y2 = v2->v.y;
+
+/* fprintf(stderr, "Vertex0 %f %f %f\n", v0->v.x, v0->v.y, v0->v.z);
+ fprintf(stderr, "Vertex1 %f %f %f\n", v1->v.x, v1->v.y, v1->v.z);
+ fprintf(stderr, "Vertex2 %f %f %f\n", v2->v.x, v2->v.y, v2->v.z);*/
+ mWait3DCmdQueue(MMIO_VERT_REG_COUNT * 3 + 1);
+ MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet);
+ SIS_MMIO_WRITE_VERTEX(v0, 0, 0);
+ SIS_MMIO_WRITE_VERTEX(v1, 1, 0);
+ SIS_MMIO_WRITE_VERTEX(v2, 2, 1);
+ mEndPrimitive();
+}
+
+static void TAG(sis6326_draw_line_mmio)(sisContextPtr smesa, char *verts)
+{
+ sisVertexPtr v0 = (sisVertexPtr)verts;
+ sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4);
+ GLint dwPrimitiveSet = smesa->dwPrimitiveSet;
+
+ if (abs(v0->v.y - v1->v.y) > abs(v0->v.x - v1->v.x))
+ {
+ dwPrimitiveSet |= OP_3D_DIRECTION_VERTICAL;
+ if (v0->v.y > v1->v.y)
+ dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_BBOT;
+ else
+ dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_ABOT;
+ } else {
+ if (v0->v.y > v1->v.y)
+ dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_ABOT;
+ else
+ dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_BBOT;
+ }
+
+ mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 2 + 1);
+ MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet);
+ SIS_MMIO_WRITE_VERTEX(v0, 0, 0);
+ SIS_MMIO_WRITE_VERTEX(v1, 1, 1);
+}
+
+static void TAG(sis6326_draw_point_mmio)(sisContextPtr smesa, char *verts)
+{
+ sisVertexPtr v0 = (sisVertexPtr)verts;
+
+ mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 1 + 1);
+ MMIO(REG_3D_PrimitiveSet, smesa->dwPrimitiveSet | OP_6326_3D_ATOP);
+ SIS_MMIO_WRITE_VERTEX(v0, 1, 1);
+}
+#endif
+
+static __inline void TAG(sis_vert_init)( void )
+{
+ sis_tri_func_mmio[SIS_STATES] = TAG(sis_draw_tri_mmio);
+ sis_line_func_mmio[SIS_STATES] = TAG(sis_draw_line_mmio);
+ sis_point_func_mmio[SIS_STATES] = TAG(sis_draw_point_mmio);
+#if !(SIS_STATES & VERT_UV1)
+ sis_tri_func_mmio[SIS_STATES | VERT_6326] = TAG(sis6326_draw_tri_mmio);
+ sis_line_func_mmio[SIS_STATES | VERT_6326] = TAG(sis6326_draw_line_mmio);
+ sis_point_func_mmio[SIS_STATES | VERT_6326] = TAG(sis6326_draw_point_mmio);
+#endif
+}
+
+#undef TAG
+#undef SIS_STATES