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

26 files changed:
Makefile.X11
src/mesa/drivers/dri/i830/Makefile.X11 [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_3d_reg.h [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_context.c [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_context.h [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_debug.c [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_debug.h [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_ioctl.c [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_ioctl.h [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_render.c [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_screen.c [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_screen.h [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_span.c [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_span.h [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_state.c [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_state.h [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_tex.c [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_tex.h [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_texmem.c [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_texstate.c [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_tris.c [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_tris.h [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_vb.c [new file with mode: 0644]
src/mesa/drivers/dri/i830/i830_vb.h [new file with mode: 0644]
src/mesa/drivers/dri/i830/server/i830_common.h [new file with mode: 0644]
src/mesa/drivers/dri/i830/server/i830_dri.h [new file with mode: 0644]

index e00c1ac..1e432a9 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile.X11,v 1.86 2003/09/30 10:54:15 alanh Exp $
+# $Id: Makefile.X11,v 1.87 2003/09/30 11:02:38 alanh Exp $
 
 # Mesa 3-D graphics library
 # Version:  5.1
@@ -240,6 +240,7 @@ linux-solo:
        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/i830 ] ; then touch src/mesa/drivers/dri/i830/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
@@ -250,6 +251,7 @@ linux-solo:
        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/i830 ] ; then cd src/mesa/drivers/dri/i830       ; $(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/i830/Makefile.X11 b/src/mesa/drivers/dri/i830/Makefile.X11
new file mode 100644 (file)
index 0000000..e690ed6
--- /dev/null
@@ -0,0 +1,117 @@
+# $Id: Makefile.X11,v 1.1 2003/09/30 11:02:39 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 = \
+               i830_context.c \
+               i830_debug.c \
+               i830_ioctl.c \
+               i830_render.c \
+               i830_screen.c \
+               i830_span.c \
+               i830_state.c \
+               i830_tex.c \
+               i830_texmem.c \
+               i830_texstate.c \
+               i830_tris.c \
+               i830_vb.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/i830/i830_3d_reg.h b/src/mesa/drivers/dri/i830/i830_3d_reg.h
new file mode 100644 (file)
index 0000000..eab1092
--- /dev/null
@@ -0,0 +1,675 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_3d_reg.h,v 1.4 2002/12/10 01:26:53 dawes Exp $ */
+#define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
+
+#define CMD_3D (0x3<<29)
+
+/* 3DPRIMITIVE, p104 */
+#define PRIM3D_INLINE          (CMD_3D | (0x1f<<24))
+#define PRIM3D_INDIRECT_SEQ    ((1<<23) | PRIM3D_INLINE)
+#define PRIM3D_INDICES         ((1<<23) | PRIM3D_INLINE | (1<<17))
+
+#define PRIM3D_INLINE_CNT(used)        ((used / 4) - 2)
+#define PRIM3D_INDICES_CNT(num_indices) ((num_indices + 1) / 2)
+#define PRIM3D_INDIRECT_CNT(verts)     (verts)
+
+#define PRIM3D_TRILIST         0
+#define PRIM3D_TRISTRIP        (0x1<<18)
+#define PRIM3D_TRISTRIP_RVRSE  (0x2<<18)
+#define PRIM3D_TRIFAN          (0x3<<18)
+#define PRIM3D_POLY            (0x4<<18)
+#define PRIM3D_LINELIST        (0x5<<18)
+#define PRIM3D_LINESTRIP       (0x6<<18)
+#define PRIM3D_RECTLIST        (0x7<<18)
+#define PRIM3D_POINTLIST       (0x8<<18)
+#define PRIM3D_DIB             (0x9<<18)
+
+/* STATE3D_ANTI_ALIASING, p 123 */
+#define STATE3D_AA_CMD                 (CMD_3D | (0x06<<24))
+
+#define AA_LINE_ECAAR_WIDTH_ENABLE     (1<<16)
+#define AA_LINE_ECAAR_WIDTH_0_5        0
+#define AA_LINE_ECAAR_WIDTH_1_0                (1<<14)
+#define AA_LINE_ECAAR_WIDTH_2_0        (2<<14)
+#define AA_LINE_ECAAR_WIDTH_4_0        (3<<14)
+
+#define AA_LINE_REGION_WIDTH_ENABLE    (1<<8)
+#define AA_LINE_REGION_WIDTH_0_5       0
+#define AA_LINE_REGION_WIDTH_1_0       (1<<6)
+#define AA_LINE_REGION_WIDTH_2_0       (2<<6)
+#define AA_LINE_REGION_WIDTH_4_0       (3<<6)
+
+#define AA_LINE_ENABLE                 ((1<<1) | 1)
+#define AA_LINE_DISABLE                        (1<<1)
+
+/* STATE3D_BUFFER_INFO, p 124 */
+#define STATE3D_BUF_INFO_CMD   (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1)
+/* Dword 1 */
+#define BUF_3D_ID_COLOR_BACK   (0x3<<24)
+#define BUF_3D_ID_DEPTH        (0x7<<24)
+#define BUF_3D_USE_FENCE       (1<<23)
+#define BUF_3D_TILED_SURFACE   (1<<22)
+#define BUF_3D_TILE_WALK_X     0
+#define BUF_3D_TILE_WALK_Y     (1<<21)
+#define BUF_3D_PITCH(x)        ((x)<<2)
+/* Dword 2 */
+#define BUF_3D_ADDR(x)         ((x) & ~0x3)
+
+/* STATE3D_COLOR_FACTOR_0, p127 */
+#define STATE3D_COLOR_FACTOR_CMD(stage)        (CMD_3D | (0x1d<<24) | ((0x90 + (stage))<<16))
+
+/* STATE3D_CONSTANT_BLEND_COLOR, p128 */
+#define STATE3D_CONST_BLEND_COLOR_CMD  (CMD_3D | (0x1d<<24) | (0x88<<16))
+
+/* STATE3D_DEFAULT_DIFFUSE, p128 */
+#define STATE3D_DFLT_DIFFUSE_CMD       (CMD_3D | (0x1d<<24) | (0x99<<16))
+
+/* STATE3D_DEFAULT_SPECULAR, p129 */
+#define STATE3D_DFLT_SPEC_CMD          (CMD_3D | (0x1d<<24) | (0x9a<<16))
+
+/* STATE3D_DEFAULT_Z, p129 */
+#define STATE3D_DFLT_Z_CMD             (CMD_3D | (0x1d<<24) | (0x98<<16))
+
+/* STATE3D_DEST_BUFFER_VARIABLES, p130 */
+#define STATE3D_DST_BUF_VARS_CMD       (CMD_3D | (0x1d<<24) | (0x85<<16))
+/* Dword 1 */
+#define DSTORG_HORT_BIAS(x)            ((x)<<20)
+#define DSTORG_VERT_BIAS(x)            ((x)<<16)
+#define COLOR_4_2_2_CHNL_WRT_ALL       0
+#define COLOR_4_2_2_CHNL_WRT_Y         (1<<12)
+#define COLOR_4_2_2_CHNL_WRT_CR                (2<<12)
+#define COLOR_4_2_2_CHNL_WRT_CB                (3<<12)
+#define COLOR_4_2_2_CHNL_WRT_CRCB      (4<<12)
+#define COLR_BUF_8BIT                  0
+#define COLR_BUF_RGB555                (1<<8)
+#define COLR_BUF_RGB565                (2<<8)
+#define COLR_BUF_ARGB8888              (3<<8)
+#define DEPTH_IS_Z                     0
+#define DEPTH_IS_W                     (1<<6)
+#define DEPTH_FRMT_16_FIXED            0
+#define DEPTH_FRMT_16_FLOAT            (1<<2)
+#define DEPTH_FRMT_24_FIXED_8_OTHER    (2<<2)
+#define DEPTH_FRMT_24_FLOAT_8_OTHER    (3<<2)
+#define VERT_LINE_STRIDE_1             (1<<1)
+#define VERT_LINE_STRIDE_0             0
+#define VERT_LINE_STRIDE_OFS_1         1
+#define VERT_LINE_STRIDE_OFS_0         0
+
+/* STATE3D_DRAWING_RECTANGLE, p133 */
+#define STATE3D_DRAW_RECT_CMD          (CMD_3D|(0x1d<<24)|(0x80<<16)|3)
+/* Dword 1 */
+#define DRAW_RECT_DIS_DEPTH_OFS        (1<<30)
+#define DRAW_DITHER_OFS_X(x)           ((x)<<26)
+#define DRAW_DITHER_OFS_Y(x)           ((x)<<24)
+/* Dword 2 */
+#define DRAW_YMIN(x)                   ((x)<<16)
+#define DRAW_XMIN(x)                   (x)
+/* Dword 3 */
+#define DRAW_YMAX(x)                   ((x)<<16)
+#define DRAW_XMAX(x)                   (x)
+/* Dword 4 */
+#define DRAW_YORG(x)                   ((x)<<16)
+#define DRAW_XORG(x)                   (x)
+
+/* STATE3D_ENABLES_1, p136 */
+#define STATE3D_ENABLES_1_CMD          (CMD_3D|(0x3<<24))
+#define ENABLE_LOGIC_OP_MASK           ((1<<23)|(1<<22))
+#define ENABLE_LOGIC_OP                ((1<<23)|(1<<22))
+#define DISABLE_LOGIC_OP               (1<<23)
+#define ENABLE_STENCIL_TEST            ((1<<21)|(1<<20))
+#define DISABLE_STENCIL_TEST           (1<<21)
+#define ENABLE_DEPTH_BIAS              ((1<<11)|(1<<10))
+#define DISABLE_DEPTH_BIAS             (1<<11)
+#define ENABLE_SPEC_ADD_MASK           ((1<<9)|(1<<8))
+#define ENABLE_SPEC_ADD                ((1<<9)|(1<<8))
+#define DISABLE_SPEC_ADD               (1<<9)
+#define ENABLE_DIS_FOG_MASK            ((1<<7)|(1<<6))
+       /* prefixed I830 because ENABLE_FOG defined elsewhere */
+#define I830_ENABLE_FOG                        ((1<<7)|(1<<6))
+#define I830_DISABLE_FOG                       (1<<7)
+#define ENABLE_DIS_ALPHA_TEST_MASK     ((1<<5)|(1<<4))
+#define ENABLE_ALPHA_TEST              ((1<<5)|(1<<4))
+#define DISABLE_ALPHA_TEST             (1<<5)
+#define ENABLE_DIS_CBLEND_MASK         ((1<<3)|(1<<2))
+#define ENABLE_COLOR_BLEND             ((1<<3)|(1<<2))
+#define DISABLE_COLOR_BLEND            (1<<3)
+#define ENABLE_DIS_DEPTH_TEST_MASK     ((1<<1)|1)
+#define ENABLE_DEPTH_TEST              ((1<<1)|1)
+#define DISABLE_DEPTH_TEST             (1<<1)
+
+/* STATE3D_ENABLES_2, p138 */
+#define STATE3D_ENABLES_2_CMD          (CMD_3D|(0x4<<24))
+#define ENABLE_STENCIL_WRITE           ((1<<21)|(1<<20))
+#define DISABLE_STENCIL_WRITE          (1<<21)
+#define ENABLE_TEX_CACHE               ((1<<17)|(1<<16))
+#define DISABLE_TEX_CACHE              (1<<17)
+#define ENABLE_DITHER                  ((1<<9)|(1<<8))
+#define DISABLE_DITHER                 (1<<9)
+#define ENABLE_COLOR_MASK              (1<<10)
+#define WRITEMASK_ALPHA                        (1<<7)
+#define WRITEMASK_ALPHA_SHIFT          7
+#define WRITEMASK_RED                  (1<<6)
+#define WRITEMASK_RED_SHIFT            6
+#define WRITEMASK_GREEN                (1<<5)
+#define WRITEMASK_GREEN_SHIFT          5
+#define WRITEMASK_BLUE                 (1<<4)
+#define WRITEMASK_BLUE_SHIFT           4
+#define WRITEMASK_MASK                 ((1<<4)|(1<<5)|(1<<6)|(1<<7))
+#define ENABLE_COLOR_WRITE             ((1<<3)|(1<<2))
+#define DISABLE_COLOR_WRITE            (1<<3)
+#define ENABLE_DIS_DEPTH_WRITE_MASK    0x3
+#define ENABLE_DEPTH_WRITE             ((1<<1)|1)
+#define DISABLE_DEPTH_WRITE            (1<<1)
+
+/* STATE3D_FOG_COLOR, p139 */
+#define STATE3D_FOG_COLOR_CMD          (CMD_3D|(0x15<<24))
+#define FOG_COLOR_RED(x)               ((x)<<16)
+#define FOG_COLOR_GREEN(x)             ((x)<<8)
+#define FOG_COLOR_BLUE(x)              (x)
+
+/* STATE3D_FOG_MODE, p140 */
+#define STATE3D_FOG_MODE_CMD           (CMD_3D|(0x1d<<24)|(0x89<<16)|2)
+/* Dword 1 */
+#define FOGFUNC_ENABLE                 (1<<31)
+#define FOGFUNC_VERTEX                 0
+#define FOGFUNC_PIXEL_EXP              (1<<28)
+#define FOGFUNC_PIXEL_EXP2             (2<<28)
+#define FOGFUNC_PIXEL_LINEAR           (3<<28)
+#define FOGSRC_INDEX_Z                 (1<<27)
+#define FOGSRC_INDEX_W                 ((1<<27)|(1<<25))
+#define FOG_LINEAR_CONST               (1<<24)
+#define FOG_CONST_1(x)                 ((x)<<4)
+#define ENABLE_FOG_DENSITY             (1<<23)
+/* Dword 2 */
+#define FOG_CONST_2(x)                 (x)
+/* Dword 3 */
+#define FOG_DENSITY(x)                 (x)
+
+/* STATE3D_INDEPENDENT_ALPHA_BLEND, p142 */
+#define STATE3D_INDPT_ALPHA_BLEND_CMD  (CMD_3D|(0x0b<<24))
+#define ENABLE_INDPT_ALPHA_BLEND       ((1<<23)|(1<<22))
+#define DISABLE_INDPT_ALPHA_BLEND      (1<<23)
+#define ALPHA_BLENDFUNC_MASK           0x3f0000
+#define ENABLE_ALPHA_BLENDFUNC         (1<<21)
+#define ABLENDFUNC_ADD                 0
+#define ABLENDFUNC_SUB                 (1<<16)
+#define ABLENDFUNC_RVSE_SUB            (2<<16)
+#define ABLENDFUNC_MIN                 (3<<16)
+#define ABLENDFUNC_MAX                 (4<<16)
+#define SRC_DST_ABLEND_MASK            0xfff
+#define ENABLE_SRC_ABLEND_FACTOR       (1<<11)
+#define SRC_ABLEND_FACT(x)             ((x)<<6)
+#define ENABLE_DST_ABLEND_FACTOR       (1<<5)
+#define DST_ABLEND_FACT(x)             (x)
+
+#define BLENDFACT_ZERO                 0x01
+#define BLENDFACT_ONE                  0x02
+#define BLENDFACT_SRC_COLR             0x03
+#define BLENDFACT_INV_SRC_COLR                 0x04
+#define BLENDFACT_SRC_ALPHA            0x05
+#define BLENDFACT_INV_SRC_ALPHA        0x06
+#define BLENDFACT_DST_ALPHA            0x07
+#define BLENDFACT_INV_DST_ALPHA        0x08
+#define BLENDFACT_DST_COLR             0x09
+#define BLENDFACT_INV_DST_COLR         0x0a
+#define BLENDFACT_SRC_ALPHA_SATURATE   0x0b
+#define BLENDFACT_CONST_COLOR          0x0c
+#define BLENDFACT_INV_CONST_COLOR      0x0d
+#define BLENDFACT_CONST_ALPHA          0x0e
+#define BLENDFACT_INV_CONST_ALPHA      0x0f
+
+/* STATE3D_MAP_BLEND_ARG, p152 */
+#define STATE3D_MAP_BLEND_ARG_CMD(stage)       (CMD_3D|(0x0e<<24)|((stage)<<20))
+
+#define TEXPIPE_COLOR                  0
+#define TEXPIPE_ALPHA                  (1<<18)
+#define TEXPIPE_KILL                   (2<<18)
+#define TEXBLEND_ARG0                  0
+#define TEXBLEND_ARG1                  (1<<15)
+#define TEXBLEND_ARG2                  (2<<15)
+#define TEXBLEND_ARG3                  (3<<15)
+#define TEXBLENDARG_MODIFY_PARMS               (1<<6)
+#define TEXBLENDARG_REPLICATE_ALPHA    (1<<5)
+#define TEXBLENDARG_INV_ARG            (1<<4)
+#define TEXBLENDARG_ONE                0
+#define TEXBLENDARG_FACTOR             0x01
+#define TEXBLENDARG_ACCUM              0x02
+#define TEXBLENDARG_DIFFUSE            0x03
+#define TEXBLENDARG_SPEC               0x04
+#define TEXBLENDARG_CURRENT            0x05
+#define TEXBLENDARG_TEXEL0             0x06
+#define TEXBLENDARG_TEXEL1             0x07
+#define TEXBLENDARG_TEXEL2             0x08
+#define TEXBLENDARG_TEXEL3             0x09
+#define TEXBLENDARG_FACTOR_N           0x0e
+
+/* STATE3D_MAP_BLEND_OP, p155 */
+#define STATE3D_MAP_BLEND_OP_CMD(stage)        (CMD_3D|(0x0d<<24)|((stage)<<20))
+#if 0
+#define TEXPIPE_COLOR                  0
+#define TEXPIPE_ALPHA                  (1<<18)
+#define TEXPIPE_KILL                   (2<<18)
+#endif
+#define ENABLE_TEXOUTPUT_WRT_SEL       (1<<17)
+#define TEXOP_OUTPUT_CURRENT           0
+#define TEXOP_OUTPUT_ACCUM             (1<<15)
+#define ENABLE_TEX_CNTRL_STAGE         ((1<<12)|(1<<11))
+#define DISABLE_TEX_CNTRL_STAGE                (1<<12)
+#define TEXOP_SCALE_SHIFT              9
+#define TEXOP_SCALE_1X                 (0 << TEXOP_SCALE_SHIFT)
+#define TEXOP_SCALE_2X                 (1 << TEXOP_SCALE_SHIFT)
+#define TEXOP_SCALE_4X                 (2 << TEXOP_SCALE_SHIFT)
+#define TEXOP_MODIFY_PARMS             (1<<8)
+#define TEXOP_LAST_STAGE               (1<<7)
+#define TEXBLENDOP_KILLPIXEL           0x02
+#define TEXBLENDOP_ARG1                0x01
+#define TEXBLENDOP_ARG2                0x02
+#define TEXBLENDOP_MODULATE            0x03
+#define TEXBLENDOP_ADD                 0x06
+#define TEXBLENDOP_ADDSIGNED           0x07
+#define TEXBLENDOP_BLEND               0x08
+#define TEXBLENDOP_BLEND_AND_ADD       0x09
+#define TEXBLENDOP_SUBTRACT            0x0a
+#define TEXBLENDOP_DOT3                0x0b
+#define TEXBLENDOP_DOT4                0x0c
+#define TEXBLENDOP_MODULATE_AND_ADD    0x0d
+#define TEXBLENDOP_MODULATE_2X_AND_ADD 0x0e
+#define TEXBLENDOP_MODULATE_4X_AND_ADD 0x0f
+
+/* STATE3D_MAP_BUMP_TABLE, p160 TODO */
+/* STATE3D_MAP_COLOR_CHROMA_KEY, p161 TODO */
+
+/* STATE3D_MAP_COORD_SET_BINDINGS, p162 */
+#define STATE3D_MAP_COORD_SETBIND_CMD  (CMD_3D|(0x1d<<24)|(0x02<<16))
+#define TEXBIND_MASK3                  ((1<<15)|(1<<14)|(1<<13)|(1<<12))
+#define TEXBIND_MASK2                  ((1<<11)|(1<<10)|(1<<9)|(1<<8))
+#define TEXBIND_MASK1                  ((1<<7)|(1<<6)|(1<<5)|(1<<4))
+#define TEXBIND_MASK0                  ((1<<3)|(1<<2)|(1<<1)|1)
+
+#define TEXBIND_SET3(x)                ((x)<<12)
+#define TEXBIND_SET2(x)                ((x)<<8)
+#define TEXBIND_SET1(x)                ((x)<<4)
+#define TEXBIND_SET0(x)                (x)
+
+#define TEXCOORDSRC_KEEP               0
+#define TEXCOORDSRC_DEFAULT            0x01
+#define TEXCOORDSRC_VTXSET_0           0x08
+#define TEXCOORDSRC_VTXSET_1           0x09
+#define TEXCOORDSRC_VTXSET_2           0x0a
+#define TEXCOORDSRC_VTXSET_3           0x0b
+#define TEXCOORDSRC_VTXSET_4           0x0c
+#define TEXCOORDSRC_VTXSET_5           0x0d
+#define TEXCOORDSRC_VTXSET_6           0x0e
+#define TEXCOORDSRC_VTXSET_7           0x0f
+
+#define MAP_UNIT(unit)                 ((unit)<<16)
+#define MAP_UNIT_MASK                  (3<<16)
+
+/* STATE3D_MAP_COORD_SETS, p164 */
+#define STATE3D_MAP_COORD_SET_CMD      (CMD_3D|(0x1c<<24)|(0x01<<19))
+#define ENABLE_TEXCOORD_PARAMS         (1<<15)
+#define TEXCOORDS_ARE_NORMAL           (1<<14)
+#define TEXCOORDS_ARE_IN_TEXELUNITS    0
+#define TEXCOORDTYPE_CARTESIAN         0
+#define TEXCOORDTYPE_HOMOGENEOUS       (1<<11)
+#define TEXCOORDTYPE_VECTOR            (2<<11)
+#define ENABLE_ADDR_V_CNTL             (1<<7)
+#define ENABLE_ADDR_U_CNTL             (1<<3)
+#define TEXCOORD_ADDR_V_MODE(x)        ((x)<<4)
+#define TEXCOORD_ADDR_U_MODE(x)        (x)
+#define TEXCOORDMODE_WRAP              0
+#define TEXCOORDMODE_MIRROR            1
+#define TEXCOORDMODE_CLAMP             2
+#define TEXCOORDMODE_WRAP_SHORTEST     3
+#define TEXCOORDMODE_CLAMP_BORDER      4
+#define TEXCOORD_ADDR_V_MASK           0x70
+#define TEXCOORD_ADDR_U_MASK           0x7
+
+/* STATE3D_MAP_CUBE, p168 TODO */
+#define STATE3D_MAP_CUBE               (CMD_3D|(0x1c<<24)|(0x0a<<19))
+#define CUBE_NEGX_ENABLE                (1<<5)
+#define CUBE_POSX_ENABLE                (1<<4)
+#define CUBE_NEGY_ENABLE                (1<<3)
+#define CUBE_POSY_ENABLE                (1<<2)
+#define CUBE_NEGZ_ENABLE                (1<<1)
+#define CUBE_POSZ_ENABLE                (1<<0)
+
+
+/* STATE3D_MODES_1, p190 */
+#define STATE3D_MODES_1_CMD            (CMD_3D|(0x08<<24))
+#define BLENDFUNC_MASK                 0x3f0000
+#define ENABLE_COLR_BLND_FUNC          (1<<21)
+#define BLENDFUNC_ADD                  0
+#define BLENDFUNC_SUB                  (1<<16)
+#define BLENDFUNC_RVRSE_SUB            (2<<16)
+#define BLENDFUNC_MIN                  (3<<16)
+#define BLENDFUNC_MAX                  (4<<16)
+#define SRC_DST_BLND_MASK              0xfff
+#define ENABLE_SRC_BLND_FACTOR         (1<<11)
+#define ENABLE_DST_BLND_FACTOR         (1<<5)
+#define SRC_BLND_FACT(x)               ((x)<<6)
+#define DST_BLND_FACT(x)               (x)
+
+/* Use the blendfact defines for BLND_FACTOR macros */
+#if 0
+#define BLENDFACT_ZERO                 0x01
+#define BLENDFACT_ONE                  0x02
+#define BLENDFACT_SRC_COLR             0x03
+#define BLENDFACT_INV_SRC_COLR                 0x04
+#define BLENDFACT_SRC_ALPHA            0x05
+#define BLENDFACT_INV_SRC_ALPHA        0x06
+#define BLENDFACT_DST_ALPHA            0x07
+#define BLENDFACT_INV_DST_ALPHA        0x08
+#define BLENDFACT_CONST_ALPHA          0x0e
+#define BLENDFACT_INV_CONST_ALPHA      0x0f
+#endif
+
+/* STATE3D_MODES_2, p192 */
+#define STATE3D_MODES_2_CMD            (CMD_3D|(0x0f<<24))
+#define ENABLE_GLOBAL_DEPTH_BIAS       (1<<22)
+#define GLOBAL_DEPTH_BIAS(x)           ((x)<<14)
+#define ENABLE_ALPHA_TEST_FUNC         (1<<13)
+#define ENABLE_ALPHA_REF_VALUE         (1<<8)
+#define ALPHA_TEST_FUNC(x)             ((x)<<9)
+#define ALPHA_REF_VALUE(x)             (x)
+
+#define ALPHA_TEST_REF_MASK            0x3fff
+#define COMPAREFUNC_ALWAYS             0
+#define COMPAREFUNC_NEVER              0x1
+#define COMPAREFUNC_LESS               0x2
+#define COMPAREFUNC_EQUAL              0x3
+#define COMPAREFUNC_LEQUAL             0x4
+#define COMPAREFUNC_GREATER            0x5
+#define COMPAREFUNC_NOTEQUAL           0x6
+#define COMPAREFUNC_GEQUAL             0x7
+
+/* STATE3D_MODES_3, p193 */
+#define STATE3D_MODES_3_CMD            (CMD_3D|(0x02<<24))
+#define DEPTH_TEST_FUNC_MASK           0x1f0000
+#define ENABLE_DEPTH_TEST_FUNC         (1<<20)
+/* Uses COMPAREFUNC */
+#define DEPTH_TEST_FUNC(x)             ((x)<<16)
+#define ENABLE_ALPHA_SHADE_MODE        (1<<11)
+#define ENABLE_FOG_SHADE_MODE          (1<<9)
+#define ENABLE_SPEC_SHADE_MODE         (1<<7)
+#define ENABLE_COLOR_SHADE_MODE        (1<<5)
+#define ALPHA_SHADE_MODE(x)            ((x)<<10)
+#define FOG_SHADE_MODE(x)              ((x)<<8)
+#define SPEC_SHADE_MODE(x)             ((x)<<6)
+#define COLOR_SHADE_MODE(x)            ((x)<<4)
+#define CULLMODE_MASK                  0xf
+#define ENABLE_CULL_MODE               (1<<3)
+#define CULLMODE_BOTH                  0
+#define CULLMODE_NONE                  1
+#define CULLMODE_CW                    2
+#define CULLMODE_CCW                   3
+
+#define SHADE_MODE_LINEAR              0
+#define SHADE_MODE_FLAT                0x1
+
+/* STATE3D_MODES_4, p195 */
+#define STATE3D_MODES_4_CMD            (CMD_3D|(0x16<<24))
+#define ENABLE_LOGIC_OP_FUNC           (1<<23)
+#define LOGIC_OP_FUNC(x)               ((x)<<18)
+#define LOGICOP_MASK                   ((1<<18)|(1<<19)|(1<<20)|(1<<21))
+#define LOGICOP_CLEAR                  0
+#define LOGICOP_NOR                    0x1
+#define LOGICOP_AND_INV                0x2
+#define LOGICOP_COPY_INV               0x3
+#define LOGICOP_AND_RVRSE              0x4
+#define LOGICOP_INV                    0x5
+#define LOGICOP_XOR                    0x6
+#define LOGICOP_NAND                   0x7
+#define LOGICOP_AND                    0x8
+#define LOGICOP_EQUIV                  0x9
+#define LOGICOP_NOOP                   0xa
+#define LOGICOP_OR_INV                 0xb
+#define LOGICOP_COPY                   0xc
+#define LOGICOP_OR_RVRSE               0xd
+#define LOGICOP_OR                     0xe
+#define LOGICOP_SET                    0xf
+#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00))
+#define ENABLE_STENCIL_TEST_MASK       (1<<17)
+#define STENCIL_TEST_MASK(x)           ((x)<<8)
+#define MODE4_ENABLE_STENCIL_WRITE_MASK        ((1<<16)|(0x00ff))
+#define ENABLE_STENCIL_WRITE_MASK      (1<<16)
+#define STENCIL_WRITE_MASK(x)          (x)
+
+/* STATE3D_MODES_5, p196 */
+#define STATE3D_MODES_5_CMD            (CMD_3D|(0x0c<<24))
+#define ENABLE_SPRITE_POINT_TEX        (1<<23)
+#define SPRITE_POINT_TEX_ON            (1<<22)
+#define SPRITE_POINT_TEX_OFF           0
+#define FLUSH_RENDER_CACHE             (1<<18)
+#define FLUSH_TEXTURE_CACHE            (1<<16)
+#define FIXED_LINE_WIDTH_MASK          0xfc00
+#define ENABLE_FIXED_LINE_WIDTH        (1<<15)
+#define FIXED_LINE_WIDTH(x)            ((x)<<10)
+#define FIXED_POINT_WIDTH_MASK         0x3ff
+#define ENABLE_FIXED_POINT_WIDTH       (1<<9)
+#define FIXED_POINT_WIDTH(x)           (x)
+
+/* STATE3D_RASTERIZATION_RULES, p198 */
+#define STATE3D_RASTER_RULES_CMD       (CMD_3D|(0x07<<24))
+#define ENABLE_POINT_RASTER_RULE       (1<<15)
+#define OGL_POINT_RASTER_RULE          (1<<13)
+#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8)
+#define ENABLE_TRI_FAN_PROVOKE_VRTX    (1<<5)
+#define ENABLE_TRI_STRIP_PROVOKE_VRTX  (1<<2)
+#define LINE_STRIP_PROVOKE_VRTX(x)     ((x)<<6)
+#define TRI_FAN_PROVOKE_VRTX(x)        ((x)<<3)
+#define TRI_STRIP_PROVOKE_VRTX(x)      (x)
+
+/* STATE3D_SCISSOR_ENABLE, p200 */
+#define STATE3D_SCISSOR_ENABLE_CMD     (CMD_3D|(0x1c<<24)|(0x10<<19))
+#define ENABLE_SCISSOR_RECT            ((1<<1) | 1)
+#define DISABLE_SCISSOR_RECT           (1<<1)
+
+/* STATE3D_SCISSOR_RECTANGLE_0, p201 */
+#define STATE3D_SCISSOR_RECT_0_CMD     (CMD_3D|(0x1d<<24)|(0x81<<16)|1)
+/* Dword 1 */
+#define SCISSOR_RECT_0_YMIN(x)         ((x)<<16)
+#define SCISSOR_RECT_0_XMIN(x)         (x)
+/* Dword 2 */
+#define SCISSOR_RECT_0_YMAX(x)         ((x)<<16)
+#define SCISSOR_RECT_0_XMAX(x)         (x)
+
+/* STATE3D_STENCIL_TEST, p202 */
+#define STATE3D_STENCIL_TEST_CMD       (CMD_3D|(0x09<<24))
+#define ENABLE_STENCIL_PARMS           (1<<23)
+#define STENCIL_OPS_MASK               (0xffc000)
+#define STENCIL_FAIL_OP(x)             ((x)<<20)
+#define STENCIL_PASS_DEPTH_FAIL_OP(x)  ((x)<<17)
+#define STENCIL_PASS_DEPTH_PASS_OP(x)  ((x)<<14)
+
+#define STENCILOP_KEEP                 0
+#define STENCILOP_ZERO                 0x1
+#define STENCILOP_REPLACE              0x2
+#define STENCILOP_INCRSAT              0x3
+#define STENCILOP_DECRSAT              0x4
+#define STENCILOP_INCR                 0x5
+#define STENCILOP_DECR                 0x6
+#define STENCILOP_INVERT               0x7
+
+#define ENABLE_STENCIL_TEST_FUNC_MASK  ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9))
+#define ENABLE_STENCIL_TEST_FUNC       (1<<13)
+/* Uses COMPAREFUNC */
+#define STENCIL_TEST_FUNC(x)           ((x)<<9)
+#define STENCIL_REF_VALUE_MASK         ((1<<8)|0xff)
+#define ENABLE_STENCIL_REF_VALUE       (1<<8)
+#define STENCIL_REF_VALUE(x)           (x)
+
+/* STATE3D_VERTEX_FORMAT, p204 */
+#define STATE3D_VERTEX_FORMAT_CMD      (CMD_3D|(0x05<<24))
+#define VRTX_HAS_POINT_WIDTH           (1<<12)
+#define VRTX_TEX_COORD_COUNT(x)        ((x)<<8)
+#define VRTX_HAS_SPEC                  (1<<7)
+#define VRTX_HAS_DIFFUSE               (1<<6)
+#define VRTX_HAS_DEPTH_OFS             (1<<5)
+#define VRTX_HAS_XYZ                   (1<<1)
+#define VRTX_HAS_XYZW                  (2<<1)
+#define VRTX_HAS_XY                    (3<<1)
+#define VRTX_HAS_XYW                   (4<<1)
+
+/* STATE3D_VERTEX_FORMAT_2, p206 */
+#define STATE3D_VERTEX_FORMAT_2_CMD    (CMD_3D|(0x0a<<24))
+#define VRTX_TEX_SET_7_FMT(x)          ((x)<<14)
+#define VRTX_TEX_SET_6_FMT(x)          ((x)<<12)
+#define VRTX_TEX_SET_5_FMT(x)          ((x)<<10)
+#define VRTX_TEX_SET_4_FMT(x)          ((x)<<8)
+#define VRTX_TEX_SET_3_FMT(x)          ((x)<<6)
+#define VRTX_TEX_SET_2_FMT(x)          ((x)<<4)
+#define VRTX_TEX_SET_1_FMT(x)          ((x)<<2)
+#define VRTX_TEX_SET_0_FMT(x)          (x)
+
+#define TEXCOORDFMT_2D                 0
+#define TEXCOORDFMT_3D                 1
+#define TEXCOORDFMT_4D                 2
+#define TEXCOORDFMT_1D                 3
+
+/*New stuff picked up along the way */
+
+#define MLC_LOD_BIAS_MASK ((1<<7)-1)
+
+
+/* STATE3D_VERTEX_TRANSFORM, p207 */
+#define STATE3D_VERTEX_TRANS_CMD       (CMD_3D|(0x1d<<24)|(0x8b<<16)|0)
+#define STATE3D_VERTEX_TRANS_MTX_CMD   (CMD_3D|(0x1d<<24)|(0x8b<<16)|6)
+/* Dword 1 */
+#define ENABLE_VIEWPORT_TRANSFORM      ((1<<31)|(1<<30))
+#define DISABLE_VIEWPORT_TRANSFORM     (1<<31)
+#define ENABLE_PERSP_DIVIDE            ((1<<29)|(1<<28))
+#define DISABLE_PERSP_DIVIDE           (1<<29)
+#define VRTX_TRANS_LOAD_MATRICES       0x7421
+#define VRTX_TRANS_NO_LOAD_MATRICES    0x0000
+/* Dword 2 -> 7  are matrix elements */
+
+/* STATE3D_W_STATE, p209 */
+#define STATE3D_W_STATE_CMD            (CMD_3D|(0x1d<<24)|(0x8d<<16)|1)
+/* Dword 1 */
+#define MAGIC_W_STATE_DWORD1           0x00000008
+/* Dword 2 */
+#define WFAR_VALUE(x)                  (x)
+
+/* if defining I830_ENABLE_4_TEXTURES, do it in i830_drm.h, too */
+
+#define I830PACKCOLOR4444(r,g,b,a) \
+  ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
+
+#define I830PACKCOLOR1555(r,g,b,a) \
+  ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
+    ((a) ? 0x8000 : 0))
+
+#define I830PACKCOLOR565(r,g,b) \
+  ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+
+#define I830PACKCOLOR8888(r,g,b,a) \
+  ((a<<24) | (r<<16) | (g<<8) | b)
+
+
+/* Stipple command, carried over from the i810, apparently:
+ */
+#define GFX_OP_STIPPLE           ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define ST1_ENABLE               (1<<16)
+#define ST1_MASK                 (0xffff)
+
+
+
+#define STATE3D_LOAD_STATE_IMMEDIATE_2      ((0x3<<29)|(0x1d<<24)|(0x03<<16))
+#define LOAD_TEXTURE_MAP0                   (1<<11)
+
+#define TM0S0_ADDRESS_MASK              0xfffffffc
+#define TM0S0_USE_FENCE                 (1<<1)
+
+#define TM0S1_HEIGHT_SHIFT              21
+#define TM0S1_WIDTH_SHIFT               10
+#define TM0S1_PALETTE_SELECT            (1<<9)
+#define TM0S1_MAPSURF_FORMAT_MASK       (0x7 << 6)
+#define TM0S1_MAPSURF_FORMAT_SHIFT      6
+#define    MAPSURF_8BIT_INDEXED                   (0<<6)
+#define    MAPSURF_8BIT                           (1<<6)
+#define    MAPSURF_16BIT                  (2<<6)
+#define    MAPSURF_32BIT                  (3<<6)
+#define    MAPSURF_411                    (4<<6)
+#define    MAPSURF_422                    (5<<6)
+#define    MAPSURF_COMPRESSED             (6<<6)
+#define    MAPSURF_4BIT_INDEXED                   (7<<6)
+#define TM0S1_MT_FORMAT_MASK         (0x7 << 3)
+#define TM0S1_MT_FORMAT_SHIFT        3
+#define    MT_4BIT_IDX_ARGB8888                   (7<<3) /* SURFACE_4BIT_INDEXED */
+#define    MT_8BIT_IDX_RGB565             (0<<3) /* SURFACE_8BIT_INDEXED */
+#define    MT_8BIT_IDX_ARGB1555                   (1<<3)
+#define    MT_8BIT_IDX_ARGB4444                   (2<<3)
+#define    MT_8BIT_IDX_AY88               (3<<3)
+#define    MT_8BIT_IDX_ABGR8888                   (4<<3)
+#define    MT_8BIT_IDX_BUMP_88DVDU        (5<<3)
+#define    MT_8BIT_IDX_BUMP_655LDVDU      (6<<3)
+#define    MT_8BIT_IDX_ARGB8888                   (7<<3)
+#define    MT_8BIT_I8                     (0<<3) /* SURFACE_8BIT */
+#define    MT_8BIT_L8                     (1<<3)
+#define    MT_16BIT_RGB565                (0<<3) /* SURFACE_16BIT */
+#define    MT_16BIT_ARGB1555              (1<<3)
+#define    MT_16BIT_ARGB4444              (2<<3)
+#define    MT_16BIT_AY88                  (3<<3)
+#define    MT_16BIT_DIB_ARGB1555_8888      (4<<3)
+#define    MT_16BIT_BUMP_88DVDU                   (5<<3)
+#define    MT_16BIT_BUMP_655LDVDU         (6<<3)
+#define    MT_16BIT_DIB_RGB565_8888       (7<<3)
+#define    MT_32BIT_ARGB8888              (0<<3) /* SURFACE_32BIT */
+#define    MT_32BIT_ABGR8888              (1<<3)
+#define    MT_32BIT_BUMP_XLDVDU_8888      (6<<3)
+#define    MT_32BIT_DIB_8888              (7<<3)
+#define    MT_411_YUV411                  (0<<3) /* SURFACE_411 */
+#define    MT_422_YCRCB_SWAPY             (0<<3) /* SURFACE_422 */
+#define    MT_422_YCRCB_NORMAL            (1<<3)
+#define    MT_422_YCRCB_SWAPUV            (2<<3)
+#define    MT_422_YCRCB_SWAPUVY                   (3<<3)
+#define    MT_COMPRESS_DXT1               (0<<3) /* SURFACE_COMPRESSED */
+#define    MT_COMPRESS_DXT2_3             (1<<3)
+#define    MT_COMPRESS_DXT4_5             (2<<3)
+#define    MT_COMPRESS_FXT1               (3<<3)
+#define TM0S1_COLORSPACE_CONVERSION     (1 << 2)
+#define TM0S1_TILED_SURFACE             (1 << 1)
+#define TM0S1_TILE_WALK                 (1 << 0)
+
+#define TM0S2_PITCH_SHIFT               21
+#define TM0S2_CUBE_FACE_ENA_SHIFT       15
+#define TM0S2_MAP_FORMAT                (1<<14)
+#define TM0S2_VERTICAL_LINE_STRIDE      (1<<13)
+#define TM0S2_VERITCAL_LINE_STRIDE_OFF  (1<<12)
+#define TM0S2_OUTPUT_CHAN_SHIFT         10
+#define TM0S2_OUTPUT_CHAN_MASK          (3<<10)
+
+#define TM0S3_MIP_FILTER_MASK           (0x3<<30)
+#define TM0S3_MIP_FILTER_SHIFT          30
+#define MIPFILTER_NONE         0
+#define MIPFILTER_NEAREST      1
+#define MIPFILTER_LINEAR       3
+#define TM0S3_MAG_FILTER_MASK           (0x3<<28)
+#define TM0S3_MAG_FILTER_SHIFT          28
+#define TM0S3_MIN_FILTER_MASK           (0x3<<26)
+#define TM0S3_MIN_FILTER_SHIFT          26
+#define FILTER_NEAREST         0
+#define FILTER_LINEAR          1
+#define FILTER_ANISOTROPIC     2
+
+#define TM0S3_LOD_BIAS_SHIFT           17
+#define TM0S3_LOD_BIAS_MASK            (0x1ff<<17)
+#define TM0S3_MAX_MIP_SHIFT            9
+#define TM0S3_MAX_MIP_MASK             (0xff<<9)
+#define TM0S3_MIN_MIP_SHIFT            3
+#define TM0S3_MIN_MIP_MASK             (0x3f<<3)
+#define TM0S3_KILL_PIXEL               (1<<2)
+#define TM0S3_KEYED_FILTER             (1<<1)
+#define TM0S3_CHROMA_KEY               (1<<0)
+
+
+/* STATE3D_MAP_TEXEL_STREAM, p188 */
+#define STATE3D_MAP_TEX_STREAM_CMD     (CMD_3D|(0x1c<<24)|(0x05<<19))
+#define DISABLE_TEX_STREAM_BUMP        (1<<12)
+#define ENABLE_TEX_STREAM_BUMP         ((1<<12)|(1<<11))
+#define TEX_MODIFY_UNIT_0              0
+#define TEX_MODIFY_UNIT_1              (1<<8)
+#define ENABLE_TEX_STREAM_COORD_SET    (1<<7)
+#define TEX_STREAM_COORD_SET(x)        ((x)<<4)
+#define ENABLE_TEX_STREAM_MAP_IDX      (1<<3)
+#define TEX_STREAM_MAP_IDX(x)          (x)
diff --git a/src/mesa/drivers/dri/i830/i830_context.c b/src/mesa/drivers/dri/i830/i830_context.c
new file mode 100644 (file)
index 0000000..254fa28
--- /dev/null
@@ -0,0 +1,588 @@
+/**************************************************************************
+ * 
+ * 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/i830/i830_context.c,v 1.9 2003/02/06 04:18:00 dawes Exp $ */
+
+/*
+ * Authors:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ *   Graeme Fisher <graeme@2d3d.co.za>
+ *   Abraham vd Merwe <abraham@2d3d.co.za>
+ *
+ * Heavily Based on I810 driver written by:
+ *   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 "i830_screen.h"
+#include "i830_dri.h"
+
+#include "i830_state.h"
+#include "i830_tex.h"
+#include "i830_span.h"
+#include "i830_tris.h"
+#include "i830_vb.h"
+#include "i830_ioctl.h"
+
+
+#include "utils.h"
+#ifndef I830_DEBUG
+int I830_DEBUG = (0);
+#endif
+
+/***************************************
+ * Mesa's Driver Functions
+ ***************************************/
+
+#define DRIVER_DATE                     "20021115"
+
+static const GLubyte *i830DDGetString( GLcontext *ctx, GLenum name )
+{
+   const char * chipset;
+   static char buffer[128];
+
+   switch (name) {
+   case GL_VENDOR:
+      switch (I830_CONTEXT(ctx)->i830Screen->deviceID) {
+      case PCI_CHIP_845_G:
+        return (GLubyte *)"2d3D, Inc";
+      
+      case PCI_CHIP_I830_M:
+        return (GLubyte *)"VA Linux, Inc";
+
+      case PCI_CHIP_I855_GM:
+      case PCI_CHIP_I865_G:
+      default:
+        return (GLubyte *)"Tungsten Graphics, Inc";
+      }
+      break;
+      
+   case GL_RENDERER:
+      switch (I830_CONTEXT(ctx)->i830Screen->deviceID) {
+      case PCI_CHIP_845_G:
+        chipset = "Intel(R) 845G"; break;
+      case PCI_CHIP_I830_M:
+        chipset = "Intel(R) 830M"; break;
+      case PCI_CHIP_I855_GM:
+        chipset = "Intel(R) 852GM/855GM"; break;
+      case PCI_CHIP_I865_G:
+        chipset = "Intel(R) 865G"; break;
+      default:
+        chipset = "Unknown Intel Chipset"; break;
+      }
+
+      (void) driGetRendererString( buffer, chipset, DRIVER_DATE, 0 );
+      return (GLubyte *) buffer;
+
+   default:
+      return NULL;
+   }
+}
+
+static void i830BufferSize(GLframebuffer *buffer,
+                          GLuint *width, GLuint *height)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   i830ContextPtr imesa = I830_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 i830 driver.
+ */
+static const char * const card_extensions[] =
+{
+   "GL_ARB_multisample",
+   "GL_ARB_multitexture",
+   "GL_ARB_texture_border_clamp",
+   "GL_ARB_texture_compression",
+   "GL_ARB_texture_env_add",
+   "GL_ARB_texture_env_combine",
+   "GL_ARB_texture_env_dot3",
+   "GL_ARB_texture_mirrored_repeat",
+   "GL_EXT_blend_color",
+   "GL_EXT_blend_func_separate",
+   "GL_EXT_blend_minmax",
+   "GL_EXT_blend_subtract",
+   "GL_EXT_fog_coord",
+   "GL_EXT_secondary_color",
+   "GL_EXT_stencil_wrap",
+   "GL_EXT_texture_edge_clamp",
+   "GL_EXT_texture_env_add",
+   "GL_EXT_texture_env_combine",
+   "GL_EXT_texture_env_dot3",
+   "GL_EXT_texture_filter_anisotropic",
+   "GL_EXT_texture_lod_bias",
+   "GL_IBM_texture_mirrored_repeat",
+   "GL_INGR_blend_func_separate",
+   "GL_MESA_ycbcr_texture",
+   "GL_NV_texture_rectangle",
+   "GL_SGIS_generate_mipmap",
+   "GL_SGIS_texture_border_clamp",
+   "GL_SGIS_texture_edge_clamp",
+   NULL
+};
+
+
+extern const struct gl_pipeline_stage _i830_render_stage;
+
+static const struct gl_pipeline_stage *i830_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
+   &_i830_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 i830CreateContext( const __GLcontextModes *mesaVis,
+                             __DRIcontextPrivate *driContextPriv,
+                             void *sharedContextPrivate)
+{
+   GLcontext *ctx , *shareCtx;
+   i830ContextPtr imesa;
+   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   i830ScreenPrivate *screen = (i830ScreenPrivate *)sPriv->private;
+   I830SAREAPtr saPriv=(I830SAREAPtr)
+       (((GLubyte *)sPriv->pSAREA)+screen->sarea_priv_offset);
+
+   /* Allocate i830 context */
+   imesa = (i830ContextPtr) CALLOC_STRUCT(i830_context_t);
+   if (!imesa) return GL_FALSE;
+
+   /* Allocate the Mesa context */
+   if (sharedContextPrivate)
+     shareCtx = ((i830ContextPtr) 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->i830Screen = screen;
+   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,
+           screen->textureSize,
+           12,
+           I830_NR_TEX_REGIONS,
+           imesa->sarea->texList,
+           & imesa->sarea->texAge,
+           & imesa->swapped,
+           sizeof( struct i830_texture_object_t ),
+           (destroy_texture_object_t *) i830DestroyTexObj );
+
+
+   /* Set the maximum texture size small enough that we can guarantee
+    * 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.MaxTextureMaxAnisotropy = 2.0;
+
+   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 = 255.0;
+   ctx->Const.MaxPointSizeAA = 3.0;
+   ctx->Const.PointSizeGranularity = 1.0;
+
+   ctx->Driver.GetBufferSize = i830BufferSize;
+   ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
+   ctx->Driver.GetString = i830DDGetString;
+
+   /* 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, i830_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->vertex_format = 0;
+
+   imesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
+
+   switch(mesaVis->depthBits) {
+   case 16:
+      imesa->depth_scale = 1.0/0xffff;
+      imesa->depth_clear_mask = ~0;
+      imesa->ClearDepth = 0xffff;
+      break;
+   case 24:
+      imesa->depth_scale = 1.0/0xffffff;
+      imesa->depth_clear_mask = 0x00ffffff;
+      imesa->stencil_clear_mask = 0xff000000;
+      imesa->ClearDepth = 0x00ffffff;
+      break;
+   case 32: /* Not supported */
+   default:
+      break;
+   }
+   /* Completely disable stenciling for now, there are some serious issues
+    * with stencil.
+    */
+#if 0
+   imesa->hw_stencil = 0;
+#endif
+
+   imesa->RenderIndex = ~0;
+   imesa->dirty = ~0;
+   imesa->upload_cliprects = GL_TRUE;
+
+   imesa->CurrentTexObj[0] = 0;
+   imesa->CurrentTexObj[1] = 0;
+
+   imesa->do_irqs = (imesa->i830Screen->irq_active &&
+                    !getenv("I830_NO_IRQS"));
+
+   _math_matrix_ctr (&imesa->ViewportMatrix);
+
+   driInitExtensions( ctx, card_extensions, GL_TRUE );
+   i830DDInitStateFuncs( ctx );
+   i830DDInitTextureFuncs( ctx );
+   i830InitTriFuncs (ctx);
+   i830DDInitSpanFuncs( ctx );
+   i830DDInitIoctlFuncs( ctx );
+   i830InitVB (ctx);
+   i830DDInitState (ctx);
+
+#if DO_DEBUG
+   I830_DEBUG  = driParseDebugString( getenv( "I830_DEBUG" ),
+                                     debug_control );
+   I830_DEBUG |= driParseDebugString( getenv( "INTEL_DEBUG" ),
+                                     debug_control );
+#endif
+
+   if (getenv("I830_NO_RAST") || 
+       getenv("INTEL_NO_RAST")) {
+      fprintf(stderr, "disabling 3D rasterization\n");
+      FALLBACK(imesa, I830_FALLBACK_USER, 1); 
+   }
+
+
+   return GL_TRUE;
+}
+
+void i830DestroyContext(__DRIcontextPrivate *driContextPriv)
+{
+   i830ContextPtr imesa = (i830ContextPtr) 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);
+
+      i830FreeVB (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 i830XMesaSetFrontClipRects( i830ContextPtr imesa )
+{
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+
+   imesa->numClipRects = dPriv->numClipRects;
+   imesa->pClipRects = dPriv->pClipRects;
+   imesa->drawX = dPriv->x;
+   imesa->drawY = dPriv->y;
+
+   i830EmitDrawingRectangle( imesa );
+   imesa->upload_cliprects = GL_TRUE;
+}
+
+void i830XMesaSetBackClipRects( i830ContextPtr 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;
+   }
+
+   i830EmitDrawingRectangle( imesa );
+   imesa->upload_cliprects = GL_TRUE;
+}
+
+static void i830XMesaWindowMoved( i830ContextPtr imesa )
+{
+   switch (imesa->glCtx->Color._DrawDestMask) {
+   case FRONT_LEFT_BIT:
+      i830XMesaSetFrontClipRects( imesa );
+      break;
+   case BACK_LEFT_BIT:
+      i830XMesaSetBackClipRects( imesa );
+      break;
+   default:
+      /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
+      i830XMesaSetFrontClipRects( imesa );
+   }
+}
+
+GLboolean i830UnbindContext(__DRIcontextPrivate *driContextPriv)
+{
+   i830ContextPtr imesa = (i830ContextPtr) driContextPriv->driverPrivate;
+   if (imesa) {
+      /* Might want to change this so texblend isn't always updated */
+      imesa->dirty |= (I830_UPLOAD_CTX |
+                      I830_UPLOAD_BUFFERS |
+                      I830_UPLOAD_STIPPLE |
+                      I830_UPLOAD_TEXBLEND0 |
+                      I830_UPLOAD_TEXBLEND1);
+
+      if (imesa->CurrentTexObj[0]) imesa->dirty |= I830_UPLOAD_TEX0;
+      if (imesa->CurrentTexObj[1]) imesa->dirty |= I830_UPLOAD_TEX1;
+   }
+   return GL_TRUE;
+}
+
+GLboolean i830MakeCurrent(__DRIcontextPrivate *driContextPriv,
+                         __DRIdrawablePrivate *driDrawPriv,
+                         __DRIdrawablePrivate *driReadPriv)
+{
+
+   if (driContextPriv) {
+      i830ContextPtr imesa = (i830ContextPtr) driContextPriv->driverPrivate;
+
+      if ( imesa->driDrawable != driDrawPriv ) {
+        /* Shouldn't the readbuffer be stored also? */
+        imesa->driDrawable = driDrawPriv;
+        i830XMesaWindowMoved( imesa );
+      }
+
+      _mesa_make_current2(imesa->glCtx,
+                         (GLframebuffer *) driDrawPriv->driverPrivate,
+                         (GLframebuffer *) driReadPriv->driverPrivate);
+
+      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;
+}
+
+void i830GetLock( i830ContextPtr imesa, GLuint flags )
+{
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+   __DRIscreenPrivate *sPriv = imesa->driScreen;
+   I830SAREAPtr 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 |= (I830_UPLOAD_CTX |
+                      I830_UPLOAD_BUFFERS | 
+                      I830_UPLOAD_STIPPLE);
+
+      if(imesa->CurrentTexObj[0]) imesa->dirty |= I830_UPLOAD_TEX0;
+      if(imesa->CurrentTexObj[1]) imesa->dirty |= I830_UPLOAD_TEX1;
+      if(imesa->TexBlendWordsUsed[0]) imesa->dirty |= I830_UPLOAD_TEXBLEND0;
+      if(imesa->TexBlendWordsUsed[1]) imesa->dirty |= I830_UPLOAD_TEXBLEND1;
+
+      sarea->perf_boxes = imesa->perf_boxes | I830_BOX_LOST_CONTEXT;
+      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) {
+      i830XMesaWindowMoved( imesa );
+      imesa->lastStamp = dPriv->lastStamp;
+   }
+
+   sarea->last_quiescent = -1;  /* just kill it for now */
+}
+
+void i830SwapBuffers( __DRIdrawablePrivate *dPriv )
+{
+   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+      i830ContextPtr imesa;
+      GLcontext *ctx;
+      imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate;
+      ctx = imesa->glCtx;
+      if (ctx->Visual.doubleBufferMode) {
+        _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */
+        if ( 0 /*imesa->doPageFlip*/ ) { /* doPageFlip is never set !!! */
+           i830PageFlip( dPriv );
+        } else {
+           i830CopyBuffer( dPriv );
+        }
+      }
+   } else {
+      /* XXX this shouldn't be an error but we can't handle it for now */
+      _mesa_problem(NULL, "%s: drawable has no context!\n", __FUNCTION__);
+   }
+}
diff --git a/src/mesa/drivers/dri/i830/i830_context.h b/src/mesa/drivers/dri/i830/i830_context.h
new file mode 100644 (file)
index 0000000..2bb71cb
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * GLX Hardware Device Driver for Intel i830
+ * 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.
+ *
+ */
+
+/* Adapted for use in the I830M driver: 
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_context.h,v 1.7 2003/02/06 04:18:01 dawes Exp $ */
+
+#ifndef I830CONTEXT_INC
+#define I830CONTEXT_INC
+
+typedef struct i830_context_t i830Context;
+typedef struct i830_context_t *i830ContextPtr;
+typedef struct i830_texture_object_t *i830TextureObjectPtr;
+
+
+#include "mtypes.h"
+#include "drm.h"
+#include "mm.h"
+
+#include "i830_screen.h"
+#include "i830_tex.h"
+
+#define TAG(x) i830##x
+#include "tnl_dd/t_dd_vertex.h"
+#undef TAG
+
+#define DV_PF_555  (1<<8)
+#define DV_PF_565  (2<<8)
+#define DV_PF_8888 (3<<8)
+
+#define I830_TEX_MAXLEVELS 10
+
+#define I830_CONTEXT(ctx)      ((i830ContextPtr)(ctx->DriverCtx))
+#define GET_DISPATCH_AGE(imesa) imesa->sarea->last_dispatch
+#define GET_ENQUEUE_AGE(imesa) imesa->sarea->last_enqueue
+
+
+typedef void (*i830_tri_func)(i830ContextPtr, i830Vertex *, i830Vertex *,
+                                                         i830Vertex *);
+typedef void (*i830_line_func)(i830ContextPtr, i830Vertex *, i830Vertex *);
+typedef void (*i830_point_func)(i830ContextPtr, i830Vertex *);
+
+#define I830_FALLBACK_TEXTURE           0x1
+#define I830_FALLBACK_DRAW_BUFFER       0x2
+#define I830_FALLBACK_READ_BUFFER       0x4
+#define I830_FALLBACK_COLORMASK                 0x8
+#define I830_FALLBACK_RENDERMODE        0x10
+#define I830_FALLBACK_STENCIL           0x20
+#define I830_FALLBACK_STIPPLE           0x40
+#define I830_FALLBACK_USER              0x80
+
+struct i830_context_t 
+{
+   GLint refcount;   
+   GLcontext *glCtx;
+
+   /*From I830 stuff*/
+   int TextureMode;
+   GLuint renderindex;
+   GLuint TexBlendWordsUsed[I830_TEXBLEND_COUNT];
+   GLuint TexBlend[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE];
+   GLuint Init_TexBlend[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE];
+   GLuint Init_TexBlendWordsUsed[I830_TEXBLEND_COUNT];
+   GLuint Init_TexBlendColorPipeNum[I830_TEXBLEND_COUNT];
+   GLuint TexBlendColorPipeNum[I830_TEXBLEND_COUNT];
+   GLuint Init_BufferSetup[I830_DEST_SETUP_SIZE];
+   GLuint LodBias[2];
+   
+   GLenum palette_format;
+   GLuint palette[256];
+   
+   
+   GLuint Init_Setup[I830_CTX_SETUP_SIZE];
+   GLuint vertex_prim;
+   drmBufPtr vertex_dma_buffer;
+   
+   GLboolean mask_red;
+   GLboolean mask_green;
+   GLboolean mask_blue;
+   GLboolean mask_alpha;
+
+   GLubyte clear_red;
+   GLubyte clear_green;
+   GLubyte clear_blue;
+   GLubyte clear_alpha;
+
+   GLfloat depth_scale;
+   int depth_clear_mask;
+   int stencil_clear_mask;
+   int ClearDepth;
+   int hw_stencil;
+   
+   GLuint MonoColor;
+   
+   GLuint LastTexEnabled;
+   GLuint TexEnabledMask;
+   
+   /* Texture object bookkeeping
+    */
+   unsigned              nr_heaps;
+   driTexHeap          * texture_heaps[1];
+   driTextureObject      swapped;
+
+   struct i830_texture_object_t *CurrentTexObj[2];
+
+   /* Rasterization and vertex state:
+    */
+   GLuint Fallback;
+   GLuint NewGLState;
+
+   /* Temporaries for translating away float colors:
+    */
+   struct gl_client_array UbyteColor;
+   struct gl_client_array UbyteSecondaryColor;
+
+   /* State for i830vb.c and i830tris.c.
+    */
+   GLuint SetupNewInputs;
+   GLuint SetupIndex;
+   GLuint RenderIndex;
+   GLmatrix ViewportMatrix;
+   GLenum render_primitive;
+   GLenum reduced_primitive;
+   GLuint hw_primitive;
+   GLuint vertex_format;
+   char *verts;
+
+   drmBufPtr  vertex_buffer;
+   char *vertex_addr;
+   GLuint vertex_low;
+   GLuint vertex_high;
+   GLuint vertex_last_prim;
+   
+   GLboolean upload_cliprects;
+
+
+   /* Fallback rasterization functions 
+    */
+   i830_point_func draw_point;
+   i830_line_func draw_line;
+   i830_tri_func draw_tri;
+
+   /* Hardware state 
+    */
+   GLuint dirty;               /* I810_UPLOAD_* */
+   GLuint Setup[I830_CTX_SETUP_SIZE];
+   GLuint BufferSetup[I830_DEST_SETUP_SIZE];
+   GLuint StippleSetup[I830_STP_SETUP_SIZE];
+   int vertex_size;
+   int vertex_stride_shift;
+   unsigned int lastStamp;
+   GLboolean hw_stipple;
+
+   GLenum TexEnvImageFmt[2];
+
+   /* State which can't be computed completely on the fly:
+    */
+   GLuint LcsCullMode;
+   GLuint LcsLineWidth;
+   GLuint LcsPointSize;
+
+   /* Funny mesa mirrors
+    */
+   GLuint ClearColor;
+
+   /* DRI stuff
+    */
+   GLuint needClip;
+   GLframebuffer *glBuffer;
+
+   /* 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;
+   int perf_boxes;
+
+   int do_irqs;
+   
+   GLboolean scissor;
+   XF86DRIClipRectRec draw_rect;
+   XF86DRIClipRectRec scissor_rect;
+
+   drmContext hHWContext;
+   drmLock *driHwLock;
+   int driFd;
+
+   __DRIdrawablePrivate *driDrawable;
+   __DRIscreenPrivate *driScreen;
+   i830ScreenPrivate *i830Screen; 
+   I830SAREAPtr sarea;
+};
+
+
+#define I830_TEX_UNIT_ENABLED(unit)     (1<<unit)
+#define VALID_I830_TEXTURE_OBJECT(tobj) (tobj)
+
+#define I830_CONTEXT(ctx)   ((i830ContextPtr)(ctx->DriverCtx))
+#define I830_DRIVER_DATA(vb) ((i830VertexBufferPtr)((vb)->driver_data))
+#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)                                         \
+        i830GetLock( imesa, 0 );                       \
+}while (0)
+  
+  /* Unlock the hardware using the global current context 
+   */
+#define UNLOCK_HARDWARE(imesa)                                         \
+do {                                                                   \
+   imesa->perf_boxes |= imesa->sarea->perf_boxes;                      \
+   DRM_UNLOCK(imesa->driFd, imesa->driHwLock, imesa->hHWContext);      \
+} while (0)
+
+  /* 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 );                              \
+   i830RegetLockQuiescent( imesa );                     \
+} while(0)
+
+
+
+extern void i830GetLock(i830ContextPtr imesa, GLuint flags);
+extern void i830EmitHwStateLocked(i830ContextPtr imesa);
+extern void i830EmitDrawingRectangle(i830ContextPtr imesa);
+extern void i830XMesaSetBackClipRects(i830ContextPtr imesa);
+extern void i830XMesaSetFrontClipRects(i830ContextPtr imesa);
+extern void i830DDExtensionsInit(GLcontext *ctx);
+extern void i830DDInitDriverFuncs(GLcontext *ctx);
+extern void i830DDUpdateHwState(GLcontext *ctx);
+
+#define SUBPIXEL_X 0.125
+#define SUBPIXEL_Y 0.125
+
+
+/* ================================================================
+ * Debugging:
+ */
+#define DO_DEBUG               1
+#if DO_DEBUG
+extern int I830_DEBUG;
+#else
+#define I830_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
+
+
+#define PCI_CHIP_845_G                 0x2562
+#define PCI_CHIP_I830_M                        0x3577
+#define PCI_CHIP_I855_GM               0x3582
+#define PCI_CHIP_I865_G                        0x2572
+
+       
+#endif
+
diff --git a/src/mesa/drivers/dri/i830/i830_debug.c b/src/mesa/drivers/dri/i830/i830_debug.c
new file mode 100644 (file)
index 0000000..66c698b
--- /dev/null
@@ -0,0 +1,377 @@
+/**************************************************************************
+
+Copyright 2001 2d3d Inc., Delray Beach, FL
+
+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.
+
+**************************************************************************/
+
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_debug.c,v 1.3 2002/12/10 01:26:53 dawes Exp $ */
+
+/*
+ * Author:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ */
+
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "enums.h"
+#include "dd.h"
+                                            
+#include "mm.h"
+
+#include "i830_screen.h"
+#include "i830_dri.h"
+
+#include "i830_context.h"
+#include "i830_state.h"
+#include "i830_tex.h"
+#include "i830_vb.h"
+#include "i830_tris.h"
+#include "i830_ioctl.h"
+#include "i830_debug.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"
+
+
+#define TINY_VERTEX_FORMAT      (STATE3D_VERTEX_FORMAT_CMD | \
+                                VRTX_TEX_COORD_COUNT(0) | \
+                                VRTX_HAS_DIFFUSE | \
+                                VRTX_HAS_XYZ)
+
+#define NOTEX_VERTEX_FORMAT     (STATE3D_VERTEX_FORMAT_CMD | \
+                                VRTX_TEX_COORD_COUNT(0) | \
+                                VRTX_HAS_DIFFUSE | \
+                                VRTX_HAS_SPEC | \
+                                VRTX_HAS_XYZW)
+
+#define TEX0_VERTEX_FORMAT      (STATE3D_VERTEX_FORMAT_CMD | \
+                                VRTX_TEX_COORD_COUNT(1) | \
+                                VRTX_HAS_DIFFUSE | \
+                                VRTX_HAS_SPEC | \
+                                VRTX_HAS_XYZW)
+
+#define TEX1_VERTEX_FORMAT      (STATE3D_VERTEX_FORMAT_CMD | \
+                                VRTX_TEX_COORD_COUNT(2) | \
+                                VRTX_HAS_DIFFUSE | \
+                                VRTX_HAS_SPEC | \
+                                VRTX_HAS_XYZW)
+
+#define PROJ_VF2               (STATE3D_VERTEX_FORMAT_2_CMD |          \
+                                VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D) |   \
+                                VRTX_TEX_SET_1_FMT(TEXCOORDFMT_3D) |   \
+                                VRTX_TEX_SET_2_FMT(TEXCOORDFMT_3D) |   \
+                                VRTX_TEX_SET_3_FMT(TEXCOORDFMT_3D))
+
+#define NON_PROJ_VF2           (STATE3D_VERTEX_FORMAT_2_CMD |          \
+                                VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) |   \
+                                VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) |   \
+                                VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) |   \
+                                VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D))
+
+void i830DumpContextState( i830ContextPtr imesa )
+{
+   GLuint *Context = imesa->Setup;
+   
+   fprintf(stderr, "%s\n", __FUNCTION__);
+   fprintf(stderr, "STATE1 : 0x%08x\n", Context[I830_CTXREG_STATE1]);
+   fprintf(stderr, "STATE2 : 0x%08x\n", Context[I830_CTXREG_STATE2]);
+   fprintf(stderr, "STATE3 : 0x%08x\n", Context[I830_CTXREG_STATE3]);
+   fprintf(stderr, "STATE4 : 0x%08x\n", Context[I830_CTXREG_STATE4]);
+   fprintf(stderr, "STATE5 : 0x%08x\n", Context[I830_CTXREG_STATE5]);
+   fprintf(stderr, "IALPHAB : 0x%08x\n", Context[I830_CTXREG_IALPHAB]);
+   fprintf(stderr, "STENCILTST : 0x%08x\n", Context[I830_CTXREG_STENCILTST]);
+   fprintf(stderr, "ENABLES_1 : 0x%08x\n", Context[I830_CTXREG_ENABLES_1]);
+   fprintf(stderr, "ENABLES_2 : 0x%08x\n", Context[I830_CTXREG_ENABLES_2]);
+   fprintf(stderr, "AA : 0x%08x\n", Context[I830_CTXREG_AA]);
+   fprintf(stderr, "FOGCOLOR : 0x%08x\n", Context[I830_CTXREG_FOGCOLOR]);
+   fprintf(stderr, "BCOLOR0 : 0x%08x\n", Context[I830_CTXREG_BLENDCOLR0]);
+   fprintf(stderr, "BCOLOR : 0x%08x\n", Context[I830_CTXREG_BLENDCOLR]);
+   fprintf(stderr, "VF : 0x%08x\n", Context[I830_CTXREG_VF]);
+   fprintf(stderr, "VF2 : 0x%08x\n", Context[I830_CTXREG_VF2]);
+   fprintf(stderr, "MCSB0 : 0x%08x\n", Context[I830_CTXREG_MCSB0]);
+   fprintf(stderr, "MCSB1 : 0x%08x\n", Context[I830_CTXREG_MCSB1]);
+}
+
+void i830DumpBufferState( i830ContextPtr imesa )
+{
+   GLuint *Buffer = imesa->BufferSetup;
+
+   fprintf(stderr, "%s\n", __FUNCTION__);
+   fprintf(stderr, "CBUFADDR : 0x%08x\n", Buffer[I830_DESTREG_CBUFADDR]);
+   fprintf(stderr, "DBUFADDR : 0x%08x\n", Buffer[I830_DESTREG_DBUFADDR]);
+   fprintf(stderr, "DV0 : 0x%08x\n", Buffer[I830_DESTREG_DV0]);
+   fprintf(stderr, "DV1 : 0x%08x\n", Buffer[I830_DESTREG_DV1]);
+   fprintf(stderr, "SENABLE : 0x%08x\n", Buffer[I830_DESTREG_SENABLE]);
+   fprintf(stderr, "SR0 : 0x%08x\n", Buffer[I830_DESTREG_SR0]);
+   fprintf(stderr, "SR1 : 0x%08x\n", Buffer[I830_DESTREG_SR1]);
+   fprintf(stderr, "SR2 : 0x%08x\n", Buffer[I830_DESTREG_SR2]);
+   fprintf(stderr, "DR0 : 0x%08x\n", Buffer[I830_DESTREG_DR0]);
+   fprintf(stderr, "DR1 : 0x%08x\n", Buffer[I830_DESTREG_DR1]);
+   fprintf(stderr, "DR2 : 0x%08x\n", Buffer[I830_DESTREG_DR2]);
+   fprintf(stderr, "DR3 : 0x%08x\n", Buffer[I830_DESTREG_DR3]);
+   fprintf(stderr, "DR4 : 0x%08x\n", Buffer[I830_DESTREG_DR4]);
+}
+
+void i830DumpStippleState( i830ContextPtr imesa )
+{
+   GLuint *Buffer = imesa->BufferSetup;
+
+   fprintf(stderr, "%s\n", __FUNCTION__);
+   fprintf(stderr, "ST1 : 0x%08x\n", Buffer[I830_STPREG_ST1]);
+}
+
+void i830DumpTextureState( i830ContextPtr imesa, int unit )
+{
+   i830TextureObjectPtr t = imesa->CurrentTexObj[unit];
+
+   if(t) {
+      fprintf(stderr, "%s : unit %d\n", __FUNCTION__, unit);
+      fprintf(stderr, "TM0LI : 0x%08x\n", t->Setup[I830_TEXREG_TM0LI]);
+      fprintf(stderr, "TM0S0 : 0x%08x\n", t->Setup[I830_TEXREG_TM0S0]);
+      fprintf(stderr, "TM0S1 : 0x%08x\n", t->Setup[I830_TEXREG_TM0S1]);
+      fprintf(stderr, "TM0S2 : 0x%08x\n", t->Setup[I830_TEXREG_TM0S2]);
+      fprintf(stderr, "TM0S3 : 0x%08x\n", t->Setup[I830_TEXREG_TM0S3]);
+      fprintf(stderr, "TM0S4 : 0x%08x\n", t->Setup[I830_TEXREG_TM0S4]);
+      fprintf(stderr, "NOP0 : 0x%08x\n", t->Setup[I830_TEXREG_NOP0]);
+      fprintf(stderr, "NOP1 : 0x%08x\n", t->Setup[I830_TEXREG_NOP1]);
+      fprintf(stderr, "NOP2 : 0x%08x\n", t->Setup[I830_TEXREG_NOP2]);
+      fprintf(stderr, "MCS : 0x%08x\n", t->Setup[I830_TEXREG_MCS]);
+   }
+}
+
+void i830DumpTextureBlendState( i830ContextPtr imesa, int unit )
+{
+   GLuint *TexBlend = imesa->TexBlend[unit];
+   GLuint length = imesa->TexBlendWordsUsed[unit];
+   int i;
+
+   fprintf(stderr, "%s : unit %d : length %d\n", __FUNCTION__, unit, length);
+   for(i = 0; i < length; i++) {
+      fprintf(stderr, "[%d] : 0x%08x\n", i, TexBlend[i]);
+   }
+}
+
+void i830VertexSanity( i830ContextPtr imesa, drmI830Vertex vertex )
+{
+   I830SAREAPtr sarea = imesa->sarea;
+   char *prim_name;
+   int size = 0;
+   int vfmt_size = 0;
+   int hw_nr_vertex = 0;
+   int hw_start_vertex = 0;
+
+   /* Do a bunch of sanity checks on the vertices sent to the hardware */
+
+   size = vertex.used - 4;
+   if(imesa->vertex_size && (size % imesa->vertex_size) != 0) {
+      fprintf(stderr, "\n\nVertex size does not match imesa "
+             "internal state\n");
+      fprintf(stderr, "Buffer size : %d\n", size);
+      fprintf(stderr, "Vertex size : %d\n", imesa->vertex_size);
+   }
+
+   /* Check to see if the vertex format is good, and get its size */
+   if (sarea->ContextState[I830_CTXREG_VF] == TINY_VERTEX_FORMAT) {
+      vfmt_size = 16; /* 4 dwords */
+   } else if (sarea->ContextState[I830_CTXREG_VF] == 
+             NOTEX_VERTEX_FORMAT) {
+      vfmt_size = 24; /* 6 dwords */
+   } else if (sarea->ContextState[I830_CTXREG_VF] == 
+             TEX0_VERTEX_FORMAT) {
+      vfmt_size = 32; /* 8 dwords */
+      if (sarea->ContextState[I830_CTXREG_VF2] != NON_PROJ_VF2) {
+        fprintf(stderr, "\n\nTex 0 vertex format, but proj "
+                "texturing\n");
+      }
+   } else if(sarea->ContextState[I830_CTXREG_VF] == 
+            TEX1_VERTEX_FORMAT) {
+      if (sarea->ContextState[I830_CTXREG_VF2] == NON_PROJ_VF2)
+       vfmt_size = 40; /* 10 dwords */
+      else
+       vfmt_size = 48; /* 12 dwords */
+   } else {
+      fprintf(stderr, "\n\nUnknown vertex format : vf : %08x "
+             "vf2 : %08x\n",
+             sarea->ContextState[I830_CTXREG_VF],
+             sarea->ContextState[I830_CTXREG_VF2]);
+   }
+
+   if(vfmt_size && (size % vfmt_size) != 0) {
+      fprintf(stderr, "\n\nVertex size does not match hardware "
+             "internal state\n");
+      fprintf(stderr, "Buffer size : %d\n", size);
+      fprintf(stderr, "Vertex size : %d\n", vfmt_size);
+   }
+
+   switch(sarea->vertex_prim) {
+   case PRIM3D_POINTLIST:
+      hw_start_vertex = 0;
+      hw_nr_vertex = 1;
+      prim_name = "PointList";
+      break;
+
+   case PRIM3D_LINELIST:
+      hw_start_vertex = 0;
+      hw_nr_vertex = 2;
+      prim_name = "LineList";
+      break;
+
+   case PRIM3D_LINESTRIP:
+      hw_start_vertex = 2;
+      hw_nr_vertex = 1;
+      prim_name = "LineStrip";
+      break;
+
+   case PRIM3D_TRILIST:
+      hw_start_vertex = 0;
+      hw_nr_vertex = 3;
+      prim_name = "TriList";
+      break;
+
+   case PRIM3D_TRISTRIP:
+      hw_start_vertex = 3;
+      hw_nr_vertex = 1;
+      prim_name = "TriStrip";
+      break;
+
+   case PRIM3D_TRIFAN:
+      hw_start_vertex = 3;
+      hw_nr_vertex = 1;
+      prim_name = "TriFan";
+      break;
+
+   case PRIM3D_POLY:
+      hw_start_vertex = 3;
+      hw_nr_vertex = 1;
+      prim_name = "Polygons";
+      break;
+   default:
+      prim_name = "Unknown";
+      fprintf(stderr, "\n\nUnknown primitive type : %08x\n",
+             sarea->vertex_prim);
+   }
+           
+   if (hw_nr_vertex && vfmt_size) {
+      int temp_size = size - (hw_start_vertex * vfmt_size);
+      int remaining = (temp_size % (hw_nr_vertex * vfmt_size));
+
+      if (remaining != 0) {
+        fprintf(stderr, "\n\nThis buffer contains an improper"
+                " multiple of vertices for this primitive : %s\n",
+                prim_name);
+        fprintf(stderr, "Number of vertices in buffer : %d\n",
+                size / vfmt_size);
+        fprintf(stderr, "temp_size : %d\n", temp_size);
+        fprintf(stderr, "remaining vertices : %d", 
+                remaining / vfmt_size);
+      }
+   }
+   if (1) {
+      fprintf(stderr, "\n\nPrim name (%s), vertices (%d)\n",
+             prim_name,
+             size / vfmt_size);
+   }
+}
+
+void i830EmitHwStateLockedDebug( i830ContextPtr imesa )
+{
+   int i;
+
+   if ((imesa->dirty & I830_UPLOAD_TEX0_IMAGE) && imesa->CurrentTexObj[0]) {
+      i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[0]);
+   }
+
+   if ((imesa->dirty & I830_UPLOAD_TEX1_IMAGE) && imesa->CurrentTexObj[1]) {
+      i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[1]);
+   }
+
+   if (imesa->dirty & I830_UPLOAD_CTX) {
+      memcpy( imesa->sarea->ContextState,
+            imesa->Setup, sizeof(imesa->Setup) );
+      i830DumpContextState(imesa);
+   }
+
+   for(i = 0; i < I830_TEXTURE_COUNT; i++) {
+      if ((imesa->dirty & I830_UPLOAD_TEX_N(i)) && imesa->CurrentTexObj[i]) {
+        imesa->sarea->dirty |= I830_UPLOAD_TEX_N(i);
+        memcpy(imesa->sarea->TexState[i],
+               imesa->CurrentTexObj[i]->Setup,
+               sizeof(imesa->sarea->TexState[i]));
+        i830DumpTextureState(imesa, i);
+      }
+   }
+   /* Need to figure out if texturing state, or enable changed. */
+
+   for(i = 0; i < I830_TEXBLEND_COUNT; i++) {
+      if (imesa->dirty & I830_UPLOAD_TEXBLEND_N(i)) {
+        imesa->sarea->dirty |= I830_UPLOAD_TEXBLEND_N(i);
+        memcpy(imesa->sarea->TexBlendState[i],imesa->TexBlend[i],
+               imesa->TexBlendWordsUsed[i] * 4);
+        imesa->sarea->TexBlendStateWordsUsed[i] =
+          imesa->TexBlendWordsUsed[i];
+        i830DumpTextureBlendState(imesa, i);
+      }
+   }
+
+   if (imesa->dirty & I830_UPLOAD_BUFFERS) {
+      memcpy( imesa->sarea->BufferState,imesa->BufferSetup, 
+             sizeof(imesa->BufferSetup) );
+      i830DumpBufferState(imesa);
+   }
+
+   if (imesa->dirty & I830_UPLOAD_STIPPLE) {
+      fprintf(stderr, "UPLOAD_STIPPLE\n");
+      memcpy( imesa->sarea->StippleState,imesa->StippleSetup, 
+             sizeof(imesa->StippleSetup) );
+      i830DumpStippleState(imesa);
+   }
+
+   if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_SHARED) {
+      memcpy( imesa->sarea->Palette[0],imesa->palette,
+             sizeof(imesa->sarea->Palette[0]));
+   } else {
+      i830TextureObjectPtr p;
+      if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(0)) {
+        p = imesa->CurrentTexObj[0];
+        memcpy( imesa->sarea->Palette[0],p->palette,
+               sizeof(imesa->sarea->Palette[0]));
+      }
+      if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(1)) {
+        p = imesa->CurrentTexObj[1];
+        memcpy( imesa->sarea->Palette[1],
+                p->palette,
+                sizeof(imesa->sarea->Palette[1]));
+      }
+   }
+   imesa->sarea->dirty |= (imesa->dirty & ~(I830_UPLOAD_TEX_MASK | 
+                                           I830_UPLOAD_TEXBLEND_MASK));
+
+   imesa->upload_cliprects = GL_TRUE;
+   imesa->dirty = 0;
+}
diff --git a/src/mesa/drivers/dri/i830/i830_debug.h b/src/mesa/drivers/dri/i830/i830_debug.h
new file mode 100644 (file)
index 0000000..deb84f7
--- /dev/null
@@ -0,0 +1,48 @@
+/**************************************************************************
+
+Copyright 2001 2d3d Inc., Delray Beach, FL
+
+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.
+
+**************************************************************************/
+
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_debug.h,v 1.3 2002/12/10 01:26:53 dawes Exp $ */
+
+/*
+ * Author:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ */
+
+/* Defines for sanity checking and debug output */
+#ifndef I830DEBUG_INC
+#define I830DEBUG_INC
+
+
+void i830DumpContextState( i830ContextPtr imesa );
+void i830DumpStippleState( i830ContextPtr imesa );
+void i830DumpBufferState( i830ContextPtr imesa );
+void i830DumpTextureState( i830ContextPtr imesa, int unit );
+void i830DumpTextureBlendState( i830ContextPtr imesa, int unit );
+void i830VertexSanity( i830ContextPtr imesa, drmI830Vertex vertex );
+void i830EmitHwStateLockedDebug( i830ContextPtr imesa );
+
+#endif
diff --git a/src/mesa/drivers/dri/i830/i830_ioctl.c b/src/mesa/drivers/dri/i830/i830_ioctl.c
new file mode 100644 (file)
index 0000000..607b813
--- /dev/null
@@ -0,0 +1,841 @@
+
+/**************************************************************************
+
+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.
+
+**************************************************************************/
+
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c,v 1.5 2002/12/10 01:26:53 dawes Exp $ */
+
+/*
+ * Author:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ *   Graeme Fisher <graeme@2d3d.co.za>
+ *   Abraham vd Merwe <abraham@2d3d.co.za>
+ *
+ * Heavily based on the I810 driver, which was written by:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "dd.h"
+#include "swrast/swrast.h"
+
+#include "mm.h"
+
+#include "i830_screen.h"
+#include "i830_dri.h"
+
+#include "i830_context.h"
+#include "i830_ioctl.h"
+#include "i830_state.h"
+#include "i830_debug.h"
+
+#include "drm.h"
+
+static drmBufPtr i830_get_buffer_ioctl( i830ContextPtr imesa )
+{
+   drmI830DMA dma;
+   drmBufPtr buf;
+   int retcode,i = 0;
+   while (1) {
+      retcode = drmCommandWriteRead(imesa->driFd, 
+                                   DRM_I830_GETBUF, 
+                                   &dma, 
+                                   sizeof(drmI830DMA));
+      if (dma.granted == 1 && retcode == 0)
+       break;
+
+      if (++i > 1000) {
+        imesa->sarea->perf_boxes |= I830_BOX_WAIT;
+        retcode = drmCommandNone(imesa->driFd, DRM_I830_FLUSH);
+        i = 0;
+      }
+   }
+
+   buf = &(imesa->i830Screen->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;
+}
+
+static void i830ClearDrawQuad(i830ContextPtr imesa, float left, 
+                                float right,
+                                float bottom, float top, GLubyte red,
+                                GLubyte green, GLubyte blue, GLubyte alpha)
+{
+    GLuint *vb = i830AllocDmaLowLocked( imesa, 128 );
+    i830Vertex tmp;
+    int i;
+
+    /* PRIM3D_TRIFAN */
+
+    /* initial vertex, left bottom */
+    tmp.v.x = left;
+    tmp.v.y = bottom;
+    tmp.v.z = 1.0;
+    tmp.v.w = 1.0;
+    tmp.v.color.red = red;
+    tmp.v.color.green = green;
+    tmp.v.color.blue = blue;
+    tmp.v.color.alpha = alpha;
+    tmp.v.specular.red = 0;
+    tmp.v.specular.green = 0;
+    tmp.v.specular.blue = 0;
+    tmp.v.specular.alpha = 0;
+    tmp.v.u0 = 0.0f;
+    tmp.v.v0 = 0.0f;
+    for (i = 0 ; i < 8 ; i++)
+        vb[i] = tmp.ui[i];
+
+    /* right bottom */
+    vb += 8;
+    tmp.v.x = right;
+    for (i = 0 ; i < 8 ; i++)
+        vb[i] = tmp.ui[i];
+
+    /* right top */
+    vb += 8;
+    tmp.v.y = top;
+    for (i = 0 ; i < 8 ; i++)
+        vb[i] = tmp.ui[i];
+
+    /* left top */
+    vb += 8;
+    tmp.v.x = left;
+    for (i = 0 ; i < 8 ; i++)
+        vb[i] = tmp.ui[i];
+}
+
+static void i830ClearWithTris(GLcontext *ctx, GLbitfield mask,
+                                GLboolean all,
+                                GLint cx, GLint cy, GLint cw, GLint ch)
+{
+   i830ContextPtr imesa = I830_CONTEXT( ctx );
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+   i830ScreenPrivate *i830Screen = imesa->i830Screen;
+   I830SAREAPtr sarea = imesa->sarea;
+   GLuint old_vertex_prim;
+   GLuint old_dirty;
+   int x0, y0, x1, y1;
+
+   if (I830_DEBUG & DEBUG_IOCTL) 
+     fprintf(stderr, "Clearing with triangles\n");
+
+   old_dirty = imesa->dirty & ~I830_UPLOAD_CLIPRECTS;
+   /* Discard all the dirty flags except the cliprect one, reset later */
+   imesa->dirty &= I830_UPLOAD_CLIPRECTS;
+
+   if(!all) {
+      x0 = cx;
+      y0 = cy;
+      x1 = x0 + cw;
+      y1 = y0 + ch;
+   } else {
+      x0 = 0;
+      y0 = 0;
+      x1 = x0 + dPriv->w;
+      y1 = y0 + dPriv->h;
+   }
+
+   /* Clip to Screen */
+   if (x0 < 0) x0 = 0;
+   if (y0 < 0) y0 = 0;
+   if (x1 > i830Screen->width-1) x1 = i830Screen->width-1;
+   if (y1 > i830Screen->height-1) y1 = i830Screen->height-1;
+
+   LOCK_HARDWARE(imesa);
+   memcpy(sarea->ContextState,
+         imesa->Init_Setup,
+         sizeof(imesa->Setup) );
+   memcpy(sarea->BufferState,
+         imesa->BufferSetup,
+         sizeof(imesa->BufferSetup) );
+   sarea->StippleState[I830_STPREG_ST1] = 0;
+
+   old_vertex_prim = imesa->hw_primitive;
+   imesa->hw_primitive = PRIM3D_TRIFAN;
+
+   if(mask & DD_FRONT_LEFT_BIT) {
+      GLuint tmp = sarea->ContextState[I830_CTXREG_ENABLES_2];
+
+      sarea->dirty |= (I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS |
+                      I830_UPLOAD_TEXBLEND0);
+
+      sarea->TexBlendState[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
+                                   TEXPIPE_COLOR |
+                                   ENABLE_TEXOUTPUT_WRT_SEL |
+                                   TEXOP_OUTPUT_CURRENT |
+                                   DISABLE_TEX_CNTRL_STAGE |
+                                   TEXOP_SCALE_1X |
+                                   TEXOP_MODIFY_PARMS |
+                                   TEXOP_LAST_STAGE |
+                                   TEXBLENDOP_ARG1);
+      sarea->TexBlendState[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
+                                   TEXPIPE_ALPHA |
+                                   ENABLE_TEXOUTPUT_WRT_SEL |
+                                   TEXOP_OUTPUT_CURRENT |
+                                   TEXOP_SCALE_1X |
+                                   TEXOP_MODIFY_PARMS |
+                                   TEXBLENDOP_ARG1);
+      sarea->TexBlendState[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
+                                   TEXPIPE_COLOR |
+                                   TEXBLEND_ARG1 |
+                                   TEXBLENDARG_MODIFY_PARMS |
+                                   TEXBLENDARG_CURRENT);
+      sarea->TexBlendState[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
+                                   TEXPIPE_ALPHA |
+                                   TEXBLEND_ARG1 |
+                                   TEXBLENDARG_MODIFY_PARMS |
+                                   TEXBLENDARG_CURRENT);
+      sarea->TexBlendStateWordsUsed[0] = 4;
+
+      tmp &= ~(ENABLE_STENCIL_WRITE | ENABLE_DEPTH_WRITE);
+      tmp |= (DISABLE_STENCIL_WRITE | 
+             DISABLE_DEPTH_WRITE |
+             (imesa->mask_red << WRITEMASK_RED_SHIFT) |
+             (imesa->mask_green << WRITEMASK_GREEN_SHIFT) |
+             (imesa->mask_blue << WRITEMASK_BLUE_SHIFT) |
+             (imesa->mask_alpha << WRITEMASK_ALPHA_SHIFT));
+      sarea->ContextState[I830_CTXREG_ENABLES_2] = tmp;
+
+      if(0)
+       fprintf(stderr, "fcdq : r_mask(%d) g_mask(%d) b_mask(%d) a_mask(%d)\n",
+               imesa->mask_red, imesa->mask_green, imesa->mask_blue,
+               imesa->mask_alpha);
+
+      sarea->BufferState[I830_DESTREG_CBUFADDR] = i830Screen->fbOffset;
+
+      if(0)
+       fprintf(stderr, "fcdq : x0(%d) x1(%d) y0(%d) y1(%d)\n"
+               "r(0x%x) g(0x%x) b(0x%x) a(0x%x)\n",
+               x0, x1, y0, y1, imesa->clear_red, imesa->clear_green,
+               imesa->clear_blue, imesa->clear_alpha);
+
+      i830ClearDrawQuad(imesa, (float)x0, (float)x1, (float)y0, (float)y1,
+                        imesa->clear_red, imesa->clear_green,
+                        imesa->clear_blue, imesa->clear_alpha);
+      i830FlushPrimsLocked( imesa );
+   }
+
+   if(mask & DD_BACK_LEFT_BIT) {
+      GLuint tmp = sarea->ContextState[I830_CTXREG_ENABLES_2];
+
+      sarea->dirty |= (I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS |
+                      I830_UPLOAD_TEXBLEND0);
+
+      sarea->TexBlendState[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
+                                   TEXPIPE_COLOR |
+                                   ENABLE_TEXOUTPUT_WRT_SEL |
+                                   TEXOP_OUTPUT_CURRENT |
+                                   DISABLE_TEX_CNTRL_STAGE |
+                                   TEXOP_SCALE_1X |
+                                   TEXOP_MODIFY_PARMS |
+                                   TEXOP_LAST_STAGE |
+                                   TEXBLENDOP_ARG1);
+      sarea->TexBlendState[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
+                                   TEXPIPE_ALPHA |
+                                   ENABLE_TEXOUTPUT_WRT_SEL |
+                                   TEXOP_OUTPUT_CURRENT |
+                                   TEXOP_SCALE_1X |
+                                   TEXOP_MODIFY_PARMS |
+                                   TEXBLENDOP_ARG1);
+      sarea->TexBlendState[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
+                                   TEXPIPE_COLOR |
+                                   TEXBLEND_ARG1 |
+                                   TEXBLENDARG_MODIFY_PARMS |
+                                   TEXBLENDARG_CURRENT);
+      sarea->TexBlendState[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
+                                   TEXPIPE_ALPHA |
+                                   TEXBLEND_ARG2 |
+                                   TEXBLENDARG_MODIFY_PARMS |
+                                   TEXBLENDARG_CURRENT);
+      sarea->TexBlendStateWordsUsed[0] = 4;
+
+      tmp &= ~(ENABLE_STENCIL_WRITE | ENABLE_DEPTH_WRITE);
+      tmp |= (DISABLE_STENCIL_WRITE | 
+             DISABLE_DEPTH_WRITE |
+             (imesa->mask_red << WRITEMASK_RED_SHIFT) |
+             (imesa->mask_green << WRITEMASK_GREEN_SHIFT) |
+             (imesa->mask_blue << WRITEMASK_BLUE_SHIFT) |
+             (imesa->mask_alpha << WRITEMASK_ALPHA_SHIFT));
+
+      if(0)
+       fprintf(stderr, "bcdq : r_mask(%d) g_mask(%d) b_mask(%d) a_mask(%d)\n",
+               imesa->mask_red, imesa->mask_green, imesa->mask_blue,
+               imesa->mask_alpha);
+
+      sarea->ContextState[I830_CTXREG_ENABLES_2] = tmp;
+
+      sarea->BufferState[I830_DESTREG_CBUFADDR] = i830Screen->backOffset;
+
+      if(0)
+       fprintf(stderr, "bcdq : x0(%d) x1(%d) y0(%d) y1(%d)\n"
+               "r(0x%x) g(0x%x) b(0x%x) a(0x%x)\n",
+               x0, x1, y0, y1, imesa->clear_red, imesa->clear_green,
+               imesa->clear_blue, imesa->clear_alpha);
+
+      i830ClearDrawQuad(imesa, (float)x0, (float)x1, (float)y0, (float)y1,
+                     imesa->clear_red, imesa->clear_green,
+                     imesa->clear_blue, imesa->clear_alpha);
+      i830FlushPrimsLocked( imesa );
+   }
+
+   if(mask & DD_STENCIL_BIT) {
+      GLuint s_mask = ctx->Stencil.WriteMask[0];
+
+      sarea->dirty |= (I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS |
+                      I830_UPLOAD_TEXBLEND0);
+
+      sarea->TexBlendState[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
+                                   TEXPIPE_COLOR |
+                                   ENABLE_TEXOUTPUT_WRT_SEL |
+                                   TEXOP_OUTPUT_CURRENT |
+                                   DISABLE_TEX_CNTRL_STAGE |
+                                   TEXOP_SCALE_1X |
+                                   TEXOP_MODIFY_PARMS |
+                                   TEXOP_LAST_STAGE |
+                                   TEXBLENDOP_ARG1);
+      sarea->TexBlendState[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
+                                   TEXPIPE_ALPHA |
+                                   ENABLE_TEXOUTPUT_WRT_SEL |
+                                   TEXOP_OUTPUT_CURRENT |
+                                   TEXOP_SCALE_1X |
+                                   TEXOP_MODIFY_PARMS |
+                                   TEXBLENDOP_ARG1);
+      sarea->TexBlendState[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
+                                   TEXPIPE_COLOR |
+                                   TEXBLEND_ARG1 |
+                                   TEXBLENDARG_MODIFY_PARMS |
+                                   TEXBLENDARG_CURRENT);
+      sarea->TexBlendState[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
+                                   TEXPIPE_ALPHA |
+                                   TEXBLEND_ARG2 |
+                                   TEXBLENDARG_MODIFY_PARMS |
+                                   TEXBLENDARG_CURRENT);
+      sarea->TexBlendStateWordsUsed[0] = 4;
+
+      sarea->ContextState[I830_CTXREG_ENABLES_1] |= (ENABLE_STENCIL_TEST |
+                                                    ENABLE_DEPTH_TEST);
+
+      sarea->ContextState[I830_CTXREG_ENABLES_2] &= ~(ENABLE_STENCIL_WRITE |
+                                                    ENABLE_DEPTH_WRITE |
+                                                    ENABLE_COLOR_WRITE);
+
+      sarea->ContextState[I830_CTXREG_ENABLES_2] |= 
+        (ENABLE_STENCIL_WRITE |
+         DISABLE_DEPTH_WRITE |
+         (1 << WRITEMASK_RED_SHIFT) |
+         (1 << WRITEMASK_GREEN_SHIFT) |
+         (1 << WRITEMASK_BLUE_SHIFT) |
+         (1 << WRITEMASK_ALPHA_SHIFT) |
+         ENABLE_COLOR_WRITE);
+
+      sarea->ContextState[I830_CTXREG_STATE4] &= 
+        ~MODE4_ENABLE_STENCIL_WRITE_MASK;
+
+      sarea->ContextState[I830_CTXREG_STATE4] |= 
+        (ENABLE_STENCIL_WRITE_MASK |
+         STENCIL_WRITE_MASK(s_mask));
+
+      sarea->ContextState[I830_CTXREG_STENCILTST] &= 
+        ~(STENCIL_OPS_MASK |
+          STENCIL_REF_VALUE_MASK |
+          ENABLE_STENCIL_TEST_FUNC_MASK);
+
+      sarea->ContextState[I830_CTXREG_STENCILTST] |= 
+        (ENABLE_STENCIL_PARMS |
+         ENABLE_STENCIL_REF_VALUE |
+         ENABLE_STENCIL_TEST_FUNC |
+         STENCIL_FAIL_OP(STENCILOP_REPLACE) |
+         STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) |
+         STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE) |
+         STENCIL_REF_VALUE((ctx->Stencil.Clear & 0xff)) |
+         STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS));
+
+      if(0) 
+       fprintf(stderr, "Enables_1 (0x%x) Enables_2 (0x%x) StenTst (0x%x)\n"
+               "Modes_4 (0x%x)\n",
+               sarea->ContextState[I830_CTXREG_ENABLES_1],
+               sarea->ContextState[I830_CTXREG_ENABLES_2],
+               sarea->ContextState[I830_CTXREG_STENCILTST],
+               sarea->ContextState[I830_CTXREG_STATE4]);
+
+      sarea->BufferState[I830_DESTREG_CBUFADDR] = i830Screen->fbOffset;
+      
+      i830ClearDrawQuad(imesa, (float)x0, (float)x1, (float)y0, (float)y1,
+                          255, 255, 255, 255);
+      i830FlushPrimsLocked( imesa );
+   }
+
+   UNLOCK_HARDWARE(imesa);
+   imesa->dirty = old_dirty;
+   imesa->dirty |= (I830_UPLOAD_CTX |
+                   I830_UPLOAD_BUFFERS |
+                   I830_UPLOAD_TEXBLEND0);
+
+   imesa->hw_primitive = old_vertex_prim;
+}
+
+static void i830Clear(GLcontext *ctx, GLbitfield mask, GLboolean all,
+                     GLint cx1, GLint cy1, GLint cw, GLint ch)
+{
+   i830ContextPtr imesa = I830_CONTEXT( ctx );
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+   const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
+   drmI830Clear clear;
+   GLbitfield tri_mask = 0;
+   int i;
+   GLint cx, cy;
+
+   /* flip top to bottom */
+   cy = dPriv->h-cy1-ch;
+   cx = cx1 + imesa->drawX;
+   cy += imesa->drawY;
+
+   if(0) fprintf(stderr, "\nClearColor : 0x%08x\n", imesa->ClearColor);
+   
+   clear.flags = 0;
+   clear.clear_color = imesa->ClearColor;
+   clear.clear_depth = 0;
+   clear.clear_colormask = 0;
+   clear.clear_depthmask = 0;
+
+   I830_FIREVERTICES( imesa );
+
+   if (mask & DD_FRONT_LEFT_BIT) {
+      if(colorMask == ~0) {
+        clear.flags |= I830_FRONT;
+      } else {
+        tri_mask |= DD_FRONT_LEFT_BIT;
+      }
+      mask &= ~DD_FRONT_LEFT_BIT;
+   }
+
+   if (mask & DD_BACK_LEFT_BIT) {
+      if(colorMask == ~0) {
+        clear.flags |= I830_BACK;
+      } else {
+        tri_mask |= DD_BACK_LEFT_BIT;
+      }
+      mask &= ~DD_BACK_LEFT_BIT;
+   }
+
+   if (mask & DD_DEPTH_BIT) {
+      clear.flags |= I830_DEPTH;
+      clear.clear_depthmask = imesa->depth_clear_mask;
+      clear.clear_depth = (GLuint)(ctx->Depth.Clear * imesa->ClearDepth);
+      mask &= ~DD_DEPTH_BIT;
+   }
+
+   if((mask & DD_STENCIL_BIT) && imesa->hw_stencil) {
+      if (ctx->Stencil.WriteMask[0] != 0xff) {
+        tri_mask |= DD_STENCIL_BIT;
+      } else {
+        clear.flags |= I830_DEPTH;
+        clear.clear_depthmask |= imesa->stencil_clear_mask;
+        clear.clear_depth |= (ctx->Stencil.Clear & 0xff) << 24;
+      }
+      mask &= ~DD_STENCIL_BIT;
+   }
+
+   /* First check for clears that need to happen with triangles */
+   if(tri_mask) {
+      i830ClearWithTris(ctx, tri_mask, all, cx, cy, cw, ch);
+   }
+
+   if (clear.flags) {
+      LOCK_HARDWARE( imesa );
+
+      for (i = 0 ; i < imesa->numClipRects ; ) 
+      {         
+        int nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, imesa->numClipRects);
+        XF86DRIClipRectRec *box = imesa->pClipRects;    
+        drm_clip_rect_t *b = (drm_clip_rect_t *)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++ = *(drm_clip_rect_t *)&box[i];
+              n++;
+           }
+        }
+
+        imesa->sarea->nbox = n;
+        drmCommandWrite(imesa->driFd, DRM_I830_CLEAR,
+                        &clear, sizeof(drmI830Clear));
+      }
+
+      UNLOCK_HARDWARE( imesa );
+      imesa->upload_cliprects = GL_TRUE;
+   }
+
+   if (mask)
+      _swrast_Clear( ctx, mask, all, cx1, cy1, cw, ch );
+}
+
+
+
+/*
+ * Copy the back buffer to the front buffer. 
+ */
+void i830CopyBuffer( const __DRIdrawablePrivate *dPriv ) 
+{
+   i830ContextPtr imesa;
+   XF86DRIClipRectPtr pbox;
+   int nbox, i, tmp;
+
+   assert(dPriv);
+   assert(dPriv->driContextPriv);
+   assert(dPriv->driContextPriv->driverPrivate);
+
+   imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate;
+
+   I830_FIREVERTICES( imesa );
+   LOCK_HARDWARE( imesa );
+
+   imesa->sarea->perf_boxes |= imesa->perf_boxes;
+   imesa->perf_boxes = 0;
+
+   pbox = dPriv->pClipRects;
+   nbox = dPriv->numClipRects;
+
+   for (i = 0 ; i < nbox ; )
+   {
+      int nr = MIN2(i + I830_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_I830_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) {
+      i830WaitAge(imesa, imesa->lastSwap);
+   }
+
+   imesa->lastSwap = tmp;
+   imesa->upload_cliprects = GL_TRUE;
+}
+
+/* Flip the front & back buffes
+ */
+void i830PageFlip( const __DRIdrawablePrivate *dPriv )
+{
+#if 0
+   i830ContextPtr imesa;
+   int tmp, ret;
+
+   if (I830_DEBUG & DEBUG_IOCTL)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   assert(dPriv);
+   assert(dPriv->driContextPriv);
+   assert(dPriv->driContextPriv->driverPrivate);
+
+   imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate;
+
+   I830_FIREVERTICES( imesa );
+   LOCK_HARDWARE( imesa );
+
+   imesa->sarea->perf_boxes |= imesa->perf_boxes;
+   imesa->perf_boxes = 0;
+
+   if (dPriv->pClipRects) {
+      *(XF86DRIClipRectRec *)imesa->sarea->boxes = dPriv->pClipRects[0];
+      imesa->sarea->nbox = 1;
+   }
+
+   ret = drmCommandNone(imesa->driFd, DRM_I830_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) {
+      i830WaitAge(imesa, imesa->lastSwap);
+   }
+
+   i830SetDrawBuffer( imesa->glCtx, imesa->glCtx->Color.DriverDrawBuffer );
+   imesa->upload_cliprects = GL_TRUE;
+   imesa->lastSwap = tmp;
+#endif
+}
+
+/* This waits for *everybody* to finish rendering -- overkill.
+ */
+void i830DmaFinish( i830ContextPtr imesa  )
+{
+   I830_FIREVERTICES( imesa );
+   LOCK_HARDWARE_QUIESCENT( imesa );
+   UNLOCK_HARDWARE( imesa );
+}
+
+void i830RegetLockQuiescent( i830ContextPtr imesa )
+{
+   drmUnlock(imesa->driFd, imesa->hHWContext);
+   i830GetLock( imesa, DRM_LOCK_QUIESCENT );
+}
+
+void i830WaitAgeLocked( i830ContextPtr imesa, int age )
+{
+   int i = 0;
+   while (++i < 5000) {
+      drmCommandNone(imesa->driFd, DRM_I830_GETAGE);
+      if (GET_DISPATCH_AGE(imesa) >= age) return;
+      imesa->sarea->perf_boxes |= I830_BOX_WAIT;
+      UNLOCK_HARDWARE( imesa );
+      if (I830_DEBUG & DEBUG_SLEEP) fprintf(stderr, ".");
+      usleep(1);
+      LOCK_HARDWARE( imesa );
+   }
+   /* If that didn't work, just do a flush:
+    */
+   drmCommandNone(imesa->driFd, DRM_I830_FLUSH); 
+}
+
+void i830WaitAge( i830ContextPtr imesa, int age  ) 
+{
+   int i = 0;
+   if (GET_DISPATCH_AGE(imesa) >= age) return;
+
+   while (1) {
+      drmCommandNone(imesa->driFd, DRM_I830_GETAGE);
+      if (GET_DISPATCH_AGE(imesa) >= age) return;
+      imesa->perf_boxes |= I830_BOX_WAIT;
+
+      if (imesa->do_irqs) {
+        drmI830IrqEmit ie;
+        drmI830IrqWait iw;
+        int ret;
+      
+        ie.irq_seq = &iw.irq_seq;
+        
+        LOCK_HARDWARE( imesa ); 
+        ret = drmCommandWriteRead( imesa->driFd, DRM_I830_IRQ_EMIT, &ie, sizeof(ie) );
+        if ( ret ) {
+           fprintf( stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret );
+           exit(1);
+        }
+        UNLOCK_HARDWARE(imesa);
+        
+        ret = drmCommandWrite( imesa->driFd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );
+        if ( ret ) {
+           fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret );
+           exit(1);
+        }
+      } else {
+        if (++i > 5000) usleep(1); 
+      }
+   }
+}
+
+static void age_imesa( i830ContextPtr imesa, int age )
+{
+   if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->base.timestamp = age;
+   if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->base.timestamp = age;
+}
+
+void i830FlushPrimsLocked( i830ContextPtr imesa )
+{
+   XF86DRIClipRectPtr pbox = (XF86DRIClipRectPtr)imesa->pClipRects;
+   int nbox = imesa->numClipRects;
+   drmBufPtr buffer = imesa->vertex_buffer;
+   I830SAREAPtr sarea = imesa->sarea;
+   drmI830Vertex vertex;
+   int i, nr;
+
+   if (I830_DEBUG & DEBUG_IOCTL) 
+      fprintf(stderr, "%s dirty: %08x\n", __FUNCTION__, imesa->dirty);
+
+
+   vertex.idx = buffer->idx;
+   vertex.used = imesa->vertex_low;
+   vertex.discard = 0;
+   sarea->vertex_prim = imesa->hw_primitive;
+
+   /* Reset imesa vars:
+    */
+   imesa->vertex_buffer = 0;
+   imesa->vertex_addr = 0;
+   imesa->vertex_low = 0;
+   imesa->vertex_high = 0;
+   imesa->vertex_last_prim = 0;
+
+   if (imesa->dirty) {
+      if (I830_DEBUG & DEBUG_SANITY)
+        i830EmitHwStateLockedDebug(imesa);
+      else
+        i830EmitHwStateLocked(imesa);
+   }
+
+   if (I830_DEBUG & DEBUG_IOCTL)
+      fprintf(stderr,"%s: Vertex idx %d used %d discard %d\n", 
+             __FUNCTION__, vertex.idx, vertex.used, vertex.discard);
+
+   if (!nbox) {
+      vertex.used = 0;
+      vertex.discard = 1;
+      if (drmCommandWrite (imesa->driFd, DRM_I830_VERTEX, 
+                          &vertex, sizeof(drmI830Vertex))) {
+        fprintf(stderr, "DRM_I830_VERTEX: %d\n",  -errno);
+        UNLOCK_HARDWARE(imesa);
+        exit(1);
+      }
+      return;
+   }
+
+   for (i = 0 ; i < nbox ; i = nr ) {
+      XF86DRIClipRectPtr b = sarea->boxes;
+      int j;
+
+      nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, nbox);
+      sarea->nbox = nr - i;
+
+      for ( j = i ; j < nr ; j++) {
+        b[j-i] = pbox[j];
+      }
+
+      /* Finished with the buffer?
+       */
+      if (nr == nbox)
+        vertex.discard = 1;
+
+      /* Do a bunch of sanity checks on the vertices sent to the hardware */
+      if (I830_DEBUG & DEBUG_SANITY) {
+        i830VertexSanity(imesa, vertex);
+      
+        for ( j = 0 ; j < sarea->nbox ; j++) {
+           fprintf(stderr, "box %d/%d %d,%d %d,%d\n",
+                   j, sarea->nbox, b[j].x1, b[j].y1, b[j].x2, b[j].y2);
+        }
+      }
+
+      drmCommandWrite (imesa->driFd, DRM_I830_VERTEX, 
+                      &vertex, sizeof(drmI830Vertex));
+      age_imesa(imesa, imesa->sarea->last_enqueue);
+   }
+
+   imesa->dirty = 0;
+   imesa->upload_cliprects = GL_FALSE;
+}
+
+void i830FlushPrimsGetBufferLocked( i830ContextPtr imesa )
+{
+   if (imesa->vertex_buffer)
+     i830FlushPrimsLocked( imesa );
+   imesa->vertex_buffer = i830_get_buffer_ioctl( imesa );
+   imesa->vertex_addr = (char *)imesa->vertex_buffer->address;
+
+   /* leave room for instruction header & footer:
+    */
+   imesa->vertex_high = imesa->vertex_buffer->total - 4; 
+   imesa->vertex_low = 4;      
+   imesa->vertex_last_prim = imesa->vertex_low;
+}
+
+void i830FlushPrimsGetBuffer( i830ContextPtr imesa )
+{
+   LOCK_HARDWARE(imesa);
+   i830FlushPrimsGetBufferLocked( imesa );
+   UNLOCK_HARDWARE(imesa);
+}
+
+
+void i830FlushPrims( i830ContextPtr imesa )
+{
+   if (imesa->vertex_buffer) {
+      LOCK_HARDWARE( imesa );
+      i830FlushPrimsLocked( imesa );
+      UNLOCK_HARDWARE( imesa );
+   }
+}
+
+int i830_check_copy(int fd)
+{
+   return drmCommandNone(fd, DRM_I830_DOCOPY);
+}
+
+static void i830DDFlush( GLcontext *ctx )
+{
+   i830ContextPtr imesa = I830_CONTEXT( ctx );
+   I830_FIREVERTICES( imesa );
+}
+
+static void i830DDFinish( GLcontext *ctx  ) 
+{
+   i830ContextPtr imesa = I830_CONTEXT( ctx );
+   i830DmaFinish( imesa );
+}
+
+void i830DDInitIoctlFuncs( GLcontext *ctx )
+{
+   ctx->Driver.Flush = i830DDFlush;
+   ctx->Driver.Clear = i830Clear;
+   ctx->Driver.Finish = i830DDFinish;
+}
+
diff --git a/src/mesa/drivers/dri/i830/i830_ioctl.h b/src/mesa/drivers/dri/i830/i830_ioctl.h
new file mode 100644 (file)
index 0000000..4c64b8d
--- /dev/null
@@ -0,0 +1,105 @@
+
+/**************************************************************************
+
+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.
+
+**************************************************************************/
+
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h,v 1.3 2002/10/30 12:51:35 alanh Exp $ */
+
+/*
+ * Author:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ *   Graeme Fisher <graeme@2d3d.co.za>
+ *   Abraham vd Merwe <abraham@2d3d.co.za>
+ *
+ * Heavily based on the I810 driver, which was written by:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef I830_IOCTL_H
+#define I830_IOCTL_H
+
+#include "i830_context.h"
+
+GLuint *i830AllocDwords (i830ContextPtr imesa, int dwords);
+void i830EmitPrim( i830ContextPtr imesa );
+void i830FlushPrims( i830ContextPtr mmesa );
+void i830FlushPrimsLocked( i830ContextPtr mmesa );
+void i830FlushPrimsGetBuffer( i830ContextPtr imesa );
+void i830FlushPrimsGetBufferLocked( i830ContextPtr imesa );
+void i830WaitAgeLocked( i830ContextPtr imesa, int age );
+void i830WaitAge( i830ContextPtr imesa, int age );
+void i830DmaFinish( i830ContextPtr imesa );
+void i830RegetLockQuiescent( i830ContextPtr imesa );
+void i830DDInitIoctlFuncs( GLcontext *ctx );
+void i830CopyBuffer( const __DRIdrawablePrivate *dpriv );
+void i830PageFlip( const __DRIdrawablePrivate *dpriv );
+int i830_check_copy(int fd);
+
+#define I830_STATECHANGE(imesa, flag)                  \
+do {                                                   \
+   if (imesa->vertex_low != imesa->vertex_last_prim)   \
+      i830FlushPrims(imesa);                           \
+   imesa->dirty |= flag;                               \
+} while (0)
+
+
+#define I830_FIREVERTICES(imesa)       \
+do {                                   \
+   if (imesa->vertex_buffer) {         \
+      i830FlushPrims(imesa);           \
+}                                      \
+} while (0)
+
+
+static __inline GLuint *i830AllocDmaLow( i830ContextPtr imesa, int bytes )
+{
+   if (imesa->vertex_low + bytes > imesa->vertex_high) {
+      i830FlushPrimsGetBuffer( imesa );
+   }
+   
+   {
+      GLuint *start = (GLuint *)(imesa->vertex_addr + imesa->vertex_low);
+      imesa->vertex_low += bytes;
+      return start;
+   }
+}
+
+static __inline GLuint *i830AllocDmaLowLocked( i830ContextPtr imesa, 
+                                              int bytes )
+{
+   if (imesa->vertex_low + bytes > imesa->vertex_high) {
+      i830FlushPrimsGetBufferLocked( imesa );
+   }
+   
+   {
+      GLuint *start = (GLuint *)(imesa->vertex_addr + imesa->vertex_low);
+      imesa->vertex_low += bytes;
+      return start;
+   }
+}
+
+
+#endif
diff --git a/src/mesa/drivers/dri/i830/i830_render.c b/src/mesa/drivers/dri/i830/i830_render.c
new file mode 100644 (file)
index 0000000..5df05df
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * 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>
+ * Adapted for use on the I830:
+ *    Jeff Hartmann <jhartmann@2d3d.com>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_render.c,v 1.2 2002/12/10 01:26:53 dawes Exp $ */
+
+/*
+ * 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 "enums.h"
+
+#include "tnl/t_context.h"
+
+#include "i830_screen.h"
+#include "i830_dri.h"
+
+#include "i830_context.h"
+#include "i830_tris.h"
+#include "i830_state.h"
+#include "i830_vb.h"
+#include "i830_ioctl.h"
+
+/*
+ * Render unclipped vertex buffers by emitting vertices directly to
+ * dma buffers.  Use strip/fan hardware primitives where possible.
+ * Try to simulate missing primitives with indexed vertices.
+ */
+#define HAVE_POINTS      0  /* Has it, but can't use because subpixel has to
+                            * be adjusted for points on the I830/I845G
+                            */
+#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,
+   PRIM3D_LINELIST,
+   PRIM3D_LINESTRIP,
+   PRIM3D_LINESTRIP,
+   PRIM3D_TRILIST,
+   PRIM3D_TRISTRIP,
+   PRIM3D_TRIFAN,
+   0,
+   0,
+   PRIM3D_POLY
+};
+
+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
+};
+
+static const int scale_prim[GL_POLYGON+1] = {  
+   0,                          /* fallback case */
+   1,
+   2,
+   2,
+   1,
+   3,
+   3,
+   0,                          /* fallback case */
+   0,                          /* fallback case */
+   3
+};
+
+/* Fallback to normal rendering.  Should now never be called.
+ */
+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 );
+   I830_CONTEXT(ctx)->SetupNewInputs = VERT_BIT_CLIP;
+}
+
+
+#define LOCAL_VARS i830ContextPtr imesa = I830_CONTEXT(ctx)
+#define INIT( prim ) do {                                              \
+   I830_STATECHANGE(imesa, 0);                                         \
+   i830RasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] );      \
+} while (0)
+
+#define NEW_PRIMITIVE()  I830_STATECHANGE( imesa, 0 )
+#define NEW_BUFFER()  I830_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() \
+  (I830_DMA_BUF_SZ-8) / (imesa->vertex_size * 4)
+  
+#define EMIT_VERTS( ctx, j, nr ) \
+  i830_emit_contiguous_verts(ctx, j, (j)+(nr))  
+  
+#define TAG(x) i830_##x
+#include "tnl_dd/t_dd_dmatmp.h"
+  
+  
+/**********************************************************************/
+/*                          Render pipeline stage                     */
+/**********************************************************************/
+
+/* Heuristic for i830, which can only emit a single primitive per dma
+ * buffer, and has only a small number of dma buffers.
+ */
+static GLboolean choose_render( struct vertex_buffer *VB, int bufsz )
+{
+   int nr_prims = 0;
+   int nr_rprims = 0;
+   int nr_rverts = 0;
+   int rprim = 0;
+   int i = 0, length, flags = 0;
+
+   
+   for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length) {
+      flags = VB->Primitive[i];
+      length = VB->PrimitiveLength[i];
+      if (!length)
+        continue;
+
+      if (!hw_prim[flags & PRIM_MODE_MASK])
+        return GL_FALSE;
+
+      nr_prims++;
+      nr_rverts += length * scale_prim[flags & PRIM_MODE_MASK];
+
+      if (reduced_prim[flags&PRIM_MODE_MASK] != rprim) {
+        nr_rprims++;
+        rprim = reduced_prim[flags&PRIM_MODE_MASK];
+      }
+   }
+
+   nr_prims += i / bufsz; 
+   nr_rprims += nr_rverts / bufsz; 
+
+   if ((nr_prims > nr_rprims * 2) ||
+       (nr_prims > nr_rprims + 3)) 
+      return GL_FALSE;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean i830_run_render( GLcontext *ctx, 
+                                struct gl_pipeline_stage *stage )
+{
+   i830ContextPtr imesa = I830_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 || 
+       !choose_render( VB, GET_SUBSEQUENT_VB_MAX_VERTS() )) {
+      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)
+        i830_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 i830_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 _i830_render_stage =
+{
+   "i830 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 */
+   i830_check_render,  /* check - initially set to alloc data */
+   i830_run_render     /* run */
+};
diff --git a/src/mesa/drivers/dri/i830/i830_screen.c b/src/mesa/drivers/dri/i830/i830_screen.c
new file mode 100644 (file)
index 0000000..a1079f6
--- /dev/null
@@ -0,0 +1,371 @@
+/**************************************************************************
+ * 
+ * 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/i830/i830_screen.c,v 1.3 2002/12/10 01:26:53 dawes Exp $ */
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ * Adapted for use on the I830M:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ */
+
+
+#include "glheader.h"
+#include "context.h"
+#include "matrix.h"
+#include "simple_list.h"
+
+#include "i830_screen.h"
+#include "i830_dri.h"
+
+#include "i830_state.h"
+#include "i830_tex.h"
+#include "i830_span.h"
+#include "i830_tris.h"
+#include "i830_ioctl.h"
+
+#include "i830_dri.h"
+
+
+static int i830_malloc_proxy_buf(drmBufMapPtr buffers)
+{
+   char *buffer;
+   drmBufPtr buf;
+   int i;
+
+   buffer = Xmalloc(I830_DMA_BUF_SZ);
+   if(buffer == NULL) return -1;
+   for(i = 0; i < I830_DMA_BUF_NR; i++) {
+      buf = &(buffers->list[i]);
+      buf->address = (drmAddress)buffer;
+   }
+
+   return 0;
+}
+
+static drmBufMapPtr i830_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) * I830_DMA_BUF_NR);
+   if(retval->list == NULL) {
+      Xfree(retval);
+      return NULL;
+   }
+
+   memset(retval->list, 0, sizeof(drmBuf) * I830_DMA_BUF_NR);
+   return retval;
+}
+
+static void i830PrintDRIInfo(i830ScreenPrivate *i830Screen,
+                            __DRIscreenPrivate *sPriv,
+                            I830DRIPtr gDRIPriv)
+{
+   GLuint size = (gDRIPriv->ringSize +
+                 i830Screen->textureSize +
+                 i830Screen->depth.size +
+                 i830Screen->back.size +
+                 sPriv->fbSize +
+                 I830_DMA_BUF_NR * I830_DMA_BUF_SZ +
+                 32768 /* Context Memory */ +
+                 16*4096 /* Ring buffer */ +
+                 64*1024 /* Scratch buffer */ +
+                 4096 /* Cursor */);
+   GLuint size_low = (gDRIPriv->ringSize +
+                     i830Screen->textureSize +
+                     sPriv->fbSize +
+                     I830_DMA_BUF_NR * I830_DMA_BUF_SZ +
+                     32768 /* Context Memory */ +
+                     16*4096 /* Ring buffer */ +
+                     64*1024 /* Scratch buffer */);
+
+   fprintf(stderr, "\nFront size : 0x%x\n", sPriv->fbSize);
+   fprintf(stderr, "Front offset : 0x%x\n", i830Screen->fbOffset);
+   fprintf(stderr, "Back size : 0x%x\n", i830Screen->back.size);
+   fprintf(stderr, "Back offset : 0x%x\n", i830Screen->backOffset);
+   fprintf(stderr, "Depth size : 0x%x\n", i830Screen->depth.size);
+   fprintf(stderr, "Depth offset : 0x%x\n", i830Screen->depthOffset);
+   fprintf(stderr, "Texture size : 0x%x\n", i830Screen->textureSize);
+   fprintf(stderr, "Texture offset : 0x%x\n", i830Screen->textureOffset);
+   fprintf(stderr, "Ring offset : 0x%x\n", gDRIPriv->ringOffset);
+   fprintf(stderr, "Ring size : 0x%x\n", gDRIPriv->ringSize);
+   fprintf(stderr, "Memory : 0x%x\n", gDRIPriv->mem);
+   fprintf(stderr, "Used Memory : low(0x%x) high(0x%x)\n", size_low, size);
+}
+
+static GLboolean i830InitDriver(__DRIscreenPrivate *sPriv)
+{
+   i830ScreenPrivate *i830Screen;
+   I830DRIPtr         gDRIPriv = (I830DRIPtr)sPriv->pDevPriv;
+
+   /* Check the DRI externsion version */
+   if ( sPriv->driMajor != 4 || sPriv->driMinor < 0 ) {
+      __driUtilMessage( "i830 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("i830 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 < 3) {
+      __driUtilMessage("i830 DRI driver expected DRM driver version 1.3.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch);
+      return GL_FALSE;
+   }
+
+   /* Allocate the private area */
+   i830Screen = (i830ScreenPrivate *)Xmalloc(sizeof(i830ScreenPrivate));
+   if (!i830Screen) {
+      fprintf(stderr,"\nERROR!  Allocating private area failed\n");
+      return GL_FALSE;
+   }
+
+   i830Screen->driScrnPriv = sPriv;
+   sPriv->private = (void *)i830Screen;
+
+   i830Screen->deviceID = gDRIPriv->deviceID;
+   i830Screen->width = gDRIPriv->width;
+   i830Screen->height = gDRIPriv->height;
+   i830Screen->mem = gDRIPriv->mem;
+   i830Screen->cpp = gDRIPriv->cpp;
+   i830Screen->fbStride = gDRIPriv->fbStride;
+   i830Screen->fbOffset = gDRIPriv->fbOffset;
+                        
+   switch (gDRIPriv->bitsPerPixel) {
+   case 15: i830Screen->fbFormat = DV_PF_555; break;
+   case 16: i830Screen->fbFormat = DV_PF_565; break;
+   case 32: i830Screen->fbFormat = DV_PF_8888; break;
+   }
+                        
+   i830Screen->backOffset = gDRIPriv->backOffset;
+   i830Screen->depthOffset = gDRIPriv->depthOffset;
+   i830Screen->backPitch = gDRIPriv->auxPitch;
+   i830Screen->backPitchBits = gDRIPriv->auxPitchBits;
+   i830Screen->textureOffset = gDRIPriv->textureOffset;
+   i830Screen->textureSize = gDRIPriv->textureSize;
+   i830Screen->logTextureGranularity = gDRIPriv->logTextureGranularity;
+                                                                        
+
+   i830Screen->bufs = i830_create_empty_buffers();
+   if(i830Screen->bufs == NULL) {
+      fprintf(stderr,"\nERROR: Failed to create empty buffers in %s \n",
+             __FUNCTION__);
+      Xfree(i830Screen);
+      return GL_FALSE;
+   }
+
+   /* Check if you need to create a fake buffer */
+   if(i830_check_copy(sPriv->fd) == 1) {
+      i830_malloc_proxy_buf(i830Screen->bufs);
+      i830Screen->use_copy_buf = 1;
+   } else {
+      i830Screen->use_copy_buf = 0;
+   }
+
+   i830Screen->back.handle = gDRIPriv->backbuffer;
+   i830Screen->back.size = gDRIPriv->backbufferSize;
+                        
+   if (drmMap(sPriv->fd,
+             i830Screen->back.handle,
+             i830Screen->back.size,
+             (drmAddress *)&i830Screen->back.map) != 0) {
+      fprintf(stderr, "\nERROR: line %d, Function %s, File %s\n",
+             __LINE__, __FUNCTION__, __FILE__);
+      Xfree(i830Screen);
+      sPriv->private = NULL;
+      return GL_FALSE;
+   }
+
+   i830Screen->depth.handle = gDRIPriv->depthbuffer;
+   i830Screen->depth.size = gDRIPriv->depthbufferSize;
+
+   if (drmMap(sPriv->fd, 
+             i830Screen->depth.handle,
+             i830Screen->depth.size,
+             (drmAddress *)&i830Screen->depth.map) != 0) {
+      fprintf(stderr, "\nERROR: line %d, Function %s, File %s\n", 
+             __LINE__, __FUNCTION__, __FILE__);
+      Xfree(i830Screen);
+      drmUnmap(i830Screen->back.map, i830Screen->back.size);
+      sPriv->private = NULL;
+      return GL_FALSE;
+   }
+
+   i830Screen->tex.handle = gDRIPriv->textures;
+   i830Screen->tex.size = gDRIPriv->textureSize;
+
+   if (drmMap(sPriv->fd,
+             i830Screen->tex.handle,
+             i830Screen->tex.size,
+             (drmAddress *)&i830Screen->tex.map) != 0) {
+      fprintf(stderr, "\nERROR: line %d, Function %s, File %s\n",
+             __LINE__, __FUNCTION__, __FILE__);
+      Xfree(i830Screen);
+      drmUnmap(i830Screen->back.map, i830Screen->back.size);
+      drmUnmap(i830Screen->depth.map, i830Screen->depth.size);
+      sPriv->private = NULL;
+      return GL_FALSE;
+   }
+                        
+   i830Screen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
+   
+   if (0) i830PrintDRIInfo(i830Screen, sPriv, gDRIPriv);
+
+   i830Screen->drmMinor = sPriv->drmMinor;
+
+   if (sPriv->drmMinor >= 3) {
+      int ret;
+      drmI830GetParam gp;
+
+      gp.param = I830_PARAM_IRQ_ACTIVE;
+      gp.value = &i830Screen->irq_active;
+
+      ret = drmCommandWriteRead( sPriv->fd, DRM_I830_GETPARAM,
+                                &gp, sizeof(gp));
+      if (ret) {
+        fprintf(stderr, "drmI830GetParam: %d\n", ret);
+        return GL_FALSE;
+      }
+   }
+
+#if 0
+   if (sPriv->drmMinor >= 3) {
+      int ret;
+      drmI830SetParam sp;
+
+      sp.param = I830_SETPARAM_PERF_BOXES;
+      sp.value = (getenv("I830_DO_BOXES") != 0);
+
+      ret = drmCommandWrite( sPriv->fd, DRM_I830_SETPARAM,
+                            &sp, sizeof(sp));
+      if (ret) 
+        fprintf(stderr, "Couldn't set perfboxes: %d\n", ret);
+   }
+#endif
+
+   return GL_TRUE;
+}
+               
+               
+static void i830DestroyScreen(__DRIscreenPrivate *sPriv)
+{
+   i830ScreenPrivate *i830Screen = (i830ScreenPrivate *)sPriv->private;
+
+   /* Need to unmap all the bufs and maps here:
+    */
+   drmUnmap(i830Screen->back.map, i830Screen->back.size);
+   drmUnmap(i830Screen->depth.map, i830Screen->depth.size);
+   drmUnmap(i830Screen->tex.map, i830Screen->tex.size);
+   Xfree(i830Screen);
+   sPriv->private = NULL;
+}
+
+static GLboolean i830CreateBuffer(__DRIscreenPrivate *driScrnPriv,
+                                 __DRIdrawablePrivate *driDrawPriv,
+                                 const __GLcontextModes *mesaVis,
+                                 GLboolean isPixmap )
+{
+   if (isPixmap) {
+      return GL_FALSE; /* not implemented */
+   } else {
+#if 0
+      GLboolean swStencil = (mesaVis->stencilBits > 0 && 
+                            mesaVis->depthBits != 24);
+#else
+      GLboolean swStencil = mesaVis->stencilBits > 0;
+#endif
+      driDrawPriv->driverPrivate = (void *) 
+        _mesa_create_framebuffer(mesaVis,
+                                 GL_FALSE,  /* software depth buffer? */
+                                 swStencil,
+                                 mesaVis->accumRedBits > 0,
+                                 GL_FALSE /* s/w alpha planes */);
+      
+      return (driDrawPriv->driverPrivate != NULL);
+   }
+}
+
+static void i830DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+   _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
+}
+
+static GLboolean i830OpenCloseFullScreen (__DRIcontextPrivate *driContextPriv)
+{
+   return GL_TRUE;  
+}
+
+static const struct __DriverAPIRec i830API = {
+   .InitDriver      = i830InitDriver,
+   .DestroyScreen   = i830DestroyScreen,
+   .CreateContext   = i830CreateContext,
+   .DestroyContext  = i830DestroyContext,
+   .CreateBuffer    = i830CreateBuffer,
+   .DestroyBuffer   = i830DestroyBuffer,
+   .SwapBuffers     = i830SwapBuffers,
+   .MakeCurrent     = i830MakeCurrent,
+   .UnbindContext   = i830UnbindContext,
+   .OpenFullScreen  = i830OpenCloseFullScreen,
+   .CloseFullScreen = i830OpenCloseFullScreen,
+   .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, &i830API);
+   return (void *) psp;
+}
+#else
+void *__driCreateScreen(struct DRIDriverRec *driver,
+                        struct DRIDriverContextRec *driverContext)
+{
+   __DRIscreenPrivate *psp;
+   psp = __driUtilCreateScreen(driver, driverContext, &i830API);
+   return (void *) psp;
+}
+#endif
diff --git a/src/mesa/drivers/dri/i830/i830_screen.h b/src/mesa/drivers/dri/i830/i830_screen.h
new file mode 100644 (file)
index 0000000..8153828
--- /dev/null
@@ -0,0 +1,107 @@
+/**************************************************************************
+
+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>
+ * Adapted for use on the I830M:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ */
+
+#ifndef _I830_INIT_H_
+#define _I830_INIT_H_
+
+#include <sys/time.h>
+#include "dri_util.h"
+
+
+typedef struct {
+   drmHandle handle;
+   drmSize size;
+   char *map;
+} i830Region, *i830RegionPtr;
+
+typedef struct 
+{
+   
+   i830Region front;
+   i830Region back;
+   i830Region depth;
+   i830Region 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;
+   int use_copy_buf;
+   unsigned int sarea_priv_offset;
+
+   int drmMinor;
+   int irq_active;
+}i830ScreenPrivate;
+
+
+extern GLboolean
+i830CreateContext( const __GLcontextModes *mesaVis,
+                   __DRIcontextPrivate *driContextPriv,
+                   void *sharedContextPrivate );
+
+extern void
+i830DestroyContext(__DRIcontextPrivate *driContextPriv);
+
+extern GLboolean
+i830UnbindContext(__DRIcontextPrivate *driContextPriv);
+
+extern GLboolean
+i830MakeCurrent(__DRIcontextPrivate *driContextPriv,
+                __DRIdrawablePrivate *driDrawPriv,
+                __DRIdrawablePrivate *driReadPriv);
+
+extern void
+i830SwapBuffers(__DRIdrawablePrivate *driDrawPriv);
+
+#endif
diff --git a/src/mesa/drivers/dri/i830/i830_span.c b/src/mesa/drivers/dri/i830/i830_span.c
new file mode 100644 (file)
index 0000000..34830bf
--- /dev/null
@@ -0,0 +1,370 @@
+/**************************************************************************
+
+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.
+
+**************************************************************************/
+
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_span.c,v 1.4 2002/12/10 01:26:53 dawes Exp $ */
+
+/*
+ * Author:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ *
+ * Heavily based on the I810 driver, which was written by:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "colormac.h"
+
+#include "i830_screen.h"
+#include "i830_dri.h"
+
+#include "i830_span.h"
+#include "i830_ioctl.h"
+#include "swrast/swrast.h"
+
+
+#define DBG 0
+
+#define LOCAL_VARS                                             \
+   i830ContextPtr imesa = I830_CONTEXT(ctx);                    \
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;           \
+   i830ScreenPrivate *i830Screen = imesa->i830Screen;          \
+   GLuint pitch = i830Screen->backPitch * i830Screen->cpp;     \
+   GLuint height = dPriv->h;                                   \
+   char *buf = (char *)(imesa->drawMap +                       \
+                       dPriv->x * i830Screen->cpp +            \
+                       dPriv->y * pitch);                      \
+   char *read_buf = (char *)(imesa->readMap +                  \
+                            dPriv->x * i830Screen->cpp +       \
+                            dPriv->y * pitch);                 \
+   GLushort p;                                                         \
+   (void) read_buf; (void) buf; (void) p
+
+#define LOCAL_DEPTH_VARS                                       \
+   i830ContextPtr imesa = I830_CONTEXT(ctx);                    \
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;           \
+   i830ScreenPrivate *i830Screen = imesa->i830Screen;          \
+   GLuint pitch = i830Screen->backPitch * i830Screen->cpp;     \
+   GLuint height = dPriv->h;                                   \
+   char *buf = (char *)(i830Screen->depth.map +                        \
+                       dPriv->x * i830Screen->cpp +            \
+                       dPriv->y * pitch)
+
+#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS 
+
+#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()
+
+#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()
+
+/* 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 >> 11) & 0x1f) * 255) / 31;                  \
+   rgba[1] = (((p >>  5) & 0x3f) * 255) / 63;                  \
+   rgba[2] = (((p >>  0) & 0x1f) * 255) / 31;                  \
+   rgba[3] = 255;                                              \
+} while(0)
+
+#define TAG(x) i830##x##_565
+#include "spantmp.h"
+
+
+
+
+/* 15 bit, 555 rgb color spanline and pixel functions
+ */
+#define WRITE_RGBA( _x, _y, r, g, b, a )                       \
+   *(GLushort *)(buf + _x*2 + _y*pitch)  = (((r & 0xf8) << 7) |        \
+                                           ((g & 0xf8) << 3) | \
+                                           ((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 >> 7) & 0xf8;                                  \
+   rgba[1] = (p >> 3) & 0xf8;                                  \
+   rgba[2] = (p << 3) & 0xf8;                                  \
+   rgba[3] = 255;                                              \
+} while(0)
+
+#define TAG(x) i830##x##_555
+#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) i830##x##_16
+#include "depthtmp.h"
+
+
+#undef LOCAL_VARS
+#define LOCAL_VARS                                     \
+   i830ContextPtr imesa = I830_CONTEXT(ctx);                    \
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;   \
+   i830ScreenPrivate *i830Screen = imesa->i830Screen;  \
+   GLuint pitch = i830Screen->backPitch * i830Screen->cpp;     \
+   GLuint height = dPriv->h;                           \
+   char *buf = (char *)(imesa->drawMap +               \
+                       dPriv->x * i830Screen->cpp +                    \
+                       dPriv->y * pitch);              \
+   char *read_buf = (char *)(imesa->readMap +          \
+                            dPriv->x * i830Screen->cpp +               \
+                            dPriv->y * pitch);         \
+   GLuint p = I830_CONTEXT( ctx )->MonoColor;         \
+   (void) read_buf; (void) buf; (void) p
+
+#undef INIT_MONO_PIXEL
+#define INIT_MONO_PIXEL(p,color)\
+        p = PACK_COLOR_888(color[0],color[1],color[2])
+
+/* 32 bit, 8888 argb color spanline and pixel functions
+ */
+#define WRITE_RGBA(_x, _y, r, g, b, a)                 \
+    *(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) |  \
+                                         (g << 8)  |   \
+                                         (b << 0)  |   \
+                                         (a << 24) )
+
+#define WRITE_PIXEL(_x, _y, p)                 \
+    *(GLuint *)(buf + _x*4 + _y*pitch) = p
+
+
+#define READ_RGBA(rgba, _x, _y)                                        \
+    do {                                                       \
+       GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch);     \
+       rgba[0] = (p >> 16) & 0xff;                             \
+       rgba[1] = (p >> 8)  & 0xff;                             \
+       rgba[2] = (p >> 0)  & 0xff;                             \
+       rgba[3] = (p >> 24) & 0xff;                             \
+    } while (0)
+
+#define TAG(x) i830##x##_8888
+#include "spantmp.h"
+
+/* 24 bit depthbuffer functions.
+ */
+#define WRITE_DEPTH( _x, _y, d )       \
+   *(GLuint *)(buf + _x*4 + _y*pitch) = 0xffffff & d;
+
+#define READ_DEPTH( d, _x, _y )                \
+   d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xffffff;
+
+#define TAG(x) i830##x##_24
+#include "depthtmp.h"
+
+/* 24/8 bit interleaved depth/stencil functions
+ */
+#define WRITE_DEPTH( _x, _y, d ) {                     \
+   GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch);    \
+   tmp &= 0xff000000;                                  \
+   tmp |= (d) & 0xffffff;                              \
+   *(GLuint *)(buf + _x*4 + _y*pitch) = tmp;           \
+}
+
+#define READ_DEPTH( d, _x, _y )                \
+   d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xffffff;
+
+
+#define TAG(x) i830##x##_24_8
+#include "depthtmp.h"
+
+#define WRITE_STENCIL( _x, _y, d ) {                   \
+   GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch);    \
+   tmp &= 0xffffff;                                    \
+   tmp |= (d<<24);                                     \
+   *(GLuint *)(buf + _x*4 + _y*pitch) = tmp;           \
+}
+
+#define READ_STENCIL( d, _x, _y )                      \
+   d = *(GLuint *)(buf + _x*4 + _y*pitch) >> 24;
+
+#define TAG(x) i830##x##_24_8
+#include "stenciltmp.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 i830SetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
+                          GLuint bufferBit)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   if (bufferBit == FRONT_LEFT_BIT) {
+      imesa->drawMap = (char *)imesa->driScreen->pFB;
+      imesa->readMap = (char *)imesa->driScreen->pFB;
+   } else if (bufferBit == BACK_LEFT_BIT) {
+      imesa->drawMap = imesa->i830Screen->back.map;
+      imesa->readMap = imesa->i830Screen->back.map;
+   } else {
+      ASSERT(0);
+   }
+}
+
+
+
+/* Move locking out to get reasonable span performance.
+ */
+void i830SpanRenderStart( GLcontext *ctx )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   I830_FIREVERTICES(imesa);
+   LOCK_HARDWARE(imesa);
+   i830RegetLockQuiescent( imesa );
+}
+
+void i830SpanRenderFinish( GLcontext *ctx )
+{
+   i830ContextPtr imesa = I830_CONTEXT( ctx );
+   _swrast_flush( ctx );
+   UNLOCK_HARDWARE( imesa );
+}
+
+void i830DDInitSpanFuncs( GLcontext *ctx )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   i830ScreenPrivate *i830Screen = imesa->i830Screen;
+
+   struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
+
+   swdd->SetBuffer = i830SetBuffer;
+
+   switch (i830Screen->fbFormat) {
+   case DV_PF_555:
+      swdd->WriteRGBASpan = i830WriteRGBASpan_555;
+      swdd->WriteRGBSpan = i830WriteRGBSpan_555;
+      swdd->WriteMonoRGBASpan = i830WriteMonoRGBASpan_555;
+      swdd->WriteRGBAPixels = i830WriteRGBAPixels_555;
+      swdd->WriteMonoRGBAPixels = i830WriteMonoRGBAPixels_555;
+      swdd->ReadRGBASpan = i830ReadRGBASpan_555;
+      swdd->ReadRGBAPixels = i830ReadRGBAPixels_555;
+
+      swdd->ReadDepthSpan = i830ReadDepthSpan_16;
+      swdd->WriteDepthSpan = i830WriteDepthSpan_16;
+      swdd->ReadDepthPixels = i830ReadDepthPixels_16;
+      swdd->WriteDepthPixels = i830WriteDepthPixels_16;
+      break;
+
+   case DV_PF_565:
+      swdd->WriteRGBASpan = i830WriteRGBASpan_565;
+      swdd->WriteRGBSpan = i830WriteRGBSpan_565;
+      swdd->WriteMonoRGBASpan = i830WriteMonoRGBASpan_565;
+      swdd->WriteRGBAPixels = i830WriteRGBAPixels_565;
+      swdd->WriteMonoRGBAPixels = i830WriteMonoRGBAPixels_565; 
+      swdd->ReadRGBASpan = i830ReadRGBASpan_565;
+      swdd->ReadRGBAPixels = i830ReadRGBAPixels_565;
+
+      swdd->ReadDepthSpan = i830ReadDepthSpan_16;
+      swdd->WriteDepthSpan = i830WriteDepthSpan_16;
+      swdd->ReadDepthPixels = i830ReadDepthPixels_16;
+      swdd->WriteDepthPixels = i830WriteDepthPixels_16;
+      break;
+
+   case DV_PF_8888:
+      swdd->WriteRGBASpan = i830WriteRGBASpan_8888;
+      swdd->WriteRGBSpan = i830WriteRGBSpan_8888;
+      swdd->WriteMonoRGBASpan = i830WriteMonoRGBASpan_8888;
+      swdd->WriteRGBAPixels = i830WriteRGBAPixels_8888;
+      swdd->WriteMonoRGBAPixels = i830WriteMonoRGBAPixels_8888;
+      swdd->ReadRGBASpan = i830ReadRGBASpan_8888;
+      swdd->ReadRGBAPixels = i830ReadRGBAPixels_8888;
+
+      if(imesa->hw_stencil) {
+        swdd->ReadDepthSpan = i830ReadDepthSpan_24_8;
+        swdd->WriteDepthSpan = i830WriteDepthSpan_24_8;
+        swdd->ReadDepthPixels = i830ReadDepthPixels_24_8;
+        swdd->WriteDepthPixels = i830WriteDepthPixels_24_8;
+
+        swdd->WriteStencilSpan = i830WriteStencilSpan_24_8;
+        swdd->ReadStencilSpan = i830ReadStencilSpan_24_8;
+        swdd->WriteStencilPixels = i830WriteStencilPixels_24_8;
+        swdd->ReadStencilPixels = i830ReadStencilPixels_24_8;
+      } else {
+        swdd->ReadDepthSpan = i830ReadDepthSpan_24;
+        swdd->WriteDepthSpan = i830WriteDepthSpan_24;
+        swdd->ReadDepthPixels = i830ReadDepthPixels_24;
+        swdd->WriteDepthPixels = i830WriteDepthPixels_24;
+      }
+      break;
+   }
+
+   swdd->SpanRenderStart = i830SpanRenderStart;
+   swdd->SpanRenderFinish = i830SpanRenderFinish; 
+}
diff --git a/src/mesa/drivers/dri/i830/i830_span.h b/src/mesa/drivers/dri/i830/i830_span.h
new file mode 100644 (file)
index 0000000..0135468
--- /dev/null
@@ -0,0 +1,46 @@
+/**************************************************************************
+
+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.
+
+**************************************************************************/
+
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_span.h,v 1.2 2002/09/11 00:29:26 dawes Exp $ */
+
+/*
+ * Author:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ *
+ * Heavily based on the I810 driver, which was written by:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef _I830_SPAN_H
+#define _I830_SPAN_H
+
+extern void i830DDInitSpanFuncs( GLcontext *ctx );
+
+extern void i830SpanRenderFinish( GLcontext *ctx );
+extern void i830SpanRenderStart( GLcontext *ctx );
+
+#endif
diff --git a/src/mesa/drivers/dri/i830/i830_state.c b/src/mesa/drivers/dri/i830/i830_state.c
new file mode 100644 (file)
index 0000000..6eb46fa
--- /dev/null
@@ -0,0 +1,1796 @@
+/**************************************************************************
+
+Copyright 2001 2d3d Inc., Delray Beach, FL
+
+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.
+
+**************************************************************************/
+
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_state.c,v 1.6 2003/01/28 22:47:06 dawes Exp $ */
+
+/*
+ * Author:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ *
+ * Heavily based on the I810 driver, which was written by:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "enums.h"
+#include "dd.h"
+
+#include "texmem.h"
+
+#include "i830_screen.h"
+#include "i830_dri.h"
+
+#include "i830_context.h"
+#include "i830_state.h"
+#include "i830_tex.h"
+#include "i830_vb.h"
+#include "i830_tris.h"
+#include "i830_ioctl.h"
+
+#include "swrast/swrast.h"
+#include "array_cache/acache.h"
+#include "tnl/tnl.h"
+#include "swrast_setup/swrast_setup.h"
+
+#include "tnl/t_pipeline.h"
+
+static __inline__ GLuint i830PackColor(GLuint format, 
+                                      GLubyte r, GLubyte g, 
+                                      GLubyte b, GLubyte a)
+{
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   switch (format) {
+   case DV_PF_555:
+      return I830PACKCOLOR1555(r,g,b,a);
+   case DV_PF_565:
+      return I830PACKCOLOR565(r,g,b);
+   case DV_PF_8888:
+      return I830PACKCOLOR8888(r,g,b,a);
+   default:
+      fprintf(stderr, "unknown format %d\n", (int)format);
+      return 0;
+   }
+}
+
+static void i830StencilFunc(GLcontext *ctx, GLenum func, GLint ref,
+                           GLuint mask)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   int test = 0;
+
+   mask = mask & 0xff;
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__,
+             _mesa_lookup_enum_by_nr(func), ref, mask);
+
+   switch(func) {
+   case GL_NEVER: 
+      test = COMPAREFUNC_NEVER; 
+      break;
+   case GL_LESS: 
+      test = COMPAREFUNC_LESS; 
+      break;
+   case GL_LEQUAL: 
+      test = COMPAREFUNC_LEQUAL; 
+      break;
+   case GL_GREATER: 
+      test = COMPAREFUNC_GREATER; 
+      break;
+   case GL_GEQUAL: 
+      test = COMPAREFUNC_GEQUAL; 
+      break;
+   case GL_NOTEQUAL: 
+      test = COMPAREFUNC_NOTEQUAL; 
+      break;
+   case GL_EQUAL: 
+      test = COMPAREFUNC_EQUAL; 
+      break;
+   case GL_ALWAYS: 
+      test = COMPAREFUNC_ALWAYS; 
+      break;
+   default:
+      return;
+   }
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+   imesa->Setup[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK;
+   imesa->Setup[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK |
+                                       STENCIL_TEST_MASK(mask));
+   imesa->Setup[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK |
+                                            ENABLE_STENCIL_TEST_FUNC_MASK);
+   imesa->Setup[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_REF_VALUE |
+                                           ENABLE_STENCIL_TEST_FUNC |
+                                           STENCIL_REF_VALUE(ref) |
+                                           STENCIL_TEST_FUNC(test));
+}
+
+static void i830StencilMask(GLcontext *ctx, GLuint mask)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask);
+
+   mask = mask & 0xff;
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+   imesa->Setup[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
+   imesa->Setup[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
+                                       STENCIL_WRITE_MASK(mask));
+}
+
+static void i830StencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
+                         GLenum zpass)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   int fop, dfop, dpop;
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__,
+             _mesa_lookup_enum_by_nr(fail),
+             _mesa_lookup_enum_by_nr(zfail),
+             _mesa_lookup_enum_by_nr(zpass));
+
+   fop = 0; dfop = 0; dpop = 0;
+
+   switch(fail) {
+   case GL_KEEP: 
+      fop = STENCILOP_KEEP; 
+      break;
+   case GL_ZERO: 
+      fop = STENCILOP_ZERO; 
+      break;
+   case GL_REPLACE: 
+      fop = STENCILOP_REPLACE; 
+      break;
+   case GL_INCR: 
+      fop = STENCILOP_INCRSAT;
+      break;
+   case GL_DECR: 
+      fop = STENCILOP_DECRSAT;
+      break;
+   case GL_INCR_WRAP:
+      fop = STENCILOP_INCR; 
+      break;
+   case GL_DECR_WRAP:
+      fop = STENCILOP_DECR; 
+      break;
+   case GL_INVERT: 
+      fop = STENCILOP_INVERT; 
+      break;
+   default: 
+      break;
+   }
+   switch(zfail) {
+   case GL_KEEP: 
+      dfop = STENCILOP_KEEP; 
+      break;
+   case GL_ZERO: 
+      dfop = STENCILOP_ZERO; 
+      break;
+   case GL_REPLACE: 
+      dfop = STENCILOP_REPLACE; 
+      break;
+   case GL_INCR: 
+      dfop = STENCILOP_INCRSAT;
+      break;
+   case GL_DECR: 
+      dfop = STENCILOP_DECRSAT;
+      break;
+   case GL_INCR_WRAP:
+      dfop = STENCILOP_INCR; 
+      break;
+   case GL_DECR_WRAP:
+      dfop = STENCILOP_DECR; 
+      break;
+   case GL_INVERT: 
+      dfop = STENCILOP_INVERT; 
+      break;
+   default: 
+      break;
+   }
+   switch(zpass) {
+   case GL_KEEP: 
+      dpop = STENCILOP_KEEP; 
+      break;
+   case GL_ZERO: 
+      dpop = STENCILOP_ZERO; 
+      break;
+   case GL_REPLACE: 
+      dpop = STENCILOP_REPLACE; 
+      break;
+   case GL_INCR: 
+      dpop = STENCILOP_INCRSAT;
+      break;
+   case GL_DECR: 
+      dpop = STENCILOP_DECRSAT;
+      break;
+   case GL_INCR_WRAP:
+      dpop = STENCILOP_INCR; 
+      break;
+   case GL_DECR_WRAP:
+      dpop = STENCILOP_DECR; 
+      break;
+   case GL_INVERT: 
+      dpop = STENCILOP_INVERT; 
+      break;
+   default: 
+      break;
+   }
+
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+   imesa->Setup[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK);
+   imesa->Setup[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_PARMS |
+                                           STENCIL_FAIL_OP(fop) |
+                                           STENCIL_PASS_DEPTH_FAIL_OP(dfop) |
+                                           STENCIL_PASS_DEPTH_PASS_OP(dpop));
+}
+
+static void i830AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   int test = 0;
+   GLuint refByte = (GLint) (ref * 255.0);
+
+   switch(func) {
+   case GL_NEVER: 
+      test = COMPAREFUNC_NEVER; 
+      break;
+   case GL_LESS: 
+      test = COMPAREFUNC_LESS; 
+      break;
+   case GL_LEQUAL: 
+      test = COMPAREFUNC_LEQUAL; 
+      break;
+   case GL_GREATER: 
+      test = COMPAREFUNC_GREATER; 
+      break;
+   case GL_GEQUAL: 
+      test = COMPAREFUNC_GEQUAL; 
+      break;
+   case GL_NOTEQUAL: 
+      test = COMPAREFUNC_NOTEQUAL; 
+      break;
+   case GL_EQUAL: 
+      test = COMPAREFUNC_EQUAL; 
+      break;
+   case GL_ALWAYS: 
+      test = COMPAREFUNC_ALWAYS; 
+      break;
+   default:
+      return;
+   }
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+   imesa->Setup[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK;
+   imesa->Setup[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC |
+                                       ENABLE_ALPHA_REF_VALUE |
+                                       ALPHA_TEST_FUNC(test) |
+                                       ALPHA_REF_VALUE(refByte));
+}
+
+/* This function makes sure that the proper enables are
+ * set for LogicOp, Independant Alpha Blend, and Blending.
+ * It needs to be called from numerous places where we
+ * could change the LogicOp or Independant Alpha Blend without subsequent
+ * calls to glEnable.
+ */
+static void i830EvalLogicOpBlendState(GLcontext *ctx)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+
+   if (ctx->Color.ColorLogicOpEnabled) {
+      imesa->Setup[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
+                                              ENABLE_LOGIC_OP_MASK);
+      imesa->Setup[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND |
+                                             ENABLE_LOGIC_OP);
+      imesa->Setup[I830_CTXREG_IALPHAB] &= ~ENABLE_INDPT_ALPHA_BLEND;
+      imesa->Setup[I830_CTXREG_IALPHAB] |= DISABLE_INDPT_ALPHA_BLEND;
+   } else if (ctx->Color.BlendEnabled) {
+      imesa->Setup[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
+                                              ENABLE_LOGIC_OP_MASK);
+      imesa->Setup[I830_CTXREG_ENABLES_1] |= (ENABLE_COLOR_BLEND |
+                                             DISABLE_LOGIC_OP);
+      imesa->Setup[I830_CTXREG_IALPHAB] &= ~ENABLE_INDPT_ALPHA_BLEND;
+      if (imesa->Setup[I830_CTXREG_IALPHAB] & SRC_DST_ABLEND_MASK) {
+        imesa->Setup[I830_CTXREG_IALPHAB] |= ENABLE_INDPT_ALPHA_BLEND;
+      } else {
+        imesa->Setup[I830_CTXREG_IALPHAB] |= DISABLE_INDPT_ALPHA_BLEND;
+      }
+   } else {
+      imesa->Setup[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
+                                              ENABLE_LOGIC_OP_MASK);
+      imesa->Setup[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND |
+                                             DISABLE_LOGIC_OP);
+      imesa->Setup[I830_CTXREG_IALPHAB] &= ~ENABLE_INDPT_ALPHA_BLEND;
+      imesa->Setup[I830_CTXREG_IALPHAB] |= DISABLE_INDPT_ALPHA_BLEND;
+   }
+}
+
+static void i830BlendColor(GLcontext *ctx, const GLfloat color[4])
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   GLubyte r, g, b, a;
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   FLOAT_COLOR_TO_UBYTE_COLOR(r, color[RCOMP]);
+   FLOAT_COLOR_TO_UBYTE_COLOR(g, color[GCOMP]);
+   FLOAT_COLOR_TO_UBYTE_COLOR(b, color[BCOMP]);
+   FLOAT_COLOR_TO_UBYTE_COLOR(a, color[ACOMP]);
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+   imesa->Setup[I830_CTXREG_BLENDCOLR] = ((a << 24) |
+                                         (r << 16) |
+                                         (g << 8) |
+                                         b);
+}
+
+static void i830BlendEquation(GLcontext *ctx, GLenum mode) 
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   int func = ENABLE_ALPHA_BLENDFUNC;
+
+   if (I830_DEBUG&DEBUG_DRI)
+     fprintf(stderr, "%s %s\n", __FUNCTION__,
+            _mesa_lookup_enum_by_nr(mode));
+
+   /* This will catch a logicop blend equation */
+   i830EvalLogicOpBlendState(ctx);
+
+   switch(mode) {
+   case GL_FUNC_ADD_EXT: 
+      func |= BLENDFUNC_ADD; 
+      break;
+   case GL_MIN_EXT: 
+      func |= BLENDFUNC_MIN; 
+      break;
+   case GL_MAX_EXT: 
+      func |= BLENDFUNC_MAX; 
+      break;
+   case GL_FUNC_SUBTRACT_EXT: 
+      func |= BLENDFUNC_SUB; 
+      break;
+   case GL_FUNC_REVERSE_SUBTRACT_EXT: 
+      func |= BLENDFUNC_RVRSE_SUB; 
+      break;
+   default: return;
+   }
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+   imesa->Setup[I830_CTXREG_STATE1] &= ~BLENDFUNC_MASK;
+   imesa->Setup[I830_CTXREG_STATE1] |= func;
+   if (0) fprintf(stderr, "%s : STATE1 : 0x%08x\n",
+                 __FUNCTION__,
+                 imesa->Setup[I830_CTXREG_STATE1]);
+}
+
+static void i830BlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   int func = (ENABLE_SRC_BLND_FACTOR|ENABLE_DST_BLND_FACTOR);
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s %s %s\n", __FUNCTION__,
+             _mesa_lookup_enum_by_nr(sfactor),
+             _mesa_lookup_enum_by_nr(dfactor));
+
+   switch(sfactor) {
+   case GL_ZERO: 
+      func |= SRC_BLND_FACT(BLENDFACT_ZERO); 
+      break;
+   case GL_SRC_ALPHA: 
+      func |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA); 
+      break;
+   case GL_ONE: 
+      func |= SRC_BLND_FACT(BLENDFACT_ONE); 
+      break;
+   case GL_DST_COLOR: 
+      func |= SRC_BLND_FACT(BLENDFACT_DST_COLR); 
+      break;
+   case GL_ONE_MINUS_DST_COLOR: 
+      func |= SRC_BLND_FACT(BLENDFACT_INV_DST_COLR); 
+      break;
+   case GL_ONE_MINUS_SRC_ALPHA:
+      func |= SRC_BLND_FACT(BLENDFACT_INV_SRC_ALPHA); 
+      break;
+   case GL_DST_ALPHA: 
+      func |= SRC_BLND_FACT(BLENDFACT_DST_ALPHA); 
+      break;
+   case GL_ONE_MINUS_DST_ALPHA:
+      func |= SRC_BLND_FACT(BLENDFACT_INV_DST_ALPHA); 
+      break;
+   case GL_SRC_ALPHA_SATURATE: 
+      func |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA_SATURATE);
+      break;
+   case GL_CONSTANT_COLOR_EXT:
+      func |= SRC_BLND_FACT(BLENDFACT_CONST_COLOR); 
+      break;
+   case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
+      func |= SRC_BLND_FACT(BLENDFACT_INV_CONST_COLOR);
+      break;
+   case GL_CONSTANT_ALPHA_EXT:
+      func |= SRC_BLND_FACT(BLENDFACT_CONST_ALPHA); 
+      break;
+   case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
+      func |= SRC_BLND_FACT(BLENDFACT_INV_CONST_ALPHA);
+      break;
+   default: 
+      return;
+   }
+
+   switch(dfactor) {
+   case GL_SRC_ALPHA: 
+      func |= DST_BLND_FACT(BLENDFACT_SRC_ALPHA); 
+      break;
+   case GL_ONE_MINUS_SRC_ALPHA: 
+      func |= DST_BLND_FACT(BLENDFACT_INV_SRC_ALPHA); 
+      break;
+   case GL_ZERO: 
+      func |= DST_BLND_FACT(BLENDFACT_ZERO); 
+      break;
+   case GL_ONE: 
+      func |= DST_BLND_FACT(BLENDFACT_ONE); 
+      break;
+   case GL_SRC_COLOR: 
+      func |= DST_BLND_FACT(BLENDFACT_SRC_COLR); 
+      break;
+   case GL_ONE_MINUS_SRC_COLOR: 
+      func |= DST_BLND_FACT(BLENDFACT_INV_SRC_COLR); 
+      break;
+   case GL_DST_ALPHA:
+      func |= DST_BLND_FACT(BLENDFACT_DST_ALPHA); 
+      break;
+   case GL_ONE_MINUS_DST_ALPHA: 
+      func |= DST_BLND_FACT(BLENDFACT_INV_DST_ALPHA); 
+      break;
+   case GL_CONSTANT_COLOR_EXT:
+      func |= DST_BLND_FACT(BLENDFACT_CONST_COLOR); 
+      break;
+   case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
+      func |= DST_BLND_FACT(BLENDFACT_INV_CONST_COLOR);
+      break;
+   case GL_CONSTANT_ALPHA_EXT:
+      func |= DST_BLND_FACT(BLENDFACT_CONST_ALPHA); 
+      break;
+   case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
+      func |= DST_BLND_FACT(BLENDFACT_INV_CONST_ALPHA); 
+      break;
+   default: 
+      return;
+   }
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+   imesa->Setup[I830_CTXREG_IALPHAB] &= ~SRC_DST_ABLEND_MASK;
+   imesa->Setup[I830_CTXREG_STATE1] &= ~SRC_DST_BLND_MASK;
+   imesa->Setup[I830_CTXREG_STATE1] |= func;
+   /* Insure Independant Alpha Blend is really disabled. */
+   i830EvalLogicOpBlendState(ctx);
+}
+
+static void i830BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, 
+                                 GLenum dfactorRGB, GLenum sfactorA,
+                                 GLenum dfactorA )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   int funcA = (ENABLE_SRC_ABLEND_FACTOR|ENABLE_DST_ABLEND_FACTOR);
+   int funcRGB = (ENABLE_SRC_BLND_FACTOR|ENABLE_DST_BLND_FACTOR);
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   switch(sfactorA) {
+   case GL_ZERO: 
+      funcA |= SRC_ABLEND_FACT(BLENDFACT_ZERO); 
+      break;
+   case GL_SRC_ALPHA: 
+      funcA |= SRC_ABLEND_FACT(BLENDFACT_SRC_ALPHA); 
+      break;
+   case GL_ONE: 
+      funcA |= SRC_ABLEND_FACT(BLENDFACT_ONE); 
+      break;
+   case GL_DST_COLOR: 
+      funcA |= SRC_ABLEND_FACT(BLENDFACT_DST_COLR); 
+      break;
+   case GL_ONE_MINUS_DST_COLOR: 
+      funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_DST_COLR); 
+      break;
+   case GL_ONE_MINUS_SRC_ALPHA:
+      funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_SRC_ALPHA); 
+      break;
+   case GL_DST_ALPHA: 
+      funcA |= SRC_ABLEND_FACT(BLENDFACT_DST_ALPHA); 
+      break;
+   case GL_ONE_MINUS_DST_ALPHA:
+      funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_DST_ALPHA); 
+      break;
+   case GL_SRC_ALPHA_SATURATE: 
+      funcA |= SRC_ABLEND_FACT(BLENDFACT_SRC_ALPHA_SATURATE);
+      break;
+   case GL_CONSTANT_COLOR_EXT:
+      funcA |= SRC_ABLEND_FACT(BLENDFACT_CONST_COLOR); 
+      break;
+   case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
+      funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_CONST_COLOR); 
+      break;
+   case GL_CONSTANT_ALPHA_EXT:
+      funcA |= SRC_ABLEND_FACT(BLENDFACT_CONST_ALPHA); 
+      break;
+   case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
+      funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_CONST_ALPHA);
+      break;
+   default: return;
+   }
+
+   switch(dfactorA) {
+   case GL_SRC_ALPHA: 
+      funcA |= DST_ABLEND_FACT(BLENDFACT_SRC_ALPHA); 
+      break;
+   case GL_ONE_MINUS_SRC_ALPHA: 
+      funcA |= DST_ABLEND_FACT(BLENDFACT_INV_SRC_ALPHA); 
+      break;
+   case GL_ZERO: 
+      funcA |= DST_ABLEND_FACT(BLENDFACT_ZERO); 
+      break;
+   case GL_ONE: 
+      funcA |= DST_ABLEND_FACT(BLENDFACT_ONE); 
+      break;
+   case GL_SRC_COLOR: 
+      funcA |= DST_ABLEND_FACT(BLENDFACT_SRC_COLR); 
+      break;
+   case GL_ONE_MINUS_SRC_COLOR: 
+      funcA |= DST_ABLEND_FACT(BLENDFACT_INV_SRC_COLR); 
+      break;
+   case GL_DST_ALPHA: 
+      funcA |= DST_ABLEND_FACT(BLENDFACT_DST_ALPHA); 
+      break;
+   case GL_ONE_MINUS_DST_ALPHA: 
+      funcA |= DST_ABLEND_FACT(BLENDFACT_INV_DST_ALPHA); 
+      break;
+   case GL_CONSTANT_COLOR_EXT:
+      funcA |= DST_ABLEND_FACT(BLENDFACT_CONST_COLOR); 
+      break;
+   case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
+      funcA |= DST_ABLEND_FACT(BLENDFACT_INV_CONST_COLOR);
+      break;
+   case GL_CONSTANT_ALPHA_EXT:
+      funcA |= DST_ABLEND_FACT(BLENDFACT_CONST_ALPHA); 
+      break;
+   case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
+      funcA |= DST_ABLEND_FACT(BLENDFACT_INV_CONST_ALPHA); 
+      break;
+   default: return;
+   }
+   
+   switch(sfactorRGB) {
+   case GL_ZERO: 
+      funcRGB |= SRC_BLND_FACT(BLENDFACT_ZERO); 
+      break;
+   case GL_SRC_ALPHA: 
+      funcRGB |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA); 
+      break;
+   case GL_ONE: 
+      funcRGB |= SRC_BLND_FACT(BLENDFACT_ONE); 
+      break;
+   case GL_DST_COLOR: 
+      funcRGB |= SRC_BLND_FACT(BLENDFACT_DST_COLR); 
+      break;
+   case GL_ONE_MINUS_DST_COLOR: 
+      funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_DST_COLR); 
+      break;
+   case GL_ONE_MINUS_SRC_ALPHA:
+      funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_SRC_ALPHA); 
+      break;
+   case GL_DST_ALPHA: 
+      funcRGB |= SRC_BLND_FACT(BLENDFACT_DST_ALPHA); 
+      break;
+   case GL_ONE_MINUS_DST_ALPHA:
+      funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_DST_ALPHA); 
+      break;
+   case GL_SRC_ALPHA_SATURATE: 
+      funcRGB |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA_SATURATE);
+      break;
+   case GL_CONSTANT_COLOR_EXT:
+      funcRGB |= SRC_BLND_FACT(BLENDFACT_CONST_COLOR); 
+      break;
+   case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
+      funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_CONST_COLOR);
+      break;
+   case GL_CONSTANT_ALPHA_EXT:
+      funcRGB |= SRC_BLND_FACT(BLENDFACT_CONST_ALPHA); 
+      break;
+   case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
+      funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_CONST_ALPHA);
+      break;
+   default: return;
+   }
+   
+   switch(dfactorRGB) {
+   case GL_SRC_ALPHA: 
+      funcRGB |= DST_BLND_FACT(BLENDFACT_SRC_ALPHA); 
+      break;
+   case GL_ONE_MINUS_SRC_ALPHA: 
+      funcRGB |= DST_BLND_FACT(BLENDFACT_INV_SRC_ALPHA); 
+      break;
+   case GL_ZERO: 
+      funcRGB |= DST_BLND_FACT(BLENDFACT_ZERO); 
+      break;
+   case GL_ONE: 
+      funcRGB |= DST_BLND_FACT(BLENDFACT_ONE); 
+      break;
+   case GL_SRC_COLOR: 
+      funcRGB |= DST_BLND_FACT(BLENDFACT_SRC_COLR); 
+      break;
+   case GL_ONE_MINUS_SRC_COLOR: 
+      funcRGB |= DST_BLND_FACT(BLENDFACT_INV_SRC_COLR); 
+      break;
+   case GL_DST_ALPHA: 
+      funcRGB |= DST_BLND_FACT(BLENDFACT_DST_ALPHA); 
+      break;
+   case GL_ONE_MINUS_DST_ALPHA: 
+      funcRGB |= DST_BLND_FACT(BLENDFACT_INV_DST_ALPHA); 
+      break;
+   case GL_CONSTANT_COLOR_EXT:
+      funcRGB |= DST_BLND_FACT(BLENDFACT_CONST_COLOR); 
+      break;
+   case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
+      funcRGB |= DST_BLND_FACT(BLENDFACT_INV_CONST_COLOR);
+      break;
+   case GL_CONSTANT_ALPHA_EXT:
+      funcRGB |= DST_BLND_FACT(BLENDFACT_CONST_ALPHA); 
+      break;
+   case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
+      funcRGB |= DST_BLND_FACT(BLENDFACT_INV_CONST_ALPHA); 
+      break;
+   default: return;
+   }
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+   imesa->Setup[I830_CTXREG_IALPHAB] &= ~SRC_DST_ABLEND_MASK;
+   imesa->Setup[I830_CTXREG_IALPHAB] |= funcA;
+   imesa->Setup[I830_CTXREG_STATE1] &= ~SRC_DST_BLND_MASK;
+   imesa->Setup[I830_CTXREG_STATE1] |= funcRGB;
+
+   /* Insure Independant Alpha Blend is really enabled if
+    * Blending is already enabled. 
+    */
+   i830EvalLogicOpBlendState(ctx);
+}
+
+static void i830DepthFunc(GLcontext *ctx, GLenum func)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   int test = 0;
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   switch(func) {
+   case GL_NEVER: 
+      test = COMPAREFUNC_NEVER; 
+      break;
+   case GL_LESS: 
+      test = COMPAREFUNC_LESS; 
+      break;
+   case GL_LEQUAL: 
+      test = COMPAREFUNC_LEQUAL; 
+      break;
+   case GL_GREATER: 
+      test = COMPAREFUNC_GREATER; 
+      break;
+   case GL_GEQUAL: 
+      test = COMPAREFUNC_GEQUAL; 
+      break;
+   case GL_NOTEQUAL: 
+      test = COMPAREFUNC_NOTEQUAL; 
+      break;
+   case GL_EQUAL: 
+      test = COMPAREFUNC_EQUAL; 
+      break;
+   case GL_ALWAYS: 
+      test = COMPAREFUNC_ALWAYS; 
+      break;
+   default: return;
+   }
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+   imesa->Setup[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK;
+   imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC |
+                                      DEPTH_TEST_FUNC(test));
+}
+
+static void i830DepthMask(GLcontext *ctx, GLboolean flag)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag);
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+
+   imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK;
+
+   if (flag && ctx->Depth.Test)
+      imesa->Setup[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE;
+   else
+      imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE;
+}
+
+/* =============================================================
+ * Polygon stipple
+ *
+ * The i830 supports a 4x4 stipple natively, GL wants 32x32.
+ * Fortunately stipple is usually a repeating pattern.
+ */
+static void i830PolygonStipple( GLcontext *ctx, const GLubyte *mask )
+{
+   i830ContextPtr imesa = I830_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) {
+      I830_STATECHANGE(imesa, I830_UPLOAD_STIPPLE);
+      imesa->StippleSetup[I830_STPREG_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 = 3 ; j >= 0; j--)
+        for (i = 0 ; i < 4 ; i++, m++)
+           if (*m != p[j]) {
+              imesa->hw_stipple = 0;
+              return;
+           }
+
+   newMask = (((p[0] & 0xf) << 0) |
+             ((p[1] & 0xf) << 4) |
+             ((p[2] & 0xf) << 8) |
+             ((p[3] & 0xf) << 12));
+
+
+   if (newMask == 0xffff || newMask == 0x0) {
+      /* this is needed to make conform pass */
+      imesa->hw_stipple = 0;
+      return;
+   }
+
+   imesa->StippleSetup[I830_STPREG_ST1] &= ~0xffff;
+   imesa->StippleSetup[I830_STPREG_ST1] |= newMask;
+   imesa->hw_stipple = 1;
+
+   if (active)
+      imesa->StippleSetup[I830_STPREG_ST1] |= ST1_ENABLE;
+}
+
+static void i830PolygonStippleFallback( GLcontext *ctx, const GLubyte *mask )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   imesa->hw_stipple = 0;
+   (void) i830PolygonStipple;
+}
+
+/* =============================================================
+ * Hardware clipping
+ */
+static void i830Scissor(GLcontext *ctx, GLint x, GLint y, 
+                       GLsizei w, GLsizei h)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   int x1 = x;
+   int y1 = imesa->driDrawable->h - (y + h);
+   int x2 = x + w - 1;
+   int y2 = y1 + h - 1;
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__,
+             x, y, w, h);
+
+   if (x1 < 0) x1 = 0;
+   if (y1 < 0) y1 = 0;
+   if (x2 < 0) x2 = 0;
+   if (y2 < 0) y2 = 0;
+
+   if (x2 >= imesa->i830Screen->width) x2 = imesa->i830Screen->width-1;
+   if (y2 >= imesa->i830Screen->height) y2 = imesa->i830Screen->height-1;
+   if (x1 >= imesa->i830Screen->width) x1 = imesa->i830Screen->width-1;
+   if (y1 >= imesa->i830Screen->height) y1 = imesa->i830Screen->height-1;
+
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS);
+   imesa->BufferSetup[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff);
+   imesa->BufferSetup[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff);
+}
+
+static void i830LogicOp(GLcontext *ctx, GLenum opcode)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   int tmp = 0;
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   /* FIXME: This should be a look-up table, like the r200 driver. */
+   switch(opcode) {
+   case GL_CLEAR: 
+      tmp = LOGICOP_CLEAR; 
+      break;
+   case GL_AND: 
+      tmp = LOGICOP_AND; 
+      break;
+   case GL_AND_REVERSE: 
+      tmp = LOGICOP_AND_RVRSE; 
+      break;
+   case GL_COPY: 
+      tmp = LOGICOP_COPY; 
+      break;
+   case GL_COPY_INVERTED: 
+      tmp = LOGICOP_COPY_INV; 
+      break;
+   case GL_AND_INVERTED: 
+      tmp = LOGICOP_AND_INV; 
+      break;
+   case GL_NOOP: 
+      tmp = LOGICOP_NOOP; 
+      break;
+   case GL_XOR: 
+      tmp = LOGICOP_XOR; 
+      break;
+   case GL_OR: 
+      tmp = LOGICOP_OR; 
+      break;
+   case GL_OR_INVERTED: 
+      tmp = LOGICOP_OR_INV; 
+      break;
+   case GL_NOR: 
+      tmp = LOGICOP_NOR; 
+      break;
+   case GL_EQUIV: 
+      tmp = LOGICOP_EQUIV; 
+      break;
+   case GL_INVERT: 
+      tmp = LOGICOP_INV; 
+      break;
+   case GL_OR_REVERSE: 
+      tmp = LOGICOP_OR_RVRSE; 
+      break;
+   case GL_NAND: 
+      tmp = LOGICOP_NAND; 
+      break;
+   case GL_SET: 
+      tmp = LOGICOP_SET; 
+      break;
+   default:
+      return;
+   }
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+   imesa->Setup[I830_CTXREG_STATE4] &= ~LOGICOP_MASK;
+   imesa->Setup[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp);
+
+   /* Make sure all the enables are correct */
+   i830EvalLogicOpBlendState(ctx);
+}
+
+/* Fallback to swrast for select and feedback.
+ */
+static void i830RenderMode( GLcontext *ctx, GLenum mode )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   FALLBACK( imesa, I830_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
+}
+
+static void i830DrawBuffer(GLcontext *ctx, GLenum mode )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+
+   /*
+    * _DrawDestMask is easier to cope with than <mode>.
+    */
+   switch ( ctx->Color._DrawDestMask ) {
+   case FRONT_LEFT_BIT:
+      I830_FIREVERTICES(imesa);
+      I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS);
+      imesa->BufferSetup[I830_DESTREG_CBUFADDR] = imesa->i830Screen->fbOffset;
+      i830XMesaSetFrontClipRects( imesa );
+      FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE );
+      break;
+   case BACK_LEFT_BIT:
+      I830_FIREVERTICES(imesa);
+      I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS);
+      imesa->BufferSetup[I830_DESTREG_CBUFADDR] = 
+                                       imesa->i830Screen->backOffset;
+      i830XMesaSetBackClipRects( imesa );
+      FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE );
+      break;
+   default:
+      /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
+      FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_TRUE );
+      return;
+   }
+
+   /* We want to update the s/w rast state too so that i830SetBuffer()
+    * gets called.
+    */
+   _swrast_DrawBuffer(ctx, mode);
+}
+
+static void i830ReadBuffer(GLcontext *ctx, GLenum mode )
+{
+   /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
+}
+
+static void i830ClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+
+   CLAMPED_FLOAT_TO_UBYTE(imesa->clear_red, color[0]);
+   CLAMPED_FLOAT_TO_UBYTE(imesa->clear_green, color[1]);
+   CLAMPED_FLOAT_TO_UBYTE(imesa->clear_blue, color[2]);
+   CLAMPED_FLOAT_TO_UBYTE(imesa->clear_alpha, color[3]);
+
+   imesa->ClearColor = i830PackColor(imesa->i830Screen->fbFormat,
+                                    imesa->clear_red,
+                                     imesa->clear_green,
+                                     imesa->clear_blue,
+                                     imesa->clear_alpha);
+}
+
+static void i830CullFaceFrontFace(GLcontext *ctx, GLenum unused)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   GLuint mode = CULLMODE_BOTH;
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
+      mode = CULLMODE_CW;
+
+      if (ctx->Polygon.CullFaceMode == GL_FRONT)
+        mode ^= (CULLMODE_CW ^ CULLMODE_CCW);
+      if (ctx->Polygon.FrontFace != GL_CCW)
+        mode ^= (CULLMODE_CW ^ CULLMODE_CCW);
+   }
+
+   imesa->LcsCullMode = mode;
+
+   if (ctx->Polygon.CullFlag) {
+      I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+      imesa->Setup[I830_CTXREG_STATE3] &= ~CULLMODE_MASK;
+      imesa->Setup[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode;
+   }
+}
+
+static void i830LineWidth( GLcontext *ctx, GLfloat widthf )
+{
+   i830ContextPtr imesa = I830_CONTEXT( ctx );
+   int width;
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   width = FloatToInt(widthf * 2);
+   CLAMP_SELF(width, 1, 15);
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+   imesa->Setup[I830_CTXREG_STATE5] &= ~FIXED_LINE_WIDTH_MASK;
+   imesa->Setup[I830_CTXREG_STATE5] |= (ENABLE_FIXED_LINE_WIDTH |
+                                      FIXED_LINE_WIDTH(width));
+}
+
+static void i830PointSize(GLcontext *ctx, GLfloat size)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   GLint point_size = FloatToInt(size);
+
+   if (I830_DEBUG&DEBUG_DRI)
+     fprintf(stderr, "%s\n", __FUNCTION__);
+
+   CLAMP_SELF(point_size, 1, 256);
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+   imesa->Setup[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK;
+   imesa->Setup[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH |
+                                      FIXED_POINT_WIDTH(point_size));
+}
+
+
+/* =============================================================
+ * Color masks
+ */
+
+static void i830ColorMask(GLcontext *ctx,
+                         GLboolean r, GLboolean g,
+                         GLboolean b, GLboolean a)
+{
+   i830ContextPtr imesa = I830_CONTEXT( ctx );
+   GLuint tmp = 0;
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a);
+
+   imesa->mask_red = !r;
+   imesa->mask_green = !g;
+   imesa->mask_blue = !b;
+   imesa->mask_alpha = !a;
+
+   tmp = (imesa->Setup[I830_CTXREG_ENABLES_2] & ~WRITEMASK_MASK) |
+      ENABLE_COLOR_MASK |
+      ENABLE_COLOR_WRITE |
+      ((!r) << WRITEMASK_RED_SHIFT) |
+      ((!g) << WRITEMASK_GREEN_SHIFT) |
+      ((!b) << WRITEMASK_BLUE_SHIFT) |
+      ((!a) << WRITEMASK_ALPHA_SHIFT);
+
+   if (tmp != imesa->Setup[I830_CTXREG_ENABLES_2]) {
+      I830_FIREVERTICES(imesa);
+      imesa->dirty |= I830_UPLOAD_CTX;
+      imesa->Setup[I830_CTXREG_ENABLES_2] = tmp;
+   }
+}
+
+static void update_specular( GLcontext *ctx )
+{
+   i830ContextPtr imesa = I830_CONTEXT( ctx );
+
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+   imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK;
+
+   if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+      imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD;
+   else
+      imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD;
+}
+
+static void i830LightModelfv(GLcontext *ctx, GLenum pname, 
+                            const GLfloat *param)
+{
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
+      update_specular( ctx );
+   }
+}
+
+/* In Mesa 3.5 we can reliably do native flatshading.
+ */
+static void i830ShadeModel(GLcontext *ctx, GLenum mode)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+
+
+#define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4))
+
+   imesa->Setup[I830_CTXREG_STATE3] &= ~SHADE_MODE_MASK;
+
+   if (mode == GL_FLAT) {
+     imesa->Setup[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_FLAT) |
+                                         FOG_SHADE_MODE(SHADE_MODE_FLAT) |
+                                         SPEC_SHADE_MODE(SHADE_MODE_FLAT) |
+                                         COLOR_SHADE_MODE(SHADE_MODE_FLAT));
+   } else {
+     imesa->Setup[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) |
+                                         FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
+                                         SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
+                                         COLOR_SHADE_MODE(SHADE_MODE_LINEAR));
+   }
+}
+
+/* =============================================================
+ * Fog
+ */
+static void i830Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+
+   if (I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   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));
+
+      I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+      imesa->Setup[I830_CTXREG_FOGCOLOR] = (STATE3D_FOG_COLOR_CMD | color);
+   }
+}
+
+/* =============================================================
+ */
+
+static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+
+   switch(cap) {
+   case GL_LIGHTING:
+   case GL_COLOR_SUM_EXT:
+      update_specular( ctx );
+      break;
+
+   case GL_ALPHA_TEST:
+      I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+      imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK;
+      if (state)
+        imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST;
+      else
+        imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST;
+
+      break;
+
+   case GL_BLEND:
+   case GL_COLOR_LOGIC_OP:
+   case GL_INDEX_LOGIC_OP:
+      i830EvalLogicOpBlendState(ctx);
+      break;
+
+   case GL_DITHER:
+      I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+      imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_DITHER;
+
+      if (state)
+        imesa->Setup[I830_CTXREG_ENABLES_2] |= ENABLE_DITHER;
+      else
+        imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_DITHER;
+      break;
+
+   case GL_DEPTH_TEST:
+      I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+      imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK;
+
+      if (state)
+        imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST;
+      else
+        imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST;
+
+      /* Also turn off depth writes when GL_DEPTH_TEST is disabled:
+       */
+      i830DepthMask( ctx, state );
+      break;
+
+   case GL_SCISSOR_TEST:
+      I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS);
+      
+      if (state)
+        imesa->BufferSetup[I830_DESTREG_SENABLE] = 
+           (STATE3D_SCISSOR_ENABLE_CMD |
+            ENABLE_SCISSOR_RECT);
+      else
+        imesa->BufferSetup[I830_DESTREG_SENABLE] = 
+           (STATE3D_SCISSOR_ENABLE_CMD |
+            DISABLE_SCISSOR_RECT);
+
+      imesa->upload_cliprects = GL_TRUE;
+      break;
+
+   case GL_LINE_SMOOTH:
+      if (imesa->reduced_primitive == GL_LINES) {
+        I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+
+        imesa->Setup[I830_CTXREG_AA] &= ~AA_LINE_ENABLE;
+        if (state)
+           imesa->Setup[I830_CTXREG_AA] |= AA_LINE_ENABLE;
+        else
+           imesa->Setup[I830_CTXREG_AA] |= AA_LINE_DISABLE;
+      }
+      break;
+
+   case GL_FOG:
+      I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+      imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK;
+      if (state)
+        imesa->Setup[I830_CTXREG_ENABLES_1] |= I830_ENABLE_FOG;
+      else
+        imesa->Setup[I830_CTXREG_ENABLES_1] |= I830_DISABLE_FOG;
+      break;
+
+   case GL_CULL_FACE:
+      I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+      imesa->Setup[I830_CTXREG_STATE3] &= ~CULLMODE_MASK;
+      if (state)
+        imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE |
+                                             imesa->LcsCullMode);
+      else
+        imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE |
+                                             CULLMODE_NONE);
+      break;
+
+   case GL_TEXTURE_2D:
+/*       I830_STATECHANGE(imesa, I830_UPLOAD_CTX); */
+/*       imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; */
+      break;
+
+   case GL_STENCIL_TEST:
+      if (imesa->hw_stencil) {
+        I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+        imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST;
+
+        if (state) {
+           imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST;
+        } else {
+           imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST;
+        }
+      } else {
+        FALLBACK( imesa, I830_FALLBACK_STENCIL, state );
+      }
+      break;
+
+   case GL_POLYGON_STIPPLE:
+#if 0
+      /* The stipple command worked on my 855GM box, but not my 845G.
+       * I'll do more testing later to find out exactly which hardware
+       * supports it.  Disabled for now.
+       */
+      if (imesa->hw_stipple && imesa->reduced_primitive == GL_TRIANGLES)
+      {
+        I830_STATECHANGE(imesa, I830_UPLOAD_STIPPLE);
+        imesa->StippleSetup[I830_STPREG_ST1] &= ~ST1_ENABLE;
+        if (state)
+           imesa->StippleSetup[I830_STPREG_ST1] |= ST1_ENABLE;
+      }
+#endif
+      break;
+
+   default:
+      ;
+   }
+}
+
+
+void i830EmitDrawingRectangle( i830ContextPtr imesa )
+{
+   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+   i830ScreenPrivate *i830Screen = imesa->i830Screen;
+   int x0 = imesa->drawX;
+   int y0 = imesa->drawY;
+   int x1 = x0 + dPriv->w;
+   int y1 = y0 + dPriv->h;
+
+   /* Don't set drawing rectangle */
+   if (I830_DEBUG & DEBUG_IOCTL)
+      fprintf(stderr, "%s x0(%d) x1(%d) y0(%d) y1(%d)\n", __FUNCTION__,
+             x0, x1, y0, y1);
+
+   /* Coordinate origin of the window - may be offscreen.
+    */
+   imesa->BufferSetup[I830_DESTREG_DR4] = ((y0<<16) | 
+                                          (((unsigned)x0)&0xFFFF));
+  
+   /* Clip to screen.
+    */
+   if (x0 < 0) x0 = 0;
+   if (y0 < 0) y0 = 0;
+   if (x1 > i830Screen->width-1) x1 = i830Screen->width-1;
+   if (y1 > i830Screen->height-1) y1 = i830Screen->height-1;
+
+
+   /* Onscreen drawing rectangle.
+    */
+   imesa->BufferSetup[I830_DESTREG_DR2] = ((y0<<16) | x0);
+   imesa->BufferSetup[I830_DESTREG_DR3] = (((y1+1)<<16) | (x1+1));
+
+   
+   /* Just add in our dirty flag, since we might be called when locked */
+   /* Might want to modify how this is done. */
+   imesa->dirty |= I830_UPLOAD_BUFFERS;
+
+   if (0)
+      fprintf(stderr, "[%s] DR2(0x%08x) DR3(0x%08x) DR4(0x%08x)\n",
+             __FUNCTION__,
+             imesa->BufferSetup[I830_DESTREG_DR2],
+             imesa->BufferSetup[I830_DESTREG_DR3],
+             imesa->BufferSetup[I830_DESTREG_DR4]);
+}
+
+/* This could be done in hardware, will do once I have the driver
+ * up and running.
+ */
+static void i830CalcViewport( GLcontext *ctx )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   const GLfloat *v = ctx->Viewport._WindowMap.m;
+   GLfloat *m = imesa->ViewportMatrix.m;
+
+   /* See also i830_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] * imesa->depth_scale;
+   m[MAT_TZ] =   v[MAT_TZ] * imesa->depth_scale;
+}
+
+static void i830Viewport( GLcontext *ctx,
+                         GLint x, GLint y,
+                         GLsizei width, GLsizei height )
+{
+   i830CalcViewport( ctx );
+}
+
+static void i830DepthRange( GLcontext *ctx,
+                           GLclampd nearval, GLclampd farval )
+{
+   i830CalcViewport( ctx );
+}
+
+void i830PrintDirty( const char *msg, GLuint state )
+{
+   fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n",
+          msg,
+          (unsigned int) state,
+          (state & I830_UPLOAD_TEX0)  ? "upload-tex0, " : "",
+          (state & I830_UPLOAD_TEX1)  ? "upload-tex1, " : "",
+          (state & I830_UPLOAD_CTX)        ? "upload-ctx, " : "",
+          (state & I830_UPLOAD_BUFFERS)    ? "upload-bufs, " : "",
+          (state & I830_UPLOAD_TEXBLEND0)  ? "upload-blend0, " : "",
+          (state & I830_UPLOAD_TEXBLEND1)  ? "upload-blend1, " : "",
+          (state & I830_UPLOAD_STIPPLE)  ? "stipple, " : ""
+          );
+}
+
+/* Push the state into the sarea and/or texture memory.
+ */
+void i830EmitHwStateLocked( i830ContextPtr imesa )
+{
+   int i;
+
+   if (I830_DEBUG & DEBUG_STATE)
+      i830PrintDirty( __FUNCTION__, imesa->dirty );
+
+   if ((imesa->dirty & I830_UPLOAD_TEX0_IMAGE) && imesa->CurrentTexObj[0])
+      i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[0]);
+   if ((imesa->dirty & I830_UPLOAD_TEX1_IMAGE) && imesa->CurrentTexObj[1])
+      i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[1]);
+   if (imesa->dirty & I830_UPLOAD_CTX) {
+      memcpy( imesa->sarea->ContextState,
+            imesa->Setup, sizeof(imesa->Setup) );
+   }
+
+   for (i = 0; i < I830_TEXTURE_COUNT; i++) {
+      if ((imesa->dirty & I830_UPLOAD_TEX_N(i)) && imesa->CurrentTexObj[i]) {
+        imesa->sarea->dirty |= I830_UPLOAD_TEX_N(i);
+        memcpy(imesa->sarea->TexState[i],
+               imesa->CurrentTexObj[i]->Setup,
+               sizeof(imesa->sarea->TexState[i]));
+         
+        imesa->sarea->TexState[i][I830_TEXREG_TM0S3] &= ~TM0S3_LOD_BIAS_MASK;
+        imesa->sarea->TexState[i][I830_TEXREG_TM0S3] |= imesa->LodBias[i];
+
+        /* Update the LRU usage */
+        if (imesa->CurrentTexObj[i]->base.memBlock)
+           driUpdateTextureLRU( (driTextureObject *) 
+                                imesa->CurrentTexObj[i] );
+      }
+   }
+   /* Need to figure out if texturing state, or enable changed. */
+
+   for (i = 0; i < I830_TEXBLEND_COUNT; i++) {
+      if (imesa->dirty & I830_UPLOAD_TEXBLEND_N(i)) {
+        imesa->sarea->dirty |= I830_UPLOAD_TEXBLEND_N(i);
+        memcpy(imesa->sarea->TexBlendState[i],imesa->TexBlend[i],
+               imesa->TexBlendWordsUsed[i] * 4);
+        imesa->sarea->TexBlendStateWordsUsed[i] =
+          imesa->TexBlendWordsUsed[i];
+      }
+   }
+
+   if (imesa->dirty & I830_UPLOAD_BUFFERS) {
+      memcpy( imesa->sarea->BufferState,imesa->BufferSetup, 
+             sizeof(imesa->BufferSetup) );
+   }
+
+   if (imesa->dirty & I830_UPLOAD_STIPPLE) {
+      memcpy( imesa->sarea->StippleState,imesa->StippleSetup, 
+             sizeof(imesa->StippleSetup) );
+   }
+
+   if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_SHARED) {
+      memcpy( imesa->sarea->Palette[0],imesa->palette,
+             sizeof(imesa->sarea->Palette[0]));
+   } else {
+      i830TextureObjectPtr p;
+      if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(0)) {
+        p = imesa->CurrentTexObj[0];
+        memcpy( imesa->sarea->Palette[0],p->palette,
+               sizeof(imesa->sarea->Palette[0]));
+      }
+      if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(1)) {
+        p = imesa->CurrentTexObj[1];
+        memcpy( imesa->sarea->Palette[1],
+                p->palette,
+                sizeof(imesa->sarea->Palette[1]));
+      }
+   }
+   
+   imesa->sarea->dirty |= (imesa->dirty & ~(I830_UPLOAD_TEX_MASK | 
+                                           I830_UPLOAD_TEXBLEND_MASK));
+
+   imesa->upload_cliprects = GL_TRUE;
+   imesa->dirty = 0;
+}
+
+
+void i830DDInitState( GLcontext *ctx )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);   
+   i830ScreenPrivate *i830Screen = imesa->i830Screen;
+   int i, j;
+
+   imesa->clear_red = 0;
+   imesa->clear_green = 0;
+   imesa->clear_blue = 0;
+   imesa->clear_alpha = 0;
+
+   imesa->mask_red = GL_FALSE;
+   imesa->mask_green = GL_FALSE;
+   imesa->mask_blue = GL_FALSE;
+   imesa->mask_alpha = GL_FALSE;
+
+   /* Zero all texture state */
+   for (i = 0; i < I830_TEXBLEND_COUNT; i++) {
+      for (j = 0; j < I830_TEXBLEND_SIZE; j++) {
+        imesa->TexBlend[i][j] = 0;
+        imesa->Init_TexBlend[i][j] = 0;
+      }
+      imesa->TexBlendWordsUsed[i] = 0;
+      imesa->Init_TexBlendWordsUsed[i] = 0;
+      imesa->TexBlendColorPipeNum[i] = 0;
+      imesa->Init_TexBlendColorPipeNum[i] = 0;
+   }
+
+   /* Set default blend state */
+   imesa->TexBlend[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
+                           TEXPIPE_COLOR |
+                           ENABLE_TEXOUTPUT_WRT_SEL |
+                           TEXOP_OUTPUT_CURRENT |
+                           DISABLE_TEX_CNTRL_STAGE |
+                           TEXOP_SCALE_1X |
+                           TEXOP_MODIFY_PARMS |
+                           TEXOP_LAST_STAGE |
+                           TEXBLENDOP_ARG1);
+   imesa->TexBlend[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
+                           TEXPIPE_ALPHA |
+                           ENABLE_TEXOUTPUT_WRT_SEL |
+                           TEXOP_OUTPUT_CURRENT |
+                           TEXOP_SCALE_1X |
+                           TEXOP_MODIFY_PARMS |
+                           TEXBLENDOP_ARG1);
+   imesa->TexBlend[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
+                           TEXPIPE_COLOR |
+                           TEXBLEND_ARG1 |
+                           TEXBLENDARG_MODIFY_PARMS |
+                           TEXBLENDARG_DIFFUSE);
+   imesa->TexBlend[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
+                           TEXPIPE_ALPHA |
+                           TEXBLEND_ARG1 |
+                           TEXBLENDARG_MODIFY_PARMS |
+                           TEXBLENDARG_DIFFUSE);
+
+   imesa->TexBlendWordsUsed[0] = 4;
+   imesa->TexBlendColorPipeNum[0] = 0;
+
+   imesa->Init_TexBlend[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
+                           TEXPIPE_COLOR |
+                           ENABLE_TEXOUTPUT_WRT_SEL |
+                           TEXOP_OUTPUT_CURRENT |
+                           DISABLE_TEX_CNTRL_STAGE |
+                           TEXOP_SCALE_1X |
+                           TEXOP_MODIFY_PARMS |
+                           TEXOP_LAST_STAGE |
+                           TEXBLENDOP_ARG1);
+   imesa->Init_TexBlend[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
+                           TEXPIPE_ALPHA |
+                           ENABLE_TEXOUTPUT_WRT_SEL |
+                           TEXOP_OUTPUT_CURRENT |
+                           TEXOP_SCALE_1X |
+                           TEXOP_MODIFY_PARMS |
+                           TEXBLENDOP_ARG1);
+   imesa->Init_TexBlend[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
+                           TEXPIPE_COLOR |
+                           TEXBLEND_ARG1 |
+                           TEXBLENDARG_MODIFY_PARMS |
+                           TEXBLENDARG_CURRENT);
+   imesa->Init_TexBlend[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
+                           TEXPIPE_ALPHA |
+                           TEXBLEND_ARG1 |
+                           TEXBLENDARG_MODIFY_PARMS |
+                           TEXBLENDARG_CURRENT);
+   imesa->Init_TexBlendWordsUsed[0] = 4;
+   imesa->Init_TexBlendColorPipeNum[0] = 0;
+
+   memset(imesa->Setup, 0, sizeof(imesa->Setup));
+
+   imesa->Setup[I830_CTXREG_VF] =  (STATE3D_VERTEX_FORMAT_CMD |
+                                   VRTX_TEX_COORD_COUNT(1) |
+                                   VRTX_HAS_DIFFUSE |
+                                   VRTX_HAS_SPEC |
+                                   VRTX_HAS_XYZW);
+   imesa->vertex_format = 0;
+   imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD |
+                                   VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) |
+                                   VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) | 
+                                   VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) |
+                                   VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D));
+
+   imesa->Setup[I830_CTXREG_AA] = (STATE3D_AA_CMD |
+                                  AA_LINE_ECAAR_WIDTH_ENABLE |
+                                  AA_LINE_ECAAR_WIDTH_1_0 |
+                                  AA_LINE_REGION_WIDTH_ENABLE |
+                                  AA_LINE_REGION_WIDTH_1_0 | 
+                                  AA_LINE_DISABLE);
+
+   imesa->Setup[I830_CTXREG_ENABLES_1] = (STATE3D_ENABLES_1_CMD |
+                                         DISABLE_LOGIC_OP |
+                                         DISABLE_STENCIL_TEST |
+                                         DISABLE_DEPTH_BIAS |
+                                         DISABLE_SPEC_ADD |
+                                         I830_DISABLE_FOG |
+                                         DISABLE_ALPHA_TEST |
+                                         DISABLE_COLOR_BLEND |
+                                         DISABLE_DEPTH_TEST);
+
+   if (imesa->hw_stencil) {
+      imesa->Setup[I830_CTXREG_ENABLES_2] = (STATE3D_ENABLES_2_CMD |
+                                            ENABLE_STENCIL_WRITE |
+                                            ENABLE_TEX_CACHE |
+                                            ENABLE_DITHER |
+                                            ENABLE_COLOR_MASK |
+                                            /* set no color comps disabled */
+                                            ENABLE_COLOR_WRITE |
+                                            ENABLE_DEPTH_WRITE);
+   } else {
+      imesa->Setup[I830_CTXREG_ENABLES_2] = (STATE3D_ENABLES_2_CMD |
+                                            DISABLE_STENCIL_WRITE |
+                                            ENABLE_TEX_CACHE |
+                                            ENABLE_DITHER |
+                                            ENABLE_COLOR_MASK |
+                                            /* set no color comps disabled */
+                                            ENABLE_COLOR_WRITE |
+                                            ENABLE_DEPTH_WRITE);
+   }
+
+   imesa->Setup[I830_CTXREG_STATE1] = (STATE3D_MODES_1_CMD |
+                                     ENABLE_COLR_BLND_FUNC |
+                                     BLENDFUNC_ADD |
+                                     ENABLE_SRC_BLND_FACTOR |
+                                     SRC_BLND_FACT(BLENDFACT_ONE) | 
+                                     ENABLE_DST_BLND_FACTOR |
+                                     DST_BLND_FACT(BLENDFACT_ZERO) );
+
+   imesa->Setup[I830_CTXREG_STATE2] = (STATE3D_MODES_2_CMD |
+                                     ENABLE_GLOBAL_DEPTH_BIAS | 
+                                     GLOBAL_DEPTH_BIAS(0) |
+                                     ENABLE_ALPHA_TEST_FUNC | 
+                                     ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) |
+                                     ALPHA_REF_VALUE(0) );
+
+   imesa->Setup[I830_CTXREG_STATE3] = (STATE3D_MODES_3_CMD |
+                                     ENABLE_DEPTH_TEST_FUNC |
+                                     DEPTH_TEST_FUNC(COMPAREFUNC_LESS) |
+                                     ENABLE_ALPHA_SHADE_MODE |
+                                     ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) |
+                                     ENABLE_FOG_SHADE_MODE |
+                                     FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
+                                     ENABLE_SPEC_SHADE_MODE |
+                                     SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
+                                     ENABLE_COLOR_SHADE_MODE |
+                                     COLOR_SHADE_MODE(SHADE_MODE_LINEAR) |
+                                     ENABLE_CULL_MODE |
+                                     CULLMODE_NONE);
+
+   imesa->Setup[I830_CTXREG_STATE4] = (STATE3D_MODES_4_CMD |
+                                     ENABLE_LOGIC_OP_FUNC |
+                                     LOGIC_OP_FUNC(LOGICOP_COPY) |
+                                     ENABLE_STENCIL_TEST_MASK |
+                                     STENCIL_TEST_MASK(0xff) |
+                                     ENABLE_STENCIL_WRITE_MASK |
+                                     STENCIL_WRITE_MASK(0xff));
+
+   imesa->Setup[I830_CTXREG_STENCILTST] = (STATE3D_STENCIL_TEST_CMD |
+                                 ENABLE_STENCIL_PARMS |
+                                 STENCIL_FAIL_OP(STENCILOP_KEEP) |
+                                 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP) |
+                                 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP) |
+                                 ENABLE_STENCIL_TEST_FUNC |
+                                 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS) |
+                                 ENABLE_STENCIL_REF_VALUE |
+                                 STENCIL_REF_VALUE(0) );
+
+   imesa->Setup[I830_CTXREG_STATE5] = (STATE3D_MODES_5_CMD |
+                                      FLUSH_TEXTURE_CACHE |
+                                      ENABLE_SPRITE_POINT_TEX |
+                                      SPRITE_POINT_TEX_OFF |
+                                      ENABLE_FIXED_LINE_WIDTH |
+                                      FIXED_LINE_WIDTH(0x2) | /* 1.0 */
+                                      ENABLE_FIXED_POINT_WIDTH |
+                                      FIXED_POINT_WIDTH(1) );
+
+   imesa->Setup[I830_CTXREG_IALPHAB] = (STATE3D_INDPT_ALPHA_BLEND_CMD |
+                                      DISABLE_INDPT_ALPHA_BLEND |
+                                      ENABLE_ALPHA_BLENDFUNC |
+                                      ABLENDFUNC_ADD);
+
+   imesa->Setup[I830_CTXREG_FOGCOLOR] = (STATE3D_FOG_COLOR_CMD |
+                                       FOG_COLOR_RED(0) |
+                                       FOG_COLOR_GREEN(0) |
+                                       FOG_COLOR_BLUE(0));
+
+   imesa->Setup[I830_CTXREG_BLENDCOLR0] = (STATE3D_CONST_BLEND_COLOR_CMD);
+
+   imesa->Setup[I830_CTXREG_BLENDCOLR] = 0;
+
+   imesa->Setup[I830_CTXREG_MCSB0] = STATE3D_MAP_COORD_SETBIND_CMD;
+   imesa->Setup[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) |
+                                    TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) |
+                                    TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
+                                    TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
+
+   imesa->LcsCullMode = CULLMODE_CW; /* GL default */
+
+   memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup));
+   memset(imesa->StippleSetup, 0, sizeof(imesa->StippleSetup));
+
+
+   if (imesa->glCtx->Visual.doubleBufferMode &&
+       imesa->sarea->pf_current_page == 0) {
+      imesa->drawMap = i830Screen->back.map;
+      imesa->readMap = i830Screen->back.map;
+      imesa->BufferSetup[I830_DESTREG_CBUFADDR] = i830Screen->backOffset;
+      imesa->BufferSetup[I830_DESTREG_DBUFADDR] = 0;
+   } else {
+      /* use front buffer by default */
+      imesa->drawMap = (char *)imesa->driScreen->pFB;
+      imesa->readMap = (char *)imesa->driScreen->pFB;
+      imesa->BufferSetup[I830_DESTREG_CBUFADDR] = i830Screen->fbOffset;
+      imesa->BufferSetup[I830_DESTREG_DBUFADDR] = 0;      
+   }
+
+   imesa->BufferSetup[I830_DESTREG_DV0] = STATE3D_DST_BUF_VARS_CMD;
+
+   switch (i830Screen->fbFormat) {
+   case DV_PF_555:
+   case DV_PF_565:
+      imesa->BufferSetup[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
+                                            DSTORG_VERT_BIAS(0x8) | /* .5 */
+                                            i830Screen->fbFormat |
+                                            DEPTH_IS_Z |
+                                            DEPTH_FRMT_16_FIXED);
+      break;
+   case DV_PF_8888:
+      imesa->BufferSetup[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
+                                            DSTORG_VERT_BIAS(0x8) | /* .5 */
+                                            i830Screen->fbFormat |
+                                            DEPTH_IS_Z |
+                                            DEPTH_FRMT_24_FIXED_8_OTHER);
+      break;
+   }
+   imesa->BufferSetup[I830_DESTREG_SENABLE] = (STATE3D_SCISSOR_ENABLE_CMD |
+                                             DISABLE_SCISSOR_RECT);
+   imesa->BufferSetup[I830_DESTREG_SR0] = STATE3D_SCISSOR_RECT_0_CMD;
+   imesa->BufferSetup[I830_DESTREG_SR1] = 0;
+   imesa->BufferSetup[I830_DESTREG_SR2] = 0;
+
+   imesa->BufferSetup[I830_DESTREG_DR0] = STATE3D_DRAW_RECT_CMD;
+   imesa->BufferSetup[I830_DESTREG_DR1] = 0;
+   imesa->BufferSetup[I830_DESTREG_DR2] = 0;
+   imesa->BufferSetup[I830_DESTREG_DR3] = (((i830Screen->height)<<16) | 
+                                         (i830Screen->width));
+   imesa->BufferSetup[I830_DESTREG_DR4] = 0;
+
+   memcpy( imesa->Init_Setup,
+          imesa->Setup, 
+          sizeof(imesa->Setup) );
+   memcpy( imesa->Init_BufferSetup,
+          imesa->BufferSetup, 
+          sizeof(imesa->BufferSetup) );
+
+}
+
+static void i830InvalidateState( 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 );
+   I830_CONTEXT(ctx)->NewGLState |= new_state;
+}
+
+void i830DDInitStateFuncs(GLcontext *ctx)
+{
+   /* Callbacks for internal Mesa events.
+    */
+   ctx->Driver.UpdateState = i830InvalidateState;
+
+   /* API callbacks
+    */
+   ctx->Driver.AlphaFunc = i830AlphaFunc;
+   ctx->Driver.BlendEquation = i830BlendEquation;
+   ctx->Driver.BlendFunc = i830BlendFunc;
+   ctx->Driver.BlendFuncSeparate = i830BlendFuncSeparate;
+   ctx->Driver.BlendColor = i830BlendColor;
+   ctx->Driver.ClearColor = i830ClearColor;
+   ctx->Driver.ColorMask = i830ColorMask;
+   ctx->Driver.CullFace = i830CullFaceFrontFace;
+   ctx->Driver.DepthFunc = i830DepthFunc;
+   ctx->Driver.DepthMask = i830DepthMask;
+   ctx->Driver.Enable = i830Enable;
+   ctx->Driver.Fogfv = i830Fogfv;
+   ctx->Driver.FrontFace = i830CullFaceFrontFace;
+   ctx->Driver.LineWidth = i830LineWidth;
+   ctx->Driver.PointSize = i830PointSize;
+   ctx->Driver.LogicOpcode = i830LogicOp;
+   ctx->Driver.PolygonStipple = i830PolygonStippleFallback;
+   ctx->Driver.RenderMode = i830RenderMode;
+   ctx->Driver.Scissor = i830Scissor;
+   ctx->Driver.DrawBuffer = i830DrawBuffer;
+   ctx->Driver.ReadBuffer = i830ReadBuffer;
+   ctx->Driver.ShadeModel = i830ShadeModel;
+   ctx->Driver.DepthRange = i830DepthRange;
+   ctx->Driver.Viewport = i830Viewport;
+   ctx->Driver.LightModelfv = i830LightModelfv;
+
+   ctx->Driver.StencilFunc = i830StencilFunc;
+   ctx->Driver.StencilMask = i830StencilMask;
+   ctx->Driver.StencilOp = i830StencilOp;
+
+   /* 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/i830/i830_state.h b/src/mesa/drivers/dri/i830/i830_state.h
new file mode 100644 (file)
index 0000000..b651651
--- /dev/null
@@ -0,0 +1,68 @@
+/**************************************************************************
+
+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.
+
+**************************************************************************/
+
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_state.h,v 1.3 2002/12/10 01:26:53 dawes Exp $ */
+
+/*
+ * Author:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ *
+ * Heavily based on the I810 driver, which was written by:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+#ifndef _I830_STATE_H
+#define _I830_STATE_H
+
+#include "i830_context.h"
+#include "colormac.h"
+#define FloatToInt(F) ((int)(F))
+
+/* 
+ *  * This function/macro is sensitive to precision.  Test carefully
+ *  * if you change it.
+ *  */
+#define FLOAT_COLOR_TO_UBYTE_COLOR(b, f)                        \
+           do {                                                            \
+           union {GLfloat r; GLuint i; }  tmp;                  \
+           tmp.r = f;                                           \
+           b = ((tmp.i >= IEEE_ONE)                             \
+                       ? ((GLint)tmp.i < 0) ? (GLubyte)0 : (GLubyte)255        \
+                       :  (tmp.r = tmp.r*(255.0F/256.0F) + 32768.0F,       \
+                  (GLubyte)tmp.i));                             \
+        } while (0)
+        
+        
+
+extern void i830DDInitState( GLcontext *ctx );
+extern void i830DDInitStateFuncs( GLcontext *ctx );
+
+extern void i830PrintDirty( const char *msg, GLuint state );
+extern void i830SetDrawBuffer(GLcontext *ctx, GLenum mode );
+
+extern void i830Fallback( i830ContextPtr imesa, GLuint bit, GLboolean mode );
+#define FALLBACK( imesa, bit, mode ) i830Fallback( imesa, bit, mode )
+#endif
diff --git a/src/mesa/drivers/dri/i830/i830_tex.c b/src/mesa/drivers/dri/i830/i830_tex.c
new file mode 100644 (file)
index 0000000..14a70a0
--- /dev/null
@@ -0,0 +1,579 @@
+/**************************************************************************
+
+Copyright 2001 2d3d Inc., Delray Beach, FL
+
+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.
+
+**************************************************************************/
+
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_tex.c,v 1.5 2003/05/07 21:56:31 dawes Exp $ */
+
+/*
+ * Author:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ *
+ * Heavily based on the I810 driver, which was written by:
+ *   Keith Whitwell <keithw@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "imports.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "texstore.h"
+#include "teximage.h"
+#include "texformat.h"
+#include "texmem.h"
+#include "swrast/swrast.h"
+
+#include "mm.h"
+
+#include "i830_screen.h"
+#include "i830_dri.h"
+#include "i830_context.h"
+#include "i830_tex.h"
+#include "i830_state.h"
+#include "i830_ioctl.h"
+
+/*
+ * Compute the 'S2.4' lod bias factor from the floating point OpenGL bias.
+ */
+static void i830ComputeLodBias( i830ContextPtr imesa, unsigned unit,
+                               GLfloat bias )
+{
+   int b;
+
+   b = (int) (bias * 16.0);
+   if(b > 63) b = 63;
+   else if (b < -64) b = -64;
+   imesa->LodBias[ unit ] = ((b << TM0S3_LOD_BIAS_SHIFT) & 
+                            TM0S3_LOD_BIAS_MASK);
+}
+
+
+/**
+ * Set the texture wrap modes.
+ * 
+ * The i830M (and related graphics cores) do not support GL_CLAMP.  The Intel
+ * drivers for "other operating systems" implement GL_CLAMP as
+ * GL_CLAMP_TO_EDGE, so the same is done here.
+ * 
+ * \param t Texture object whose wrap modes are to be set
+ * \param swrap Wrap mode for the \a s texture coordinate
+ * \param twrap Wrap mode for the \a t texture coordinate
+ */
+
+static void i830SetTexWrapping(i830TextureObjectPtr tex,
+                              GLenum swrap, GLenum twrap)
+{
+   tex->Setup[I830_TEXREG_MCS] &= ~(TEXCOORD_ADDR_U_MASK|TEXCOORD_ADDR_V_MASK);
+
+   switch( swrap ) {
+   case GL_REPEAT:
+      tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP);
+      break;
+   case GL_CLAMP:
+   case GL_CLAMP_TO_EDGE:
+      tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP);
+      break;
+   case GL_CLAMP_TO_BORDER:
+      tex->Setup[I830_TEXREG_MCS] |= 
+                       TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP_BORDER);
+      break;
+   case GL_MIRRORED_REPEAT:
+      tex->Setup[I830_TEXREG_MCS] |= 
+                       TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_MIRROR);
+      break;
+   default:
+      _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__);
+   }
+
+   switch( twrap ) {
+   case GL_REPEAT:
+      tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP);
+      break;
+   case GL_CLAMP:
+   case GL_CLAMP_TO_EDGE:
+      tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP);
+      break;
+   case GL_CLAMP_TO_BORDER:
+      tex->Setup[I830_TEXREG_MCS] |= 
+                       TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP_BORDER);
+      break;
+   case GL_MIRRORED_REPEAT:
+      tex->Setup[I830_TEXREG_MCS] |=
+                       TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_MIRROR);
+      break;
+   default:
+      _mesa_problem(NULL, "bad T wrap mode in %s", __FUNCTION__);
+   }
+}
+
+static void i830SetTexMaxAnisotropy( i830TextureObjectPtr t, GLfloat max )
+{
+   t->max_anisotropy = max;
+}
+
+
+/**
+ * Set the texture magnification and minification modes.
+ * 
+ * \param t Texture whose filter modes are to be set
+ * \param minf Texture minification mode
+ * \param magf Texture magnification mode
+ * \param bias LOD bias for this texture unit.
+ */
+
+static void i830SetTexFilter( i830TextureObjectPtr t,
+                             GLenum minf, GLenum magf )
+{
+   int minFilt = 0, mipFilt = 0, magFilt = 0;
+
+   if(I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   if ( t->max_anisotropy > 1.0 ) {
+      minFilt = FILTER_ANISOTROPIC;
+      magFilt = FILTER_ANISOTROPIC;
+   }
+   else {
+      switch (minf) {
+      case GL_NEAREST:
+        minFilt = FILTER_NEAREST;
+        mipFilt = MIPFILTER_NONE;
+        break;
+      case GL_LINEAR:
+        minFilt = FILTER_LINEAR;
+        mipFilt = MIPFILTER_NONE;
+        break;
+      case GL_NEAREST_MIPMAP_NEAREST:
+        minFilt = FILTER_NEAREST;
+        mipFilt = MIPFILTER_NEAREST;
+        break;
+      case GL_LINEAR_MIPMAP_NEAREST:
+        minFilt = FILTER_LINEAR;
+        mipFilt = MIPFILTER_NEAREST;
+        break;
+      case GL_NEAREST_MIPMAP_LINEAR:
+        minFilt = FILTER_NEAREST;
+        mipFilt = MIPFILTER_LINEAR;
+        break;
+      case GL_LINEAR_MIPMAP_LINEAR:
+        minFilt = FILTER_LINEAR;
+        mipFilt = MIPFILTER_LINEAR;
+        break;
+      default:
+        _mesa_problem(NULL, "%s: Unsupported min. filter %d", __FUNCTION__,
+                      (int) minf );
+        break;
+      }
+
+      switch (magf) {
+      case GL_NEAREST:
+        magFilt = FILTER_NEAREST;
+        break;
+      case GL_LINEAR:
+        magFilt = FILTER_LINEAR;
+        break;
+      default:
+        _mesa_problem(NULL, "%s: Unsupported mag. filter %d", __FUNCTION__,
+                      (int) magf );
+        break;
+      }  
+   }
+
+   t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_FILTER_MASK;
+   t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIP_FILTER_MASK;
+   t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAG_FILTER_MASK;
+   t->Setup[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) |
+                                  (mipFilt << TM0S3_MIP_FILTER_SHIFT) |
+                                  (magFilt << TM0S3_MAG_FILTER_SHIFT));
+}
+
+static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4])
+{
+   if(I830_DEBUG&DEBUG_DRI)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+    t->Setup[I830_TEXREG_TM0S4] = 
+        I830PACKCOLOR8888(color[0],color[1],color[2],color[3]);
+}
+
+
+/**
+ * Allocate space for and load the mesa images into the texture memory block.
+ * This will happen before drawing with a new texture, or drawing with a
+ * texture after it was swapped out or teximaged again.
+ */
+
+static i830TextureObjectPtr i830AllocTexObj( struct gl_texture_object *texObj )
+{
+   i830TextureObjectPtr t;
+
+   t = CALLOC_STRUCT( i830_texture_object_t );
+   texObj->DriverData = t;
+   if ( t != NULL ) {
+      /* Initialize non-image-dependent parts of the state:
+       */
+      t->base.tObj = texObj;
+
+      t->Setup[I830_TEXREG_TM0LI] = STATE3D_LOAD_STATE_IMMEDIATE_2;
+      t->Setup[I830_TEXREG_TM0S0] = TM0S0_USE_FENCE;
+      t->Setup[I830_TEXREG_TM0S1] = 0;
+      t->Setup[I830_TEXREG_TM0S2] = 0;
+      t->Setup[I830_TEXREG_TM0S3] = 0;
+
+      t->Setup[I830_TEXREG_NOP0] = 0;
+      t->Setup[I830_TEXREG_NOP1] = 0;
+      t->Setup[I830_TEXREG_NOP2] = 0;
+
+      t->Setup[I830_TEXREG_MCS] = (STATE3D_MAP_COORD_SET_CMD |
+                                  MAP_UNIT(0) |
+                                  ENABLE_TEXCOORD_PARAMS |
+                                  TEXCOORDS_ARE_NORMAL |
+                                  TEXCOORDTYPE_CARTESIAN |
+                                  ENABLE_ADDR_V_CNTL |
+                                  TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) |
+                                  ENABLE_ADDR_U_CNTL |
+                                  TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP));
+
+      make_empty_list( & t->base );
+
+      i830SetTexWrapping( t, texObj->WrapS, texObj->WrapT );
+      i830SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );
+      i830SetTexFilter( t, texObj->MinFilter, texObj->MagFilter );
+      i830SetTexBorderColor( t, texObj->_BorderChan );
+   }
+
+   return t;
+}
+
+
+static void i830TexParameter( GLcontext *ctx, GLenum target,
+                             struct gl_texture_object *tObj,
+                             GLenum pname, const GLfloat *params )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData;
+   GLuint unit = ctx->Texture.CurrentUnit;
+   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->NewGLState means that
+    * i830UpdateTextureState() 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:
+   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+      i830SetTexMaxAnisotropy( t, tObj->MaxAnisotropy );
+      i830SetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
+      break;
+
+   case GL_TEXTURE_WRAP_S:
+   case GL_TEXTURE_WRAP_T:
+      i830SetTexWrapping( t, tObj->WrapS, tObj->WrapT );
+      break;
+  
+   case GL_TEXTURE_BORDER_COLOR:
+      i830SetTexBorderColor( t, tObj->_BorderChan );
+      break;
+
+   case GL_TEXTURE_BASE_LEVEL:
+   case GL_TEXTURE_MAX_LEVEL:
+   case GL_TEXTURE_MIN_LOD:
+   case GL_TEXTURE_MAX_LOD:
+      /* The i830 and its successors can do a lot of this without
+       * reloading the textures.  A project for someone?
+       */
+      I830_FIREVERTICES( I830_CONTEXT(ctx) );
+      driSwapOutTextureObject( (driTextureObject *) t );
+      break;
+
+   default:
+      return;
+   }
+
+   if (t == imesa->CurrentTexObj[unit]) {
+      I830_STATECHANGE( imesa, I830_UPLOAD_TEX0 );
+   }
+}
+
+
+static void i830TexEnv( GLcontext *ctx, GLenum target, 
+                       GLenum pname, const GLfloat *param )
+{
+   i830ContextPtr imesa = I830_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:
+   case GL_TEXTURE_ENV_MODE:
+   case GL_COMBINE_RGB_EXT:
+   case GL_COMBINE_ALPHA_EXT:
+   case GL_SOURCE0_RGB_EXT:
+   case GL_SOURCE1_RGB_EXT:
+   case GL_SOURCE2_RGB_EXT:
+   case GL_SOURCE0_ALPHA_EXT:
+   case GL_SOURCE1_ALPHA_EXT:
+   case GL_SOURCE2_ALPHA_EXT:
+   case GL_OPERAND0_RGB_EXT:
+   case GL_OPERAND1_RGB_EXT:
+   case GL_OPERAND2_RGB_EXT:
+   case GL_OPERAND0_ALPHA_EXT:
+   case GL_OPERAND1_ALPHA_EXT:
+   case GL_OPERAND2_ALPHA_EXT:
+   case GL_RGB_SCALE_EXT:
+   case GL_ALPHA_SCALE:
+      imesa->TexEnvImageFmt[unit] = 0; /* force recalc of env state */
+      break;
+
+   case GL_TEXTURE_LOD_BIAS_EXT:
+      i830ComputeLodBias( imesa, unit, *param );
+      I830_STATECHANGE( imesa, I830_UPLOAD_TEX_N(unit) );
+      break;
+
+   default:
+      break;
+   }
+} 
+
+static void i830TexImage2D( 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) {
+      I830_FIREVERTICES( I830_CONTEXT(ctx) );
+      driSwapOutTextureObject( t );
+   }
+   else {
+      t = (driTextureObject *) i830AllocTexObj( 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 i830TexSubImage2D( 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) {
+      I830_FIREVERTICES( I830_CONTEXT(ctx) );
+      driSwapOutTextureObject( t );
+   }
+   _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, 
+                            height, format, type, pixels, packing, texObj,
+                            texImage);
+
+}
+
+
+static void i830BindTexture( GLcontext *ctx, GLenum target,
+                            struct gl_texture_object *tObj )
+{
+   if (!tObj->DriverData) {
+      i830AllocTexObj( tObj );
+   }
+}
+
+
+static void i830DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
+{
+   driTextureObject * t = (driTextureObject *) tObj->DriverData;
+
+   if ( t != NULL ) {
+      i830ContextPtr imesa = I830_CONTEXT( ctx );
+
+      if ( imesa ) {
+         I830_FIREVERTICES( imesa );
+      }
+
+      driDestroyTextureObject( t );
+   }
+}
+
+
+static const struct gl_texture_format *
+i830ChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
+                        GLenum format, GLenum type )
+{
+   i830ContextPtr imesa = I830_CONTEXT( ctx );
+   const GLboolean do32bpt = ( imesa->i830Screen->cpp == 4 &&
+                              imesa->i830Screen->textureSize > 4*1024*1024);
+
+   switch ( internalFormat ) {
+   case 4:
+   case GL_RGBA:
+   case GL_COMPRESSED_RGBA:
+      if ( format == GL_BGRA ) {
+        if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
+           return &_mesa_texformat_argb8888;
+        }
+         else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
+            return &_mesa_texformat_argb4444;
+        }
+         else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
+           return &_mesa_texformat_argb1555;
+        }
+      }
+      return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
+
+   case 3:
+   case GL_RGB:
+   case GL_COMPRESSED_RGB:
+      if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
+        return &_mesa_texformat_rgb565;
+      }
+      return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
+
+   case GL_RGBA8:
+   case GL_RGB10_A2:
+   case GL_RGBA12:
+   case GL_RGBA16:
+      return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
+
+   case GL_RGBA4:
+   case GL_RGBA2:
+      return &_mesa_texformat_argb4444;
+
+   case GL_RGB5_A1:
+      return &_mesa_texformat_argb1555;
+
+   case GL_RGB8:
+   case GL_RGB10:
+   case GL_RGB12:
+   case GL_RGB16:
+      return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
+
+   case GL_RGB5:
+   case GL_RGB4:
+   case GL_R3_G3_B2:
+      return &_mesa_texformat_rgb565;
+
+   case GL_ALPHA:
+   case GL_ALPHA4:
+   case GL_ALPHA8:
+   case GL_ALPHA12:
+   case GL_ALPHA16:
+   case GL_COMPRESSED_ALPHA:
+      return &_mesa_texformat_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_l8;
+
+   case 2:
+   case GL_LUMINANCE_ALPHA:
+   case GL_LUMINANCE4_ALPHA4:
+   case GL_LUMINANCE6_ALPHA2:
+   case GL_LUMINANCE8_ALPHA8:
+   case GL_LUMINANCE12_ALPHA4:
+   case GL_LUMINANCE12_ALPHA12:
+   case GL_LUMINANCE16_ALPHA16:
+   case GL_COMPRESSED_LUMINANCE_ALPHA:
+      return &_mesa_texformat_al88;
+
+   case GL_INTENSITY:
+   case GL_INTENSITY4:
+   case GL_INTENSITY8:
+   case GL_INTENSITY12:
+   case GL_INTENSITY16:
+   case GL_COMPRESSED_INTENSITY:
+      return &_mesa_texformat_i8;
+
+   case GL_YCBCR_MESA:
+      if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
+         type == GL_UNSIGNED_BYTE)
+         return &_mesa_texformat_ycbcr;
+      else
+         return &_mesa_texformat_ycbcr_rev;
+
+   default:
+      fprintf(stderr, "unexpected texture format in %s\n", __FUNCTION__);
+      return NULL;
+   }
+
+   return NULL; /* never get here */
+}
+
+void i830DDInitTextureFuncs( GLcontext *ctx )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+
+   ctx->Driver.TexEnv                    = i830TexEnv;
+   ctx->Driver.ChooseTextureFormat       = i830ChooseTextureFormat;
+   ctx->Driver.TexImage1D                = _mesa_store_teximage1d;
+   ctx->Driver.TexImage2D                = i830TexImage2D;
+   ctx->Driver.TexImage3D                = _mesa_store_teximage3d;
+   ctx->Driver.TexSubImage1D             = _mesa_store_texsubimage1d;
+   ctx->Driver.TexSubImage2D             = i830TexSubImage2D;
+   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               = i830BindTexture;
+   ctx->Driver.DeleteTexture             = i830DeleteTexture;
+   ctx->Driver.TexParameter              = i830TexParameter;
+   ctx->Driver.UpdateTexturePalette      = NULL;
+   ctx->Driver.IsTextureResident         = driIsTextureResident;
+   ctx->Driver.TestProxyTexImage         = _mesa_test_proxy_teximage;
+
+   driInitTextureObjects( ctx, & imesa->swapped,
+                         DRI_TEXMGR_DO_TEXTURE_2D
+                         | DRI_TEXMGR_DO_TEXTURE_RECT );
+}
diff --git a/src/mesa/drivers/dri/i830/i830_tex.h b/src/mesa/drivers/dri/i830/i830_tex.h
new file mode 100644 (file)
index 0000000..dbfcbe3
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ *
+ * Adapted for use in the I830M driver:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ */
+
+#ifndef I830TEX_INC
+#define I830TEX_INC
+
+#include "mtypes.h"
+#include "i830_context.h"
+#include "i830_3d_reg.h"
+#include "texmem.h"
+
+#define I830_TEX_MAXLEVELS 10
+
+struct i830_texture_object_t 
+{
+   driTextureObject    base;
+
+   int texelBytes;
+   int Pitch;
+   int Height;
+   char *BufAddr;   
+   GLenum palette_format;
+   GLuint palette[256];
+   struct {
+      const struct gl_texture_image *image;
+      int offset;       /* into BufAddr */
+      int height;
+      int internalFormat;
+   } image[6][I830_TEX_MAXLEVELS];
+
+   /* Support for multitexture.
+    */
+
+   GLuint current_unit;
+   GLuint Setup[I830_TEX_SETUP_SIZE];
+   GLuint dirty;
+
+   GLfloat  max_anisotropy;
+};
+
+void i830UpdateTextureState( GLcontext *ctx );
+void i830DDInitTextureFuncs( GLcontext *ctx );
+void i830UpdateTexUnitProj( GLcontext *ctx, GLuint unit, GLboolean state );
+
+void i830DestroyTexObj( i830ContextPtr imesa, i830TextureObjectPtr t );
+int i830UploadTexImagesLocked( i830ContextPtr imesa, i830TextureObjectPtr t );
+
+#endif
diff --git a/src/mesa/drivers/dri/i830/i830_texmem.c b/src/mesa/drivers/dri/i830/i830_texmem.c
new file mode 100644 (file)
index 0000000..6cb5531
--- /dev/null
@@ -0,0 +1,214 @@
+/**************************************************************************
+
+Copyright 2001 2d3d Inc., Delray Beach, FL
+
+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.
+
+**************************************************************************/
+
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_texmem.c,v 1.3 2002/12/10 01:26:53 dawes Exp $ */
+
+/*
+ * Author:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ *
+ * Heavily based on the I810 driver, which was written by:
+ *   Keith Whitwell <keithw@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "texformat.h"
+
+#include "i830_screen.h"
+#include "i830_dri.h"
+
+#include "i830_context.h"
+#include "i830_tex.h"
+#include "i830_state.h"
+#include "i830_ioctl.h"
+
+
+void i830DestroyTexObj(i830ContextPtr imesa, i830TextureObjectPtr t)
+{
+   unsigned   i;
+
+
+   /* See if it was the driver's current object.
+    */
+   if ( imesa != NULL ) { 
+      for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) {
+        if ( t == imesa->CurrentTexObj[ i ] ) {
+           imesa->CurrentTexObj[ i ] = NULL;
+           imesa->dirty &= ~(I830_UPLOAD_TEX0 << i);
+        }
+      }
+   }
+}
+
+/* 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 i830UploadTexLevel( i830ContextPtr imesa,
+                               i830TextureObjectPtr t, int hwlevel )
+{
+   const struct gl_texture_image *image = t->image[0][hwlevel].image;
+   int j;
+
+   if (!image || !image->Data)
+      return;
+
+   if (image->Width * image->TexFormat->TexelBytes == t->Pitch) {
+        GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[0][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[0][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[0][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;
+
+   case 4:
+      {
+        GLuint *dst = (GLuint *)(t->BufAddr + t->image[0][hwlevel].offset);
+        GLuint *src = (GLuint *)image->Data;
+
+        for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/4)) {
+           __memcpy(dst, src, image->Width * 4 );
+           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 i830UploadTexImagesLocked( i830ContextPtr imesa, i830TextureObjectPtr t )
+{
+   int ofs;
+
+   if ( t->base.memBlock == NULL ) {
+      int heap;
+
+      heap = driAllocateTexture( imesa->texture_heaps, imesa->nr_heaps,
+                                (driTextureObject *) t );
+      if ( heap == -1 ) {
+        return -1;
+      }
+
+      /* Set the base offset of the texture image */
+      ofs = t->base.memBlock->ofs;
+      t->BufAddr = imesa->i830Screen->tex.map + ofs;
+      t->Setup[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE |
+                                    (imesa->i830Screen->textureOffset + ofs));
+
+      if (t == imesa->CurrentTexObj[0])
+        imesa->dirty |= I830_UPLOAD_TEX0;
+
+      if (t == imesa->CurrentTexObj[1])
+        imesa->dirty |= I830_UPLOAD_TEX1;
+#if 0
+      if (t == imesa->CurrentTexObj[2])
+        I830_STATECHANGE(imesa, I830_UPLOAD_TEX2);
+
+      if (t == imesa->CurrentTexObj[3])
+        I830_STATECHANGE(imesa, I830_UPLOAD_TEX3);
+#endif
+   }
+
+
+   /* Let the world know we've used this memory recently.
+    */
+   driUpdateTextureLRU( (driTextureObject *) t );
+
+   if (imesa->texture_heaps[0]->timestamp >= GET_DISPATCH_AGE(imesa)) 
+      i830WaitAgeLocked( imesa, imesa->texture_heaps[0]->timestamp ); 
+
+   /* Upload any images that are new */
+   if (t->base.dirty_images[0]) {
+      int i;
+      const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
+
+      for (i = 0 ; i < numLevels ; i++) { 
+         if ( (t->base.dirty_images[0] & (1 << (i+t->base.firstLevel))) != 0 ) {
+           i830UploadTexLevel( imesa, t, i );
+         }
+      }
+      t->base.dirty_images[0] = 0;
+      imesa->sarea->perf_boxes |= I830_BOX_TEXTURE_LOAD;
+   }
+
+   return 0;
+}
diff --git a/src/mesa/drivers/dri/i830/i830_texstate.c b/src/mesa/drivers/dri/i830/i830_texstate.c
new file mode 100644 (file)
index 0000000..03c98d2
--- /dev/null
@@ -0,0 +1,1607 @@
+/**************************************************************************
+
+Copyright 2001 2d3d Inc., Delray Beach, FL
+
+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.
+
+**************************************************************************/
+
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_texstate.c,v 1.3 2002/12/10 01:26:53 dawes Exp $ */
+
+/*
+ * Author:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ *
+ * Heavily based on the I810 driver, which was written by:
+ *   Keith Whitwell <keithw@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "texformat.h"
+#include "texstore.h"
+#include "texutil.h"
+
+#include "mm.h"
+
+#include "i830_screen.h"
+#include "i830_dri.h"
+
+#include "i830_context.h"
+#include "i830_tex.h"
+#include "i830_state.h"
+#include "i830_ioctl.h"
+
+#define I830_TEX_UNIT_ENABLED(unit)            (1<<unit)
+
+static void i830SetTexImages( i830ContextPtr imesa, 
+                             struct gl_texture_object *tObj )
+{
+   GLuint total_height, pitch, i, textureFormat;
+   i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData;
+   const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel];
+   GLint firstLevel, lastLevel, numLevels;
+
+   switch( baseImage->TexFormat->MesaFormat ) {
+   case MESA_FORMAT_L8:
+      t->texelBytes = 1;
+      textureFormat = MAPSURF_8BIT | MT_8BIT_L8;
+      break;
+
+   case MESA_FORMAT_I8:
+      t->texelBytes = 1;
+      textureFormat = MAPSURF_8BIT | MT_8BIT_I8;
+      break;
+
+   case MESA_FORMAT_AL88:
+      t->texelBytes = 2;
+      textureFormat = MAPSURF_16BIT | MT_16BIT_AY88;
+      break;
+
+   case MESA_FORMAT_RGB565:
+      t->texelBytes = 2;
+      textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
+      break;
+
+   case MESA_FORMAT_ARGB1555:
+      t->texelBytes = 2;
+      textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555;
+      break;
+
+   case MESA_FORMAT_ARGB4444:
+      t->texelBytes = 2;
+      textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB4444;
+      break;
+
+   case MESA_FORMAT_ARGB8888:
+      t->texelBytes = 4;
+      textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
+      break;
+
+   case MESA_FORMAT_YCBCR_REV:
+      t->texelBytes = 2;
+      textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL | 
+                      TM0S1_COLORSPACE_CONVERSION);
+      break;
+
+   case MESA_FORMAT_YCBCR:
+      t->texelBytes = 2;
+      textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY | /* ??? */
+                      TM0S1_COLORSPACE_CONVERSION);
+      break;
+
+   default:
+      fprintf(stderr, "%s: bad image format\n", __FUNCTION__);
+      free( t );
+      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.
+    */
+   switch (tObj->Target) {
+   case GL_TEXTURE_1D:
+   case GL_TEXTURE_2D:
+      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 */
+      break;
+   case GL_TEXTURE_RECTANGLE_NV:
+      firstLevel = lastLevel = 0;
+      break;
+   default:
+      fprintf(stderr, "%s: bad target %s\n", __FUNCTION__,
+             _mesa_lookup_enum_by_nr(tObj->Target));
+      return;
+   }
+
+
+   /* save these values */
+   t->base.firstLevel = firstLevel;
+   t->base.lastLevel = lastLevel;
+
+
+   /* Figure out the amount of memory required to hold all the mipmap
+    * levels.  Choose the smallest pitch to accomodate the largest
+    * mipmap:
+    */
+   numLevels = lastLevel - firstLevel + 1;
+
+   /* Pitch would be subject to additional rules if texture memory were
+    * tiled.  Currently it isn't. 
+    */
+   if (0) {
+      pitch = 128;
+      while (pitch < tObj->Image[firstLevel]->Width * t->texelBytes)
+        pitch *= 2;
+   }
+   else {
+      pitch = tObj->Image[firstLevel]->Width * t->texelBytes;
+      pitch = (pitch + 3) & ~3;
+   }
+
+
+   /* All images must be loaded at this pitch.  Count the number of
+    * lines required:
+    */
+   for ( total_height = i = 0 ; i < numLevels ; i++ ) {
+      t->image[0][i].image = tObj->Image[firstLevel + i];
+      if (!t->image[0][i].image) 
+        break;
+      
+      t->image[0][i].offset = total_height * pitch;
+      t->image[0][i].internalFormat = baseImage->Format;
+      total_height += t->image[0][i].image->Height;
+   }
+
+   t->Pitch = pitch;
+   t->base.totalSize = total_height*pitch;
+   t->Setup[I830_TEXREG_TM0S1] = 
+      (((tObj->Image[firstLevel]->Height - 1) << TM0S1_HEIGHT_SHIFT) |
+       ((tObj->Image[firstLevel]->Width - 1) << TM0S1_WIDTH_SHIFT) |
+       textureFormat);
+   t->Setup[I830_TEXREG_TM0S2] = 
+      ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT));   
+   t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK;
+   t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK;
+   t->Setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT;
+   t->dirty = I830_UPLOAD_TEX0 | I830_UPLOAD_TEX1;
+
+   LOCK_HARDWARE( imesa );
+   i830UploadTexImagesLocked( imesa, t );
+   UNLOCK_HARDWARE( imesa );
+}
+
+/* ================================================================
+ * Texture combine functions
+ */
+static __inline__ GLuint GetTexelOp(GLint unit)
+{
+   switch(unit) {
+    case 0: return TEXBLENDARG_TEXEL0;
+    case 1: return TEXBLENDARG_TEXEL1;
+    case 2: return TEXBLENDARG_TEXEL2;
+    case 3: return TEXBLENDARG_TEXEL3;
+    default: return TEXBLENDARG_TEXEL0;
+   }
+}
+
+static void i830SetBlend_GL1_2(i830ContextPtr imesa, int curTex, 
+                              GLenum envMode, GLenum format)
+{
+   GLuint texel_op = GetTexelOp(curTex);
+
+   if(I830_DEBUG&DEBUG_TEXTURE)
+     fprintf(stderr, "%s %s %s unit (%d) texel_op(0x%x)\n",
+            __FUNCTION__,
+            _mesa_lookup_enum_by_nr(format),
+            _mesa_lookup_enum_by_nr(envMode),
+            curTex,
+            texel_op);
+
+   switch(envMode) {
+   case GL_REPLACE:
+      switch(format) {
+      case GL_ALPHA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 4;
+        break;
+      case GL_LUMINANCE:
+      case GL_RGB:
+      case GL_YCBCR_MESA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 4;
+        break;
+
+      case GL_INTENSITY:
+      case GL_LUMINANCE_ALPHA:
+      case GL_RGBA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 4;
+        break;
+      default:
+        /* Always set to passthru if something is funny */
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 4;
+        break;
+      }
+      break;
+
+   case GL_MODULATE:
+      switch(format) {
+      case GL_ALPHA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_MODULATE);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 5;
+        break;
+
+      case GL_LUMINANCE:
+      case GL_RGB:
+      case GL_YCBCR_MESA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_MODULATE);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 5;
+        break;
+
+      case GL_INTENSITY:
+      case GL_LUMINANCE_ALPHA:
+      case GL_RGBA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_MODULATE);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_MODULATE);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 6;
+        break;
+      default:
+        /* Always set to passthru if something is funny */
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 4;
+        break;
+      }
+      break;
+
+   case GL_DECAL:
+      switch(format) {
+      case GL_RGB:
+      case GL_YCBCR_MESA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 4;
+        break;
+
+      case GL_RGBA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_BLEND);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG0 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_REPLICATE_ALPHA |
+                                      texel_op);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 6;
+        break;
+      default:
+        /* Always set to passthru if something is funny */
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 4;
+        break;
+      }
+      break;
+
+   case GL_BLEND:
+      switch(format) {
+      case GL_ALPHA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_MODULATE);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 5;
+        break;
+
+      case GL_LUMINANCE:
+      case GL_RGB:
+      case GL_YCBCR_MESA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_BLEND);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG0 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_FACTOR_N);
+        imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 6;
+        break;
+
+      case GL_INTENSITY:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_BLEND);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_BLEND);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG0 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_FACTOR_N);
+        imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG0 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][6] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_FACTOR_N);
+        imesa->TexBlend[curTex][7] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 8;
+        break;
+
+      case GL_LUMINANCE_ALPHA:
+      case GL_RGBA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_BLEND);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_MODULATE);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG0 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_FACTOR_N);
+        imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][6] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 7;
+        break;
+      default:
+        /* Always set to passthru if something is funny */
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 4;
+        break;
+      }
+      break;
+
+   case GL_ADD:
+      switch(format) {
+      case GL_ALPHA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_MODULATE);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 5;
+        break;
+      case GL_LUMINANCE:
+      case GL_RGB:
+      case GL_YCBCR_MESA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ADD);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 5;
+        break;
+
+      case GL_INTENSITY:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ADD);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ADD);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 6;
+        break;
+
+      case GL_LUMINANCE_ALPHA:
+      case GL_RGBA:
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ADD);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_MODULATE);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      texel_op);
+        imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG2 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 6;
+        break;
+      default:
+        /* Always set to passthru if something is funny */
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 4;
+        break;
+      }
+      break;
+   default:
+        /* Always set to passthru if something is funny */
+        imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      DISABLE_TEX_CNTRL_STAGE |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      ENABLE_TEXOUTPUT_WRT_SEL |
+                                      TEXOP_OUTPUT_CURRENT |
+                                      TEXOP_SCALE_1X |
+                                      TEXOP_MODIFY_PARMS |
+                                      TEXBLENDOP_ARG1);
+        imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_COLOR |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) |
+                                      TEXPIPE_ALPHA |
+                                      TEXBLEND_ARG1 |
+                                      TEXBLENDARG_MODIFY_PARMS |
+                                      TEXBLENDARG_CURRENT);
+        imesa->TexBlendColorPipeNum[curTex] = 0;
+        imesa->TexBlendWordsUsed[curTex] = 4;
+        break;
+   }
+
+   if (I830_DEBUG&DEBUG_TEXTURE)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+}
+
+static void i830SetTexEnvCombine(i830ContextPtr imesa,
+                                const struct gl_texture_unit *texUnit, 
+                                GLint unit)
+{
+   GLuint blendop;
+   GLuint ablendop;
+   GLuint args_RGB[3];
+   GLuint args_A[3];
+   GLuint texel_op = GetTexelOp(unit);
+   GLuint rgb_shift = texUnit->CombineScaleShiftRGB;
+   GLuint alpha_shift = texUnit->CombineScaleShiftA;
+   int i;
+
+   if(I830_DEBUG&DEBUG_TEXTURE)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   switch(texUnit->CombineModeRGB) {
+   case GL_REPLACE: 
+      blendop = TEXBLENDOP_ARG1;
+      break;
+   case GL_MODULATE: 
+      blendop = TEXBLENDOP_MODULATE;
+      break;
+   case GL_ADD: 
+      blendop = TEXBLENDOP_ADD;
+      break;
+   case GL_ADD_SIGNED:
+      blendop = TEXBLENDOP_ADDSIGNED; 
+      break;
+   case GL_INTERPOLATE:
+      blendop = TEXBLENDOP_BLEND; 
+      break;
+   case GL_SUBTRACT: 
+      blendop = TEXBLENDOP_SUBTRACT;
+      break;
+   case GL_DOT3_RGB_EXT:
+   case GL_DOT3_RGBA_EXT:
+      /* The EXT version of the DOT3 extension does not support the
+       * scale factor, but the ARB version (and the version in OpenGL
+       * 1.3) does.
+       */
+      rgb_shift = 0;
+      alpha_shift = 0;
+      /* FALLTHROUGH */
+
+   case GL_DOT3_RGB:
+   case GL_DOT3_RGBA:
+      blendop = TEXBLENDOP_DOT3;
+      break;
+   default: 
+      return;
+   }
+
+   blendop |= (rgb_shift << TEXOP_SCALE_SHIFT);
+
+   switch(texUnit->CombineModeA) {
+   case GL_REPLACE: 
+      ablendop = TEXBLENDOP_ARG1;
+      break;
+   case GL_MODULATE: 
+      ablendop = TEXBLENDOP_MODULATE;
+      break;
+   case GL_ADD: 
+      ablendop = TEXBLENDOP_ADD;
+      break;
+   case GL_ADD_SIGNED:
+      ablendop = TEXBLENDOP_ADDSIGNED; 
+      break;
+   case GL_INTERPOLATE:
+      ablendop = TEXBLENDOP_BLEND; 
+      break;
+   case GL_SUBTRACT: 
+      ablendop = TEXBLENDOP_SUBTRACT;
+      break;
+   default:
+      return;
+   }
+
+   if ( (texUnit->CombineModeRGB == GL_DOT3_RGBA_EXT)
+       || (texUnit->CombineModeRGB == GL_DOT3_RGBA) ) {
+      ablendop = TEXBLENDOP_DOT3;
+   }
+
+   ablendop |= (alpha_shift << TEXOP_SCALE_SHIFT);
+
+   /* Handle RGB args */
+   for(i = 0; i < 3; i++) {
+      switch(texUnit->CombineSourceRGB[i]) {
+      case GL_TEXTURE: 
+        args_RGB[i] = texel_op;
+        break;
+      case GL_CONSTANT:
+        args_RGB[i] = TEXBLENDARG_FACTOR_N; 
+        break;
+      case GL_PRIMARY_COLOR:
+        args_RGB[i] = TEXBLENDARG_DIFFUSE;
+        break;
+      case GL_PREVIOUS:
+        args_RGB[i] = TEXBLENDARG_CURRENT; 
+        break;
+      default: 
+        return;
+        
+      }
+
+      switch(texUnit->CombineOperandRGB[i]) {
+      case GL_SRC_COLOR: 
+        args_RGB[i] |= 0;
+        break;
+      case GL_ONE_MINUS_SRC_COLOR: 
+        args_RGB[i] |= TEXBLENDARG_INV_ARG;
+        break;
+      case GL_SRC_ALPHA: 
+        args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA;
+        break;
+      case GL_ONE_MINUS_SRC_ALPHA: 
+        args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA | 
+                        TEXBLENDARG_INV_ARG);
+        break;
+      default: 
+        return;
+      }
+   }
+
+   /* Handle A args */
+   for(i = 0; i < 3; i++) {
+      switch(texUnit->CombineSourceA[i]) {
+      case GL_TEXTURE: 
+        args_A[i] = texel_op;
+        break;
+      case GL_CONSTANT:
+        args_A[i] = TEXBLENDARG_FACTOR_N; 
+        break;
+      case GL_PRIMARY_COLOR:
+        args_A[i] = TEXBLENDARG_DIFFUSE; 
+        break;
+      case GL_PREVIOUS:
+        args_A[i] = TEXBLENDARG_CURRENT; 
+        break;
+      default: 
+        return;
+        
+      }
+
+      switch(texUnit->CombineOperandA[i]) {
+      case GL_SRC_ALPHA: 
+        args_A[i] |= 0;
+        break;
+      case GL_ONE_MINUS_SRC_ALPHA: 
+        args_A[i] |= TEXBLENDARG_INV_ARG;
+        break;
+      default: 
+        return;
+      }
+   }
+
+   /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */
+   /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */
+   /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */
+
+   /* When we render we need to figure out which is the last really enabled
+    * tex unit, and put last stage on it
+    */
+
+   imesa->TexBlendColorPipeNum[unit] = 0;
+
+   /* Build color pipeline */
+
+   imesa->TexBlend[unit][0] = (STATE3D_MAP_BLEND_OP_CMD(unit) |
+                              TEXPIPE_COLOR |
+                              ENABLE_TEXOUTPUT_WRT_SEL |
+                              TEXOP_OUTPUT_CURRENT |
+                              DISABLE_TEX_CNTRL_STAGE |
+                              TEXOP_MODIFY_PARMS |
+                              blendop);
+   imesa->TexBlend[unit][1] = (STATE3D_MAP_BLEND_ARG_CMD(unit) |
+                              TEXPIPE_COLOR |
+                              TEXBLEND_ARG1 |
+                              TEXBLENDARG_MODIFY_PARMS |
+                              args_RGB[0]);
+   imesa->TexBlend[unit][2] = (STATE3D_MAP_BLEND_ARG_CMD(unit) |
+                              TEXPIPE_COLOR |
+                              TEXBLEND_ARG2 |
+                              TEXBLENDARG_MODIFY_PARMS |
+                              args_RGB[1]);
+   imesa->TexBlend[unit][3] = (STATE3D_MAP_BLEND_ARG_CMD(unit) |
+                              TEXPIPE_COLOR |
+                              TEXBLEND_ARG0 |
+                              TEXBLENDARG_MODIFY_PARMS |
+                              args_RGB[2]);
+
+   /* Build Alpha pipeline */
+   imesa->TexBlend[unit][4] = (STATE3D_MAP_BLEND_OP_CMD(unit) |
+                              TEXPIPE_ALPHA |
+                              ENABLE_TEXOUTPUT_WRT_SEL |
+                              TEXOP_OUTPUT_CURRENT |
+                              TEXOP_MODIFY_PARMS |
+                              ablendop);
+   imesa->TexBlend[unit][5] = (STATE3D_MAP_BLEND_ARG_CMD(unit) |
+                              TEXPIPE_ALPHA |
+                              TEXBLEND_ARG1 |
+                              TEXBLENDARG_MODIFY_PARMS |
+                              args_A[0]);
+   imesa->TexBlend[unit][6] = (STATE3D_MAP_BLEND_ARG_CMD(unit) |
+                              TEXPIPE_ALPHA |
+                              TEXBLEND_ARG2 |
+                              TEXBLENDARG_MODIFY_PARMS |
+                              args_A[1]);
+   imesa->TexBlend[unit][7] = (STATE3D_MAP_BLEND_ARG_CMD(unit) |
+                              TEXPIPE_ALPHA |
+                              TEXBLEND_ARG0 |
+                              TEXBLENDARG_MODIFY_PARMS |
+                              args_A[2]);
+
+   {
+      GLubyte r, g, b, a;
+      GLfloat *fc = texUnit->EnvColor;
+
+      FLOAT_COLOR_TO_UBYTE_COLOR(r, fc[RCOMP]);
+      FLOAT_COLOR_TO_UBYTE_COLOR(g, fc[GCOMP]);
+      FLOAT_COLOR_TO_UBYTE_COLOR(b, fc[BCOMP]);
+      FLOAT_COLOR_TO_UBYTE_COLOR(a, fc[ACOMP]);
+
+      imesa->TexBlend[unit][8] = STATE3D_COLOR_FACTOR_CMD(unit);
+      imesa->TexBlend[unit][9] =  ((a << 24) |
+                                  (r << 16) |
+                                  (g << 8) |
+                                  b);
+   }
+   imesa->TexBlendWordsUsed[unit] = 10;
+}
+
+
+
+
+static void i830UpdateTexEnv( GLcontext *ctx, GLuint unit )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+   const struct gl_texture_object *tObj = texUnit->_Current;
+   i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData;
+   GLuint col;
+
+   imesa->TexBlendWordsUsed[unit] = 0;
+
+   if (0) fprintf(stderr, "i830UpdateTexEnv called : %s\n",
+                 _mesa_lookup_enum_by_nr(texUnit->EnvMode));
+
+   if(texUnit->EnvMode == GL_COMBINE) {
+      i830SetTexEnvCombine(imesa,
+                          texUnit,
+                          unit);
+   } else {
+      i830SetBlend_GL1_2(imesa,
+                        unit,
+                        texUnit->EnvMode,
+                        t->image[0][0].internalFormat);
+
+      /* add blend color */
+      {
+        GLubyte r, g, b, a;
+        GLfloat *fc = texUnit->EnvColor;
+
+        FLOAT_COLOR_TO_UBYTE_COLOR(r, fc[RCOMP]);
+        FLOAT_COLOR_TO_UBYTE_COLOR(g, fc[GCOMP]);
+        FLOAT_COLOR_TO_UBYTE_COLOR(b, fc[BCOMP]);
+        FLOAT_COLOR_TO_UBYTE_COLOR(a, fc[ACOMP]);
+
+        col = ((a << 24) |
+               (r << 16) |
+               (g << 8) |
+               b);
+      }       
+
+      {
+        int i;
+
+        i = imesa->TexBlendWordsUsed[unit];
+        imesa->TexBlend[unit][i++] = STATE3D_COLOR_FACTOR_CMD(unit);     
+        imesa->TexBlend[unit][i++] = col;
+
+        imesa->TexBlendWordsUsed[unit] = i;
+      }
+   }
+
+   I830_STATECHANGE( imesa, I830_UPLOAD_TEXBLEND_N(unit) );
+}
+
+
+/* This is bogus -- can't load the same texture object on two units.
+ */
+static void i830TexSetUnit( i830TextureObjectPtr t, GLuint unit )
+{
+   if(I830_DEBUG&DEBUG_TEXTURE)
+      fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit);
+   
+   t->Setup[I830_TEXREG_TM0LI] = (STATE3D_LOAD_STATE_IMMEDIATE_2 | 
+                                 (LOAD_TEXTURE_MAP0 << unit) | 4);
+
+   I830_SET_FIELD(t->Setup[I830_TEXREG_MCS], MAP_UNIT_MASK, MAP_UNIT(unit));
+
+   t->current_unit = unit;
+   t->base.bound |= (1U << unit);
+}
+
+#define TEXCOORDTYPE_MASK      (~((1<<13)|(1<<12)|(1<<11)))
+
+
+static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+   struct gl_texture_object *tObj = texUnit->_Current;
+   i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData;
+   GLuint mcs = t->Setup[I830_TEXREG_MCS] & TEXCOORDTYPE_MASK;
+
+   /* Handle projective texturing */
+   if (imesa->vertex_format & (1<<31)) {
+      mcs |= TEXCOORDTYPE_HOMOGENEOUS;
+   } else {
+      mcs |= TEXCOORDTYPE_CARTESIAN;
+   }
+
+   /* Fallback if there's a texture border */
+   if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) {
+      return GL_FALSE;
+   }
+
+   /* Upload teximages (not pipelined)
+    */
+   if (t->base.dirty_images[0]) {
+      i830SetTexImages( imesa, tObj );
+      if (!t->base.memBlock) {
+        return GL_FALSE;
+      }
+   }
+
+   /* Update state if this is a different texture object to last
+    * time.
+    */
+   if (imesa->CurrentTexObj[unit] != t ||
+       mcs != t->Setup[I830_TEXREG_MCS]) {
+
+      if ( imesa->CurrentTexObj[unit] != NULL ) {
+        /* The old texture is no longer bound to this texture unit.
+         * Mark it as such.
+         */
+
+        imesa->CurrentTexObj[unit]->base.bound &= ~(1U << unit);
+      }
+
+      I830_STATECHANGE(imesa, (I830_UPLOAD_TEX0<<unit));
+      t->Setup[I830_TEXREG_MCS] = mcs;
+      imesa->CurrentTexObj[unit] = t;
+      i830TexSetUnit(t, unit);
+   }
+
+   /* Update texture environment if texture object image format or 
+    * texture environment state has changed. 
+    *
+    * KW: doesn't work -- change from tex0 only to tex0+tex1 gets
+    * missed (need to update last stage flag?).  Call
+    * i830UpdateTexEnv always.
+    */
+   if (tObj->Image[tObj->BaseLevel]->Format !=
+       imesa->TexEnvImageFmt[unit]) {
+      imesa->TexEnvImageFmt[unit] = tObj->Image[tObj->BaseLevel]->Format;
+   }
+   i830UpdateTexEnv( ctx, unit );
+   imesa->TexEnabledMask |= I830_TEX_UNIT_ENABLED(unit);
+
+   return GL_TRUE;
+}
+
+static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+   struct gl_texture_object *tObj = texUnit->_Current;
+   i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData;
+   GLuint mcs = t->Setup[I830_TEXREG_MCS];
+
+   mcs &= ~TEXCOORDS_ARE_NORMAL;
+   mcs |= TEXCOORDS_ARE_IN_TEXELUNITS;
+
+   if (mcs != t->Setup[I830_TEXREG_MCS]) {
+      I830_STATECHANGE(imesa, (I830_UPLOAD_TEX0<<unit));
+      t->Setup[I830_TEXREG_MCS] = mcs;
+   }
+
+   return GL_TRUE;
+}
+
+
+static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+   struct gl_texture_object *tObj = texUnit->_Current;
+   i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData;
+   GLuint mcs = t->Setup[I830_TEXREG_MCS];
+
+   mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS;
+   mcs |= TEXCOORDS_ARE_NORMAL;
+
+   if (mcs != t->Setup[I830_TEXREG_MCS]) {
+      I830_STATECHANGE(imesa, (I830_UPLOAD_TEX0<<unit));
+      t->Setup[I830_TEXREG_MCS] = mcs;
+   }
+
+   return GL_TRUE;
+}
+
+static GLboolean disable_tex0( GLcontext *ctx )
+{
+   const int unit = 0;
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+
+   /* This is happening too often.  I need to conditionally send diffuse
+    * state to the card.  Perhaps a diffuse dirty flag of some kind.
+    * Will need to change this logic if more than 2 texture units are
+    * used.  We need to only do this up to the last unit enabled, or unit
+    * one if nothing is enabled.
+    */
+
+   if ( imesa->CurrentTexObj[unit] != NULL ) {
+      /* The old texture is no longer bound to this texture unit.
+       * Mark it as such.
+       */
+
+      imesa->CurrentTexObj[unit]->base.bound &= ~(1U << unit);
+      imesa->CurrentTexObj[unit] = NULL;
+   }
+
+   imesa->TexEnvImageFmt[unit] = 0;
+   imesa->dirty &= ~(I830_UPLOAD_TEX_N(unit));
+   
+   imesa->TexBlend[unit][0] = (STATE3D_MAP_BLEND_OP_CMD(unit) |
+                              TEXPIPE_COLOR |
+                              ENABLE_TEXOUTPUT_WRT_SEL |
+                              TEXOP_OUTPUT_CURRENT |
+                              DISABLE_TEX_CNTRL_STAGE |
+                              TEXOP_SCALE_1X |
+                              TEXOP_MODIFY_PARMS |
+                              TEXBLENDOP_ARG1);
+   imesa->TexBlend[unit][1] = (STATE3D_MAP_BLEND_OP_CMD(unit) |
+                              TEXPIPE_ALPHA |
+                              ENABLE_TEXOUTPUT_WRT_SEL |
+                              TEXOP_OUTPUT_CURRENT |
+                              TEXOP_SCALE_1X |
+                              TEXOP_MODIFY_PARMS |
+                              TEXBLENDOP_ARG1);
+   imesa->TexBlend[unit][2] = (STATE3D_MAP_BLEND_ARG_CMD(unit) |
+                              TEXPIPE_COLOR |
+                              TEXBLEND_ARG1 |
+                              TEXBLENDARG_MODIFY_PARMS |
+                              TEXBLENDARG_CURRENT);
+   imesa->TexBlend[unit][3] = (STATE3D_MAP_BLEND_ARG_CMD(unit) |
+                              TEXPIPE_ALPHA |
+                              TEXBLEND_ARG1 |
+                              TEXBLENDARG_MODIFY_PARMS |
+                              TEXBLENDARG_CURRENT);
+   imesa->TexBlendColorPipeNum[unit] = 0;
+   imesa->TexBlendWordsUsed[unit] = 4;
+   I830_STATECHANGE(imesa, (I830_UPLOAD_TEXBLEND_N(unit)));
+
+   return GL_TRUE;
+}
+
+static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+
+   imesa->TexEnabledMask &= ~(I830_TEX_UNIT_ENABLED(unit));
+
+   if (texUnit->_ReallyEnabled == TEXTURE_2D_BIT) {
+      return (enable_tex_common( ctx, unit ) &&
+             enable_tex_2d( ctx, unit ));
+   }
+   else if (texUnit->_ReallyEnabled == TEXTURE_RECT_BIT) {      
+      return (enable_tex_common( ctx, unit ) &&
+             enable_tex_rect( ctx, unit ));
+   }
+   else if (texUnit->_ReallyEnabled) {
+      return GL_FALSE;
+   }
+   else if (unit == 0) {
+      return disable_tex0( ctx );
+   }
+   else {
+      return GL_TRUE;
+   }
+}
+
+
+/* Called from vb code to update projective texturing properly */
+void i830UpdateTexUnitProj( GLcontext *ctx, GLuint unit, GLboolean state )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+   struct gl_texture_object *tObj = texUnit->_Current;
+   i830TextureObjectPtr t; 
+   GLuint mcs;
+
+   if (!tObj) return;
+
+   t = (i830TextureObjectPtr)tObj->DriverData;
+   mcs = (t->Setup[I830_TEXREG_MCS] & 
+                TEXCOORDTYPE_MASK &
+                ~TEXCOORDS_ARE_NORMAL);
+
+   /* Handle projective texturing */
+   if (state) {
+      mcs |= TEXCOORDTYPE_HOMOGENEOUS;
+   } else {
+      mcs |= TEXCOORDTYPE_CARTESIAN;
+   }
+   
+   if (texUnit->_ReallyEnabled == TEXTURE_2D_BIT) {
+      mcs |= TEXCOORDS_ARE_NORMAL;
+   }
+   else if (texUnit->_ReallyEnabled == TEXTURE_RECT_BIT) {
+      mcs |= TEXCOORDS_ARE_IN_TEXELUNITS;
+   }
+   else
+      return;
+
+   if (mcs != t->Setup[I830_TEXREG_MCS]) {
+      I830_STATECHANGE(imesa, (I830_UPLOAD_TEX0<<unit));
+      t->Setup[I830_TEXREG_MCS] = mcs;
+   }
+}
+
+/* Only deal with unit 0 and 1 for right now */
+void i830UpdateTextureState( GLcontext *ctx )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   int pipe_num = 0;
+   GLboolean ok;
+
+   ok = (i830UpdateTexUnit( ctx, 0 ) &&
+        i830UpdateTexUnit( ctx, 1 ) &&
+        i830UpdateTexUnit( ctx, 2 ) &&
+        i830UpdateTexUnit( ctx, 3 ));
+
+   FALLBACK( imesa, I830_FALLBACK_TEXTURE, !ok );
+
+
+   /* Make sure last stage is set correctly */
+   if(imesa->TexEnabledMask & I830_TEX_UNIT_ENABLED(3)) {
+      pipe_num = imesa->TexBlendColorPipeNum[3];
+      imesa->TexBlend[3][pipe_num] |= TEXOP_LAST_STAGE;
+   } else if(imesa->TexEnabledMask & I830_TEX_UNIT_ENABLED(2)) {
+      pipe_num = imesa->TexBlendColorPipeNum[2];
+      imesa->TexBlend[2][pipe_num] |= TEXOP_LAST_STAGE;
+   } else if(imesa->TexEnabledMask & I830_TEX_UNIT_ENABLED(1)) {
+      pipe_num = imesa->TexBlendColorPipeNum[1];
+      imesa->TexBlend[1][pipe_num] |= TEXOP_LAST_STAGE;
+   } else {
+      pipe_num = imesa->TexBlendColorPipeNum[0];
+      imesa->TexBlend[0][pipe_num] |= TEXOP_LAST_STAGE;
+   }
+}
+
+
+
diff --git a/src/mesa/drivers/dri/i830/i830_tris.c b/src/mesa/drivers/dri/i830/i830_tris.c
new file mode 100644 (file)
index 0000000..66720c1
--- /dev/null
@@ -0,0 +1,880 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_tris.c,v 1.4 2002/12/10 01:26:54 dawes 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.
+
+**************************************************************************/
+
+/*
+ * Original Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ * Adapted for use on the I830M:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ */
+
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "enums.h"
+#include "dd.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+#include "i830_screen.h"
+#include "i830_dri.h"
+
+#include "i830_tris.h"
+#include "i830_state.h"
+#include "i830_vb.h"
+#include "i830_ioctl.h"
+#include "i830_span.h"
+
+static void i830RenderPrimitive( 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__ i830_draw_triangle( i830ContextPtr imesa,
+                                          i830VertexPtr v0,
+                                          i830VertexPtr v1,
+                                          i830VertexPtr v2 )
+{
+   GLuint vertsize = imesa->vertex_size;
+   GLuint *vb = i830AllocDmaLow( 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__ i830_draw_quad( i830ContextPtr imesa,
+                                      i830VertexPtr v0,
+                                      i830VertexPtr v1,
+                                      i830VertexPtr v2,
+                                      i830VertexPtr v3 )
+{
+   GLuint vertsize = imesa->vertex_size;
+   GLuint *vb = i830AllocDmaLow( 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 i830_draw_point( i830ContextPtr imesa,
+                                       i830VertexPtr tmp )
+{
+   GLuint vertsize = imesa->vertex_size;
+   GLuint *vb = i830AllocDmaLow( imesa, 4 * vertsize );
+   int j;
+
+   /* Adjust for sub pixel position */
+   *(float *)&vb[0] = tmp->v.x - 0.125;
+   *(float *)&vb[1] = tmp->v.y - 0.125;
+   for (j = 2 ; j < vertsize ; j++)
+     vb[j] = tmp->ui[j];
+}
+
+
+static __inline__ void i830_draw_line( i830ContextPtr imesa,
+                                      i830VertexPtr v0,
+                                      i830VertexPtr v1 )
+{
+   GLuint vertsize = imesa->vertex_size;
+   GLuint *vb = i830AllocDmaLow( 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 (DO_FALLBACK)                            \
+      imesa->draw_tri( imesa, a, b, c );       \
+   else                                                \
+      i830_draw_triangle( imesa, a, b, c );    \
+} while (0)
+
+#define QUAD( a, b, c, d )                     \
+do {                                           \
+   if (DO_FALLBACK) {                          \
+      imesa->draw_tri( imesa, a, b, d );       \
+      imesa->draw_tri( imesa, b, c, d );       \
+   } else                                      \
+      i830_draw_quad( imesa, a, b, c, d );     \
+} while (0)
+
+#define LINE( v0, v1 )                         \
+do {                                           \
+   if (DO_FALLBACK)                            \
+      imesa->draw_line( imesa, v0, v1 );       \
+   else                                                \
+      i830_draw_line( imesa, v0, v1 );         \
+} while (0)
+
+#define POINT( v0 )                            \
+do {                                           \
+   if (DO_FALLBACK)                            \
+      imesa->draw_point( imesa, v0 );          \
+   else                                                \
+      i830_draw_point( imesa, v0 );            \
+} while (0)
+
+
+/***********************************************************************
+ *              Build render functions from dd templates               *
+ ***********************************************************************/
+
+#define I830_OFFSET_BIT        0x01
+#define I830_TWOSIDE_BIT       0x02
+#define I830_UNFILLED_BIT      0x04
+#define I830_FALLBACK_BIT      0x08
+#define I830_MAX_TRIFUNC       0x10
+
+
+static struct {
+   points_func         points;
+   line_func           line;
+   triangle_func       triangle;
+   quad_func           quad;
+} rast_tab[I830_MAX_TRIFUNC];
+
+
+#define DO_FALLBACK (IND & I830_FALLBACK_BIT)
+#define DO_OFFSET   (IND & I830_OFFSET_BIT)
+#define DO_UNFILLED (IND & I830_UNFILLED_BIT)
+#define DO_TWOSIDE  (IND & I830_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            i830Vertex
+#define TAB               rast_tab
+
+/* Only used to pull back colors into vertices (ie, we know color is
+ * floating point).
+ */
+#define I830_COLOR( dst, src )                 \
+do {                                           \
+   dst[0] = src[2];                            \
+   dst[1] = src[1];                            \
+   dst[2] = src[0];                            \
+   dst[3] = src[3];                            \
+} while (0)
+
+#define I830_SPEC( dst, src )                  \
+do {                                           \
+   dst[0] = src[2];                            \
+   dst[1] = src[1];                            \
+   dst[2] = src[0];                            \
+} while (0)
+
+
+#define DEPTH_SCALE (imesa->depth_scale)
+#define UNFILLED_TRI unfilled_tri
+#define UNFILLED_QUAD unfilled_quad
+#define VERT_X(_v) _v->v.x
+#define VERT_Y(_v) _v->v.y
+#define VERT_Z(_v) _v->v.z
+#define AREA_IS_CCW( a ) (a > 0)
+#define GET_VERTEX(e) (imesa->verts + (e<<imesa->vertex_stride_shift))
+
+#define VERT_SET_RGBA( v, c )    I830_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) I830_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)                                                  \
+   i830ContextPtr imesa = I830_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] = {
+   PRIM3D_POINTLIST,
+   PRIM3D_LINELIST,
+   PRIM3D_LINELIST,
+   PRIM3D_LINELIST,
+   PRIM3D_TRILIST,
+   PRIM3D_TRILIST,
+   PRIM3D_TRILIST,
+   PRIM3D_TRILIST,
+   PRIM3D_TRILIST,
+   PRIM3D_TRILIST
+};
+
+#define RASTERIZE(x) if (imesa->hw_primitive != hw_prim[x]) \
+                        i830RasterPrimitive( ctx, x, hw_prim[x] )
+#define RENDER_PRIMITIVE imesa->render_primitive
+#define TAG(x) x
+#define IND I830_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 (I830_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_UNFILLED_BIT)
+#define TAG(x) x##_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_OFFSET_BIT|I830_UNFILLED_BIT)
+#define TAG(x) x##_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_TWOSIDE_BIT|I830_UNFILLED_BIT)
+#define TAG(x) x##_twoside_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT|I830_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_FALLBACK_BIT)
+#define TAG(x) x##_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_OFFSET_BIT|I830_FALLBACK_BIT)
+#define TAG(x) x##_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_TWOSIDE_BIT|I830_FALLBACK_BIT)
+#define TAG(x) x##_twoside_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT|I830_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_UNFILLED_BIT|I830_FALLBACK_BIT)
+#define TAG(x) x##_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_OFFSET_BIT|I830_UNFILLED_BIT|I830_FALLBACK_BIT)
+#define TAG(x) x##_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_TWOSIDE_BIT|I830_UNFILLED_BIT|I830_FALLBACK_BIT)
+#define TAG(x) x##_twoside_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT|I830_UNFILLED_BIT| \
+            I830_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
+i830_fallback_tri( i830ContextPtr imesa,
+                  i830Vertex *v0,
+                  i830Vertex *v1,
+                  i830Vertex *v2 )
+{
+   GLcontext *ctx = imesa->glCtx;
+   SWvertex v[3];
+
+   if (0)
+      fprintf(stderr, "\n%s\n", __FUNCTION__);
+
+   i830_translate_vertex( ctx, v0, &v[0] );
+   i830_translate_vertex( ctx, v1, &v[1] );
+   i830_translate_vertex( ctx, v2, &v[2] );
+   i830SpanRenderStart( ctx );
+   _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
+   i830SpanRenderFinish( ctx );
+}
+
+
+static void
+i830_fallback_line( i830ContextPtr imesa,
+                   i830Vertex *v0,
+                   i830Vertex *v1 )
+{
+   GLcontext *ctx = imesa->glCtx;
+   SWvertex v[2];
+
+   if (0)
+      fprintf(stderr, "\n%s\n", __FUNCTION__);
+
+   i830_translate_vertex( ctx, v0, &v[0] );
+   i830_translate_vertex( ctx, v1, &v[1] );
+   i830SpanRenderStart( ctx );
+   _swrast_Line( ctx, &v[0], &v[1] );
+   i830SpanRenderFinish( ctx );
+}
+
+
+static void
+i830_fallback_point( i830ContextPtr imesa,
+                    i830Vertex *v0 )
+{
+   GLcontext *ctx = imesa->glCtx;
+   SWvertex v[1];
+
+   if (0)
+      fprintf(stderr, "\n%s\n", __FUNCTION__);
+
+   i830_translate_vertex( ctx, v0, &v[0] );
+   i830SpanRenderStart( ctx );
+   _swrast_Point( ctx, &v[0] );
+   i830SpanRenderFinish( ctx );
+}
+
+
+
+/**********************************************************************/
+/*               Render unclipped begin/end objects                   */
+/**********************************************************************/
+
+#define IND 0
+#define V(x) (i830Vertex *)(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) i830RenderPrimitive( ctx, x )
+#undef LOCAL_VARS
+#define LOCAL_VARS                                             \
+    i830ContextPtr imesa = I830_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) i830_##x##_verts
+#include "tnl/t_vb_rendertmp.h"
+#undef ELT
+#undef TAG
+#define TAG(x) i830_##x##_elts
+#define ELT(x) elt[x]
+#include "tnl/t_vb_rendertmp.h"
+
+/**********************************************************************/
+/*                   Render clipped primitives                        */
+/**********************************************************************/
+
+
+
+static void i830RenderClippedPoly( GLcontext *ctx, const GLuint *elts,
+                                  GLuint n )
+{
+   i830ContextPtr imesa = I830_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 i830RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+   tnl->Driver.Render.Line( ctx, ii, jj );
+}
+
+static void i830FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
+                                      GLuint n )
+{
+   i830ContextPtr imesa = I830_CONTEXT( ctx );
+   GLuint vertsize = imesa->vertex_size;
+   GLuint *vb = i830AllocDmaLow( 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                         */
+/**********************************************************************/
+
+
+
+#define _I830_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 i830ChooseRenderState(GLcontext *ctx)
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   GLuint flags = ctx->_TriangleCaps;
+   GLuint index = 0;
+
+   if (I830_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 |= I830_TWOSIDE_BIT;
+        if (flags & DD_TRI_OFFSET)           index |= I830_OFFSET_BIT;
+        if (flags & DD_TRI_UNFILLED)         index |= I830_UNFILLED_BIT;
+      }
+
+      imesa->draw_point = i830_draw_point;
+      imesa->draw_line = i830_draw_line;
+      imesa->draw_tri = i830_draw_triangle;
+
+      /* Hook in fallbacks for specific primitives.
+       */
+      if (flags & ANY_FALLBACK_FLAGS)
+      {
+        if (flags & POINT_FALLBACK)
+           imesa->draw_point = i830_fallback_point;
+
+        if (flags & LINE_FALLBACK)
+           imesa->draw_line = i830_fallback_line;
+
+        if (flags & TRI_FALLBACK)
+           imesa->draw_tri = i830_fallback_tri;
+
+        if ((flags & DD_TRI_STIPPLE) && !imesa->hw_stipple) {
+           imesa->draw_tri = i830_fallback_tri;
+        }
+
+        index |= I830_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 = i830_render_tab_verts;
+        tnl->Driver.Render.PrimTabElts = i830_render_tab_elts;
+        tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
+        tnl->Driver.Render.ClippedPolygon = i830FastRenderClippedPoly;
+      } else {
+        tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+        tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+        tnl->Driver.Render.ClippedLine = i830RenderClippedLine;
+        tnl->Driver.Render.ClippedPolygon = i830RenderClippedPoly;
+      }
+   }
+}
+
+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 i830RenderPrimitive( GLcontext *ctx, GLenum prim )
+{
+   i830ContextPtr imesa = I830_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) {
+      i830RasterPrimitive( ctx, rprim, hw_prim[prim] );
+   }
+}
+
+static void i830RunPipeline( GLcontext *ctx )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+
+   if (imesa->NewGLState) {
+      if (imesa->NewGLState & _NEW_TEXTURE) {
+        I830_FIREVERTICES( imesa );
+        i830UpdateTextureState( ctx ); /* may modify imesa->NewGLState */
+      }
+
+      if (!imesa->Fallback) {
+        if (imesa->NewGLState & _I830_NEW_VERTEX)
+           i830ChooseVertexState( ctx );
+
+        if (imesa->NewGLState & _I830_NEW_RENDERSTATE)
+           i830ChooseRenderState( ctx );
+      }
+
+      imesa->NewGLState = 0;
+   }
+
+   _tnl_run_pipeline( ctx );
+}
+
+static void i830RenderStart( GLcontext *ctx )
+{
+   /* Check for projective textureing.  Make sure all texcoord
+    * pointers point to something.  (fix in mesa?)
+    */
+
+   i830CheckTexSizes( ctx );
+}
+
+static void i830RenderFinish( GLcontext *ctx )
+{
+   if (I830_CONTEXT(ctx)->RenderIndex & I830_FALLBACK_BIT)
+      _swrast_flush( ctx );
+}
+
+
+
+
+/* System to flush dma and emit state changes based on the rasterized
+ * primitive.
+ */
+void i830RasterPrimitive( GLcontext *ctx,
+                         GLenum rprim,
+                         GLuint hwprim )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   GLuint aa = imesa->Setup[I830_CTXREG_AA];
+   GLuint st1 = imesa->StippleSetup[I830_STPREG_ST1];
+
+   aa &= ~AA_LINE_ENABLE;
+
+   if (I830_DEBUG & DEBUG_PRIMS) {
+      /* Prints reduced prim, and hw prim */
+      char *prim_name = "Unknown";
+
+      switch(hwprim) {
+      case PRIM3D_POINTLIST:
+        prim_name = "PointList";
+        break;
+      case PRIM3D_LINELIST:
+        prim_name = "LineList";
+        break;
+      case PRIM3D_LINESTRIP:
+        prim_name = "LineStrip";
+        break;  
+      case PRIM3D_TRILIST:
+        prim_name = "TriList";
+        break;  
+      case PRIM3D_TRISTRIP:
+        prim_name = "TriStrip";
+        break;  
+      case PRIM3D_TRIFAN:
+        prim_name = "TriFan";
+        break;  
+      case PRIM3D_POLY:
+        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:
+      aa |= AA_LINE_DISABLE;
+      if (ctx->Polygon.StippleFlag)
+        st1 |= ST1_ENABLE;
+      else
+        st1 &= ~ST1_ENABLE;
+      break;
+   case GL_LINES:
+      st1 &= ~ST1_ENABLE;
+      if (ctx->Line.SmoothFlag) {
+        aa |= AA_LINE_ENABLE;
+      } else {
+        aa |= AA_LINE_DISABLE;
+      }
+      break;
+   case GL_POINTS:
+      st1 &= ~ST1_ENABLE;
+      aa |= AA_LINE_DISABLE;
+      break;
+   default:
+      return;
+   }
+
+   imesa->reduced_primitive = rprim;
+
+   if (aa != imesa->Setup[I830_CTXREG_AA]) {
+      I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+      imesa->Setup[I830_CTXREG_AA] = aa;
+   }
+   
+#if 0
+   if (st1 != imesa->StippleSetup[I830_STPREG_ST1]) {
+      I830_STATECHANGE(imesa, I830_UPLOAD_STIPPLE);
+      imesa->StippleSetup[I830_STPREG_ST1] = st1;
+   }
+#endif
+
+   if (hwprim != imesa->hw_primitive) {
+      I830_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 i830Fallback( i830ContextPtr imesa, GLuint bit, GLboolean mode )
+{
+   GLcontext *ctx = imesa->glCtx;
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   GLuint oldfallback = imesa->Fallback;
+
+   if (mode) {
+      imesa->Fallback |= bit;
+      if (oldfallback == 0) {
+        I830_FIREVERTICES(imesa);
+        if (I830_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 (I830_DEBUG & DEBUG_FALLBACKS) 
+           fprintf(stderr, "LEAVE FALLBACK %s\n", getFallbackString( bit ));
+        tnl->Driver.Render.Start = i830RenderStart;
+        tnl->Driver.Render.PrimitiveNotify = i830RenderPrimitive;
+        tnl->Driver.Render.Finish = i830RenderFinish;
+        tnl->Driver.Render.BuildVertices = i830BuildVertices;
+        imesa->NewGLState |= (_I830_NEW_RENDERSTATE|_I830_NEW_VERTEX);
+      }
+   }
+}
+
+
+
+
+/**********************************************************************/
+/*                            Initialization.                         */
+/**********************************************************************/
+
+
+void i830InitTriFuncs( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   static int firsttime = 1;
+
+   if (firsttime) {
+      init_rast_tab();
+      firsttime = 0;
+   }
+
+   tnl->Driver.RunPipeline = i830RunPipeline;
+   tnl->Driver.Render.Start = i830RenderStart;
+   tnl->Driver.Render.Finish = i830RenderFinish;
+   tnl->Driver.Render.PrimitiveNotify = i830RenderPrimitive;
+   tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
+   tnl->Driver.Render.BuildVertices = i830BuildVertices;
+}
diff --git a/src/mesa/drivers/dri/i830/i830_tris.h b/src/mesa/drivers/dri/i830/i830_tris.h
new file mode 100644 (file)
index 0000000..ae4f0a5
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ *
+ * Adapted for use in the I830M:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_tris.h,v 1.3 2002/09/09 19:18:48 dawes Exp $ */
+
+#ifndef I830TRIS_INC
+#define I830TRIS_INC
+
+#include "mtypes.h"
+
+extern void i830PrintRenderState( const char *msg, GLuint state );
+extern void i830InitTriFuncs( GLcontext *ctx );
+extern void i830RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
+
+#endif
diff --git a/src/mesa/drivers/dri/i830/i830_vb.c b/src/mesa/drivers/dri/i830/i830_vb.c
new file mode 100644 (file)
index 0000000..a7ac054
--- /dev/null
@@ -0,0 +1,592 @@
+/*
+ * 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.
+ *
+ * Adapted for use on the I830M:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_vb.c,v 1.5 2002/12/10 01:26:54 dawes 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 "i830_screen.h"
+#include "i830_dri.h"
+
+#include "i830_context.h"
+#include "i830_vb.h"
+#include "i830_ioctl.h"
+#include "i830_tris.h"
+#include "i830_state.h"
+
+#define I830_TEX1_BIT       0x1
+#define I830_TEX0_BIT       0x2
+#define I830_RGBA_BIT       0x4
+#define I830_SPEC_BIT       0x8
+#define I830_FOG_BIT       0x10
+#define I830_XYZW_BIT       0x20
+#define I830_PTEX_BIT       0x40
+#define I830_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[I830_MAX_SETUP];
+
+#define TINY_VERTEX_FORMAT      (STATE3D_VERTEX_FORMAT_CMD | \
+                                VRTX_TEX_COORD_COUNT(0) | \
+                                VRTX_HAS_DIFFUSE | \
+                                VRTX_HAS_XYZ)
+
+#define NOTEX_VERTEX_FORMAT     (STATE3D_VERTEX_FORMAT_CMD | \
+                                VRTX_TEX_COORD_COUNT(0) | \
+                                VRTX_HAS_DIFFUSE | \
+                                VRTX_HAS_SPEC | \
+                                VRTX_HAS_XYZW)
+
+#define TEX0_VERTEX_FORMAT      (STATE3D_VERTEX_FORMAT_CMD | \
+                                VRTX_TEX_COORD_COUNT(1) | \
+                                VRTX_HAS_DIFFUSE | \
+                                VRTX_HAS_SPEC | \
+                                VRTX_HAS_XYZW)
+
+#define TEX1_VERTEX_FORMAT      (STATE3D_VERTEX_FORMAT_CMD | \
+                                VRTX_TEX_COORD_COUNT(2) | \
+                                VRTX_HAS_DIFFUSE | \
+                                VRTX_HAS_SPEC | \
+                                VRTX_HAS_XYZW)
+
+
+/* I'm cheating here hardcore : if bit 31 is set I know to emit
+ * a vf2 state == TEXCOORDFMT_3D.  We never mix 2d/3d texcoords,
+ * so this solution works for now.
+ */
+
+#define PROJ_TEX1_VERTEX_FORMAT ((1<<31) | \
+                                STATE3D_VERTEX_FORMAT_CMD | \
+                                VRTX_TEX_COORD_COUNT(2) | \
+                                VRTX_HAS_DIFFUSE | \
+                                VRTX_HAS_SPEC | \
+                                VRTX_HAS_XYZW)
+
+/* Might want to do these later */
+#define TEX2_VERTEX_FORMAT      0
+#define TEX3_VERTEX_FORMAT      0
+#define PROJ_TEX3_VERTEX_FORMAT 0
+
+#define DO_XYZW (IND & I830_XYZW_BIT)
+#define DO_RGBA (IND & I830_RGBA_BIT)
+#define DO_SPEC (IND & I830_SPEC_BIT)
+#define DO_FOG  (IND & I830_FOG_BIT)
+#define DO_TEX0 (IND & I830_TEX0_BIT)
+#define DO_TEX1 (IND & I830_TEX1_BIT)
+#define DO_TEX2 0
+#define DO_TEX3 0
+#define DO_PTEX (IND & I830_PTEX_BIT)
+
+#define VERTEX i830Vertex
+#define VERTEX_COLOR i830_color_t
+#define GET_VIEWPORT_MAT() I830_CONTEXT(ctx)->ViewportMatrix.m
+#define GET_TEXSOURCE(n)  n
+#define GET_VERTEX_FORMAT() I830_CONTEXT(ctx)->vertex_format
+#define GET_VERTEX_STORE() ((GLubyte *)I830_CONTEXT(ctx)->verts)
+#define GET_VERTEX_STRIDE_SHIFT() I830_CONTEXT(ctx)->vertex_stride_shift
+#define GET_UBYTE_COLOR_STORE() &I830_CONTEXT(ctx)->UbyteColor
+#define GET_UBYTE_SPEC_COLOR_STORE() &I830_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  1
+
+#define UNVIEWPORT_VARS  GLfloat h = I830_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)I830_CONTEXT(ctx)->ClearDepth
+
+#define PTEX_FALLBACK() FALLBACK(I830_CONTEXT(ctx), I830_FALLBACK_TEXTURE, 1)
+
+#define IMPORT_FLOAT_COLORS i830_import_float_colors
+#define IMPORT_FLOAT_SPEC_COLORS i830_import_float_spec_colors
+
+#define INTERP_VERTEX setup_tab[I830_CONTEXT(ctx)->SetupIndex].interp
+#define COPY_PV_VERTEX setup_tab[I830_CONTEXT(ctx)->SetupIndex].copy_pv
+
+
+/***********************************************************************
+ *         Generate  pv-copying and translation functions              *
+ ***********************************************************************/
+
+#define TAG(x) i830_##x
+#include "tnl_dd/t_dd_vb.c"
+
+/***********************************************************************
+ *             Generate vertex emit and interp functions               *
+ ***********************************************************************/
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT)
+#define TAG(x) x##_wg
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT)
+#define TAG(x) x##_wgs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT)
+#define TAG(x) x##_wgt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
+#define TAG(x) x##_wgt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_PTEX_BIT)
+#define TAG(x) x##_wgpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT)
+#define TAG(x) x##_wgst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\
+             I830_TEX1_BIT)
+#define TAG(x) x##_wgst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\
+             I830_PTEX_BIT)
+#define TAG(x) x##_wgspt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT)
+#define TAG(x) x##_wgf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT)
+#define TAG(x) x##_wgfs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT)
+#define TAG(x) x##_wgft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\
+             I830_TEX1_BIT)
+#define TAG(x) x##_wgft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\
+             I830_PTEX_BIT)
+#define TAG(x) x##_wgfpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\
+             I830_TEX0_BIT)
+#define TAG(x) x##_wgfst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\
+             I830_TEX0_BIT|I830_TEX1_BIT)
+#define TAG(x) x##_wgfst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\
+             I830_TEX0_BIT|I830_PTEX_BIT)
+#define TAG(x) x##_wgfspt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_TEX0_BIT)
+#define TAG(x) x##_t0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_TEX0_BIT|I830_TEX1_BIT)
+#define TAG(x) x##_t0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_FOG_BIT)
+#define TAG(x) x##_f
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_FOG_BIT|I830_TEX0_BIT)
+#define TAG(x) x##_ft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
+#define TAG(x) x##_ft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_RGBA_BIT)
+#define TAG(x) x##_g
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_RGBA_BIT|I830_SPEC_BIT)
+#define TAG(x) x##_gs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_RGBA_BIT|I830_TEX0_BIT)
+#define TAG(x) x##_gt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
+#define TAG(x) x##_gt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT)
+#define TAG(x) x##_gst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
+#define TAG(x) x##_gst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_RGBA_BIT|I830_FOG_BIT)
+#define TAG(x) x##_gf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT)
+#define TAG(x) x##_gfs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT)
+#define TAG(x) x##_gft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
+#define TAG(x) x##_gft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT)
+#define TAG(x) x##_gfst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\
+             I830_TEX1_BIT)
+#define TAG(x) x##_gfst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+/* Add functions for proj texturing for t0 and t1 */
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT|\
+            I830_PTEX_BIT)
+#define TAG(x) x##_wgpt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\
+             I830_TEX1_BIT|I830_PTEX_BIT)
+#define TAG(x) x##_wgspt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\
+             I830_TEX1_BIT|I830_PTEX_BIT)
+#define TAG(x) x##_wgfpt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\
+             I830_TEX1_BIT|I830_TEX0_BIT|I830_PTEX_BIT)
+#define TAG(x) x##_wgfspt0t1
+#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();
+   /* Add proj texturing on t1 */
+   init_wgpt0t1();
+   init_wgspt0t1();
+   init_wgfpt0t1();
+   init_wgfspt0t1();
+}
+
+
+
+void i830PrintSetupFlags(char *msg, GLuint flags )
+{
+   fprintf(stderr, "%s(%x): %s%s%s%s%s%s%s\n",
+          msg,
+          (int)flags,
+          (flags & I830_XYZW_BIT)      ? " xyzw," : "",
+          (flags & I830_RGBA_BIT)     ? " rgba," : "",
+          (flags & I830_SPEC_BIT)     ? " spec," : "",
+          (flags & I830_FOG_BIT)      ? " fog," : "",
+          (flags & I830_TEX0_BIT)     ? " tex-0," : "",
+          (flags & I830_TEX1_BIT)     ? " tex-1," : "",
+          (flags & I830_PTEX_BIT)     ? " ptex," : "");
+}
+
+void i830CheckTexSizes( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   i830ContextPtr imesa = I830_CONTEXT( ctx );
+
+   if (!setup_tab[imesa->SetupIndex].check_tex_sizes(ctx)) {
+      int ind = imesa->SetupIndex |= I830_PTEX_BIT;
+        
+      if(setup_tab[ind].vertex_format != imesa->vertex_format) {
+        int vfmt = setup_tab[ind].vertex_format;
+
+        I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+        imesa->Setup[I830_CTXREG_VF] = ~(1<<31) & vfmt;
+
+        if (vfmt & (1<<31)) {
+           /* Proj texturing */
+           imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD |
+                                         VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D) |
+                                         VRTX_TEX_SET_1_FMT(TEXCOORDFMT_3D) | 
+                                         VRTX_TEX_SET_2_FMT(TEXCOORDFMT_3D) |
+                                         VRTX_TEX_SET_3_FMT(TEXCOORDFMT_3D));
+           i830UpdateTexUnitProj( ctx, 0, GL_TRUE );
+           i830UpdateTexUnitProj( ctx, 1, GL_TRUE );
+           
+        } else {
+           /* Normal texturing */
+           imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD |
+                                         VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) |
+                                         VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) | 
+                                         VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) |
+                                         VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D));
+           i830UpdateTexUnitProj( ctx, 0, GL_FALSE );
+           i830UpdateTexUnitProj( ctx, 1, GL_FALSE );
+        }
+        imesa->vertex_format = vfmt;
+        imesa->vertex_size = setup_tab[ind].vertex_size;
+        imesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift;
+      }
+
+      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;
+      }
+   }
+}
+
+void i830BuildVertices( GLcontext *ctx,
+                       GLuint start,
+                       GLuint count,
+                       GLuint newinputs )
+{
+   i830ContextPtr imesa = I830_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 |= I830_RGBA_BIT;
+
+      if (newinputs & VERT_BIT_COLOR1)
+        ind |= I830_SPEC_BIT;
+
+      if (newinputs & VERT_BIT_TEX0)
+        ind |= I830_TEX0_BIT;
+
+      if (newinputs & VERT_BIT_TEX1)
+        ind |= I830_TEX1_BIT;
+
+      if (newinputs & VERT_BIT_FOG)
+        ind |= I830_FOG_BIT;
+
+#if 0
+      if (imesa->SetupIndex & I830_PTEX_BIT)
+        ind = ~0;
+#endif
+
+      ind &= imesa->SetupIndex;
+
+      if (ind) {
+        setup_tab[ind].emit( ctx, start, count, v, stride );
+      }
+   }
+}
+
+void i830ChooseVertexState( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   i830ContextPtr imesa = I830_CONTEXT( ctx );
+   GLuint ind = I830_XYZW_BIT|I830_RGBA_BIT;
+
+   if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+      ind |= I830_SPEC_BIT;
+
+   if (ctx->Fog.Enabled)
+      ind |= I830_FOG_BIT;
+
+   if (ctx->Texture._EnabledUnits & 0x2)
+      /* unit 1 enabled */
+      ind |= I830_TEX1_BIT|I830_TEX0_BIT;
+   else if (ctx->Texture._EnabledUnits & 0x1)
+      /* unit 0 enabled */
+      ind |= I830_TEX0_BIT;
+
+   imesa->SetupIndex = ind;
+
+   if (I830_DEBUG & (DEBUG_VERTS|DEBUG_STATE))
+      i830PrintSetupFlags( __FUNCTION__, ind );
+
+   if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
+      tnl->Driver.Render.Interp = i830_interp_extras;
+      tnl->Driver.Render.CopyPV = i830_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->vertex_format) {
+      int vfmt = setup_tab[ind].vertex_format;
+
+      I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
+      imesa->Setup[I830_CTXREG_VF] = ~(1<<31) & vfmt;
+
+      if (vfmt & (1<<31)) {
+        /* Proj texturing */
+        imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD |
+                                         VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D) |
+                                         VRTX_TEX_SET_1_FMT(TEXCOORDFMT_3D) | 
+                                         VRTX_TEX_SET_2_FMT(TEXCOORDFMT_3D) |
+                                         VRTX_TEX_SET_3_FMT(TEXCOORDFMT_3D));
+        i830UpdateTexUnitProj( ctx, 0, GL_TRUE );
+        i830UpdateTexUnitProj( ctx, 1, GL_TRUE );
+      } else {
+        /* Normal texturing */
+        imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD |
+                                         VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) |
+                                         VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) | 
+                                         VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) |
+                                         VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D));
+        i830UpdateTexUnitProj( ctx, 0, GL_FALSE );
+        i830UpdateTexUnitProj( ctx, 1, GL_FALSE );
+      }
+      imesa->vertex_format = vfmt;
+      imesa->vertex_size = setup_tab[ind].vertex_size;
+      imesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift;
+   }
+}
+
+
+
+void i830_emit_contiguous_verts( GLcontext *ctx,
+                                GLuint start,
+                                GLuint count )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   GLuint vertex_size = imesa->vertex_size * 4;
+   GLuint *dest = i830AllocDmaLow( imesa, (count-start) * vertex_size);
+   setup_tab[imesa->SetupIndex].emit( ctx, start, count, dest, vertex_size );
+}
+
+
+
+void i830InitVB( GLcontext *ctx )
+{
+   i830ContextPtr imesa = I830_CONTEXT(ctx);
+   GLuint size = TNL_CONTEXT(ctx)->vb.Size;
+   
+   imesa->verts = (char *)ALIGN_MALLOC(size * 4 * 16, 32);
+
+   {
+      static int firsttime = 1;
+      if (firsttime) {
+        init_setup_tab();
+        firsttime = 0;
+      }
+   }
+}
+
+
+void i830FreeVB( GLcontext *ctx )
+{
+   i830ContextPtr imesa = I830_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/i830/i830_vb.h b/src/mesa/drivers/dri/i830/i830_vb.h
new file mode 100644 (file)
index 0000000..5233544
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ *
+ * Adapted for use in the I830M:
+ *   Jeff Hartmann <jhartmann@2d3d.com>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_vb.h,v 1.1 2002/09/09 19:18:49 dawes Exp $ */
+
+#ifndef I830VB_INC
+#define I830VB_INC
+
+#include "mtypes.h"
+#include "swrast/swrast.h"
+
+#define _I830_NEW_VERTEX (_NEW_TEXTURE |                       \
+                         _DD_NEW_SEPARATE_SPECULAR |           \
+                         _DD_NEW_TRI_UNFILLED |                \
+                         _DD_NEW_TRI_LIGHT_TWOSIDE |           \
+                         _NEW_FOG)
+
+
+extern void i830ChooseVertexState( GLcontext *ctx );
+extern void i830CheckTexSizes( GLcontext *ctx );
+extern void i830BuildVertices( GLcontext *ctx,
+                              GLuint start,
+                              GLuint count,
+                              GLuint newinputs );
+
+
+extern void i830_emit_contiguous_verts( GLcontext *ctx,
+                                       GLuint start,
+                                       GLuint count );
+
+extern void i830_translate_vertex( GLcontext *ctx,
+                                  const i830Vertex *src,
+                                  SWvertex *dst );
+
+extern void i830InitVB( GLcontext *ctx );
+extern void i830FreeVB( GLcontext *ctx );
+
+extern void i830_print_vertex( GLcontext *ctx, const i830Vertex *v );
+extern void i830PrintSetupFlags(char *msg, GLuint flags );
+
+#endif
diff --git a/src/mesa/drivers/dri/i830/server/i830_common.h b/src/mesa/drivers/dri/i830/server/i830_common.h
new file mode 100644 (file)
index 0000000..3367bfc
--- /dev/null
@@ -0,0 +1,288 @@
+/**************************************************************************
+
+Copyright 2001 VA Linux Systems Inc., Fremont, California.
+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
+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.
+
+**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.2 2002/12/10 01:27:05 dawes Exp $ */
+
+/* Author: Jeff Hartmann <jhartmann@valinux.com> 
+
+   Converted to common header format:
+     Jens Owen <jens@tungstengraphics.com>
+ */
+
+#ifndef _I830_COMMON_H_
+#define _I830_COMMON_H_
+
+/* WARNING: These defines must be the same as what the Xserver uses.
+ * if you change them, you must change the defines in the Xserver.
+ */
+
+#ifndef _I830_DEFINES_
+#define _I830_DEFINES_
+
+#define I830_DMA_BUF_ORDER             12
+#define I830_DMA_BUF_SZ                (1<<I830_DMA_BUF_ORDER)
+#define I830_DMA_BUF_NR                256
+#define I830_NR_SAREA_CLIPRECTS        8
+
+/* Each region is a minimum of 64k, and there are at most 64 of them.
+ */
+#define I830_NR_TEX_REGIONS 64
+#define I830_LOG_MIN_TEX_REGION_SIZE 16
+
+/* if defining I830_ENABLE_4_TEXTURES, do it in i830_3d_reg.h, too */
+#if !defined(I830_ENABLE_4_TEXTURES)
+#define I830_TEXTURE_COUNT     2
+#define I830_TEXBLEND_COUNT    2       /* always same as TEXTURE_COUNT? */
+#else /* defined(I830_ENABLE_4_TEXTURES) */
+#define I830_TEXTURE_COUNT     4
+#define I830_TEXBLEND_COUNT    4       /* always same as TEXTURE_COUNT? */
+#endif /* I830_ENABLE_4_TEXTURES */
+
+#define I830_TEXBLEND_SIZE     12      /* (4 args + op) * 2 + COLOR_FACTOR */
+
+#define I830_UPLOAD_CTX                        0x1
+#define I830_UPLOAD_BUFFERS            0x2
+#define I830_UPLOAD_CLIPRECTS          0x4
+#define I830_UPLOAD_TEX0_IMAGE         0x100   /* handled clientside */
+#define I830_UPLOAD_TEX0_CUBE          0x200   /* handled clientside */
+#define I830_UPLOAD_TEX1_IMAGE         0x400   /* handled clientside */
+#define I830_UPLOAD_TEX1_CUBE          0x800   /* handled clientside */
+#define I830_UPLOAD_TEX2_IMAGE         0x1000  /* handled clientside */
+#define I830_UPLOAD_TEX2_CUBE          0x2000  /* handled clientside */
+#define I830_UPLOAD_TEX3_IMAGE         0x4000  /* handled clientside */
+#define I830_UPLOAD_TEX3_CUBE          0x8000  /* handled clientside */
+#define I830_UPLOAD_TEX_N_IMAGE(n)     (0x100 << (n * 2))
+#define I830_UPLOAD_TEX_N_CUBE(n)      (0x200 << (n * 2))
+#define I830_UPLOAD_TEXIMAGE_MASK      0xff00
+#define I830_UPLOAD_TEX0                       0x10000
+#define I830_UPLOAD_TEX1                       0x20000
+#define I830_UPLOAD_TEX2                       0x40000
+#define I830_UPLOAD_TEX3                       0x80000
+#define I830_UPLOAD_TEX_N(n)           (0x10000 << (n))
+#define I830_UPLOAD_TEX_MASK           0xf0000
+#define I830_UPLOAD_TEXBLEND0          0x100000
+#define I830_UPLOAD_TEXBLEND1          0x200000
+#define I830_UPLOAD_TEXBLEND2          0x400000
+#define I830_UPLOAD_TEXBLEND3          0x800000
+#define I830_UPLOAD_TEXBLEND_N(n)      (0x100000 << (n))
+#define I830_UPLOAD_TEXBLEND_MASK      0xf00000
+#define I830_UPLOAD_TEX_PALETTE_N(n)    (0x1000000 << (n))
+#define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000
+#define I830_UPLOAD_STIPPLE            0x8000000
+
+/* Indices into buf.Setup where various bits of state are mirrored per
+ * context and per buffer.  These can be fired at the card as a unit,
+ * or in a piecewise fashion as required.
+ */
+
+/* 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 I830_DESTREG_CBUFADDR 0
+/* Invarient */
+#define I830_DESTREG_DBUFADDR 1
+#define I830_DESTREG_DV0 2
+#define I830_DESTREG_DV1 3
+#define I830_DESTREG_SENABLE 4
+#define I830_DESTREG_SR0 5
+#define I830_DESTREG_SR1 6
+#define I830_DESTREG_SR2 7
+#define I830_DESTREG_DR0 8
+#define I830_DESTREG_DR1 9
+#define I830_DESTREG_DR2 10
+#define I830_DESTREG_DR3 11
+#define I830_DESTREG_DR4 12
+#define I830_DEST_SETUP_SIZE 13
+
+/* Context state
+ */
+#define I830_CTXREG_STATE1             0
+#define I830_CTXREG_STATE2             1
+#define I830_CTXREG_STATE3             2
+#define I830_CTXREG_STATE4             3
+#define I830_CTXREG_STATE5             4
+#define I830_CTXREG_IALPHAB            5
+#define I830_CTXREG_STENCILTST         6
+#define I830_CTXREG_ENABLES_1          7
+#define I830_CTXREG_ENABLES_2          8
+#define I830_CTXREG_AA                 9
+#define I830_CTXREG_FOGCOLOR           10
+#define I830_CTXREG_BLENDCOLR0         11
+#define I830_CTXREG_BLENDCOLR          12      /* Dword 1 of 2 dword command */
+#define I830_CTXREG_VF                 13
+#define I830_CTXREG_VF2                        14
+#define I830_CTXREG_MCSB0              15
+#define I830_CTXREG_MCSB1              16
+#define I830_CTX_SETUP_SIZE            17
+
+/* 1.3: Stipple state
+ */ 
+#define I830_STPREG_ST0 0
+#define I830_STPREG_ST1 1
+#define I830_STP_SETUP_SIZE 2
+
+/* Texture state (per tex unit)
+ */
+#define I830_TEXREG_MI0        0               /* GFX_OP_MAP_INFO (6 dwords) */
+#define I830_TEXREG_MI1        1
+#define I830_TEXREG_MI2        2
+#define I830_TEXREG_MI3        3
+#define I830_TEXREG_MI4        4
+#define I830_TEXREG_MI5        5
+#define I830_TEXREG_MF 6               /* GFX_OP_MAP_FILTER */
+#define I830_TEXREG_MLC        7               /* GFX_OP_MAP_LOD_CTL */
+#define I830_TEXREG_MLL        8               /* GFX_OP_MAP_LOD_LIMITS */
+#define I830_TEXREG_MCS        9               /* GFX_OP_MAP_COORD_SETS */
+#define I830_TEX_SETUP_SIZE 10
+
+/* New version.  Kernel auto-detects.
+ */
+#define I830_TEXREG_TM0LI      0 /* load immediate 2 texture map n */
+#define I830_TEXREG_TM0S0      1
+#define I830_TEXREG_TM0S1      2
+#define I830_TEXREG_TM0S2      3
+#define I830_TEXREG_TM0S3      4
+#define I830_TEXREG_TM0S4      5
+#define I830_TEXREG_NOP0       6       /* noop */
+#define I830_TEXREG_NOP1       7       /* noop */
+#define I830_TEXREG_NOP2       8       /* noop */
+#define __I830_TEXREG_MCS      9       /* GFX_OP_MAP_COORD_SETS -- shared */
+#define __I830_TEX_SETUP_SIZE   10
+
+
+#define I830_FRONT   0x1
+#define I830_BACK    0x2
+#define I830_DEPTH   0x4
+
+/* Driver specific DRM command indices
+ * NOTE: these are not OS specific, but they are driver specific
+ */
+#define DRM_I830_INIT                     0x00
+#define DRM_I830_VERTEX                   0x01
+#define DRM_I830_CLEAR                    0x02
+#define DRM_I830_FLUSH                    0x03
+#define DRM_I830_GETAGE                   0x04
+#define DRM_I830_GETBUF                   0x05
+#define DRM_I830_SWAP                     0x06
+#define DRM_I830_COPY                     0x07
+#define DRM_I830_DOCOPY                   0x08
+#define DRM_I830_FLIP                     0x09
+#define DRM_I830_IRQ_EMIT                 0x0a
+#define DRM_I830_IRQ_WAIT                 0x0b
+#define DRM_I830_GETPARAM                 0x0c
+#define DRM_I830_SETPARAM                 0x0d
+
+#endif /* _I830_DEFINES_ */
+
+typedef struct {
+   enum {
+      I830_INIT_DMA = 0x01,
+      I830_CLEANUP_DMA = 0x02
+   } 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 w;
+   unsigned int h;
+   unsigned int pitch;
+   unsigned int pitch_bits;
+   unsigned int back_pitch;
+   unsigned int depth_pitch;
+   unsigned int cpp;
+} drmI830Init;
+
+typedef struct {
+   int clear_color;
+   int clear_depth;
+   int flags;
+   unsigned int clear_colormask;
+   unsigned int clear_depthmask;
+} drmI830Clear;
+
+/* These may be placeholders if we have more cliprects than
+ * I830_NR_SAREA_CLIPRECTS.  In that case, the client sets discard to
+ * false, indicating that the buffer will be dispatched again with a
+ * new set of cliprects.
+ */
+typedef struct {
+   int idx;                            /* buffer index */
+   int used;                           /* nr bytes in use */
+   int discard;                                /* client is finished with the buffer? */
+} drmI830Vertex;
+
+typedef struct {
+   int idx;                            /* buffer index */
+   int used;                           /* nr bytes in use */
+   void *address;                      /* Address to copy from */
+} drmI830Copy;
+
+typedef struct {
+   void *virtual;
+   int request_idx;
+   int request_size;
+   int granted;
+} drmI830DMA;
+
+typedef struct drm_i830_irq_emit {
+       int *irq_seq;
+} drmI830IrqEmit;
+
+typedef struct drm_i830_irq_wait {
+       int irq_seq;
+} drmI830IrqWait;
+
+typedef struct drm_i830_getparam {
+       int param;
+       int *value;
+} drmI830GetParam;
+
+#define I830_PARAM_IRQ_ACTIVE  1
+
+
+typedef struct drm_i830_setparam {
+       int param;
+       int value;
+} drmI830SetParam;
+
+#define I830_SETPARAM_USE_MI_BATCHBUFFER_START  1
+
+
+
+#endif /* _I830_DRM_H_ */
diff --git a/src/mesa/drivers/dri/i830/server/i830_dri.h b/src/mesa/drivers/dri/i830/server/i830_dri.h
new file mode 100644 (file)
index 0000000..69a4f67
--- /dev/null
@@ -0,0 +1,140 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.5 2002/12/10 01:27:05 dawes Exp $ */
+
+#ifndef _I830_DRI_H
+#define _I830_DRI_H
+
+#include "xf86drm.h"
+#include "i830_common.h"
+
+#define I830_MAX_DRAWABLES 256
+
+#define I830_MAJOR_VERSION 1
+#define I830_MINOR_VERSION 3
+#define I830_PATCHLEVEL 0
+
+#define I830_REG_SIZE 0x80000
+
+typedef struct _I830DRIRec {
+   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;
+   int sarea_priv_offset;
+} I830DRIRec, *I830DRIPtr;
+
+typedef struct {
+   /* Nothing here yet */
+   int dummy;
+} I830ConfigPrivRec, *I830ConfigPrivPtr;
+
+typedef struct {
+   /* Nothing here yet */
+   int dummy;
+} I830DRIContextRec, *I830DRIContextPtr;
+
+/* Warning: If you change the SAREA structure you must change the kernel
+ * structure as well */
+
+typedef struct _I830SAREA {
+   unsigned int ContextState[I830_CTX_SETUP_SIZE];
+   unsigned int BufferState[I830_DEST_SETUP_SIZE];
+   unsigned int TexState[I830_TEXTURE_COUNT][I830_TEX_SETUP_SIZE];
+   unsigned int TexBlendState[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE];
+   unsigned int TexBlendStateWordsUsed[I830_TEXBLEND_COUNT];
+   unsigned int Palette[2][256];
+   unsigned int dirty;
+
+   unsigned int nbox;
+   XF86DRIClipRectRec boxes[I830_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[I830_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? */
+
+   int perf_boxes;             /* performance boxes to be displayed */
+
+   /* Here's the state for texunits 2,3:
+    */
+   unsigned int TexState2[I830_TEX_SETUP_SIZE];
+   unsigned int TexBlendState2[I830_TEXBLEND_SIZE];
+   unsigned int TexBlendStateWordsUsed2;
+
+   unsigned int TexState3[I830_TEX_SETUP_SIZE];
+   unsigned int TexBlendState3[I830_TEXBLEND_SIZE];
+   unsigned int TexBlendStateWordsUsed3;
+   
+   unsigned int StippleState[I830_STP_SETUP_SIZE];
+} I830SAREARec, *I830SAREAPtr;
+
+/* Flags for perf_boxes
+ */
+#define I830_BOX_RING_EMPTY    0x1 /* populated by kernel */
+#define I830_BOX_FLIP          0x2 /* populated by kernel */
+#define I830_BOX_WAIT          0x4 /* populated by kernel & client */
+#define I830_BOX_TEXTURE_LOAD  0x8 /* populated by kernel */
+#define I830_BOX_LOST_CONTEXT  0x10 /* populated by client */
+
+#endif