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