summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@tungstengraphics.com>2003-09-30 11:02:38 +0000
committerAlan Hourihane <alanh@tungstengraphics.com>2003-09-30 11:02:38 +0000
commit6bec5b30e1144fb530971b34087e86afd7162441 (patch)
tree11169cc8a3805f5941e59f39ced4db8dc3781090
parent73b0420bba16b5dcfbb75b32bc519295f925041a (diff)
add the i830 driver - no kernel driver yet
(build tested, but not physically tested)
-rw-r--r--Makefile.X114
-rw-r--r--src/mesa/drivers/dri/i830/Makefile.X11117
-rw-r--r--src/mesa/drivers/dri/i830/i830_3d_reg.h675
-rw-r--r--src/mesa/drivers/dri/i830/i830_context.c588
-rw-r--r--src/mesa/drivers/dri/i830/i830_context.h310
-rw-r--r--src/mesa/drivers/dri/i830/i830_debug.c377
-rw-r--r--src/mesa/drivers/dri/i830/i830_debug.h48
-rw-r--r--src/mesa/drivers/dri/i830/i830_ioctl.c841
-rw-r--r--src/mesa/drivers/dri/i830/i830_ioctl.h105
-rw-r--r--src/mesa/drivers/dri/i830/i830_render.c267
-rw-r--r--src/mesa/drivers/dri/i830/i830_screen.c371
-rw-r--r--src/mesa/drivers/dri/i830/i830_screen.h107
-rw-r--r--src/mesa/drivers/dri/i830/i830_span.c370
-rw-r--r--src/mesa/drivers/dri/i830/i830_span.h46
-rw-r--r--src/mesa/drivers/dri/i830/i830_state.c1796
-rw-r--r--src/mesa/drivers/dri/i830/i830_state.h68
-rw-r--r--src/mesa/drivers/dri/i830/i830_tex.c579
-rw-r--r--src/mesa/drivers/dri/i830/i830_tex.h71
-rw-r--r--src/mesa/drivers/dri/i830/i830_texmem.c214
-rw-r--r--src/mesa/drivers/dri/i830/i830_texstate.c1607
-rw-r--r--src/mesa/drivers/dri/i830/i830_tris.c880
-rw-r--r--src/mesa/drivers/dri/i830/i830_tris.h37
-rw-r--r--src/mesa/drivers/dri/i830/i830_vb.c592
-rw-r--r--src/mesa/drivers/dri/i830/i830_vb.h63
-rw-r--r--src/mesa/drivers/dri/i830/server/i830_common.h288
-rw-r--r--src/mesa/drivers/dri/i830/server/i830_dri.h140
26 files changed, 10560 insertions, 1 deletions
diff --git a/Makefile.X11 b/Makefile.X11
index e00c1acb17..1e432a97e0 100644
--- a/Makefile.X11
+++ b/Makefile.X11
@@ -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
index 0000000000..e690ed6b2f
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/Makefile.X11
@@ -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
index 0000000000..eab1092094
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_3d_reg.h
@@ -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
index 0000000000..254fa28462
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_context.c
@@ -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
index 0000000000..2bb71cb719
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_context.h
@@ -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
index 0000000000..66c698ba30
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_debug.c
@@ -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
index 0000000000..deb84f7b0a
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_debug.h
@@ -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
index 0000000000..607b813e53
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_ioctl.c
@@ -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
index 0000000000..4c64b8d7ab
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_ioctl.h
@@ -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
index 0000000000..5df05dfde8
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_render.c
@@ -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
index 0000000000..a1079f6f56
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_screen.c
@@ -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
index 0000000000..8153828ffc
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_screen.h
@@ -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
index 0000000000..34830bf58c
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_span.c
@@ -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
index 0000000000..0135468ffa
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_span.h
@@ -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
index 0000000000..6eb46fac46
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_state.c
@@ -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
index 0000000000..b651651246
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_state.h
@@ -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
index 0000000000..14a70a0905
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_tex.c
@@ -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
index 0000000000..dbfcbe3963
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_tex.h
@@ -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
index 0000000000..6cb5531349
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_texmem.c
@@ -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
index 0000000000..03c98d2ee9
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_texstate.c
@@ -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
index 0000000000..66720c1efc
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_tris.c
@@ -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
index 0000000000..ae4f0a5df5
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_tris.h
@@ -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
index 0000000000..a7ac054c23
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_vb.c
@@ -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
index 0000000000..523354465f
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/i830_vb.h
@@ -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
index 0000000000..3367bfc168
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/server/i830_common.h
@@ -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
index 0000000000..69a4f678d2
--- /dev/null
+++ b/src/mesa/drivers/dri/i830/server/i830_dri.h
@@ -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