add the i810 driver - no kernel driver yet
authorAlan Hourihane <alanh@tungstengraphics.com>
Tue, 30 Sep 2003 10:54:15 +0000 (10:54 +0000)
committerAlan Hourihane <alanh@tungstengraphics.com>
Tue, 30 Sep 2003 10:54:15 +0000 (10:54 +0000)
(build tested, but not physically tested)

25 files changed:
Makefile.X11
src/mesa/drivers/dri/i810/Makefile.X11 [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810_3d_reg.h [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810context.c [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810context.h [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810ioctl.c [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810ioctl.h [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810render.c [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810screen.c [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810screen.h [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810span.c [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810span.h [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810state.c [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810state.h [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810tex.c [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810tex.h [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810texmem.c [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810texstate.c [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810tris.c [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810tris.h [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810vb.c [new file with mode: 0644]
src/mesa/drivers/dri/i810/i810vb.h [new file with mode: 0644]
src/mesa/drivers/dri/i810/server/i810_common.h [new file with mode: 0644]
src/mesa/drivers/dri/i810/server/i810_dri.h [new file with mode: 0644]
src/mesa/drivers/dri/i810/server/i810_reg.h [new file with mode: 0644]

index 0478ffc0601a012a6ccb51deb830e513d6bf1814..e00c1acb17f0e1cd192fc4a25d337d4100f5b085 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile.X11,v 1.85 2003/09/09 15:08:44 brianp Exp $
+# $Id: Makefile.X11,v 1.86 2003/09/30 10:54:15 alanh Exp $
 
 # Mesa 3-D graphics library
 # Version:  5.1
@@ -239,6 +239,7 @@ linux-solo:
        if [ -d src/mesa/drivers/dri/r128 ] ; then touch src/mesa/drivers/dri/r128/depend ; fi
        if [ -d src/mesa/drivers/dri/radeon ] ; then touch src/mesa/drivers/dri/radeon/depend ; fi
        if [ -d src/mesa/drivers/dri/mga ] ; then touch src/mesa/drivers/dri/mga/depend ; fi
+       if [ -d src/mesa/drivers/dri/i810 ] ; then touch src/mesa/drivers/dri/i810/depend ; fi
        if [ -d src/mesa/drivers/dri/fb ] ; then touch src/mesa/drivers/dri/fb/depend ; fi
        if [ -d src/glut/mini ] ; then touch src/glut/mini/depend ; fi
        if [ -d progs/miniglx ] ; then touch progs/miniglx/depend ; fi
@@ -248,6 +249,7 @@ linux-solo:
        if [ -d src/mesa/drivers/dri/r128 ] ; then cd src/mesa/drivers/dri/r128     ; $(MAKE) -f Makefile.X11 $@ ; fi
        if [ -d src/mesa/drivers/dri/radeon ] ; then cd src/mesa/drivers/dri/radeon ; $(MAKE) -f Makefile.X11 $@ ; fi
        if [ -d src/mesa/drivers/dri/mga ] ; then cd src/mesa/drivers/dri/mga       ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d src/mesa/drivers/dri/i810 ] ; then cd src/mesa/drivers/dri/i810       ; $(MAKE) -f Makefile.X11 $@ ; fi
        if [ -d src/mesa/drivers/dri/fb ] ; then cd src/mesa/drivers/dri/fb         ; $(MAKE) -f Makefile.X11 $@ ; fi
        if [ -d src/glx/mini  ] ; then cd src/glx/mini  ; $(MAKE) -f Makefile.X11 $@ ; fi
        if [ -d src/glu/mini  ] ; then cd src/glu/mini  ; $(MAKE) -f Makefile.X11 $@ ; fi
diff --git a/src/mesa/drivers/dri/i810/Makefile.X11 b/src/mesa/drivers/dri/i810/Makefile.X11
new file mode 100644 (file)
index 0000000..461da45
--- /dev/null
@@ -0,0 +1,116 @@
+# $Id: Makefile.X11,v 1.1 2003/09/30 10:54:15 alanh Exp $
+
+# Mesa 3-D graphics library
+# Version:  5.0
+# Copyright (C) 1995-2002  Brian Paul
+
+TOP = ../../../../..
+
+default: linux-solo
+
+SHARED_INCLUDES = $(INCLUDE_DIRS) -I. -I../common -Iserver
+MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini
+
+DEFINES += \
+       -D_HAVE_SWRAST=1 \
+       -D_HAVE_SWTNL=1 \
+       -D_HAVE_SANITY=1 \
+       -D_HAVE_CODEGEN=1 \
+       -D_HAVE_LIGHTING=1 \
+       -D_HAVE_TEXGEN=1 \
+       -D_HAVE_USERCLIP=1 \
+       -DGLX_DIRECT_RENDERING 
+
+# Not yet
+# MINIGLX_SOURCES = server/i810_dri.c 
+
+DRIVER_SOURCES = \
+               i810context.c \
+               i810ioctl.c \
+               i810render.c \
+               i810screen.c \
+               i810span.c \
+               i810state.c \
+               i810tex.c \
+               i810texmem.c \
+               i810texstate.c \
+               i810tris.c \
+               i810vb.c \
+                ../common/mm.c \
+                ../common/utils.c \
+                ../common/texmem.c \
+                ../common/vblank.c
+
+INCLUDES = $(MINIGLX_INCLUDES) \
+          $(SHARED_INCLUDES)
+
+
+C_SOURCES = $(DRIVER_SOURCES) \
+           $(MINIGLX_SOURCES) 
+
+MESA_MODULES = $(TOP)/src/mesa/mesa.a
+
+
+ifeq ($(WINDOW_SYSTEM),dri)
+WINOBJ=$(MESABUILDDIR)/dri/dri.a
+WINLIB=
+else
+WINOBJ=
+WINLIB=-L$(MESA)/src/glx/mini
+endif
+
+ASM_SOURCES = 
+OBJECTS = $(C_SOURCES:.c=.o) \
+         $(ASM_SOURCES:.S=.o) 
+
+### Include directories
+
+INCLUDE_DIRS = \
+       -I$(TOP)/include \
+       -I$(TOP)/src/mesa \
+       -I$(TOP)/src/mesa/main \
+       -I$(TOP)/src/mesa/glapi \
+       -I$(TOP)/src/mesa/math \
+       -I$(TOP)/src/mesa/transform \
+       -I$(TOP)/src/mesa/swrast \
+       -I$(TOP)/src/mesa/swrast_setup
+
+
+##### RULES #####
+
+.c.o:
+       $(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+.S.o:
+       $(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES)  $< -o $@
+
+
+##### TARGETS #####
+
+targets: depend i810_dri.so
+
+i810_dri.so:  $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile.X11
+       rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lc $(GL_LIB_DEPS)
+       rm -f $(TOP)/lib/i810_dri.so && \
+       install i810_dri.so $(TOP)/lib/i810_dri.so
+
+# Run 'make -f Makefile.X11 dep' to update the dependencies if you change
+# what's included by any source file.
+depend: $(C_SOURCES) $(ASM_SOURCES)
+       makedepend -fdepend -Y $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) \
+               $(C_SOURCES) $(ASM_SOURCES)
+
+
+# Emacs tags
+tags:
+       etags `find . -name \*.[ch]` `find ../include`
+
+
+# Remove .o and backup files
+clean:
+       -rm -f *.o */*.o *~ *.o *~ *.so server/*.o
+
+
+include $(TOP)/Make-config
+
+include depend
diff --git a/src/mesa/drivers/dri/i810/i810_3d_reg.h b/src/mesa/drivers/dri/i810/i810_3d_reg.h
new file mode 100644 (file)
index 0000000..dade1a8
--- /dev/null
@@ -0,0 +1,636 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h,v 1.7 2002/02/22 21:33:03 dawes Exp $ */
+
+#ifndef I810_3D_REG_H
+#define I810_3D_REG_H
+
+#include "i810_reg.h"
+
+/* Registers not used in the X server
+ */
+
+#define I810_NOP_ID           0x2094
+#define I810_NOP_ID_MASK        ((1<<22)-1)
+
+
+/* 3D instructions
+ */
+
+
+/* GFXRENDERSTATE_PV_PIXELIZATION_RULE, p149
+ *
+ * Format:
+ *     0: GFX_OP_PV_RULE | PV_*
+ *
+ */
+#define GFX_OP_PV_RULE           ((0x3<<29)|(0x7<<24))
+#define PV_SMALL_TRI_FILTER_ENABLE   (0x1<<11)
+#define PV_UPDATE_PIXRULE            (0x1<<10)
+#define PV_PIXRULE_ENABLE            (0x1<<9)
+#define PV_UPDATE_LINELIST           (0x1<<8)
+#define PV_LINELIST_MASK             (0x3<<6)
+#define PV_LINELIST_PV0              (0x0<<6)
+#define PV_LINELIST_PV1              (0x1<<6)
+#define PV_UPDATE_TRIFAN             (0x1<<5)
+#define PV_TRIFAN_MASK               (0x3<<3)
+#define PV_TRIFAN_PV0                (0x0<<3)
+#define PV_TRIFAN_PV1                (0x1<<3)
+#define PV_TRIFAN_PV2                (0x2<<3)
+#define PV_UPDATE_TRISTRIP           (0x1<<2)
+#define PV_TRISTRIP_MASK             (0x3<<0)
+#define PV_TRISTRIP_PV0              (0x0<<0)
+#define PV_TRISTRIP_PV1              (0x1<<0)
+#define PV_TRISTRIP_PV2              (0x2<<0)
+
+
+/* GFXRENDERSTATE_SCISSOR_ENABLE, p146
+ *
+ * Format:
+ *     0: GFX_OP_SCISSOR | SC_*
+ */
+#define GFX_OP_SCISSOR         ((0x3<<29)|(0x1c<<24)|(0x10<<19))
+#define SC_UPDATE_SCISSOR       (0x1<<1)
+#define SC_ENABLE_MASK          (0x1<<0)
+#define SC_ENABLE               (0x1<<0)
+
+/* GFXRENDERSTATE_SCISSOR_INFO, p147
+ *
+ * Format:
+ *     0: GFX_OP_SCISSOR_INFO
+ *     1: SCI_MIN_*
+ *     2: SCI_MAX_*
+ */
+#define GFX_OP_SCISSOR_INFO    ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
+#define SCI_YMIN_MASK      (0xffff<<16)
+#define SCI_XMIN_MASK      (0xffff<<0)
+#define SCI_YMAX_MASK      (0xffff<<16)
+#define SCI_XMAX_MASK      (0xffff<<0)
+
+/* GFXRENDERSTATE_DRAWING_RECT_INFO, p144
+ *
+ * Format:
+ *     0: GFX_OP_DRAWRECT_INFO
+ *     1: DR1_*
+ *     2: DR2_*
+ *     3: DR3_*
+ *     4: DR4_*
+ */
+#define GFX_OP_DRAWRECT_INFO   ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
+#define DR1_RECT_CLIP_ENABLE   (0x0<<31)
+#define DR1_RECT_CLIP_DISABLE  (0x1<<31)
+#define DR1_X_DITHER_BIAS_MASK (0x3<<26)
+#define DR1_X_DITHER_BIAS_SHIFT      26
+#define DR1_Y_DITHER_BIAS_MASK (0x3<<24)
+#define DR1_Y_DITHER_BIAS_SHIFT      24
+#define DR2_YMIN_MASK          (0xffff<<16)
+#define DR2_XMIN_MASK          (0xffff<<0)
+#define DR3_YMAX_MASK          (0xffff<<16)
+#define DR3_XMAX_MASK          (0xffff<<0)
+#define DR4_YORG_MASK          (0x3ff<<16)
+#define DR4_XORG_MASK          (0x7ff<<0)
+
+
+/* GFXRENDERSTATE_LINEWIDTH_CULL_SHADE_MODE, p140
+ *
+ * Format:
+ *     0: GFX_OP_LINEWIDTH_CULL_SHADE_MODE | LCS_*
+ */
+#define GFX_OP_LINEWIDTH_CULL_SHADE_MODE  ((0x3<<29)|(0x2<<24))
+#define LCS_UPDATE_ZMODE        (0x1<<20)
+#define LCS_Z_MASK              (0xf<<16)
+#define LCS_Z_NEVER             (0x1<<16)
+#define LCS_Z_LESS              (0x2<<16)
+#define LCS_Z_EQUAL             (0x3<<16)
+#define LCS_Z_LEQUAL            (0x4<<16)
+#define LCS_Z_GREATER           (0x5<<16)
+#define LCS_Z_NOTEQUAL          (0x6<<16)
+#define LCS_Z_GEQUAL            (0x7<<16)
+#define LCS_Z_ALWAYS            (0x8<<16)
+#define LCS_UPDATE_LINEWIDTH    (0x1<<15)
+#define LCS_LINEWIDTH_MASK      (0x7<<12)
+#define LCS_LINEWIDTH_SHIFT           12
+#define LCS_LINEWIDTH_0_5       (0x1<<12)
+#define LCS_LINEWIDTH_1_0       (0x2<<12)
+#define LCS_LINEWIDTH_2_0       (0x4<<12)
+#define LCS_LINEWIDTH_3_0       (0x6<<12)
+#define LCS_UPDATE_ALPHA_INTERP (0x1<<11)
+#define LCS_ALPHA_FLAT          (0x1<<10)
+#define LCS_ALPHA_INTERP        (0x0<<10)
+#define LCS_UPDATE_FOG_INTERP   (0x1<<9)
+#define LCS_FOG_INTERP          (0x0<<8)
+#define LCS_FOG_FLAT            (0x1<<8)
+#define LCS_UPDATE_SPEC_INTERP  (0x1<<7)
+#define LCS_SPEC_INTERP         (0x0<<6)
+#define LCS_SPEC_FLAT           (0x1<<6)
+#define LCS_UPDATE_RGB_INTERP   (0x1<<5)
+#define LCS_RGB_INTERP          (0x0<<4)
+#define LCS_RGB_FLAT            (0x1<<4)
+#define LCS_UPDATE_CULL_MODE    (0x1<<3)
+#define LCS_CULL_MASK           (0x7<<0)
+#define LCS_CULL_DISABLE        (0x1<<0)
+#define LCS_CULL_CW             (0x2<<0)
+#define LCS_CULL_CCW            (0x3<<0)
+#define LCS_CULL_BOTH           (0x4<<0)
+
+#define LCS_INTERP_FLAT (LCS_ALPHA_FLAT|LCS_RGB_FLAT|LCS_SPEC_FLAT)
+#define LCS_UPDATE_INTERP (LCS_UPDATE_ALPHA_INTERP|    \
+                          LCS_UPDATE_RGB_INTERP|       \
+                          LCS_UPDATE_SPEC_INTERP)
+
+
+/* GFXRENDERSTATE_BOOLEAN_ENA_1, p142
+ *
+ */
+#define GFX_OP_BOOL_1           ((0x3<<29)|(0x3<<24))
+#define B1_UPDATE_SPEC_SETUP_ENABLE   (1<<19)
+#define B1_SPEC_SETUP_ENABLE          (1<<18)
+#define B1_UPDATE_ALPHA_SETUP_ENABLE  (1<<17)
+#define B1_ALPHA_SETUP_ENABLE         (1<<16)
+#define B1_UPDATE_CI_KEY_ENABLE       (1<<15)
+#define B1_CI_KEY_ENABLE              (1<<14)
+#define B1_UPDATE_CHROMAKEY_ENABLE    (1<<13)
+#define B1_CHROMAKEY_ENABLE           (1<<12)
+#define B1_UPDATE_Z_BIAS_ENABLE       (1<<11)
+#define B1_Z_BIAS_ENABLE              (1<<10)
+#define B1_UPDATE_SPEC_ENABLE         (1<<9)
+#define B1_SPEC_ENABLE                (1<<8)
+#define B1_UPDATE_FOG_ENABLE          (1<<7)
+#define B1_FOG_ENABLE                 (1<<6)
+#define B1_UPDATE_ALPHA_TEST_ENABLE   (1<<5)
+#define B1_ALPHA_TEST_ENABLE          (1<<4)
+#define B1_UPDATE_BLEND_ENABLE        (1<<3)
+#define B1_BLEND_ENABLE               (1<<2)
+#define B1_UPDATE_Z_TEST_ENABLE       (1<<1)
+#define B1_Z_TEST_ENABLE              (1<<0)
+
+/* GFXRENDERSTATE_BOOLEAN_ENA_2, p143
+ *
+ */
+#define GFX_OP_BOOL_2          ((0x3<<29)|(0x4<<24))
+#define B2_UPDATE_MAP_CACHE_ENABLE     (1<<17)
+#define B2_MAP_CACHE_ENABLE            (1<<16)
+#define B2_UPDATE_ALPHA_DITHER_ENABLE  (1<<15)
+#define B2_ALPHA_DITHER_ENABLE         (1<<14)
+#define B2_UPDATE_FOG_DITHER_ENABLE    (1<<13)
+#define B2_FOG_DITHER_ENABLE           (1<<12)
+#define B2_UPDATE_SPEC_DITHER_ENABLE   (1<<11)
+#define B2_SPEC_DITHER_ENABLE          (1<<10)
+#define B2_UPDATE_RGB_DITHER_ENABLE    (1<<9)
+#define B2_RGB_DITHER_ENABLE           (1<<8)
+#define B2_UPDATE_FB_WRITE_ENABLE      (1<<3)
+#define B2_FB_WRITE_ENABLE             (1<<2)
+#define B2_UPDATE_ZB_WRITE_ENABLE      (1<<1)
+#define B2_ZB_WRITE_ENABLE             (1<<0)
+
+
+/* GFXRENDERSTATE_FOG_COLOR, p144
+ */
+#define GFX_OP_FOG_COLOR       ((0x3<<29)|(0x15<<24))
+#define FOG_RED_SHIFT          16
+#define FOG_GREEN_SHIFT        8
+#define FOG_BLUE_SHIFT         0
+#define FOG_RESERVED_MASK      ((0x7<<16)|(0x3<<8)|(0x3))
+
+
+/* GFXRENDERSTATE_Z_BIAS_ALPHA_FUNC_REF, p139
+ */
+#define GFX_OP_ZBIAS_ALPHAFUNC ((0x3<<29)|(0x14<<24))
+#define ZA_UPDATE_ZBIAS        (1<<22)
+#define ZA_ZBIAS_SHIFT         14
+#define ZA_ZBIAS_MASK          (0xff<<14)
+#define ZA_UPDATE_ALPHAFUNC    (1<<13)
+#define ZA_ALPHA_MASK          (0xf<<9)
+#define ZA_ALPHA_NEVER         (1<<9)
+#define ZA_ALPHA_LESS          (2<<9)
+#define ZA_ALPHA_EQUAL         (3<<9)
+#define ZA_ALPHA_LEQUAL        (4<<9)
+#define ZA_ALPHA_GREATER       (5<<9)
+#define ZA_ALPHA_NOTEQUAL      (6<<9)
+#define ZA_ALPHA_GEQUAL        (7<<9)
+#define ZA_ALPHA_ALWAYS        (8<<9)
+#define ZA_UPDATE_ALPHAREF     (1<<8)
+#define ZA_ALPHAREF_MASK       (0xff<<0)
+#define ZA_ALPHAREF_SHIFT      0
+#define ZA_ALPHAREF_RESERVED   (0x7<<0)
+
+
+/* GFXRENDERSTATE_SRC_DST_BLEND_MONO, p136
+ */
+#define GFX_OP_SRC_DEST_MONO    ((0x3<<29)|(0x8<<24))
+#define SDM_UPDATE_MONO_ENABLE      (1<<13)
+#define SDM_MONO_ENABLE             (1<<12)
+#define SDM_UPDATE_SRC_BLEND        (1<<11)
+#define SDM_SRC_MASK               (0xf<<6)
+#define SDM_SRC_ZERO               (0x1<<6)
+#define SDM_SRC_ONE                (0x2<<6)
+#define SDM_SRC_SRC_COLOR          (0x3<<6)
+#define SDM_SRC_INV_SRC_COLOR      (0x4<<6)
+#define SDM_SRC_SRC_ALPHA          (0x5<<6)
+#define SDM_SRC_INV_SRC_ALPHA      (0x6<<6)
+#define SDM_SRC_DST_COLOR          (0x9<<6)
+#define SDM_SRC_INV_DST_COLOR      (0xa<<6)
+#define SDM_SRC_BOTH_SRC_ALPHA     (0xc<<6)
+#define SDM_SRC_BOTH_INV_SRC_ALPHA (0xd<<6)
+#define SDM_UPDATE_DST_BLEND        (1<<5)
+#define SDM_DST_MASK               (0xf<<0)
+#define SDM_DST_ZERO               (0x1<<0)
+#define SDM_DST_ONE                (0x2<<0)
+#define SDM_DST_SRC_COLOR          (0x3<<0)
+#define SDM_DST_INV_SRC_COLOR      (0x4<<0)
+#define SDM_DST_SRC_ALPHA          (0x5<<0)
+#define SDM_DST_INV_SRC_ALPHA      (0x6<<0)
+#define SDM_DST_DST_COLOR          (0x9<<0)
+#define SDM_DST_INV_DST_COLOR      (0xa<<0)
+#define SDM_DST_BOTH_SRC_ALPHA     (0xc<<0)
+#define SDM_DST_BOTH_INV_SRC_ALPHA (0xd<<0)
+
+
+/* GFXRENDERSTATE_COLOR_FACTOR, p134
+ *
+ * Format:
+ *     0: GFX_OP_COLOR_FACTOR
+ *     1: ARGB8888 color factor
+ */
+#define GFX_OP_COLOR_FACTOR      ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
+
+/* GFXRENDERSTATE_MAP_ALPHA_BLEND_STAGES, p132
+ */
+#define GFX_OP_MAP_ALPHA_STAGES  ((0x3<<29)|(0x1<<24))
+#define MA_STAGE_SHIFT           20
+#define MA_STAGE_0               (0<<20)
+#define MA_STAGE_1               (1<<20)
+#define MA_STAGE_2               (2<<20)
+#define MA_UPDATE_ARG1           (1<<18)
+#define MA_ARG1_MASK             ((0x7<<15)|(0x1<<13))
+#define MA_ARG1_ALPHA_FACTOR     (0x1<<15)
+#define MA_ARG1_ITERATED_ALPHA   (0x3<<15)
+#define MA_ARG1_CURRENT_ALPHA    (0x5<<15)
+#define MA_ARG1_TEX0_ALPHA       (0x6<<15)
+#define MA_ARG1_TEX1_ALPHA       (0x7<<15)
+#define MA_ARG1_INVERT           (0x1<<13)
+#define MA_ARG1_DONT_INVERT      (0x0<<13)
+#define MA_UPDATE_ARG2           (1<<12)
+#define MA_ARG2_MASK             ((0x7<<8)|(0x1<<6))
+#define MA_ARG2_ALPHA_FACTOR     (0x1<<8)
+#define MA_ARG2_ITERATED_ALPHA   (0x3<<8)
+#define MA_ARG2_CURRENT_ALPHA    (0x5<<8)
+#define MA_ARG2_TEX0_ALPHA       (0x6<<8)
+#define MA_ARG2_TEX1_ALPHA       (0x7<<8)
+#define MA_ARG2_INVERT           (0x1<<6)
+#define MA_ARG2_DONT_INVERT      (0x0<<6)
+#define MA_UPDATE_OP             (1<<5)
+#define MA_OP_MASK                   (0xf)
+#define MA_OP_ARG1                   (0x1)
+#define MA_OP_ARG2                   (0x2)
+#define MA_OP_MODULATE               (0x3)
+#define MA_OP_MODULATE_X2            (0x4)
+#define MA_OP_MODULATE_X4            (0x5)
+#define MA_OP_ADD                    (0x6)
+#define MA_OP_ADD_SIGNED             (0x7)
+#define MA_OP_LIN_BLEND_ITER_ALPHA   (0x8)
+#define MA_OP_LIN_BLEND_ALPHA_FACTOR (0xa)
+#define MA_OP_LIN_BLEND_TEX0_ALPHA   (0x10)
+#define MA_OP_LIN_BLEND_TEX1_ALPHA   (0x11)
+
+
+/* GFXRENDERSTATE_MAP_COLOR_BLEND_STAGES, p129
+ */
+#define GFX_OP_MAP_COLOR_STAGES  ((0x3<<29)|(0x0<<24))
+#define MC_STAGE_SHIFT           20
+#define MC_STAGE_0               (0<<20)
+#define MC_STAGE_1               (1<<20)
+#define MC_STAGE_2               (2<<20)
+#define MC_UPDATE_DEST           (1<<19)
+#define MC_DEST_MASK             (1<<18)
+#define MC_DEST_CURRENT          (0<<18)
+#define MC_DEST_ACCUMULATOR      (1<<18)
+#define MC_UPDATE_ARG1           (1<<17)
+#define MC_ARG1_MASK             ((0x7<<14)|(0x1<<13)|(0x1<<12))
+#define MC_ARG1_ONE              (0x0<<14)
+#define MC_ARG1_COLOR_FACTOR     (0x1<<14)
+#define MC_ARG1_ACCUMULATOR      (0x2<<14)
+#define MC_ARG1_ITERATED_COLOR   (0x3<<14)
+#define MC_ARG1_SPECULAR_COLOR   (0x4<<14)
+#define MC_ARG1_CURRENT_COLOR    (0x5<<14)
+#define MC_ARG1_TEX0_COLOR       (0x6<<14)
+#define MC_ARG1_TEX1_COLOR       (0x7<<14)
+#define MC_ARG1_DONT_REPLICATE_ALPHA   (0x0<<13)
+#define MC_ARG1_REPLICATE_ALPHA        (0x1<<13)
+#define MC_ARG1_DONT_INVERT      (0x0<<12)
+#define MC_ARG1_INVERT           (0x1<<12)
+#define MC_UPDATE_ARG2           (1<<11)
+#define MC_ARG2_MASK             ((0x7<<8)|(0x1<<7)|(0x1<<6))
+#define MC_ARG2_ONE              (0x0<<8)
+#define MC_ARG2_COLOR_FACTOR     (0x1<<8)
+#define MC_ARG2_ACCUMULATOR      (0x2<<8)
+#define MC_ARG2_ITERATED_COLOR   (0x3<<8)
+#define MC_ARG2_SPECULAR_COLOR   (0x4<<8)
+#define MC_ARG2_CURRENT_COLOR    (0x5<<8)
+#define MC_ARG2_TEX0_COLOR       (0x6<<8)
+#define MC_ARG2_TEX1_COLOR       (0x7<<8)
+#define MC_ARG2_DONT_REPLICATE_ALPHA   (0x0<<7)
+#define MC_ARG2_REPLICATE_ALPHA        (0x1<<7)
+#define MC_ARG2_DONT_INVERT      (0x0<<6)
+#define MC_ARG2_INVERT           (0x1<<6)
+#define MC_UPDATE_OP             (1<<5)
+#define MC_OP_MASK                   (0xf)
+#define MC_OP_DISABLE                (0x0)
+#define MC_OP_ARG1                   (0x1)
+#define MC_OP_ARG2                   (0x2)
+#define MC_OP_MODULATE               (0x3)
+#define MC_OP_MODULATE_X2            (0x4)
+#define MC_OP_MODULATE_X4            (0x5)
+#define MC_OP_ADD                    (0x6)
+#define MC_OP_ADD_SIGNED             (0x7)
+#define MC_OP_LIN_BLEND_ITER_ALPHA   (0x8)
+#define MC_OP_LIN_BLEND_ALPHA_FACTOR (0xa)
+#define MC_OP_LIN_BLEND_TEX0_ALPHA   (0x10)
+#define MC_OP_LIN_BLEND_TEX1_ALPHA   (0x11)
+#define MC_OP_LIN_BLEND_TEX0_COLOR   (0x12)
+#define MC_OP_LIN_BLEND_TEX1_COLOR   (0x13)
+#define MC_OP_SUBTRACT               (0x14)
+
+/* GFXRENDERSTATE_MAP_PALETTE_LOAD, p128
+ *
+ * Format:
+ *     0:  GFX_OP_MAP_PALETTE_LOAD
+ *     1:  16bpp color[0]
+ *     ...
+ *     256: 16bpp color[255]
+ */
+#define GFX_OP_MAP_PALETTE_LOAD ((0x3<<29)|(0x1d<<24)|(0x82<<16)|0xff)
+
+/* GFXRENDERSTATE_MAP_LOD_CONTROL, p127
+ */
+#define GFX_OP_MAP_LOD_CTL       ((0x3<<29)|(0x1c<<24)|(0x4<<19))
+#define MLC_MAP_ID_SHIFT         16
+#define MLC_MAP_0                (0<<16)
+#define MLC_MAP_1                (1<<16)
+#define MLC_UPDATE_DITHER_WEIGHT (1<<10)
+#define MLC_DITHER_WEIGHT_MASK   (0x3<<8)
+#define MLC_DITHER_WEIGHT_FULL   (0x0<<8)
+#define MLC_DITHER_WEIGHT_50     (0x1<<8)
+#define MLC_DITHER_WEIGHT_25     (0x2<<8)
+#define MLC_DITHER_WEIGHT_12     (0x3<<8)
+#define MLC_UPDATE_LOD_BIAS      (1<<7)
+#define MLC_LOD_BIAS_MASK        ((1<<7)-1)
+
+/* GFXRENDERSTATE_MAP_LOD_LIMITS, p126
+ */
+#define GFX_OP_MAP_LOD_LIMITS   ((0x3<<29)|(0x1c<<24)|(0x3<<19))
+#define MLL_MAP_ID_SHIFT         16
+#define MLL_MAP_0                (0<<16)
+#define MLL_MAP_1                (1<<16)
+#define MLL_UPDATE_MAX_MIP       (1<<13)
+#define MLL_MAX_MIP_SHIFT        5
+#define MLL_MAX_MIP_MASK         (0xff<<5)
+#define MLL_MAX_MIP_ONE          (0x10<<5)
+#define MLL_UPDATE_MIN_MIP       (1<<4)
+#define MLL_MIN_MIP_SHIFT        0
+#define MLL_MIN_MIP_MASK         (0xf<<0)
+
+/* GFXRENDERSTATE_MAP_FILTER, p124
+ */
+#define GFX_OP_MAP_FILTER       ((0x3<<29)|(0x1c<<24)|(0x2<<19))
+#define MF_MAP_ID_SHIFT         16
+#define MF_MAP_0                (0<<16)
+#define MF_MAP_1                (1<<16)
+#define MF_UPDATE_ANISOTROPIC   (1<<12)
+#define MF_ANISOTROPIC_MASK     (1<<10)
+#define MF_ANISOTROPIC_ENABLE   (1<<10)
+#define MF_UPDATE_MIP_FILTER    (1<<9)
+#define MF_MIP_MASK             (0x3<<6)
+#define MF_MIP_NONE             (0x0<<6)
+#define MF_MIP_NEAREST          (0x1<<6)
+#define MF_MIP_DITHER           (0x2<<6)
+#define MF_MIP_LINEAR           (0x3<<6)
+#define MF_UPDATE_MAG_FILTER    (1<<5)
+#define MF_MAG_MASK             (1<<3)
+#define MF_MAG_LINEAR           (1<<3)
+#define MF_MAG_NEAREST          (0<<3)
+#define MF_UPDATE_MIN_FILTER    (1<<2)
+#define MF_MIN_MASK             (1<<0)
+#define MF_MIN_LINEAR           (1<<0)
+#define MF_MIN_NEAREST          (0<<0)
+
+/* GFXRENDERSTATE_MAP_INFO, p118
+ */
+#define GFX_OP_MAP_INFO      ((0x3<<29)|(0x1d<<24)|0x2)
+#define MI1_MAP_ID_SHIFT         28
+#define MI1_MAP_0                (0<<28)
+#define MI1_MAP_1                (1<<28)
+#define MI1_FMT_MASK             (0x7<<24)
+#define MI1_FMT_8CI              (0x0<<24)
+#define MI1_FMT_8BPP             (0x1<<24)
+#define MI1_FMT_16BPP            (0x2<<24)
+#define MI1_FMT_422              (0x5<<24)
+#define MI1_PF_MASK              (0x3<<21)
+#define MI1_PF_8CI_RGB565         (0x0<<21)
+#define MI1_PF_8CI_ARGB1555       (0x1<<21)
+#define MI1_PF_8CI_ARGB4444       (0x2<<21)
+#define MI1_PF_8CI_AY88           (0x3<<21)
+#define MI1_PF_16BPP_RGB565       (0x0<<21)
+#define MI1_PF_16BPP_ARGB1555     (0x1<<21)
+#define MI1_PF_16BPP_ARGB4444     (0x2<<21)
+#define MI1_PF_16BPP_AY88         (0x3<<21)
+#define MI1_PF_422_YCRCB_SWAP_Y   (0x0<<21)
+#define MI1_PF_422_YCRCB          (0x1<<21)
+#define MI1_PF_422_YCRCB_SWAP_UV  (0x2<<21)
+#define MI1_PF_422_YCRCB_SWAP_YUV (0x3<<21)
+#define MI1_OUTPUT_CHANNEL_MASK   (0x3<<19)
+#define MI1_COLOR_CONV_ENABLE     (1<<18)
+#define MI1_VERT_STRIDE_MASK      (1<<17)
+#define MI1_VERT_STRIDE_1         (1<<17)
+#define MI1_VERT_OFFSET_MASK      (1<<16)
+#define MI1_VERT_OFFSET_1         (1<<16)
+#define MI1_ENABLE_FENCE_REGS     (1<<10)
+#define MI1_TILED_SURFACE         (1<<9)
+#define MI1_TILE_WALK_X           (0<<8)
+#define MI1_TILE_WALK_Y           (1<<8)
+#define MI1_PITCH_MASK            (0xf<<0)
+#define MI2_DIMENSIONS_ARE_LOG2   (1<<31)
+#define MI2_DIMENSIONS_ARE_EXACT  (0<<31)
+#define MI2_HEIGHT_SHIFT          16
+#define MI2_HEIGHT_MASK           (0x1ff<<16)
+#define MI2_WIDTH_SHIFT           0
+#define MI2_WIDTH_MASK            (0x1ff<<0)
+#define MI3_BASE_ADDR_MASK        (~0xf)
+
+/* GFXRENDERSTATE_MAP_COORD_SETS, p116
+ */
+#define GFX_OP_MAP_COORD_SETS ((0x3<<29)|(0x1c<<24)|(0x1<<19))
+#define MCS_COORD_ID_SHIFT         16
+#define MCS_COORD_0                (0<<16)
+#define MCS_COORD_1                (1<<16)
+#define MCS_UPDATE_NORMALIZED      (1<<15)
+#define MCS_NORMALIZED_COORDS_MASK (1<<14)
+#define MCS_NORMALIZED_COORDS      (1<<14)
+#define MCS_UPDATE_V_STATE         (1<<7)
+#define MCS_V_STATE_MASK           (0x3<<4)
+#define MCS_V_WRAP                 (0x0<<4)
+#define MCS_V_MIRROR               (0x1<<4)
+#define MCS_V_CLAMP                (0x2<<4)
+#define MCS_V_WRAP_SHORTEST        (0x3<<4)
+#define MCS_UPDATE_U_STATE         (1<<3)
+#define MCS_U_STATE_MASK           (0x3<<0)
+#define MCS_U_WRAP                 (0x0<<0)
+#define MCS_U_MIRROR               (0x1<<0)
+#define MCS_U_CLAMP                (0x2<<0)
+#define MCS_U_WRAP_SHORTEST        (0x3<<0)
+
+/* GFXRENDERSTATE_MAP_TEXELS, p115
+ */
+#define GFX_OP_MAP_TEXELS   ((0x3<<29)|(0x1c<<24)|(0x0<<19))
+#define MT_UPDATE_TEXEL1_STATE     (1<<15)
+#define MT_TEXEL1_DISABLE          (0<<14)
+#define MT_TEXEL1_ENABLE           (1<<14)
+#define MT_TEXEL1_COORD0           (0<<11)
+#define MT_TEXEL1_COORD1           (1<<11)
+#define MT_TEXEL1_MAP0             (0<<8)
+#define MT_TEXEL1_MAP1             (1<<8)
+#define MT_UPDATE_TEXEL0_STATE     (1<<7)
+#define MT_TEXEL0_DISABLE          (0<<6)
+#define MT_TEXEL0_ENABLE           (1<<6)
+#define MT_TEXEL0_COORD0           (0<<3)
+#define MT_TEXEL0_COORD1           (1<<3)
+#define MT_TEXEL0_MAP0             (0<<0)
+#define MT_TEXEL0_MAP1             (1<<0)
+
+/* GFXRENDERSTATE_VERTEX_FORMAT, p110
+ */
+#define GFX_OP_VERTEX_FMT  ((0x3<<29)|(0x5<<24))
+#define VF_TEXCOORD_COUNT_SHIFT    8
+#define VF_TEXCOORD_COUNT_0        (0<<8)
+#define VF_TEXCOORD_COUNT_1        (1<<8)
+#define VF_TEXCOORD_COUNT_2        (2<<8)
+#define VF_SPEC_FOG_ENABLE         (1<<7)
+#define VF_RGBA_ENABLE             (1<<6)
+#define VF_Z_OFFSET_ENABLE         (1<<5)
+#define VF_XYZ                     (0x1<<1)
+#define VF_XYZW                    (0x2<<1)
+#define VF_XY                      (0x3<<1)
+#define VF_XYW                     (0x4<<1)
+
+
+#define VERT_X_MASK       (~0xf)
+#define VERT_X_EDGE_V2V0  (1<<2)
+#define VERT_X_EDGE_V1V2  (1<<1)
+#define VERT_X_EDGE_V0V1  (1<<0)
+
+/* Not enabled fields should not be sent to hardware:
+ */
+typedef struct {
+   union {
+      float x;
+      unsigned int edge_flags;
+   } x;
+   float y;
+   float z;
+   float z_bias;
+   float oow;
+   unsigned int argb;
+   unsigned int fog_spec_rgb;  /* spec g and r ignored. */
+   float tu0;
+   float tv0;
+   float tu1;
+   float tv1;
+} i810_full_vertex;
+
+
+
+/* GFXCMDPARSER_BATCH_BUFFER, p105
+ *
+ * Not clear whether start address must be shifted or not.  Not clear
+ * whether address is physical system memory, or subject to GTT
+ * translation.  Because the address appears to be 32 bits long,
+ * perhaps it refers to physical system memory...
+ */
+#define CMD_OP_BATCH_BUFFER  ((0x0<<29)|(0x30<<23)|0x1)
+#define BB1_START_ADDR_MASK   (~0x7)
+#define BB1_PROTECTED         (1<<0)
+#define BB1_UNPROTECTED       (0<<0)
+#define BB2_END_ADDR_MASK     (~0x7)
+
+/* Hardware seems to barf on buffers larger than this (in strange ways)...
+ */
+#define MAX_BATCH (512*1024)
+
+
+/* GFXCMDPARSER_Z_BUFFER_INFO, p98
+ *
+ * Base address is in GTT space, and must be 4K aligned
+ */
+#define CMD_OP_Z_BUFFER_INFO  ((0x0<<29)|(0x16<<23))
+#define ZB_BASE_ADDR_SHIFT     0
+#define ZB_BASE_ADDR_MASK     (~((1<<12)-1))
+#define ZB_PITCH_512B         (0x0<<0)
+#define ZB_PITCH_1K           (0x1<<0)
+#define ZB_PITCH_2K           (0x2<<0)
+#define ZB_PITCH_4K           (0x3<<0)
+
+/* GFXCMDPARSER_FRONT_BUFFER_INFO, p97
+ *
+ * Format:
+ *     0:  CMD_OP_FRONT_BUFFER_INFO | (pitch<<FB0_PITCH_SHIFT) | FB0_*
+ *     1:  FB1_*
+ */
+#define CMD_OP_FRONT_BUFFER_INFO ((0x0<<29)|(0x14<<23))
+#define FB0_PITCH_SHIFT           8
+#define FB0_FLIP_SYNC            (0<<6)
+#define FB0_FLIP_ASYNC           (1<<6)
+#define FB0_BASE_ADDR_SHIFT       0
+#define FB0_BASE_ADDR_MASK        0x03FFFFF8
+
+/* GFXCMDPARSER_DEST_BUFFER_INFO, p96
+ *
+ * Format:
+ */
+#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23))
+#define DB1_BASE_ADDR_SHIFT       0
+#define DB1_BASE_ADDR_MASK        0x03FFF000
+#define DB1_PITCH_512B            (0x0<<0)
+#define DB1_PITCH_1K              (0x1<<0)
+#define DB1_PITCH_2K              (0x2<<0)
+#define DB1_PITCH_4K              (0x4<<0)
+
+
+/* GFXRENDERSTATE_DEST_BUFFER_VARIABLES, p152
+ *
+ * Format:
+ *     0:  GFX_OP_DESTBUFFER_VARS
+ *     1:  DEST_*
+ */
+#define GFX_OP_DESTBUFFER_VARS   ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
+#define DV_HORG_BIAS_MASK      (0xf<<20)
+#define DV_HORG_BIAS_OGL       (0x0<<20)
+#define DV_VORG_BIAS_MASK      (0xf<<16)
+#define DV_VORG_BIAS_OGL       (0x0<<16)
+#define DV_PF_MASK             (0x7<<8)
+#define DV_PF_INDEX            (0x0<<8)
+#define DV_PF_555           (0x1<<8)
+#define DV_PF_565           (0x2<<8)
+
+#define GFX_OP_ANTIALIAS         ((0x3<<29)|(0x6<<24))
+#define AA_UPDATE_EDGEFLAG       (1<<13)
+#define AA_ENABLE_EDGEFLAG       (1<<12)
+#define AA_UPDATE_POLYWIDTH      (1<<11)
+#define AA_POLYWIDTH_05          (1<<9)
+#define AA_POLYWIDTH_10          (2<<9)
+#define AA_POLYWIDTH_20          (3<<9)
+#define AA_POLYWIDTH_40          (4<<9)
+#define AA_UPDATE_LINEWIDTH      (1<<8)
+#define AA_LINEWIDTH_05          (1<<6)
+#define AA_LINEWIDTH_10          (2<<6)
+#define AA_LINEWIDTH_20          (3<<6)
+#define AA_LINEWIDTH_40          (4<<6)
+#define AA_UPDATE_BB_EXPANSION   (1<<5)
+#define AA_BB_EXPANSION_SHIFT    2
+#define AA_UPDATE_AA_ENABLE      (1<<1)
+#define AA_ENABLE                (1<<0)
+
+#define GFX_OP_STIPPLE           ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define ST1_ENABLE               (1<<16)
+#define ST1_MASK                 (0xffff)
+
+#define I810_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
+
+#endif
diff --git a/src/mesa/drivers/dri/i810/i810context.c b/src/mesa/drivers/dri/i810/i810context.c
new file mode 100644 (file)
index 0000000..da1764c
--- /dev/null
@@ -0,0 +1,532 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810context.c,v 1.3 2002/10/30 12:51:33 alanh Exp $ */
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ *
+ */
+
+
+#include "glheader.h"
+#include "context.h"
+#include "matrix.h"
+#include "simple_list.h"
+#include "extensions.h"
+#include "imports.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "array_cache/acache.h"
+
+#include "tnl/t_pipeline.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810state.h"
+#include "i810tex.h"
+#include "i810span.h"
+#include "i810tris.h"
+#include "i810vb.h"
+#include "i810ioctl.h"
+
+#include "utils.h"
+#ifndef I810_DEBUG
+int I810_DEBUG = (0);
+#endif
+
+static const GLubyte *i810GetString( GLcontext *ctx, GLenum name )
+{
+   switch (name) {
+   case GL_VENDOR:
+      return (GLubyte *)"Keith Whitwell";
+   case GL_RENDERER:
+      return (GLubyte *)"Mesa DRI I810 20021125";
+   default:
+      return 0;
+   }
+}
+
+static void i810BufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+   /* Need to lock to make sure the driDrawable is uptodate.  This
+    * information is used to resize Mesa's software buffers, so it has
+    * to be correct.
+    */
+   LOCK_HARDWARE(imesa);
+   *width = imesa->driDrawable->w;
+   *height = imesa->driDrawable->h;
+   UNLOCK_HARDWARE(imesa);
+}
+
+/* Extension strings exported by the i810 driver.
+ */
+static const char * const card_extensions[] =
+{
+   "GL_ARB_multitexture",
+   "GL_ARB_texture_env_add",
+   "GL_ARB_texture_mirrored_repeat",
+   "GL_EXT_stencil_wrap",
+   "GL_EXT_texture_edge_clamp",
+   "GL_EXT_texture_env_add",
+   "GL_EXT_texture_lod_bias",
+   "GL_IBM_texture_mirrored_repeat",
+   "GL_MESA_ycbcr_texture",
+   "GL_SGIS_generate_mipmap",
+   "GL_SGIS_texture_edge_clamp",
+   NULL
+};
+
+extern const struct gl_pipeline_stage _i810_render_stage;
+
+static const struct gl_pipeline_stage *i810_pipeline[] = {
+   &_tnl_vertex_transform_stage,
+   &_tnl_normal_transform_stage,
+   &_tnl_lighting_stage,
+   &_tnl_fog_coordinate_stage,
+   &_tnl_texgen_stage,
+   &_tnl_texture_transform_stage,
+                               /* REMOVE: point attenuation stage */
+#if 1
+   &_i810_render_stage,                /* ADD: unclipped rastersetup-to-dma */
+#endif
+   &_tnl_render_stage,
+   0,
+};
+
+static const struct dri_debug_control debug_control[] =
+{
+    { "fall",  DEBUG_FALLBACKS },
+    { "tex",   DEBUG_TEXTURE },
+    { "ioctl", DEBUG_IOCTL },
+    { "prim",  DEBUG_PRIMS },
+    { "vert",  DEBUG_VERTS },
+    { "state", DEBUG_STATE },
+    { "verb",  DEBUG_VERBOSE },
+    { "dri",   DEBUG_DRI },
+    { "dma",   DEBUG_DMA },
+    { "san",   DEBUG_SANITY },
+    { "sync",  DEBUG_SYNC },
+    { "sleep", DEBUG_SLEEP },
+    { NULL,    0 }
+};
+
+GLboolean
+i810CreateContext( const __GLcontextModes *mesaVis,
+                   __DRIcontextPrivate *driContextPriv,
+                   void *sharedContextPrivate )
+{
+   GLcontext *ctx, *shareCtx;
+   i810ContextPtr imesa;
+   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private;
+   I810SAREAPtr saPriv = (I810SAREAPtr)
+      (((GLubyte *)sPriv->pSAREA) + i810Screen->sarea_priv_offset);
+
+   /* Allocate i810 context */
+   imesa = (i810ContextPtr) CALLOC_STRUCT(i810_context_t);
+   if (!imesa) {
+      return GL_FALSE;
+   }
+
+   /* Allocate the Mesa context */
+   if (sharedContextPrivate)
+      shareCtx = ((i810ContextPtr) sharedContextPrivate)->glCtx;
+   else
+      shareCtx = NULL;
+   imesa->glCtx = _mesa_create_context(mesaVis, shareCtx, (void*) imesa, GL_TRUE);
+   if (!imesa->glCtx) {
+      FREE(imesa);
+      return GL_FALSE;
+   }
+   driContextPriv->driverPrivate = imesa;
+
+   imesa->i810Screen = i810Screen;
+   imesa->driScreen = sPriv;
+   imesa->sarea = saPriv;
+   imesa->glBuffer = NULL;
+
+   (void) memset( imesa->texture_heaps, 0, sizeof( imesa->texture_heaps ) );
+   make_empty_list( & imesa->swapped );
+   
+   imesa->nr_heaps = 1;
+   imesa->texture_heaps[0] = driCreateTextureHeap( 0, imesa,
+           i810Screen->textureSize,
+           12,
+           I810_NR_TEX_REGIONS,
+           imesa->sarea->texList,
+           & imesa->sarea->texAge,
+           & imesa->swapped,
+           sizeof( struct i810_texture_object_t ),
+           (destroy_texture_object_t *) i810DestroyTexObj );
+
+
+
+   /* Set the maximum texture size small enough that we can guarentee
+    * that both texture units can bind a maximal texture and have them
+    * in memory at once.
+    */
+
+
+
+   ctx = imesa->glCtx;
+   ctx->Const.MaxTextureUnits = 2;
+
+
+   /* FIXME: driCalcualteMaxTextureLevels assumes that mipmaps are tightly
+    * FIXME: packed, but they're not in Intel graphics hardware.
+    */
+   driCalculateMaxTextureLevels( imesa->texture_heaps,
+                                imesa->nr_heaps,
+                                & ctx->Const,
+                                4,
+                                11, /* max 2D texture size is 2048x2048 */
+                                0,  /* 3D textures unsupported */
+                                0,  /* cube textures unsupported. */
+                                0,  /* texture rectangles unsupported. */
+                                12,
+                                GL_FALSE );
+
+   ctx->Const.MinLineWidth = 1.0;
+   ctx->Const.MinLineWidthAA = 1.0;
+   ctx->Const.MaxLineWidth = 3.0;
+   ctx->Const.MaxLineWidthAA = 3.0;
+   ctx->Const.LineWidthGranularity = 1.0;
+
+   ctx->Const.MinPointSize = 1.0;
+   ctx->Const.MinPointSizeAA = 1.0;
+   ctx->Const.MaxPointSize = 3.0;
+   ctx->Const.MaxPointSizeAA = 3.0;
+   ctx->Const.PointSizeGranularity = 1.0;
+
+   ctx->Driver.GetBufferSize = i810BufferSize;
+   ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
+   ctx->Driver.GetString = i810GetString;
+
+   /* Who owns who?
+    */
+   ctx->DriverCtx = (void *) imesa;
+   imesa->glCtx = ctx;
+
+   /* Initialize the software rasterizer and helper modules.
+    */
+   _swrast_CreateContext( ctx );
+   _ac_CreateContext( ctx );
+   _tnl_CreateContext( ctx );
+   _swsetup_CreateContext( ctx );
+
+   /* Install the customized pipeline:
+    */
+   _tnl_destroy_pipeline( ctx );
+   _tnl_install_pipeline( ctx, i810_pipeline );
+
+   /* Configure swrast to match hardware characteristics:
+    */
+   _swrast_allow_pixel_fog( ctx, GL_FALSE );
+   _swrast_allow_vertex_fog( ctx, GL_TRUE );
+
+   /* Dri stuff
+    */
+   imesa->hHWContext = driContextPriv->hHWContext;
+   imesa->driFd = sPriv->fd;
+   imesa->driHwLock = &sPriv->pSAREA->lock;
+
+   imesa->stipple_in_hw = 1;
+   imesa->RenderIndex = ~0;
+   imesa->dirty = I810_UPLOAD_CTX|I810_UPLOAD_BUFFERS;
+   imesa->upload_cliprects = GL_TRUE;
+
+   imesa->CurrentTexObj[0] = 0;
+   imesa->CurrentTexObj[1] = 0;
+
+   _math_matrix_ctr( &imesa->ViewportMatrix );
+
+   driInitExtensions( ctx, card_extensions, GL_TRUE );
+   i810InitStateFuncs( ctx );
+   i810InitTextureFuncs( ctx );
+   i810InitTriFuncs( ctx );
+   i810InitSpanFuncs( ctx );
+   i810InitIoctlFuncs( ctx );
+   i810InitVB( ctx );
+   i810InitState( ctx );
+
+#if DO_DEBUG
+   I810_DEBUG  = driParseDebugString( getenv( "I810_DEBUG" ),
+                                     debug_control );
+   I810_DEBUG |= driParseDebugString( getenv( "INTEL_DEBUG" ),
+                                     debug_control );
+#endif
+
+   return GL_TRUE;
+}
+
+void
+i810DestroyContext(__DRIcontextPrivate *driContextPriv)
+{
+   i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate;
+
+   assert(imesa); /* should never be null */
+   if (imesa) {
+      GLboolean   release_texture_heaps;
+
+
+      release_texture_heaps = (imesa->glCtx->Shared->RefCount == 1);
+      _swsetup_DestroyContext( imesa->glCtx );
+      _tnl_DestroyContext( imesa->glCtx );
+      _ac_DestroyContext( imesa->glCtx );
+      _swrast_DestroyContext( imesa->glCtx );
+
+      i810FreeVB( imesa->glCtx );
+
+      /* free the Mesa context */
+      imesa->glCtx->DriverCtx = NULL;
+      _mesa_destroy_context(imesa->glCtx);
+      if ( release_texture_heaps ) {
+        /* This share group is about to go away, free our private
+          * texture object data.
+          */
+         int i;
+
+        assert( is_empty_list( & imesa->swapped ) );
+
+         for ( i = 0 ; i < imesa->nr_heaps ; i++ ) {
+           driDestroyTextureHeap( imesa->texture_heaps[ i ] );
+           imesa->texture_heaps[ i ] = NULL;
+         }
+      }
+
+      Xfree(imesa);
+   }
+}
+
+
+void i810XMesaSetFrontClipRects( i810ContextPtr imesa )
+{
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+
+   imesa->numClipRects = dPriv->numClipRects;
+   imesa->pClipRects = dPriv->pClipRects;
+   imesa->drawX = dPriv->x;
+   imesa->drawY = dPriv->y;
+
+   i810EmitDrawingRectangle( imesa );
+   imesa->upload_cliprects = GL_TRUE;
+}
+
+
+void i810XMesaSetBackClipRects( i810ContextPtr imesa )
+{
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+
+   if (imesa->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0)
+   {
+      imesa->numClipRects = dPriv->numClipRects;
+      imesa->pClipRects = dPriv->pClipRects;
+      imesa->drawX = dPriv->x;
+      imesa->drawY = dPriv->y;
+   } else {
+      imesa->numClipRects = dPriv->numBackClipRects;
+      imesa->pClipRects = dPriv->pBackClipRects;
+      imesa->drawX = dPriv->backX;
+      imesa->drawY = dPriv->backY;
+   }
+
+   i810EmitDrawingRectangle( imesa );
+   imesa->upload_cliprects = GL_TRUE;
+}
+
+
+static void i810XMesaWindowMoved( i810ContextPtr imesa )
+{
+   switch (imesa->glCtx->Color._DrawDestMask) {
+   case FRONT_LEFT_BIT:
+      i810XMesaSetFrontClipRects( imesa );
+      break;
+   case BACK_LEFT_BIT:
+      i810XMesaSetBackClipRects( imesa );
+      break;
+   case GL_FRONT_LEFT:
+   default:
+      /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
+      i810XMesaSetFrontClipRects( imesa );
+   }
+}
+
+
+GLboolean
+i810UnbindContext(__DRIcontextPrivate *driContextPriv)
+{
+   i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate;
+   if (imesa) {
+      imesa->dirty = I810_UPLOAD_CTX|I810_UPLOAD_BUFFERS;
+      if (imesa->CurrentTexObj[0]) imesa->dirty |= I810_UPLOAD_TEX0;
+      if (imesa->CurrentTexObj[1]) imesa->dirty |= I810_UPLOAD_TEX1;
+   }
+
+   return GL_TRUE;
+}
+
+
+GLboolean
+i810MakeCurrent(__DRIcontextPrivate *driContextPriv,
+                __DRIdrawablePrivate *driDrawPriv,
+                __DRIdrawablePrivate *driReadPriv)
+{
+   if (driContextPriv) {
+      i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate;
+
+      /* Shouldn't the readbuffer be stored also?
+       */
+      imesa->driDrawable = driDrawPriv;
+
+      _mesa_make_current2(imesa->glCtx,
+                          (GLframebuffer *) driDrawPriv->driverPrivate,
+                          (GLframebuffer *) driReadPriv->driverPrivate);
+
+      /* Are these necessary?
+       */
+      i810XMesaWindowMoved( imesa );
+      if (!imesa->glCtx->Viewport.Width)
+        _mesa_set_viewport(imesa->glCtx, 0, 0,
+                            driDrawPriv->w, driDrawPriv->h);
+   }
+   else {
+      _mesa_make_current(0,0);
+   }
+
+   return GL_TRUE;
+}
+
+static void
+i810UpdatePageFlipping( i810ContextPtr imesa )
+{
+   GLcontext *ctx = imesa->glCtx;
+   int front = 0;
+
+   switch (ctx->Color._DrawDestMask) {
+   case FRONT_LEFT_BIT:
+      front = 1;
+      break;
+   case BACK_LEFT_BIT:
+      front = 0;
+      break;
+   default:
+      return;
+   }
+
+   if ( imesa->sarea->pf_current_page == 1 ) 
+     front ^= 1;
+   
+   if (front) {
+      imesa->BufferSetup[I810_DESTREG_DI1] = imesa->i810Screen->fbOffset | imesa->i810Screen->backPitchBits;
+      imesa->drawMap = (char *)imesa->driScreen->pFB;
+      imesa->readMap = (char *)imesa->driScreen->pFB;
+   } else {
+      imesa->BufferSetup[I810_DESTREG_DI1] = imesa->i810Screen->backOffset | imesa->i810Screen->backPitchBits;
+      imesa->drawMap = imesa->i810Screen->back.map;
+      imesa->readMap = imesa->i810Screen->back.map;
+   }
+
+   imesa->dirty |= I810_UPLOAD_BUFFERS;
+}
+
+void i810GetLock( i810ContextPtr imesa, GLuint flags )
+{
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+   __DRIscreenPrivate *sPriv = imesa->driScreen;
+   I810SAREAPtr sarea = imesa->sarea;
+   int me = imesa->hHWContext;
+   unsigned i;
+
+   drmGetLock(imesa->driFd, imesa->hHWContext, flags);
+
+   /* If the window moved, may need to set a new cliprect now.
+    *
+    * NOTE: This releases and regains the hw lock, so all state
+    * checking must be done *after* this call:
+    */
+   DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
+
+
+   /* If we lost context, need to dump all registers to hardware.
+    * Note that we don't care about 2d contexts, even if they perform
+    * accelerated commands, so the DRI locking in the X server is even
+    * more broken than usual.
+    */
+   if (sarea->ctxOwner != me) {
+      imesa->upload_cliprects = GL_TRUE;
+      imesa->dirty = I810_UPLOAD_CTX|I810_UPLOAD_BUFFERS;
+      if (imesa->CurrentTexObj[0]) imesa->dirty |= I810_UPLOAD_TEX0;
+      if (imesa->CurrentTexObj[1]) imesa->dirty |= I810_UPLOAD_TEX1;
+      sarea->ctxOwner = me;
+   }
+
+   /* Shared texture managment - if another client has played with
+    * texture space, figure out which if any of our textures have been
+    * ejected, and update our global LRU.
+    */ 
+   for ( i = 0 ; i < imesa->nr_heaps ; i++ ) {
+      DRI_AGE_TEXTURES( imesa->texture_heaps[ i ] );
+   }
+
+   if (imesa->lastStamp != dPriv->lastStamp) {
+      i810UpdatePageFlipping( imesa );
+      i810XMesaWindowMoved( imesa );
+      imesa->lastStamp = dPriv->lastStamp;
+   }
+}
+
+
+void
+i810SwapBuffers( __DRIdrawablePrivate *dPriv )
+{
+   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+      i810ContextPtr imesa;
+      GLcontext *ctx;
+      imesa = (i810ContextPtr) dPriv->driContextPriv->driverPrivate;
+      ctx = imesa->glCtx;
+      if (ctx->Visual.doubleBufferMode) {
+         _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */
+         if ( imesa->sarea->pf_active ) {
+            i810PageFlip( dPriv );
+         } else {
+            i810CopyBuffer( dPriv );
+         }
+      }
+   }
+   else {
+      /* XXX this shouldn't be an error but we can't handle it for now */
+      _mesa_problem(NULL, "i810SwapBuffers: drawable has no context!\n");
+   }
+}
+
diff --git a/src/mesa/drivers/dri/i810/i810context.h b/src/mesa/drivers/dri/i810/i810context.h
new file mode 100644 (file)
index 0000000..b24bd7c
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810context.h,v 1.9 2002/12/16 16:18:51 dawes Exp $ */
+
+#ifndef I810CONTEXT_INC
+#define I810CONTEXT_INC
+
+typedef struct i810_context_t i810Context;
+typedef struct i810_context_t *i810ContextPtr;
+typedef struct i810_texture_object_t *i810TextureObjectPtr;
+
+#include "mtypes.h"
+#include "mm.h"
+
+#include "i810screen.h"
+#include "i810tex.h"
+
+
+/* Reasons to disable hardware rasterization. 
+ */
+#define I810_FALLBACK_TEXTURE        0x1
+#define I810_FALLBACK_DRAW_BUFFER    0x2
+#define I810_FALLBACK_READ_BUFFER    0x4
+#define I810_FALLBACK_COLORMASK      0x8  
+#define I810_FALLBACK_SPECULAR       0x20 
+#define I810_FALLBACK_LOGICOP        0x40
+#define I810_FALLBACK_RENDERMODE     0x80
+#define I810_FALLBACK_STENCIL        0x100
+#define I810_FALLBACK_BLEND_EQ       0x200
+#define I810_FALLBACK_BLEND_FUNC     0x400
+
+
+#ifndef PCI_CHIP_I810                           
+#define PCI_CHIP_I810              0x7121
+#define PCI_CHIP_I810_DC100        0x7123
+#define PCI_CHIP_I810_E            0x7125 
+#define PCI_CHIP_I815              0x1132 
+#endif
+
+#define IS_I810(imesa) (imesa->i810Screen->deviceID == PCI_CHIP_I810 ||        \
+                       imesa->i810Screen->deviceID == PCI_CHIP_I810_DC100 || \
+                       imesa->i810Screen->deviceID == PCI_CHIP_I810_E)
+#define IS_I815(imesa) (imesa->i810Screen->deviceID == PCI_CHIP_I815)
+
+
+#define I810_UPLOAD_TEX(i) (I810_UPLOAD_TEX0<<(i))
+
+/* Use the templated vertex formats:
+ */
+#define TAG(x) i810##x
+#include "tnl_dd/t_dd_vertex.h"
+#undef TAG
+
+typedef void (*i810_tri_func)( i810ContextPtr, i810Vertex *, i810Vertex *,
+                              i810Vertex * );
+typedef void (*i810_line_func)( i810ContextPtr, i810Vertex *, i810Vertex * );
+typedef void (*i810_point_func)( i810ContextPtr, i810Vertex * );
+
+struct i810_context_t {
+   GLint refcount;   
+   GLcontext *glCtx;
+
+   /* Texture object bookkeeping
+    */
+   unsigned              nr_heaps;
+   driTexHeap          * texture_heaps[1];
+   driTextureObject      swapped;
+
+   struct i810_texture_object_t *CurrentTexObj[2];
+
+
+   /* Bit flag to keep track of fallbacks.
+    */
+   GLuint Fallback;
+
+   /* Temporaries for translating away float colors:
+    */
+   struct gl_client_array UbyteColor;
+   struct gl_client_array UbyteSecondaryColor;
+
+   /* State for i810vb.c and i810tris.c.
+    */
+   GLuint new_state;           /* _NEW_* flags */
+   GLuint SetupNewInputs;
+   GLuint SetupIndex;
+   GLuint RenderIndex;
+   GLmatrix ViewportMatrix;
+   GLenum render_primitive;
+   GLenum reduced_primitive;
+   GLuint hw_primitive;
+   GLubyte *verts;
+
+   drmBufPtr  vertex_buffer;
+   char *vertex_addr;
+   GLuint vertex_low;
+   GLuint vertex_high;
+   GLuint vertex_last_prim;
+   
+   GLboolean upload_cliprects;
+
+
+   /* Fallback rasterization functions 
+    */
+   i810_point_func draw_point;
+   i810_line_func draw_line;
+   i810_tri_func draw_tri;
+
+   /* Hardware state 
+    */
+   GLuint dirty;               /* I810_UPLOAD_* */
+   GLuint Setup[I810_CTX_SETUP_SIZE];
+   GLuint BufferSetup[I810_DEST_SETUP_SIZE];
+   int vertex_size;
+   int vertex_stride_shift;
+   unsigned int lastStamp;
+   GLboolean stipple_in_hw;
+
+   GLenum TexEnvImageFmt[2];
+
+   /* State which can't be computed completely on the fly:
+    */
+   GLuint LcsCullMode;
+   GLuint LcsLineWidth;
+   GLuint LcsPointSize;
+
+   /* Funny mesa mirrors
+    */
+   GLushort ClearColor;
+
+   /* DRI stuff
+    */
+   GLuint needClip;
+   GLframebuffer *glBuffer;
+   GLboolean doPageFlip;
+
+   /* These refer to the current draw (front vs. back) buffer:
+    */
+   char *drawMap;              /* draw buffer address in virtual mem */
+   char *readMap;      
+   int drawX;                  /* origin of drawable in draw buffer */
+   int drawY;
+   GLuint numClipRects;                /* cliprects for that buffer */
+   XF86DRIClipRectPtr pClipRects;
+
+   int lastSwap;
+   int texAge;
+   int ctxAge;
+   int dirtyAge;
+  
+   GLboolean scissor;
+   XF86DRIClipRectRec draw_rect;
+   XF86DRIClipRectRec scissor_rect;
+
+   drmContext hHWContext;
+   drmLock *driHwLock;
+   int driFd;
+
+   __DRIdrawablePrivate *driDrawable;
+   __DRIscreenPrivate *driScreen;
+   i810ScreenPrivate *i810Screen; 
+   I810SAREAPtr sarea;
+};
+
+
+#define I810_CONTEXT(ctx)    ((i810ContextPtr)(ctx->DriverCtx))
+
+#define GET_DISPATCH_AGE( imesa ) imesa->sarea->last_dispatch
+#define GET_ENQUEUE_AGE( imesa ) imesa->sarea->last_enqueue
+
+
+/* Lock the hardware and validate our state.  
+ */
+#define LOCK_HARDWARE( imesa )                         \
+  do {                                                 \
+    char __ret=0;                                      \
+    DRM_CAS(imesa->driHwLock, imesa->hHWContext,       \
+           (DRM_LOCK_HELD|imesa->hHWContext), __ret);  \
+    if (__ret)                                         \
+        i810GetLock( imesa, 0 );                       \
+  } while (0)
+
+
+
+/* Release the kernel lock.
+ */
+#define UNLOCK_HARDWARE(imesa)                                 \
+    DRM_UNLOCK(imesa->driFd, imesa->driHwLock, imesa->hHWContext);     
+
+
+/* This is the wrong way to do it, I'm sure.  Otherwise the drm
+ * bitches that I've already got the heavyweight lock.  At worst,
+ * this is 3 ioctls.  The best solution probably only gets me down 
+ * to 2 ioctls in the worst case.
+ */
+#define LOCK_HARDWARE_QUIESCENT( imesa ) do {  \
+   LOCK_HARDWARE( imesa );                     \
+   i810RegetLockQuiescent( imesa );            \
+} while(0)
+
+
+extern void i810GetLock( i810ContextPtr imesa, GLuint flags );
+extern void i810EmitHwStateLocked( i810ContextPtr imesa );
+extern void i810EmitScissorValues( i810ContextPtr imesa, int box_nr, int emit );
+extern void i810EmitDrawingRectangle( i810ContextPtr imesa );
+extern void i810XMesaSetBackClipRects( i810ContextPtr imesa );
+extern void i810XMesaSetFrontClipRects( i810ContextPtr imesa );
+
+#define SUBPIXEL_X -.5
+#define SUBPIXEL_Y -.5
+
+/* ================================================================
+ * Debugging:
+ */
+#define DO_DEBUG               1
+#if DO_DEBUG
+extern int I810_DEBUG;
+#else
+#define I810_DEBUG             0
+#endif
+
+#define DEBUG_TEXTURE  0x1
+#define DEBUG_STATE    0x2
+#define DEBUG_IOCTL    0x4
+#define DEBUG_PRIMS    0x8
+#define DEBUG_VERTS    0x10
+#define DEBUG_FALLBACKS        0x20
+#define DEBUG_VERBOSE  0x40
+#define DEBUG_DRI       0x80
+#define DEBUG_DMA       0x100
+#define DEBUG_SANITY    0x200
+#define DEBUG_SYNC      0x400
+#define DEBUG_SLEEP     0x800
+
+#endif
diff --git a/src/mesa/drivers/dri/i810/i810ioctl.c b/src/mesa/drivers/dri/i810/i810ioctl.c
new file mode 100644 (file)
index 0000000..d769d58
--- /dev/null
@@ -0,0 +1,510 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810ioctl.c,v 1.7 2002/10/30 12:51:33 alanh Exp $ */
+
+#include <unistd.h> /* for usleep() */
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "dd.h"
+#include "swrast/swrast.h"
+#include "mm.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810ioctl.h"
+#include "i810state.h"
+
+static drmBufPtr i810_get_buffer_ioctl( i810ContextPtr imesa )
+{
+   drmI810DMA dma;
+   drmBufPtr buf;
+   int retcode, i = 0;
+   
+   while (1) {
+      retcode = drmCommandWriteRead(imesa->driFd, DRM_I810_GETBUF,
+                                    &dma, sizeof(drmI810DMA));
+
+      if (dma.granted == 1 && retcode == 0) 
+        break;
+      
+      if (++i > 1000) {
+        drmCommandNone(imesa->driFd, DRM_I810_FLUSH);
+        i = 0;
+      }
+   }
+
+   buf = &(imesa->i810Screen->bufs->list[dma.request_idx]);
+   buf->idx = dma.request_idx;
+   buf->used = 0;
+   buf->total = dma.request_size;
+   buf->address = (drmAddress)dma.virtual;
+
+   return buf;
+}
+
+
+
+#define DEPTH_SCALE ((1<<16)-1)
+
+static void i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+                      GLint cx, GLint cy, GLint cw, GLint ch ) 
+{
+   i810ContextPtr imesa = I810_CONTEXT( ctx );
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+   const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
+   drmI810Clear clear;
+   int i;
+
+   clear.flags = 0;
+   clear.clear_color = imesa->ClearColor;
+   clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE);
+
+   I810_FIREVERTICES( imesa );
+       
+   if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) {
+      clear.flags |= I810_FRONT;
+      mask &= ~DD_FRONT_LEFT_BIT;
+   }
+
+   if ((mask & DD_BACK_LEFT_BIT) && colorMask == ~0) {
+      clear.flags |= I810_BACK;
+      mask &= ~DD_BACK_LEFT_BIT;
+   }
+
+   if (mask & DD_DEPTH_BIT) {
+      if (ctx->Depth.Mask) 
+        clear.flags |= I810_DEPTH;
+      mask &= ~DD_DEPTH_BIT;
+   }
+
+   if (clear.flags) {
+      LOCK_HARDWARE( imesa );
+
+      /* flip top to bottom */
+      cy = dPriv->h-cy-ch;
+      cx += imesa->drawX;
+      cy += imesa->drawY;
+
+      for (i = 0 ; i < imesa->numClipRects ; ) 
+      {         
+        int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, imesa->numClipRects);
+        XF86DRIClipRectPtr box = imesa->pClipRects;     
+        XF86DRIClipRectPtr b = imesa->sarea->boxes;
+        int n = 0;
+
+        if (!all) {
+           for ( ; i < nr ; i++) {
+              GLint x = box[i].x1;
+              GLint y = box[i].y1;
+              GLint w = box[i].x2 - x;
+              GLint h = box[i].y2 - y;
+
+              if (x < cx) w -= cx - x, x = cx; 
+              if (y < cy) h -= cy - y, y = cy;
+              if (x + w > cx + cw) w = cx + cw - x;
+              if (y + h > cy + ch) h = cy + ch - y;
+              if (w <= 0) continue;
+              if (h <= 0) continue;
+
+              b->x1 = x;
+              b->y1 = y;
+              b->x2 = x + w;
+              b->y2 = y + h;
+              b++;
+              n++;
+           }
+        } else {
+           for ( ; i < nr ; i++) {
+              *b++ = *(XF86DRIClipRectPtr)&box[i];
+              n++;
+           }
+        }
+
+        imesa->sarea->nbox = n;
+         drmCommandWrite(imesa->driFd, DRM_I810_CLEAR,
+                         &clear, sizeof(drmI810Clear));
+      }
+
+      UNLOCK_HARDWARE( imesa );
+      imesa->upload_cliprects = GL_TRUE;
+   }
+
+   if (mask) 
+      _swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
+}
+
+
+
+
+/*
+ * Copy the back buffer to the front buffer. 
+ */
+void i810CopyBuffer( const __DRIdrawablePrivate *dPriv ) 
+{
+   i810ContextPtr imesa;
+   XF86DRIClipRectPtr pbox;
+   int nbox, i, tmp;
+
+   assert(dPriv);
+   assert(dPriv->driContextPriv);
+   assert(dPriv->driContextPriv->driverPrivate);
+
+   imesa = (i810ContextPtr) dPriv->driContextPriv->driverPrivate;
+
+   I810_FIREVERTICES( imesa );
+   LOCK_HARDWARE( imesa );
+   
+   pbox = dPriv->pClipRects;
+   nbox = dPriv->numClipRects;
+
+   for (i = 0 ; i < nbox ; )
+   {
+      int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
+      XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)imesa->sarea->boxes;
+
+      imesa->sarea->nbox = nr - i;
+
+      for ( ; i < nr ; i++) 
+        *b++ = pbox[i];
+
+      drmCommandNone(imesa->driFd, DRM_I810_SWAP);
+   }
+
+   tmp = GET_ENQUEUE_AGE(imesa);
+   UNLOCK_HARDWARE( imesa );
+
+   /* multiarb will suck the life out of the server without this throttle:
+    */
+   if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) {
+      i810WaitAge(imesa, imesa->lastSwap);
+   }
+
+   imesa->lastSwap = tmp;
+   imesa->upload_cliprects = GL_TRUE;
+}
+
+
+/*
+ * XXX implement when full-screen extension is done.
+ */
+void i810PageFlip( const __DRIdrawablePrivate *dPriv ) 
+{
+  i810ContextPtr imesa;
+  int tmp, ret;
+
+  assert(dPriv);
+  assert(dPriv->driContextPriv);
+  assert(dPriv->driContextPriv->driverPrivate);
+    
+  imesa = (i810ContextPtr) dPriv->driContextPriv->driverPrivate;
+
+  I810_FIREVERTICES( imesa );
+  LOCK_HARDWARE( imesa );
+  
+  if (dPriv->pClipRects) {
+    *(XF86DRIClipRectRec *)imesa->sarea->boxes = dPriv->pClipRects[0];
+    imesa->sarea->nbox = 1;
+  }
+  ret = drmCommandNone(imesa->driFd, DRM_I810_FLIP);
+  if (ret) {
+    fprintf(stderr, "%s: %d\n", __FUNCTION__, ret);
+    UNLOCK_HARDWARE( imesa );
+    exit(1);
+  }
+
+  tmp = GET_ENQUEUE_AGE(imesa);
+  UNLOCK_HARDWARE( imesa );
+  
+   /* multiarb will suck the life out of the server without this throttle:
+    */
+  if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) {
+    i810WaitAge(imesa, imesa->lastSwap);
+   }
+
+  /*  i810SetDrawBuffer( imesa->glCtx, imesa->glCtx->Color.DriverDrawBuffer );*/
+  i810DrawBuffer( imesa->glCtx, imesa->glCtx->Color.DrawBuffer );
+  imesa->upload_cliprects = GL_TRUE;
+  imesa->lastSwap = tmp;
+  return;
+}
+
+
+/* This waits for *everybody* to finish rendering -- overkill.
+ */
+void i810DmaFinish( i810ContextPtr imesa  ) 
+{
+   I810_FIREVERTICES( imesa );
+
+   LOCK_HARDWARE( imesa );
+   i810RegetLockQuiescent( imesa );
+   UNLOCK_HARDWARE( imesa );
+}
+
+
+void i810RegetLockQuiescent( i810ContextPtr imesa  ) 
+{
+   drmUnlock(imesa->driFd, imesa->hHWContext);
+   i810GetLock( imesa, DRM_LOCK_QUIESCENT ); 
+}
+
+void i810WaitAgeLocked( i810ContextPtr imesa, int age  ) 
+{
+   int i = 0, j;
+
+   while (++i < 5000) {
+      drmCommandNone(imesa->driFd, DRM_I810_GETAGE);
+      if (GET_DISPATCH_AGE(imesa) >= age)
+        return;
+      for (j = 0 ; j < 1000 ; j++)
+        ;
+   }
+
+   drmCommandNone(imesa->driFd, DRM_I810_FLUSH);
+}
+
+
+void i810WaitAge( i810ContextPtr imesa, int age  ) 
+{
+   int i = 0, j;
+
+   while (++i < 5000) {
+      drmCommandNone(imesa->driFd, DRM_I810_GETAGE);
+      if (GET_DISPATCH_AGE(imesa) >= age)
+        return;
+      for (j = 0 ; j < 1000 ; j++)
+        ;
+   }
+
+   i = 0;
+   while (++i < 1000) {
+      drmCommandNone(imesa->driFd, DRM_I810_GETAGE);
+      if (GET_DISPATCH_AGE(imesa) >= age)
+        return;
+      usleep(1000);
+   }
+
+   LOCK_HARDWARE(imesa);
+   drmCommandNone(imesa->driFd, DRM_I810_FLUSH);
+   UNLOCK_HARDWARE(imesa);
+}
+
+
+
+
+static int intersect_rect( XF86DRIClipRectPtr out,
+                           XF86DRIClipRectPtr a,
+                           XF86DRIClipRectPtr b )
+{
+   *out = *a;
+   if (b->x1 > out->x1) out->x1 = b->x1;
+   if (b->x2 < out->x2) out->x2 = b->x2;
+   if (out->x1 >= out->x2) return 0;
+
+   if (b->y1 > out->y1) out->y1 = b->y1;
+   if (b->y2 < out->y2) out->y2 = b->y2;
+   if (out->y1 >= out->y2) return 0;
+   return 1;
+}
+
+
+static void emit_state( i810ContextPtr imesa )
+{
+   GLuint dirty = imesa->dirty;   
+   I810SAREAPtr sarea = imesa->sarea;
+
+   if (dirty & I810_UPLOAD_BUFFERS) {
+      memcpy( sarea->BufferState, imesa->BufferSetup, 
+             sizeof(imesa->BufferSetup) );
+   }    
+
+   if (dirty & I810_UPLOAD_CTX) {
+      memcpy( sarea->ContextState, imesa->Setup, 
+             sizeof(imesa->Setup) );
+   }
+
+   if (dirty & I810_UPLOAD_TEX0) {
+      memcpy(sarea->TexState[0], 
+            imesa->CurrentTexObj[0]->Setup,
+            sizeof(imesa->CurrentTexObj[0]->Setup));
+   }
+
+   if (dirty & I810_UPLOAD_TEX1) {
+      GLuint *setup = sarea->TexState[1];
+
+      memcpy( setup,
+             imesa->CurrentTexObj[1]->Setup,
+             sizeof(imesa->CurrentTexObj[1]->Setup));
+
+      /* Need this for the case where both units are bound to the same
+       * texobj.  
+       */
+      setup[I810_TEXREG_MI1] ^= (MI1_MAP_0 ^ MI1_MAP_1);
+      setup[I810_TEXREG_MLC] ^= (MLC_MAP_0 ^ MLC_MAP_1);
+      setup[I810_TEXREG_MLL] ^= (MLL_MAP_0 ^ MLL_MAP_1);
+      setup[I810_TEXREG_MCS] ^= (MCS_COORD_0 ^ MCS_COORD_1);
+      setup[I810_TEXREG_MF]  ^= (MF_MAP_0 ^ MF_MAP_1);
+   }
+    
+   sarea->dirty = dirty;
+   imesa->dirty = 0;
+}
+
+
+static void age_imesa( i810ContextPtr imesa, int age )
+{
+   if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->base.timestamp = age;
+   if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->base.timestamp = age;
+}
+
+
+void i810FlushPrimsLocked( i810ContextPtr imesa )
+{
+   XF86DRIClipRectPtr pbox = (XF86DRIClipRectPtr)imesa->pClipRects;
+   int nbox = imesa->numClipRects;
+   drmBufPtr buffer = imesa->vertex_buffer;
+   I810SAREAPtr sarea = imesa->sarea;
+   drmI810Vertex vertex;
+   int i;
+         
+   if (I810_DEBUG & DEBUG_STATE)
+      i810PrintDirty( __FUNCTION__, imesa->dirty );
+   
+   if (imesa->dirty)
+      emit_state( imesa );
+
+   vertex.idx = buffer->idx;
+   vertex.used = imesa->vertex_low;
+   vertex.discard = 0;
+   sarea->vertex_prim = imesa->hw_primitive;
+
+   if (!nbox) {
+      vertex.used = 0;
+   }
+   else if (nbox > I810_NR_SAREA_CLIPRECTS) {      
+      imesa->upload_cliprects = GL_TRUE;
+   }
+
+   if (!nbox || !imesa->upload_cliprects) 
+   {
+      if (nbox == 1) 
+        sarea->nbox = 0;
+      else
+        sarea->nbox = nbox;
+
+      vertex.discard = 1;      
+      drmCommandWrite(imesa->driFd, DRM_I810_VERTEX,
+                      &vertex, sizeof(drmI810Vertex));
+      age_imesa(imesa, sarea->last_enqueue);
+   }  
+   else 
+   {
+      for (i = 0 ; i < nbox ; )
+      {
+        int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, nbox);
+        XF86DRIClipRectPtr b = sarea->boxes;
+
+        if (imesa->scissor) {
+           sarea->nbox = 0;
+        
+           for ( ; i < nr ; i++) {
+              b->x1 = pbox[i].x1 - imesa->drawX;
+              b->y1 = pbox[i].y1 - imesa->drawY;
+              b->x2 = pbox[i].x2 - imesa->drawX;
+              b->y2 = pbox[i].y2 - imesa->drawY;
+
+              if (intersect_rect(b, b, &imesa->scissor_rect)) {
+                 sarea->nbox++;
+                 b++;
+              }
+           }
+
+           /* Culled?
+            */
+           if (!sarea->nbox) {
+              if (nr < nbox) continue;
+              vertex.used = 0;
+           }
+        } else {
+           sarea->nbox = nr - i;
+           for ( ; i < nr ; i++, b++) {
+              b->x1 = pbox[i].x1 - imesa->drawX;
+              b->y1 = pbox[i].y1 - imesa->drawY;
+              b->x2 = pbox[i].x2 - imesa->drawX;
+              b->y2 = pbox[i].y2 - imesa->drawY;
+           }
+        }
+        
+        /* Finished with the buffer?
+         */
+        if (nr == nbox) 
+           vertex.discard = 1;
+
+        drmCommandWrite(imesa->driFd, DRM_I810_VERTEX,
+                         &vertex, sizeof(drmI810Vertex));
+        age_imesa(imesa, imesa->sarea->last_enqueue);
+      }
+   }
+
+   /* Reset imesa vars:
+    */
+   imesa->vertex_buffer = 0;
+   imesa->vertex_addr = 0;
+   imesa->vertex_low = 0;
+   imesa->vertex_high = 0;
+   imesa->vertex_last_prim = 0;
+   imesa->dirty = 0;
+   imesa->upload_cliprects = GL_FALSE;
+}
+
+void i810FlushPrimsGetBuffer( i810ContextPtr imesa )
+{
+   LOCK_HARDWARE(imesa);
+
+   if (imesa->vertex_buffer) 
+      i810FlushPrimsLocked( imesa );      
+
+   imesa->vertex_buffer = i810_get_buffer_ioctl( imesa );
+   imesa->vertex_high = imesa->vertex_buffer->total;
+   imesa->vertex_addr = (char *)imesa->vertex_buffer->address;
+   imesa->vertex_low = 4;      /* leave room for instruction header */
+   imesa->vertex_last_prim = imesa->vertex_low;
+   UNLOCK_HARDWARE(imesa);
+}
+
+
+void i810FlushPrims( i810ContextPtr imesa ) 
+{
+   if (imesa->vertex_buffer) {
+      LOCK_HARDWARE( imesa );
+      i810FlushPrimsLocked( imesa );
+      UNLOCK_HARDWARE( imesa );
+   }
+}
+
+
+
+int i810_check_copy(int fd)
+{
+   return(drmCommandNone(fd, DRM_I810_DOCOPY));
+}
+
+static void i810Flush( GLcontext *ctx )
+{
+   i810ContextPtr imesa = I810_CONTEXT( ctx );
+   I810_FIREVERTICES( imesa );
+}
+
+static void i810Finish( GLcontext *ctx  ) 
+{
+   i810ContextPtr imesa = I810_CONTEXT( ctx );
+   i810DmaFinish( imesa );
+}
+
+void i810InitIoctlFuncs( GLcontext *ctx )
+{
+   ctx->Driver.Flush = i810Flush;
+   ctx->Driver.Clear = i810Clear;
+   ctx->Driver.Finish = i810Finish;
+}
diff --git a/src/mesa/drivers/dri/i810/i810ioctl.h b/src/mesa/drivers/dri/i810/i810ioctl.h
new file mode 100644 (file)
index 0000000..e287b57
--- /dev/null
@@ -0,0 +1,49 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810ioctl.h,v 1.7 2002/10/30 12:51:33 alanh Exp $ */
+
+#ifndef I810_IOCTL_H
+#define I810_IOCTL_H
+
+#include "i810context.h"
+
+void i810EmitPrim( i810ContextPtr imesa );
+void i810FlushPrims( i810ContextPtr mmesa ); 
+void i810FlushPrimsLocked( i810ContextPtr mmesa );
+void i810FlushPrimsGetBuffer( i810ContextPtr imesa );
+
+void i810WaitAgeLocked( i810ContextPtr imesa, int age );
+void i810WaitAge( i810ContextPtr imesa, int age );
+void i810DmaFinish( i810ContextPtr imesa );
+void i810RegetLockQuiescent( i810ContextPtr imesa );
+void i810InitIoctlFuncs( GLcontext *ctx );
+void i810CopyBuffer( const __DRIdrawablePrivate *dpriv );
+void i810PageFlip( const __DRIdrawablePrivate *dpriv );
+int i810_check_copy(int fd);
+
+#define I810_STATECHANGE(imesa, flag)                          \
+do {                                                           \
+   if (imesa->vertex_low != imesa->vertex_last_prim)           \
+      i810FlushPrims(imesa);                                   \
+   imesa->dirty |= flag;                                       \
+} while (0)                                                    \
+
+
+#define I810_FIREVERTICES(imesa)                               \
+do {                                                           \
+   if (imesa->vertex_buffer) {                                 \
+      i810FlushPrims(imesa);                                   \
+   }                                                           \
+} while (0)
+
+static __inline GLuint *i810AllocDmaLow( i810ContextPtr imesa, int bytes )
+{
+   if (imesa->vertex_low + bytes > imesa->vertex_high) 
+      i810FlushPrimsGetBuffer( imesa );
+
+   {
+      GLuint *start = (GLuint *)(imesa->vertex_addr + imesa->vertex_low);
+      imesa->vertex_low += bytes;
+      return start;
+   }
+}
+
+#endif
diff --git a/src/mesa/drivers/dri/i810/i810render.c b/src/mesa/drivers/dri/i810/i810render.c
new file mode 100644 (file)
index 0000000..8d388d8
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Intel i810 DRI driver for Mesa 3.5
+ *
+ * Copyright (C) 1999-2000  Keith Whitwell   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 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 KEITH WHITWELL 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.
+ *
+ * Author:
+ *    Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+/*
+ * Render unclipped vertex buffers by emitting vertices directly to
+ * dma buffers.  Use strip/fan hardware acceleration where possible.
+ *
+ */
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "imports.h"
+#include "mtypes.h"
+
+#include "tnl/t_context.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810tris.h"
+#include "i810state.h"
+#include "i810vb.h"
+#include "i810ioctl.h"
+
+/*
+ * Render unclipped vertex buffers by emitting vertices directly to
+ * dma buffers.  Use strip/fan hardware primitives where possible.
+ * Try to simulate missing primitives with indexed vertices.
+ */
+#define HAVE_POINTS      0
+#define HAVE_LINES       1
+#define HAVE_LINE_STRIPS 1
+#define HAVE_TRIANGLES   1
+#define HAVE_TRI_STRIPS  1
+#define HAVE_TRI_STRIP_1 0     /* has it, template can't use it yet */
+#define HAVE_TRI_FANS    1
+#define HAVE_POLYGONS    1
+#define HAVE_QUADS       0
+#define HAVE_QUAD_STRIPS 0
+
+#define HAVE_ELTS        0
+
+
+static GLuint hw_prim[GL_POLYGON+1] = {
+   0,
+   PR_LINES,
+   0,
+   PR_LINESTRIP,
+   PR_TRIANGLES,
+   PR_TRISTRIP_0,
+   PR_TRIFAN,
+   0,
+   0,
+   PR_POLYGON
+};
+
+static const GLenum reduced_prim[GL_POLYGON+1] = {
+   GL_POINTS,
+   GL_LINES,
+   GL_LINES,
+   GL_LINES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES
+};
+
+/* Fallback to normal rendering.
+ */
+static void VERT_FALLBACK( GLcontext *ctx,
+                          GLuint start,
+                          GLuint count,
+                          GLuint flags )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   tnl->Driver.Render.PrimitiveNotify( ctx, flags & PRIM_MODE_MASK );
+   tnl->Driver.Render.BuildVertices( ctx, start, count, ~0 );
+   tnl->Driver.Render.PrimTabVerts[flags&PRIM_MODE_MASK]( ctx, start, 
+                                                         count, flags );
+   I810_CONTEXT(ctx)->SetupNewInputs = VERT_BIT_CLIP;
+}
+
+
+
+#define LOCAL_VARS i810ContextPtr imesa = I810_CONTEXT(ctx)
+#define INIT( prim ) do {                                              \
+   I810_STATECHANGE(imesa, 0);                                         \
+   i810RasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] );      \
+} while (0)
+#define NEW_PRIMITIVE()  I810_STATECHANGE( imesa, 0 )
+#define NEW_BUFFER()  I810_FIREVERTICES( imesa )
+#define GET_CURRENT_VB_MAX_VERTS() \
+  (((int)imesa->vertex_high - (int)imesa->vertex_low) / (imesa->vertex_size*4))
+#define GET_SUBSEQUENT_VB_MAX_VERTS() \
+  (I810_DMA_BUF_SZ-4) / (imesa->vertex_size * 4)
+
+
+#define EMIT_VERTS( ctx, j, nr ) \
+  i810_emit_contiguous_verts(ctx, j, (j)+(nr))
+
+
+#define TAG(x) i810_##x
+#include "tnl_dd/t_dd_dmatmp.h"
+
+
+/**********************************************************************/
+/*                          Render pipeline stage                     */
+/**********************************************************************/
+
+
+static GLboolean i810_run_render( GLcontext *ctx,
+                                 struct gl_pipeline_stage *stage )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb;
+   GLuint i, length, flags = 0;
+
+   /* Don't handle clipping or indexed vertices.
+    */
+   if (VB->ClipOrMask || imesa->RenderIndex != 0 || VB->Elts) {
+      return GL_TRUE;
+   }
+
+   imesa->SetupNewInputs = VERT_BIT_CLIP;
+
+   tnl->Driver.Render.Start( ctx );
+
+   for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length)
+   {
+      flags = VB->Primitive[i];
+      length= VB->PrimitiveLength[i];
+      if (length)
+        i810_render_tab_verts[flags & PRIM_MODE_MASK]( ctx, i, i + length,
+                                                       flags );
+   }
+
+   tnl->Driver.Render.Finish( ctx );
+
+   return GL_FALSE;            /* finished the pipe */
+}
+
+
+static void i810_check_render( GLcontext *ctx, struct gl_pipeline_stage *stage )
+{
+   GLuint inputs = VERT_BIT_CLIP | VERT_BIT_COLOR0;
+
+   if (ctx->RenderMode == GL_RENDER) {
+      if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+        inputs |= VERT_BIT_COLOR1;
+
+      if (ctx->Texture.Unit[0]._ReallyEnabled)
+        inputs |= VERT_BIT_TEX0;
+
+      if (ctx->Texture.Unit[1]._ReallyEnabled)
+        inputs |= VERT_BIT_TEX1;
+
+      if (ctx->Fog.Enabled)
+        inputs |= VERT_BIT_FOG;
+   }
+
+   stage->inputs = inputs;
+}
+
+
+static void dtr( struct gl_pipeline_stage *stage )
+{
+   (void)stage;
+}
+
+
+const struct gl_pipeline_stage _i810_render_stage =
+{
+   "i810 render",
+   (_DD_NEW_SEPARATE_SPECULAR |
+    _NEW_TEXTURE|
+    _NEW_FOG|
+    _NEW_RENDERMODE),          /* re-check (new inputs) */
+   0,                          /* re-run (always runs) */
+   GL_TRUE,                    /* active */
+   0, 0,                       /* inputs (set in check_render), outputs */
+   0, 0,                       /* changed_inputs, private */
+   dtr,                                /* destructor */
+   i810_check_render,          /* check - initially set to alloc data */
+   i810_run_render             /* run */
+};
diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c
new file mode 100644 (file)
index 0000000..2c978e1
--- /dev/null
@@ -0,0 +1,288 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810screen.c,v 1.2 2002/10/30 12:51:33 alanh Exp $ */
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ *
+ */
+
+
+#include "glheader.h"
+#include "context.h"
+#include "matrix.h"
+#include "simple_list.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810state.h"
+#include "i810tex.h"
+#include "i810span.h"
+#include "i810tris.h"
+#include "i810ioctl.h"
+
+
+
+/*  static int i810_malloc_proxy_buf(drmBufMapPtr buffers) */
+/*  { */
+/*     char *buffer; */
+/*     drmBufPtr buf; */
+/*     int i; */
+
+/*     buffer = Xmalloc(I810_DMA_BUF_SZ); */
+/*     if(buffer == NULL) return -1; */
+/*     for(i = 0; i < I810_DMA_BUF_NR; i++) { */
+/*        buf = &(buffers->list[i]); */
+/*        buf->address = (drmAddress)buffer; */
+/*     } */
+/*     return 0; */
+/*  } */
+
+static drmBufMapPtr i810_create_empty_buffers(void)
+{
+   drmBufMapPtr retval;
+
+   retval = (drmBufMapPtr)Xmalloc(sizeof(drmBufMap));
+   if(retval == NULL) return NULL;
+   memset(retval, 0, sizeof(drmBufMap));
+   retval->list = (drmBufPtr)Xmalloc(sizeof(drmBuf) * I810_DMA_BUF_NR);
+   if(retval->list == NULL) {
+      Xfree(retval);
+      return NULL;
+   }
+   memset(retval->list, 0, sizeof(drmBuf) * I810_DMA_BUF_NR);
+   return retval;
+}
+
+
+static GLboolean
+i810InitDriver(__DRIscreenPrivate *sPriv)
+{
+   i810ScreenPrivate *i810Screen;
+   I810DRIPtr         gDRIPriv = (I810DRIPtr)sPriv->pDevPriv;
+
+   /* Check the DRI externsion version */
+   if ( sPriv->driMajor != 4 || sPriv->driMinor < 0 ) {
+      __driUtilMessage( "i810 DRI driver expected DRI version 4.0.x "
+                        "but got version %d.%d.%d",
+                        sPriv->driMajor, sPriv->driMinor, sPriv->driPatch );
+      return GL_FALSE;
+   }
+
+   /* Check that the DDX driver version is compatible */
+   if (sPriv->ddxMajor != 1 ||
+       sPriv->ddxMinor < 0) {
+      __driUtilMessage("i810 DRI driver expected DDX driver version 1.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch);
+      return GL_FALSE;
+   }
+
+   /* Check that the DRM driver version is compatible */
+   if (sPriv->drmMajor != 1 ||
+       sPriv->drmMinor < 2) {
+      __driUtilMessage("i810 DRI driver expected DRM driver version 1.2.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch);
+      return GL_FALSE;
+   }
+
+   /* Allocate the private area */
+   i810Screen = (i810ScreenPrivate *)Xmalloc(sizeof(i810ScreenPrivate));
+   if (!i810Screen) {
+      __driUtilMessage("i810InitDriver: alloc i810ScreenPrivate struct failed");
+      return GL_FALSE;
+   }
+
+   i810Screen->driScrnPriv = sPriv;
+   sPriv->private = (void *)i810Screen;
+
+   i810Screen->deviceID=gDRIPriv->deviceID;
+   i810Screen->width=gDRIPriv->width;
+   i810Screen->height=gDRIPriv->height;
+   i810Screen->mem=gDRIPriv->mem;
+   i810Screen->cpp=gDRIPriv->cpp;
+   i810Screen->fbStride=gDRIPriv->fbStride;
+   i810Screen->fbOffset=gDRIPriv->fbOffset;
+
+   if (gDRIPriv->bitsPerPixel == 15)
+      i810Screen->fbFormat = DV_PF_555;
+   else
+      i810Screen->fbFormat = DV_PF_565;
+
+   i810Screen->backOffset=gDRIPriv->backOffset;
+   i810Screen->depthOffset=gDRIPriv->depthOffset;
+   i810Screen->backPitch = gDRIPriv->auxPitch;
+   i810Screen->backPitchBits = gDRIPriv->auxPitchBits;
+   i810Screen->textureOffset=gDRIPriv->textureOffset;
+   i810Screen->textureSize=gDRIPriv->textureSize;
+   i810Screen->logTextureGranularity = gDRIPriv->logTextureGranularity;
+
+   i810Screen->bufs = i810_create_empty_buffers();
+   if (i810Screen->bufs == NULL) {
+      __driUtilMessage("i810InitDriver: i810_create_empty_buffers() failed");
+      Xfree(i810Screen);
+      return GL_FALSE;
+   }
+
+   i810Screen->back.handle = gDRIPriv->backbuffer;
+   i810Screen->back.size = gDRIPriv->backbufferSize;
+
+   if (drmMap(sPriv->fd,
+             i810Screen->back.handle,
+             i810Screen->back.size,
+             (drmAddress *)&i810Screen->back.map) != 0) {
+      Xfree(i810Screen);
+      sPriv->private = NULL;
+      __driUtilMessage("i810InitDriver: drmMap failed");
+      return GL_FALSE;
+   }
+
+   i810Screen->depth.handle = gDRIPriv->depthbuffer;
+   i810Screen->depth.size = gDRIPriv->depthbufferSize;
+
+   if (drmMap(sPriv->fd,
+             i810Screen->depth.handle,
+             i810Screen->depth.size,
+             (drmAddress *)&i810Screen->depth.map) != 0) {
+      Xfree(i810Screen);
+      drmUnmap(i810Screen->back.map, i810Screen->back.size);
+      sPriv->private = NULL;
+      __driUtilMessage("i810InitDriver: drmMap (2) failed");
+      return GL_FALSE;
+   }
+
+   i810Screen->tex.handle = gDRIPriv->textures;
+   i810Screen->tex.size = gDRIPriv->textureSize;
+
+   if (drmMap(sPriv->fd,
+             i810Screen->tex.handle,
+             i810Screen->tex.size,
+             (drmAddress *)&i810Screen->tex.map) != 0) {
+      Xfree(i810Screen);
+      drmUnmap(i810Screen->back.map, i810Screen->back.size);
+      drmUnmap(i810Screen->depth.map, i810Screen->depth.size);
+      sPriv->private = NULL;
+      __driUtilMessage("i810InitDriver: drmMap (3) failed");
+      return GL_FALSE;
+   }
+
+   i810Screen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
+
+   return GL_TRUE;
+}
+
+static void
+i810DestroyScreen(__DRIscreenPrivate *sPriv)
+{
+   i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private;
+
+   /* Need to unmap all the bufs and maps here:
+    */
+   drmUnmap(i810Screen->back.map, i810Screen->back.size);
+   drmUnmap(i810Screen->depth.map, i810Screen->depth.size);
+   drmUnmap(i810Screen->tex.map, i810Screen->tex.size);
+
+   Xfree(i810Screen);
+   sPriv->private = NULL;
+}
+
+
+static GLboolean
+i810CreateBuffer( __DRIscreenPrivate *driScrnPriv,
+                  __DRIdrawablePrivate *driDrawPriv,
+                  const __GLcontextModes *mesaVis,
+                  GLboolean isPixmap )
+{
+   if (isPixmap) {
+      return GL_FALSE; /* not implemented */
+   }
+   else {
+      driDrawPriv->driverPrivate = (void *)
+         _mesa_create_framebuffer(mesaVis,
+                                  GL_FALSE,  /* software depth buffer? */
+                                  mesaVis->stencilBits > 0,
+                                  mesaVis->accumRedBits > 0,
+                                  GL_FALSE /* s/w alpha planes */);
+      return (driDrawPriv->driverPrivate != NULL);
+   }
+}
+
+
+static void
+i810DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+   _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
+}
+
+
+static GLboolean
+i810OpenCloseFullScreen(__DRIcontextPrivate *driContextPriv)
+{
+    return GL_TRUE;
+}
+
+static const struct __DriverAPIRec i810API = {
+   .InitDriver      = i810InitDriver,
+   .DestroyScreen   = i810DestroyScreen,
+   .CreateContext   = i810CreateContext,
+   .DestroyContext  = i810DestroyContext,
+   .CreateBuffer    = i810CreateBuffer,
+   .DestroyBuffer   = i810DestroyBuffer,
+   .SwapBuffers     = i810SwapBuffers,
+   .MakeCurrent     = i810MakeCurrent,
+   .UnbindContext   = i810UnbindContext,
+   .OpenFullScreen  = i810OpenCloseFullScreen,
+   .CloseFullScreen = i810OpenCloseFullScreen,
+   .GetSwapInfo     = NULL,
+   .GetMSC          = NULL,
+   .WaitForMSC      = NULL,
+   .WaitForSBC      = NULL,
+   .SwapBuffersMSC  = NULL
+};
+
+
+/*
+ * This is the bootstrap function for the driver.
+ * The __driCreateScreen name is the symbol that libGL.so fetches.
+ * Return:  pointer to a __DRIscreenPrivate.
+ */
+#ifndef _SOLO
+void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
+                        int numConfigs, __GLXvisualConfig *config)
+{
+   __DRIscreenPrivate *psp;
+   psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &i810API);
+   return (void *) psp;
+}
+#else
+void *__driCreateScreen(struct DRIDriverRec *driver,
+                        struct DRIDriverContextRec *driverContext)
+{
+   __DRIscreenPrivate *psp;
+   psp = __driUtilCreateScreen(driver, driverContext, &i810API);
+   return (void *) psp;
+}
+#endif
diff --git a/src/mesa/drivers/dri/i810/i810screen.h b/src/mesa/drivers/dri/i810/i810screen.h
new file mode 100644 (file)
index 0000000..4625bc5
--- /dev/null
@@ -0,0 +1,99 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ *
+ */
+
+#ifndef _I810_INIT_H_
+#define _I810_INIT_H_
+
+#include <sys/time.h>
+#include "dri_util.h"
+
+typedef struct {
+   drmHandle handle;
+   drmSize size;
+   char *map;
+} i810Region, *i810RegionPtr;
+
+typedef struct {
+   i810Region front;
+   i810Region back;
+   i810Region depth;
+   i810Region tex;
+
+   int deviceID;
+   int width;
+   int height;
+   int mem;
+
+   int cpp;                    /* for front and back buffers */
+   int bitsPerPixel;
+
+   int fbFormat;
+   int fbOffset;
+   int fbStride;
+
+   int backOffset;
+   int depthOffset;
+
+   int backPitch;
+   int backPitchBits;
+
+   int textureOffset;
+   int textureSize;
+   int logTextureGranularity;
+
+   __DRIscreenPrivate *driScrnPriv;
+   drmBufMapPtr  bufs;
+   unsigned int sarea_priv_offset;
+} i810ScreenPrivate;
+
+
+extern GLboolean
+i810CreateContext( const __GLcontextModes *mesaVis,
+                   __DRIcontextPrivate *driContextPriv,
+                   void *sharedContextPrivate );
+
+extern void
+i810DestroyContext(__DRIcontextPrivate *driContextPriv);
+
+extern GLboolean
+i810UnbindContext(__DRIcontextPrivate *driContextPriv);
+
+extern GLboolean
+i810MakeCurrent(__DRIcontextPrivate *driContextPriv,
+                __DRIdrawablePrivate *driDrawPriv,
+                __DRIdrawablePrivate *driReadPriv);
+
+extern void
+i810SwapBuffers(__DRIdrawablePrivate *driDrawPriv);
+
+#endif
diff --git a/src/mesa/drivers/dri/i810/i810span.c b/src/mesa/drivers/dri/i810/i810span.c
new file mode 100644 (file)
index 0000000..dc8f4d1
--- /dev/null
@@ -0,0 +1,170 @@
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "colormac.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810span.h"
+#include "i810ioctl.h"
+#include "swrast/swrast.h"
+
+
+#define DBG 0
+
+#define LOCAL_VARS                                     \
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;   \
+   i810ScreenPrivate *i810Screen = imesa->i810Screen;  \
+   GLuint pitch = i810Screen->backPitch;               \
+   GLuint height = dPriv->h;                           \
+   GLushort p;                                         \
+   char *buf = (char *)(imesa->drawMap +               \
+                       dPriv->x * 2 +                  \
+                       dPriv->y * pitch);              \
+   char *read_buf = (char *)(imesa->readMap +          \
+                            dPriv->x * 2 +             \
+                            dPriv->y * pitch);         \
+   (void) read_buf; (void) buf; (void) p
+
+#define LOCAL_DEPTH_VARS                               \
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;   \
+   i810ScreenPrivate *i810Screen = imesa->i810Screen;  \
+   GLuint pitch = i810Screen->backPitch;               \
+   GLuint height = dPriv->h;                           \
+   char *buf = (char *)(i810Screen->depth.map +        \
+                       dPriv->x * 2 +                  \
+                       dPriv->y * pitch)
+
+#define INIT_MONO_PIXEL(p, color) \
+   p = PACK_COLOR_565( color[0], color[1], color[2] )
+
+#define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
+                         _y >= miny && _y < maxy)
+
+
+#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i )                           \
+   if ( _y < miny || _y >= maxy ) {                                    \
+      _n1 = 0, _x1 = x;                                                        \
+   } else {                                                            \
+      _n1 = _n;                                                                \
+      _x1 = _x;                                                                \
+      if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
+      if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx);                        \
+   }
+
+#define Y_FLIP(_y) (height - _y - 1)
+
+#define HW_LOCK()                              \
+   i810ContextPtr imesa = I810_CONTEXT(ctx);   \
+   I810_FIREVERTICES(imesa);                   \
+   i810DmaFinish(imesa);                       \
+   LOCK_HARDWARE_QUIESCENT(imesa);
+
+#define HW_CLIPLOOP()                                          \
+  do {                                                         \
+    __DRIdrawablePrivate *dPriv = imesa->driDrawable;          \
+    int _nc = dPriv->numClipRects;                             \
+    while (_nc--) {                                            \
+       int minx = dPriv->pClipRects[_nc].x1 - dPriv->x;                \
+       int miny = dPriv->pClipRects[_nc].y1 - dPriv->y;        \
+       int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x;                \
+       int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
+
+
+#define HW_ENDCLIPLOOP()                       \
+    }                                          \
+  } while (0)
+
+#define HW_UNLOCK()                            \
+    UNLOCK_HARDWARE(imesa);
+
+
+
+
+/* 16 bit, 565 rgb color spanline and pixel functions
+ */
+#define WRITE_RGBA( _x, _y, r, g, b, a )                               \
+   *(GLushort *)(buf + _x*2 + _y*pitch)  = ( (((int)r & 0xf8) << 8) |  \
+                                            (((int)g & 0xfc) << 3) |   \
+                                            (((int)b & 0xf8) >> 3))
+#define WRITE_PIXEL( _x, _y, p )  \
+   *(GLushort *)(buf + _x*2 + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y )                                      \
+do {                                                                   \
+   GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch);             \
+   rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8;                           \
+   rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc;                           \
+   rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8;                           \
+   rgba[3] = 255;                                                      \
+} while(0)
+
+#define TAG(x) i810##x##_565
+#include "spantmp.h"
+
+
+
+/* 16 bit depthbuffer functions.
+ */
+#define WRITE_DEPTH( _x, _y, d ) \
+   *(GLushort *)(buf + _x*2 + _y*pitch)  = d;
+
+#define READ_DEPTH( d, _x, _y )        \
+   d = *(GLushort *)(buf + _x*2 + _y*pitch);
+
+#define TAG(x) i810##x##_16
+#include "depthtmp.h"
+
+
+/*
+ * This function is called to specify which buffer to read and write
+ * for software rasterization (swrast) fallbacks.  This doesn't necessarily
+ * correspond to glDrawBuffer() or glReadBuffer() calls.
+ */
+static void i810SetBuffer(GLcontext *ctx, GLframebuffer *buffer,
+                          GLuint bufferBit )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   (void) buffer;
+
+   switch(bufferBit) {
+    case FRONT_LEFT_BIT:
+      if ( imesa->sarea->pf_current_page == 1)
+        imesa->readMap = imesa->i810Screen->back.map;
+      else
+        imesa->readMap = (char*)imesa->driScreen->pFB;
+      break;
+    case BACK_LEFT_BIT:
+      if ( imesa->sarea->pf_current_page == 1)
+        imesa->readMap =  (char*)imesa->driScreen->pFB;
+      else
+        imesa->readMap = imesa->i810Screen->back.map;
+      break;
+    default:
+       ASSERT(0);
+       break;
+   }
+   imesa->drawMap = imesa->readMap;
+}
+
+
+void i810InitSpanFuncs( GLcontext *ctx )
+{
+   struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
+
+   swdd->SetBuffer = i810SetBuffer;
+
+   swdd->WriteRGBASpan = i810WriteRGBASpan_565;
+   swdd->WriteRGBSpan = i810WriteRGBSpan_565;
+   swdd->WriteMonoRGBASpan = i810WriteMonoRGBASpan_565;
+   swdd->WriteRGBAPixels = i810WriteRGBAPixels_565;
+   swdd->WriteMonoRGBAPixels = i810WriteMonoRGBAPixels_565;
+   swdd->ReadRGBASpan = i810ReadRGBASpan_565;
+   swdd->ReadRGBAPixels = i810ReadRGBAPixels_565;
+
+   swdd->ReadDepthSpan = i810ReadDepthSpan_16;
+   swdd->WriteDepthSpan = i810WriteDepthSpan_16;
+   swdd->ReadDepthPixels = i810ReadDepthPixels_16;
+   swdd->WriteDepthPixels = i810WriteDepthPixels_16;
+}
diff --git a/src/mesa/drivers/dri/i810/i810span.h b/src/mesa/drivers/dri/i810/i810span.h
new file mode 100644 (file)
index 0000000..a7b809b
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _I810_SPAN_H
+#define _I810_SPAN_H
+
+extern void i810InitSpanFuncs( GLcontext *ctx );
+
+#endif
diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c
new file mode 100644 (file)
index 0000000..23432b2
--- /dev/null
@@ -0,0 +1,1019 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810state.c,v 1.9 2002/10/30 12:51:33 alanh Exp $ */
+
+#include <stdio.h>
+
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "enums.h"
+#include "dd.h"
+#include "colormac.h"
+
+#include "texmem.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810state.h"
+#include "i810tex.h"
+#include "i810vb.h"
+#include "i810tris.h"
+#include "i810ioctl.h"
+
+#include "swrast/swrast.h"
+#include "array_cache/acache.h"
+#include "tnl/tnl.h"
+#include "swrast_setup/swrast_setup.h"
+
+#include "tnl/t_pipeline.h"
+
+static __inline__ GLuint i810PackColor(GLuint format,
+                                      GLubyte r, GLubyte g,
+                                      GLubyte b, GLubyte a)
+{
+
+   if (I810_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   switch (format) {
+   case DV_PF_555:
+      return PACK_COLOR_1555( a, r, g, b );
+   case DV_PF_565:
+      return PACK_COLOR_565( r, g, b );
+   default:
+      fprintf(stderr, "unknown format %d\n", (int)format);
+      return 0;
+   }
+}
+
+
+static void i810AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   GLuint a = (ZA_UPDATE_ALPHAFUNC|ZA_UPDATE_ALPHAREF);
+   GLubyte refByte;
+
+   CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
+
+   switch (ctx->Color.AlphaFunc) {
+   case GL_NEVER:    a |= ZA_ALPHA_NEVER;    break;
+   case GL_LESS:     a |= ZA_ALPHA_LESS;     break;
+   case GL_GEQUAL:   a |= ZA_ALPHA_GEQUAL;   break;
+   case GL_LEQUAL:   a |= ZA_ALPHA_LEQUAL;   break;
+   case GL_GREATER:  a |= ZA_ALPHA_GREATER;  break;
+   case GL_NOTEQUAL: a |= ZA_ALPHA_NOTEQUAL; break;
+   case GL_EQUAL:    a |= ZA_ALPHA_EQUAL;    break;
+   case GL_ALWAYS:   a |= ZA_ALPHA_ALWAYS;   break;
+   default: return;
+   }
+
+   a |= ((refByte & 0xfc) << ZA_ALPHAREF_SHIFT);
+
+   I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+   imesa->Setup[I810_CTXREG_ZA] &= ~(ZA_ALPHA_MASK|ZA_ALPHAREF_MASK);
+   imesa->Setup[I810_CTXREG_ZA] |= a;
+}
+
+static void i810BlendEquation(GLcontext *ctx, GLenum mode)
+{
+   /* Can only do GL_ADD equation in hardware */
+   FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_BLEND_EQ, mode != GL_FUNC_ADD_EXT);
+
+   /* BlendEquation sets ColorLogicOpEnabled in an unexpected
+    * manner.
+    */
+   FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_LOGICOP,
+            (ctx->Color.ColorLogicOpEnabled &&
+             ctx->Color.LogicOp != GL_COPY));
+}
+
+static void i810BlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   GLuint a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND;
+   GLboolean fallback = GL_FALSE;
+
+   switch (ctx->Color.BlendSrcRGB) {
+   case GL_ZERO:                a |= SDM_SRC_ZERO; break;
+   case GL_SRC_ALPHA:           a |= SDM_SRC_SRC_ALPHA; break;
+   case GL_ONE:                 a |= SDM_SRC_ONE; break;
+   case GL_DST_COLOR:           a |= SDM_SRC_DST_COLOR; break;
+   case GL_ONE_MINUS_DST_COLOR: a |= SDM_SRC_INV_DST_COLOR; break;
+   case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_SRC_INV_SRC_ALPHA; break;
+   case GL_DST_ALPHA:           a |= SDM_SRC_ONE; break;
+   case GL_ONE_MINUS_DST_ALPHA: a |= SDM_SRC_ZERO; break;
+   case GL_SRC_ALPHA_SATURATE:  /*a |= SDM_SRC_SRC_ALPHA; break;*/
+   case GL_CONSTANT_COLOR:
+   case GL_ONE_MINUS_CONSTANT_COLOR:
+   case GL_CONSTANT_ALPHA:
+   case GL_ONE_MINUS_CONSTANT_ALPHA:
+      fallback = GL_TRUE;
+      break;
+   default:
+      return;
+   }
+
+   switch (ctx->Color.BlendDstRGB) {
+   case GL_SRC_ALPHA:           a |= SDM_DST_SRC_ALPHA; break;
+   case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_DST_INV_SRC_ALPHA; break;
+   case GL_ZERO:                a |= SDM_DST_ZERO; break;
+   case GL_ONE:                 a |= SDM_DST_ONE; break;
+   case GL_SRC_COLOR:           a |= SDM_DST_SRC_COLOR; break;
+   case GL_ONE_MINUS_SRC_COLOR: a |= SDM_DST_INV_SRC_COLOR; break;
+   case GL_DST_ALPHA:           a |= SDM_DST_ONE; break;
+   case GL_ONE_MINUS_DST_ALPHA: a |= SDM_DST_ZERO; break;
+   case GL_CONSTANT_COLOR:
+   case GL_ONE_MINUS_CONSTANT_COLOR:
+   case GL_CONSTANT_ALPHA:
+   case GL_ONE_MINUS_CONSTANT_ALPHA:
+      fallback = GL_TRUE;
+      break;
+   default:
+      return;
+   }
+
+   FALLBACK( imesa, I810_FALLBACK_BLEND_FUNC, fallback);
+   if (!fallback) {
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->Setup[I810_CTXREG_SDM] &= ~(SDM_SRC_MASK|SDM_DST_MASK);
+      imesa->Setup[I810_CTXREG_SDM] |= a;
+   }
+}
+
+
+/* Shouldn't be called as the extension is disabled.
+ */
+static void i810BlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
+                                    GLenum dfactorRGB, GLenum sfactorA,
+                                    GLenum dfactorA )
+{
+   if (dfactorRGB != dfactorA || sfactorRGB != sfactorA) {
+      _mesa_error( ctx, GL_INVALID_OPERATION, "glBlendEquation (disabled)");
+   }
+
+   i810BlendFunc( ctx, sfactorRGB, dfactorRGB );
+}
+
+
+
+static void i810DepthFunc(GLcontext *ctx, GLenum func)
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   int zmode;
+
+   switch(func)  {
+   case GL_NEVER: zmode = LCS_Z_NEVER; break;
+   case GL_ALWAYS: zmode = LCS_Z_ALWAYS; break;
+   case GL_LESS: zmode = LCS_Z_LESS; break;
+   case GL_LEQUAL: zmode = LCS_Z_LEQUAL; break;
+   case GL_EQUAL: zmode = LCS_Z_EQUAL; break;
+   case GL_GREATER: zmode = LCS_Z_GREATER; break;
+   case GL_GEQUAL: zmode = LCS_Z_GEQUAL; break;
+   case GL_NOTEQUAL: zmode = LCS_Z_NOTEQUAL; break;
+   default: return;
+   }
+
+   I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+   imesa->Setup[I810_CTXREG_LCS] &= ~LCS_Z_MASK;
+   imesa->Setup[I810_CTXREG_LCS] |= zmode;
+}
+
+static void i810DepthMask(GLcontext *ctx, GLboolean flag)
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+
+   if (flag)
+      imesa->Setup[I810_CTXREG_B2] |= B2_ZB_WRITE_ENABLE;
+   else
+      imesa->Setup[I810_CTXREG_B2] &= ~B2_ZB_WRITE_ENABLE;
+}
+
+
+/* =============================================================
+ * Polygon stipple
+ *
+ * The i810 supports a 4x4 stipple natively, GL wants 32x32.
+ * Fortunately stipple is usually a repeating pattern.
+ */
+static void i810PolygonStipple( GLcontext *ctx, const GLubyte *mask )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   const GLubyte *m = mask;
+   GLubyte p[4];
+   int i,j,k;
+   int active = (ctx->Polygon.StippleFlag &&
+                imesa->reduced_primitive == GL_TRIANGLES);
+   GLuint newMask;
+
+   if (active) {
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
+   }
+
+   p[0] = mask[12] & 0xf; p[0] |= p[0] << 4;
+   p[1] = mask[8] & 0xf; p[1] |= p[1] << 4;
+   p[2] = mask[4] & 0xf; p[2] |= p[2] << 4;
+   p[3] = mask[0] & 0xf; p[3] |= p[3] << 4;
+
+   for (k = 0 ; k < 8 ; k++)
+      for (j = 0 ; j < 4; j++)
+        for (i = 0 ; i < 4 ; i++)
+           if (*m++ != p[j]) {
+              imesa->stipple_in_hw = 0;
+              return;
+           }
+
+   newMask = ((p[0] & 0xf) << 0) |
+             ((p[1] & 0xf) << 4) |
+             ((p[2] & 0xf) << 8) |
+             ((p[3] & 0xf) << 12);
+
+   if (newMask == 0xffff) {
+      /* this is needed to make conform pass */
+      imesa->stipple_in_hw = 0;
+      return;
+   }
+
+   imesa->Setup[I810_CTXREG_ST1] &= ~0xffff;
+   imesa->Setup[I810_CTXREG_ST1] |= newMask;
+   imesa->stipple_in_hw = 1;
+
+   if (active)
+      imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
+}
+
+
+
+/* =============================================================
+ * Hardware clipping
+ */
+
+
+static void i810Scissor( GLcontext *ctx, GLint x, GLint y,
+                        GLsizei w, GLsizei h )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+   if (ctx->Scissor.Enabled) {
+      I810_FIREVERTICES(imesa);        /* don't pipeline cliprect changes */
+      imesa->upload_cliprects = GL_TRUE;
+   }
+
+   imesa->scissor_rect.x1 = x;
+   imesa->scissor_rect.y1 = imesa->driDrawable->h - (y + h);
+   imesa->scissor_rect.x2 = x + w;
+   imesa->scissor_rect.y2 = imesa->driDrawable->h - y;
+}
+
+
+static void i810LogicOp( GLcontext *ctx, GLenum opcode )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   FALLBACK( imesa, I810_FALLBACK_LOGICOP,
+            (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) );
+}
+
+/* Fallback to swrast for select and feedback.
+ */
+static void i810RenderMode( GLcontext *ctx, GLenum mode )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   FALLBACK( imesa, I810_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
+}
+
+
+void i810DrawBuffer(GLcontext *ctx, GLenum mode )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   int front = 0;
+  
+   /*
+    * _DrawDestMask is easier to cope with than <mode>.
+    */
+   switch ( ctx->Color._DrawDestMask ) {
+   case FRONT_LEFT_BIT:
+     front=1;
+     break;
+   case BACK_LEFT_BIT:
+     front = 0;
+     break;
+   default:
+      /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
+      FALLBACK( imesa, I810_FALLBACK_DRAW_BUFFER, GL_TRUE );
+      return;
+   }
+
+   if ( imesa->sarea->pf_current_page == 1 ) 
+     front ^= 1;
+   FALLBACK( imesa, I810_FALLBACK_DRAW_BUFFER, GL_FALSE );
+   I810_FIREVERTICES(imesa);
+   I810_STATECHANGE(imesa, I810_UPLOAD_BUFFERS);
+
+   if (front)
+   {
+     imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->fbOffset |
+                                            imesa->i810Screen->backPitchBits);
+     i810XMesaSetFrontClipRects( imesa );
+   }
+   else
+   {
+     imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->backOffset |
+                                            imesa->i810Screen->backPitchBits);
+     i810XMesaSetBackClipRects( imesa );
+   }
+
+   /* We want to update the s/w rast state too so that r200SetBuffer()
+    * gets called.
+    */
+   _swrast_DrawBuffer(ctx, mode);
+}
+
+
+static void i810ReadBuffer(GLcontext *ctx, GLenum mode )
+{
+   /* XXX anything? */
+}
+
+
+static void i810ClearColor(GLcontext *ctx, const GLfloat color[4] )
+{
+   i810ContextPtr imesa = I810_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]);
+   imesa->ClearColor = i810PackColor( imesa->i810Screen->fbFormat,
+                                     c[0], c[1], c[2], c[3] );
+}
+
+
+/* =============================================================
+ * Culling - the i810 isn't quite as clean here as the rest of
+ *           its interfaces, but it's not bad.
+ */
+static void i810CullFaceFrontFace(GLcontext *ctx, GLenum unused)
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   GLuint mode = LCS_CULL_BOTH;
+
+   if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
+      mode = LCS_CULL_CW;
+      if (ctx->Polygon.CullFaceMode == GL_FRONT)
+        mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW);
+      if (ctx->Polygon.FrontFace != GL_CCW)
+        mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW);
+   }
+
+   imesa->LcsCullMode = mode;
+
+   if (ctx->Polygon.CullFlag)
+   {
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
+      imesa->Setup[I810_CTXREG_LCS] |= mode;
+   }
+}
+
+
+static void i810LineWidth( GLcontext *ctx, GLfloat widthf )
+{
+   i810ContextPtr imesa = I810_CONTEXT( ctx );
+   int width = (int)ctx->Line._Width;
+
+   imesa->LcsLineWidth = 0;
+   if (width & 1) imesa->LcsLineWidth |= LCS_LINEWIDTH_1_0;
+   if (width & 2) imesa->LcsLineWidth |= LCS_LINEWIDTH_2_0;
+
+   if (imesa->reduced_primitive == GL_LINES) {
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_3_0;
+      imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsLineWidth;
+   }
+}
+
+static void i810PointSize( GLcontext *ctx, GLfloat sz )
+{
+   i810ContextPtr imesa = I810_CONTEXT( ctx );
+   int size = (int)ctx->Point._Size;
+
+   imesa->LcsPointSize = 0;
+   if (size & 1) imesa->LcsPointSize |= LCS_LINEWIDTH_1_0;
+   if (size & 2) imesa->LcsPointSize |= LCS_LINEWIDTH_2_0;
+
+   if (imesa->reduced_primitive == GL_POINTS) {
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_3_0;
+      imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsPointSize;
+   }
+}
+
+/* =============================================================
+ * Color masks
+ */
+
+static void i810ColorMask(GLcontext *ctx,
+                         GLboolean r, GLboolean g,
+                         GLboolean b, GLboolean a )
+{
+   i810ContextPtr imesa = I810_CONTEXT( ctx );
+   GLuint tmp = 0;
+
+   if (r && g && b) {
+      tmp = imesa->Setup[I810_CTXREG_B2] | B2_FB_WRITE_ENABLE;
+      FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_FALSE );
+   } else if (!r && !g && !b) {
+      tmp = imesa->Setup[I810_CTXREG_B2] & ~B2_FB_WRITE_ENABLE;
+      FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_FALSE );
+   } else {
+      FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_TRUE );
+      return;
+   }
+
+   if (tmp != imesa->Setup[I810_CTXREG_B2]) {
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->Setup[I810_CTXREG_B2] = tmp;
+      imesa->dirty |= I810_UPLOAD_CTX;
+   }
+}
+
+/* Seperate specular not fully implemented on the i810.
+ */
+static void i810LightModelfv(GLcontext *ctx, GLenum pname,
+                              const GLfloat *param)
+{
+   if (pname == GL_LIGHT_MODEL_COLOR_CONTROL)
+   {
+      i810ContextPtr imesa = I810_CONTEXT( ctx );
+      FALLBACK( imesa, I810_FALLBACK_SPECULAR,
+               (ctx->Light.Enabled &&
+                ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR));
+   }
+}
+
+/* But the 815 has it...
+ */
+static void i810LightModelfv_i815(GLcontext *ctx, GLenum pname,
+                                   const GLfloat *param)
+{
+   if (pname == GL_LIGHT_MODEL_COLOR_CONTROL)
+   {
+      i810ContextPtr imesa = I810_CONTEXT( ctx );
+
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+        imesa->Setup[I810_CTXREG_B1] |= B1_SPEC_ENABLE;
+      else
+        imesa->Setup[I810_CTXREG_B1] &= ~B1_SPEC_ENABLE;
+   }
+}
+
+/* In Mesa 3.5 we can reliably do native flatshading.
+ */
+static void i810ShadeModel(GLcontext *ctx, GLenum mode)
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+   if (mode == GL_FLAT)
+      imesa->Setup[I810_CTXREG_LCS] |= LCS_INTERP_FLAT;
+   else
+      imesa->Setup[I810_CTXREG_LCS] &= ~LCS_INTERP_FLAT;
+}
+
+
+
+/* =============================================================
+ * Fog
+ */
+static void i810Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+   if (pname == GL_FOG_COLOR) {
+      GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) |
+                     ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
+                     ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
+
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->Setup[I810_CTXREG_FOG] = ((GFX_OP_FOG_COLOR | color) &
+                                     ~FOG_RESERVED_MASK);
+   }
+}
+
+
+/* =============================================================
+ */
+static void i810Enable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+   switch(cap) {
+   case GL_ALPHA_TEST:
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->Setup[I810_CTXREG_B1] &= ~B1_ALPHA_TEST_ENABLE;
+      if (state)
+        imesa->Setup[I810_CTXREG_B1] |= B1_ALPHA_TEST_ENABLE;
+      break;
+   case GL_BLEND:
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->Setup[I810_CTXREG_B1] &= ~B1_BLEND_ENABLE;
+      if (state)
+        imesa->Setup[I810_CTXREG_B1] |= B1_BLEND_ENABLE;
+
+      /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
+       */
+      FALLBACK( imesa, I810_FALLBACK_LOGICOP,
+               (ctx->Color.ColorLogicOpEnabled &&
+                ctx->Color.LogicOp != GL_COPY));
+      break;
+   case GL_DEPTH_TEST:
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->Setup[I810_CTXREG_B1] &= ~B1_Z_TEST_ENABLE;
+      if (state)
+        imesa->Setup[I810_CTXREG_B1] |= B1_Z_TEST_ENABLE;
+      break;
+   case GL_SCISSOR_TEST:
+      /* XXX without these next two lines, conform's scissor test fails */
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      I810_STATECHANGE(imesa, I810_UPLOAD_BUFFERS);
+      I810_FIREVERTICES(imesa);        /* don't pipeline cliprect changes */
+      imesa->upload_cliprects = GL_TRUE;
+      imesa->scissor = state;
+      break;
+   case GL_POLYGON_STIPPLE:
+      if (imesa->stipple_in_hw && imesa->reduced_primitive == GL_TRIANGLES)
+      {
+        I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+        imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
+        if (state)
+           imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
+      }
+      break;
+   case GL_LINE_SMOOTH:
+      /* Need to fatten the lines by .5, or they disappear...
+       */
+      if (imesa->reduced_primitive == GL_LINES) {
+        I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+        imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+        imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5;
+        if (state) {
+           imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+           imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5;
+        }
+      }
+      break;
+   case GL_POINT_SMOOTH:
+      if (imesa->reduced_primitive == GL_POINTS) {
+        I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+        imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+        imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5;
+        if (state) {
+           imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+           imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5;
+        }
+      }
+      break;
+   case GL_POLYGON_SMOOTH:
+      if (imesa->reduced_primitive == GL_TRIANGLES) {
+        I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+        imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+        if (state)
+           imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+      }
+      break;
+   case GL_FOG:
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->Setup[I810_CTXREG_B1] &= ~B1_FOG_ENABLE;
+      if (state)
+        imesa->Setup[I810_CTXREG_B1] |= B1_FOG_ENABLE;
+      break;
+   case GL_CULL_FACE:
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
+      if (state)
+        imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsCullMode;
+      else
+        imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
+      break;
+   case GL_TEXTURE_2D:
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      if (ctx->Texture.CurrentUnit == 0) {
+        imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE;
+        if (state)
+           imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE;
+      } else {
+        imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE;
+        if (state)
+           imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE;
+      }
+      break;
+   case GL_COLOR_LOGIC_OP:
+      FALLBACK( imesa, I810_FALLBACK_LOGICOP,
+               (state && ctx->Color.LogicOp != GL_COPY));
+      break;
+   case GL_STENCIL_TEST:
+      FALLBACK( imesa, I810_FALLBACK_STENCIL, state );
+      break;
+   default:
+      ;
+   }
+}
+
+
+
+
+
+
+
+/* =============================================================
+ */
+
+
+
+
+void i810EmitDrawingRectangle( i810ContextPtr imesa )
+{
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+   i810ScreenPrivate *i810Screen = imesa->i810Screen;
+   int x0 = imesa->drawX;
+   int y0 = imesa->drawY;
+   int x1 = x0 + dPriv->w;
+   int y1 = y0 + dPriv->h;
+   GLuint dr2, dr3, dr4;
+
+
+   /* Coordinate origin of the window - may be offscreen.
+    */
+   dr4 = imesa->BufferSetup[I810_DESTREG_DR4] = ((y0<<16) |
+                                                (((unsigned)x0)&0xFFFF));
+
+   /* Clip to screen.
+    */
+   if (x0 < 0) x0 = 0;
+   if (y0 < 0) y0 = 0;
+   if (x1 > i810Screen->width-1) x1 = i810Screen->width-1;
+   if (y1 > i810Screen->height-1) y1 = i810Screen->height-1;
+
+
+   /* Onscreen drawing rectangle.
+    */
+   dr2 = imesa->BufferSetup[I810_DESTREG_DR2] = ((y0<<16) | x0);
+   dr3 = imesa->BufferSetup[I810_DESTREG_DR3] = (((y1+1)<<16) | (x1+1));
+
+
+   imesa->dirty |= I810_UPLOAD_BUFFERS;
+}
+
+
+
+static void i810CalcViewport( GLcontext *ctx )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   const GLfloat *v = ctx->Viewport._WindowMap.m;
+   GLfloat *m = imesa->ViewportMatrix.m;
+
+   /* See also i810_translate_vertex.  SUBPIXEL adjustments can be done
+    * via state vars, too.
+    */
+   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] + imesa->driDrawable->h + SUBPIXEL_Y;
+   m[MAT_SZ] =   v[MAT_SZ] * (1.0 / 0xffff);
+   m[MAT_TZ] =   v[MAT_TZ] * (1.0 / 0xffff);
+}
+
+static void i810Viewport( GLcontext *ctx,
+                         GLint x, GLint y,
+                         GLsizei width, GLsizei height )
+{
+   i810CalcViewport( ctx );
+}
+
+static void i810DepthRange( GLcontext *ctx,
+                           GLclampd nearval, GLclampd farval )
+{
+   i810CalcViewport( ctx );
+}
+
+
+
+void i810PrintDirty( const char *msg, GLuint state )
+{
+   fprintf(stderr, "%s (0x%x): %s%s%s%s\n",
+          msg,
+          (unsigned int) state,
+          (state & I810_UPLOAD_TEX0)  ? "upload-tex0, " : "",
+          (state & I810_UPLOAD_TEX1)  ? "upload-tex1, " : "",
+          (state & I810_UPLOAD_CTX)        ? "upload-ctx, " : "",
+          (state & I810_UPLOAD_BUFFERS)    ? "upload-bufs, " : ""
+          );
+}
+
+
+
+void i810InitState( GLcontext *ctx )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   i810ScreenPrivate *i810Screen = imesa->i810Screen;
+
+   memset(imesa->Setup, 0, sizeof(imesa->Setup));
+
+   imesa->Setup[I810_CTXREG_VF] = 0;
+
+   imesa->Setup[I810_CTXREG_MT] = (GFX_OP_MAP_TEXELS |
+                                  MT_UPDATE_TEXEL1_STATE |
+                                  MT_TEXEL1_COORD1 |
+                                  MT_TEXEL1_MAP1 |
+                                  MT_TEXEL1_DISABLE |
+                                  MT_UPDATE_TEXEL0_STATE |
+                                  MT_TEXEL0_COORD0 |
+                                  MT_TEXEL0_MAP0 |
+                                  MT_TEXEL0_DISABLE);
+
+   imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+                                    MC_STAGE_0 |
+                                    MC_UPDATE_DEST |
+                                    MC_DEST_CURRENT |
+                                    MC_UPDATE_ARG1 |
+                                    MC_ARG1_ITERATED_COLOR |
+                                    MC_ARG1_DONT_REPLICATE_ALPHA |
+                                    MC_ARG1_DONT_INVERT |
+                                    MC_UPDATE_ARG2 |
+                                    MC_ARG2_ONE |
+                                    MC_ARG2_DONT_REPLICATE_ALPHA |
+                                    MC_ARG2_DONT_INVERT |
+                                    MC_UPDATE_OP |
+                                    MC_OP_ARG1 );
+
+   imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+                                    MC_STAGE_1 |
+                                    MC_UPDATE_DEST |
+                                    MC_DEST_CURRENT |
+                                    MC_UPDATE_ARG1 |
+                                    MC_ARG1_ONE |
+                                    MC_ARG1_DONT_REPLICATE_ALPHA |
+                                    MC_ARG1_DONT_INVERT |
+                                    MC_UPDATE_ARG2 |
+                                    MC_ARG2_ONE |
+                                    MC_ARG2_DONT_REPLICATE_ALPHA |
+                                    MC_ARG2_DONT_INVERT |
+                                    MC_UPDATE_OP |
+                                    MC_OP_DISABLE );
+
+
+   imesa->Setup[I810_CTXREG_MC2] = ( GFX_OP_MAP_COLOR_STAGES |
+                                    MC_STAGE_2 |
+                                    MC_UPDATE_DEST |
+                                    MC_DEST_CURRENT |
+                                    MC_UPDATE_ARG1 |
+                                    MC_ARG1_CURRENT_COLOR |
+                                    MC_ARG1_REPLICATE_ALPHA |
+                                    MC_ARG1_DONT_INVERT |
+                                    MC_UPDATE_ARG2 |
+                                    MC_ARG2_ONE |
+                                    MC_ARG2_DONT_REPLICATE_ALPHA |
+                                    MC_ARG2_DONT_INVERT |
+                                    MC_UPDATE_OP |
+                                    MC_OP_DISABLE );
+
+
+   imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+                                    MA_STAGE_0 |
+                                    MA_UPDATE_ARG1 |
+                                    MA_ARG1_ITERATED_ALPHA |
+                                    MA_ARG1_DONT_INVERT |
+                                    MA_UPDATE_ARG2 |
+                                    MA_ARG2_CURRENT_ALPHA |
+                                    MA_ARG2_DONT_INVERT |
+                                    MA_UPDATE_OP |
+                                    MA_OP_ARG1 );
+
+
+   imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+                                    MA_STAGE_1 |
+                                    MA_UPDATE_ARG1 |
+                                    MA_ARG1_CURRENT_ALPHA |
+                                    MA_ARG1_DONT_INVERT |
+                                    MA_UPDATE_ARG2 |
+                                    MA_ARG2_CURRENT_ALPHA |
+                                    MA_ARG2_DONT_INVERT |
+                                    MA_UPDATE_OP |
+                                    MA_OP_ARG1 );
+
+
+   imesa->Setup[I810_CTXREG_MA2] = ( GFX_OP_MAP_ALPHA_STAGES |
+                                    MA_STAGE_2 |
+                                    MA_UPDATE_ARG1 |
+                                    MA_ARG1_CURRENT_ALPHA |
+                                    MA_ARG1_DONT_INVERT |
+                                    MA_UPDATE_ARG2 |
+                                    MA_ARG2_CURRENT_ALPHA |
+                                    MA_ARG2_DONT_INVERT |
+                                    MA_UPDATE_OP |
+                                    MA_OP_ARG1 );
+
+
+   imesa->Setup[I810_CTXREG_SDM] = ( GFX_OP_SRC_DEST_MONO |
+                                    SDM_UPDATE_MONO_ENABLE |
+                                    0 |
+                                    SDM_UPDATE_SRC_BLEND |
+                                    SDM_SRC_ONE |
+                                    SDM_UPDATE_DST_BLEND |
+                                    SDM_DST_ZERO );
+
+   /* Use for colormask:
+    */
+   imesa->Setup[I810_CTXREG_CF0] = GFX_OP_COLOR_FACTOR;
+   imesa->Setup[I810_CTXREG_CF1] = 0xffffffff;
+
+   imesa->Setup[I810_CTXREG_ZA] = (GFX_OP_ZBIAS_ALPHAFUNC |
+                                  ZA_UPDATE_ALPHAFUNC |
+                                  ZA_ALPHA_ALWAYS |
+                                  ZA_UPDATE_ZBIAS |
+                                  0 |
+                                  ZA_UPDATE_ALPHAREF |
+                                  0x0);
+
+   imesa->Setup[I810_CTXREG_FOG] = (GFX_OP_FOG_COLOR |
+                                   (0xffffff & ~FOG_RESERVED_MASK));
+
+   /* Choose a pipe
+    */
+   imesa->Setup[I810_CTXREG_B1] = ( GFX_OP_BOOL_1 |
+                                   B1_UPDATE_SPEC_SETUP_ENABLE |
+                                   0 |
+                                   B1_UPDATE_ALPHA_SETUP_ENABLE |
+                                   B1_ALPHA_SETUP_ENABLE |
+                                   B1_UPDATE_CI_KEY_ENABLE |
+                                   0 |
+                                   B1_UPDATE_CHROMAKEY_ENABLE |
+                                   0 |
+                                   B1_UPDATE_Z_BIAS_ENABLE |
+                                   0 |
+                                   B1_UPDATE_SPEC_ENABLE |
+                                   0 |
+                                   B1_UPDATE_FOG_ENABLE |
+                                   0 |
+                                   B1_UPDATE_ALPHA_TEST_ENABLE |
+                                   0 |
+                                   B1_UPDATE_BLEND_ENABLE |
+                                   0 |
+                                   B1_UPDATE_Z_TEST_ENABLE |
+                                   0 );
+
+   imesa->Setup[I810_CTXREG_B2] = ( GFX_OP_BOOL_2 |
+                                   B2_UPDATE_MAP_CACHE_ENABLE |
+                                   B2_MAP_CACHE_ENABLE |
+                                   B2_UPDATE_ALPHA_DITHER_ENABLE |
+                                   0 |
+                                   B2_UPDATE_FOG_DITHER_ENABLE |
+                                   0 |
+                                   B2_UPDATE_SPEC_DITHER_ENABLE |
+                                   0 |
+                                   B2_UPDATE_RGB_DITHER_ENABLE |
+                                   B2_RGB_DITHER_ENABLE |
+                                   B2_UPDATE_FB_WRITE_ENABLE |
+                                   B2_FB_WRITE_ENABLE |
+                                   B2_UPDATE_ZB_WRITE_ENABLE |
+                                   B2_ZB_WRITE_ENABLE );
+
+   imesa->Setup[I810_CTXREG_LCS] = ( GFX_OP_LINEWIDTH_CULL_SHADE_MODE |
+                                    LCS_UPDATE_ZMODE |
+                                    LCS_Z_LESS |
+                                    LCS_UPDATE_LINEWIDTH |
+                                    LCS_LINEWIDTH_1_0 |
+                                    LCS_UPDATE_ALPHA_INTERP |
+                                    LCS_ALPHA_INTERP |
+                                    LCS_UPDATE_FOG_INTERP |
+                                    0 |
+                                    LCS_UPDATE_SPEC_INTERP |
+                                    0 |
+                                    LCS_UPDATE_RGB_INTERP |
+                                    LCS_RGB_INTERP |
+                                    LCS_UPDATE_CULL_MODE |
+                                    LCS_CULL_DISABLE);
+
+   imesa->LcsCullMode = LCS_CULL_CW;
+   imesa->LcsLineWidth = LCS_LINEWIDTH_1_0;
+   imesa->LcsPointSize = LCS_LINEWIDTH_1_0;
+
+   imesa->Setup[I810_CTXREG_PV] = ( GFX_OP_PV_RULE |
+                                   PV_UPDATE_PIXRULE |
+                                   PV_PIXRULE_ENABLE |
+                                   PV_UPDATE_LINELIST |
+                                   PV_LINELIST_PV1 |
+                                   PV_UPDATE_TRIFAN |
+                                   PV_TRIFAN_PV2 |
+                                   PV_UPDATE_TRISTRIP |
+                                   PV_TRISTRIP_PV2 );
+
+
+   imesa->Setup[I810_CTXREG_ST0] = GFX_OP_STIPPLE;
+   imesa->Setup[I810_CTXREG_ST1] = 0;
+
+   imesa->Setup[I810_CTXREG_AA] = ( GFX_OP_ANTIALIAS |
+                                   AA_UPDATE_EDGEFLAG |
+                                   0 |
+                                   AA_UPDATE_POLYWIDTH |
+                                   AA_POLYWIDTH_05 |
+                                   AA_UPDATE_LINEWIDTH |
+                                   AA_LINEWIDTH_05 |
+                                   AA_UPDATE_BB_EXPANSION |
+                                   0 |
+                                   AA_UPDATE_AA_ENABLE |
+                                   0 );
+
+   memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup));
+   imesa->BufferSetup[I810_DESTREG_DI0] = CMD_OP_DESTBUFFER_INFO;
+
+   if (imesa->glCtx->Visual.doubleBufferMode && imesa->sarea->pf_current_page == 0) {
+      /* use back buffer by default */
+      imesa->drawMap = i810Screen->back.map;
+      imesa->readMap = i810Screen->back.map;
+      imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->backOffset |
+                                             i810Screen->backPitchBits);
+   } else {
+      /* use front buffer by default */
+      imesa->drawMap = (char *)imesa->driScreen->pFB;
+      imesa->readMap = (char *)imesa->driScreen->pFB;
+      imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->fbOffset |
+                                             i810Screen->backPitchBits);
+   }
+
+   imesa->BufferSetup[I810_DESTREG_DV0] = GFX_OP_DESTBUFFER_VARS;
+   imesa->BufferSetup[I810_DESTREG_DV1] = (DV_HORG_BIAS_OGL |
+                                          DV_VORG_BIAS_OGL |
+                                          i810Screen->fbFormat);
+
+   imesa->BufferSetup[I810_DESTREG_DR0] = GFX_OP_DRAWRECT_INFO;
+   imesa->BufferSetup[I810_DESTREG_DR1] = DR1_RECT_CLIP_ENABLE;
+}
+
+
+static void i810InvalidateState( GLcontext *ctx, GLuint new_state )
+{
+   _swrast_InvalidateState( ctx, new_state );
+   _swsetup_InvalidateState( ctx, new_state );
+   _ac_InvalidateState( ctx, new_state );
+   _tnl_InvalidateState( ctx, new_state );
+   I810_CONTEXT(ctx)->new_state |= new_state;
+}
+
+
+void i810InitStateFuncs(GLcontext *ctx)
+{
+   /* Callbacks for internal Mesa events.
+    */
+   ctx->Driver.UpdateState = i810InvalidateState;
+
+   /* API callbacks
+    */
+   ctx->Driver.AlphaFunc = i810AlphaFunc;
+   ctx->Driver.BlendEquation = i810BlendEquation;
+   ctx->Driver.BlendFunc = i810BlendFunc;
+   ctx->Driver.BlendFuncSeparate = i810BlendFuncSeparate;
+   ctx->Driver.ClearColor = i810ClearColor;
+   ctx->Driver.ColorMask = i810ColorMask;
+   ctx->Driver.CullFace = i810CullFaceFrontFace;
+   ctx->Driver.DepthFunc = i810DepthFunc;
+   ctx->Driver.DepthMask = i810DepthMask;
+   ctx->Driver.Enable = i810Enable;
+   ctx->Driver.Fogfv = i810Fogfv;
+   ctx->Driver.FrontFace = i810CullFaceFrontFace;
+   ctx->Driver.LineWidth = i810LineWidth;
+   ctx->Driver.LogicOpcode = i810LogicOp;
+   ctx->Driver.PolygonStipple = i810PolygonStipple;
+   ctx->Driver.RenderMode = i810RenderMode;
+   ctx->Driver.Scissor = i810Scissor;
+   ctx->Driver.DrawBuffer = i810DrawBuffer;
+   ctx->Driver.ReadBuffer = i810ReadBuffer;
+   ctx->Driver.ShadeModel = i810ShadeModel;
+   ctx->Driver.DepthRange = i810DepthRange;
+   ctx->Driver.Viewport = i810Viewport;
+   ctx->Driver.PointSize = i810PointSize;
+
+   if (IS_I815(I810_CONTEXT(ctx))) {
+      ctx->Driver.LightModelfv = i810LightModelfv_i815;
+   } else {
+      ctx->Driver.LightModelfv = i810LightModelfv;
+   }
+
+   /* Pixel path fallbacks.
+    */
+   ctx->Driver.Accum = _swrast_Accum;
+   ctx->Driver.Bitmap = _swrast_Bitmap;
+   ctx->Driver.CopyPixels = _swrast_CopyPixels;
+   ctx->Driver.DrawPixels = _swrast_DrawPixels;
+   ctx->Driver.ReadPixels = _swrast_ReadPixels;
+
+   /* Swrast hooks for imaging extensions:
+    */
+   ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
+   ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
+   ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+   ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+}
diff --git a/src/mesa/drivers/dri/i810/i810state.h b/src/mesa/drivers/dri/i810/i810state.h
new file mode 100644 (file)
index 0000000..118b075
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef _I810_STATE_H
+#define _I810_STATE_H
+
+#include "i810context.h"
+
+extern void i810InitState( GLcontext *ctx );
+extern void i810InitStateFuncs( GLcontext *ctx );
+extern void i810PrintDirty( const char *msg, GLuint state );
+extern void i810DrawBuffer(GLcontext *ctx, GLenum mode );
+
+extern void i810Fallback( i810ContextPtr imesa, GLuint bit, GLboolean mode );
+#define FALLBACK( imesa, bit, mode ) i810Fallback( imesa, bit, mode )
+
+
+#endif
diff --git a/src/mesa/drivers/dri/i810/i810tex.c b/src/mesa/drivers/dri/i810/i810tex.c
new file mode 100644 (file)
index 0000000..f2ebd35
--- /dev/null
@@ -0,0 +1,544 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tex.c,v 1.9 2002/10/30 12:51:33 alanh Exp $ */
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "imports.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "texstore.h"
+#include "texformat.h"
+#include "teximage.h"
+#include "texmem.h"
+#include "swrast/swrast.h"
+#include "colormac.h"
+
+#include "mm.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810tex.h"
+#include "i810state.h"
+#include "i810ioctl.h"
+
+
+/*
+ * Compute the 'S2.4' lod bias factor from the floating point OpenGL bias.
+ */
+static GLuint i810ComputeLodBias(GLfloat bias)
+{
+   int b = (int) (bias * 16.0) + 12;
+   if (b > 63)
+      b = 63;
+   else if (b < -64)
+      b = -64;
+   return (GLuint) (b & MLC_LOD_BIAS_MASK);
+}
+
+
+static void i810SetTexWrapping(i810TextureObjectPtr tex,
+                              GLenum swrap, GLenum twrap)
+{
+   tex->Setup[I810_TEXREG_MCS] &= ~(MCS_U_STATE_MASK| MCS_V_STATE_MASK);
+
+   switch( swrap ) {
+   case GL_REPEAT:
+      tex->Setup[I810_TEXREG_MCS] |= MCS_U_WRAP;
+      break;
+   case GL_CLAMP:
+   case GL_CLAMP_TO_EDGE:
+      tex->Setup[I810_TEXREG_MCS] |= MCS_U_CLAMP;
+      break;
+   case GL_MIRRORED_REPEAT:
+      tex->Setup[I810_TEXREG_MCS] |= MCS_U_MIRROR;
+      break;
+   default:
+      _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__);
+   }
+
+   switch( twrap ) {
+   case GL_REPEAT:
+      tex->Setup[I810_TEXREG_MCS] |= MCS_V_WRAP;
+      break;
+   case GL_CLAMP:
+   case GL_CLAMP_TO_EDGE:
+      tex->Setup[I810_TEXREG_MCS] |= MCS_V_CLAMP;
+      break;
+   case GL_MIRRORED_REPEAT:
+      tex->Setup[I810_TEXREG_MCS] |= MCS_V_MIRROR;
+      break;
+   default:
+      _mesa_problem(NULL, "bad T wrap mode in %s", __FUNCTION__);
+   }
+}
+
+
+static void i810SetTexFilter(i810ContextPtr imesa, 
+                            i810TextureObjectPtr t, 
+                            GLenum minf, GLenum magf,
+                             GLfloat bias)
+{
+   t->Setup[I810_TEXREG_MF] &= ~(MF_MIN_MASK|
+                                MF_MAG_MASK|
+                                MF_MIP_MASK);
+   t->Setup[I810_TEXREG_MLC] &= ~(MLC_LOD_BIAS_MASK);
+
+   switch (minf) {
+   case GL_NEAREST:
+      t->Setup[I810_TEXREG_MF] |= MF_MIN_NEAREST | MF_MIP_NONE;
+      break;
+   case GL_LINEAR:
+      t->Setup[I810_TEXREG_MF] |= MF_MIN_LINEAR | MF_MIP_NONE;
+      break;
+   case GL_NEAREST_MIPMAP_NEAREST:
+      t->Setup[I810_TEXREG_MF] |= MF_MIN_NEAREST | MF_MIP_NEAREST;
+      if (magf == GL_LINEAR) {
+         /*bias -= 0.5;*/  /* this doesn't work too good */
+      }
+      break;
+   case GL_LINEAR_MIPMAP_NEAREST:
+      t->Setup[I810_TEXREG_MF] |= MF_MIN_LINEAR | MF_MIP_NEAREST;
+      break;
+   case GL_NEAREST_MIPMAP_LINEAR:
+      if (IS_I815(imesa)) 
+        t->Setup[I810_TEXREG_MF] |= MF_MIN_NEAREST | MF_MIP_LINEAR;
+      else 
+        t->Setup[I810_TEXREG_MF] |= MF_MIN_NEAREST | MF_MIP_DITHER;
+      /*
+      if (magf == GL_LINEAR) {
+         bias -= 0.5;
+      }
+      */
+      bias -= 0.5; /* always biasing here looks better */
+      break;
+   case GL_LINEAR_MIPMAP_LINEAR:
+      if (IS_I815(imesa))
+        t->Setup[I810_TEXREG_MF] |= MF_MIN_LINEAR | MF_MIP_LINEAR;
+      else 
+        t->Setup[I810_TEXREG_MF] |= MF_MIN_LINEAR | MF_MIP_DITHER;
+      break;
+   default:
+      return;
+   }
+
+   switch (magf) {
+   case GL_NEAREST: 
+      t->Setup[I810_TEXREG_MF] |= MF_MAG_NEAREST; 
+      break;
+   case GL_LINEAR: 
+      t->Setup[I810_TEXREG_MF] |= MF_MAG_LINEAR; 
+      break;
+   default: 
+      return;
+   }
+
+   t->Setup[I810_TEXREG_MLC] |= i810ComputeLodBias(bias);
+}
+
+
+static void i810SetTexBorderColor(i810TextureObjectPtr t, 
+                                 GLubyte color[4])
+{
+   /* Need a fallback.
+    */
+}
+static i810TextureObjectPtr i810AllocTexObj( GLcontext *ctx, struct gl_texture_object *texObj )
+{
+   i810TextureObjectPtr t;
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+   t = CALLOC_STRUCT( i810_texture_object_t );
+   texObj->DriverData = t;
+   if ( t != NULL ) {
+      GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias;
+      /* Initialize non-image-dependent parts of the state:
+       */
+      t->base.tObj = texObj;
+      t->Setup[I810_TEXREG_MI0] = GFX_OP_MAP_INFO;
+      t->Setup[I810_TEXREG_MI1] = MI1_MAP_0; 
+      t->Setup[I810_TEXREG_MI2] = MI2_DIMENSIONS_ARE_LOG2;
+      t->Setup[I810_TEXREG_MLC] = (GFX_OP_MAP_LOD_CTL | 
+                                  MLC_MAP_0 |
+                                  /*MLC_DITHER_WEIGHT_FULL |*/
+                                  MLC_DITHER_WEIGHT_12 |
+                                  MLC_UPDATE_LOD_BIAS |
+                                  0x0);
+      t->Setup[I810_TEXREG_MCS] = (GFX_OP_MAP_COORD_SETS |
+                                  MCS_COORD_0 |
+                                  MCS_UPDATE_NORMALIZED |
+                                  MCS_NORMALIZED_COORDS |
+                                  MCS_UPDATE_V_STATE |
+                                  MCS_V_WRAP |
+                                  MCS_UPDATE_U_STATE |
+                                  MCS_U_WRAP);
+      t->Setup[I810_TEXREG_MF] = (GFX_OP_MAP_FILTER |
+                                 MF_MAP_0 |
+                                 MF_UPDATE_ANISOTROPIC |
+                                 MF_UPDATE_MIP_FILTER |
+                                 MF_UPDATE_MAG_FILTER |
+                                 MF_UPDATE_MIN_FILTER);
+      
+      make_empty_list( & t->base );
+
+      i810SetTexWrapping( t, texObj->WrapS, texObj->WrapT );
+      /*i830SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );*/
+      i810SetTexFilter( imesa, t, texObj->MinFilter, texObj->MagFilter, bias );
+      i810SetTexBorderColor( t, texObj->_BorderChan );
+   }
+
+   return t;
+}
+
+
+static void i810TexParameter( GLcontext *ctx, GLenum target,
+                             struct gl_texture_object *tObj,
+                             GLenum pname, const GLfloat *params )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData;
+   if (!t)
+      return;
+
+   if ( target != GL_TEXTURE_2D )
+      return;
+
+   /* Can't do the update now as we don't know whether to flush
+    * vertices or not.  Setting imesa->new_state means that
+    * i810UpdateTextureState() will be called before any triangles are
+    * rendered.  If a statechange has occurred, it will be detected at
+    * that point, and buffered vertices flushed.  
+    */
+   switch (pname) {
+   case GL_TEXTURE_MIN_FILTER:
+   case GL_TEXTURE_MAG_FILTER:
+      {
+         GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias;
+         i810SetTexFilter( imesa, t, tObj->MinFilter, tObj->MagFilter, bias );
+      }
+      break;
+
+   case GL_TEXTURE_WRAP_S:
+   case GL_TEXTURE_WRAP_T:
+      i810SetTexWrapping( t, tObj->WrapS, tObj->WrapT );
+      break;
+  
+   case GL_TEXTURE_BORDER_COLOR:
+      i810SetTexBorderColor( t, tObj->_BorderChan );
+      break;
+
+   case GL_TEXTURE_BASE_LEVEL:
+   case GL_TEXTURE_MAX_LEVEL:
+   case GL_TEXTURE_MIN_LOD:
+   case GL_TEXTURE_MAX_LOD:
+      /* This isn't the most efficient solution but there doesn't appear to
+       * be a nice alternative for Radeon.  Since there's no LOD clamping,
+       * we just have to rely on loading the right subset of mipmap levels
+       * to simulate a clamped LOD.
+       */
+      I810_FIREVERTICES( I810_CONTEXT(ctx) );
+      driSwapOutTextureObject( (driTextureObject *) t );
+      break;
+
+   default:
+      return;
+   }
+
+   if (t == imesa->CurrentTexObj[0]) {
+      I810_STATECHANGE( imesa, I810_UPLOAD_TEX0 );
+   }
+
+   if (t == imesa->CurrentTexObj[1]) {
+      I810_STATECHANGE( imesa, I810_UPLOAD_TEX1 );
+   }
+}
+
+
+static void i810TexEnv( GLcontext *ctx, GLenum target, 
+                       GLenum pname, const GLfloat *param )
+{
+   i810ContextPtr imesa = I810_CONTEXT( ctx );
+   GLuint unit = ctx->Texture.CurrentUnit;
+
+   /* Only one env color.  Need a fallback if env colors are different
+    * and texture setup references env color in both units.  
+    */
+   switch (pname) {
+   case GL_TEXTURE_ENV_COLOR: {
+      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+      GLfloat *fc = texUnit->EnvColor;
+      GLuint r, g, b, a, col;
+      CLAMPED_FLOAT_TO_UBYTE(r, fc[0]);
+      CLAMPED_FLOAT_TO_UBYTE(g, fc[1]);
+      CLAMPED_FLOAT_TO_UBYTE(b, fc[2]);
+      CLAMPED_FLOAT_TO_UBYTE(a, fc[3]);
+
+      col = ((a << 24) | 
+            (r << 16) | 
+            (g <<  8) | 
+            (b <<  0));
+      if (imesa->Setup[I810_CTXREG_CF1] != col) {
+        I810_STATECHANGE(imesa, I810_UPLOAD_CTX);      
+        imesa->Setup[I810_CTXREG_CF1] = col;      
+      }
+      break;
+   }
+   case GL_TEXTURE_ENV_MODE:
+      imesa->TexEnvImageFmt[unit] = 0; /* force recalc of env state */
+      break;
+
+   case GL_TEXTURE_LOD_BIAS_EXT:
+      {
+         struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
+         i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData;
+         t->Setup[I810_TEXREG_MLC] &= ~(MLC_LOD_BIAS_MASK);
+         t->Setup[I810_TEXREG_MLC] |= i810ComputeLodBias(*param);
+      }
+      break;
+
+   default:
+      break;
+   }
+} 
+
+
+
+#if 0
+static void i810TexImage1D( GLcontext *ctx, GLenum target, GLint level,
+                           GLint internalFormat,
+                           GLint width, GLint border,
+                           GLenum format, GLenum type, 
+                           const GLvoid *pixels,
+                           const struct gl_pixelstore_attrib *pack,
+                           struct gl_texture_object *texObj,
+                           struct gl_texture_image *texImage )
+{
+   i810TextureObjectPtr t = (i810TextureObjectPtr) texObj->DriverData;
+   if (t) {
+      i810SwapOutTexObj( imesa, t );
+   }
+}
+
+static void i810TexSubImage1D( GLcontext *ctx, 
+                              GLenum target,
+                              GLint level,     
+                              GLint xoffset,
+                              GLsizei width,
+                              GLenum format, GLenum type,
+                              const GLvoid *pixels,
+                              const struct gl_pixelstore_attrib *pack,
+                              struct gl_texture_object *texObj,
+                              struct gl_texture_image *texImage )
+{
+}
+#endif
+
+
+static void i810TexImage2D( 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 )
+{
+   driTextureObject *t = (driTextureObject *) texObj->DriverData;
+   if (t) {
+      I810_FIREVERTICES( I810_CONTEXT(ctx) );
+      driSwapOutTextureObject( t );
+   }
+   else {
+      t = (driTextureObject *) i810AllocTexObj( ctx, texObj );
+      if (!t) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+         return;
+      }
+   }
+   _mesa_store_teximage2d( ctx, target, level, internalFormat,
+                          width, height, border, format, type,
+                          pixels, packing, texObj, texImage );
+
+}
+
+static void i810TexSubImage2D( 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 )
+{
+   driTextureObject *t = (driTextureObject *)texObj->DriverData;
+
+   if (t) {
+     I810_FIREVERTICES( I810_CONTEXT(ctx) );
+     driSwapOutTextureObject( t );
+   }
+   _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, 
+                            height, format, type, pixels, packing, texObj,
+                            texImage);
+
+}
+
+
+static void i810BindTexture( GLcontext *ctx, GLenum target,
+                            struct gl_texture_object *tObj )
+{
+  if (!tObj->DriverData) {
+      i810AllocTexObj( ctx, tObj );
+  }
+}
+
+
+static void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
+{
+  driTextureObject * t = (driTextureObject *) tObj->DriverData;
+   if (t) {
+      i810ContextPtr imesa = I810_CONTEXT( ctx );
+      if (imesa)
+         I810_FIREVERTICES( imesa );
+      driDestroyTextureObject( t );
+   }
+}
+
+static const struct gl_texture_format *
+i810ChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
+                        GLenum format, GLenum type )
+{
+   switch ( internalFormat ) {
+   case 4:
+   case GL_RGBA:
+   case GL_COMPRESSED_RGBA:
+      if ( format == GL_BGRA ) {
+         if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
+           return &_mesa_texformat_argb1555;
+        }
+      }
+      return &_mesa_texformat_argb4444;
+
+   case 3:
+   case GL_RGB:
+   case GL_COMPRESSED_RGB:
+   case GL_R3_G3_B2:
+   case GL_RGB4:
+   case GL_RGB5:
+   case GL_RGB8:
+   case GL_RGB10:
+   case GL_RGB12:
+   case GL_RGB16:
+     return &_mesa_texformat_rgb565;
+
+   case GL_RGBA2:
+   case GL_RGBA4:
+   case GL_RGBA8:
+   case GL_RGB10_A2:
+   case GL_RGBA12:
+   case GL_RGBA16:
+      return &_mesa_texformat_argb4444;
+
+   case GL_RGB5_A1:
+      return &_mesa_texformat_argb1555;
+
+   case GL_ALPHA:
+   case GL_ALPHA4:
+   case GL_ALPHA8:
+   case GL_ALPHA12:
+   case GL_ALPHA16:
+   case GL_COMPRESSED_ALPHA:
+      return &_mesa_texformat_al88;
+
+   case 1:
+   case GL_LUMINANCE:
+   case GL_LUMINANCE4:
+   case GL_LUMINANCE8:
+   case GL_LUMINANCE12:
+   case GL_LUMINANCE16:
+   case GL_COMPRESSED_LUMINANCE:
+      return &_mesa_texformat_rgb565;
+
+   case 2:
+   case GL_LUMINANCE_ALPHA:
+   case GL_LUMINANCE4_ALPHA4:
+   case GL_LUMINANCE6_ALPHA2:
+   case GL_LUMINANCE8_ALPHA8:
+   case GL_LUMINANCE12_ALPHA4:
+   case GL_LUMINANCE12_ALPHA12:
+   case GL_LUMINANCE16_ALPHA16:
+   case GL_COMPRESSED_LUMINANCE_ALPHA:
+   case GL_INTENSITY:
+   case GL_INTENSITY4:
+   case GL_INTENSITY8:
+   case GL_INTENSITY12:
+   case GL_INTENSITY16:
+   case GL_COMPRESSED_INTENSITY:
+      return &_mesa_texformat_argb4444;
+
+   case GL_YCBCR_MESA:
+      if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
+         type == GL_UNSIGNED_BYTE)
+         return &_mesa_texformat_ycbcr;
+      else
+         return &_mesa_texformat_ycbcr_rev;
+
+   default:
+      fprintf(stderr, "unexpected texture format in %s\n", __FUNCTION__);
+      return NULL;
+   }
+
+   return NULL; /* never get here */
+}
+
+void i810InitTextureFuncs( GLcontext *ctx )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+   ctx->Driver.TexEnv = i810TexEnv;
+   ctx->Driver.ChooseTextureFormat = i810ChooseTextureFormat;
+   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
+   ctx->Driver.TexImage2D = i810TexImage2D;
+   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+   ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
+   ctx->Driver.TexSubImage2D = i810TexSubImage2D;
+   ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+   ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
+   ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
+   ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
+   ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+   ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+   ctx->Driver.BindTexture = i810BindTexture;
+   ctx->Driver.DeleteTexture = i810DeleteTexture;
+   ctx->Driver.TexParameter = i810TexParameter;
+   ctx->Driver.UpdateTexturePalette = 0;
+   ctx->Driver.IsTextureResident = driIsTextureResident;
+   ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
+
+   driInitTextureObjects( ctx, &imesa->swapped, DRI_TEXMGR_DO_TEXTURE_2D);
+
+}
diff --git a/src/mesa/drivers/dri/i810/i810tex.h b/src/mesa/drivers/dri/i810/i810tex.h
new file mode 100644 (file)
index 0000000..f0b4b88
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#ifndef I810TEX_INC
+#define I810TEX_INC
+
+#include "mtypes.h"
+#include "mm.h"
+
+#include "i810context.h"
+#include "i810_3d_reg.h"
+#include "texmem.h"
+
+#define I810_TEX_MAXLEVELS 11
+
+/* For shared texture space managment, these texture objects may also
+ * be used as proxies for regions of texture memory containing other
+ * client's textures.  Such proxy textures (not to be confused with GL
+ * proxy textures) are subject to the same LRU aging we use for our
+ * own private textures, and thus we have a mechanism where we can
+ * fairly decide between kicking out our own textures and those of
+ * other clients.
+ *
+ * Non-local texture objects have a valid MemBlock to describe the
+ * region managed by the other client, and can be identified by
+ * 't->globj == 0' 
+ */
+struct i810_texture_object_t {
+   driTextureObject base;
+     
+   int Pitch;
+   int Height;
+   int texelBytes;
+   char *BufAddr;
+   
+   GLuint max_level;
+
+   struct { 
+      const struct gl_texture_image *image;
+      int offset;              /* into BufAddr */
+      int height;
+      int internalFormat;
+   } image[I810_TEX_MAXLEVELS];
+
+   GLuint Setup[I810_TEX_SETUP_SIZE];
+   GLuint dirty;
+
+};             
+
+void i810UpdateTextureState( GLcontext *ctx );
+void i810InitTextureFuncs( GLcontext *ctx );
+
+void i810DestroyTexObj( i810ContextPtr imesa, i810TextureObjectPtr t );
+int i810UploadTexImagesLocked( i810ContextPtr imesa, i810TextureObjectPtr t );
+
+#endif
diff --git a/src/mesa/drivers/dri/i810/i810texmem.c b/src/mesa/drivers/dri/i810/i810texmem.c
new file mode 100644 (file)
index 0000000..87f535d
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ * Texmem interface changes (C) 2003 Dave Airlie
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "colormac.h"
+#include "mm.h"
+#include "texformat.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810tex.h"
+#include "i810state.h"
+#include "i810ioctl.h"
+
+
+void i810DestroyTexObj(i810ContextPtr imesa, i810TextureObjectPtr t)
+{
+   /* See if it was the driver's current object.
+    */
+   if ( imesa != NULL ) { 
+     if (imesa->CurrentTexObj[0] == t) {
+       imesa->CurrentTexObj[0] = 0;
+       imesa->dirty &= ~I810_UPLOAD_TEX0;
+     }
+     
+     if (imesa->CurrentTexObj[1] == t) {
+       imesa->CurrentTexObj[1] = 0;
+       imesa->dirty &= ~I810_UPLOAD_TEX1;
+     }
+   }
+}
+
+
+
+/* From linux kernel i386 header files, copes with odd sizes better
+ * than COPY_DWORDS would:
+ */
+static __inline__ void * __memcpy(void * to, const void * from, size_t n)
+{
+int d0, d1, d2;
+__asm__ __volatile__(
+       "rep ; movsl\n\t"
+       "testb $2,%b4\n\t"
+       "je 1f\n\t"
+       "movsw\n"
+       "1:\ttestb $1,%b4\n\t"
+       "je 2f\n\t"
+       "movsb\n"
+       "2:"
+       : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+       :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+       : "memory");
+return (to);
+}
+
+/* Upload an image from mesa's internal copy.
+ */
+static void i810UploadTexLevel( i810ContextPtr imesa,
+                               i810TextureObjectPtr t, int hwlevel )
+{
+   const struct gl_texture_image *image = t->image[hwlevel].image;
+   int j;
+
+   if (!image || !image->Data)
+      return;
+
+   if (image->Width * image->TexFormat->TexelBytes == t->Pitch) {
+        GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[hwlevel].offset);
+        GLubyte *src = (GLubyte *)image->Data;
+        
+        memcpy( dst, src, t->Pitch * image->Height );
+   }
+   else switch (image->TexFormat->TexelBytes) {
+   case 1:
+      {
+        GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[hwlevel].offset);
+        GLubyte *src = (GLubyte *)image->Data;
+
+        for (j = 0 ; j < image->Height ; j++, dst += t->Pitch) {
+           __memcpy(dst, src, image->Width );
+           src += image->Width;
+        }
+      }
+      break;
+
+   case 2:
+      {
+        GLushort *dst = (GLushort *)(t->BufAddr + t->image[hwlevel].offset);
+        GLushort *src = (GLushort *)image->Data;
+
+        for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) {
+           __memcpy(dst, src, image->Width * 2 );
+           src += image->Width;
+        }
+      }
+      break;
+
+   default:
+      fprintf(stderr, "%s: Not supported texel size %d\n",
+             __FUNCTION__, image->TexFormat->TexelBytes);
+   }
+}
+
+/* This is called with the lock held.  May have to eject our own and/or
+ * other client's texture objects to make room for the upload.
+ */
+int i810UploadTexImagesLocked( i810ContextPtr imesa, i810TextureObjectPtr t )
+{
+   int i;
+   int ofs;
+   int numLevels;
+
+   /* Do we need to eject LRU texture objects?
+    */
+   if (!t->base.memBlock) {
+      int heap;
+       
+      heap = driAllocateTexture( imesa->texture_heaps, imesa->nr_heaps,
+                                (driTextureObject *) t);
+      
+      if ( heap == -1 ) {
+       return -1;
+      }
+      
+      ofs = t->base.memBlock->ofs;
+      t->BufAddr = imesa->i810Screen->tex.map + ofs;
+      t->Setup[I810_TEXREG_MI3] = imesa->i810Screen->textureOffset + ofs;
+      
+      if (t == imesa->CurrentTexObj[0])
+       I810_STATECHANGE(imesa, I810_UPLOAD_TEX0);
+      
+      if (t == imesa->CurrentTexObj[1])
+        I810_STATECHANGE(imesa, I810_UPLOAD_TEX1);
+      
+       /*      i810UpdateTexLRU( imesa, t );*/
+     }
+   driUpdateTextureLRU( (driTextureObject *) t );
+   
+   if (imesa->texture_heaps[0]->timestamp >= GET_DISPATCH_AGE(imesa))
+      i810WaitAgeLocked( imesa, imesa->texture_heaps[0]->timestamp );
+
+   numLevels = t->base.lastLevel - t->base.firstLevel + 1;
+   for (i = 0 ; i < numLevels ; i++)
+      if (t->base.dirty_images[0] & (1<<i))
+        i810UploadTexLevel( imesa, t, i );
+
+   t->base.dirty_images[0] = 0;
+
+   return 0;
+}  
diff --git a/src/mesa/drivers/dri/i810/i810texstate.c b/src/mesa/drivers/dri/i810/i810texstate.c
new file mode 100644 (file)
index 0000000..6219353
--- /dev/null
@@ -0,0 +1,766 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "simple_list.h"
+#include "enums.h"
+
+#include "mm.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810tex.h"
+#include "i810state.h"
+#include "i810ioctl.h"
+
+
+
+
+static void i810SetTexImages( i810ContextPtr imesa, 
+                             struct gl_texture_object *tObj )
+{
+   GLuint height, width, pitch, i, textureFormat, log_pitch;
+   i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData;
+   const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel];
+   GLint firstLevel, lastLevel, numLevels;
+   GLint log2Width, log2Height;
+
+/*     fprintf(stderr, "%s\n", __FUNCTION__); */
+
+   switch (baseImage->Format) {
+   case GL_RGB:
+   case GL_LUMINANCE:
+      t->texelBytes = 2;
+      textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_RGB565;
+      break;
+   case GL_ALPHA:
+   case GL_LUMINANCE_ALPHA:
+   case GL_INTENSITY:
+   case GL_RGBA:
+      t->texelBytes = 2;
+      textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_ARGB4444;
+      break;
+   case GL_COLOR_INDEX:
+      textureFormat = MI1_FMT_8CI | MI1_PF_8CI_ARGB4444;
+      t->texelBytes = 1;
+      break;
+   case GL_YCBCR_MESA:
+      t->texelBytes = 2;
+      textureFormat = MI1_FMT_422 | MI1_PF_422_YCRCB_SWAP_Y
+         | MI1_COLOR_CONV_ENABLE;
+      break;
+       
+   default:
+      fprintf(stderr, "i810SetTexImages: bad image->Format\n" );
+      return;
+   }
+
+   /* Compute which mipmap levels we really want to send to the hardware.
+    * This depends on the base image size, GL_TEXTURE_MIN_LOD,
+    * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
+    * Yes, this looks overly complicated, but it's all needed.
+    */
+   if (tObj->MinFilter == GL_LINEAR || tObj->MinFilter == GL_NEAREST) {
+      firstLevel = lastLevel = tObj->BaseLevel;
+   }
+   else {
+      firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
+      firstLevel = MAX2(firstLevel, tObj->BaseLevel);
+      lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
+      lastLevel = MAX2(lastLevel, tObj->BaseLevel);
+      lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
+      lastLevel = MIN2(lastLevel, tObj->MaxLevel);
+      lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
+   }
+
+   /* save these values */
+   t->base.firstLevel = firstLevel;
+   t->base.lastLevel = lastLevel;
+
+   numLevels = lastLevel - firstLevel + 1;
+
+   log2Width = tObj->Image[firstLevel]->WidthLog2;
+   log2Height = tObj->Image[firstLevel]->HeightLog2;
+
+   /* Figure out the amount of memory required to hold all the mipmap
+    * levels.  Choose the smallest pitch to accomodate the largest
+    * mipmap:
+    */
+   width = tObj->Image[firstLevel]->Width * t->texelBytes;
+   for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 )
+      log_pitch++;
+   
+   /* All images must be loaded at this pitch.  Count the number of
+    * lines required:
+    */
+   for ( height = i = 0 ; i < numLevels ; i++ ) {
+      t->image[i].image = tObj->Image[firstLevel + i];
+      t->image[i].offset = height * pitch;
+      t->image[i].internalFormat = baseImage->Format;
+      height += t->image[i].image->Height;
+   }
+
+   t->Pitch = pitch;
+   t->base.totalSize = height*pitch;
+   t->max_level = i-1;
+   t->dirty = I810_UPLOAD_TEX0 | I810_UPLOAD_TEX1;   
+   t->Setup[I810_TEXREG_MI1] = (MI1_MAP_0 | textureFormat | log_pitch); 
+   t->Setup[I810_TEXREG_MI2] = (MI2_DIMENSIONS_ARE_LOG2 |
+                               (log2Height << 16) | log2Width);
+   t->Setup[I810_TEXREG_MLL] = (GFX_OP_MAP_LOD_LIMITS |
+                               MLL_MAP_0  |
+                               MLL_UPDATE_MAX_MIP | 
+                               MLL_UPDATE_MIN_MIP |
+                               ((numLevels - 1) << MLL_MIN_MIP_SHIFT));
+
+   LOCK_HARDWARE( imesa );
+   i810UploadTexImagesLocked( imesa, t );
+   UNLOCK_HARDWARE( imesa );
+}
+
+/* ================================================================
+ * Texture combine functions
+ */
+
+#define I810_DISABLE           0
+#define I810_PASSTHRU          1
+#define I810_REPLACE           2
+#define I810_MODULATE          3
+#define I810_DECAL             4
+#define I810_BLEND             5
+#define I810_ALPHA_BLEND       6
+#define I810_ADD               7
+#define I810_MAX_COMBFUNC      8
+
+
+static GLuint i810_color_combine[][I810_MAX_COMBFUNC] =
+{
+   /* Unit 0:
+    */
+   {
+      /* Disable combiner stage
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_0 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_ITERATED_COLOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_ONE |
+       MC_UPDATE_OP |
+       MC_OP_ARG1 ),           /* actually passthru */
+
+      /* Passthru
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_0 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_ITERATED_COLOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_ONE |
+       MC_UPDATE_OP |
+       MC_OP_ARG1 ),
+
+      /* GL_REPLACE 
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_0 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_TEX0_COLOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_ONE |
+       MC_UPDATE_OP |
+       MC_OP_ARG1 ),
+
+      /* GL_MODULATE
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_0 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_TEX0_COLOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_ITERATED_COLOR |
+       MC_UPDATE_OP |
+       MC_OP_MODULATE ),
+
+      /* GL_DECAL 
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_0 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_COLOR_FACTOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_TEX0_COLOR |
+       MC_UPDATE_OP |
+       MC_OP_LIN_BLEND_TEX0_ALPHA ),
+
+      /* GL_BLEND 
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_0 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_COLOR_FACTOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_ITERATED_COLOR |
+       MC_UPDATE_OP |
+       MC_OP_LIN_BLEND_TEX0_COLOR ),
+
+      /* GL_BLEND according to alpha
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_0 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_TEX0_COLOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_ITERATED_COLOR |
+       MC_UPDATE_OP |
+       MC_OP_LIN_BLEND_TEX0_ALPHA ),
+
+      /* GL_ADD 
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_0 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_TEX0_COLOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_ITERATED_COLOR |
+       MC_UPDATE_OP |
+       MC_OP_ADD ),
+   },
+
+   /* Unit 1:
+    */
+   {
+      /* Disable combiner stage (Note: disables all subsequent stages)
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_1 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_ONE | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_ONE |
+       MC_UPDATE_OP |
+       MC_OP_DISABLE ),
+
+      
+      /* Passthru
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_1 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_CURRENT_COLOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_ONE |
+       MC_UPDATE_OP |
+       MC_OP_ARG1 ),
+
+      /* GL_REPLACE
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_1 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_TEX1_COLOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_ONE |
+       MC_UPDATE_OP |
+       MC_OP_ARG1 ),
+
+      /* GL_MODULATE
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_1 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_TEX1_COLOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_CURRENT_COLOR |
+       MC_UPDATE_OP |
+       MC_OP_MODULATE ),
+
+      /* GL_DECAL
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_1 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_COLOR_FACTOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_TEX1_COLOR |
+       MC_UPDATE_OP |
+       MC_OP_LIN_BLEND_TEX1_ALPHA ),
+      
+      /* GL_BLEND 
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_1 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_COLOR_FACTOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_CURRENT_COLOR |
+       MC_UPDATE_OP |
+       MC_OP_LIN_BLEND_TEX1_COLOR ),
+
+      /* GL_BLEND according to alpha
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_1 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_TEX1_COLOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_CURRENT_COLOR |
+       MC_UPDATE_OP |
+       MC_OP_LIN_BLEND_TEX1_ALPHA ),
+
+      /* GL_ADD 
+       */
+      ( GFX_OP_MAP_COLOR_STAGES |
+       MC_STAGE_1 |
+       MC_UPDATE_DEST |
+       MC_DEST_CURRENT |
+       MC_UPDATE_ARG1 |
+       MC_ARG1_TEX1_COLOR | 
+       MC_UPDATE_ARG2 |
+       MC_ARG2_CURRENT_COLOR |
+       MC_UPDATE_OP |
+       MC_OP_ADD ),
+   }
+};
+
+static GLuint i810_alpha_combine[][I810_MAX_COMBFUNC] =
+{
+   /* Unit 0:
+    */
+   {
+      /* Disable combiner stage
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_0 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_ITERATED_ALPHA |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_TEX0_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_ARG1 ),
+
+      /* Passthru
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_0 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_ITERATED_ALPHA |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_TEX0_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_ARG1 ),
+
+      /* GL_REPLACE 
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_0 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_ITERATED_ALPHA |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_TEX0_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_ARG2 ),
+
+      /* GL_MODULATE
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_0 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_ITERATED_ALPHA |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_TEX0_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_MODULATE ),
+
+      /* GL_DECAL 
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_0 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_ALPHA_FACTOR |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_ALPHA_FACTOR |
+       MA_UPDATE_OP |
+       MA_OP_ARG1 ),
+
+      /* GL_BLEND 
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_0 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_ALPHA_FACTOR |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_ITERATED_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_LIN_BLEND_TEX0_ALPHA ),
+
+      /* GL_BLEND according to alpha (same as above)
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_0 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_ALPHA_FACTOR |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_ITERATED_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_LIN_BLEND_TEX0_ALPHA ),
+
+      /* GL_ADD 
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_0 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_ITERATED_ALPHA |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_TEX0_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_ADD ),
+   },
+
+   /* Unit 1:
+    */
+   {
+      /* Disable combiner stage
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_1 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_CURRENT_ALPHA |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_CURRENT_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_ARG1 ),
+
+      /* Passthru
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_1 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_CURRENT_ALPHA |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_CURRENT_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_ARG1 ),
+
+      /* GL_REPLACE 
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_1 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_CURRENT_ALPHA |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_TEX1_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_ARG2 ),
+
+      /* GL_MODULATE 
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_1 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_CURRENT_ALPHA |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_TEX1_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_MODULATE ),
+
+      /* GL_DECAL 
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_1 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_ALPHA_FACTOR |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_ALPHA_FACTOR |
+       MA_UPDATE_OP |
+       MA_OP_ARG1 ),
+
+      /* GL_BLEND 
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_1 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_ALPHA_FACTOR |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_ITERATED_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_LIN_BLEND_TEX1_ALPHA ),
+
+      /* GL_BLEND according to alpha (same as above)
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_1 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_ALPHA_FACTOR |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_ITERATED_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_LIN_BLEND_TEX1_ALPHA ),
+
+      /* GL_ADD 
+       */
+      ( GFX_OP_MAP_ALPHA_STAGES |
+       MA_STAGE_1 |
+       MA_UPDATE_ARG1 |
+       MA_ARG1_CURRENT_ALPHA |
+       MA_UPDATE_ARG2 |
+       MA_ARG2_TEX1_ALPHA |
+       MA_UPDATE_OP |
+       MA_OP_ADD ),
+   }
+
+};
+
+
+
+static void i810UpdateTexEnv( GLcontext *ctx, GLuint unit )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+   const struct gl_texture_object *tObj = texUnit->_Current;
+   const GLuint format = tObj->Image[tObj->BaseLevel]->Format;
+   GLuint color_combine, alpha_combine;
+
+   switch (texUnit->EnvMode) {
+   case GL_REPLACE:
+      if (format == GL_ALPHA) {
+        color_combine = i810_color_combine[unit][I810_PASSTHRU];
+        alpha_combine = i810_alpha_combine[unit][I810_REPLACE];
+      } else if (format == GL_LUMINANCE || format == GL_RGB) {
+        color_combine = i810_color_combine[unit][I810_REPLACE];
+        alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU];
+      } else {
+        color_combine = i810_color_combine[unit][I810_REPLACE];
+        alpha_combine = i810_alpha_combine[unit][I810_REPLACE];
+      }
+      break;
+
+   case GL_MODULATE:
+      if (format == GL_ALPHA) {
+        color_combine = i810_color_combine[unit][I810_PASSTHRU];
+        alpha_combine = i810_alpha_combine[unit][I810_MODULATE];
+      } else {
+        color_combine = i810_color_combine[unit][I810_MODULATE];
+        alpha_combine = i810_alpha_combine[unit][I810_MODULATE];
+      }
+      break;
+
+   case GL_DECAL:
+      switch (format) {
+      case GL_RGBA:
+        color_combine = i810_color_combine[unit][I810_ALPHA_BLEND];
+        alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU];
+        break;
+      case GL_RGB:
+        color_combine = i810_color_combine[unit][I810_REPLACE];
+        alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU];
+        break;
+      case GL_ALPHA:
+      case GL_LUMINANCE:
+      case GL_LUMINANCE_ALPHA:
+      case GL_INTENSITY:
+        color_combine = i810_color_combine[unit][I810_PASSTHRU];
+        alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU];
+        break;
+      case GL_COLOR_INDEX:
+      default:
+        return;
+      }
+      break;
+
+   case GL_BLEND:
+      switch (format) {
+      case GL_RGB:
+      case GL_LUMINANCE:
+        color_combine = i810_color_combine[unit][I810_BLEND];
+        alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU];
+        break;
+      case GL_RGBA:
+      case GL_LUMINANCE_ALPHA:
+        color_combine = i810_color_combine[unit][I810_BLEND];
+        alpha_combine = i810_alpha_combine[unit][I810_MODULATE];
+        break;
+      case GL_ALPHA:
+        color_combine = i810_color_combine[unit][I810_PASSTHRU];
+        alpha_combine = i810_alpha_combine[unit][I810_MODULATE];
+        break;
+      case GL_INTENSITY:
+        color_combine = i810_color_combine[unit][I810_BLEND];
+        alpha_combine = i810_alpha_combine[unit][I810_BLEND];
+        break;
+      case GL_COLOR_INDEX:
+      default:
+        return;
+      }
+      break;
+
+   case GL_ADD:
+      switch (format) {
+      case GL_RGB:
+      case GL_LUMINANCE:
+        color_combine = i810_color_combine[unit][I810_ADD];
+        alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU];
+        break;
+      case GL_RGBA:
+      case GL_LUMINANCE_ALPHA:
+        color_combine = i810_color_combine[unit][I810_ADD];
+        alpha_combine = i810_alpha_combine[unit][I810_MODULATE];
+        break;
+      case GL_ALPHA:
+        color_combine = i810_color_combine[unit][I810_PASSTHRU];
+        alpha_combine = i810_alpha_combine[unit][I810_MODULATE];
+        break;
+      case GL_INTENSITY:
+        color_combine = i810_color_combine[unit][I810_ADD];
+        alpha_combine = i810_alpha_combine[unit][I810_ADD];
+        break;
+      case GL_COLOR_INDEX:
+      default:
+        return;
+      }
+      break;
+
+   default:
+      return;
+   }
+
+   if (alpha_combine != imesa->Setup[I810_CTXREG_MA0 + unit] ||
+       color_combine != imesa->Setup[I810_CTXREG_MC0 + unit]) 
+   {
+      I810_STATECHANGE( imesa, I810_UPLOAD_CTX );
+      imesa->Setup[I810_CTXREG_MA0 + unit] = alpha_combine;
+      imesa->Setup[I810_CTXREG_MC0 + unit] = color_combine;
+   }   
+}
+
+
+
+
+static void i810UpdateTexUnit( GLcontext *ctx, GLuint unit )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+
+   if (texUnit->_ReallyEnabled == TEXTURE_2D_BIT) 
+   {
+      struct gl_texture_object *tObj = texUnit->_Current;
+      i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
+
+      /* Upload teximages (not pipelined)
+       */
+      if (t->base.dirty_images[0]) {
+        I810_FIREVERTICES(imesa);
+        i810SetTexImages( imesa, tObj );
+        if (!t->base.memBlock) {
+           FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
+           return;
+        }
+      }
+
+      if (tObj->Image[tObj->BaseLevel]->Border > 0) {
+         FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
+         return;
+      }
+
+      /* Update state if this is a different texture object to last
+       * time.
+       */
+      if (imesa->CurrentTexObj[unit] != t) {
+        I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<<unit));
+        imesa->CurrentTexObj[unit] = t;
+        t->base.bound |= (1U << unit);
+        
+        driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked */
+
+      }
+      
+      /* Update texture environment if texture object image format or 
+       * texture environment state has changed.
+       */
+      if (tObj->Image[tObj->BaseLevel]->Format != imesa->TexEnvImageFmt[unit]) {
+        imesa->TexEnvImageFmt[unit] = tObj->Image[tObj->BaseLevel]->Format;
+        i810UpdateTexEnv( ctx, unit );
+      }
+   }
+   else if (texUnit->_ReallyEnabled) {
+      FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
+   }
+   else /*if (imesa->CurrentTexObj[unit])*/ {
+      imesa->CurrentTexObj[unit] = 0;
+      imesa->TexEnvImageFmt[unit] = 0; 
+      imesa->dirty &= ~(I810_UPLOAD_TEX0<<unit); 
+      imesa->Setup[I810_CTXREG_MA0 + unit] = 
+        i810_alpha_combine[unit][I810_DISABLE];
+      imesa->Setup[I810_CTXREG_MC0 + unit] = 
+        i810_color_combine[unit][I810_DISABLE];
+      I810_STATECHANGE( imesa, I810_UPLOAD_CTX );
+   }
+}
+
+
+void i810UpdateTextureState( GLcontext *ctx )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   /*  fprintf(stderr, "%s\n", __FUNCTION__); */
+   FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_FALSE );
+   i810UpdateTexUnit( ctx, 0 );
+   i810UpdateTexUnit( ctx, 1 );
+}
+
+
+
diff --git a/src/mesa/drivers/dri/i810/i810tris.c b/src/mesa/drivers/dri/i810/i810tris.c
new file mode 100644 (file)
index 0000000..364b571
--- /dev/null
@@ -0,0 +1,867 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.c,v 1.7 2002/10/30 12:51:33 alanh Exp $ */
+/**************************************************************************
+
+Copyright 2001 VA Linux Systems Inc., Fremont, California.
+
+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
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "enums.h"
+#include "colormac.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810tris.h"
+#include "i810state.h"
+#include "i810vb.h"
+#include "i810ioctl.h"
+
+static void i810RenderPrimitive( GLcontext *ctx, GLenum prim );
+
+/***********************************************************************
+ *                    Emit primitives as inline vertices               *
+ ***********************************************************************/
+
+#if defined(USE_X86_ASM)
+#define COPY_DWORDS( j, vb, vertsize, v )                              \
+do {                                                                   \
+       int __tmp;                                                      \
+       __asm__ __volatile__( "rep ; movsl"                             \
+                             : "=%c" (j), "=D" (vb), "=S" (__tmp)      \
+                             : "0" (vertsize),                         \
+                               "D" ((long)vb),                         \
+                               "S" ((long)v) );                        \
+} while (0)
+#else
+#define COPY_DWORDS( j, vb, vertsize, v )                              \
+do {                                                                   \
+   for ( j = 0 ; j < vertsize ; j++ )                                  \
+      vb[j] = ((GLuint *)v)[j];                                                \
+   vb += vertsize;                                                     \
+} while (0)
+#endif
+
+static void __inline__ i810_draw_triangle( i810ContextPtr imesa,
+                                          i810VertexPtr v0,
+                                          i810VertexPtr v1,
+                                          i810VertexPtr v2 )
+{
+   GLuint vertsize = imesa->vertex_size;
+   GLuint *vb = i810AllocDmaLow( imesa, 3 * 4 * vertsize );
+   int j;
+
+   COPY_DWORDS( j, vb, vertsize, v0 );
+   COPY_DWORDS( j, vb, vertsize, v1 );
+   COPY_DWORDS( j, vb, vertsize, v2 );
+}
+
+
+static void __inline__ i810_draw_quad( i810ContextPtr imesa,
+                                      i810VertexPtr v0,
+                                      i810VertexPtr v1,
+                                      i810VertexPtr v2,
+                                      i810VertexPtr v3 )
+{
+   GLuint vertsize = imesa->vertex_size;
+   GLuint *vb = i810AllocDmaLow( imesa, 6 * 4 * vertsize );
+   int j;
+
+   COPY_DWORDS( j, vb, vertsize, v0 );
+   COPY_DWORDS( j, vb, vertsize, v1 );
+   COPY_DWORDS( j, vb, vertsize, v3 );
+   COPY_DWORDS( j, vb, vertsize, v1 );
+   COPY_DWORDS( j, vb, vertsize, v2 );
+   COPY_DWORDS( j, vb, vertsize, v3 );
+}
+
+
+static __inline__ void i810_draw_point( i810ContextPtr imesa,
+                                       i810VertexPtr tmp )
+{
+   GLfloat sz = imesa->glCtx->Point._Size * .5;
+   int vertsize = imesa->vertex_size;
+   GLuint *vb = i810AllocDmaLow( imesa, 2 * 4 * vertsize );
+   int j;
+
+   /* Draw a point as a horizontal line.
+    */
+   *(float *)&vb[0] = tmp->v.x - sz + 0.125;
+   for (j = 1 ; j < vertsize ; j++)
+      vb[j] = tmp->ui[j];
+   vb += vertsize;
+
+   *(float *)&vb[0] = tmp->v.x + sz + 0.125;
+   for (j = 1 ; j < vertsize ; j++)
+      vb[j] = tmp->ui[j];
+   vb += vertsize;
+}
+
+
+static __inline__ void i810_draw_line( i810ContextPtr imesa,
+                                      i810VertexPtr v0,
+                                      i810VertexPtr v1 )
+{
+   GLuint vertsize = imesa->vertex_size;
+   GLuint *vb = i810AllocDmaLow( imesa, 2 * 4 * vertsize );
+   int j;
+
+   COPY_DWORDS( j, vb, vertsize, v0 );
+   COPY_DWORDS( j, vb, vertsize, v1 );
+}
+
+
+
+/***********************************************************************
+ *          Macros for t_dd_tritmp.h to draw basic primitives          *
+ ***********************************************************************/
+
+#define TRI( a, b, c )                         \
+do {                                           \
+   if (0) fprintf(stderr, "hw TRI\n");         \
+   if (DO_FALLBACK)                            \
+      imesa->draw_tri( imesa, a, b, c );       \
+   else                                                \
+      i810_draw_triangle( imesa, a, b, c );    \
+} while (0)
+
+#define QUAD( a, b, c, d )                     \
+do {                                           \
+   if (0) fprintf(stderr, "hw QUAD\n");                \
+   if (DO_FALLBACK) {                          \
+      imesa->draw_tri( imesa, a, b, d );       \
+      imesa->draw_tri( imesa, b, c, d );       \
+   } else                                      \
+      i810_draw_quad( imesa, a, b, c, d );     \
+} while (0)
+
+#define LINE( v0, v1 )                         \
+do {                                           \
+   if (0) fprintf(stderr, "hw LINE\n");                \
+   if (DO_FALLBACK)                            \
+      imesa->draw_line( imesa, v0, v1 );       \
+   else                                                \
+      i810_draw_line( imesa, v0, v1 );         \
+} while (0)
+
+#define POINT( v0 )                            \
+do {                                           \
+   if (0) fprintf(stderr, "hw POINT\n");       \
+   if (DO_FALLBACK)                            \
+      imesa->draw_point( imesa, v0 );          \
+   else                                                \
+      i810_draw_point( imesa, v0 );            \
+} while (0)
+
+
+/***********************************************************************
+ *              Build render functions from dd templates               *
+ ***********************************************************************/
+
+#define I810_OFFSET_BIT        0x01
+#define I810_TWOSIDE_BIT       0x02
+#define I810_UNFILLED_BIT      0x04
+#define I810_FALLBACK_BIT      0x08
+#define I810_MAX_TRIFUNC       0x10
+
+
+static struct {
+   points_func         points;
+   line_func           line;
+   triangle_func       triangle;
+   quad_func           quad;
+} rast_tab[I810_MAX_TRIFUNC];
+
+
+#define DO_FALLBACK (IND & I810_FALLBACK_BIT)
+#define DO_OFFSET   (IND & I810_OFFSET_BIT)
+#define DO_UNFILLED (IND & I810_UNFILLED_BIT)
+#define DO_TWOSIDE  (IND & I810_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            i810Vertex
+#define TAB               rast_tab
+
+/* Only used to pull back colors into vertices (ie, we know color is
+ * floating point).
+ */
+#define I810_COLOR( dst, src )                 \
+do {                                           \
+   dst[0] = src[2];                            \
+   dst[1] = src[1];                            \
+   dst[2] = src[0];                            \
+   dst[3] = src[3];                            \
+} while (0)
+
+#define I810_SPEC( dst, src )                  \
+do {                                           \
+   dst[0] = src[2];                            \
+   dst[1] = src[1];                            \
+   dst[2] = src[0];                            \
+} while (0)
+
+
+#define DEPTH_SCALE (1.0/0xffff)
+#define UNFILLED_TRI unfilled_tri
+#define UNFILLED_QUAD unfilled_quad
+#define VERT_X(_v) _v->v.x
+#define VERT_Y(_v) _v->v.y
+#define VERT_Z(_v) _v->v.z
+#define AREA_IS_CCW( a ) (a > 0)
+#define GET_VERTEX(e) (imesa->verts + (e<<imesa->vertex_stride_shift))
+
+#define VERT_SET_RGBA( v, c )    I810_COLOR( v->ub4[coloroffset], c )
+#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
+#define VERT_SAVE_RGBA( idx )    color[idx] = v[idx]->ui[coloroffset]
+#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
+
+#define VERT_SET_SPEC( v, c )    if (havespec) I810_SPEC( v->ub4[5], c )
+#define VERT_COPY_SPEC( v0, v1 ) if (havespec) COPY_3V(v0->ub4[5], v1->ub4[5])
+#define VERT_SAVE_SPEC( idx )    if (havespec) spec[idx] = v[idx]->ui[5]
+#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
+
+#define LOCAL_VARS(n)                                                  \
+   i810ContextPtr imesa = I810_CONTEXT(ctx);                           \
+   GLuint color[n], spec[n];                                           \
+   GLuint coloroffset = (imesa->vertex_size == 4 ? 3 : 4);             \
+   GLboolean havespec = (imesa->vertex_size > 4);                      \
+   (void) color; (void) spec; (void) coloroffset; (void) havespec;
+
+
+/***********************************************************************
+ *                Helpers for rendering unfilled primitives            *
+ ***********************************************************************/
+
+static const GLuint hw_prim[GL_POLYGON+1] = {
+   PR_LINES,
+   PR_LINES,
+   PR_LINES,
+   PR_LINES,
+   PR_TRIANGLES,
+   PR_TRIANGLES,
+   PR_TRIANGLES,
+   PR_TRIANGLES,
+   PR_TRIANGLES,
+   PR_TRIANGLES
+};
+
+#define RASTERIZE(x) if (imesa->hw_primitive != hw_prim[x]) \
+                        i810RasterPrimitive( ctx, x, hw_prim[x] )
+#define RENDER_PRIMITIVE imesa->render_primitive
+#define TAG(x) x
+#define IND I810_FALLBACK_BIT
+#include "tnl_dd/t_dd_unfilled.h"
+#undef IND
+
+/***********************************************************************
+ *                      Generate GL render functions                   *
+ ***********************************************************************/
+
+#define IND (0)
+#define TAG(x) x
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_UNFILLED_BIT)
+#define TAG(x) x##_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_OFFSET_BIT|I810_UNFILLED_BIT)
+#define TAG(x) x##_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_UNFILLED_BIT)
+#define TAG(x) x##_twoside_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_FALLBACK_BIT)
+#define TAG(x) x##_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_OFFSET_BIT|I810_FALLBACK_BIT)
+#define TAG(x) x##_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_FALLBACK_BIT)
+#define TAG(x) x##_twoside_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_UNFILLED_BIT|I810_FALLBACK_BIT)
+#define TAG(x) x##_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_OFFSET_BIT|I810_UNFILLED_BIT|I810_FALLBACK_BIT)
+#define TAG(x) x##_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_UNFILLED_BIT|I810_FALLBACK_BIT)
+#define TAG(x) x##_twoside_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_UNFILLED_BIT| \
+            I810_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
+i810_fallback_tri( i810ContextPtr imesa,
+                  i810Vertex *v0,
+                  i810Vertex *v1,
+                  i810Vertex *v2 )
+{
+   GLcontext *ctx = imesa->glCtx;
+   SWvertex v[3];
+   i810_translate_vertex( ctx, v0, &v[0] );
+   i810_translate_vertex( ctx, v1, &v[1] );
+   i810_translate_vertex( ctx, v2, &v[2] );
+   _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
+}
+
+
+static void
+i810_fallback_line( i810ContextPtr imesa,
+                   i810Vertex *v0,
+                   i810Vertex *v1 )
+{
+   GLcontext *ctx = imesa->glCtx;
+   SWvertex v[2];
+   i810_translate_vertex( ctx, v0, &v[0] );
+   i810_translate_vertex( ctx, v1, &v[1] );
+   _swrast_Line( ctx, &v[0], &v[1] );
+}
+
+
+static void
+i810_fallback_point( i810ContextPtr imesa,
+                    i810Vertex *v0 )
+{
+   GLcontext *ctx = imesa->glCtx;
+   SWvertex v[1];
+   i810_translate_vertex( ctx, v0, &v[0] );
+   _swrast_Point( ctx, &v[0] );
+}
+
+
+
+/**********************************************************************/
+/*               Render unclipped begin/end objects                   */
+/**********************************************************************/
+
+#define IND 0
+#define V(x) (i810Vertex *)(vertptr + ((x)<<vertshift))
+#define RENDER_POINTS( start, count )  \
+   for ( ; start < count ; start++) POINT( V(ELT(start)) );
+#define RENDER_LINE( v0, v1 )         LINE( V(v0), V(v1) )
+#define RENDER_TRI(  v0, v1, v2 )     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) i810RenderPrimitive( ctx, x )
+#undef LOCAL_VARS
+#define LOCAL_VARS                                             \
+    i810ContextPtr imesa = I810_CONTEXT(ctx);                  \
+    GLubyte *vertptr = (GLubyte *)imesa->verts;                        \
+    const GLuint vertshift = imesa->vertex_stride_shift;               \
+    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) i810_##x##_verts
+#include "tnl/t_vb_rendertmp.h"
+#undef ELT
+#undef TAG
+#define TAG(x) i810_##x##_elts
+#define ELT(x) elt[x]
+#include "tnl/t_vb_rendertmp.h"
+
+/**********************************************************************/
+/*                   Render clipped primitives                        */
+/**********************************************************************/
+
+
+
+static void i810RenderClippedPoly( GLcontext *ctx, const GLuint *elts,
+                                  GLuint n )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+   GLuint prim = imesa->render_primitive;
+
+   /* Render the new vertices as an unclipped polygon.
+    */
+   {
+      GLuint *tmp = VB->Elts;
+      VB->Elts = (GLuint *)elts;
+      tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, 
+                                                 PRIM_BEGIN|PRIM_END );
+      VB->Elts = tmp;
+   }
+
+   /* Restore the render primitive
+    */
+   if (prim != GL_POLYGON)
+      tnl->Driver.Render.PrimitiveNotify( ctx, prim );
+}
+
+static void i810RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   tnl->Driver.Render.Line( ctx, ii, jj );
+}
+
+static void i810FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
+                                      GLuint n )
+{
+   i810ContextPtr imesa = I810_CONTEXT( ctx );
+   GLuint vertsize = imesa->vertex_size;
+   GLuint *vb = i810AllocDmaLow( imesa, (n-2) * 3 * 4 * vertsize );
+   GLubyte *vertptr = (GLubyte *)imesa->verts;
+   const GLuint vertshift = imesa->vertex_stride_shift;
+   const GLuint *start = (const GLuint *)V(elts[0]);
+   int i,j;
+
+   for (i = 2 ; i < n ; i++) {
+      COPY_DWORDS( j, vb, vertsize, V(elts[i-1]) );
+      COPY_DWORDS( j, vb, vertsize, V(elts[i]) );
+      COPY_DWORDS( j, vb, vertsize, start );
+   }
+}
+
+/**********************************************************************/
+/*                    Choose render functions                         */
+/**********************************************************************/
+
+/***********************************************************************
+ *                    Rasterization fallback helpers                   *
+ ***********************************************************************/
+
+
+
+#define _I810_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE |          \
+                              _DD_NEW_TRI_UNFILLED |           \
+                              _DD_NEW_TRI_LIGHT_TWOSIDE |      \
+                              _DD_NEW_TRI_OFFSET |             \
+                              _DD_NEW_TRI_STIPPLE |            \
+                              _NEW_POLYGONSTIPPLE)
+
+#define POINT_FALLBACK (0)
+#define LINE_FALLBACK (DD_LINE_STIPPLE)
+#define TRI_FALLBACK (0)
+#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\
+                            DD_TRI_STIPPLE)
+#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
+
+static void i810ChooseRenderState(GLcontext *ctx)
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   GLuint flags = ctx->_TriangleCaps;
+   GLuint index = 0;
+
+   if (I810_DEBUG & DEBUG_STATE)
+     fprintf(stderr,"\n%s\n",__FUNCTION__);
+
+   if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) {
+      if (flags & ANY_RASTER_FLAGS) {
+        if (flags & DD_TRI_LIGHT_TWOSIDE)    index |= I810_TWOSIDE_BIT;
+        if (flags & DD_TRI_OFFSET)           index |= I810_OFFSET_BIT;
+        if (flags & DD_TRI_UNFILLED)         index |= I810_UNFILLED_BIT;
+      }
+
+      imesa->draw_point = i810_draw_point;
+      imesa->draw_line = i810_draw_line;
+      imesa->draw_tri = i810_draw_triangle;
+
+      /* Hook in fallbacks for specific primitives.
+       */
+      if (flags & ANY_FALLBACK_FLAGS)
+      {
+        if (flags & POINT_FALLBACK)
+           imesa->draw_point = i810_fallback_point;
+
+        if (flags & LINE_FALLBACK)
+           imesa->draw_line = i810_fallback_line;
+
+        if (flags & TRI_FALLBACK)
+           imesa->draw_tri = i810_fallback_tri;
+
+        if ((flags & DD_TRI_STIPPLE) && !imesa->stipple_in_hw)
+           imesa->draw_tri = i810_fallback_tri;
+
+        index |= I810_FALLBACK_BIT;
+      }
+   }
+
+   if (imesa->RenderIndex != index) {
+      imesa->RenderIndex = index;
+
+      tnl->Driver.Render.Points = rast_tab[index].points;
+      tnl->Driver.Render.Line = rast_tab[index].line;
+      tnl->Driver.Render.Triangle = rast_tab[index].triangle;
+      tnl->Driver.Render.Quad = rast_tab[index].quad;
+
+      if (index == 0) {
+        tnl->Driver.Render.PrimTabVerts = i810_render_tab_verts;
+        tnl->Driver.Render.PrimTabElts = i810_render_tab_elts;
+        tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
+        tnl->Driver.Render.ClippedPolygon = i810FastRenderClippedPoly;
+      } else {
+        tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+        tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+        tnl->Driver.Render.ClippedLine = i810RenderClippedLine;
+        tnl->Driver.Render.ClippedPolygon = i810RenderClippedPoly;
+      }
+   }
+}
+
+static const GLenum reduced_prim[GL_POLYGON+1] = {
+   GL_POINTS,
+   GL_LINES,
+   GL_LINES,
+   GL_LINES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES
+};
+
+
+/**********************************************************************/
+/*                 High level hooks for t_vb_render.c                 */
+/**********************************************************************/
+
+
+
+/* Determine the rasterized primitive when not drawing unfilled
+ * polygons.
+ *
+ * Used only for the default render stage which always decomposes
+ * primitives to trianges/lines/points.  For the accelerated stage,
+ * which renders strips as strips, the equivalent calculations are
+ * performed in i810render.c.
+ */
+static void i810RenderPrimitive( GLcontext *ctx, GLenum prim )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   GLuint rprim = reduced_prim[prim];
+
+   imesa->render_primitive = prim;
+
+   if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
+      return;
+
+   if (imesa->reduced_primitive != rprim ||
+       hw_prim[prim] != imesa->hw_primitive) {
+      i810RasterPrimitive( ctx, rprim, hw_prim[prim] );
+   }
+}
+
+static void i810RunPipeline( GLcontext *ctx )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+   if (imesa->new_state) {
+      if (imesa->new_state & _NEW_TEXTURE)
+        i810UpdateTextureState( ctx ); /* may modify imesa->new_state */
+
+      if (!imesa->Fallback) {
+        if (imesa->new_state & _I810_NEW_VERTEX)
+           i810ChooseVertexState( ctx );
+
+        if (imesa->new_state & _I810_NEW_RENDERSTATE)
+           i810ChooseRenderState( ctx );
+      }
+
+      imesa->new_state = 0;
+   }
+
+   _tnl_run_pipeline( ctx );
+}
+
+static void i810RenderStart( GLcontext *ctx )
+{
+   /* Check for projective textureing.  Make sure all texcoord
+    * pointers point to something.  (fix in mesa?)
+    */
+   i810CheckTexSizes( ctx );
+}
+
+static void i810RenderFinish( GLcontext *ctx )
+{
+   if (I810_CONTEXT(ctx)->RenderIndex & I810_FALLBACK_BIT)
+      _swrast_flush( ctx );
+}
+
+
+
+
+/* System to flush dma and emit state changes based on the rasterized
+ * primitive.
+ */
+void i810RasterPrimitive( GLcontext *ctx,
+                         GLenum rprim,
+                         GLuint hwprim )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   GLuint st1 = imesa->Setup[I810_CTXREG_ST1];
+   GLuint aa = imesa->Setup[I810_CTXREG_AA];
+   GLuint lcs = imesa->Setup[I810_CTXREG_LCS];
+
+   st1 &= ~ST1_ENABLE;
+   aa &= ~AA_ENABLE;
+
+   if (I810_DEBUG & DEBUG_PRIMS) {
+      /* Prints reduced prim, and hw prim */
+      char *prim_name = "Unknown";
+      
+      switch(hwprim) {
+      case PR_LINES:
+        prim_name = "Lines";
+        break;
+      case PR_LINESTRIP:
+        prim_name = "LineStrip";
+        break;  
+      case PR_TRIANGLES:
+        prim_name = "Triangles";
+        break;  
+      case PR_TRISTRIP_0:
+        prim_name = "TriStrip_0";
+        break;  
+      case PR_TRIFAN:
+        prim_name = "TriFan";
+        break;  
+      case PR_POLYGON:
+        prim_name = "Polygons";
+        break;
+      default:
+        break;
+      }
+
+      fprintf(stderr, "%s : rprim(%s), hwprim(%s)\n",
+             __FUNCTION__,
+             _mesa_lookup_enum_by_nr(rprim),
+             prim_name);
+   }
+
+   switch (rprim) {
+   case GL_TRIANGLES:
+      if (ctx->Polygon.StippleFlag)
+        st1 |= ST1_ENABLE;
+      if (ctx->Polygon.SmoothFlag)
+        aa |= AA_ENABLE;
+      break;
+   case GL_LINES:
+      lcs &= ~(LCS_LINEWIDTH_3_0|LCS_LINEWIDTH_0_5);
+      lcs |= imesa->LcsLineWidth;
+      if (ctx->Line.SmoothFlag) {
+        aa |= AA_ENABLE;
+        lcs |= LCS_LINEWIDTH_0_5;
+      }
+      break;
+   case GL_POINTS:
+      lcs &= ~(LCS_LINEWIDTH_3_0|LCS_LINEWIDTH_0_5);
+      lcs |= imesa->LcsPointSize;
+      if (ctx->Point.SmoothFlag) {
+        aa |= AA_ENABLE;
+        lcs |= LCS_LINEWIDTH_0_5;
+      }
+      break;
+   default:
+      return;
+   }
+
+   imesa->reduced_primitive = rprim;
+
+   if (st1 != imesa->Setup[I810_CTXREG_ST1] ||
+       aa != imesa->Setup[I810_CTXREG_AA] ||
+       lcs != imesa->Setup[I810_CTXREG_LCS])
+   {
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->hw_primitive = hwprim;
+      imesa->Setup[I810_CTXREG_LCS] = lcs;
+      imesa->Setup[I810_CTXREG_ST1] = st1;
+      imesa->Setup[I810_CTXREG_AA] = aa;
+   }
+   else if (hwprim != imesa->hw_primitive) {
+      I810_STATECHANGE(imesa, 0);
+      imesa->hw_primitive = hwprim;
+   }
+}
+
+/**********************************************************************/
+/*           Transition to/from hardware rasterization.               */
+/**********************************************************************/
+static char *fallbackStrings[] = {
+   "Texture",
+   "Draw buffer",
+   "Read buffer",
+   "Color mask",
+   "Render mode",
+   "Stencil",
+   "Stipple",
+   "User disable"
+};
+
+
+static char *getFallbackString(GLuint bit)
+{
+   int i = 0;
+   while (bit > 1) {
+      i++;
+      bit >>= 1;
+   }
+   return fallbackStrings[i];
+}
+
+void i810Fallback( i810ContextPtr imesa, GLuint bit, GLboolean mode )
+{
+   GLcontext *ctx = imesa->glCtx;
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   GLuint oldfallback = imesa->Fallback;
+
+   if (0) fprintf(stderr, "%s old %x bit %x mode %d\n", __FUNCTION__,
+                 imesa->Fallback, bit, mode );
+
+   if (mode) {
+      imesa->Fallback |= bit;
+      if (oldfallback == 0) {
+        I810_FIREVERTICES(imesa);
+        if (I810_DEBUG & DEBUG_FALLBACKS) 
+           fprintf(stderr, "ENTER FALLBACK %s\n", getFallbackString( bit ));
+        _swsetup_Wakeup( ctx );
+        imesa->RenderIndex = ~0;
+      }
+   }
+   else {
+      imesa->Fallback &= ~bit;
+      if (oldfallback == bit) {
+        _swrast_flush( ctx );
+        if (I810_DEBUG & DEBUG_FALLBACKS) 
+           fprintf(stderr, "LEAVE FALLBACK %s\n", getFallbackString( bit ));
+        tnl->Driver.Render.Start = i810RenderStart;
+        tnl->Driver.Render.PrimitiveNotify = i810RenderPrimitive;
+        tnl->Driver.Render.Finish = i810RenderFinish;
+        tnl->Driver.Render.BuildVertices = i810BuildVertices;
+        imesa->new_state |= (_I810_NEW_RENDERSTATE|_I810_NEW_VERTEX);
+      }
+   }
+}
+
+
+/**********************************************************************/
+/*                            Initialization.                         */
+/**********************************************************************/
+
+
+void i810InitTriFuncs( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   static int firsttime = 1;
+
+   if (firsttime) {
+      init_rast_tab();
+      firsttime = 0;
+   }
+
+   tnl->Driver.RunPipeline = i810RunPipeline;
+   tnl->Driver.Render.Start = i810RenderStart;
+   tnl->Driver.Render.Finish = i810RenderFinish;
+   tnl->Driver.Render.PrimitiveNotify = i810RenderPrimitive;
+   tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
+   tnl->Driver.Render.BuildVertices = i810BuildVertices;
+}
diff --git a/src/mesa/drivers/dri/i810/i810tris.h b/src/mesa/drivers/dri/i810/i810tris.h
new file mode 100644 (file)
index 0000000..06c8b3f
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.h,v 1.10 2002/02/22 21:33:04 dawes Exp $ */
+
+#ifndef I810TRIS_INC
+#define I810TRIS_INC
+
+#include "mtypes.h"
+
+extern void i810PrintRenderState( const char *msg, GLuint state );
+extern void i810InitTriFuncs( GLcontext *ctx );
+extern void i810RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
+
+#endif
diff --git a/src/mesa/drivers/dri/i810/i810vb.c b/src/mesa/drivers/dri/i810/i810vb.c
new file mode 100644 (file)
index 0000000..ada7f6d
--- /dev/null
@@ -0,0 +1,505 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810vb.c,v 1.13 2003/03/26 20:43:48 tsi Exp $ */
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "imports.h"
+#include "macros.h"
+#include "colormac.h"
+
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/t_context.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810vb.h"
+#include "i810ioctl.h"
+#include "i810tris.h"
+#include "i810state.h"
+
+
+#define I810_TEX1_BIT       0x1
+#define I810_TEX0_BIT       0x2
+#define I810_RGBA_BIT       0x4
+#define I810_SPEC_BIT       0x8
+#define I810_FOG_BIT       0x10
+#define I810_XYZW_BIT       0x20
+#define I810_PTEX_BIT       0x40
+#define I810_MAX_SETUP      0x80
+
+static struct {
+   void                (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
+   interp_func         interp;
+   copy_pv_func                copy_pv;
+   GLboolean           (*check_tex_sizes)( GLcontext *ctx );
+   GLuint               vertex_size;
+   GLuint               vertex_stride_shift;
+   GLuint               vertex_format;
+} setup_tab[I810_MAX_SETUP];
+
+#define TINY_VERTEX_FORMAT (GFX_OP_VERTEX_FMT |                \
+                           VF_TEXCOORD_COUNT_0 |       \
+                           VF_RGBA_ENABLE |            \
+                           VF_XYZ)
+
+#define NOTEX_VERTEX_FORMAT (GFX_OP_VERTEX_FMT |       \
+                            VF_TEXCOORD_COUNT_0 |      \
+                            VF_SPEC_FOG_ENABLE |       \
+                            VF_RGBA_ENABLE |           \
+                            VF_XYZW)
+
+#define TEX0_VERTEX_FORMAT (GFX_OP_VERTEX_FMT |                \
+                           VF_TEXCOORD_COUNT_1 |       \
+                           VF_SPEC_FOG_ENABLE |        \
+                           VF_RGBA_ENABLE |            \
+                           VF_XYZW)
+
+#define TEX1_VERTEX_FORMAT (GFX_OP_VERTEX_FMT |                \
+                           VF_TEXCOORD_COUNT_2 |       \
+                           VF_SPEC_FOG_ENABLE |        \
+                           VF_RGBA_ENABLE |            \
+                           VF_XYZW)
+
+#define PROJ_TEX1_VERTEX_FORMAT 0
+#define TEX2_VERTEX_FORMAT      0
+#define TEX3_VERTEX_FORMAT      0
+#define PROJ_TEX3_VERTEX_FORMAT 0
+
+#define DO_XYZW (IND & I810_XYZW_BIT)
+#define DO_RGBA (IND & I810_RGBA_BIT)
+#define DO_SPEC (IND & I810_SPEC_BIT)
+#define DO_FOG  (IND & I810_FOG_BIT)
+#define DO_TEX0 (IND & I810_TEX0_BIT)
+#define DO_TEX1 (IND & I810_TEX1_BIT)
+#define DO_TEX2 0
+#define DO_TEX3 0
+#define DO_PTEX (IND & I810_PTEX_BIT)
+
+#define VERTEX i810Vertex
+#define VERTEX_COLOR i810_color_t
+#define GET_VIEWPORT_MAT() I810_CONTEXT(ctx)->ViewportMatrix.m
+#define GET_TEXSOURCE(n)  n
+#define GET_VERTEX_FORMAT() I810_CONTEXT(ctx)->Setup[I810_CTXREG_VF]
+#define GET_VERTEX_STORE() I810_CONTEXT(ctx)->verts
+#define GET_VERTEX_STRIDE_SHIFT() I810_CONTEXT(ctx)->vertex_stride_shift
+#define GET_UBYTE_COLOR_STORE() &I810_CONTEXT(ctx)->UbyteColor
+#define GET_UBYTE_SPEC_COLOR_STORE() &I810_CONTEXT(ctx)->UbyteSecondaryColor
+#define INVALIDATE_STORED_VERTICES()
+
+#define HAVE_HW_VIEWPORT    0
+#define HAVE_HW_DIVIDE      0
+#define HAVE_RGBA_COLOR     0
+#define HAVE_TINY_VERTICES  1
+#define HAVE_NOTEX_VERTICES 1
+#define HAVE_TEX0_VERTICES  1
+#define HAVE_TEX1_VERTICES  1
+#define HAVE_TEX2_VERTICES  0
+#define HAVE_TEX3_VERTICES  0
+#define HAVE_PTEX_VERTICES  0
+
+#define UNVIEWPORT_VARS  GLfloat h = I810_CONTEXT(ctx)->driDrawable->h
+#define UNVIEWPORT_X(x)  x - SUBPIXEL_X
+#define UNVIEWPORT_Y(y)  - y + h + SUBPIXEL_Y
+#define UNVIEWPORT_Z(z)  z * (float)0xffff
+
+#define PTEX_FALLBACK() FALLBACK(I810_CONTEXT(ctx), I810_FALLBACK_TEXTURE, 1)
+
+#define IMPORT_FLOAT_COLORS i810_import_float_colors
+#define IMPORT_FLOAT_SPEC_COLORS i810_import_float_spec_colors
+
+#define INTERP_VERTEX setup_tab[I810_CONTEXT(ctx)->SetupIndex].interp
+#define COPY_PV_VERTEX setup_tab[I810_CONTEXT(ctx)->SetupIndex].copy_pv
+
+
+/***********************************************************************
+ *         Generate  pv-copying and translation functions              *
+ ***********************************************************************/
+
+#define TAG(x) i810_##x
+#include "tnl_dd/t_dd_vb.c"
+
+/***********************************************************************
+ *             Generate vertex emit and interp functions               *
+ ***********************************************************************/
+
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT)
+#define TAG(x) x##_wg
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT)
+#define TAG(x) x##_wgs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_wgt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_wgt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_PTEX_BIT)
+#define TAG(x) x##_wgpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_wgst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
+             I810_TEX1_BIT)
+#define TAG(x) x##_wgst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
+             I810_PTEX_BIT)
+#define TAG(x) x##_wgspt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT)
+#define TAG(x) x##_wgf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT)
+#define TAG(x) x##_wgfs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_wgft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|\
+             I810_TEX1_BIT)
+#define TAG(x) x##_wgft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|\
+             I810_PTEX_BIT)
+#define TAG(x) x##_wgfpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
+             I810_TEX0_BIT)
+#define TAG(x) x##_wgfst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
+             I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_wgfst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
+             I810_TEX0_BIT|I810_PTEX_BIT)
+#define TAG(x) x##_wgfspt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_TEX0_BIT)
+#define TAG(x) x##_t0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_t0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_FOG_BIT)
+#define TAG(x) x##_f
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_FOG_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_ft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_ft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT)
+#define TAG(x) x##_g
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_SPEC_BIT)
+#define TAG(x) x##_gs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_gt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_gt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_gst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_gst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_FOG_BIT)
+#define TAG(x) x##_gf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT)
+#define TAG(x) x##_gfs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_gft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_gft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_gfst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
+             I810_TEX1_BIT)
+#define TAG(x) x##_gfst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+
+static void init_setup_tab( void )
+{
+   init_wg();
+   init_wgs();
+   init_wgt0();
+   init_wgt0t1();
+   init_wgpt0();
+   init_wgst0();
+   init_wgst0t1();
+   init_wgspt0();
+   init_wgf();
+   init_wgfs();
+   init_wgft0();
+   init_wgft0t1();
+   init_wgfpt0();
+   init_wgfst0();
+   init_wgfst0t1();
+   init_wgfspt0();
+   init_t0();
+   init_t0t1();
+   init_f();
+   init_ft0();
+   init_ft0t1();
+   init_g();
+   init_gs();
+   init_gt0();
+   init_gt0t1();
+   init_gst0();
+   init_gst0t1();
+   init_gf();
+   init_gfs();
+   init_gft0();
+   init_gft0t1();
+   init_gfst0();
+   init_gfst0t1();
+}
+
+
+
+void i810PrintSetupFlags(char *msg, GLuint flags )
+{
+   fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
+          msg,
+          (int)flags,
+          (flags & I810_XYZW_BIT)      ? " xyzw," : "",
+          (flags & I810_RGBA_BIT)     ? " rgba," : "",
+          (flags & I810_SPEC_BIT)     ? " spec," : "",
+          (flags & I810_FOG_BIT)      ? " fog," : "",
+          (flags & I810_TEX0_BIT)     ? " tex-0," : "",
+          (flags & I810_TEX1_BIT)     ? " tex-1," : "");
+}
+
+
+
+void i810CheckTexSizes( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   i810ContextPtr imesa = I810_CONTEXT( ctx );
+
+   if (!setup_tab[imesa->SetupIndex].check_tex_sizes(ctx)) {
+      /* Invalidate stored verts
+       */
+      imesa->SetupNewInputs = ~0;
+      imesa->SetupIndex |= I810_PTEX_BIT;
+
+      if (!imesa->Fallback &&
+         !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
+        tnl->Driver.Render.Interp = setup_tab[imesa->SetupIndex].interp;
+        tnl->Driver.Render.CopyPV = setup_tab[imesa->SetupIndex].copy_pv;
+      }
+      if (imesa->Fallback) {
+         tnl->Driver.Render.Start(ctx);
+      }
+   }
+}
+
+void i810BuildVertices( GLcontext *ctx,
+                       GLuint start,
+                       GLuint count,
+                       GLuint newinputs )
+{
+   i810ContextPtr imesa = I810_CONTEXT( ctx );
+   GLubyte *v = ((GLubyte *)imesa->verts + (start<<imesa->vertex_stride_shift));
+   GLuint stride = 1<<imesa->vertex_stride_shift;
+
+   if (0) fprintf(stderr, "%s\n", __FUNCTION__);
+
+   newinputs |= imesa->SetupNewInputs;
+   imesa->SetupNewInputs = 0;
+
+   if (!newinputs)
+      return;
+
+   if (newinputs & VERT_BIT_CLIP) {
+      setup_tab[imesa->SetupIndex].emit( ctx, start, count, v, stride );
+   } else {
+      GLuint ind = 0;
+
+      if (newinputs & VERT_BIT_COLOR0)
+        ind |= I810_RGBA_BIT;
+
+      if (newinputs & VERT_BIT_COLOR1)
+        ind |= I810_SPEC_BIT;
+
+      if (newinputs & VERT_BIT_TEX0)
+        ind |= I810_TEX0_BIT;
+
+      if (newinputs & VERT_BIT_TEX1)
+        ind |= I810_TEX1_BIT;
+
+      if (newinputs & VERT_BIT_FOG)
+        ind |= I810_FOG_BIT;
+
+      if (imesa->SetupIndex & I810_PTEX_BIT)
+        ind = ~0;
+
+      ind &= imesa->SetupIndex;
+
+      if (ind) {
+        setup_tab[ind].emit( ctx, start, count, v, stride );
+      }
+   }
+}
+
+void i810ChooseVertexState( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   i810ContextPtr imesa = I810_CONTEXT( ctx );
+   GLuint ind = I810_XYZW_BIT|I810_RGBA_BIT;
+
+   if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+      ind |= I810_SPEC_BIT;
+
+   if (ctx->Fog.Enabled)
+      ind |= I810_FOG_BIT;
+
+   if (ctx->Texture._EnabledUnits & 0x2)
+      /* unit 1 enabled */
+      ind |= I810_TEX1_BIT|I810_TEX0_BIT;
+   else if (ctx->Texture._EnabledUnits & 0x1)
+      /* unit 0 enabled */
+      ind |= I810_TEX0_BIT;
+
+   imesa->SetupIndex = ind;
+
+   if (I810_DEBUG & (DEBUG_VERTS|DEBUG_STATE))
+      i810PrintSetupFlags( __FUNCTION__, ind );
+
+   if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
+      tnl->Driver.Render.Interp = i810_interp_extras;
+      tnl->Driver.Render.CopyPV = i810_copy_pv_extras;
+   } else {
+      tnl->Driver.Render.Interp = setup_tab[ind].interp;
+      tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
+   }
+
+   if (setup_tab[ind].vertex_format != imesa->Setup[I810_CTXREG_VF]) {
+      I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+      imesa->Setup[I810_CTXREG_VF] = setup_tab[ind].vertex_format;
+      imesa->vertex_size = setup_tab[ind].vertex_size;
+      imesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift;
+   }
+}
+
+
+
+void i810_emit_contiguous_verts( GLcontext *ctx,
+                                GLuint start,
+                                GLuint count )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   GLuint vertex_size = imesa->vertex_size * 4;
+   GLuint *dest = i810AllocDmaLow( imesa, (count-start) * vertex_size);
+   setup_tab[imesa->SetupIndex].emit( ctx, start, count, dest, vertex_size );
+}
+
+
+
+void i810InitVB( GLcontext *ctx )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   GLuint size = TNL_CONTEXT(ctx)->vb.Size;
+
+   imesa->verts = (GLubyte *)ALIGN_MALLOC(size * 4 * 16, 32);
+
+   {
+      static int firsttime = 1;
+      if (firsttime) {
+        init_setup_tab();
+        firsttime = 0;
+      }
+   }
+}
+
+
+void i810FreeVB( GLcontext *ctx )
+{
+   i810ContextPtr imesa = I810_CONTEXT(ctx);
+   if (imesa->verts) {
+      ALIGN_FREE(imesa->verts);
+      imesa->verts = 0;
+   }
+
+   if (imesa->UbyteSecondaryColor.Ptr) {
+      ALIGN_FREE(imesa->UbyteSecondaryColor.Ptr);
+      imesa->UbyteSecondaryColor.Ptr = 0;
+   }
+
+   if (imesa->UbyteColor.Ptr) {
+      ALIGN_FREE(imesa->UbyteColor.Ptr);
+      imesa->UbyteColor.Ptr = 0;
+   }
+}
diff --git a/src/mesa/drivers/dri/i810/i810vb.h b/src/mesa/drivers/dri/i810/i810vb.h
new file mode 100644 (file)
index 0000000..30e5835
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810vb.h,v 1.4 2002/02/22 21:33:04 dawes Exp $ */
+
+#ifndef I810VB_INC
+#define I810VB_INC
+
+#include "mtypes.h"
+#include "swrast/swrast.h"
+
+#define _I810_NEW_VERTEX (_NEW_TEXTURE |                       \
+                         _DD_NEW_SEPARATE_SPECULAR |           \
+                         _DD_NEW_TRI_UNFILLED |                \
+                         _DD_NEW_TRI_LIGHT_TWOSIDE |           \
+                         _NEW_FOG)
+
+
+extern void i810ChooseVertexState( GLcontext *ctx );
+extern void i810CheckTexSizes( GLcontext *ctx );
+extern void i810BuildVertices( GLcontext *ctx,
+                              GLuint start,
+                              GLuint count,
+                              GLuint newinputs );
+
+
+extern void i810_emit_contiguous_verts( GLcontext *ctx,
+                                       GLuint start,
+                                       GLuint count );
+
+extern void i810_translate_vertex( GLcontext *ctx,
+                                  const i810Vertex *src,
+                                  SWvertex *dst );
+
+extern void i810InitVB( GLcontext *ctx );
+extern void i810FreeVB( GLcontext *ctx );
+
+extern void i810_print_vertex( GLcontext *ctx, const i810Vertex *v );
+extern void i810PrintSetupFlags(char *msg, GLuint flags );
+
+#endif
diff --git a/src/mesa/drivers/dri/i810/server/i810_common.h b/src/mesa/drivers/dri/i810/server/i810_common.h
new file mode 100644 (file)
index 0000000..02e548b
--- /dev/null
@@ -0,0 +1,192 @@
+/* i810_common.h -- common header definitions for I810 2D/3D/DRM suite
+ *
+ * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Converted to common header format:
+ *   Jens Owen <jens@tungstengraphics.com>
+ *
+ * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_common.h,v 1.1 2002/09/11 00:29:31 dawes Exp $
+ *
+ */
+
+/* WARNING: If you change any of these defines, make sure to change
+ * the kernel include file as well (i810_drm.h)
+ */
+
+#ifndef _I810_COMMON_H_
+#define _I810_COMMON_H_
+
+#ifndef _I810_DEFINES_
+#define _I810_DEFINES_
+#define I810_USE_BATCH 1
+
+#define I810_DMA_BUF_ORDER     12
+#define I810_DMA_BUF_SZ        (1<<I810_DMA_BUF_ORDER)
+#define I810_DMA_BUF_NR        256
+
+#define I810_NR_SAREA_CLIPRECTS 8
+
+/* Each region is a minimum of 64k, and there are at most 64 of them.
+ */
+#define I810_NR_TEX_REGIONS 64
+#define I810_LOG_MIN_TEX_REGION_SIZE 16
+
+/* Destbuffer state
+ *    - backbuffer linear offset and pitch -- invarient in the current dri
+ *    - zbuffer linear offset and pitch -- also invarient
+ *    - drawing origin in back and depth buffers.
+ *
+ * Keep the depth/back buffer state here to acommodate private buffers
+ * in the future.
+ */
+#define I810_DESTREG_DI0  0            /* CMD_OP_DESTBUFFER_INFO (2 dwords) */
+#define I810_DESTREG_DI1  1
+#define I810_DESTREG_DV0  2            /* GFX_OP_DESTBUFFER_VARS (2 dwords) */
+#define I810_DESTREG_DV1  3
+#define I810_DESTREG_DR0  4            /* GFX_OP_DRAWRECT_INFO (4 dwords) */
+#define I810_DESTREG_DR1  5
+#define I810_DESTREG_DR2  6
+#define I810_DESTREG_DR3  7
+#define I810_DESTREG_DR4  8
+#define I810_DEST_SETUP_SIZE 10
+
+/* Context state
+ */
+#define I810_CTXREG_CF0   0            /* GFX_OP_COLOR_FACTOR */
+#define I810_CTXREG_CF1   1
+#define I810_CTXREG_ST0   2            /* GFX_OP_STIPPLE */
+#define I810_CTXREG_ST1   3
+#define I810_CTXREG_VF    4            /* GFX_OP_VERTEX_FMT */
+#define I810_CTXREG_MT    5            /* GFX_OP_MAP_TEXELS */
+#define I810_CTXREG_MC0   6            /* GFX_OP_MAP_COLOR_STAGES - stage 0 */
+#define I810_CTXREG_MC1   7            /* GFX_OP_MAP_COLOR_STAGES - stage 1 */
+#define I810_CTXREG_MC2   8            /* GFX_OP_MAP_COLOR_STAGES - stage 2 */
+#define I810_CTXREG_MA0   9            /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */
+#define I810_CTXREG_MA1   10           /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */
+#define I810_CTXREG_MA2   11           /* GFX_OP_MAP_ALPHA_STAGES - stage 2 */
+#define I810_CTXREG_SDM   12           /* GFX_OP_SRC_DEST_MONO */
+#define I810_CTXREG_FOG   13           /* GFX_OP_FOG_COLOR */
+#define I810_CTXREG_B1    14           /* GFX_OP_BOOL_1 */
+#define I810_CTXREG_B2    15           /* GFX_OP_BOOL_2 */
+#define I810_CTXREG_LCS   16           /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */
+#define I810_CTXREG_PV    17           /* GFX_OP_PV_RULE -- Invarient! */
+#define I810_CTXREG_ZA    18           /* GFX_OP_ZBIAS_ALPHAFUNC */
+#define I810_CTXREG_AA    19           /* GFX_OP_ANTIALIAS */
+#define I810_CTX_SETUP_SIZE 20
+
+/* Texture state (per tex unit)
+ */
+#define I810_TEXREG_MI0  0             /* GFX_OP_MAP_INFO (4 dwords) */
+#define I810_TEXREG_MI1  1
+#define I810_TEXREG_MI2  2
+#define I810_TEXREG_MI3  3
+#define I810_TEXREG_MF   4             /* GFX_OP_MAP_FILTER */
+#define I810_TEXREG_MLC  5             /* GFX_OP_MAP_LOD_CTL */
+#define I810_TEXREG_MLL  6             /* GFX_OP_MAP_LOD_LIMITS */
+#define I810_TEXREG_MCS  7             /* GFX_OP_MAP_COORD_SETS ??? */
+#define I810_TEX_SETUP_SIZE 8
+
+/* Driver specific DRM command indices
+ * NOTE: these are not OS specific, but they are driver specific
+ */
+#define DRM_I810_INIT                     0x00
+#define DRM_I810_VERTEX                   0x01
+#define DRM_I810_CLEAR                    0x02
+#define DRM_I810_FLUSH                    0x03
+#define DRM_I810_GETAGE                   0x04
+#define DRM_I810_GETBUF                   0x05
+#define DRM_I810_SWAP                     0x06
+#define DRM_I810_COPY                     0x07
+#define DRM_I810_DOCOPY                   0x08
+#define DRM_I810_OV0INFO                  0x09
+#define DRM_I810_FSTATUS                  0x0a
+#define DRM_I810_OV0FLIP                  0x0b
+#define DRM_I810_MC                       0x0c
+#define DRM_I810_RSTATUS                  0x0d
+#define DRM_I810_FLIP                     0x0e
+
+#endif
+
+typedef enum _drmI810Initfunc {
+       I810_INIT_DMA = 0x01,
+       I810_CLEANUP_DMA = 0x02,
+       I810_INIT_DMA_1_4 = 0x03
+} drmI810Initfunc;
+
+typedef struct {
+   drmI810Initfunc func;
+   unsigned int mmio_offset;
+   unsigned int buffers_offset;
+   int sarea_priv_offset;
+   unsigned int ring_start;
+   unsigned int ring_end;
+   unsigned int ring_size;
+   unsigned int front_offset;
+   unsigned int back_offset;
+   unsigned int depth_offset;
+   unsigned int overlay_offset;
+   unsigned int overlay_physical;
+   unsigned int w;
+   unsigned int h;
+   unsigned int pitch;
+   unsigned int pitch_bits;
+} drmI810Init;
+
+typedef struct {
+   void *virtual;
+   int request_idx;
+   int request_size;
+   int granted;
+} drmI810DMA;
+
+/* Flags for clear ioctl
+ */
+#define I810_FRONT   0x1
+#define I810_BACK    0x2
+#define I810_DEPTH   0x4
+
+typedef struct {
+   int clear_color;
+   int clear_depth;
+   int flags;
+} drmI810Clear;
+
+typedef struct {
+   int idx;                            /* buffer index */
+   int used;                           /* nr bytes in use */
+   int discard;                                /* client is finished with the buffer? */
+} drmI810Vertex;
+
+/* Flags for vertex ioctl
+ */
+#define PR_TRIANGLES         (0x0<<18)
+#define PR_TRISTRIP_0        (0x1<<18)
+#define PR_TRISTRIP_1        (0x2<<18)
+#define PR_TRIFAN            (0x3<<18)
+#define PR_POLYGON           (0x4<<18)
+#define PR_LINES             (0x5<<18)
+#define PR_LINESTRIP         (0x6<<18)
+#define PR_RECTS             (0x7<<18)
+#define PR_MASK              (0x7<<18)
+
+#endif
diff --git a/src/mesa/drivers/dri/i810/server/i810_dri.h b/src/mesa/drivers/dri/i810/server/i810_dri.h
new file mode 100644 (file)
index 0000000..cfca20a
--- /dev/null
@@ -0,0 +1,129 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h,v 1.10 2002/12/10 01:27:04 dawes Exp $ */
+
+#ifndef _I810_DRI_
+#define _I810_DRI_
+
+#include "xf86drm.h"
+#include "i810_common.h"
+
+#define I810_MAX_DRAWABLES 256
+
+typedef struct {
+   drmHandle regs;
+   drmSize regsSize;
+   drmAddress regsMap;
+
+   drmSize backbufferSize;
+   drmHandle backbuffer;
+
+   drmSize depthbufferSize;
+   drmHandle depthbuffer;
+
+   drmHandle textures;
+   int textureSize;
+
+   drmHandle agp_buffers;
+   drmSize agp_buf_size;
+
+   int deviceID;
+   int width;
+   int height;
+   int mem;
+   int cpp;
+   int bitsPerPixel;
+   int fbOffset;
+   int fbStride;
+
+   int backOffset;
+   int depthOffset;
+
+   int auxPitch;
+   int auxPitchBits;
+
+   int logTextureGranularity;
+   int textureOffset;
+
+   /* For non-dma direct rendering.
+    */
+   int ringOffset;
+   int ringSize;
+
+   drmBufMapPtr drmBufs;
+   int irq;
+   unsigned int sarea_priv_offset;
+
+} I810DRIRec, *I810DRIPtr;
+
+/* WARNING: Do not change the SAREA structure without changing the kernel
+ * as well */
+
+#define I810_UPLOAD_TEX0IMAGE  0x1     /* handled clientside */
+#define I810_UPLOAD_TEX1IMAGE  0x2     /* handled clientside */
+#define I810_UPLOAD_CTX        0x4
+#define I810_UPLOAD_BUFFERS    0x8
+#define I810_UPLOAD_TEX0       0x10
+#define I810_UPLOAD_TEX1       0x20
+#define I810_UPLOAD_CLIPRECTS  0x40
+
+typedef struct {
+   unsigned char next, prev;           /* indices to form a circular LRU  */
+   unsigned char in_use;               /* owned by a client, or free? */
+   int age;                            /* tracked by clients to update local LRU's */
+} I810TexRegionRec, *I810TexRegionPtr;
+
+typedef struct {
+   unsigned int ContextState[I810_CTX_SETUP_SIZE];
+   unsigned int BufferState[I810_DEST_SETUP_SIZE];
+   unsigned int TexState[2][I810_TEX_SETUP_SIZE];
+   unsigned int dirty;
+
+   unsigned int nbox;
+   XF86DRIClipRectRec boxes[I810_NR_SAREA_CLIPRECTS];
+
+   /* Maintain an LRU of contiguous regions of texture space.  If
+    * you think you own a region of texture memory, and it has an
+    * age different to the one you set, then you are mistaken and
+    * it has been stolen by another client.  If global texAge
+    * hasn't changed, there is no need to walk the list.
+    *
+    * These regions can be used as a proxy for the fine-grained
+    * texture information of other clients - by maintaining them
+    * in the same lru which is used to age their own textures,
+    * clients have an approximate lru for the whole of global
+    * texture space, and can make informed decisions as to which
+    * areas to kick out.  There is no need to choose whether to
+    * kick out your own texture or someone else's - simply eject
+    * them all in LRU order.
+    */
+   drmTextureRegion texList[I810_NR_TEX_REGIONS + 1];
+
+   /* Last elt is sentinal */
+   int texAge;                         /* last time texture was uploaded */
+
+   int last_enqueue;                   /* last time a buffer was enqueued */
+   int last_dispatch;                  /* age of the most recently dispatched buffer */
+   int last_quiescent;                 /*  */
+
+   int ctxOwner;                       /* last context to upload state */
+
+   int vertex_prim;
+
+   int pf_enabled;                  /* is pageflipping allowed? */
+   int pf_active;                   /* is pageflipping active right now? */
+   int pf_current_page;            /* which buffer is being displayed? */
+
+
+} I810SAREARec, *I810SAREAPtr;
+
+typedef struct {
+   /* Nothing here yet */
+   int dummy;
+} I810ConfigPrivRec, *I810ConfigPrivPtr;
+
+typedef struct {
+   /* Nothing here yet */
+   int dummy;
+} I810DRIContextRec, *I810DRIContextPtr;
+
+#endif
diff --git a/src/mesa/drivers/dri/i810/server/i810_reg.h b/src/mesa/drivers/dri/i810/server/i810_reg.h
new file mode 100644 (file)
index 0000000..c935982
--- /dev/null
@@ -0,0 +1,992 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_reg.h,v 1.13 2003/02/06 04:18:04 dawes Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ *
+ *   based on the i740 driver by
+ *        Kevin E. Martin <kevin@precisioninsight.com> 
+ *   
+ *
+ */
+
+#ifndef _I810_REG_H
+#define _I810_REG_H
+
+/* I/O register offsets
+ */
+#define SRX 0x3C4              /* p208 */
+#define GRX 0x3CE              /* p213 */
+#define ARX 0x3C0              /* p224 */
+
+/* VGA Color Palette Registers */
+#define DACMASK  0x3C6         /* p232 */
+#define DACSTATE 0x3C7         /* p232 */
+#define DACRX    0x3C7         /* p233 */
+#define DACWX    0x3C8         /* p233 */
+#define DACDATA  0x3C9         /* p233 */
+
+/* CRT Controller Registers (CRX) */
+#define START_ADDR_HI        0x0C /* p246 */
+#define START_ADDR_LO        0x0D /* p247 */
+#define VERT_SYNC_END        0x11 /* p249 */
+#define EXT_VERT_TOTAL       0x30 /* p257 */
+#define EXT_VERT_DISPLAY     0x31 /* p258 */
+#define EXT_VERT_SYNC_START  0x32 /* p259 */
+#define EXT_VERT_BLANK_START 0x33 /* p260 */
+#define EXT_HORIZ_TOTAL      0x35 /* p261 */
+#define EXT_HORIZ_BLANK      0x39 /* p261 */
+#define EXT_START_ADDR       0x40 /* p262 */
+#define EXT_START_ADDR_ENABLE    0x80 
+#define EXT_OFFSET           0x41 /* p263 */
+#define EXT_START_ADDR_HI    0x42 /* p263 */
+#define INTERLACE_CNTL       0x70 /* p264 */
+#define INTERLACE_ENABLE         0x80 
+#define INTERLACE_DISABLE        0x00 
+
+/* Miscellaneous Output Register 
+ */
+#define MSR_R          0x3CC   /* p207 */
+#define MSR_W          0x3C2   /* p207 */
+#define IO_ADDR_SELECT     0x01
+
+#define MDA_BASE       0x3B0   /* p207 */
+#define CGA_BASE       0x3D0   /* p207 */
+
+/* CR80 - IO Control, p264
+ */
+#define IO_CTNL            0x80
+#define EXTENDED_ATTR_CNTL     0x02
+#define EXTENDED_CRTC_CNTL     0x01
+
+/* GR10 - Address mapping, p221
+ */
+#define ADDRESS_MAPPING    0x10
+#define PAGE_TO_LOCAL_MEM_ENABLE 0x10
+#define GTT_MEM_MAP_ENABLE     0x08
+#define PACKED_MODE_ENABLE     0x04
+#define LINEAR_MODE_ENABLE     0x02
+#define PAGE_MAPPING_ENABLE    0x01
+
+/* Blitter control, p378
+ */
+#define BITBLT_CNTL        0x7000c
+#define COLEXP_MODE            0x30
+#define COLEXP_8BPP            0x00
+#define COLEXP_16BPP           0x10
+#define COLEXP_24BPP           0x20
+#define COLEXP_RESERVED        0x30
+#define BITBLT_STATUS          0x01
+
+/* p375. 
+ */
+#define DISPLAY_CNTL       0x70008
+#define VGA_WRAP_MODE          0x02
+#define VGA_WRAP_AT_256KB      0x00
+#define VGA_NO_WRAP            0x02
+#define GUI_MODE               0x01
+#define STANDARD_VGA_MODE      0x00
+#define HIRES_MODE             0x01
+
+/* p375
+ */
+#define PIXPIPE_CONFIG_0   0x70009
+#define DAC_8_BIT              0x80
+#define DAC_6_BIT              0x00
+#define HW_CURSOR_ENABLE       0x10
+#define EXTENDED_PALETTE       0x01
+
+/* p375
+ */
+#define PIXPIPE_CONFIG_1   0x7000a
+#define DISPLAY_COLOR_MODE     0x0F
+#define DISPLAY_VGA_MODE       0x00
+#define DISPLAY_8BPP_MODE      0x02
+#define DISPLAY_15BPP_MODE     0x04
+#define DISPLAY_16BPP_MODE     0x05
+#define DISPLAY_24BPP_MODE     0x06
+#define DISPLAY_32BPP_MODE     0x07
+
+/* p375
+ */
+#define PIXPIPE_CONFIG_2   0x7000b
+#define DISPLAY_GAMMA_ENABLE   0x08
+#define DISPLAY_GAMMA_DISABLE  0x00
+#define OVERLAY_GAMMA_ENABLE   0x04
+#define OVERLAY_GAMMA_DISABLE  0x00
+
+
+/* p380
+ */
+#define DISPLAY_BASE       0x70020
+#define DISPLAY_BASE_MASK  0x03fffffc
+
+
+/* Cursor control registers, pp383-384
+ */
+/* Desktop (845G, 865G) */
+#define CURSOR_CONTROL     0x70080
+#define CURSOR_ENABLE          0x80000000
+#define CURSOR_GAMMA_ENABLE    0x40000000
+#define CURSOR_STRIDE_MASK     0x30000000
+#define CURSOR_FORMAT_SHIFT    24
+#define CURSOR_FORMAT_MASK     (0x07 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_2C       (0x00 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_3C       (0x01 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_4C       (0x02 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_ARGB     (0x04 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_XRGB     (0x05 << CURSOR_FORMAT_SHIFT)
+
+/* Mobile and i810 */
+#define CURSOR_A_CONTROL   CURSOR_CONTROL
+#define CURSOR_ORIGIN_SCREEN   0x00    /* i810 only */
+#define CURSOR_ORIGIN_DISPLAY  0x1     /* i810 only */
+#define CURSOR_MODE            0x27
+#define CURSOR_MODE_DISABLE    0x00
+#define CURSOR_MODE_32_4C_AX   0x01    /* i810 only */
+#define CURSOR_MODE_64_3C      0x04
+#define CURSOR_MODE_64_4C_AX   0x05
+#define CURSOR_MODE_64_4C      0x06
+#define CURSOR_MODE_64_32B_AX  0x07
+#define CURSOR_MODE_64_ARGB_AX (0x20 | CURSOR_MODE_64_32B_AX)
+#define MCURSOR_PIPE_SELECT    (1 << 28)
+#define MCURSOR_PIPE_A         0x00
+#define MCURSOR_PIPE_B         (1 << 28)
+#define MCURSOR_GAMMA_ENABLE   (1 << 26)
+#define MCURSOR_MEM_TYPE_LOCAL (1 << 25)
+
+
+#define CURSOR_BASEADDR    0x70084
+#define CURSOR_A_BASE      CURSOR_BASEADDR
+#define CURSOR_BASEADDR_MASK 0x1FFFFF00
+#define CURSOR_A_POSITION  0x70088
+#define CURSOR_POS_SIGN        0x8000
+#define CURSOR_POS_MASK        0x007FF
+#define CURSOR_X_SHIFT        0
+#define CURSOR_Y_SHIFT         16
+#define CURSOR_X_LO        0x70088
+#define CURSOR_X_HI        0x70089
+#define CURSOR_X_POS           0x00
+#define CURSOR_X_NEG           0x80
+#define CURSOR_Y_LO        0x7008A
+#define CURSOR_Y_HI        0x7008B
+#define CURSOR_Y_POS           0x00
+#define CURSOR_Y_NEG           0x80
+
+#define CURSOR_A_PALETTE0  0x70090
+#define CURSOR_A_PALETTE1  0x70094
+#define CURSOR_A_PALETTE2  0x70098
+#define CURSOR_A_PALETTE3  0x7009C
+
+#define CURSOR_SIZE       0x700A0
+#define CURSOR_SIZE_MASK       0x3FF
+#define CURSOR_SIZE_HSHIFT     0
+#define CURSOR_SIZE_VSHIFT     12
+
+
+/* Similar registers exist in Device 0 on the i810 (pp55-65), but I'm
+ * not sure they refer to local (graphics) memory.
+ *
+ * These details are for the local memory control registers,
+ * (pp301-310).  The test machines are not equiped with local memory,
+ * so nothing is tested.  Only a single row seems to be supported.
+ */
+#define DRAM_ROW_TYPE      0x3000
+#define DRAM_ROW_0             0x01
+#define DRAM_ROW_0_SDRAM       0x01
+#define DRAM_ROW_0_EMPTY       0x00
+#define DRAM_ROW_CNTL_LO   0x3001
+#define DRAM_PAGE_MODE_CTRL    0x10
+#define DRAM_RAS_TO_CAS_OVRIDE 0x08
+#define DRAM_CAS_LATENCY       0x04
+#define DRAM_RAS_TIMING        0x02
+#define DRAM_RAS_PRECHARGE     0x01
+#define DRAM_ROW_CNTL_HI   0x3002
+#define DRAM_REFRESH_RATE      0x18
+#define DRAM_REFRESH_DISABLE   0x00
+#define DRAM_REFRESH_60HZ      0x08
+#define DRAM_REFRESH_FAST_TEST 0x10
+#define DRAM_REFRESH_RESERVED  0x18
+#define DRAM_SMS               0x07
+#define DRAM_SMS_NORMAL        0x00
+#define DRAM_SMS_NOP_ENABLE    0x01
+#define DRAM_SMS_ABPCE         0x02
+#define DRAM_SMS_MRCE          0x03
+#define DRAM_SMS_CBRCE         0x04
+
+/* p307
+ */
+#define DPMS_SYNC_SELECT   0x5002
+#define VSYNC_CNTL             0x08
+#define VSYNC_ON               0x00
+#define VSYNC_OFF              0x08
+#define HSYNC_CNTL             0x02
+#define HSYNC_ON               0x00
+#define HSYNC_OFF              0x02
+
+
+
+/* p317, 319
+ */
+#define VCLK2_VCO_M        0x6008 /* treat as 16 bit? (includes msbs) */
+#define VCLK2_VCO_N        0x600a
+#define VCLK2_VCO_DIV_SEL  0x6012
+
+#define VCLK_DIVISOR_VGA0   0x6000
+#define VCLK_DIVISOR_VGA1   0x6004
+#define VCLK_POST_DIV      0x6010
+
+#define POST_DIV_SELECT        0x70
+#define POST_DIV_1             0x00
+#define POST_DIV_2             0x10
+#define POST_DIV_4             0x20
+#define POST_DIV_8             0x30
+#define POST_DIV_16            0x40
+#define POST_DIV_32            0x50
+#define VCO_LOOP_DIV_BY_4M     0x00
+#define VCO_LOOP_DIV_BY_16M    0x04
+
+
+/* Instruction Parser Mode Register 
+ *    - p281
+ *    - 2 new bits.
+ */
+#define INST_PM                  0x20c0        
+#define AGP_SYNC_PACKET_FLUSH_ENABLE 0x20 /* reserved */
+#define SYNC_PACKET_FLUSH_ENABLE     0x10
+#define TWO_D_INST_DISABLE           0x08
+#define THREE_D_INST_DISABLE         0x04
+#define STATE_VAR_UPDATE_DISABLE     0x02
+#define PAL_STIP_DISABLE             0x01
+
+#define INST_DONE                0x2090
+#define INST_PS                  0x20c4
+
+#define MEMMODE                  0x20dc
+
+
+/* Instruction parser error register.  p279
+ */
+#define IPEIR                  0x2088
+#define IPEHR                  0x208C
+
+
+/* General error reporting regs, p296
+ */
+#define EIR               0x20B0
+#define EMR               0x20B4
+#define ESR               0x20B8
+#define IP_ERR                    0x0001
+#define ERROR_RESERVED            0xffc6
+
+
+/* Interrupt Control Registers 
+ *   - new bits for i810
+ *   - new register hwstam (mask)
+ */
+#define HWSTAM               0x2098 /* p290 */
+#define IER                  0x20a0 /* p291 */
+#define IIR                  0x20a4 /* p292 */
+#define IMR                  0x20a8 /* p293 */
+#define ISR                  0x20ac /* p294 */
+#define HW_ERROR                 0x8000
+#define SYNC_STATUS_TOGGLE       0x1000
+#define DPY_0_FLIP_PENDING       0x0800
+#define DPY_1_FLIP_PENDING       0x0400        /* not implemented on i810 */
+#define OVL_0_FLIP_PENDING       0x0200
+#define OVL_1_FLIP_PENDING       0x0100        /* not implemented on i810 */
+#define DPY_0_VBLANK             0x0080
+#define DPY_0_EVENT              0x0040
+#define DPY_1_VBLANK             0x0020        /* not implemented on i810 */
+#define DPY_1_EVENT              0x0010        /* not implemented on i810 */
+#define HOST_PORT_EVENT          0x0008        /*  */
+#define CAPTURE_EVENT            0x0004        /*  */
+#define USER_DEFINED             0x0002
+#define BREAKPOINT               0x0001
+
+
+#define INTR_RESERVED            (0x6000 |             \
+                                 DPY_1_FLIP_PENDING |  \
+                                 OVL_1_FLIP_PENDING |  \
+                                 DPY_1_VBLANK |        \
+                                 DPY_1_EVENT |         \
+                                 HOST_PORT_EVENT |     \
+                                 CAPTURE_EVENT )
+
+/* FIFO Watermark and Burst Length Control Register 
+ *
+ * - different offset and contents on i810 (p299) (fewer bits per field)
+ * - some overlay fields added
+ * - what does it all mean?
+ */
+#define FWATER_BLC       0x20d8
+#define FWATER_BLC2     0x20dc
+#define MM_BURST_LENGTH     0x00700000
+#define MM_FIFO_WATERMARK   0x0001F000
+#define LM_BURST_LENGTH     0x00000700
+#define LM_FIFO_WATERMARK   0x0000001F
+
+
+/* Fence/Tiling ranges [0..7]
+ */
+#define FENCE            0x2000
+#define FENCE_NR         8
+
+#define I830_FENCE_START_MASK  0x07f80000
+
+#define FENCE_START_MASK    0x03F80000
+#define FENCE_X_MAJOR       0x00000000
+#define FENCE_Y_MAJOR       0x00001000
+#define FENCE_SIZE_MASK     0x00000700
+#define FENCE_SIZE_512K     0x00000000
+#define FENCE_SIZE_1M       0x00000100
+#define FENCE_SIZE_2M       0x00000200
+#define FENCE_SIZE_4M       0x00000300
+#define FENCE_SIZE_8M       0x00000400
+#define FENCE_SIZE_16M      0x00000500
+#define FENCE_SIZE_32M      0x00000600
+#define FENCE_SIZE_64M     0x00000700
+#define FENCE_PITCH_MASK    0x00000070
+#define FENCE_PITCH_1       0x00000000
+#define FENCE_PITCH_2       0x00000010
+#define FENCE_PITCH_4       0x00000020
+#define FENCE_PITCH_8       0x00000030
+#define FENCE_PITCH_16      0x00000040
+#define FENCE_PITCH_32      0x00000050
+#define FENCE_PITCH_64     0x00000060
+#define FENCE_VALID         0x00000001
+
+
+/* Registers to control page table, p274
+ */
+#define PGETBL_CTL       0x2020
+#define PGETBL_ADDR_MASK    0xFFFFF000
+#define PGETBL_ENABLE_MASK  0x00000001
+#define PGETBL_ENABLED      0x00000001
+
+/* Register containing pge table error results, p276
+ */
+#define PGE_ERR          0x2024
+#define PGE_ERR_ADDR_MASK   0xFFFFF000
+#define PGE_ERR_ID_MASK     0x00000038
+#define PGE_ERR_CAPTURE     0x00000000
+#define PGE_ERR_OVERLAY     0x00000008
+#define PGE_ERR_DISPLAY     0x00000010
+#define PGE_ERR_HOST        0x00000018
+#define PGE_ERR_RENDER      0x00000020
+#define PGE_ERR_BLITTER     0x00000028
+#define PGE_ERR_MAPPING     0x00000030
+#define PGE_ERR_CMD_PARSER  0x00000038
+#define PGE_ERR_TYPE_MASK   0x00000007
+#define PGE_ERR_INV_TABLE   0x00000000
+#define PGE_ERR_INV_PTE     0x00000001
+#define PGE_ERR_MIXED_TYPES 0x00000002
+#define PGE_ERR_PAGE_MISS   0x00000003
+#define PGE_ERR_ILLEGAL_TRX 0x00000004
+#define PGE_ERR_LOCAL_MEM   0x00000005
+#define PGE_ERR_TILED       0x00000006
+
+
+
+/* Page table entries loaded via mmio region, p323
+ */
+#define PTE_BASE         0x10000
+#define PTE_ADDR_MASK       0x3FFFF000
+#define PTE_TYPE_MASK       0x00000006
+#define PTE_LOCAL           0x00000002
+#define PTE_MAIN_UNCACHED   0x00000000
+#define PTE_MAIN_CACHED     0x00000006
+#define PTE_VALID_MASK      0x00000001
+#define PTE_VALID           0x00000001
+
+
+/* Ring buffer registers, p277, overview p19
+ */
+#define LP_RING     0x2030
+#define HP_RING     0x2040
+
+#define RING_TAIL      0x00
+#define TAIL_ADDR           0x000FFFF8
+#define I830_TAIL_MASK     0x001FFFF8
+
+#define RING_HEAD      0x04
+#define HEAD_WRAP_COUNT     0xFFE00000
+#define HEAD_WRAP_ONE       0x00200000
+#define HEAD_ADDR           0x001FFFFC
+#define I830_HEAD_MASK      0x001FFFFC
+
+#define RING_START     0x08
+#define START_ADDR          0x00FFFFF8
+#define I830_RING_START_MASK   0xFFFFF000
+
+#define RING_LEN       0x0C
+#define RING_NR_PAGES       0x000FF000 
+#define I830_RING_NR_PAGES     0x001FF000
+#define RING_REPORT_MASK    0x00000006
+#define RING_REPORT_64K     0x00000002
+#define RING_REPORT_128K    0x00000004
+#define RING_NO_REPORT      0x00000000
+#define RING_VALID_MASK     0x00000001
+#define RING_VALID          0x00000001
+#define RING_INVALID        0x00000000
+
+
+
+/* BitBlt Instructions
+ *
+ * There are many more masks & ranges yet to add.
+ */
+#define BR00_BITBLT_CLIENT   0x40000000
+#define BR00_OP_COLOR_BLT    0x10000000
+#define BR00_OP_SRC_COPY_BLT 0x10C00000
+#define BR00_OP_FULL_BLT     0x11400000
+#define BR00_OP_MONO_SRC_BLT 0x11800000
+#define BR00_OP_MONO_SRC_COPY_BLT 0x11000000
+#define BR00_OP_MONO_PAT_BLT 0x11C00000
+#define BR00_OP_MONO_SRC_COPY_IMMEDIATE_BLT (0x61 << 22)
+#define BR00_OP_TEXT_IMMEDIATE_BLT 0xc000000
+
+
+#define BR00_TPCY_DISABLE    0x00000000
+#define BR00_TPCY_ENABLE     0x00000010
+
+#define BR00_TPCY_ROP        0x00000000
+#define BR00_TPCY_NO_ROP     0x00000020
+#define BR00_TPCY_EQ         0x00000000
+#define BR00_TPCY_NOT_EQ     0x00000040
+
+#define BR00_PAT_MSB_FIRST   0x00000000        /* ? */
+
+#define BR00_PAT_VERT_ALIGN  0x000000e0
+
+#define BR00_LENGTH          0x0000000F
+
+#define BR09_DEST_ADDR       0x03FFFFFF
+
+#define BR11_SOURCE_PITCH    0x00003FFF
+
+#define BR12_SOURCE_ADDR     0x03FFFFFF
+
+#define BR13_SOLID_PATTERN   0x80000000
+#define BR13_RIGHT_TO_LEFT   0x40000000
+#define BR13_LEFT_TO_RIGHT   0x00000000
+#define BR13_MONO_TRANSPCY   0x20000000
+#define BR13_USE_DYN_DEPTH   0x04000000
+#define BR13_DYN_8BPP        0x00000000
+#define BR13_DYN_16BPP       0x01000000
+#define BR13_DYN_24BPP       0x02000000
+#define BR13_ROP_MASK        0x00FF0000
+#define BR13_DEST_PITCH      0x0000FFFF
+#define BR13_PITCH_SIGN_BIT  0x00008000
+
+#define BR14_DEST_HEIGHT     0xFFFF0000
+#define BR14_DEST_WIDTH      0x0000FFFF
+
+#define BR15_PATTERN_ADDR    0x03FFFFFF
+
+#define BR16_SOLID_PAT_COLOR 0x00FFFFFF
+#define BR16_BACKGND_PAT_CLR 0x00FFFFFF
+
+#define BR17_FGND_PAT_CLR    0x00FFFFFF
+
+#define BR18_SRC_BGND_CLR    0x00FFFFFF
+#define BR19_SRC_FGND_CLR    0x00FFFFFF
+
+
+/* Instruction parser instructions
+ */
+
+#define INST_PARSER_CLIENT   0x00000000
+#define INST_OP_FLUSH        0x02000000
+#define INST_FLUSH_MAP_CACHE 0x00000001
+
+
+#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
+
+
+/* Registers in the i810 host-pci bridge pci config space which affect
+ * the i810 graphics operations.  
+ */
+#define SMRAM_MISCC         0x70
+#define GMS                    0x000000c0
+#define GMS_DISABLE            0x00000000
+#define GMS_ENABLE_BARE        0x00000040
+#define GMS_ENABLE_512K        0x00000080
+#define GMS_ENABLE_1M          0x000000c0
+#define USMM                   0x00000030 
+#define USMM_DISABLE           0x00000000
+#define USMM_TSEG_ZERO         0x00000010
+#define USMM_TSEG_512K         0x00000020
+#define USMM_TSEG_1M           0x00000030  
+#define GFX_MEM_WIN_SIZE       0x00010000
+#define GFX_MEM_WIN_32M        0x00010000
+#define GFX_MEM_WIN_64M        0x00000000
+
+/* Overkill?  I don't know.  Need to figure out top of mem to make the
+ * SMRAM calculations come out.  Linux seems to have problems
+ * detecting it all on its own, so this seems a reasonable double
+ * check to any user supplied 'mem=...' boot param.
+ *
+ * ... unfortunately this reg doesn't work according to spec on the
+ * test hardware.
+ */
+#define WHTCFG_PAMR_DRP      0x50
+#define SYS_DRAM_ROW_0_SHIFT    16
+#define SYS_DRAM_ROW_1_SHIFT    20
+#define DRAM_MASK           0x0f
+#define DRAM_VALUE_0        0
+#define DRAM_VALUE_1        8
+/* No 2 value defined */
+#define DRAM_VALUE_3        16
+#define DRAM_VALUE_4        16
+#define DRAM_VALUE_5        24
+#define DRAM_VALUE_6        32
+#define DRAM_VALUE_7        32
+#define DRAM_VALUE_8        48
+#define DRAM_VALUE_9        64
+#define DRAM_VALUE_A        64
+#define DRAM_VALUE_B        96
+#define DRAM_VALUE_C        128
+#define DRAM_VALUE_D        128
+#define DRAM_VALUE_E        192
+#define DRAM_VALUE_F        256        /* nice one, geezer */
+#define LM_FREQ_MASK        0x10
+#define LM_FREQ_133         0x10
+#define LM_FREQ_100         0x00
+
+
+
+
+/* These are 3d state registers, but the state is invarient, so we let
+ * the X server handle it:
+ */
+
+
+
+/* GFXRENDERSTATE_COLOR_CHROMA_KEY, p135
+ */
+#define GFX_OP_COLOR_CHROMA_KEY  ((0x3<<29)|(0x1d<<24)|(0x2<<16)|0x1)
+#define CC1_UPDATE_KILL_WRITE    (1<<28)
+#define CC1_ENABLE_KILL_WRITE    (1<<27)
+#define CC1_DISABLE_KILL_WRITE    0
+#define CC1_UPDATE_COLOR_IDX     (1<<26)
+#define CC1_UPDATE_CHROMA_LOW    (1<<25)
+#define CC1_UPDATE_CHROMA_HI     (1<<24)
+#define CC1_CHROMA_LOW_MASK      ((1<<24)-1)
+#define CC2_COLOR_IDX_SHIFT      24
+#define CC2_COLOR_IDX_MASK       (0xff<<24)
+#define CC2_CHROMA_HI_MASK       ((1<<24)-1)
+
+
+#define GFX_CMD_CONTEXT_SEL      ((0<<29)|(0x5<<23))
+#define CS_UPDATE_LOAD           (1<<17)
+#define CS_UPDATE_USE            (1<<16)
+#define CS_UPDATE_LOAD           (1<<17)
+#define CS_LOAD_CTX0             0
+#define CS_LOAD_CTX1             (1<<8)
+#define CS_USE_CTX0              0
+#define CS_USE_CTX1              (1<<0)
+
+/* I810 LCD/TV registers */
+#define LCD_TV_HTOTAL  0x60000
+#define LCD_TV_C       0x60018
+#define LCD_TV_OVRACT   0x6001C
+
+#define LCD_TV_ENABLE (1 << 31)
+#define LCD_TV_VGAMOD (1 << 28)
+
+/* I830 CRTC registers */
+#define HTOTAL_A       0x60000
+#define HBLANK_A       0x60004
+#define HSYNC_A        0x60008
+#define VTOTAL_A       0x6000c
+#define VBLANK_A       0x60010
+#define VSYNC_A        0x60014
+#define PIPEASRC       0x6001c
+#define BCLRPAT_A      0x60020
+
+#define HTOTAL_B       0x61000
+#define HBLANK_B       0x61004
+#define HSYNC_B        0x61008
+#define VTOTAL_B       0x6100c
+#define VBLANK_B       0x61010
+#define VSYNC_B        0x61014
+#define PIPEBSRC       0x6101c
+#define BCLRPAT_B      0x61020
+
+#define DPLL_A         0x06014
+#define DPLL_B         0x06018
+#define FPA0           0x06040
+#define FPA1           0x06044
+
+#define I830_HTOTAL_MASK       0xfff0000
+#define I830_HACTIVE_MASK      0x7ff
+
+#define I830_HBLANKEND_MASK    0xfff0000
+#define I830_HBLANKSTART_MASK    0xfff
+
+#define I830_HSYNCEND_MASK     0xfff0000
+#define I830_HSYNCSTART_MASK    0xfff
+
+#define I830_VTOTAL_MASK       0xfff0000
+#define I830_VACTIVE_MASK      0x7ff
+
+#define I830_VBLANKEND_MASK    0xfff0000
+#define I830_VBLANKSTART_MASK    0xfff
+
+#define I830_VSYNCEND_MASK     0xfff0000
+#define I830_VSYNCSTART_MASK    0xfff
+
+#define I830_PIPEA_HORZ_MASK   0x7ff0000
+#define I830_PIPEA_VERT_MASK   0x7ff
+
+#define ADPA                   0x61100
+#define ADPA_DAC_ENABLE        (1<<31)
+#define ADPA_DAC_DISABLE       0
+#define ADPA_PIPE_SELECT_MASK  (1<<30)
+#define ADPA_PIPE_A_SELECT     0
+#define ADPA_PIPE_B_SELECT     (1<<30)
+#define ADPA_USE_VGA_HVPOLARITY (1<<15)
+#define ADPA_SETS_HVPOLARITY   0
+#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
+#define ADPA_VSYNC_CNTL_ENABLE 0
+#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
+#define ADPA_HSYNC_CNTL_ENABLE 0
+#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
+#define ADPA_VSYNC_ACTIVE_LOW  0
+#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
+#define ADPA_HSYNC_ACTIVE_LOW  0
+
+
+#define DVOA                   0x61120
+#define DVOB                   0x61140
+#define DVOC                   0x61160
+#define DVO_ENABLE             (1<<31)
+
+#define DVOA_SRCDIM            0x61124
+#define DVOB_SRCDIM            0x61144
+#define DVOC_SRCDIM            0x61164
+
+#define LVDS                   0x61180
+
+#define PIPEACONF 0x70008
+#define PIPEACONF_ENABLE       (1<<31)
+#define PIPEACONF_DISABLE      0
+#define PIPEACONF_DOUBLE_WIDE  (1<<30)
+#define PIPEACONF_SINGLE_WIDE  0
+#define PIPEACONF_PIPE_UNLOCKED 0
+#define PIPEACONF_PIPE_LOCKED  (1<<25)
+#define PIPEACONF_PALETTE      0
+#define PIPEACONF_GAMMA        (1<<24)
+
+#define PIPEBCONF 0x71008
+#define PIPEBCONF_ENABLE       (1<<31)
+#define PIPEBCONF_DISABLE      0
+#define PIPEBCONF_GAMMA        (1<<24)
+#define PIPEBCONF_PALETTE      0
+
+#define DSPACNTR               0x70180
+#define DSPBCNTR               0x71180
+#define DISPLAY_PLANE_ENABLE                   (1<<31)
+#define DISPLAY_PLANE_DISABLE                  0
+#define DISPPLANE_GAMMA_ENABLE                 (1<<30)
+#define DISPPLANE_GAMMA_DISABLE                        0
+#define DISPPLANE_PIXFORMAT_MASK               (0xf<<26)
+#define DISPPLANE_8BPP                         (0x2<<26)
+#define DISPPLANE_15_16BPP                     (0x4<<26)
+#define DISPPLANE_16BPP                                (0x5<<26)
+#define DISPPLANE_32BPP_NO_ALPHA               (0x6<<26)
+#define DISPPLANE_32BPP                                (0x7<<26)
+#define DISPPLANE_STEREO_ENABLE                        (1<<25)
+#define DISPPLANE_STEREO_DISABLE               0
+#define DISPPLANE_SEL_PIPE_MASK                        (1<<24)
+#define DISPPLANE_SEL_PIPE_A                   0
+#define DISPPLANE_SEL_PIPE_B                   (1<<24)
+#define DISPPLANE_SRC_KEY_ENABLE               (1<<22)
+#define DISPPLANE_SRC_KEY_DISABLE              0
+#define DISPPLANE_LINE_DOUBLE                  (1<<20)
+#define DISPPLANE_NO_LINE_DOUBLE               0
+#define DISPPLANE_STEREO_POLARITY_FIRST                0
+#define DISPPLANE_STEREO_POLARITY_SECOND       (1<<18)
+/* plane B only */
+#define DISPPLANE_ALPHA_TRANS_ENABLE           (1<<15)
+#define DISPPLANE_ALPHA_TRANS_DISABLE          0
+#define DISPPLANE_SPRITE_ABOVE_DISPLAYA                0
+#define DISPPLANE_SPRITE_ABOVE_OVERLAY         (1)
+
+#define DSPABASE               0x70184
+#define DSPASTRIDE             0x70188
+
+#define DSPBBASE               0x71184
+#define DSPBADDR               DSPBBASE
+#define DSPBSTRIDE             0x71188
+
+/* Various masks for reserved bits, etc. */
+#define I830_FWATER1_MASK        (~((1<<11)|(1<<10)|(1<<9)|      \
+        (1<<8)|(1<<26)|(1<<25)|(1<<24)|(1<<5)|(1<<4)|(1<<3)|    \
+        (1<<2)|(1<<1)|1|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)))
+#define I830_FWATER2_MASK ~(0)
+
+#define DV0A_RESERVED ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<16)|(1<<5)|(1<<1)|1)
+#define DV0B_RESERVED ((1<<27)|(1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<16)|(1<<5)|(1<<1)|1)
+#define VGA0_N_DIVISOR_MASK     ((1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16))
+#define VGA0_M1_DIVISOR_MASK    ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8))
+#define VGA0_M2_DIVISOR_MASK    ((1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1)
+#define VGA0_M1M2N_RESERVED    ~(VGA0_N_DIVISOR_MASK|VGA0_M1_DIVISOR_MASK|VGA0_M2_DIVISOR_MASK)
+#define VGA0_POSTDIV_MASK       ((1<<7)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1)
+#define VGA1_POSTDIV_MASK       ((1<<15)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8))
+#define VGA_POSTDIV_RESERVED   ~(VGA0_POSTDIV_MASK|VGA1_POSTDIV_MASK|(1<<7)|(1<<15))
+#define DPLLA_POSTDIV_MASK ((1<<23)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16))
+#define DPLLA_RESERVED     ((1<<27)|(1<<26)|(1<<25)|(1<<24)|(1<<22)|(1<<15)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1)
+#define ADPA_RESERVED  ((1<<2)|(1<<1)|1|(1<<9)|(1<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16))
+#define SUPER_WORD              32
+#define BURST_A_MASK    ((1<<11)|(1<<10)|(1<<9)|(1<<8))
+#define BURST_B_MASK    ((1<<26)|(1<<25)|(1<<24))
+#define WATER_A_MASK    ((1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1)
+#define WATER_B_MASK    ((1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16))
+#define WATER_RESERVED ((1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<23)|(1<<22)|(1<<21)|(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<7)|(1<<6))
+#define PIPEACONF_RESERVED ((1<<29)|(1<<28)|(1<<27)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)|0xffff)
+#define PIPEBCONF_RESERVED ((1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)|0xffff)
+#define DSPACNTR_RESERVED ((1<<23)|(1<<19)|(1<<17)|(1<<16)|0xffff)
+#define DSPBCNTR_RESERVED ((1<<23)|(1<<19)|(1<<17)|(1<<16)|0x7ffe)
+
+#define I830_GMCH_CTRL         0x52
+
+#define I830_GMCH_ENABLED      0x4
+#define I830_GMCH_MEM_MASK     0x1
+#define I830_GMCH_MEM_64M      0x1
+#define I830_GMCH_MEM_128M     0
+
+#define I830_GMCH_GMS_MASK                     0x70
+#define I830_GMCH_GMS_DISABLED         0x00
+#define I830_GMCH_GMS_LOCAL                    0x10
+#define I830_GMCH_GMS_STOLEN_512       0x20
+#define I830_GMCH_GMS_STOLEN_1024      0x30
+#define I830_GMCH_GMS_STOLEN_8192      0x40
+
+#define I830_RDRAM_CHANNEL_TYPE                0x03010
+#define I830_RDRAM_ND(x)                       (((x) & 0x20) >> 5)
+#define I830_RDRAM_DDT(x)                      (((x) & 0x18) >> 3)
+
+#define I855_GMCH_GMS_MASK                     (0x7 << 4)
+#define I855_GMCH_GMS_DISABLED                 0x00
+#define I855_GMCH_GMS_STOLEN_1M                        (0x1 << 4)
+#define I855_GMCH_GMS_STOLEN_4M                        (0x2 << 4)
+#define I855_GMCH_GMS_STOLEN_8M                        (0x3 << 4)
+#define I855_GMCH_GMS_STOLEN_16M               (0x4 << 4)
+#define I855_GMCH_GMS_STOLEN_32M               (0x5 << 4)
+
+#define I85X_CAPID                     0x44
+#define I85X_VARIANT_MASK                      0x7
+#define I85X_VARIANT_SHIFT                     5
+#define I855_GME                               0x0
+#define I855_GM                                        0x4
+#define I852_GME                               0x2
+#define I852_GM                                        0x5
+
+/* BLT commands */
+#define COLOR_BLT_CMD          ((2<<29)|(0x40<<22)|(0x3))
+#define COLOR_BLT_WRITE_ALPHA  (1<<21)
+#define COLOR_BLT_WRITE_RGB    (1<<20)
+
+#define XY_COLOR_BLT_CMD               ((2<<29)|(0x50<<22)|(0x4))
+#define XY_COLOR_BLT_WRITE_ALPHA       (1<<21)
+#define XY_COLOR_BLT_WRITE_RGB         (1<<20)
+
+#define XY_SETUP_CLIP_BLT_CMD          ((2<<29)|(3<<22)|1)
+
+#define XY_SRC_COPY_BLT_CMD            ((2<<29)|(0x53<<22)|6)
+#define XY_SRC_COPY_BLT_WRITE_ALPHA    (1<<21)
+#define XY_SRC_COPY_BLT_WRITE_RGB      (1<<20)
+
+#define SRC_COPY_BLT_CMD               ((2<<29)|(0x43<<22)|0x4)
+#define SRC_COPY_BLT_WRITE_ALPHA       (1<<21)
+#define SRC_COPY_BLT_WRITE_RGB         (1<<20)
+
+#define XY_MONO_PAT_BLT_CMD            ((0x2<<29)|(0x52<<22)|0x7)
+#define XY_MONO_PAT_VERT_SEED          ((1<<10)|(1<<9)|(1<<8))
+#define XY_MONO_PAT_HORT_SEED          ((1<<14)|(1<<13)|(1<<12))
+#define XY_MONO_PAT_BLT_WRITE_ALPHA    (1<<21)
+#define XY_MONO_PAT_BLT_WRITE_RGB      (1<<20)
+
+#define XY_MONO_SRC_BLT_CMD            ((0x2<<29)|(0x54<<22)|(0x6))
+#define XY_MONO_SRC_BLT_WRITE_ALPHA    (1<<21)
+#define XY_MONO_SRC_BLT_WRITE_RGB      (1<<20)
+
+/* 3d state */
+#define STATE3D_FOG_MODE               ((3<<29)|(0x1d<<24)|(0x89<<16)|2)
+#define FOG_MODE_VERTEX                (1<<31)
+#define STATE3D_MAP_COORD_TRANSFORM    ((3<<29)|(0x1d<<24)|(0x8c<<16))
+#define DISABLE_TEX_TRANSFORM          (1<<28)
+#define TEXTURE_SET(x)                 (x<<29)
+#define STATE3D_RASTERIZATION_RULES    ((3<<29)|(0x07<<24))
+#define POINT_RASTER_ENABLE            (1<<15)
+#define POINT_RASTER_OGL               (1<<13)
+#define STATE3D_VERTEX_TRANSFORM       ((3<<29)|(0x1d<<24)|(0x8b<<16))
+#define DISABLE_VIEWPORT_TRANSFORM     (1<<31)
+#define DISABLE_PERSPECTIVE_DIVIDE     (1<<29)
+
+#define MI_SET_CONTEXT                 (0x18<<23)
+#define CTXT_NO_RESTORE                (1)
+#define CTXT_PALETTE_SAVE_DISABLE      (1<<3)
+#define CTXT_PALETTE_RESTORE_DISABLE   (1<<2)
+
+/* Dword 0 */
+#define MI_VERTEX_BUFFER               (0x17<<23)
+#define MI_VERTEX_BUFFER_IDX(x)        (x<<20)
+#define MI_VERTEX_BUFFER_PITCH(x)      (x<<13)
+#define MI_VERTEX_BUFFER_WIDTH(x)      (x<<6)
+/* Dword 1 */
+#define MI_VERTEX_BUFFER_DISABLE       (1)
+
+/* Overlay Flip */
+#define MI_OVERLAY_FLIP                        (0x11<<23)
+#define MI_OVERLAY_FLIP_CONTINUE       (0<<21)
+#define MI_OVERLAY_FLIP_ON             (1<<21)
+#define MI_OVERLAY_FLIP_OFF            (2<<21)
+
+/* Wait for Events */
+#define MI_WAIT_FOR_EVENT              (0x03<<23)
+#define MI_WAIT_FOR_OVERLAY_FLIP       (1<<16)
+
+/* Flush */
+#define MI_FLUSH                       (0x04<<23)
+#define MI_WRITE_DIRTY_STATE           (1<<4)
+#define MI_END_SCENE                   (1<<3)
+#define MI_INHIBIT_RENDER_CACHE_FLUSH  (1<<2)
+#define MI_INVALIDATE_MAP_CACHE                (1<<0)
+
+/* Noop */
+#define MI_NOOP                                0x00
+#define MI_NOOP_WRITE_ID               (1<<22)
+#define MI_NOOP_ID_MASK                        (1<<22 - 1)
+
+#define STATE3D_COLOR_FACTOR   ((0x3<<29)|(0x1d<<24)|(0x01<<16))
+
+/* STATE3D_FOG_MODE stuff */
+#define ENABLE_FOG_SOURCE      (1<<27)
+#define ENABLE_FOG_CONST       (1<<24)
+#define ENABLE_FOG_DENSITY     (1<<23)
+
+
+#define MAX_DISPLAY_PIPES      2
+
+typedef enum {
+   CrtIndex = 0,
+   TvIndex,
+   DfpIndex,
+   LfpIndex,
+   Tv2Index,
+   Dfp2Index,
+   UnknownIndex,
+   Unknown2Index,
+   NumDisplayTypes,
+   NumKnownDisplayTypes = UnknownIndex
+} DisplayType;
+
+/* What's connected to the pipes (as reported by the BIOS) */
+#define PIPE_ACTIVE_MASK               0xff
+#define PIPE_CRT_ACTIVE                        (1 << CrtIndex)
+#define PIPE_TV_ACTIVE                 (1 << TvIndex)
+#define PIPE_DFP_ACTIVE                        (1 << DfpIndex)
+#define PIPE_LCD_ACTIVE                        (1 << LfpIndex)
+#define PIPE_TV2_ACTIVE                        (1 << Tv2Index)
+#define PIPE_DFP2_ACTIVE               (1 << Dfp2Index)
+#define PIPE_UNKNOWN_ACTIVE            ((1 << UnknownIndex) |  \
+                                        (1 << Unknown2Index))
+
+#define PIPE_SIZED_DISP_MASK           (PIPE_DFP_ACTIVE |      \
+                                        PIPE_LCD_ACTIVE |      \
+                                        PIPE_DFP2_ACTIVE)
+
+#define PIPE_A_SHIFT                   0
+#define PIPE_B_SHIFT                   8
+#define PIPE_SHIFT(n)                  ((n) == 0 ? \
+                                        PIPE_A_SHIFT : PIPE_B_SHIFT)
+
+/*
+ * Some BIOS scratch area registers.  The 845 (and 830?) store the amount
+ * of video memory available to the BIOS in SWF1.
+ */
+
+#define SWF0                   0x71410
+#define SWF1                   0x71414
+#define SWF2                   0x71418
+#define SWF3                   0x7141c
+#define SWF4                   0x71420
+#define SWF5                   0x71424
+#define SWF6                   0x71428
+
+/*
+ * 855 scratch registers.
+ */
+#define SWF00                  0x70410
+#define SWF01                  0x70414
+#define SWF02                  0x70418
+#define SWF03                  0x7041c
+#define SWF04                  0x70420
+#define SWF05                  0x70424
+#define SWF06                  0x70428
+
+#define SWF10                  SWF0
+#define SWF11                  SWF1
+#define SWF12                  SWF2
+#define SWF13                  SWF3
+#define SWF14                  SWF4
+#define SWF15                  SWF5
+#define SWF16                  SWF6
+
+#define SWF30                  0x72414
+#define SWF31                  0x72418
+#define SWF32                  0x7241c
+
+/*
+ * Overlay registers.  These are overlay registers accessed via MMIO.
+ * Those loaded via the overlay register page are defined in i830_video.c.
+ */
+#define OVADD                  0x30000
+
+#define DOVSTA                 0x30008
+#define OC_BUF                 (0x3<<20)
+
+#define OGAMC5                 0x30010
+#define OGAMC4                 0x30014
+#define OGAMC3                 0x30018
+#define OGAMC2                 0x3001c
+#define OGAMC1                 0x30020
+#define OGAMC0                 0x30024
+
+
+/*
+ * Palette registers
+ */
+#define PALETTE_A              0x0a000
+#define PALETTE_B              0x0a800
+
+#endif /* _I810_REG_H */