summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2010-03-09 06:13:46 +0100
committerLuc Verhaegen <libv@skynet.be>2010-03-09 06:13:46 +0100
commit100971599d48e42618f74352d5715997b7d7c1b5 (patch)
tree0b4de979992e3c6fd6dc0ed20d80eb601e5962a6
parent5dee9b7b19c1aa3a13618b08bc24f00677b5364b (diff)
Import i810 dri driver from mesa 7.0.3.7.0.47.0.3
-rw-r--r--configure.ac5
-rw-r--r--src/Makefile.am22
-rw-r--r--src/i810_3d_reg.h631
-rw-r--r--src/i810context.c584
-rw-r--r--src/i810context.h250
-rw-r--r--src/i810ioctl.c520
-rw-r--r--src/i810ioctl.h49
-rw-r--r--src/i810render.c173
-rw-r--r--src/i810screen.c472
-rw-r--r--src/i810screen.h99
-rw-r--r--src/i810span.c136
-rw-r--r--src/i810span.h14
-rw-r--r--src/i810state.c998
-rw-r--r--src/i810state.h15
-rw-r--r--src/i810tex.c550
-rw-r--r--src/i810tex.h78
-rw-r--r--src/i810texmem.c183
-rw-r--r--src/i810texstate.c752
-rw-r--r--src/i810tris.c871
-rw-r--r--src/i810tris.h36
-rw-r--r--src/i810vb.c489
-rw-r--r--src/i810vb.h60
-rw-r--r--src/server/i810_common.h192
-rw-r--r--src/server/i810_dri.c975
-rw-r--r--src/server/i810_dri.h128
-rw-r--r--src/server/i810_reg.h992
26 files changed, 9267 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac
index 2a78cfd..cb0cd4c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
# Process this file with autoconf to produce a configure script
AC_PREREQ(2.57)
-AC_INIT([mesa-dri-xxx], 7.0.3, [], mesa-dri-xxx)
+AC_INIT([mesa-dri-i810], 7.0.3, [], mesa-dri-i810)
AM_INIT_AUTOMAKE([dist-bzip2])
@@ -16,7 +16,8 @@ AC_PROG_CC
AC_HEADER_STDC
PKG_CHECK_MODULES([DRM], [libdrm >= 2.3.0])
-PKG_CHECK_MODULES([DRI], [libmesadri = 7.0.3 libmesadricommon = 7.0.3])
+PKG_CHECK_MODULES([DRI], [libmesadri >= 7.0.3 libmesadri < 7.1.0
+ libmesadricommon >= 7.0.3 libmesadricommon < 7.1.0])
AC_OUTPUT([
Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index aa854c5..3339583 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,19 @@
AM_CFLAGS = -DIN_DRI_DRIVER -DGLX_DIRECT_RENDERING -DGLX_INDIRECT_RENDERING
-xxx_dri_la_LTLIBRARIES = xxx_dri.la
-xxx_dri_la_CFLAGS = $(AM_CFLAGS) $(DRM_CFLAGS) $(DRI_CFLAGS) -Iserver
-xxx_dri_la_LDFLAGS = -module -noprefix -lm -ldl $(DRM_LIBS) $(DRI_LIBS)
-xxx_dri_ladir = @libdir@/dri
-xxx_dri_la_SOURCES = \
+i810_dri_la_LTLIBRARIES = i810_dri.la
+i810_dri_la_CFLAGS = $(AM_CFLAGS) $(DRM_CFLAGS) $(DRI_CFLAGS) -Iserver
+i810_dri_la_LDFLAGS = -module -noprefix -avoid-version -lm -ldl \
+ $(DRM_LIBS) $(DRI_LIBS)
+i810_dri_ladir = @libdir@/dri
+i810_dri_la_SOURCES = \
+ i810context.c \
+ i810ioctl.c \
+ i810render.c \
+ i810screen.c \
+ i810span.c \
+ i810state.c \
+ i810tex.c \
+ i810texmem.c \
+ i810texstate.c \
+ i810tris.c \
+ i810vb.c
diff --git a/src/i810_3d_reg.h b/src/i810_3d_reg.h
new file mode 100644
index 0000000..7cc59d5
--- /dev/null
+++ b/src/i810_3d_reg.h
@@ -0,0 +1,631 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h,v 1.7 2002/02/22 21:33:03 dawes Exp $ */
+
+#ifndef I810_3D_REG_H
+#define I810_3D_REG_H
+
+#include "i810_reg.h"
+
+/* Registers not used in the X server
+ */
+
+#define I810_NOP_ID 0x2094
+#define I810_NOP_ID_MASK ((1<<22)-1)
+
+
+/* 3D instructions
+ */
+
+
+/* GFXRENDERSTATE_PV_PIXELIZATION_RULE, p149
+ *
+ * Format:
+ * 0: GFX_OP_PV_RULE | PV_*
+ *
+ */
+#define GFX_OP_PV_RULE ((0x3<<29)|(0x7<<24))
+#define PV_SMALL_TRI_FILTER_ENABLE (0x1<<11)
+#define PV_UPDATE_PIXRULE (0x1<<10)
+#define PV_PIXRULE_ENABLE (0x1<<9)
+#define PV_UPDATE_LINELIST (0x1<<8)
+#define PV_LINELIST_MASK (0x3<<6)
+#define PV_LINELIST_PV0 (0x0<<6)
+#define PV_LINELIST_PV1 (0x1<<6)
+#define PV_UPDATE_TRIFAN (0x1<<5)
+#define PV_TRIFAN_MASK (0x3<<3)
+#define PV_TRIFAN_PV0 (0x0<<3)
+#define PV_TRIFAN_PV1 (0x1<<3)
+#define PV_TRIFAN_PV2 (0x2<<3)
+#define PV_UPDATE_TRISTRIP (0x1<<2)
+#define PV_TRISTRIP_MASK (0x3<<0)
+#define PV_TRISTRIP_PV0 (0x0<<0)
+#define PV_TRISTRIP_PV1 (0x1<<0)
+#define PV_TRISTRIP_PV2 (0x2<<0)
+
+
+/* GFXRENDERSTATE_SCISSOR_ENABLE, p146
+ *
+ * Format:
+ * 0: GFX_OP_SCISSOR | SC_*
+ */
+#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
+#define SC_UPDATE_SCISSOR (0x1<<1)
+#define SC_ENABLE_MASK (0x1<<0)
+#define SC_ENABLE (0x1<<0)
+
+/* GFXRENDERSTATE_SCISSOR_INFO, p147
+ *
+ * Format:
+ * 0: GFX_OP_SCISSOR_INFO
+ * 1: SCI_MIN_*
+ * 2: SCI_MAX_*
+ */
+#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
+#define SCI_YMIN_MASK (0xffff<<16)
+#define SCI_XMIN_MASK (0xffff<<0)
+#define SCI_YMAX_MASK (0xffff<<16)
+#define SCI_XMAX_MASK (0xffff<<0)
+
+/* GFXRENDERSTATE_DRAWING_RECT_INFO, p144
+ *
+ * Format:
+ * 0: GFX_OP_DRAWRECT_INFO
+ * 1: DR1_*
+ * 2: DR2_*
+ * 3: DR3_*
+ * 4: DR4_*
+ */
+#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
+#define DR1_RECT_CLIP_ENABLE (0x0<<31)
+#define DR1_RECT_CLIP_DISABLE (0x1<<31)
+#define DR1_X_DITHER_BIAS_MASK (0x3<<26)
+#define DR1_X_DITHER_BIAS_SHIFT 26
+#define DR1_Y_DITHER_BIAS_MASK (0x3<<24)
+#define DR1_Y_DITHER_BIAS_SHIFT 24
+#define DR2_YMIN_MASK (0xffff<<16)
+#define DR2_XMIN_MASK (0xffff<<0)
+#define DR3_YMAX_MASK (0xffff<<16)
+#define DR3_XMAX_MASK (0xffff<<0)
+#define DR4_YORG_MASK (0x3ff<<16)
+#define DR4_XORG_MASK (0x7ff<<0)
+
+
+/* GFXRENDERSTATE_LINEWIDTH_CULL_SHADE_MODE, p140
+ *
+ * Format:
+ * 0: GFX_OP_LINEWIDTH_CULL_SHADE_MODE | LCS_*
+ */
+#define GFX_OP_LINEWIDTH_CULL_SHADE_MODE ((0x3<<29)|(0x2<<24))
+#define LCS_UPDATE_ZMODE (0x1<<20)
+#define LCS_Z_MASK (0xf<<16)
+#define LCS_Z_NEVER (0x1<<16)
+#define LCS_Z_LESS (0x2<<16)
+#define LCS_Z_EQUAL (0x3<<16)
+#define LCS_Z_LEQUAL (0x4<<16)
+#define LCS_Z_GREATER (0x5<<16)
+#define LCS_Z_NOTEQUAL (0x6<<16)
+#define LCS_Z_GEQUAL (0x7<<16)
+#define LCS_Z_ALWAYS (0x8<<16)
+#define LCS_UPDATE_LINEWIDTH (0x1<<15)
+#define LCS_LINEWIDTH_MASK (0x7<<12)
+#define LCS_LINEWIDTH_SHIFT 12
+#define LCS_LINEWIDTH_0_5 (0x1<<12)
+#define LCS_LINEWIDTH_1_0 (0x2<<12)
+#define LCS_LINEWIDTH_2_0 (0x4<<12)
+#define LCS_LINEWIDTH_3_0 (0x6<<12)
+#define LCS_UPDATE_ALPHA_INTERP (0x1<<11)
+#define LCS_ALPHA_FLAT (0x1<<10)
+#define LCS_ALPHA_INTERP (0x0<<10)
+#define LCS_UPDATE_FOG_INTERP (0x1<<9)
+#define LCS_FOG_INTERP (0x0<<8)
+#define LCS_FOG_FLAT (0x1<<8)
+#define LCS_UPDATE_SPEC_INTERP (0x1<<7)
+#define LCS_SPEC_INTERP (0x0<<6)
+#define LCS_SPEC_FLAT (0x1<<6)
+#define LCS_UPDATE_RGB_INTERP (0x1<<5)
+#define LCS_RGB_INTERP (0x0<<4)
+#define LCS_RGB_FLAT (0x1<<4)
+#define LCS_UPDATE_CULL_MODE (0x1<<3)
+#define LCS_CULL_MASK (0x7<<0)
+#define LCS_CULL_DISABLE (0x1<<0)
+#define LCS_CULL_CW (0x2<<0)
+#define LCS_CULL_CCW (0x3<<0)
+#define LCS_CULL_BOTH (0x4<<0)
+
+#define LCS_INTERP_FLAT (LCS_ALPHA_FLAT|LCS_RGB_FLAT|LCS_SPEC_FLAT)
+#define LCS_UPDATE_INTERP (LCS_UPDATE_ALPHA_INTERP| \
+ LCS_UPDATE_RGB_INTERP| \
+ LCS_UPDATE_SPEC_INTERP)
+
+
+/* GFXRENDERSTATE_BOOLEAN_ENA_1, p142
+ *
+ */
+#define GFX_OP_BOOL_1 ((0x3<<29)|(0x3<<24))
+#define B1_UPDATE_SPEC_SETUP_ENABLE (1<<19)
+#define B1_SPEC_SETUP_ENABLE (1<<18)
+#define B1_UPDATE_ALPHA_SETUP_ENABLE (1<<17)
+#define B1_ALPHA_SETUP_ENABLE (1<<16)
+#define B1_UPDATE_CI_KEY_ENABLE (1<<15)
+#define B1_CI_KEY_ENABLE (1<<14)
+#define B1_UPDATE_CHROMAKEY_ENABLE (1<<13)
+#define B1_CHROMAKEY_ENABLE (1<<12)
+#define B1_UPDATE_Z_BIAS_ENABLE (1<<11)
+#define B1_Z_BIAS_ENABLE (1<<10)
+#define B1_UPDATE_SPEC_ENABLE (1<<9)
+#define B1_SPEC_ENABLE (1<<8)
+#define B1_UPDATE_FOG_ENABLE (1<<7)
+#define B1_FOG_ENABLE (1<<6)
+#define B1_UPDATE_ALPHA_TEST_ENABLE (1<<5)
+#define B1_ALPHA_TEST_ENABLE (1<<4)
+#define B1_UPDATE_BLEND_ENABLE (1<<3)
+#define B1_BLEND_ENABLE (1<<2)
+#define B1_UPDATE_Z_TEST_ENABLE (1<<1)
+#define B1_Z_TEST_ENABLE (1<<0)
+
+/* GFXRENDERSTATE_BOOLEAN_ENA_2, p143
+ *
+ */
+#define GFX_OP_BOOL_2 ((0x3<<29)|(0x4<<24))
+#define B2_UPDATE_MAP_CACHE_ENABLE (1<<17)
+#define B2_MAP_CACHE_ENABLE (1<<16)
+#define B2_UPDATE_ALPHA_DITHER_ENABLE (1<<15)
+#define B2_ALPHA_DITHER_ENABLE (1<<14)
+#define B2_UPDATE_FOG_DITHER_ENABLE (1<<13)
+#define B2_FOG_DITHER_ENABLE (1<<12)
+#define B2_UPDATE_SPEC_DITHER_ENABLE (1<<11)
+#define B2_SPEC_DITHER_ENABLE (1<<10)
+#define B2_UPDATE_RGB_DITHER_ENABLE (1<<9)
+#define B2_RGB_DITHER_ENABLE (1<<8)
+#define B2_UPDATE_FB_WRITE_ENABLE (1<<3)
+#define B2_FB_WRITE_ENABLE (1<<2)
+#define B2_UPDATE_ZB_WRITE_ENABLE (1<<1)
+#define B2_ZB_WRITE_ENABLE (1<<0)
+
+
+/* GFXRENDERSTATE_FOG_COLOR, p144
+ */
+#define GFX_OP_FOG_COLOR ((0x3<<29)|(0x15<<24))
+#define FOG_RED_SHIFT 16
+#define FOG_GREEN_SHIFT 8
+#define FOG_BLUE_SHIFT 0
+#define FOG_RESERVED_MASK ((0x7<<16)|(0x3<<8)|(0x3))
+
+
+/* GFXRENDERSTATE_Z_BIAS_ALPHA_FUNC_REF, p139
+ */
+#define GFX_OP_ZBIAS_ALPHAFUNC ((0x3<<29)|(0x14<<24))
+#define ZA_UPDATE_ZBIAS (1<<22)
+#define ZA_ZBIAS_SHIFT 14
+#define ZA_ZBIAS_MASK (0xff<<14)
+#define ZA_UPDATE_ALPHAFUNC (1<<13)
+#define ZA_ALPHA_MASK (0xf<<9)
+#define ZA_ALPHA_NEVER (1<<9)
+#define ZA_ALPHA_LESS (2<<9)
+#define ZA_ALPHA_EQUAL (3<<9)
+#define ZA_ALPHA_LEQUAL (4<<9)
+#define ZA_ALPHA_GREATER (5<<9)
+#define ZA_ALPHA_NOTEQUAL (6<<9)
+#define ZA_ALPHA_GEQUAL (7<<9)
+#define ZA_ALPHA_ALWAYS (8<<9)
+#define ZA_UPDATE_ALPHAREF (1<<8)
+#define ZA_ALPHAREF_MASK (0xff<<0)
+#define ZA_ALPHAREF_SHIFT 0
+#define ZA_ALPHAREF_RESERVED (0x7<<0)
+
+
+/* GFXRENDERSTATE_SRC_DST_BLEND_MONO, p136
+ */
+#define GFX_OP_SRC_DEST_MONO ((0x3<<29)|(0x8<<24))
+#define SDM_UPDATE_MONO_ENABLE (1<<13)
+#define SDM_MONO_ENABLE (1<<12)
+#define SDM_UPDATE_SRC_BLEND (1<<11)
+#define SDM_SRC_MASK (0xf<<6)
+#define SDM_SRC_ZERO (0x1<<6)
+#define SDM_SRC_ONE (0x2<<6)
+#define SDM_SRC_SRC_COLOR (0x3<<6)
+#define SDM_SRC_INV_SRC_COLOR (0x4<<6)
+#define SDM_SRC_SRC_ALPHA (0x5<<6)
+#define SDM_SRC_INV_SRC_ALPHA (0x6<<6)
+#define SDM_SRC_DST_COLOR (0x9<<6)
+#define SDM_SRC_INV_DST_COLOR (0xa<<6)
+#define SDM_SRC_BOTH_SRC_ALPHA (0xc<<6)
+#define SDM_SRC_BOTH_INV_SRC_ALPHA (0xd<<6)
+#define SDM_UPDATE_DST_BLEND (1<<5)
+#define SDM_DST_MASK (0xf<<0)
+#define SDM_DST_ZERO (0x1<<0)
+#define SDM_DST_ONE (0x2<<0)
+#define SDM_DST_SRC_COLOR (0x3<<0)
+#define SDM_DST_INV_SRC_COLOR (0x4<<0)
+#define SDM_DST_SRC_ALPHA (0x5<<0)
+#define SDM_DST_INV_SRC_ALPHA (0x6<<0)
+#define SDM_DST_DST_COLOR (0x9<<0)
+#define SDM_DST_INV_DST_COLOR (0xa<<0)
+#define SDM_DST_BOTH_SRC_ALPHA (0xc<<0)
+#define SDM_DST_BOTH_INV_SRC_ALPHA (0xd<<0)
+
+
+/* GFXRENDERSTATE_COLOR_FACTOR, p134
+ *
+ * Format:
+ * 0: GFX_OP_COLOR_FACTOR
+ * 1: ARGB8888 color factor
+ */
+#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
+
+/* GFXRENDERSTATE_MAP_ALPHA_BLEND_STAGES, p132
+ */
+#define GFX_OP_MAP_ALPHA_STAGES ((0x3<<29)|(0x1<<24))
+#define MA_STAGE_SHIFT 20
+#define MA_STAGE_0 (0<<20)
+#define MA_STAGE_1 (1<<20)
+#define MA_STAGE_2 (2<<20)
+
+#define MA_ARG_ONE (0x0<<2)
+#define MA_ARG_ALPHA_FACTOR (0x1<<2)
+#define MA_ARG_ITERATED_ALPHA (0x3<<2)
+#define MA_ARG_CURRENT_ALPHA (0x5<<2)
+#define MA_ARG_TEX0_ALPHA (0x6<<2)
+#define MA_ARG_TEX1_ALPHA (0x7<<2)
+#define MA_ARG_INVERT (0x1)
+#define MA_ARG_DONT_INVERT (0x0)
+
+#define MA_UPDATE_ARG1 (1<<18)
+#define MA_ARG1_SHIFT 13
+#define MA_ARG1_MASK (0x1d << MA_ARG1_SHIFT)
+
+#define MA_UPDATE_ARG2 (1<<12)
+#define MA_ARG2_SHIFT 6
+#define MA_ARG2_MASK (0x1d << MA_ARG2_SHIFT)
+
+#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)
+#define MA_OP_SUBTRACT (0x14)
+
+
+/* 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_ARG_ONE (0x0<<2)
+#define MC_ARG_COLOR_FACTOR (0x1<<2)
+#define MC_ARG_ACCUMULATOR (0x2<<2)
+#define MC_ARG_ITERATED_COLOR (0x3<<2)
+#define MC_ARG_SPECULAR_COLOR (0x4<<2)
+#define MC_ARG_CURRENT_COLOR (0x5<<2)
+#define MC_ARG_TEX0_COLOR (0x6<<2)
+#define MC_ARG_TEX1_COLOR (0x7<<2)
+#define MC_ARG_DONT_REPLICATE_ALPHA (0x0<<1)
+#define MC_ARG_REPLICATE_ALPHA (0x1<<1)
+#define MC_ARG_DONT_INVERT (0x0)
+#define MC_ARG_INVERT (0x1)
+
+#define MC_UPDATE_ARG1 (1<<17)
+#define MC_ARG1_SHIFT 12
+#define MC_ARG1_MASK (0x1f << MC_ARG1_SHIFT)
+
+#define MC_UPDATE_ARG2 (1<<11)
+#define MC_ARG2_SHIFT 6
+#define MC_ARG2_MASK (0x1f << MC_ARG2_SHIFT)
+
+#define MC_UPDATE_OP (1<<5)
+#define MC_OP_MASK (0xf)
+#define MC_OP_DISABLE (0x0)
+#define MC_OP_ARG1 (0x1)
+#define MC_OP_ARG2 (0x2)
+#define MC_OP_MODULATE (0x3)
+#define MC_OP_MODULATE_X2 (0x4)
+#define MC_OP_MODULATE_X4 (0x5)
+#define MC_OP_ADD (0x6)
+#define MC_OP_ADD_SIGNED (0x7)
+#define MC_OP_LIN_BLEND_ITER_ALPHA (0x8)
+#define MC_OP_LIN_BLEND_ALPHA_FACTOR (0xa)
+#define MC_OP_LIN_BLEND_TEX0_ALPHA (0x10)
+#define MC_OP_LIN_BLEND_TEX1_ALPHA (0x11)
+#define MC_OP_LIN_BLEND_TEX0_COLOR (0x12)
+#define MC_OP_LIN_BLEND_TEX1_COLOR (0x13)
+#define MC_OP_SUBTRACT (0x14)
+
+/* GFXRENDERSTATE_MAP_PALETTE_LOAD, p128
+ *
+ * Format:
+ * 0: GFX_OP_MAP_PALETTE_LOAD
+ * 1: 16bpp color[0]
+ * ...
+ * 256: 16bpp color[255]
+ */
+#define GFX_OP_MAP_PALETTE_LOAD ((0x3<<29)|(0x1d<<24)|(0x82<<16)|0xff)
+
+/* GFXRENDERSTATE_MAP_LOD_CONTROL, p127
+ */
+#define GFX_OP_MAP_LOD_CTL ((0x3<<29)|(0x1c<<24)|(0x4<<19))
+#define MLC_MAP_ID_SHIFT 16
+#define MLC_MAP_0 (0<<16)
+#define MLC_MAP_1 (1<<16)
+#define MLC_UPDATE_DITHER_WEIGHT (1<<10)
+#define MLC_DITHER_WEIGHT_MASK (0x3<<8)
+#define MLC_DITHER_WEIGHT_FULL (0x0<<8)
+#define MLC_DITHER_WEIGHT_50 (0x1<<8)
+#define MLC_DITHER_WEIGHT_25 (0x2<<8)
+#define MLC_DITHER_WEIGHT_12 (0x3<<8)
+#define MLC_UPDATE_LOD_BIAS (1<<7)
+#define MLC_LOD_BIAS_MASK ((1<<7)-1)
+
+/* GFXRENDERSTATE_MAP_LOD_LIMITS, p126
+ */
+#define GFX_OP_MAP_LOD_LIMITS ((0x3<<29)|(0x1c<<24)|(0x3<<19))
+#define MLL_MAP_ID_SHIFT 16
+#define MLL_MAP_0 (0<<16)
+#define MLL_MAP_1 (1<<16)
+#define MLL_UPDATE_MAX_MIP (1<<13)
+#define MLL_MAX_MIP_SHIFT 5
+#define MLL_MAX_MIP_MASK (0xff<<5)
+#define MLL_MAX_MIP_ONE (0x10<<5)
+#define MLL_UPDATE_MIN_MIP (1<<4)
+#define MLL_MIN_MIP_SHIFT 0
+#define MLL_MIN_MIP_MASK (0xf<<0)
+
+/* GFXRENDERSTATE_MAP_FILTER, p124
+ */
+#define GFX_OP_MAP_FILTER ((0x3<<29)|(0x1c<<24)|(0x2<<19))
+#define MF_MAP_ID_SHIFT 16
+#define MF_MAP_0 (0<<16)
+#define MF_MAP_1 (1<<16)
+#define MF_UPDATE_ANISOTROPIC (1<<12)
+#define MF_ANISOTROPIC_MASK (1<<10)
+#define MF_ANISOTROPIC_ENABLE (1<<10)
+#define MF_UPDATE_MIP_FILTER (1<<9)
+#define MF_MIP_MASK (0x3<<6)
+#define MF_MIP_NONE (0x0<<6)
+#define MF_MIP_NEAREST (0x1<<6)
+#define MF_MIP_DITHER (0x2<<6)
+#define MF_MIP_LINEAR (0x3<<6)
+#define MF_UPDATE_MAG_FILTER (1<<5)
+#define MF_MAG_MASK (1<<3)
+#define MF_MAG_LINEAR (1<<3)
+#define MF_MAG_NEAREST (0<<3)
+#define MF_UPDATE_MIN_FILTER (1<<2)
+#define MF_MIN_MASK (1<<0)
+#define MF_MIN_LINEAR (1<<0)
+#define MF_MIN_NEAREST (0<<0)
+
+/* GFXRENDERSTATE_MAP_INFO, p118
+ */
+#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x2)
+#define MI1_MAP_ID_SHIFT 28
+#define MI1_MAP_0 (0<<28)
+#define MI1_MAP_1 (1<<28)
+#define MI1_FMT_MASK (0x7<<24)
+#define MI1_FMT_8CI (0x0<<24)
+#define MI1_FMT_8BPP (0x1<<24)
+#define MI1_FMT_16BPP (0x2<<24)
+#define MI1_FMT_422 (0x5<<24)
+#define MI1_PF_MASK (0x3<<21)
+#define MI1_PF_8CI_RGB565 (0x0<<21)
+#define MI1_PF_8CI_ARGB1555 (0x1<<21)
+#define MI1_PF_8CI_ARGB4444 (0x2<<21)
+#define MI1_PF_8CI_AY88 (0x3<<21)
+#define MI1_PF_16BPP_RGB565 (0x0<<21)
+#define MI1_PF_16BPP_ARGB1555 (0x1<<21)
+#define MI1_PF_16BPP_ARGB4444 (0x2<<21)
+#define MI1_PF_16BPP_AY88 (0x3<<21)
+#define MI1_PF_422_YCRCB_SWAP_Y (0x0<<21)
+#define MI1_PF_422_YCRCB (0x1<<21)
+#define MI1_PF_422_YCRCB_SWAP_UV (0x2<<21)
+#define MI1_PF_422_YCRCB_SWAP_YUV (0x3<<21)
+#define MI1_OUTPUT_CHANNEL_MASK (0x3<<19)
+#define MI1_COLOR_CONV_ENABLE (1<<18)
+#define MI1_VERT_STRIDE_MASK (1<<17)
+#define MI1_VERT_STRIDE_1 (1<<17)
+#define MI1_VERT_OFFSET_MASK (1<<16)
+#define MI1_VERT_OFFSET_1 (1<<16)
+#define MI1_ENABLE_FENCE_REGS (1<<10)
+#define MI1_TILED_SURFACE (1<<9)
+#define MI1_TILE_WALK_X (0<<8)
+#define MI1_TILE_WALK_Y (1<<8)
+#define MI1_PITCH_MASK (0xf<<0)
+#define MI2_DIMENSIONS_ARE_LOG2 (1<<31)
+#define MI2_DIMENSIONS_ARE_EXACT (0<<31)
+#define MI2_HEIGHT_SHIFT 16
+#define MI2_HEIGHT_MASK (0x1ff<<16)
+#define MI2_WIDTH_SHIFT 0
+#define MI2_WIDTH_MASK (0x1ff<<0)
+#define MI3_BASE_ADDR_MASK (~0xf)
+
+/* GFXRENDERSTATE_MAP_COORD_SETS, p116
+ */
+#define GFX_OP_MAP_COORD_SETS ((0x3<<29)|(0x1c<<24)|(0x1<<19))
+#define MCS_COORD_ID_SHIFT 16
+#define MCS_COORD_0 (0<<16)
+#define MCS_COORD_1 (1<<16)
+#define MCS_UPDATE_NORMALIZED (1<<15)
+#define MCS_NORMALIZED_COORDS_MASK (1<<14)
+#define MCS_NORMALIZED_COORDS (1<<14)
+#define MCS_UPDATE_V_STATE (1<<7)
+#define MCS_V_STATE_MASK (0x3<<4)
+#define MCS_V_WRAP (0x0<<4)
+#define MCS_V_MIRROR (0x1<<4)
+#define MCS_V_CLAMP (0x2<<4)
+#define MCS_V_WRAP_SHORTEST (0x3<<4)
+#define MCS_UPDATE_U_STATE (1<<3)
+#define MCS_U_STATE_MASK (0x3<<0)
+#define MCS_U_WRAP (0x0<<0)
+#define MCS_U_MIRROR (0x1<<0)
+#define MCS_U_CLAMP (0x2<<0)
+#define MCS_U_WRAP_SHORTEST (0x3<<0)
+
+/* GFXRENDERSTATE_MAP_TEXELS, p115
+ */
+#define GFX_OP_MAP_TEXELS ((0x3<<29)|(0x1c<<24)|(0x0<<19))
+#define MT_UPDATE_TEXEL1_STATE (1<<15)
+#define MT_TEXEL1_DISABLE (0<<14)
+#define MT_TEXEL1_ENABLE (1<<14)
+#define MT_TEXEL1_COORD0 (0<<11)
+#define MT_TEXEL1_COORD1 (1<<11)
+#define MT_TEXEL1_MAP0 (0<<8)
+#define MT_TEXEL1_MAP1 (1<<8)
+#define MT_UPDATE_TEXEL0_STATE (1<<7)
+#define MT_TEXEL0_DISABLE (0<<6)
+#define MT_TEXEL0_ENABLE (1<<6)
+#define MT_TEXEL0_COORD0 (0<<3)
+#define MT_TEXEL0_COORD1 (1<<3)
+#define MT_TEXEL0_MAP0 (0<<0)
+#define MT_TEXEL0_MAP1 (1<<0)
+
+/* GFXRENDERSTATE_VERTEX_FORMAT, p110
+ */
+#define GFX_OP_VERTEX_FMT ((0x3<<29)|(0x5<<24))
+#define VF_TEXCOORD_COUNT_SHIFT 8
+#define VF_TEXCOORD_COUNT_0 (0<<8)
+#define VF_TEXCOORD_COUNT_1 (1<<8)
+#define VF_TEXCOORD_COUNT_2 (2<<8)
+#define VF_SPEC_FOG_ENABLE (1<<7)
+#define VF_RGBA_ENABLE (1<<6)
+#define VF_Z_OFFSET_ENABLE (1<<5)
+#define VF_XYZ (0x1<<1)
+#define VF_XYZW (0x2<<1)
+#define VF_XY (0x3<<1)
+#define VF_XYW (0x4<<1)
+
+
+#define VERT_X_MASK (~0xf)
+#define VERT_X_EDGE_V2V0 (1<<2)
+#define VERT_X_EDGE_V1V2 (1<<1)
+#define VERT_X_EDGE_V0V1 (1<<0)
+
+/* Not enabled fields should not be sent to hardware:
+ */
+typedef struct {
+ union {
+ float x;
+ unsigned int edge_flags;
+ } x;
+ float y;
+ float z;
+ float z_bias;
+ float oow;
+ unsigned int argb;
+ unsigned int fog_spec_rgb; /* spec g and r ignored. */
+ float tu0;
+ float tv0;
+ float tu1;
+ float tv1;
+} i810_full_vertex;
+
+
+
+/* GFXCMDPARSER_BATCH_BUFFER, p105
+ *
+ * Not clear whether start address must be shifted or not. Not clear
+ * whether address is physical system memory, or subject to GTT
+ * translation. Because the address appears to be 32 bits long,
+ * perhaps it refers to physical system memory...
+ */
+#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
+#define BB1_START_ADDR_MASK (~0x7)
+#define BB1_PROTECTED (1<<0)
+#define BB1_UNPROTECTED (0<<0)
+#define BB2_END_ADDR_MASK (~0x7)
+
+/* Hardware seems to barf on buffers larger than this (in strange ways)...
+ */
+#define MAX_BATCH (512*1024)
+
+
+/* GFXCMDPARSER_Z_BUFFER_INFO, p98
+ *
+ * Base address is in GTT space, and must be 4K aligned
+ */
+#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23))
+#define ZB_BASE_ADDR_SHIFT 0
+#define ZB_BASE_ADDR_MASK (~((1<<12)-1))
+#define ZB_PITCH_512B (0x0<<0)
+#define ZB_PITCH_1K (0x1<<0)
+#define ZB_PITCH_2K (0x2<<0)
+#define ZB_PITCH_4K (0x3<<0)
+
+/* GFXCMDPARSER_FRONT_BUFFER_INFO, p97
+ *
+ * Format:
+ * 0: CMD_OP_FRONT_BUFFER_INFO | (pitch<<FB0_PITCH_SHIFT) | FB0_*
+ * 1: FB1_*
+ */
+#define CMD_OP_FRONT_BUFFER_INFO ((0x0<<29)|(0x14<<23))
+#define FB0_PITCH_SHIFT 8
+#define FB0_FLIP_SYNC (0<<6)
+#define FB0_FLIP_ASYNC (1<<6)
+#define FB0_BASE_ADDR_SHIFT 0
+#define FB0_BASE_ADDR_MASK 0x03FFFFF8
+
+/* GFXCMDPARSER_DEST_BUFFER_INFO, p96
+ *
+ * Format:
+ */
+#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23))
+#define DB1_BASE_ADDR_SHIFT 0
+#define DB1_BASE_ADDR_MASK 0x03FFF000
+#define DB1_PITCH_512B (0x0<<0)
+#define DB1_PITCH_1K (0x1<<0)
+#define DB1_PITCH_2K (0x2<<0)
+#define DB1_PITCH_4K (0x4<<0)
+
+
+/* GFXRENDERSTATE_DEST_BUFFER_VARIABLES, p152
+ *
+ * Format:
+ * 0: GFX_OP_DESTBUFFER_VARS
+ * 1: DEST_*
+ */
+#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
+#define DV_HORG_BIAS_MASK (0xf<<20)
+#define DV_HORG_BIAS_OGL (0x0<<20)
+#define DV_VORG_BIAS_MASK (0xf<<16)
+#define DV_VORG_BIAS_OGL (0x0<<16)
+#define DV_PF_MASK (0x7<<8)
+#define DV_PF_INDEX (0x0<<8)
+#define DV_PF_555 (0x1<<8)
+#define DV_PF_565 (0x2<<8)
+
+#define GFX_OP_ANTIALIAS ((0x3<<29)|(0x6<<24))
+#define AA_UPDATE_EDGEFLAG (1<<13)
+#define AA_ENABLE_EDGEFLAG (1<<12)
+#define AA_UPDATE_POLYWIDTH (1<<11)
+#define AA_POLYWIDTH_05 (1<<9)
+#define AA_POLYWIDTH_10 (2<<9)
+#define AA_POLYWIDTH_20 (3<<9)
+#define AA_POLYWIDTH_40 (4<<9)
+#define AA_UPDATE_LINEWIDTH (1<<8)
+#define AA_LINEWIDTH_05 (1<<6)
+#define AA_LINEWIDTH_10 (2<<6)
+#define AA_LINEWIDTH_20 (3<<6)
+#define AA_LINEWIDTH_40 (4<<6)
+#define AA_UPDATE_BB_EXPANSION (1<<5)
+#define AA_BB_EXPANSION_SHIFT 2
+#define AA_UPDATE_AA_ENABLE (1<<1)
+#define AA_ENABLE (1<<0)
+
+#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define ST1_ENABLE (1<<16)
+#define ST1_MASK (0xffff)
+
+#define I810_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
+
+#endif
diff --git a/src/i810context.c b/src/i810context.c
new file mode 100644
index 0000000..3f7f2cc
--- /dev/null
+++ b/src/i810context.c
@@ -0,0 +1,584 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810context.c,v 1.3 2002/10/30 12:51:33 alanh Exp $ */
+
+/*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ *
+ */
+
+
+#include "glheader.h"
+#include "context.h"
+#include "matrix.h"
+#include "simple_list.h"
+#include "extensions.h"
+#include "framebuffer.h"
+#include "imports.h"
+#include "points.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "vbo/vbo.h"
+
+#include "tnl/t_pipeline.h"
+
+#include "drivers/common/driverfuncs.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810state.h"
+#include "i810tex.h"
+#include "i810span.h"
+#include "i810tris.h"
+#include "i810vb.h"
+#include "i810ioctl.h"
+
+#include "drirenderbuffer.h"
+#include "utils.h"
+
+#define need_GL_ARB_multisample
+#define need_GL_ARB_texture_compression
+#define need_GL_ARB_vertex_buffer_object
+#include "extension_helper.h"
+
+#ifndef I810_DEBUG
+int I810_DEBUG = (0);
+#endif
+
+PUBLIC const char __driConfigOptions[] = { 0 };
+const GLuint __driNConfigOptions = 0;
+
+#define DRIVER_DATE "20050821"
+
+static const GLubyte *i810GetString( GLcontext *ctx, GLenum name )
+{
+ static char buffer[128];
+
+ switch (name) {
+ case GL_VENDOR:
+ return (GLubyte *)"Keith Whitwell";
+ case GL_RENDERER: {
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ const char * chipset;
+
+ switch (imesa->i810Screen->deviceID) {
+ case PCI_CHIP_I810: chipset = "i810"; break;
+ case PCI_CHIP_I810_DC100: chipset = "i810 DC-100"; break;
+ case PCI_CHIP_I810_E: chipset = "i810E"; break;
+ case PCI_CHIP_I815: chipset = "i815"; break;
+ default: chipset = "Unknown i810-class Chipset"; break;
+ }
+
+ (void) driGetRendererString( buffer, chipset, DRIVER_DATE, 0 );
+ return (GLubyte *) buffer;
+ }
+ default:
+ return 0;
+ }
+}
+
+static void i810BufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ /* Need to lock to make sure the driDrawable is uptodate. This
+ * information is used to resize Mesa's software buffers, so it has
+ * to be correct.
+ */
+ LOCK_HARDWARE(imesa);
+ *width = imesa->driDrawable->w;
+ *height = imesa->driDrawable->h;
+ UNLOCK_HARDWARE(imesa);
+}
+
+/* Extension strings exported by the i810 driver.
+ */
+const struct dri_extension card_extensions[] =
+{
+ { "GL_ARB_multisample", GL_ARB_multisample_functions },
+ { "GL_ARB_multitexture", NULL },
+ { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
+ { "GL_ARB_texture_env_add", NULL },
+ { "GL_ARB_texture_env_combine", NULL },
+ { "GL_ARB_texture_env_crossbar", NULL },
+ { "GL_ARB_texture_mirrored_repeat", NULL },
+ { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions },
+ { "GL_EXT_stencil_wrap", NULL },
+ { "GL_EXT_texture_edge_clamp", NULL },
+ { "GL_EXT_texture_env_combine", NULL },
+ { "GL_EXT_texture_lod_bias", NULL },
+ { "GL_EXT_texture_rectangle", NULL },
+ { "GL_MESA_ycbcr_texture", NULL },
+ { "GL_NV_blend_square", NULL },
+ { "GL_SGIS_generate_mipmap", NULL },
+ { NULL, NULL }
+};
+
+extern const struct tnl_pipeline_stage _i810_render_stage;
+
+static const struct tnl_pipeline_stage *i810_pipeline[] = {
+ &_tnl_vertex_transform_stage,
+ &_tnl_normal_transform_stage,
+ &_tnl_lighting_stage,
+ &_tnl_fog_coordinate_stage,
+ &_tnl_texgen_stage,
+ &_tnl_texture_transform_stage,
+ /* REMOVE: point attenuation stage */
+#if 1
+ &_i810_render_stage, /* ADD: unclipped rastersetup-to-dma */
+#endif
+ &_tnl_render_stage,
+ 0,
+};
+
+static const struct dri_debug_control debug_control[] =
+{
+ { "fall", DEBUG_FALLBACKS },
+ { "tex", DEBUG_TEXTURE },
+ { "ioctl", DEBUG_IOCTL },
+ { "prim", DEBUG_PRIMS },
+ { "vert", DEBUG_VERTS },
+ { "state", DEBUG_STATE },
+ { "verb", DEBUG_VERBOSE },
+ { "dri", DEBUG_DRI },
+ { "dma", DEBUG_DMA },
+ { "san", DEBUG_SANITY },
+ { "sync", DEBUG_SYNC },
+ { "sleep", DEBUG_SLEEP },
+ { NULL, 0 }
+};
+
+GLboolean
+i810CreateContext( const __GLcontextModes *mesaVis,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate )
+{
+ GLcontext *ctx, *shareCtx;
+ i810ContextPtr imesa;
+ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+ i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private;
+ I810SAREAPtr saPriv = (I810SAREAPtr)
+ (((GLubyte *)sPriv->pSAREA) + i810Screen->sarea_priv_offset);
+ struct dd_function_table functions;
+
+ /* Allocate i810 context */
+ imesa = (i810ContextPtr) CALLOC_STRUCT(i810_context_t);
+ if (!imesa) {
+ return GL_FALSE;
+ }
+
+ driContextPriv->driverPrivate = imesa;
+
+ imesa->i810Screen = i810Screen;
+ imesa->driScreen = sPriv;
+ imesa->sarea = saPriv;
+ imesa->glBuffer = NULL;
+
+ /* Init default driver functions then plug in our I810-specific functions
+ * (the texture functions are especially important)
+ */
+ _mesa_init_driver_functions( &functions );
+ i810InitIoctlFuncs( &functions );
+ i810InitTextureFuncs( &functions );
+
+
+ /* Allocate the Mesa context */
+ if (sharedContextPrivate)
+ shareCtx = ((i810ContextPtr) sharedContextPrivate)->glCtx;
+ else
+ shareCtx = NULL;
+ imesa->glCtx = _mesa_create_context(mesaVis, shareCtx,
+ &functions, (void*) imesa);
+ if (!imesa->glCtx) {
+ FREE(imesa);
+ return GL_FALSE;
+ }
+
+ (void) memset( imesa->texture_heaps, 0, sizeof( imesa->texture_heaps ) );
+ make_empty_list( & imesa->swapped );
+
+ imesa->nr_heaps = 1;
+ imesa->texture_heaps[0] = driCreateTextureHeap( 0, imesa,
+ i810Screen->textureSize,
+ 12,
+ I810_NR_TEX_REGIONS,
+ imesa->sarea->texList,
+ (unsigned *) & imesa->sarea->texAge, /* XXX we shouldn't cast! */
+ & imesa->swapped,
+ sizeof( struct i810_texture_object_t ),
+ (destroy_texture_object_t *) i810DestroyTexObj );
+
+
+
+ /* Set the maximum texture size small enough that we can guarentee
+ * that both texture units can bind a maximal texture and have them
+ * in memory at once.
+ */
+
+
+
+ ctx = imesa->glCtx;
+ ctx->Const.MaxTextureUnits = 2;
+ ctx->Const.MaxTextureImageUnits = 2;
+ ctx->Const.MaxTextureCoordUnits = 2;
+
+
+ /* FIXME: driCalcualteMaxTextureLevels assumes that mipmaps are tightly
+ * FIXME: packed, but they're not in Intel graphics hardware.
+ */
+ driCalculateMaxTextureLevels( imesa->texture_heaps,
+ imesa->nr_heaps,
+ & ctx->Const,
+ 4,
+ 11, /* max 2D texture size is 2048x2048 */
+ 0, /* 3D textures unsupported */
+ 0, /* cube textures unsupported. */
+ 0, /* texture rectangles unsupported. */
+ 12,
+ GL_FALSE,
+ 0 );
+
+ ctx->Const.MinLineWidth = 1.0;
+ ctx->Const.MinLineWidthAA = 1.0;
+ ctx->Const.MaxLineWidth = 3.0;
+ ctx->Const.MaxLineWidthAA = 3.0;
+ ctx->Const.LineWidthGranularity = 1.0;
+
+ ctx->Const.MinPointSize = 1.0;
+ ctx->Const.MinPointSizeAA = 1.0;
+ ctx->Const.MaxPointSize = 3.0;
+ ctx->Const.MaxPointSizeAA = 3.0;
+ ctx->Const.PointSizeGranularity = 1.0;
+
+ /* reinitialize the context point state.
+ * It depend on constants in __GLcontextRec::Const
+ */
+ _mesa_init_point(ctx);
+
+ ctx->Driver.GetBufferSize = i810BufferSize;
+ ctx->Driver.GetString = i810GetString;
+
+ /* Who owns who?
+ */
+ ctx->DriverCtx = (void *) imesa;
+ imesa->glCtx = ctx;
+
+ /* Initialize the software rasterizer and helper modules.
+ */
+ _swrast_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
+ _tnl_CreateContext( ctx );
+ _swsetup_CreateContext( ctx );
+
+ /* Install the customized pipeline:
+ */
+ _tnl_destroy_pipeline( ctx );
+ _tnl_install_pipeline( ctx, i810_pipeline );
+
+ /* Configure swrast and T&L to match hardware characteristics:
+ */
+ _swrast_allow_pixel_fog( ctx, GL_FALSE );
+ _swrast_allow_vertex_fog( ctx, GL_TRUE );
+ _tnl_allow_pixel_fog( ctx, GL_FALSE );
+ _tnl_allow_vertex_fog( ctx, GL_TRUE );
+
+ /* Dri stuff
+ */
+ imesa->hHWContext = driContextPriv->hHWContext;
+ imesa->driFd = sPriv->fd;
+ imesa->driHwLock = &sPriv->pSAREA->lock;
+
+ imesa->stipple_in_hw = 1;
+ imesa->RenderIndex = ~0;
+ imesa->dirty = I810_UPLOAD_CTX|I810_UPLOAD_BUFFERS;
+ imesa->upload_cliprects = GL_TRUE;
+
+ imesa->CurrentTexObj[0] = 0;
+ imesa->CurrentTexObj[1] = 0;
+
+ _math_matrix_ctr( &imesa->ViewportMatrix );
+
+ driInitExtensions( ctx, card_extensions, GL_TRUE );
+ /* XXX these should really go right after _mesa_init_driver_functions() */
+ i810InitStateFuncs( ctx );
+ i810InitTriFuncs( ctx );
+ i810InitSpanFuncs( ctx );
+ i810InitVB( ctx );
+ i810InitState( ctx );
+
+#if DO_DEBUG
+ I810_DEBUG = driParseDebugString( getenv( "I810_DEBUG" ),
+ debug_control );
+ I810_DEBUG |= driParseDebugString( getenv( "INTEL_DEBUG" ),
+ debug_control );
+#endif
+
+ return GL_TRUE;
+}
+
+void
+i810DestroyContext(__DRIcontextPrivate *driContextPriv)
+{
+ i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate;
+
+ assert(imesa); /* should never be null */
+ if (imesa) {
+ GLboolean release_texture_heaps;
+
+
+ release_texture_heaps = (imesa->glCtx->Shared->RefCount == 1);
+ _swsetup_DestroyContext( imesa->glCtx );
+ _tnl_DestroyContext( imesa->glCtx );
+ _vbo_DestroyContext( imesa->glCtx );
+ _swrast_DestroyContext( imesa->glCtx );
+
+ i810FreeVB( imesa->glCtx );
+
+ /* free the Mesa context */
+ imesa->glCtx->DriverCtx = NULL;
+ _mesa_destroy_context(imesa->glCtx);
+ if ( release_texture_heaps ) {
+ /* This share group is about to go away, free our private
+ * texture object data.
+ */
+ unsigned int i;
+
+ for ( i = 0 ; i < imesa->nr_heaps ; i++ ) {
+ driDestroyTextureHeap( imesa->texture_heaps[ i ] );
+ imesa->texture_heaps[ i ] = NULL;
+ }
+
+ assert( is_empty_list( & imesa->swapped ) );
+ }
+
+ FREE(imesa);
+ }
+}
+
+
+void i810XMesaSetFrontClipRects( i810ContextPtr imesa )
+{
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+
+ imesa->numClipRects = dPriv->numClipRects;
+ imesa->pClipRects = dPriv->pClipRects;
+ imesa->drawX = dPriv->x;
+ imesa->drawY = dPriv->y;
+
+ i810EmitDrawingRectangle( imesa );
+ imesa->upload_cliprects = GL_TRUE;
+}
+
+
+void i810XMesaSetBackClipRects( i810ContextPtr imesa )
+{
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+
+ if (imesa->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0)
+ {
+ imesa->numClipRects = dPriv->numClipRects;
+ imesa->pClipRects = dPriv->pClipRects;
+ imesa->drawX = dPriv->x;
+ imesa->drawY = dPriv->y;
+ } else {
+ imesa->numClipRects = dPriv->numBackClipRects;
+ imesa->pClipRects = dPriv->pBackClipRects;
+ imesa->drawX = dPriv->backX;
+ imesa->drawY = dPriv->backY;
+ }
+
+ i810EmitDrawingRectangle( imesa );
+ imesa->upload_cliprects = GL_TRUE;
+}
+
+
+static void i810XMesaWindowMoved( i810ContextPtr imesa )
+{
+ /* Determine current color drawing buffer */
+ switch (imesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0]) {
+ case BUFFER_BIT_FRONT_LEFT:
+ i810XMesaSetFrontClipRects( imesa );
+ break;
+ case BUFFER_BIT_BACK_LEFT:
+ i810XMesaSetBackClipRects( imesa );
+ break;
+ default:
+ /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
+ i810XMesaSetFrontClipRects( imesa );
+ }
+}
+
+
+GLboolean
+i810UnbindContext(__DRIcontextPrivate *driContextPriv)
+{
+ i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate;
+ if (imesa) {
+ imesa->dirty = I810_UPLOAD_CTX|I810_UPLOAD_BUFFERS;
+ if (imesa->CurrentTexObj[0]) imesa->dirty |= I810_UPLOAD_TEX0;
+ if (imesa->CurrentTexObj[1]) imesa->dirty |= I810_UPLOAD_TEX1;
+ }
+
+ return GL_TRUE;
+}
+
+
+GLboolean
+i810MakeCurrent(__DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv)
+{
+ if (driContextPriv) {
+ i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate;
+
+ /* Shouldn't the readbuffer be stored also?
+ */
+ imesa->driDrawable = driDrawPriv;
+
+ _mesa_make_current(imesa->glCtx,
+ (GLframebuffer *) driDrawPriv->driverPrivate,
+ (GLframebuffer *) driReadPriv->driverPrivate);
+
+ /* Are these necessary?
+ */
+ i810XMesaWindowMoved( imesa );
+ }
+ else {
+ _mesa_make_current(NULL, NULL, NULL);
+ }
+
+ return GL_TRUE;
+}
+
+static void
+i810UpdatePageFlipping( i810ContextPtr imesa )
+{
+ GLcontext *ctx = imesa->glCtx;
+ int front = 0;
+
+ /* Determine current color drawing buffer */
+ switch (ctx->DrawBuffer->_ColorDrawBufferMask[0]) {
+ case BUFFER_BIT_FRONT_LEFT:
+ front = 1;
+ break;
+ case BUFFER_BIT_BACK_LEFT:
+ front = 0;
+ break;
+ default:
+ return;
+ }
+
+ if ( imesa->sarea->pf_current_page == 1 )
+ front ^= 1;
+
+ driFlipRenderbuffers(ctx->WinSysDrawBuffer, front);
+
+ if (front) {
+ imesa->BufferSetup[I810_DESTREG_DI1] = imesa->i810Screen->fbOffset | imesa->i810Screen->backPitchBits;
+ } else {
+ imesa->BufferSetup[I810_DESTREG_DI1] = imesa->i810Screen->backOffset | imesa->i810Screen->backPitchBits;
+ }
+
+ imesa->dirty |= I810_UPLOAD_BUFFERS;
+}
+
+void i810GetLock( i810ContextPtr imesa, GLuint flags )
+{
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ __DRIscreenPrivate *sPriv = imesa->driScreen;
+ I810SAREAPtr sarea = imesa->sarea;
+ int me = imesa->hHWContext;
+ unsigned i;
+
+ drmGetLock(imesa->driFd, imesa->hHWContext, flags);
+
+ /* If the window moved, may need to set a new cliprect now.
+ *
+ * NOTE: This releases and regains the hw lock, so all state
+ * checking must be done *after* this call:
+ */
+ DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
+
+
+ /* If we lost context, need to dump all registers to hardware.
+ * Note that we don't care about 2d contexts, even if they perform
+ * accelerated commands, so the DRI locking in the X server is even
+ * more broken than usual.
+ */
+ if (sarea->ctxOwner != me) {
+ driUpdateFramebufferSize(imesa->glCtx, dPriv);
+ imesa->upload_cliprects = GL_TRUE;
+ imesa->dirty = I810_UPLOAD_CTX|I810_UPLOAD_BUFFERS;
+ if (imesa->CurrentTexObj[0]) imesa->dirty |= I810_UPLOAD_TEX0;
+ if (imesa->CurrentTexObj[1]) imesa->dirty |= I810_UPLOAD_TEX1;
+ sarea->ctxOwner = me;
+ }
+
+ /* Shared texture managment - if another client has played with
+ * texture space, figure out which if any of our textures have been
+ * ejected, and update our global LRU.
+ */
+ for ( i = 0 ; i < imesa->nr_heaps ; i++ ) {
+ DRI_AGE_TEXTURES( imesa->texture_heaps[ i ] );
+ }
+
+ if (imesa->lastStamp != dPriv->lastStamp) {
+ i810UpdatePageFlipping( imesa );
+ i810XMesaWindowMoved( imesa );
+ imesa->lastStamp = dPriv->lastStamp;
+ }
+}
+
+
+void
+i810SwapBuffers( __DRIdrawablePrivate *dPriv )
+{
+ if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+ i810ContextPtr imesa;
+ GLcontext *ctx;
+ imesa = (i810ContextPtr) dPriv->driContextPriv->driverPrivate;
+ ctx = imesa->glCtx;
+ if (ctx->Visual.doubleBufferMode) {
+ _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
+ if ( imesa->sarea->pf_active ) {
+ i810PageFlip( dPriv );
+ } else {
+ i810CopyBuffer( dPriv );
+ }
+ }
+ }
+ else {
+ /* XXX this shouldn't be an error but we can't handle it for now */
+ _mesa_problem(NULL, "i810SwapBuffers: drawable has no context!\n");
+ }
+}
+
diff --git a/src/i810context.h b/src/i810context.h
new file mode 100644
index 0000000..b83500b
--- /dev/null
+++ b/src/i810context.h
@@ -0,0 +1,250 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810context.h,v 1.9 2002/12/16 16:18:51 dawes Exp $ */
+
+#ifndef I810CONTEXT_INC
+#define I810CONTEXT_INC
+
+typedef struct i810_context_t i810Context;
+typedef struct i810_context_t *i810ContextPtr;
+typedef struct i810_texture_object_t *i810TextureObjectPtr;
+
+#include "drm.h"
+#include "mtypes.h"
+#include "mm.h"
+
+#include "i810screen.h"
+#include "i810tex.h"
+
+
+/* Reasons to disable hardware rasterization.
+ */
+#define I810_FALLBACK_TEXTURE 0x1
+#define I810_FALLBACK_DRAW_BUFFER 0x2
+#define I810_FALLBACK_READ_BUFFER 0x4
+#define I810_FALLBACK_COLORMASK 0x8
+#define I810_FALLBACK_SPECULAR 0x20
+#define I810_FALLBACK_LOGICOP 0x40
+#define I810_FALLBACK_RENDERMODE 0x80
+#define I810_FALLBACK_STENCIL 0x100
+#define I810_FALLBACK_BLEND_EQ 0x200
+#define I810_FALLBACK_BLEND_FUNC 0x400
+
+
+#ifndef PCI_CHIP_I810
+#define PCI_CHIP_I810 0x7121
+#define PCI_CHIP_I810_DC100 0x7123
+#define PCI_CHIP_I810_E 0x7125
+#define PCI_CHIP_I815 0x1132
+#endif
+
+#define IS_I810(imesa) (imesa->i810Screen->deviceID == PCI_CHIP_I810 || \
+ imesa->i810Screen->deviceID == PCI_CHIP_I810_DC100 || \
+ imesa->i810Screen->deviceID == PCI_CHIP_I810_E)
+#define IS_I815(imesa) (imesa->i810Screen->deviceID == PCI_CHIP_I815)
+
+
+#define I810_UPLOAD_TEX(i) (I810_UPLOAD_TEX0<<(i))
+
+/* Use the templated vertex formats:
+ */
+#define TAG(x) i810##x
+#include "tnl_dd/t_dd_vertex.h"
+#undef TAG
+
+typedef void (*i810_tri_func)( i810ContextPtr, i810Vertex *, i810Vertex *,
+ i810Vertex * );
+typedef void (*i810_line_func)( i810ContextPtr, i810Vertex *, i810Vertex * );
+typedef void (*i810_point_func)( i810ContextPtr, i810Vertex * );
+
+struct i810_context_t {
+ GLint refcount;
+ GLcontext *glCtx;
+
+ /* Texture object bookkeeping
+ */
+ unsigned nr_heaps;
+ driTexHeap * texture_heaps[1];
+ driTextureObject swapped;
+
+ struct i810_texture_object_t *CurrentTexObj[2];
+
+
+ /* Bit flag to keep track of fallbacks.
+ */
+ GLuint Fallback;
+
+ /* State for i810vb.c and i810tris.c.
+ */
+ GLuint new_state; /* _NEW_* flags */
+ GLuint SetupNewInputs;
+ GLuint SetupIndex;
+ GLuint RenderIndex;
+ GLmatrix ViewportMatrix;
+ GLenum render_primitive;
+ GLenum reduced_primitive;
+ GLuint hw_primitive;
+ GLubyte *verts;
+
+ drmBufPtr vertex_buffer;
+ char *vertex_addr;
+ GLuint vertex_low;
+ GLuint vertex_high;
+ GLuint vertex_last_prim;
+
+ GLboolean upload_cliprects;
+
+
+ /* Fallback rasterization functions
+ */
+ i810_point_func draw_point;
+ i810_line_func draw_line;
+ i810_tri_func draw_tri;
+
+ /* Hardware state
+ */
+ GLuint dirty; /* I810_UPLOAD_* */
+ GLuint Setup[I810_CTX_SETUP_SIZE];
+ GLuint BufferSetup[I810_DEST_SETUP_SIZE];
+ int vertex_size;
+ int vertex_stride_shift;
+ unsigned int lastStamp;
+ GLboolean stipple_in_hw;
+
+ GLenum TexEnvImageFmt[2];
+
+ /* State which can't be computed completely on the fly:
+ */
+ GLuint LcsCullMode;
+ GLuint LcsLineWidth;
+ GLuint LcsPointSize;
+
+ /* Funny mesa mirrors
+ */
+ GLushort ClearColor;
+
+ /* DRI stuff
+ */
+ GLuint needClip;
+ GLframebuffer *glBuffer;
+ GLboolean doPageFlip;
+
+ /* These refer to the current draw (front vs. back) buffer:
+ */
+ int drawX; /* origin of drawable in draw buffer */
+ int drawY;
+ GLuint numClipRects; /* cliprects for that buffer */
+ drm_clip_rect_t *pClipRects;
+
+ int lastSwap;
+ int texAge;
+ int ctxAge;
+ int dirtyAge;
+
+
+ GLboolean scissor;
+ drm_clip_rect_t draw_rect;
+ drm_clip_rect_t scissor_rect;
+
+ drm_context_t hHWContext;
+ drm_hw_lock_t *driHwLock;
+ int driFd;
+
+ __DRIdrawablePrivate *driDrawable;
+ __DRIscreenPrivate *driScreen;
+ i810ScreenPrivate *i810Screen;
+ I810SAREAPtr sarea;
+};
+
+
+#define I810_CONTEXT(ctx) ((i810ContextPtr)(ctx->DriverCtx))
+
+#define GET_DISPATCH_AGE( imesa ) imesa->sarea->last_dispatch
+#define GET_ENQUEUE_AGE( imesa ) imesa->sarea->last_enqueue
+
+
+/* Lock the hardware and validate our state.
+ */
+#define LOCK_HARDWARE( imesa ) \
+ do { \
+ char __ret=0; \
+ DRM_CAS(imesa->driHwLock, imesa->hHWContext, \
+ (DRM_LOCK_HELD|imesa->hHWContext), __ret); \
+ if (__ret) \
+ i810GetLock( imesa, 0 ); \
+ } while (0)
+
+
+
+/* Release the kernel lock.
+ */
+#define UNLOCK_HARDWARE(imesa) \
+ DRM_UNLOCK(imesa->driFd, imesa->driHwLock, imesa->hHWContext);
+
+
+/* This is the wrong way to do it, I'm sure. Otherwise the drm
+ * bitches that I've already got the heavyweight lock. At worst,
+ * this is 3 ioctls. The best solution probably only gets me down
+ * to 2 ioctls in the worst case.
+ */
+#define LOCK_HARDWARE_QUIESCENT( imesa ) do { \
+ LOCK_HARDWARE( imesa ); \
+ i810RegetLockQuiescent( imesa ); \
+} while(0)
+
+
+extern void i810GetLock( i810ContextPtr imesa, GLuint flags );
+extern void i810EmitHwStateLocked( i810ContextPtr imesa );
+extern void i810EmitScissorValues( i810ContextPtr imesa, int box_nr, int emit );
+extern void i810EmitDrawingRectangle( i810ContextPtr imesa );
+extern void i810XMesaSetBackClipRects( i810ContextPtr imesa );
+extern void i810XMesaSetFrontClipRects( i810ContextPtr imesa );
+
+#define SUBPIXEL_X -.5
+#define SUBPIXEL_Y -.5
+
+/* ================================================================
+ * Debugging:
+ */
+#define DO_DEBUG 1
+#if DO_DEBUG
+extern int I810_DEBUG;
+#else
+#define I810_DEBUG 0
+#endif
+
+#define DEBUG_TEXTURE 0x1
+#define DEBUG_STATE 0x2
+#define DEBUG_IOCTL 0x4
+#define DEBUG_PRIMS 0x8
+#define DEBUG_VERTS 0x10
+#define DEBUG_FALLBACKS 0x20
+#define DEBUG_VERBOSE 0x40
+#define DEBUG_DRI 0x80
+#define DEBUG_DMA 0x100
+#define DEBUG_SANITY 0x200
+#define DEBUG_SYNC 0x400
+#define DEBUG_SLEEP 0x800
+
+#endif
diff --git a/src/i810ioctl.c b/src/i810ioctl.c
new file mode 100644
index 0000000..57c8419
--- /dev/null
+++ b/src/i810ioctl.c
@@ -0,0 +1,520 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810ioctl.c,v 1.7 2002/10/30 12:51:33 alanh Exp $ */
+
+#include <unistd.h> /* for usleep() */
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "dd.h"
+#include "swrast/swrast.h"
+#include "mm.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810ioctl.h"
+#include "i810state.h"
+
+static drmBufPtr i810_get_buffer_ioctl( i810ContextPtr imesa )
+{
+ drmI810DMA dma;
+ drmBufPtr buf;
+ int retcode, i = 0;
+
+ while (1) {
+ retcode = drmCommandWriteRead(imesa->driFd, DRM_I810_GETBUF,
+ &dma, sizeof(drmI810DMA));
+
+ if (dma.granted == 1 && retcode == 0)
+ break;
+
+ if (++i > 1000) {
+ drmCommandNone(imesa->driFd, DRM_I810_FLUSH);
+ i = 0;
+ }
+ }
+
+ buf = &(imesa->i810Screen->bufs->list[dma.request_idx]);
+ buf->idx = dma.request_idx;
+ buf->used = 0;
+ buf->total = dma.request_size;
+ buf->address = (drmAddress)dma.virtual;
+
+ return buf;
+}
+
+
+
+#define DEPTH_SCALE ((1<<16)-1)
+
+static void i810Clear( GLcontext *ctx, GLbitfield mask )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
+ drmI810Clear clear;
+ unsigned int i;
+
+ clear.flags = 0;
+ clear.clear_color = imesa->ClearColor;
+ clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE);
+
+ I810_FIREVERTICES( imesa );
+
+ if ((mask & BUFFER_BIT_FRONT_LEFT) && colorMask == ~0U) {
+ clear.flags |= I810_FRONT;
+ mask &= ~BUFFER_BIT_FRONT_LEFT;
+ }
+
+ if ((mask & BUFFER_BIT_BACK_LEFT) && colorMask == ~0U) {
+ clear.flags |= I810_BACK;
+ mask &= ~BUFFER_BIT_BACK_LEFT;
+ }
+
+ if (mask & BUFFER_BIT_DEPTH) {
+ if (ctx->Depth.Mask)
+ clear.flags |= I810_DEPTH;
+ mask &= ~BUFFER_BIT_DEPTH;
+ }
+
+ if (clear.flags) {
+ GLint cx, cy, cw, ch;
+
+ LOCK_HARDWARE( imesa );
+
+ /* compute region after locking: */
+ cx = ctx->DrawBuffer->_Xmin;
+ cy = ctx->DrawBuffer->_Ymin;
+ cw = ctx->DrawBuffer->_Xmax - cx;
+ ch = ctx->DrawBuffer->_Ymax - cy;
+
+ /* flip top to bottom */
+ cy = dPriv->h-cy-ch;
+ cx += imesa->drawX;
+ cy += imesa->drawY;
+
+ for (i = 0 ; i < imesa->numClipRects ; )
+ {
+ unsigned int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, imesa->numClipRects);
+ drm_clip_rect_t *box = imesa->pClipRects;
+ drm_clip_rect_t *b = (drm_clip_rect_t *)imesa->sarea->boxes;
+ int n = 0;
+
+ if (cw != dPriv->w || ch != dPriv->h) {
+ /* clear sub region */
+ for ( ; i < nr ; i++) {
+ GLint x = box[i].x1;
+ GLint y = box[i].y1;
+ GLint w = box[i].x2 - x;
+ GLint h = box[i].y2 - y;
+
+ if (x < cx) w -= cx - x, x = cx;
+ if (y < cy) h -= cy - y, y = cy;
+ if (x + w > cx + cw) w = cx + cw - x;
+ if (y + h > cy + ch) h = cy + ch - y;
+ if (w <= 0) continue;
+ if (h <= 0) continue;
+
+ b->x1 = x;
+ b->y1 = y;
+ b->x2 = x + w;
+ b->y2 = y + h;
+ b++;
+ n++;
+ }
+ } else {
+ /* clear whole buffer */
+ for ( ; i < nr ; i++) {
+ *b++ = box[i];
+ n++;
+ }
+ }
+
+ imesa->sarea->nbox = n;
+ drmCommandWrite(imesa->driFd, DRM_I810_CLEAR,
+ &clear, sizeof(drmI810Clear));
+ }
+
+ UNLOCK_HARDWARE( imesa );
+ imesa->upload_cliprects = GL_TRUE;
+ }
+
+ if (mask)
+ _swrast_Clear( ctx, mask );
+}
+
+
+
+
+/*
+ * Copy the back buffer to the front buffer.
+ */
+void i810CopyBuffer( const __DRIdrawablePrivate *dPriv )
+{
+ i810ContextPtr imesa;
+ drm_clip_rect_t *pbox;
+ int nbox, i, tmp;
+
+ assert(dPriv);
+ assert(dPriv->driContextPriv);
+ assert(dPriv->driContextPriv->driverPrivate);
+
+ imesa = (i810ContextPtr) dPriv->driContextPriv->driverPrivate;
+
+ I810_FIREVERTICES( imesa );
+ LOCK_HARDWARE( imesa );
+
+ pbox = (drm_clip_rect_t *)dPriv->pClipRects;
+ nbox = dPriv->numClipRects;
+
+ for (i = 0 ; i < nbox ; )
+ {
+ int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
+ drm_clip_rect_t *b = (drm_clip_rect_t *)imesa->sarea->boxes;
+
+ imesa->sarea->nbox = nr - i;
+
+ for ( ; i < nr ; i++)
+ *b++ = pbox[i];
+
+ drmCommandNone(imesa->driFd, DRM_I810_SWAP);
+ }
+
+ tmp = GET_ENQUEUE_AGE(imesa);
+ UNLOCK_HARDWARE( imesa );
+
+ /* multiarb will suck the life out of the server without this throttle:
+ */
+ if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) {
+ i810WaitAge(imesa, imesa->lastSwap);
+ }
+
+ imesa->lastSwap = tmp;
+ imesa->upload_cliprects = GL_TRUE;
+}
+
+
+/*
+ * XXX implement when full-screen extension is done.
+ */
+void i810PageFlip( const __DRIdrawablePrivate *dPriv )
+{
+ i810ContextPtr imesa;
+ int tmp, ret;
+
+ assert(dPriv);
+ assert(dPriv->driContextPriv);
+ assert(dPriv->driContextPriv->driverPrivate);
+
+ imesa = (i810ContextPtr) dPriv->driContextPriv->driverPrivate;
+
+ I810_FIREVERTICES( imesa );
+ LOCK_HARDWARE( imesa );
+
+ if (dPriv->pClipRects) {
+ memcpy(&(imesa->sarea->boxes[0]), &(dPriv->pClipRects[0]),
+ sizeof(drm_clip_rect_t));
+ imesa->sarea->nbox = 1;
+ }
+ ret = drmCommandNone(imesa->driFd, DRM_I810_FLIP);
+ if (ret) {
+ fprintf(stderr, "%s: %d\n", __FUNCTION__, ret);
+ UNLOCK_HARDWARE( imesa );
+ exit(1);
+ }
+
+ tmp = GET_ENQUEUE_AGE(imesa);
+ UNLOCK_HARDWARE( imesa );
+
+ /* multiarb will suck the life out of the server without this throttle:
+ */
+ if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) {
+ i810WaitAge(imesa, imesa->lastSwap);
+ }
+
+ /* i810SetDrawBuffer( imesa->glCtx, imesa->glCtx->Color.DriverDrawBuffer );*/
+ i810DrawBuffer( imesa->glCtx, imesa->glCtx->Color.DrawBuffer[0] );
+ imesa->upload_cliprects = GL_TRUE;
+ imesa->lastSwap = tmp;
+ return;
+}
+
+
+/* This waits for *everybody* to finish rendering -- overkill.
+ */
+void i810DmaFinish( i810ContextPtr imesa )
+{
+ I810_FIREVERTICES( imesa );
+
+ LOCK_HARDWARE( imesa );
+ i810RegetLockQuiescent( imesa );
+ UNLOCK_HARDWARE( imesa );
+}
+
+
+void i810RegetLockQuiescent( i810ContextPtr imesa )
+{
+ drmUnlock(imesa->driFd, imesa->hHWContext);
+ i810GetLock( imesa, DRM_LOCK_QUIESCENT );
+}
+
+void i810WaitAgeLocked( i810ContextPtr imesa, int age )
+{
+ int i = 0, j;
+
+ while (++i < 5000) {
+ drmCommandNone(imesa->driFd, DRM_I810_GETAGE);
+ if (GET_DISPATCH_AGE(imesa) >= age)
+ return;
+ for (j = 0 ; j < 1000 ; j++)
+ ;
+ }
+
+ drmCommandNone(imesa->driFd, DRM_I810_FLUSH);
+}
+
+
+void i810WaitAge( i810ContextPtr imesa, int age )
+{
+ int i = 0, j;
+
+ while (++i < 5000) {
+ drmCommandNone(imesa->driFd, DRM_I810_GETAGE);
+ if (GET_DISPATCH_AGE(imesa) >= age)
+ return;
+ for (j = 0 ; j < 1000 ; j++)
+ ;
+ }
+
+ i = 0;
+ while (++i < 1000) {
+ drmCommandNone(imesa->driFd, DRM_I810_GETAGE);
+ if (GET_DISPATCH_AGE(imesa) >= age)
+ return;
+ usleep(1000);
+ }
+
+ LOCK_HARDWARE(imesa);
+ drmCommandNone(imesa->driFd, DRM_I810_FLUSH);
+ UNLOCK_HARDWARE(imesa);
+}
+
+
+
+
+static int intersect_rect( drm_clip_rect_t *out,
+ drm_clip_rect_t *a,
+ drm_clip_rect_t *b )
+{
+ *out = *a;
+ if (b->x1 > out->x1) out->x1 = b->x1;
+ if (b->x2 < out->x2) out->x2 = b->x2;
+ if (out->x1 >= out->x2) return 0;
+
+ if (b->y1 > out->y1) out->y1 = b->y1;
+ if (b->y2 < out->y2) out->y2 = b->y2;
+ if (out->y1 >= out->y2) return 0;
+ return 1;
+}
+
+
+static void emit_state( i810ContextPtr imesa )
+{
+ GLuint dirty = imesa->dirty;
+ I810SAREAPtr sarea = imesa->sarea;
+
+ if (dirty & I810_UPLOAD_BUFFERS) {
+ memcpy( sarea->BufferState, imesa->BufferSetup,
+ sizeof(imesa->BufferSetup) );
+ }
+
+ if (dirty & I810_UPLOAD_CTX) {
+ memcpy( sarea->ContextState, imesa->Setup,
+ sizeof(imesa->Setup) );
+ }
+
+ if (dirty & I810_UPLOAD_TEX0) {
+ memcpy(sarea->TexState[0],
+ imesa->CurrentTexObj[0]->Setup,
+ sizeof(imesa->CurrentTexObj[0]->Setup));
+ }
+
+ if (dirty & I810_UPLOAD_TEX1) {
+ GLuint *setup = sarea->TexState[1];
+
+ memcpy( setup,
+ imesa->CurrentTexObj[1]->Setup,
+ sizeof(imesa->CurrentTexObj[1]->Setup));
+
+ /* Need this for the case where both units are bound to the same
+ * texobj.
+ */
+ setup[I810_TEXREG_MI1] ^= (MI1_MAP_0 ^ MI1_MAP_1);
+ setup[I810_TEXREG_MLC] ^= (MLC_MAP_0 ^ MLC_MAP_1);
+ setup[I810_TEXREG_MLL] ^= (MLL_MAP_0 ^ MLL_MAP_1);
+ setup[I810_TEXREG_MCS] ^= (MCS_COORD_0 ^ MCS_COORD_1);
+ setup[I810_TEXREG_MF] ^= (MF_MAP_0 ^ MF_MAP_1);
+ }
+
+ sarea->dirty = dirty;
+ imesa->dirty = 0;
+}
+
+
+static void age_imesa( i810ContextPtr imesa, int age )
+{
+ if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->base.timestamp = age;
+ if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->base.timestamp = age;
+}
+
+
+void i810FlushPrimsLocked( i810ContextPtr imesa )
+{
+ drm_clip_rect_t *pbox = imesa->pClipRects;
+ int nbox = imesa->numClipRects;
+ drmBufPtr buffer = imesa->vertex_buffer;
+ I810SAREAPtr sarea = imesa->sarea;
+ drmI810Vertex vertex;
+ int i;
+
+ if (I810_DEBUG & DEBUG_STATE)
+ i810PrintDirty( __FUNCTION__, imesa->dirty );
+
+ if (imesa->dirty)
+ emit_state( imesa );
+
+ vertex.idx = buffer->idx;
+ vertex.used = imesa->vertex_low;
+ vertex.discard = 0;
+ sarea->vertex_prim = imesa->hw_primitive;
+
+ if (!nbox) {
+ vertex.used = 0;
+ }
+ else if (nbox > I810_NR_SAREA_CLIPRECTS) {
+ imesa->upload_cliprects = GL_TRUE;
+ }
+
+ if (!nbox || !imesa->upload_cliprects)
+ {
+ if (nbox == 1)
+ sarea->nbox = 0;
+ else
+ sarea->nbox = nbox;
+
+ vertex.discard = 1;
+ drmCommandWrite(imesa->driFd, DRM_I810_VERTEX,
+ &vertex, sizeof(drmI810Vertex));
+ age_imesa(imesa, sarea->last_enqueue);
+ }
+ else
+ {
+ for (i = 0 ; i < nbox ; )
+ {
+ int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, nbox);
+ drm_clip_rect_t *b = (drm_clip_rect_t *)sarea->boxes;
+
+ if (imesa->scissor) {
+ sarea->nbox = 0;
+
+ for ( ; i < nr ; i++) {
+ b->x1 = pbox[i].x1 - imesa->drawX;
+ b->y1 = pbox[i].y1 - imesa->drawY;
+ b->x2 = pbox[i].x2 - imesa->drawX;
+ b->y2 = pbox[i].y2 - imesa->drawY;
+
+ if (intersect_rect(b, b, &imesa->scissor_rect)) {
+ sarea->nbox++;
+ b++;
+ }
+ }
+
+ /* Culled?
+ */
+ if (!sarea->nbox) {
+ if (nr < nbox) continue;
+ vertex.used = 0;
+ }
+ } else {
+ sarea->nbox = nr - i;
+ for ( ; i < nr ; i++, b++) {
+ b->x1 = pbox[i].x1 - imesa->drawX;
+ b->y1 = pbox[i].y1 - imesa->drawY;
+ b->x2 = pbox[i].x2 - imesa->drawX;
+ b->y2 = pbox[i].y2 - imesa->drawY;
+ }
+ }
+
+ /* Finished with the buffer?
+ */
+ if (nr == nbox)
+ vertex.discard = 1;
+
+ drmCommandWrite(imesa->driFd, DRM_I810_VERTEX,
+ &vertex, sizeof(drmI810Vertex));
+ age_imesa(imesa, imesa->sarea->last_enqueue);
+ }
+ }
+
+ /* Reset imesa vars:
+ */
+ imesa->vertex_buffer = 0;
+ imesa->vertex_addr = 0;
+ imesa->vertex_low = 0;
+ imesa->vertex_high = 0;
+ imesa->vertex_last_prim = 0;
+ imesa->dirty = 0;
+ imesa->upload_cliprects = GL_FALSE;
+}
+
+void i810FlushPrimsGetBuffer( i810ContextPtr imesa )
+{
+ LOCK_HARDWARE(imesa);
+
+ if (imesa->vertex_buffer)
+ i810FlushPrimsLocked( imesa );
+
+ imesa->vertex_buffer = i810_get_buffer_ioctl( imesa );
+ imesa->vertex_high = imesa->vertex_buffer->total;
+ imesa->vertex_addr = (char *)imesa->vertex_buffer->address;
+ imesa->vertex_low = 4; /* leave room for instruction header */
+ imesa->vertex_last_prim = imesa->vertex_low;
+ UNLOCK_HARDWARE(imesa);
+}
+
+
+void i810FlushPrims( i810ContextPtr imesa )
+{
+ if (imesa->vertex_buffer) {
+ LOCK_HARDWARE( imesa );
+ i810FlushPrimsLocked( imesa );
+ UNLOCK_HARDWARE( imesa );
+ }
+}
+
+
+
+int i810_check_copy(int fd)
+{
+ return(drmCommandNone(fd, DRM_I810_DOCOPY));
+}
+
+static void i810Flush( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ I810_FIREVERTICES( imesa );
+}
+
+static void i810Finish( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ i810DmaFinish( imesa );
+}
+
+void i810InitIoctlFuncs( struct dd_function_table *functions )
+{
+ functions->Flush = i810Flush;
+ functions->Clear = i810Clear;
+ functions->Finish = i810Finish;
+}
diff --git a/src/i810ioctl.h b/src/i810ioctl.h
new file mode 100644
index 0000000..61399ee
--- /dev/null
+++ b/src/i810ioctl.h
@@ -0,0 +1,49 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810ioctl.h,v 1.7 2002/10/30 12:51:33 alanh Exp $ */
+
+#ifndef I810_IOCTL_H
+#define I810_IOCTL_H
+
+#include "i810context.h"
+
+void i810EmitPrim( i810ContextPtr imesa );
+void i810FlushPrims( i810ContextPtr mmesa );
+void i810FlushPrimsLocked( i810ContextPtr mmesa );
+void i810FlushPrimsGetBuffer( i810ContextPtr imesa );
+
+void i810WaitAgeLocked( i810ContextPtr imesa, int age );
+void i810WaitAge( i810ContextPtr imesa, int age );
+void i810DmaFinish( i810ContextPtr imesa );
+void i810RegetLockQuiescent( i810ContextPtr imesa );
+void i810InitIoctlFuncs( struct dd_function_table *functions );
+void i810CopyBuffer( const __DRIdrawablePrivate *dpriv );
+void i810PageFlip( const __DRIdrawablePrivate *dpriv );
+int i810_check_copy(int fd);
+
+#define I810_STATECHANGE(imesa, flag) \
+do { \
+ if (imesa->vertex_low != imesa->vertex_last_prim) \
+ i810FlushPrims(imesa); \
+ imesa->dirty |= flag; \
+} while (0) \
+
+
+#define I810_FIREVERTICES(imesa) \
+do { \
+ if (imesa->vertex_buffer) { \
+ i810FlushPrims(imesa); \
+ } \
+} while (0)
+
+static __inline GLuint *i810AllocDmaLow( i810ContextPtr imesa, int bytes )
+{
+ if (imesa->vertex_low + bytes > imesa->vertex_high)
+ i810FlushPrimsGetBuffer( imesa );
+
+ {
+ GLuint *start = (GLuint *)(imesa->vertex_addr + imesa->vertex_low);
+ imesa->vertex_low += bytes;
+ return start;
+ }
+}
+
+#endif
diff --git a/src/i810render.c b/src/i810render.c
new file mode 100644
index 0000000..d022596
--- /dev/null
+++ b/src/i810render.c
@@ -0,0 +1,173 @@
+/*
+ * Intel i810 DRI driver for Mesa 3.5
+ *
+ * Copyright (C) 1999-2000 Keith Whitwell All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL KEITH WHITWELL BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+/*
+ * Render unclipped vertex buffers by emitting vertices directly to
+ * dma buffers. Use strip/fan hardware acceleration where possible.
+ *
+ */
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "imports.h"
+#include "mtypes.h"
+
+#include "tnl/t_context.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810tris.h"
+#include "i810state.h"
+#include "i810vb.h"
+#include "i810ioctl.h"
+
+/*
+ * Render unclipped vertex buffers by emitting vertices directly to
+ * dma buffers. Use strip/fan hardware primitives where possible.
+ * Try to simulate missing primitives with indexed vertices.
+ */
+#define HAVE_POINTS 0
+#define HAVE_LINES 1
+#define HAVE_LINE_STRIPS 1
+#define HAVE_TRIANGLES 1
+#define HAVE_TRI_STRIPS 1
+#define HAVE_TRI_STRIP_1 0 /* has it, template can't use it yet */
+#define HAVE_TRI_FANS 1
+#define HAVE_POLYGONS 1
+#define HAVE_QUADS 0
+#define HAVE_QUAD_STRIPS 0
+
+#define HAVE_ELTS 0
+
+
+static GLuint hw_prim[GL_POLYGON+1] = {
+ 0,
+ PR_LINES,
+ 0,
+ PR_LINESTRIP,
+ PR_TRIANGLES,
+ PR_TRISTRIP_0,
+ PR_TRIFAN,
+ 0,
+ 0,
+ PR_POLYGON
+};
+
+static const GLenum reduced_prim[GL_POLYGON+1] = {
+ GL_POINTS,
+ GL_LINES,
+ GL_LINES,
+ GL_LINES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES
+};
+
+
+
+
+#define LOCAL_VARS i810ContextPtr imesa = I810_CONTEXT(ctx)
+#define INIT( prim ) do { \
+ I810_STATECHANGE(imesa, 0); \
+ i810RasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] ); \
+} while (0)
+#define GET_CURRENT_VB_MAX_VERTS() \
+ (((int)imesa->vertex_high - (int)imesa->vertex_low) / (imesa->vertex_size*4))
+#define GET_SUBSEQUENT_VB_MAX_VERTS() \
+ (I810_DMA_BUF_SZ-4) / (imesa->vertex_size * 4)
+
+#define ALLOC_VERTS( nr ) \
+ i810AllocDmaLow( imesa, (nr) * imesa->vertex_size * 4)
+#define EMIT_VERTS( ctx, j, nr, buf ) \
+ i810_emit_contiguous_verts(ctx, j, (j)+(nr), buf)
+
+#define FLUSH() I810_FIREVERTICES( imesa )
+
+
+#define TAG(x) i810_##x
+#include "tnl_dd/t_dd_dmatmp.h"
+
+
+/**********************************************************************/
+/* Render pipeline stage */
+/**********************************************************************/
+
+
+static GLboolean i810_run_render( GLcontext *ctx,
+ struct tnl_pipeline_stage *stage )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ GLuint i;
+
+ /* Don't handle clipping or indexed vertices.
+ */
+ if (imesa->RenderIndex != 0 ||
+ !i810_validate_render( ctx, VB )) {
+ return GL_TRUE;
+ }
+
+ imesa->SetupNewInputs = VERT_BIT_POS;
+
+ tnl->Driver.Render.Start( ctx );
+
+ for (i = 0 ; i < VB->PrimitiveCount ; i++)
+ {
+ GLuint prim = _tnl_translate_prim(&VB->Primitive[i]);
+ GLuint start = VB->Primitive[i].start;
+ GLuint length = VB->Primitive[i].count;
+
+ if (!length)
+ continue;
+
+ i810_render_tab_verts[prim & PRIM_MODE_MASK]( ctx, start, start + length,
+ prim );
+ }
+
+ tnl->Driver.Render.Finish( ctx );
+
+ return GL_FALSE; /* finished the pipe */
+}
+
+
+
+const struct tnl_pipeline_stage _i810_render_stage =
+{
+ "i810 render",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i810_run_render /* run */
+};
diff --git a/src/i810screen.c b/src/i810screen.c
new file mode 100644
index 0000000..f8cf050
--- /dev/null
+++ b/src/i810screen.c
@@ -0,0 +1,472 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810screen.c,v 1.2 2002/10/30 12:51:33 alanh Exp $ */
+
+/*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ *
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "framebuffer.h"
+#include "fbobject.h"
+#include "matrix.h"
+#include "renderbuffer.h"
+#include "simple_list.h"
+#include "utils.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810state.h"
+#include "i810tex.h"
+#include "i810span.h"
+#include "i810tris.h"
+#include "i810ioctl.h"
+
+#include "GL/internal/dri_interface.h"
+
+extern const struct dri_extension card_extensions[];
+
+static __GLcontextModes *fill_in_modes( __GLcontextModes *modes,
+ unsigned pixel_bits,
+ unsigned depth_bits,
+ unsigned stencil_bits,
+ const GLenum * db_modes,
+ unsigned num_db_modes,
+ int visType )
+{
+ static const u_int8_t bits[1][4] = {
+ { 5, 6, 5, 0 }
+ };
+
+ static const u_int32_t masks[1][4] = {
+ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }
+ };
+
+ unsigned i;
+ unsigned j;
+ const unsigned index = 0;
+
+ for ( i = 0 ; i < num_db_modes ; i++ ) {
+ for ( j = 0 ; j < 2 ; j++ ) {
+
+ modes->redBits = bits[index][0];
+ modes->greenBits = bits[index][1];
+ modes->blueBits = bits[index][2];
+ modes->alphaBits = bits[index][3];
+ modes->redMask = masks[index][0];
+ modes->greenMask = masks[index][1];
+ modes->blueMask = masks[index][2];
+ modes->alphaMask = masks[index][3];
+ modes->rgbBits = modes->redBits + modes->greenBits
+ + modes->blueBits + modes->alphaBits;
+
+ modes->accumRedBits = 16 * j;
+ modes->accumGreenBits = 16 * j;
+ modes->accumBlueBits = 16 * j;
+ modes->accumAlphaBits = (masks[index][3] != 0) ? 16 * j : 0;
+ modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
+
+ modes->stencilBits = stencil_bits;
+ modes->depthBits = depth_bits;
+
+ modes->visualType = visType;
+ modes->renderType = GLX_RGBA_BIT;
+ modes->drawableType = GLX_WINDOW_BIT;
+ modes->rgbMode = GL_TRUE;
+
+ if ( db_modes[i] == GLX_NONE ) {
+ modes->doubleBufferMode = GL_FALSE;
+ }
+ else {
+ modes->doubleBufferMode = GL_TRUE;
+ modes->swapMethod = db_modes[i];
+ }
+
+ modes = modes->next;
+ }
+ }
+
+ return modes;
+
+}
+
+
+static __GLcontextModes *
+i810FillInModes( unsigned pixel_bits, unsigned depth_bits,
+ unsigned stencil_bits, GLboolean have_back_buffer )
+{ __GLcontextModes * modes;
+ __GLcontextModes * m;
+ unsigned num_modes;
+ unsigned depth_buffer_factor;
+ unsigned back_buffer_factor;
+ unsigned i;
+
+ /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
+ * enough to add support. Basically, if a context is created with an
+ * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
+ * will never be used.
+ */
+ static const GLenum back_buffer_modes[] = {
+ GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
+ };
+
+ int depth_buffer_modes[2][2];
+
+
+ depth_buffer_modes[0][0] = depth_bits;
+ depth_buffer_modes[1][0] = depth_bits;
+
+ /* Just like with the accumulation buffer, always provide some modes
+ * with a stencil buffer. It will be a sw fallback, but some apps won't
+ * care about that.
+ */
+ depth_buffer_modes[0][1] = 0;
+ depth_buffer_modes[1][1] = (stencil_bits == 0) ? 8 : stencil_bits;
+
+ depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
+ back_buffer_factor = (have_back_buffer) ? 2 : 1;
+
+ num_modes = depth_buffer_factor * back_buffer_factor * 4;
+
+ modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) );
+ m = modes;
+ for ( i = 0 ; i < depth_buffer_factor ; i++ ) {
+ m = fill_in_modes( m, pixel_bits,
+ depth_buffer_modes[i][0], depth_buffer_modes[i][1],
+ back_buffer_modes, back_buffer_factor,
+ GLX_TRUE_COLOR );
+ }
+
+ for ( i = 0 ; i < depth_buffer_factor ; i++ ) {
+ m = fill_in_modes( m, pixel_bits,
+ depth_buffer_modes[i][0], depth_buffer_modes[i][1],
+ back_buffer_modes, back_buffer_factor,
+ GLX_DIRECT_COLOR );
+ }
+
+ /* Mark the visual as slow if there are "fake" stencil bits.
+ */
+ for ( m = modes ; m != NULL ; m = m->next ) {
+ if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
+ m->visualRating = GLX_SLOW_CONFIG;
+ }
+ }
+
+ return modes;
+
+}
+
+
+/* static int i810_malloc_proxy_buf(drmBufMapPtr buffers) */
+/* { */
+/* char *buffer; */
+/* drmBufPtr buf; */
+/* int i; */
+
+/* buffer = CALLOC(I810_DMA_BUF_SZ); */
+/* if(buffer == NULL) return -1; */
+/* for(i = 0; i < I810_DMA_BUF_NR; i++) { */
+/* buf = &(buffers->list[i]); */
+/* buf->address = (drmAddress)buffer; */
+/* } */
+/* return 0; */
+/* } */
+
+static drmBufMapPtr i810_create_empty_buffers(void)
+{
+ drmBufMapPtr retval;
+
+ retval = (drmBufMapPtr)ALIGN_MALLOC(sizeof(drmBufMap), 32);
+ if(retval == NULL) return NULL;
+ memset(retval, 0, sizeof(drmBufMap));
+ retval->list = (drmBufPtr)ALIGN_MALLOC(sizeof(drmBuf) * I810_DMA_BUF_NR, 32);
+ if(retval->list == NULL) {
+ ALIGN_FREE(retval);
+ return NULL;
+ }
+ memset(retval->list, 0, sizeof(drmBuf) * I810_DMA_BUF_NR);
+ return retval;
+}
+
+
+static GLboolean
+i810InitDriver(__DRIscreenPrivate *sPriv)
+{
+ i810ScreenPrivate *i810Screen;
+ I810DRIPtr gDRIPriv = (I810DRIPtr)sPriv->pDevPriv;
+
+ if (sPriv->devPrivSize != sizeof(I810DRIRec)) {
+ fprintf(stderr,"\nERROR! sizeof(I810DRIRec) does not match passed size from device driver\n");
+ return GL_FALSE;
+ }
+
+ /* Allocate the private area */
+ i810Screen = (i810ScreenPrivate *)CALLOC(sizeof(i810ScreenPrivate));
+ if (!i810Screen) {
+ __driUtilMessage("i810InitDriver: alloc i810ScreenPrivate struct failed");
+ return GL_FALSE;
+ }
+
+ i810Screen->driScrnPriv = sPriv;
+ sPriv->private = (void *)i810Screen;
+
+ i810Screen->deviceID=gDRIPriv->deviceID;
+ i810Screen->width=gDRIPriv->width;
+ i810Screen->height=gDRIPriv->height;
+ i810Screen->mem=gDRIPriv->mem;
+ i810Screen->cpp=gDRIPriv->cpp;
+ i810Screen->fbStride=gDRIPriv->fbStride;
+ i810Screen->fbOffset=gDRIPriv->fbOffset;
+
+ if (gDRIPriv->bitsPerPixel == 15)
+ i810Screen->fbFormat = DV_PF_555;
+ else
+ i810Screen->fbFormat = DV_PF_565;
+
+ i810Screen->backOffset=gDRIPriv->backOffset;
+ i810Screen->depthOffset=gDRIPriv->depthOffset;
+ i810Screen->backPitch = gDRIPriv->auxPitch;
+ i810Screen->backPitchBits = gDRIPriv->auxPitchBits;
+ i810Screen->textureOffset=gDRIPriv->textureOffset;
+ i810Screen->textureSize=gDRIPriv->textureSize;
+ i810Screen->logTextureGranularity = gDRIPriv->logTextureGranularity;
+
+ i810Screen->bufs = i810_create_empty_buffers();
+ if (i810Screen->bufs == NULL) {
+ __driUtilMessage("i810InitDriver: i810_create_empty_buffers() failed");
+ FREE(i810Screen);
+ return GL_FALSE;
+ }
+
+ i810Screen->back.handle = gDRIPriv->backbuffer;
+ i810Screen->back.size = gDRIPriv->backbufferSize;
+
+ if (drmMap(sPriv->fd,
+ i810Screen->back.handle,
+ i810Screen->back.size,
+ (drmAddress *)&i810Screen->back.map) != 0) {
+ FREE(i810Screen);
+ sPriv->private = NULL;
+ __driUtilMessage("i810InitDriver: drmMap failed");
+ return GL_FALSE;
+ }
+
+ i810Screen->depth.handle = gDRIPriv->depthbuffer;
+ i810Screen->depth.size = gDRIPriv->depthbufferSize;
+
+ if (drmMap(sPriv->fd,
+ i810Screen->depth.handle,
+ i810Screen->depth.size,
+ (drmAddress *)&i810Screen->depth.map) != 0) {
+ drmUnmap(i810Screen->back.map, i810Screen->back.size);
+ FREE(i810Screen);
+ sPriv->private = NULL;
+ __driUtilMessage("i810InitDriver: drmMap (2) failed");
+ return GL_FALSE;
+ }
+
+ i810Screen->tex.handle = gDRIPriv->textures;
+ i810Screen->tex.size = gDRIPriv->textureSize;
+
+ if (drmMap(sPriv->fd,
+ i810Screen->tex.handle,
+ i810Screen->tex.size,
+ (drmAddress *)&i810Screen->tex.map) != 0) {
+ drmUnmap(i810Screen->back.map, i810Screen->back.size);
+ drmUnmap(i810Screen->depth.map, i810Screen->depth.size);
+ FREE(i810Screen);
+ sPriv->private = NULL;
+ __driUtilMessage("i810InitDriver: drmMap (3) failed");
+ return GL_FALSE;
+ }
+
+ i810Screen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
+
+ return GL_TRUE;
+}
+
+static void
+i810DestroyScreen(__DRIscreenPrivate *sPriv)
+{
+ i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private;
+
+ /* Need to unmap all the bufs and maps here:
+ */
+ drmUnmap(i810Screen->back.map, i810Screen->back.size);
+ drmUnmap(i810Screen->depth.map, i810Screen->depth.size);
+ drmUnmap(i810Screen->tex.map, i810Screen->tex.size);
+
+ FREE(i810Screen);
+ sPriv->private = NULL;
+}
+
+
+/**
+ * Create a buffer which corresponds to the window.
+ */
+static GLboolean
+i810CreateBuffer( __DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ const __GLcontextModes *mesaVis,
+ GLboolean isPixmap )
+{
+ i810ScreenPrivate *screen = (i810ScreenPrivate *) driScrnPriv->private;
+
+ if (isPixmap) {
+ return GL_FALSE; /* not implemented */
+ }
+ else {
+ struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
+
+ {
+ driRenderbuffer *frontRb
+ = driNewRenderbuffer(GL_RGBA,
+ driScrnPriv->pFB,
+ screen->cpp,
+ /*screen->frontOffset*/0, screen->backPitch,
+ driDrawPriv);
+ i810SetSpanFunctions(frontRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
+ }
+
+ if (mesaVis->doubleBufferMode) {
+ driRenderbuffer *backRb
+ = driNewRenderbuffer(GL_RGBA,
+ screen->back.map,
+ screen->cpp,
+ screen->backOffset, screen->backPitch,
+ driDrawPriv);
+ i810SetSpanFunctions(backRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
+ }
+
+ if (mesaVis->depthBits == 16) {
+ driRenderbuffer *depthRb
+ = driNewRenderbuffer(GL_DEPTH_COMPONENT16,
+ screen->depth.map,
+ screen->cpp,
+ screen->depthOffset, screen->backPitch,
+ driDrawPriv);
+ i810SetSpanFunctions(depthRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
+ }
+
+ _mesa_add_soft_renderbuffers(fb,
+ GL_FALSE, /* color */
+ GL_FALSE, /* depth */
+ mesaVis->stencilBits > 0,
+ mesaVis->accumRedBits > 0,
+ GL_FALSE, /* alpha */
+ GL_FALSE /* aux */);
+ driDrawPriv->driverPrivate = (void *) fb;
+
+ return (driDrawPriv->driverPrivate != NULL);
+ }
+}
+
+
+static void
+i810DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+ _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
+}
+
+
+static const struct __DriverAPIRec i810API = {
+ .InitDriver = i810InitDriver,
+ .DestroyScreen = i810DestroyScreen,
+ .CreateContext = i810CreateContext,
+ .DestroyContext = i810DestroyContext,
+ .CreateBuffer = i810CreateBuffer,
+ .DestroyBuffer = i810DestroyBuffer,
+ .SwapBuffers = i810SwapBuffers,
+ .MakeCurrent = i810MakeCurrent,
+ .UnbindContext = i810UnbindContext,
+ .GetSwapInfo = NULL,
+ .GetMSC = NULL,
+ .WaitForMSC = NULL,
+ .WaitForSBC = NULL,
+ .SwapBuffersMSC = NULL
+};
+
+
+/**
+ * This is the bootstrap function for the driver. libGL supplies all of the
+ * requisite information about the system, and the driver initializes itself.
+ * This routine also fills in the linked list pointed to by \c driver_modes
+ * with the \c __GLcontextModes that the driver can support for windows or
+ * pbuffers.
+ *
+ * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
+ * failure.
+ */
+PUBLIC
+void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
+ const __GLcontextModes * modes,
+ const __DRIversion * ddx_version,
+ const __DRIversion * dri_version,
+ const __DRIversion * drm_version,
+ const __DRIframebuffer * frame_buffer,
+ drmAddress pSAREA, int fd,
+ int internal_api_version,
+ const __DRIinterfaceMethods * interface,
+ __GLcontextModes ** driver_modes )
+
+{
+ __DRIscreenPrivate *psp;
+ static const __DRIversion ddx_expected = { 1, 0, 0 };
+ static const __DRIversion dri_expected = { 4, 0, 0 };
+ static const __DRIversion drm_expected = { 1, 2, 0 };
+
+ dri_interface = interface;
+
+ if ( ! driCheckDriDdxDrmVersions2( "i810",
+ dri_version, & dri_expected,
+ ddx_version, & ddx_expected,
+ drm_version, & drm_expected ) ) {
+ return NULL;
+ }
+
+ psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
+ ddx_version, dri_version, drm_version,
+ frame_buffer, pSAREA, fd,
+ internal_api_version, &i810API);
+ if ( psp != NULL ) {
+ *driver_modes = i810FillInModes( 16,
+ 16, 0,
+ 1);
+ driInitExtensions( NULL, card_extensions, GL_TRUE );
+ }
+
+ return (void *) psp;
+}
diff --git a/src/i810screen.h b/src/i810screen.h
new file mode 100644
index 0000000..b299376
--- /dev/null
+++ b/src/i810screen.h
@@ -0,0 +1,99 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ *
+ */
+
+#ifndef _I810_INIT_H_
+#define _I810_INIT_H_
+
+#include <sys/time.h>
+#include "dri_util.h"
+
+typedef struct {
+ drm_handle_t handle;
+ drmSize size;
+ char *map;
+} i810Region, *i810RegionPtr;
+
+typedef struct {
+ i810Region front;
+ i810Region back;
+ i810Region depth;
+ i810Region tex;
+
+ int deviceID;
+ int width;
+ int height;
+ int mem;
+
+ int cpp; /* for front and back buffers */
+ int bitsPerPixel;
+
+ int fbFormat;
+ int fbOffset;
+ int fbStride;
+
+ int backOffset;
+ int depthOffset;
+
+ int backPitch;
+ int backPitchBits;
+
+ int textureOffset;
+ int textureSize;
+ int logTextureGranularity;
+
+ __DRIscreenPrivate *driScrnPriv;
+ drmBufMapPtr bufs;
+ unsigned int sarea_priv_offset;
+} i810ScreenPrivate;
+
+
+extern GLboolean
+i810CreateContext( const __GLcontextModes *mesaVis,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate );
+
+extern void
+i810DestroyContext(__DRIcontextPrivate *driContextPriv);
+
+extern GLboolean
+i810UnbindContext(__DRIcontextPrivate *driContextPriv);
+
+extern GLboolean
+i810MakeCurrent(__DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv);
+
+extern void
+i810SwapBuffers(__DRIdrawablePrivate *driDrawPriv);
+
+#endif
diff --git a/src/i810span.c b/src/i810span.c
new file mode 100644
index 0000000..2112800
--- /dev/null
+++ b/src/i810span.c
@@ -0,0 +1,136 @@
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "colormac.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810span.h"
+#include "i810ioctl.h"
+#include "swrast/swrast.h"
+
+
+#define DBG 0
+
+#define LOCAL_VARS \
+ i810ContextPtr imesa = I810_CONTEXT(ctx); \
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable; \
+ driRenderbuffer *drb = (driRenderbuffer *) rb; \
+ GLuint pitch = drb->pitch; \
+ GLuint height = dPriv->h; \
+ GLushort p; \
+ char *buf = (char *)(drb->flippedData + \
+ dPriv->x * 2 + \
+ dPriv->y * pitch); \
+ (void) buf; (void) p
+
+#define LOCAL_DEPTH_VARS \
+ i810ContextPtr imesa = I810_CONTEXT(ctx); \
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable; \
+ driRenderbuffer *drb = (driRenderbuffer *) rb; \
+ GLuint pitch = drb->pitch; \
+ GLuint height = dPriv->h; \
+ char *buf = (char *)(drb->Base.Data + \
+ dPriv->x * 2 + \
+ dPriv->y * pitch)
+
+#define INIT_MONO_PIXEL(p, color) \
+ p = PACK_COLOR_565( color[0], color[1], color[2] )
+
+#define Y_FLIP(_y) (height - _y - 1)
+
+#define HW_LOCK()
+
+#define HW_UNLOCK()
+
+/* 16 bit, 565 rgb color spanline and pixel functions
+ */
+#define WRITE_RGBA( _x, _y, r, g, b, a ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = ( (((int)r & 0xf8) << 8) | \
+ (((int)g & 0xfc) << 3) | \
+ (((int)b & 0xf8) >> 3))
+#define WRITE_PIXEL( _x, _y, p ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y ) \
+do { \
+ GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
+ rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
+ rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
+ rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \
+ rgba[3] = 255; \
+} while(0)
+
+#define TAG(x) i810##x##_565
+#include "spantmp.h"
+
+/* 16 bit depthbuffer functions.
+ */
+#define WRITE_DEPTH( _x, _y, d ) \
+ *(GLushort *)(buf + (_x)*2 + (_y)*pitch) = d;
+
+#define READ_DEPTH( d, _x, _y ) \
+ d = *(GLushort *)(buf + (_x)*2 + (_y)*pitch);
+
+#define TAG(x) i810##x##_z16
+#include "depthtmp.h"
+
+
+/* Move locking out to get reasonable span performance.
+ */
+void i810SpanRenderStart( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ I810_FIREVERTICES(imesa);
+ LOCK_HARDWARE(imesa);
+ i810RegetLockQuiescent( imesa );
+}
+
+void i810SpanRenderFinish( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ _swrast_flush( ctx );
+ UNLOCK_HARDWARE( imesa );
+}
+
+void i810InitSpanFuncs( GLcontext *ctx )
+{
+ struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
+ swdd->SpanRenderStart = i810SpanRenderStart;
+ swdd->SpanRenderFinish = i810SpanRenderFinish;
+}
+
+
+
+/**
+ * Plug in the Get/Put routines for the given driRenderbuffer.
+ */
+void
+i810SetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
+{
+ if (drb->Base.InternalFormat == GL_RGBA) {
+ /* always 565 RGB */
+ i810InitPointers_565(&drb->Base);
+ }
+ else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) {
+ i810InitDepthPointers_z16(&drb->Base);
+ }
+ else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) {
+ /* should never get here */
+ drb->Base.GetRow = NULL;
+ drb->Base.GetValues = NULL;
+ drb->Base.PutRow = NULL;
+ drb->Base.PutMonoRow = NULL;
+ drb->Base.PutValues = NULL;
+ drb->Base.PutMonoValues = NULL;
+ }
+ else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
+ drb->Base.GetRow = NULL;
+ drb->Base.GetValues = NULL;
+ drb->Base.PutRow = NULL;
+ drb->Base.PutMonoRow = NULL;
+ drb->Base.PutValues = NULL;
+ drb->Base.PutMonoValues = NULL;
+ }
+}
diff --git a/src/i810span.h b/src/i810span.h
new file mode 100644
index 0000000..9aed253
--- /dev/null
+++ b/src/i810span.h
@@ -0,0 +1,14 @@
+#ifndef _I810_SPAN_H
+#define _I810_SPAN_H
+
+#include "drirenderbuffer.h"
+
+extern void i810InitSpanFuncs( GLcontext *ctx );
+
+extern void i810SpanRenderFinish( GLcontext *ctx );
+extern void i810SpanRenderStart( GLcontext *ctx );
+
+extern void
+i810SetSpanFunctions(driRenderbuffer *rb, const GLvisual *vis);
+
+#endif
diff --git a/src/i810state.c b/src/i810state.c
new file mode 100644
index 0000000..3ad2528
--- /dev/null
+++ b/src/i810state.c
@@ -0,0 +1,998 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810state.c,v 1.9 2002/10/30 12:51:33 alanh Exp $ */
+
+#include <stdio.h>
+
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "dd.h"
+#include "colormac.h"
+
+#include "texmem.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810state.h"
+#include "i810tex.h"
+#include "i810vb.h"
+#include "i810tris.h"
+#include "i810ioctl.h"
+
+#include "swrast/swrast.h"
+#include "tnl/tnl.h"
+#include "vbo/vbo.h"
+#include "swrast_setup/swrast_setup.h"
+
+#include "tnl/t_pipeline.h"
+
+static __inline__ GLuint i810PackColor(GLuint format,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a)
+{
+
+ if (I810_DEBUG&DEBUG_DRI)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ switch (format) {
+ case DV_PF_555:
+ return PACK_COLOR_1555( a, r, g, b );
+ case DV_PF_565:
+ return PACK_COLOR_565( r, g, b );
+ default:
+ fprintf(stderr, "unknown format %d\n", (int)format);
+ return 0;
+ }
+}
+
+
+static void i810AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint a = (ZA_UPDATE_ALPHAFUNC|ZA_UPDATE_ALPHAREF);
+ GLubyte refByte;
+
+ CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
+
+ switch (ctx->Color.AlphaFunc) {
+ case GL_NEVER: a |= ZA_ALPHA_NEVER; break;
+ case GL_LESS: a |= ZA_ALPHA_LESS; break;
+ case GL_GEQUAL: a |= ZA_ALPHA_GEQUAL; break;
+ case GL_LEQUAL: a |= ZA_ALPHA_LEQUAL; break;
+ case GL_GREATER: a |= ZA_ALPHA_GREATER; break;
+ case GL_NOTEQUAL: a |= ZA_ALPHA_NOTEQUAL; break;
+ case GL_EQUAL: a |= ZA_ALPHA_EQUAL; break;
+ case GL_ALWAYS: a |= ZA_ALPHA_ALWAYS; break;
+ default: return;
+ }
+
+ a |= ((refByte & 0xfc) << ZA_ALPHAREF_SHIFT);
+
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_ZA] &= ~(ZA_ALPHA_MASK|ZA_ALPHAREF_MASK);
+ imesa->Setup[I810_CTXREG_ZA] |= a;
+}
+
+static void i810BlendEquationSeparate(GLcontext *ctx,
+ GLenum modeRGB, GLenum modeA)
+{
+ assert( modeRGB == modeA );
+
+ /* Can only do GL_ADD equation in hardware */
+ FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_BLEND_EQ,
+ modeRGB != GL_FUNC_ADD);
+
+ /* BlendEquation sets ColorLogicOpEnabled in an unexpected
+ * manner.
+ */
+ FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_LOGICOP,
+ (ctx->Color.ColorLogicOpEnabled &&
+ ctx->Color.LogicOp != GL_COPY));
+}
+
+static void i810BlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
+ GLenum dfactorRGB, GLenum sfactorA,
+ GLenum dfactorA )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND;
+ GLboolean fallback = GL_FALSE;
+
+ switch (ctx->Color.BlendSrcRGB) {
+ case GL_ZERO: a |= SDM_SRC_ZERO; break;
+ case GL_ONE: a |= SDM_SRC_ONE; break;
+ case GL_SRC_COLOR: a |= SDM_SRC_SRC_COLOR; break;
+ case GL_ONE_MINUS_SRC_COLOR: a |= SDM_SRC_INV_SRC_COLOR; break;
+ case GL_SRC_ALPHA: a |= SDM_SRC_SRC_ALPHA; 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_DST_COLOR: a |= SDM_SRC_DST_COLOR; break;
+ case GL_ONE_MINUS_DST_COLOR: a |= SDM_SRC_INV_DST_COLOR; break;
+
+ /* (f, f, f, 1), f = min(As, 1 - Ad) = min(As, 1 - 1) = 0
+ * So (f, f, f, 1) = (0, 0, 0, 1). Since there is no destination alpha and
+ * the only supported alpha operation is GL_FUNC_ADD, the result modulating
+ * the source alpha with the alpha factor is largely irrelevant.
+ */
+ case GL_SRC_ALPHA_SATURATE: a |= SDM_SRC_ZERO; break;
+
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ fallback = GL_TRUE;
+ break;
+ default:
+ return;
+ }
+
+ switch (ctx->Color.BlendDstRGB) {
+ 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_SRC_ALPHA: a |= SDM_DST_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_DST_INV_SRC_ALPHA; break;
+ case GL_DST_ALPHA: a |= SDM_DST_ONE; break;
+ case GL_ONE_MINUS_DST_ALPHA: a |= SDM_DST_ZERO; break;
+ case GL_DST_COLOR: a |= SDM_DST_DST_COLOR; break;
+ case GL_ONE_MINUS_DST_COLOR: a |= SDM_DST_INV_DST_COLOR; break;
+
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ fallback = GL_TRUE;
+ break;
+ default:
+ return;
+ }
+
+ FALLBACK( imesa, I810_FALLBACK_BLEND_FUNC, fallback);
+ if (!fallback) {
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_SDM] &= ~(SDM_SRC_MASK|SDM_DST_MASK);
+ imesa->Setup[I810_CTXREG_SDM] |= a;
+ }
+}
+
+
+
+static void i810DepthFunc(GLcontext *ctx, GLenum func)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ int zmode;
+
+ switch(func) {
+ case GL_NEVER: zmode = LCS_Z_NEVER; break;
+ case GL_ALWAYS: zmode = LCS_Z_ALWAYS; break;
+ case GL_LESS: zmode = LCS_Z_LESS; break;
+ case GL_LEQUAL: zmode = LCS_Z_LEQUAL; break;
+ case GL_EQUAL: zmode = LCS_Z_EQUAL; break;
+ case GL_GREATER: zmode = LCS_Z_GREATER; break;
+ case GL_GEQUAL: zmode = LCS_Z_GEQUAL; break;
+ case GL_NOTEQUAL: zmode = LCS_Z_NOTEQUAL; break;
+ default: return;
+ }
+
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_Z_MASK;
+ imesa->Setup[I810_CTXREG_LCS] |= zmode;
+}
+
+static void i810DepthMask(GLcontext *ctx, GLboolean flag)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+
+ if (flag)
+ imesa->Setup[I810_CTXREG_B2] |= B2_ZB_WRITE_ENABLE;
+ else
+ imesa->Setup[I810_CTXREG_B2] &= ~B2_ZB_WRITE_ENABLE;
+}
+
+
+/* =============================================================
+ * Polygon stipple
+ *
+ * The i810 supports a 4x4 stipple natively, GL wants 32x32.
+ * Fortunately stipple is usually a repeating pattern.
+ */
+static void i810PolygonStipple( GLcontext *ctx, const GLubyte *mask )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ const GLubyte *m = mask;
+ GLubyte p[4];
+ int i,j,k;
+ int active = (ctx->Polygon.StippleFlag &&
+ imesa->reduced_primitive == GL_TRIANGLES);
+ GLuint newMask;
+
+ if (active) {
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
+ }
+
+ p[0] = mask[12] & 0xf; p[0] |= p[0] << 4;
+ p[1] = mask[8] & 0xf; p[1] |= p[1] << 4;
+ p[2] = mask[4] & 0xf; p[2] |= p[2] << 4;
+ p[3] = mask[0] & 0xf; p[3] |= p[3] << 4;
+
+ for (k = 0 ; k < 8 ; k++)
+ for (j = 0 ; j < 4; j++)
+ for (i = 0 ; i < 4 ; i++)
+ if (*m++ != p[j]) {
+ imesa->stipple_in_hw = 0;
+ return;
+ }
+
+ newMask = ((p[0] & 0xf) << 0) |
+ ((p[1] & 0xf) << 4) |
+ ((p[2] & 0xf) << 8) |
+ ((p[3] & 0xf) << 12);
+
+ if (newMask == 0xffff) {
+ /* this is needed to make conform pass */
+ imesa->stipple_in_hw = 0;
+ return;
+ }
+
+ imesa->Setup[I810_CTXREG_ST1] &= ~0xffff;
+ imesa->Setup[I810_CTXREG_ST1] |= newMask;
+ imesa->stipple_in_hw = 1;
+
+ if (active)
+ imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
+}
+
+
+
+/* =============================================================
+ * Hardware clipping
+ */
+
+
+static void i810Scissor( GLcontext *ctx, GLint x, GLint y,
+ GLsizei w, GLsizei h )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ if (ctx->Scissor.Enabled) {
+ I810_FIREVERTICES(imesa); /* don't pipeline cliprect changes */
+ imesa->upload_cliprects = GL_TRUE;
+ }
+
+ imesa->scissor_rect.x1 = x;
+ imesa->scissor_rect.y1 = imesa->driDrawable->h - (y + h);
+ imesa->scissor_rect.x2 = x + w;
+ imesa->scissor_rect.y2 = imesa->driDrawable->h - y;
+}
+
+
+static void i810LogicOp( GLcontext *ctx, GLenum opcode )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ FALLBACK( imesa, I810_FALLBACK_LOGICOP,
+ (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) );
+}
+
+/* Fallback to swrast for select and feedback.
+ */
+static void i810RenderMode( GLcontext *ctx, GLenum mode )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ FALLBACK( imesa, I810_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
+}
+
+
+void i810DrawBuffer(GLcontext *ctx, GLenum mode )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ int front = 0;
+
+ /*
+ * _DrawDestMask is easier to cope with than <mode>.
+ */
+ switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0]) {
+ case BUFFER_BIT_FRONT_LEFT:
+ front = 1;
+ break;
+ case BUFFER_BIT_BACK_LEFT:
+ front = 0;
+ break;
+ default:
+ /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
+ FALLBACK( imesa, I810_FALLBACK_DRAW_BUFFER, GL_TRUE );
+ return;
+ }
+
+ if ( imesa->sarea->pf_current_page == 1 )
+ front ^= 1;
+
+ FALLBACK( imesa, I810_FALLBACK_DRAW_BUFFER, GL_FALSE );
+ I810_FIREVERTICES(imesa);
+ I810_STATECHANGE(imesa, I810_UPLOAD_BUFFERS);
+
+ if (front)
+ {
+ imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->fbOffset |
+ imesa->i810Screen->backPitchBits);
+ i810XMesaSetFrontClipRects( imesa );
+ }
+ else
+ {
+ imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->backOffset |
+ imesa->i810Screen->backPitchBits);
+ i810XMesaSetBackClipRects( imesa );
+ }
+}
+
+
+static void i810ReadBuffer(GLcontext *ctx, GLenum mode )
+{
+ /* XXX anything? */
+}
+
+
+static void i810ClearColor(GLcontext *ctx, const GLfloat color[4] )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLubyte c[4];
+ CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
+ imesa->ClearColor = i810PackColor( imesa->i810Screen->fbFormat,
+ c[0], c[1], c[2], c[3] );
+}
+
+
+/* =============================================================
+ * Culling - the i810 isn't quite as clean here as the rest of
+ * its interfaces, but it's not bad.
+ */
+static void i810CullFaceFrontFace(GLcontext *ctx, GLenum unused)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint mode = LCS_CULL_BOTH;
+
+ if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
+ mode = LCS_CULL_CW;
+ if (ctx->Polygon.CullFaceMode == GL_FRONT)
+ mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW);
+ if (ctx->Polygon.FrontFace != GL_CCW)
+ mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW);
+ }
+
+ imesa->LcsCullMode = mode;
+
+ if (ctx->Polygon.CullFlag)
+ {
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
+ imesa->Setup[I810_CTXREG_LCS] |= mode;
+ }
+}
+
+
+static void i810LineWidth( GLcontext *ctx, GLfloat widthf )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ int width = (int)ctx->Line._Width;
+
+ imesa->LcsLineWidth = 0;
+ if (width & 1) imesa->LcsLineWidth |= LCS_LINEWIDTH_1_0;
+ if (width & 2) imesa->LcsLineWidth |= LCS_LINEWIDTH_2_0;
+
+ if (imesa->reduced_primitive == GL_LINES) {
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_3_0;
+ imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsLineWidth;
+ }
+}
+
+static void i810PointSize( GLcontext *ctx, GLfloat sz )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ int size = (int)ctx->Point._Size;
+
+ imesa->LcsPointSize = 0;
+ if (size & 1) imesa->LcsPointSize |= LCS_LINEWIDTH_1_0;
+ if (size & 2) imesa->LcsPointSize |= LCS_LINEWIDTH_2_0;
+
+ if (imesa->reduced_primitive == GL_POINTS) {
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_3_0;
+ imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsPointSize;
+ }
+}
+
+/* =============================================================
+ * Color masks
+ */
+
+static void i810ColorMask(GLcontext *ctx,
+ GLboolean r, GLboolean g,
+ GLboolean b, GLboolean a )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ GLuint tmp = 0;
+
+ if (r && g && b) {
+ tmp = imesa->Setup[I810_CTXREG_B2] | B2_FB_WRITE_ENABLE;
+ FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_FALSE );
+ } else if (!r && !g && !b) {
+ tmp = imesa->Setup[I810_CTXREG_B2] & ~B2_FB_WRITE_ENABLE;
+ FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_FALSE );
+ } else {
+ FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_TRUE );
+ return;
+ }
+
+ if (tmp != imesa->Setup[I810_CTXREG_B2]) {
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_B2] = tmp;
+ imesa->dirty |= I810_UPLOAD_CTX;
+ }
+}
+
+/* Seperate specular not fully implemented on the i810.
+ */
+static void i810LightModelfv(GLcontext *ctx, GLenum pname,
+ const GLfloat *param)
+{
+ if (pname == GL_LIGHT_MODEL_COLOR_CONTROL)
+ {
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ FALLBACK( imesa, I810_FALLBACK_SPECULAR,
+ (ctx->Light.Enabled &&
+ ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR));
+ }
+}
+
+/* But the 815 has it...
+ */
+static void i810LightModelfv_i815(GLcontext *ctx, GLenum pname,
+ const GLfloat *param)
+{
+ if (pname == GL_LIGHT_MODEL_COLOR_CONTROL)
+ {
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+ imesa->Setup[I810_CTXREG_B1] |= B1_SPEC_ENABLE;
+ else
+ imesa->Setup[I810_CTXREG_B1] &= ~B1_SPEC_ENABLE;
+ }
+}
+
+/* In Mesa 3.5 we can reliably do native flatshading.
+ */
+static void i810ShadeModel(GLcontext *ctx, GLenum mode)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ if (mode == GL_FLAT)
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_INTERP_FLAT;
+ else
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_INTERP_FLAT;
+}
+
+
+
+/* =============================================================
+ * Fog
+ */
+static void i810Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ if (pname == GL_FOG_COLOR) {
+ GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) |
+ ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
+ ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
+
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_FOG] = ((GFX_OP_FOG_COLOR | color) &
+ ~FOG_RESERVED_MASK);
+ }
+}
+
+
+/* =============================================================
+ */
+static void i810Enable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ switch(cap) {
+ case GL_ALPHA_TEST:
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_B1] &= ~B1_ALPHA_TEST_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_B1] |= B1_ALPHA_TEST_ENABLE;
+ break;
+ case GL_BLEND:
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_B1] &= ~B1_BLEND_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_B1] |= B1_BLEND_ENABLE;
+
+ /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
+ */
+ FALLBACK( imesa, I810_FALLBACK_LOGICOP,
+ (ctx->Color.ColorLogicOpEnabled &&
+ ctx->Color.LogicOp != GL_COPY));
+ break;
+ case GL_DEPTH_TEST:
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_B1] &= ~B1_Z_TEST_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_B1] |= B1_Z_TEST_ENABLE;
+ break;
+ case GL_SCISSOR_TEST:
+ /* XXX without these next two lines, conform's scissor test fails */
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ I810_STATECHANGE(imesa, I810_UPLOAD_BUFFERS);
+ I810_FIREVERTICES(imesa); /* don't pipeline cliprect changes */
+ imesa->upload_cliprects = GL_TRUE;
+ imesa->scissor = state;
+ break;
+ case GL_POLYGON_STIPPLE:
+ if (imesa->stipple_in_hw && imesa->reduced_primitive == GL_TRIANGLES)
+ {
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
+ }
+ break;
+ case GL_LINE_SMOOTH:
+ /* Need to fatten the lines by .5, or they disappear...
+ */
+ if (imesa->reduced_primitive == GL_LINES) {
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5;
+ if (state) {
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5;
+ }
+ }
+ break;
+ case GL_POINT_SMOOTH:
+ if (imesa->reduced_primitive == GL_POINTS) {
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5;
+ if (state) {
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5;
+ }
+ }
+ break;
+ case GL_POLYGON_SMOOTH:
+ if (imesa->reduced_primitive == GL_TRIANGLES) {
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ }
+ break;
+ case GL_FOG:
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_B1] &= ~B1_FOG_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_B1] |= B1_FOG_ENABLE;
+ break;
+ case GL_CULL_FACE:
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
+ if (state)
+ imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsCullMode;
+ else
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
+ break;
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE_NV:
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ if (ctx->Texture.CurrentUnit == 0) {
+ imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE;
+ } else {
+ imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE;
+ }
+ break;
+ case GL_COLOR_LOGIC_OP:
+ FALLBACK( imesa, I810_FALLBACK_LOGICOP,
+ (state && ctx->Color.LogicOp != GL_COPY));
+ break;
+ case GL_STENCIL_TEST:
+ FALLBACK( imesa, I810_FALLBACK_STENCIL, state );
+ break;
+ default:
+ ;
+ }
+}
+
+
+
+
+
+
+
+/* =============================================================
+ */
+
+
+
+
+void i810EmitDrawingRectangle( i810ContextPtr imesa )
+{
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ i810ScreenPrivate *i810Screen = imesa->i810Screen;
+ int x0 = imesa->drawX;
+ int y0 = imesa->drawY;
+ int x1 = x0 + dPriv->w;
+ int y1 = y0 + dPriv->h;
+ GLuint dr2, dr3, dr4;
+
+
+ /* Coordinate origin of the window - may be offscreen.
+ */
+ dr4 = imesa->BufferSetup[I810_DESTREG_DR4] = ((y0<<16) |
+ (((unsigned)x0)&0xFFFF));
+
+ /* Clip to screen.
+ */
+ if (x0 < 0) x0 = 0;
+ if (y0 < 0) y0 = 0;
+ if (x1 > i810Screen->width-1) x1 = i810Screen->width-1;
+ if (y1 > i810Screen->height-1) y1 = i810Screen->height-1;
+
+
+ /* Onscreen drawing rectangle.
+ */
+ dr2 = imesa->BufferSetup[I810_DESTREG_DR2] = ((y0<<16) | x0);
+ dr3 = imesa->BufferSetup[I810_DESTREG_DR3] = (((y1+1)<<16) | (x1+1));
+
+
+ imesa->dirty |= I810_UPLOAD_BUFFERS;
+}
+
+
+
+static void i810CalcViewport( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+ GLfloat *m = imesa->ViewportMatrix.m;
+
+ /* See also i810_translate_vertex. SUBPIXEL adjustments can be done
+ * via state vars, too.
+ */
+ m[MAT_SX] = v[MAT_SX];
+ m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
+ m[MAT_SY] = - v[MAT_SY];
+ m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + SUBPIXEL_Y;
+ m[MAT_SZ] = v[MAT_SZ] * (1.0 / 0xffff);
+ m[MAT_TZ] = v[MAT_TZ] * (1.0 / 0xffff);
+}
+
+static void i810Viewport( GLcontext *ctx,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height )
+{
+ i810CalcViewport( ctx );
+}
+
+static void i810DepthRange( GLcontext *ctx,
+ GLclampd nearval, GLclampd farval )
+{
+ i810CalcViewport( ctx );
+}
+
+
+
+void i810PrintDirty( const char *msg, GLuint state )
+{
+ fprintf(stderr, "%s (0x%x): %s%s%s%s\n",
+ msg,
+ (unsigned int) state,
+ (state & I810_UPLOAD_TEX0) ? "upload-tex0, " : "",
+ (state & I810_UPLOAD_TEX1) ? "upload-tex1, " : "",
+ (state & I810_UPLOAD_CTX) ? "upload-ctx, " : "",
+ (state & I810_UPLOAD_BUFFERS) ? "upload-bufs, " : ""
+ );
+}
+
+
+
+void i810InitState( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ i810ScreenPrivate *i810Screen = imesa->i810Screen;
+
+ memset(imesa->Setup, 0, sizeof(imesa->Setup));
+
+ imesa->Setup[I810_CTXREG_VF] = 0;
+
+ imesa->Setup[I810_CTXREG_MT] = (GFX_OP_MAP_TEXELS |
+ MT_UPDATE_TEXEL1_STATE |
+ MT_TEXEL1_COORD1 |
+ MT_TEXEL1_MAP1 |
+ MT_TEXEL1_DISABLE |
+ MT_UPDATE_TEXEL0_STATE |
+ MT_TEXEL0_COORD0 |
+ MT_TEXEL0_MAP0 |
+ MT_TEXEL0_DISABLE);
+
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ ((MC_ARG_ITERATED_COLOR |
+ MC_ARG_DONT_REPLICATE_ALPHA |
+ MC_ARG_DONT_INVERT) << MC_ARG1_SHIFT) |
+ MC_UPDATE_ARG2 |
+ ((MC_ARG_ONE |
+ MC_ARG_DONT_REPLICATE_ALPHA |
+ MC_ARG_DONT_INVERT) << MC_ARG2_SHIFT) |
+ 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_ARG_ONE |
+ MC_ARG_DONT_REPLICATE_ALPHA |
+ MC_ARG_DONT_INVERT) << MC_ARG1_SHIFT) |
+ MC_UPDATE_ARG2 |
+ ((MC_ARG_ONE |
+ MC_ARG_DONT_REPLICATE_ALPHA |
+ MC_ARG_DONT_INVERT) << MC_ARG2_SHIFT) |
+ 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_ARG_CURRENT_COLOR |
+ MC_ARG_REPLICATE_ALPHA |
+ MC_ARG_DONT_INVERT) << MC_ARG1_SHIFT) |
+ MC_UPDATE_ARG2 |
+ ((MC_ARG_ONE |
+ MC_ARG_DONT_REPLICATE_ALPHA |
+ MC_ARG_DONT_INVERT) << MC_ARG2_SHIFT) |
+ MC_UPDATE_OP |
+ MC_OP_DISABLE );
+
+
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ ((MA_ARG_ITERATED_ALPHA |
+ MA_ARG_DONT_INVERT) << MA_ARG1_SHIFT) |
+ MA_UPDATE_ARG2 |
+ ((MA_ARG_CURRENT_ALPHA |
+ MA_ARG_DONT_INVERT) << MA_ARG2_SHIFT) |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+
+
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ ((MA_ARG_CURRENT_ALPHA |
+ MA_ARG_DONT_INVERT) << MA_ARG1_SHIFT) |
+ MA_UPDATE_ARG2 |
+ ((MA_ARG_CURRENT_ALPHA |
+ MA_ARG_DONT_INVERT) << MA_ARG2_SHIFT) |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+
+
+ imesa->Setup[I810_CTXREG_MA2] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_2 |
+ MA_UPDATE_ARG1 |
+ ((MA_ARG_CURRENT_ALPHA |
+ MA_ARG_DONT_INVERT) << MA_ARG1_SHIFT) |
+ MA_UPDATE_ARG2 |
+ ((MA_ARG_CURRENT_ALPHA |
+ MA_ARG_DONT_INVERT) << MA_ARG2_SHIFT) |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+
+
+ imesa->Setup[I810_CTXREG_SDM] = ( GFX_OP_SRC_DEST_MONO |
+ SDM_UPDATE_MONO_ENABLE |
+ 0 |
+ SDM_UPDATE_SRC_BLEND |
+ SDM_SRC_ONE |
+ SDM_UPDATE_DST_BLEND |
+ SDM_DST_ZERO );
+
+ /* Use for colormask:
+ */
+ imesa->Setup[I810_CTXREG_CF0] = GFX_OP_COLOR_FACTOR;
+ imesa->Setup[I810_CTXREG_CF1] = 0xffffffff;
+
+ imesa->Setup[I810_CTXREG_ZA] = (GFX_OP_ZBIAS_ALPHAFUNC |
+ ZA_UPDATE_ALPHAFUNC |
+ ZA_ALPHA_ALWAYS |
+ ZA_UPDATE_ZBIAS |
+ 0 |
+ ZA_UPDATE_ALPHAREF |
+ 0x0);
+
+ imesa->Setup[I810_CTXREG_FOG] = (GFX_OP_FOG_COLOR |
+ (0xffffff & ~FOG_RESERVED_MASK));
+
+ /* Choose a pipe
+ */
+ imesa->Setup[I810_CTXREG_B1] = ( GFX_OP_BOOL_1 |
+ B1_UPDATE_SPEC_SETUP_ENABLE |
+ 0 |
+ B1_UPDATE_ALPHA_SETUP_ENABLE |
+ B1_ALPHA_SETUP_ENABLE |
+ B1_UPDATE_CI_KEY_ENABLE |
+ 0 |
+ B1_UPDATE_CHROMAKEY_ENABLE |
+ 0 |
+ B1_UPDATE_Z_BIAS_ENABLE |
+ 0 |
+ B1_UPDATE_SPEC_ENABLE |
+ 0 |
+ B1_UPDATE_FOG_ENABLE |
+ 0 |
+ B1_UPDATE_ALPHA_TEST_ENABLE |
+ 0 |
+ B1_UPDATE_BLEND_ENABLE |
+ 0 |
+ B1_UPDATE_Z_TEST_ENABLE |
+ 0 );
+
+ imesa->Setup[I810_CTXREG_B2] = ( GFX_OP_BOOL_2 |
+ B2_UPDATE_MAP_CACHE_ENABLE |
+ B2_MAP_CACHE_ENABLE |
+ B2_UPDATE_ALPHA_DITHER_ENABLE |
+ 0 |
+ B2_UPDATE_FOG_DITHER_ENABLE |
+ 0 |
+ B2_UPDATE_SPEC_DITHER_ENABLE |
+ 0 |
+ B2_UPDATE_RGB_DITHER_ENABLE |
+ B2_RGB_DITHER_ENABLE |
+ B2_UPDATE_FB_WRITE_ENABLE |
+ B2_FB_WRITE_ENABLE |
+ B2_UPDATE_ZB_WRITE_ENABLE |
+ B2_ZB_WRITE_ENABLE );
+
+ imesa->Setup[I810_CTXREG_LCS] = ( GFX_OP_LINEWIDTH_CULL_SHADE_MODE |
+ LCS_UPDATE_ZMODE |
+ LCS_Z_LESS |
+ LCS_UPDATE_LINEWIDTH |
+ LCS_LINEWIDTH_1_0 |
+ LCS_UPDATE_ALPHA_INTERP |
+ LCS_ALPHA_INTERP |
+ LCS_UPDATE_FOG_INTERP |
+ 0 |
+ LCS_UPDATE_SPEC_INTERP |
+ 0 |
+ LCS_UPDATE_RGB_INTERP |
+ LCS_RGB_INTERP |
+ LCS_UPDATE_CULL_MODE |
+ LCS_CULL_DISABLE);
+
+ imesa->LcsCullMode = LCS_CULL_CW;
+ imesa->LcsLineWidth = LCS_LINEWIDTH_1_0;
+ imesa->LcsPointSize = LCS_LINEWIDTH_1_0;
+
+ imesa->Setup[I810_CTXREG_PV] = ( GFX_OP_PV_RULE |
+ PV_UPDATE_PIXRULE |
+ PV_PIXRULE_ENABLE |
+ PV_UPDATE_LINELIST |
+ PV_LINELIST_PV1 |
+ PV_UPDATE_TRIFAN |
+ PV_TRIFAN_PV2 |
+ PV_UPDATE_TRISTRIP |
+ PV_TRISTRIP_PV2 );
+
+
+ imesa->Setup[I810_CTXREG_ST0] = GFX_OP_STIPPLE;
+ imesa->Setup[I810_CTXREG_ST1] = 0;
+
+ imesa->Setup[I810_CTXREG_AA] = ( GFX_OP_ANTIALIAS |
+ AA_UPDATE_EDGEFLAG |
+ 0 |
+ AA_UPDATE_POLYWIDTH |
+ AA_POLYWIDTH_05 |
+ AA_UPDATE_LINEWIDTH |
+ AA_LINEWIDTH_05 |
+ AA_UPDATE_BB_EXPANSION |
+ 0 |
+ AA_UPDATE_AA_ENABLE |
+ 0 );
+
+ memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup));
+ imesa->BufferSetup[I810_DESTREG_DI0] = CMD_OP_DESTBUFFER_INFO;
+
+ if (imesa->glCtx->Visual.doubleBufferMode && imesa->sarea->pf_current_page == 0) {
+ /* use back buffer by default */
+ imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->backOffset |
+ i810Screen->backPitchBits);
+ } else {
+ /* use front buffer by default */
+ imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->fbOffset |
+ i810Screen->backPitchBits);
+ }
+
+ imesa->BufferSetup[I810_DESTREG_DV0] = GFX_OP_DESTBUFFER_VARS;
+ imesa->BufferSetup[I810_DESTREG_DV1] = (DV_HORG_BIAS_OGL |
+ DV_VORG_BIAS_OGL |
+ i810Screen->fbFormat);
+
+ imesa->BufferSetup[I810_DESTREG_DR0] = GFX_OP_DRAWRECT_INFO;
+ imesa->BufferSetup[I810_DESTREG_DR1] = DR1_RECT_CLIP_ENABLE;
+}
+
+
+static void i810InvalidateState( GLcontext *ctx, GLuint new_state )
+{
+ _swrast_InvalidateState( ctx, new_state );
+ _swsetup_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
+ _tnl_InvalidateState( ctx, new_state );
+ I810_CONTEXT(ctx)->new_state |= new_state;
+}
+
+
+void i810InitStateFuncs(GLcontext *ctx)
+{
+ /* Callbacks for internal Mesa events.
+ */
+ ctx->Driver.UpdateState = i810InvalidateState;
+
+ /* API callbacks
+ */
+ ctx->Driver.AlphaFunc = i810AlphaFunc;
+ ctx->Driver.BlendEquationSeparate = i810BlendEquationSeparate;
+ ctx->Driver.BlendFuncSeparate = i810BlendFuncSeparate;
+ ctx->Driver.ClearColor = i810ClearColor;
+ ctx->Driver.ColorMask = i810ColorMask;
+ ctx->Driver.CullFace = i810CullFaceFrontFace;
+ ctx->Driver.DepthFunc = i810DepthFunc;
+ ctx->Driver.DepthMask = i810DepthMask;
+ ctx->Driver.Enable = i810Enable;
+ ctx->Driver.Fogfv = i810Fogfv;
+ ctx->Driver.FrontFace = i810CullFaceFrontFace;
+ ctx->Driver.LineWidth = i810LineWidth;
+ ctx->Driver.LogicOpcode = i810LogicOp;
+ ctx->Driver.PolygonStipple = i810PolygonStipple;
+ ctx->Driver.RenderMode = i810RenderMode;
+ ctx->Driver.Scissor = i810Scissor;
+ ctx->Driver.DrawBuffer = i810DrawBuffer;
+ ctx->Driver.ReadBuffer = i810ReadBuffer;
+ ctx->Driver.ShadeModel = i810ShadeModel;
+ ctx->Driver.DepthRange = i810DepthRange;
+ ctx->Driver.Viewport = i810Viewport;
+ ctx->Driver.PointSize = i810PointSize;
+
+ if (IS_I815(I810_CONTEXT(ctx))) {
+ ctx->Driver.LightModelfv = i810LightModelfv_i815;
+ } else {
+ ctx->Driver.LightModelfv = i810LightModelfv;
+ }
+}
diff --git a/src/i810state.h b/src/i810state.h
new file mode 100644
index 0000000..118b075
--- /dev/null
+++ b/src/i810state.h
@@ -0,0 +1,15 @@
+#ifndef _I810_STATE_H
+#define _I810_STATE_H
+
+#include "i810context.h"
+
+extern void i810InitState( GLcontext *ctx );
+extern void i810InitStateFuncs( GLcontext *ctx );
+extern void i810PrintDirty( const char *msg, GLuint state );
+extern void i810DrawBuffer(GLcontext *ctx, GLenum mode );
+
+extern void i810Fallback( i810ContextPtr imesa, GLuint bit, GLboolean mode );
+#define FALLBACK( imesa, bit, mode ) i810Fallback( imesa, bit, mode )
+
+
+#endif
diff --git a/src/i810tex.c b/src/i810tex.c
new file mode 100644
index 0000000..f657abe
--- /dev/null
+++ b/src/i810tex.c
@@ -0,0 +1,550 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tex.c,v 1.9 2002/10/30 12:51:33 alanh Exp $ */
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "imports.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "texstore.h"
+#include "texformat.h"
+#include "teximage.h"
+#include "texmem.h"
+#include "texobj.h"
+#include "swrast/swrast.h"
+#include "colormac.h"
+#include "texobj.h"
+#include "mm.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810tex.h"
+#include "i810state.h"
+#include "i810ioctl.h"
+
+
+/*
+ * Compute the 'S2.4' lod bias factor from the floating point OpenGL bias.
+ */
+static GLuint i810ComputeLodBias(GLfloat bias)
+{
+ int b = (int) (bias * 16.0) + 12;
+ if (b > 63)
+ b = 63;
+ else if (b < -64)
+ b = -64;
+ return (GLuint) (b & MLC_LOD_BIAS_MASK);
+}
+
+
+static void i810SetTexWrapping(i810TextureObjectPtr tex,
+ GLenum swrap, GLenum twrap)
+{
+ tex->Setup[I810_TEXREG_MCS] &= ~(MCS_U_STATE_MASK| MCS_V_STATE_MASK);
+
+ switch( swrap ) {
+ case GL_REPEAT:
+ tex->Setup[I810_TEXREG_MCS] |= MCS_U_WRAP;
+ break;
+ case GL_CLAMP:
+ case GL_CLAMP_TO_EDGE:
+ tex->Setup[I810_TEXREG_MCS] |= MCS_U_CLAMP;
+ break;
+ case GL_MIRRORED_REPEAT:
+ tex->Setup[I810_TEXREG_MCS] |= MCS_U_MIRROR;
+ break;
+ default:
+ _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__);
+ }
+
+ switch( twrap ) {
+ case GL_REPEAT:
+ tex->Setup[I810_TEXREG_MCS] |= MCS_V_WRAP;
+ break;
+ case GL_CLAMP:
+ case GL_CLAMP_TO_EDGE:
+ tex->Setup[I810_TEXREG_MCS] |= MCS_V_CLAMP;
+ break;
+ case GL_MIRRORED_REPEAT:
+ tex->Setup[I810_TEXREG_MCS] |= MCS_V_MIRROR;
+ break;
+ default:
+ _mesa_problem(NULL, "bad T wrap mode in %s", __FUNCTION__);
+ }
+}
+
+
+static void i810SetTexFilter(i810ContextPtr imesa,
+ i810TextureObjectPtr t,
+ GLenum minf, GLenum magf,
+ GLfloat bias)
+{
+ t->Setup[I810_TEXREG_MF] &= ~(MF_MIN_MASK|
+ MF_MAG_MASK|
+ MF_MIP_MASK);
+ t->Setup[I810_TEXREG_MLC] &= ~(MLC_LOD_BIAS_MASK);
+
+ switch (minf) {
+ case GL_NEAREST:
+ t->Setup[I810_TEXREG_MF] |= MF_MIN_NEAREST | MF_MIP_NONE;
+ break;
+ case GL_LINEAR:
+ t->Setup[I810_TEXREG_MF] |= MF_MIN_LINEAR | MF_MIP_NONE;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ t->Setup[I810_TEXREG_MF] |= MF_MIN_NEAREST | MF_MIP_NEAREST;
+ if (magf == GL_LINEAR) {
+ /*bias -= 0.5;*/ /* this doesn't work too good */
+ }
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ t->Setup[I810_TEXREG_MF] |= MF_MIN_LINEAR | MF_MIP_NEAREST;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ if (IS_I815(imesa))
+ t->Setup[I810_TEXREG_MF] |= MF_MIN_NEAREST | MF_MIP_LINEAR;
+ else
+ t->Setup[I810_TEXREG_MF] |= MF_MIN_NEAREST | MF_MIP_DITHER;
+ /*
+ if (magf == GL_LINEAR) {
+ bias -= 0.5;
+ }
+ */
+ bias -= 0.5; /* always biasing here looks better */
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ if (IS_I815(imesa))
+ t->Setup[I810_TEXREG_MF] |= MF_MIN_LINEAR | MF_MIP_LINEAR;
+ else
+ t->Setup[I810_TEXREG_MF] |= MF_MIN_LINEAR | MF_MIP_DITHER;
+ break;
+ default:
+ return;
+ }
+
+ switch (magf) {
+ case GL_NEAREST:
+ t->Setup[I810_TEXREG_MF] |= MF_MAG_NEAREST;
+ break;
+ case GL_LINEAR:
+ t->Setup[I810_TEXREG_MF] |= MF_MAG_LINEAR;
+ break;
+ default:
+ return;
+ }
+
+ t->Setup[I810_TEXREG_MLC] |= i810ComputeLodBias(bias);
+}
+
+
+static void
+i810SetTexBorderColor( i810TextureObjectPtr t, GLubyte color[4] )
+{
+ /* Need a fallback.
+ */
+}
+
+
+static i810TextureObjectPtr
+i810AllocTexObj( GLcontext *ctx, struct gl_texture_object *texObj )
+{
+ i810TextureObjectPtr t;
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ t = CALLOC_STRUCT( i810_texture_object_t );
+ texObj->DriverData = t;
+ if ( t != NULL ) {
+ GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias;
+ /* Initialize non-image-dependent parts of the state:
+ */
+ t->base.tObj = texObj;
+ t->Setup[I810_TEXREG_MI0] = GFX_OP_MAP_INFO;
+ t->Setup[I810_TEXREG_MI1] = MI1_MAP_0;
+ t->Setup[I810_TEXREG_MI2] = MI2_DIMENSIONS_ARE_LOG2;
+ t->Setup[I810_TEXREG_MLC] = (GFX_OP_MAP_LOD_CTL |
+ MLC_MAP_0 |
+ /*MLC_DITHER_WEIGHT_FULL |*/
+ MLC_DITHER_WEIGHT_12 |
+ MLC_UPDATE_LOD_BIAS |
+ 0x0);
+ t->Setup[I810_TEXREG_MCS] = (GFX_OP_MAP_COORD_SETS |
+ MCS_COORD_0 |
+ MCS_UPDATE_NORMALIZED |
+ MCS_NORMALIZED_COORDS |
+ MCS_UPDATE_V_STATE |
+ MCS_V_WRAP |
+ MCS_UPDATE_U_STATE |
+ MCS_U_WRAP);
+ t->Setup[I810_TEXREG_MF] = (GFX_OP_MAP_FILTER |
+ MF_MAP_0 |
+ MF_UPDATE_ANISOTROPIC |
+ MF_UPDATE_MIP_FILTER |
+ MF_UPDATE_MAG_FILTER |
+ MF_UPDATE_MIN_FILTER);
+
+ make_empty_list( & t->base );
+
+ i810SetTexWrapping( t, texObj->WrapS, texObj->WrapT );
+ /*i830SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );*/
+ i810SetTexFilter( imesa, t, texObj->MinFilter, texObj->MagFilter, bias );
+ i810SetTexBorderColor( t, texObj->_BorderChan );
+ }
+
+ return t;
+}
+
+
+static void i810TexParameter( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData;
+
+ if (!t)
+ return;
+
+ if ( target != GL_TEXTURE_2D )
+ return;
+
+ /* Can't do the update now as we don't know whether to flush
+ * vertices or not. Setting imesa->new_state means that
+ * i810UpdateTextureState() will be called before any triangles are
+ * rendered. If a statechange has occurred, it will be detected at
+ * that point, and buffered vertices flushed.
+ */
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ {
+ GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias;
+ i810SetTexFilter( imesa, t, tObj->MinFilter, tObj->MagFilter, bias );
+ }
+ break;
+
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ i810SetTexWrapping( t, tObj->WrapS, tObj->WrapT );
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ i810SetTexBorderColor( t, tObj->_BorderChan );
+ break;
+
+ case GL_TEXTURE_BASE_LEVEL:
+ case GL_TEXTURE_MAX_LEVEL:
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ /* This isn't the most efficient solution but there doesn't appear to
+ * be a nice alternative for Radeon. Since there's no LOD clamping,
+ * we just have to rely on loading the right subset of mipmap levels
+ * to simulate a clamped LOD.
+ */
+ I810_FIREVERTICES( I810_CONTEXT(ctx) );
+ driSwapOutTextureObject( (driTextureObject *) t );
+ break;
+
+ default:
+ return;
+ }
+
+ if (t == imesa->CurrentTexObj[0]) {
+ I810_STATECHANGE( imesa, I810_UPLOAD_TEX0 );
+ }
+
+ if (t == imesa->CurrentTexObj[1]) {
+ I810_STATECHANGE( imesa, I810_UPLOAD_TEX1 );
+ }
+}
+
+
+/**
+ * Setup hardware bits for new texture environment settings.
+ *
+ * \todo
+ * Determine whether or not \c param can be used instead of
+ * \c texUnit->EnvColor in the \c GL_TEXTURE_ENV_COLOR case.
+ */
+static void i810TexEnv( GLcontext *ctx, GLenum target,
+ GLenum pname, const GLfloat *param )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ const GLuint unit = ctx->Texture.CurrentUnit;
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+
+ /* Only one env color. Need a fallback if env colors are different
+ * and texture setup references env color in both units.
+ */
+ switch (pname) {
+ case GL_TEXTURE_ENV_COLOR: {
+ GLubyte c[4];
+ GLuint envColor;
+
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor );
+ envColor = PACK_COLOR_8888( c[3], c[0], c[1], c[2] );
+
+ if (imesa->Setup[I810_CTXREG_CF1] != envColor) {
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_CF1] = envColor;
+ }
+ break;
+ }
+
+ case GL_TEXTURE_ENV_MODE:
+ imesa->TexEnvImageFmt[unit] = 0; /* force recalc of env state */
+ break;
+
+ case GL_TEXTURE_LOD_BIAS: {
+ if ( texUnit->_Current != NULL ) {
+ const struct gl_texture_object *tObj = texUnit->_Current;
+ i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData;
+
+ t->Setup[I810_TEXREG_MLC] &= ~(MLC_LOD_BIAS_MASK);
+ t->Setup[I810_TEXREG_MLC] |= i810ComputeLodBias(*param);
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+
+#if 0
+static void i810TexImage1D( GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *pack,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
+{
+ i810TextureObjectPtr t = (i810TextureObjectPtr) texObj->DriverData;
+ if (t) {
+ i810SwapOutTexObj( imesa, t );
+ }
+}
+
+static void i810TexSubImage1D( GLcontext *ctx,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *pack,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
+{
+}
+#endif
+
+
+static void i810TexImage2D( GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
+{
+ driTextureObject *t = (driTextureObject *) texObj->DriverData;
+ if (t) {
+ I810_FIREVERTICES( I810_CONTEXT(ctx) );
+ driSwapOutTextureObject( t );
+ }
+ else {
+ t = (driTextureObject *) i810AllocTexObj( ctx, texObj );
+ if (!t) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+ return;
+ }
+ }
+ _mesa_store_teximage2d( ctx, target, level, internalFormat,
+ width, height, border, format, type,
+ pixels, packing, texObj, texImage );
+}
+
+static void i810TexSubImage2D( GLcontext *ctx,
+ GLenum target,
+ GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
+{
+ driTextureObject *t = (driTextureObject *)texObj->DriverData;
+ if (t) {
+ I810_FIREVERTICES( I810_CONTEXT(ctx) );
+ driSwapOutTextureObject( t );
+ }
+ _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
+ height, format, type, pixels, packing, texObj,
+ texImage);
+}
+
+
+static void i810BindTexture( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj )
+{
+ assert( (target != GL_TEXTURE_2D) || (tObj->DriverData != NULL) );
+}
+
+
+static void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
+{
+ driTextureObject * t = (driTextureObject *) tObj->DriverData;
+ if (t) {
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ if (imesa)
+ I810_FIREVERTICES( imesa );
+ driDestroyTextureObject( t );
+ }
+ /* Free mipmap images and the texture object itself */
+ _mesa_delete_texture_object(ctx, tObj);
+}
+
+/**
+ * Choose a Mesa texture format to match the requested format.
+ *
+ * The i810 only supports 5 texture modes that are useful to Mesa. That
+ * makes this routine pretty simple.
+ */
+static const struct gl_texture_format *
+i810ChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
+ GLenum format, GLenum type )
+{
+ switch ( internalFormat ) {
+ case 4:
+ case GL_RGBA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ case GL_COMPRESSED_RGBA:
+ if ( ((format == GL_BGRA) && (type == GL_UNSIGNED_SHORT_1_5_5_5_REV))
+ || ((format == GL_RGBA) && (type == GL_UNSIGNED_SHORT_5_5_5_1))
+ || (internalFormat == GL_RGB5_A1) ) {
+ return &_mesa_texformat_argb1555;
+ }
+ return &_mesa_texformat_argb4444;
+
+ case 3:
+ case GL_RGB:
+ case GL_COMPRESSED_RGB:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ return &_mesa_texformat_rgb565;
+
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ case GL_COMPRESSED_ALPHA:
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ case GL_COMPRESSED_LUMINANCE:
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ case GL_COMPRESSED_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ case GL_COMPRESSED_INTENSITY:
+ return &_mesa_texformat_al88;
+
+ case GL_YCBCR_MESA:
+ if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
+ type == GL_UNSIGNED_BYTE)
+ return &_mesa_texformat_ycbcr;
+ else
+ return &_mesa_texformat_ycbcr_rev;
+
+ default:
+ fprintf(stderr, "unexpected texture format in %s\n", __FUNCTION__);
+ return NULL;
+ }
+
+ return NULL; /* never get here */
+}
+
+/**
+ * Allocate a new texture object.
+ * Called via ctx->Driver.NewTextureObject.
+ * Note: this function will be called during context creation to
+ * allocate the default texture objects.
+ * Note: we could use containment here to 'derive' the driver-specific
+ * texture object from the core mesa gl_texture_object. Not done at this time.
+ */
+static struct gl_texture_object *
+i810NewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
+{
+ struct gl_texture_object *obj;
+ obj = _mesa_new_texture_object(ctx, name, target);
+ i810AllocTexObj( ctx, obj );
+ return obj;
+}
+
+void i810InitTextureFuncs( struct dd_function_table *functions )
+{
+ functions->ChooseTextureFormat = i810ChooseTextureFormat;
+ functions->TexImage2D = i810TexImage2D;
+ functions->TexSubImage2D = i810TexSubImage2D;
+ functions->BindTexture = i810BindTexture;
+ functions->NewTextureObject = i810NewTextureObject;
+ functions->DeleteTexture = i810DeleteTexture;
+ functions->TexParameter = i810TexParameter;
+ functions->TexEnv = i810TexEnv;
+ functions->IsTextureResident = driIsTextureResident;
+}
diff --git a/src/i810tex.h b/src/i810tex.h
new file mode 100644
index 0000000..c6ab4c8
--- /dev/null
+++ b/src/i810tex.h
@@ -0,0 +1,78 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#ifndef I810TEX_INC
+#define I810TEX_INC
+
+#include "mtypes.h"
+#include "mm.h"
+
+#include "i810context.h"
+#include "i810_3d_reg.h"
+#include "texmem.h"
+
+#define I810_TEX_MAXLEVELS 11
+
+/* For shared texture space managment, these texture objects may also
+ * be used as proxies for regions of texture memory containing other
+ * client's textures. Such proxy textures (not to be confused with GL
+ * proxy textures) are subject to the same LRU aging we use for our
+ * own private textures, and thus we have a mechanism where we can
+ * fairly decide between kicking out our own textures and those of
+ * other clients.
+ *
+ * Non-local texture objects have a valid MemBlock to describe the
+ * region managed by the other client, and can be identified by
+ * 't->globj == 0'
+ */
+struct i810_texture_object_t {
+ driTextureObject base;
+
+ int Pitch;
+ int Height;
+ int texelBytes;
+ char *BufAddr;
+
+ GLuint max_level;
+
+ struct {
+ const struct gl_texture_image *image;
+ int offset; /* into BufAddr */
+ int height;
+ int internalFormat;
+ } image[I810_TEX_MAXLEVELS];
+
+ GLuint Setup[I810_TEX_SETUP_SIZE];
+ GLuint dirty;
+
+};
+
+void i810UpdateTextureState( GLcontext *ctx );
+void i810InitTextureFuncs( struct dd_function_table *functions );
+
+void i810DestroyTexObj( i810ContextPtr imesa, i810TextureObjectPtr t );
+int i810UploadTexImagesLocked( i810ContextPtr imesa, i810TextureObjectPtr t );
+
+#endif
diff --git a/src/i810texmem.c b/src/i810texmem.c
new file mode 100644
index 0000000..08900cc
--- /dev/null
+++ b/src/i810texmem.c
@@ -0,0 +1,183 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ * Texmem interface changes (C) 2003 Dave Airlie
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "colormac.h"
+#include "mm.h"
+#include "texformat.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810tex.h"
+#include "i810state.h"
+#include "i810ioctl.h"
+
+
+void i810DestroyTexObj(i810ContextPtr imesa, i810TextureObjectPtr t)
+{
+ /* See if it was the driver's current object.
+ */
+ if ( imesa != NULL ) {
+ if (imesa->CurrentTexObj[0] == t) {
+ imesa->CurrentTexObj[0] = 0;
+ imesa->dirty &= ~I810_UPLOAD_TEX0;
+ }
+
+ if (imesa->CurrentTexObj[1] == t) {
+ imesa->CurrentTexObj[1] = 0;
+ imesa->dirty &= ~I810_UPLOAD_TEX1;
+ }
+ }
+}
+
+
+
+#if defined(i386) || defined(__i386__)
+/* From linux kernel i386 header files, copes with odd sizes better
+ * than COPY_DWORDS would:
+ */
+static __inline__ void * __memcpy(void * to, const void * from, size_t n)
+{
+int d0, d1, d2;
+__asm__ __volatile__(
+ "rep ; movsl\n\t"
+ "testb $2,%b4\n\t"
+ "je 1f\n\t"
+ "movsw\n"
+ "1:\ttestb $1,%b4\n\t"
+ "je 2f\n\t"
+ "movsb\n"
+ "2:"
+ : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+ :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+ : "memory");
+return (to);
+}
+#else
+/* Allow compilation on other architectures */
+#define __memcpy memcpy
+#endif
+
+/* Upload an image from mesa's internal copy.
+ */
+static void i810UploadTexLevel( i810ContextPtr imesa,
+ i810TextureObjectPtr t, int hwlevel )
+{
+ const struct gl_texture_image *image = t->image[hwlevel].image;
+ int j;
+
+ if (!image || !image->Data)
+ return;
+
+ if (image->Width * image->TexFormat->TexelBytes == t->Pitch) {
+ GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[hwlevel].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+
+ memcpy( dst, src, t->Pitch * image->Height );
+ }
+ else switch (image->TexFormat->TexelBytes) {
+ case 1:
+ {
+ GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[hwlevel].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+
+ for (j = 0 ; j < image->Height ; j++, dst += t->Pitch) {
+ __memcpy(dst, src, image->Width );
+ src += image->Width;
+ }
+ }
+ break;
+
+ case 2:
+ {
+ GLushort *dst = (GLushort *)(t->BufAddr + t->image[hwlevel].offset);
+ GLushort *src = (GLushort *)image->Data;
+
+ for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) {
+ __memcpy(dst, src, image->Width * 2 );
+ src += image->Width;
+ }
+ }
+ break;
+
+ default:
+ fprintf(stderr, "%s: Not supported texel size %d\n",
+ __FUNCTION__, image->TexFormat->TexelBytes);
+ }
+}
+
+/* This is called with the lock held. May have to eject our own and/or
+ * other client's texture objects to make room for the upload.
+ */
+int i810UploadTexImagesLocked( i810ContextPtr imesa, i810TextureObjectPtr t )
+{
+ int i;
+ int ofs;
+ int numLevels;
+
+ /* Do we need to eject LRU texture objects?
+ */
+ if (!t->base.memBlock) {
+ int heap;
+
+ heap = driAllocateTexture( imesa->texture_heaps, imesa->nr_heaps,
+ (driTextureObject *) t);
+
+ if ( heap == -1 ) {
+ return -1;
+ }
+
+ ofs = t->base.memBlock->ofs;
+ t->BufAddr = imesa->i810Screen->tex.map + ofs;
+ t->Setup[I810_TEXREG_MI3] = imesa->i810Screen->textureOffset + ofs;
+
+ if (t == imesa->CurrentTexObj[0])
+ I810_STATECHANGE(imesa, I810_UPLOAD_TEX0);
+
+ if (t == imesa->CurrentTexObj[1])
+ I810_STATECHANGE(imesa, I810_UPLOAD_TEX1);
+
+ /* i810UpdateTexLRU( imesa, t );*/
+ }
+ driUpdateTextureLRU( (driTextureObject *) t );
+
+ if (imesa->texture_heaps[0]->timestamp >= GET_DISPATCH_AGE(imesa))
+ i810WaitAgeLocked( imesa, imesa->texture_heaps[0]->timestamp );
+
+ numLevels = t->base.lastLevel - t->base.firstLevel + 1;
+ for (i = 0 ; i < numLevels ; i++)
+ if (t->base.dirty_images[0] & (1<<i))
+ i810UploadTexLevel( imesa, t, i );
+
+ t->base.dirty_images[0] = 0;
+
+ return 0;
+}
diff --git a/src/i810texstate.c b/src/i810texstate.c
new file mode 100644
index 0000000..558aef9
--- /dev/null
+++ b/src/i810texstate.c
@@ -0,0 +1,752 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "texformat.h"
+#include "simple_list.h"
+#include "enums.h"
+
+#include "mm.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810tex.h"
+#include "i810state.h"
+#include "i810ioctl.h"
+
+
+
+
+static void i810SetTexImages( i810ContextPtr imesa,
+ struct gl_texture_object *tObj )
+{
+ GLuint height, width, pitch, i, textureFormat, log_pitch;
+ i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData;
+ const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
+ GLint numLevels;
+ GLint log2Width, log2Height;
+
+/* fprintf(stderr, "%s\n", __FUNCTION__); */
+
+ t->texelBytes = 2;
+ switch (baseImage->TexFormat->MesaFormat) {
+ case MESA_FORMAT_ARGB1555:
+ textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_ARGB1555;
+ break;
+ case MESA_FORMAT_ARGB4444:
+ textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_ARGB4444;
+ break;
+ case MESA_FORMAT_RGB565:
+ textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_RGB565;
+ break;
+ case MESA_FORMAT_AL88:
+ textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_AY88;
+ break;
+ case MESA_FORMAT_YCBCR:
+ textureFormat = MI1_FMT_422 | MI1_PF_422_YCRCB_SWAP_Y
+ | MI1_COLOR_CONV_ENABLE;
+ break;
+ case MESA_FORMAT_YCBCR_REV:
+ textureFormat = MI1_FMT_422 | MI1_PF_422_YCRCB
+ | MI1_COLOR_CONV_ENABLE;
+ break;
+ case MESA_FORMAT_CI8:
+ textureFormat = MI1_FMT_8CI | MI1_PF_8CI_ARGB4444;
+ t->texelBytes = 1;
+ break;
+
+ default:
+ fprintf(stderr, "i810SetTexImages: bad image->Format\n" );
+ return;
+ }
+
+ driCalculateTextureFirstLastLevel( (driTextureObject *) t );
+
+ numLevels = t->base.lastLevel - t->base.firstLevel + 1;
+
+ log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
+ log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
+
+ /* Figure out the amount of memory required to hold all the mipmap
+ * levels. Choose the smallest pitch to accomodate the largest
+ * mipmap:
+ */
+ width = tObj->Image[0][t->base.firstLevel]->Width * t->texelBytes;
+ for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 )
+ log_pitch++;
+
+ /* All images must be loaded at this pitch. Count the number of
+ * lines required:
+ */
+ for ( height = i = 0 ; i < numLevels ; i++ ) {
+ t->image[i].image = tObj->Image[0][t->base.firstLevel + i];
+ t->image[i].offset = height * pitch;
+ t->image[i].internalFormat = baseImage->_BaseFormat;
+ height += t->image[i].image->Height;
+ }
+
+ t->Pitch = pitch;
+ t->base.totalSize = height*pitch;
+ t->max_level = i-1;
+ t->dirty = I810_UPLOAD_TEX0 | I810_UPLOAD_TEX1;
+ t->Setup[I810_TEXREG_MI1] = (MI1_MAP_0 | textureFormat | log_pitch);
+ t->Setup[I810_TEXREG_MLL] = (GFX_OP_MAP_LOD_LIMITS |
+ MLL_MAP_0 |
+ MLL_UPDATE_MAX_MIP |
+ MLL_UPDATE_MIN_MIP |
+ ((numLevels - 1) << MLL_MIN_MIP_SHIFT));
+
+ LOCK_HARDWARE( imesa );
+ i810UploadTexImagesLocked( imesa, t );
+ UNLOCK_HARDWARE( imesa );
+}
+
+/* ================================================================
+ * Texture combine functions
+ */
+
+
+static void set_color_stage( unsigned color, int stage,
+ i810ContextPtr imesa )
+{
+ if ( color != imesa->Setup[I810_CTXREG_MC0 + stage] ) {
+ I810_STATECHANGE( imesa, I810_UPLOAD_CTX );
+ imesa->Setup[I810_CTXREG_MC0 + stage] = color;
+ }
+}
+
+
+static void set_alpha_stage( unsigned alpha, int stage,
+ i810ContextPtr imesa )
+{
+ if ( alpha != imesa->Setup[I810_CTXREG_MA0 + stage] ) {
+ I810_STATECHANGE( imesa, I810_UPLOAD_CTX );
+ imesa->Setup[I810_CTXREG_MA0 + stage] = alpha;
+ }
+}
+
+
+static const unsigned operand_modifiers[] = {
+ 0, MC_ARG_INVERT,
+ MC_ARG_REPLICATE_ALPHA, MC_ARG_INVERT | MC_ARG_REPLICATE_ALPHA
+};
+
+/**
+ * Configure the hardware bits for the specified texture environment.
+ *
+ * Configures the hardware bits for the texture environment state for the
+ * specified texture unit. As combine stages are added, the values pointed
+ * to by \c color_stage and \c alpha_stage are incremented.
+ *
+ * \param ctx GL context pointer.
+ * \param unit Texture unit to be added.
+ * \param color_stage Next available hardware color combine stage.
+ * \param alpha_stage Next available hardware alpha combine stage.
+ *
+ * \returns
+ * If the combine mode for the specified texture unit could be added without
+ * requiring a software fallback, \c GL_TRUE is returned. Otherwise,
+ * \c GL_FALSE is returned.
+ *
+ * \todo
+ * If the mode is (GL_REPLACE, GL_PREVIOUS), treat it as though the texture
+ * stage is disabled. That is, don't emit any combine stages.
+ *
+ * \todo
+ * Add support for ATI_texture_env_combine3 modes. This will require using
+ * two combine stages.
+ *
+ * \todo
+ * Add support for the missing \c GL_INTERPOLATE modes. This will require
+ * using all three combine stages. There is a comment in the function
+ * describing how this might work.
+ *
+ * \todo
+ * If, after all the combine stages have been emitted, a texture is never
+ * actually used, disable the texture unit. That should save texture some
+ * memory bandwidth. This won't happen in this function, but this seems like
+ * a reasonable place to make note of it.
+ */
+static GLboolean
+i810UpdateTexEnvCombine( GLcontext *ctx, GLuint unit,
+ int * color_stage, int * alpha_stage )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ GLuint color_arg[3] = {
+ MC_ARG_ONE, MC_ARG_ONE, MC_ARG_ONE
+ };
+ GLuint alpha_arg[3] = {
+ MA_ARG_ITERATED_ALPHA, MA_ARG_ITERATED_ALPHA, MA_ARG_ITERATED_ALPHA
+ };
+ GLuint i;
+ GLuint color_combine, alpha_combine;
+ const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
+ const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
+ GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
+ GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
+
+
+ if ( !texUnit->_ReallyEnabled ) {
+ return GL_TRUE;
+ }
+
+
+ if ((*color_stage >= 3) || (*alpha_stage >= 3)) {
+ return GL_FALSE;
+ }
+
+
+ /* Step 1:
+ * Extract the color and alpha combine function arguments.
+ */
+
+ for ( i = 0 ; i < numColorArgs ; i++ ) {
+ unsigned op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;
+ assert(op >= 0);
+ assert(op <= 3);
+ switch ( texUnit->_CurrentCombine->SourceRGB[i] ) {
+ case GL_TEXTURE0:
+ color_arg[i] = MC_ARG_TEX0_COLOR;
+ break;
+ case GL_TEXTURE1:
+ color_arg[i] = MC_ARG_TEX1_COLOR;
+ break;
+ case GL_TEXTURE:
+ color_arg[i] = (unit == 0)
+ ? MC_ARG_TEX0_COLOR : MC_ARG_TEX1_COLOR;
+ break;
+ case GL_CONSTANT:
+ color_arg[i] = MC_ARG_COLOR_FACTOR;
+ break;
+ case GL_PRIMARY_COLOR:
+ color_arg[i] = MC_ARG_ITERATED_COLOR;
+ break;
+ case GL_PREVIOUS:
+ color_arg[i] = (unit == 0)
+ ? MC_ARG_ITERATED_COLOR : MC_ARG_CURRENT_COLOR;
+ break;
+ case GL_ZERO:
+ /* Toggle the low bit of the op value. The is the 'invert' bit,
+ * and it acts to convert GL_ZERO+op to the equivalent GL_ONE+op.
+ */
+ op ^= 1;
+
+ /*FALLTHROUGH*/
+
+ case GL_ONE:
+ color_arg[i] = MC_ARG_ONE;
+ break;
+ default:
+ return GL_FALSE;
+ }
+
+ color_arg[i] |= operand_modifiers[op];
+ }
+
+
+ for ( i = 0 ; i < numAlphaArgs ; i++ ) {
+ unsigned op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;
+ assert(op >= 0);
+ assert(op <= 1);
+ switch ( texUnit->_CurrentCombine->SourceA[i] ) {
+ case GL_TEXTURE0:
+ alpha_arg[i] = MA_ARG_TEX0_ALPHA;
+ break;
+ case GL_TEXTURE1:
+ alpha_arg[i] = MA_ARG_TEX1_ALPHA;
+ break;
+ case GL_TEXTURE:
+ alpha_arg[i] = (unit == 0)
+ ? MA_ARG_TEX0_ALPHA : MA_ARG_TEX1_ALPHA;
+ break;
+ case GL_CONSTANT:
+ alpha_arg[i] = MA_ARG_ALPHA_FACTOR;
+ break;
+ case GL_PRIMARY_COLOR:
+ alpha_arg[i] = MA_ARG_ITERATED_ALPHA;
+ break;
+ case GL_PREVIOUS:
+ alpha_arg[i] = (unit == 0)
+ ? MA_ARG_ITERATED_ALPHA : MA_ARG_CURRENT_ALPHA;
+ break;
+ case GL_ZERO:
+ /* Toggle the low bit of the op value. The is the 'invert' bit,
+ * and it acts to convert GL_ZERO+op to the equivalent GL_ONE+op.
+ */
+ op ^= 1;
+
+ /*FALLTHROUGH*/
+
+ case GL_ONE:
+ if (i != 2) {
+ return GL_FALSE;
+ }
+
+ alpha_arg[i] = MA_ARG_ONE;
+ break;
+ default:
+ return GL_FALSE;
+ }
+
+ alpha_arg[i] |= operand_modifiers[op];
+ }
+
+
+ /* Step 2:
+ * Build up the color and alpha combine functions.
+ */
+ switch ( texUnit->_CurrentCombine->ModeRGB ) {
+ case GL_REPLACE:
+ color_combine = MC_OP_ARG1;
+ break;
+ case GL_MODULATE:
+ color_combine = MC_OP_MODULATE + RGBshift;
+ RGBshift = 0;
+ break;
+ case GL_ADD:
+ color_combine = MC_OP_ADD;
+ break;
+ case GL_ADD_SIGNED:
+ color_combine = MC_OP_ADD_SIGNED;
+ break;
+ case GL_SUBTRACT:
+ color_combine = MC_OP_SUBTRACT;
+ break;
+ case GL_INTERPOLATE:
+ /* For interpolation, the i810 hardware has some limitations. It
+ * can't handle using the secondary or diffuse color (diffuse alpha
+ * is okay) for the third argument.
+ *
+ * It is possible to emulate the missing modes by using multiple
+ * combine stages. Unfortunately it requires all three stages to
+ * emulate a single interpolate stage. The (arg0*arg2) portion is
+ * done in stage zero and writes to MC_DEST_ACCUMULATOR. The
+ * (arg1*(1-arg2)) portion is done in stage 1, and the final stage is
+ * (MC_ARG1_ACCUMULATOR | MC_ARG2_CURRENT_COLOR | MC_OP_ADD).
+ *
+ * It can also be done without using the accumulator by rearranging
+ * the equation as (arg1 + (arg2 * (arg0 - arg1))). Too bad the i810
+ * doesn't support the MODULATE_AND_ADD mode that the i830 supports.
+ * If it did, the interpolate could be done in only two stages.
+ */
+
+ if ( (color_arg[2] & MC_ARG_INVERT) != 0 ) {
+ unsigned temp = color_arg[0];
+
+ color_arg[0] = color_arg[1];
+ color_arg[1] = temp;
+ color_arg[2] &= ~MC_ARG_INVERT;
+ }
+
+ switch (color_arg[2]) {
+ case (MC_ARG_ONE):
+ case (MC_ARG_ONE | MC_ARG_REPLICATE_ALPHA):
+ color_combine = MC_OP_ARG1;
+ color_arg[1] = MC_ARG_ONE;
+ break;
+
+ case (MC_ARG_COLOR_FACTOR):
+ return GL_FALSE;
+
+ case (MC_ARG_COLOR_FACTOR | MC_ARG_REPLICATE_ALPHA):
+ color_combine = MC_OP_LIN_BLEND_ALPHA_FACTOR;
+ break;
+
+ case (MC_ARG_ITERATED_COLOR):
+ return GL_FALSE;
+
+ case (MC_ARG_ITERATED_COLOR | MC_ARG_REPLICATE_ALPHA):
+ color_combine = MC_OP_LIN_BLEND_ITER_ALPHA;
+ break;
+
+ case (MC_ARG_SPECULAR_COLOR):
+ case (MC_ARG_SPECULAR_COLOR | MC_ARG_REPLICATE_ALPHA):
+ return GL_FALSE;
+
+ case (MC_ARG_TEX0_COLOR):
+ color_combine = MC_OP_LIN_BLEND_TEX0_COLOR;
+ break;
+
+ case (MC_ARG_TEX0_COLOR | MC_ARG_REPLICATE_ALPHA):
+ color_combine = MC_OP_LIN_BLEND_TEX0_ALPHA;
+ break;
+
+ case (MC_ARG_TEX1_COLOR):
+ color_combine = MC_OP_LIN_BLEND_TEX1_COLOR;
+ break;
+
+ case (MC_ARG_TEX1_COLOR | MC_ARG_REPLICATE_ALPHA):
+ color_combine = MC_OP_LIN_BLEND_TEX1_ALPHA;
+ break;
+
+ default:
+ return GL_FALSE;
+ }
+ break;
+
+ default:
+ return GL_FALSE;
+ }
+
+
+ switch ( texUnit->_CurrentCombine->ModeA ) {
+ case GL_REPLACE:
+ alpha_combine = MA_OP_ARG1;
+ break;
+ case GL_MODULATE:
+ alpha_combine = MA_OP_MODULATE + Ashift;
+ Ashift = 0;
+ break;
+ case GL_ADD:
+ alpha_combine = MA_OP_ADD;
+ break;
+ case GL_ADD_SIGNED:
+ alpha_combine = MA_OP_ADD_SIGNED;
+ break;
+ case GL_SUBTRACT:
+ alpha_combine = MA_OP_SUBTRACT;
+ break;
+ case GL_INTERPOLATE:
+ if ( (alpha_arg[2] & MA_ARG_INVERT) != 0 ) {
+ unsigned temp = alpha_arg[0];
+
+ alpha_arg[0] = alpha_arg[1];
+ alpha_arg[1] = temp;
+ alpha_arg[2] &= ~MA_ARG_INVERT;
+ }
+
+ switch (alpha_arg[2]) {
+ case MA_ARG_ONE:
+ alpha_combine = MA_OP_ARG1;
+ alpha_arg[1] = MA_ARG_ITERATED_ALPHA;
+ break;
+
+ case MA_ARG_ALPHA_FACTOR:
+ alpha_combine = MA_OP_LIN_BLEND_ALPHA_FACTOR;
+ break;
+
+ case MA_ARG_ITERATED_ALPHA:
+ alpha_combine = MA_OP_LIN_BLEND_ITER_ALPHA;
+ break;
+
+ case MA_ARG_TEX0_ALPHA:
+ alpha_combine = MA_OP_LIN_BLEND_TEX0_ALPHA;
+ break;
+
+ case MA_ARG_TEX1_ALPHA:
+ alpha_combine = MA_OP_LIN_BLEND_TEX1_ALPHA;
+ break;
+
+ default:
+ return GL_FALSE;
+ }
+ break;
+
+ default:
+ return GL_FALSE;
+ }
+
+
+ color_combine |= GFX_OP_MAP_COLOR_STAGES | (*color_stage << MC_STAGE_SHIFT)
+ | MC_UPDATE_DEST | MC_DEST_CURRENT
+ | MC_UPDATE_ARG1 | (color_arg[0] << MC_ARG1_SHIFT)
+ | MC_UPDATE_ARG2 | (color_arg[1] << MC_ARG2_SHIFT)
+ | MC_UPDATE_OP;
+
+ alpha_combine |= GFX_OP_MAP_ALPHA_STAGES | (*alpha_stage << MA_STAGE_SHIFT)
+ | MA_UPDATE_ARG1 | (alpha_arg[0] << MA_ARG1_SHIFT)
+ | MA_UPDATE_ARG2 | (alpha_arg[1] << MA_ARG2_SHIFT)
+ | MA_UPDATE_OP;
+
+ set_color_stage( color_combine, *color_stage, imesa );
+ set_alpha_stage( alpha_combine, *alpha_stage, imesa );
+ (*color_stage)++;
+ (*alpha_stage)++;
+
+
+ /* Step 3:
+ * Apply the scale factor.
+ */
+ /* The only operation where the i810 directly supports adding a post-
+ * scale factor is modulate. For all the other modes the post-scale is
+ * emulated by inserting and extra modulate stage. For the modulate
+ * case, the scaling is handled above when color_combine / alpha_combine
+ * are initially set.
+ */
+
+ if ( RGBshift != 0 ) {
+ const unsigned color_scale = GFX_OP_MAP_COLOR_STAGES
+ | (*color_stage << MC_STAGE_SHIFT)
+ | MC_UPDATE_DEST | MC_DEST_CURRENT
+ | MC_UPDATE_ARG1 | (MC_ARG_CURRENT_COLOR << MC_ARG1_SHIFT)
+ | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT)
+ | MC_UPDATE_OP | (MC_OP_MODULATE + RGBshift);
+
+ if ( *color_stage >= 3 ) {
+ return GL_FALSE;
+ }
+
+ set_color_stage( color_scale, *color_stage, imesa );
+ (*color_stage)++;
+ }
+
+
+ if ( Ashift != 0 ) {
+ const unsigned alpha_scale = GFX_OP_MAP_ALPHA_STAGES
+ | (*alpha_stage << MA_STAGE_SHIFT)
+ | MA_UPDATE_ARG1 | (MA_ARG_CURRENT_ALPHA << MA_ARG1_SHIFT)
+ | MA_UPDATE_ARG2 | (MA_ARG_ONE << MA_ARG2_SHIFT)
+ | MA_UPDATE_OP | (MA_OP_MODULATE + Ashift);
+
+ if ( *alpha_stage >= 3 ) {
+ return GL_FALSE;
+ }
+
+ set_alpha_stage( alpha_scale, *alpha_stage, imesa );
+ (*alpha_stage)++;
+ }
+
+ return GL_TRUE;
+}
+
+static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *tObj = texUnit->_Current;
+ i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
+
+ if (tObj->Image[0][tObj->BaseLevel]->Border > 0) {
+ return GL_FALSE;
+ }
+
+ /* Upload teximages (not pipelined)
+ */
+ if (t->base.dirty_images[0]) {
+ I810_FIREVERTICES(imesa);
+ i810SetTexImages( imesa, tObj );
+ if (!t->base.memBlock) {
+ return GL_FALSE;
+ }
+ }
+
+ /* Update state if this is a different texture object to last
+ * time.
+ */
+ if (imesa->CurrentTexObj[unit] != t) {
+ I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<<unit));
+ imesa->CurrentTexObj[unit] = t;
+ t->base.bound |= (1U << unit);
+
+ /* XXX: should be locked */
+ driUpdateTextureLRU( (driTextureObject *) t );
+ }
+
+ imesa->TexEnvImageFmt[unit] = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
+ return GL_TRUE;
+}
+
+static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *tObj = texUnit->_Current;
+ i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
+ GLint Width, Height;
+
+ Width = tObj->Image[0][t->base.firstLevel]->Width - 1;
+ Height = tObj->Image[0][t->base.firstLevel]->Height - 1;
+
+ I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<<unit));
+ t->Setup[I810_TEXREG_MCS] &= ~MCS_NORMALIZED_COORDS;
+ t->Setup[I810_TEXREG_MCS] |= MCS_UPDATE_NORMALIZED;
+ t->Setup[I810_TEXREG_MI2] = (MI2_DIMENSIONS_ARE_EXACT |
+ (Height << MI2_HEIGHT_SHIFT) | Width);
+
+ return GL_TRUE;
+}
+
+static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *tObj = texUnit->_Current;
+ i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
+ GLint log2Width, log2Height;
+
+
+ log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
+ log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
+
+ I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<<unit));
+ t->Setup[I810_TEXREG_MCS] |= MCS_NORMALIZED_COORDS | MCS_UPDATE_NORMALIZED;
+ t->Setup[I810_TEXREG_MI2] = (MI2_DIMENSIONS_ARE_LOG2 |
+ (log2Height << MI2_HEIGHT_SHIFT) | log2Width);
+
+ return GL_TRUE;
+}
+
+static void disable_tex( GLcontext *ctx, GLuint unit )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ imesa->CurrentTexObj[unit] = 0;
+ imesa->TexEnvImageFmt[unit] = 0;
+ imesa->dirty &= ~(I810_UPLOAD_TEX0<<unit);
+
+}
+
+/**
+ * Update hardware state for a texture unit.
+ *
+ * \todo
+ * 1D textures should be supported! Just use a 2D texture with the second
+ * texture coordinate value fixed at 0.0.
+ */
+static void i810UpdateTexUnit( GLcontext *ctx, GLuint unit,
+ int * next_color_stage, int * next_alpha_stage )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ GLboolean ret;
+
+ switch(texUnit->_ReallyEnabled) {
+ case TEXTURE_2D_BIT:
+ ret = enable_tex_common( ctx, unit);
+ ret &= enable_tex_2d(ctx, unit);
+ if (ret == GL_FALSE) {
+ FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
+ }
+ break;
+ case TEXTURE_RECT_BIT:
+ ret = enable_tex_common( ctx, unit);
+ ret &= enable_tex_rect(ctx, unit);
+ if (ret == GL_FALSE) {
+ FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
+ }
+ break;
+ case 0:
+ disable_tex(ctx, unit);
+ break;
+ }
+
+
+ if (!i810UpdateTexEnvCombine( ctx, unit,
+ next_color_stage, next_alpha_stage )) {
+ FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
+ }
+
+ return;
+}
+
+
+void i810UpdateTextureState( GLcontext *ctx )
+{
+ static const unsigned color_pass[3] = {
+ GFX_OP_MAP_COLOR_STAGES | MC_STAGE_0 | MC_UPDATE_DEST | MC_DEST_CURRENT
+ | MC_UPDATE_ARG1 | (MC_ARG_ITERATED_COLOR << MC_ARG1_SHIFT)
+ | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT)
+ | MC_UPDATE_OP | MC_OP_ARG1,
+ GFX_OP_MAP_COLOR_STAGES | MC_STAGE_1 | MC_UPDATE_DEST | MC_DEST_CURRENT
+ | MC_UPDATE_ARG1 | (MC_ARG_CURRENT_COLOR << MC_ARG1_SHIFT)
+ | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT)
+ | MC_UPDATE_OP | MC_OP_ARG1,
+ GFX_OP_MAP_COLOR_STAGES | MC_STAGE_2 | MC_UPDATE_DEST | MC_DEST_CURRENT
+ | MC_UPDATE_ARG1 | (MC_ARG_CURRENT_COLOR << MC_ARG1_SHIFT)
+ | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT)
+ | MC_UPDATE_OP | MC_OP_ARG1
+ };
+ static const unsigned alpha_pass[3] = {
+ GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_0
+ | MA_UPDATE_ARG1 | (MA_ARG_ITERATED_ALPHA << MA_ARG1_SHIFT)
+ | MA_UPDATE_ARG2 | (MA_ARG_ITERATED_ALPHA << MA_ARG2_SHIFT)
+ | MA_UPDATE_OP | MA_OP_ARG1,
+ GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_1
+ | MA_UPDATE_ARG1 | (MA_ARG_CURRENT_ALPHA << MA_ARG1_SHIFT)
+ | MA_UPDATE_ARG2 | (MA_ARG_CURRENT_ALPHA << MA_ARG2_SHIFT)
+ | MA_UPDATE_OP | MA_OP_ARG1,
+ GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_2
+ | MA_UPDATE_ARG1 | (MA_ARG_CURRENT_ALPHA << MA_ARG1_SHIFT)
+ | MA_UPDATE_ARG2 | (MA_ARG_CURRENT_ALPHA << MA_ARG2_SHIFT)
+ | MA_UPDATE_OP | MA_OP_ARG1
+ };
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ int next_color_stage = 0;
+ int next_alpha_stage = 0;
+
+
+ /* fprintf(stderr, "%s\n", __FUNCTION__); */
+ FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_FALSE );
+
+ i810UpdateTexUnit( ctx, 0, & next_color_stage, & next_alpha_stage );
+ i810UpdateTexUnit( ctx, 1, & next_color_stage, & next_alpha_stage );
+
+ /* There needs to be at least one combine stage emitted that just moves
+ * the incoming primary color to the current color register. In addition,
+ * there number be the same number of color and alpha stages emitted.
+ * Finally, if there are less than 3 combine stages, a MC_OP_DISABLE stage
+ * must be emitted.
+ */
+
+ while ( (next_color_stage == 0) ||
+ (next_color_stage < next_alpha_stage) ) {
+ set_color_stage( color_pass[ next_color_stage ], next_color_stage,
+ imesa );
+ next_color_stage++;
+ }
+
+ assert( next_color_stage <= 3 );
+
+ while ( next_alpha_stage < next_color_stage ) {
+ set_alpha_stage( alpha_pass[ next_alpha_stage ], next_alpha_stage,
+ imesa );
+ next_alpha_stage++;
+ }
+
+ assert( next_alpha_stage <= 3 );
+ assert( next_color_stage == next_alpha_stage );
+
+ if ( next_color_stage < 3 ) {
+ const unsigned color = GFX_OP_MAP_COLOR_STAGES
+ | (next_color_stage << MC_STAGE_SHIFT)
+ | MC_UPDATE_DEST | MC_DEST_CURRENT
+ | MC_UPDATE_ARG1 | (MC_ARG_ONE << MC_ARG1_SHIFT)
+ | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT)
+ | MC_UPDATE_OP | (MC_OP_DISABLE);
+
+ const unsigned alpha = GFX_OP_MAP_ALPHA_STAGES
+ | (next_color_stage << MC_STAGE_SHIFT)
+ | MA_UPDATE_ARG1 | (MA_ARG_CURRENT_ALPHA << MA_ARG1_SHIFT)
+ | MA_UPDATE_ARG2 | (MA_ARG_CURRENT_ALPHA << MA_ARG2_SHIFT)
+ | MA_UPDATE_OP | (MA_OP_ARG1);
+
+ set_color_stage( color, next_color_stage, imesa );
+ set_alpha_stage( alpha, next_alpha_stage, imesa );
+ }
+}
diff --git a/src/i810tris.c b/src/i810tris.c
new file mode 100644
index 0000000..3e09427
--- /dev/null
+++ b/src/i810tris.c
@@ -0,0 +1,871 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.c,v 1.7 2002/10/30 12:51:33 alanh Exp $ */
+/**************************************************************************
+
+Copyright 2001 VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "enums.h"
+#include "colormac.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810tris.h"
+#include "i810state.h"
+#include "i810vb.h"
+#include "i810ioctl.h"
+
+static void i810RenderPrimitive( GLcontext *ctx, GLenum prim );
+
+/***********************************************************************
+ * Emit primitives as inline vertices *
+ ***********************************************************************/
+
+#if defined(USE_X86_ASM)
+#define COPY_DWORDS( j, vb, vertsize, v ) \
+do { \
+ int __tmp; \
+ __asm__ __volatile__( "rep ; movsl" \
+ : "=%c" (j), "=D" (vb), "=S" (__tmp) \
+ : "0" (vertsize), \
+ "D" ((long)vb), \
+ "S" ((long)v) ); \
+} while (0)
+#else
+#define COPY_DWORDS( j, vb, vertsize, v ) \
+do { \
+ for ( j = 0 ; j < vertsize ; j++ ) \
+ vb[j] = ((GLuint *)v)[j]; \
+ vb += vertsize; \
+} while (0)
+#endif
+
+static __inline__ void i810_draw_triangle( i810ContextPtr imesa,
+ i810VertexPtr v0,
+ i810VertexPtr v1,
+ i810VertexPtr v2 )
+{
+ GLuint vertsize = imesa->vertex_size;
+ GLuint *vb = i810AllocDmaLow( imesa, 3 * 4 * vertsize );
+ int j;
+
+ COPY_DWORDS( j, vb, vertsize, v0 );
+ COPY_DWORDS( j, vb, vertsize, v1 );
+ COPY_DWORDS( j, vb, vertsize, v2 );
+}
+
+
+static __inline__ void i810_draw_quad( i810ContextPtr imesa,
+ i810VertexPtr v0,
+ i810VertexPtr v1,
+ i810VertexPtr v2,
+ i810VertexPtr v3 )
+{
+ GLuint vertsize = imesa->vertex_size;
+ GLuint *vb = i810AllocDmaLow( imesa, 6 * 4 * vertsize );
+ int j;
+
+ COPY_DWORDS( j, vb, vertsize, v0 );
+ COPY_DWORDS( j, vb, vertsize, v1 );
+ COPY_DWORDS( j, vb, vertsize, v3 );
+ COPY_DWORDS( j, vb, vertsize, v1 );
+ COPY_DWORDS( j, vb, vertsize, v2 );
+ COPY_DWORDS( j, vb, vertsize, v3 );
+}
+
+
+static __inline__ void i810_draw_point( i810ContextPtr imesa,
+ i810VertexPtr tmp )
+{
+ GLfloat sz = imesa->glCtx->Point._Size * .5;
+ int vertsize = imesa->vertex_size;
+ GLuint *vb = i810AllocDmaLow( imesa, 2 * 4 * vertsize );
+ int j;
+
+ /* Draw a point as a horizontal line.
+ */
+ *(float *)&vb[0] = tmp->v.x - sz + 0.125;
+ for (j = 1 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp->v.x + sz + 0.125;
+ for (j = 1 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
+ vb += vertsize;
+}
+
+
+static __inline__ void i810_draw_line( i810ContextPtr imesa,
+ i810VertexPtr v0,
+ i810VertexPtr v1 )
+{
+ GLuint vertsize = imesa->vertex_size;
+ GLuint *vb = i810AllocDmaLow( imesa, 2 * 4 * vertsize );
+ int j;
+
+ COPY_DWORDS( j, vb, vertsize, v0 );
+ COPY_DWORDS( j, vb, vertsize, v1 );
+}
+
+
+
+/***********************************************************************
+ * Macros for t_dd_tritmp.h to draw basic primitives *
+ ***********************************************************************/
+
+#define TRI( a, b, c ) \
+do { \
+ if (0) fprintf(stderr, "hw TRI\n"); \
+ if (DO_FALLBACK) \
+ imesa->draw_tri( imesa, a, b, c ); \
+ else \
+ i810_draw_triangle( imesa, a, b, c ); \
+} while (0)
+
+#define QUAD( a, b, c, d ) \
+do { \
+ if (0) fprintf(stderr, "hw QUAD\n"); \
+ if (DO_FALLBACK) { \
+ imesa->draw_tri( imesa, a, b, d ); \
+ imesa->draw_tri( imesa, b, c, d ); \
+ } else \
+ i810_draw_quad( imesa, a, b, c, d ); \
+} while (0)
+
+#define LINE( v0, v1 ) \
+do { \
+ if (0) fprintf(stderr, "hw LINE\n"); \
+ if (DO_FALLBACK) \
+ imesa->draw_line( imesa, v0, v1 ); \
+ else \
+ i810_draw_line( imesa, v0, v1 ); \
+} while (0)
+
+#define POINT( v0 ) \
+do { \
+ if (0) fprintf(stderr, "hw POINT\n"); \
+ if (DO_FALLBACK) \
+ imesa->draw_point( imesa, v0 ); \
+ else \
+ i810_draw_point( imesa, v0 ); \
+} while (0)
+
+
+/***********************************************************************
+ * Build render functions from dd templates *
+ ***********************************************************************/
+
+#define I810_OFFSET_BIT 0x01
+#define I810_TWOSIDE_BIT 0x02
+#define I810_UNFILLED_BIT 0x04
+#define I810_FALLBACK_BIT 0x08
+#define I810_MAX_TRIFUNC 0x10
+
+
+static struct {
+ tnl_points_func points;
+ tnl_line_func line;
+ tnl_triangle_func triangle;
+ tnl_quad_func quad;
+} rast_tab[I810_MAX_TRIFUNC];
+
+
+#define DO_FALLBACK (IND & I810_FALLBACK_BIT)
+#define DO_OFFSET (IND & I810_OFFSET_BIT)
+#define DO_UNFILLED (IND & I810_UNFILLED_BIT)
+#define DO_TWOSIDE (IND & I810_TWOSIDE_BIT)
+#define DO_FLAT 0
+#define DO_TRI 1
+#define DO_QUAD 1
+#define DO_LINE 1
+#define DO_POINTS 1
+#define DO_FULL_QUAD 1
+
+#define HAVE_RGBA 1
+#define HAVE_SPEC 1
+#define HAVE_BACK_COLORS 0
+#define HAVE_HW_FLATSHADE 1
+#define VERTEX i810Vertex
+#define TAB rast_tab
+
+
+#define DEPTH_SCALE (1.0/0xffff)
+#define UNFILLED_TRI unfilled_tri
+#define UNFILLED_QUAD unfilled_quad
+#define VERT_X(_v) _v->v.x
+#define VERT_Y(_v) _v->v.y
+#define VERT_Z(_v) _v->v.z
+#define AREA_IS_CCW( a ) (a > 0)
+#define GET_VERTEX(e) (imesa->verts + (e * imesa->vertex_size * sizeof(int)))
+
+#define VERT_SET_RGBA( v, c ) \
+do { \
+ i810_color_t *color = (i810_color_t *)&((v)->ui[coloroffset]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
+} while (0)
+
+#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
+
+#define VERT_SET_SPEC( v0, c ) \
+do { \
+ if (havespec) { \
+ UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
+ UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
+ } \
+} while (0)
+#define VERT_COPY_SPEC( v0, v1 ) \
+do { \
+ if (havespec) { \
+ v0->v.specular.red = v1->v.specular.red; \
+ v0->v.specular.green = v1->v.specular.green; \
+ v0->v.specular.blue = v1->v.specular.blue; \
+ } \
+} while (0)
+
+#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
+#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
+#define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5]
+#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
+
+#define LOCAL_VARS(n) \
+ i810ContextPtr imesa = I810_CONTEXT(ctx); \
+ GLuint color[n], spec[n]; \
+ GLuint coloroffset = (imesa->vertex_size == 4 ? 3 : 4); \
+ GLboolean havespec = (imesa->vertex_size > 4); \
+ (void) color; (void) spec; (void) coloroffset; (void) havespec;
+
+
+/***********************************************************************
+ * Helpers for rendering unfilled primitives *
+ ***********************************************************************/
+
+static const GLuint hw_prim[GL_POLYGON+1] = {
+ PR_LINES,
+ PR_LINES,
+ PR_LINES,
+ PR_LINES,
+ PR_TRIANGLES,
+ PR_TRIANGLES,
+ PR_TRIANGLES,
+ PR_TRIANGLES,
+ PR_TRIANGLES,
+ PR_TRIANGLES
+};
+
+#define RASTERIZE(x) if (imesa->hw_primitive != hw_prim[x]) \
+ i810RasterPrimitive( ctx, x, hw_prim[x] )
+#define RENDER_PRIMITIVE imesa->render_primitive
+#define TAG(x) x
+#define IND I810_FALLBACK_BIT
+#include "tnl_dd/t_dd_unfilled.h"
+#undef IND
+
+/***********************************************************************
+ * Generate GL render functions *
+ ***********************************************************************/
+
+#define IND (0)
+#define TAG(x) x
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_UNFILLED_BIT)
+#define TAG(x) x##_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_OFFSET_BIT|I810_UNFILLED_BIT)
+#define TAG(x) x##_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_UNFILLED_BIT)
+#define TAG(x) x##_twoside_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_FALLBACK_BIT)
+#define TAG(x) x##_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_OFFSET_BIT|I810_FALLBACK_BIT)
+#define TAG(x) x##_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_FALLBACK_BIT)
+#define TAG(x) x##_twoside_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_UNFILLED_BIT|I810_FALLBACK_BIT)
+#define TAG(x) x##_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_OFFSET_BIT|I810_UNFILLED_BIT|I810_FALLBACK_BIT)
+#define TAG(x) x##_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_UNFILLED_BIT|I810_FALLBACK_BIT)
+#define TAG(x) x##_twoside_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_UNFILLED_BIT| \
+ I810_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+
+static void init_rast_tab( void )
+{
+ init();
+ init_offset();
+ init_twoside();
+ init_twoside_offset();
+ init_unfilled();
+ init_offset_unfilled();
+ init_twoside_unfilled();
+ init_twoside_offset_unfilled();
+ init_fallback();
+ init_offset_fallback();
+ init_twoside_fallback();
+ init_twoside_offset_fallback();
+ init_unfilled_fallback();
+ init_offset_unfilled_fallback();
+ init_twoside_unfilled_fallback();
+ init_twoside_offset_unfilled_fallback();
+}
+
+
+/***********************************************************************
+ * Rasterization fallback helpers *
+ ***********************************************************************/
+
+
+/* This code is hit only when a mix of accelerated and unaccelerated
+ * primitives are being drawn, and only for the unaccelerated
+ * primitives.
+ */
+static void
+i810_fallback_tri( i810ContextPtr imesa,
+ i810Vertex *v0,
+ i810Vertex *v1,
+ i810Vertex *v2 )
+{
+ GLcontext *ctx = imesa->glCtx;
+ SWvertex v[3];
+ i810_translate_vertex( ctx, v0, &v[0] );
+ i810_translate_vertex( ctx, v1, &v[1] );
+ i810_translate_vertex( ctx, v2, &v[2] );
+ _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
+}
+
+
+static void
+i810_fallback_line( i810ContextPtr imesa,
+ i810Vertex *v0,
+ i810Vertex *v1 )
+{
+ GLcontext *ctx = imesa->glCtx;
+ SWvertex v[2];
+ i810_translate_vertex( ctx, v0, &v[0] );
+ i810_translate_vertex( ctx, v1, &v[1] );
+ _swrast_Line( ctx, &v[0], &v[1] );
+}
+
+
+static void
+i810_fallback_point( i810ContextPtr imesa,
+ i810Vertex *v0 )
+{
+ GLcontext *ctx = imesa->glCtx;
+ SWvertex v[1];
+ i810_translate_vertex( ctx, v0, &v[0] );
+ _swrast_Point( ctx, &v[0] );
+}
+
+
+
+/**********************************************************************/
+/* Render unclipped begin/end objects */
+/**********************************************************************/
+
+#define IND 0
+#define V(x) (i810Vertex *)(vertptr + ((x)*vertsize*sizeof(int)))
+#define RENDER_POINTS( start, count ) \
+ for ( ; start < count ; start++) POINT( V(ELT(start)) );
+#define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) )
+#define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) )
+#define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) )
+#define INIT(x) i810RenderPrimitive( ctx, x )
+#undef LOCAL_VARS
+#define LOCAL_VARS \
+ i810ContextPtr imesa = I810_CONTEXT(ctx); \
+ GLubyte *vertptr = (GLubyte *)imesa->verts; \
+ const GLuint vertsize = imesa->vertex_size; \
+ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
+ (void) elt;
+#define RESET_STIPPLE
+#define RESET_OCCLUSION
+#define PRESERVE_VB_DEFS
+#define ELT(x) x
+#define TAG(x) i810_##x##_verts
+#include "tnl/t_vb_rendertmp.h"
+#undef ELT
+#undef TAG
+#define TAG(x) i810_##x##_elts
+#define ELT(x) elt[x]
+#include "tnl/t_vb_rendertmp.h"
+
+/**********************************************************************/
+/* Render clipped primitives */
+/**********************************************************************/
+
+
+
+static void i810RenderClippedPoly( GLcontext *ctx, const GLuint *elts,
+ GLuint n )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+ GLuint prim = imesa->render_primitive;
+
+ /* Render the new vertices as an unclipped polygon.
+ */
+ {
+ GLuint *tmp = VB->Elts;
+ VB->Elts = (GLuint *)elts;
+ tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n,
+ PRIM_BEGIN|PRIM_END );
+ VB->Elts = tmp;
+ }
+
+ /* Restore the render primitive
+ */
+ if (prim != GL_POLYGON)
+ tnl->Driver.Render.PrimitiveNotify( ctx, prim );
+}
+
+static void i810RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ tnl->Driver.Render.Line( ctx, ii, jj );
+}
+
+static void i810FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
+ GLuint n )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ GLuint vertsize = imesa->vertex_size;
+ GLuint *vb = i810AllocDmaLow( imesa, (n-2) * 3 * 4 * vertsize );
+ GLubyte *vertptr = (GLubyte *)imesa->verts;
+ const GLuint *start = (const GLuint *)V(elts[0]);
+ int i,j;
+
+ for (i = 2 ; i < n ; i++) {
+ COPY_DWORDS( j, vb, vertsize, V(elts[i-1]) );
+ COPY_DWORDS( j, vb, vertsize, V(elts[i]) );
+ COPY_DWORDS( j, vb, vertsize, start );
+ }
+}
+
+/**********************************************************************/
+/* Choose render functions */
+/**********************************************************************/
+
+/***********************************************************************
+ * Rasterization fallback helpers *
+ ***********************************************************************/
+
+
+
+#define _I810_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \
+ _DD_NEW_TRI_UNFILLED | \
+ _DD_NEW_TRI_LIGHT_TWOSIDE | \
+ _DD_NEW_TRI_OFFSET | \
+ _DD_NEW_TRI_STIPPLE | \
+ _NEW_POLYGONSTIPPLE)
+
+#define POINT_FALLBACK (0)
+#define LINE_FALLBACK (DD_LINE_STIPPLE)
+#define TRI_FALLBACK (0)
+#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\
+ DD_TRI_STIPPLE)
+#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
+
+static void i810ChooseRenderState(GLcontext *ctx)
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint flags = ctx->_TriangleCaps;
+ GLuint index = 0;
+
+ if (I810_DEBUG & DEBUG_STATE)
+ fprintf(stderr,"\n%s\n",__FUNCTION__);
+
+ if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) {
+ if (flags & ANY_RASTER_FLAGS) {
+ if (flags & DD_TRI_LIGHT_TWOSIDE) index |= I810_TWOSIDE_BIT;
+ if (flags & DD_TRI_OFFSET) index |= I810_OFFSET_BIT;
+ if (flags & DD_TRI_UNFILLED) index |= I810_UNFILLED_BIT;
+ }
+
+ imesa->draw_point = i810_draw_point;
+ imesa->draw_line = i810_draw_line;
+ imesa->draw_tri = i810_draw_triangle;
+
+ /* Hook in fallbacks for specific primitives.
+ */
+ if (flags & ANY_FALLBACK_FLAGS)
+ {
+ if (flags & POINT_FALLBACK)
+ imesa->draw_point = i810_fallback_point;
+
+ if (flags & LINE_FALLBACK)
+ imesa->draw_line = i810_fallback_line;
+
+ if (flags & TRI_FALLBACK)
+ imesa->draw_tri = i810_fallback_tri;
+
+ if ((flags & DD_TRI_STIPPLE) && !imesa->stipple_in_hw)
+ imesa->draw_tri = i810_fallback_tri;
+
+ index |= I810_FALLBACK_BIT;
+ }
+ }
+
+ if (imesa->RenderIndex != index) {
+ imesa->RenderIndex = index;
+
+ tnl->Driver.Render.Points = rast_tab[index].points;
+ tnl->Driver.Render.Line = rast_tab[index].line;
+ tnl->Driver.Render.Triangle = rast_tab[index].triangle;
+ tnl->Driver.Render.Quad = rast_tab[index].quad;
+
+ if (index == 0) {
+ tnl->Driver.Render.PrimTabVerts = i810_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = i810_render_tab_elts;
+ tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
+ tnl->Driver.Render.ClippedPolygon = i810FastRenderClippedPoly;
+ } else {
+ tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+ tnl->Driver.Render.ClippedLine = i810RenderClippedLine;
+ tnl->Driver.Render.ClippedPolygon = i810RenderClippedPoly;
+ }
+ }
+}
+
+static const GLenum reduced_prim[GL_POLYGON+1] = {
+ GL_POINTS,
+ GL_LINES,
+ GL_LINES,
+ GL_LINES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES
+};
+
+
+/**********************************************************************/
+/* High level hooks for t_vb_render.c */
+/**********************************************************************/
+
+
+
+/* Determine the rasterized primitive when not drawing unfilled
+ * polygons.
+ *
+ * Used only for the default render stage which always decomposes
+ * primitives to trianges/lines/points. For the accelerated stage,
+ * which renders strips as strips, the equivalent calculations are
+ * performed in i810render.c.
+ */
+static void i810RenderPrimitive( GLcontext *ctx, GLenum prim )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint rprim = reduced_prim[prim];
+
+ imesa->render_primitive = prim;
+
+ if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
+ return;
+
+ if (imesa->reduced_primitive != rprim ||
+ hw_prim[prim] != imesa->hw_primitive) {
+ i810RasterPrimitive( ctx, rprim, hw_prim[prim] );
+ }
+}
+
+static void i810RunPipeline( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ if (imesa->new_state) {
+ if (imesa->new_state & _NEW_TEXTURE)
+ i810UpdateTextureState( ctx ); /* may modify imesa->new_state */
+
+ if (!imesa->Fallback) {
+ if (imesa->new_state & _I810_NEW_VERTEX)
+ i810ChooseVertexState( ctx );
+
+ if (imesa->new_state & _I810_NEW_RENDERSTATE)
+ i810ChooseRenderState( ctx );
+ }
+
+ imesa->new_state = 0;
+ }
+
+ _tnl_run_pipeline( ctx );
+}
+
+static void i810RenderStart( GLcontext *ctx )
+{
+ /* Check for projective textureing. Make sure all texcoord
+ * pointers point to something. (fix in mesa?)
+ */
+ i810CheckTexSizes( ctx );
+}
+
+static void i810RenderFinish( GLcontext *ctx )
+{
+ if (I810_CONTEXT(ctx)->RenderIndex & I810_FALLBACK_BIT)
+ _swrast_flush( ctx );
+}
+
+
+
+
+/* System to flush dma and emit state changes based on the rasterized
+ * primitive.
+ */
+void i810RasterPrimitive( GLcontext *ctx,
+ GLenum rprim,
+ GLuint hwprim )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint st1 = imesa->Setup[I810_CTXREG_ST1];
+ GLuint aa = imesa->Setup[I810_CTXREG_AA];
+ GLuint lcs = imesa->Setup[I810_CTXREG_LCS];
+
+ st1 &= ~ST1_ENABLE;
+ aa &= ~AA_ENABLE;
+
+ if (I810_DEBUG & DEBUG_PRIMS) {
+ /* Prints reduced prim, and hw prim */
+ char *prim_name = "Unknown";
+
+ switch(hwprim) {
+ case PR_LINES:
+ prim_name = "Lines";
+ break;
+ case PR_LINESTRIP:
+ prim_name = "LineStrip";
+ break;
+ case PR_TRIANGLES:
+ prim_name = "Triangles";
+ break;
+ case PR_TRISTRIP_0:
+ prim_name = "TriStrip_0";
+ break;
+ case PR_TRIFAN:
+ prim_name = "TriFan";
+ break;
+ case PR_POLYGON:
+ prim_name = "Polygons";
+ break;
+ default:
+ break;
+ }
+
+ fprintf(stderr, "%s : rprim(%s), hwprim(%s)\n",
+ __FUNCTION__,
+ _mesa_lookup_enum_by_nr(rprim),
+ prim_name);
+ }
+
+ switch (rprim) {
+ case GL_TRIANGLES:
+ if (ctx->Polygon.StippleFlag)
+ st1 |= ST1_ENABLE;
+ if (ctx->Polygon.SmoothFlag)
+ aa |= AA_ENABLE;
+ break;
+ case GL_LINES:
+ lcs &= ~(LCS_LINEWIDTH_3_0|LCS_LINEWIDTH_0_5);
+ lcs |= imesa->LcsLineWidth;
+ if (ctx->Line.SmoothFlag) {
+ aa |= AA_ENABLE;
+ lcs |= LCS_LINEWIDTH_0_5;
+ }
+ break;
+ case GL_POINTS:
+ lcs &= ~(LCS_LINEWIDTH_3_0|LCS_LINEWIDTH_0_5);
+ lcs |= imesa->LcsPointSize;
+ if (ctx->Point.SmoothFlag) {
+ aa |= AA_ENABLE;
+ lcs |= LCS_LINEWIDTH_0_5;
+ }
+ break;
+ default:
+ return;
+ }
+
+ imesa->reduced_primitive = rprim;
+
+ if (st1 != imesa->Setup[I810_CTXREG_ST1] ||
+ aa != imesa->Setup[I810_CTXREG_AA] ||
+ lcs != imesa->Setup[I810_CTXREG_LCS])
+ {
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->hw_primitive = hwprim;
+ imesa->Setup[I810_CTXREG_LCS] = lcs;
+ imesa->Setup[I810_CTXREG_ST1] = st1;
+ imesa->Setup[I810_CTXREG_AA] = aa;
+ }
+ else if (hwprim != imesa->hw_primitive) {
+ I810_STATECHANGE(imesa, 0);
+ imesa->hw_primitive = hwprim;
+ }
+}
+
+/**********************************************************************/
+/* Transition to/from hardware rasterization. */
+/**********************************************************************/
+static char *fallbackStrings[] = {
+ "Texture",
+ "Draw buffer",
+ "Read buffer",
+ "Color mask",
+ "Render mode",
+ "Stencil",
+ "Stipple",
+ "User disable"
+};
+
+
+static char *getFallbackString(GLuint bit)
+{
+ int i = 0;
+ while (bit > 1) {
+ i++;
+ bit >>= 1;
+ }
+ return fallbackStrings[i];
+}
+
+void i810Fallback( i810ContextPtr imesa, GLuint bit, GLboolean mode )
+{
+ GLcontext *ctx = imesa->glCtx;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint oldfallback = imesa->Fallback;
+
+ if (0) fprintf(stderr, "%s old %x bit %x mode %d\n", __FUNCTION__,
+ imesa->Fallback, bit, mode );
+
+ if (mode) {
+ imesa->Fallback |= bit;
+ if (oldfallback == 0) {
+ I810_FIREVERTICES(imesa);
+ if (I810_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr, "ENTER FALLBACK %s\n", getFallbackString( bit ));
+ _swsetup_Wakeup( ctx );
+ imesa->RenderIndex = ~0;
+ }
+ }
+ else {
+ imesa->Fallback &= ~bit;
+ if (oldfallback == bit) {
+ _swrast_flush( ctx );
+ if (I810_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr, "LEAVE FALLBACK %s\n", getFallbackString( bit ));
+ tnl->Driver.Render.Start = i810RenderStart;
+ tnl->Driver.Render.PrimitiveNotify = i810RenderPrimitive;
+ tnl->Driver.Render.Finish = i810RenderFinish;
+ tnl->Driver.Render.BuildVertices = i810BuildVertices;
+ imesa->new_state |= (_I810_NEW_RENDERSTATE|_I810_NEW_VERTEX);
+ }
+ }
+}
+
+
+/**********************************************************************/
+/* Initialization. */
+/**********************************************************************/
+
+
+void i810InitTriFuncs( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ static int firsttime = 1;
+
+ if (firsttime) {
+ init_rast_tab();
+ firsttime = 0;
+ }
+
+ tnl->Driver.RunPipeline = i810RunPipeline;
+ tnl->Driver.Render.Start = i810RenderStart;
+ tnl->Driver.Render.Finish = i810RenderFinish;
+ tnl->Driver.Render.PrimitiveNotify = i810RenderPrimitive;
+ tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
+ tnl->Driver.Render.BuildVertices = i810BuildVertices;
+}
diff --git a/src/i810tris.h b/src/i810tris.h
new file mode 100644
index 0000000..06c8b3f
--- /dev/null
+++ b/src/i810tris.h
@@ -0,0 +1,36 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.h,v 1.10 2002/02/22 21:33:04 dawes Exp $ */
+
+#ifndef I810TRIS_INC
+#define I810TRIS_INC
+
+#include "mtypes.h"
+
+extern void i810PrintRenderState( const char *msg, GLuint state );
+extern void i810InitTriFuncs( GLcontext *ctx );
+extern void i810RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
+
+#endif
diff --git a/src/i810vb.c b/src/i810vb.c
new file mode 100644
index 0000000..5ce98a9
--- /dev/null
+++ b/src/i810vb.c
@@ -0,0 +1,489 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810vb.c,v 1.13 2003/03/26 20:43:48 tsi Exp $ */
+
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "imports.h"
+#include "macros.h"
+#include "colormac.h"
+
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/t_context.h"
+
+#include "i810screen.h"
+#include "i810_dri.h"
+
+#include "i810context.h"
+#include "i810vb.h"
+#include "i810ioctl.h"
+#include "i810tris.h"
+#include "i810state.h"
+
+
+#define I810_TEX1_BIT 0x1
+#define I810_TEX0_BIT 0x2
+#define I810_RGBA_BIT 0x4
+#define I810_SPEC_BIT 0x8
+#define I810_FOG_BIT 0x10
+#define I810_XYZW_BIT 0x20
+#define I810_PTEX_BIT 0x40
+#define I810_MAX_SETUP 0x80
+
+static struct {
+ void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
+ tnl_interp_func interp;
+ tnl_copy_pv_func copy_pv;
+ GLboolean (*check_tex_sizes)( GLcontext *ctx );
+ GLuint vertex_size;
+ GLuint vertex_format;
+} setup_tab[I810_MAX_SETUP];
+
+#define TINY_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
+ VF_TEXCOORD_COUNT_0 | \
+ VF_RGBA_ENABLE | \
+ VF_XYZ)
+
+#define NOTEX_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
+ VF_TEXCOORD_COUNT_0 | \
+ VF_SPEC_FOG_ENABLE | \
+ VF_RGBA_ENABLE | \
+ VF_XYZW)
+
+#define TEX0_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
+ VF_TEXCOORD_COUNT_1 | \
+ VF_SPEC_FOG_ENABLE | \
+ VF_RGBA_ENABLE | \
+ VF_XYZW)
+
+#define TEX1_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
+ VF_TEXCOORD_COUNT_2 | \
+ VF_SPEC_FOG_ENABLE | \
+ VF_RGBA_ENABLE | \
+ VF_XYZW)
+
+#define PROJ_TEX1_VERTEX_FORMAT 0
+#define TEX2_VERTEX_FORMAT 0
+#define TEX3_VERTEX_FORMAT 0
+#define PROJ_TEX3_VERTEX_FORMAT 0
+
+#define DO_XYZW (IND & I810_XYZW_BIT)
+#define DO_RGBA (IND & I810_RGBA_BIT)
+#define DO_SPEC (IND & I810_SPEC_BIT)
+#define DO_FOG (IND & I810_FOG_BIT)
+#define DO_TEX0 (IND & I810_TEX0_BIT)
+#define DO_TEX1 (IND & I810_TEX1_BIT)
+#define DO_TEX2 0
+#define DO_TEX3 0
+#define DO_PTEX (IND & I810_PTEX_BIT)
+
+#define VERTEX i810Vertex
+#define VERTEX_COLOR i810_color_t
+#define GET_VIEWPORT_MAT() I810_CONTEXT(ctx)->ViewportMatrix.m
+#define GET_TEXSOURCE(n) n
+#define GET_VERTEX_FORMAT() I810_CONTEXT(ctx)->Setup[I810_CTXREG_VF]
+#define GET_VERTEX_STORE() I810_CONTEXT(ctx)->verts
+#define GET_VERTEX_SIZE() I810_CONTEXT(ctx)->vertex_size * sizeof(GLuint)
+#define INVALIDATE_STORED_VERTICES()
+
+#define HAVE_HW_VIEWPORT 0
+#define HAVE_HW_DIVIDE 0
+#define HAVE_RGBA_COLOR 0
+#define HAVE_TINY_VERTICES 1
+#define HAVE_NOTEX_VERTICES 1
+#define HAVE_TEX0_VERTICES 1
+#define HAVE_TEX1_VERTICES 1
+#define HAVE_TEX2_VERTICES 0
+#define HAVE_TEX3_VERTICES 0
+#define HAVE_PTEX_VERTICES 0
+
+#define UNVIEWPORT_VARS GLfloat h = I810_CONTEXT(ctx)->driDrawable->h
+#define UNVIEWPORT_X(x) x - SUBPIXEL_X
+#define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y
+#define UNVIEWPORT_Z(z) z * (float)0xffff
+
+#define PTEX_FALLBACK() FALLBACK(I810_CONTEXT(ctx), I810_FALLBACK_TEXTURE, 1)
+
+#define INTERP_VERTEX setup_tab[I810_CONTEXT(ctx)->SetupIndex].interp
+#define COPY_PV_VERTEX setup_tab[I810_CONTEXT(ctx)->SetupIndex].copy_pv
+
+
+/***********************************************************************
+ * Generate pv-copying and translation functions *
+ ***********************************************************************/
+
+#define TAG(x) i810_##x
+#include "tnl_dd/t_dd_vb.c"
+
+/***********************************************************************
+ * Generate vertex emit and interp functions *
+ ***********************************************************************/
+
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT)
+#define TAG(x) x##_wg
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT)
+#define TAG(x) x##_wgs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_wgt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_wgt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_PTEX_BIT)
+#define TAG(x) x##_wgpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_wgst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
+ I810_TEX1_BIT)
+#define TAG(x) x##_wgst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
+ I810_PTEX_BIT)
+#define TAG(x) x##_wgspt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT)
+#define TAG(x) x##_wgf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT)
+#define TAG(x) x##_wgfs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_wgft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|\
+ I810_TEX1_BIT)
+#define TAG(x) x##_wgft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|\
+ I810_PTEX_BIT)
+#define TAG(x) x##_wgfpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
+ I810_TEX0_BIT)
+#define TAG(x) x##_wgfst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
+ I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_wgfst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
+ I810_TEX0_BIT|I810_PTEX_BIT)
+#define TAG(x) x##_wgfspt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_TEX0_BIT)
+#define TAG(x) x##_t0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_t0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_FOG_BIT)
+#define TAG(x) x##_f
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_FOG_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_ft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_ft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT)
+#define TAG(x) x##_g
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_SPEC_BIT)
+#define TAG(x) x##_gs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_gt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_gt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_gst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_gst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_FOG_BIT)
+#define TAG(x) x##_gf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT)
+#define TAG(x) x##_gfs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_gft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_gft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_gfst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
+ I810_TEX1_BIT)
+#define TAG(x) x##_gfst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+
+static void init_setup_tab( void )
+{
+ init_wg();
+ init_wgs();
+ init_wgt0();
+ init_wgt0t1();
+ init_wgpt0();
+ init_wgst0();
+ init_wgst0t1();
+ init_wgspt0();
+ init_wgf();
+ init_wgfs();
+ init_wgft0();
+ init_wgft0t1();
+ init_wgfpt0();
+ init_wgfst0();
+ init_wgfst0t1();
+ init_wgfspt0();
+ init_t0();
+ init_t0t1();
+ init_f();
+ init_ft0();
+ init_ft0t1();
+ init_g();
+ init_gs();
+ init_gt0();
+ init_gt0t1();
+ init_gst0();
+ init_gst0t1();
+ init_gf();
+ init_gfs();
+ init_gft0();
+ init_gft0t1();
+ init_gfst0();
+ init_gfst0t1();
+}
+
+
+
+static void i810PrintSetupFlags(const char *msg, GLuint flags )
+{
+ fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
+ msg,
+ (int)flags,
+ (flags & I810_XYZW_BIT) ? " xyzw," : "",
+ (flags & I810_RGBA_BIT) ? " rgba," : "",
+ (flags & I810_SPEC_BIT) ? " spec," : "",
+ (flags & I810_FOG_BIT) ? " fog," : "",
+ (flags & I810_TEX0_BIT) ? " tex-0," : "",
+ (flags & I810_TEX1_BIT) ? " tex-1," : "");
+}
+
+
+
+void i810CheckTexSizes( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+
+ if (!setup_tab[imesa->SetupIndex].check_tex_sizes(ctx)) {
+ /* Invalidate stored verts
+ */
+ imesa->SetupNewInputs = ~0;
+ imesa->SetupIndex |= I810_PTEX_BIT;
+
+ if (!imesa->Fallback &&
+ !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
+ tnl->Driver.Render.Interp = setup_tab[imesa->SetupIndex].interp;
+ tnl->Driver.Render.CopyPV = setup_tab[imesa->SetupIndex].copy_pv;
+ }
+ if (imesa->Fallback) {
+ tnl->Driver.Render.Start(ctx);
+ }
+ }
+}
+
+void i810BuildVertices( GLcontext *ctx,
+ GLuint start,
+ GLuint count,
+ GLuint newinputs )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ GLuint stride = imesa->vertex_size * sizeof(int);
+ GLubyte *v = ((GLubyte *)imesa->verts + (start * stride));
+
+ if (0) fprintf(stderr, "%s\n", __FUNCTION__);
+
+ newinputs |= imesa->SetupNewInputs;
+ imesa->SetupNewInputs = 0;
+
+ if (!newinputs)
+ return;
+
+ if (newinputs & VERT_BIT_POS) {
+ setup_tab[imesa->SetupIndex].emit( ctx, start, count, v, stride );
+ } else {
+ GLuint ind = 0;
+
+ if (newinputs & VERT_BIT_COLOR0)
+ ind |= I810_RGBA_BIT;
+
+ if (newinputs & VERT_BIT_COLOR1)
+ ind |= I810_SPEC_BIT;
+
+ if (newinputs & VERT_BIT_TEX0)
+ ind |= I810_TEX0_BIT;
+
+ if (newinputs & VERT_BIT_TEX1)
+ ind |= I810_TEX1_BIT;
+
+ if (newinputs & VERT_BIT_FOG)
+ ind |= I810_FOG_BIT;
+
+ if (imesa->SetupIndex & I810_PTEX_BIT)
+ ind = ~0;
+
+ ind &= imesa->SetupIndex;
+
+ if (ind) {
+ setup_tab[ind].emit( ctx, start, count, v, stride );
+ }
+ }
+}
+
+void i810ChooseVertexState( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ GLuint ind = I810_XYZW_BIT|I810_RGBA_BIT;
+
+ if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+ ind |= I810_SPEC_BIT;
+
+ if (ctx->Fog.Enabled)
+ ind |= I810_FOG_BIT;
+
+ if (ctx->Texture._EnabledUnits & 0x2)
+ /* unit 1 enabled */
+ ind |= I810_TEX1_BIT|I810_TEX0_BIT;
+ else if (ctx->Texture._EnabledUnits & 0x1)
+ /* unit 0 enabled */
+ ind |= I810_TEX0_BIT;
+
+ imesa->SetupIndex = ind;
+
+ if (I810_DEBUG & (DEBUG_VERTS|DEBUG_STATE))
+ i810PrintSetupFlags( __FUNCTION__, ind );
+
+ if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
+ tnl->Driver.Render.Interp = i810_interp_extras;
+ tnl->Driver.Render.CopyPV = i810_copy_pv_extras;
+ } else {
+ tnl->Driver.Render.Interp = setup_tab[ind].interp;
+ tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
+ }
+
+ if (setup_tab[ind].vertex_format != imesa->Setup[I810_CTXREG_VF]) {
+ I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
+ imesa->Setup[I810_CTXREG_VF] = setup_tab[ind].vertex_format;
+ imesa->vertex_size = setup_tab[ind].vertex_size;
+ }
+}
+
+
+
+void *i810_emit_contiguous_verts( GLcontext *ctx,
+ GLuint start,
+ GLuint count,
+ void *dest )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint stride = imesa->vertex_size * 4;
+ setup_tab[imesa->SetupIndex].emit( ctx, start, count, dest, stride );
+ return (void *)((char *)dest + stride * (count - start));
+}
+
+
+
+void i810InitVB( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint size = TNL_CONTEXT(ctx)->vb.Size;
+
+ imesa->verts = (GLubyte *)ALIGN_MALLOC(size * 4 * 16, 32);
+
+ {
+ static int firsttime = 1;
+ if (firsttime) {
+ init_setup_tab();
+ firsttime = 0;
+ }
+ }
+}
+
+
+void i810FreeVB( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ if (imesa->verts) {
+ ALIGN_FREE(imesa->verts);
+ imesa->verts = 0;
+ }
+}
diff --git a/src/i810vb.h b/src/i810vb.h
new file mode 100644
index 0000000..1cced86
--- /dev/null
+++ b/src/i810vb.h
@@ -0,0 +1,60 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810vb.h,v 1.4 2002/02/22 21:33:04 dawes Exp $ */
+
+#ifndef I810VB_INC
+#define I810VB_INC
+
+#include "mtypes.h"
+#include "swrast/swrast.h"
+
+#define _I810_NEW_VERTEX (_NEW_TEXTURE | \
+ _DD_NEW_SEPARATE_SPECULAR | \
+ _DD_NEW_TRI_UNFILLED | \
+ _DD_NEW_TRI_LIGHT_TWOSIDE | \
+ _NEW_FOG)
+
+
+extern void i810ChooseVertexState( GLcontext *ctx );
+extern void i810CheckTexSizes( GLcontext *ctx );
+extern void i810BuildVertices( GLcontext *ctx,
+ GLuint start,
+ GLuint count,
+ GLuint newinputs );
+
+
+extern void *i810_emit_contiguous_verts( GLcontext *ctx,
+ GLuint start,
+ GLuint count,
+ void *dest );
+
+extern void i810_translate_vertex( GLcontext *ctx,
+ const i810Vertex *src,
+ SWvertex *dst );
+
+extern void i810InitVB( GLcontext *ctx );
+extern void i810FreeVB( GLcontext *ctx );
+
+#endif
diff --git a/src/server/i810_common.h b/src/server/i810_common.h
new file mode 100644
index 0000000..02e548b
--- /dev/null
+++ b/src/server/i810_common.h
@@ -0,0 +1,192 @@
+/* i810_common.h -- common header definitions for I810 2D/3D/DRM suite
+ *
+ * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Converted to common header format:
+ * Jens Owen <jens@tungstengraphics.com>
+ *
+ * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_common.h,v 1.1 2002/09/11 00:29:31 dawes Exp $
+ *
+ */
+
+/* WARNING: If you change any of these defines, make sure to change
+ * the kernel include file as well (i810_drm.h)
+ */
+
+#ifndef _I810_COMMON_H_
+#define _I810_COMMON_H_
+
+#ifndef _I810_DEFINES_
+#define _I810_DEFINES_
+#define I810_USE_BATCH 1
+
+#define I810_DMA_BUF_ORDER 12
+#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER)
+#define I810_DMA_BUF_NR 256
+
+#define I810_NR_SAREA_CLIPRECTS 8
+
+/* Each region is a minimum of 64k, and there are at most 64 of them.
+ */
+#define I810_NR_TEX_REGIONS 64
+#define I810_LOG_MIN_TEX_REGION_SIZE 16
+
+/* Destbuffer state
+ * - backbuffer linear offset and pitch -- invarient in the current dri
+ * - zbuffer linear offset and pitch -- also invarient
+ * - drawing origin in back and depth buffers.
+ *
+ * Keep the depth/back buffer state here to acommodate private buffers
+ * in the future.
+ */
+#define I810_DESTREG_DI0 0 /* CMD_OP_DESTBUFFER_INFO (2 dwords) */
+#define I810_DESTREG_DI1 1
+#define I810_DESTREG_DV0 2 /* GFX_OP_DESTBUFFER_VARS (2 dwords) */
+#define I810_DESTREG_DV1 3
+#define I810_DESTREG_DR0 4 /* GFX_OP_DRAWRECT_INFO (4 dwords) */
+#define I810_DESTREG_DR1 5
+#define I810_DESTREG_DR2 6
+#define I810_DESTREG_DR3 7
+#define I810_DESTREG_DR4 8
+#define I810_DEST_SETUP_SIZE 10
+
+/* Context state
+ */
+#define I810_CTXREG_CF0 0 /* GFX_OP_COLOR_FACTOR */
+#define I810_CTXREG_CF1 1
+#define I810_CTXREG_ST0 2 /* GFX_OP_STIPPLE */
+#define I810_CTXREG_ST1 3
+#define I810_CTXREG_VF 4 /* GFX_OP_VERTEX_FMT */
+#define I810_CTXREG_MT 5 /* GFX_OP_MAP_TEXELS */
+#define I810_CTXREG_MC0 6 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */
+#define I810_CTXREG_MC1 7 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */
+#define I810_CTXREG_MC2 8 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */
+#define I810_CTXREG_MA0 9 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */
+#define I810_CTXREG_MA1 10 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */
+#define I810_CTXREG_MA2 11 /* GFX_OP_MAP_ALPHA_STAGES - stage 2 */
+#define I810_CTXREG_SDM 12 /* GFX_OP_SRC_DEST_MONO */
+#define I810_CTXREG_FOG 13 /* GFX_OP_FOG_COLOR */
+#define I810_CTXREG_B1 14 /* GFX_OP_BOOL_1 */
+#define I810_CTXREG_B2 15 /* GFX_OP_BOOL_2 */
+#define I810_CTXREG_LCS 16 /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */
+#define I810_CTXREG_PV 17 /* GFX_OP_PV_RULE -- Invarient! */
+#define I810_CTXREG_ZA 18 /* GFX_OP_ZBIAS_ALPHAFUNC */
+#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */
+#define I810_CTX_SETUP_SIZE 20
+
+/* Texture state (per tex unit)
+ */
+#define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */
+#define I810_TEXREG_MI1 1
+#define I810_TEXREG_MI2 2
+#define I810_TEXREG_MI3 3
+#define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */
+#define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */
+#define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */
+#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */
+#define I810_TEX_SETUP_SIZE 8
+
+/* Driver specific DRM command indices
+ * NOTE: these are not OS specific, but they are driver specific
+ */
+#define DRM_I810_INIT 0x00
+#define DRM_I810_VERTEX 0x01
+#define DRM_I810_CLEAR 0x02
+#define DRM_I810_FLUSH 0x03
+#define DRM_I810_GETAGE 0x04
+#define DRM_I810_GETBUF 0x05
+#define DRM_I810_SWAP 0x06
+#define DRM_I810_COPY 0x07
+#define DRM_I810_DOCOPY 0x08
+#define DRM_I810_OV0INFO 0x09
+#define DRM_I810_FSTATUS 0x0a
+#define DRM_I810_OV0FLIP 0x0b
+#define DRM_I810_MC 0x0c
+#define DRM_I810_RSTATUS 0x0d
+#define DRM_I810_FLIP 0x0e
+
+#endif
+
+typedef enum _drmI810Initfunc {
+ I810_INIT_DMA = 0x01,
+ I810_CLEANUP_DMA = 0x02,
+ I810_INIT_DMA_1_4 = 0x03
+} drmI810Initfunc;
+
+typedef struct {
+ drmI810Initfunc func;
+ unsigned int mmio_offset;
+ unsigned int buffers_offset;
+ int sarea_priv_offset;
+ unsigned int ring_start;
+ unsigned int ring_end;
+ unsigned int ring_size;
+ unsigned int front_offset;
+ unsigned int back_offset;
+ unsigned int depth_offset;
+ unsigned int overlay_offset;
+ unsigned int overlay_physical;
+ unsigned int w;
+ unsigned int h;
+ unsigned int pitch;
+ unsigned int pitch_bits;
+} drmI810Init;
+
+typedef struct {
+ void *virtual;
+ int request_idx;
+ int request_size;
+ int granted;
+} drmI810DMA;
+
+/* Flags for clear ioctl
+ */
+#define I810_FRONT 0x1
+#define I810_BACK 0x2
+#define I810_DEPTH 0x4
+
+typedef struct {
+ int clear_color;
+ int clear_depth;
+ int flags;
+} drmI810Clear;
+
+typedef struct {
+ int idx; /* buffer index */
+ int used; /* nr bytes in use */
+ int discard; /* client is finished with the buffer? */
+} drmI810Vertex;
+
+/* Flags for vertex ioctl
+ */
+#define PR_TRIANGLES (0x0<<18)
+#define PR_TRISTRIP_0 (0x1<<18)
+#define PR_TRISTRIP_1 (0x2<<18)
+#define PR_TRIFAN (0x3<<18)
+#define PR_POLYGON (0x4<<18)
+#define PR_LINES (0x5<<18)
+#define PR_LINESTRIP (0x6<<18)
+#define PR_RECTS (0x7<<18)
+#define PR_MASK (0x7<<18)
+
+#endif
diff --git a/src/server/i810_dri.c b/src/server/i810_dri.c
new file mode 100644
index 0000000..f52797c
--- /dev/null
+++ b/src/server/i810_dri.c
@@ -0,0 +1,975 @@
+/**
+ * \file server/i810_dri.c
+ * \brief File to perform the device-specific initialization tasks typically
+ * done in the X server.
+ *
+ * Here they are converted to run in the client (or perhaps a standalone
+ * process), and to work with the frame buffer device rather than the X
+ * server infrastructure.
+ *
+ * Copyright (C) 2004 Dave Airlie (airlied@linux.ie)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "driver.h"
+#include "drm.h"
+
+#include "i810.h"
+#include "i810_dri.h"
+#include "i810_reg.h"
+
+
+static int i810_pitches[] = {
+ 512,
+ 1024,
+ 2048,
+ 4096,
+ 0
+};
+
+static int i810_pitch_flags[] = {
+ 0x0,
+ 0x1,
+ 0x2,
+ 0x3,
+ 0
+};
+
+static unsigned int i810_drm_version = 0;
+
+static int
+I810AllocLow(I810MemRange * result, I810MemRange * pool, int size)
+{
+ if (size > pool->Size)
+ return 0;
+
+ pool->Size -= size;
+ result->Size = size;
+ result->Start = pool->Start;
+ result->End = pool->Start += size;
+
+ return 1;
+}
+
+static int
+I810AllocHigh(I810MemRange * result, I810MemRange * pool, int size)
+{
+ if (size > pool->Size)
+ return 0;
+
+ pool->Size -= size;
+ result->Size = size;
+ result->End = pool->End;
+ result->Start = pool->End -= size;
+
+ return 1;
+}
+
+
+/**
+ * \brief Wait for free FIFO entries.
+ *
+ * \param ctx display handle.
+ * \param entries number of free entries to wait.
+ *
+ * It polls the free entries from the chip until it reaches the requested value
+ * or a timeout (3000 tries) occurs. Aborts the program if the FIFO times out.
+ */
+static void I810WaitForFifo( const DRIDriverContext *ctx,
+ int entries )
+{
+}
+
+/**
+ * \brief Reset graphics card to known state.
+ *
+ * \param ctx display handle.
+ *
+ * Resets the values of several I810 registers.
+ */
+static void I810EngineReset( const DRIDriverContext *ctx )
+{
+ unsigned char *I810MMIO = ctx->MMIOAddress;
+}
+
+/**
+ * \brief Restore the drawing engine.
+ *
+ * \param ctx display handle
+ *
+ * Resets the graphics card and sets initial values for several registers of
+ * the card's drawing engine.
+ *
+ * Turns on the i810 command processor engine (i.e., the ringbuffer).
+ */
+static int I810EngineRestore( const DRIDriverContext *ctx )
+{
+ I810Ptr info = ctx->driverPrivate;
+ unsigned char *I810MMIO = ctx->MMIOAddress;
+
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ return 1;
+}
+
+
+/**
+ * \brief Shutdown the drawing engine.
+ *
+ * \param ctx display handle
+ *
+ * Turns off the command processor engine & restores the graphics card
+ * to a state that fbdev understands.
+ */
+static int I810EngineShutdown( const DRIDriverContext *ctx )
+{
+ drmI810Init info;
+ int ret;
+
+ memset(&info, 0, sizeof(drmI810Init));
+ info.func = I810_CLEANUP_DMA;
+
+ ret = drmCommandWrite(ctx->drmFD, DRM_I810_INIT, &info, sizeof(drmI810Init));
+ if (ret>0)
+ {
+ fprintf(stderr,"[dri] I810 DMA Cleanup failed\n");
+ return -errno;
+ }
+ return 0;
+}
+
+/**
+ * \brief Compute base 2 logarithm.
+ *
+ * \param val value.
+ *
+ * \return base 2 logarithm of \p val.
+ */
+static int I810MinBits(int val)
+{
+ int bits;
+
+ if (!val) return 1;
+ for (bits = 0; val; val >>= 1, ++bits);
+ return bits;
+}
+
+static int I810DRIAgpPreInit( const DRIDriverContext *ctx, I810Ptr info)
+{
+
+ if (drmAgpAcquire(ctx->drmFD) < 0) {
+ fprintf(stderr, "[gart] AGP not available\n");
+ return 0;
+ }
+
+
+ if (drmAgpEnable(ctx->drmFD, 0) < 0) {
+ fprintf(stderr, "[gart] AGP not enabled\n");
+ drmAgpRelease(ctx->drmFD);
+ return 0;
+ }
+}
+
+/**
+ * \brief Initialize the AGP state
+ *
+ * \param ctx display handle.
+ * \param info driver private data.
+ *
+ * \return one on success, or zero on failure.
+ *
+ * Acquires and enables the AGP device. Reserves memory in the AGP space for
+ * the ring buffer, vertex buffers and textures. Initialize the I810
+ * registers to point to that memory and add client mappings.
+ */
+static int I810DRIAgpInit( const DRIDriverContext *ctx, I810Ptr info)
+{
+ unsigned char *I810MMIO = ctx->MMIOAddress;
+ int ret;
+ int s, l;
+ unsigned long dcacheHandle;
+ unsigned long agpHandle;
+ int pitch_idx = 0;
+ int back_size = 0;
+ int sysmem_size = 0;
+ int width = ctx->shared.virtualWidth * ctx->cpp;
+
+
+ info->backHandle = DRM_AGP_NO_HANDLE;
+ info->zHandle = DRM_AGP_NO_HANDLE;
+ info->sysmemHandle = DRM_AGP_NO_HANDLE;
+ info->dcacheHandle = DRM_AGP_NO_HANDLE;
+
+ memset(&info->DcacheMem, 0, sizeof(I810MemRange));
+ memset(&info->BackBuffer, 0, sizeof(I810MemRange));
+ memset(&info->DepthBuffer, 0, sizeof(I810MemRange));
+
+ drmAgpAlloc(ctx->drmFD, 4096 * 1024, 1, NULL, &dcacheHandle);
+ info->dcacheHandle = dcacheHandle;
+
+ fprintf(stderr, "[agp] dcacheHandle : 0x%x\n", dcacheHandle);
+
+#define Elements(x) sizeof(x)/sizeof(*x)
+ for (pitch_idx = 0; pitch_idx < Elements(i810_pitches); pitch_idx++)
+ if (width <= i810_pitches[pitch_idx])
+ break;
+
+ if (pitch_idx == Elements(i810_pitches)) {
+ fprintf(stderr,"[dri] Couldn't find depth/back buffer pitch\n");
+ exit(-1);
+ }
+ else
+ {
+ int lines = (ctx->shared.virtualWidth + 15) / 16 * 16;
+ back_size = i810_pitches[pitch_idx] * lines;
+ back_size = ((back_size + 4096 - 1) / 4096) * 4096;
+ }
+
+ sysmem_size = ctx->shared.fbSize;
+ fprintf(stderr,"sysmem_size is %lu back_size is %lu\n", sysmem_size, back_size);
+ if (dcacheHandle != DRM_AGP_NO_HANDLE) {
+ if (back_size > 4 * 1024 * 1024) {
+ fprintf(stderr,"[dri] Backsize is larger then 4 meg\n");
+ sysmem_size = sysmem_size - 2 * back_size;
+ drmAgpFree(ctx->drmFD, dcacheHandle);
+ info->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE;
+ } else {
+ sysmem_size = sysmem_size - back_size;
+ }
+ } else {
+ sysmem_size = sysmem_size - 2 * back_size;
+ }
+
+ info->SysMem.Start=0;
+ info->SysMem.Size = sysmem_size;
+ info->SysMem.End = sysmem_size;
+
+ if (dcacheHandle != DRM_AGP_NO_HANDLE) {
+ if (drmAgpBind(ctx->drmFD, dcacheHandle, info->DepthOffset) == 0) {
+ memset(&info->DcacheMem, 0, sizeof(I810MemRange));
+ fprintf(stderr,"[agp] GART: Found 4096K Z buffer memory\n");
+ info->DcacheMem.Start = info->DepthOffset;
+ info->DcacheMem.Size = 1024 * 4096;
+ info->DcacheMem.End = info->DcacheMem.Start + info->DcacheMem.Size;
+ } else {
+ fprintf(stderr, "[agp] GART: dcache bind failed\n");
+ drmAgpFree(ctx->drmFD, dcacheHandle);
+ info->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE;
+ }
+ } else {
+ fprintf(stderr, "[agp] GART: no dcache memory found\n");
+ }
+
+ drmAgpAlloc(ctx->drmFD, back_size, 0, NULL, &agpHandle);
+ info->backHandle = agpHandle;
+
+ if (agpHandle != DRM_AGP_NO_HANDLE) {
+ if (drmAgpBind(ctx->drmFD, agpHandle, info->BackOffset) == 0) {
+ fprintf(stderr, "[agp] Bound backbuffer memory\n");
+
+ info->BackBuffer.Start = info->BackOffset;
+ info->BackBuffer.Size = back_size;
+ info->BackBuffer.End = (info->BackBuffer.Start +
+ info->BackBuffer.Size);
+ } else {
+ fprintf(stderr,"[agp] Unable to bind backbuffer. Disabling DRI.\n");
+ return 0;
+ }
+ } else {
+ fprintf(stderr, "[dri] Unable to allocate backbuffer memory. Disabling DRI.\n");
+ return 0;
+ }
+
+ if (dcacheHandle == DRM_AGP_NO_HANDLE) {
+ drmAgpAlloc(ctx->drmFD, back_size, 0, NULL, &agpHandle);
+
+ info->zHandle = agpHandle;
+
+ if (agpHandle != DRM_AGP_NO_HANDLE) {
+ if (drmAgpBind(ctx->drmFD, agpHandle, info->DepthOffset) == 0) {
+ fprintf(stderr,"[agp] Bound depthbuffer memory\n");
+ info->DepthBuffer.Start = info->DepthOffset;
+ info->DepthBuffer.Size = back_size;
+ info->DepthBuffer.End = (info->DepthBuffer.Start +
+ info->DepthBuffer.Size);
+ } else {
+ fprintf(stderr,"[agp] Unable to bind depthbuffer. Disabling DRI.\n");
+ return 0;
+ }
+ } else {
+ fprintf(stderr,"[agp] Unable to allocate depthbuffer memory. Disabling DRI.\n");
+ return 0;
+ }
+ }
+
+ /* Now allocate and bind the agp space. This memory will include the
+ * regular framebuffer as well as texture memory.
+ */
+ drmAgpAlloc(ctx->drmFD, sysmem_size, 0, NULL, &agpHandle);
+ info->sysmemHandle = agpHandle;
+
+ if (agpHandle != DRM_AGP_NO_HANDLE) {
+ if (drmAgpBind(ctx->drmFD, agpHandle, 0) == 0) {
+ fprintf(stderr, "[agp] Bound System Texture Memory\n");
+ } else {
+ fprintf(stderr, "[agp] Unable to bind system texture memory. Disabling DRI.\n");
+ return 0;
+ }
+ } else {
+ fprintf(stderr, "[agp] Unable to allocate system texture memory. Disabling DRI.\n");
+ return 0;
+ }
+
+ info->auxPitch = i810_pitches[pitch_idx];
+ info->auxPitchBits = i810_pitch_flags[pitch_idx];
+
+ return 1;
+}
+
+
+/**
+ * \brief Initialize the kernel data structures and enable the CP engine.
+ *
+ * \param ctx display handle.
+ * \param info driver private data.
+ *
+ * \return non-zero on success, or zero on failure.
+ *
+ * This function is a wrapper around the DRM_I810_CP_INIT command, passing
+ * all the parameters in a drmI810Init structure.
+ */
+static int I810DRIKernelInit( const DRIDriverContext *ctx,
+ I810Ptr info)
+{
+ int cpp = ctx->bpp / 8;
+ drmI810Init drmInfo;
+ int ret;
+ I810RingBuffer *ring = &(info->LpRing);
+
+ /* This is the struct passed to the kernel module for its initialization */
+ memset(&drmInfo, 0, sizeof(drmI810Init));
+
+ /* make sure we have at least 1.4 */
+ drmInfo.func = I810_INIT_DMA_1_4;
+
+ drmInfo.ring_start = ring->mem.Start;
+ drmInfo.ring_end = ring->mem.End;
+ drmInfo.ring_size = ring->mem.Size;
+
+ drmInfo.mmio_offset = (unsigned int)info->regs;
+ drmInfo.buffers_offset = (unsigned int)info->buffer_map;
+ drmInfo.sarea_priv_offset = sizeof(drm_sarea_t);
+
+ drmInfo.front_offset = 0;
+ drmInfo.back_offset = info->BackBuffer.Start;
+ drmInfo.depth_offset = info->DepthBuffer.Start;
+
+ drmInfo.w = ctx->shared.virtualWidth;
+ drmInfo.h = ctx->shared.virtualHeight;
+ drmInfo.pitch = info->auxPitch;
+ drmInfo.pitch_bits = info->auxPitchBits;
+
+
+ ret = drmCommandWrite(ctx->drmFD, DRM_I810_INIT, &drmInfo,
+ sizeof(drmI810Init));
+
+ return ret >= 0;
+}
+
+
+/**
+ * \brief Add a map for the vertex buffers that will be accessed by any
+ * DRI-based clients.
+ *
+ * \param ctx display handle.
+ * \param info driver private data.
+ *
+ * \return one on success, or zero on failure.
+ *
+ * Calls drmAddBufs() with the previously allocated vertex buffers.
+ */
+static int I810DRIBufInit( const DRIDriverContext *ctx, I810Ptr info )
+{
+ /* Initialize vertex buffers */
+ info->bufNumBufs = drmAddBufs(ctx->drmFD,
+ I810_DMA_BUF_NR,
+ I810_DMA_BUF_SZ,
+ DRM_AGP_BUFFER,
+ info->BufferMem.Start);
+
+ if (info->bufNumBufs <= 0) {
+ fprintf(stderr,
+ "[drm] Could not create vertex/indirect buffers list\n");
+ return 0;
+ }
+ fprintf(stderr,
+ "[drm] Added %d %d byte vertex/indirect buffers\n",
+ info->bufNumBufs, I810_DMA_BUF_SZ);
+
+ return 1;
+}
+
+/**
+ * \brief Install an IRQ handler.
+ *
+ * \param ctx display handle.
+ * \param info driver private data.
+ *
+ * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to
+ * IRQ-free operation on failure.
+ */
+static void I810DRIIrqInit(const DRIDriverContext *ctx,
+ I810Ptr info)
+{
+ if (!info->irq) {
+ info->irq = drmGetInterruptFromBusID(ctx->drmFD,
+ ctx->pciBus,
+ ctx->pciDevice,
+ ctx->pciFunc);
+
+ if ((drmCtlInstHandler(ctx->drmFD, info->irq)) != 0) {
+ fprintf(stderr,
+ "[drm] failure adding irq handler, "
+ "there is a device already using that irq\n"
+ "[drm] falling back to irq-free operation\n");
+ info->irq = 0;
+ }
+ }
+
+ if (info->irq)
+ fprintf(stderr,
+ "[drm] dma control initialized, using IRQ %d\n",
+ info->irq);
+}
+
+static int I810CheckDRMVersion( const DRIDriverContext *ctx,
+ I810Ptr info )
+{
+ drmVersionPtr version;
+
+ version = drmGetVersion(ctx->drmFD);
+ if (version) {
+ int req_minor, req_patch;
+
+ req_minor = 4;
+ req_patch = 0;
+
+ i810_drm_version = (version->version_major<<16) | version->version_minor;
+ if (version->version_major != 1 ||
+ version->version_minor < req_minor ||
+ (version->version_minor == req_minor &&
+ version->version_patchlevel < req_patch)) {
+ /* Incompatible drm version */
+ fprintf(stderr,
+ "[dri] I810DRIScreenInit failed because of a version "
+ "mismatch.\n"
+ "[dri] i810.o kernel module version is %d.%d.%d "
+ "but version 1.%d.%d or newer is needed.\n"
+ "[dri] Disabling DRI.\n",
+ version->version_major,
+ version->version_minor,
+ version->version_patchlevel,
+ req_minor,
+ req_patch);
+ drmFreeVersion(version);
+ return 0;
+ }
+
+ info->drmMinor = version->version_minor;
+ drmFreeVersion(version);
+ }
+
+ return 1;
+}
+
+static int I810MemoryInit( const DRIDriverContext *ctx, I810Ptr info )
+{
+ int width_bytes = ctx->shared.virtualWidth * ctx->cpp;
+ int cpp = ctx->cpp;
+ int bufferSize = (ctx->shared.virtualHeight * width_bytes);
+ int depthSize = (((ctx->shared.virtualHeight+15) & ~15) * width_bytes);
+ int l;
+
+ if (drmAddMap(ctx->drmFD, (drm_handle_t) info->BackBuffer.Start,
+ info->BackBuffer.Size, DRM_AGP, 0,
+ &info->backbuffer) < 0) {
+ fprintf(stderr, "[drm] drmAddMap(backbuffer) failed. Disabling DRI\n");
+ return 0;
+ }
+
+ if (drmAddMap(ctx->drmFD, (drm_handle_t) info->DepthBuffer.Start,
+ info->DepthBuffer.Size, DRM_AGP, 0,
+ &info->depthbuffer) < 0) {
+ fprintf(stderr, "[drm] drmAddMap(depthbuffer) failed. Disabling DRI.\n");
+ return 0;
+ }
+
+ if (!I810AllocLow(&(info->FrontBuffer), &(info->SysMem), (((ctx->shared.virtualHeight * width_bytes) + 4095) & ~4095)))
+ {
+ fprintf(stderr,"Framebuffer allocation failed\n");
+ return 0;
+ }
+ else
+ fprintf(stderr,"Frame buffer at 0x%.8x (%luk, %lu bytes)\n",
+ info->FrontBuffer.Start,
+ info->FrontBuffer.Size / 1024, info->FrontBuffer.Size);
+
+ memset(&(info->LpRing), 0, sizeof(I810RingBuffer));
+ if (I810AllocLow(&(info->LpRing.mem), &(info->SysMem), 16 * 4096)) {
+ fprintf(stderr,
+ "Ring buffer at 0x%.8x (%luk, %lu bytes)\n",
+ info->LpRing.mem.Start,
+ info->LpRing.mem.Size / 1024, info->LpRing.mem.Size);
+
+ info->LpRing.tail_mask = info->LpRing.mem.Size - 1;
+ info->LpRing.virtual_start = info->LpRing.mem.Start;
+ info->LpRing.head = 0;
+ info->LpRing.tail = 0;
+ info->LpRing.space = 0;
+ } else {
+ fprintf(stderr, "Ring buffer allocation failed\n");
+ return (0);
+ }
+
+ /* Allocate buffer memory */
+ I810AllocHigh(&(info->BufferMem), &(info->SysMem),
+ I810_DMA_BUF_NR * I810_DMA_BUF_SZ);
+
+
+ fprintf(stderr, "[dri] Buffer map : %lx\n",
+ info->BufferMem.Start);
+
+ if (info->BufferMem.Start == 0 ||
+ info->BufferMem.End - info->BufferMem.Start >
+ I810_DMA_BUF_NR * I810_DMA_BUF_SZ) {
+ fprintf(stderr,"[dri] Not enough memory for dma buffers. Disabling DRI.\n");
+ return 0;
+ }
+
+ if (drmAddMap(ctx->drmFD, (drm_handle_t) info->BufferMem.Start,
+ info->BufferMem.Size, DRM_AGP, 0, &info->buffer_map) < 0) {
+ fprintf(stderr, "[drm] drmAddMap(buffer_map) failed. Disabling DRI.\n");
+ return 0;
+ }
+
+ if (drmAddMap(ctx->drmFD, (drm_handle_t) info->LpRing.mem.Start,
+ info->LpRing.mem.Size, DRM_AGP, 0, &info->ring_map) < 0) {
+ fprintf(stderr, "[drm] drmAddMap(ring_map) failed. Disabling DRI. \n");
+ return 0;
+ }
+
+ /* Front, back and depth buffers - everything else texture??
+ */
+ info->textureSize = info->SysMem.Size;
+
+ if (info->textureSize < 0)
+ return 0;
+
+
+ l = I810MinBits((info->textureSize-1) / I810_NR_TEX_REGIONS);
+ if (l < I810_LOG_MIN_TEX_REGION_SIZE) l = I810_LOG_MIN_TEX_REGION_SIZE;
+
+ /* Round the texture size up to the nearest whole number of
+ * texture regions. Again, be greedy about this, don't
+ * round down.
+ */
+ info->logTextureGranularity = l;
+ info->textureSize = (info->textureSize >> l) << l;
+
+ /* Set a minimum usable local texture heap size. This will fit
+ * two 256x256x32bpp textures.
+ */
+ if (info->textureSize < 512 * 1024) {
+ info->textureOffset = 0;
+ info->textureSize = 0;
+ }
+
+ I810AllocLow(&(info->TexMem), &(info->SysMem), info->textureSize);
+
+ if (drmAddMap(ctx->drmFD, (drm_handle_t) info->TexMem.Start,
+ info->TexMem.Size, DRM_AGP, 0, &info->textures) < 0) {
+ fprintf(stderr,
+ "[drm] drmAddMap(textures) failed. Disabling DRI.\n");
+ return 0;
+ }
+
+ /* Reserve space for textures */
+ fprintf(stderr,
+ "Will use back buffer at offset 0x%x\n",
+ info->BackOffset);
+ fprintf(stderr,
+ "Will use depth buffer at offset 0x%x\n",
+ info->DepthOffset);
+ fprintf(stderr,
+ "Will use %d kb for textures at offset 0x%x\n",
+ info->TexMem.Size/1024, info->TexMem.Start);
+
+ return 1;
+}
+
+
+
+/**
+ * Called at the start of each server generation.
+ *
+ * \param ctx display handle.
+ * \param info driver private data.
+ *
+ * \return non-zero on success, or zero on failure.
+ *
+ * Performs static frame buffer allocation. Opens the DRM device and add maps
+ * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more
+ * information. Creates a \e server context to grab the lock for the
+ * initialization ioctls and calls the other initilization functions in this
+ * file. Starts the CP engine via the DRM_I810_CP_START command.
+ *
+ * Setups a I810DRIRec structure to be passed to i810_dri.so for its
+ * initialization.
+ */
+static int I810ScreenInit( DRIDriverContext *ctx, I810Ptr info )
+{
+ I810DRIPtr pI810DRI;
+ int err;
+
+ usleep(100);
+ /*assert(!ctx->IsClient);*/
+
+ /* from XFree86 driver */
+ info->DepthOffset = 0x3000000;
+ info->BackOffset = 0x3800000;
+ {
+ int width_bytes = (ctx->shared.virtualWidth * ctx->cpp);
+ int maxy = ctx->shared.fbSize / width_bytes;
+
+
+ if (maxy <= ctx->shared.virtualHeight * 3) {
+ fprintf(stderr,
+ "Static buffer allocation failed -- "
+ "need at least %d kB video memory (have %d kB)\n",
+ (ctx->shared.virtualWidth * ctx->shared.virtualHeight *
+ ctx->cpp * 3 + 1023) / 1024,
+ ctx->shared.fbSize / 1024);
+ return 0;
+ }
+ }
+
+
+ info->regsSize = ctx->MMIOSize;
+ ctx->shared.SAREASize = 0x2000;
+
+ /* Note that drmOpen will try to load the kernel module, if needed. */
+ ctx->drmFD = drmOpen("i810", NULL );
+ if (ctx->drmFD < 0) {
+ fprintf(stderr, "[drm] drmOpen failed\n");
+ return 0;
+ }
+
+ if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) {
+ fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
+ ctx->drmFD, ctx->pciBusID, strerror(-err));
+ return 0;
+ }
+
+ if (drmAddMap( ctx->drmFD,
+ 0,
+ ctx->shared.SAREASize,
+ DRM_SHM,
+ DRM_CONTAINS_LOCK,
+ &ctx->shared.hSAREA) < 0)
+ {
+ fprintf(stderr, "[drm] drmAddMap failed\n");
+ return 0;
+ }
+ fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n",
+ ctx->shared.SAREASize, ctx->shared.hSAREA);
+
+ if (drmMap( ctx->drmFD,
+ ctx->shared.hSAREA,
+ ctx->shared.SAREASize,
+ (drmAddressPtr)(&ctx->pSAREA)) < 0)
+ {
+ fprintf(stderr, "[drm] drmMap failed\n");
+ return 0;
+ }
+ memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
+ fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
+ ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
+
+ if (drmAddMap(ctx->drmFD,
+ ctx->MMIOStart,
+ ctx->MMIOSize,
+ DRM_REGISTERS,
+ DRM_READ_ONLY,
+ &info->regs) < 0) {
+ fprintf(stderr, "[drm] drmAddMap mmio failed\n");
+ return 0;
+ }
+ fprintf(stderr,
+ "[drm] register handle = 0x%08x\n", info->regs);
+
+ I810DRIAgpPreInit(ctx, info);
+ /* Need to AddMap the framebuffer and mmio regions here:
+ */
+ if (drmAddMap( ctx->drmFD,
+ (drm_handle_t)ctx->FBStart,
+ ctx->FBSize,
+ DRM_FRAME_BUFFER,
+#ifndef _EMBEDDED
+ 0,
+#else
+ DRM_READ_ONLY,
+#endif
+ &ctx->shared.hFrameBuffer) < 0)
+ {
+ fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
+ return 0;
+ }
+
+ fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
+ ctx->shared.hFrameBuffer);
+
+ /* Check the i810 DRM version */
+ if (!I810CheckDRMVersion(ctx, info)) {
+ return 0;
+ }
+
+ /* Initialize AGP */
+ if (!I810DRIAgpInit(ctx, info)) {
+ return 0;
+ }
+
+
+ /* Memory manager setup */
+ if (!I810MemoryInit(ctx, info)) {
+ return 0;
+ }
+
+ /* Initialize the SAREA private data structure */
+ {
+ I810SAREAPtr pSAREAPriv;
+ pSAREAPriv = (I810SAREAPtr)(((char*)ctx->pSAREA) +
+ sizeof(drm_sarea_t));
+ memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
+ // pSAREAPriv->pf_enabled=1;
+ }
+
+
+ /* Create a 'server' context so we can grab the lock for
+ * initialization ioctls.
+ */
+ if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) {
+ fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
+ return 0;
+ }
+
+ DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0);
+
+ /* Initialize the vertex buffers list */
+ if (!I810DRIBufInit(ctx, info)) {
+ fprintf(stderr, "I810DRIBufInit failed\n");
+ DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
+ return 0;
+ }
+
+ /* Initialize the kernel data structures */
+ if (!I810DRIKernelInit(ctx, info)) {
+ fprintf(stderr, "I810DRIKernelInit failed\n");
+ DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
+ return 0;
+ }
+
+ /* Initialize IRQ */
+ I810DRIIrqInit(ctx, info);
+
+ /* Quick hack to clear the front & back buffers. Could also use
+ * the clear ioctl to do this, but would need to setup hw state
+ * first.
+ */
+#if 0
+ memset((char *)ctx->FBAddress,
+ 0,
+ info->auxPitch * ctx->cpp * ctx->shared.virtualHeight );
+
+ memset((char *)info->backbuffer,
+ 0,
+ info->auxPitch * ctx->cpp * ctx->shared.virtualHeight );
+#endif
+
+ /* This is the struct passed to i810_dri.so for its initialization */
+ ctx->driverClientMsg = malloc(sizeof(I810DRIRec));
+ ctx->driverClientMsgSize = sizeof(I810DRIRec);
+ pI810DRI = (I810DRIPtr)ctx->driverClientMsg;
+
+ pI810DRI->regs = info->regs;
+ pI810DRI->regsSize = info->regsSize;
+ // regsMap is unused
+
+ pI810DRI->backbufferSize = info->BackBuffer.Size;
+ pI810DRI->backbuffer = info->backbuffer;
+
+ pI810DRI->depthbufferSize = info->DepthBuffer.Size;
+ pI810DRI->depthbuffer = info->depthbuffer;
+
+ pI810DRI->textures = info->textures;
+ pI810DRI->textureSize = info->textureSize;
+
+ pI810DRI->agp_buffers = info->buffer_map;
+ pI810DRI->agp_buf_size = info->BufferMem.Size;
+
+ pI810DRI->deviceID = info->Chipset;
+ pI810DRI->width = ctx->shared.virtualWidth;
+ pI810DRI->height = ctx->shared.virtualHeight;
+ pI810DRI->mem = ctx->shared.fbSize;
+ pI810DRI->cpp = ctx->bpp / 8;
+ pI810DRI->bitsPerPixel = ctx->bpp;
+ pI810DRI->fbOffset = info->FrontBuffer.Start;
+ pI810DRI->fbStride = info->auxPitch;
+
+ pI810DRI->backOffset = info->BackBuffer.Start;
+ pI810DRI->depthOffset = info->DepthBuffer.Start;
+
+ pI810DRI->auxPitch = info->auxPitch;
+ pI810DRI->auxPitchBits = info->auxPitchBits;
+
+ pI810DRI->logTextureGranularity = info->logTextureGranularity;
+ pI810DRI->textureOffset = info->TexMem.Start;
+
+ pI810DRI->ringOffset = info->LpRing.mem.Start;
+ pI810DRI->ringSize = info->LpRing.mem.Size;
+
+ // drmBufs looks unused
+ pI810DRI->irq = info->irq;
+ pI810DRI->sarea_priv_offset = sizeof(drm_sarea_t);
+
+ /* Don't release the lock now - let the VT switch handler do it. */
+ return 1;
+}
+
+
+/**
+ * \brief Validate the fbdev mode.
+ *
+ * \param ctx display handle.
+ *
+ * \return one on success, or zero on failure.
+ *
+ * Saves some registers and returns 1.
+ *
+ * \sa i810ValidateMode().
+ */
+static int i810ValidateMode( const DRIDriverContext *ctx )
+{
+ unsigned char *I810MMIO = ctx->MMIOAddress;
+ I810Ptr info = ctx->driverPrivate;
+
+ return 1;
+}
+
+
+/**
+ * \brief Examine mode returned by fbdev.
+ *
+ * \param ctx display handle.
+ *
+ * \return one on success, or zero on failure.
+ *
+ * Restores registers that fbdev has clobbered and returns 1.
+ *
+ * \sa i810ValidateMode().
+ */
+static int i810PostValidateMode( const DRIDriverContext *ctx )
+{
+ unsigned char *I810MMIO = ctx->MMIOAddress;
+ I810Ptr info = ctx->driverPrivate;
+
+ return 1;
+}
+
+
+/**
+ * \brief Initialize the framebuffer device mode
+ *
+ * \param ctx display handle.
+ *
+ * \return one on success, or zero on failure.
+ *
+ * Fills in \p info with some default values and some information from \p ctx
+ * and then calls I810ScreenInit() for the screen initialization.
+ *
+ * Before exiting clears the framebuffer memory accessing it directly.
+ */
+static int i810InitFBDev( DRIDriverContext *ctx )
+{
+ I810Ptr info = calloc(1, sizeof(*info));
+
+ {
+ int dummy = ctx->shared.virtualWidth;
+
+ switch (ctx->bpp / 8) {
+ case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break;
+ case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break;
+ case 3:
+ case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break;
+ }
+
+ ctx->shared.virtualWidth = dummy;
+ }
+
+ ctx->driverPrivate = (void *)info;
+
+ info->Chipset = ctx->chipset;
+
+ if (!I810ScreenInit( ctx, info ))
+ return 0;
+
+
+ return 1;
+}
+
+
+/**
+ * \brief The screen is being closed, so clean up any state and free any
+ * resources used by the DRI.
+ *
+ * \param ctx display handle.
+ *
+ * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
+ * private data.
+ */
+static void i810HaltFBDev( DRIDriverContext *ctx )
+{
+ drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
+ drmClose(ctx->drmFD);
+
+ if (ctx->driverPrivate) {
+ free(ctx->driverPrivate);
+ ctx->driverPrivate = 0;
+ }
+}
+
+
+extern void i810NotifyFocus( int );
+
+/**
+ * \brief Exported driver interface for Mini GLX.
+ *
+ * \sa DRIDriverRec.
+ */
+const struct DRIDriverRec __driDriver = {
+ i810ValidateMode,
+ i810PostValidateMode,
+ i810InitFBDev,
+ i810HaltFBDev,
+ I810EngineShutdown,
+ I810EngineRestore,
+#ifndef _EMBEDDED
+ 0,
+#else
+ i810NotifyFocus,
+#endif
+};
diff --git a/src/server/i810_dri.h b/src/server/i810_dri.h
new file mode 100644
index 0000000..408a4eb
--- /dev/null
+++ b/src/server/i810_dri.h
@@ -0,0 +1,128 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h,v 1.10 2002/12/10 01:27:04 dawes Exp $ */
+
+#ifndef _I810_DRI_
+#define _I810_DRI_
+
+#include "xf86drm.h"
+#include "i810_common.h"
+
+#define I810_MAX_DRAWABLES 256
+
+typedef struct {
+ drm_handle_t regs;
+ drmSize regsSize;
+
+ drmSize backbufferSize;
+ drm_handle_t backbuffer;
+
+ drmSize depthbufferSize;
+ drm_handle_t depthbuffer;
+
+ drm_handle_t textures;
+ int textureSize;
+
+ drm_handle_t agp_buffers;
+ drmSize agp_buf_size;
+
+ int deviceID;
+ int width;
+ int height;
+ int mem;
+ int cpp;
+ int bitsPerPixel;
+ int fbOffset;
+ int fbStride;
+
+ int backOffset;
+ int depthOffset;
+
+ int auxPitch;
+ int auxPitchBits;
+
+ int logTextureGranularity;
+ int textureOffset;
+
+ /* For non-dma direct rendering.
+ */
+ int ringOffset;
+ int ringSize;
+
+ drmBufMapPtr drmBufs;
+ int irq;
+ unsigned int sarea_priv_offset;
+
+} I810DRIRec, *I810DRIPtr;
+
+/* WARNING: Do not change the SAREA structure without changing the kernel
+ * as well */
+
+#define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
+#define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
+#define I810_UPLOAD_CTX 0x4
+#define I810_UPLOAD_BUFFERS 0x8
+#define I810_UPLOAD_TEX0 0x10
+#define I810_UPLOAD_TEX1 0x20
+#define I810_UPLOAD_CLIPRECTS 0x40
+
+typedef struct {
+ unsigned char next, prev; /* indices to form a circular LRU */
+ unsigned char in_use; /* owned by a client, or free? */
+ int age; /* tracked by clients to update local LRU's */
+} I810TexRegionRec, *I810TexRegionPtr;
+
+typedef struct {
+ unsigned int ContextState[I810_CTX_SETUP_SIZE];
+ unsigned int BufferState[I810_DEST_SETUP_SIZE];
+ unsigned int TexState[2][I810_TEX_SETUP_SIZE];
+ unsigned int dirty;
+
+ unsigned int nbox;
+ drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS];
+
+ /* Maintain an LRU of contiguous regions of texture space. If
+ * you think you own a region of texture memory, and it has an
+ * age different to the one you set, then you are mistaken and
+ * it has been stolen by another client. If global texAge
+ * hasn't changed, there is no need to walk the list.
+ *
+ * These regions can be used as a proxy for the fine-grained
+ * texture information of other clients - by maintaining them
+ * in the same lru which is used to age their own textures,
+ * clients have an approximate lru for the whole of global
+ * texture space, and can make informed decisions as to which
+ * areas to kick out. There is no need to choose whether to
+ * kick out your own texture or someone else's - simply eject
+ * them all in LRU order.
+ */
+
+ drmTextureRegion texList[I810_NR_TEX_REGIONS + 1];
+
+ /* Last elt is sentinal */
+ int texAge; /* last time texture was uploaded */
+
+ int last_enqueue; /* last time a buffer was enqueued */
+ int last_dispatch; /* age of the most recently dispatched buffer */
+ int last_quiescent; /* */
+
+ int ctxOwner; /* last context to upload state */
+
+ int vertex_prim;
+
+ int pf_enabled; /* is pageflipping allowed? */
+ int pf_active; /* is pageflipping active right now? */
+ int pf_current_page; /* which buffer is being displayed? */
+
+
+} I810SAREARec, *I810SAREAPtr;
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} I810ConfigPrivRec, *I810ConfigPrivPtr;
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} I810DRIContextRec, *I810DRIContextPtr;
+
+#endif
diff --git a/src/server/i810_reg.h b/src/server/i810_reg.h
new file mode 100644
index 0000000..c935982
--- /dev/null
+++ b/src/server/i810_reg.h
@@ -0,0 +1,992 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_reg.h,v 1.13 2003/02/06 04:18:04 dawes Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ *
+ * based on the i740 driver by
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ *
+ */
+
+#ifndef _I810_REG_H
+#define _I810_REG_H
+
+/* I/O register offsets
+ */
+#define SRX 0x3C4 /* p208 */
+#define GRX 0x3CE /* p213 */
+#define ARX 0x3C0 /* p224 */
+
+/* VGA Color Palette Registers */
+#define DACMASK 0x3C6 /* p232 */
+#define DACSTATE 0x3C7 /* p232 */
+#define DACRX 0x3C7 /* p233 */
+#define DACWX 0x3C8 /* p233 */
+#define DACDATA 0x3C9 /* p233 */
+
+/* CRT Controller Registers (CRX) */
+#define START_ADDR_HI 0x0C /* p246 */
+#define START_ADDR_LO 0x0D /* p247 */
+#define VERT_SYNC_END 0x11 /* p249 */
+#define EXT_VERT_TOTAL 0x30 /* p257 */
+#define EXT_VERT_DISPLAY 0x31 /* p258 */
+#define EXT_VERT_SYNC_START 0x32 /* p259 */
+#define EXT_VERT_BLANK_START 0x33 /* p260 */
+#define EXT_HORIZ_TOTAL 0x35 /* p261 */
+#define EXT_HORIZ_BLANK 0x39 /* p261 */
+#define EXT_START_ADDR 0x40 /* p262 */
+#define EXT_START_ADDR_ENABLE 0x80
+#define EXT_OFFSET 0x41 /* p263 */
+#define EXT_START_ADDR_HI 0x42 /* p263 */
+#define INTERLACE_CNTL 0x70 /* p264 */
+#define INTERLACE_ENABLE 0x80
+#define INTERLACE_DISABLE 0x00
+
+/* Miscellaneous Output Register
+ */
+#define MSR_R 0x3CC /* p207 */
+#define MSR_W 0x3C2 /* p207 */
+#define IO_ADDR_SELECT 0x01
+
+#define MDA_BASE 0x3B0 /* p207 */
+#define CGA_BASE 0x3D0 /* p207 */
+
+/* CR80 - IO Control, p264
+ */
+#define IO_CTNL 0x80
+#define EXTENDED_ATTR_CNTL 0x02
+#define EXTENDED_CRTC_CNTL 0x01
+
+/* GR10 - Address mapping, p221
+ */
+#define ADDRESS_MAPPING 0x10
+#define PAGE_TO_LOCAL_MEM_ENABLE 0x10
+#define GTT_MEM_MAP_ENABLE 0x08
+#define PACKED_MODE_ENABLE 0x04
+#define LINEAR_MODE_ENABLE 0x02
+#define PAGE_MAPPING_ENABLE 0x01
+
+/* Blitter control, p378
+ */
+#define BITBLT_CNTL 0x7000c
+#define COLEXP_MODE 0x30
+#define COLEXP_8BPP 0x00
+#define COLEXP_16BPP 0x10
+#define COLEXP_24BPP 0x20
+#define COLEXP_RESERVED 0x30
+#define BITBLT_STATUS 0x01
+
+/* p375.
+ */
+#define DISPLAY_CNTL 0x70008
+#define VGA_WRAP_MODE 0x02
+#define VGA_WRAP_AT_256KB 0x00
+#define VGA_NO_WRAP 0x02
+#define GUI_MODE 0x01
+#define STANDARD_VGA_MODE 0x00
+#define HIRES_MODE 0x01
+
+/* p375
+ */
+#define PIXPIPE_CONFIG_0 0x70009
+#define DAC_8_BIT 0x80
+#define DAC_6_BIT 0x00
+#define HW_CURSOR_ENABLE 0x10
+#define EXTENDED_PALETTE 0x01
+
+/* p375
+ */
+#define PIXPIPE_CONFIG_1 0x7000a
+#define DISPLAY_COLOR_MODE 0x0F
+#define DISPLAY_VGA_MODE 0x00
+#define DISPLAY_8BPP_MODE 0x02
+#define DISPLAY_15BPP_MODE 0x04
+#define DISPLAY_16BPP_MODE 0x05
+#define DISPLAY_24BPP_MODE 0x06
+#define DISPLAY_32BPP_MODE 0x07
+
+/* p375
+ */
+#define PIXPIPE_CONFIG_2 0x7000b
+#define DISPLAY_GAMMA_ENABLE 0x08
+#define DISPLAY_GAMMA_DISABLE 0x00
+#define OVERLAY_GAMMA_ENABLE 0x04
+#define OVERLAY_GAMMA_DISABLE 0x00
+
+
+/* p380
+ */
+#define DISPLAY_BASE 0x70020
+#define DISPLAY_BASE_MASK 0x03fffffc
+
+
+/* Cursor control registers, pp383-384
+ */
+/* Desktop (845G, 865G) */
+#define CURSOR_CONTROL 0x70080
+#define CURSOR_ENABLE 0x80000000
+#define CURSOR_GAMMA_ENABLE 0x40000000
+#define CURSOR_STRIDE_MASK 0x30000000
+#define CURSOR_FORMAT_SHIFT 24
+#define CURSOR_FORMAT_MASK (0x07 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_2C (0x00 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_3C (0x01 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_4C (0x02 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_ARGB (0x04 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_XRGB (0x05 << CURSOR_FORMAT_SHIFT)
+
+/* Mobile and i810 */
+#define CURSOR_A_CONTROL CURSOR_CONTROL
+#define CURSOR_ORIGIN_SCREEN 0x00 /* i810 only */
+#define CURSOR_ORIGIN_DISPLAY 0x1 /* i810 only */
+#define CURSOR_MODE 0x27
+#define CURSOR_MODE_DISABLE 0x00
+#define CURSOR_MODE_32_4C_AX 0x01 /* i810 only */
+#define CURSOR_MODE_64_3C 0x04
+#define CURSOR_MODE_64_4C_AX 0x05
+#define CURSOR_MODE_64_4C 0x06
+#define CURSOR_MODE_64_32B_AX 0x07
+#define CURSOR_MODE_64_ARGB_AX (0x20 | CURSOR_MODE_64_32B_AX)
+#define MCURSOR_PIPE_SELECT (1 << 28)
+#define MCURSOR_PIPE_A 0x00
+#define MCURSOR_PIPE_B (1 << 28)
+#define MCURSOR_GAMMA_ENABLE (1 << 26)
+#define MCURSOR_MEM_TYPE_LOCAL (1 << 25)
+
+
+#define CURSOR_BASEADDR 0x70084
+#define CURSOR_A_BASE CURSOR_BASEADDR
+#define CURSOR_BASEADDR_MASK 0x1FFFFF00
+#define CURSOR_A_POSITION 0x70088
+#define CURSOR_POS_SIGN 0x8000
+#define CURSOR_POS_MASK 0x007FF
+#define CURSOR_X_SHIFT 0
+#define CURSOR_Y_SHIFT 16
+#define CURSOR_X_LO 0x70088
+#define CURSOR_X_HI 0x70089
+#define CURSOR_X_POS 0x00
+#define CURSOR_X_NEG 0x80
+#define CURSOR_Y_LO 0x7008A
+#define CURSOR_Y_HI 0x7008B
+#define CURSOR_Y_POS 0x00
+#define CURSOR_Y_NEG 0x80
+
+#define CURSOR_A_PALETTE0 0x70090
+#define CURSOR_A_PALETTE1 0x70094
+#define CURSOR_A_PALETTE2 0x70098
+#define CURSOR_A_PALETTE3 0x7009C
+
+#define CURSOR_SIZE 0x700A0
+#define CURSOR_SIZE_MASK 0x3FF
+#define CURSOR_SIZE_HSHIFT 0
+#define CURSOR_SIZE_VSHIFT 12
+
+
+/* Similar registers exist in Device 0 on the i810 (pp55-65), but I'm
+ * not sure they refer to local (graphics) memory.
+ *
+ * These details are for the local memory control registers,
+ * (pp301-310). The test machines are not equiped with local memory,
+ * so nothing is tested. Only a single row seems to be supported.
+ */
+#define DRAM_ROW_TYPE 0x3000
+#define DRAM_ROW_0 0x01
+#define DRAM_ROW_0_SDRAM 0x01
+#define DRAM_ROW_0_EMPTY 0x00
+#define DRAM_ROW_CNTL_LO 0x3001
+#define DRAM_PAGE_MODE_CTRL 0x10
+#define DRAM_RAS_TO_CAS_OVRIDE 0x08
+#define DRAM_CAS_LATENCY 0x04
+#define DRAM_RAS_TIMING 0x02
+#define DRAM_RAS_PRECHARGE 0x01
+#define DRAM_ROW_CNTL_HI 0x3002
+#define DRAM_REFRESH_RATE 0x18
+#define DRAM_REFRESH_DISABLE 0x00
+#define DRAM_REFRESH_60HZ 0x08
+#define DRAM_REFRESH_FAST_TEST 0x10
+#define DRAM_REFRESH_RESERVED 0x18
+#define DRAM_SMS 0x07
+#define DRAM_SMS_NORMAL 0x00
+#define DRAM_SMS_NOP_ENABLE 0x01
+#define DRAM_SMS_ABPCE 0x02
+#define DRAM_SMS_MRCE 0x03
+#define DRAM_SMS_CBRCE 0x04
+
+/* p307
+ */
+#define DPMS_SYNC_SELECT 0x5002
+#define VSYNC_CNTL 0x08
+#define VSYNC_ON 0x00
+#define VSYNC_OFF 0x08
+#define HSYNC_CNTL 0x02
+#define HSYNC_ON 0x00
+#define HSYNC_OFF 0x02
+
+
+
+/* p317, 319
+ */
+#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */
+#define VCLK2_VCO_N 0x600a
+#define VCLK2_VCO_DIV_SEL 0x6012
+
+#define VCLK_DIVISOR_VGA0 0x6000
+#define VCLK_DIVISOR_VGA1 0x6004
+#define VCLK_POST_DIV 0x6010
+
+#define POST_DIV_SELECT 0x70
+#define POST_DIV_1 0x00
+#define POST_DIV_2 0x10
+#define POST_DIV_4 0x20
+#define POST_DIV_8 0x30
+#define POST_DIV_16 0x40
+#define POST_DIV_32 0x50
+#define VCO_LOOP_DIV_BY_4M 0x00
+#define VCO_LOOP_DIV_BY_16M 0x04
+
+
+/* Instruction Parser Mode Register
+ * - p281
+ * - 2 new bits.
+ */
+#define INST_PM 0x20c0
+#define AGP_SYNC_PACKET_FLUSH_ENABLE 0x20 /* reserved */
+#define SYNC_PACKET_FLUSH_ENABLE 0x10
+#define TWO_D_INST_DISABLE 0x08
+#define THREE_D_INST_DISABLE 0x04
+#define STATE_VAR_UPDATE_DISABLE 0x02
+#define PAL_STIP_DISABLE 0x01
+
+#define INST_DONE 0x2090
+#define INST_PS 0x20c4
+
+#define MEMMODE 0x20dc
+
+
+/* Instruction parser error register. p279
+ */
+#define IPEIR 0x2088
+#define IPEHR 0x208C
+
+
+/* General error reporting regs, p296
+ */
+#define EIR 0x20B0
+#define EMR 0x20B4
+#define ESR 0x20B8
+#define IP_ERR 0x0001
+#define ERROR_RESERVED 0xffc6
+
+
+/* Interrupt Control Registers
+ * - new bits for i810
+ * - new register hwstam (mask)
+ */
+#define HWSTAM 0x2098 /* p290 */
+#define IER 0x20a0 /* p291 */
+#define IIR 0x20a4 /* p292 */
+#define IMR 0x20a8 /* p293 */
+#define ISR 0x20ac /* p294 */
+#define HW_ERROR 0x8000
+#define SYNC_STATUS_TOGGLE 0x1000
+#define DPY_0_FLIP_PENDING 0x0800
+#define DPY_1_FLIP_PENDING 0x0400 /* not implemented on i810 */
+#define OVL_0_FLIP_PENDING 0x0200
+#define OVL_1_FLIP_PENDING 0x0100 /* not implemented on i810 */
+#define DPY_0_VBLANK 0x0080
+#define DPY_0_EVENT 0x0040
+#define DPY_1_VBLANK 0x0020 /* not implemented on i810 */
+#define DPY_1_EVENT 0x0010 /* not implemented on i810 */
+#define HOST_PORT_EVENT 0x0008 /* */
+#define CAPTURE_EVENT 0x0004 /* */
+#define USER_DEFINED 0x0002
+#define BREAKPOINT 0x0001
+
+
+#define INTR_RESERVED (0x6000 | \
+ DPY_1_FLIP_PENDING | \
+ OVL_1_FLIP_PENDING | \
+ DPY_1_VBLANK | \
+ DPY_1_EVENT | \
+ HOST_PORT_EVENT | \
+ CAPTURE_EVENT )
+
+/* FIFO Watermark and Burst Length Control Register
+ *
+ * - different offset and contents on i810 (p299) (fewer bits per field)
+ * - some overlay fields added
+ * - what does it all mean?
+ */
+#define FWATER_BLC 0x20d8
+#define FWATER_BLC2 0x20dc
+#define MM_BURST_LENGTH 0x00700000
+#define MM_FIFO_WATERMARK 0x0001F000
+#define LM_BURST_LENGTH 0x00000700
+#define LM_FIFO_WATERMARK 0x0000001F
+
+
+/* Fence/Tiling ranges [0..7]
+ */
+#define FENCE 0x2000
+#define FENCE_NR 8
+
+#define I830_FENCE_START_MASK 0x07f80000
+
+#define FENCE_START_MASK 0x03F80000
+#define FENCE_X_MAJOR 0x00000000
+#define FENCE_Y_MAJOR 0x00001000
+#define FENCE_SIZE_MASK 0x00000700
+#define FENCE_SIZE_512K 0x00000000
+#define FENCE_SIZE_1M 0x00000100
+#define FENCE_SIZE_2M 0x00000200
+#define FENCE_SIZE_4M 0x00000300
+#define FENCE_SIZE_8M 0x00000400
+#define FENCE_SIZE_16M 0x00000500
+#define FENCE_SIZE_32M 0x00000600
+#define FENCE_SIZE_64M 0x00000700
+#define FENCE_PITCH_MASK 0x00000070
+#define FENCE_PITCH_1 0x00000000
+#define FENCE_PITCH_2 0x00000010
+#define FENCE_PITCH_4 0x00000020
+#define FENCE_PITCH_8 0x00000030
+#define FENCE_PITCH_16 0x00000040
+#define FENCE_PITCH_32 0x00000050
+#define FENCE_PITCH_64 0x00000060
+#define FENCE_VALID 0x00000001
+
+
+/* Registers to control page table, p274
+ */
+#define PGETBL_CTL 0x2020
+#define PGETBL_ADDR_MASK 0xFFFFF000
+#define PGETBL_ENABLE_MASK 0x00000001
+#define PGETBL_ENABLED 0x00000001
+
+/* Register containing pge table error results, p276
+ */
+#define PGE_ERR 0x2024
+#define PGE_ERR_ADDR_MASK 0xFFFFF000
+#define PGE_ERR_ID_MASK 0x00000038
+#define PGE_ERR_CAPTURE 0x00000000
+#define PGE_ERR_OVERLAY 0x00000008
+#define PGE_ERR_DISPLAY 0x00000010
+#define PGE_ERR_HOST 0x00000018
+#define PGE_ERR_RENDER 0x00000020
+#define PGE_ERR_BLITTER 0x00000028
+#define PGE_ERR_MAPPING 0x00000030
+#define PGE_ERR_CMD_PARSER 0x00000038
+#define PGE_ERR_TYPE_MASK 0x00000007
+#define PGE_ERR_INV_TABLE 0x00000000
+#define PGE_ERR_INV_PTE 0x00000001
+#define PGE_ERR_MIXED_TYPES 0x00000002
+#define PGE_ERR_PAGE_MISS 0x00000003
+#define PGE_ERR_ILLEGAL_TRX 0x00000004
+#define PGE_ERR_LOCAL_MEM 0x00000005
+#define PGE_ERR_TILED 0x00000006
+
+
+
+/* Page table entries loaded via mmio region, p323
+ */
+#define PTE_BASE 0x10000
+#define PTE_ADDR_MASK 0x3FFFF000
+#define PTE_TYPE_MASK 0x00000006
+#define PTE_LOCAL 0x00000002
+#define PTE_MAIN_UNCACHED 0x00000000
+#define PTE_MAIN_CACHED 0x00000006
+#define PTE_VALID_MASK 0x00000001
+#define PTE_VALID 0x00000001
+
+
+/* Ring buffer registers, p277, overview p19
+ */
+#define LP_RING 0x2030
+#define HP_RING 0x2040
+
+#define RING_TAIL 0x00
+#define TAIL_ADDR 0x000FFFF8
+#define I830_TAIL_MASK 0x001FFFF8
+
+#define RING_HEAD 0x04
+#define HEAD_WRAP_COUNT 0xFFE00000
+#define HEAD_WRAP_ONE 0x00200000
+#define HEAD_ADDR 0x001FFFFC
+#define I830_HEAD_MASK 0x001FFFFC
+
+#define RING_START 0x08
+#define START_ADDR 0x00FFFFF8
+#define I830_RING_START_MASK 0xFFFFF000
+
+#define RING_LEN 0x0C
+#define RING_NR_PAGES 0x000FF000
+#define I830_RING_NR_PAGES 0x001FF000
+#define RING_REPORT_MASK 0x00000006
+#define RING_REPORT_64K 0x00000002
+#define RING_REPORT_128K 0x00000004
+#define RING_NO_REPORT 0x00000000
+#define RING_VALID_MASK 0x00000001
+#define RING_VALID 0x00000001
+#define RING_INVALID 0x00000000
+
+
+
+/* BitBlt Instructions
+ *
+ * There are many more masks & ranges yet to add.
+ */
+#define BR00_BITBLT_CLIENT 0x40000000
+#define BR00_OP_COLOR_BLT 0x10000000
+#define BR00_OP_SRC_COPY_BLT 0x10C00000
+#define BR00_OP_FULL_BLT 0x11400000
+#define BR00_OP_MONO_SRC_BLT 0x11800000
+#define BR00_OP_MONO_SRC_COPY_BLT 0x11000000
+#define BR00_OP_MONO_PAT_BLT 0x11C00000
+#define BR00_OP_MONO_SRC_COPY_IMMEDIATE_BLT (0x61 << 22)
+#define BR00_OP_TEXT_IMMEDIATE_BLT 0xc000000
+
+
+#define BR00_TPCY_DISABLE 0x00000000
+#define BR00_TPCY_ENABLE 0x00000010
+
+#define BR00_TPCY_ROP 0x00000000
+#define BR00_TPCY_NO_ROP 0x00000020
+#define BR00_TPCY_EQ 0x00000000
+#define BR00_TPCY_NOT_EQ 0x00000040
+
+#define BR00_PAT_MSB_FIRST 0x00000000 /* ? */
+
+#define BR00_PAT_VERT_ALIGN 0x000000e0
+
+#define BR00_LENGTH 0x0000000F
+
+#define BR09_DEST_ADDR 0x03FFFFFF
+
+#define BR11_SOURCE_PITCH 0x00003FFF
+
+#define BR12_SOURCE_ADDR 0x03FFFFFF
+
+#define BR13_SOLID_PATTERN 0x80000000
+#define BR13_RIGHT_TO_LEFT 0x40000000
+#define BR13_LEFT_TO_RIGHT 0x00000000
+#define BR13_MONO_TRANSPCY 0x20000000
+#define BR13_USE_DYN_DEPTH 0x04000000
+#define BR13_DYN_8BPP 0x00000000
+#define BR13_DYN_16BPP 0x01000000
+#define BR13_DYN_24BPP 0x02000000
+#define BR13_ROP_MASK 0x00FF0000
+#define BR13_DEST_PITCH 0x0000FFFF
+#define BR13_PITCH_SIGN_BIT 0x00008000
+
+#define BR14_DEST_HEIGHT 0xFFFF0000
+#define BR14_DEST_WIDTH 0x0000FFFF
+
+#define BR15_PATTERN_ADDR 0x03FFFFFF
+
+#define BR16_SOLID_PAT_COLOR 0x00FFFFFF
+#define BR16_BACKGND_PAT_CLR 0x00FFFFFF
+
+#define BR17_FGND_PAT_CLR 0x00FFFFFF
+
+#define BR18_SRC_BGND_CLR 0x00FFFFFF
+#define BR19_SRC_FGND_CLR 0x00FFFFFF
+
+
+/* Instruction parser instructions
+ */
+
+#define INST_PARSER_CLIENT 0x00000000
+#define INST_OP_FLUSH 0x02000000
+#define INST_FLUSH_MAP_CACHE 0x00000001
+
+
+#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
+
+
+/* Registers in the i810 host-pci bridge pci config space which affect
+ * the i810 graphics operations.
+ */
+#define SMRAM_MISCC 0x70
+#define GMS 0x000000c0
+#define GMS_DISABLE 0x00000000
+#define GMS_ENABLE_BARE 0x00000040
+#define GMS_ENABLE_512K 0x00000080
+#define GMS_ENABLE_1M 0x000000c0
+#define USMM 0x00000030
+#define USMM_DISABLE 0x00000000
+#define USMM_TSEG_ZERO 0x00000010
+#define USMM_TSEG_512K 0x00000020
+#define USMM_TSEG_1M 0x00000030
+#define GFX_MEM_WIN_SIZE 0x00010000
+#define GFX_MEM_WIN_32M 0x00010000
+#define GFX_MEM_WIN_64M 0x00000000
+
+/* Overkill? I don't know. Need to figure out top of mem to make the
+ * SMRAM calculations come out. Linux seems to have problems
+ * detecting it all on its own, so this seems a reasonable double
+ * check to any user supplied 'mem=...' boot param.
+ *
+ * ... unfortunately this reg doesn't work according to spec on the
+ * test hardware.
+ */
+#define WHTCFG_PAMR_DRP 0x50
+#define SYS_DRAM_ROW_0_SHIFT 16
+#define SYS_DRAM_ROW_1_SHIFT 20
+#define DRAM_MASK 0x0f
+#define DRAM_VALUE_0 0
+#define DRAM_VALUE_1 8
+/* No 2 value defined */
+#define DRAM_VALUE_3 16
+#define DRAM_VALUE_4 16
+#define DRAM_VALUE_5 24
+#define DRAM_VALUE_6 32
+#define DRAM_VALUE_7 32
+#define DRAM_VALUE_8 48
+#define DRAM_VALUE_9 64
+#define DRAM_VALUE_A 64
+#define DRAM_VALUE_B 96
+#define DRAM_VALUE_C 128
+#define DRAM_VALUE_D 128
+#define DRAM_VALUE_E 192
+#define DRAM_VALUE_F 256 /* nice one, geezer */
+#define LM_FREQ_MASK 0x10
+#define LM_FREQ_133 0x10
+#define LM_FREQ_100 0x00
+
+
+
+
+/* These are 3d state registers, but the state is invarient, so we let
+ * the X server handle it:
+ */
+
+
+
+/* GFXRENDERSTATE_COLOR_CHROMA_KEY, p135
+ */
+#define GFX_OP_COLOR_CHROMA_KEY ((0x3<<29)|(0x1d<<24)|(0x2<<16)|0x1)
+#define CC1_UPDATE_KILL_WRITE (1<<28)
+#define CC1_ENABLE_KILL_WRITE (1<<27)
+#define CC1_DISABLE_KILL_WRITE 0
+#define CC1_UPDATE_COLOR_IDX (1<<26)
+#define CC1_UPDATE_CHROMA_LOW (1<<25)
+#define CC1_UPDATE_CHROMA_HI (1<<24)
+#define CC1_CHROMA_LOW_MASK ((1<<24)-1)
+#define CC2_COLOR_IDX_SHIFT 24
+#define CC2_COLOR_IDX_MASK (0xff<<24)
+#define CC2_CHROMA_HI_MASK ((1<<24)-1)
+
+
+#define GFX_CMD_CONTEXT_SEL ((0<<29)|(0x5<<23))
+#define CS_UPDATE_LOAD (1<<17)
+#define CS_UPDATE_USE (1<<16)
+#define CS_UPDATE_LOAD (1<<17)
+#define CS_LOAD_CTX0 0
+#define CS_LOAD_CTX1 (1<<8)
+#define CS_USE_CTX0 0
+#define CS_USE_CTX1 (1<<0)
+
+/* I810 LCD/TV registers */
+#define LCD_TV_HTOTAL 0x60000
+#define LCD_TV_C 0x60018
+#define LCD_TV_OVRACT 0x6001C
+
+#define LCD_TV_ENABLE (1 << 31)
+#define LCD_TV_VGAMOD (1 << 28)
+
+/* I830 CRTC registers */
+#define HTOTAL_A 0x60000
+#define HBLANK_A 0x60004
+#define HSYNC_A 0x60008
+#define VTOTAL_A 0x6000c
+#define VBLANK_A 0x60010
+#define VSYNC_A 0x60014
+#define PIPEASRC 0x6001c
+#define BCLRPAT_A 0x60020
+
+#define HTOTAL_B 0x61000
+#define HBLANK_B 0x61004
+#define HSYNC_B 0x61008
+#define VTOTAL_B 0x6100c
+#define VBLANK_B 0x61010
+#define VSYNC_B 0x61014
+#define PIPEBSRC 0x6101c
+#define BCLRPAT_B 0x61020
+
+#define DPLL_A 0x06014
+#define DPLL_B 0x06018
+#define FPA0 0x06040
+#define FPA1 0x06044
+
+#define I830_HTOTAL_MASK 0xfff0000
+#define I830_HACTIVE_MASK 0x7ff
+
+#define I830_HBLANKEND_MASK 0xfff0000
+#define I830_HBLANKSTART_MASK 0xfff
+
+#define I830_HSYNCEND_MASK 0xfff0000
+#define I830_HSYNCSTART_MASK 0xfff
+
+#define I830_VTOTAL_MASK 0xfff0000
+#define I830_VACTIVE_MASK 0x7ff
+
+#define I830_VBLANKEND_MASK 0xfff0000
+#define I830_VBLANKSTART_MASK 0xfff
+
+#define I830_VSYNCEND_MASK 0xfff0000
+#define I830_VSYNCSTART_MASK 0xfff
+
+#define I830_PIPEA_HORZ_MASK 0x7ff0000
+#define I830_PIPEA_VERT_MASK 0x7ff
+
+#define ADPA 0x61100
+#define ADPA_DAC_ENABLE (1<<31)
+#define ADPA_DAC_DISABLE 0
+#define ADPA_PIPE_SELECT_MASK (1<<30)
+#define ADPA_PIPE_A_SELECT 0
+#define ADPA_PIPE_B_SELECT (1<<30)
+#define ADPA_USE_VGA_HVPOLARITY (1<<15)
+#define ADPA_SETS_HVPOLARITY 0
+#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
+#define ADPA_VSYNC_CNTL_ENABLE 0
+#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
+#define ADPA_HSYNC_CNTL_ENABLE 0
+#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
+#define ADPA_VSYNC_ACTIVE_LOW 0
+#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
+#define ADPA_HSYNC_ACTIVE_LOW 0
+
+
+#define DVOA 0x61120
+#define DVOB 0x61140
+#define DVOC 0x61160
+#define DVO_ENABLE (1<<31)
+
+#define DVOA_SRCDIM 0x61124
+#define DVOB_SRCDIM 0x61144
+#define DVOC_SRCDIM 0x61164
+
+#define LVDS 0x61180
+
+#define PIPEACONF 0x70008
+#define PIPEACONF_ENABLE (1<<31)
+#define PIPEACONF_DISABLE 0
+#define PIPEACONF_DOUBLE_WIDE (1<<30)
+#define PIPEACONF_SINGLE_WIDE 0
+#define PIPEACONF_PIPE_UNLOCKED 0
+#define PIPEACONF_PIPE_LOCKED (1<<25)
+#define PIPEACONF_PALETTE 0
+#define PIPEACONF_GAMMA (1<<24)
+
+#define PIPEBCONF 0x71008
+#define PIPEBCONF_ENABLE (1<<31)
+#define PIPEBCONF_DISABLE 0
+#define PIPEBCONF_GAMMA (1<<24)
+#define PIPEBCONF_PALETTE 0
+
+#define DSPACNTR 0x70180
+#define DSPBCNTR 0x71180
+#define DISPLAY_PLANE_ENABLE (1<<31)
+#define DISPLAY_PLANE_DISABLE 0
+#define DISPPLANE_GAMMA_ENABLE (1<<30)
+#define DISPPLANE_GAMMA_DISABLE 0
+#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
+#define DISPPLANE_8BPP (0x2<<26)
+#define DISPPLANE_15_16BPP (0x4<<26)
+#define DISPPLANE_16BPP (0x5<<26)
+#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
+#define DISPPLANE_32BPP (0x7<<26)
+#define DISPPLANE_STEREO_ENABLE (1<<25)
+#define DISPPLANE_STEREO_DISABLE 0
+#define DISPPLANE_SEL_PIPE_MASK (1<<24)
+#define DISPPLANE_SEL_PIPE_A 0
+#define DISPPLANE_SEL_PIPE_B (1<<24)
+#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
+#define DISPPLANE_SRC_KEY_DISABLE 0
+#define DISPPLANE_LINE_DOUBLE (1<<20)
+#define DISPPLANE_NO_LINE_DOUBLE 0
+#define DISPPLANE_STEREO_POLARITY_FIRST 0
+#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
+/* plane B only */
+#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
+#define DISPPLANE_ALPHA_TRANS_DISABLE 0
+#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0
+#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
+
+#define DSPABASE 0x70184
+#define DSPASTRIDE 0x70188
+
+#define DSPBBASE 0x71184
+#define DSPBADDR DSPBBASE
+#define DSPBSTRIDE 0x71188
+
+/* Various masks for reserved bits, etc. */
+#define I830_FWATER1_MASK (~((1<<11)|(1<<10)|(1<<9)| \
+ (1<<8)|(1<<26)|(1<<25)|(1<<24)|(1<<5)|(1<<4)|(1<<3)| \
+ (1<<2)|(1<<1)|1|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)))
+#define I830_FWATER2_MASK ~(0)
+
+#define DV0A_RESERVED ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<16)|(1<<5)|(1<<1)|1)
+#define DV0B_RESERVED ((1<<27)|(1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<16)|(1<<5)|(1<<1)|1)
+#define VGA0_N_DIVISOR_MASK ((1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16))
+#define VGA0_M1_DIVISOR_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8))
+#define VGA0_M2_DIVISOR_MASK ((1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1)
+#define VGA0_M1M2N_RESERVED ~(VGA0_N_DIVISOR_MASK|VGA0_M1_DIVISOR_MASK|VGA0_M2_DIVISOR_MASK)
+#define VGA0_POSTDIV_MASK ((1<<7)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1)
+#define VGA1_POSTDIV_MASK ((1<<15)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8))
+#define VGA_POSTDIV_RESERVED ~(VGA0_POSTDIV_MASK|VGA1_POSTDIV_MASK|(1<<7)|(1<<15))
+#define DPLLA_POSTDIV_MASK ((1<<23)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16))
+#define DPLLA_RESERVED ((1<<27)|(1<<26)|(1<<25)|(1<<24)|(1<<22)|(1<<15)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1)
+#define ADPA_RESERVED ((1<<2)|(1<<1)|1|(1<<9)|(1<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16))
+#define SUPER_WORD 32
+#define BURST_A_MASK ((1<<11)|(1<<10)|(1<<9)|(1<<8))
+#define BURST_B_MASK ((1<<26)|(1<<25)|(1<<24))
+#define WATER_A_MASK ((1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1)
+#define WATER_B_MASK ((1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16))
+#define WATER_RESERVED ((1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<23)|(1<<22)|(1<<21)|(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<7)|(1<<6))
+#define PIPEACONF_RESERVED ((1<<29)|(1<<28)|(1<<27)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)|0xffff)
+#define PIPEBCONF_RESERVED ((1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)|0xffff)
+#define DSPACNTR_RESERVED ((1<<23)|(1<<19)|(1<<17)|(1<<16)|0xffff)
+#define DSPBCNTR_RESERVED ((1<<23)|(1<<19)|(1<<17)|(1<<16)|0x7ffe)
+
+#define I830_GMCH_CTRL 0x52
+
+#define I830_GMCH_ENABLED 0x4
+#define I830_GMCH_MEM_MASK 0x1
+#define I830_GMCH_MEM_64M 0x1
+#define I830_GMCH_MEM_128M 0
+
+#define I830_GMCH_GMS_MASK 0x70
+#define I830_GMCH_GMS_DISABLED 0x00
+#define I830_GMCH_GMS_LOCAL 0x10
+#define I830_GMCH_GMS_STOLEN_512 0x20
+#define I830_GMCH_GMS_STOLEN_1024 0x30
+#define I830_GMCH_GMS_STOLEN_8192 0x40
+
+#define I830_RDRAM_CHANNEL_TYPE 0x03010
+#define I830_RDRAM_ND(x) (((x) & 0x20) >> 5)
+#define I830_RDRAM_DDT(x) (((x) & 0x18) >> 3)
+
+#define I855_GMCH_GMS_MASK (0x7 << 4)
+#define I855_GMCH_GMS_DISABLED 0x00
+#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4)
+#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4)
+#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4)
+#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4)
+#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4)
+
+#define I85X_CAPID 0x44
+#define I85X_VARIANT_MASK 0x7
+#define I85X_VARIANT_SHIFT 5
+#define I855_GME 0x0
+#define I855_GM 0x4
+#define I852_GME 0x2
+#define I852_GM 0x5
+
+/* BLT commands */
+#define COLOR_BLT_CMD ((2<<29)|(0x40<<22)|(0x3))
+#define COLOR_BLT_WRITE_ALPHA (1<<21)
+#define COLOR_BLT_WRITE_RGB (1<<20)
+
+#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|(0x4))
+#define XY_COLOR_BLT_WRITE_ALPHA (1<<21)
+#define XY_COLOR_BLT_WRITE_RGB (1<<20)
+
+#define XY_SETUP_CLIP_BLT_CMD ((2<<29)|(3<<22)|1)
+
+#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
+#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
+#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
+
+#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|0x4)
+#define SRC_COPY_BLT_WRITE_ALPHA (1<<21)
+#define SRC_COPY_BLT_WRITE_RGB (1<<20)
+
+#define XY_MONO_PAT_BLT_CMD ((0x2<<29)|(0x52<<22)|0x7)
+#define XY_MONO_PAT_VERT_SEED ((1<<10)|(1<<9)|(1<<8))
+#define XY_MONO_PAT_HORT_SEED ((1<<14)|(1<<13)|(1<<12))
+#define XY_MONO_PAT_BLT_WRITE_ALPHA (1<<21)
+#define XY_MONO_PAT_BLT_WRITE_RGB (1<<20)
+
+#define XY_MONO_SRC_BLT_CMD ((0x2<<29)|(0x54<<22)|(0x6))
+#define XY_MONO_SRC_BLT_WRITE_ALPHA (1<<21)
+#define XY_MONO_SRC_BLT_WRITE_RGB (1<<20)
+
+/* 3d state */
+#define STATE3D_FOG_MODE ((3<<29)|(0x1d<<24)|(0x89<<16)|2)
+#define FOG_MODE_VERTEX (1<<31)
+#define STATE3D_MAP_COORD_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8c<<16))
+#define DISABLE_TEX_TRANSFORM (1<<28)
+#define TEXTURE_SET(x) (x<<29)
+#define STATE3D_RASTERIZATION_RULES ((3<<29)|(0x07<<24))
+#define POINT_RASTER_ENABLE (1<<15)
+#define POINT_RASTER_OGL (1<<13)
+#define STATE3D_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16))
+#define DISABLE_VIEWPORT_TRANSFORM (1<<31)
+#define DISABLE_PERSPECTIVE_DIVIDE (1<<29)
+
+#define MI_SET_CONTEXT (0x18<<23)
+#define CTXT_NO_RESTORE (1)
+#define CTXT_PALETTE_SAVE_DISABLE (1<<3)
+#define CTXT_PALETTE_RESTORE_DISABLE (1<<2)
+
+/* Dword 0 */
+#define MI_VERTEX_BUFFER (0x17<<23)
+#define MI_VERTEX_BUFFER_IDX(x) (x<<20)
+#define MI_VERTEX_BUFFER_PITCH(x) (x<<13)
+#define MI_VERTEX_BUFFER_WIDTH(x) (x<<6)
+/* Dword 1 */
+#define MI_VERTEX_BUFFER_DISABLE (1)
+
+/* Overlay Flip */
+#define MI_OVERLAY_FLIP (0x11<<23)
+#define MI_OVERLAY_FLIP_CONTINUE (0<<21)
+#define MI_OVERLAY_FLIP_ON (1<<21)
+#define MI_OVERLAY_FLIP_OFF (2<<21)
+
+/* Wait for Events */
+#define MI_WAIT_FOR_EVENT (0x03<<23)
+#define MI_WAIT_FOR_OVERLAY_FLIP (1<<16)
+
+/* Flush */
+#define MI_FLUSH (0x04<<23)
+#define MI_WRITE_DIRTY_STATE (1<<4)
+#define MI_END_SCENE (1<<3)
+#define MI_INHIBIT_RENDER_CACHE_FLUSH (1<<2)
+#define MI_INVALIDATE_MAP_CACHE (1<<0)
+
+/* Noop */
+#define MI_NOOP 0x00
+#define MI_NOOP_WRITE_ID (1<<22)
+#define MI_NOOP_ID_MASK (1<<22 - 1)
+
+#define STATE3D_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x01<<16))
+
+/* STATE3D_FOG_MODE stuff */
+#define ENABLE_FOG_SOURCE (1<<27)
+#define ENABLE_FOG_CONST (1<<24)
+#define ENABLE_FOG_DENSITY (1<<23)
+
+
+#define MAX_DISPLAY_PIPES 2
+
+typedef enum {
+ CrtIndex = 0,
+ TvIndex,
+ DfpIndex,
+ LfpIndex,
+ Tv2Index,
+ Dfp2Index,
+ UnknownIndex,
+ Unknown2Index,
+ NumDisplayTypes,
+ NumKnownDisplayTypes = UnknownIndex
+} DisplayType;
+
+/* What's connected to the pipes (as reported by the BIOS) */
+#define PIPE_ACTIVE_MASK 0xff
+#define PIPE_CRT_ACTIVE (1 << CrtIndex)
+#define PIPE_TV_ACTIVE (1 << TvIndex)
+#define PIPE_DFP_ACTIVE (1 << DfpIndex)
+#define PIPE_LCD_ACTIVE (1 << LfpIndex)
+#define PIPE_TV2_ACTIVE (1 << Tv2Index)
+#define PIPE_DFP2_ACTIVE (1 << Dfp2Index)
+#define PIPE_UNKNOWN_ACTIVE ((1 << UnknownIndex) | \
+ (1 << Unknown2Index))
+
+#define PIPE_SIZED_DISP_MASK (PIPE_DFP_ACTIVE | \
+ PIPE_LCD_ACTIVE | \
+ PIPE_DFP2_ACTIVE)
+
+#define PIPE_A_SHIFT 0
+#define PIPE_B_SHIFT 8
+#define PIPE_SHIFT(n) ((n) == 0 ? \
+ PIPE_A_SHIFT : PIPE_B_SHIFT)
+
+/*
+ * Some BIOS scratch area registers. The 845 (and 830?) store the amount
+ * of video memory available to the BIOS in SWF1.
+ */
+
+#define SWF0 0x71410
+#define SWF1 0x71414
+#define SWF2 0x71418
+#define SWF3 0x7141c
+#define SWF4 0x71420
+#define SWF5 0x71424
+#define SWF6 0x71428
+
+/*
+ * 855 scratch registers.
+ */
+#define SWF00 0x70410
+#define SWF01 0x70414
+#define SWF02 0x70418
+#define SWF03 0x7041c
+#define SWF04 0x70420
+#define SWF05 0x70424
+#define SWF06 0x70428
+
+#define SWF10 SWF0
+#define SWF11 SWF1
+#define SWF12 SWF2
+#define SWF13 SWF3
+#define SWF14 SWF4
+#define SWF15 SWF5
+#define SWF16 SWF6
+
+#define SWF30 0x72414
+#define SWF31 0x72418
+#define SWF32 0x7241c
+
+/*
+ * Overlay registers. These are overlay registers accessed via MMIO.
+ * Those loaded via the overlay register page are defined in i830_video.c.
+ */
+#define OVADD 0x30000
+
+#define DOVSTA 0x30008
+#define OC_BUF (0x3<<20)
+
+#define OGAMC5 0x30010
+#define OGAMC4 0x30014
+#define OGAMC3 0x30018
+#define OGAMC2 0x3001c
+#define OGAMC1 0x30020
+#define OGAMC0 0x30024
+
+
+/*
+ * Palette registers
+ */
+#define PALETTE_A 0x0a000
+#define PALETTE_B 0x0a800
+
+#endif /* _I810_REG_H */