summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkeithw <keithw>1999-12-14 00:23:48 +0000
committerkeithw <keithw>1999-12-14 00:23:48 +0000
commitaf51f10342876a5da08d550d7786ea310ceb40ab (patch)
treee797615662252b79ff6d9eb8f12582aadcecfb08
parente7adc714237383d89258f076a15ec93693d894e0 (diff)
A non functional 3d driver for i810
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h695
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810buf.c210
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810buf.h92
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810clear.c147
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810clear.h7
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810common.h38
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810context.c128
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810context.h128
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dd.c221
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dd.h49
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810depth.c737
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810depth.h82
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810direct.c647
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810direct.h22
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dma.c475
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dma.h138
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dmainit.c389
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810glx.c650
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810glx.h46
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810lib.c74
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810lib.h137
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810log.h56
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810pipeline.c120
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810pipeline.h10
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810span.c111
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810span.h6
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810state.c685
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810state.h11
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tex.c1144
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tex.h119
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tris.c303
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tris.h208
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tritmp.h199
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810vb.c444
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810vb.h117
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/mm.c264
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/mm.h103
37 files changed, 9012 insertions, 0 deletions
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h
new file mode 100644
index 000000000..677a35222
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h
@@ -0,0 +1,695 @@
+
+
+#ifndef I810_3D_REG_H
+#define I810_3D_REG_H
+
+#include "i810_reg.h"
+
+/* Registers not used in the X server
+ */
+
+#define I810_NOP_ID 0x2094
+#define I810_NOP_ID_MASK ((1<<22)-1)
+
+
+/* 3D instructions
+ */
+
+
+/* GFXRENDERSTATE_PV_PIXELIZATION_RULE, p149
+ *
+ * Format:
+ * 0: GFX_OP_PV_RULE | PV_*
+ *
+ */
+#define GFX_OP_PV_RULE ((0x3<<29)|(0x7<<24))
+#define PV_SMALL_TRI_FILTER_ENABLE (0x1<<11)
+#define PV_UPDATE_PIXRULE (0x1<<10)
+#define PV_PIXRULE_ENABLE (0x1<<9)
+#define PV_UPDATE_LINELIST (0x1<<8)
+#define PV_LINELIST_MASK (0x3<<6)
+#define PV_LINELIST_PV0 (0x0<<6)
+#define PV_LINELIST_PV1 (0x1<<6)
+#define PV_UPDATE_TRIFAN (0x1<<5)
+#define PV_TRIFAN_MASK (0x3<<3)
+#define PV_TRIFAN_PV0 (0x0<<3)
+#define PV_TRIFAN_PV1 (0x1<<3)
+#define PV_TRIFAN_PV2 (0x2<<3)
+#define PV_UPDATE_TRISTRIP (0x1<<2)
+#define PV_TRISTRIP_MASK (0x3<<0)
+#define PV_TRISTRIP_PV0 (0x0<<0)
+#define PV_TRISTRIP_PV1 (0x1<<0)
+#define PV_TRISTRIP_PV2 (0x2<<0)
+
+
+/* GFXRENDERSTATE_SCISSOR_ENABLE, p146
+ *
+ * Format:
+ * 0: GFX_OP_SCISSOR | SC_*
+ */
+#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
+#define SC_UPDATE_SCISSOR (0x1<<1)
+#define SC_ENABLE_MASK (0x1<<0)
+#define SC_ENABLE (0x1<<0)
+
+/* GFXRENDERSTATE_SCISSOR_INFO, p147
+ *
+ * Format:
+ * 0: GFX_OP_SCISSOR_INFO
+ * 1: SCI_MIN_*
+ * 2: SCI_MAX_*
+ */
+#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
+#define SCI_YMIN_MASK (0xffff<<16)
+#define SCI_XMIN_MASK (0xffff<<0)
+#define SCI_YMAX_MASK (0xffff<<16)
+#define SCI_XMAX_MASK (0xffff<<0)
+
+/* GFXRENDERSTATE_DRAWING_RECT_INFO, p144
+ *
+ * Format:
+ * 0: GFX_OP_DRAWRECT_INFO
+ * 1: DR1_*
+ * 2: DR2_*
+ * 3: DR3_*
+ * 4: DR4_*
+ */
+#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
+#define DR1_RECT_CLIP_ENABLE (0x1<<31)
+#define DR1_X_DITHER_BIAS_MASK (0x3<<26)
+#define DR1_X_DITHER_BIAS_SHIFT 26
+#define DR1_Y_DITHER_BIAS_MASK (0x3<<24)
+#define DR1_Y_DITHER_BIAS_SHIFT 24
+#define DR2_YMIN_MASK (0xffff<<16)
+#define DR2_XMIN_MASK (0xffff<<0)
+#define DR3_YMAX_MASK (0xffff<<16)
+#define DR3_XMAX_MASK (0xffff<<0)
+#define DR4_YORG_MASK (0x3ff<<16)
+#define DR4_XORG_MASK (0x7ff<<0)
+
+
+/* GFXRENDERSTATE_LINEWIDTH_CULL_SHADE_MODE, p140
+ *
+ * Format:
+ * 0: GFX_OP_LINEWIDTH_CULL_SHADE_MODE | LCS_*
+ */
+#define GFX_OP_LINEWIDTH_CULL_SHADE_MODE ((0x3<<29)|(0x2<<24))
+#define LCS_UPDATE_ZMODE (0x1<<20)
+#define LCS_Z_MASK (0xf<<16)
+#define LCS_Z_NEVER (0x1<<16)
+#define LCS_Z_LESS (0x2<<16)
+#define LCS_Z_EQUAL (0x3<<16)
+#define LCS_Z_LEQUAL (0x4<<16)
+#define LCS_Z_GREATER (0x5<<16)
+#define LCS_Z_NOTEQUAL (0x6<<16)
+#define LCS_Z_GEQUAL (0x7<<16)
+#define LCS_Z_ALWAYS (0x8<<16)
+#define LCS_UPDATE_LINEWIDTH (0x1<<15)
+#define LCS_LINEWIDTH_MASK (0x7<<12)
+#define LCS_LINEWIDTH_SHIFT 12
+#define LCS_UPDATE_ALPHA_INTERP (0x1<<11)
+#define LCS_ALPHA_FLAT (0x0<<10)
+#define LCS_ALPHA_INTERP (0x1<<10)
+#define LCS_UPDATE_FOG_INTERP (0x1<<9)
+#define LCS_FOG_INTERP (0x0<<8)
+#define LCS_FOG_FLAT (0x1<<8)
+#define LCS_UPDATE_SPEC_INTERP (0x1<<7)
+#define LCS_SPEC_INTERP (0x0<<6)
+#define LCS_SPEC_FLAT (0x1<<6)
+#define LCS_UPDATE_RGB_INTERP (0x1<<5)
+#define LCS_RGB_INTERP (0x0<<4)
+#define LCS_RGB_FLAT (0x1<<4)
+#define LCS_UPDATE_CULL_MODE (0x1<<3)
+#define LCS_CULL_MASK (0x7<<0)
+#define LCS_CULL_DISABLE (0x1<<0)
+#define LCS_CULL_CW (0x2<<0)
+#define LCS_CULL_CCW (0x3<<0)
+#define LCS_CULL_BOTH (0x4<<0)
+
+#define LCS_INTERP_FLAT (LCS_ALPHA_FLAT|LCS_RGB_FLAT|LCS_SPEC_FLAT)
+#define LCS_UPDATE_INTERP (LCS_UPDATE_ALPHA_INTERP| \
+ LCS_UPDATE_RGB_INTERP| \
+ LCS_UPDATE_SPEC_INTERP)
+
+
+/* GFXRENDERSTATE_BOOLEAN_ENA_1, p142
+ *
+ */
+#define GFX_OP_BOOL_1 ((0x3<<29)|(0x3<<24))
+#define B1_UPDATE_SPEC_SETUP_ENABLE (1<<19)
+#define B1_SPEC_SETUP_ENABLE (1<<18)
+#define B1_UPDATE_ALPHA_SETUP_ENABLE (1<<17)
+#define B1_ALPHA_SETUP_ENABLE (1<<16)
+#define B1_UPDATE_CI_KEY_ENABLE (1<<15)
+#define B1_CI_KEY_ENABLE (1<<14)
+#define B1_UPDATE_CHROMAKEY_ENABLE (1<<13)
+#define B1_CHROMAKEY_ENABLE (1<<12)
+#define B1_UPDATE_Z_BIAS_ENABLE (1<<11)
+#define B1_Z_BIAS_ENABLE (1<<10)
+#define B1_UPDATE_SPEC_ENABLE (1<<9)
+#define B1_SPEC_ENABLE (1<<8)
+#define B1_UPDATE_FOG_ENABLE (1<<7)
+#define B1_FOG_ENABLE (1<<6)
+#define B1_UPDATE_ALPHA_TEST_ENABLE (1<<5)
+#define B1_ALPHA_TEST_ENABLE (1<<4)
+#define B1_UPDATE_BLEND_ENABLE (1<<3)
+#define B1_BLEND_ENABLE (1<<2)
+#define B1_UPDATE_Z_TEST_ENABLE (1<<1)
+#define B1_Z_TEST_ENABLE (1<<0)
+
+/* GFXRENDERSTATE_BOOLEAN_ENA_2, p143
+ *
+ */
+#define GFX_OP_BOOL_2 ((0x3<<29)|(0x4<<24))
+#define B2_UPDATE_MAP_CACHE_ENABLE (1<<17)
+#define B2_MAP_CACHE_ENABLE (1<<16)
+#define B2_UPDATE_ALPHA_DITHER_ENABLE (1<<15)
+#define B2_ALPHA_DITHER_ENABLE (1<<14)
+#define B2_UPDATE_FOG_DITHER_ENABLE (1<<13)
+#define B2_FOG_DITHER_ENABLE (1<<12)
+#define B2_UPDATE_SPEC_DITHER_ENABLE (1<<11)
+#define B2_SPEC_DITHER_ENABLE (1<<10)
+#define B2_UPDATE_RGB_DITHER_ENABLE (1<<9)
+#define B2_RGB_DITHER_ENABLE (1<<8)
+#define B2_UPDATE_FB_WRITE_ENABLE (1<<3)
+#define B2_FB_WRITE_ENABLE (1<<2)
+#define B2_UPDATE_ZB_WRITE_ENABLE (1<<1)
+#define B2_ZB_WRITE_ENABLE (1<<0)
+
+
+/* GFXRENDERSTATE_FOG_COLOR, p144
+ */
+#define GFX_OP_FOG_COLOR ((0x3<<29)|(0x15<<24))
+#define FOG_RED_SHIFT 16
+#define FOG_GREEN_SHIFT 8
+#define FOG_BLUE_SHIFT 0
+#define FOG_RESERVED_MASK ((0x7<<16)|(0x3<<8)|(0x3))
+
+
+/* GFXRENDERSTATE_Z_BIAS_ALPHA_FUNC_REF, p139
+ */
+#define GFX_OP_ZBIAS_ALPHAFUNC ((0x3<<29)|(0x14<<24))
+#define ZA_UPDATE_ZBIAS (1<<22)
+#define ZA_ZBIAS_SHIFT 14
+#define ZA_ZBIAS_MASK (0xff<<14)
+#define ZA_UPDATE_ALPHAFUNC (1<<13)
+#define ZA_ALPHA_MASK (0xf<<9)
+#define ZA_ALPHA_NEVER (1<<9)
+#define ZA_ALPHA_LESS (2<<9)
+#define ZA_ALPHA_EQUAL (3<<9)
+#define ZA_ALPHA_LEQUAL (4<<9)
+#define ZA_ALPHA_GREATER (5<<9)
+#define ZA_ALPHA_NOTEQUAL (6<<9)
+#define ZA_ALPHA_GEQUAL (7<<9)
+#define ZA_ALPHA_ALWAYS (8<<9)
+#define ZA_UPDATE_ALPHAREF (1<<8)
+#define ZA_ALPHAREF_MASK (0xff<<0)
+#define ZA_ALPHAREF_SHIFT 0
+#define ZA_ALPHAREF_RESERVED (0x7<<0)
+
+
+/* GFXRENDERSTATE_SRC_DST_BLEND_MONO, p136
+ */
+#define GFX_OP_SRC_DEST_MONO ((0x3<<29)|(0x8<<24))
+#define SDM_UPDATE_MONO_ENABLE (1<<13)
+#define SDM_MONO_ENABLE (1<<12)
+#define SDM_UPDATE_SRC_BLEND (1<<11)
+#define SDM_SRC_MASK (0xf<<6)
+#define SDM_SRC_ZERO (0x1<<6)
+#define SDM_SRC_ONE (0x2<<6)
+#define SDM_SRC_SRC_COLOR (0x3<<6)
+#define SDM_SRC_INV_SRC_COLOR (0x4<<6)
+#define SDM_SRC_SRC_ALPHA (0x5<<6)
+#define SDM_SRC_INV_SRC_ALPHA (0x6<<6)
+#define SDM_SRC_DST_COLOR (0x9<<6)
+#define SDM_SRC_INV_DST_COLOR (0xa<<6)
+#define SDM_SRC_BOTH_SRC_ALPHA (0xc<<6)
+#define SDM_SRC_BOTH_INV_SRC_ALPHA (0xd<<6)
+#define SDM_UPDATE_DST_BLEND (1<<5)
+#define SDM_DST_MASK (0xf<<0)
+#define SDM_DST_ZERO (0x1<<0)
+#define SDM_DST_ONE (0x2<<0)
+#define SDM_DST_SRC_COLOR (0x3<<0)
+#define SDM_DST_INV_SRC_COLOR (0x4<<0)
+#define SDM_DST_SRC_ALPHA (0x5<<0)
+#define SDM_DST_INV_SRC_ALPHA (0x6<<0)
+#define SDM_DST_DST_COLOR (0x9<<0)
+#define SDM_DST_INV_DST_COLOR (0xa<<0)
+#define SDM_DST_BOTH_SRC_ALPHA (0xc<<0)
+#define SDM_DST_BOTH_INV_SRC_ALPHA (0xd<<0)
+
+/* GFXRENDERSTATE_COLOR_CHROMA_KEY, p135
+ */
+#define GFX_OP_COLOR_CHROMA_KEY ((0x3<<29)|(0x1d<<24)|(0x2<<16)|0x1)
+#define CC1_UPDATE_CC_TEST_ENABLE (1<<28)
+#define CC1_CC_TEST_ENABLE (1<<27)
+#define CC1_UPDATE_CI_VALUE (1<<26)
+#define CC1_UPDATE_CK_LOW_VALUE (1<<25)
+#define CC1_UPDATE_CK_HI_VALUE (1<<24)
+#define CC1_CK_LOW_VALUE_MASK ((1<<24)-1)
+#define CC2_CI_VALUE_MASK (0xff<<24)
+#define CC2_CI_VALUE_SHIFT 24
+#define CC2_CK_HIGH_VALUE_MASK ((1<<24)-1)
+
+/* GFXRENDERSTATE_COLOR_FACTOR, p134
+ *
+ * Format:
+ * 0: GFX_OP_COLOR_FACTOR
+ * 1: ARGB8888 color factor
+ */
+#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
+
+/* GFXRENDERSTATE_MAP_ALPHA_BLEND_STAGES, p132
+ */
+#define GFX_OP_MAP_ALPHA_STAGES ((0x3<<29)|(0x1<<24))
+#define MA_STAGE_SHIFT 20
+#define MA_STAGE_0 (0<<20)
+#define MA_STAGE_1 (1<<20)
+#define MA_STAGE_2 (2<<20)
+#define MA_UPDATE_ARG1 (1<<18)
+#define MA_ARG1_MASK ((0x7<<15)|(0x1<<13))
+#define MA_ARG1_ALPHA_FACTOR (0x1<<15)
+#define MA_ARG1_ITERATED_ALPHA (0x3<<15)
+#define MA_ARG1_CURRENT_ALPHA (0x5<<15)
+#define MA_ARG1_TEX0_ALPHA (0x6<<15)
+#define MA_ARG1_TEX1_ALPHA (0x7<<15)
+#define MA_ARG1_INVERT (0x1<<13)
+#define MA_ARG1_DONT_INVERT (0x0<<13)
+#define MA_UPDATE_ARG2 (1<<12)
+#define MA_ARG2_MASK ((0x7<<8)|(0x1<<6))
+#define MA_ARG2_ALPHA_FACTOR (0x1<<8)
+#define MA_ARG2_ITERATED_ALPHA (0x3<<8)
+#define MA_ARG2_CURRENT_ALPHA (0x5<<8)
+#define MA_ARG2_TEX0_ALPHA (0x6<<8)
+#define MA_ARG2_TEX1_ALPHA (0x7<<8)
+#define MA_ARG2_INVERT (0x1<<6)
+#define MA_ARG2_DONT_INVERT (0x0<<6)
+#define MA_UPDATE_OP (1<<5)
+#define MA_OP_MASK (0xf)
+#define MA_OP_ARG1 (0x1)
+#define MA_OP_ARG2 (0x2)
+#define MA_OP_MODULATE (0x3)
+#define MA_OP_MODULATE_X2 (0x4)
+#define MA_OP_MODULATE_X4 (0x5)
+#define MA_OP_ADD (0x6)
+#define MA_OP_ADD_SIGNED (0x7)
+#define MA_OP_LIN_BLEND_ITER_ALPHA (0x8)
+#define MA_OP_LIN_BLEND_ALPHA_FACTOR (0xa)
+#define MA_OP_LIN_BLEND_TEX0_ALPHA (0x10)
+#define MA_OP_LIN_BLEND_TEX1_ALPHA (0x11)
+
+
+/* GFXRENDERSTATE_MAP_COLOR_BLEND_STAGES, p129
+ */
+#define GFX_OP_MAP_COLOR_STAGES ((0x3<<29)|(0x0<<24))
+#define MC_STAGE_SHIFT 20
+#define MC_STAGE_0 (0<<20)
+#define MC_STAGE_1 (1<<20)
+#define MC_STAGE_2 (2<<20)
+#define MC_UPDATE_DEST (1<<19)
+#define MC_DEST_MASK (1<<18)
+#define MC_DEST_CURRENT (0<<18)
+#define MC_DEST_ACCUMULATOR (1<<18)
+#define MC_UPDATE_ARG1 (1<<17)
+#define MC_ARG1_MASK ((0x7<<14)|(0x1<<13)|(0x1<<12))
+#define MC_ARG1_ONE (0x0<<14)
+#define MC_ARG1_COLOR_FACTOR (0x1<<14)
+#define MC_ARG1_ACCUMULATOR (0x2<<14)
+#define MC_ARG1_ITERATED_COLOR (0x3<<14)
+#define MC_ARG1_SPECULAR_COLOR (0x4<<14)
+#define MC_ARG1_CURRENT_COLOR (0x5<<14)
+#define MC_ARG1_TEX0_COLOR (0x6<<14)
+#define MC_ARG1_TEX1_COLOR (0x7<<14)
+#define MC_ARG1_DONT_REPLICATE_ALPHA (0x0<<13)
+#define MC_ARG1_REPLICATE_ALPHA (0x1<<13)
+#define MC_ARG1_DONT_INVERT (0x0<<12)
+#define MC_ARG1_INVERT (0x1<<12)
+#define MC_UPDATE_ARG2 (1<<11)
+#define MC_ARG2_MASK ((0x7<<8)|(0x1<<7)|(0x1<<6))
+#define MC_ARG2_ONE (0x0<<8)
+#define MC_ARG2_COLOR_FACTOR (0x1<<8)
+#define MC_ARG2_ACCUMULATOR (0x2<<8)
+#define MC_ARG2_ITERATED_COLOR (0x3<<8)
+#define MC_ARG2_SPECULAR_COLOR (0x4<<8)
+#define MC_ARG2_CURRENT_COLOR (0x5<<8)
+#define MC_ARG2_TEX0_COLOR (0x6<<8)
+#define MC_ARG2_TEX1_COLOR (0x7<<8)
+#define MC_ARG2_DONT_REPLICATE_ALPHA (0x0<<7)
+#define MC_ARG2_REPLICATE_ALPHA (0x1<<7)
+#define MC_ARG2_DONT_INVERT (0x0<<6)
+#define MC_ARG2_INVERT (0x1<<6)
+#define MC_UPDATE_OP (1<<5)
+#define MC_OP_MASK (0xf)
+#define MC_OP_DISABLE (0x0)
+#define MC_OP_ARG1 (0x1)
+#define MC_OP_ARG2 (0x2)
+#define MC_OP_MODULATE (0x3)
+#define MC_OP_MODULATE_X2 (0x4)
+#define MC_OP_MODULATE_X4 (0x5)
+#define MC_OP_ADD (0x6)
+#define MC_OP_ADD_SIGNED (0x7)
+#define MC_OP_LIN_BLEND_ITER_ALPHA (0x8)
+#define MC_OP_LIN_BLEND_ALPHA_FACTOR (0xa)
+#define MC_OP_LIN_BLEND_TEX0_ALPHA (0x10)
+#define MC_OP_LIN_BLEND_TEX1_ALPHA (0x11)
+#define MC_OP_LIN_BLEND_TEX0_COLOR (0x12)
+#define MC_OP_LIN_BLEND_TEX1_COLOR (0x13)
+#define MC_OP_SUBTRACT (0x14)
+
+/* GFXRENDERSTATE_MAP_PALETTE_LOAD, p128
+ *
+ * Format:
+ * 0: GFX_OP_MAP_PALETTE_LOAD
+ * 1: 16bpp color[0]
+ * ...
+ * 256: 16bpp color[255]
+ */
+#define GFX_OP_MAP_PALETTE_LOAD ((0x3<<29)|(0x1d<<24)|(0x82<<16)|0xff)
+
+/* GFXRENDERSTATE_MAP_LOD_CONTROL, p127
+ */
+#define GFX_OP_MAP_LOD_CTL ((0x3<<29)|(0x1c<<24)|(0x4<<19))
+#define MLC_MAP_ID_SHIFT 16
+#define MLC_MAP_0 (0<<16)
+#define MLC_MAP_1 (1<<16)
+#define MLC_UPDATE_DITHER_WEIGHT (1<<10)
+#define MLC_DITHER_WEIGHT_MASK (0x3<<8)
+#define MLC_DITHER_WEIGHT_FULL (0x0<<8)
+#define MLC_DITHER_WEIGHT_50 (0x1<<8)
+#define MLC_DITHER_WEIGHT_25 (0x2<<8)
+#define MLC_DITHER_WEIGHT_12 (0x3<<8)
+#define MLC_UPDATE_LOD_BIAS (1<<7)
+#define MLC_LOD_BIAS_MASK ((1<<7)-1)
+
+/* GFXRENDERSTATE_MAP_LOD_LIMITS, p126
+ */
+#define GFX_OP_MAP_LOD_LIMITS ((0x3<<29)|(0x1c<<24)|(0x3<<19))
+#define MLL_MAP_ID_SHIFT 16
+#define MLL_MAP_0 (0<<16)
+#define MLL_MAP_1 (1<<16)
+#define MLL_UPDATE_MAX_MIP (1<<13)
+#define MLL_MAX_MIP_SHIFT 5
+#define MLL_MAX_MIP_MASK (0xff<<5)
+#define MLL_MAX_MIP_ONE (0x10<<5)
+#define MLL_UPDATE_MIN_MIP (1<<4)
+#define MLL_MIN_MIP_SHIFT 0
+#define MLL_MIN_MIP_MASK (0xf<<0)
+
+/* GFXRENDERSTATE_MAP_FILTER, p124
+ */
+#define GFX_OP_MAP_FILTER ((0x3<<29)|(0x1c<<24)|(0x2<<19))
+#define MF_MAP_ID_SHIFT 16
+#define MF_MAP_0 (0<<16)
+#define MF_MAP_1 (1<<16)
+#define MF_UPDATE_ANISOTROPIC (1<<12)
+#define MF_ANISOTROPIC_MASK (1<<10)
+#define MF_ANISOTROPIC_ENABLE (1<<10)
+#define MF_UPDATE_MIP_FILTER (1<<9)
+#define MF_MIP_MASK (0x3<<6)
+#define MF_MIP_NONE (0x0<<6)
+#define MF_MIP_NEAREST (0x1<<6)
+#define MF_MIP_DITHER (0x2<<6)
+#define MF_UPDATE_MAG_FILTER (1<<5)
+#define MF_MAG_MASK (1<<3)
+#define MF_MAG_LINEAR (1<<3)
+#define MF_MAG_NEAREST (0<<3)
+#define MF_UPDATE_MIN_FILTER (1<<2)
+#define MF_MIN_MASK (1<<0)
+#define MF_MIN_LINEAR (1<<0)
+#define MF_MIN_NEAREST (0<<0)
+
+/* GFXRENDERSTATE_MAP_INFO, p118
+ */
+#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x2)
+#define MI1_MAP_ID_SHIFT 28
+#define MI1_MAP_0 (0<<28)
+#define MI1_MAP_1 (1<<28)
+#define MI1_FMT_MASK (0x7<<24)
+#define MI1_FMT_8CI (0x0<<24)
+#define MI1_FMT_8BPP (0x1<<24)
+#define MI1_FMT_16BPP (0x2<<24)
+#define MI1_FMT_422 (0x5<<24)
+#define MI1_PF_MASK (0x3<<21)
+#define MI1_PF_8CI_RGB565 (0x0<<21)
+#define MI1_PF_8CI_ARGB1555 (0x1<<21)
+#define MI1_PF_8CI_ARGB4444 (0x2<<21)
+#define MI1_PF_8CI_AY88 (0x3<<21)
+#define MI1_PF_16BPP_RGB565 (0x0<<21)
+#define MI1_PF_16BPP_ARGB1555 (0x1<<21)
+#define MI1_PF_16BPP_ARGB4444 (0x2<<21)
+#define MI1_PF_16BPP_AY88 (0x3<<21)
+#define MI1_PF_422_YCRCB_SWAP_Y (0x0<<21)
+#define MI1_PF_422_YCRCB (0x1<<21)
+#define MI1_PF_422_YCRCB_SWAP_UV (0x2<<21)
+#define MI1_PF_422_YCRCB_SWAP_YUV (0x3<<21)
+#define MI1_OUTPUT_CHANNEL_MASK (0x3<<19)
+#define MI1_COLOR_CONV_ENABLE (1<<18)
+#define MI1_VERT_STRIDE_MASK (1<<17)
+#define MI1_VERT_STRIDE_1 (1<<17)
+#define MI1_VERT_OFFSET_MASK (1<<16)
+#define MI1_VERT_OFFSET_1 (1<<16)
+#define MI1_ENABLE_FENCE_REGS (1<<10)
+#define MI1_TILED_SURFACE (1<<9)
+#define MI1_TILE_WALK_X (0<<8)
+#define MI1_TILE_WALK_Y (1<<8)
+#define MI1_PITCH_MASK (0xf<<0)
+#define MI2_DIMENSIONS_ARE_LOG2 (1<<31)
+#define MI2_DIMENSIONS_ARE_EXACT (0<<31)
+#define MI2_HEIGHT_SHIFT 16
+#define MI2_HEIGHT_MASK (0x1ff<<16)
+#define MI2_WIDTH_SHIFT 0
+#define MI2_WIDTH_MASK (0x1ff<<0)
+#define MI3_BASE_ADDR_MASK (~0xf)
+
+/* GFXRENDERSTATE_MAP_COORD_SETS, p116
+ */
+#define GFX_OP_MAP_COORD_SETS ((0x3<<29)|(0x1c<<24)|(0x1<<19))
+#define MCS_COORD_ID_SHIFT 16
+#define MCS_COORD_0 (0<<16)
+#define MCS_COORD_1 (1<<16)
+#define MCS_UPDATE_NORMALIZED (1<<15)
+#define MCS_NORMALIZED_COORDS_MASK (1<<14)
+#define MCS_NORMALIZED_COORDS (1<<14)
+#define MCS_UPDATE_V_STATE (1<<7)
+#define MCS_V_STATE_MASK (0x3<<4)
+#define MCS_V_WRAP (0x0<<4)
+#define MCS_V_MIRROR (0x1<<4)
+#define MCS_V_CLAMP (0x2<<4)
+#define MCS_V_WRAP_SHORTEST (0x3<<4)
+#define MCS_UPDATE_U_STATE (1<<3)
+#define MCS_U_STATE_MASK (0x3<<0)
+#define MCS_U_WRAP (0x0<<0)
+#define MCS_U_MIRROR (0x1<<0)
+#define MCS_U_CLAMP (0x2<<0)
+#define MCS_U_WRAP_SHORTEST (0x3<<0)
+
+/* GFXRENDERSTATE_MAP_TEXELS, p115
+ */
+#define GFX_OP_MAP_TEXELS ((0x3<<29)|(0x1c<<24)|(0x0<<19))
+#define MT_UPDATE_TEXEL1_STATE (1<<15)
+#define MT_TEXEL1_DISABLE (0<<14)
+#define MT_TEXEL1_ENABLE (1<<14)
+#define MT_TEXEL1_COORD0 (0<<11)
+#define MT_TEXEL1_COORD1 (1<<11)
+#define MT_TEXEL1_MAP0 (0<<8)
+#define MT_TEXEL1_MAP1 (1<<8)
+#define MT_UPDATE_TEXEL0_STATE (1<<7)
+#define MT_TEXEL0_DISABLE (0<<6)
+#define MT_TEXEL0_ENABLE (1<<6)
+#define MT_TEXEL0_COORD0 (0<<3)
+#define MT_TEXEL0_COORD1 (1<<3)
+#define MT_TEXEL0_MAP0 (0<<0)
+#define MT_TEXEL0_MAP1 (1<<0)
+
+/* GFXRENDERSTATE_VERTEX_FORMAT, p110
+ */
+#define GFX_OP_VERTEX_FMT ((0x3<<29)|(0x5<<24))
+#define VF_TEXCOORD_COUNT_SHIFT 8
+#define VF_TEXCOORD_COUNT_0 (0<<8)
+#define VF_TEXCOORD_COUNT_1 (1<<8)
+#define VF_TEXCOORD_COUNT_2 (2<<8)
+#define VF_SPEC_FOG_ENABLE (1<<7)
+#define VF_RGBA_ENABLE (1<<6)
+#define VF_Z_OFFSET_ENABLE (1<<5)
+#define VF_XYZ (0x1<<1)
+#define VF_XYZW (0x2<<1)
+#define VF_XY (0x3<<1)
+#define VF_XYW (0x4<<1)
+
+
+#define VERT_X_MASK (~0xf)
+#define VERT_X_EDGE_V2V0 (1<<2)
+#define VERT_X_EDGE_V1V2 (1<<1)
+#define VERT_X_EDGE_V0V1 (1<<0)
+
+/* Not enabled fields should not be sent to hardware:
+ */
+typedef struct {
+ union {
+ float x;
+ unsigned int edge_flags;
+ } x;
+ float y;
+ float z;
+ float z_bias;
+ float oow;
+ unsigned int argb;
+ unsigned int fog_spec_rgb; /* spec g and r ignored. */
+ float tu0;
+ float tv0;
+ float tu1;
+ float tv1;
+} i810_full_vertex;
+
+
+/* GFX_PRIMITIVE, p106
+ */
+#define GFX_OP_PRIMITIVE ((0x3<<29)|(0x1f<<24))
+#define PR_TRIANGLES (0x0<<18)
+#define PR_TRISTRIP_0 (0x1<<18)
+#define PR_TRISTRIP_1 (0x2<<18)
+#define PR_TRIFAN (0x3<<18)
+#define PR_POLYGON (0x4<<18)
+#define PR_LINES (0x5<<18)
+#define PR_LINESTRIP (0x6<<18)
+#define PR_RECTS (0x7<<18)
+#define PR_DWORD_COUNT_SHIFT 0
+
+/* GFXCMDPARSER_BATCH_BUFFER, p105
+ *
+ * Not clear whether start address must be shifted or not. Not clear
+ * whether address is physical system memory, or subject to GTT
+ * translation. Because the address appears to be 32 bits long,
+ * perhaps it refers to physical system memory...
+ */
+#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
+#define BB1_START_ADDR_MASK (~0x7)
+#define BB1_PROTECTED (1<<0)
+#define BB1_UNPROTECTED (0<<0)
+#define BB2_END_ADDR_MASK (~0x7)
+
+/* Hardware seems to barf on buffers larger than this (in strange ways)...
+ */
+#define MAX_BATCH (512*1024)
+
+
+/* GFXCMDPARSER_Z_BUFFER_INFO, p98
+ *
+ * Base address is in GTT space, and must be 4K aligned
+ */
+#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23))
+#define ZB_BASE_ADDR_SHIFT 0
+#define ZB_BASE_ADDR_MASK (~((1<<12)-1))
+#define ZB_PITCH_512B (0x0<<0)
+#define ZB_PITCH_1K (0x1<<0)
+#define ZB_PITCH_2K (0x2<<0)
+#define ZB_PITCH_4K (0x3<<0)
+
+/* GFXCMDPARSER_FRONT_BUFFER_INFO, p97
+ *
+ * Format:
+ * 0: CMD_OP_FRONT_BUFFER_INFO | (pitch<<FB0_PITCH_SHIFT) | FB0_*
+ * 1: FB1_*
+ */
+#define CMD_OP_FRONT_BUFFER_INFO ((0x0<<29)|(0x14<<23))
+#define FB0_PITCH_SHIFT 8
+#define FB0_FLIP_SYNC (0<<6)
+#define FB0_FLIP_ASYNC (1<<6)
+#define FB0_BASE_ADDR_SHIFT 0
+#define FB0_BASE_ADDR_MASK 0x03FFFFF8
+
+/* GFXCMDPARSER_DEST_BUFFER_INFO, p96
+ *
+ * Format:
+ */
+#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23))
+#define DB1_BASE_ADDR_SHIFT 0
+#define DB1_BASE_ADDR_MASK 0x03FFF000
+#define DB1_PITCH_512B (0x0<<0)
+#define DB1_PITCH_1K (0x1<<0)
+#define DB1_PITCH_2K (0x2<<0)
+#define DB1_PITCH_4K (0x4<<0)
+
+
+/* GFXRENDERSTATE_DEST_BUFFER_VARIABLES, p152
+ *
+ * Format:
+ * 0: GFX_OP_DESTBUFFER_VARS
+ * 1: DEST_*
+ */
+#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
+#define DV_HORG_BIAS_MASK (0xf<<20)
+#define DV_HORG_BIAS_OGL (0x0<<20)
+#define DV_VORG_BIAS_MASK (0xf<<16)
+#define DV_VORG_BIAS_OGL (0x0<<16)
+#define DV_PF_MASK (0x7<<8)
+#define DV_PF_INDEX (0x0<<8)
+#define DV_PF_555 (0x1<<8)
+#define DV_PF_565 (0x2<<8)
+
+
+/* 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 (includes zbuffer). Drawrect is the only thing
+ * that needs to be restored for 2d???
+ */
+#define I810_DESTREG_DI0 0 /* CMD_OP_DESTBUFFER_INFO (2 dwords) */
+#define I810_DESTREG_DI1 1
+#define I810_DESTREG_ZB0 2 /* CMD_OP_Z_BUFFER_INFO */
+#define I810_DESTREG_ZB1 3 /* CMD_OP_Z_BUFFER_INFO */
+#define I810_DESTREG_DV0 4 /* GFX_OP_DESTBUFFER_VARS (2 dwords) */
+#define I810_DESTREG_DV1 5
+#define I810_DESTREG_DR0 6 /* GFX_OP_DRAWRECT_INFO (4 dwords) */
+#define I810_DESTREG_DR1 7
+#define I810_DESTREG_DR2 8
+#define I810_DESTREG_DR3 9
+#define I810_DESTREG_DR4 10
+
+#define I810_DEST_SETUP_SIZE (11+1)
+
+/* Context state
+ */
+#define I810_CTXREG_VF 0 /* GFX_OP_VERTEX_FMT */
+#define I810_CTXREG_MT 1 /* GFX_OP_MAP_TEXELS */
+#define I810_CTXREG_MC0 2 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */
+#define I810_CTXREG_MC1 3 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */
+#define I810_CTXREG_MC2 4 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */
+#define I810_CTXREG_MA0 5 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */
+#define I810_CTXREG_MA1 6 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */
+#define I810_CTXREG_MA2 7 /* GFX_OP_MAP_ALPHA_STAGES - stage 2 */
+#define I810_CTXREG_SDM 8 /* GFX_OP_SRC_DEST_MONO */
+#define I810_CTXREG_CF0 9 /* GFX_OP_COLOR_FACTOR */
+#define I810_CTXREG_CF1 10
+#define I810_CTXREG_FOG 11 /* GFX_OP_FOG_COLOR */
+#define I810_CTXREG_B1 12 /* GFX_OP_BOOL_1 */
+#define I810_CTXREG_B2 13 /* GFX_OP_BOOL_2 */
+#define I810_CTXREG_LCS 14 /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */
+#define I810_CTXREG_SCI0 15 /* GFX_OP_SCISSOR_INFO (3 dwords) */
+#define I810_CTXREG_SCI1 16
+#define I810_CTXREG_SCI2 17
+#define I810_CTXREG_SC 18 /* GFX_OP_SCISSOR */
+#define I810_CTXREG_PV 19 /* GFX_OP_PV_RULE -- Invarient! */
+#define I810_CTXREG_ZA 20 /* GFX_OP_ZBIAS_ALPHAFUNC */
+
+#define I810_CTX_SETUP_SIZE (21+1) /* pad to qword */
+
+/* Texture state (per tex_buffer)
+ */
+#define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */
+#define I810_TEXREG_MI1 1
+#define I810_TEXREG_MI2 2
+#define I810_TEXREG_MI3 3
+#define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */
+#define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */
+#define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */
+#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */
+
+#define I810_TEX_SETUP_SIZE 8
+
+
+#define I810_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810buf.c b/xc/lib/GL/mesa/src/drv/i810/i810buf.c
new file mode 100644
index 000000000..e5b607851
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810buf.c
@@ -0,0 +1,210 @@
+/*
+ * GLX Hardware Device Driver for Intel 810
+ * 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.
+ *
+ * Based on matrox driver by
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ */
+
+/* $Id: i810buf.c,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+#include <stdlib.h>
+#include "vga.h"
+#include "i810lib.h"
+#include "simple_list.h"
+#include "i810_3d_reg.h"
+
+
+struct { int pitch; CARD32 bits; } i810_dest_pitch[] = {
+ { 512, 0x0 },
+ { 1024, 0x1 },
+ { 2048, 0x2 },
+ { 4096, 0x3 }
+};
+
+struct i810_dest_buffer *i810CreateDestBuffer(int Format, int Width,
+ int Height)
+{
+ struct i810_dest_buffer *buf;
+ int ofs, i;
+ GLuint pitch_bits;
+
+ buf = CALLOC_STRUCT(i810_dest_buffer);
+ if (!buf) return 0;
+
+ buf->Format = Format;
+
+ switch (Format) {
+ case DV_PF_INDEX:
+ buf->BytesPerPixel = 1;
+ FatalError("wrong");
+ break;
+ case DV_PF_565:
+ buf->BytesPerPixel = 2;
+ break;
+ case DV_PF_555:
+ buf->BytesPerPixel = 2;
+ FatalError("wrong");
+ break;
+ default:
+ FatalError("wrong");
+ return 0;
+ }
+
+ for (i = 0 ; i < Elements(i810_dest_pitch) ; i++)
+ if (Width * buf->BytesPerPixel < i810_dest_pitch[i].pitch) {
+ pitch_bits = i810_dest_pitch[i].bits;
+ buf->Pitch = i810_dest_pitch[i].pitch;
+ break;
+ }
+
+ if (i == Elements(i810_dest_pitch)) {
+ free(buf);
+ return 0;
+ }
+
+ buf->Height = Height;
+ buf->Width = Width;
+ buf->Drawable = 1; /* wtf */
+
+ buf->MemBlock = mmAllocMem( i810glx.sysmemHeap,
+ buf->Pitch*buf->Height,
+ 12, 0);
+
+ if (!buf->MemBlock) {
+ free(buf);
+ return 0;
+ }
+
+ ofs = buf->MemBlock->ofs;
+
+ buf->Setup[I810_DESTREG_DI0] = CMD_OP_DESTBUFFER_INFO;
+ buf->Setup[I810_DESTREG_DI1] = (ofs & DB1_BASE_ADDR_MASK) | pitch_bits;
+ buf->Setup[I810_DESTREG_DV0] = GFX_OP_DESTBUFFER_VARS;
+ buf->Setup[I810_DESTREG_DV1] = (DV_HORG_BIAS_OGL |
+ DV_VORG_BIAS_OGL |
+ Format);
+
+ buf->Setup[I810_DESTREG_DR0] = GFX_OP_DRAWRECT_INFO;
+ buf->Setup[I810_DESTREG_DR1] = ( 0
+ | DR1_RECT_CLIP_ENABLE
+ );
+ buf->Setup[I810_DESTREG_DR2] = 0;
+ buf->Setup[I810_DESTREG_DR3] = ( 0
+ | ((Height-1)<<16)|(Width-1)
+ );
+ buf->Setup[I810_DESTREG_DR4] = 0;
+
+ buf->Setup[I810_DESTREG_ZB0] = 0;
+ buf->Setup[I810_DESTREG_ZB1] = 0;
+
+
+ buf->BufAddr = vgaLinearBase + ofs;
+/* mmMarkReserved(buf->MemBlock); */
+ return buf;
+}
+
+
+void i810DestroyDestBuffer(struct i810_dest_buffer *buf)
+{
+ if (buf->ZBuffer) {
+ i810FreeZBuffer( buf->ZBuffer );
+ buf->ZBuffer = 0;
+ }
+
+ if (mmFreeMem(buf->MemBlock) == -1) {
+ ErrorF("Could not free dest buffer %08x\n",buf->MemBlock->ofs);
+ FatalError("memory problem\n");
+ }
+
+ free(buf);
+}
+
+
+
+/* Create and attach a zbuffer to the parent buffer. Put setup instructions
+ * into the parent->Setup field.
+ */
+struct i810_z_buffer *i810CreateZBuffer(struct i810_dest_buffer *parent)
+{
+ struct i810_z_buffer *zb;
+ int bytesPerPixel = 2;
+ int i, pitch_bits, size;
+
+ /* Catch this earlier */
+ if (parent->ZBuffer) {
+ i810FreeZBuffer(parent->ZBuffer);
+ parent->ZBuffer = 0;
+ }
+
+ zb = CALLOC_STRUCT(i810_z_buffer);
+ if (!zb)
+ return 0;
+
+ for (i = 0 ; i < Elements(i810_dest_pitch) ; i++)
+ if (parent->Width * bytesPerPixel < i810_dest_pitch[i].pitch) {
+ pitch_bits = i810_dest_pitch[i].bits;
+ zb->Pitch = i810_dest_pitch[i].pitch;
+ break;
+ }
+
+ if (i == Elements(i810_dest_pitch)) {
+ free(zb);
+ return 0;
+ }
+
+ size = zb->Pitch * parent->Height;
+
+
+ /* Try to allocate it in dcache if possible, else use system memory.
+ */
+ if ( !(zb->MemBlock = mmAllocMem( i810glx.cardHeap, size, 12, 0 )) &&
+ !(zb->MemBlock = mmAllocMem( i810glx.sysmemHeap, size, 12, 0 ))) {
+ free(zb);
+ return 0;
+ }
+
+ zb->BufAddr = i810glx.sysmemVirtual + zb->MemBlock->ofs;
+
+ parent->Setup[I810_DESTREG_ZB0] = CMD_OP_Z_BUFFER_INFO;
+ parent->Setup[I810_DESTREG_ZB1] = (((zb->MemBlock->ofs)&ZB_BASE_ADDR_MASK) |
+ pitch_bits);
+
+
+ if (parent == i810DB)
+ i810DmaExecute( i810DB->Setup, I810_DEST_SETUP_SIZE );
+
+ parent->ZBuffer = zb;
+
+ return zb;
+}
+
+void i810FreeZBuffer(struct i810_z_buffer *buf)
+{
+ if (mmFreeMem(buf->MemBlock) == -1) {
+ ErrorF("Could not free z buffer %08x\n",buf->MemBlock->ofs);
+ FatalError("memory problem\n");
+ }
+
+ free(buf);
+}
+
+
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810buf.h b/xc/lib/GL/mesa/src/drv/i810/i810buf.h
new file mode 100644
index 000000000..a25ba9903
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810buf.h
@@ -0,0 +1,92 @@
+/*
+ * GLX Hardware Device Driver for Intel 810
+ * 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.
+ *
+ * Keith Whitwell <keithw@precisioninsight.com>
+ *
+ * based on matrox driver by
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ * and others.
+ */
+
+/* $Id: i810buf.h,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+#ifndef I810BUF_INC
+#define I810BUF_INC
+
+#include "i810common.h"
+#include "i810_3d_reg.h"
+#include "types.h"
+#include "mm.h"
+
+#define VALID_I810_BUFFER(b) (b)
+
+
+struct i810_dest_buffer
+{
+ int refcount;
+ PMemBlock MemBlock;
+ GLuint Setup[I810_DEST_SETUP_SIZE];
+
+ int Format;
+ int Width; /* in pixels */
+ int Height;
+ int Pitch;
+ int BytesPerPixel;
+ int Size;
+ int Drawable;
+ char *BufAddr;
+ struct i810_z_buffer *ZBuffer;
+};
+
+struct i810_z_buffer
+{
+ int refcount;
+ PMemBlock MemBlock;
+
+ int Format;
+ char *BufAddr;
+
+ int Pitch;
+};
+
+
+
+/* Don't bother trying to hide the differences between these types of
+ * buffer.
+ */
+struct i810_dest_buffer *i810CreateDestBuffer(int Format,
+ int Width,
+ int Height);
+void i810DestroyDestBuffer(struct i810_dest_buffer *buf);
+
+
+
+/* Parent is a dest-buffer, supplies geometry info.
+ */
+struct i810_z_buffer *i810CreateZBuffer( struct i810_dest_buffer *parent );
+void i810FreeZBuffer(struct i810_z_buffer *buf);
+
+
+
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810clear.c b/xc/lib/GL/mesa/src/drv/i810/i810clear.c
new file mode 100644
index 000000000..a621922f7
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810clear.c
@@ -0,0 +1,147 @@
+
+
+#include "xsmesaP.h"
+#include "mesaglx/types.h"
+#include "vbrender.h"
+#include "glx_log.h"
+
+#include "vga.h"
+#include "vgaPCI.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mm.h"
+#include "i810lib.h"
+#include "i810dd.h"
+#include "i810glx.h"
+#include "i810clear.h"
+#include "i810state.h"
+#include "i810tris.h"
+
+
+
+/*
+ * i810Clear
+ * perform hardware accelerated clearing of the color and/or depth
+ * buffer. Software may still clear stencil buffers.
+ * If all==GL_TRUE, clear whole buffer, else just clear region defined
+ * by x,y,width,height
+ */
+#define I810_CLEAR_COLOR 1
+#define I810_CLEAR_Z 2
+#define I810_CLEAR_ALL I810_CLEAR_COLOR|I810_CLEAR_Z
+
+
+GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height )
+{
+ XSMesaContext xsmesa = (XSMesaContext) ctx->DriverCtx;
+ GLubyte *c;
+ GLuint zval;
+
+ i810Msg(10, "i810Clear( %i, %i, %i, %i, %i )\n",
+ mask, x, y, width, height );
+
+ CHECK_CONTEXT( return mask; );
+
+ if (all == GL_TRUE) {
+ x = 0;
+ y = 0;
+ width = i810DB->Width;
+ height = i810DB->Height;
+ }
+
+ if ( y + height > i810DB->Height ) {
+ height = i810DB->Height - y;
+ }
+ if ( x + width > i810DB->Width ) {
+ width = i810DB->Width - x;
+ }
+ if ( x < 0 ) {
+ width += x;
+ x = 0;
+ }
+ if ( y < 0 ) {
+ height += y;
+ y = 0;
+ }
+ if ( x >= i810DB->Width || y >= i810DB->Height || width < 1 || height < 1 ) {
+ return 0;
+ }
+
+ /* flip top to bottom */
+ y = i810DB->Height-y-height;
+ c = xsmesa->clearcolor;
+ zval = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE);
+
+ i810FinishPrimitive();
+
+ if (1)
+ {
+ BEGIN_BATCH(2);
+ OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH );
+ OUT_BATCH( 0 ); /* pad to quadword */
+ ADVANCE_BATCH();
+ }
+
+ /* color buffer */
+ if (mask & GL_COLOR_BUFFER_BIT)
+ {
+ int start = (i810DB->MemBlock->ofs +
+ y * i810DB->Pitch +
+ x * vgaBytesPerPixel);
+
+ BEGIN_BATCH(6);
+
+ OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
+ OUT_BATCH( BR13_SOLID_PATTERN |
+ (0xF0 << 16) |
+ i810DB->Pitch );
+ OUT_BATCH( (height << 16) | (width * vgaBytesPerPixel));
+ OUT_BATCH( start );
+ OUT_BATCH( i810PackColor( c[0], c[1], c[2], c[3] ) );
+ OUT_BATCH( 0 );
+
+ ADVANCE_BATCH();
+
+ mask &= ~GL_COLOR_BUFFER_BIT;
+ }
+
+ /* depth buffer */
+ if ( (mask & GL_DEPTH_BUFFER_BIT) &&
+ i810DB->ZBuffer &&
+ ctx->Depth.Mask )
+ {
+ int start = (i810DB->ZBuffer->MemBlock->ofs +
+ y * i810DB->ZBuffer->Pitch +
+ x * 2);
+
+ BEGIN_BATCH(6);
+
+ OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
+ OUT_BATCH( BR13_SOLID_PATTERN |
+ (0xF0 << 16) |
+ i810DB->ZBuffer->Pitch );
+ OUT_BATCH( (height << 16) | (width * 2));
+ OUT_BATCH( start );
+ OUT_BATCH( zval );
+ OUT_BATCH( 0 );
+
+ ADVANCE_BATCH();
+
+ mask &= ~GL_DEPTH_BUFFER_BIT;
+ }
+
+ if (1)
+ {
+ BEGIN_BATCH(2);
+ OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH );
+ OUT_BATCH( 0 ); /* pad to quadword */
+ ADVANCE_BATCH();
+ }
+
+ return mask;
+}
+
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810clear.h b/xc/lib/GL/mesa/src/drv/i810/i810clear.h
new file mode 100644
index 000000000..aedbf84d9
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810clear.h
@@ -0,0 +1,7 @@
+#ifndef _I810_CLEAR_H
+#define _I810_CLEAR_H
+
+extern GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810common.h b/xc/lib/GL/mesa/src/drv/i810/i810common.h
new file mode 100644
index 000000000..cb0d6be92
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810common.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ *
+ */
+
+/* $Id: i810common.h,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+#ifndef I810COMMON_INC
+#define I810COMMON_INC
+
+#include "misc.h"
+
+struct i810_context_t;
+typedef struct i810_context_t i810Context;
+typedef struct i810_context_t *i810ContextPtr;
+
+extern unsigned char* I810MMIOBase;
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810context.c b/xc/lib/GL/mesa/src/drv/i810/i810context.c
new file mode 100644
index 000000000..797ef2202
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810context.c
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ *
+ */
+
+/* $Id: i810context.c,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+#include "xsmesaP.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <GL/gl.h>
+
+#include "i810context.h"
+#include "i810lib.h"
+#include "i810log.h"
+#include "i810dd.h"
+#include "i810pipeline.h"
+/* #include "i810render.h" */
+#include "i810state.h"
+#include "i810tris.h"
+#include "simple_list.h"
+
+
+
+i810ContextPtr i810CreateContext(GLcontext *ctx)
+{
+ i810ContextPtr c;
+
+ c = (i810ContextPtr) calloc(1,sizeof(i810Context));
+ if (!c)
+ return NULL;
+
+ c->gl_ctx = ctx;
+
+ c->renderindex = -1; /* impossible value */
+ c->new_state = ~0;
+ c->reg_dirty = ~0;
+
+ make_empty_list(&c->SwappedOut);
+ make_empty_list(&c->TexObjList);
+
+ c->TextureMode = ctx->Texture.Unit[0].EnvMode;
+
+ c->CurrentTex0Obj = 0;
+ c->CurrentTex1Obj = 0;
+ ctx->Shared->DefaultD[2][0].DriverData = 0;
+
+ if (ctx->VB)
+ i810DDRegisterVB( ctx->VB );
+
+ if (ctx->NrPipelineStages)
+ ctx->NrPipelineStages =
+ i810DDRegisterPipelineStages(ctx->PipelineStage,
+ ctx->PipelineStage,
+ ctx->NrPipelineStages);
+
+
+ /* Ask mesa to clip fog coordinates for us.
+ */
+ ctx->TriangleCaps |= DD_CLIP_FOG_COORD;
+
+
+#if 0
+ if (!getenv("I810_NO_FAST_PATH"))
+ ctx->Driver.BuildPrecalcPipeline = i810DDBuildPrecalcPipeline;
+
+ i810DDRenderInit();
+ i810DDFastPathInit();
+#endif
+
+
+ i810DDTrifuncInit();
+ i810DDSetupInit();
+ i810DDExtensionsInit( ctx );
+ i810DDInitState( c );
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER)
+ fprintf(stderr,"i810CreateContext(): successful.\n");
+
+ return c;
+}
+
+int i810DestroyContext(i810ContextPtr ctx)
+{
+ i810TextureObjectPtr next_t, t;
+
+ if (!ctx)
+ return 0;
+
+ if (--(ctx->refcount) > 0)
+ return 0;
+
+ foreach_s (t, next_t, &(ctx->TexObjList))
+ i810DestroyTexObj(ctx, t);
+
+ foreach_s (t, next_t, &(ctx->SwappedOut))
+ i810DestroyTexObj(ctx, t);
+
+ if ( ctx == i810Ctx )
+ i810Ctx = 0;
+
+ free(ctx);
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER)
+ fprintf(stderr,"i810DestroyContext(): successfully destroyed.\n");
+
+ return 0;
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810context.h b/xc/lib/GL/mesa/src/drv/i810/i810context.h
new file mode 100644
index 000000000..498672d6d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810context.h
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ *
+ */
+
+/* $Id: i810context.h,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+
+#ifndef I810CONTEXT_INC
+#define I810CONTEXT_INC
+
+
+#include "mesaglx/types.h"
+
+#include "i810common.h"
+#include "i810buf.h"
+#include "i810tex.h"
+#include "i810vb.h"
+
+#include "xsmesaP.h"
+
+/* Hmmm */
+#define FALLBACK_TEXTURE 1
+
+
+
+/* For i810Ctx->new_state.
+ */
+#define I810_NEW_TEXTURE 0x20
+#define I810_NEW_CONTEXT 0x100
+
+
+
+struct i810_context_t {
+ GLint refcount;
+
+ struct i810_dest_buffer *DB;
+ GLcontext *gl_ctx;
+
+ i810TextureObjectPtr CurrentTex0Obj;
+ i810TextureObjectPtr CurrentTex1Obj;
+
+ struct i810_texture_object_t TexObjList, SwappedOut;
+
+ int TextureMode;
+
+ /* flags
+ */
+ int GlobalPaletteUpdated:1;
+
+
+ /* Hardware state
+ */
+ GLuint Setup[I810_CTX_SETUP_SIZE];
+
+
+ /* Context hardware state mirrors.
+ */
+ GLushort GlobalPalette[256];
+
+ /* Support for CVA and the fast paths.
+ */
+ GLuint setupdone;
+ GLuint setupindex;
+ GLuint renderindex;
+ GLuint using_fast_path;
+ GLuint using_immediate_fast_path;
+/* gl_vertex_interp_func interp; */
+
+ /* Shortcircuit some state changes.
+ */
+ points_func PointsFunc;
+ line_func LineFunc;
+ triangle_func TriangleFunc;
+ quad_func QuadFunc;
+
+ /* Manage our own state */
+ GLuint new_state;
+ GLuint reg_dirty;
+
+ /* One of the few bits of hardware state that can't be calculated
+ * completely on the fly:
+ */
+ GLuint LcsCullMode;
+};
+
+i810ContextPtr i810CreateContext(GLcontext *ctx); /* Do I need visual info? */
+int i810DestroyContext(i810ContextPtr ctx);
+int i810BindBuffer(i810ContextPtr ctx, struct i810_dest_buffer *buf);
+
+extern GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr );
+
+extern GLboolean i810DDBuildPrecalcPipeline( GLcontext *ctx );
+
+
+/* i810DB will be invalid when the frame buffer have to be reallocate
+ * but there was not enough video memory avialable.
+ * TODO: fix this.
+ */
+#define CHECK_CONTEXT(x) do { \
+ if (!i810Ctx || !i810DB) { \
+ fprintf(stderr, "CHECK_CONTEXT failed in %s\n", __FUNCTION__); \
+ x \
+ } \
+} while(0)
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dd.c b/xc/lib/GL/mesa/src/drv/i810/i810dd.c
new file mode 100644
index 000000000..01202a0b3
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810dd.c
@@ -0,0 +1,221 @@
+/*
+ * 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.
+ *
+ */
+
+/* $Id: i810dd.c,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+
+#include "xsmesaP.h"
+#include "mesaglx/types.h"
+#include "vbrender.h"
+#include "glx_log.h"
+
+#include "vga.h"
+#include "vgaPCI.h"
+
+#include <stdio.h>
+
+#include "mm.h"
+#include "i810lib.h"
+#include "i810glx.h"
+#include "i810clear.h"
+#include "i810dd.h"
+#include "i810direct.h"
+#include "i810depth.h"
+#include "i810log.h"
+#include "i810state.h"
+#include "i810span.h"
+#include "i810tex.h"
+#include "i810tris.h"
+#include "i810vb.h"
+#include "extensions.h"
+#include "vb.h"
+#include "dd.h"
+
+
+extern int I810ydstorg;
+extern int I810maccess;
+extern void xsmesa_setup_DD_pointers( GLcontext *ctx );
+extern int xf86VTSema;
+
+
+/***************************************
+ * Mesa's Driver Functions
+ ***************************************/
+
+
+const GLubyte *i810DDGetString( GLcontext *ctx, GLenum name )
+{
+ switch (name) {
+ case GL_VENDOR:
+ return "Keith Whitwell, Precision Insight Inc.";
+ case GL_RENDERER:
+ return "GLX-I810";
+ default:
+ return 0;
+ }
+}
+
+
+void i810DDExtensionsInit( GLcontext *ctx )
+{
+ /* CVA only available for direct contexts.
+ */
+ if (__glx_is_server)
+ gl_extensions_disable( ctx, "GL_EXT_compiled_vertex_array" );
+
+ /* No support for multitexture
+ */
+ if (getenv("I810_NO_MULTITEX")) {
+ gl_extensions_disable( ctx, "GL_EXT_multitexture" );
+ gl_extensions_disable( ctx, "GL_SGIS_multitexture" );
+ gl_extensions_disable( ctx, "GL_ARB_multitexture" );
+ }
+
+ /* we don't support point parameters in hardware yet */
+ gl_extensions_disable( ctx, "GL_EXT_point_parameters" );
+
+ gl_extensions_disable( ctx, "ARB_imaging" );
+ gl_extensions_disable( ctx, "GL_EXT_blend_minmax" );
+ gl_extensions_disable( ctx, "GL_EXT_blend_logic_op" );
+ gl_extensions_disable( ctx, "GL_EXT_blend_subtract" );
+ gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" );
+}
+
+
+static GLint i810GetParameteri(const GLcontext *ctx, GLint param)
+{
+ switch (param) {
+ case DD_HAVE_HARDWARE_FOG:
+ return 1;
+ default:
+ fprintf(stderr, "i810GetParameteri(): unknown parameter!\n");
+ return 0; /* Should I really return 0? */
+ }
+}
+
+
+GLboolean i810IsTextureResident( GLcontext *ctx, struct gl_texture_object *t )
+{
+ i810TextureObjectPtr mt = (i810TextureObjectPtr)t->DriverData;
+ return mt && mt->MemBlock;
+}
+
+
+static int i810CanUseHardware(const GLcontext *ctx)
+{
+ XSMesaContext xsmesa = (XSMesaContext) ctx->DriverCtx;
+ XSMesaBuffer xsmbuf = xsmesa->xsm_buffer;
+ CHECK_CONTEXT( return 0; );
+
+ if ( !i810DB || !xsmbuf->buffer == XIMAGE) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/*
+ * if we can't hardware accelerate the context now, but could
+ * before (the window was sized up to the point a buffer alloc failed)
+ * then just have software mesa do everything.
+ */
+void i810_setup_DD_pointers_no_accel( GLcontext *ctx ) {
+ /* disable hardware accel. */
+ i810Msg(5,"no hw accel.\n");
+
+ ctx->Driver.RenderStart = NULL;
+ ctx->Driver.RenderFinish = NULL;
+ ctx->Driver.NearFar = NULL;
+ ctx->Driver.GetParameteri = NULL;
+ ctx->Driver.RasterSetup = NULL;
+ ctx->Driver.TexEnv = NULL;
+ ctx->Driver.TexImage = NULL;
+ ctx->Driver.BindTexture = NULL;
+ ctx->Driver.DeleteTexture = NULL;
+ ctx->Driver.TexParameter = NULL;
+
+ xsmesa_setup_DD_pointers(ctx);
+ ctx->Driver.UpdateState = i810_setup_DD_pointers;
+}
+
+
+
+void i810_setup_DD_pointers( GLcontext *ctx ) {
+
+ if ( !i810CanUseHardware(ctx) ) {
+ i810_setup_DD_pointers_no_accel( ctx );
+ return;
+ }
+
+ xsmesa_setup_DD_pointers(ctx);
+
+ i810DDInitStatePointers(ctx);
+
+ ctx->Driver.GetString = i810DDGetString;
+ ctx->Driver.UpdateState = i810DDUpdateState;
+ ctx->Driver.RegisterVB = i810DDRegisterVB;
+ ctx->Driver.UnregisterVB = i810DDUnregisterVB;
+ ctx->Driver.Clear = i810Clear;
+ ctx->Driver.GetParameteri = i810GetParameteri;
+ ctx->Driver.TexEnv = i810TexEnv;
+ ctx->Driver.TexImage = i810TexImage;
+ ctx->Driver.TexSubImage = i810TexSubImage;
+ ctx->Driver.BindTexture = i810BindTexture;
+ ctx->Driver.DeleteTexture = i810DeleteTexture;
+ ctx->Driver.TexParameter = i810TexParameter;
+ ctx->Driver.UpdateTexturePalette = i810UpdateTexturePalette;
+ ctx->Driver.IsTextureResident = i810IsTextureResident;
+
+ ctx->Driver.TriangleCaps = (DD_TRI_CULL|
+ DD_TRI_LIGHT_TWOSIDE|
+ DD_TRI_OFFSET);
+
+ i810DDInitSpans( ctx );
+
+ if (i810DB->ZBuffer) {
+ ctx->Driver.ReadDepthSpanFloat = i810_read_depth_span_float;
+ ctx->Driver.ReadDepthSpanInt = i810_read_depth_span_int;
+ if (ctx->Depth.Test) {
+ switch (ctx->Depth.Func) {
+ case GL_LESS:
+ ctx->Driver.DepthTestSpan = i810_depth_test_span_less;
+ ctx->Driver.DepthTestPixels = i810_depth_test_pixels_less;
+ break;
+ case GL_GREATER:
+ ctx->Driver.DepthTestSpan = i810_depth_test_span_greater;
+ ctx->Driver.DepthTestPixels = i810_depth_test_pixels_greater;
+ break;
+ default:
+ ctx->Driver.DepthTestSpan = i810_depth_test_span_generic;
+ ctx->Driver.DepthTestPixels = i810_depth_test_pixels_generic;
+ break;
+ }
+ }
+ }
+
+ /* Also do the normal GL state-change checks.
+ */
+ i810DDUpdateState( ctx );
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dd.h b/xc/lib/GL/mesa/src/drv/i810/i810dd.h
new file mode 100644
index 000000000..94f2aec18
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810dd.h
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ *
+ */
+
+/* $Id: i810dd.h,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+#ifndef I810DD_INC
+#define I810DD_INC
+
+#include "mesaglx/context.h"
+
+#include "i810buf.h"
+
+void i810_setup_DD_pointers( GLcontext *ctx );
+void i810DDRegisterVB( struct vertex_buffer *VB );
+
+void i810DDFastPath( struct vertex_buffer *VB );
+void i810DDImmediateFastPath( struct vertex_buffer *VB );
+void i810DDFastPathInit();
+void i810DDExtensionsInit( GLcontext *ctx );
+
+void i810_setup_DD_pointers_no_accel( GLcontext *ctx );
+/* void i810FinishPrimitive( void ); */
+
+#define i810FinishPrimitive()
+
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810depth.c b/xc/lib/GL/mesa/src/drv/i810/i810depth.c
new file mode 100644
index 000000000..c5c735fd4
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810depth.c
@@ -0,0 +1,737 @@
+/* $Id: i810depth.c,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.1
+ *
+ * Copyright (C) 1999 Brian Paul 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
+ * BRIAN PAUL 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.
+ */
+
+/*
+ * This file has been modified by Wittawat Yamwong for GLX module.
+ */
+
+/*
+ * Depth buffer functions
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <stdlib.h>
+#include <string.h>
+#include "mesaglx/context.h"
+#include "i810depth.h"
+#include "mesaglx/types.h"
+#include "mm.h"
+#include "i810lib.h"
+#endif
+
+
+
+/*
+ * Return the address of the Z-buffer value for window coordinate (x,y):
+ */
+#define Z_SETUP \
+ GLdepth *zbstart = (GLdepth *)i810DB->ZBuffer->BufAddr; \
+ GLint zbpitch = i810DB->ZBuffer->Pitch;
+#define Z_ADDRESS( X, Y ) \
+ (zbstart + zbpitch * (Y) + (X))
+
+
+/**********************************************************************/
+/***** Depth Testing Functions *****/
+/**********************************************************************/
+
+
+/*
+ * Depth test horizontal spans of fragments. These functions are called
+ * via ctx->Driver.depth_test_span only.
+ *
+ * Input: n - number of pixels in the span
+ * x, y - location of leftmost pixel in span in window coords
+ * z - array [n] of integer depth values
+ * In/Out: mask - array [n] of flags (1=draw pixel, 0=don't draw)
+ * Return: number of pixels which passed depth test
+ */
+
+
+/*
+ * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
+ */
+GLuint i810_depth_test_span_generic( GLcontext* ctx,
+ GLuint n, GLint x, GLint y,
+ const GLdepth z[],
+ GLubyte mask[] )
+{
+ Z_SETUP
+ GLdepth *zptr = Z_ADDRESS( x, y );
+ GLubyte *m = mask;
+ GLuint i;
+ GLuint passed = 0;
+
+ i810WaitDrawingEngine();
+
+ /* switch cases ordered from most frequent to less frequent */
+ switch (ctx->Depth.Func) {
+ case GL_LESS:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] < *zptr) {
+ /* pass */
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ /* fail */
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] < *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_LEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] <= *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] <= *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_GEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] >= *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] >= *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_GREATER:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] > *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] > *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_NOTEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] != *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] != *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_EQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] == *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m =0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] == *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m =0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_ALWAYS:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ *zptr = z[i];
+ passed++;
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer or mask */
+ passed = n;
+ }
+ break;
+ case GL_NEVER:
+ for (i=0;i<n;i++) {
+ mask[i] = 0;
+ }
+ break;
+ default:
+ gl_problem(ctx, "Bad depth func in gl_depth_test_span_generic");
+ } /*switch*/
+
+ return passed;
+}
+
+
+
+/*
+ * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE).
+ */
+GLuint i810_depth_test_span_less( GLcontext* ctx,
+ GLuint n, GLint x, GLint y, const GLdepth z[],
+ GLubyte mask[] )
+{
+ Z_SETUP
+ GLdepth *zptr = Z_ADDRESS( x, y );
+ GLuint i;
+ GLuint passed = 0;
+
+ i810WaitDrawingEngine();
+
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ if (z[i] < zptr[i]) {
+ /* pass */
+ zptr[i] = z[i];
+ passed++;
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ return passed;
+}
+
+
+/*
+ * glDepthFunc(GL_GREATER) and glDepthMask(GL_TRUE).
+ */
+GLuint i810_depth_test_span_greater( GLcontext* ctx,
+ GLuint n, GLint x, GLint y,
+ const GLdepth z[],
+ GLubyte mask[] )
+{
+ Z_SETUP
+ GLdepth *zptr = Z_ADDRESS( x, y );
+ GLuint i;
+ GLuint passed = 0;
+
+ i810WaitDrawingEngine();
+
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ if (z[i] > zptr[i]) {
+ /* pass */
+ zptr[i] = z[i];
+ passed++;
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ return passed;
+}
+
+
+
+/*
+ * Depth test an array of randomly positioned fragments.
+ */
+
+/*
+ * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
+ */
+void i810_depth_test_pixels_generic( GLcontext* ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ const GLdepth z[], GLubyte mask[] )
+{
+ Z_SETUP
+ register GLdepth *zptr;
+ register GLuint i;
+
+ i810WaitDrawingEngine();
+
+ /* switch cases ordered from most frequent to less frequent */
+ switch (ctx->Depth.Func) {
+ case GL_LESS:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] < *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] < *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_LEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] <= *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] <= *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_GEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] >= *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] >= *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_GREATER:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] > *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] > *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_NOTEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] != *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] != *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_EQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] == *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] == *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_ALWAYS:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ *zptr = z[i];
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer or mask */
+ }
+ break;
+ case GL_NEVER:
+ /* depth test never passes */
+ for (i=0;i<n;i++) {
+ mask[i] = 0;
+ }
+ break;
+ default:
+ gl_problem(ctx, "Bad depth func in gl_depth_test_pixels_generic");
+ } /*switch*/
+}
+
+
+
+/*
+ * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ).
+ */
+void i810_depth_test_pixels_less( GLcontext* ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ const GLdepth z[], GLubyte mask[] )
+{
+ Z_SETUP
+ GLdepth *zptr;
+ GLuint i;
+
+ i810WaitDrawingEngine();
+
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] < *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+}
+
+
+/*
+ * glDepthFunc( GL_GREATER ) and glDepthMask( GL_TRUE ).
+ */
+void i810_depth_test_pixels_greater( GLcontext* ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ const GLdepth z[], GLubyte mask[] )
+{
+ Z_SETUP
+ GLdepth *zptr;
+ GLuint i;
+
+ i810WaitDrawingEngine();
+
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] > *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+}
+
+
+
+
+/**********************************************************************/
+/***** Read Depth Buffer *****/
+/**********************************************************************/
+
+
+/*
+ * Return a span of depth values from the depth buffer as floats in [0,1].
+ * This function is only called through Driver.read_depth_span_float()
+ * Input: n - how many pixels
+ * x,y - location of first pixel
+ * Output: depth - the array of depth values
+ */
+void i810_read_depth_span_float( GLcontext* ctx,
+ GLuint n, GLint x, GLint y, GLfloat depth[] )
+{
+ Z_SETUP
+ GLdepth *zptr;
+ GLfloat scale;
+ GLuint i;
+
+ i810WaitDrawingEngine();
+
+ scale = 1.0F / DEPTH_SCALE;
+
+ if (ctx->Buffer->Depth) {
+ zptr = Z_ADDRESS( x, y );
+ for (i=0;i<n;i++) {
+ depth[i] = (GLfloat) zptr[i] * scale;
+ }
+ }
+ else {
+ for (i=0;i<n;i++) {
+ depth[i] = 0.0F;
+ }
+ }
+}
+
+
+/*
+ * Return a span of depth values from the depth buffer as integers in
+ * [0,MAX_DEPTH].
+ * This function is only called through Driver.read_depth_span_int()
+ * Input: n - how many pixels
+ * x,y - location of first pixel
+ * Output: depth - the array of depth values
+ */
+void i810_read_depth_span_int( GLcontext* ctx,
+ GLuint n, GLint x, GLint y, GLdepth depth[] )
+{
+ Z_SETUP
+
+ i810WaitDrawingEngine();
+
+ if (ctx->Buffer->Depth) {
+ GLdepth *zptr = Z_ADDRESS( x, y );
+ MEMCPY( depth, zptr, n * sizeof(GLdepth) );
+ }
+ else {
+ GLuint i;
+ for (i=0;i<n;i++) {
+ depth[i] = 0;
+ }
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810depth.h b/xc/lib/GL/mesa/src/drv/i810/i810depth.h
new file mode 100644
index 000000000..5b6b7ae83
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810depth.h
@@ -0,0 +1,82 @@
+/* $Id: i810depth.h,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.1
+ *
+ * Copyright (C) 1999 Brian Paul 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
+ * BRIAN PAUL 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.
+ */
+
+/*
+ * This file has been modified by Wittawat Yamwong for GLX module.
+ */
+
+
+#ifndef I810DEPTH_INC
+#define I810DEPTH_INC
+
+
+#include "mesaglx/types.h"
+
+
+
+
+
+extern GLuint
+i810_depth_test_span_generic( GLcontext* ctx, GLuint n, GLint x, GLint y,
+ const GLdepth z[], GLubyte mask[] );
+
+extern GLuint
+i810_depth_test_span_less( GLcontext* ctx, GLuint n, GLint x, GLint y,
+ const GLdepth z[], GLubyte mask[] );
+
+extern GLuint
+i810_depth_test_span_greater( GLcontext* ctx, GLuint n, GLint x, GLint y,
+ const GLdepth z[], GLubyte mask[] );
+
+
+
+extern void
+i810_depth_test_pixels_generic( GLcontext* ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ const GLdepth z[], GLubyte mask[] );
+
+extern void
+i810_depth_test_pixels_less( GLcontext* ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ const GLdepth z[], GLubyte mask[] );
+
+extern void
+i810_depth_test_pixels_greater( GLcontext* ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ const GLdepth z[], GLubyte mask[] );
+
+
+extern void i810_read_depth_span_float( GLcontext* ctx,
+ GLuint n, GLint x, GLint y,
+ GLfloat depth[] );
+
+
+extern void i810_read_depth_span_int( GLcontext* ctx, GLuint n, GLint x, GLint y,
+ GLdepth depth[] );
+
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810direct.c b/xc/lib/GL/mesa/src/drv/i810/i810direct.c
new file mode 100644
index 000000000..5fa2bf7d3
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810direct.c
@@ -0,0 +1,647 @@
+/* $Id: i810direct.c,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdlib.h>
+#include <signal.h>
+
+#include "context.h"
+#include "depth.h"
+#include "macros.h"
+#include "texstate.h"
+#include "triangle.h"
+#include "vb.h"
+#include "types.h"
+
+#include "xsmesaP.h"
+#include "glx_log.h"
+#include "mesaglx/context.h"
+#include "mesaglx/matrix.h"
+#include "mesaglx/types.h"
+
+#define GC XXGC
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "servermd.h" /* PixmapBytePad */
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "windowstr.h"
+#undef GC
+
+#include "vga.h"
+#include "vgaPCI.h"
+#include "i810.h"
+#include "xaa/xf86xaa.h"
+
+#include "mm.h"
+#include "i810buf.h"
+#include "i810dd.h"
+#include "i810lib.h"
+#include "i810log.h"
+#include "i810direct.h"
+#include "i810dma.h"
+#include "i810glx.h"
+
+#include "glx_clients.h"
+#include "xf86_OSproc.h"
+
+
+static void i810ClientDMAFlush( int wait );
+static void i810ClientSwapBuffers( XSMesaBuffer b ) ;
+static void i810ClientReleaseHardware( void );
+
+/*
+ */
+#define GLX_START X_GLXDirectPrivateStart
+
+/* Although not strictly necessary, I've used different numbers
+ * to the mga driver.
+ */
+#define X_GLXI810SwapBuffers (GLX_START+5)
+#define X_GLXI810DmaFlush (GLX_START+6)
+#define X_GLXI810FBGeom (GLX_START+7)
+
+
+/* Nice thing about direct rendering is that the server *is* the
+ * client, in the sense that they should both be the same executable
+ * image 'glx.so'. This means that most of the protocol structs can
+ * be private to this file.
+ */
+typedef struct {
+ char init_fn[20]; /* The first element is always the
+ * name of the function for the client
+ * to call to initialize glx.so. */
+
+ int screenNum; /* not respected - assumed to be zero */
+
+ int vgaInfoVirtualX;
+ int vgaInfoVirtualY;
+ int vgaInfoDepth;
+ int vgaInfoDisplayWidth;
+ int vgaInfoVideoRam;
+ int vgaInfoChipID;
+ unsigned long vgaInfoPhysBase;
+
+ char vgaInfoChipset[80];
+ int vgaBitsPerPixel;
+ int vgaBytesPerPixel;
+ int vgaLinearSize;
+
+ int i810chipset;
+ int i810dcache_start;
+ int i810dcache_end;
+
+ int i810glx_dma;
+ int i810glx_dmaadr;
+ int i810glx_dmasize;
+ int i810glx_cmdsize;
+
+ int i810ActiveDmaBuffer;
+ int glx_first_visual;
+
+} i810DirectHWInfo;
+
+
+extern int __glx_is_server;
+extern int __glx_first_visual;
+extern int vgaLinearSize;
+extern ClientPtr direct_client;
+extern int __glXNumClients();
+
+static ClientRec fake_client;
+
+
+static int (*send_vendor_private)( int opcode,
+ char *vp,
+ size_t vp_sz,
+ xReply *reply,
+ char *data,
+ size_t data_sz ) = 0;
+
+
+ClientPtr i810GLXClientInit( i810DirectHWInfo *hw,
+ int (*send_func)(),
+ void (**release_hook)( void ))
+{
+ __glx_is_server = 0;
+
+ send_vendor_private = send_func;
+
+ i810DoDmaFlush = i810ClientDMAFlush;
+ i810GLXSwapBuffers = i810ClientSwapBuffers;
+
+ direct_client = &fake_client;
+ direct_client->index = 1;
+
+ memset(&vga256InfoRec, 0, sizeof(vga256InfoRec));
+ memset(&xf86AccelInfoRec, 0, sizeof(xf86AccelInfoRec));
+
+ vgaLinearSize = hw->vgaLinearSize;
+ vga256InfoRec.virtualX = hw->vgaInfoVirtualX;
+ vga256InfoRec.virtualY = hw->vgaInfoVirtualY;
+ vga256InfoRec.depth = hw->vgaInfoDepth;
+ vga256InfoRec.displayWidth = hw->vgaInfoDisplayWidth;
+ vga256InfoRec.videoRam = hw->vgaInfoVideoRam;
+ vga256InfoRec.chipID = hw->vgaInfoChipID;
+ vga256InfoRec.physBase = hw->vgaInfoPhysBase;
+ vga256InfoRec.chipset = hw->vgaInfoChipset;
+ vgaBytesPerPixel = hw->vgaBytesPerPixel;
+ vgaBitsPerPixel = hw->vgaBitsPerPixel;
+
+ i810glx.dmaDriver = hw->i810glx_dma;
+ i810glx.dmaAdr = hw->i810glx_dmaadr;
+ i810glx.dmaSize = hw->i810glx_dmasize;
+ i810glx.cmdSize = hw->i810glx_cmdsize;
+ __glx_first_visual = hw->glx_first_visual;
+
+ I810DcacheMem.Start = hw->i810dcache_start;
+ I810DcacheMem.End = hw->i810dcache_end;
+ I810DcacheMem.Size = I810DcacheMem.End - I810DcacheMem.Start;
+ I810Chipset = hw->i810chipset;
+
+ i810ActiveDmaBuffer = hw->i810ActiveDmaBuffer;
+
+ vgaLinearBase = xf86MapVidMem(hw->screenNum,
+ LINEAR_REGION,
+ (pointer) vga256InfoRec.physBase,
+ vgaLinearSize);
+
+ if (vgaLinearBase == (pointer) -1) {
+ i810Error("failed to map vga linear region");
+ i810ClientReleaseHardware();
+ return 0;
+ }
+
+ *release_hook = i810ClientReleaseHardware;
+ return direct_client;
+}
+
+static void i810ClientReleaseHardware( void )
+{
+ if (vgaLinearBase != (pointer) -1) {
+ xf86UnMapVidMem(0,
+ LINEAR_REGION,
+ (pointer) vga256InfoRec.physBase,
+ vgaLinearSize);
+ vgaLinearBase = 0;
+ }
+}
+
+
+static int i810GLXGoDirect( ClientPtr client )
+{
+ xGLXGetStringReply reply;
+ i810DirectHWInfo *hw;
+ int l;
+
+ /* Allow only one direct client, which must be the only active
+ * client, and must be on the local server.
+ */
+ if (direct_client || !__glx_is_server || __glXNumClients() != 1 ||
+ !LocalClient(client))
+ return BadAccess;
+
+ if (i810glx.dmaDriver < 2) {
+ i810Error("Direct clients only allowed with real dma");
+ return BadMatch;
+ }
+
+ i810DmaFlush();
+
+ direct_client = client;
+ hw = (i810DirectHWInfo *)malloc( sizeof(*hw) );
+
+ /* Name of function to call to revive the struct. Client will
+ * receive buf in reply to its go_direct request. Client will map
+ * glx.so, and use buf as a string argument to dlsym(), to retreive
+ * a function to call, namely i810GLXClientInit. It will then call
+ * that function passing hw as its argument.
+ *
+ * hw should contain all the information necessary to get glx.so
+ * talking to hardware from the client.
+ */
+ strcpy(hw->init_fn, "i810GLXClientInit");
+
+ hw->screenNum = 0; /* oh really? */
+ hw->vgaInfoVirtualX = vga256InfoRec.virtualX;
+ hw->vgaInfoVirtualY = vga256InfoRec.virtualY;
+ hw->vgaInfoDepth = vga256InfoRec.depth;
+ hw->vgaInfoDisplayWidth = vga256InfoRec.displayWidth;
+ hw->vgaInfoVideoRam = vga256InfoRec.videoRam;
+ hw->vgaInfoChipID = vga256InfoRec.chipID;
+ hw->vgaInfoPhysBase = vga256InfoRec.physBase;
+
+ strncpy(hw->vgaInfoChipset, vga256InfoRec.chipset, 80);
+ hw->vgaInfoChipset[79] = 0;
+
+ hw->vgaBitsPerPixel = vgaBitsPerPixel;
+ hw->vgaBytesPerPixel = vgaBytesPerPixel;
+ hw->vgaLinearSize = vgaLinearSize;
+
+ hw->i810dcache_start = I810DcacheMem.Start;
+ hw->i810dcache_end = I810DcacheMem.End;
+ hw->i810chipset = I810Chipset;
+
+ hw->i810glx_dma = i810glx.dmaDriver;
+ hw->i810glx_dmaadr = i810glx.dmaAdr;
+ hw->i810glx_dmasize = i810glx.dmaSize;
+ hw->i810glx_cmdsize = i810glx.cmdSize;
+
+ hw->i810ActiveDmaBuffer = i810ActiveDmaBuffer;
+ hw->glx_first_visual = __glx_first_visual;
+
+ reply.type=X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length=0;
+ reply.n=l=(sizeof(*hw)+3)/4;
+
+ WriteToClient(client, sizeof(xGLXGetStringReply), (char*)&reply);
+ WriteToClient(client, sizeof(int)*l, (char*)hw);
+
+ return client->noClientException;
+}
+
+
+
+static int i810GLXReleaseDirect( ClientPtr client )
+{
+ if (__glx_is_server && direct_client && direct_client == client) {
+ direct_client = 0;
+ return Success;
+ }
+
+ return BadAccess;
+}
+
+
+
+
+/* =======================================================================
+ * Dma flush
+ */
+typedef struct {
+ CARD32 dma_head;
+ CARD32 dma_buffer_id; /* validation only */
+ CARD32 dma_sync;
+} DmaFlushReq;
+
+
+typedef struct {
+ BYTE type;
+ CARD8 xpad;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD32 dma_buffer_id; /* new active id */
+} DmaFlushReply;
+
+
+
+static int i810GLXDirectDMAFlush( ClientPtr client,
+ xGLXVendorPrivateReq *stuff )
+{
+ DmaFlushReq *vp = (DmaFlushReq *)(stuff + 1);
+ xReply reply;
+ DmaFlushReply *rep = (DmaFlushReply *)&reply;
+ extern void i810ServerDmaFlush( int );
+
+
+ if (client != direct_client)
+ return BadAccess;
+
+ if ( i810ActiveDmaBuffer != vp->dma_buffer_id )
+ {
+ i810Error("someone's been playing with dma on the server\n");
+ return BadImplementation;
+ }
+
+ i810glx.dma_buffer->head = vp->dma_head;
+ i810glx.dma_buffer->space -= vp->dma_head;
+
+ i810ServerDmaFlush( vp->dma_sync );
+
+ rep->type = X_Reply;
+ rep->length = 0;
+ rep->sequenceNumber = client->sequence;
+ rep->dma_buffer_id = i810ActiveDmaBuffer;
+
+ WriteToClient( client, sizeof(xReply), (char *) &reply );
+
+ return client->noClientException;
+}
+
+
+/*
+ * i810ClientDMAFlush
+ * When direct rendering, this is called instead of starting
+ * the dma from user space. This only happens for overflows,
+ * explicit flush/finish, and software rendering. The swapbuffers
+ * interface handles flushing in normal cases.
+ */
+static void i810ClientDMAFlush( int wait )
+{
+ DmaFlushReq vp;
+ xReply reply;
+
+ vp.dma_buffer_id = i810ActiveDmaBuffer;
+ vp.dma_head = i810glx.dma_buffer->head;
+ vp.dma_sync = wait;
+
+ if (send_vendor_private( X_GLXI810DmaFlush,
+ (char *)&vp, sizeof(vp),
+ &reply, 0, 0 ))
+ {
+ DmaFlushReply *rep = (DmaFlushReply *)&reply;
+ i810ActiveDmaBuffer = rep->dma_buffer_id;
+ }
+
+ i810DmaResetBuffer();
+}
+
+
+/* =======================================================================
+ * Geometry request
+ * - could just use XGetGeom, but this is simpler, really.
+ */
+typedef struct {
+ CARD32 drawable;
+} FBGeomReq;
+
+
+typedef struct {
+ BYTE type;
+ CARD8 xpad;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD16 width;
+ CARD16 height;
+} FBGeomReply;
+
+
+static int i810GLXDirectGetGeometry( ClientPtr client,
+ xGLXVendorPrivateReq *stuff )
+{
+ xReply reply;
+ DrawablePtr frontbuf;
+ FBGeomReq *vp = (FBGeomReq *)(stuff + 1);
+ FBGeomReply *rep = (FBGeomReply *)&reply;
+
+ if (client != direct_client)
+ return BadAccess;
+
+ frontbuf = LookupIDByClass( vp->drawable, RC_DRAWABLE );
+ if (!frontbuf)
+ return GLXBadDrawable;
+
+ rep->type = X_Reply;
+ rep->length = 0;
+ rep->sequenceNumber = client->sequence;
+ rep->width = frontbuf->width;
+ rep->height = frontbuf->height;
+
+ WriteToClient( client, sizeof(xReply), (char *) &reply );
+
+ return client->noClientException;
+}
+
+
+void i810ClientGetGeometry( DrawablePtr d )
+{
+ FBGeomReq vp;
+ xReply reply;
+
+ vp.drawable = d->id;
+
+ if (send_vendor_private( X_GLXI810FBGeom,
+ (char *)&vp, sizeof(vp),
+ &reply, 0, 0 ))
+ {
+ FBGeomReply *rep = (FBGeomReply *)&reply;
+ d->width = rep->width;
+ d->height = rep->height;
+ }
+}
+
+
+
+
+/* ===========================================================================
+ * Buffer swap
+ * - Combines dma flush, buffer swap and get geometry.
+ */
+
+/* Need to issue the swap commands from the server as the client
+ * doesn't have the clip rects. This isn't so bad as we would want to
+ * do a dma flush immediately afterwards anyhow.
+ */
+typedef struct {
+ CARD16 back_width;
+ CARD16 back_height;
+ CARD16 back_pitch;
+ CARD16 back_format;
+ CARD32 back_offset;
+ CARD32 front_drawable;
+ CARD32 dma_head;
+ CARD32 dma_buffer_id; /* validation only */
+ CARD32 flag;
+} SwapBufferReq;
+
+typedef struct {
+ BYTE type;
+ CARD8 xpad;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD32 dma_buffer_id; /* new active id */
+ CARD16 width;
+ CARD16 height;
+} SwapBufferReply;
+
+#define FLG_TEX_SWAP 0x1
+
+static int i810GLXDirectSwapBuffers( ClientPtr client,
+ xGLXVendorPrivateReq *stuff )
+{
+ SwapBufferReq *vp = (SwapBufferReq *)(stuff+1);
+ xReply reply;
+ SwapBufferReply *rep = (SwapBufferReply *)&reply;
+ struct i810_dest_buffer *old = i810DB;
+ struct i810_dest_buffer backbuf;
+ TMemBlock tmp;
+ DrawablePtr frontbuf;
+
+ if (client != direct_client)
+ return BadAccess;
+
+ if ( i810ActiveDmaBuffer != vp->dma_buffer_id )
+ {
+ fprintf(stderr, "somebody's been playing with dma on the server %d %ld\n",
+ i810ActiveDmaBuffer, vp->dma_buffer_id);
+
+ return BadImplementation;
+ }
+
+ i810glx.dma_buffer->head = vp->dma_head;
+ i810glx.dma_buffer->space -= vp->dma_head;
+
+ frontbuf = LookupIDByClass( vp->front_drawable, RC_DRAWABLE );
+
+ if (!frontbuf) {
+ return GLXBadDrawable;
+ }
+
+ backbuf.Width = vp->back_width;
+ backbuf.Height = vp->back_height;
+ backbuf.Pitch = vp->back_pitch;
+ backbuf.Format = vp->back_format;
+ backbuf.MemBlock = &tmp;
+ backbuf.MemBlock->ofs = vp->back_offset;
+
+ if (vp->flag & FLG_TEX_SWAP) i810glx.c_textureSwaps++;
+
+ i810DB=&backbuf;
+ i810PerformanceBoxes( 1 );
+ i810DB=old;
+
+ i810BackToFront(frontbuf, &backbuf);
+ i810DmaFlush();
+
+ rep->type = X_Reply;
+ rep->length = 0;
+ rep->sequenceNumber = client->sequence;
+ rep->dma_buffer_id = i810ActiveDmaBuffer;
+ rep->width = frontbuf->width;
+ rep->height = frontbuf->height;
+
+ WriteToClient( client, sizeof(xReply), (char *) &reply );
+
+ return client->noClientException;
+}
+
+static void i810ClientSwapBuffers( XSMesaBuffer b )
+{
+ SwapBufferReq vp;
+ xReply reply;
+ struct i810_dest_buffer *buf;
+
+ if (!b ||
+ !b->db_state ||
+ !b->backimage ||
+ !(buf = (struct i810_dest_buffer *)b->backimage->devPriv))
+ {
+ fprintf(stderr, "client swap buffers: wtf???\n");
+ return;
+ }
+
+ if (i810Ctx && i810Ctx->gl_ctx) {
+ FLUSH_VB(i810Ctx->gl_ctx, "i810 client swap buffers");
+ }
+
+/* i810WarpFinishSerie(); */
+/* i810glx.swapBuffersCount++; */
+
+ i810glx.dma_buffer->texture_age = ++i810glx.current_texture_age;
+
+ if (i810Ctx) {
+ if (i810Ctx->CurrentTex0Obj)
+ i810Ctx->CurrentTex0Obj->age = ++i810glx.current_texture_age;
+
+ if (i810Ctx->CurrentTex1Obj)
+ i810Ctx->CurrentTex1Obj->age = ++i810glx.current_texture_age;
+ }
+
+
+ vp.front_drawable = b->frontbuffer->id;
+ vp.back_width = buf->Width;
+ vp.back_height = buf->Height;
+ vp.back_pitch = buf->Pitch;
+ vp.back_format = buf->Format;
+ vp.back_offset = buf->MemBlock->ofs;
+
+ vp.dma_buffer_id = i810ActiveDmaBuffer;
+ vp.dma_head = i810glx.dma_buffer->head;
+ vp.flag = 0;
+
+ if (i810glx.c_textureSwaps) {
+ vp.flag |= FLG_TEX_SWAP;
+ i810glx.c_textureSwaps = 0;
+ }
+
+ if (send_vendor_private( X_GLXI810SwapBuffers,
+ (char *)&vp, sizeof(vp), &reply, 0, 0 ))
+ {
+ SwapBufferReply *rep = (SwapBufferReply *)&reply;
+
+ b->frontbuffer->width = rep->width;
+ b->frontbuffer->height = rep->height;
+
+ i810ActiveDmaBuffer = rep->dma_buffer_id;
+ i810DmaResetBuffer();
+ }
+ else
+ FatalError("clientSwapBuffers failed");
+}
+
+
+
+
+
+
+
+/* ===========================================================================
+ */
+
+int i810GLXVendorPrivate( ClientPtr client,
+ XSMesaContext ctx,
+ xGLXVendorPrivateReq *stuff )
+{
+ if (!__glx_is_server)
+ return GLXUnsupportedPrivateRequest;
+
+ switch (stuff->opcode) {
+ case X_GLXDirectGoDirect:
+ return i810GLXGoDirect( client );
+ case X_GLXDirectRelease:
+ return i810GLXReleaseDirect( client );
+ case X_GLXI810SwapBuffers:
+ return i810GLXDirectSwapBuffers( client, stuff );
+ case X_GLXI810DmaFlush:
+ return i810GLXDirectDMAFlush( client, stuff );
+ case X_GLXI810FBGeom:
+ return i810GLXDirectGetGeometry( client, stuff );
+ }
+
+ i810Error("not-handled case");
+ return GLXUnsupportedPrivateRequest;
+}
+
+
+int i810GLXAllowDirect( ClientPtr client )
+{
+#if (!I810_USE_BATCH)
+ i810Error("Don't allow direct clients unless compiled for true dma");
+ return 0;
+#endif
+
+ return 1;
+}
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810direct.h b/xc/lib/GL/mesa/src/drv/i810/i810direct.h
new file mode 100644
index 000000000..6ff8e1dd6
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810direct.h
@@ -0,0 +1,22 @@
+#ifndef I810_DIRECT_H
+#define I810_DIRECT_H
+
+#include "xsmesa.h"
+
+extern int __glx_is_server;
+
+extern int i810GLXVendorPrivate( ClientPtr client,
+ XSMesaContext ctx,
+ xGLXVendorPrivateReq *stuff );
+
+
+extern int i810GLXAllowDirect( ClientPtr client );
+
+
+extern void i810ClientGetGeometry( DrawablePtr b );
+
+#endif
+
+
+
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dma.c b/xc/lib/GL/mesa/src/drv/i810/i810dma.c
new file mode 100644
index 000000000..c6fe0941c
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810dma.c
@@ -0,0 +1,475 @@
+/* -*- mode: C; c-basic-offset:8 -*- */
+/*
+ * 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.
+ *
+ * based on the original mgadma.c by Jeff Hartmann <slicer@ionet.net>
+ * as rewritten by John Carmack <johnc@idsoftware.com>
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "mm.h"
+#include "i810buf.h"
+#include "i810dd.h"
+#include "i810lib.h"
+#include "i810log.h"
+#include "i810tris.h"
+#include "i810direct.h"
+#include "i810state.h"
+
+#include "pb.h"
+
+/* X server include:
+ */
+#include "i810.h"
+
+
+
+/* This will be overwritten from the default values when glx.so is
+ * loaded on the client.
+ */
+void i810ServerDmaFlush( int wait );
+void (*i810DoDmaFlush)( int ) = i810ServerDmaFlush;
+GLuint i810ActiveDmaBuffer = 0;
+
+
+
+#ifndef I810_DEBUG
+int I810_DEBUG = (0
+/* | DEBUG_ALWAYS_SYNC */
+/* | DEBUG_VERBOSE_ACCEL */
+/* | DEBUG_VERBOSE_SYNC */
+/* | DEBUG_VERBOSE_VGA */
+/* | DEBUG_VERBOSE_RING */
+/* | DEBUG_VERBOSE_OUTREG */
+/* | DEBUG_VERBOSE_MEMORY */
+/* | DEBUG_ALWAYS_SYNC */
+/* | DEBUG_VERBOSE_MSG */
+ );
+#endif
+
+
+
+static void delay( void ) {
+}
+
+
+/* Duplicates code in i810_accel.c, but which was declared static...
+ */
+void I810WaitLpRing( int n )
+{
+ int j = 0;
+
+ if (I810_DEBUG & DEBUG_VERBOSE_RING)
+ fprintf(stderr, "I810WaitLpRing %d\n", n);
+
+ while (I810LpRing.space < n)
+ {
+ I810LpRing.head = INREG(I810LpRing.base_reg + RING_HEAD);
+ I810LpRing.head &= HEAD_ADDR;
+
+ I810LpRing.space = I810LpRing.head - (I810LpRing.tail + 8);
+ if (I810LpRing.space < 0)
+ I810LpRing.space += I810LpRing.mem.Size;
+
+ if (++j > 500) {
+ int i;
+ for (i = 0 ; i<10000 ; i++)
+ delay();
+ }
+
+ if (j > 5000) {
+ I810PrintErrorState();
+ fprintf(stderr, "space: %d wanted %d\n",
+ I810LpRing.space, n );
+
+ I810FrameBufferLocked = 0;
+ FatalError("lockup in i810dma.c\n");
+ }
+ }
+}
+
+
+/* Duplicates code in i810_accel.c, but which was declared static...
+ */
+void I810Sync( void )
+{
+ if (I810_DEBUG)
+ fprintf(stderr, "I810Sync\n");
+
+ if (I810LpRing.head == I810LpRing.tail && I810LpRing.space)
+ return;
+
+ {
+ BEGIN_LP_RING(2);
+ OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH );
+ OUT_RING( 0 ); /* pad to quadword */
+ ADVANCE_LP_RING();
+ }
+
+ I810WaitLpRing( I810LpRing.mem.Size - 8 );
+ I810LpRing.space = I810LpRing.mem.Size - 8;
+}
+
+
+int i810WaitForDmaCompletion( void )
+{
+ int start, end;
+
+ if (I810LpRing.head == I810LpRing.tail && I810LpRing.space)
+ return 0;
+
+ start = i810_usec();
+ I810LpRing.head = INREG(I810LpRing.base_reg + RING_HEAD);
+ end = i810_usec();
+
+ if (0 && start + 100 < end)
+ fprintf(stderr, "INREG in WaitForDma: %d usec\n", end - start);
+
+ I810LpRing.head &= HEAD_ADDR;
+ I810LpRing.space = I810LpRing.head - (I810LpRing.tail + 8);
+ if (I810LpRing.space < 0)
+ I810LpRing.space += I810LpRing.mem.Size;
+
+ if (I810LpRing.head == I810LpRing.tail)
+ return 0;
+
+ start = i810_usec();
+ I810Sync();
+ end = i810_usec();
+
+ return 1;
+}
+
+int i810WaitForDmaBuffer( int buffer_id )
+{
+ int start, end;
+
+ if (I810LpRing.head == I810LpRing.tail && I810LpRing.space)
+ return 0;
+
+ start = i810_usec();
+ I810LpRing.head = INREG(I810LpRing.base_reg + RING_HEAD);
+ end = i810_usec();
+
+ if (start + 100 < end)
+ fprintf(stderr, "INREG in WaitForDma: %d usec\n", end - start);
+
+ I810LpRing.head &= HEAD_ADDR;
+ I810LpRing.space = I810LpRing.head - (I810LpRing.tail + 8);
+ if (I810LpRing.space < 0)
+ I810LpRing.space += I810LpRing.mem.Size;
+
+ if (I810LpRing.head == I810LpRing.tail)
+ return 0;
+
+ start = i810_usec();
+ I810Sync();
+ end = i810_usec();
+
+ if (start + 200 < end)
+ fprintf(stderr, "Sync in WaitForDma: %d usec\n", end - start);
+
+ return 1;
+}
+
+
+/*
+ * i810DmaResetBuffer
+ */
+void i810DmaResetBuffer( void ) {
+
+ i810glx.dma_buffer = dmaBuffers[ i810ActiveDmaBuffer ];
+ i810glx.dma_buffer->head = 0;
+ i810glx.dma_buffer->space = 0;
+ i810glx.dma_buffer->additional_space =
+ i810glx.dma_buffer->mem.Size - 256;
+
+ i810DmaOverflow( 0 );
+
+ if (i810glx.dma_buffer_age < i810glx.dma_buffer->texture_age)
+ i810glx.dma_buffer_age = i810glx.dma_buffer->texture_age;
+
+
+ /* This is required because each dma buffer is finished by a
+ * return to 2d state, as expected by the X server. Could
+ * alternately do the stuff to make the fallback inside the
+ * signal handler, but this way is nicer if we ever support
+ * multiple direct clients.
+ */
+/* if (i810Ctx) */
+/* i810Ctx->new_state |= I810_NEW_CONTEXT; */
+}
+
+
+
+
+/*
+ * i810FlushRealDma
+ */
+void i810FlushRealDma( void ) {
+
+ GLuint start;
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER)
+ fprintf(stderr, "i810FlushRealDma()\n" );
+
+
+ if ( i810glx.skipDma || !I810_USE_BATCH )
+ return;
+
+
+ if (i810glx.dma_buffer->head & 0x4) {
+ FatalError( "Misaligned batch buffer\n" );
+ }
+
+ if ( (I810_DEBUG&DEBUG_VERBOSE_OUTREG) && 0)
+ {
+ int i;
+ for (i = 0 ; i <= i810glx.dma_buffer->head ; i+=4)
+ fprintf(stderr,
+ " 0x%05x : 0x%08x\n",
+ i/4,
+ *(GLuint *)(i810glx.dma_buffer->virtual_start +
+ i));
+ }
+
+
+ /* fire the batch buffer */
+ for (start = 0 ; start < i810glx.dma_buffer->head ; start += MAX_BATCH)
+ {
+ GLuint ofs = i810glx.dma_buffer->mem.Start;
+ GLuint end = MIN2(start + MAX_BATCH, i810glx.dma_buffer->head);
+
+ BEGIN_LP_RING(4);
+
+/* if (I810_DEBUG & DEBUG_VERBOSE_RING) */
+if (0)
+ fprintf(stderr, "Fire: start: %x end: %x\n", start,end);
+
+ OUT_RING( CMD_OP_BATCH_BUFFER );
+ OUT_RING( (ofs + start) | BB1_PROTECTED );
+ OUT_RING( (ofs + end) - 4 );
+ OUT_RING( 0 );
+ ADVANCE_LP_RING();
+ }
+
+ {
+ BEGIN_LP_RING(2);
+ OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH |
+ INST_FLUSH_MAP_CACHE );
+ OUT_RING( 0 );
+ }
+}
+
+/*
+ * i810DmaFlush
+ * Send all pending commands off to the hardware.
+ * If we are running async, the hardware will be drawing
+ * while we return to do other things.
+ */
+void i810ServerDmaFlush( int wait ) {
+ int start, end;
+
+ if (I810_DEBUG)
+ fprintf(stderr,
+ "i810ServerDmaFlush, buffer %d, head %x space %x\n",
+ i810ActiveDmaBuffer,
+ i810glx.dma_buffer->head,
+ i810glx.dma_buffer->space);
+
+ if ( i810glx.dma_buffer->head == 0 )
+ {
+ if (wait && !i810WaitForDmaCompletion())
+ i810glx.hardwareWentIdle = 1;
+
+ return;
+ }
+
+ i810glx.c_dmaFlush++;
+
+ /* wait for the last buffer to complete */
+ if ( !i810WaitForDmaCompletion() )
+ i810glx.hardwareWentIdle = 1;
+
+
+ /* collect timing information if we are going syncronously */
+ if ( i810glx.dmaDriver != 3 ) {
+ start = i810_usec();
+ } else {
+ start = end = 0;
+ }
+
+ i810FlushRealDma();
+
+ if ( i810glx.dmaDriver == 2 ) {
+ /* wait until the dma completes */
+ i810WaitForDmaCompletion();
+ }
+
+ if ( i810glx.dmaDriver != 3 ) {
+ end = i810_usec();
+ }
+
+ i810Msg(10, "flushmode %i, buffer %i: prim dwords:%i usec:%i\n",
+ i810glx.dmaDriver, i810ActiveDmaBuffer,
+ i810glx.dma_buffer->head / 4,
+ end - start );
+
+ /* swap to using the other buffer */
+ i810ActiveDmaBuffer ^= 1;
+ i810DmaResetBuffer();
+
+ if ( wait )
+ i810WaitForDmaCompletion();
+}
+
+
+/*
+ * i810DmaFlush
+ */
+void i810DmaFlush( void ) {
+ i810FinishPrimitive();
+ i810glx.dma_buffer->texture_age = ++i810glx.current_texture_age;
+
+ if ( i810Ctx && i810Ctx->CurrentTex0Obj )
+ i810Ctx->CurrentTex0Obj->age = ++i810glx.current_texture_age;
+
+ if ( i810Ctx && i810Ctx->CurrentTex1Obj )
+ i810Ctx->CurrentTex1Obj->age = ++i810glx.current_texture_age;
+
+ i810DoDmaFlush( 0 );
+}
+
+
+/*
+ * i810DmaFinish
+ */
+void i810DmaFinish( void ) {
+ i810FinishPrimitive();
+ i810DoDmaFlush( 1 );
+
+ i810glx.dma_buffer_age = ++i810glx.current_texture_age;
+
+ if ( i810Ctx && i810Ctx->CurrentTex0Obj )
+ i810Ctx->CurrentTex0Obj->age = ++i810glx.current_texture_age;
+
+ if ( i810Ctx && i810Ctx->CurrentTex1Obj )
+ i810Ctx->CurrentTex1Obj->age = ++i810glx.current_texture_age;
+}
+
+
+/*
+ * i810DmaOverflow
+ * This is called when I810DMAGETPTR is at the end of the buffer
+ */
+void i810DmaOverflow( int newDwords ) {
+
+ if (i810glx.dma_buffer->additional_space) {
+ GLuint incr = MAX_BATCH;
+
+ if (i810glx.dma_buffer->additional_space < incr)
+ incr = i810glx.dma_buffer->additional_space;
+
+ while (i810glx.dma_buffer->head & (MAX_BATCH - 1)) {
+ GLuint outbatch = i810glx.dma_buffer->head;
+ GLubyte *virt = i810glx.dma_buffer->virtual_start;
+
+ *(volatile unsigned int *)(virt + outbatch) = 0;
+ i810glx.dma_buffer->head += 4;
+ }
+
+ i810glx.dma_buffer->space += incr;
+ i810glx.dma_buffer->additional_space -= incr;
+
+ if (0)
+ fprintf(stderr, "overflow, head %x space %x\n",
+ i810glx.dma_buffer->head,
+ i810glx.dma_buffer->space);
+ return;
+ }
+
+ i810Msg( 9, "i810DmaOverflow(%i)\n", newDwords );
+
+ /* flush all the current commands so we will have another
+ empty buffer */
+ i810DmaFlush();
+
+ /* Overflow can happen anywhere, so normal update mechanisms
+ * aren't sufficient.
+ if (i810Ctx) {
+ i810Ctx->new_state |= I810_NEW_CONTEXT;
+ i810DDUpdateHwState( i810Ctx->gl_ctx );
+ }
+ */
+
+ i810glx.c_overflows++;
+
+ if ( newDwords > i810glx.dma_buffer->space )
+ FatalError("i810DmaOverflow > maxPrimaryDwords");
+}
+
+
+/*
+ * i810WaitDrawingEngine
+ * This will not return until the drawing engine has completed
+ * drawing pixels and it is safe to read or write the framebuffer
+ * for software rendering.
+ */
+int i810WaitDrawingEngine( void ) {
+ /* note this for the performance block display */
+ i810glx.c_drawWaits++;
+
+ /* make sure all pending dma has completed */
+ i810DmaFinish();
+ return 0;
+}
+
+
+/*
+ * i810DmaExecute
+ * Add a block of data to the dma buffer
+ */
+void i810DmaExecute( GLuint *code, int dwords )
+{
+ int i;
+ BEGIN_BATCH(dwords);
+
+ if (dwords & 1)
+ FatalError( "Misaligned buffer in i810DmaExecute\n" );
+
+ for ( i = 0 ; i < dwords ; i++ )
+ OUT_BATCH( code[i] );
+ ADVANCE_BATCH();
+}
+
+
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dma.h b/xc/lib/GL/mesa/src/drv/i810/i810dma.h
new file mode 100644
index 000000000..55adbcddd
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810dma.h
@@ -0,0 +1,138 @@
+/*
+ GLX Hardware Device Driver for Intel i810
+ Copyright (C) 1999 Keith Whitwell <keithw@precisioninsight.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ original by Jeff Hartmann <slicer@ionet.net>
+ 6/16/99: rewrite by John Carmack <johnc@idsoftware.com>
+ Oct 99: port to i180 by Keith Whitwell <keithw@precisioninsight.com>
+*/
+
+#ifndef I810DMA_H
+#define I810DMA_H
+
+#include "i810common.h"
+#include "i810lib.h"
+#include "i810.h"
+#include "mm.h"
+
+/* the main initialization of the entire i810 hardware driver */
+GLboolean i810InitGLX( void );
+
+/* a flush command will guarantee that all data added to the dma buffer
+is on its way to the card, and will eventually complete with no more
+intervention.
+*/
+void i810DmaFlush(void);
+
+/* the overflow function is called when a block can't be allocated
+in the current dma buffer. It flushes the current buffer and
+records some information */
+void i810DmaOverflow(int newDwords);
+
+/* a finish command will guarantee that all dma commands have actually
+been consumed by the card. Note that there may still be a couple primitives
+that have not yet been executed out of the internal FIFO, so this does not
+guarantee that the drawing engine is idle. */
+void i810DmaFinish( void );
+
+/* a i810WaitDrawingEngine command will guarantee that the framebuffer
+is safe to read or write for software rendering */
+int i810WaitDrawingEngine( void );
+
+
+
+
+
+typedef struct {
+ I810MemRange mem;
+ char *virtual_start;
+ int head;
+ int space;
+ int additional_space;
+ int texture_age;
+} i810BatchBuffer;
+
+
+
+#define I810_USE_BATCH 1
+#if I810_USE_BATCH
+
+#define BEGIN_BATCH(n) \
+ unsigned int outbatch; \
+ volatile char *virt; \
+ if (I810_DEBUG & DEBUG_VERBOSE_RING) \
+ fprintf(stderr, \
+ "BEGIN_BATCH(%d) in %s\n" \
+ "(spc left %d/%d, head %x vstart %x start %x)\n", \
+ n, __FUNCTION__, i810glx.dma_buffer->space, \
+ i810glx.dma_buffer->mem.Size - i810glx.dma_buffer->head, \
+ i810glx.dma_buffer->head, \
+ i810glx.dma_buffer->virtual_start, \
+ i810glx.dma_buffer->mem.Start ); \
+ if (i810glx.dma_buffer->space < n*4) \
+ i810DmaOverflow(n); \
+ outbatch = i810glx.dma_buffer->head; \
+ virt = i810glx.dma_buffer->virtual_start;
+
+
+#define OUT_BATCH(val) { \
+ *(volatile unsigned int *)(virt + outbatch) = val; \
+ if (I810_DEBUG & DEBUG_VERBOSE_RING) \
+ fprintf(stderr, "OUT_BATCH %x: %x\n", outbatch/4, val); \
+ outbatch += 4; \
+}
+
+
+#define ADVANCE_BATCH() { \
+ if (I810_DEBUG & DEBUG_VERBOSE_RING) \
+ fprintf(stderr, "ADVANCE_BATCH(%f) in %s\n", \
+ (outbatch - i810glx.dma_buffer->head) / 4.0, \
+ __FUNCTION__); \
+ i810glx.dma_buffer->space -= outbatch - i810glx.dma_buffer->head; \
+ i810glx.dma_buffer->head = outbatch; \
+}
+
+#define FINISH_PRIM()
+
+#else
+
+/* Need some work to be able to do primitives this way.
+ */
+#define BEGIN_BATCH(n) BEGIN_LP_RING(n)
+#define ADVANCE_BATCH() ADVANCE_LP_RING()
+#define OUT_BATCH(val) OUT_RING(val)
+#define FINISH_PRIM() OUTREG(I810LpRing.base_reg + RING_TAIL, I810LpRing.tail)
+
+#endif
+
+
+/* These are only required by i810direct.c:
+ */
+extern GLuint i810ActiveDmaBuffer;
+extern void (*i810DoDmaFlush)( int );
+extern i810BatchBuffer *dmaBuffers[2];
+
+extern int i810WaitForDmaCompletion( void );
+extern void i810DmaResetBuffer( void );
+
+extern void i810DmaExecute( GLuint *code, int dwords );
+
+extern void I810Sync( void ) ;
+extern void I810WaitLpRing( int n );
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dmainit.c b/xc/lib/GL/mesa/src/drv/i810/i810dmainit.c
new file mode 100644
index 000000000..335c4a612
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810dmainit.c
@@ -0,0 +1,389 @@
+
+/* -*- mode: C; c-basic-offset:8 -*- */
+/*
+ * 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.
+ *
+ *
+ * based on the original by Jeff Hartmann <slicer@ionet.net>
+ * as rewritten by John Carmack <johnc@idsoftware.com>
+ */
+
+/*
+
+This file is only entered at startup. After i810GlxInit completes,
+nothing here will be executed again.
+
+*/
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "context.h"
+#include "depth.h"
+#include "macros.h"
+#include "texstate.h"
+#include "triangle.h"
+#include "vb.h"
+#include "types.h"
+
+#include "xsmesaP.h"
+#include "glx_log.h"
+#include "mesaglx/context.h"
+#include "mesaglx/matrix.h"
+#include "mesaglx/types.h"
+
+#define GC XXGC
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "servermd.h" /* PixmapBytePad */
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "windowstr.h"
+#undef GC
+
+#include "vga.h"
+#include "vgaPCI.h"
+#include "i810.h"
+#include "xaa/xf86xaa.h"
+
+#include "mm.h"
+#include "i810buf.h"
+#include "i810dd.h"
+#include "i810lib.h"
+#include "i810log.h"
+#include "i810direct.h"
+#include "i810glx.h"
+
+#include <agpgart.h>
+
+/* private vars */
+i810BatchBuffer *dmaBuffers[2];
+static I810MemRange I810SysMem2;
+
+
+static const char *getenvSafe(const char *name ) {
+ const char *r;
+
+ r = getenv( name );
+ if ( !r ) {
+ return "";
+ }
+ return r;
+}
+
+
+static void AllocateCommandBuffers( void )
+{
+ PMemBlock block;
+ GLuint bufferBytes = i810glx.cmdSize;
+ GLuint start, i;
+
+ if ( 1 || !bufferBytes ) {
+ fprintf(stderr,"temporarily hardwiring GLX_I810_CMDSIZE = 1\n" );
+ bufferBytes = 1;
+ }
+
+ bufferBytes *= 0x100000;
+
+ block = mmAllocMem( i810glx.sysmemHeap, bufferBytes, 8, 0 );
+
+ if ( !block ) {
+ fprintf(stderr,
+ "failed to allocate 0x%x bytes from "
+ "sysmemHeap for command buffers.\n",
+ bufferBytes );
+
+ FatalError("Couldn't get dma buffer\n");
+ }
+
+ start = block->ofs;
+
+ /* setup the two buffers that will be ping-ponged
+ */
+ for (i = 0 ; i < 2 ; i++) {
+ dmaBuffers[i] = calloc(1,sizeof(i810BatchBuffer));
+ dmaBuffers[i]->virtual_start = i810glx.sysmemVirtual + start;
+ dmaBuffers[i]->mem.Start = start;
+ dmaBuffers[i]->mem.Size = bufferBytes / 2;
+ dmaBuffers[i]->mem.End = (start += bufferBytes / 2);
+ }
+
+ i810DmaResetBuffer();
+}
+
+
+/* Another bit of duplication caused by 'static' code in the X server.
+ */
+static int gartfd;
+static struct gart_info gartinf;
+static char *gart_buf;
+
+static int AllocateGARTMemory( int size )
+{
+ int i, pages = size / 4096;
+ int start = vga256InfoRec.videoRam / 4; /* a crock! */
+ struct stat sb;
+
+ if (stat("/dev/agpgart", &sb) != 0) {
+ ErrorF("Stat failed on /dev/agpgart: %s\n",
+ sys_errlist[errno]);
+ return -1;
+ }
+
+ gartfd = open("/dev/agpgart", O_RDWR);
+ if (gartfd == -1) {
+ ErrorF("unable to open /dev/agpgart: %s\n",
+ sys_errlist[errno]);
+ FatalError("Aborting");
+ }
+
+ if (ioctl(gartfd, GARTIOCINFO, &gartinf) != 0) {
+ ErrorF("error doing ioctl(GARTIOCINFO): %s\n",
+ sys_errlist[errno]);
+ FatalError("Aborting");
+ }
+
+ /* Treat the gart like video memory - we assume we own all that is
+ * there, so ignore EBUSY errors. Don't try to remove it on
+ * failure, either.
+ */
+ for (i = start; i < start+pages; i++)
+ if (ioctl(gartfd, GARTIOCINSERT, &i) != 0) {
+ if (errno != EBUSY)
+ {
+ perror("gart insert");
+ ErrorF("GART: allocation of %d pages failed at page %d\n",
+ pages, i);
+ FatalError("Aborting");
+ }
+ }
+
+ ErrorF("GART: allocated %dK system ram\n", pages * 4);
+
+ I810SysMem2.Start = start * 4096;
+ I810SysMem2.End = (start + pages) * 4096;
+ I810SysMem2.Size = pages * 4096;
+
+ gart_buf = mmap( 0,
+ gartinf.size * 0x100000,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ gartfd,
+ 0 );
+
+ if ((unsigned int)gart_buf == ~0) {
+ perror("/dev/agpgart");
+ FatalError("Couldn't mmap /dev/agpgart - aborting");
+ }
+
+ return 0;
+}
+
+
+/*
+ * AllocateSystemMemory
+ * Looks at environment variables to determine if a block
+ * of physical memory has been left for graphics after the
+ * memory available to the kernel.
+ * System memory can be used for dma command buffers or
+ * textures.
+ */
+static void AllocateSystemMemory( void )
+{
+ GLuint sysmemBytes = i810glx.dmaSize;
+
+ if ( !sysmemBytes )
+ sysmemBytes = 8;
+
+ sysmemBytes *= 0x100000;
+
+ if (AllocateGARTMemory(sysmemBytes) != 0)
+ FatalError( "AllocateGARTMemory failed.\n" );
+
+
+ i810glx.sysmemVirtual = (unsigned char *)gart_buf;
+
+ /* Suck in any leftover memory from the 2d server.
+
+ i810glx.sysmemHeap = mmInit( I810SysMem.Start,
+ I810SysMem.Size );
+ */
+
+ /* Add our new memory.
+ */
+ i810glx.sysmemHeap =
+/* mmAddRange( i810glx.sysmemHeap, */
+ mmInit(
+ I810SysMem2.Start,
+ I810SysMem2.Size );
+
+
+ /* Manage dcache mem via. a seperate heap.
+ */
+ i810glx.cardHeap = mmInit( I810DcacheMem.Start,
+ I810DcacheMem.Size );
+
+ i810Msg( 1, "sysmemSize: 0x%x\n", sysmemBytes );
+ i810Msg( 1, "cardSize: 0x%lx\n", I810DcacheMem.Size );
+}
+
+
+
+/*
+ * i810DmaInit
+ *
+*/
+void i810DmaInit(void) {
+
+ /* Server init - queries environment variables. The client
+ * gets these values from the sever and initializes them in
+ * i810direct.c
+ */
+ if (__glx_is_server) {
+ i810glx.dmaDriver = atoi( getenvSafe("GLX_I810_DMA") );
+ i810glx.dmaSize = atoi( getenvSafe("GLX_I810_DMASIZE") );
+ i810glx.cmdSize = atoi( getenvSafe("GLX_I810_CMDSIZE") );
+
+ if (i810glx.dmaDriver != 3)
+ FatalError("GLX_I810_DMA not set\n");
+ }
+
+ /* get some system memory and make it write combining if we can */
+ AllocateSystemMemory();
+
+ /* read the command environment variable */
+ i810Msg(1,"i810DmaInit: GLX_I810_DMA = %i\n", i810glx.dmaDriver );
+
+ /* setup the two command buffers in the apropriate memory space */
+ AllocateCommandBuffers();
+
+ /* prepare the first buffer for use */
+ i810DmaResetBuffer();
+}
+
+
+/*
+ * This function should only verify that the current hardware is supported.
+ * It should do no setup.
+ */
+static GLboolean i810_detect_hw( void )
+{
+ if (I810Chipset == -1)
+ return GL_FALSE;
+
+ if (vga256InfoRec.depth != 15 &&
+ vga256InfoRec.depth != 16)
+ {
+ i810Error("Unsupported depth: %d, only 15 and 16d bpp "
+ "are supported right now\n",
+ vga256InfoRec.depth);
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+/*
+ * i810InitLogging
+ *
+ */
+void i810InitLogging( void )
+{
+ i810glx.logLevel = 100;
+}
+
+
+
+/*
+ * i810InitGLX
+ * This is the initial entry point for the i810 hardware driver,
+ * called at X server module load time, or libGL direct rendering
+ * init time.
+ */
+GLboolean i810InitGLX( void ) {
+
+ fprintf(stderr, "\n\n\n\ni810InitGLX\n");
+
+ i810InitLogging();
+
+ i810Msg(1,"virtual (x, y) (%d, %d)\n", vga256InfoRec.virtualX,
+ vga256InfoRec.virtualY);
+ i810Msg(1,"width: %d\n", vga256InfoRec.displayWidth);
+ i810Msg(1,"depth: %d\n", vga256InfoRec.depth);
+ i810Msg(1,"memBase: %p\n", vgaLinearBase);
+ i810Msg(1,"videoRam: 0x%08x\n", vga256InfoRec.videoRam);
+
+ if (!i810_detect_hw()) {
+ ErrorF("Couldn't find i810 hardware\n\n\n");
+ return GL_FALSE;
+ }
+
+ /* init the dma system */
+ i810DmaInit();
+
+ /* Register as a glx driver */
+ GLXProcs.CreateContext = i810GLXCreateContext;
+ GLXProcs.DestroyContext = i810GLXDestroyContext;
+ GLXProcs.SwapBuffers = i810GLXSwapBuffers;
+ GLXProcs.CreateImage = i810GLXCreateImage;
+ GLXProcs.DestroyImage = i810GLXDestroyImage;
+ GLXProcs.CreateDepthBuffer = i810GLXCreateDepthBuffer;
+ GLXProcs.MakeCurrent = i810GLXMakeCurrent;
+ GLXProcs.BindBuffer = i810GLXBindBuffer;
+ GLXProcs.SwapBuffers = i810GLXSwapBuffers;
+ GLXProcs.VendorPrivate = i810GLXVendorPrivate;
+ GLXProcs.AllowDirect = i810GLXAllowDirect;
+
+ if (!__glx_is_server) {
+ GLXProcs.ValidateFrontBuffer = i810ClientGetGeometry;
+ }
+
+ /* these vars can be changed between invocations of direct clients */
+ if (getenv("GLX_I810_NULLPRIMS") ) {
+ i810Msg( 1, "enabling GLX_I810_NULLPRIMS\n" );
+ i810glx.nullprims = 1;
+ }
+ if (getenv("GLX_I810_SKIPDMA") ) {
+ i810Msg( 1, "enabling GLX_I810_SKIPDMA\n" );
+ i810glx.skipDma = 1;
+ }
+ if (getenv("GLX_I810_BOXES") ) {
+ i810Msg( 1, "enabling GLX_I810_BOXES\n" );
+ i810glx.boxes = 1;
+ }
+ if (getenv("GLX_I810_NOFALLBACK") ) {
+ i810Msg( 1, "enabling GLX_I810_NOFALLBACK\n" );
+ i810glx.noFallback = 1;
+ }
+
+ i810Error("i810InitGLX completed\n");
+ return GL_TRUE;
+}
+
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810glx.c b/xc/lib/GL/mesa/src/drv/i810/i810glx.c
new file mode 100644
index 000000000..ba71623d6
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810glx.c
@@ -0,0 +1,650 @@
+/*
+ * 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.
+ *
+ */
+
+/* $Id: i810glx.c,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+#include <stdlib.h>
+
+#include "context.h"
+#include "depth.h"
+#include "macros.h"
+#include "texstate.h"
+#include "triangle.h"
+#include "vb.h"
+#include "types.h"
+
+#include "xsmesaP.h"
+#include "glx_log.h"
+#include "mesaglx/context.h"
+#include "mesaglx/matrix.h"
+#include "mesaglx/types.h"
+
+#define GC XXGC
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "servermd.h" /* PixmapBytePad */
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "windowstr.h"
+#undef GC
+
+#include "vga.h"
+#include "vgaPCI.h"
+#include "i810.h"
+#include "xaa/xf86xaa.h"
+
+#include "mm.h"
+#include "i810buf.h"
+#include "i810dd.h"
+#include "i810lib.h"
+#include "i810tris.h"
+#include "i810log.h"
+#include "i810direct.h"
+
+#include "i810dma.h"
+
+
+extern int xf86VTSema;
+extern XSMesaContext XSMesa;
+
+/* our collected globals */
+i810Glx_t i810glx;
+
+static void i810ServerSwapBuffers( XSMesaBuffer b );
+
+void (*i810GLXSwapBuffers)(XSMesaBuffer b) = i810ServerSwapBuffers;
+
+
+/* are these for the multi-hardware glx support? */
+GLboolean (*hwInitGLX)() = i810InitGLX;
+GLboolean (*hwInitVisuals)(VisualPtr *, DepthPtr *, int *, int *,
+ int *, VisualID *, unsigned long, int) = NULL;
+
+
+void i810DumpDB( struct i810_dest_buffer *buf )
+{
+ i810Msg(1,"\nCard Heap:");
+ mmDumpMemInfo( i810glx.cardHeap );
+ i810Msg(1,"\nSystem Heap:");
+ mmDumpMemInfo( i810glx.sysmemHeap );
+ i810Msg(1,"\nDump DB:\n");
+ i810Msg(1," %s %s\n",(buf->Drawable) ? "Drawable" : "-",
+ (buf->ZBuffer) ? "HasZORG" : "-");
+ i810Msg(1," w,h,p = %d,%d,%d\n",buf->Width,buf->Height,buf->Pitch);
+ i810Msg(1,"End Dump DB\n");
+}
+
+
+void i810GLXCreateDepthBuffer(GLcontext* ctx)
+{
+ XSMesaContext xsmesa = (XSMesaContext) ctx->DriverCtx;
+ struct i810_dest_buffer *buf;
+ struct i810_z_buffer *zb=0;
+
+ i810Msg( 1, "i810GLXCreateDepthBuffer\n" );
+
+ /* deallocate current depth buffer if present */
+ if (ctx->Buffer->Depth)
+ {
+ free(ctx->Buffer->Depth);
+ ctx->Buffer->Depth = NULL;
+ }
+
+ if (xsmesa->xsm_buffer->db_state == BACK_XIMAGE &&
+ xsmesa->xsm_buffer->backimage->devPriv != 0)
+ {
+ buf = (struct i810_dest_buffer *) xsmesa->xsm_buffer->backimage->devPriv;
+ zb = i810CreateZBuffer( buf );
+
+ if (!zb) {
+ /* We need a depth buffer, but cannot allocate it. So, disable hardware
+ acceleration. */
+ i810_setup_DD_pointers_no_accel( ctx );
+ }
+
+ if ( i810glx.logLevel >= 1 ) {
+ i810DumpDB(buf);
+ }
+ }
+
+ /* allocate new depth buffer, but don't initialize it */
+ /* FIXME: we shouldn't need to do this if we got a hardware buffer */
+ ctx->Buffer->Depth = (GLdepth *) malloc(ctx->Buffer->Width *
+ ctx->Buffer->Height *
+ sizeof(GLdepth));
+ if (!ctx->Buffer->Depth)
+ {
+ /* out of memory */
+ ctx->Depth.Test = GL_FALSE;
+ ErrorF("Couldn't allocate depth buffer\n" );
+ }
+
+}
+
+/*
+ * i810GLXDestroyImage
+ */
+void i810GLXDestroyImage(GLXImage* image)
+{
+ if (image->devPriv) {
+ i810DestroyDestBuffer((struct i810_dest_buffer *)image->devPriv);
+ if ( i810glx.logLevel >= 10 ) {
+ i810Msg(1, "\nAfter destroy image\nCard heap:\n");
+ mmDumpMemInfo( i810glx.cardHeap );
+ i810Msg(1, "System heap:\n");
+ mmDumpMemInfo( i810glx.sysmemHeap );
+ }
+ } else if (image->data)
+ free(image->data);
+ xfree(image);
+}
+
+/*
+ * i810GLXCreateImage
+ * We can't accelerate rendering to images
+ */
+GLXImage* i810GLXCreateImage(WindowPtr pwindow, int depth,
+ int width, int height)
+{
+ int Attrib;
+ struct i810_dest_buffer *buf;
+ GLXImage* image=(GLXImage*)xalloc(sizeof(GLXImage));
+
+ if (!image)
+ return (NULL);
+ image->pwin = pwindow;
+ image->width=width;
+ image->height=height;
+ image->bits_per_pixel=depth;
+ image->data=0;
+ image->devPriv=NULL;
+
+ Attrib = -1;
+ switch (depth)
+ {
+ case 8:
+ Attrib = DV_PF_INDEX;
+ break;
+ case 15:
+ Attrib = DV_PF_555;
+ break;
+ case 16:
+ Attrib = DV_PF_565;
+ break;
+ default:
+ i810Error("Unknown width in GLXCreateImage\n");
+ break;
+ }
+ if (Attrib != -1)
+ buf = i810CreateDestBuffer(Attrib,width,height);
+ else
+ buf = NULL;
+ image->devPriv = (void *) buf;
+ if (!image->devPriv) {
+ image->bytes_per_line=PixmapBytePad(width, depth);
+ image->data = (char *) malloc( image->height * image->bytes_per_line );
+ if (!image->data)
+ {
+ i810Error("i810GLXCreateImage: malloc failed.");
+ xfree(image);
+ image = NULL;
+ }
+ } else {
+ buf->refcount++;
+ image->bytes_per_line=buf->Pitch;
+ image->width = buf->Pitch / buf->BytesPerPixel;
+ image->data = buf->BufAddr;
+ }
+ if ( i810glx.logLevel >= 1 ) {
+ fprintf(stderr, "After i810GLXCreateImage\nCard heap:\n");
+ mmDumpMemInfo( i810glx.cardHeap );
+ fprintf(stderr, "System heap:\n");
+ mmDumpMemInfo( i810glx.sysmemHeap );
+ }
+ return (image);
+}
+
+
+/*
+ * i810BackToFront
+ *
+ * Blit the visible rectangles from the back buffer to the screen
+ * Can't really do this from a direct context - don't have the clip
+ * info, and getting it would be a lot slower than just sending a
+ * request to the server to do the blit there.
+ *
+ * drawable -- front buffer
+ * buf -- back buffer
+ */
+int i810BackToFront(DrawablePtr drawable,
+ struct i810_dest_buffer *buf)
+{
+ RegionPtr prgnClip;
+ BoxPtr pbox;
+ int i,nbox;
+ int ofs, xorg, yorg, pitch;
+
+ if ( !xf86VTSema ) {
+ i810Error("BackToFront(): !xf86VTSema\n");
+ return BadMatch; /* Is this really an error? */
+ }
+
+ if ( drawable->width != buf->Width ||
+ drawable->height != buf->Height ||
+ drawable->type != DRAWABLE_WINDOW ) {
+ i810Error("BackToFront(): bad drawable\n");
+ return BadMatch;
+ }
+
+ prgnClip = &((WindowPtr)drawable)->clipList;
+ pbox = REGION_RECTS(prgnClip);
+ nbox = REGION_NUM_RECTS(prgnClip);
+ if( !nbox ) return Success;
+
+ xorg = drawable->x;
+ yorg = drawable->y;
+ pitch = buf->Pitch;
+ ofs = buf->MemBlock->ofs;
+
+ {
+ unsigned int BR13 = ((vga256InfoRec.displayWidth * vgaBytesPerPixel) |
+ (0xCC << 16));
+
+
+ for (i=0; i < nbox; i++, pbox++) {
+ int x = pbox->x1 - xorg;
+ int y = pbox->y1 - yorg;
+ int w = pbox->x2 - pbox->x1;
+ int h = pbox->y2 - pbox->y1;
+
+ int start = ofs + x*vgaBytesPerPixel + y*pitch;
+ int dst = ((pbox->x1 + pbox->y1 * vga256InfoRec.displayWidth) *
+ vgaBytesPerPixel);
+
+ {
+ BEGIN_BATCH( 6 );
+ OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 );
+ OUT_BATCH( BR13 ); /* dest pitch, rop */
+
+ OUT_BATCH( (h << 16) | (w * vgaBytesPerPixel));
+ OUT_BATCH( dst );
+
+ OUT_BATCH( pitch ); /* src pitch */
+ OUT_BATCH( start );
+ ADVANCE_BATCH();
+ }
+ }
+ }
+
+ return Success;
+}
+
+
+/*
+ * ClearBox
+ * Add hardware commands to draw a filled box for the
+ * debugging display.
+ */
+static void ClearBox( int x, int y, int w, int h, int r, int g, int b )
+{
+ int start = (i810DB->MemBlock->ofs +
+ y * i810DB->Pitch +
+ x * vgaBytesPerPixel);
+
+ BEGIN_BATCH(6);
+
+ OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
+ OUT_BATCH( BR13_SOLID_PATTERN |
+ (0xF0 << 16) |
+ i810DB->Pitch );
+ OUT_BATCH( (h << 16) | (w * vgaBytesPerPixel));
+ OUT_BATCH( start );
+ OUT_BATCH( i810PackColor( r, g, b, 0 ) );
+ OUT_BATCH( 0 );
+
+ if (0)
+ fprintf(stderr, "box %d,%x %dx%d col %x (%d,%d,%d)\n", x,y,w,h,
+ i810PackColor( r, g, b, 0 ), r, g, b);
+
+ ADVANCE_BATCH();
+
+
+}
+
+
+/*
+ * performanceBoxes
+ * Draw some small boxesin the corner of the buffer
+ * based on some performance information
+ */
+void i810PerformanceBoxes( int is_direct ) {
+ int w, t;
+
+ if ( !i810glx.boxes || !i810DB ) {
+ return;
+ }
+
+ /* draw a box to show we are active, so if it is't seen
+ it means that it is completely software based rendering */
+ /* draw a purple box if we are direct rendering */
+ if ( is_direct ) { /* purple = direct (client dma) rendering */
+ ClearBox( 4, 4, 8, 8, 255, 0, 255 );
+ } else if ( i810glx.dmaDriver ) { /* white = server dma rendering */
+ ClearBox( 4, 4, 8, 8, 255, 255, 255 );
+ } else { /* grey = servery PDMA */
+ ClearBox( 4, 4, 8, 8, 128, 128, 128 );
+ }
+
+ /* draw a red box if we had to wait for drawing to complete
+ (software render or texture swap) */
+ if ( i810glx.c_drawWaits ) {
+ ClearBox( 16, 4, 8, 8, 255, 0, 0 );
+ i810glx.c_drawWaits = 0;
+ }
+
+ /* draw a blue box if the register protection signal was hit */
+ if ( i810glx.c_signals ) {
+ ClearBox( 28, 4, 8, 8, 0, 0, 255 );
+ i810glx.c_signals = 0;
+ }
+
+ /* draw a yellow box if textures were swapped */
+ if ( i810glx.c_textureSwaps ) {
+ ClearBox( 40, 4, 8, 8, 255, 255, 0 );
+ i810glx.c_textureSwaps = 0;
+ }
+
+
+ /* draw a green box if we had to wait for dma to complete (full utilization)
+ on the previous frame */
+ if ( !i810glx.hardwareWentIdle ) {
+ ClearBox( 64, 4, 8, 8, 0, 255, 0 );
+ }
+ i810glx.hardwareWentIdle = 0;
+
+ /* show buffer utilization */
+ if ( i810glx.c_dmaFlush > 1 ) {
+ /* draw a solid bar if we flushed more than one buffer */
+ ClearBox( 4, 16, 252, 4, 255, 32, 32 );
+ } else {
+ /* draw bars to represent the utilization of primary and secondary buffers */
+ ClearBox( 4, 16, 252, 4, 32, 32, 32 );
+ t = i810glx.dma_buffer->mem.Size;
+ w = 252 * i810glx.dma_buffer->head / t;
+ if ( w < 1 ) {
+ w = 1;
+ }
+ ClearBox( 4, 16, w, 4, 196, 128, 128 );
+ }
+ i810glx.c_dmaFlush = 0;
+}
+
+static void i810SendDmaFlush( void )
+{
+ BEGIN_BATCH(2);
+ OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH );
+ OUT_BATCH( 0 );
+ ADVANCE_BATCH();
+}
+
+
+/*
+ * Copy the back buffer to the front buffer. If there's no back buffer
+ * this is a no-op. Only called in indirect contexts.
+ */
+static void i810ServerSwapBuffers( XSMesaBuffer b )
+{
+ /* make sure mesa gives us everything */
+ if (i810Ctx && i810Ctx->gl_ctx)
+ glFlush();
+
+ if ( !b->db_state ) {
+ /* not double buffered, so do nothing */
+ } else {
+ ValidateGC(b->frontbuffer, b->cleargc);
+ if ( b->backimage ) {
+
+ struct i810_dest_buffer *buf =
+ (struct i810_dest_buffer *)b->backimage->devPriv;
+
+ if ( buf && buf->Drawable ) {
+
+ /* flush the last primitive */
+ i810FinishPrimitive();
+
+ /* Drop a flush op into the dma stream */
+ i810SendDmaFlush();
+
+ /* diagnostic drawing tools */
+ i810PerformanceBoxes( 0 );
+
+ /* hardware accelerated back to front blit */
+ i810BackToFront( (DrawablePtr)b->frontbuffer,buf );
+
+ /* make sure all dma is going to get executed if
+ * everything has gone well, this will be the only flush
+ * each frame
+ */
+ i810DmaFlush();
+
+ } else {
+ /* Use backimage's dimension (not buffer's) */
+ (*b->cleargc->ops->PutImage)((DrawablePtr)b->frontbuffer,
+ b->cleargc,
+ b->frontbuffer->depth,
+ 0, 0,
+ b->backimage->width,
+ b->backimage->height,
+ 0, ZPixmap, b->backimage->data);
+ }
+ } else {
+ /* Copy pixmap to window on server */
+ (*b->cleargc->ops->CopyArea)((DrawablePtr)b->backpixmap,
+ b->frontbuffer,
+ b->cleargc,
+ 0, 0, b->width, b->height,
+ 0, 0);
+ }
+ }
+
+ /* report performance counters */
+ i810Msg(10, "swapBuffers: c_triangles:%i c_lines:%i c_points:%i c_setup:%i c_textures:%i\n",
+ i810glx.c_triangles, i810glx.c_lines, i810glx.c_points, i810glx.c_setupPointers,
+ i810glx.c_textureSwaps );
+ i810glx.c_triangles = 0;
+ i810glx.c_lines = 0;
+ i810glx.c_points = 0;
+ i810glx.c_setupPointers = 0;
+ i810Msg(10, "---------------------------------------------------------\n" );
+}
+
+
+/*
+ * DoMakeCurrent
+ * Changing either the context or the buffer will force this.
+ */
+static int DoMakeCurrent(XSMesaContext c, XSMesaBuffer b) {
+ i810ContextPtr ctx, oldctx = i810Ctx;
+ struct i810_dest_buffer *buf, *oldbuf = i810DB;
+
+ i810Msg( 10, "DoMakeCurrent( %p, %p )\n", c, b );
+
+ i810Ctx = NULL;
+ i810DB = NULL;
+
+ if ( c ) {
+ ctx = c->hw_ctx;
+ if (!ctx) {
+ return -1;
+ }
+ } else {
+ ctx = NULL;
+ }
+
+ if ( b && b->buffer == XIMAGE ) {
+ buf = (struct i810_dest_buffer *) b->backimage->devPriv;
+ if (!buf->Drawable) {
+ buf = NULL;
+ }
+ } else {
+ buf = NULL;
+ }
+
+ if ( !ctx && buf ) {
+ return -1;
+ }
+ if (!ctx) {
+ return 0;
+ }
+
+ ctx->DB = buf;
+
+ /* valid conditions to render with */
+ i810Ctx = ctx;
+ i810DB = ctx->DB;
+
+ /* Even this is overkill:
+ */
+ if (oldctx != ctx || oldbuf != i810DB) {
+
+ if (i810DB) {
+ i810DmaExecute( i810DB->Setup, I810_DEST_SETUP_SIZE );
+ i810Ctx->Setup[I810_CTXREG_SCI2] = (i810DB->Width |
+ (i810DB->Height << 16));
+ }
+
+ i810Ctx->new_state |= I810_NEW_CONTEXT;
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER)
+ fprintf(stderr, "needEnter3D in DoMakeCurrent\n");
+ }
+
+
+ return 0;
+}
+
+
+/*
+ * i810GLXMakeCurrent
+ * Note that GLX calls this every batch of commands,
+ * so it will show up several times a frame even if
+ * the client application isn't issuing makeCurrent calls.
+ */
+GLboolean i810GLXMakeCurrent( XSMesaContext c ) {
+ if (c == XSMesa) {
+ return (GL_TRUE);
+ }
+
+ /* mesa 3.1 will sometimes leave unflushed vertexes */
+ if ( XSMesa ) {
+ glFlush();
+ }
+
+ i810Msg( 10, "i810GLXMakeCurrent( %p )\n", c );
+ XSMesa = c;
+ if (c) {
+ DoMakeCurrent(c,c->xsm_buffer);
+ gl_make_current(c->gl_ctx,
+ c->xsm_buffer ? c->xsm_buffer->gl_buffer : NULL);
+ } else {
+ /* detach */
+ DoMakeCurrent(NULL,NULL);
+ gl_make_current(NULL, NULL);
+ }
+ return(GL_TRUE);
+}
+
+/*
+ * Bind buffer b to context c and make c the current rendering context.
+ */
+GLboolean i810GLXBindBuffer( XSMesaContext c, XSMesaBuffer b ) {
+ i810Msg( 10, "i810GLXBindBuffer( %p, %p )\n", c, b );
+ DoMakeCurrent(c,b);
+ return(XSMesaBindBuffer(c,b));
+}
+
+
+/*
+ * Create a new XSMesaContext.
+ * Input: v - XSMesaVisual
+ * share_list - another XSMesaContext with which to share display
+ * lists or NULL if no sharing is wanted.
+ * Return: an XSMesaContext or NULL if error.
+ */
+XSMesaContext i810GLXCreateContext( XSMesaVisual v,
+ XSMesaContext share_list )
+{
+ XSMesaContext c;
+
+ i810Msg (0, "### Creating new xsmesa context for i810 ...\n" );
+
+ c = (XSMesaContext) calloc( 1, sizeof(struct xsmesa_context) );
+ if (!c)
+ {
+ return(NULL);
+ }
+
+ c->gl_ctx = gl_create_context(v->gl_visual,
+ share_list ? share_list->gl_ctx : NULL,
+ (void *) c, GL_TRUE /* direct rendering */);
+ if (!c->gl_ctx)
+ {
+ free(c);
+ return(NULL);
+ }
+
+ c->xsm_visual = v;
+ c->xsm_buffer = NULL; /* set later by XSMesaMakeCurrent */
+ c->pixelformat = v->dithered_pf; /* Dithering is enabled by default */
+ c->hw_ctx = (void *)i810CreateContext(c->gl_ctx);
+ if (!c->hw_ctx) {
+ i810Error("Cannot create hardware specific context.\n");
+ return (NULL);
+ }
+ ((i810ContextPtr)(c->hw_ctx))->refcount++;
+ c->gl_ctx->Driver.UpdateState = i810_setup_DD_pointers;
+
+ i810Msg( 1, "i810GLXCreateContext succeeded: %p\n", c );
+
+ return(c);
+}
+
+void i810GLXDestroyContext( XSMesaContext c ) {
+ i810Msg( 1, "i810GLXDestroyContext( %p )\n", c );
+
+ /* make sure all drawing is completed */
+ i810WaitDrawingEngine();
+
+ if (i810DestroyContext((i810ContextPtr) c->hw_ctx) != 0) {
+ i810Error("i810GLXDestroyContext(): i810DestroyContext() failed!\n");
+ }
+ XSMesaDestroyContext(c);
+ if ( XSMesa == c ) {
+ XSMesa = 0;
+ }
+}
+
+
+
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810glx.h b/xc/lib/GL/mesa/src/drv/i810/i810glx.h
new file mode 100644
index 000000000..f952af0d8
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810glx.h
@@ -0,0 +1,46 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ */
+
+/* $Id: i810glx.h,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+#ifndef I810GLX_INC
+#define I810GLX_INC
+
+void i810DumpDB(struct i810_dest_buffer *buf);
+void i810GLXCreateDepthBuffer(GLcontext* ctx);
+void i810GLXDestroyImage(GLXImage* image);
+GLXImage* i810GLXCreateImage(WindowPtr pwindow, int depth, int width, int height);
+GLboolean i810GLXMakeCurrent( XSMesaContext c );
+GLboolean i810GLXBindBuffer( XSMesaContext c, XSMesaBuffer b );
+XSMesaContext i810GLXCreateContext( XSMesaVisual v,
+ XSMesaContext share_list );
+void i810GLXDestroyContext( XSMesaContext c );
+
+extern int i810BackToFront(DrawablePtr drawable, struct i810_dest_buffer *buf);
+extern void (*i810GLXSwapBuffers)(XSMesaBuffer b);
+extern void i810PerformanceBoxes( int is_direct );
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810lib.c b/xc/lib/GL/mesa/src/drv/i810/i810lib.c
new file mode 100644
index 000000000..111b1a041
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810lib.c
@@ -0,0 +1,74 @@
+/*
+ * GLX Hardware Device Driver for Intel 810
+ * 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.
+ *
+ *
+ */
+
+/* $Id: i810lib.c,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+#include <unistd.h> /* for usleep() */
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "mesaglx/types.h" /* DEPTH_BITS */
+
+#include "mm.h"
+#include "i810lib.h"
+#include "i810log.h"
+
+struct i810_dest_buffer *i810DB = NULL;
+i810ContextPtr i810Ctx = NULL;
+
+int i810_usec( void )
+{
+ struct timeval tv;
+ struct timezone tz;
+
+ gettimeofday( &tv, &tz );
+
+ return (tv.tv_sec & 2047) * 1000000 + tv.tv_usec;
+}
+
+
+void i810SoftReset()
+{
+}
+
+/*
+ * - Palette format is TW16 (RGB565)
+ * - pal MUST be padded as follow: sizeof(pal) = (len+1)/2 dword
+ * - After the call you must reprogramm MACCESS and PITCH. It depends on
+ * which context you are in. (ie 2D or 3D)
+ */
+void i810LoadTexturePalette(GLushort *pal, int start, int len)
+{
+}
+
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810lib.h b/xc/lib/GL/mesa/src/drv/i810/i810lib.h
new file mode 100644
index 000000000..baa83b1be
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810lib.h
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ *
+ *
+ */
+
+/* $Id: i810lib.h,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+#ifndef I810LIB_INC
+#define I810LIB_INC
+
+#include <stdio.h>
+
+#include "i810common.h"
+#include "i810buf.h"
+#include "i810context.h"
+#include "mm.h"
+#include "i810log.h"
+#include "i810dma.h"
+
+#ifndef MESA31
+#error "The I810 driver now requires Mesa 3.1 or higher"
+#endif
+
+extern struct i810_dest_buffer *i810DB;
+extern i810ContextPtr i810Ctx;
+extern int i810In3DContext;
+
+typedef struct {
+ /* logging stuff */
+ GLuint logLevel;
+ FILE *logFile;
+
+ /* dma stuff */
+ GLuint dmaDriver;
+ GLuint dmaSize;
+ GLuint dmaAdr;
+ GLuint cmdSize;
+
+ /* bookkeeping for texture swaps */
+ GLuint dma_buffer_age;
+ GLuint current_texture_age;
+
+ /* options */
+ GLuint nullprims; /* skip all primitive generation */
+ GLuint boxes; /* draw performance boxes */
+ GLuint noFallback; /* don't fall back to software */
+ GLuint skipDma; /* don't send anything to hardware */
+
+ /* performance counters */
+ GLuint c_setupPointers;
+ GLuint c_triangles;
+ GLuint c_points;
+ GLuint c_lines;
+ GLuint c_drawWaits;
+ GLuint c_textureSwaps;
+ GLuint c_signals;
+ GLuint c_dmaFlush;
+ GLuint c_overflows;
+
+ GLuint hardwareWentIdle; /* cleared each swapbuffers, set if a
+ waitfordmacompletion ever exited
+ without having to wait */
+
+ /* Primitive managment (like warpSerie) */
+ GLuint prim_start;
+ GLuint prim_dwords;
+
+ /* card == dcache
+ * sysmem == normal gart memory
+ */
+ memHeap_t *cardHeap;
+ memHeap_t *sysmemHeap;
+ unsigned char *sysmemVirtual;
+
+ i810BatchBuffer *dma_buffer;
+
+} i810Glx_t;
+
+extern i810Glx_t i810glx;
+
+int i810_usec( void );
+void i810LibInit();
+void i810SoftReset();
+
+int i810MakeCurrent(i810ContextPtr ctx, struct i810_dest_buffer *buf);
+void i810LoadTexturePalette(unsigned short *pal, int start, int len);
+
+#define I810PACKCOLOR1555(r,g,b,a) \
+ ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
+ ((a) ? 0x8000 : 0))
+
+#define I810PACKCOLOR565(r,g,b) \
+ ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+
+#define I810PACKCOLOR4444(r,g,b,a) \
+ ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
+
+
+#include "i810_3d_reg.h"
+
+static __inline__ GLuint i810PackColor(GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a)
+{
+ switch (i810DB->Format) {
+ case DV_PF_555:
+ return I810PACKCOLOR1555(r,g,b,a);
+ case DV_PF_565:
+ return I810PACKCOLOR565(r,g,b);
+ default:
+ return 0;
+ }
+}
+
+
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810log.h b/xc/lib/GL/mesa/src/drv/i810/i810log.h
new file mode 100644
index 000000000..d74186e5f
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810log.h
@@ -0,0 +1,56 @@
+/* $Id: i810log.h,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+/*
+ * 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.
+ *
+ *
+ */
+
+/* Usage:
+ * - use i810Error for error messages. Always write to X error and log file.
+ * - use i810Msg for debugging. Can be disabled by undefining I810_LOG_ENABLED.
+ */
+
+#ifndef I810LOG_INC
+#define I810LOG_INC
+
+static __inline__ int i810OpenLog(const char *f) { return -1; }
+static __inline__ int i810IsLogReady() { return 0; }
+static __inline__ int i810GetLogLevel() { return -1; }
+static __inline__ int i810LogLevel(int level) { return 0; }
+
+#define i810CloseLog()
+#define i810SetLogLevel(x)
+#define i810Log(l,f,a...)
+#define i810Logv(l,f,a)
+
+#define DBG_LEVEL 10
+#define i810Msg(l,f,a...) do { \
+ if ((I810_DEBUG&DEBUG_VERBOSE_MSG) && l<DBG_LEVEL) \
+ fprintf(stderr, f, ## a); \
+} while(0)
+
+#define i810Error(format, args...) do { \
+ ErrorF(format, ## args); \
+} while(0)
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c
new file mode 100644
index 000000000..565608c99
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c
@@ -0,0 +1,120 @@
+/* #include "i810pipeline.h" */
+
+#include <stdio.h>
+#include "xsmesaP.h"
+#include "i810vb.h"
+#include "i810dd.h"
+#include "i810lib.h"
+#include "i810tris.h"
+
+#include "fog.h"
+
+#if 0
+
+static struct gl_pipeline_stage i810_fast_stage = {
+ "I810 fast path",
+ (PIPE_OP_VERT_XFORM|PIPE_OP_RAST_SETUP_0|
+ PIPE_OP_RAST_SETUP_1|PIPE_OP_RENDER),
+ PIPE_PRECALC,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ i810DDFastPath
+};
+
+
+#define ILLEGAL_ENABLES (TEXTURE0_3D| \
+ TEXTURE1_3D| \
+ ENABLE_TEXMAT0 | \
+ ENABLE_TEXMAT1 | \
+ ENABLE_TEXGEN0 | \
+ ENABLE_TEXGEN1 | \
+ ENABLE_USERCLIP | \
+ ENABLE_LIGHT | \
+ ENABLE_FOG)
+
+
+/* The driver gets first shot at building the pipeline - make some
+ * quick tests to see if we can use the fast path.
+ */
+GLboolean i810DDBuildPrecalcPipeline( GLcontext *ctx )
+{
+ struct gl_pipeline *pipe = &ctx->CVA.pre;
+
+ if (i810Ctx->renderindex == 0 &&
+ (ctx->Enabled & ILLEGAL_ENABLES) == 0 &&
+ (ctx->Array.Flags & (VERT_OBJ_234|
+ VERT_TEX0_4|
+ VERT_TEX1_4|
+ VERT_ELT)) == (VERT_OBJ_23|VERT_ELT))
+ {
+ pipe->stages[0] = &i810_fast_stage;
+ pipe->stages[1] = 0;
+ pipe->new_inputs = ctx->RenderFlags & VERT_DATA;
+ pipe->ops = pipe->stages[0]->ops;
+ i810Ctx->using_fast_path = 1;
+ return 1;
+ }
+
+ if (i810Ctx->using_fast_path)
+ {
+ i810Ctx->using_fast_path = 0;
+ ctx->CVA.VB->ClipOrMask = 0;
+ ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS;
+ ctx->Array.NewArrayState |= ctx->Array.Summary;
+ return 0;
+ }
+
+ return 0;
+}
+
+
+#endif
+
+
+
+
+
+GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr )
+{
+ GLuint i, o;
+
+ for (i = o = 0 ; i < nr ; i++) {
+ switch (in[i].ops) {
+
+#if 0
+ case PIPE_OP_RAST_SETUP_0:
+ out[o] = in[i];
+ out[o].cva_state_change = NEW_LIGHTING|NEW_TEXTURING|NEW_RASTER_OPS;
+ out[o].state_change = ~0;
+ out[o].check = i810DDCheckPartialRasterSetup;
+ out[o].run = i810DDPartialRasterSetup;
+ o++;
+ break;
+
+ case PIPE_OP_RAST_SETUP_0|PIPE_OP_RAST_SETUP_1:
+ out[o] = in[i];
+ out[o].run = i810DDDoRasterSetup;
+ o++;
+ break;
+#endif
+
+ /* Completely replace Mesa's fog processing to generate fog
+ * coordinates instead of messing with colors.
+ */
+ case PIPE_OP_FOG:
+ out[o] = gl_fog_coord_stage;
+ o++;
+ break;
+
+
+ default:
+ out[o++] = in[i];
+ break;
+ }
+ }
+
+ return o;
+}
+
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h
new file mode 100644
index 000000000..350f23431
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h
@@ -0,0 +1,10 @@
+#ifndef _I810_PIPELINE_H
+#define _I810_PIPELINE_H
+
+extern GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr );
+
+extern GLboolean i810DDBuildPrecalcPipeline( GLcontext *ctx );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.c b/xc/lib/GL/mesa/src/drv/i810/i810span.c
new file mode 100644
index 000000000..94c14e3ad
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810span.c
@@ -0,0 +1,111 @@
+#include "types.h"
+#include "i810buf.h"
+#include "i810dd.h"
+#include "i810lib.h"
+#include "i810dma.h"
+#include "i810log.h"
+
+static void (*xsmWriteRGBASpan)( const GLcontext *ctx,
+ GLuint n, GLint x, GLint y,
+ CONST GLubyte rgba[][4],
+ const GLubyte mask[] );
+static void (*xsmWriteRGBSpan)( const GLcontext *ctx,
+ GLuint n, GLint x, GLint y,
+ CONST GLubyte rgb[][3], const GLubyte mask[] );
+static void (*xsmWriteMonoRGBASpan)(const GLcontext *ctx, GLuint n,
+ GLint x, GLint y,const GLubyte mask[] );
+static void (*xsmWriteRGBAPixels)(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ CONST GLubyte rgba[][4],
+ const GLubyte mask[] );
+static void (*xsmWriteMonoRGBAPixels)(const GLcontext *ctx,GLuint n,
+ const GLint x[], const GLint y[],
+ const GLubyte mask[] );
+static void (*xsmReadRGBASpan)(const GLcontext *ctx, GLuint n,
+ GLint x, GLint y,GLubyte rgba[][4] );
+static void (*xsmReadRGBAPixels)(const GLcontext *ctx,GLuint n,
+ const GLint x[], const GLint y[],
+ GLubyte rgba[][4], const GLubyte mask[] );
+
+/* Wrapper functions */
+
+static void WriteRGBASpan( const GLcontext *ctx,
+ GLuint n, GLint x, GLint y,
+ CONST GLubyte rgba[][4],
+ const GLubyte mask[] )
+{
+ i810Msg(12,__FUNCTION__ "\n");
+ i810WaitDrawingEngine();
+ (*xsmWriteRGBASpan)(ctx,n,x,y,rgba,mask);
+}
+
+static void WriteRGBSpan( const GLcontext *ctx,
+ GLuint n, GLint x, GLint y,
+ CONST GLubyte rgb[][3], const GLubyte mask[] )
+{
+ i810Msg(12,__FUNCTION__ "\n");
+ i810WaitDrawingEngine();
+ (*xsmWriteRGBSpan)(ctx,n,x,y,rgb,mask);
+}
+
+static void WriteMonoRGBASpan(const GLcontext *ctx, GLuint n,
+ GLint x, GLint y,const GLubyte mask[] )
+{
+ i810Msg(12,__FUNCTION__ "\n");
+ i810WaitDrawingEngine();
+ (*xsmWriteMonoRGBASpan)(ctx,n,x,y,mask);
+}
+
+static void WriteRGBAPixels(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ CONST GLubyte rgba[][4],
+ const GLubyte mask[] )
+{
+ i810Msg(12,__FUNCTION__ "\n");
+ i810WaitDrawingEngine();
+ (*xsmWriteRGBAPixels)(ctx,n,x,y,rgba,mask);
+}
+
+static void WriteMonoRGBAPixels(const GLcontext *ctx,GLuint n,
+ const GLint x[], const GLint y[],
+ const GLubyte mask[] )
+{
+ i810Msg(12,__FUNCTION__ "\n");
+ i810WaitDrawingEngine();
+ (*xsmWriteMonoRGBAPixels)(ctx,n,x,y,mask);
+}
+
+static void ReadRGBASpan(const GLcontext *ctx, GLuint n,
+ GLint x, GLint y,GLubyte rgba[][4] )
+{
+ i810Msg(12,__FUNCTION__ "\n");
+ i810WaitDrawingEngine();
+ (*xsmReadRGBASpan)(ctx,n,x,y,rgba);
+}
+
+static void ReadRGBAPixels(const GLcontext *ctx,GLuint n,
+ const GLint x[], const GLint y[],
+ GLubyte rgba[][4], const GLubyte mask[] )
+{
+ i810Msg(12,__FUNCTION__ "\n");
+ i810WaitDrawingEngine();
+ (*xsmReadRGBAPixels)(ctx,n,x,y,rgba,mask);
+}
+
+#define WRAP(x) \
+ xsm ## x = ctx->Driver.x; \
+ ctx->Driver.x = x
+
+void i810DDInitSpans( GLcontext *ctx )
+{
+ /* Need another hook from mesa to synchronize hardware before
+ * write-pixels and read-spans/pixels.
+ */
+ WRAP(WriteRGBASpan);
+ WRAP(WriteRGBSpan);
+ WRAP(WriteMonoRGBASpan);
+ WRAP(WriteRGBAPixels);
+ WRAP(WriteMonoRGBAPixels);
+ WRAP(ReadRGBASpan);
+ WRAP(ReadRGBAPixels);
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.h b/xc/lib/GL/mesa/src/drv/i810/i810span.h
new file mode 100644
index 000000000..07276cd86
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810span.h
@@ -0,0 +1,6 @@
+#ifndef _I810_SPAN_H
+#define _I810_SPAN_H
+
+extern void i810DDInitSpans( GLcontext *ctx );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810state.c b/xc/lib/GL/mesa/src/drv/i810/i810state.c
new file mode 100644
index 000000000..18107ff74
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810state.c
@@ -0,0 +1,685 @@
+
+#include <stdio.h>
+
+#include "xsmesaP.h"
+
+#include "types.h"
+#include "pb.h"
+#include "dd.h"
+
+#include "glx_log.h"
+#include "mm.h"
+#include "i810lib.h"
+#include "i810glx.h"
+#include "i810dd.h"
+#include "i810context.h"
+#include "i810state.h"
+#include "i810depth.h"
+#include "i810tex.h"
+#include "i810log.h"
+#include "i810vb.h"
+#include "i810tris.h"
+
+
+
+static void i810DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ CARD32 a = (ZA_UPDATE_ALPHAFUNC|ZA_UPDATE_ALPHAREF);
+
+ switch (ctx->Color.AlphaFunc) {
+ case GL_NEVER: a |= ZA_ALPHA_NEVER; break;
+ case GL_LESS: a |= ZA_ALPHA_LESS; break;
+ case GL_GEQUAL: a |= ZA_ALPHA_GEQUAL; break;
+ case GL_LEQUAL: a |= ZA_ALPHA_LEQUAL; break;
+ case GL_GREATER: a |= ZA_ALPHA_GREATER; break;
+ case GL_NOTEQUAL: a |= ZA_ALPHA_NOTEQUAL; break;
+ case GL_EQUAL: a |= ZA_ALPHA_EQUAL; break;
+ case GL_ALWAYS: a |= ZA_ALPHA_ALWAYS; break;
+ default: return;
+ }
+
+ a |= ctx->Color.AlphaRef << ZA_ALPHAREF_SHIFT;
+
+ imesa->reg_dirty |= (1<<I810_CTXREG_ZA);
+ imesa->Setup[I810_CTXREG_ZA] &= ~(ZA_ALPHA_MASK|ZA_ALPHAREF_MASK);
+ imesa->Setup[I810_CTXREG_ZA] |= a;
+}
+
+/* This shouldn't get called, as the extension is disabled. However,
+ * there are internal Mesa calls, and rouge use of the api which must be
+ * caught.
+ */
+static void i810DDBlendEquation(GLcontext *ctx, GLenum mode)
+{
+ if (mode != GL_FUNC_ADD_EXT) {
+ ctx->Color.BlendEquation = GL_FUNC_ADD_EXT;
+ FatalError("Unsupported blend equation");
+ gl_error( ctx, GL_INVALID_OPERATION, "glBlendEquation (disabled)");
+ }
+}
+
+static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint a;
+
+ a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND;
+
+ switch (ctx->Color.BlendSrcRGB) {
+ case GL_ZERO: a |= SDM_SRC_ZERO; break;
+ case GL_SRC_ALPHA: a |= SDM_SRC_SRC_ALPHA; break;
+ case GL_ONE: a |= SDM_SRC_ONE; break;
+ case GL_DST_COLOR: a |= SDM_SRC_DST_COLOR; break;
+ case GL_ONE_MINUS_DST_COLOR: a |= SDM_SRC_INV_DST_COLOR; break;
+ case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_SRC_INV_SRC_ALPHA; break;
+ case GL_DST_ALPHA: a |= SDM_SRC_ONE; break;
+ case GL_ONE_MINUS_DST_ALPHA: a |= SDM_SRC_ZERO; break;
+ case GL_SRC_ALPHA_SATURATE:
+ a |= SDM_SRC_SRC_ALPHA; /* use GFXRENDERSTATE_COLOR_FACTOR ??? */
+ break;
+ default:
+ FatalError("unknown blend source func");
+ return;
+ }
+
+ switch (ctx->Color.BlendDstRGB) {
+ case GL_SRC_ALPHA: a |= SDM_DST_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_DST_INV_SRC_ALPHA; break;
+ case GL_ZERO: a |= SDM_DST_ZERO; break;
+ case GL_ONE: a |= SDM_DST_ONE; break;
+ case GL_SRC_COLOR: a |= SDM_DST_SRC_COLOR; break;
+ case GL_ONE_MINUS_SRC_COLOR: a |= SDM_DST_INV_SRC_COLOR; break;
+ case GL_DST_ALPHA: a |= SDM_DST_ONE; break;
+ case GL_ONE_MINUS_DST_ALPHA: a |= SDM_DST_ZERO; break;
+ default:
+ FatalError("unknown blend dst func");
+ return;
+ }
+
+ imesa->reg_dirty |= (1<<I810_CTXREG_SDM);
+ imesa->Setup[I810_CTXREG_SDM] &= ~(SDM_SRC_MASK|SDM_DST_MASK);
+ imesa->Setup[I810_CTXREG_SDM] |= a;
+}
+
+
+/* Shouldn't be called as the extension is disabled.
+ */
+static void i810DDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
+ GLenum dfactorRGB, GLenum sfactorA,
+ GLenum dfactorA )
+{
+ if (dfactorRGB != dfactorA || sfactorRGB != sfactorA) {
+ gl_error( ctx, GL_INVALID_OPERATION, "glBlendEquation (disabled)");
+ }
+
+ i810DDBlendFunc( ctx, sfactorRGB, dfactorRGB );
+}
+
+
+
+static void i810DDDepthFunc(GLcontext *ctx, GLenum func)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ int zmode;
+
+ switch(func) {
+ case GL_NEVER: zmode = LCS_Z_NEVER; break;
+ case GL_ALWAYS: zmode = LCS_Z_ALWAYS; break;
+ case GL_LESS: zmode = LCS_Z_LESS; break;
+ case GL_LEQUAL: zmode = LCS_Z_LEQUAL; break;
+ case GL_EQUAL: zmode = LCS_Z_EQUAL; break;
+ case GL_GREATER: zmode = LCS_Z_GREATER; break;
+ case GL_GEQUAL: zmode = LCS_Z_GEQUAL; break;
+ case GL_NOTEQUAL: zmode = LCS_Z_NOTEQUAL; break;
+ default: return;
+ }
+
+ /* Could just fire it off now...
+ */
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_Z_MASK;
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_UPDATE_ZMODE | zmode;
+ imesa->reg_dirty |= (1<<I810_CTXREG_LCS);
+}
+
+static void i810DDDepthMask(GLcontext *ctx, GLboolean flag)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ imesa->reg_dirty |= (1<<I810_CTXREG_B2);
+ imesa->Setup[I810_CTXREG_B2] &= ~B2_ZB_WRITE_ENABLE;
+ imesa->Setup[I810_CTXREG_B2] |= B2_UPDATE_ZB_WRITE_ENABLE;
+
+ if (flag)
+ imesa->Setup[I810_CTXREG_B2] |= B2_ZB_WRITE_ENABLE;
+
+/*
+ Possible technique to reduce the amount of checking for small state
+ changes. Large ones detect wrap on update_count & just send the
+ whole state...
+
+ {
+ imesa->Update[imesa->update_count & MAX_UPDATE] =
+ ( imesa->Setup[I810_CTXREG_B2] &
+ (B1_ZB_WRITE_ENABLE | B1_UPDATE_ZB_WRITE_ENABLE | GFX_OP_BOOL_1)
+ );
+ imesa->update_count++;
+ }
+*/
+}
+
+
+
+
+
+
+
+
+
+
+/* =============================================================
+ * Hardware clipping
+ */
+
+
+static void i810DDScissor( GLcontext *ctx, GLint x, GLint y,
+ GLsizei w, GLsizei h )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ int x1,x2,y1,y2;
+
+ x1 = ctx->Scissor.X;
+ x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
+ y1 = i810DB->Height - ctx->Scissor.Y - ctx->Scissor.Height;
+ y2 = i810DB->Height - ctx->Scissor.Y - 1;
+
+ if (x1 < 0) x1 = 0;
+ if (y1 < 0) y1 = 0;
+ if (x2 >= i810DB->Width) x2 = i810DB->Width-1;
+ if (y2 >= i810DB->Height) y2 = i810DB->Height-1;
+
+ if (x1 > x2 || y1 > y2) {
+ x1 = 0; x2 = 0;
+ y2 = 0; y1 = 1;
+ }
+
+ /* Turn it off if full screen?
+ */
+ imesa->Setup[I810_CTXREG_SCI0] = GFX_OP_SCISSOR_INFO;
+ imesa->Setup[I810_CTXREG_SCI1] = (y1<<16)|x1;
+ imesa->Setup[I810_CTXREG_SCI2] = (y2<<16)|x2;
+
+
+ i810Ctx->reg_dirty |= ((1<<I810_CTXREG_SCI0) |
+ (1<<I810_CTXREG_SCI1) |
+ (1<<I810_CTXREG_SCI2));
+}
+
+
+/* =============================================================
+ * Culling - the i810 isn't quite as clean here as the rest of
+ * its interfaces, but it's not bad.
+ */
+static void i810DDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint mode = LCS_CULL_BOTH;
+
+ if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
+ mode = LCS_CULL_CW;
+ if (ctx->Polygon.CullFaceMode == GL_FRONT)
+ mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW);
+ if (ctx->Polygon.FrontFace != GL_CCW)
+ mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW);
+ }
+
+ imesa->LcsCullMode = mode;
+
+ if (ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON)
+ {
+ imesa->reg_dirty |= (1<<I810_CTXREG_LCS);
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
+ imesa->Setup[I810_CTXREG_LCS] |= (LCS_UPDATE_CULL_MODE | mode);
+ }
+}
+
+
+static void i810DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim )
+{
+ if (ctx->Polygon.CullFlag) {
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint mode = imesa->LcsCullMode;
+
+ if (ctx->PB->primitive != GL_POLYGON)
+ mode = LCS_CULL_DISABLE;
+
+ imesa->reg_dirty |= (1<<I810_CTXREG_LCS);
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
+ imesa->Setup[I810_CTXREG_LCS] |= (LCS_UPDATE_CULL_MODE | mode);
+ }
+}
+
+
+
+/* =============================================================
+ * Color masks
+ */
+
+/* Mesa calls this from the wrong place.
+ *
+ * Its a fallback...
+ */
+static GLboolean i810DDColorMask(GLcontext *ctx,
+ GLboolean r, GLboolean g,
+ GLboolean b, GLboolean a )
+{
+ return 1;
+}
+
+/* Seperate specular not fully implemented in hardware... Needs
+ * some interaction with material state? Just punt to software
+ * in all cases?
+ */
+static void i810DDLightModelfv(GLcontext *ctx, GLenum pname,
+ const GLfloat *param)
+{
+ if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
+ I810_CONTEXT(ctx)->new_state |= I810_NEW_TEXTURE;
+ }
+}
+
+
+
+/* =============================================================
+ * Fog
+ */
+
+void i810DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ if (pname == GL_FOG_COLOR) {
+ GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) |
+ ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
+ ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
+
+ imesa->reg_dirty |= (1<<I810_CTXREG_FOG);
+ imesa->Setup[I810_CTXREG_FOG] = ((GFX_OP_FOG_COLOR | color) &
+ ~FOG_RESERVED_MASK);
+ }
+}
+
+
+/* =============================================================
+ */
+
+static void i810DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ switch(cap) {
+ case GL_ALPHA_TEST:
+ imesa->reg_dirty |= (1<<I810_CTXREG_B1);
+ imesa->Setup[I810_CTXREG_B1] &= ~B1_ALPHA_TEST_ENABLE;
+ imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_ALPHA_TEST_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_B1] |= B1_ALPHA_TEST_ENABLE;
+ break;
+ case GL_BLEND:
+ imesa->reg_dirty |= (1<<I810_CTXREG_B1);
+ imesa->Setup[I810_CTXREG_B1] &= ~B1_BLEND_ENABLE;
+ imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_BLEND_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_B1] |= B1_BLEND_ENABLE;
+ break;
+ case GL_DEPTH_TEST:
+ imesa->reg_dirty |= (1<<I810_CTXREG_B1);
+ imesa->Setup[I810_CTXREG_B1] &= ~B1_Z_TEST_ENABLE;
+ imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_Z_TEST_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_B1] |= B1_Z_TEST_ENABLE;
+ break;
+ case GL_SCISSOR_TEST:
+ imesa->reg_dirty |= (1<<I810_CTXREG_SC);
+ imesa->Setup[I810_CTXREG_SC] &= ~SC_ENABLE_MASK;
+ imesa->Setup[I810_CTXREG_SC] |= SC_UPDATE_SCISSOR;
+ if (state)
+ imesa->Setup[I810_CTXREG_SC] |= SC_ENABLE;
+ break;
+ case GL_FOG:
+ imesa->reg_dirty |= (1<<I810_CTXREG_B1);
+ imesa->Setup[I810_CTXREG_B1] &= ~B1_FOG_ENABLE;
+ imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_FOG_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_B1] |= B1_FOG_ENABLE;
+ break;
+ case GL_CULL_FACE:
+ if (ctx->PB->primitive == GL_POLYGON) {
+ imesa->reg_dirty |= (1<<I810_CTXREG_LCS);
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_UPDATE_CULL_MODE;
+ if (state)
+ imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsCullMode;
+ else
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
+ }
+ break;
+ case GL_TEXTURE_2D:
+ imesa->reg_dirty |= (1<<I810_CTXREG_MT);
+ if (ctx->Texture.CurrentUnit == 0) {
+ imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE;
+ imesa->Setup[I810_CTXREG_MT] |= MT_UPDATE_TEXEL0_STATE;
+ if (state)
+ imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE;
+ } else {
+ imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE;
+ imesa->Setup[I810_CTXREG_MT] |= MT_UPDATE_TEXEL1_STATE;
+ if (state)
+ imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE;
+ }
+
+ I810_CONTEXT(ctx)->new_state |= I810_NEW_TEXTURE;
+ break;
+ default:
+ ;
+ }
+}
+
+
+/* Don't use the regs parm yet.
+ */
+static void i810UpdateRegs( GLcontext *ctx, GLuint regs )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ int i;
+
+ {
+ BEGIN_BATCH( I810_CTX_SETUP_SIZE );
+
+ for (i = 0 ; i < I810_CTX_SETUP_SIZE ; i++) {
+ OUT_BATCH( imesa->Setup[i] );
+ }
+
+ ADVANCE_BATCH();
+ }
+
+ imesa->reg_dirty = 0;
+}
+
+
+/* =============================================================
+ */
+
+/* Delightfully few possibilities:
+ */
+void i810DDPrintState( const char *msg, GLuint state )
+{
+ fprintf(stderr, "%s (0x%x): %s\n",
+ msg,
+ state,
+ (state & I810_NEW_TEXTURE) ? "texture, " : "");
+}
+
+void i810DDUpdateHwState( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ if (imesa->new_state & I810_NEW_TEXTURE)
+ i810UpdateTextureState( ctx );
+
+ imesa->new_state = 0;
+
+ if (imesa->reg_dirty) {
+ i810FinishPrimitive();
+ i810UpdateRegs( ctx, imesa->reg_dirty );
+ }
+}
+
+
+
+void i810DDInitStatePointers(GLcontext *ctx)
+{
+ ctx->Driver.Enable = i810DDEnable;
+ ctx->Driver.LightModelfv = i810DDLightModelfv;
+ ctx->Driver.AlphaFunc = i810DDAlphaFunc;
+ ctx->Driver.BlendEquation = i810DDBlendEquation;
+ ctx->Driver.BlendFunc = i810DDBlendFunc;
+ ctx->Driver.BlendFuncSeparate = i810DDBlendFuncSeparate;
+ ctx->Driver.DepthFunc = i810DDDepthFunc;
+ ctx->Driver.DepthMask = i810DDDepthMask;
+ ctx->Driver.Fogfv = i810DDFogfv;
+ ctx->Driver.Scissor = i810DDScissor;
+ ctx->Driver.CullFace = i810DDCullFaceFrontFace;
+ ctx->Driver.FrontFace = i810DDCullFaceFrontFace;
+ ctx->Driver.ColorMask = i810DDColorMask;
+ ctx->Driver.ReducedPrimitiveChange = i810DDReducedPrimitiveChange;
+ ctx->Driver.RenderStart = i810DDUpdateHwState;
+ ctx->Driver.RenderFinish = 0;
+}
+
+
+void i810DDInitState( i810ContextPtr imesa )
+{
+
+ imesa->Setup[I810_CTXREG_VF] = (GFX_OP_VERTEX_FMT |
+ VF_TEXCOORD_COUNT_2 |
+ VF_SPEC_FOG_ENABLE |
+ VF_RGBA_ENABLE |
+ VF_XYZW);
+
+ imesa->Setup[I810_CTXREG_MT] = (GFX_OP_MAP_TEXELS |
+ MT_UPDATE_TEXEL1_STATE |
+ MT_TEXEL1_COORD1 |
+ MT_TEXEL1_MAP1 |
+ MT_TEXEL1_DISABLE |
+ MT_UPDATE_TEXEL0_STATE |
+ MT_TEXEL0_COORD0 |
+ MT_TEXEL0_MAP0 |
+ MT_TEXEL0_DISABLE);
+
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_ITERATED_COLOR |
+ MC_ARG1_DONT_REPLICATE_ALPHA |
+ MC_ARG1_DONT_INVERT |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_ARG2_DONT_REPLICATE_ALPHA |
+ MC_ARG2_DONT_INVERT |
+ MC_UPDATE_OP |
+ MC_OP_ARG1 );
+
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_ONE |
+ MC_ARG1_DONT_REPLICATE_ALPHA |
+ MC_ARG1_DONT_INVERT |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_ARG2_DONT_REPLICATE_ALPHA |
+ MC_ARG2_DONT_INVERT |
+ MC_UPDATE_OP |
+ MC_OP_DISABLE );
+
+
+ imesa->Setup[I810_CTXREG_MC2] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_2 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_CURRENT_COLOR |
+ MC_ARG1_REPLICATE_ALPHA |
+ MC_ARG1_DONT_INVERT |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_ARG2_DONT_REPLICATE_ALPHA |
+ MC_ARG2_DONT_INVERT |
+ MC_UPDATE_OP |
+ MC_OP_DISABLE );
+
+
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_ARG1_DONT_INVERT |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_CURRENT_ALPHA |
+ MA_ARG2_DONT_INVERT |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+
+
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_ARG1_DONT_INVERT |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_CURRENT_ALPHA |
+ MA_ARG2_DONT_INVERT |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+
+
+ imesa->Setup[I810_CTXREG_MA2] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_2 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_ARG1_DONT_INVERT |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_CURRENT_ALPHA |
+ MA_ARG2_DONT_INVERT |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+
+
+ imesa->Setup[I810_CTXREG_SDM] = ( GFX_OP_SRC_DEST_MONO |
+ SDM_UPDATE_SRC_BLEND |
+ SDM_SRC_ONE |
+ SDM_UPDATE_DST_BLEND |
+ SDM_DST_ZERO );
+
+ /* Use for colormask:
+ */
+ imesa->Setup[I810_CTXREG_CF0] = GFX_OP_COLOR_FACTOR;
+ imesa->Setup[I810_CTXREG_CF1] = 0xffffffff;
+
+ imesa->Setup[I810_CTXREG_ZA] = (GFX_OP_ZBIAS_ALPHAFUNC |
+ ZA_UPDATE_ALPHAFUNC |
+ ZA_ALPHA_ALWAYS |
+ ZA_UPDATE_ZBIAS |
+ 0 |
+ ZA_UPDATE_ALPHAREF |
+ 0x0);
+
+ imesa->Setup[I810_CTXREG_FOG] = (GFX_OP_FOG_COLOR |
+ (0xffffff & ~FOG_RESERVED_MASK));
+
+ /* Choose a pipe
+ */
+ imesa->Setup[I810_CTXREG_B1] = ( GFX_OP_BOOL_1 |
+ B1_UPDATE_SPEC_SETUP_ENABLE |
+ 0 |
+ B1_UPDATE_ALPHA_SETUP_ENABLE |
+ B1_ALPHA_SETUP_ENABLE |
+ B1_UPDATE_CI_KEY_ENABLE |
+ 0 |
+ B1_UPDATE_CHROMAKEY_ENABLE |
+ 0 |
+ B1_UPDATE_Z_BIAS_ENABLE |
+ 0 |
+ B1_UPDATE_SPEC_ENABLE |
+ 0 |
+ B1_UPDATE_FOG_ENABLE |
+ 0 |
+ B1_UPDATE_ALPHA_TEST_ENABLE |
+ 0 |
+ B1_UPDATE_BLEND_ENABLE |
+ 0 |
+ B1_UPDATE_Z_TEST_ENABLE |
+ 0 );
+
+ imesa->Setup[I810_CTXREG_B2] = ( GFX_OP_BOOL_2 |
+ B2_UPDATE_MAP_CACHE_ENABLE |
+ B2_MAP_CACHE_ENABLE |
+ B2_UPDATE_ALPHA_DITHER_ENABLE |
+ 0 |
+ B2_UPDATE_FOG_DITHER_ENABLE |
+ 0 |
+ B2_UPDATE_SPEC_DITHER_ENABLE |
+ 0 |
+ B2_UPDATE_RGB_DITHER_ENABLE |
+ B2_RGB_DITHER_ENABLE |
+ B2_UPDATE_FB_WRITE_ENABLE |
+ B2_FB_WRITE_ENABLE |
+ B2_UPDATE_ZB_WRITE_ENABLE |
+ B2_ZB_WRITE_ENABLE );
+
+ imesa->Setup[I810_CTXREG_LCS] = ( GFX_OP_LINEWIDTH_CULL_SHADE_MODE |
+ LCS_UPDATE_ZMODE |
+ LCS_Z_LESS |
+ LCS_UPDATE_LINEWIDTH |
+ (0x2<<LCS_LINEWIDTH_SHIFT) |
+ LCS_UPDATE_ALPHA_INTERP |
+ LCS_ALPHA_INTERP |
+ LCS_UPDATE_FOG_INTERP |
+ 0 |
+ LCS_UPDATE_SPEC_INTERP |
+ 0 |
+ LCS_UPDATE_RGB_INTERP |
+ LCS_RGB_INTERP |
+ LCS_UPDATE_CULL_MODE |
+ LCS_CULL_DISABLE);
+
+ imesa->LcsCullMode = LCS_CULL_CW;
+
+ imesa->Setup[I810_CTXREG_SCI0] = GFX_OP_SCISSOR_INFO;
+ imesa->Setup[I810_CTXREG_SCI1] = 0;
+ imesa->Setup[I810_CTXREG_SCI2] = 0;
+
+ imesa->Setup[I810_CTXREG_SC] = ( GFX_OP_SCISSOR |
+ SC_UPDATE_SCISSOR |
+ 0 );
+
+ imesa->Setup[I810_CTXREG_PV] = ( GFX_OP_PV_RULE |
+ PV_UPDATE_PIXRULE |
+ PV_PIXRULE_ENABLE |
+ PV_UPDATE_LINELIST |
+ PV_LINELIST_PV0 |
+ PV_UPDATE_TRIFAN |
+ PV_TRIFAN_PV0 |
+ PV_UPDATE_TRISTRIP |
+ PV_TRISTRIP_PV0 );
+
+}
+
+
+
+#define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\
+ NEW_TEXTURE_MATRIX|\
+ NEW_USER_CLIP|NEW_CLIENT_STATE|\
+ NEW_TEXTURE_ENABLE))
+
+void i810DDUpdateState( GLcontext *ctx )
+{
+ if (ctx->NewState & INTERESTED) {
+ i810FinishPrimitive();
+ i810DDChooseRenderState(ctx);
+ i810ChooseRasterSetupFunc(ctx);
+ }
+
+ /* TODO: stop mesa from clobbering these.
+ */
+ ctx->Driver.PointsFunc=i810Ctx->PointsFunc;
+ ctx->Driver.LineFunc=i810Ctx->LineFunc;
+ ctx->Driver.TriangleFunc=i810Ctx->TriangleFunc;
+ ctx->Driver.QuadFunc=i810Ctx->QuadFunc;
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810state.h b/xc/lib/GL/mesa/src/drv/i810/i810state.h
new file mode 100644
index 000000000..1cccb44bb
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810state.h
@@ -0,0 +1,11 @@
+#ifndef _I810_STATE_H
+#define _I810_STATE_H
+
+
+extern void i810DDInitStatePointers(GLcontext *ctx);
+extern void i810DDUpdateHwState( GLcontext *ctx );
+extern void i810DDUpdateState( GLcontext *ctx );
+extern void i810DDInitState( i810ContextPtr imesa );
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.c b/xc/lib/GL/mesa/src/drv/i810/i810tex.c
new file mode 100644
index 000000000..e6e658a7d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.c
@@ -0,0 +1,1144 @@
+/*
+ * 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.
+ *
+ */
+
+/* $Id: i810tex.c,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+#include "xsmesaP.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <GL/gl.h>
+
+#include "mm.h"
+#include "i810lib.h"
+#include "i810tex.h"
+#include "i810log.h"
+#include "simple_list.h"
+#include "enums.h"
+
+static void i810SetTexWrapping(i810TextureObjectPtr tex, GLenum s, GLenum t)
+{
+ unsigned int val = tex->Setup[I810_TEXREG_MCS];
+
+ val &= ~(MCS_U_STATE_MASK|MCS_V_STATE_MASK);
+ val |= (MCS_U_WRAP|MCS_V_WRAP);
+
+ if (s != GL_REPEAT)
+ val ^= (MCS_U_WRAP^MCS_U_CLAMP);
+
+ if (t != GL_REPEAT)
+ val ^= (MCS_V_WRAP^MCS_V_CLAMP);
+
+ tex->Setup[I810_TEXREG_MCS] = val;
+ tex->reg_dirty |= (1 << I810_TEXREG_MCS);
+}
+
+static void i810SetTexFilter(i810TextureObjectPtr t, GLenum minf, GLenum magf)
+{
+ GLuint LastLevel;
+
+ switch (minf) {
+ case GL_NEAREST:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MIN_MASK | MF_MIP_MASK,
+ MF_MIN_NEAREST | MF_MIP_NONE);
+ break;
+ case GL_LINEAR:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MIN_MASK | MF_MIP_MASK,
+ MF_MIN_LINEAR | MF_MIP_NONE);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MIN_MASK | MF_MIP_MASK,
+ MF_MIN_NEAREST | MF_MIP_NEAREST);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MIN_MASK | MF_MIP_MASK,
+ MF_MIN_LINEAR | MF_MIP_NEAREST);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MIN_MASK | MF_MIP_MASK,
+ MF_MIN_NEAREST | MF_MIP_DITHER );
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MIN_MASK | MF_MIP_MASK,
+ MF_MIN_LINEAR | MF_MIP_DITHER );
+ break;
+ default:
+ i810Error("i810SetTexFilter(): not supported min. filter %d\n",(int)minf);
+ break;
+ }
+
+ switch (magf) {
+ case GL_NEAREST:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MAG_MASK,MF_MAG_NEAREST);
+ break;
+ case GL_LINEAR:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MAG_MASK,MF_MAG_LINEAR);
+ break;
+ default:
+ i810Error("i810SetTexFilter(): not supported mag. filter %d\n",(int)magf);
+ break;
+ }
+
+
+ if (t->globj->MinFilter != GL_NEAREST &&
+ t->globj->MinFilter != GL_LINEAR) {
+ LastLevel = t->max_level;
+ } else {
+ LastLevel = t->min_level;
+ }
+
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MLL],
+ MLL_MAX_MIP_MASK,
+ (t->min_level << (MLL_MAX_MIP_SHIFT+4)));
+
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MLL],
+ MLL_MIN_MIP_MASK,
+ (LastLevel << MLL_MIN_MIP_SHIFT));
+
+ /* See OpenGL 1.2 specification */
+ if (magf == GL_LINEAR && (minf == GL_NEAREST_MIPMAP_NEAREST ||
+ minf == GL_NEAREST_MIPMAP_LINEAR))
+ {
+ /* c = 0.5 */
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MLC],
+ MLC_LOD_BIAS_MASK,
+ 0x10);
+ } else {
+ /* c = 0 */
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MLC],
+ MLC_LOD_BIAS_MASK,
+ 0x0);
+ }
+
+ t->reg_dirty |= ((1<<I810_TEXREG_MLC) |
+ (1<<I810_TEXREG_MLL) |
+ (1<<I810_TEXREG_MF));
+}
+
+
+/* Need a fallback ?
+ */
+static void i810SetTexBorderColor(i810TextureObjectPtr t, GLubyte color[4])
+{
+/* t->Setup[I810_TEXREG_TEXBORDERCOL] = */
+/* I810PACKCOLOR8888(color[0],color[1],color[2],color[3]); */
+}
+
+
+
+static void ReplicateMesaTexState(i810TextureObjectPtr t,
+ struct gl_texture_object *mesatex)
+{
+ i810SetTexWrapping(t,mesatex->WrapS,mesatex->WrapT);
+ i810SetTexFilter(t,mesatex->MinFilter,mesatex->MagFilter);
+ i810SetTexBorderColor(t,mesatex->BorderColor);
+}
+
+i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx,
+ struct gl_texture_object *tObj)
+{
+ i810TextureObjectPtr t;
+ GLuint height, width, pitch, i, textureFormat, log_pitch;
+ struct gl_texture_image *image;
+
+ image = tObj->Image[ 0 ];
+ if ( !image ) {
+ fprintf(stderr, "no image at level zero - not creating texobj\n");
+ return 0;
+ }
+
+ t = (i810TextureObjectPtr) calloc(1,sizeof(*t));
+ if (!t)
+ return 0;
+
+ switch( image->Format ) {
+ case GL_RGB:
+ case GL_LUMINANCE:
+ case GL_ALPHA:
+ t->texelBytes = 2;
+ textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_RGB565;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_RGBA:
+ t->texelBytes = 2;
+ textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_ARGB4444;
+ break;
+ case GL_COLOR_INDEX:
+ textureFormat = MI1_FMT_8CI | MI1_PF_8CI_ARGB4444;
+ t->texelBytes = 1;
+ t->UsePalette = 1;
+ break;
+ default:
+ i810Error( "i810CreateTexObj: bad image->Format\n" );
+ free( t );
+ return 0;
+ }
+
+
+ /* Figure out the size now (and count the levels). Upload won't be done
+ * until later.
+ */
+ width = image->Width * t->texelBytes;
+ for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 )
+ log_pitch++;
+
+ t->dirty_images = 0;
+
+ for ( height = i = 0 ; i < I810_TEX_MAXLEVELS && tObj->Image[i] ; i++ ) {
+ t->image[i].image = tObj->Image[i];
+ t->image[i].offset = height * pitch;
+ t->image[i].internalFormat = image->Format;
+ t->dirty_images |= (1<<i);
+ height += t->image[i].image->Height;
+ }
+
+ t->Pitch = pitch;
+ t->totalSize = height*pitch;
+ t->max_level = i-1;
+ t->min_level = 0;
+ t->globj = tObj;
+ t->age = 0;
+ t->reg_dirty = ~0;
+
+ t->Setup[I810_TEXREG_MI0] = GFX_OP_MAP_INFO;
+
+ t->Setup[I810_TEXREG_MI1] = (MI1_MAP_0 |
+ textureFormat |
+ log_pitch);
+
+ t->Setup[I810_TEXREG_MI2] = (MI2_DIMENSIONS_ARE_LOG2 |
+ (image->HeightLog2 << 16) |
+ (image->WidthLog2));
+
+ t->Setup[I810_TEXREG_MI3] = 0;
+
+ t->Setup[I810_TEXREG_MLC] = (GFX_OP_MAP_LOD_CTL |
+ MLC_MAP_0 |
+ MLC_DITHER_WEIGHT_FULL |
+ MLC_UPDATE_LOD_BIAS |
+ 0x0);
+
+ t->Setup[I810_TEXREG_MLL] = (GFX_OP_MAP_LOD_LIMITS |
+ MLL_MAP_0 |
+ MLL_UPDATE_MAX_MIP |
+ (t->min_level << MLL_MAX_MIP_SHIFT) |
+ MLL_UPDATE_MIN_MIP |
+ t->max_level);
+
+ /* I think this is context state, really.
+ */
+ t->Setup[I810_TEXREG_MCS] = (GFX_OP_MAP_COORD_SETS |
+ MCS_COORD_0 |
+ MCS_UPDATE_NORMALIZED |
+ MCS_NORMALIZED_COORDS |
+ MCS_UPDATE_V_STATE |
+ MCS_V_WRAP |
+ MCS_UPDATE_U_STATE |
+ MCS_U_WRAP);
+
+ t->Setup[I810_TEXREG_MF] = (GFX_OP_MAP_FILTER |
+ MF_MAP_0 |
+ MF_UPDATE_ANISOTROPIC |
+ 0 |
+ MF_UPDATE_MIP_FILTER |
+ MF_MIP_NEAREST |
+ MF_UPDATE_MAG_FILTER |
+ MF_MAG_NEAREST |
+ MF_UPDATE_MIN_FILTER |
+ MF_MIN_NEAREST);
+
+ t->current_unit = 0;
+
+ ReplicateMesaTexState(t,tObj);
+ tObj->DriverData = t;
+ insert_at_head(&ctx->SwappedOut, t);
+ return t;
+}
+
+int i810DestroyTexObj(i810ContextPtr ctx, i810TextureObjectPtr t)
+{
+ if (t) {
+ if (t->age > i810glx.dma_buffer_age)
+ i810WaitDrawingEngine();
+
+ mmFreeMem(t->MemBlock);
+ t->MemBlock = 0;
+ remove_from_list(t);
+ free(t);
+ }
+ return 0;
+}
+
+
+/* Card memory management
+ */
+static void i810SwapOutOldestTexObj( i810ContextPtr ctx )
+{
+ i810TextureObjectPtr t = ctx->TexObjList.prev;
+
+ fprintf(stderr, "swap out oldest, age %d, dma age %d\n",
+ t->age, i810glx.dma_buffer_age);
+
+ if (t->age > i810glx.dma_buffer_age)
+ i810WaitDrawingEngine();
+
+ mmFreeMem( t->MemBlock );
+ t->MemBlock = 0;
+ t->dirty_images = ~0;
+ move_to_tail(&ctx->SwappedOut, t);
+}
+
+/* Just allocates the memory - doesn't do the upload.
+ */
+static int i810SwapInTexObj( i810ContextPtr ctx, i810TextureObjectPtr t)
+{
+ i810Msg(10," Swapping in texture.\n");
+ i810glx.c_textureSwaps++;
+
+ /* Try to allocate textureHeap memory, swapping out stuff until we
+ * can.
+ */
+ while (1)
+ {
+ t->MemBlock = mmAllocMem( i810glx.sysmemHeap, t->totalSize, 12, 0 );
+
+ if (t->MemBlock)
+ break;
+
+ if (is_empty_list(&ctx->TexObjList))
+ return -1;
+
+ i810SwapOutOldestTexObj( ctx );
+ }
+
+ t->Setup[I810_TEXREG_MI3] = t->MemBlock->ofs;
+ t->BufAddr = i810glx.sysmemVirtual + t->MemBlock->ofs;
+ t->reg_dirty |= ((1<<I810_TEXREG_MI0) |
+ (1<<I810_TEXREG_MI1) |
+ (1<<I810_TEXREG_MI2) |
+ (1<<I810_TEXREG_MI3));
+ return 0;
+}
+
+/* Upload an image from mesa's internal copy.
+ */
+static int i810UploadTexLevel( i810TextureObjectPtr t, int level )
+{
+ const struct gl_texture_image *image = t->image[level].image;
+ int i,j;
+
+ i810Msg(10,"CopyImage():\n");
+
+ /* Need triangle (rather than pixel) fallbacks to simulate this using
+ * normal textured triangles.
+ */
+ if (image->Border != 0)
+ i810Error("Not supported texture border %d.\n",image->Border);
+
+ switch (t->image[level].internalFormat) {
+ case GL_RGB:
+ {
+ GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ i810Msg(10," CopyRGB: %p %p\n", dst, src);
+
+ for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) {
+ for (i = 0 ; i < image->Width ; i++) {
+ dst[i] = I810PACKCOLOR565(src[0],src[1],src[2]);
+ src += 3;
+ }
+ }
+ }
+ break;
+
+ case GL_RGBA:
+ {
+ GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ i810Msg(10," CopyRGBA: %p %p\n", dst, src);
+
+ for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) {
+ for (i = 0 ; i < image->Width ; i++) {
+ dst[i] = I810PACKCOLOR4444(src[0],src[1],src[2],src[3]);
+ src += 4;
+ }
+ }
+ }
+ break;
+
+ case GL_LUMINANCE:
+ {
+ GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ i810Msg(10," CopyL: %p %p\n", dst, src);
+
+ for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) {
+ for (i = 0 ; i < image->Width ; i++) {
+ dst[i] = I810PACKCOLOR565(src[0],src[0],src[0]);
+ src ++;
+ }
+ }
+ }
+ break;
+
+ case GL_INTENSITY:
+ {
+ GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ int i;
+ i810Msg(10," CopyI: %p %p\n", dst, src);
+
+ for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) {
+ for (i = 0 ; i < image->Width ; i++) {
+ dst[i] = I810PACKCOLOR4444(src[0],src[0],src[0],src[0]);
+ src ++;
+ }
+ }
+ }
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ {
+ GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ i810Msg(10," CopyLA: %p %p\n", dst, src);
+
+ for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) {
+ for (i = 0 ; i < image->Width ; i++) {
+ dst[i] = I810PACKCOLOR4444(src[0],src[0],src[0],src[1]);
+ src += 2;
+ }
+ }
+ }
+ break;
+
+ case GL_COLOR_INDEX:
+ {
+ GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[level].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ i810Msg(10," CopyIndex: %p %p\n", dst, src);
+
+ for (j = 0 ; j < image->Height ; j++, dst += t->Pitch) {
+ for (i = 0 ; i < image->Width ; i++) {
+ dst[i] = src[0];
+ src += 1;
+ }
+ }
+
+ t->UsePalette = I810_USE_PALETTE;
+ }
+ break;
+
+ default:
+ i810Error("Not supported texture format %d\n",image->Format);
+ FatalError("bummer");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+static int i810UploadTexImages( i810ContextPtr ctx, i810TextureObjectPtr t )
+{
+ int i;
+ i810glx.c_textureSwaps++;
+
+ if (!t->MemBlock)
+ i810SwapInTexObj( ctx, t );
+
+ if (t->age > i810glx.dma_buffer_age)
+ i810WaitDrawingEngine();
+
+ for (i = t->min_level ; i <= t->max_level ; i++)
+ if (t->dirty_images & (1<<i)) {
+ if (i810UploadTexLevel( t, i ) != 0)
+ return -1;
+ }
+
+ t->dirty_images = 0;
+ return 0;
+}
+
+static void i810TexSetUnit( i810TextureObjectPtr t, GLuint unit )
+{
+ if (t->current_unit == unit) return;
+
+ t->Setup[I810_TEXREG_MI1] ^= (MI1_MAP_0 ^ MI1_MAP_1);
+ t->Setup[I810_TEXREG_MLC] ^= (MLC_MAP_0 ^ MLC_MAP_1);
+ t->Setup[I810_TEXREG_MLL] ^= (MLL_MAP_0 ^ MLL_MAP_1);
+ t->Setup[I810_TEXREG_MCS] ^= (MCS_COORD_0 ^ MCS_COORD_1);
+ t->Setup[I810_TEXREG_MF] ^= (MF_MAP_0 ^ MF_MAP_1);
+
+ t->reg_dirty = ~0;
+ t->current_unit = unit;
+}
+
+
+
+
+static void i810UpdateTex0State( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ struct gl_texture_object *tObj;
+ i810TextureObjectPtr t;
+ int ma_modulate_op;
+
+
+ tObj = ctx->Texture.Unit[0].Current;
+
+ if ( tObj != ctx->Texture.Unit[0].CurrentD[2] )
+ tObj = 0;
+
+ if (!(ctx->Texture.Enabled & 0xf) || !tObj || !tObj->Complete) {
+
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_ITERATED_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_UPDATE_OP |
+ MC_OP_ARG1 );
+
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ITERATED_ALPHA |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_TEX0_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+
+ imesa->reg_dirty |= ((1<<I810_CTXREG_MA0) |
+ (1<<I810_CTXREG_MC0));
+ return;
+ }
+
+ t = tObj->DriverData;
+
+ if (!t) {
+ t = i810CreateTexObj( imesa, tObj );
+ if (!t) return;
+ }
+
+ if (t->current_unit != 0)
+ i810TexSetUnit( t, 0 );
+
+ if (t->dirty_images)
+ i810UploadTexImages(imesa, t);
+
+ t->age = ++i810glx.current_texture_age;
+ move_to_head(&imesa->TexObjList, t);
+
+ imesa->CurrentTex0Obj = t;
+
+ if (0)
+ if (t->UsePalette == I810_USE_PALETTE) {
+ if (ctx->Texture.SharedPalette) {
+ if (imesa->GlobalPaletteUpdated)
+ i810LoadTexturePalette(imesa->GlobalPalette,0,256);
+ imesa->GlobalPaletteUpdated = 0;
+ }
+ else {
+ i810LoadTexturePalette(t->Palette,0,256);
+ imesa->GlobalPaletteUpdated = 1;
+ }
+ }
+
+
+ if (t->reg_dirty)
+ i810DmaExecute(t->Setup,I810_TEX_SETUP_SIZE);
+
+
+ switch (ctx->Texture.Unit[0].EnvMode) {
+ case GL_REPLACE:
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_TEX0_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_UPDATE_OP |
+ MC_OP_ARG1 );
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ ma_modulate_op = MA_OP_ARG1;
+ } else {
+ ma_modulate_op = MA_OP_ARG2;
+ }
+
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ITERATED_ALPHA |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_TEX0_ALPHA |
+ MA_UPDATE_OP |
+ ma_modulate_op );
+ break;
+ case GL_MODULATE:
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_TEX0_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ITERATED_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_MODULATE );
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ ma_modulate_op = MA_OP_ARG1;
+ } else {
+ ma_modulate_op = MA_OP_MODULATE;
+ }
+
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ITERATED_ALPHA |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_TEX0_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_MODULATE );
+ break;
+ case GL_DECAL:
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_COLOR_FACTOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_TEX0_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_ARG2 );
+
+ } else {
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_COLOR_FACTOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_TEX0_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_LIN_BLEND_TEX0_ALPHA );
+ }
+
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ALPHA_FACTOR |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_ALPHA_FACTOR |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+ break;
+ case GL_BLEND:
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_COLOR_FACTOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ITERATED_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_LIN_BLEND_TEX0_COLOR );
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ALPHA_FACTOR |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_ITERATED_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+ } else {
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ALPHA_FACTOR |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_ITERATED_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_LIN_BLEND_TEX0_ALPHA );
+ }
+ break;
+
+ default:
+ FatalError("unkown tex env mode");
+ break;
+ }
+
+
+
+ imesa->reg_dirty |= ((1<<I810_CTXREG_MA0) |
+ (1<<I810_CTXREG_MC0));
+
+}
+
+
+
+static void i810UpdateTex1State( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ struct gl_texture_object *tObj;
+ i810TextureObjectPtr t;
+ int ma_modulate_op;
+
+
+ tObj = ctx->Texture.Unit[1].Current;
+
+ if ( tObj != ctx->Texture.Unit[1].CurrentD[2] )
+ tObj = 0;
+
+ if (!(ctx->Texture.Enabled & 0xf0) || !tObj || !tObj->Complete) {
+
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_ONE |
+ MC_ARG1_DONT_REPLICATE_ALPHA |
+ MC_ARG1_DONT_INVERT |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_ARG2_DONT_REPLICATE_ALPHA |
+ MC_ARG2_DONT_INVERT |
+ MC_UPDATE_OP |
+ MC_OP_DISABLE );
+
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_ARG1_DONT_INVERT |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_CURRENT_ALPHA |
+ MA_ARG2_DONT_INVERT |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+
+ imesa->reg_dirty |= ((1<<I810_CTXREG_MA1) |
+ (1<<I810_CTXREG_MC1));
+ return;
+ }
+
+ t = tObj->DriverData;
+
+ if (!t) {
+ t = i810CreateTexObj( imesa, tObj );
+ if (!t) return;
+ }
+
+ if (t->dirty_images)
+ i810UploadTexImages(imesa, t);
+
+ if (t->current_unit != 1)
+ i810TexSetUnit( t, 1 );
+
+ t->age = ++i810glx.current_texture_age;
+ move_to_head(&imesa->TexObjList, t);
+ imesa->CurrentTex1Obj = t;
+
+ if (0)
+ if (t->UsePalette == I810_USE_PALETTE) {
+ if (ctx->Texture.SharedPalette) {
+ if (imesa->GlobalPaletteUpdated)
+ i810LoadTexturePalette(imesa->GlobalPalette,0,256);
+ imesa->GlobalPaletteUpdated = 0;
+ }
+ else {
+ i810LoadTexturePalette(t->Palette,0,256);
+ imesa->GlobalPaletteUpdated = 1;
+ }
+ }
+
+
+ if (t->reg_dirty)
+ i810DmaExecute(t->Setup,I810_TEX_SETUP_SIZE);
+
+
+
+ switch (ctx->Texture.Unit[1].EnvMode) {
+ case GL_REPLACE:
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_TEX1_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_UPDATE_OP |
+ MC_OP_ARG1 );
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ ma_modulate_op = MA_OP_ARG1;
+ } else {
+ ma_modulate_op = MA_OP_ARG2;
+ }
+
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_TEX1_ALPHA |
+ MA_UPDATE_OP |
+ ma_modulate_op );
+ break;
+ case GL_MODULATE:
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_TEX1_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_CURRENT_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_MODULATE );
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ ma_modulate_op = MA_OP_ARG1;
+ } else {
+ ma_modulate_op = MA_OP_MODULATE;
+ }
+
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_TEX1_ALPHA |
+ MA_UPDATE_OP |
+ ma_modulate_op );
+ break;
+
+ case GL_DECAL:
+ if (t->image[0].internalFormat == GL_RGB) {
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_COLOR_FACTOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_TEX1_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_ARG2 );
+
+ } else {
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_COLOR_FACTOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_TEX1_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_LIN_BLEND_TEX1_ALPHA );
+ }
+
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ALPHA_FACTOR |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_ALPHA_FACTOR |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+ break;
+
+ case GL_BLEND:
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_COLOR_FACTOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_CURRENT_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_LIN_BLEND_TEX1_COLOR );
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ALPHA_FACTOR |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_CURRENT_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+ } else {
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ALPHA_FACTOR |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_ITERATED_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_LIN_BLEND_TEX1_ALPHA );
+ }
+ break;
+
+ default:
+ FatalError("unkown tex 1 env mode");
+ break;
+ }
+
+ imesa->reg_dirty |= ((1<<I810_CTXREG_MA1) |
+ (1<<I810_CTXREG_MC1));
+}
+
+
+void i810UpdateTextureState( GLcontext *ctx )
+{
+ i810UpdateTex0State( ctx );
+ i810UpdateTex1State( ctx );
+}
+
+
+
+/*****************************************
+ * Driver functions
+ *****************************************/
+
+void i810TexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param )
+{
+ if (!i810Ctx)
+ return;
+
+
+ if (pname == GL_TEXTURE_ENV_MODE) {
+
+ i810Ctx->new_state |= I810_NEW_TEXTURE;
+
+ } else if (pname == GL_TEXTURE_ENV_COLOR) {
+
+ struct gl_texture_unit *texUnit =
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ GLubyte c[4];
+ GLuint col;
+
+ FLOAT_RGBA_TO_UBYTE_RGBA(texUnit->EnvColor, c);
+ col = i810PackColor(c[0],c[1],c[2],c[3]);
+
+ if (i810DB->Setup[I810_CTXREG_CF1] != col) {
+ i810DB->Setup[I810_CTXREG_CF1] = col;
+ i810Ctx->reg_dirty |= (1<<I810_CTXREG_CF1);
+ }
+ }
+}
+
+void i810TexImage( GLcontext *ctx,
+ GLenum target,
+ struct gl_texture_object *tObj,
+ GLint level,
+ GLint internalFormat,
+ const struct gl_texture_image *image )
+{
+ i810TextureObjectPtr t;
+
+ CHECK_CONTEXT( return; );
+
+ i810Msg(10,"i810TexImage(%d): level %d internalFormat %x\n",
+ tObj->Name, level, internalFormat);
+
+ if (target != GL_TEXTURE_2D)
+ return;
+
+ if (level >= I810_TEX_MAXLEVELS)
+ return;
+
+ t = (i810TextureObjectPtr) tObj->DriverData;
+ if (t) {
+ /* if this is the current object, it will force an update */
+ i810DestroyTexObj( i810Ctx, t );
+ tObj->DriverData = 0;
+ i810Ctx->new_state |= I810_NEW_TEXTURE;
+ }
+}
+
+void i810TexSubImage( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLint internalFormat,
+ const struct gl_texture_image *image )
+{
+ i810TextureObjectPtr t;
+ i810Msg(10,"i810TexSubImage():\n");
+ i810Msg(10," Size: %d,%d of %d,%d; Level %d\n",
+ width, height, image->Width,image->Height,
+ level);
+
+ CHECK_CONTEXT( return; );
+
+ if ( target != GL_TEXTURE_2D )
+ return;
+
+ t = (i810TextureObjectPtr) tObj->DriverData;
+ if (t) {
+ i810DestroyTexObj( i810Ctx, t );
+ tObj->DriverData = 0;
+ i810Ctx->new_state |= I810_NEW_TEXTURE;
+ i810glx.c_textureSwaps++;
+ }
+}
+
+void i810TexParameter( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params )
+{
+ i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData;
+
+ CHECK_CONTEXT( return; );
+
+ if (!t || target != GL_TEXTURE_2D)
+ return;
+
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ i810SetTexFilter(t,tObj->MinFilter,tObj->MagFilter);
+ break;
+
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ i810SetTexWrapping(t,tObj->WrapS,tObj->WrapT);
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ i810SetTexBorderColor(t,tObj->BorderColor);
+ break;
+
+ default:
+ return;
+ }
+ i810Ctx->new_state |= I810_NEW_TEXTURE;
+}
+
+void i810BindTexture( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj )
+{
+ CHECK_CONTEXT( return; );
+
+ if (target != GL_TEXTURE_2D)
+ return;
+
+ i810Ctx->new_state |= I810_NEW_TEXTURE;
+}
+
+void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
+{
+ i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
+ CHECK_CONTEXT( return; );
+
+ i810DestroyTexObj(i810Ctx,t);
+ tObj->DriverData=0;
+}
+
+void i810UpdateTexturePalette( GLcontext *ctx, struct gl_texture_object *tObj )
+{
+ i810TextureObjectPtr t;
+ GLushort *dst;
+ GLubyte *src;
+ int i, size, next;
+ GLenum format;
+
+ CHECK_CONTEXT( return; );
+
+ return;
+
+
+ if (tObj)
+ {
+ i810Msg(8,"i810UpdateTexturePalette(): size %d\n", tObj->PaletteSize);
+ t = (i810TextureObjectPtr) tObj->DriverData;;
+ if (!t) return;
+ size = tObj->PaletteSize;
+ format = tObj->PaletteFormat;
+ dst = t->Palette;
+ src = (GLubyte *) tObj->Palette;
+ }
+ else
+ {
+ /* shared palette */
+ i810Ctx->GlobalPaletteUpdated = 1;
+ size = ctx->Texture.PaletteSize;
+ format = ctx->Texture.PaletteFormat;
+ dst = i810Ctx->GlobalPalette;
+ src = (GLubyte *) ctx->Texture.Palette;
+
+ i810Msg(8, "i810UpdateTexturePalette(): size %d intFormat %x format %x\n",
+ size, ctx->Texture.PaletteIntFormat, ctx->Texture.PaletteFormat);
+ }
+
+ if (size > 256) {
+ i810Error("i810UpdateTexturePalette(): palette > 256 entries!\n");
+ return;
+ }
+
+ switch (format)
+ {
+ case GL_RGB: next = 3; break;
+ case GL_RGBA:next = 4; break;
+ default :
+ i810Error("i810UpdateTexturePalette(): unsupported palette format %x\n");
+ next = 4;
+ }
+
+ for (i=0; i < size; i++) {
+ *dst = I810PACKCOLOR565(src[RCOMP],src[GCOMP],src[BCOMP]);
+ dst++;
+ src += next;
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.h b/xc/lib/GL/mesa/src/drv/i810/i810tex.h
new file mode 100644
index 000000000..bd7140504
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.h
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ *
+ *
+ */
+
+/* $Id: i810tex.h,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+#ifndef I810TEX_INC
+#define I810TEX_INC
+
+#include "mesaglx/types.h"
+#include "mmath.h"
+
+#include "i810common.h"
+#include "i810buf.h"
+
+#define VALID_I810_TEXTURE_OBJECT(tobj) (tobj)
+
+#define I810_TEX_MAXLEVELS 10
+
+struct i810_texture_object_t {
+ struct i810_texture_object_t *next, *prev;
+
+ GLuint age;
+ struct gl_texture_object *globj;
+
+ int Pitch;
+ int Height;
+ int texelBytes;
+ int totalSize;
+
+ PMemBlock MemBlock;
+
+ char *BufAddr;
+
+ GLuint min_level;
+ GLuint max_level;
+ GLuint dirty_images;
+
+ struct {
+ const struct gl_texture_image *image;
+ int offset; /* into BufAddr */
+ int height;
+ int internalFormat;
+ } image[I810_TEX_MAXLEVELS];
+
+ /* Support for multitexture.
+ */
+ GLuint current_unit;
+
+ GLuint Setup[I810_TEX_SETUP_SIZE];
+ GLuint reg_dirty;
+
+ GLushort Palette[256];
+ int UsePalette;
+};
+
+#define I810_NO_PALETTE 0x0
+#define I810_USE_PALETTE 0x1
+#define I810_UPDATE_PALETTE 0x2
+#define I810_FALLBACK_PALETTE 0x4
+
+typedef struct i810_texture_object_t *i810TextureObjectPtr;
+
+i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx,
+ struct gl_texture_object *tObj);
+int i810DestroyTexObj(i810ContextPtr ctx, i810TextureObjectPtr t);
+void i810UpdateTextureState(GLcontext *ctx);
+
+
+/* Driver functions */
+
+void i810TexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param );
+
+void i810TexImage( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint internalFormat,
+ const struct gl_texture_image *image );
+
+void i810TexSubImage( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLint internalFormat,
+ const struct gl_texture_image *image );
+
+void i810TexParameter( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params );
+
+void i810BindTexture( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj );
+
+void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj );
+
+void i810UpdateTexturePalette( GLcontext *ctx, struct gl_texture_object *tObj );
+void i810UseGlobalTexturePalette( GLcontext *ctx, GLboolean state );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.c b/xc/lib/GL/mesa/src/drv/i810/i810tris.c
new file mode 100644
index 000000000..7ab3ed7ed
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.c
@@ -0,0 +1,303 @@
+/* $Id: i810tris.c,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "vb.h"
+#include "pipeline.h"
+
+#include "mm.h"
+#include "i810lib.h"
+#include "i810tris.h"
+#include "i810vb.h"
+#include "i810log.h"
+#include "xsmesaP.h"
+
+
+static void i810_null_quad( GLcontext *ctx, GLuint v0,
+ GLuint v1, GLuint v2, GLuint v3, GLuint pv )
+{
+}
+
+static void i810_null_triangle( GLcontext *ctx, GLuint v0,
+ GLuint v1, GLuint v2, GLuint pv )
+{
+}
+
+static void i810_null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
+{
+}
+
+static void i810_null_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+}
+
+
+#define I810_COLOR(to, from) { \
+ (to)[0] = (from)[2]; \
+ (to)[1] = (from)[1]; \
+ (to)[2] = (from)[0]; \
+ (to)[3] = (from)[3]; \
+}
+
+
+
+static triangle_func tri_tab[0x20];
+static quad_func quad_tab[0x20];
+static line_func line_tab[0x20];
+static points_func points_tab[0x20];
+
+void i810PrintRenderState( const char *msg, GLuint state )
+{
+ fprintf(stderr, "%s: (%x) %s%s%s%s%s%s\n",
+ msg, state,
+ (state & I810_FLAT_BIT) ? "flat, " : "",
+ (state & I810_OFFSET_BIT) ? "offset, " : "",
+ (state & I810_TWOSIDE_BIT) ? "twoside, " : "",
+ (state & I810_ANTIALIAS_BIT) ? "antialias, " : "",
+ (state & I810_NODRAW_BIT) ? "no-draw, " : "",
+ (state & I810_FALLBACK_BIT) ? "fallback" : "");
+}
+
+#define IND (0)
+#define TAG(x) x
+#include "i810tritmp.h"
+
+#define IND (I810_FLAT_BIT)
+#define TAG(x) x##_flat
+#include "i810tritmp.h"
+
+#define IND (I810_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "i810tritmp.h"
+
+#define IND (I810_OFFSET_BIT|I810_FLAT_BIT)
+#define TAG(x) x##_offset_flat
+#include "i810tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "i810tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_FLAT_BIT)
+#define TAG(x) x##_twoside_flat
+#include "i810tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "i810tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_flat
+#include "i810tritmp.h"
+
+void i810DDTrifuncInit()
+{
+ int i;
+ init();
+ init_flat();
+ init_offset();
+ init_offset_flat();
+ init_twoside();
+ init_twoside_flat();
+ init_twoside_offset();
+ init_twoside_offset_flat();
+
+ /* Hmmm...
+ */
+ for (i = 0 ; i < 0x20 ; i++) {
+ if (i & ~I810_FLAT_BIT) {
+ points_tab[i] = points_tab[i&I810_FLAT_BIT];
+ line_tab[i] = line_tab[i&I810_FLAT_BIT];
+ }
+ }
+
+ for (i = 0 ; i < 0x20 ; i++)
+ if ((i & (I810_NODRAW_BIT|I810_FALLBACK_BIT)) == I810_NODRAW_BIT ||
+ i810glx.nullprims)
+ {
+ quad_tab[i] = i810_null_quad;
+ tri_tab[i] = i810_null_triangle;
+ line_tab[i] = i810_null_line;
+ points_tab[i] = i810_null_points;
+ }
+
+ if (i810glx.noFallback) {
+ for (i = 0 ; i < 0x10 ; i++) {
+ points_tab[i|I810_FALLBACK_BIT] = points_tab[i];
+ line_tab[i|I810_FALLBACK_BIT] = line_tab[i];
+ tri_tab[i|I810_FALLBACK_BIT] = tri_tab[i];
+ quad_tab[i|I810_FALLBACK_BIT] = quad_tab[i];
+ }
+ }
+
+}
+
+
+/* Everything is done via single triangle instructiopns at the moment;
+ * this can change fairly easily.
+ */
+#if I810_USE_BATCH
+
+GLuint *i810AllocPrimitiveVerts( int dwords )
+{
+ GLuint orig_dwords = dwords;
+
+ dwords+=2;
+ dwords&=~1;
+
+ while (1) {
+ if (i810glx.dma_buffer->space < dwords * 4)
+ {
+ if (I810_DEBUG & DEBUG_VERBOSE_RING)
+ fprintf(stderr, "i810AllocPrimitiveVerts: dma buffer overflow\n");
+ i810DmaOverflow( dwords );
+ }
+ else
+ {
+ GLuint start = i810glx.dma_buffer->head;
+ i810glx.dma_buffer->head += dwords * 4;
+ i810glx.dma_buffer->space -= dwords * 4;
+
+ if ((orig_dwords & 1) == 0) {
+ *(GLuint *)(i810glx.dma_buffer->virtual_start + start ) = 0;
+ start += 4;
+ }
+
+ *(GLuint *)(i810glx.dma_buffer->virtual_start + start ) =
+ GFX_OP_PRIMITIVE | PR_TRIANGLES | (orig_dwords-1);
+
+ return (GLuint *)(i810glx.dma_buffer->virtual_start + start + 4);
+ }
+ }
+}
+
+#else
+GLuint *i810AllocPrimitiveVerts( int dwords )
+{
+ GLuint orig_dwords = dwords;
+
+ dwords+=2;
+ dwords&=~1;
+
+ while (1)
+ {
+ BEGIN_LP_RING( dwords );
+
+ if (outring + dwords * 4 != ((outring + dwords * 4) & ringmask))
+ {
+ int i;
+
+ if (I810_DEBUG & DEBUG_VERBOSE_RING)
+ fprintf(stderr, "\n\nwrap case in i810AllocPrimitiveVerts\n\n");
+
+ for (i = 0 ; i < dwords ; i++)
+ OUT_RING( 0 );
+ ADVANCE_LP_RING();
+ }
+ else
+ {
+ I810LpRing.tail = outring + dwords * 4;
+
+ if ((orig_dwords & 1) == 0)
+ OUT_RING(0);
+
+ OUT_RING( GFX_OP_PRIMITIVE | PR_TRIANGLES | (orig_dwords-1) );
+ return (GLuint *)(virt + outring);
+ }
+ }
+}
+#endif
+
+
+
+void i810DDChooseRenderState( GLcontext *ctx )
+{
+ GLuint flags = ctx->TriangleCaps;
+
+ ctx->IndirectTriangles &= ~DD_SW_RASTERIZE;
+
+ if (flags) {
+ GLuint ind = 0;
+ GLuint shared = 0;
+ GLuint setup = i810Ctx->setupindex;
+ GLuint fallback = I810_FALLBACK_BIT;
+
+ if (i810glx.noFallback) fallback = 0;
+
+ if ((flags & DD_FLATSHADE) && (setup & I810_RGBA_BIT)) shared |= I810_FLAT_BIT;
+ if (flags & DD_MULTIDRAW) shared |= fallback;
+ if (flags & DD_SELECT) shared |= I810_FALLBACK_BIT;
+ if (flags & DD_FEEDBACK) shared |= I810_FALLBACK_BIT;
+
+ ind = shared;
+ if (flags & DD_POINT_SMOOTH) ind |= I810_ANTIALIAS_BIT;
+ if (flags & DD_POINT_ATTEN) ind |= fallback;
+
+ i810Ctx->renderindex = ind;
+ i810Ctx->PointsFunc = points_tab[ind];
+ if (ind & I810_FALLBACK_BIT)
+ ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE;
+
+ ind = shared;
+ if (flags & DD_LINE_SMOOTH) ind |= I810_ANTIALIAS_BIT;
+ if (flags & DD_LINE_STIPPLE) ind |= fallback;
+
+ i810Ctx->renderindex |= ind;
+ i810Ctx->LineFunc = line_tab[ind];
+ if (ind & I810_FALLBACK_BIT)
+ ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE;
+
+ ind = shared;
+ if (flags & DD_TRI_SMOOTH) ind |= I810_ANTIALIAS_BIT;
+ if (flags & DD_TRI_OFFSET) ind |= I810_OFFSET_BIT;
+ if (flags & DD_TRI_LIGHT_TWOSIDE) ind |= I810_TWOSIDE_BIT;
+ if (flags & (DD_TRI_UNFILLED|DD_TRI_STIPPLE)) ind |= fallback;
+
+ i810Ctx->renderindex |= ind;
+ i810Ctx->TriangleFunc = tri_tab[ind];
+ i810Ctx->QuadFunc = quad_tab[ind];
+ if (ind & I810_FALLBACK_BIT)
+ ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE);
+ }
+ else if (i810Ctx->renderindex)
+ {
+ i810Ctx->renderindex = 0;
+ i810Ctx->PointsFunc = points_tab[0];
+ i810Ctx->LineFunc = line_tab[0];
+ i810Ctx->TriangleFunc = tri_tab[0];
+ i810Ctx->QuadFunc = quad_tab[0];
+ }
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ gl_print_tri_caps("tricaps", ctx->TriangleCaps);
+ i810PrintRenderState("i810: Render state", i810Ctx->renderindex);
+ }
+}
+
+
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.h b/xc/lib/GL/mesa/src/drv/i810/i810tris.h
new file mode 100644
index 000000000..ee7063dc3
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.h
@@ -0,0 +1,208 @@
+/* $Id: i810tris.h,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#ifndef I810TIS_INC
+#define I810TIS_INC
+
+#include "mesaglx/types.h"
+
+extern void i810DDChooseRenderState(GLcontext *ctx);
+extern void i810DDTrifuncInit();
+
+/* extern void i810FinishPrimitive( void ); */
+extern void i810NaughtyFinishPrimitive( void );
+extern GLuint *i810AllocPrimitiveVerts( int dwords );
+
+
+
+/* Todo:
+ * - multidraw, ...
+ * - Antialiasing (?)
+ * - line and polygon stipple
+ * - select and feedback
+ * - stencil
+ * - point parameters
+ * -
+ */
+#define I810_ANTIALIAS_BIT 0 /* ignored for now, no fallback */
+#define I810_FLAT_BIT 0x1
+#define I810_OFFSET_BIT 0x2 /* 3.1 only */
+#define I810_TWOSIDE_BIT 0x4 /* 3.1 only */
+#define I810_NODRAW_BIT 0x8
+#define I810_FALLBACK_BIT 0x10
+
+/* Not in use:
+ */
+#define I810_FEEDBACK_BIT 0x20
+#define I810_SELECT_BIT 0x40
+#define I810_POINT_PARAM_BIT 0x80 /* not needed? */
+
+
+
+
+
+static inline void i810_draw_triangle( i810_vertex *v0,
+ i810_vertex *v1,
+ i810_vertex *v2 )
+{
+
+#if 0
+ fprintf(stderr, "i810_draw_triangle( %p, %p, %p )\n", v0, v1, v2);
+#endif
+
+#if 0
+#define WID 640
+#define HI 480
+ {
+ GLuint print = 1, draw = 1;
+ GLfloat area = ((v0->x - v2->x) * (v1->y - v2->y) -
+ (v0->y - v2->y) * (v1->x - v2->x));
+
+ if (v0->x < -.501 || v0->x > WID || v0->y < -.501 || v0->y > HI ||
+ v1->x < -.501 || v1->x > WID || v1->y < -.501 || v1->y > HI ||
+ v2->x < -.501 || v2->x > WID || v2->y < -.501 || v2->y > HI) {
+ fprintf(stderr, "not clipped\n");
+ print = 1;
+ }
+
+ if (area == 0 && ((v0 == v1) || (v1 == v2))) {
+ fprintf(stderr, "zero area %p %p %p\n", v0, v1, v2);
+ draw = 0;
+ }
+
+ if (print) {
+ fprintf(stderr," v0: %f %f %f %f tex: %f %f\n",
+ v0->x, v0->y, v0->z, v0->oow, v0->tu0, v0->tv0);
+ fprintf(stderr," v1: %f %f %f %f tex: %f %f\n",
+ v1->x, v1->y, v1->z, v1->oow, v1->tu0, v1->tv0);
+ fprintf(stderr," v2: %f %f %f %f tex: %f %f\n",
+ v2->x, v2->y, v2->z, v2->oow, v2->tu0, v2->tv0);
+ return;
+ }
+
+ if (!draw) return;
+ }
+#endif
+
+ {
+ i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( 3 * 10 );
+ wv[0] = *v0;
+ wv[1] = *v1;
+ wv[2] = *v2;
+ FINISH_PRIM();
+ }
+}
+
+
+
+
+/* These can go soon, but for the meantime we're using triangles for
+ * everything.
+ */
+static inline void i810_draw_point( i810_vertex *tmp, float sz )
+{
+ i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts(6*10);
+
+ wv[0] = *tmp;
+ wv[0].x = tmp->x - sz;
+ wv[0].y = tmp->y - sz;
+
+ wv[1] = *tmp;
+ wv[1].x = tmp->x + sz;
+ wv[1].y = tmp->y - sz;
+
+ wv[2] = *tmp;
+ wv[2].x = tmp->x + sz;
+ wv[2].y = tmp->y + sz;
+
+ wv[3] = *tmp;
+ wv[3].x = tmp->x + sz;
+ wv[3].y = tmp->y + sz;
+
+ wv[4] = *tmp;
+ wv[4].x = tmp->x - sz;
+ wv[4].y = tmp->y + sz;
+
+ wv[5] = *tmp;
+ wv[5].x = tmp->x - sz;
+ wv[5].y = tmp->y - sz;
+
+ FINISH_PRIM();
+}
+
+
+static inline void i810_draw_line( i810_vertex *tmp0,
+ i810_vertex *tmp1,
+ float width )
+{
+ i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( 6 * 10 );
+ float dx, dy, ix, iy;
+
+ dx = tmp0->x - tmp1->x;
+ dy = tmp0->y - tmp1->y;
+
+ ix = width * .5; iy = 0;
+ if (dx * dx > dy * dy) {
+ iy = ix; ix = 0;
+ }
+
+#if 0
+ fprintf(stderr,"tmp0: %f %f %f %f col: %x tex: %f %f\n",
+ tmp0->x, tmp0->y, tmp0->z, tmp0->oow, *(GLuint*)&tmp0->color, tmp0->tu0, tmp0->tv0);
+ fprintf(stderr,"tmp1: %f %f %f %f col: %x tex: %f %f\n",
+ tmp1->x, tmp1->y, tmp1->z, tmp1->oow, *(GLuint*)&tmp1->color, tmp1->tu0, tmp1->tv0);
+ fprintf(stderr, "ix: %f, iy: %f\n", ix, iy);
+#endif
+
+
+ wv[0] = *tmp0;
+ wv[0].x = tmp0->x - ix;
+ wv[0].y = tmp0->y - iy;
+
+ wv[1] = *tmp1;
+ wv[1].x = tmp1->x + ix;
+ wv[1].y = tmp1->y + iy;
+
+ wv[2] = *tmp0;
+ wv[2].x = tmp0->x + ix;
+ wv[2].y = tmp0->y + iy;
+
+ wv[3] = *tmp0;
+ wv[3].x = tmp0->x - ix;
+ wv[3].y = tmp0->y - iy;
+
+ wv[4] = *tmp1;
+ wv[4].x = tmp1->x - ix;
+ wv[4].y = tmp1->y - iy;
+
+ wv[5] = *tmp1;
+ wv[5].x = tmp1->x + ix;
+ wv[5].y = tmp1->y + iy;
+
+ FINISH_PRIM();
+}
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h b/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h
new file mode 100644
index 000000000..99159f418
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h
@@ -0,0 +1,199 @@
+
+static inline void TAG(triangle)( GLcontext *ctx, GLuint e0,
+ GLuint e1, GLuint e2, GLuint pv )
+{
+ struct vertex_buffer *VB = ctx->VB;
+ i810VertexPtr i810VB = I810_DRIVER_DATA(VB)->verts;
+ const i810_vertex *v0 = &i810VB[e0].v.v;
+ const i810_vertex *v1 = &i810VB[e1].v.v;
+ const i810_vertex *v2 = &i810VB[e2].v.v;
+
+#if (IND & I810_OFFSET_BIT)
+ GLfloat offset = ctx->Polygon.OffsetUnits * 1.0/0x10000;
+#endif
+
+#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
+ int c0 = *(int *)&i810VB[pv].v.v.color;
+ int c1 = c0;
+ int c2 = c0;
+#endif
+
+
+#if (IND & (I810_TWOSIDE_BIT|I810_OFFSET_BIT))
+ {
+ GLfloat ex = v0->x - v2->x;
+ GLfloat ey = v0->y - v2->y;
+ GLfloat fx = v1->x - v2->x;
+ GLfloat fy = v1->y - v2->y;
+ GLfloat c = ex*fy-ey*fx;
+
+#if (IND & I810_TWOSIDE_BIT)
+ {
+ GLuint facing = (c>0.0) ^ ctx->Polygon.FrontBit;
+ GLubyte (*vbcolor)[4] = VB->Color[facing]->data;
+ if (IND & I810_FLAT_BIT) {
+ I810_COLOR((char *)&c0,vbcolor[pv]);
+ c2 = c1 = c0;
+ } else {
+ I810_COLOR((char *)&c0,vbcolor[e0]);
+ I810_COLOR((char *)&c1,vbcolor[e1]);
+ I810_COLOR((char *)&c2,vbcolor[e2]);
+ }
+ }
+#endif
+
+#if (IND & I810_OFFSET_BIT)
+ {
+ if (c * c > 1e-16) {
+ GLfloat factor = ctx->Polygon.OffsetFactor;
+ GLfloat ez = v0->z - v2->z;
+ GLfloat fz = v1->z - v2->z;
+ GLfloat a = ey*fz-ez*fy;
+ GLfloat b = ez*fx-ex*fz;
+ GLfloat ic = 1.0 / c;
+ GLfloat ac = a * ic;
+ GLfloat bc = b * ic;
+ if (ac<0.0F) ac = -ac;
+ if (bc<0.0F) bc = -bc;
+ offset += MAX2( ac, bc ) * factor;
+ }
+ }
+#endif
+ }
+#endif
+
+ i810glx.c_triangles++;
+
+#if 0
+#define WID 512
+#define HI 384
+ {
+ GLuint print = 0, draw = 1;
+ GLfloat area = ((v0->x - v2->x) * (v1->y - v2->y) -
+ (v0->y - v2->y) * (v1->x - v2->x));
+
+ if (v0->x < -.501 || v0->x > WID || v0->y < -.501 || v0->y > HI ||
+ v1->x < -.501 || v1->x > WID || v1->y < -.501 || v1->y > HI ||
+ v2->x < -.501 || v2->x > WID || v2->y < -.501 || v2->y > HI) {
+ fprintf(stderr, "not clipped\n");
+ print = 1;
+ }
+
+ if (area == 0 && ((v0 == v1) || (v1 == v2))) {
+ fprintf(stderr, "zero area %p %p %p\n", v0, v1, v2);
+ draw = 0;
+ }
+
+ if (print) {
+ fprintf(stderr,"v0: %f %f %f %f col: %x tex: %f %f\n",
+ v0->x, v0->y, v0->z, v0->oow,
+ *(GLuint*)&v0->color, v0->tu0, v0->tv0);
+ fprintf(stderr,"v1: %f %f %f %f col: %x tex: %f %f\n",
+ v1->x, v1->y, v1->z, v1->oow,
+ *(GLuint*)&v1->color, v1->tu0, v1->tv0);
+ fprintf(stderr,"v2: %f %f %f %f col: %x tex: %f %f\n",
+ v2->x, v2->y, v2->z, v2->oow,
+ *(GLuint*)&v2->color, v2->tu0, v2->tv0);
+/* return; */
+ }
+
+ if (!draw) return;
+ }
+#endif
+
+ {
+ i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( 3 * 10 );
+ wv[0] = *v0;
+#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
+ *((int *)(&wv[0].color)) = c0;
+#endif
+#if (IND & I810_OFFSET_BIT)
+ wv[0].z = v0->z + offset;
+#endif
+
+
+ wv[1] = *v1;
+#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
+ *((int *)(&wv[1].color)) = c1;
+#endif
+#if (IND & I810_OFFSET_BIT)
+ wv[1].z = v1->z + offset;
+#endif
+
+ wv[2] = *v2;
+#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
+ *((int *)(&wv[2].color)) = c2;
+#endif
+#if (IND & I810_OFFSET_BIT)
+ wv[2].z = v2->z + offset;
+#endif
+
+ FINISH_PRIM();
+ }
+}
+
+
+
+static void TAG(quad)( GLcontext *ctx, GLuint v0,
+ GLuint v1, GLuint v2, GLuint v3,
+ GLuint pv )
+{
+ TAG(triangle)( ctx, v0, v1, v3, pv );
+ TAG(triangle)( ctx, v1, v2, v3, pv );
+}
+
+
+#if ((IND & ~I810_FLAT_BIT) == 0)
+
+static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
+{
+ i810VertexPtr i810VB = I810_DRIVER_DATA(ctx->VB)->verts;
+ i810_vertex tmp0 = i810VB[v0].v.v;
+ i810_vertex tmp1 = i810VB[v1].v.v;
+ float width = ctx->Line.Width;
+
+ if (IND & I810_FLAT_BIT) {
+ *(int *)&tmp1.color = *(int *)&tmp0.color =
+ *(int *)&i810VB[pv].v.v.color;
+ }
+
+ i810_draw_line( &tmp0, &tmp1, width );
+}
+
+
+static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
+{
+ int i;
+ struct vertex_buffer *VB = ctx->VB;
+ i810VertexPtr i810VB = I810_DRIVER_DATA(VB)->verts;
+ GLfloat sz = ctx->Point.Size * .5;
+
+ /* Culling is disabled automatically via. the
+ * ctx->Driver.ReducedPrimitiveChange() callback.
+ */
+
+ for(i=first;i<=last;i++) {
+ if(VB->ClipMask[i]==0) {
+ i810_vertex *tmp = &i810VB[i].v.v;
+ i810_draw_point( tmp, sz );
+ }
+ }
+}
+
+#endif
+
+
+static void TAG(init)()
+{
+ tri_tab[IND] = TAG(triangle);
+ quad_tab[IND] = TAG(quad);
+
+#if ((IND & ~I810_FLAT_BIT) == 0)
+ line_tab[IND] = TAG(line);
+ points_tab[IND] = TAG(points);
+#endif
+}
+
+
+#undef IND
+#undef TAG
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.c b/xc/lib/GL/mesa/src/drv/i810/i810vb.c
new file mode 100644
index 000000000..28138dbc5
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.c
@@ -0,0 +1,444 @@
+/* $Id: i810vb.c,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#include "i810lib.h"
+#include "i810context.h"
+#include "i810vb.h"
+#include "i810log.h"
+#include "i810dma.h"
+#include "xsmesaP.h"
+#include "xsmesa.h"
+
+#include "stages.h"
+
+#include "os.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+extern i810ContextPtr i810Ctx;
+extern struct i810_dest_buffer *i810DB;
+
+#define TEX0 { \
+ v->v.v.tu0 = tc0[i][0]; \
+ v->v.v.tv0 = tc0[i][1]; \
+}
+
+#define TEX1 { \
+ v->v.v.tu1 = tc1[i][0]; \
+ v->v.v.tv1 = tc1[i][1]; \
+}
+
+/* Doesn't seem to work very well (golly).
+ */
+#define SPC { \
+ GLubyte *spec = &(VB->Spec[0][i][0]); \
+ v->v.v.specular.red = spec[0]; \
+ v->v.v.specular.green = spec[1]; \
+ v->v.v.specular.blue = spec[2]; \
+}
+
+#define FOG { \
+ GLubyte *spec = &(VB->Spec[0][i][0]); \
+ v->v.v.specular.alpha = spec[3]; \
+}
+
+#define COL { \
+ GLubyte *col = &(VB->Color[0]->data[i][0]); \
+ v->v.v.color.blue = col[2]; \
+ v->v.v.color.green = col[1]; \
+ v->v.v.color.red = col[0]; \
+ v->v.v.color.alpha = col[3]; \
+}
+
+/* The vertex formats we have don't seem to support projective texturing
+ * in the multitexture case. (Would require another 1/w value for the
+ * second set of texcoords).
+ */
+#define TEX0_4 \
+ if (VB->TexCoordPtr[0]->size == 4) \
+ { \
+ GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \
+ v = &(I810_DRIVER_DATA(VB)->verts[start]); \
+ i810Ctx->setupdone &= ~I810_WIN_BIT; \
+ for (i=start; i < end; i++, v++) { \
+ float oow = 1.0 / tc[i][3]; \
+ v->v.v.oow *= tc[i][3]; \
+ v->v.v.tu0 *= oow; \
+ v->v.v.tv0 *= oow; \
+ } \
+ }
+
+
+#define COORD \
+ GLfloat *win = VB->Win.data[i]; \
+ v->v.v.x = win[0]; \
+ v->v.v.y = i810height - win[1]; \
+ v->v.v.z = (1.0/0x10000) * win[2]; \
+ v->v.v.oow = win[3];
+
+
+
+#define NOP
+
+
+
+
+#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,spec,fog) \
+static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \
+{ \
+ i810VertexPtr v; \
+ GLfloat (*tc0)[4]; \
+ GLfloat (*tc1)[4]; \
+ GLfloat i810height = i810DB->Height; \
+ int i; \
+ (void) i810height; \
+ \
+ CHECK_CONTEXT( return; ); \
+ \
+ gl_import_client_data( VB, VB->ctx->RenderFlags, \
+ (VB->ClipOrMask \
+ ? VEC_WRITABLE|VEC_GOOD_STRIDE \
+ : VEC_GOOD_STRIDE)); \
+ \
+ tc0 = VB->TexCoordPtr[0]->data; \
+ tc1 = VB->TexCoordPtr[1]->data; \
+ \
+ v = &(I810_DRIVER_DATA(VB)->verts[start]); \
+ \
+ if (VB->ClipOrMask == 0) \
+ for (i=start; i < end; i++, v++) { \
+ win; \
+ col; \
+ spec; \
+ fog; \
+ tex0; \
+ tex1; \
+ } \
+ else \
+ for (i=start; i < end; i++, v++) { \
+ if (VB->ClipMask[i] == 0) { \
+ win; \
+ spec; \
+ fog; \
+ tex0; \
+ tex1; \
+ } \
+ col; \
+ } \
+ tex0_4; \
+}
+
+
+
+
+SETUPFUNC(rs_wt0, COORD,NOP,TEX0,NOP,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_wt0t1, COORD,NOP,TEX0,TEX1,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_wft0, COORD,NOP,TEX0,NOP,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_wft0t1, COORD,NOP,TEX0,TEX1,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_wg, COORD,COL,NOP,NOP,NOP,NOP,NOP)
+SETUPFUNC(rs_wgt0, COORD,COL,TEX0,NOP,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_wgt0t1, COORD,COL,TEX0,TEX1,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_wgst0, COORD,COL,TEX0,NOP,TEX0_4,SPC,NOP)
+SETUPFUNC(rs_wgst0t1, COORD,COL,TEX0,TEX1,TEX0_4,SPC,NOP)
+SETUPFUNC(rs_wgf, COORD,COL,NOP,NOP,NOP,NOP,FOG)
+SETUPFUNC(rs_wgft0, COORD,COL,TEX0,NOP,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_wgft0t1, COORD,COL,TEX0,TEX1,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_wgfst0, COORD,COL,TEX0,NOP,TEX0_4,SPC,FOG)
+SETUPFUNC(rs_wgfst0t1, COORD,COL,TEX0,TEX1,TEX0_4,SPC,FOG)
+
+SETUPFUNC(rs_t0, NOP,NOP,TEX0,NOP,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_t0t1, NOP,NOP,TEX0,TEX1,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_f, NOP,NOP,NOP,NOP,NOP,NOP,FOG)
+SETUPFUNC(rs_ft0, NOP,NOP,TEX0,NOP,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_ft0t1, NOP,NOP,TEX0,TEX1,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_g, NOP,COL,NOP,NOP,NOP,NOP,NOP)
+SETUPFUNC(rs_gt0, NOP,COL,TEX0,NOP,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_gt0t1, NOP,COL,TEX0,TEX1,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_gst0, NOP,COL,TEX0,NOP,TEX0_4,SPC,NOP)
+SETUPFUNC(rs_gst0t1, NOP,COL,TEX0,TEX1,TEX0_4,SPC,NOP)
+SETUPFUNC(rs_gf, NOP,COL,NOP,NOP,NOP,NOP,FOG)
+SETUPFUNC(rs_gft0, NOP,COL,TEX0,NOP,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_gft0t1, NOP,COL,TEX0,TEX1,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_gfst0, NOP,COL,TEX0,NOP,TEX0_4,SPC,FOG)
+SETUPFUNC(rs_gfst0t1, NOP,COL,TEX0,TEX1,TEX0_4,SPC,FOG)
+
+
+
+static void rs_invalid(struct vertex_buffer *VB, GLuint start, GLuint end)
+{
+
+ fprintf(stderr, "i810RasterSetup(): invalid setup function\n");
+}
+
+typedef void (*setupFunc)(struct vertex_buffer *,GLuint,GLuint);
+
+static setupFunc setup_func[0x80];
+
+void i810DDSetupInit( void )
+{
+ int i;
+
+ for (i = 0 ; i < 0x80 ; i++)
+ setup_func[i] = rs_invalid;
+
+ /* Functions to build vert's from scratch */
+ setup_func[I810_WIN_BIT|I810_TEX0_BIT] = rs_wt0;
+ setup_func[I810_WIN_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wt0t1;
+ setup_func[I810_WIN_BIT|I810_FOG_BIT|I810_TEX0_BIT] = rs_wft0;
+ setup_func[I810_WIN_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wft0t1;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT] = rs_wg;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_TEX0_BIT] = rs_wgt0;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgt0t1;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_wgst0;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgst0t1;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT] = rs_wgf;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT] = rs_wgft0;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgft0t1;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_wgfst0;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgfst0t1;
+
+ /* Repair functions */
+ setup_func[I810_TEX0_BIT] = rs_t0;
+ setup_func[I810_TEX0_BIT|I810_TEX1_BIT] = rs_t0t1;
+ setup_func[I810_FOG_BIT] = rs_f;
+ setup_func[I810_FOG_BIT|I810_TEX0_BIT] = rs_ft0;
+ setup_func[I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_ft0t1;
+ setup_func[I810_RGBA_BIT] = rs_g;
+ setup_func[I810_RGBA_BIT|I810_TEX0_BIT] = rs_gt0;
+ setup_func[I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gt0t1;
+ setup_func[I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_gst0;
+ setup_func[I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gst0t1;
+ setup_func[I810_RGBA_BIT|I810_FOG_BIT] = rs_gf;
+ setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT] = rs_gft0;
+ setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gft0t1;
+ setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_gfst0;
+ setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gfst0t1;
+
+}
+
+
+void i810PrintSetupFlags(char *msg, GLuint flags )
+{
+ fprintf(stderr, "%s: %d %s%s%s%s%s%s%s\n",
+ msg,
+ flags,
+ (flags & I810_WIN_BIT) ? " xyzw," : "",
+ (flags & I810_RGBA_BIT) ? " rgba," : "",
+ (flags & I810_SPEC_BIT) ? " spec," : "",
+ (flags & I810_FOG_BIT) ? " fog," : "",
+ (flags & I810_TEX0_BIT) ? " tex-0," : "",
+ (flags & I810_TEX1_BIT) ? " tex-1," : "",
+ (flags & I810_ALPHA_BIT) ? " alpha," : "");
+}
+
+
+
+
+void i810ChooseRasterSetupFunc(GLcontext *ctx)
+{
+ int funcindex = (I810_WIN_BIT | I810_RGBA_BIT);
+
+ if (ctx->Texture.Enabled & 0xf) {
+ if (ctx->Texture.Unit[0].EnvMode == GL_REPLACE)
+ funcindex &= ~I810_RGBA_BIT;
+
+ funcindex |= I810_TEX0_BIT;
+ }
+
+ if (ctx->Texture.Enabled & 0xf0)
+ funcindex |= I810_TEX1_BIT;
+
+ if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+ funcindex |= I810_SPEC_BIT;
+
+ if (ctx->FogMode == FOG_FRAGMENT)
+ funcindex |= I810_FOG_BIT;
+
+ if (MESA_VERBOSE || I810_DEBUG)
+ i810PrintSetupFlags("xsmesa: full setup function", funcindex);
+
+ i810Ctx->setupindex = funcindex;
+ ctx->Driver.RasterSetup = setup_func[funcindex];
+}
+
+
+
+
+void i810DDCheckPartialRasterSetup( GLcontext *ctx,
+ struct gl_pipeline_stage *d )
+{
+ GLuint tmp = i810Ctx->setupdone;
+
+ d->type = 0;
+ i810Ctx->setupdone = 0; /* cleared if we return */
+
+ if ((ctx->Array.Summary & VERT_OBJ_ANY) == 0)
+ return;
+
+ if (ctx->IndirectTriangles)
+ return;
+
+ i810Ctx->setupdone = tmp;
+
+ /* disabled until we have a merge&render op */
+ /* d->inputs = available; */
+ /* d->outputs = VERT_RAST_SETUP_PART; */
+ /* d->type = PIPE_PRECALC; */
+}
+
+
+/* Repair existing precalculated vertices with new data.
+ */
+void i810DDPartialRasterSetup( struct vertex_buffer *VB )
+{
+ GLuint new = VB->pipeline->new_outputs;
+ GLuint available = VB->pipeline->outputs;
+ GLuint ind = 0;
+
+ if (new & VERT_WIN) {
+ new = available;
+ ind |= I810_WIN_BIT | I810_FOG_BIT;
+ }
+
+ if (new & VERT_RGBA)
+ ind |= I810_RGBA_BIT | I810_SPEC_BIT;
+
+ if (new & VERT_TEX0_ANY)
+ ind |= I810_TEX0_BIT;
+
+ if (new & VERT_TEX1_ANY)
+ ind |= I810_TEX1_BIT;
+
+ if (new & VERT_FOG_COORD)
+ ind |= I810_FOG_BIT;
+
+ i810Ctx->setupdone &= ~ind;
+ ind &= i810Ctx->setupindex;
+ i810Ctx->setupdone |= ind;
+
+ i810PrintSetupFlags("xsmesa: partial setup function", ind);
+
+ if (ind)
+ setup_func[ind&~I810_ALPHA_BIT]( VB, VB->Start, VB->Count );
+}
+
+
+void i810DDDoRasterSetup( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+
+ if (VB->Type == VB_CVA_PRECALC)
+ i810DDPartialRasterSetup( VB );
+ else if (ctx->Driver.RasterSetup)
+ ctx->Driver.RasterSetup( VB, VB->CopyStart, VB->Count );
+}
+
+
+
+
+void i810DDResizeVB( struct vertex_buffer *VB, GLuint size )
+{
+ i810VertexBufferPtr mvb = I810_DRIVER_DATA(VB);
+
+ while (mvb->size < size)
+ mvb->size *= 2;
+
+ free( mvb->vert_store );
+ mvb->vert_store = malloc( sizeof(i810Vertex) * mvb->size + 31);
+ if (!mvb->vert_store)
+ FatalError("i810-glx: out of memory !\n");
+
+ mvb->verts = (i810VertexPtr)(((unsigned long)mvb->vert_store + 31) & ~31);
+
+ gl_vector1ui_free( &mvb->clipped_elements );
+ gl_vector1ui_alloc( &mvb->clipped_elements, VEC_WRITABLE, mvb->size, 32 );
+ if (!mvb->clipped_elements.start)
+ FatalError("i810-glx: out of memory !\n");
+
+ free( VB->ClipMask );
+ VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size);
+ if (!VB->ClipMask)
+ FatalError("i810-glx: out of memory !\n");
+
+ if (VB->Type == VB_IMMEDIATE) {
+ free( mvb->primitive );
+ free( mvb->next_primitive );
+ mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
+ mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
+ if (!mvb->primitive || !mvb->next_primitive)
+ FatalError("i810-glx: out of memory!");
+ }
+}
+
+
+void i810DDRegisterVB( struct vertex_buffer *VB )
+{
+ i810VertexBufferPtr mvb;
+
+ mvb = (i810VertexBufferPtr)calloc( 1, sizeof(*mvb) );
+
+ /* This looks like it allocates a lot of memory, but it basically
+ * just sets an upper limit on how much can be used - nothing like
+ * this amount will ever be turned into 'real' memory.
+ */
+ mvb->size = VB->Size * 5;
+ mvb->vert_store = malloc( sizeof(i810Vertex) * mvb->size + 31);
+ if (!mvb->vert_store)
+ FatalError("i810-glx: out of memory !\n");
+
+ mvb->verts = (i810VertexPtr)(((unsigned long)mvb->vert_store + 31) & ~31);
+
+ gl_vector1ui_alloc( &mvb->clipped_elements, VEC_WRITABLE, mvb->size, 32 );
+ if (!mvb->clipped_elements.start)
+ FatalError("i810-glx: out of memory !\n");
+
+ free( VB->ClipMask );
+ VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size);
+ if (!VB->ClipMask)
+ FatalError("i810-glx: out of memory !\n");
+
+ mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
+ mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
+ if (!mvb->primitive || !mvb->next_primitive)
+ FatalError("i810-glx: out of memory!");
+
+ VB->driver_data = mvb;
+}
+
+
+void i810DDUnregisterVB( struct vertex_buffer *VB )
+{
+ i810VertexBufferPtr mvb = I810_DRIVER_DATA(VB);
+
+ if (mvb) {
+ if (mvb->vert_store) free(mvb->vert_store);
+ if (mvb->primitive) free(mvb->primitive);
+ if (mvb->next_primitive) free(mvb->next_primitive);
+ gl_vector1ui_free( &mvb->clipped_elements );
+ free(mvb);
+ VB->driver_data = 0;
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.h b/xc/lib/GL/mesa/src/drv/i810/i810vb.h
new file mode 100644
index 000000000..f35e4a0e5
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.h
@@ -0,0 +1,117 @@
+/* $Id: i810vb.h,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#ifndef I810VB_INC
+#define I810VB_INC
+
+#include "mesaglx/vb.h"
+
+/*
+ * color type for the vertex data
+ * we probably want to use an internal datatype here?
+ */
+typedef struct {
+ GLubyte blue;
+ GLubyte green;
+ GLubyte red;
+ GLubyte alpha;
+} i810_color;
+
+
+/* A basic fixed format vertex to kick things off. Move to dynamic
+ * layouts later on. (see also the i810_full_vertex struct in
+ * i810_3d_reg.h)
+ */
+typedef struct {
+ GLfloat x,y,z; /* coordinates in screen space*/
+ GLfloat oow; /* reciprocal homogeneous w */
+ i810_color color; /* vertex color */
+ i810_color specular; /* specular color, alpha is fog */
+ GLfloat tu0,tv0; /* texture 0 */
+ GLfloat tu1,tv1; /* texture 1 */
+} i810_vertex;
+
+
+/* Unfortunately only have assembly for 16-stride vertices.
+ */
+struct i810_vertex_t {
+ union {
+ i810_vertex v;
+ float f[16];
+ } v;
+};
+
+typedef struct i810_vertex_t i810Vertex;
+typedef struct i810_vertex_t *i810VertexPtr;
+
+struct i810_vertex_buffer_t {
+ GLvector1ui clipped_elements;
+ i810VertexPtr verts;
+ int last_vert;
+ GLuint *primitive;
+ GLuint *next_primitive;
+ void *vert_store;
+ GLuint size;
+};
+
+typedef struct i810_vertex_buffer_t *i810VertexBufferPtr;
+
+#define I810_CONTEXT(ctx) ((i810ContextPtr)(((XSMesaContext)(ctx)->DriverCtx)->hw_ctx))
+#define I810_DRIVER_DATA(vb) ((i810VertexBufferPtr)((vb)->driver_data))
+
+
+#define I810_SPEC_BIT 0x1
+#define I810_FOG_BIT 0x2
+#define I810_ALPHA_BIT 0x4 /* GL_BLEND, not used */
+#define I810_TEX1_BIT 0x8
+#define I810_TEX0_BIT 0x10
+#define I810_RGBA_BIT 0x20
+#define I810_WIN_BIT 0x40
+
+
+extern void i810ChooseRasterSetupFunc(GLcontext *ctx);
+extern void i810PrintSetupFlags(char *msg, GLuint flags );
+extern void i810DDDoRasterSetup( struct vertex_buffer *VB );
+extern void i810DDPartialRasterSetup( struct vertex_buffer *VB );
+extern void i810DDCheckPartialRasterSetup( GLcontext *ctx,
+ struct gl_pipeline_stage *d );
+
+extern void i810DDViewport( GLcontext *ctx,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height );
+
+extern void i810DDDepthRange( GLcontext *ctx,
+ GLclampd nearval, GLclampd farval );
+
+
+extern void i810DDUnregisterVB( struct vertex_buffer *VB );
+extern void i810DDRegisterVB( struct vertex_buffer *VB );
+extern void i810DDResizeVB( struct vertex_buffer *VB, GLuint size );
+
+extern void i810DDSetupInit( void );
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/mm.c b/xc/lib/GL/mesa/src/drv/i810/mm.c
new file mode 100644
index 000000000..47b9281f1
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/mm.c
@@ -0,0 +1,264 @@
+/*
+ * 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.
+ *
+ *
+ */
+
+/* $Id: mm.c,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "os.h" /* ErrorF */
+
+#include "mm.h"
+
+#define ISFREE(bptr) ((bptr)->free)
+#define PRINTF(f,a...) fprintf(stderr,f, ## a)
+
+void mmDumpMemInfo( memHeap_t *heap )
+{
+ TMemBlock *p;
+
+ PRINTF("Memory heap %p:\n", heap);
+ if (heap == 0) {
+ PRINTF(" heap == 0\n");
+ } else {
+ p = (TMemBlock *)heap;
+ while (p) {
+ PRINTF(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
+ p->free ? '.':'U',
+ p->reserved ? 'R':'.');
+ p = p->next;
+ }
+ }
+ PRINTF("End of memory blocks\n");
+}
+
+memHeap_t *mmInit(int ofs,
+ int size)
+{
+ PMemBlock blocks;
+
+ if (size <= 0) {
+ return 0;
+ }
+ blocks = (TMemBlock *) calloc(1,sizeof(TMemBlock));
+ if (blocks) {
+ blocks->ofs = ofs;
+ blocks->size = size;
+ blocks->free = 1;
+ return (memHeap_t *)blocks;
+ } else
+ return 0;
+}
+
+/* Kludgey workaround for existing i810 server. Remove soon.
+ */
+memHeap_t *mmAddRange( memHeap_t *heap,
+ int ofs,
+ int size )
+{
+ PMemBlock blocks;
+ blocks = (TMemBlock *) calloc(2,sizeof(TMemBlock));
+ if (blocks) {
+ blocks[0].size = size;
+ blocks[0].free = 1;
+ blocks[0].ofs = ofs;
+ blocks[0].next = &blocks[1];
+
+ /* Discontinuity - stops JoinBlock from trying to join non-adjacent
+ * ranges.
+ */
+ blocks[1].size = 0;
+ blocks[1].free = 0;
+ blocks[1].ofs = ofs+size;
+ blocks[1].next = (PMemBlock) heap;
+ return (memHeap_t *)blocks;
+ }
+ else
+ return heap;
+}
+
+static TMemBlock* SliceBlock(TMemBlock *p,
+ int startofs, int size,
+ int reserved, int alignment)
+{
+ TMemBlock *newblock;
+
+ /* break left */
+ if (startofs > p->ofs) {
+ newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock));
+ newblock->ofs = startofs;
+ newblock->size = p->size - (startofs - p->ofs);
+ newblock->free = 1;
+ newblock->next = p->next;
+ p->size -= newblock->size;
+ p->next = newblock;
+ p = newblock;
+ }
+
+ /* break right */
+ if (size < p->size) {
+ newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock));
+ newblock->ofs = startofs + size;
+ newblock->size = p->size - size;
+ newblock->free = 1;
+ newblock->next = p->next;
+ p->size = size;
+ p->next = newblock;
+ }
+
+ /* p = middle block */
+ p->align = alignment;
+ p->free = 0;
+ p->reserved = reserved;
+ return p;
+}
+
+PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
+{
+ int mask,startofs,endofs;
+ TMemBlock *p;
+
+ if (!heap || align2 < 0 || size <= 0)
+ return NULL;
+ mask = (1 << align2)-1;
+ startofs = 0;
+ p = (TMemBlock *)heap;
+ while (p) {
+ if (ISFREE(p)) {
+ startofs = (p->ofs + mask) & ~mask;
+ if ( startofs < startSearch ) {
+ startofs = startSearch;
+ }
+ endofs = startofs+size;
+ if (endofs <= (p->ofs+p->size))
+ break;
+ }
+ p = p->next;
+ }
+ if (!p)
+ return NULL;
+ p = SliceBlock(p,startofs,size,0,mask+1);
+ p->heap = heap;
+ return p;
+}
+
+static __inline__ int Join2Blocks(TMemBlock *p)
+{
+ if (p->free && p->next && p->next->free) {
+ TMemBlock *q = p->next;
+ p->size += q->size;
+ p->next = q->next;
+ free(q);
+ return 1;
+ }
+ return 0;
+}
+
+int mmFreeMem(PMemBlock b)
+{
+ TMemBlock *p,*prev;
+
+ if (!b)
+ return 0;
+ if (!b->heap) {
+ fprintf(stderr, "no heap\n");
+ return -1;
+ }
+ p = b->heap;
+ prev = NULL;
+ while (p && p != b) {
+ prev = p;
+ p = p->next;
+ }
+ if (!p || p->free || p->reserved) {
+ if (!p)
+ fprintf(stderr, "block not found in heap\n");
+ else if (p->free)
+ fprintf(stderr, "block already free\n");
+ else
+ fprintf(stderr, "block is reserved\n");
+ return -1;
+ }
+ p->free = 1;
+ Join2Blocks(p);
+ if (prev)
+ Join2Blocks(prev);
+ return 0;
+}
+
+int mmReserveMem(memHeap_t *heap, int offset,int size)
+{
+ int endofs;
+ TMemBlock *p;
+
+ if (!heap || size <= 0)
+ return -1;
+ endofs = offset+size;
+ p = (TMemBlock *)heap;
+ while (p && p->ofs <= offset) {
+ if (ISFREE(p) && endofs <= (p->ofs+p->size)) {
+ SliceBlock(p,offset,size,1,1);
+ return 0;
+ }
+ p = p->next;
+ }
+ return -1;
+}
+
+int mmFreeReserved(memHeap_t *heap, int offset)
+{
+ TMemBlock *p,*prev;
+
+ if (!heap)
+ return -1;
+ p = (TMemBlock *)heap;
+ prev = NULL;
+ while (p && p->ofs != offset) {
+ prev = p;
+ p = p->next;
+ }
+ if (!p || !p->reserved)
+ return -1;
+ p->free = 1;
+ p->reserved = 0;
+ Join2Blocks(p);
+ if (prev)
+ Join2Blocks(prev);
+ return 0;
+}
+
+void mmDestroy(memHeap_t *heap)
+{
+ TMemBlock *p,*q;
+
+ if (!heap)
+ return;
+ p = (TMemBlock *)heap;
+ while (p) {
+ q = p->next;
+ free(p);
+ p = q;
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/mm.h b/xc/lib/GL/mesa/src/drv/i810/mm.h
new file mode 100644
index 000000000..0a469200b
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/mm.h
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ *
+ */
+
+/* $Id: mm.h,v 1.1 1999/12/14 00:23:48 keithw Exp $ */
+
+#ifndef MM_INC
+#define MM_INC
+
+struct mem_block_t {
+ struct mem_block_t *next;
+ struct mem_block_t *heap;
+ int ofs,size;
+ int align;
+ int free:1;
+ int reserved:1;
+};
+typedef struct mem_block_t TMemBlock;
+typedef struct mem_block_t *PMemBlock;
+
+/* a heap is just the first block in a chain */
+typedef struct mem_block_t memHeap_t;
+
+static __inline__ int mmBlockSize(PMemBlock b)
+{ return b->size; }
+
+static __inline__ int mmOffset(PMemBlock b)
+{ return b->ofs; }
+
+static __inline__ void mmMarkReserved(PMemBlock b)
+{ b->reserved = 1; }
+
+/*
+ * input: total size in bytes
+ * return: a heap pointer if OK, NULL if error
+ */
+memHeap_t *mmInit( int ofs, int size );
+
+
+
+memHeap_t *mmAddRange( memHeap_t *heap,
+ int ofs,
+ int size );
+
+
+/*
+ * Allocate 'size' bytes with 2^align2 bytes alignment,
+ * restrict the search to free memory after 'startSearch'
+ * depth and back buffers should be in different 4mb banks
+ * to get better page hits if possible
+ * input: size = size of block
+ * align2 = 2^align2 bytes alignment
+ * startSearch = linear offset from start of heap to begin search
+ * return: pointer to the allocated block, 0 if error
+ */
+PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch );
+
+/*
+ * Free block starts at offset
+ * input: pointer to a block
+ * return: 0 if OK, -1 if error
+ */
+int mmFreeMem( PMemBlock b );
+
+/*
+ * Reserve 'size' bytes block start at offset
+ * This is used to prevent allocation of memory already used
+ * by the X server for the front buffer, pixmaps, and cursor
+ * input: size, offset
+ * output: 0 if OK, -1 if error
+ */
+int mmReserveMem( memHeap_t *heap, int offset,int size );
+int mmFreeReserved( memHeap_t *heap, int offset );
+
+/*
+ * destroy MM
+ */
+void mmDestroy( memHeap_t *mmInit );
+
+/* For debuging purpose. */
+void mmDumpMemInfo( memHeap_t *mmInit );
+
+#endif